summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test-custom-comments-comment-block-banner.el228
-rw-r--r--tests/test-custom-comments-comment-box.el241
-rw-r--r--tests/test-custom-comments-comment-heavy-box.el251
-rw-r--r--tests/test-custom-comments-comment-inline-border.el235
-rw-r--r--tests/test-custom-comments-comment-padded-divider.el250
-rw-r--r--tests/test-custom-comments-comment-simple-divider.el246
-rw-r--r--tests/test-custom-comments-comment-unicode-box.el264
7 files changed, 1715 insertions, 0 deletions
diff --git a/tests/test-custom-comments-comment-block-banner.el b/tests/test-custom-comments-comment-block-banner.el
new file mode 100644
index 00000000..6561ebfa
--- /dev/null
+++ b/tests/test-custom-comments-comment-block-banner.el
@@ -0,0 +1,228 @@
+;;; test-custom-comments-comment-block-banner.el --- Tests for cj/comment-block-banner -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for the cj/comment-block-banner function from custom-comments.el
+;;
+;; This function generates a 3-line block banner comment (JSDoc/Doxygen style):
+;; - Top line: comment-start (e.g., /*) + decoration chars
+;; - Text line: space + decoration char + space + text
+;; - Bottom line: space + decoration chars + comment-end (e.g., */)
+;;
+;; This style is common in C, JavaScript, Java, and other languages that use
+;; block comments.
+;;
+;; We test the NON-INTERACTIVE implementation (cj/--comment-block-banner)
+;; to avoid mocking user prompts. This follows our testing best practice
+;; of separating business logic from UI interaction.
+;;
+;; Cross-Language Testing Strategy:
+;; - Comprehensive testing in C (the primary language for this style)
+;; - Representative testing in JavaScript/Java (similar block comment syntax)
+;; - This style is specifically designed for block comments, so we focus
+;; testing on languages that use /* */ syntax
+;; - See test-custom-comments-delete-buffer-comments.el for detailed rationale
+
+;;; Code:
+
+(require 'ert)
+(require 'testutil-general)
+
+;; Add modules directory to load path
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+;; Now load the actual production module
+(require 'custom-comments)
+
+;;; Test Helpers
+
+(defun test-block-banner-at-column (column-pos comment-start comment-end decoration-char text length)
+ "Test cj/--comment-block-banner at COLUMN-POS indentation.
+Insert spaces to reach COLUMN-POS, then call cj/--comment-block-banner with
+COMMENT-START, COMMENT-END, DECORATION-CHAR, TEXT, and LENGTH.
+Returns the buffer string for assertions."
+ (with-temp-buffer
+ (when (> column-pos 0)
+ (insert (make-string column-pos ?\s)))
+ (cj/--comment-block-banner comment-start comment-end decoration-char text length)
+ (buffer-string)))
+
+;;; C/JavaScript/Java Tests (Block Comment Languages - Comprehensive Coverage)
+
+;;; Normal Cases
+
+(ert-deftest test-block-banner-c-basic ()
+ "Should generate 3-line block banner in C style."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "Section Header" 70)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; First line should start with /*
+ (should (string-match-p "^/\\*\\*" result))
+ ;; Middle line should contain text
+ (should (string-match-p "\\* Section Header" result))
+ ;; Last line should end with */
+ (should (string-match-p "\\*/$" result))))
+
+(ert-deftest test-block-banner-c-custom-decoration ()
+ "Should use custom decoration character."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "#" "Header" 70)))
+ (should (string-match-p "/\\*#" result))
+ (should (string-match-p " # Header" result))))
+
+(ert-deftest test-block-banner-c-custom-text ()
+ "Should include custom text in banner."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "Custom Text Here" 70)))
+ (should (string-match-p "Custom Text Here" result))))
+
+(ert-deftest test-block-banner-c-empty-text ()
+ "Should handle empty text string."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "" 70)))
+ ;; Should still generate 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Should have comment delimiters
+ (should (string-match-p "/\\*" result))
+ (should (string-match-p "\\*/$" result))))
+
+(ert-deftest test-block-banner-c-at-column-0 ()
+ "Should work at column 0."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "Header" 70)))
+ ;; First character should be /
+ (should (string-prefix-p "/*" result))))
+
+(ert-deftest test-block-banner-c-indented ()
+ "Should work when indented."
+ (let ((result (test-block-banner-at-column 4 "/*" "*/" "*" "Header" 70)))
+ ;; First line should start with spaces
+ (should (string-prefix-p " /*" result))
+ ;; Other lines should be indented
+ (let ((lines (split-string result "\n" t)))
+ (should (string-prefix-p " " (nth 1 lines))) ; text line has extra space
+ (should (string-prefix-p " " (nth 2 lines)))))) ; bottom line has extra space
+
+(ert-deftest test-block-banner-c-short-text ()
+ "Should handle short text properly."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "X" 70)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Text should be present
+ (should (string-match-p "X" result))))
+
+(ert-deftest test-block-banner-c-long-text ()
+ "Should handle longer text."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "This is a longer header text" 70)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Text should be present
+ (should (string-match-p "This is a longer header text" result))))
+
+(ert-deftest test-block-banner-c-custom-length ()
+ "Should respect custom length."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "Header" 50)))
+ ;; Top line should be approximately 50 chars
+ (let ((first-line (car (split-string result "\n" t))))
+ (should (<= (length first-line) 51))
+ (should (>= (length first-line) 48)))))
+
+;;; Boundary Cases
+
+(ert-deftest test-block-banner-c-minimum-length ()
+ "Should work with minimum viable length."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "X" 10)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "X" result))))
+
+(ert-deftest test-block-banner-c-very-long-length ()
+ "Should handle very long length."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "Header" 200)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Top line should be very long
+ (let ((first-line (car (split-string result "\n" t))))
+ (should (> (length first-line) 100)))))
+
+(ert-deftest test-block-banner-c-unicode-decoration ()
+ "Should handle unicode decoration character."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "✦" "Header" 70)))
+ (should (string-match-p "✦" result))))
+
+(ert-deftest test-block-banner-c-unicode-text ()
+ "Should handle unicode in text."
+ (let ((result (test-block-banner-at-column 0 "/*" "*/" "*" "Hello 👋 مرحبا café" 70)))
+ (should (string-match-p "👋" result))
+ (should (string-match-p "مرحبا" result))
+ (should (string-match-p "café" result))))
+
+(ert-deftest test-block-banner-c-very-long-text ()
+ "Should handle very long text."
+ (let* ((long-text (make-string 100 ?x))
+ (result (test-block-banner-at-column 0 "/*" "*/" "*" long-text 70)))
+ ;; Should still generate output
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Middle line should contain some of the text
+ (should (string-match-p "xxx" result))))
+
+(ert-deftest test-block-banner-c-max-indentation ()
+ "Should handle maximum practical indentation."
+ (let ((result (test-block-banner-at-column 60 "/*" "*/" "*" "Header" 100)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; First line should start with 60 spaces
+ (should (string-prefix-p (make-string 60 ?\s) result))))
+
+;;; Error Cases
+
+(ert-deftest test-block-banner-c-length-too-small ()
+ "Should error when length is too small."
+ (should-error
+ (test-block-banner-at-column 0 "/*" "*/" "*" "Header" 3)
+ :type 'error))
+
+(ert-deftest test-block-banner-c-negative-length ()
+ "Should error with negative length."
+ (should-error
+ (test-block-banner-at-column 0 "/*" "*/" "*" "Header" -10)
+ :type 'error))
+
+(ert-deftest test-block-banner-c-zero-length ()
+ "Should error with zero length."
+ (should-error
+ (test-block-banner-at-column 0 "/*" "*/" "*" "Header" 0)
+ :type 'error))
+
+(ert-deftest test-block-banner-c-nil-decoration ()
+ "Should error when decoration-char is nil."
+ (should-error
+ (test-block-banner-at-column 0 "/*" "*/" nil "Header" 70)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-block-banner-c-nil-text ()
+ "Should error when text is nil."
+ (should-error
+ (test-block-banner-at-column 0 "/*" "*/" "*" nil 70)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-block-banner-c-non-integer-length ()
+ "Should error when length is not an integer."
+ (should-error
+ (test-block-banner-at-column 0 "/*" "*/" "*" "Header" "not-a-number")
+ :type 'wrong-type-argument))
+
+;;; Alternative Block Comment Styles
+
+(ert-deftest test-block-banner-java-style ()
+ "Should work with Java-style block comments."
+ (let ((result (test-block-banner-at-column 0 "/**" "*/" "*" "JavaDoc Comment" 70)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^/\\*\\*\\*" result))
+ (should (string-match-p "JavaDoc Comment" result))))
+
+(ert-deftest test-block-banner-js-style ()
+ "Should work with JavaScript-style block comments."
+ (let ((result (test-block-banner-at-column 2 "/*" "*/" "*" "Function Documentation" 70)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-prefix-p " /*" result))
+ (should (string-match-p "Function Documentation" result))))
+
+(provide 'test-custom-comments-comment-block-banner)
+;;; test-custom-comments-comment-block-banner.el ends here
diff --git a/tests/test-custom-comments-comment-box.el b/tests/test-custom-comments-comment-box.el
new file mode 100644
index 00000000..10b1a67d
--- /dev/null
+++ b/tests/test-custom-comments-comment-box.el
@@ -0,0 +1,241 @@
+;;; test-custom-comments-comment-box.el --- Tests for cj/comment-box -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for the cj/comment-box function from custom-comments.el
+;;
+;; This function generates a 3-line box comment:
+;; - Top border: comment-start + full decoration line
+;; - Text line: comment-start + decoration + spaces + text + spaces + decoration
+;; - Bottom border: comment-start + full decoration line
+;;
+;; The text is centered within the box with decoration characters on the sides.
+;;
+;; We test the NON-INTERACTIVE implementation (cj/--comment-box)
+;; to avoid mocking user prompts. This follows our testing best practice
+;; of separating business logic from UI interaction.
+;;
+;; Cross-Language Testing Strategy:
+;; - Comprehensive testing in Emacs Lisp (our primary language)
+;; - Representative testing in Python and C (hash-based and C-style comments)
+;; - Function handles comment syntax generically, so testing 3 syntaxes
+;; proves cross-language compatibility
+;; - See test-custom-comments-delete-buffer-comments.el for detailed rationale
+
+;;; Code:
+
+(require 'ert)
+(require 'testutil-general)
+
+;; Add modules directory to load path
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+;; Now load the actual production module
+(require 'custom-comments)
+
+;;; Test Helpers
+
+(defun test-comment-box-at-column (column-pos comment-start comment-end decoration-char text length)
+ "Test cj/--comment-box at COLUMN-POS indentation.
+Insert spaces to reach COLUMN-POS, then call cj/--comment-box with
+COMMENT-START, COMMENT-END, DECORATION-CHAR, TEXT, and LENGTH.
+Returns the buffer string for assertions."
+ (with-temp-buffer
+ (when (> column-pos 0)
+ (insert (make-string column-pos ?\s)))
+ (cj/--comment-box comment-start comment-end decoration-char text length)
+ (buffer-string)))
+
+;;; Emacs Lisp Tests (Primary Language - Comprehensive Coverage)
+
+;;; Normal Cases
+
+(ert-deftest test-comment-box-elisp-basic ()
+ "Should generate 3-line box in emacs-lisp style."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "Section Header" 70)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; First line should start with ;; and have decoration
+ (should (string-match-p "^;; -" result))
+ ;; Middle line should contain text with side borders
+ (should (string-match-p ";; - .* Section Header .* - ;;" result))
+ ;; Should have top and bottom borders
+ (should (string-match-p "^;; -" result))))
+
+(ert-deftest test-comment-box-elisp-custom-decoration ()
+ "Should use custom decoration character."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "*" "Header" 70)))
+ (should (string-match-p ";; \\*" result))
+ (should-not (string-match-p "-" result))))
+
+(ert-deftest test-comment-box-elisp-custom-text ()
+ "Should include custom text centered in box."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "Custom Text Here" 70)))
+ (should (string-match-p "Custom Text Here" result))))
+
+(ert-deftest test-comment-box-elisp-empty-text ()
+ "Should handle empty text string."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "" 70)))
+ ;; Should still generate 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Should have side borders
+ (should (string-match-p "- .*-" result))))
+
+(ert-deftest test-comment-box-elisp-at-column-0 ()
+ "Should work at column 0."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "Header" 70)))
+ ;; First character should be semicolon
+ (should (string-prefix-p ";;" result))))
+
+(ert-deftest test-comment-box-elisp-indented ()
+ "Should work when indented."
+ (let ((result (test-comment-box-at-column 4 ";;" "" "-" "Header" 70)))
+ ;; First line should start with spaces
+ (should (string-prefix-p " ;;" result))
+ ;; Other lines should be indented
+ (let ((lines (split-string result "\n" t)))
+ (should (string-prefix-p " " (nth 1 lines)))
+ (should (string-prefix-p " " (nth 2 lines))))))
+
+(ert-deftest test-comment-box-elisp-short-text ()
+ "Should center short text properly."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "X" 70)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Text should be present and centered
+ (should (string-match-p "- .* X .* -" result))))
+
+(ert-deftest test-comment-box-elisp-long-text ()
+ "Should handle longer text."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "This is a longer header text" 70)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Text should be present
+ (should (string-match-p "This is a longer header text" result))))
+
+;;; Boundary Cases
+
+(ert-deftest test-comment-box-elisp-minimum-length ()
+ "Should work with minimum viable length."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "X" 15)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "X" result))))
+
+(ert-deftest test-comment-box-elisp-very-long-length ()
+ "Should handle very long length."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "Header" 200)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Border lines should be very long
+ (let ((first-line (car (split-string result "\n" t))))
+ (should (> (length first-line) 100)))))
+
+(ert-deftest test-comment-box-elisp-unicode-decoration ()
+ "Should handle unicode decoration character."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "═" "Header" 70)))
+ (should (string-match-p "═" result))))
+
+(ert-deftest test-comment-box-elisp-unicode-text ()
+ "Should handle unicode in text."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "Hello 👋 مرحبا café" 70)))
+ (should (string-match-p "👋" result))
+ (should (string-match-p "مرحبا" result))
+ (should (string-match-p "café" result))))
+
+(ert-deftest test-comment-box-elisp-very-long-text ()
+ "Should handle very long text."
+ (let* ((long-text (make-string 100 ?x))
+ (result (test-comment-box-at-column 0 ";;" "" "-" long-text 70)))
+ ;; Should still generate output
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Middle line should contain some of the text
+ (should (string-match-p "xxx" result))))
+
+(ert-deftest test-comment-box-elisp-comment-end-symmetric ()
+ "Should use symmetric comment syntax when comment-end is empty."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "Header" 70)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Should use ;; on both sides for symmetry
+ (should (string-match-p ";;.*;;$" result))))
+
+(ert-deftest test-comment-box-elisp-max-indentation ()
+ "Should handle maximum practical indentation."
+ (let ((result (test-comment-box-at-column 60 ";;" "" "-" "Header" 100)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; First line should start with 60 spaces
+ (should (string-prefix-p (make-string 60 ?\s) result))))
+
+(ert-deftest test-comment-box-elisp-text-centering-even ()
+ "Should center text properly with even length."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "EVEN" 70)))
+ ;; Text should be centered (roughly equal padding on both sides)
+ (should (string-match-p "- .* EVEN .* -" result))))
+
+(ert-deftest test-comment-box-elisp-text-centering-odd ()
+ "Should center text properly with odd length."
+ (let ((result (test-comment-box-at-column 0 ";;" "" "-" "ODD" 70)))
+ ;; Text should be centered (roughly equal padding on both sides)
+ (should (string-match-p "- .* ODD .* -" result))))
+
+;;; Error Cases
+
+(ert-deftest test-comment-box-elisp-length-too-small ()
+ "Should error when length is too small."
+ (should-error
+ (test-comment-box-at-column 0 ";;" "" "-" "Header" 5)
+ :type 'error))
+
+(ert-deftest test-comment-box-elisp-negative-length ()
+ "Should error with negative length."
+ (should-error
+ (test-comment-box-at-column 0 ";;" "" "-" "Header" -10)
+ :type 'error))
+
+(ert-deftest test-comment-box-elisp-zero-length ()
+ "Should error with zero length."
+ (should-error
+ (test-comment-box-at-column 0 ";;" "" "-" "Header" 0)
+ :type 'error))
+
+(ert-deftest test-comment-box-elisp-nil-decoration ()
+ "Should error when decoration-char is nil."
+ (should-error
+ (test-comment-box-at-column 0 ";;" "" nil "Header" 70)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-comment-box-elisp-non-integer-length ()
+ "Should error when length is not an integer."
+ (should-error
+ (test-comment-box-at-column 0 ";;" "" "-" "Header" "not-a-number")
+ :type 'wrong-type-argument))
+
+;;; Python Tests (Hash-based comments)
+
+(ert-deftest test-comment-box-python-basic ()
+ "Should generate box with Python comment syntax."
+ (let ((result (test-comment-box-at-column 0 "#" "" "-" "Section" 70)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^# -" result))
+ (should (string-match-p "Section" result))))
+
+(ert-deftest test-comment-box-python-indented ()
+ "Should handle indented Python comments."
+ (let ((result (test-comment-box-at-column 4 "#" "" "#" "Function Section" 70)))
+ (should (string-prefix-p " #" result))
+ (should (string-match-p "Function Section" result))))
+
+;;; C Tests (C-style comments)
+
+(ert-deftest test-comment-box-c-block-comments ()
+ "Should generate box with C block comment syntax."
+ (let ((result (test-comment-box-at-column 0 "/*" "*/" "-" "Section" 70)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^/\\* -" result))
+ (should (string-match-p "Section" result))
+ ;; Should include comment-end
+ (should (string-match-p "\\*/" result))))
+
+(provide 'test-custom-comments-comment-box)
+;;; test-custom-comments-comment-box.el ends here
diff --git a/tests/test-custom-comments-comment-heavy-box.el b/tests/test-custom-comments-comment-heavy-box.el
new file mode 100644
index 00000000..30289625
--- /dev/null
+++ b/tests/test-custom-comments-comment-heavy-box.el
@@ -0,0 +1,251 @@
+;;; test-custom-comments-comment-heavy-box.el --- Tests for cj/comment-heavy-box -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for the cj/comment-heavy-box function from custom-comments.el
+;;
+;; This function generates a 5-line heavy box comment:
+;; - Top border: comment-start + full decoration line
+;; - Empty line: decoration char + spaces + decoration char
+;; - Centered text: decoration char + spaces + text + spaces + decoration char
+;; - Empty line: decoration char + spaces + decoration char
+;; - Bottom border: comment-start + full decoration line
+;;
+;; The text is centered within the box with padding on both sides.
+;;
+;; We test the NON-INTERACTIVE implementation (cj/--comment-heavy-box)
+;; to avoid mocking user prompts. This follows our testing best practice
+;; of separating business logic from UI interaction.
+;;
+;; Cross-Language Testing Strategy:
+;; - Comprehensive testing in Emacs Lisp (our primary language)
+;; - Representative testing in Python and C (hash-based and C-style comments)
+;; - Function handles comment syntax generically, so testing 3 syntaxes
+;; proves cross-language compatibility
+;; - See test-custom-comments-delete-buffer-comments.el for detailed rationale
+
+;;; Code:
+
+(require 'ert)
+(require 'testutil-general)
+
+;; Add modules directory to load path
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+;; Now load the actual production module
+(require 'custom-comments)
+
+;;; Test Helpers
+
+(defun test-heavy-box-at-column (column-pos comment-start comment-end decoration-char text length)
+ "Test cj/--comment-heavy-box at COLUMN-POS indentation.
+Insert spaces to reach COLUMN-POS, then call cj/--comment-heavy-box with
+COMMENT-START, COMMENT-END, DECORATION-CHAR, TEXT, and LENGTH.
+Returns the buffer string for assertions."
+ (with-temp-buffer
+ (when (> column-pos 0)
+ (insert (make-string column-pos ?\s)))
+ (cj/--comment-heavy-box comment-start comment-end decoration-char text length)
+ (buffer-string)))
+
+;;; Emacs Lisp Tests (Primary Language - Comprehensive Coverage)
+
+;;; Normal Cases
+
+(ert-deftest test-heavy-box-elisp-basic ()
+ "Should generate 5-line heavy box in emacs-lisp style."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "Section Header" 70)))
+ ;; Should have 5 lines
+ (should (= 5 (length (split-string result "\n" t))))
+ ;; First line should start with ;; and have decoration
+ (should (string-match-p "^;; \\*" result))
+ ;; Middle line should contain centered text
+ (should (string-match-p "Section Header" result))
+ ;; Should have side borders
+ (should (string-match-p "^\\*.*\\*$" result))))
+
+(ert-deftest test-heavy-box-elisp-custom-decoration ()
+ "Should use custom decoration character."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "#" "Header" 70)))
+ (should (string-match-p ";; #" result))
+ (should-not (string-match-p "\\*" result))))
+
+(ert-deftest test-heavy-box-elisp-custom-text ()
+ "Should include custom text centered in box."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "Custom Text Here" 70)))
+ (should (string-match-p "Custom Text Here" result))))
+
+(ert-deftest test-heavy-box-elisp-empty-text ()
+ "Should handle empty text string."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "" 70)))
+ ;; Should still generate 5 lines
+ (should (= 5 (length (split-string result "\n" t))))
+ ;; Middle line should just have side borders and spaces
+ (should (string-match-p "^\\*.*\\*$" result))))
+
+(ert-deftest test-heavy-box-elisp-at-column-0 ()
+ "Should work at column 0."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "Header" 70)))
+ ;; First character should be semicolon
+ (should (string-prefix-p ";;" result))))
+
+(ert-deftest test-heavy-box-elisp-indented ()
+ "Should work when indented."
+ (let ((result (test-heavy-box-at-column 4 ";;" "" "*" "Header" 70)))
+ ;; First line should start with spaces
+ (should (string-prefix-p " ;;" result))
+ ;; Other lines should be indented
+ (let ((lines (split-string result "\n" t)))
+ (should (string-prefix-p " " (nth 1 lines)))
+ (should (string-prefix-p " " (nth 2 lines))))))
+
+(ert-deftest test-heavy-box-elisp-short-text ()
+ "Should center short text properly."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "X" 70)))
+ ;; Should have 5 lines
+ (should (= 5 (length (split-string result "\n" t))))
+ ;; Text should be present and centered
+ (should (string-match-p "\\* .* X .* \\*" result))))
+
+(ert-deftest test-heavy-box-elisp-long-text ()
+ "Should handle longer text."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "This is a longer header text" 70)))
+ ;; Should have 5 lines
+ (should (= 5 (length (split-string result "\n" t))))
+ ;; Text should be present
+ (should (string-match-p "This is a longer header text" result))))
+
+;;; Boundary Cases
+
+(ert-deftest test-heavy-box-elisp-minimum-length ()
+ "Should work with minimum viable length."
+ ;; Minimum for a box: comment + spaces + borders + minimal content
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "X" 15)))
+ (should (= 5 (length (split-string result "\n" t))))
+ (should (string-match-p "X" result))))
+
+(ert-deftest test-heavy-box-elisp-very-long-length ()
+ "Should handle very long length."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "Header" 200)))
+ (should (= 5 (length (split-string result "\n" t))))
+ ;; Border lines should be very long
+ (let ((first-line (car (split-string result "\n" t))))
+ (should (> (length first-line) 100)))))
+
+(ert-deftest test-heavy-box-elisp-unicode-decoration ()
+ "Should handle unicode decoration character."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "═" "Header" 70)))
+ (should (string-match-p "═" result))))
+
+(ert-deftest test-heavy-box-elisp-unicode-text ()
+ "Should handle unicode in text."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "Hello 👋 مرحبا café" 70)))
+ (should (string-match-p "👋" result))
+ (should (string-match-p "مرحبا" result))
+ (should (string-match-p "café" result))))
+
+(ert-deftest test-heavy-box-elisp-very-long-text ()
+ "Should handle very long text."
+ (let* ((long-text (make-string 100 ?x))
+ (result (test-heavy-box-at-column 0 ";;" "" "*" long-text 70)))
+ ;; Should still generate output
+ (should (= 5 (length (split-string result "\n" t))))
+ ;; Middle line should contain some of the text
+ (should (string-match-p "xxx" result))))
+
+(ert-deftest test-heavy-box-elisp-comment-end-empty ()
+ "Should handle empty comment-end by using symmetric comment syntax."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "Header" 70)))
+ (should (= 5 (length (split-string result "\n" t))))
+ ;; When comment-end is empty, function uses comment-char for symmetry
+ ;; So border lines will have ";; ... ;;" for visual balance
+ (should (string-match-p ";;.*;;$" result))))
+
+(ert-deftest test-heavy-box-elisp-max-indentation ()
+ "Should handle maximum practical indentation."
+ (let ((result (test-heavy-box-at-column 60 ";;" "" "*" "Header" 100)))
+ (should (= 5 (length (split-string result "\n" t))))
+ ;; First line should start with 60 spaces
+ (should (string-prefix-p (make-string 60 ?\s) result))))
+
+(ert-deftest test-heavy-box-elisp-text-centering-even ()
+ "Should center text properly with even length."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "EVEN" 70)))
+ ;; Text should be centered (roughly equal padding on both sides)
+ (should (string-match-p "\\* .* EVEN .* \\*" result))))
+
+(ert-deftest test-heavy-box-elisp-text-centering-odd ()
+ "Should center text properly with odd length."
+ (let ((result (test-heavy-box-at-column 0 ";;" "" "*" "ODD" 70)))
+ ;; Text should be centered (roughly equal padding on both sides)
+ (should (string-match-p "\\* .* ODD .* \\*" result))))
+
+;;; Error Cases
+
+(ert-deftest test-heavy-box-elisp-length-too-small ()
+ "Should error when length is too small."
+ (should-error
+ (test-heavy-box-at-column 0 ";;" "" "*" "Header" 5)
+ :type 'error))
+
+(ert-deftest test-heavy-box-elisp-negative-length ()
+ "Should error with negative length."
+ (should-error
+ (test-heavy-box-at-column 0 ";;" "" "*" "Header" -10)
+ :type 'error))
+
+(ert-deftest test-heavy-box-elisp-zero-length ()
+ "Should error with zero length."
+ (should-error
+ (test-heavy-box-at-column 0 ";;" "" "*" "Header" 0)
+ :type 'error))
+
+(ert-deftest test-heavy-box-elisp-nil-decoration ()
+ "Should error when decoration-char is nil."
+ (should-error
+ (test-heavy-box-at-column 0 ";;" "" nil "Header" 70)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-heavy-box-elisp-nil-text ()
+ "Should error when text is nil."
+ (should-error
+ (test-heavy-box-at-column 0 ";;" "" "*" nil 70)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-heavy-box-elisp-non-integer-length ()
+ "Should error when length is not an integer."
+ (should-error
+ (test-heavy-box-at-column 0 ";;" "" "*" "Header" "not-a-number")
+ :type 'wrong-type-argument))
+
+;;; Python Tests (Hash-based comments)
+
+(ert-deftest test-heavy-box-python-basic ()
+ "Should generate heavy box with Python comment syntax."
+ (let ((result (test-heavy-box-at-column 0 "#" "" "*" "Section" 70)))
+ (should (= 5 (length (split-string result "\n" t))))
+ (should (string-match-p "^# \\*" result))
+ (should (string-match-p "Section" result))))
+
+(ert-deftest test-heavy-box-python-indented ()
+ "Should handle indented Python comments."
+ (let ((result (test-heavy-box-at-column 4 "#" "" "#" "Function Section" 70)))
+ (should (string-prefix-p " #" result))
+ (should (string-match-p "Function Section" result))))
+
+;;; C Tests (C-style comments)
+
+(ert-deftest test-heavy-box-c-block-comments ()
+ "Should generate heavy box with C block comment syntax."
+ (let ((result (test-heavy-box-at-column 0 "/*" "*/" "*" "Section" 70)))
+ (should (= 5 (length (split-string result "\n" t))))
+ (should (string-match-p "^/\\* \\*" result))
+ (should (string-match-p "Section" result))
+ ;; Should include comment-end
+ (should (string-match-p "\\*/" result))))
+
+(provide 'test-custom-comments-comment-heavy-box)
+;;; test-custom-comments-comment-heavy-box.el ends here
diff --git a/tests/test-custom-comments-comment-inline-border.el b/tests/test-custom-comments-comment-inline-border.el
new file mode 100644
index 00000000..ca2bef06
--- /dev/null
+++ b/tests/test-custom-comments-comment-inline-border.el
@@ -0,0 +1,235 @@
+;;; test-custom-comments-comment-inline-border.el --- Tests for cj/comment-inline-border -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for the cj/comment-inline-border function from custom-comments.el
+;;
+;; This function generates a single-line centered comment with decoration borders:
+;; Format: comment-start + decoration + space + text + space + decoration + comment-end
+;; Example: ";; ======= Section Header ======="
+;;
+;; The text is centered with decoration characters on both sides. When text has
+;; odd length, the right side gets one less decoration character.
+;;
+;; We test the NON-INTERACTIVE implementation (cj/--comment-inline-border)
+;; to avoid mocking user prompts. This follows our testing best practice
+;; of separating business logic from UI interaction.
+;;
+;; Cross-Language Testing Strategy:
+;; - Comprehensive testing in Emacs Lisp (our primary language)
+;; - Representative testing in Python and C (hash-based and C-style comments)
+;; - Function handles comment syntax generically, so testing 3 syntaxes
+;; proves cross-language compatibility
+;; - See test-custom-comments-delete-buffer-comments.el for detailed rationale
+
+;;; Code:
+
+(require 'ert)
+(require 'testutil-general)
+
+;; Add modules directory to load path
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+;; Now load the actual production module
+(require 'custom-comments)
+
+;;; Test Helpers
+
+(defun test-inline-border-at-column (column-pos comment-start comment-end decoration-char text length)
+ "Test cj/--comment-inline-border at COLUMN-POS indentation.
+Insert spaces to reach COLUMN-POS, then call cj/--comment-inline-border with
+COMMENT-START, COMMENT-END, DECORATION-CHAR, TEXT, and LENGTH.
+Returns the buffer string for assertions."
+ (with-temp-buffer
+ (when (> column-pos 0)
+ (insert (make-string column-pos ?\s)))
+ (cj/--comment-inline-border comment-start comment-end decoration-char text length)
+ (buffer-string)))
+
+;;; Emacs Lisp Tests (Primary Language - Comprehensive Coverage)
+
+;;; Normal Cases
+
+(ert-deftest test-inline-border-elisp-basic ()
+ "Should generate single-line centered comment in emacs-lisp style."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "Section Header" 70)))
+ ;; Should be single line
+ (should (= 1 (length (split-string result "\n" t))))
+ ;; Should start with ;;
+ (should (string-match-p "^;; =" result))
+ ;; Should contain text
+ (should (string-match-p "Section Header" result))
+ ;; Should have decoration on both sides
+ (should (string-match-p "= Section Header =" result))))
+
+(ert-deftest test-inline-border-elisp-custom-decoration ()
+ "Should use custom decoration character."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "#" "Header" 70)))
+ (should (string-match-p ";; #" result))
+ (should (string-match-p "# Header #" result))
+ (should-not (string-match-p "=" result))))
+
+(ert-deftest test-inline-border-elisp-custom-text ()
+ "Should include custom text centered."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "Custom Text Here" 70)))
+ (should (string-match-p "Custom Text Here" result))))
+
+(ert-deftest test-inline-border-elisp-empty-text ()
+ "Should handle empty text string."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "" 70)))
+ ;; Should still generate output with decoration
+ (should (string-match-p ";; =" result))
+ ;; Should not have extra spaces where text would be
+ (should-not (string-match-p " " result))))
+
+(ert-deftest test-inline-border-elisp-at-column-0 ()
+ "Should work at column 0."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "Header" 70)))
+ ;; First character should be semicolon
+ (should (string-prefix-p ";;" result))))
+
+(ert-deftest test-inline-border-elisp-indented ()
+ "Should work when indented."
+ (let ((result (test-inline-border-at-column 4 ";;" "" "=" "Header" 70)))
+ ;; Result should start with spaces
+ (should (string-prefix-p " ;;" result))))
+
+(ert-deftest test-inline-border-elisp-short-text ()
+ "Should center short text properly."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "X" 70)))
+ (should (string-match-p "X" result))
+ ;; Should have decoration on both sides
+ (should (string-match-p "= X =" result))))
+
+(ert-deftest test-inline-border-elisp-custom-length ()
+ "Should respect custom length."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "Header" 50)))
+ ;; Line should be approximately 50 chars
+ (let ((line (car (split-string result "\n" t))))
+ (should (<= (length line) 51))
+ (should (>= (length line) 48)))))
+
+;;; Boundary Cases
+
+(ert-deftest test-inline-border-elisp-minimum-length ()
+ "Should work with minimum viable length."
+ ;; Minimum: 2 (;;) + 1 (space) + 1 (space) + 2 (min decoration each side) = 6
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "" 10)))
+ (should (string-match-p ";" result))))
+
+(ert-deftest test-inline-border-elisp-text-centering-even ()
+ "Should center text properly with even length."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "EVEN" 70)))
+ ;; Text should be centered with roughly equal decoration
+ (should (string-match-p "= EVEN =" result))))
+
+(ert-deftest test-inline-border-elisp-text-centering-odd ()
+ "Should center text properly with odd length."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "ODD" 70)))
+ ;; Text should be centered (right side has one less due to odd length)
+ (should (string-match-p "= ODD =" result))))
+
+(ert-deftest test-inline-border-elisp-very-long-text ()
+ "Should handle text that fills most of the line."
+ (let* ((long-text (make-string 50 ?x))
+ (result (test-inline-border-at-column 0 ";;" "" "=" long-text 70)))
+ ;; Should still have decoration
+ (should (string-match-p "=" result))
+ ;; Text should be present
+ (should (string-match-p "xxx" result))))
+
+(ert-deftest test-inline-border-elisp-unicode-decoration ()
+ "Should handle unicode decoration character."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "─" "Header" 70)))
+ (should (string-match-p "─" result))))
+
+(ert-deftest test-inline-border-elisp-unicode-text ()
+ "Should handle unicode in text."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "Hello 👋 café" 70)))
+ (should (string-match-p "👋" result))
+ (should (string-match-p "café" result))))
+
+(ert-deftest test-inline-border-elisp-comment-end-empty ()
+ "Should handle empty comment-end correctly."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "Header" 70)))
+ ;; Line should not have trailing comment-end
+ (should-not (string-match-p ";;$" result))))
+
+(ert-deftest test-inline-border-elisp-max-indentation ()
+ "Should handle maximum practical indentation."
+ (let ((result (test-inline-border-at-column 60 ";;" "" "=" "H" 100)))
+ (should (string-prefix-p (make-string 60 ?\s) result))))
+
+(ert-deftest test-inline-border-elisp-minimum-decoration-each-side ()
+ "Should have at least 2 decoration chars on each side."
+ (let ((result (test-inline-border-at-column 0 ";;" "" "=" "Test" 20)))
+ ;; Should have at least == on each side
+ (should (string-match-p "== Test ==" result))))
+
+;;; Error Cases
+
+(ert-deftest test-inline-border-elisp-length-too-small ()
+ "Should error when length is too small for text."
+ (should-error
+ (test-inline-border-at-column 0 ";;" "" "=" "Very Long Header Text" 20)
+ :type 'error))
+
+(ert-deftest test-inline-border-elisp-negative-length ()
+ "Should error with negative length."
+ (should-error
+ (test-inline-border-at-column 0 ";;" "" "=" "Header" -10)
+ :type 'error))
+
+(ert-deftest test-inline-border-elisp-zero-length ()
+ "Should error with zero length."
+ (should-error
+ (test-inline-border-at-column 0 ";;" "" "=" "Header" 0)
+ :type 'error))
+
+(ert-deftest test-inline-border-elisp-nil-decoration ()
+ "Should error when decoration-char is nil."
+ (should-error
+ (test-inline-border-at-column 0 ";;" "" nil "Header" 70)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-inline-border-elisp-non-integer-length ()
+ "Should error when length is not an integer."
+ (should-error
+ (test-inline-border-at-column 0 ";;" "" "=" "Header" "not-a-number")
+ :type 'wrong-type-argument))
+
+;;; Python Tests (Hash-based comments)
+
+(ert-deftest test-inline-border-python-basic ()
+ "Should generate inline border with Python comment syntax."
+ (let ((result (test-inline-border-at-column 0 "#" "" "=" "Section" 70)))
+ (should (string-match-p "^# =" result))
+ (should (string-match-p "Section" result))))
+
+(ert-deftest test-inline-border-python-indented ()
+ "Should handle indented Python comments."
+ (let ((result (test-inline-border-at-column 4 "#" "" "-" "Function Section" 70)))
+ (should (string-prefix-p " #" result))
+ (should (string-match-p "Function Section" result))))
+
+;;; C Tests (C-style comments)
+
+(ert-deftest test-inline-border-c-block-comments ()
+ "Should generate inline border with C block comment syntax."
+ (let ((result (test-inline-border-at-column 0 "/*" "*/" "=" "Section" 70)))
+ (should (string-match-p "^/\\* =" result))
+ (should (string-match-p "Section" result))
+ ;; Should include comment-end
+ (should (string-match-p "\\*/$" result))))
+
+(ert-deftest test-inline-border-c-line-comments ()
+ "Should generate inline border with C line comment syntax."
+ (let ((result (test-inline-border-at-column 0 "//" "" "-" "Header" 70)))
+ (should (string-match-p "^// -" result))
+ (should (string-match-p "Header" result))))
+
+(provide 'test-custom-comments-comment-inline-border)
+;;; test-custom-comments-comment-inline-border.el ends here
diff --git a/tests/test-custom-comments-comment-padded-divider.el b/tests/test-custom-comments-comment-padded-divider.el
new file mode 100644
index 00000000..702a4c67
--- /dev/null
+++ b/tests/test-custom-comments-comment-padded-divider.el
@@ -0,0 +1,250 @@
+;;; test-custom-comments-comment-padded-divider.el --- Tests for cj/comment-padded-divider -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for the cj/comment-padded-divider function from custom-comments.el
+;;
+;; This function generates a padded 3-line comment divider banner:
+;; - Top line: comment-start + decoration chars
+;; - Middle line: comment-start + padding spaces + text
+;; - Bottom line: comment-start + decoration chars
+;;
+;; The key difference from simple-divider is the PADDING parameter which
+;; adds spaces before the text to create visual indentation.
+;;
+;; We test the NON-INTERACTIVE implementation (cj/--comment-padded-divider)
+;; to avoid mocking user prompts. This follows our testing best practice
+;; of separating business logic from UI interaction.
+;;
+;; Cross-Language Testing Strategy:
+;; - Comprehensive testing in Emacs Lisp (our primary language)
+;; - Representative testing in Python and C (hash-based and C-style comments)
+;; - Function handles comment syntax generically, so testing 3 syntaxes
+;; proves cross-language compatibility
+;; - See test-custom-comments-delete-buffer-comments.el for detailed rationale
+
+;;; Code:
+
+(require 'ert)
+(require 'testutil-general)
+
+;; Add modules directory to load path
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+;; Now load the actual production module
+(require 'custom-comments)
+
+;;; Test Helpers
+
+(defun test-padded-divider-at-column (column-pos comment-start comment-end decoration-char text length padding)
+ "Test cj/--comment-padded-divider at COLUMN-POS indentation.
+Insert spaces to reach COLUMN-POS, then call cj/--comment-padded-divider with
+COMMENT-START, COMMENT-END, DECORATION-CHAR, TEXT, LENGTH, and PADDING.
+Returns the buffer string for assertions."
+ (with-temp-buffer
+ (when (> column-pos 0)
+ (insert (make-string column-pos ?\s)))
+ (cj/--comment-padded-divider comment-start comment-end decoration-char text length padding)
+ (buffer-string)))
+
+;;; Emacs Lisp Tests (Primary Language - Comprehensive Coverage)
+
+;;; Normal Cases
+
+(ert-deftest test-padded-divider-elisp-basic ()
+ "Should generate padded 3-line divider in emacs-lisp style."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "=" "Section Header" 70 2)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; First line should start with ;; and have decoration
+ (should (string-match-p "^;; =" result))
+ ;; Middle line should contain text with padding
+ (should (string-match-p ";; Section Header" result))))
+
+(ert-deftest test-padded-divider-elisp-custom-padding ()
+ "Should respect custom padding value."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "=" "Header" 70 4)))
+ ;; Middle line should have 4 spaces before text
+ (should (string-match-p ";; Header" result))))
+
+(ert-deftest test-padded-divider-elisp-zero-padding ()
+ "Should work with zero padding."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "-" "Header" 70 0)))
+ ;; Middle line should have text immediately after comment-start + space
+ (should (string-match-p "^;; Header$" result))))
+
+(ert-deftest test-padded-divider-elisp-large-padding ()
+ "Should work with large padding value."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "=" "Text" 70 10)))
+ ;; Middle line should have 10 spaces before text
+ (should (string-match-p ";; Text" result))))
+
+(ert-deftest test-padded-divider-elisp-custom-decoration ()
+ "Should use custom decoration character."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "*" "Header" 70 2)))
+ (should (string-match-p ";; \\*" result))
+ (should-not (string-match-p ";; =" result))))
+
+(ert-deftest test-padded-divider-elisp-custom-text ()
+ "Should include custom text in middle line."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "=" "Custom Text Here" 70 2)))
+ (should (string-match-p "Custom Text Here" result))))
+
+(ert-deftest test-padded-divider-elisp-empty-text ()
+ "Should handle empty text string."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "-" "" 70 2)))
+ ;; Should still generate 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Middle line should just be comment-start + padding
+ (should (string-match-p "^;; *\n" result))))
+
+(ert-deftest test-padded-divider-elisp-at-column-0 ()
+ "Should work at column 0."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "=" "Header" 70 2)))
+ ;; First character should be semicolon
+ (should (string-prefix-p ";;" result))))
+
+(ert-deftest test-padded-divider-elisp-indented ()
+ "Should work when indented."
+ (let ((result (test-padded-divider-at-column 4 ";;" "" "=" "Header" 70 2)))
+ ;; Result should start with spaces
+ (should (string-prefix-p " ;;" result))
+ ;; All lines should be indented
+ (dolist (line (split-string result "\n" t))
+ (should (string-prefix-p " ;;" line)))))
+
+;;; Boundary Cases
+
+(ert-deftest test-padded-divider-elisp-minimum-length ()
+ "Should work with minimum viable length at column 0."
+ ;; Minimum: 2 (;;) + 1 (space) + 1 (space) + 3 (dashes) = 7
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "-" "" 7 0)))
+ (should (= 3 (length (split-string result "\n" t))))))
+
+(ert-deftest test-padded-divider-elisp-very-long-length ()
+ "Should handle very long length."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "=" "Header" 200 2)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Decoration lines should be very long
+ (let ((first-line (car (split-string result "\n" t))))
+ (should (> (length first-line) 100)))))
+
+(ert-deftest test-padded-divider-elisp-padding-larger-than-length ()
+ "Should handle padding that exceeds reasonable bounds."
+ ;; This tests behavior when padding is very large relative to length
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "=" "X" 70 50)))
+ ;; Should still generate output (text may extend beyond decoration)
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "X" result))))
+
+(ert-deftest test-padded-divider-elisp-unicode-decoration ()
+ "Should handle unicode decoration character."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "─" "Header" 70 2)))
+ (should (string-match-p "─" result))))
+
+(ert-deftest test-padded-divider-elisp-unicode-text ()
+ "Should handle unicode in text."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "=" "Hello 👋 مرحبا café" 70 2)))
+ (should (string-match-p "👋" result))
+ (should (string-match-p "مرحبا" result))
+ (should (string-match-p "café" result))))
+
+(ert-deftest test-padded-divider-elisp-very-long-text ()
+ "Should handle very long text."
+ (let* ((long-text (make-string 100 ?x))
+ (result (test-padded-divider-at-column 0 ";;" "" "=" long-text 70 2)))
+ ;; Should still generate output
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Middle line should contain some of the text
+ (should (string-match-p "xxx" result))))
+
+(ert-deftest test-padded-divider-elisp-comment-end-empty ()
+ "Should handle empty comment-end correctly."
+ (let ((result (test-padded-divider-at-column 0 ";;" "" "=" "Header" 70 2)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Lines should not have trailing comment-end
+ (should-not (string-match-p ";;.*;;$" result))))
+
+(ert-deftest test-padded-divider-elisp-max-indentation ()
+ "Should handle maximum practical indentation."
+ (let ((result (test-padded-divider-at-column 60 ";;" "" "=" "Header" 100 2)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; All lines should start with 60 spaces
+ (dolist (line (split-string result "\n" t))
+ (should (string-prefix-p (make-string 60 ?\s) line)))))
+
+;;; Error Cases
+
+(ert-deftest test-padded-divider-elisp-negative-padding ()
+ "Should error with negative padding."
+ (should-error
+ (test-padded-divider-at-column 0 ";;" "" "=" "Header" 70 -5)
+ :type 'error))
+
+(ert-deftest test-padded-divider-elisp-negative-length ()
+ "Should error with negative length."
+ (should-error
+ (test-padded-divider-at-column 0 ";;" "" "=" "Header" -10 2)
+ :type 'error))
+
+(ert-deftest test-padded-divider-elisp-zero-length ()
+ "Should error with zero length."
+ (should-error
+ (test-padded-divider-at-column 0 ";;" "" "=" "Header" 0 2)
+ :type 'error))
+
+(ert-deftest test-padded-divider-elisp-nil-decoration ()
+ "Should error when decoration-char is nil."
+ (should-error
+ (test-padded-divider-at-column 0 ";;" "" nil "Header" 70 2)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-padded-divider-elisp-nil-text ()
+ "Should error when text is nil."
+ (should-error
+ (test-padded-divider-at-column 0 ";;" "" "=" nil 70 2)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-padded-divider-elisp-non-integer-length ()
+ "Should error when length is not an integer."
+ (should-error
+ (test-padded-divider-at-column 0 ";;" "" "=" "Header" "not-a-number" 2)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-padded-divider-elisp-non-integer-padding ()
+ "Should error when padding is not an integer."
+ (should-error
+ (test-padded-divider-at-column 0 ";;" "" "=" "Header" 70 "not-a-number")
+ :type 'wrong-type-argument))
+
+;;; Python Tests (Hash-based comments)
+
+(ert-deftest test-padded-divider-python-basic ()
+ "Should generate padded divider with Python comment syntax."
+ (let ((result (test-padded-divider-at-column 0 "#" "" "=" "Section" 70 2)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^# =" result))
+ (should (string-match-p "# Section" result))))
+
+(ert-deftest test-padded-divider-python-indented ()
+ "Should handle indented Python comments with padding."
+ (let ((result (test-padded-divider-at-column 4 "#" "" "-" "Function Section" 70 4)))
+ (should (string-prefix-p " #" result))
+ (should (string-match-p "Function Section" result))))
+
+;;; C Tests (C-style comments)
+
+(ert-deftest test-padded-divider-c-block-comments ()
+ "Should generate padded divider with C block comment syntax."
+ (let ((result (test-padded-divider-at-column 0 "/*" "*/" "=" "Section" 70 2)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^/\\* =" result))
+ (should (string-match-p "/\\* Section" result))
+ ;; Should include comment-end
+ (should (string-match-p "\\*/" result))))
+
+(provide 'test-custom-comments-comment-padded-divider)
+;;; test-custom-comments-comment-padded-divider.el ends here
diff --git a/tests/test-custom-comments-comment-simple-divider.el b/tests/test-custom-comments-comment-simple-divider.el
new file mode 100644
index 00000000..a61e6b4c
--- /dev/null
+++ b/tests/test-custom-comments-comment-simple-divider.el
@@ -0,0 +1,246 @@
+;;; test-custom-comments-comment-simple-divider.el --- Tests for cj/comment-simple-divider -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for the cj/comment-simple-divider function from custom-comments.el
+;;
+;; This function generates a simple 3-line comment divider banner:
+;; - Top line: comment-start + decoration chars
+;; - Middle line: comment-start + text
+;; - Bottom line: comment-start + decoration chars
+;;
+;; We test the NON-INTERACTIVE implementation (cj/--comment-simple-divider)
+;; to avoid mocking user prompts. This follows our testing best practice
+;; of separating business logic from UI interaction.
+;;
+;; Cross-Language Testing Strategy:
+;; - Comprehensive testing in Emacs Lisp (our primary language)
+;; - Representative testing in Python and C (hash-based and C-style comments)
+;; - Function handles comment syntax generically, so testing 3 syntaxes
+;; proves cross-language compatibility
+;; - See test-custom-comments-delete-buffer-comments.el for detailed rationale
+
+;;; Code:
+
+(require 'ert)
+(require 'testutil-general)
+
+;; Add modules directory to load path
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+;; Now load the actual production module
+(require 'custom-comments)
+
+;;; Test Helpers
+
+(defun test-simple-divider-at-column (column-pos comment-start comment-end decoration-char text length)
+ "Test cj/--comment-simple-divider at COLUMN-POS indentation.
+Insert spaces to reach COLUMN-POS, then call cj/--comment-simple-divider with
+COMMENT-START, COMMENT-END, DECORATION-CHAR, TEXT, and LENGTH.
+Returns the buffer string for assertions."
+ (with-temp-buffer
+ (when (> column-pos 0)
+ (insert (make-string column-pos ?\s)))
+ (cj/--comment-simple-divider comment-start comment-end decoration-char text length)
+ (buffer-string)))
+
+;;; Emacs Lisp Tests (Primary Language - Comprehensive Coverage)
+
+;;; Normal Cases
+
+(ert-deftest test-simple-divider-elisp-basic ()
+ "Should generate simple 3-line divider in emacs-lisp style."
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "-" "Section Header" 70)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Each line should start with ;;
+ (should (string-match-p "^;; -" result))
+ ;; Middle line should contain text
+ (should (string-match-p ";; Section Header" result))))
+
+(ert-deftest test-simple-divider-elisp-custom-decoration ()
+ "Should use custom decoration character."
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "=" "Header" 70)))
+ (should (string-match-p ";; =" result))
+ (should-not (string-match-p ";; -" result))))
+
+(ert-deftest test-simple-divider-elisp-custom-text ()
+ "Should include custom text in middle line."
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "-" "Custom Text Here" 70)))
+ (should (string-match-p ";; Custom Text Here" result))))
+
+(ert-deftest test-simple-divider-elisp-custom-length ()
+ "Should respect custom length."
+ (let* ((result (test-simple-divider-at-column 0 ";;" "" "-" "Header" 50))
+ (lines (split-string result "\n" t)))
+ ;; Should have 3 lines
+ (should (= 3 (length lines)))
+ ;; First and last lines (decoration) should be approximately 50 chars
+ (should (<= (length (car lines)) 51))
+ (should (>= (length (car lines)) 48))
+ (should (<= (length (car (last lines))) 51))
+ (should (>= (length (car (last lines))) 48))))
+
+(ert-deftest test-simple-divider-elisp-empty-text ()
+ "Should handle empty text string."
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "-" "" 70)))
+ ;; Should still generate 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Middle line should just be comment-start
+ (should (string-match-p "^;; *\n" result))))
+
+(ert-deftest test-simple-divider-elisp-at-column-0 ()
+ "Should work at column 0."
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "-""Header" 70)))
+ ;; First character should be semicolon
+ (should (string-prefix-p ";;" result))))
+
+(ert-deftest test-simple-divider-elisp-indented ()
+ "Should work when indented."
+ (let ((result (test-simple-divider-at-column 4 ";;" "" "-""Header" 70)))
+ ;; Result should start with spaces
+ (should (string-prefix-p " ;;" result))
+ ;; All lines should be indented
+ (dolist (line (split-string result "\n" t))
+ (should (string-prefix-p " ;;" line)))))
+
+;;; Boundary Cases
+
+(ert-deftest test-simple-divider-elisp-minimum-length ()
+ "Should work with minimum viable length at column 0."
+ ;; Minimum length at column 0: 2 (;;) + 1 (space) + 1 (space) + 3 (dashes) = 7
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "-""" 7)))
+ (should (= 3 (length (split-string result "\n" t))))))
+
+(ert-deftest test-simple-divider-elisp-minimum-length-indented ()
+ "Should work with minimum viable length when indented."
+ ;; At column 4, minimum is 4 + 2 + 1 + 1 + 3 = 11
+ (let ((result (test-simple-divider-at-column 4 ";;" "" "-""" 11)))
+ (should (= 3 (length (split-string result "\n" t))))))
+
+(ert-deftest test-simple-divider-elisp-very-long-length ()
+ "Should handle very long length."
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "-""Header" 200)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Decoration lines should be very long
+ (let ((first-line (car (split-string result "\n" t))))
+ (should (> (length first-line) 100)))))
+
+(ert-deftest test-simple-divider-elisp-unicode-decoration ()
+ "Should handle unicode decoration character."
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "─""Header" 70)))
+ (should (string-match-p "─" result))))
+
+(ert-deftest test-simple-divider-elisp-unicode-text ()
+ "Should handle unicode in text."
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "-""Hello 👋 مرحبا café" 70)))
+ (should (string-match-p "👋" result))
+ (should (string-match-p "مرحبا" result))
+ (should (string-match-p "café" result))))
+
+(ert-deftest test-simple-divider-elisp-very-long-text ()
+ "Should handle very long text (may wrap or truncate)."
+ (let* ((long-text (make-string 100 ?x))
+ (result (test-simple-divider-at-column 0 ";;" "" "-"long-text 70)))
+ ;; Should still generate output (behavior may vary)
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Middle line should contain some of the text
+ (should (string-match-p "xxx" result))))
+
+(ert-deftest test-simple-divider-elisp-comment-end-empty ()
+ "Should handle empty comment-end correctly."
+ (let ((result (test-simple-divider-at-column 0 ";;" "" "-""Header" 70)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Lines should not have trailing comment-end
+ (should-not (string-match-p ";;.*;;$" result))))
+
+(ert-deftest test-simple-divider-elisp-max-indentation ()
+ "Should handle maximum practical indentation."
+ (let ((result (test-simple-divider-at-column 60 ";;" "" "-""Header" 100)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; All lines should start with 60 spaces
+ (dolist (line (split-string result "\n" t))
+ (should (string-prefix-p (make-string 60 ?\s) line)))))
+
+;;; Error Cases
+
+(ert-deftest test-simple-divider-elisp-length-too-small-column-0 ()
+ "Should error when length is too small at column 0."
+ (should-error
+ (test-simple-divider-at-column 0 ";;" "" "-" "Header" 5)
+ :type 'error))
+
+(ert-deftest test-simple-divider-elisp-length-too-small-indented ()
+ "Should error when length is too small for indentation level."
+ (should-error
+ (test-simple-divider-at-column 10 ";;" "" "-" "Header" 15)
+ :type 'error))
+
+(ert-deftest test-simple-divider-elisp-negative-length ()
+ "Should error with negative length."
+ (should-error
+ (test-simple-divider-at-column 0 ";;" "" "-" "Header" -10)
+ :type 'error))
+
+(ert-deftest test-simple-divider-elisp-zero-length ()
+ "Should error with zero length."
+ (should-error
+ (test-simple-divider-at-column 0 ";;" "" "-" "Header" 0)
+ :type 'error))
+
+(ert-deftest test-simple-divider-elisp-nil-decoration ()
+ "Should error when decoration-char is nil."
+ (should-error
+ (test-simple-divider-at-column 0 ";;" "" nil "Header" 70)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-simple-divider-elisp-nil-text ()
+ "Should error when text is nil."
+ (should-error
+ (test-simple-divider-at-column 0 ";;" "" "-" nil 70)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-simple-divider-elisp-non-integer-length ()
+ "Should error when length is not an integer."
+ (should-error
+ (test-simple-divider-at-column 0 ";;" "" "-""Header" "not-a-number")
+ :type 'wrong-type-argument))
+
+;;; Python Tests (Hash-based comments)
+
+(ert-deftest test-simple-divider-python-basic ()
+ "Should generate simple divider with Python comment syntax."
+ (let ((result (test-simple-divider-at-column 0 "#" "" "-""Section" 70)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^# -" result))
+ (should (string-match-p "# Section" result))))
+
+(ert-deftest test-simple-divider-python-indented ()
+ "Should handle indented Python comments."
+ (let ((result (test-simple-divider-at-column 4 "#" "" "=""Function Section" 70)))
+ (should (string-prefix-p " #" result))
+ (should (string-match-p "Function Section" result))))
+
+;;; C Tests (C-style comments)
+
+(ert-deftest test-simple-divider-c-block-comments ()
+ "Should generate simple divider with C block comment syntax."
+ (let ((result (test-simple-divider-at-column 0 "/*" "*/" "-""Section" 70)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^/\\* -" result))
+ (should (string-match-p "/\\* Section" result))
+ ;; Should include comment-end
+ (should (string-match-p "\\*/" result))))
+
+(ert-deftest test-simple-divider-c-line-comments ()
+ "Should generate simple divider with C line comment syntax."
+ (let ((result (test-simple-divider-at-column 0 "//" "" "=""Header" 70)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^// =" result))
+ (should (string-match-p "// Header" result))))
+
+(provide 'test-custom-comments-comment-simple-divider)
+;;; test-custom-comments-comment-simple-divider.el ends here
diff --git a/tests/test-custom-comments-comment-unicode-box.el b/tests/test-custom-comments-comment-unicode-box.el
new file mode 100644
index 00000000..f34329c8
--- /dev/null
+++ b/tests/test-custom-comments-comment-unicode-box.el
@@ -0,0 +1,264 @@
+;;; test-custom-comments-comment-unicode-box.el --- Tests for cj/comment-unicode-box -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for the cj/comment-unicode-box function from custom-comments.el
+;;
+;; This function generates a 3-line unicode box comment:
+;; - Top line: comment-start + top-left corner + horizontal lines + top-right corner
+;; - Text line: comment-start + vertical bar + text + vertical bar
+;; - Bottom line: comment-start + bottom-left corner + horizontal lines + bottom-right corner
+;;
+;; Supports both 'single and 'double box styles with different unicode characters.
+;;
+;; We test the NON-INTERACTIVE implementation (cj/--comment-unicode-box)
+;; to avoid mocking user prompts. This follows our testing best practice
+;; of separating business logic from UI interaction.
+;;
+;; Cross-Language Testing Strategy:
+;; - Comprehensive testing in Emacs Lisp (our primary language)
+;; - Representative testing in Python and C (hash-based and C-style comments)
+;; - Function handles comment syntax generically, so testing 3 syntaxes
+;; proves cross-language compatibility
+;; - See test-custom-comments-delete-buffer-comments.el for detailed rationale
+
+;;; Code:
+
+(require 'ert)
+(require 'testutil-general)
+
+;; Add modules directory to load path
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+;; Now load the actual production module
+(require 'custom-comments)
+
+;;; Test Helpers
+
+(defun test-unicode-box-at-column (column-pos comment-start comment-end text length box-style)
+ "Test cj/--comment-unicode-box at COLUMN-POS indentation.
+Insert spaces to reach COLUMN-POS, then call cj/--comment-unicode-box with
+COMMENT-START, COMMENT-END, TEXT, LENGTH, and BOX-STYLE.
+Returns the buffer string for assertions."
+ (with-temp-buffer
+ (when (> column-pos 0)
+ (insert (make-string column-pos ?\s)))
+ (cj/--comment-unicode-box comment-start comment-end text length box-style)
+ (buffer-string)))
+
+;;; Emacs Lisp Tests (Primary Language - Comprehensive Coverage)
+
+;;; Normal Cases - Single Box Style
+
+(ert-deftest test-unicode-box-elisp-single-basic ()
+ "Should generate 3-line single-line unicode box in emacs-lisp style."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "Section Header" 70 'single)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Should have single-line box characters
+ (should (string-match-p "┌" result))
+ (should (string-match-p "┐" result))
+ (should (string-match-p "└" result))
+ (should (string-match-p "┘" result))
+ (should (string-match-p "─" result))
+ (should (string-match-p "│" result))
+ ;; Should contain text
+ (should (string-match-p "Section Header" result))))
+
+(ert-deftest test-unicode-box-elisp-double-basic ()
+ "Should generate 3-line double-line unicode box in emacs-lisp style."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "Section Header" 70 'double)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Should have double-line box characters
+ (should (string-match-p "╔" result))
+ (should (string-match-p "╗" result))
+ (should (string-match-p "╚" result))
+ (should (string-match-p "╝" result))
+ (should (string-match-p "═" result))
+ (should (string-match-p "║" result))
+ ;; Should contain text
+ (should (string-match-p "Section Header" result))))
+
+(ert-deftest test-unicode-box-elisp-single-vs-double ()
+ "Should use different characters for single vs double."
+ (let ((single-result (test-unicode-box-at-column 0 ";;" "" "Header" 70 'single))
+ (double-result (test-unicode-box-at-column 0 ";;" "" "Header" 70 'double)))
+ ;; Single should have single-line chars but not double
+ (should (string-match-p "─" single-result))
+ (should-not (string-match-p "═" single-result))
+ ;; Double should have double-line chars but not single
+ (should (string-match-p "═" double-result))
+ (should-not (string-match-p "─" double-result))))
+
+(ert-deftest test-unicode-box-elisp-custom-text ()
+ "Should include custom text in box."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "Custom Text Here" 70 'single)))
+ (should (string-match-p "Custom Text Here" result))))
+
+(ert-deftest test-unicode-box-elisp-empty-text ()
+ "Should handle empty text string."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "" 70 'single)))
+ ;; Should still generate 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Should have box characters
+ (should (string-match-p "┌" result))))
+
+(ert-deftest test-unicode-box-elisp-at-column-0 ()
+ "Should work at column 0."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "Header" 70 'single)))
+ ;; First character should be semicolon
+ (should (string-prefix-p ";;" result))))
+
+(ert-deftest test-unicode-box-elisp-indented ()
+ "Should work when indented."
+ (let ((result (test-unicode-box-at-column 4 ";;" "" "Header" 70 'single)))
+ ;; Result should start with spaces
+ (should (string-prefix-p " ;;" result))
+ ;; All lines should be indented
+ (dolist (line (split-string result "\n" t))
+ (should (string-prefix-p " ;;" line)))))
+
+(ert-deftest test-unicode-box-elisp-short-text ()
+ "Should handle short text properly."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "X" 70 'single)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Text should be present
+ (should (string-match-p "X" result))))
+
+(ert-deftest test-unicode-box-elisp-long-text ()
+ "Should handle longer text."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "This is a longer header text" 70 'single)))
+ ;; Should have 3 lines
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Text should be present
+ (should (string-match-p "This is a longer header text" result))))
+
+;;; Boundary Cases
+
+(ert-deftest test-unicode-box-elisp-minimum-length ()
+ "Should work with minimum viable length."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "X" 15 'single)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "X" result))))
+
+(ert-deftest test-unicode-box-elisp-very-long-length ()
+ "Should handle very long length."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "Header" 200 'single)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Border lines should be very long
+ (let ((first-line (car (split-string result "\n" t))))
+ (should (> (length first-line) 100)))))
+
+(ert-deftest test-unicode-box-elisp-unicode-text ()
+ "Should handle unicode in text."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "Hello 👋 مرحبا café" 70 'single)))
+ (should (string-match-p "👋" result))
+ (should (string-match-p "مرحبا" result))
+ (should (string-match-p "café" result))))
+
+(ert-deftest test-unicode-box-elisp-very-long-text ()
+ "Should handle very long text."
+ (let* ((long-text (make-string 100 ?x))
+ (result (test-unicode-box-at-column 0 ";;" "" long-text 70 'single)))
+ ;; Should still generate output
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Middle line should contain some of the text
+ (should (string-match-p "xxx" result))))
+
+(ert-deftest test-unicode-box-elisp-comment-end-empty ()
+ "Should handle empty comment-end correctly."
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "Header" 70 'single)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; Lines should not have trailing comment-end
+ (should-not (string-match-p ";;.*;;$" result))))
+
+(ert-deftest test-unicode-box-elisp-max-indentation ()
+ "Should handle maximum practical indentation."
+ (let ((result (test-unicode-box-at-column 60 ";;" "" "Header" 100 'single)))
+ (should (= 3 (length (split-string result "\n" t))))
+ ;; All lines should start with 60 spaces
+ (dolist (line (split-string result "\n" t))
+ (should (string-prefix-p (make-string 60 ?\s) line)))))
+
+;;; Error Cases
+
+(ert-deftest test-unicode-box-elisp-length-too-small ()
+ "Should error when length is too small."
+ (should-error
+ (test-unicode-box-at-column 0 ";;" "" "Header" 5 'single)
+ :type 'error))
+
+(ert-deftest test-unicode-box-elisp-negative-length ()
+ "Should error with negative length."
+ (should-error
+ (test-unicode-box-at-column 0 ";;" "" "Header" -10 'single)
+ :type 'error))
+
+(ert-deftest test-unicode-box-elisp-zero-length ()
+ "Should error with zero length."
+ (should-error
+ (test-unicode-box-at-column 0 ";;" "" "Header" 0 'single)
+ :type 'error))
+
+(ert-deftest test-unicode-box-elisp-nil-text ()
+ "Should error when text is nil."
+ (should-error
+ (test-unicode-box-at-column 0 ";;" "" nil 70 'single)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-unicode-box-elisp-non-integer-length ()
+ "Should error when length is not an integer."
+ (should-error
+ (test-unicode-box-at-column 0 ";;" "" "Header" "not-a-number" 'single)
+ :type 'wrong-type-argument))
+
+(ert-deftest test-unicode-box-elisp-invalid-box-style ()
+ "Should handle invalid box-style gracefully."
+ ;; Function may use a default or error - either is acceptable
+ (let ((result (test-unicode-box-at-column 0 ";;" "" "Header" 70 'invalid)))
+ ;; Should still generate some output
+ (should (stringp result))))
+
+;;; Python Tests (Hash-based comments)
+
+(ert-deftest test-unicode-box-python-single ()
+ "Should generate unicode box with Python comment syntax."
+ (let ((result (test-unicode-box-at-column 0 "#" "" "Section" 70 'single)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^# ┌" result))
+ (should (string-match-p "Section" result))))
+
+(ert-deftest test-unicode-box-python-double ()
+ "Should generate double-line unicode box with Python comment syntax."
+ (let ((result (test-unicode-box-at-column 0 "#" "" "Section" 70 'double)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^# ╔" result))
+ (should (string-match-p "Section" result))))
+
+;;; C Tests (C-style comments)
+
+(ert-deftest test-unicode-box-c-block-comments-single ()
+ "Should generate unicode box with C block comment syntax."
+ (let ((result (test-unicode-box-at-column 0 "/*" "*/" "Section" 70 'single)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^/\\* ┌" result))
+ (should (string-match-p "Section" result))
+ ;; Should include comment-end
+ (should (string-match-p "\\*/" result))))
+
+(ert-deftest test-unicode-box-c-block-comments-double ()
+ "Should generate double-line unicode box with C block comment syntax."
+ (let ((result (test-unicode-box-at-column 0 "/*" "*/" "Section" 70 'double)))
+ (should (= 3 (length (split-string result "\n" t))))
+ (should (string-match-p "^/\\* ╔" result))
+ (should (string-match-p "Section" result))
+ ;; Should include comment-end
+ (should (string-match-p "\\*/" result))))
+
+(provide 'test-custom-comments-comment-unicode-box)
+;;; test-custom-comments-comment-unicode-box.el ends here