File: test_deterministic.py

package info (click to toggle)
pytest-mpl 0.17.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,132 kB
  • sloc: python: 2,514; javascript: 179; makefile: 16
file content (129 lines) | stat: -rw-r--r-- 4,442 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import matplotlib
import matplotlib.pyplot as plt
import pytest
from helpers import pytester_path, skip_if_format_unsupported
from packaging.version import Version
from PIL import Image

MPL_VERSION = Version(matplotlib.__version__)

METADATA = {
    "png": {"Software": None},
    "pdf": {"Creator": None, "Producer": None, "CreationDate": None},
    "eps": {"Creator": "test"},
    "svg": {"Date": None},
}


def test_multiple_cli_flags(pytester):
    result = pytester.runpytest("--mpl", "--mpl-deterministic", "--mpl-no-deterministic")
    result.stderr.fnmatch_lines(
        ["*ValueError: Only one of `--mpl-deterministic` and `--mpl-no-deterministic` can be set.*"]
    )


def test_warning(pytester):
    path = pytester_path(pytester)
    hash_library = path / "hash_library.json"
    kwarg = f"hash_library=r'{hash_library}'"
    pytester.makepyfile(
        f"""
        import matplotlib.pyplot as plt
        import pytest
        @pytest.mark.mpl_image_compare({kwarg})
        def test_mpl():
            fig, ax = plt.subplots()
            ax.plot([1, 3, 2])
            return fig
        """
    )
    result = pytester.runpytest(f"--mpl-generate-hash-library={hash_library}")
    result.stdout.fnmatch_lines(["*FutureWarning: deterministic option not set*"])
    result.assert_outcomes(failed=1)


@pytest.mark.parametrize("file_format", ["eps", "pdf", "png", "svg"])
@pytest.mark.parametrize(
    "ini, cli, kwarg, success_expected",
    [
        ("true", "", None, True),
        ("false", "--mpl-deterministic", None, True),
        ("true", "--mpl-no-deterministic", None, False),
        ("", "--mpl-no-deterministic", True, True),
        ("true", "", False, False),
    ],
)
@pytest.mark.skipif(MPL_VERSION < Version("3.3.0"), reason="Test unsupported: Default metadata is different in MPL<3.3")
def test_config(pytester, file_format, ini, cli, kwarg, success_expected):
    skip_if_format_unsupported(file_format, using_hashes=True)

    path = pytester_path(pytester)
    baseline_dir = path / "baseline"
    hash_library = path / "hash_library.json"

    ini = f"mpl-deterministic = {ini}" if ini else ""
    pytester.makeini(
        f"""
        [pytest]
        mpl-hash-library = {hash_library}
        {ini}
        """
    )

    kwarg = f", deterministic={kwarg}" if isinstance(kwarg, bool) else ""
    pytester.makepyfile(
        f"""
        import matplotlib.pyplot as plt
        import pytest
        @pytest.mark.mpl_image_compare(savefig_kwargs={{'format': '{file_format}'}}{kwarg})
        def test_mpl():
            fig, ax = plt.subplots()
            ax.plot([1, 2, 3])
            return fig
        """
    )

    # Generate baseline hashes
    assert not hash_library.exists()
    pytester.runpytest(
        f"--mpl-generate-path={baseline_dir}",
        f"--mpl-generate-hash-library={hash_library}",
        cli,
    )
    assert hash_library.exists()
    baseline_image = baseline_dir / f"test_mpl.{file_format}"
    assert baseline_image.exists()
    deterministic_metadata = METADATA[file_format]

    if file_format == "svg":  # The only format that is reliably non-deterministic between runs
        result = pytester.runpytest("--mpl", f"--mpl-baseline-path={baseline_dir}", cli)
        if success_expected:
            result.assert_outcomes(passed=1)
        else:
            result.assert_outcomes(failed=1)

    elif file_format == "pdf":
        with open(baseline_image, "rb") as fp:
            file = str(fp.read())
        for metadata_key in deterministic_metadata.keys():
            key_in_file = fr"/{metadata_key}" in file
            if success_expected:  # metadata keys should not be in the file
                assert not key_in_file
            else:
                assert key_in_file

    else:  # "eps" or "png"
        with Image.open(str(baseline_image)) as image:
            actual_metadata = image.info
        for k, expected in deterministic_metadata.items():
            actual = actual_metadata.get(k, None)
            if success_expected:  # metadata keys should not be in the file
                if expected is None:
                    assert actual is None
                else:
                    assert actual == expected
            else:  # metadata keys should still be in the file
                if expected is None:
                    assert actual is not None
                else:
                    assert actual != expected