aboutsummaryrefslogtreecommitdiff
path: root/claude-templates/.ai/scripts/tests/test_flashcard_diff_ids.py
blob: 9554b48758e0c11cd3300ac1980ead7cc76016c3 (plain)
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