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
|
"""Tests for flashcard-diff-ids.py: :ID: extraction + SRS-state diff CLI.
Plain python3 script (no third-party deps), so card_id_map imports directly;
the disappeared/appeared reporting is exercised through the CLI.
"""
from __future__ import annotations
import importlib.util
import subprocess
import sys
from pathlib import Path
import pytest
SCRIPT = Path(__file__).resolve().parents[1] / "flashcard-diff-ids.py"
@pytest.fixture(scope="module")
def diff_ids():
spec = importlib.util.spec_from_file_location("flashcard_diff_ids", SCRIPT)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
DECK_A = """* Section
** What is DeepSat? :drill:
:PROPERTIES:
:ID: id-1
:END:
Body.
** Who founded it? :drill:
:PROPERTIES:
:ID: id-2
:END:
Body.
"""
# id-2 dropped, id-3 added relative to DECK_A
DECK_B = """* Section
** What is DeepSat? :drill:
:PROPERTIES:
:ID: id-1
:END:
Body.
** When was it founded? :drill:
:PROPERTIES:
:ID: id-3
:END:
Body.
"""
def test_card_id_map_extracts_id_to_heading(diff_ids, tmp_path):
f = tmp_path / "a.org"
f.write_text(DECK_A)
m = diff_ids.card_id_map(f)
assert set(m) == {"id-1", "id-2"}
assert m["id-1"] == "What is DeepSat?"
def _run(before, after):
return subprocess.run(
[sys.executable, str(SCRIPT), str(before), str(after)],
capture_output=True, text=True,
)
def test_cli_identical_decks_exit_zero(tmp_path):
a = tmp_path / "a.org"
a.write_text(DECK_A)
b = tmp_path / "b.org"
b.write_text(DECK_A)
r = _run(a, b)
assert r.returncode == 0
assert "preserved" in r.stdout.lower()
def test_cli_dropped_id_warns_and_exits_one(tmp_path):
a = tmp_path / "a.org"
a.write_text(DECK_A)
b = tmp_path / "b.org"
b.write_text(DECK_B)
r = _run(a, b)
assert r.returncode == 1
assert "disappeared" in r.stdout.lower()
assert "id-2" in r.stdout
DECK_ONE = """* Section
** What is DeepSat? :drill:
:PROPERTIES:
:ID: id-1
:END:
Body.
"""
def test_cli_appeared_only_notes_new_ids_and_exits_one(tmp_path):
# before has id-1; after adds id-2 and drops nothing.
before = tmp_path / "before.org"
before.write_text(DECK_ONE)
after = tmp_path / "after.org"
after.write_text(DECK_A)
r = _run(before, after)
assert r.returncode == 1
assert "appeared" in r.stdout.lower()
assert "id-2" in r.stdout
|