1import pytest
2
3
4def pytest_addoption(parser):
5    group = parser.getgroup("regressions")
6    group.addoption(
7        "--force-regen",
8        action="store_true",
9        default=False,
10        help="Re-generate all data_regression fixture data files.",
11    )
12
13
14@pytest.fixture
15def data_regression(datadir, original_datadir, request):
16    """
17    Fixture used to test arbitrary data against known versions previously
18    recorded by this same fixture. Useful to test 3rd party APIs or where testing directly
19    generated data from other sources.
20
21    Create a dict in your test containing a arbitrary data you want to test, and
22    call the `Check` function. The first time it will fail but will generate a file in your
23    data directory.
24
25    Subsequent runs against the same data will now compare against the generated file and pass
26    if the dicts are equal, or fail showing a diff otherwise. To regenerate the data,
27    either set `force_regen` attribute to True or pass the `--force-regen` flag to pytest
28    which will regenerate the data files for all tests. Make sure to diff the files to ensure
29    the new changes are expected and not regressions.
30
31    The dict may be anything serializable by the `yaml` library.
32
33    :type datadir: Path
34    :type request: FixtureRequest
35    :rtype: DataRegressionFixture
36    :return: Data regression fixture.
37    """
38    from .data_regression import DataRegressionFixture
39
40    return DataRegressionFixture(datadir, original_datadir, request)
41
42
43@pytest.fixture
44def dataframe_regression(datadir, original_datadir, request):
45    """
46    Example usage:
47
48    def testSomeData(num_regression):
49        dataframe_regression.check(
50            pandas.DataFrame.from_dict(
51                {
52                    'U_gas': U[0],
53                    'U_liquid': U[1],
54                    'gas_vol_frac [-]': α[0],
55                    'liquid_vol_frac [-]': α[1],
56                    'P': Pa_to_bar(P),
57                }
58            ),
59            default_tolerance=dict(atol=1e-8, rtol=1e-8)
60        )
61
62    :type embed_data: _EmbedDataFixture
63    :type request: FixtureRequest
64    :rtype: DataRegressionFixture
65    :return: Data regression fixture.
66    """
67    from .dataframe_regression import DataFrameRegressionFixture
68
69    return DataFrameRegressionFixture(datadir, original_datadir, request)
70
71
72@pytest.fixture
73def file_regression(datadir, original_datadir, request):
74    """
75    Very similar to `data_regression`, but instead of saving data to YAML file it saves to an
76    arbitrary format.
77
78    Useful when used to compare contents of files of specific format (like documents, for instance).
79
80    :type embed_data: _EmbedDataFixture
81    :type request: FixtureRequest
82    :rtype: FileRegressionFixture
83    :return: File regression fixture.
84    """
85    from .file_regression import FileRegressionFixture
86
87    return FileRegressionFixture(datadir, original_datadir, request)
88
89
90@pytest.fixture
91def num_regression(datadir, original_datadir, request):
92    """
93    Example usage:
94
95    def testSomeData(num_regression):
96        num_regression.check(
97            {
98                'U_gas': U[0],
99                'U_liquid': U[1],
100                'gas_vol_frac [-]': α[0],
101                'liquid_vol_frac [-]': α[1],
102                'P': Pa_to_bar(P),
103            },
104            data_index=positions,
105            default_tolerance=dict(atol=1e-8, rtol=1e-8)
106        )
107
108    :type embed_data: _EmbedDataFixture
109    :type request: FixtureRequest
110    :rtype: DataRegressionFixture
111    :return: Data regression fixture.
112    """
113    from .num_regression import NumericRegressionFixture
114
115    return NumericRegressionFixture(datadir, original_datadir, request)
116
117
118@pytest.fixture
119def image_regression(datadir, original_datadir, request):
120    """
121    Regression checks for images, accounting for small differences between them.
122
123    Example:
124        def test_plots(datadir, image_regression):
125            path = generate_plot(datadir / 'plot.png')
126            image_regression.check(path.read_bytes(), diff_threshold=2.5)  # 2.5%
127    """
128    from .image_regression import ImageRegressionFixture
129
130    return ImageRegressionFixture(datadir, original_datadir, request)
131