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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
import logging
from collections.abc import Callable
from pathlib import Path
from textwrap import dedent
import pytest
from _pytest.logging import LogCaptureFixture
from testlib.fixtures.command import Command
from testlib.fixtures.env import ManagedEnv
from testlib.fixtures.file_helper import (
CopyFile,
File,
FileDeclaration,
merge_file_declaration,
with_files,
)
from testlib.fixtures.snapshot import Snapshot
from testlib.utils import get_functional2_files
def _get_f2_snapshot_files(additional_files: FileDeclaration) -> FileDeclaration:
return get_functional2_files(
merge_file_declaration(
{
"functional2": {
"testlib": {
"__init__.py": CopyFile("../__init__.py"),
"environ.py": CopyFile("../environ.py"),
"fixtures": {
"__init__.py": CopyFile("__init__.py"),
"snapshot.py": CopyFile("snapshot.py"),
"logger.py": CopyFile("logger.py"),
},
},
"conftest.py": File(
"pytest_plugins = ('testlib.fixtures.logger', 'testlib.fixtures.snapshot')"
),
}
},
additional_files,
)
)
def test_snapshot_empty_on_no_file(snapshot: Callable[[str], Snapshot]):
# no qa here, as we want to exactly check for empty string
assert snapshot("this_file_does_not_exist") == "" # noqa: PLC1901
@with_files({"empty_file.txt": File("")})
def test_snapshot_empty_on_empty_file(snapshot: Callable[[str], Snapshot]):
# no qa here, as we want to exactly check for empty string
assert snapshot("empty_file.txt") == "" # noqa: PLC1901
@with_files({"out.exp": File("Hell o' World")})
def test_snapshot_warns_on_non_symlink_file(
snapshot: Callable[[str], Snapshot], caplog: LogCaptureFixture
):
with caplog.at_level(logging.WARNING):
snapshot("out.exp")
assert len(caplog.records) == 1
assert (
caplog.records[0].msg
== "expected output file isn't a symlink. When accepting the tests output, the update might not propagate"
)
@pytest.mark.parametrize("pytest_command", [([], False)], indirect=True)
@with_files(
_get_f2_snapshot_files(
{
"functional2": {
"test_snapshot": {
"test_snapshot.py": File(
dedent("""
def test_noupdate(do_snapshot_update):
assert not do_snapshot_update
""")
)
}
}
}
)
)
def test_do_update_false_when_none_set(pytest_command: Command):
pytest_command.run().ok()
_update_test_files = _get_f2_snapshot_files(
{
"functional2": {
"test_snapshot": {
"test_snapshot.py": File(
dedent("""
def test_does_update(do_snapshot_update):
assert do_snapshot_update
""")
)
}
}
}
)
@pytest.mark.parametrize(
"pytest_command", [([], False), (["--accept-tests"], False)], indirect=True
)
@pytest.mark.parametrize("set_env", [False, True])
@with_files(_update_test_files)
def test_do_update_true_when_any_set(env: ManagedEnv, pytest_command: Command, set_env: bool):
if not (set_env or "--accept-tests" in pytest_command.argv):
pytest_command.discard()
pytest.skip("not this test case")
if set_env:
env.set_env("_NIX_TEST_ACCEPT", "1")
pytest_command.run().ok()
def _snapshot_test_files(content: str) -> FileDeclaration:
return _get_f2_snapshot_files(
{
"functional2": {
"test_snapshot": {
"test_snapshot.py": File(
dedent(f"""
def test_snapshot(snapshot, tmp_path):
(tmp_path / "test-home" / "out.exp").write_text("{content}")
assert snapshot("out.exp") == "plush plush"
""")
)
}
}
}
)
@pytest.mark.parametrize("pytest_command", [(["--accept-tests"], False)], indirect=True)
@with_files(_snapshot_test_files("plush plush"))
def test_snapshot_no_updated_when_equal(pytest_command: Command):
res = pytest_command.run().ok()
assert "the updated file can be found here" not in res.stdout_plain
@pytest.mark.parametrize("pytest_command", [([], False)], indirect=True)
@with_files(_snapshot_test_files("fops plush"))
def test_snapshot_fails_on_diff(pytest_command: Command):
res = pytest_command.run().expect(1)
assert "FAILED test_snapshot/test_snapshot.py::test_snapshot" in res.stdout_plain
@pytest.mark.parametrize("pytest_command", [(["--accept-tests"], False)], indirect=True)
@with_files(_snapshot_test_files("fops plush"))
def test_snapshot_updates_diff(files: Path, pytest_command: Command):
output_file = files / "pytest_files/test_snapshot0/test-home/out.exp"
pytest_command.run().ok()
assert output_file.read_text() == "plush plush"
@pytest.mark.parametrize("pytest_command", [(["--accept-tests"], False)], indirect=True)
@with_files(_snapshot_test_files("fops plush"))
def test_snapshot_updates_shares_updated_location_without_symlink(
files: Path, pytest_command: Command
):
expected_path = "pytest_files/test_snapshot0/test-home/out.exp"
output_file = files / expected_path
res = pytest_command.run().ok()
assert output_file.read_text() == "plush plush"
assert "the updated file can be found here" in res.stdout_plain
assert expected_path in res.stdout_plain
@pytest.mark.parametrize("pytest_command", [(["--accept-tests"], False)], indirect=True)
@with_files(_snapshot_test_files("fops plush"))
def test_snapshot_marks_skip_after_update(files: Path, pytest_command: Command):
expected_path = "pytest_files/test_snapshot0/test-home/out.exp"
output_file = files / expected_path
res = pytest_command.run().ok()
assert output_file.read_text() == "plush plush"
assert "test_snapshot/test_snapshot.py::test_snapshot SKIPPED (Updated" in res.stdout_plain
@pytest.mark.parametrize("pytest_command", [(["--accept-tests"], False)], indirect=True)
@with_files(
_get_f2_snapshot_files(
{
"functional2": {
"test_snapshot": {
"test_snapshot.py": File(
dedent("""
def test_snapshot(snapshot, tmp_path):
(tmp_path / "test-home" / "out.exp").write_text("fops plush")
(tmp_path / "test-home" / "err.exp").write_text("shork plush")
assert snapshot("out.exp") == "plush plush"
assert snapshot("err.exp") == "blobhaj"
""")
)
}
}
}
)
)
def test_snapshot_updates_multiple(files: Path, pytest_command: Command):
expected_path = "pytest_files/test_snapshot0/test-home"
first_file = files / expected_path / "out.exp"
second_file = files / expected_path / "err.exp"
res = pytest_command.run().ok()
assert "test_snapshot/test_snapshot.py::test_snapshot SKIPPED (Updated" in res.stdout_plain
assert first_file.read_text() == "plush plush"
assert second_file.read_text() == "blobhaj"
@pytest.mark.parametrize("pytest_command", [(["--accept-tests"], False)], indirect=True)
@with_files(
_get_f2_snapshot_files(
{
"functional2": {
"test_snapshot": {
"test_snapshot.py": File(
dedent("""
def test_snapshot(snapshot, tmp_path):
(tmp_path / "test-home" / "updated.txt").write_text("snek plush")
(tmp_path / "test-home" / "out.exp").symlink_to("./updated.txt")
assert snapshot("out.exp") == "plush plush"
""")
)
}
}
}
)
)
def test_snapshot_updates_no_location_when_symlink(files: Path, pytest_command: Command):
expected_path = "pytest_files/test_snapshot0/test-home/updated.txt"
output_file = files / expected_path
res = pytest_command.run().ok()
assert output_file.read_text() == "plush plush"
assert "the updated file can be found here" not in res.stdout_plain
|