diff options
| author | Craig Jennings <c@cjennings.net> | 2026-04-30 01:07:44 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-04-30 01:07:44 -0500 |
| commit | d313c37f14511564849c70c564c14ca51bd4ae7c (patch) | |
| tree | 315a0bf268c937f406e3060f07325dae9378152c /tests | |
| parent | eefd55510cf6b180a7dcc9be40fde894d9adf3ac (diff) | |
| download | gloss-d313c37f14511564849c70c564c14ca51bd4ae7c.tar.gz gloss-d313c37f14511564849c70c564c14ca51bd4ae7c.zip | |
test: add gloss secondary commands test suite (red phase)
Six test files for the remaining stub commands. All 14 tests fail at
this commit because the implementations are stubs.
`gloss--add-finish-internal' (the pure save side of `gloss-add') gets
N/B/E coverage on validation and the persistence side effect.
`gloss--stats-text' (the pure stats string formatter) covers empty,
populated, and missing-file cases. The interactive commands
(`gloss-edit', `gloss-list-terms', `gloss-reload', `gloss-drill-export')
get smoke tests only — the design treats them as mode-glue with 70%
coverage targets, since prompts and `switch-to-buffer' are framework
behaviour Emacs already tests.
Two error-path tests assert the message contains a specific substring,
not just that `user-error' was raised. The stubs raise `user-error' too,
so a bare `should-error' would pass for the wrong reason. The substring
check anchors red against the real error path.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-gloss--add-finish-internal.el | 61 | ||||
| -rw-r--r-- | tests/test-gloss--drill-export-smoke.el | 32 | ||||
| -rw-r--r-- | tests/test-gloss--edit-smoke.el | 38 | ||||
| -rw-r--r-- | tests/test-gloss--list-terms-smoke.el | 35 | ||||
| -rw-r--r-- | tests/test-gloss--reload-smoke.el | 24 | ||||
| -rw-r--r-- | tests/test-gloss--stats-text.el | 40 |
6 files changed, 230 insertions, 0 deletions
diff --git a/tests/test-gloss--add-finish-internal.el b/tests/test-gloss--add-finish-internal.el new file mode 100644 index 0000000..688d6f2 --- /dev/null +++ b/tests/test-gloss--add-finish-internal.el @@ -0,0 +1,61 @@ +;;; test-gloss--add-finish-internal.el --- Tests for gloss--add-finish-internal -*- lexical-binding: t -*- + +;; SPDX-License-Identifier: GPL-3.0-or-later + +;;; Commentary: +;; Tests for the pure save-side helper `gloss--add-finish-internal'. +;; The interactive temp-buffer UI is exercised separately at the smoke +;; level; this file covers the term/body validation and the persistence +;; side effect via a real temp glossary. + +;;; Code: + +(require 'ert) +(require 'cl-lib) +(require 'gloss) +(require 'testutil-gloss) + +(ert-deftest test-gloss-add-finish-internal-saves-and-shows () + "Normal: a fresh term + body is saved with source `manual' and shown." + (gloss-test--with-missing-glossary + (let (shown) + (cl-letf (((symbol-function 'gloss-display-show-entry) + (lambda (term body) (setq shown (list term body))))) + (gloss--add-finish-internal "newterm" "A new definition.") + (let ((saved (gloss-core-lookup "newterm"))) + (should saved) + (should (equal (plist-get saved :body) "A new definition.")) + (should (eq (plist-get saved :source) 'manual))) + (should (equal shown '("newterm" "A new definition."))))))) + +(ert-deftest test-gloss-add-finish-internal-empty-term-raises () + "Error: empty TERM raises `user-error'." + (gloss-test--with-missing-glossary + (cl-letf (((symbol-function 'gloss-display-show-entry) + (lambda (_ _) nil))) + (should-error (gloss--add-finish-internal "" "Body.") + :type 'user-error) + (should-error (gloss--add-finish-internal " " "Body.") + :type 'user-error)))) + +(ert-deftest test-gloss-add-finish-internal-empty-body-raises () + "Error: empty BODY raises `user-error'." + (gloss-test--with-missing-glossary + (cl-letf (((symbol-function 'gloss-display-show-entry) + (lambda (_ _) nil))) + (should-error (gloss--add-finish-internal "term" "") + :type 'user-error) + (should-error (gloss--add-finish-internal "term" " \n ") + :type 'user-error)))) + +(ert-deftest test-gloss-add-finish-internal-trims-body-whitespace () + "Boundary: leading/trailing whitespace in BODY is trimmed before save." + (gloss-test--with-missing-glossary + (cl-letf (((symbol-function 'gloss-display-show-entry) + (lambda (_ _) nil))) + (gloss--add-finish-internal "term" " Body content.\n\n") + (let ((saved (gloss-core-lookup "term"))) + (should (equal (plist-get saved :body) "Body content.")))))) + +(provide 'test-gloss--add-finish-internal) +;;; test-gloss--add-finish-internal.el ends here diff --git a/tests/test-gloss--drill-export-smoke.el b/tests/test-gloss--drill-export-smoke.el new file mode 100644 index 0000000..55b83e8 --- /dev/null +++ b/tests/test-gloss--drill-export-smoke.el @@ -0,0 +1,32 @@ +;;; test-gloss--drill-export-smoke.el --- Smoke test for gloss-drill-export -*- lexical-binding: t -*- + +;; SPDX-License-Identifier: GPL-3.0-or-later + +;;; Commentary: +;; Smoke test confirming `gloss-drill-export' is a thin wrapper around +;; `gloss-drill-export-all' and runs end-to-end against a real glossary. + +;;; Code: + +(require 'ert) +(require 'gloss) +(require 'testutil-gloss) +(require 'testutil-gloss-drill) + +(ert-deftest test-gloss-drill-export-tags-every-entry () + "Smoke: drill-export delegates and tags every entry with :drill:." + (gloss-test--with-temp-glossary gloss-test--sample-content + (gloss-test--with-org-drill-feature + (gloss-drill-export) + (with-current-buffer (find-file-noselect gloss-file) + (revert-buffer t t t) + (let ((tagged 0)) + (org-map-entries + (lambda () + (when (and (= 1 (org-current-level)) + (member "drill" (org-get-tags nil t))) + (setq tagged (1+ tagged))))) + (should (= tagged 2))))))) + +(provide 'test-gloss--drill-export-smoke) +;;; test-gloss--drill-export-smoke.el ends here diff --git a/tests/test-gloss--edit-smoke.el b/tests/test-gloss--edit-smoke.el new file mode 100644 index 0000000..6d1a2a0 --- /dev/null +++ b/tests/test-gloss--edit-smoke.el @@ -0,0 +1,38 @@ +;;; test-gloss--edit-smoke.el --- Smoke tests for gloss-edit -*- lexical-binding: t -*- + +;; SPDX-License-Identifier: GPL-3.0-or-later + +;;; Commentary: +;; Smoke tests for `gloss-edit'. Switches to the source buffer and +;; positions point at the heading; installs a buffer-local +;; `after-save-hook' so cache refresh follows hand edits. + +;;; Code: + +(require 'ert) +(require 'gloss) +(require 'testutil-gloss) + +(ert-deftest test-gloss-edit-known-term-positions-at-heading () + "Smoke: edit on a known term puts point at its heading line." + (gloss-test--with-temp-glossary gloss-test--sample-content + (save-window-excursion + (gloss-edit "anaphora") + (should (looking-at-p "^\\* anaphora"))))) + +(ert-deftest test-gloss-edit-installs-buffer-local-cache-refresh-hook () + "Smoke: edit installs `gloss--after-save-refresh-cache' buffer-locally." + (gloss-test--with-temp-glossary gloss-test--sample-content + (save-window-excursion + (gloss-edit "anaphora") + (should (memq 'gloss--after-save-refresh-cache after-save-hook)) + (should (local-variable-p 'after-save-hook))))) + +(ert-deftest test-gloss-edit-unknown-term-raises () + "Error: edit on a non-existent term raises `user-error' naming the term." + (gloss-test--with-temp-glossary gloss-test--sample-content + (let ((err (should-error (gloss-edit "no-such-term") :type 'user-error))) + (should (string-match-p "no-such-term" (error-message-string err)))))) + +(provide 'test-gloss--edit-smoke) +;;; test-gloss--edit-smoke.el ends here diff --git a/tests/test-gloss--list-terms-smoke.el b/tests/test-gloss--list-terms-smoke.el new file mode 100644 index 0000000..0e331b6 --- /dev/null +++ b/tests/test-gloss--list-terms-smoke.el @@ -0,0 +1,35 @@ +;;; test-gloss--list-terms-smoke.el --- Smoke tests for gloss-list-terms -*- lexical-binding: t -*- + +;; SPDX-License-Identifier: GPL-3.0-or-later + +;;; Commentary: +;; Smoke tests for `gloss-list-terms'. Uses `completing-read' on the +;; cached term list and dispatches to the lookup flow with the chosen +;; term. + +;;; Code: + +(require 'ert) +(require 'cl-lib) +(require 'gloss) +(require 'testutil-gloss) + +(ert-deftest test-gloss-list-terms-empty-glossary-raises () + "Error: list-terms on an empty glossary raises `user-error' mentioning empty." + (gloss-test--with-temp-glossary "#+TITLE: Glossary\n" + (let ((err (should-error (gloss-list-terms) :type 'user-error))) + (should (string-match-p "empty" (error-message-string err)))))) + +(ert-deftest test-gloss-list-terms-dispatches-chosen-to-lookup () + "Smoke: list-terms passes the chosen term to `gloss--lookup-flow'." + (gloss-test--with-temp-glossary gloss-test--sample-content + (let (looked-up) + (cl-letf (((symbol-function 'completing-read) + (lambda (&rest _) "anaphora")) + ((symbol-function 'gloss--lookup-flow) + (lambda (term &optional _) (setq looked-up term) :show))) + (gloss-list-terms) + (should (equal looked-up "anaphora")))))) + +(provide 'test-gloss--list-terms-smoke) +;;; test-gloss--list-terms-smoke.el ends here diff --git a/tests/test-gloss--reload-smoke.el b/tests/test-gloss--reload-smoke.el new file mode 100644 index 0000000..14af147 --- /dev/null +++ b/tests/test-gloss--reload-smoke.el @@ -0,0 +1,24 @@ +;;; test-gloss--reload-smoke.el --- Smoke test for gloss-reload -*- lexical-binding: t -*- + +;; SPDX-License-Identifier: GPL-3.0-or-later + +;;; Commentary: +;; Smoke test for `gloss-reload'. Clears the in-memory cache, then the +;; next lookup repopulates from disk (handled by core's mtime path). + +;;; Code: + +(require 'ert) +(require 'gloss) +(require 'testutil-gloss) + +(ert-deftest test-gloss-reload-resets-and-repopulates-cache () + "Smoke: reload clears the cache and the next lookup re-reads from disk." + (gloss-test--with-temp-glossary gloss-test--sample-content + (gloss-core-lookup "anaphora") + (should gloss-core--cache) + (gloss-reload) + (should (gloss-core-lookup "anaphora")))) + +(provide 'test-gloss--reload-smoke) +;;; test-gloss--reload-smoke.el ends here diff --git a/tests/test-gloss--stats-text.el b/tests/test-gloss--stats-text.el new file mode 100644 index 0000000..32093b1 --- /dev/null +++ b/tests/test-gloss--stats-text.el @@ -0,0 +1,40 @@ +;;; test-gloss--stats-text.el --- Tests for gloss--stats-text -*- lexical-binding: t -*- + +;; SPDX-License-Identifier: GPL-3.0-or-later + +;;; Commentary: +;; Tests for the pure helper `gloss--stats-text' which formats a +;; multi-line stats summary. Drill-tagged count walks the org file via +;; the same primitives as `gloss-drill', so this also indirectly +;; exercises that integration. + +;;; Code: + +(require 'ert) +(require 'gloss) +(require 'testutil-gloss) + +(ert-deftest test-gloss-stats-text-empty-glossary-reports-zero () + "Boundary: empty glossary file reports zero terms." + (gloss-test--with-temp-glossary "#+TITLE: Glossary\n#+STARTUP: showall\n" + (let ((text (gloss--stats-text))) + (should (string-match-p "Total terms: +0" text)) + (should (string-match-p "Drill-tagged: +0" text))))) + +(ert-deftest test-gloss-stats-text-populated-glossary-counts-terms () + "Normal: populated glossary reports total terms and source breakdown." + (gloss-test--with-temp-glossary gloss-test--sample-content + (let ((text (gloss--stats-text))) + (should (string-match-p "Total terms: +2" text)) + (should (string-match-p "wiktionary=2" text)) + (should (string-match-p "File size:" text)) + (should (string-match-p "Cache mtime:" text))))) + +(ert-deftest test-gloss-stats-text-missing-file-reports-zero-and-never () + "Error: missing glossary file reports zero terms and \"never\" mtime." + (gloss-test--with-missing-glossary + (let ((text (gloss--stats-text))) + (should (string-match-p "Total terms: +0" text))))) + +(provide 'test-gloss--stats-text) +;;; test-gloss--stats-text.el ends here |
