|
| 1 | +"""Tests targeting functions that expose sample data.""" |
| 2 | + |
| 3 | +import json |
| 4 | +from collections.abc import Generator |
| 5 | +from pathlib import Path |
| 6 | +from tempfile import TemporaryDirectory |
| 7 | + |
| 8 | +import pytest |
| 9 | +import yaml |
| 10 | + |
| 11 | +from sample_data import get_sample_data, get_sample_data_file_paths, get_sample_data_text |
| 12 | + |
| 13 | + |
| 14 | +@pytest.fixture |
| 15 | +def sample_json_content() -> str: |
| 16 | + """Fixture that returns the text content of a sample JSON file.""" |
| 17 | + return r""" |
| 18 | +{ |
| 19 | + "id": "001", |
| 20 | + "name": "foo bar", |
| 21 | + "primary email": "foo.bar@example.com", |
| 22 | + "age_in_years": 33 |
| 23 | +} |
| 24 | +""" |
| 25 | + |
| 26 | +@pytest.fixture |
| 27 | +def sample_yaml_content() -> str: |
| 28 | + """Fixture that returns the text content of a sample YAML file.""" |
| 29 | + return r""" |
| 30 | +# Some YAML documents begin with "front matter". |
| 31 | +--- |
| 32 | +id: "001" |
| 33 | +name: foo bar |
| 34 | +primary email: foo.bar@example.com |
| 35 | +age_in_years: 33 |
| 36 | +""" |
| 37 | + |
| 38 | +@pytest.fixture(autouse=True) |
| 39 | +def mock__get_traversable( |
| 40 | + monkeypatch: Generator[pytest.MonkeyPatch, None, None], |
| 41 | + sample_yaml_content: str, |
| 42 | + sample_json_content: str, |
| 43 | +) -> Generator[None, None, None]: |
| 44 | + """Fixture that mocks the `sample_data._get_traversable` helper function. |
| 45 | +
|
| 46 | + This fixture (a) creates a temporary directory, (b) populates it with sample data files, |
| 47 | + and (c) patches the `_get_traversable` function so it returns a `Path` object pointing |
| 48 | + to that temporary directory. This decouples the tests from the contents of the real |
| 49 | + `sample_data/` directory that the module-under-test accesses in production. |
| 50 | +
|
| 51 | + Note: All `Path` objects are also `Traversable` object. |
| 52 | + """ |
| 53 | + with TemporaryDirectory() as temp_dir: |
| 54 | + temp_dir_path = Path(temp_dir) |
| 55 | + (temp_dir_path / "data.json").write_text(sample_json_content) |
| 56 | + (temp_dir_path / "data.yaml").write_text(sample_yaml_content) |
| 57 | + (temp_dir_path / "data.yml").write_text(sample_yaml_content) |
| 58 | + (temp_dir_path / "data.txt").write_text("some text") # unsupported file suffix |
| 59 | + monkeypatch.setattr("sample_data._get_traversable", lambda: temp_dir_path) |
| 60 | + yield None |
| 61 | + |
| 62 | + |
| 63 | +def test_get_sample_data_file_paths_returns_list_of_file_paths_supported() -> None: |
| 64 | + """Test that `get_sample_data_file_paths` returns a list of the file paths we support.""" |
| 65 | + assert get_sample_data_file_paths() == ["data.json", "data.yaml", "data.yml"] |
| 66 | + |
| 67 | + |
| 68 | +def test_get_sample_data_text_returns_expected_sample_data_as_string( |
| 69 | + sample_json_content: str, |
| 70 | + sample_yaml_content: str, |
| 71 | +) -> None: |
| 72 | + """Test that `get_sample_data_text` returns the sample data we expect, as a string.""" |
| 73 | + for path in get_sample_data_file_paths(): |
| 74 | + if path == "data.json": |
| 75 | + assert sample_json_content == get_sample_data_text(path) |
| 76 | + if path in ("data.yaml", "data.yml"): |
| 77 | + assert sample_yaml_content == get_sample_data_text(path) |
| 78 | + |
| 79 | + |
| 80 | +def test_get_sample_data_returns_sample_data_as_python_object( |
| 81 | + sample_json_content: str, |
| 82 | + sample_yaml_content: str, |
| 83 | +) -> None: |
| 84 | + """Test that `get_sample_data` returns sample data as a Python object.""" |
| 85 | + for path in get_sample_data_file_paths(): |
| 86 | + if path == "data.json": |
| 87 | + assert json.loads(sample_json_content) == get_sample_data(path) |
| 88 | + if path in ("data.yaml", "data.yml"): |
| 89 | + assert yaml.safe_load(sample_yaml_content) == get_sample_data(path) |
| 90 | + |
| 91 | + |
| 92 | +def test_get_sample_data_rejects_unsupported_filename_extensions() -> None: |
| 93 | + """Test that `get_sample_data` raises an exception for an unsupported filename extension.""" |
| 94 | + with pytest.raises(ValueError, match=r"^Filename extension"): |
| 95 | + get_sample_data("my_file.txt") |
0 commit comments