]> code.delx.au - gnu-emacs-elpa/blob - admin/test.el
Merge branch 'master' of https://github.com/leoliu/easy-kill
[gnu-emacs-elpa] / admin / test.el
1 (require 'easy-kill)
2 (require 'ert)
3
4 ;; (defmacro with-named-temp-buffer (name &rest body)
5 ;; (declare (indent with-current-buffer))
6 ;; `(unwind-protect
7 ;; (with-current-buffer (get-buffer-create ,name)
8 ;; ,@body)
9 ;; (and (get-buffer ,name) (kill-buffer ,name))))
10
11 ;; (ert-deftest test-compilation ()
12 ;; (should (zerop (call-process "emacs" nil nil nil
13 ;; "-batch" "-Q" "-f" "batch-byte-compile"
14 ;; "easy-kill.el"))))
15
16 (ert-deftest test-easy-kill-trim ()
17 (should (string= "" (easy-kill-trim " \f\t\n\n\n")))
18 (should (string= "abc" (easy-kill-trim " \t\fabc")))
19 (should (string= "abc" (easy-kill-trim "abc")))
20 (should (string= " \t\fabc" (easy-kill-trim " \t\fabc" 'right)))
21 (should (string= "abc" (easy-kill-trim " \t\fabc" 'left))))
22
23 (ert-deftest test-easy-kill-get ()
24 (with-temp-buffer
25 (insert "two words")
26 (easy-kill)
27 (setf (easy-kill-get bounds) '(1 . 4))
28 (should (string= (easy-kill-candidate) "two"))
29 (should-error (setf (easy-kill-get bounds) nil))
30 (setf (easy-kill-get end) (point-max))
31 (should (= (easy-kill-get end) (point-max)))))
32
33 (ert-deftest test-easy-kill-candidate ()
34 (let ((w "yes"))
35 (with-temp-buffer
36 (insert w)
37 (should-error (easy-kill-candidate))
38 (easy-kill)
39 (easy-kill-thing 'word)
40 (should (string= w (easy-kill-candidate)))
41 (easy-kill-thing 'buffer-file-name)
42 (should (string= (directory-file-name default-directory)
43 (easy-kill-candidate))))))
44
45 (ert-deftest test-easy-kill-describe-candidate ()
46 (with-temp-buffer
47 (insert "(list 1 2 3)")
48 (forward-word -1)
49 (easy-kill)
50 (easy-kill-thing 'sexp)
51 (easy-kill-thing 'list)
52 (should (string-match-p "^\\s-*thing:\\s-*list"
53 (easy-kill-describe-candidate)))))
54
55 (ert-deftest test-easy-kill-append ()
56 (with-temp-buffer
57 (insert "abc")
58 (easy-kill)
59 (easy-kill-thing 'word)
60 (call-interactively #'easy-kill-append)
61 (should (string= (car kill-ring) "abc"))))
62
63 ;;; Make sure the old format of easy-kill-alist is still supported.
64 (ert-deftest test-old-easy-kill-alist ()
65 (let ((easy-kill-alist '((?w . word)
66 (?s . sexp)
67 (?l . list)
68 (?f . filename)
69 (?d . defun)
70 (?e . line)
71 (?b . buffer-file-name)))
72 (text "(first line\nsecond line\nthird line)"))
73 (with-temp-buffer
74 (insert text)
75 (goto-char (point-min))
76 (easy-kill)
77 (let ((last-command-event ?d))
78 (call-interactively #'easy-kill-thing))
79 (should (string= text (easy-kill-candidate))))))
80
81 (ert-deftest test-easy-kill-help ()
82 (let ((easy-kill-alist '((?w . word)
83 (?s . sexp)
84 (?l . list)
85 (?f filename)
86 (?d defun "\n\n")
87 (?e . line)
88 (?b . buffer-file-name)
89 (?x buffer-file-name-buffer-file-name "\t"))))
90 (easy-kill-help)
91 (with-current-buffer (help-buffer)
92 (goto-char (point-min))
93 (should (save-excursion
94 (re-search-forward "^w\\s-*word$" nil t)))
95 (should (save-excursion
96 (re-search-forward "^d\\s-*defun\\s-*\"\\\\n\\\\n\"$" nil t)))
97 (should (save-excursion
98 (re-search-forward "^f\\s-*filename$" nil t)))
99 (should (save-excursion
100 (re-search-forward "^b\\s-*buffer-file-name$" nil t))))))
101
102 (ert-deftest test-easy-kill-thing-handler ()
103 (should (eq (easy-kill-thing-handler "easy-kill-on-list" 'nxml-mode)
104 'easy-kill-on-list:nxml))
105 (should (eq (easy-kill-thing-handler "easy-kill-on-list" 'js2-mode)
106 'easy-kill-on-list:js2))
107 (should (eq (easy-kill-thing-handler "easy-kill-on-sexp" 'nxml-mode)
108 'easy-kill-on-sexp))
109 ;; XXX: side-effect
110 (fset 'js2:easy-kill-on-list #'ignore)
111 (eq (easy-kill-thing-handler "easy-kill-on-sexp" 'js2-mode)
112 'js2:easy-kill-on-list))
113
114 (ert-deftest test-easy-kill-bounds-of-list-at-point ()
115 (let ((text "\"abc (1 2 3) xyz\" ; dummy comment")
116 (text2 "(progn
117 \"[compile\"
118 (should (string= \"display editor.\\nsome of the ways to customize it;\"
119 (easy-kill-candidate))))"))
120 (cl-labels ((getb (bounds)
121 (if bounds
122 (buffer-substring (car bounds) (cdr bounds))
123 "")))
124 (with-temp-buffer
125 (emacs-lisp-mode)
126 (insert text)
127 (search-backward "2")
128 (should (string= (getb (easy-kill-bounds-of-list-at-point)) "(1 2 3)"))
129 (up-list -1)
130 (forward-word -1)
131 (should (string= (getb (easy-kill-bounds-of-list-at-point))
132 "\"abc (1 2 3) xyz\""))
133 (search-forward "dummy")
134 (forward-word -1)
135 (should (string= (getb (easy-kill-bounds-of-list-at-point))
136 "dummy"))
137 ;; text2
138 (erase-buffer)
139 (insert text2)
140 (goto-char (point-min))
141 (re-search-forward "customize")
142 (call-interactively 'easy-kill)
143 (easy-kill-thing 'list)
144 (should (string= "\"display editor.\\nsome of the ways to customize it;\""
145 (easy-kill-candidate)))))))
146
147 (ert-deftest test-easy-kill-on-list ()
148 (let ((text "(defun first-error (&optional n)
149 \"This operates on the output from the \\\\[compile] command, for instance.\"
150 (interactive \"p\")
151 (next-error n t)) ;some dummy comment here"))
152 (with-temp-buffer
153 (emacs-lisp-mode)
154 (insert text)
155 (goto-char (point-min))
156 (search-forward "[compile")
157 (call-interactively 'easy-kill)
158 (easy-kill-thing 'list)
159 (should (string= "[compile]" (easy-kill-candidate)))
160 (up-list -1)
161 (call-interactively 'easy-kill)
162 (let ((clipboard))
163 (cl-letf (((symbol-function 'easy-kill-interprogram-cut)
164 (lambda (text) (setq clipboard text))))
165 (easy-kill-thing 'list))
166 (should (string= (easy-kill-candidate) clipboard)))
167 (should (string= "\"This operates on the output from the \\\\[compile] command, for instance.\""
168 (easy-kill-candidate)))
169 (easy-kill-thing 'list)
170 (should (string-match-p "(interactive \"p\")" (easy-kill-candidate)))
171 (should (string-prefix-p "\"This operates on" (easy-kill-candidate)))
172 (forward-sexp 1) ; where bounds of list is nil
173 (call-interactively 'easy-kill)
174 (easy-kill-thing 'list)
175 (should (string= "\"This operates on the output from the \\\\[compile] command, for instance.\""
176 (easy-kill-candidate)))
177 (search-forward "dummy")
178 (forward-word -1)
179 (call-interactively 'easy-kill)
180 (easy-kill-thing 'list)
181 (should (string= "dummy" (easy-kill-candidate))))))
182
183 (ert-deftest test-js2-mode ()
184 :expected-result :failed
185 (let ((js "function View(name, options) {
186 options = options || {};
187 this.name = name;
188 this.root = options.root;
189 var engines = options.engines;
190 this.defaultEngine = options.defaultEngine;
191 var ext = this.ext = extname(name);
192 if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
193 if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
194 this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
195 this.path = this.lookup(name);
196 }")
197 (buff (get-buffer-create "*js2*")))
198 (eval-and-compile (require 'js2-mode nil t))
199 (setq js2-idle-timer-delay 0)
200 (global-font-lock-mode 1)
201 (unwind-protect
202 (with-current-buffer buff
203 (js2-mode)
204 (insert js)
205 (goto-char (point-min))
206 (js2-reparse t)
207 ;; (js2-do-parse)
208 (while js2-mode-buffer-dirty-p
209 (sit-for 0.1))
210 (search-forward "this.defaultEngine =")
211 (forward-char -1)
212 (easy-kill)
213 (easy-kill-thing 'char)
214 (easy-kill-thing 'list)
215 (should (string= "this.defaultEngine = options.defaultEngine"
216 (easy-kill-candidate)))
217 ;; XXX: should also test (easy-kill-digit-argument 0)
218 )
219 (kill-buffer buff))))
220
221 (ert-deftest test-nxml-mode ()
222 (let ((xml "<?xml version=\"1.0\"?>
223 <catalog>
224 <book id=\"bk101\">
225 <author>Gambardella, Matthew</author>
226 <title>XML Developer's Guide</title>
227 <genre>Computer</genre>
228 <price>44.95</price>
229 <publish_date>2000-10-01</publish_date>
230 <description>An in-depth look at creating applications
231 with XML.</description>
232 </book>
233 </catalog>"))
234 (with-temp-buffer
235 (nxml-mode)
236 (insert xml)
237 (goto-char (point-min))
238 (search-forward "Gambardella")
239 (easy-kill)
240 (easy-kill-thing 'sexp)
241 (easy-kill-expand)
242 (easy-kill-expand)
243 (easy-kill-shrink)
244 (should (eq (easy-kill-get thing) 'sexp))
245 (should (string= "<author>Gambardella, Matthew</author>"
246 (easy-kill-candidate)))
247 (call-interactively 'easy-kill)
248 (easy-kill-thing 'list)
249 (should (string= "<author>Gambardella, Matthew</author>"
250 (easy-kill-candidate)))
251 (easy-kill-thing nil 1)
252 (easy-kill-digit-argument 0)
253 (should (string= "<author>Gambardella, Matthew</author>"
254 (easy-kill-candidate))))))
255
256 (ert-deftest test-org-mode ()
257 (let ((org "#+title: This is a title
258 #+author: Leo Liu
259
260 This is an example of org document.
261
262 * Life
263 One two three ....
264 *** Fruits
265 1. apple
266 2. orange
267 3. mango
268
269 * Sports cars
270 + Lamborghini
271 + Ferrari
272 + Porsche
273 "))
274 (with-temp-buffer
275 (org-mode)
276 (insert org)
277 (goto-char (point-min))
278 (search-forward "This is")
279 (call-interactively 'easy-kill)
280 (easy-kill-thing 'sexp)
281 (easy-kill-expand)
282 (should (string= "#+title: This is a title\n" (easy-kill-candidate)))
283 (search-forward "Fruits")
284 (call-interactively 'easy-kill)
285 (easy-kill-thing 'sexp)
286 (easy-kill-expand)
287 (should (string-prefix-p "*** Fruits" (easy-kill-candidate)))
288 (search-forward "Ferrari")
289 (call-interactively 'easy-kill)
290 (easy-kill-thing 'list)
291 (should (string= "Ferrari\n" (easy-kill-candidate)))
292 (easy-kill-expand)
293 (should (string= " + Ferrari\n" (easy-kill-candidate)))
294 ;; org quirks
295 (search-backward "Lamborghini")
296 (call-interactively 'easy-kill)
297 (easy-kill-thing 'list)
298 ;; You get the whole plainlist here; see `org-element-at-point'.
299 (easy-kill-expand)
300 (should (string= " + Lamborghini\n + Ferrari\n + Porsche\n"
301 (easy-kill-candidate)))
302 (easy-kill-expand)
303 (should (string= "* Sports cars\n + Lamborghini\n + Ferrari\n + Porsche\n"
304 (easy-kill-candidate))))))
305
306 (ert-deftest test-elisp-mode ()
307 (let ((el "(defun set-hard-newline-properties (from to)
308 (let ((sticky (get-text-property from 'rear-nonsticky)))
309 ;; XXX: (put-text-property from to 'hard 't)
310 ;; If rear-nonsticky is not \"t\", add 'hard to rear-nonsticky list
311 (if (and (listp sticky) (not (memq 'hard sticky)))
312 (put-text-property from (point) 'rear-nonsticky
313 (cons 'hard sticky)))))"))
314 (with-temp-buffer
315 (insert el)
316 (goto-char (point-min))
317 (search-forward "put-text-property")
318 (easy-kill)
319 (easy-kill-thing 'sexp)
320 (easy-kill-expand)
321 (should (eq (easy-kill-get thing) 'sexp))
322 (should (string= "(put-text-property from to 'hard 't)"
323 (easy-kill-candidate)))
324 (easy-kill-expand)
325 (easy-kill-expand)
326 (should (string= el (easy-kill-candidate)))
327 (easy-kill-shrink)
328 (easy-kill-shrink)
329 (should (string= "(put-text-property from to 'hard 't)"
330 (easy-kill-candidate)))
331 (easy-kill-digit-argument 0)
332 (should (string= (thing-at-point 'sexp) (easy-kill-candidate))))))
333
334 (ert-deftest test-easy-kill-thing-forward ()
335 (let ((txt "Emacs is the extensible
336 display editor.
337 some of the ways to customize it;
338 24.3."))
339 (with-temp-buffer
340 (insert txt)
341 (forward-line -1)
342 (easy-kill)
343 (easy-kill-thing 'line)
344 (should (string= "some of the ways to customize it;\n24.3."
345 (easy-kill-candidate)))
346 (easy-kill-shrink)
347 (should (string= "some of the ways to customize it;\n"
348 (easy-kill-candidate)))
349 (easy-kill-shrink)
350 (should (string= " display editor.\nsome of the ways to customize it;\n"
351 (easy-kill-candidate)))
352 (easy-kill-thing 'word)
353 (easy-kill-shrink)
354 (should (string= "editor.\nsome" (easy-kill-candidate)))
355 (easy-kill-shrink)
356 (should (string= "display editor.\nsome" (easy-kill-candidate)))
357 (easy-kill-expand)
358 (should (string= " editor.\nsome" (easy-kill-candidate)))
359 (easy-kill-destroy-candidate)
360 (goto-char (point-min))
361 (forward-line 1)
362 (call-interactively 'easy-mark)
363 (should (string= " display" (easy-kill-candidate)))
364 (goto-char (easy-kill-get origin))
365 (deactivate-mark 1)
366 ;; Test the case where there is no thing at point
367 (call-interactively 'easy-kill)
368 (setf (easy-kill-get thing) 'word)
369 (setf (easy-kill-get bounds) (cons (point) (point)))
370 (easy-kill-expand)
371 (should (string= " display" (easy-kill-candidate)))
372 (easy-kill-shrink)
373 (easy-kill-shrink)
374 (easy-kill-shrink)
375 (should (string= "the extensible\n" (easy-kill-candidate))))))
376
377 (ert-deftest test-workaround-defun-bug ()
378 ;; http://debbugs.gnu.org/17247
379 (let ((txt "(tan 2)\n\n(sin 2)\n(cos 2)\n"))
380 (with-temp-buffer
381 (insert txt)
382 (easy-kill)
383 (easy-kill-thing 'defun)
384 (easy-kill-shrink)
385 (should (string= "(sin 2)\n(cos 2)\n" (easy-kill-candidate)))
386 (easy-kill-shrink)
387 (should (string= txt (easy-kill-candidate))))))
388
389 (ert-deftest test-easy-kill-exchange-point-and-mark ()
390 (let ((txt "(delete-region (point)
391 (if (re-search-forward \"[^ \\t\\n]\" nil t)
392 (progn (beginning-of-line) (point))
393 (point-max)))"))
394 (with-temp-buffer
395 (emacs-lisp-mode)
396 (insert txt)
397 (goto-char (point-min))
398 (search-forward "re-search-forward")
399 (call-interactively 'easy-mark)
400 (should (string= "re-search-forward" (easy-kill-candidate)))
401 (should (= (point) (easy-kill-get end)))
402 (call-interactively 'easy-kill-exchange-point-and-mark)
403 (easy-kill-expand)
404 (should (= (point) (easy-kill-get start)))
405 (should (= (mark t) (easy-kill-get end)))
406 (call-interactively 'easy-kill-exchange-point-and-mark)
407 (easy-kill-shrink)
408 (should (= (mark t) (easy-kill-get start)))
409 (should (= (point) (easy-kill-get end))))))