Skip to content

Commit 6672261

Browse files
committed
refactor(consume): Fixtures cache
1 parent 179bbf6 commit 6672261

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

src/pytest_plugins/consume/hive_simulators/conftest.py

+29-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import io
44
import json
55
from pathlib import Path
6-
from typing import Generator, List, Literal, cast
6+
from typing import Dict, Generator, List, Literal, cast
77

88
import pytest
99
import rich
@@ -226,17 +226,40 @@ def timing_data(
226226
yield timing_data
227227

228228

229-
TestCase = TestCaseIndexFile | TestCaseStream
229+
class FixturesDict(Dict[Path, Fixtures]):
230+
"""
231+
A dictionary caches loaded fixture files to avoid reloading the same file
232+
multiple times.
233+
"""
234+
235+
def __init__(self) -> None:
236+
"""Initialize the dictionary that caches loaded fixture files."""
237+
self._fixtures: Dict[Path, Fixtures] = {}
238+
239+
def __getitem__(self, key: Path) -> Fixtures:
240+
"""Return the fixtures from the index file, if not found, load from disk."""
241+
assert key.is_file(), f"Expected a file path, got '{key}'"
242+
if key not in self._fixtures:
243+
self._fixtures[key] = Fixtures.model_validate_json(key.read_text())
244+
return self._fixtures[key]
245+
246+
247+
@pytest.fixture(scope="session")
248+
def fixture_file_loader() -> Dict[Path, Fixtures]:
249+
"""Return a singleton dictionary that caches loaded fixture files used in all tests."""
250+
return FixturesDict()
230251

231252

232253
@pytest.fixture(scope="function")
233254
def fixture(
234-
fixture_format: FixtureFormat,
235255
fixtures_source: FixturesSource,
236-
test_case: TestCase,
256+
fixture_format: FixtureFormat,
257+
fixture_file_loader: Dict[Path, Fixtures],
258+
test_case: TestCaseIndexFile | TestCaseStream,
237259
) -> BaseFixture:
238260
"""
239-
Create the blockchain engine fixture pydantic model for the current test case.
261+
Load the fixture from a file or from stream in any of the supported
262+
fixture formats.
240263
241264
The fixture is either already available within the test case (if consume
242265
is taking input on stdin) or loaded from the fixture json file if taking
@@ -248,10 +271,8 @@ def fixture(
248271
fixture = test_case.fixture
249272
else:
250273
assert isinstance(test_case, TestCaseIndexFile), "Expected an index file test case"
251-
# TODO: Optimize, json files will be loaded multiple times. This pytest fixture
252-
# is executed per test case, and a fixture json will contain multiple test cases.
253274
fixtures_file_path = Path(fixtures_source) / test_case.json_path
254-
fixtures: Fixtures = Fixtures.model_validate_json(fixtures_file_path.read_text())
275+
fixtures: Fixtures = fixture_file_loader[fixtures_file_path]
255276
fixture = fixtures[test_case.id]
256277
assert isinstance(fixture, fixture_format), (
257278
f"Expected a {fixture_format.__name__} test fixture"

0 commit comments

Comments
 (0)