From f59ff9606fd96c6b1b9037ea5befb39b5e5a57b9 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 10 May 2026 15:33:33 -0500 Subject: refactor(tests): rename test files to match cj-*-lib.el modules The earlier cj-cache and cj-org-text rename commits renamed the modules but missed renaming the test files. Bring them in line: - tests/test-cj-cache.el -> tests/test-cj-cache-lib.el - tests/test-cj-org-text-sanitize.el -> tests/test-cj-org-text-lib-sanitize.el Update file headers, provide forms, and the in-commentary references. No behavior change. --- tests/test-cj-cache-lib.el | 163 +++++++++++++++++++++++++++++++++ tests/test-cj-cache.el | 163 --------------------------------- tests/test-cj-org-text-lib-sanitize.el | 111 ++++++++++++++++++++++ tests/test-cj-org-text-sanitize.el | 111 ---------------------- 4 files changed, 274 insertions(+), 274 deletions(-) create mode 100644 tests/test-cj-cache-lib.el delete mode 100644 tests/test-cj-cache.el create mode 100644 tests/test-cj-org-text-lib-sanitize.el delete mode 100644 tests/test-cj-org-text-sanitize.el (limited to 'tests') diff --git a/tests/test-cj-cache-lib.el b/tests/test-cj-cache-lib.el new file mode 100644 index 00000000..aeb329dd --- /dev/null +++ b/tests/test-cj-cache-lib.el @@ -0,0 +1,163 @@ +;;; test-cj-cache-lib.el --- Tests for cj-cache-lib.el -*- lexical-binding: t; -*- + +;;; Commentary: +;; Unit tests for the TTL+building cache helper. Covers cache-make / +;; cache-valid-p / cache-value-or-rebuild / cache-building-p / +;; cache-invalidate against the contract in +;; docs/design/cache-helper-design.org. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'cj-cache-lib) + +;;; cj/cache-make + +(ert-deftest test-cj-cache-make-default-ttl () + "Normal: a fresh cache has the default TTL when none specified." + (let ((c (cj/cache-make))) + (should (= 3600 (plist-get c :ttl))) + (should-not (plist-get c :value)) + (should-not (plist-get c :time)) + (should-not (plist-get c :building)))) + +(ert-deftest test-cj-cache-make-custom-ttl () + "Normal: an explicit :ttl keyword sets the TTL field." + (let ((c (cj/cache-make :ttl 60))) + (should (= 60 (plist-get c :ttl))))) + +;;; cj/cache-valid-p + +(ert-deftest test-cj-cache-valid-fresh-cache-invalid () + "Boundary: a fresh cache with no value is not valid." + (let ((c (cj/cache-make))) + (should-not (cj/cache-valid-p c)))) + +(ert-deftest test-cj-cache-valid-recent-build-valid () + "Normal: a cache built one second ago is valid." + (let ((c (cj/cache-make :ttl 60))) + (plist-put c :value '(file1 file2)) + (plist-put c :time (- (float-time) 1)) + (should (cj/cache-valid-p c)))) + +(ert-deftest test-cj-cache-valid-expired-cache-invalid () + "Boundary: a cache older than TTL is invalid." + (let ((c (cj/cache-make :ttl 60))) + (plist-put c :value '(file1)) + (plist-put c :time (- (float-time) 120)) + (should-not (cj/cache-valid-p c)))) + +(ert-deftest test-cj-cache-valid-nil-value-treated-invalid () + "Boundary: a nil cached value reads as invalid -- a build that +returned nil legitimately will rebuild on the next request, matching +the prior agenda/refile contract." + (let ((c (cj/cache-make :ttl 60))) + (plist-put c :value nil) + (plist-put c :time (float-time)) + (should-not (cj/cache-valid-p c)))) + +;;; cj/cache-value-or-rebuild + +(ert-deftest test-cj-cache-value-or-rebuild-miss-calls-build () + "Normal: a fresh cache calls BUILD-FN and stores its result." + (let* ((c (cj/cache-make)) + (build-calls 0) + (result (cj/cache-value-or-rebuild + c + (lambda () (cl-incf build-calls) '(a b c))))) + (should (= 1 build-calls)) + (should (equal '(a b c) result)) + (should (equal '(a b c) (plist-get c :value))) + (should (numberp (plist-get c :time))))) + +(ert-deftest test-cj-cache-value-or-rebuild-hit-skips-build () + "Normal: a valid cache returns the stored value without calling BUILD-FN." + (let* ((c (cj/cache-make :ttl 60)) + (build-calls 0)) + (plist-put c :value '(cached)) + (plist-put c :time (- (float-time) 1)) + (let ((result (cj/cache-value-or-rebuild + c + (lambda () (cl-incf build-calls) '(rebuilt))))) + (should (= 0 build-calls)) + (should (equal '(cached) result))))) + +(ert-deftest test-cj-cache-value-or-rebuild-force-rebuild-overrides-hit () + "Normal: :force-rebuild bypasses a valid cache." + (let* ((c (cj/cache-make :ttl 60)) + (build-calls 0)) + (plist-put c :value '(cached)) + (plist-put c :time (- (float-time) 1)) + (let ((result (cj/cache-value-or-rebuild + c + (lambda () (cl-incf build-calls) '(rebuilt)) + :force-rebuild t))) + (should (= 1 build-calls)) + (should (equal '(rebuilt) result))))) + +(ert-deftest test-cj-cache-value-or-rebuild-on-hit-fires () + "Normal: :on-hit fires with the cached value when valid." + (let* ((c (cj/cache-make :ttl 60)) + (hit-with nil)) + (plist-put c :value '(cached)) + (plist-put c :time (- (float-time) 1)) + (cj/cache-value-or-rebuild + c + (lambda () '(rebuilt)) + :on-hit (lambda (v) (setq hit-with v))) + (should (equal '(cached) hit-with)))) + +(ert-deftest test-cj-cache-value-or-rebuild-on-build-callbacks-fire () + "Normal: :on-build-start and :on-build-success fire on a miss." + (let* ((c (cj/cache-make)) + (events nil)) + (cj/cache-value-or-rebuild + c + (lambda () '(built)) + :on-build-start (lambda () (push 'start events)) + :on-build-success (lambda (v) (push (cons 'success v) events))) + (should (equal '((success built) start) events)))) + +(ert-deftest test-cj-cache-value-or-rebuild-on-build-error-fires-and-rethrows () + "Error: :on-build-error fires with the error and the helper rethrows." + (let* ((c (cj/cache-make)) + (caught-err nil)) + (should-error + (cj/cache-value-or-rebuild + c + (lambda () (error "boom")) + :on-build-error (lambda (err) (setq caught-err err)))) + (should caught-err))) + +(ert-deftest test-cj-cache-value-or-rebuild-clears-building-flag-on-error () + "Boundary: building flag is cleared even when BUILD-FN signals." + (let ((c (cj/cache-make))) + (ignore-errors + (cj/cache-value-or-rebuild + c + (lambda () (error "boom")))) + (should-not (cj/cache-building-p c)))) + +(ert-deftest test-cj-cache-value-or-rebuild-clears-building-flag-on-success () + "Normal: building flag is cleared after a successful build." + (let ((c (cj/cache-make))) + (cj/cache-value-or-rebuild c (lambda () 'ok)) + (should-not (cj/cache-building-p c)))) + +;;; cj/cache-invalidate + +(ert-deftest test-cj-cache-invalidate-clears-value-and-time () + "Normal: invalidate resets value and time, keeps TTL." + (let ((c (cj/cache-make :ttl 60))) + (plist-put c :value '(some)) + (plist-put c :time (float-time)) + (cj/cache-invalidate c) + (should-not (plist-get c :value)) + (should-not (plist-get c :time)) + (should (= 60 (plist-get c :ttl))))) + +(provide 'test-cj-cache-lib) +;;; test-cj-cache-lib.el ends here diff --git a/tests/test-cj-cache.el b/tests/test-cj-cache.el deleted file mode 100644 index 68f2bf0e..00000000 --- a/tests/test-cj-cache.el +++ /dev/null @@ -1,163 +0,0 @@ -;;; test-cj-cache.el --- Tests for cj-cache.el -*- lexical-binding: t; -*- - -;;; Commentary: -;; Unit tests for the TTL+building cache helper. Covers cache-make / -;; cache-valid-p / cache-value-or-rebuild / cache-building-p / -;; cache-invalidate against the contract in -;; docs/design/cache-helper-design.org. - -;;; Code: - -(require 'ert) -(require 'cl-lib) - -(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) -(require 'cj-cache-lib) - -;;; cj/cache-make - -(ert-deftest test-cj-cache-make-default-ttl () - "Normal: a fresh cache has the default TTL when none specified." - (let ((c (cj/cache-make))) - (should (= 3600 (plist-get c :ttl))) - (should-not (plist-get c :value)) - (should-not (plist-get c :time)) - (should-not (plist-get c :building)))) - -(ert-deftest test-cj-cache-make-custom-ttl () - "Normal: an explicit :ttl keyword sets the TTL field." - (let ((c (cj/cache-make :ttl 60))) - (should (= 60 (plist-get c :ttl))))) - -;;; cj/cache-valid-p - -(ert-deftest test-cj-cache-valid-fresh-cache-invalid () - "Boundary: a fresh cache with no value is not valid." - (let ((c (cj/cache-make))) - (should-not (cj/cache-valid-p c)))) - -(ert-deftest test-cj-cache-valid-recent-build-valid () - "Normal: a cache built one second ago is valid." - (let ((c (cj/cache-make :ttl 60))) - (plist-put c :value '(file1 file2)) - (plist-put c :time (- (float-time) 1)) - (should (cj/cache-valid-p c)))) - -(ert-deftest test-cj-cache-valid-expired-cache-invalid () - "Boundary: a cache older than TTL is invalid." - (let ((c (cj/cache-make :ttl 60))) - (plist-put c :value '(file1)) - (plist-put c :time (- (float-time) 120)) - (should-not (cj/cache-valid-p c)))) - -(ert-deftest test-cj-cache-valid-nil-value-treated-invalid () - "Boundary: a nil cached value reads as invalid -- a build that -returned nil legitimately will rebuild on the next request, matching -the prior agenda/refile contract." - (let ((c (cj/cache-make :ttl 60))) - (plist-put c :value nil) - (plist-put c :time (float-time)) - (should-not (cj/cache-valid-p c)))) - -;;; cj/cache-value-or-rebuild - -(ert-deftest test-cj-cache-value-or-rebuild-miss-calls-build () - "Normal: a fresh cache calls BUILD-FN and stores its result." - (let* ((c (cj/cache-make)) - (build-calls 0) - (result (cj/cache-value-or-rebuild - c - (lambda () (cl-incf build-calls) '(a b c))))) - (should (= 1 build-calls)) - (should (equal '(a b c) result)) - (should (equal '(a b c) (plist-get c :value))) - (should (numberp (plist-get c :time))))) - -(ert-deftest test-cj-cache-value-or-rebuild-hit-skips-build () - "Normal: a valid cache returns the stored value without calling BUILD-FN." - (let* ((c (cj/cache-make :ttl 60)) - (build-calls 0)) - (plist-put c :value '(cached)) - (plist-put c :time (- (float-time) 1)) - (let ((result (cj/cache-value-or-rebuild - c - (lambda () (cl-incf build-calls) '(rebuilt))))) - (should (= 0 build-calls)) - (should (equal '(cached) result))))) - -(ert-deftest test-cj-cache-value-or-rebuild-force-rebuild-overrides-hit () - "Normal: :force-rebuild bypasses a valid cache." - (let* ((c (cj/cache-make :ttl 60)) - (build-calls 0)) - (plist-put c :value '(cached)) - (plist-put c :time (- (float-time) 1)) - (let ((result (cj/cache-value-or-rebuild - c - (lambda () (cl-incf build-calls) '(rebuilt)) - :force-rebuild t))) - (should (= 1 build-calls)) - (should (equal '(rebuilt) result))))) - -(ert-deftest test-cj-cache-value-or-rebuild-on-hit-fires () - "Normal: :on-hit fires with the cached value when valid." - (let* ((c (cj/cache-make :ttl 60)) - (hit-with nil)) - (plist-put c :value '(cached)) - (plist-put c :time (- (float-time) 1)) - (cj/cache-value-or-rebuild - c - (lambda () '(rebuilt)) - :on-hit (lambda (v) (setq hit-with v))) - (should (equal '(cached) hit-with)))) - -(ert-deftest test-cj-cache-value-or-rebuild-on-build-callbacks-fire () - "Normal: :on-build-start and :on-build-success fire on a miss." - (let* ((c (cj/cache-make)) - (events nil)) - (cj/cache-value-or-rebuild - c - (lambda () '(built)) - :on-build-start (lambda () (push 'start events)) - :on-build-success (lambda (v) (push (cons 'success v) events))) - (should (equal '((success built) start) events)))) - -(ert-deftest test-cj-cache-value-or-rebuild-on-build-error-fires-and-rethrows () - "Error: :on-build-error fires with the error and the helper rethrows." - (let* ((c (cj/cache-make)) - (caught-err nil)) - (should-error - (cj/cache-value-or-rebuild - c - (lambda () (error "boom")) - :on-build-error (lambda (err) (setq caught-err err)))) - (should caught-err))) - -(ert-deftest test-cj-cache-value-or-rebuild-clears-building-flag-on-error () - "Boundary: building flag is cleared even when BUILD-FN signals." - (let ((c (cj/cache-make))) - (ignore-errors - (cj/cache-value-or-rebuild - c - (lambda () (error "boom")))) - (should-not (cj/cache-building-p c)))) - -(ert-deftest test-cj-cache-value-or-rebuild-clears-building-flag-on-success () - "Normal: building flag is cleared after a successful build." - (let ((c (cj/cache-make))) - (cj/cache-value-or-rebuild c (lambda () 'ok)) - (should-not (cj/cache-building-p c)))) - -;;; cj/cache-invalidate - -(ert-deftest test-cj-cache-invalidate-clears-value-and-time () - "Normal: invalidate resets value and time, keeps TTL." - (let ((c (cj/cache-make :ttl 60))) - (plist-put c :value '(some)) - (plist-put c :time (float-time)) - (cj/cache-invalidate c) - (should-not (plist-get c :value)) - (should-not (plist-get c :time)) - (should (= 60 (plist-get c :ttl))))) - -(provide 'test-cj-cache) -;;; test-cj-cache.el ends here diff --git a/tests/test-cj-org-text-lib-sanitize.el b/tests/test-cj-org-text-lib-sanitize.el new file mode 100644 index 00000000..a4f8dca3 --- /dev/null +++ b/tests/test-cj-org-text-lib-sanitize.el @@ -0,0 +1,111 @@ +;;; test-cj-org-text-lib-sanitize.el --- Tests for the Org-safe text sanitizers -*- lexical-binding: t; -*- + +;;; Commentary: +;; Unit tests for `cj/org-sanitize-body-text', `cj/org-sanitize-property-value', +;; and `cj/org-sanitize-heading' in cj-org-text-lib.el. Pure string helpers +;; for safely composing Org content from external sources (calendar +;; bodies, web-clipped HTML, mail subjects, AI transcripts). Originally +;; lived in calendar-sync.el under `calendar-sync--sanitize-*' names. + +;;; Code: + +(require 'ert) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'cj-org-text-lib) + +;;; cj/org-sanitize-body-text -- Normal cases + +(ert-deftest test-cj-org-sanitize-body-single-asterisk () + "Normal: single leading asterisk replaced with dash." + (should (equal "- item one" (cj/org-sanitize-body-text "* item one")))) + +(ert-deftest test-cj-org-sanitize-body-double-asterisk () + "Normal: double leading asterisks replaced with double dashes." + (should (equal "-- sub-item" (cj/org-sanitize-body-text "** sub-item")))) + +(ert-deftest test-cj-org-sanitize-body-triple-asterisk () + "Normal: triple leading asterisks replaced with triple dashes." + (should (equal "--- deep item" (cj/org-sanitize-body-text "*** deep item")))) + +(ert-deftest test-cj-org-sanitize-body-multiline () + "Normal: multiple lines with leading stars all get sanitized." + (let ((input "Format:\n* What did you do yesterday?\n* What are you doing today?\n* Is anything in your way?") + (expected "Format:\n- What did you do yesterday?\n- What are you doing today?\n- Is anything in your way?")) + (should (equal expected (cj/org-sanitize-body-text input))))) + +(ert-deftest test-cj-org-sanitize-body-mixed-lines () + "Normal: only lines starting with asterisks change." + (let ((input "Normal line\n* Bullet line\nAnother normal line")) + (should (equal "Normal line\n- Bullet line\nAnother normal line" + (cj/org-sanitize-body-text input))))) + +(ert-deftest test-cj-org-sanitize-body-mixed-levels () + "Normal: lines with different asterisk counts each handled independently." + (let ((input "* Top\n** Middle\n*** Bottom")) + (should (equal "- Top\n-- Middle\n--- Bottom" + (cj/org-sanitize-body-text input))))) + +;;; cj/org-sanitize-body-text -- Boundary cases + +(ert-deftest test-cj-org-sanitize-body-nil-input () + "Boundary: nil input returns nil." + (should (null (cj/org-sanitize-body-text nil)))) + +(ert-deftest test-cj-org-sanitize-body-empty-string () + "Boundary: empty string returns empty string." + (should (equal "" (cj/org-sanitize-body-text "")))) + +(ert-deftest test-cj-org-sanitize-body-no-asterisks () + "Boundary: text without leading asterisks is returned unchanged." + (let ((input "Just a normal description\nwith multiple lines")) + (should (equal input (cj/org-sanitize-body-text input))))) + +(ert-deftest test-cj-org-sanitize-body-asterisk-mid-line () + "Boundary: asterisks not at line start are left alone." + (should (equal "Use * for emphasis" (cj/org-sanitize-body-text "Use * for emphasis")))) + +(ert-deftest test-cj-org-sanitize-body-asterisk-no-space () + "Boundary: asterisk at line start without trailing space is not a heading -- left alone." + (should (equal "*bold text*" (cj/org-sanitize-body-text "*bold text*")))) + +(ert-deftest test-cj-org-sanitize-body-asterisk-only () + "Boundary: lone asterisk with space at start of line is sanitized." + (should (equal "- " (cj/org-sanitize-body-text "* ")))) + +;;; cj/org-sanitize-heading + +(ert-deftest test-cj-org-sanitize-heading-flattens-newlines () + "Normal: heading text stays on one Org heading line." + (should (equal "Planning Agenda" + (cj/org-sanitize-heading "Planning\nAgenda")))) + +(ert-deftest test-cj-org-sanitize-heading-replaces-leading-stars () + "Normal: heading text doesn't start with Org heading stars." + (should (equal "- Planning -- Hidden" + (cj/org-sanitize-heading "* Planning\n** Hidden")))) + +(ert-deftest test-cj-org-sanitize-heading-nil-input () + "Boundary: nil input returns nil." + (should (null (cj/org-sanitize-heading nil)))) + +;;; cj/org-sanitize-property-value + +(ert-deftest test-cj-org-sanitize-property-value-flattens-structure () + "Normal: property values do not create extra property drawer lines." + (should (equal "Room 1 :END: * Not a heading" + (cj/org-sanitize-property-value + "Room 1\n:END:\n* Not a heading")))) + +(ert-deftest test-cj-org-sanitize-property-value-trims-and-collapses () + "Normal: property values are compact single-line values." + (should (equal "alpha beta gamma" + (cj/org-sanitize-property-value + " alpha\t beta\n\n gamma ")))) + +(ert-deftest test-cj-org-sanitize-property-value-nil-input () + "Boundary: nil input returns nil." + (should (null (cj/org-sanitize-property-value nil)))) + +(provide 'test-cj-org-text-lib-sanitize) +;;; test-cj-org-text-lib-sanitize.el ends here diff --git a/tests/test-cj-org-text-sanitize.el b/tests/test-cj-org-text-sanitize.el deleted file mode 100644 index 4a4ef2c3..00000000 --- a/tests/test-cj-org-text-sanitize.el +++ /dev/null @@ -1,111 +0,0 @@ -;;; test-cj-org-text-sanitize.el --- Tests for the Org-safe text sanitizers -*- lexical-binding: t; -*- - -;;; Commentary: -;; Unit tests for `cj/org-sanitize-body-text', `cj/org-sanitize-property-value', -;; and `cj/org-sanitize-heading' in cj-org-text.el. Pure string helpers -;; for safely composing Org content from external sources (calendar -;; bodies, web-clipped HTML, mail subjects, AI transcripts). Originally -;; lived in calendar-sync.el under `calendar-sync--sanitize-*' names. - -;;; Code: - -(require 'ert) - -(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) -(require 'cj-org-text-lib) - -;;; cj/org-sanitize-body-text -- Normal cases - -(ert-deftest test-cj-org-sanitize-body-single-asterisk () - "Normal: single leading asterisk replaced with dash." - (should (equal "- item one" (cj/org-sanitize-body-text "* item one")))) - -(ert-deftest test-cj-org-sanitize-body-double-asterisk () - "Normal: double leading asterisks replaced with double dashes." - (should (equal "-- sub-item" (cj/org-sanitize-body-text "** sub-item")))) - -(ert-deftest test-cj-org-sanitize-body-triple-asterisk () - "Normal: triple leading asterisks replaced with triple dashes." - (should (equal "--- deep item" (cj/org-sanitize-body-text "*** deep item")))) - -(ert-deftest test-cj-org-sanitize-body-multiline () - "Normal: multiple lines with leading stars all get sanitized." - (let ((input "Format:\n* What did you do yesterday?\n* What are you doing today?\n* Is anything in your way?") - (expected "Format:\n- What did you do yesterday?\n- What are you doing today?\n- Is anything in your way?")) - (should (equal expected (cj/org-sanitize-body-text input))))) - -(ert-deftest test-cj-org-sanitize-body-mixed-lines () - "Normal: only lines starting with asterisks change." - (let ((input "Normal line\n* Bullet line\nAnother normal line")) - (should (equal "Normal line\n- Bullet line\nAnother normal line" - (cj/org-sanitize-body-text input))))) - -(ert-deftest test-cj-org-sanitize-body-mixed-levels () - "Normal: lines with different asterisk counts each handled independently." - (let ((input "* Top\n** Middle\n*** Bottom")) - (should (equal "- Top\n-- Middle\n--- Bottom" - (cj/org-sanitize-body-text input))))) - -;;; cj/org-sanitize-body-text -- Boundary cases - -(ert-deftest test-cj-org-sanitize-body-nil-input () - "Boundary: nil input returns nil." - (should (null (cj/org-sanitize-body-text nil)))) - -(ert-deftest test-cj-org-sanitize-body-empty-string () - "Boundary: empty string returns empty string." - (should (equal "" (cj/org-sanitize-body-text "")))) - -(ert-deftest test-cj-org-sanitize-body-no-asterisks () - "Boundary: text without leading asterisks is returned unchanged." - (let ((input "Just a normal description\nwith multiple lines")) - (should (equal input (cj/org-sanitize-body-text input))))) - -(ert-deftest test-cj-org-sanitize-body-asterisk-mid-line () - "Boundary: asterisks not at line start are left alone." - (should (equal "Use * for emphasis" (cj/org-sanitize-body-text "Use * for emphasis")))) - -(ert-deftest test-cj-org-sanitize-body-asterisk-no-space () - "Boundary: asterisk at line start without trailing space is not a heading -- left alone." - (should (equal "*bold text*" (cj/org-sanitize-body-text "*bold text*")))) - -(ert-deftest test-cj-org-sanitize-body-asterisk-only () - "Boundary: lone asterisk with space at start of line is sanitized." - (should (equal "- " (cj/org-sanitize-body-text "* ")))) - -;;; cj/org-sanitize-heading - -(ert-deftest test-cj-org-sanitize-heading-flattens-newlines () - "Normal: heading text stays on one Org heading line." - (should (equal "Planning Agenda" - (cj/org-sanitize-heading "Planning\nAgenda")))) - -(ert-deftest test-cj-org-sanitize-heading-replaces-leading-stars () - "Normal: heading text doesn't start with Org heading stars." - (should (equal "- Planning -- Hidden" - (cj/org-sanitize-heading "* Planning\n** Hidden")))) - -(ert-deftest test-cj-org-sanitize-heading-nil-input () - "Boundary: nil input returns nil." - (should (null (cj/org-sanitize-heading nil)))) - -;;; cj/org-sanitize-property-value - -(ert-deftest test-cj-org-sanitize-property-value-flattens-structure () - "Normal: property values do not create extra property drawer lines." - (should (equal "Room 1 :END: * Not a heading" - (cj/org-sanitize-property-value - "Room 1\n:END:\n* Not a heading")))) - -(ert-deftest test-cj-org-sanitize-property-value-trims-and-collapses () - "Normal: property values are compact single-line values." - (should (equal "alpha beta gamma" - (cj/org-sanitize-property-value - " alpha\t beta\n\n gamma ")))) - -(ert-deftest test-cj-org-sanitize-property-value-nil-input () - "Boundary: nil input returns nil." - (should (null (cj/org-sanitize-property-value nil)))) - -(provide 'test-cj-org-text-sanitize) -;;; test-cj-org-text-sanitize.el ends here -- cgit v1.2.3