/
/
/
1"""Fixture management utilities for nicovideo tests."""
2
3from __future__ import annotations
4
5import json
6import pathlib
7from typing import TYPE_CHECKING, cast
8
9import pytest
10
11if TYPE_CHECKING:
12 from pydantic import BaseModel
13
14from tests.providers.nicovideo.types import JsonContainer
15
16
17class FixtureLoader:
18 """Loads and validates test fixtures with type validation."""
19
20 def __init__(self, fixtures_dir: pathlib.Path) -> None:
21 """Initialize the fixture manager with the directory containing fixtures."""
22 self.fixtures_dir = fixtures_dir
23
24 def load_fixture(self, relative_path: pathlib.Path) -> BaseModel | list[BaseModel] | None:
25 """Load and validate a JSON fixture against its expected type."""
26 data = self._load_json_fixture(relative_path)
27
28 fixture_type = self._get_fixture_type_from_path(relative_path)
29 if fixture_type is None:
30 pytest.fail(f"Unknown fixture type for {relative_path}")
31
32 try:
33 if isinstance(data, list):
34 return [fixture_type.model_validate(item) for item in data]
35 # Single object case
36 return fixture_type.model_validate(data)
37 except Exception as e:
38 pytest.fail(f"Failed to validate fixture {relative_path}: {e}")
39
40 def _get_fixture_type_from_path(self, relative_path: pathlib.Path) -> type[BaseModel] | None:
41 from tests.providers.nicovideo.fixture_data.fixture_type_mappings import ( # noqa: PLC0415 - Because it does not exist before generation
42 FIXTURE_TYPE_MAPPINGS,
43 )
44
45 for key, fixture_type in FIXTURE_TYPE_MAPPINGS.items():
46 if relative_path == pathlib.Path(key):
47 return fixture_type
48 return None
49
50 def _load_json_fixture(self, relative_path: pathlib.Path) -> JsonContainer:
51 """Load a JSON fixture file."""
52 fixture_path = self.fixtures_dir / relative_path
53 if not fixture_path.exists():
54 pytest.skip(f"Fixture {fixture_path} not found")
55
56 with fixture_path.open("r", encoding="utf-8") as f:
57 return cast("JsonContainer", json.load(f))
58