From dc1c808edc1ad0cd6a867edfd31ad88e0277d8fa Mon Sep 17 00:00:00 2001 From: Yujong Lee Date: Mon, 31 Aug 2026 17:04:19 -0700 Subject: [PATCH] refactor(tests): simplify transformation contract fixture --- .../cases/mistral/ocr.json | 1 - tests/transform_contracts/conftest.py | 19 ------------------- tests/transform_contracts/loader.py | 4 ++-- tests/transform_contracts/schema.py | 7 +++---- tests/transform_contracts/test_contracts.py | 18 +++++++++++++++++- tests/transform_contracts/test_foundation.py | 7 ------- 6 files changed, 22 insertions(+), 34 deletions(-) delete mode 100644 tests/transform_contracts/conftest.py diff --git a/tests/transform_contracts/cases/mistral/ocr.json b/tests/transform_contracts/cases/mistral/ocr.json index 38ae9b1cc0f..eb9ce95a8f2 100644 --- a/tests/transform_contracts/cases/mistral/ocr.json +++ b/tests/transform_contracts/cases/mistral/ocr.json @@ -1,5 +1,4 @@ { - "schema_version": 1, "cases": [ { "id": "mistral.ocr.get_supported_ocr_params.latest", diff --git a/tests/transform_contracts/conftest.py b/tests/transform_contracts/conftest.py deleted file mode 100644 index 623e94f8509..00000000000 --- a/tests/transform_contracts/conftest.py +++ /dev/null @@ -1,19 +0,0 @@ -from __future__ import annotations - -from typing import Final - -import pytest - -from tests.transform_contracts.loader import load_contract_cases - - -def pytest_generate_tests(metafunc: pytest.Metafunc) -> None: - if "contract_case" not in metafunc.fixturenames: - return - cases: Final = load_contract_cases() - metafunc.parametrize("contract_case", cases, ids=tuple(case.id for case in cases)) - - -@pytest.fixture(autouse=True) -def use_local_model_cost_map(monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True") diff --git a/tests/transform_contracts/loader.py b/tests/transform_contracts/loader.py index 3d83115345c..eb1693f12f5 100644 --- a/tests/transform_contracts/loader.py +++ b/tests/transform_contracts/loader.py @@ -6,7 +6,7 @@ from typing import Final from pydantic import ValidationError -from tests.transform_contracts.schema import CONTRACT_SUITE_ADAPTER, ContractSuiteV1, TransformationCase +from tests.transform_contracts.schema import CONTRACT_SUITE_ADAPTER, ContractSuite, TransformationCase CONTRACTS_ROOT: Final = Path(__file__).resolve().parent CASES_ROOT: Final = CONTRACTS_ROOT / "cases" @@ -21,7 +21,7 @@ def discover_contract_paths(root: Path = CASES_ROOT) -> tuple[Path, ...]: raise FileNotFoundError(f"no transformation contract files found under: {root}") -def load_contract_file(path: Path) -> ContractSuiteV1: +def load_contract_file(path: Path) -> ContractSuite: try: return CONTRACT_SUITE_ADAPTER.validate_json(path.read_text(encoding="utf-8")) except (OSError, ValidationError) as exc: diff --git a/tests/transform_contracts/schema.py b/tests/transform_contracts/schema.py index 12e1a16bd42..6e489e11615 100644 --- a/tests/transform_contracts/schema.py +++ b/tests/transform_contracts/schema.py @@ -106,12 +106,11 @@ def expected_output(case: TransformationCase) -> JsonValue: return case.expected -class ContractSuiteV1(_ContractModel): - schema_version: Literal[1] +class ContractSuite(_ContractModel): cases: tuple[TransformationCase, ...] = Field(min_length=1) @model_validator(mode="after") - def validate_id_namespaces(self) -> ContractSuiteV1: + def validate_id_namespaces(self) -> ContractSuite: invalid: tuple[TransformationCase, ...] = tuple( case for case in self.cases if not case.id.startswith(f"{case.operation}.") ) @@ -121,4 +120,4 @@ class ContractSuiteV1(_ContractModel): raise ValueError(f"case id must start with '{case.operation}.'") -CONTRACT_SUITE_ADAPTER: TypeAdapter[ContractSuiteV1] = TypeAdapter(ContractSuiteV1) +CONTRACT_SUITE_ADAPTER: TypeAdapter[ContractSuite] = TypeAdapter(ContractSuite) diff --git a/tests/transform_contracts/test_contracts.py b/tests/transform_contracts/test_contracts.py index 0c7c722e6e0..d60ad1ce6e6 100644 --- a/tests/transform_contracts/test_contracts.py +++ b/tests/transform_contracts/test_contracts.py @@ -1,8 +1,24 @@ -from typing import Final +from typing import Final, Protocol +import pytest + +from tests.transform_contracts.loader import load_contract_cases from tests.transform_contracts.registry import run_contract_case from tests.transform_contracts.schema import JsonValue, TransformationCase, expected_output +_CONTRACT_CASES: Final = load_contract_cases() + + +class _ContractCaseRequest(Protocol): + @property + def param(self) -> TransformationCase: ... + + +@pytest.fixture(params=_CONTRACT_CASES, ids=tuple(case.id for case in _CONTRACT_CASES)) +def contract_case(request: _ContractCaseRequest, monkeypatch: pytest.MonkeyPatch) -> TransformationCase: + monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True") + return request.param + def test_transformation_contract(contract_case: TransformationCase) -> None: actual: Final[JsonValue] = run_contract_case(contract_case) diff --git a/tests/transform_contracts/test_foundation.py b/tests/transform_contracts/test_foundation.py index 732f2caa991..ffb987bdab9 100644 --- a/tests/transform_contracts/test_foundation.py +++ b/tests/transform_contracts/test_foundation.py @@ -7,7 +7,6 @@ from tests.transform_contracts.loader import discover_contract_paths, load_contr _VALID_CASE: Final = """ { - "schema_version": 1, "cases": [ { "id": "mistral.ocr.get_supported_ocr_params.latest", @@ -39,12 +38,6 @@ def test_invalid_json_fails_loudly(tmp_path: Path) -> None: load_contract_cases(tmp_path) -def test_unsupported_schema_version_fails_loudly(tmp_path: Path) -> None: - _write(tmp_path / "future.json", _VALID_CASE.replace('"schema_version": 1', '"schema_version": 2')) - with pytest.raises(ValueError, match="invalid transformation contract file"): - load_contract_cases(tmp_path) - - def test_duplicate_case_ids_fail_loudly(tmp_path: Path) -> None: _write(tmp_path / "first.json", _VALID_CASE) _write(tmp_path / "second.json", _VALID_CASE)