Reorganize unit-tests and test workflow

+ Moved unit tests out of tests/ and into their respective modules.
+ Rewrite makefile and added these tasks:
  + <MODULE>/<SUBMODULE> -- byte-compile a specific module
  + test:<MODULE>/<SUBMODULE> -- runs tests for a specific module
  + testi -- run tests in an interactive session of Emacs (WIP)
  + run -- opens an Emacs session with this config; useful when it is in
    a non-standard location.
This commit is contained in:
Henrik Lissner 2017-06-14 20:26:17 +02:00
parent cacd188286
commit 9c93c453e8
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
22 changed files with 511 additions and 423 deletions

View file

@ -0,0 +1,99 @@
;; -*- no-byte-compile: t; -*-
;;; core/test/autoload-buffers.el
(defmacro -with-temp-buffers! (buffer-args &rest body)
(declare (indent defun))
(let (buffers)
(dolist (bsym buffer-args)
(push `(,bsym (get-buffer-create ,(symbol-name bsym)))
buffers))
`(let* (,@buffers
(buffer-list (list ,@(reverse (mapcar #'car buffers)))))
,@body
(mapc #'kill-buffer buffer-list))))
;;
(def-test! get-buffers
(-with-temp-buffers! (a b c)
(should (cl-every #'buffer-live-p buffer-list))
(should (equal buffer-list (list a b c)))
(dolist (buf (list (cons a doom-emacs-dir)
(cons b doom-emacs-dir)
(cons c "/tmp/")))
(with-current-buffer (car buf)
(setq-local default-directory (cdr buf))))
(with-current-buffer a
;; should produce all buffers
(let ((buffers (doom-buffer-list)))
(should (cl-every (lambda (x) (memq x buffers)) (list a b c))))
;; should produce only project buffers
(let ((buffers (doom-buffer-list t)))
(should (cl-every (lambda (x) (memq x buffers)) (list a b)))
(should-not (memq c buffers))))
;; If no project is available, just get all buffers
(with-current-buffer c
(let ((buffers (doom-buffer-list t)))
(should (cl-every (lambda (x) (memq x buffers)) (list a b c)))))))
(def-test! get-real-buffers
(-with-temp-buffers! (a b c d)
(dolist (buf (list a b))
(with-current-buffer buf
(setq-local buffer-file-name "x")))
(with-current-buffer c
(rename-buffer "*C*"))
(with-current-buffer d
(doom-popup-mode +1))
(let ((buffers (doom-real-buffers-list buffer-list)))
(should (= (length buffers) 2))
(should (cl-every (lambda (x) (memq x buffers)) (list a b)))
(should (cl-notany (lambda (x) (memq x buffers)) (list c d))))))
(def-test! kill-buffers
(-with-temp-buffers! (a b)
(doom-kill-buffer a)
(should-not (buffer-live-p a))
;; modified buffer
(with-current-buffer b
(set-buffer-modified-p t))
(doom-kill-buffer b t)
(should-not (buffer-live-p a))))
(def-test! kill-buffer-then-show-real-buffer
(-with-temp-buffers! (a b c d)
(dolist (buf (list a b d))
(with-current-buffer buf
(setq-local buffer-file-name "x")))
(should (cl-every #'buffer-live-p buffer-list))
(switch-to-buffer a)
(should (eq (current-buffer) a))
(should (eq (selected-window) (get-buffer-window a)))
(should (doom-kill-buffer a))
(should (eq (current-buffer) b))
(should (doom-kill-buffer))
(should (eq (current-buffer) d))
(doom/kill-this-buffer)
(should (eq (current-buffer) (doom-fallback-buffer)))))
(def-test! matching-buffers
(-with-temp-buffers! (a b c)
(let ((buffers (doom-matching-buffers "^[ac]$")))
(should (= 2 (length buffers)))
(should (cl-every #'bufferp buffers))
(should (cl-every (lambda (x) (memq x buffers)) (list a c)))
(should (equal (reverse buffers)
(doom-matching-buffers "^[ac]$" buffer-list))))))
(def-test! buffers-in-mode
(-with-temp-buffers! (a b c d e)
(dolist (buf (list a b))
(with-current-buffer buf
(emacs-lisp-mode)))
(dolist (buf (list c d e))
(with-current-buffer buf
(text-mode)))
(let ((el-buffers (doom-buffers-in-mode 'emacs-lisp-mode))
(txt-buffers (doom-buffers-in-mode 'text-mode)))
(should (cl-every #'buffer-live-p (append el-buffers txt-buffers)))
(should (= 2 (length el-buffers)))
(should (= 3 (length txt-buffers))))))

View file

@ -0,0 +1,19 @@
;; -*- no-byte-compile: t; -*-
;;; core/test/autoload-debug.el
(def-test! what-face
(with-temp-buffer
(insert (propertize "Hello " 'face 'font-lock-keyword-face))
(insert "world")
(should (equal (doom/what-face (point-min)) '((font-lock-keyword-face) ())))
(should-not (doom/what-face (point-max)))))
(def-test! what-face-overlays
(with-temp-buffer
(insert "Hello world")
(let ((ov (make-overlay 1 6)))
(overlay-put ov 'face 'font-lock-keyword-face))
(should (equal (doom/what-face (point-min)) '(() (font-lock-keyword-face))))
(should-not (doom/what-face (point-max)))))

View file

@ -0,0 +1,41 @@
;; -*- no-byte-compile: t; -*-
;;; core/test/autoload-message.el
;; ansi messages
(def-test! ansi-format
(let ((noninteractive t))
(should (equal (format! "Hello %s" "World")
"Hello World"))
(should (equal (format! (red "Hello %s" "World"))
"Hello World"))
(should (equal (format! (green "Hello %s" "World"))
(format "\e[%dm%s\e[0m"
(cdr (assq 'green doom-message-fg))
"Hello World")))
(should (equal (format! (on-red "Hello %s" "World"))
(format "\e[%dm%s\e[0m"
(cdr (assq 'on-red doom-message-bg))
"Hello World")))
(should (equal (format! (bold "Hello %s" "World"))
(format "\e[%dm%s\e[0m"
(cdr (assq 'bold doom-message-fx))
"Hello World")))))
(def-test! ansi-format-nested
(let ((noninteractive t))
(should (equal (format! (bold (red "Hello %s" "World")))
(format "\e[%dm%s\e[0m" 1
(format "\e[%dm%s\e[0m" 31 "Hello World"))))
(should (equal (format! (on-red (bold "Hello %s" "World")))
(format "\e[%dm%s\e[0m" 41
(format "\e[%dm%s\e[0m" 1 "Hello World"))))
(should (equal (format! (dark (white "Hello %s" "World")))
(format "\e[%dm%s\e[0m" 2
(format "\e[%dm%s\e[0m" 37 "Hello World"))))))
(def-test! ansi-format-apply
(let ((noninteractive t))
(should (equal (format! (color 'red "Hello %s" "World"))
(format! (red "Hello %s" "World"))))
(should (equal (format! (color (if nil 'red 'blue) "Hello %s" "World"))
(format! (blue "Hello %s" "World"))))))

View file

@ -0,0 +1,75 @@
;; -*- no-byte-compile: t; -*-
;;; core/test/autoload-package.el
(defun -new-package (name version &optional reqs)
(package-desc-create :name name :version version :reqs reqs))
(defmacro -with-temp-packages! (&rest forms)
"Run FORMS in the context of a temporary package setup (as in, it won't
affects your Emacs packages)."
`(let* ((doom-local-dir ,(expand-file-name "test/.local/" doom-emacs-dir))
(doom-packages-dir (concat doom-local-dir "packages/"))
(doom-etc-dir (concat doom-local-dir "etc/"))
(doom-cache-dir (concat doom-local-dir "cache/"))
(package-user-dir (expand-file-name "elpa" doom-packages-dir))
package-alist
package-archive-contents
package-initialize)
(package-initialize)
,@forms))
;;
;; Tests
;;
(def-test! backend-detection
(let ((package-alist `((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234)))))
(quelpa-cache '((doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")))
(quelpa-initialized-p t))
(should (eq (doom-package-backend 'doom-dummy) 'elpa))
(should (eq (doom-package-backend 'doom-quelpa-dummy) 'quelpa))))
(def-test! elpa-outdated-detection
(cl-letf (((symbol-function 'package-refresh-contents) (lambda (&rest _))))
(let* ((doom--last-refresh (current-time))
(package-alist
`((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234)))))
(package-archive-contents
`((doom-dummy ,(-new-package 'doom-dummy '(20170405 1234)))))
(outdated (doom-package-outdated-p 'doom-dummy)))
(should outdated)
(should (equal outdated '(doom-dummy (20160405 1234) (20170405 1234)))))))
;; TODO quelpa-outdated-detection
(def-test! get-packages
(let ((quelpa-initialized-p t)
(doom-packages '((doom-dummy)))
(package-alist
`((doom-dummy nil)
(doom-dummy-dep nil)))
doom-core-packages)
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _))))
(should (equal (doom-get-packages) '((doom-dummy)))))))
(def-test! orphaned-packages
"Test `doom-get-orphaned-packages', which gets a list of packages that are
no longer enabled or depended on."
(let ((doom-packages '((doom-dummy)))
(package-alist
`((doom-dummy ,(-new-package 'doom-dummy '(20160405 1234) '((doom-dummy-dep (1 0)))))
(doom-dummy-unwanted ,(-new-package 'doom-dummy-unwanted '(20160601 1234)))
(doom-dummy-dep ,(-new-package 'doom-dummy-dep '(20160301 1234)))))
doom-core-packages)
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _))))
(should (equal (doom-get-orphaned-packages) '(doom-dummy-unwanted))))))
(def-test! missing-packages
"Test `doom-get-missing-packages, which gets a list of enabled packages that
aren't installed."
(let ((doom-packages '((doom-dummy) (doom-dummy-installed)))
(package-alist `((doom-dummy-installed ,(-new-package 'doom-dummy-installed '(20160405 1234)))))
doom-core-packages)
(cl-letf (((symbol-function 'doom-initialize-packages) (lambda (&rest _))))
(should (equal (doom-get-missing-packages) '((doom-dummy)))))))

81
core/test/core-lib.el Normal file
View file

@ -0,0 +1,81 @@
;; -*- no-byte-compile: t; -*-
;;; core/test/core-lib.el
;; `add-hook!'
(def-test! add-one-to-one-hook
(let (hooks)
(add-hook! 'hooks 'a-hook)
(should (equal hooks '(a-hook)))))
(def-test! add-many-to-one-hook
(let (hooks)
(add-hook! 'hooks '(hook-a hook-b hook-c))
(should (equal hooks '(hook-c hook-b hook-a)))))
(def-test! add-one-to-many-hooks
(let (hooks-a hooks-b hooks-c)
(add-hook! '(hooks-a hooks-b hooks-c) 'a-hook)
(should (equal hooks-a '(a-hook)))
(should (equal hooks-b '(a-hook)))
(should (equal hooks-c '(a-hook)))))
(def-test! add-many-to-many-hooks
(let (hooks-a hooks-b hooks-c)
(add-hook! '(hooks-a hooks-b hooks-c) '(hook-a hook-b hook-c))
(should (equal hooks-a '(hook-c hook-b hook-a)))
(should (equal hooks-b '(hook-c hook-b hook-a)))
(should (equal hooks-c '(hook-c hook-b hook-a)))))
(def-test! add-non-literal-hooks
(let (some-mode-hook)
(add-hook! some-mode 'a-hook)
(should (equal some-mode-hook '(a-hook)))))
;; `remove-hook!'
(def-test! remove-hooks
(let ((hooks-a '(hook-c hook-b hook-a))
(hooks-b '(hook-c hook-b hook-a))
(hooks-c '(hook-c hook-b hook-a)))
(remove-hook! '(hooks-a hooks-b hooks-c) '(hook-a hook-b hook-c))
(should (null hooks-a))
(should (null hooks-b))
(should (null hooks-c))))
(def-test! remove-hook-forms
(let (hooks)
(add-hook! 'hooks (message "Hello world"))
(should hooks)
(remove-hook! 'hooks (message "Hello world"))
(should (null hooks))))
;; `add-transient-hook!'
(def-test! transient-hooks
(let (hooks value)
(add-transient-hook! 'hooks (setq value t))
(run-hooks 'hooks)
(should (eq value t))
(should (null hooks))))
(def-test! transient-function
(let (value)
(add-transient-hook! #'ignore (setq value (not value)))
(ignore t)
(should (eq value t))
;; repeat to ensure it was only run once
(ignore t)
(should (eq value t))))
(def-test! unquote
(should (equal (doom-unquote '(quote (a b c))) '(a b c)))
;; nested
(should (equal (doom-unquote '(quote (quote (a b c)))) '(a b c)))
;; sub-quote
(should (equal (doom-unquote '(quote (a (quote b) c))) '(a (quote b) c))))
(def-test! enlist
(should (equal (doom-enlist 'a) '(a)))
(should (equal (doom-enlist '(a)) '(a))))
;; TODO `associate!'
;; TODO `def-setting!' & `set!'