pytest-digline 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/PKG-INFO +1 -1
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/pyproject.toml +1 -1
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/src/pytest_digline/plugin.py +15 -2
- pytest_digline-0.2.2/tests/test_summary_note.py +54 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/.gitignore +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/README.md +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/src/pytest_digline/__init__.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/src/pytest_digline/py.typed +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/_cycle.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/conftest.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/test_calibration_rows.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/test_contract.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/test_cost.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/test_escapes.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/test_incomparable_rows.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/test_inert.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/test_message.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/test_no_promote.py +0 -0
- {pytest_digline-0.2.1 → pytest_digline-0.2.2}/tests/test_states.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pytest-digline
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Gate a pytest run on a digline comparison: one row per check, against the baseline committed in your repo.
|
|
5
5
|
Project-URL: Homepage, https://digline.dev/
|
|
6
6
|
Project-URL: Documentation, https://digline.dev/product/pytest/
|
|
@@ -76,6 +76,7 @@ RUN_SCOPE = "<run>"
|
|
|
76
76
|
#: Set by `pytest_collection_modifyitems`, read by `pytest_terminal_summary`.
|
|
77
77
|
#: On the config's stash rather than a module global: a module global is shared
|
|
78
78
|
#: by every `Config` in the process, and `pytester` runs several in one.
|
|
79
|
+
#: Each suite's headline, followed by its `latest` note when there is one.
|
|
79
80
|
HEADLINES: pytest.StashKey[list[str]] = pytest.StashKey()
|
|
80
81
|
|
|
81
82
|
|
|
@@ -204,6 +205,8 @@ def pytest_collection_modifyitems(
|
|
|
204
205
|
node = _child(session, DiglineSuite, path=opened.path, opened=opened)
|
|
205
206
|
items.extend(node.collect())
|
|
206
207
|
config.stash[HEADLINES].append(opened.headline)
|
|
208
|
+
if opened.note:
|
|
209
|
+
config.stash[HEADLINES].append(f"note: {opened.note}")
|
|
207
210
|
|
|
208
211
|
|
|
209
212
|
def _child[N: pytest.Item | pytest.File](
|
|
@@ -242,6 +245,11 @@ class _Opened:
|
|
|
242
245
|
#: The calibration cases of the run that left their band, read off the run
|
|
243
246
|
#: by the report's own function. (ADR 0024 §4.7)
|
|
244
247
|
lost: Sequence[ScaleLost] = ()
|
|
248
|
+
#: What resolving `latest` stepped over, or empty. Its sharpest case is a
|
|
249
|
+
#: baseline promoted from a run newer than the one compared: every row is
|
|
250
|
+
#: then an older run held against a newer reference, and a red there is
|
|
251
|
+
#: not a regression. (#433)
|
|
252
|
+
note: str = ""
|
|
245
253
|
|
|
246
254
|
|
|
247
255
|
def _open(spec: str, config: pytest.Config) -> _Opened:
|
|
@@ -286,8 +294,8 @@ def _opened(spec: str, root: Path, *, run_first: bool) -> _Opened:
|
|
|
286
294
|
if run_first:
|
|
287
295
|
_measure(suite, loaded, spec, path, store, root=root)
|
|
288
296
|
|
|
289
|
-
|
|
290
|
-
run = read_run(store, suite, key)
|
|
297
|
+
resolved = resolve_key(store, suite, "latest")
|
|
298
|
+
run = read_run(store, suite, resolved.key)
|
|
291
299
|
baseline = need_baseline(store, suite)
|
|
292
300
|
comparison = compare(run, baseline)
|
|
293
301
|
head = headline(comparison, run, baseline, locale=LOCALE)
|
|
@@ -299,6 +307,7 @@ def _opened(spec: str, root: Path, *, run_first: bool) -> _Opened:
|
|
|
299
307
|
headline=head.sentence,
|
|
300
308
|
reasons_available=head.reasons_available,
|
|
301
309
|
lost=scale_lost(run),
|
|
310
|
+
note=resolved.note,
|
|
302
311
|
)
|
|
303
312
|
|
|
304
313
|
|
|
@@ -665,6 +674,10 @@ def pytest_terminal_summary(
|
|
|
665
674
|
It is `headline().sentence`, byte for byte the sentence `digline compare`
|
|
666
675
|
prints and the report shows, because a gate and a document must never say
|
|
667
676
|
two different things about one run.
|
|
677
|
+
|
|
678
|
+
Under it, the note `latest` left, as `note: …`, the line `digline compare`
|
|
679
|
+
prints on stderr. Here and not as a warning: under `-W error` a warning
|
|
680
|
+
fails the session, and a note is not a verdict. (#433)
|
|
668
681
|
"""
|
|
669
682
|
none: list[str] = []
|
|
670
683
|
sentences = config.stash.get(HEADLINES, none)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""The note `latest` leaves, under the headline it qualifies. (#433)
|
|
2
|
+
|
|
3
|
+
This plugin compares `latest` against the baseline, and until #433 it took the
|
|
4
|
+
key and dropped the note. The case that matters: the baseline was promoted from
|
|
5
|
+
a run newer than `latest`, so every row holds an older run against a newer
|
|
6
|
+
reference, and a red row there is not a regression.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from collections.abc import Callable
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
import pytest
|
|
15
|
+
from _cycle import cycle
|
|
16
|
+
|
|
17
|
+
FINE = {"alpha": "Acme, SATISFIED", "beta": "Acme, SATISFIED"}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_the_note_follows_the_headline_in_the_summary(
|
|
21
|
+
pytester: pytest.Pytester, repo: Callable[[dict[str, str]], Path]
|
|
22
|
+
) -> None:
|
|
23
|
+
path = repo(FINE)
|
|
24
|
+
older = cycle(path, pytester.path, promote=False)
|
|
25
|
+
newer = cycle(path, pytester.path, promote=True)
|
|
26
|
+
(gone,) = (pytester.path / ".digline").glob(f"*/runs/**/{newer}.json")
|
|
27
|
+
gone.unlink()
|
|
28
|
+
|
|
29
|
+
# `-W error` too: the note is not a warning, so it cannot fail a session
|
|
30
|
+
# that turns warnings into errors.
|
|
31
|
+
result = pytester.runpytest_subprocess("--digline-suite", str(path), "-W", "error")
|
|
32
|
+
|
|
33
|
+
expected = (
|
|
34
|
+
f"note: the baseline was promoted from run {newer}, newer than {older}, "
|
|
35
|
+
"and that run was not read here"
|
|
36
|
+
)
|
|
37
|
+
text = result.stdout.str()
|
|
38
|
+
assert expected in text
|
|
39
|
+
assert text.index("= digline =") < text.index(expected)
|
|
40
|
+
assert result.ret == 0, text
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_no_note_when_latest_steps_over_nothing(
|
|
44
|
+
pytester: pytest.Pytester, repo: Callable[[dict[str, str]], Path]
|
|
45
|
+
) -> None:
|
|
46
|
+
"""The control: a note on every session would be a line people learn to
|
|
47
|
+
skip, and would pass the test above."""
|
|
48
|
+
path = repo(FINE)
|
|
49
|
+
cycle(path, pytester.path, promote=True)
|
|
50
|
+
cycle(path, pytester.path, promote=False)
|
|
51
|
+
|
|
52
|
+
result = pytester.runpytest_subprocess("--digline-suite", str(path))
|
|
53
|
+
|
|
54
|
+
assert "note:" not in result.stdout.str()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|