blob: f2bf793f44dca6e23e47cbc3a69e6f464649cc1e (
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
|
;;; test-custom-misc-count-words.el --- Tests for cj/--count-words -*- lexical-binding: t; -*-
;;; Commentary:
;; Tests for the cj/--count-words function from custom-misc.el
;;
;; This function counts words in a region using Emacs's built-in count-words.
;; A word is defined by Emacs's word boundaries, which generally means
;; sequences of word-constituent characters separated by whitespace or punctuation.
;;
;; We test the NON-INTERACTIVE implementation (cj/--count-words) to avoid
;; mocking region selection. This follows our testing best practice of
;; separating business logic from UI interaction.
;;; 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-misc)
;;; Test Helpers
(defun test-count-words (input-text)
"Test cj/--count-words on INPUT-TEXT.
Returns the word count."
(with-temp-buffer
(insert input-text)
(cj/--count-words (point-min) (point-max))))
;;; Normal Cases
(ert-deftest test-count-words-multiple-words ()
"Should count multiple words."
(should (= 5 (test-count-words "The quick brown fox jumps"))))
(ert-deftest test-count-words-single-word ()
"Should count single word."
(should (= 1 (test-count-words "hello"))))
(ert-deftest test-count-words-with-punctuation ()
"Should count words with punctuation."
(should (= 5 (test-count-words "Hello, world! How are you?"))))
(ert-deftest test-count-words-multiple-spaces ()
"Should count words separated by multiple spaces."
(should (= 3 (test-count-words "hello world test"))))
(ert-deftest test-count-words-with-newlines ()
"Should count words across newlines."
(should (= 6 (test-count-words "line one\nline two\nline three"))))
(ert-deftest test-count-words-with-tabs ()
"Should count words separated by tabs."
(should (= 3 (test-count-words "hello\tworld\ttest"))))
(ert-deftest test-count-words-mixed-whitespace ()
"Should count words with mixed whitespace."
(should (= 4 (test-count-words "hello \t world\n\ntest end"))))
(ert-deftest test-count-words-hyphenated ()
"Should count hyphenated words."
;; Emacs treats hyphens as word separators in count-words
(should (= 7 (test-count-words "This is state-of-the-art technology"))))
(ert-deftest test-count-words-contractions ()
"Should count contractions."
;; Emacs treats apostrophes as word separators in count-words
(should (= 6 (test-count-words "don't can't won't"))))
(ert-deftest test-count-words-numbers ()
"Should count numbers as words."
(should (= 6 (test-count-words "The year 2024 has 365 days"))))
;;; Boundary Cases
(ert-deftest test-count-words-empty-string ()
"Should return 0 for empty string."
(should (= 0 (test-count-words ""))))
(ert-deftest test-count-words-only-whitespace ()
"Should return 0 for whitespace-only text."
(should (= 0 (test-count-words " \t\n\n "))))
(ert-deftest test-count-words-only-punctuation ()
"Should count punctuation-only text."
;; Emacs may count consecutive punctuation as a word
(should (= 1 (test-count-words "!@#$%^&*()"))))
(ert-deftest test-count-words-leading-trailing-spaces ()
"Should count words ignoring leading/trailing spaces."
(should (= 3 (test-count-words " hello world test "))))
(ert-deftest test-count-words-unicode ()
"Should count Unicode words."
(should (= 3 (test-count-words "café résumé naïve"))))
(ert-deftest test-count-words-very-long-text ()
"Should handle very long text."
(let ((long-text (mapconcat (lambda (_) "word") (make-list 1000 nil) " ")))
(should (= 1000 (test-count-words long-text)))))
(ert-deftest test-count-words-multiline-paragraph ()
"Should count words in multi-line paragraph."
(let ((text "This is a paragraph
that spans multiple
lines with various
words in it."))
(should (= 13 (test-count-words text)))))
;;; Error Cases
(ert-deftest test-count-words-start-greater-than-end ()
"Should error when start > end."
(should-error
(with-temp-buffer
(insert "hello world")
(cj/--count-words (point-max) (point-min)))
:type 'error))
(ert-deftest test-count-words-empty-region ()
"Should return 0 for empty region (start == end)."
(with-temp-buffer
(insert "hello world")
(let ((pos (/ (+ (point-min) (point-max)) 2)))
(should (= 0 (cj/--count-words pos pos))))))
(ert-deftest test-count-words-partial-region ()
"Should count words only in specified region."
(with-temp-buffer
(insert "one two three four five")
;; Count only "two three four" (positions roughly in middle)
(goto-char (point-min))
(search-forward "two")
(let ((start (match-beginning 0)))
(search-forward "four")
(let ((end (match-end 0)))
(should (= 3 (cj/--count-words start end)))))))
(provide 'test-custom-misc-count-words)
;;; test-custom-misc-count-words.el ends here
|