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