]> code.delx.au - gnu-emacs-elpa/blob - company-tests.el
Use cl-lib
[gnu-emacs-elpa] / company-tests.el
1 ;;; company-tests.el --- company-mode tests -*- lexical-binding: t -*-
2
3 ;; Copyright (C) 2011, 2013-2014 Free Software Foundation, Inc.
4
5 ;; Author: Nikolaj Schumacher
6
7 ;; This file is part of GNU Emacs.
8
9 ;; GNU Emacs is free software: you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
13
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
21
22
23 ;;; Commentary:
24 ;;
25
26 ;;; Code:
27
28 (require 'ert)
29 (require 'company)
30 (require 'company-keywords)
31 (require 'company-clang)
32
33 ;;; Core
34
35 (ert-deftest company-sorted-keywords ()
36 "Test that keywords in `company-keywords-alist' are in alphabetical order."
37 (dolist (pair company-keywords-alist)
38 (when (consp (cdr pair))
39 (let ((prev (cadr pair)))
40 (dolist (next (cddr pair))
41 (should (not (equal prev next)))
42 (should (string< prev next))
43 (setq prev next))))))
44
45 (ert-deftest company-good-prefix ()
46 (let ((company-minimum-prefix-length 5)
47 company-abort-manual-when-too-short
48 company--manual-action ;idle begin
49 (company-selection-changed t)) ;has no effect
50 (should (eq t (company--good-prefix-p "!@#$%")))
51 (should (eq nil (company--good-prefix-p "abcd")))
52 (should (eq nil (company--good-prefix-p 'stop)))
53 (should (eq t (company--good-prefix-p '("foo" . 5))))
54 (should (eq nil (company--good-prefix-p '("foo" . 4))))
55 (should (eq t (company--good-prefix-p '("foo" . t))))))
56
57 (ert-deftest company--manual-prefix-set-and-unset ()
58 (with-temp-buffer
59 (insert "ab")
60 (company-mode)
61 (let (company-frontends
62 (company-backends
63 (list (lambda (command &optional arg)
64 (cl-case command
65 (prefix (buffer-substring (point-min) (point)))
66 (candidates '("abc" "abd")))))))
67 (company-manual-begin)
68 (should (equal "ab" company--manual-prefix))
69 (company-abort)
70 (should (null company--manual-prefix)))))
71
72 (ert-deftest company-abort-manual-when-too-short ()
73 (let ((company-minimum-prefix-length 5)
74 (company-abort-manual-when-too-short t)
75 (company-selection-changed t)) ;has not effect
76 (let ((company--manual-action nil)) ;idle begin
77 (should (eq t (company--good-prefix-p "!@#$%")))
78 (should (eq t (company--good-prefix-p '("foo" . 5))))
79 (should (eq t (company--good-prefix-p '("foo" . t)))))
80 (let ((company--manual-action t)
81 (company--manual-prefix "abc")) ;manual begin from this prefix
82 (should (eq t (company--good-prefix-p "!@#$")))
83 (should (eq nil (company--good-prefix-p "ab")))
84 (should (eq nil (company--good-prefix-p 'stop)))
85 (should (eq t (company--good-prefix-p '("foo" . 4))))
86 (should (eq t (company--good-prefix-p "abcd")))
87 (should (eq t (company--good-prefix-p "abc")))
88 (should (eq t (company--good-prefix-p '("bar" . t)))))))
89
90 (ert-deftest company-multi-backend-with-lambdas ()
91 (let ((company-backend
92 (list (lambda (command &optional arg &rest ignore)
93 (cl-case command
94 (prefix "z")
95 (candidates '("a" "b"))))
96 (lambda (command &optional arg &rest ignore)
97 (cl-case command
98 (prefix "z")
99 (candidates '("c" "d")))))))
100 (should (equal (company-call-backend 'candidates "z") '("a" "b" "c" "d")))))
101
102 (ert-deftest company-multi-backend-remembers-candidate-backend ()
103 (let ((company-backend
104 (list (lambda (command &optional arg)
105 (cl-case command
106 (ignore-case nil)
107 (annotation "1")
108 (candidates '("a" "c"))
109 (post-completion "13")))
110 (lambda (command &optional arg)
111 (cl-case command
112 (ignore-case t)
113 (annotation "2")
114 (candidates '("b" "d"))
115 (post-completion "42")))
116 (lambda (command &optional arg)
117 (cl-case command
118 (annotation "3")
119 (candidates '("e"))
120 (post-completion "74"))))))
121 (let ((candidates (company-calculate-candidates nil)))
122 (should (equal candidates '("a" "b" "c" "d" "e")))
123 (should (equal t (company-call-backend 'ignore-case)))
124 (should (equal "1" (company-call-backend 'annotation (nth 0 candidates))))
125 (should (equal "2" (company-call-backend 'annotation (nth 1 candidates))))
126 (should (equal "13" (company-call-backend 'post-completion (nth 2 candidates))))
127 (should (equal "42" (company-call-backend 'post-completion (nth 3 candidates))))
128 (should (equal "3" (company-call-backend 'annotation (nth 4 candidates))))
129 (should (equal "74" (company-call-backend 'post-completion (nth 4 candidates)))))))
130
131 (ert-deftest company-multi-backend-handles-keyword-with ()
132 (let ((primo (lambda (command &optional arg)
133 (cl-case command
134 (prefix "a")
135 (candidates '("abb" "abc" "abd")))))
136 (secundo (lambda (command &optional arg)
137 (cl-case command
138 (prefix "a")
139 (candidates '("acc" "acd"))))))
140 (let ((company-backend (list 'ignore 'ignore :with secundo)))
141 (should (null (company-call-backend 'prefix))))
142 (let ((company-backend (list 'ignore primo :with secundo)))
143 (should (equal "a" (company-call-backend 'prefix)))
144 (should (equal '("abb" "abc" "abd" "acc" "acd")
145 (company-call-backend 'candidates "a"))))))
146
147 (ert-deftest company-begin-backend-failure-doesnt-break-company-backends ()
148 (with-temp-buffer
149 (insert "a")
150 (company-mode)
151 (should-error
152 (company-begin-backend (lambda (command &rest ignore))))
153 (let (company-frontends
154 (company-backends
155 (list (lambda (command &optional arg)
156 (cl-case command
157 (prefix "a")
158 (candidates '("a" "ab" "ac")))))))
159 (let (this-command)
160 (company-call 'complete))
161 (should (eq 3 company-candidates-length)))))
162
163 (ert-deftest company-require-match-explicit ()
164 (with-temp-buffer
165 (insert "ab")
166 (company-mode)
167 (let (company-frontends
168 (company-require-match 'company-explicit-action-p)
169 (company-backends
170 (list (lambda (command &optional arg)
171 (cl-case command
172 (prefix (buffer-substring (point-min) (point)))
173 (candidates '("abc" "abd")))))))
174 (let (this-command)
175 (company-complete))
176 (let ((last-command-event ?e))
177 (company-call 'self-insert-command 1))
178 (should (eq 2 company-candidates-length))
179 (should (eq 3 (point))))))
180
181 (ert-deftest company-dont-require-match-when-idle ()
182 (with-temp-buffer
183 (insert "ab")
184 (company-mode)
185 (let (company-frontends
186 (company-require-match 'company-explicit-action-p)
187 (company-backends
188 (list (lambda (command &optional arg)
189 (cl-case command
190 (prefix (buffer-substring (point-min) (point)))
191 (candidates '("abc" "abd")))))))
192 (company-idle-begin (current-buffer) (selected-window)
193 (buffer-chars-modified-tick) (point))
194 (let ((last-command-event ?e))
195 (company-call 'self-insert-command 1))
196 (should (eq nil company-candidates-length))
197 (should (eq 4 (point))))))
198
199 (ert-deftest company-should-complete-whitelist ()
200 (with-temp-buffer
201 (insert "ab")
202 (company-mode)
203 (let (company-frontends
204 company-begin-commands
205 (company-backends
206 (list (lambda (command &optional arg)
207 (cl-case command
208 (prefix (buffer-substring (point-min) (point)))
209 (candidates '("abc" "abd")))))))
210 (let ((company-continue-commands nil))
211 (let (this-command)
212 (company-complete))
213 (company-call 'backward-delete-char 1)
214 (should (null company-candidates-length)))
215 (let ((company-continue-commands '(backward-delete-char)))
216 (let (this-command)
217 (company-complete))
218 (company-call 'backward-delete-char 1)
219 (should (eq 2 company-candidates-length))))))
220
221 (ert-deftest company-should-complete-blacklist ()
222 (with-temp-buffer
223 (insert "ab")
224 (company-mode)
225 (let (company-frontends
226 company-begin-commands
227 (company-backends
228 (list (lambda (command &optional arg)
229 (cl-case command
230 (prefix (buffer-substring (point-min) (point)))
231 (candidates '("abc" "abd")))))))
232 (let ((company-continue-commands '(not backward-delete-char)))
233 (let (this-command)
234 (company-complete))
235 (company-call 'backward-delete-char 1)
236 (should (null company-candidates-length)))
237 (let ((company-continue-commands '(not backward-delete-char-untabify)))
238 (let (this-command)
239 (company-complete))
240 (company-call 'backward-delete-char 1)
241 (should (eq 2 company-candidates-length))))))
242
243 (ert-deftest company-auto-complete-explicit ()
244 (with-temp-buffer
245 (insert "ab")
246 (company-mode)
247 (let (company-frontends
248 (company-auto-complete 'company-explicit-action-p)
249 (company-auto-complete-chars '(? ))
250 (company-backends
251 (list (lambda (command &optional arg)
252 (cl-case command
253 (prefix (buffer-substring (point-min) (point)))
254 (candidates '("abcd" "abef")))))))
255 (let (this-command)
256 (company-complete))
257 (let ((last-command-event ? ))
258 (company-call 'self-insert-command 1))
259 (should (string= "abcd " (buffer-string))))))
260
261 (ert-deftest company-no-auto-complete-when-idle ()
262 (with-temp-buffer
263 (insert "ab")
264 (company-mode)
265 (let (company-frontends
266 (company-auto-complete 'company-explicit-action-p)
267 (company-auto-complete-chars '(? ))
268 (company-backends
269 (list (lambda (command &optional arg)
270 (cl-case command
271 (prefix (buffer-substring (point-min) (point)))
272 (candidates '("abcd" "abef")))))))
273 (company-idle-begin (current-buffer) (selected-window)
274 (buffer-chars-modified-tick) (point))
275 (let ((last-command-event ? ))
276 (company-call 'self-insert-command 1))
277 (should (string= "ab " (buffer-string))))))
278
279 (ert-deftest company-clears-explicit-action-when-no-matches ()
280 (with-temp-buffer
281 (company-mode)
282 (let (company-frontends
283 company-backends)
284 (company-call 'manual-begin) ;; fails
285 (should (null company-candidates))
286 (should (null (company-explicit-action-p))))))
287
288 (ert-deftest company-ignore-case-replaces-prefix ()
289 (with-temp-buffer
290 (company-mode)
291 (let (company-frontends
292 company-end-of-buffer-workaround
293 (company-backends
294 (list (lambda (command &optional arg)
295 (cl-case command
296 (prefix (buffer-substring (point-min) (point)))
297 (candidates '("abcd" "abef"))
298 (ignore-case t))))))
299 (insert "A")
300 (let (this-command)
301 (company-complete))
302 (should (string= "ab" (buffer-string)))
303 (delete-char -2)
304 (insert "A") ; hack, to keep it in one test
305 (company-complete-selection)
306 (should (string= "abcd" (buffer-string))))))
307
308 (ert-deftest company-ignore-case-with-keep-prefix ()
309 (with-temp-buffer
310 (insert "AB")
311 (company-mode)
312 (let (company-frontends
313 (company-backends
314 (list (lambda (command &optional arg)
315 (cl-case command
316 (prefix (buffer-substring (point-min) (point)))
317 (candidates '("abcd" "abef"))
318 (ignore-case 'keep-prefix))))))
319 (let (this-command)
320 (company-complete))
321 (company-complete-selection)
322 (should (string= "ABcd" (buffer-string))))))
323
324 (ert-deftest company-non-prefix-completion ()
325 (with-temp-buffer
326 (insert "tc")
327 (company-mode)
328 (let (company-frontends
329 company-end-of-buffer-workaround
330 (company-backends
331 (list (lambda (command &optional arg)
332 (cl-case command
333 (prefix (buffer-substring (point-min) (point)))
334 (candidates '("tea-cup" "teal-color")))))))
335 (let (this-command)
336 (company-complete))
337 (should (string= "tc" (buffer-string)))
338 (company-complete-selection)
339 (should (string= "tea-cup" (buffer-string))))))
340
341 (ert-deftest company-pseudo-tooltip-does-not-get-displaced ()
342 :tags '(interactive)
343 (with-temp-buffer
344 (save-window-excursion
345 (set-window-buffer nil (current-buffer))
346 (save-excursion (insert " ff"))
347 (company-mode)
348 (let ((company-frontends '(company-pseudo-tooltip-frontend))
349 (company-begin-commands '(self-insert-command))
350 (company-backends
351 (list (lambda (c &optional arg)
352 (cl-case c (prefix "") (candidates '("a" "b" "c")))))))
353 (let (this-command)
354 (company-call 'complete))
355 (company-call 'open-line 1)
356 (should (eq 2 (overlay-start company-pseudo-tooltip-overlay)))))))
357
358 (ert-deftest company-pseudo-tooltip-show ()
359 :tags '(interactive)
360 (with-temp-buffer
361 (save-window-excursion
362 (set-window-buffer nil (current-buffer))
363 (insert "aaaa\n bb\nccccccc\nddd")
364 (search-backward "bb")
365 (let ((col (company--column))
366 (company-candidates-length 2)
367 (company-candidates '("123" "45"))
368 (company-backend 'ignore))
369 (company-pseudo-tooltip-show (company--row) col 0)
370 (let ((ov company-pseudo-tooltip-overlay))
371 ;; With margins.
372 (should (eq (overlay-get ov 'company-width) 5))
373 ;; FIXME: Make it 2?
374 (should (eq (overlay-get ov 'company-height) company-tooltip-limit))
375 (should (eq (overlay-get ov 'company-column) col))
376 (should (string= (overlay-get ov 'company-after)
377 " 123 \nc 45 c\nddd\n")))))))
378
379 (ert-deftest company-preview-show-with-annotations ()
380 :tags '(interactive)
381 (with-temp-buffer
382 (save-window-excursion
383 (set-window-buffer nil (current-buffer))
384 (save-excursion (insert "\n"))
385 (let ((company-candidates-length 1)
386 (company-candidates '("123")))
387 (company-preview-show-at-point (point))
388 (let ((ov company-preview-overlay))
389 (should (string= (overlay-get ov 'display) "123\n")))))))
390
391 (ert-deftest company-pseudo-tooltip-show-with-annotations ()
392 :tags '(interactive)
393 (with-temp-buffer
394 (save-window-excursion
395 (set-window-buffer nil (current-buffer))
396 (insert " ")
397 (save-excursion (insert "\n"))
398 (let ((company-candidates-length 2)
399 (company-backend (lambda (action &optional arg &rest _ignore)
400 (when (eq action 'annotation)
401 (cdr (assoc arg '(("123" . "(4)")))))))
402 (company-candidates '("123" "45"))
403 company-tooltip-align-annotations)
404 (company-pseudo-tooltip-show-at-point (point))
405 (let ((ov company-pseudo-tooltip-overlay))
406 ;; With margins.
407 (should (eq (overlay-get ov 'company-width) 8))
408 (should (string= (overlay-get ov 'company-after)
409 " 123(4) \n 45 \n")))))))
410
411 (ert-deftest company-pseudo-tooltip-show-with-annotations-right-aligned ()
412 :tags '(interactive)
413 (with-temp-buffer
414 (save-window-excursion
415 (set-window-buffer nil (current-buffer))
416 (insert " ")
417 (save-excursion (insert "\n"))
418 (let ((company-candidates-length 3)
419 (company-backend (lambda (action &optional arg &rest _ignore)
420 (when (eq action 'annotation)
421 (cdr (assoc arg '(("123" . "(4)")
422 ("67" . "(891011)")))))))
423 (company-candidates '("123" "45" "67"))
424 (company-tooltip-align-annotations t))
425 (company-pseudo-tooltip-show-at-point (point))
426 (let ((ov company-pseudo-tooltip-overlay))
427 ;; With margins.
428 (should (eq (overlay-get ov 'company-width) 13))
429 (should (string= (overlay-get ov 'company-after)
430 " 123 (4) \n 45 \n 67 (891011) \n")))))))
431
432 (ert-deftest company-create-lines-shows-numbers ()
433 (let ((company-show-numbers t)
434 (company-candidates '("x" "y" "z"))
435 (company-candidates-length 3)
436 (company-backend 'ignore))
437 (should (equal '(" x 1 " " y 2 " " z 3 ")
438 (company--create-lines 0 999)))))
439
440 (ert-deftest company-create-lines-truncates-annotations ()
441 (let* ((ww (company--window-width))
442 (data `(("1" . "(123)")
443 ("2" . nil)
444 ("3" . ,(concat "(" (make-string (- ww 2) ?4) ")"))
445 (,(make-string ww ?4) . "<4>")))
446 (company-candidates (mapcar #'car data))
447 (company-candidates-length 4)
448 (company-tooltip-margin 1)
449 (company-backend (lambda (cmd &optional arg)
450 (when (eq cmd 'annotation)
451 (cdr (assoc arg data)))))
452 company-tooltip-align-annotations)
453 (should (equal (list (format " 1(123)%s " (company-space-string (- ww 8)))
454 (format " 2%s " (company-space-string (- ww 3)))
455 (format " 3(444%s " (make-string (- ww 7) ?4))
456 (format " %s " (make-string (- ww 2) ?4)))
457 (company--create-lines 0 999)))
458 (let ((company-tooltip-align-annotations t))
459 (should (equal (list (format " 1%s(123) " (company-space-string (- ww 8)))
460 (format " 2%s " (company-space-string (- ww 3)))
461 (format " 3 (444%s " (make-string (- ww 8) ?4))
462 (format " %s " (make-string (- ww 2) ?4)))
463 (company--create-lines 0 999))))))
464
465 (ert-deftest company-column-with-composition ()
466 (with-temp-buffer
467 (insert "lambda ()")
468 (compose-region 1 (1+ (length "lambda")) "\\")
469 (should (= (company--column) 4))))
470
471 (ert-deftest company-column-with-line-prefix ()
472 (with-temp-buffer
473 (insert "foo")
474 (put-text-property (point-min) (point) 'line-prefix " ")
475 (should (= (company--column) 5))))
476
477 (ert-deftest company-column-wth-line-prefix-on-empty-line ()
478 (with-temp-buffer
479 (insert "\n")
480 (forward-char -1)
481 (put-text-property (point-min) (point-max) 'line-prefix " ")
482 (should (= (company--column) 2))))
483
484 (ert-deftest company-plainify ()
485 (let ((tab-width 8))
486 (should (equal-including-properties
487 (company-plainify "\tabc\td\t")
488 (concat " "
489 "abc "
490 "d "))))
491 (should (equal-including-properties
492 (company-plainify (propertize "foobar" 'line-prefix "-*-"))
493 "-*-foobar")))
494
495 (ert-deftest company-modify-line ()
496 (let ((str "-*-foobar"))
497 (should (equal-including-properties
498 (company-modify-line str "zz" 4)
499 "-*-fzzbar"))
500 (should (equal-including-properties
501 (company-modify-line str "xx" 0)
502 "xx-foobar"))
503 (should (equal-including-properties
504 (company-modify-line str "zz" 10)
505 "-*-foobar zz"))))
506
507 (ert-deftest company-scrollbar-bounds ()
508 (should (equal nil (company--scrollbar-bounds 0 3 3)))
509 (should (equal nil (company--scrollbar-bounds 0 4 3)))
510 (should (equal '(0 . 0) (company--scrollbar-bounds 0 1 2)))
511 (should (equal '(1 . 1) (company--scrollbar-bounds 2 2 4)))
512 (should (equal '(2 . 3) (company--scrollbar-bounds 7 4 12)))
513 (should (equal '(1 . 2) (company--scrollbar-bounds 3 4 12)))
514 (should (equal '(1 . 3) (company--scrollbar-bounds 4 5 11))))
515
516 ;;; Async
517
518 (defun company-async-backend (command &optional arg)
519 (pcase command
520 (`prefix "foo")
521 (`candidates
522 (cons :async
523 (lambda (cb)
524 (run-with-timer 0.05 nil
525 #'funcall cb '("abc" "abd")))))))
526
527 (ert-deftest company-call-backend-forces-sync ()
528 (let ((company-backend 'company-async-backend)
529 (company-async-timeout 0.1))
530 (should (equal '("abc" "abd") (company-call-backend 'candidates)))))
531
532 (ert-deftest company-call-backend-errors-on-timeout ()
533 (with-temp-buffer
534 (let* ((company-backend (lambda (command &optional _arg)
535 (pcase command
536 (`candidates (cons :async 'ignore)))))
537 (company-async-timeout 0.1)
538 (err (should-error (company-call-backend 'candidates "foo"))))
539 (should (string-match-p "async timeout" (cadr err))))))
540
541 (ert-deftest company-call-backend-raw-passes-return-value-verbatim ()
542 (let ((company-backend 'company-async-backend))
543 (should (equal "foo" (company-call-backend-raw 'prefix)))
544 (should (equal :async (car (company-call-backend-raw 'candidates "foo"))))
545 (should (equal 'closure (cadr (company-call-backend-raw 'candidates "foo"))))))
546
547 (ert-deftest company-manual-begin-forces-async-candidates-to-sync ()
548 (with-temp-buffer
549 (company-mode)
550 (let (company-frontends
551 (company-backends (list 'company-async-backend)))
552 (company-manual-begin)
553 (should (equal "foo" company-prefix))
554 (should (equal '("abc" "abd") company-candidates)))))
555
556 (ert-deftest company-idle-begin-allows-async-candidates ()
557 (with-temp-buffer
558 (company-mode)
559 (let (company-frontends
560 (company-backends (list 'company-async-backend)))
561 (company-idle-begin (current-buffer) (selected-window)
562 (buffer-chars-modified-tick) (point))
563 (should (null company-candidates))
564 (sleep-for 0.1)
565 (should (equal "foo" company-prefix))
566 (should (equal '("abc" "abd") company-candidates)))))
567
568 (ert-deftest company-idle-begin-cancels-async-candidates-if-buffer-changed ()
569 (with-temp-buffer
570 (company-mode)
571 (let (company-frontends
572 (company-backends (list 'company-async-backend)))
573 (company-idle-begin (current-buffer) (selected-window)
574 (buffer-chars-modified-tick) (point))
575 (should (null company-candidates))
576 (insert "a")
577 (sleep-for 0.1)
578 (should (null company-prefix))
579 (should (null company-candidates)))))
580
581 (ert-deftest company-idle-begin-async-allows-immediate-callbacks ()
582 (with-temp-buffer
583 (company-mode)
584 (let (company-frontends
585 (company-backends
586 (list (lambda (command &optional arg)
587 (pcase command
588 (`prefix (buffer-substring (point-min) (point)))
589 (`candidates
590 (let ((c (all-completions arg '("abc" "def"))))
591 (cons :async
592 (lambda (cb) (funcall cb c)))))
593 (`no-cache t)))))
594 (company-minimum-prefix-length 0))
595 (company-idle-begin (current-buffer) (selected-window)
596 (buffer-chars-modified-tick) (point))
597 (should (equal '("abc" "def") company-candidates))
598 (let ((last-command-event ?a))
599 (company-call 'self-insert-command 1))
600 (should (equal '("abc") company-candidates)))))
601
602 (ert-deftest company-multi-backend-forces-prefix-to-sync ()
603 (with-temp-buffer
604 (let ((company-backend (list 'ignore
605 (lambda (command)
606 (should (eq command 'prefix))
607 (cons :async
608 (lambda (cb)
609 (run-with-timer
610 0.01 nil
611 (lambda () (funcall cb nil))))))
612 (lambda (command)
613 (should (eq command 'prefix))
614 "foo"))))
615 (should (equal "foo" (company-call-backend-raw 'prefix))))
616 (let ((company-backend (list (lambda (_command)
617 (cons :async
618 (lambda (cb)
619 (run-with-timer
620 0.01 nil
621 (lambda () (funcall cb "bar"))))))
622 (lambda (_command)
623 "foo"))))
624 (should (equal "bar" (company-call-backend-raw 'prefix))))))
625
626 (ert-deftest company-multi-backend-merges-deferred-candidates ()
627 (with-temp-buffer
628 (let* ((immediate (lambda (command &optional arg)
629 (pcase command
630 (`prefix "foo")
631 (`candidates
632 (cons :async
633 (lambda (cb) (funcall cb '("f"))))))))
634 (company-backend (list 'ignore
635 (lambda (command &optional arg)
636 (pcase command
637 (`prefix "foo")
638 (`candidates
639 (should (equal arg "foo"))
640 (cons :async
641 (lambda (cb)
642 (run-with-timer
643 0.01 nil
644 (lambda () (funcall cb '("a" "b")))))))))
645 (lambda (command &optional arg)
646 (pcase command
647 (`prefix "foo")
648 (`candidates '("c" "d" "e"))))
649 immediate)))
650 (should (equal :async (car (company-call-backend-raw 'candidates "foo"))))
651 (should (equal '("a" "b" "c" "d" "e" "f")
652 (company-call-backend 'candidates "foo")))
653 (let ((company-backend (list immediate)))
654 (should (equal '("f") (company-call-backend 'candidates "foo")))))))
655
656 ;;; Template
657
658 (ert-deftest company-template-removed-after-the-last-jump ()
659 (with-temp-buffer
660 (insert "{ }")
661 (goto-char 2)
662 (let ((tpl (company-template-declare-template (point) (1- (point-max)))))
663 (save-excursion
664 (dotimes (i 2)
665 (insert " ")
666 (company-template-add-field tpl (point) "foo")))
667 (company-call 'template-forward-field)
668 (should (= 3 (point)))
669 (company-call 'template-forward-field)
670 (should (= 7 (point)))
671 (company-call 'template-forward-field)
672 (should (= 11 (point)))
673 (should (zerop (length (overlay-get tpl 'company-template-fields))))
674 (should (null (overlay-buffer tpl))))))
675
676 (ert-deftest company-template-removed-after-input-and-jump ()
677 (with-temp-buffer
678 (insert "{ }")
679 (goto-char 2)
680 (let ((tpl (company-template-declare-template (point) (1- (point-max)))))
681 (save-excursion
682 (insert " ")
683 (company-template-add-field tpl (point) "bar"))
684 (company-call 'template-move-to-first tpl)
685 (should (= 3 (point)))
686 (dolist (c (string-to-list "tee"))
687 (let ((last-command-event c))
688 (company-call 'self-insert-command 1)))
689 (should (string= "{ tee }" (buffer-string)))
690 (should (overlay-buffer tpl))
691 (company-call 'template-forward-field)
692 (should (= 7 (point)))
693 (should (null (overlay-buffer tpl))))))
694
695 (defun company-call (name &rest args)
696 (let* ((maybe (intern (format "company-%s" name)))
697 (command (if (fboundp maybe) maybe name)))
698 (let ((this-command command))
699 (run-hooks 'pre-command-hook))
700 (apply command args)
701 (let ((this-command command))
702 (run-hooks 'post-command-hook))))
703
704 (ert-deftest company-template-c-like-templatify ()
705 (with-temp-buffer
706 (let ((text "foo(int a, short b)"))
707 (insert text)
708 (company-template-c-like-templatify text)
709 (should (equal "foo(arg0, arg1)" (buffer-string)))
710 (should (looking-at "arg0"))
711 (should (equal "int a"
712 (overlay-get (company-template-field-at) 'display))))))
713
714 (ert-deftest company-template-c-like-templatify-trims-after-closing-paren ()
715 (with-temp-buffer
716 (let ((text "foo(int a, short b)!@ #1334 a"))
717 (insert text)
718 (company-template-c-like-templatify text)
719 (should (equal "foo(arg0, arg1)" (buffer-string)))
720 (should (looking-at "arg0")))))
721
722 ;;; Clang
723
724 (ert-deftest company-clang-objc-templatify ()
725 (with-temp-buffer
726 (let ((text "createBookWithTitle:andAuthor:"))
727 (insert text)
728 (company-clang-objc-templatify text)
729 (should (equal "createBookWithTitle:arg0 andAuthor:arg1" (buffer-string)))
730 (should (looking-at "arg0"))
731 (should (null (overlay-get (company-template-field-at) 'display))))))