Repository navigation
Expand file tree
/
Copy pathtest_options.py
More file actions
230 lines (176 loc) · 7.36 KB
/
Copy pathtest_options.py
File metadata and controls
230 lines (176 loc) · 7.36 KB
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
import importlib
import inspect
import pathlib
import sys
from typing_extensions import override
from approvaltests import (
DiffReporter,
ReporterForTesting,
approvals,
combination_approvals, # noqa: F401
get_default_reporter,
verify,
verify_all,
)
from approvaltests.core.comparator import Comparator
from approvaltests.core.options import Options
from approvaltests.core.scenario_namer import ScenarioNamer
from approvaltests.inline.parse import Parse
from approvaltests.namer.default_name import get_default_namer
from approvaltests.namer.stack_frame_namer import StackFrameNamer
from approvaltests.reporters import MultiReporter, ReportByCreatingDiffFile
from approvaltests.reporters.diff_tools import ReportWithBeyondCompare
from approvaltests.reporters.python_native_reporter import PythonNativeReporter
from approvaltests.utilities import command_line_approvals # noqa: F401
from approvaltests.utilities.logger import simple_logger_approvals # noqa: F401
from approvaltests.utilities.logging import logging_approvals # noqa: F401
def _is_approval_module(name: str) -> bool:
return name.startswith("approvaltests.") and name.endswith("approvals")
_approvals_modules = sorted(filter(_is_approval_module, sys.modules.keys()))
def test_list_of_modules() -> None:
verify_all("", _approvals_modules)
def test_every_function_in_approvals_with_verify_has_an_options() -> None:
for module_name in _approvals_modules:
assert_verify_methods_have_options(importlib.import_module(module_name))
def assert_verify_methods_have_options(module) -> None:
for function_name, obj in module.__dict__.items():
if "verify" not in function_name:
continue
if not callable(obj):
continue
# if it has a decorator, we need to get the original function
if hasattr(obj, "__wrapped__"):
obj = obj.__wrapped__
argspec = inspect.getfullargspec(obj)
has_options = "options" in argspec.kwonlyargs
assert has_options, (
f"Missing Keyword only parameter `options` in {function_name}:\n\t{argspec}"
)
def test_empty_options_has_default_reporter() -> None:
##approvals.set_default_reporter(None)
options = Options()
assert options.reporter == get_default_reporter()
def test_with_reporter() -> None:
testr = ReporterForTesting()
options = Options().with_reporter(testr)
try:
verify("Data2", options=options)
except:
pass
assert testr.called
def test_setting_reporter() -> None:
testr = ReporterForTesting()
options = Options().with_reporter(testr)
assert options.reporter == testr
def test_file_extensions() -> None:
approvals.settings().allow_multiple_verify_calls_for_this_method()
content = "# This is a markdown header\n"
# begin-snippet: options_with_file_extension
verify(content, options=Options().for_file.with_extension(".md"))
# end-snippet
verify(content, options=Options().for_file.with_extension("md"))
def test_scrubber() -> None:
options = Options().with_scrubber(lambda text: text.upper())
verify("Hello, Approvals!", options=options)
def test_add_scrubber() -> None:
options = (
Options()
.with_scrubber(lambda text: text.upper())
.add_scrubber(lambda text: text.replace("!", "!!!"))
)
verify("Hello, Approvals!", options=options)
def test_with_scrubber_adds_to_existing_scrubbers() -> None:
"""
Hello, Approvals! -> HELLO, APPROVALS!!!
"""
options = (
Options()
.with_scrubber(lambda text: text.upper())
.with_scrubber(lambda text: text.replace("!", "!!!"))
)
Parse.doc_string().verify_all(options.scrub)
def test_with_scrubber_replace_overwrites_existing_scrubbers() -> None:
"""
Hello, Approvals! -> Hello, Approvals!!!
"""
options = (
Options()
.with_scrubber(lambda text: text.upper())
.with_scrubber(lambda text: text.replace("!", "!!!"), replace=True)
)
Parse.doc_string().verify_all(options.scrub)
class MyCustomFileNamer(StackFrameNamer):
@override
def get_file_name(self) -> str:
return "my_custom_file_name"
def test_namer() -> None:
options = Options().with_namer(MyCustomFileNamer())
verify("Hello, Approvals!", options=options)
def test_comparator() -> None:
options = Options().with_comparator(IgnoreTrailingExclamationsComparator())
verify("Hello, Approvals!!!", options=options)
def test_reporter() -> None:
options = Options().with_reporter(ReportWithBeyondCompare())
verify("Hello, Approvals!", options=options)
def test_overwrite_reporter() -> None:
# current behaviour, override
options0 = (
Options()
.with_reporter(ReportByCreatingDiffFile())
.with_reporter(DiffReporter())
)
assert type(options0.reporter) == DiffReporter
def test_add_reporter() -> None:
reporter1 = ReportByCreatingDiffFile()
reporter2 = DiffReporter()
handmade = MultiReporter(reporter1, reporter2)
options0 = Options().with_reporter(reporter1).add_reporter(reporter2)
assert str(options0.reporter) == str(handmade)
# Original Input = Hello, Approvals!
# apply scrubber = text.upper()
# Result = HELLO, APPROVALS!
# add scrubber = text.replace("!", "!!!")
# Result = HELLO, APPROVALS!!!
# use comparator = IgnoreTrailingExclamationsComparator()
# Result = True, because it compares
# received "HELLO, APPROVALS!!!" against
# approved "HELLO, APPROVALS!"
# NOTE: The trailing "!"s are stripped from both files before the compare
# the effect is to IGNORE all trailing "!" characters
class IgnoreTrailingExclamationsComparator(Comparator):
@override
def compare(self, received_path: str, approved_path: str) -> bool:
received = pathlib.Path(received_path).read_text().rstrip("!\n")
approved = pathlib.Path(approved_path).read_text().rstrip("!\n")
return received == approved
def test_demonstrate_available_approvaltests_options() -> None:
# begin-snippet: options_with_all_options
options = (
Options()
# write the .approved/.received files as Markdown instead of .txt
.for_file.with_extension(".md")
# uppercase the text before it is written/compared, so the effect
# is visible in the received/approved files themselves
.with_scrubber(lambda text: text.upper())
# a second scrubber runs after the first; this one turns "!" into "!!!"
.with_scrubber(lambda text: text.replace("!", "!!!"))
# add a scenario name to the file name, so one test can keep a separate
# approved file per case (e.g. one per language)
.with_namer(ScenarioNamer(get_default_namer(), "english"))
# use a custom comparator that ignores trailing "!"s, so the mismatch
# created by the second scrubber above still counts as approved
.with_comparator(IgnoreTrailingExclamationsComparator())
# print a diff and the approve command to the test output on any mismatch
.with_reporter(PythonNativeReporter())
)
verify("Hello, Approvals!", options=options)
# end-snippet
def test_options_example() -> None:
# begin-snippet: options_example
verify(
"Hello, World!",
options=Options()
.with_scrubber(lambda text: text.replace("World", "Approvals"))
.for_file.with_extension(".md"),
)
# end-snippet