blob: adda84f04590a26d32f08423e8e7c101f5ffe888 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
;;; test-custom-ordering-number-lines.el --- Tests for cj/--number-lines -*- lexical-binding: t; -*-
;;; Commentary:
;; Tests for the cj/--number-lines function from custom-ordering.el
;;
;; This function numbers lines in a region with a customizable format.
;; The format string uses "N" as a placeholder for the line number.
;; Optionally supports zero-padding for alignment.
;;
;; Examples:
;; Input: "apple\nbanana\ncherry"
;; Format: "N. "
;; Output: "1. apple\n2. banana\n3. cherry"
;;
;; With zero-padding and 100 lines:
;; "001. line\n002. line\n...\n100. line"
;;
;; We test the NON-INTERACTIVE implementation (cj/--number-lines) to avoid
;; mocking user input. This follows our testing best practice of
;; separating business logic from UI interaction.
;;; Code:
(require 'ert)
(require 'testutil-general)
(require 'cl-lib)
;; 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-ordering)
;;; Test Helpers
(defun test-number-lines (input-text format-string zero-pad)
"Test cj/--number-lines on INPUT-TEXT.
FORMAT-STRING is the format template.
ZERO-PAD enables zero-padding.
Returns the transformed string."
(with-temp-buffer
(insert input-text)
(cj/--number-lines (point-min) (point-max) format-string zero-pad)))
;;; Normal Cases - Standard Format "N. "
(ert-deftest test-number-lines-standard-format ()
"Should number lines with standard format."
(let ((result (test-number-lines "apple\nbanana\ncherry" "N. " nil)))
(should (string= result "1. apple\n2. banana\n3. cherry"))))
(ert-deftest test-number-lines-two-lines ()
"Should number two lines."
(let ((result (test-number-lines "first\nsecond" "N. " nil)))
(should (string= result "1. first\n2. second"))))
(ert-deftest test-number-lines-single-line ()
"Should number single line."
(let ((result (test-number-lines "only" "N. " nil)))
(should (string= result "1. only"))))
;;; Normal Cases - Alternative Formats
(ert-deftest test-number-lines-parenthesis-format ()
"Should number with parenthesis format."
(let ((result (test-number-lines "a\nb\nc" "N) " nil)))
(should (string= result "1) a\n2) b\n3) c"))))
(ert-deftest test-number-lines-bracket-format ()
"Should number with bracket format."
(let ((result (test-number-lines "x\ny\nz" "[N] " nil)))
(should (string= result "[1] x\n[2] y\n[3] z"))))
(ert-deftest test-number-lines-no-space-format ()
"Should number without space."
(let ((result (test-number-lines "a\nb" "N." nil)))
(should (string= result "1.a\n2.b"))))
(ert-deftest test-number-lines-custom-format ()
"Should number with custom format."
(let ((result (test-number-lines "foo\nbar" "Item N: " nil)))
(should (string= result "Item 1: foo\nItem 2: bar"))))
;;; Normal Cases - Zero Padding
(ert-deftest test-number-lines-zero-pad-single-digit ()
"Should not pad when max is single digit."
(let ((result (test-number-lines "a\nb\nc" "N. " t)))
(should (string= result "1. a\n2. b\n3. c"))))
(ert-deftest test-number-lines-zero-pad-double-digit ()
"Should pad to 2 digits when max is 10-99."
(let* ((lines (make-list 12 "line"))
(input (mapconcat #'identity lines "\n"))
(result (test-number-lines input "N. " t))
(result-lines (split-string result "\n")))
(should (string-prefix-p "01. " (nth 0 result-lines)))
(should (string-prefix-p "09. " (nth 8 result-lines)))
(should (string-prefix-p "10. " (nth 9 result-lines)))
(should (string-prefix-p "12. " (nth 11 result-lines)))))
(ert-deftest test-number-lines-zero-pad-triple-digit ()
"Should pad to 3 digits when max is 100+."
(let* ((lines (make-list 105 "x"))
(input (mapconcat #'identity lines "\n"))
(result (test-number-lines input "N. " t))
(result-lines (split-string result "\n")))
(should (string-prefix-p "001. " (nth 0 result-lines)))
(should (string-prefix-p "099. " (nth 98 result-lines)))
(should (string-prefix-p "100. " (nth 99 result-lines)))
(should (string-prefix-p "105. " (nth 104 result-lines)))))
;;; Boundary Cases
(ert-deftest test-number-lines-empty-string ()
"Should handle empty string."
(let ((result (test-number-lines "" "N. " nil)))
(should (string= result "1. "))))
(ert-deftest test-number-lines-empty-lines ()
"Should number empty lines."
(let ((result (test-number-lines "\n\n" "N. " nil)))
(should (string= result "1. \n2. \n3. "))))
(ert-deftest test-number-lines-with-existing-numbers ()
"Should number lines that already have content."
(let ((result (test-number-lines "1. old\n2. old" "N. " nil)))
(should (string= result "1. 1. old\n2. 2. old"))))
(ert-deftest test-number-lines-multiple-N-in-format ()
"Should replace multiple N occurrences."
(let ((result (test-number-lines "a\nb" "N-N. " nil)))
(should (string= result "1-1. a\n2-2. b"))))
(ert-deftest test-number-lines-long-content ()
"Should number lines with long content."
(let* ((long-line (make-string 100 ?x))
(input (format "%s\n%s" long-line long-line))
(result (test-number-lines input "N. " nil)))
(should (string-prefix-p "1. " result))
(should (string-match "2\\. " result))))
;;; Normal Cases - No Zero Padding vs Zero Padding
(ert-deftest test-number-lines-comparison-no-pad-vs-pad ()
"Should show difference between no padding and padding."
(let* ((input "a\nb\nc\nd\ne\nf\ng\nh\ni\nj")
(no-pad (test-number-lines input "N. " nil))
(with-pad (test-number-lines input "N. " t))
(no-pad-lines (split-string no-pad "\n"))
(with-pad-lines (split-string with-pad "\n")))
;; Without padding: "1. ", "10. "
(should (string-prefix-p "1. " (nth 0 no-pad-lines)))
(should (string-prefix-p "10. " (nth 9 no-pad-lines)))
;; With padding: "01. ", "10. "
(should (string-prefix-p "01. " (nth 0 with-pad-lines)))
(should (string-prefix-p "10. " (nth 9 with-pad-lines)))))
;;; Error Cases
(ert-deftest test-number-lines-start-greater-than-end ()
"Should error when start > end."
(should-error
(with-temp-buffer
(insert "line1\nline2")
(cj/--number-lines (point-max) (point-min) "N. " nil))
:type 'error))
(ert-deftest test-number-lines-empty-region ()
"Should handle empty region (start == end)."
(with-temp-buffer
(insert "line1\nline2")
(let ((pos (/ (+ (point-min) (point-max)) 2)))
(should (string= "1. " (cj/--number-lines pos pos "N. " nil))))))
(provide 'test-custom-ordering-number-lines)
;;; test-custom-ordering-number-lines.el ends here
|