]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/company/test/async-tests.el
Merge commit 'eb0d8d9e687e1364098f9abc6f9281fcbc0d3abd' from company
[gnu-emacs-elpa] / packages / company / test / async-tests.el
diff --git a/packages/company/test/async-tests.el b/packages/company/test/async-tests.el
new file mode 100644 (file)
index 0000000..5d8be3e
--- /dev/null
@@ -0,0 +1,161 @@
+;;; async-tests.el --- company-mode tests  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015  Free Software Foundation, Inc.
+
+;; Author: Dmitry Gutov
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'company-tests)
+
+(defun company-async-backend (command &optional _)
+  (pcase command
+    (`prefix "foo")
+    (`candidates
+     (cons :async
+           (lambda (cb)
+             (run-with-timer 0.05 nil
+                             #'funcall cb '("abc" "abd")))))))
+
+(ert-deftest company-call-backend-forces-sync ()
+  (let ((company-backend 'company-async-backend)
+        (company-async-timeout 0.1))
+    (should (equal '("abc" "abd") (company-call-backend 'candidates)))))
+
+(ert-deftest company-call-backend-errors-on-timeout ()
+  (with-temp-buffer
+    (let* ((company-backend (lambda (command &optional _arg)
+                              (pcase command
+                                (`candidates (cons :async 'ignore)))))
+           (company-async-timeout 0.1)
+           (err (should-error (company-call-backend 'candidates "foo"))))
+      (should (string-match-p "async timeout" (cadr err))))))
+
+(ert-deftest company-call-backend-raw-passes-return-value-verbatim ()
+  (let ((company-backend 'company-async-backend))
+    (should (equal "foo" (company-call-backend-raw 'prefix)))
+    (should (equal :async (car (company-call-backend-raw 'candidates "foo"))))
+    (should (equal 'closure (cadr (company-call-backend-raw 'candidates "foo"))))))
+
+(ert-deftest company-manual-begin-forces-async-candidates-to-sync ()
+  (with-temp-buffer
+    (company-mode)
+    (let (company-frontends
+          company-transformers
+          (company-backends (list 'company-async-backend)))
+      (company-manual-begin)
+      (should (equal "foo" company-prefix))
+      (should (equal '("abc" "abd") company-candidates)))))
+
+(ert-deftest company-idle-begin-allows-async-candidates ()
+  (with-temp-buffer
+    (company-mode)
+    (let (company-frontends
+          company-transformers
+          (company-backends (list 'company-async-backend)))
+      (company-idle-begin (current-buffer) (selected-window)
+                          (buffer-chars-modified-tick) (point))
+      (should (null company-candidates))
+      (sleep-for 0.1)
+      (should (equal "foo" company-prefix))
+      (should (equal '("abc" "abd") company-candidates)))))
+
+(ert-deftest company-idle-begin-cancels-async-candidates-if-buffer-changed ()
+  (with-temp-buffer
+    (company-mode)
+    (let (company-frontends
+          (company-backends (list 'company-async-backend)))
+      (company-idle-begin (current-buffer) (selected-window)
+                          (buffer-chars-modified-tick) (point))
+      (should (null company-candidates))
+      (insert "a")
+      (sleep-for 0.1)
+      (should (null company-candidates)))))
+
+(ert-deftest company-idle-begin-async-allows-immediate-callbacks ()
+  (with-temp-buffer
+    (company-mode)
+    (let (company-frontends
+          (company-backends
+           (list (lambda (command &optional arg)
+                   (pcase command
+                     (`prefix (buffer-substring (point-min) (point)))
+                     (`candidates
+                      (let ((c (all-completions arg '("abc" "def"))))
+                        (cons :async
+                              (lambda (cb) (funcall cb c)))))
+                     (`no-cache t)))))
+          (company-minimum-prefix-length 0))
+      (company-idle-begin (current-buffer) (selected-window)
+                          (buffer-chars-modified-tick) (point))
+      (should (equal '("abc" "def") company-candidates))
+      (let ((last-command-event ?a))
+        (company-call 'self-insert-command 1))
+      (should (equal '("abc") company-candidates)))))
+
+(ert-deftest company-multi-backend-forces-prefix-to-sync ()
+  (with-temp-buffer
+    (let ((company-backend (list 'ignore
+                                 (lambda (command)
+                                   (should (eq command 'prefix))
+                                   (cons :async
+                                         (lambda (cb)
+                                           (run-with-timer
+                                            0.01 nil
+                                            (lambda () (funcall cb nil))))))
+                                 (lambda (command)
+                                   (should (eq command 'prefix))
+                                   "foo"))))
+      (should (equal "foo" (company-call-backend-raw 'prefix))))
+    (let ((company-backend (list (lambda (_command)
+                                   (cons :async
+                                         (lambda (cb)
+                                           (run-with-timer
+                                            0.01 nil
+                                            (lambda () (funcall cb "bar"))))))
+                                 (lambda (_command)
+                                   "foo"))))
+      (should (equal "bar" (company-call-backend-raw 'prefix))))))
+
+(ert-deftest company-multi-backend-merges-deferred-candidates ()
+  (with-temp-buffer
+    (let* ((immediate (lambda (command &optional _)
+                        (pcase command
+                          (`prefix "foo")
+                          (`candidates
+                           (cons :async
+                                 (lambda (cb) (funcall cb '("f"))))))))
+           (company-backend (list 'ignore
+                                  (lambda (command &optional arg)
+                                    (pcase command
+                                      (`prefix "foo")
+                                      (`candidates
+                                       (should (equal arg "foo"))
+                                       (cons :async
+                                             (lambda (cb)
+                                               (run-with-timer
+                                                0.01 nil
+                                                (lambda () (funcall cb '("a" "b")))))))))
+                                  (lambda (command &optional _)
+                                    (pcase command
+                                      (`prefix "foo")
+                                      (`candidates '("c" "d" "e"))))
+                                  immediate)))
+      (should (equal :async (car (company-call-backend-raw 'candidates "foo"))))
+      (should (equal '("a" "b" "c" "d" "e" "f")
+                     (company-call-backend 'candidates "foo")))
+      (let ((company-backend (list immediate)))
+        (should (equal '("f") (company-call-backend 'candidates "foo")))))))