aboutsummaryrefslogtreecommitdiff
path: root/.ai/scripts/tests/test_flashcard_diff_ids.py
diff options
context:
space:
mode:
Diffstat (limited to '.ai/scripts/tests/test_flashcard_diff_ids.py')
-rw-r--r--.ai/scripts/tests/test_flashcard_diff_ids.py109
1 files changed, 109 insertions, 0 deletions
diff --git a/.ai/scripts/tests/test_flashcard_diff_ids.py b/.ai/scripts/tests/test_flashcard_diff_ids.py
new file mode 100644
index 0000000..9554b48
--- /dev/null
+++ b/.ai/scripts/tests/test_flashcard_diff_ids.py
@@ -0,0 +1,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