aboutsummaryrefslogtreecommitdiff
path: root/.ai/scripts/tests
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-31 12:19:34 -0500
committerCraig Jennings <c@cjennings.net>2026-05-31 12:19:34 -0500
commitddf48dc7ac780da1aacdff4e03f1d7da255b8f39 (patch)
tree99926b681a9ea6d4210d0dcd1bd8e8a6d47d7d9e /.ai/scripts/tests
parentb46619cd17ed4e36f2e59c1b600078521b2049ef (diff)
downloadrulesets-ddf48dc7ac780da1aacdff4e03f1d7da255b8f39.tar.gz
rulesets-ddf48dc7ac780da1aacdff4e03f1d7da255b8f39.zip
feat: add rename-ai-artifact tool and rename the drill-deck family to flashcard
Renaming an .ai artifact by hand is the kind of mechanical job that gets done incompletely: the canonical copy moves but the mirror doesn't, a reference in the INDEX is missed, a trigger phrase points at the old name. I'd also assumed a rename was costly because references scatter, when the index update is trivial and the drift check already guards it. So I built the discipline into a script instead of re-deriving it each time. scripts/rename-ai-artifact.sh takes old and new basenames, moves the file in both the canonical and mirror trees, and rewrites every reference repo-wide on a token boundary so renaming "foo" can't corrupt "foobar" or "foo-bar". It rewrites the underscore module-name variant too (a hyphenated script imported as foo_bar via importlib), leaves the archived session records under sessions/ alone because they're history, and runs workflow-integrity + sync-check at the end to prove no drift. rename-artifact.org documents it and indexes the triggers. Then I used the tool to do the rename that prompted it: the org-drill deck workflow and its helpers are now flashcard-named, since "flashcard" is the word you'd actually search for. The renamed set is flashcard-review.org plus flashcard-stats.py, flashcard-sync, flashcard-to-anki.py, and flashcard-diff-ids.py, with their tests, every reference, and the INDEX entry updated. The deck is still an org-drill deck under the hood, so the ":drill:" tag handling and the "drill deck" trigger phrases stay. I added "review/update the flashcards" alongside them. Tests: 9 bats for the rename tool (including the prefix-collision and history-preservation edges), and the renamed script suites all pass under make test.
Diffstat (limited to '.ai/scripts/tests')
-rw-r--r--.ai/scripts/tests/flashcard-sync.bats (renamed from .ai/scripts/tests/drill-deck-sync.bats)12
-rw-r--r--.ai/scripts/tests/test_flashcard_diff_ids.py (renamed from .ai/scripts/tests/test_drill_deck_diff_ids.py)6
-rw-r--r--.ai/scripts/tests/test_flashcard_stats.py (renamed from .ai/scripts/tests/test_drill_deck_stats.py)6
-rw-r--r--.ai/scripts/tests/test_flashcard_to_anki.py (renamed from .ai/scripts/tests/test_drill_to_anki.py)6
4 files changed, 15 insertions, 15 deletions
diff --git a/.ai/scripts/tests/drill-deck-sync.bats b/.ai/scripts/tests/flashcard-sync.bats
index e141cab..608a280 100644
--- a/.ai/scripts/tests/drill-deck-sync.bats
+++ b/.ai/scripts/tests/flashcard-sync.bats
@@ -1,11 +1,11 @@
#!/usr/bin/env bats
-# Tests for the drill-deck-sync wrapper: argument handling + the stats gate.
-# The clean end-to-end path runs drill-to-anki.py (uv-resolved genanki) and is
+# Tests for the flashcard-sync wrapper: argument handling + the stats gate.
+# The clean end-to-end path runs flashcard-to-anki.py (uv-resolved genanki) and is
# not exercised here; these cover the guard paths that stop before that step.
setup() {
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
- SYNC="$SCRIPT_DIR/drill-deck-sync"
+ SYNC="$SCRIPT_DIR/flashcard-sync"
TMP="$(mktemp -d)"
}
@@ -13,17 +13,17 @@ teardown() {
rm -rf "$TMP"
}
-@test "drill-deck-sync: no args exits 2" {
+@test "flashcard-sync: no args exits 2" {
run "$SYNC"
[ "$status" -eq 2 ]
}
-@test "drill-deck-sync: missing source file exits 2" {
+@test "flashcard-sync: missing source file exits 2" {
run "$SYNC" "$TMP/nope.org"
[ "$status" -eq 2 ]
}
-@test "drill-deck-sync: stats gate failure exits 1 and writes no apkg" {
+@test "flashcard-sync: stats gate failure exits 1 and writes no apkg" {
cat > "$TMP/dirty.org" <<'EOF'
#+TITLE: DeepSat Org-Drill Flashcards
diff --git a/.ai/scripts/tests/test_drill_deck_diff_ids.py b/.ai/scripts/tests/test_flashcard_diff_ids.py
index 15fb148..9554b48 100644
--- a/.ai/scripts/tests/test_drill_deck_diff_ids.py
+++ b/.ai/scripts/tests/test_flashcard_diff_ids.py
@@ -1,4 +1,4 @@
-"""Tests for drill-deck-diff-ids.py: :ID: extraction + SRS-state diff CLI.
+"""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.
@@ -12,12 +12,12 @@ from pathlib import Path
import pytest
-SCRIPT = Path(__file__).resolve().parents[1] / "drill-deck-diff-ids.py"
+SCRIPT = Path(__file__).resolve().parents[1] / "flashcard-diff-ids.py"
@pytest.fixture(scope="module")
def diff_ids():
- spec = importlib.util.spec_from_file_location("drill_deck_diff_ids", SCRIPT)
+ 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)
diff --git a/.ai/scripts/tests/test_drill_deck_stats.py b/.ai/scripts/tests/test_flashcard_stats.py
index d60084d..606f7c1 100644
--- a/.ai/scripts/tests/test_drill_deck_stats.py
+++ b/.ai/scripts/tests/test_flashcard_stats.py
@@ -1,4 +1,4 @@
-"""Tests for drill-deck-stats.py: prompt-form heuristic + CLI inventory/gate.
+"""Tests for flashcard-stats.py: prompt-form heuristic + CLI inventory/gate.
Plain python3 script (no third-party deps), so the pure helper imports directly;
the inventory/gate behavior is exercised through the CLI.
@@ -12,12 +12,12 @@ from pathlib import Path
import pytest
-SCRIPT = Path(__file__).resolve().parents[1] / "drill-deck-stats.py"
+SCRIPT = Path(__file__).resolve().parents[1] / "flashcard-stats.py"
@pytest.fixture(scope="module")
def stats():
- spec = importlib.util.spec_from_file_location("drill_deck_stats", SCRIPT)
+ spec = importlib.util.spec_from_file_location("flashcard_stats", SCRIPT)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
diff --git a/.ai/scripts/tests/test_drill_to_anki.py b/.ai/scripts/tests/test_flashcard_to_anki.py
index fc17817..058b0cd 100644
--- a/.ai/scripts/tests/test_drill_to_anki.py
+++ b/.ai/scripts/tests/test_flashcard_to_anki.py
@@ -1,4 +1,4 @@
-"""Tests for drill-to-anki.py default-path and deck-name helpers.
+"""Tests for flashcard-to-anki.py default-path and deck-name helpers.
The script is a PEP 723 uv-run script that imports genanki, which uv resolves
at runtime but isn't installed in the test environment. The fixture stubs
@@ -14,14 +14,14 @@ from pathlib import Path
import pytest
-SCRIPT = Path(__file__).resolve().parents[1] / "drill-to-anki.py"
+SCRIPT = Path(__file__).resolve().parents[1] / "flashcard-to-anki.py"
@pytest.fixture(scope="module")
def drill():
# Only stub when genanki is genuinely absent, so a real install isn't shadowed.
sys.modules.setdefault("genanki", types.ModuleType("genanki"))
- spec = importlib.util.spec_from_file_location("drill_to_anki", SCRIPT)
+ spec = importlib.util.spec_from_file_location("flashcard_to_anki", SCRIPT)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)