aboutsummaryrefslogtreecommitdiff
path: root/claude-templates/.ai/scripts/tests
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-14 01:27:17 -0500
committerCraig Jennings <c@cjennings.net>2026-07-14 01:27:17 -0500
commit951b6fc63129577a80e1d46f46eeafff005fe636 (patch)
treeb5ecd33ae60971ad23448d4b20ef1e3edf488923 /claude-templates/.ai/scripts/tests
parentf573c35885583900e3e319cea384606c4e0321cf (diff)
downloadrulesets-951b6fc63129577a80e1d46f46eeafff005fe636.tar.gz
rulesets-951b6fc63129577a80e1d46f46eeafff005fe636.zip
fix(scripts): stop org table helpers rewriting block content
Both helpers treated any pipe-led line as a table row, so ASCII art in an example block got mangled into a bordered table (a work file took a 1949-line reformat on 2026-07-09). The scanners now track the open block's type and skip its content. Only the matching end marker closes a block, so a literal end_src quoted inside an example block can't re-expose it. The deeper cause was wrap-org-table's load-time dispatch: it fired when lint-org merely required the library, running the reformatter over files lint-org was only asked to report on. It now dispatches only when named as the entry script. lint-org's CLI is also report-only by default now. Writes require --fix, and the wrap-up workflow and lint command pass it.
Diffstat (limited to 'claude-templates/.ai/scripts/tests')
-rw-r--r--claude-templates/.ai/scripts/tests/lint-org-cli.bats18
-rw-r--r--claude-templates/.ai/scripts/tests/test-lint-org.el23
-rw-r--r--claude-templates/.ai/scripts/tests/test-wrap-org-table.el42
3 files changed, 83 insertions, 0 deletions
diff --git a/claude-templates/.ai/scripts/tests/lint-org-cli.bats b/claude-templates/.ai/scripts/tests/lint-org-cli.bats
index d457696..b9faef6 100644
--- a/claude-templates/.ai/scripts/tests/lint-org-cli.bats
+++ b/claude-templates/.ai/scripts/tests/lint-org-cli.bats
@@ -20,6 +20,24 @@ teardown() {
[[ "$output" == *"lint-org: file="* ]]
}
+@test "lint-org.el default invocation is report-only — file untouched" {
+ # bare #+begin_src is a mechanical fix (→ #+begin_example) that the old
+ # default applied on disk; a linter reports, it doesn't write
+ printf '* H\n\n#+begin_src\nx\n#+end_src\n' > "$TMPFILE"
+ before="$(cat "$TMPFILE")"
+ run emacs --batch -q -l "$SCRIPTS_DIR/lint-org.el" "$TMPFILE"
+ [ "$status" -eq 0 ]
+ [[ "$output" == *"would-fix"* ]]
+ [ "$(cat "$TMPFILE")" = "$before" ]
+}
+
+@test "lint-org.el --fix applies mechanical fixes on disk" {
+ printf '* H\n\n#+begin_src\nx\n#+end_src\n' > "$TMPFILE"
+ run emacs --batch -q -l "$SCRIPTS_DIR/lint-org.el" --fix "$TMPFILE"
+ [ "$status" -eq 0 ]
+ grep -q '#+begin_example' "$TMPFILE"
+}
+
@test "wrap-org-table.el loads and runs without -L on the load path" {
run emacs --batch -q -l "$SCRIPTS_DIR/wrap-org-table.el" --width=120 "$TMPFILE"
[ "$status" -eq 0 ]
diff --git a/claude-templates/.ai/scripts/tests/test-lint-org.el b/claude-templates/.ai/scripts/tests/test-lint-org.el
index d14879f..8e3e190 100644
--- a/claude-templates/.ai/scripts/tests/test-lint-org.el
+++ b/claude-templates/.ai/scripts/tests/test-lint-org.el
@@ -620,6 +620,29 @@ followups file on the next run."
;;; ---------------------------------------------------------------------------
;;; org-table-standard check (width budget + rules between rows)
+(ert-deftest lo-table-inside-example-block-not-flagged ()
+ "Pipe-led ASCII art inside an example block is not a table; no judgment."
+ (let* ((run (lo-test--run
+ "* H\n\n#+begin_example\n| client |----->| server |\n| box | | box |\n#+end_example\n"
+ 1 t))
+ (judgments (lo-test--judgments (plist-get run :issues))))
+ (should-not (memq 'org-table-standard (lo-test--checkers judgments)))))
+
+(ert-deftest lo-table-inside-src-block-not-flagged ()
+ "Shell pipes inside a src block are not a table; no judgment."
+ (let* ((run (lo-test--run
+ "* H\n\n#+begin_src sh\n| sort\n| uniq -c\n#+end_src\n" 1 t))
+ (judgments (lo-test--judgments (plist-get run :issues))))
+ (should-not (memq 'org-table-standard (lo-test--checkers judgments)))))
+
+(ert-deftest lo-real-table-after-block-still-flagged ()
+ "Block safety must not mask a genuine violation later in the file."
+ (let* ((run (lo-test--run
+ "* H\n\n#+begin_example\n| art |\n#+end_example\n\n| a | b |\n| 1 | 2 |\n"
+ 1 t))
+ (judgments (lo-test--judgments (plist-get run :issues))))
+ (should (memq 'org-table-standard (lo-test--checkers judgments)))))
+
(ert-deftest lo-table-over-budget-emits-judgment ()
"A table line rendering wider than 120 surfaces as an org-table-standard judgment."
(let* ((wide (make-string 130 ?x))
diff --git a/claude-templates/.ai/scripts/tests/test-wrap-org-table.el b/claude-templates/.ai/scripts/tests/test-wrap-org-table.el
index 8d1ecb6..0b3b375 100644
--- a/claude-templates/.ai/scripts/tests/test-wrap-org-table.el
+++ b/claude-templates/.ai/scripts/tests/test-wrap-org-table.el
@@ -186,3 +186,45 @@
(should (string-match-p "Prose before\\." content))
(should (string-match-p "Prose after\\." content))))
(delete-file file))))
+
+;;; ---------------------------------------------------------------------------
+;;; block safety — pipe lines inside #+begin_/#+end_ blocks are never tables
+
+(defconst wot-test--block-content
+ "#+begin_example
+| client |----->| server |
+| box | | box |
+#+end_example
+"
+ "An example block whose ASCII-art lines start with pipes.")
+
+(defun wot-test--process-content (content budget)
+ "Write CONTENT to a temp file, run `wot-process-file' at BUDGET, return result."
+ (let ((file (make-temp-file "wot-test" nil ".org")))
+ (unwind-protect
+ (progn
+ (with-temp-file file (insert content))
+ (wot-process-file file budget)
+ (with-temp-buffer (insert-file-contents file) (buffer-string)))
+ (delete-file file))))
+
+(ert-deftest wot-process-file-leaves-example-block-byte-identical ()
+ (let ((content (concat "* Diagram\n\n" wot-test--block-content)))
+ (should (equal (wot-test--process-content content 120) content))))
+
+(ert-deftest wot-process-file-reformats-table-but-not-block ()
+ (let* ((content (concat "* Doc\n\n" wot-test--block-content "\n"
+ wot-test--wide-input))
+ (result (wot-test--process-content content 40)))
+ (should (string-match-p (regexp-quote wot-test--block-content) result))
+ (should (string-match-p (regexp-quote wot-test--wide-expected) result))))
+
+(ert-deftest wot-process-file-skips-pipes-in-src-block ()
+ (let ((content "* Pipeline\n\n#+begin_src sh\n| sort\n| uniq -c\n#+end_src\n"))
+ (should (equal (wot-test--process-content content 120) content))))
+
+(ert-deftest wot-process-file-literal-inner-end-marker-stays-in-block ()
+ "A literal #+end_src quoted inside an example block must not close it."
+ (let ((content (concat "* Doc\n\n#+begin_example\n#+begin_src sh\nx\n"
+ "#+end_src\n| art |----| art |\n#+end_example\n")))
+ (should (equal (wot-test--process-content content 120) content))))