Update all unit tests

To meet changes introduced from the straight branch merge.
This commit is contained in:
Henrik Lissner 2019-09-03 00:41:03 -04:00
parent 52b6c51914
commit 059ede53b6
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
20 changed files with 728 additions and 426 deletions

View file

@ -10,9 +10,6 @@ before_install:
- export PATH="/home/travis/.evm/bin:$PATH" - export PATH="/home/travis/.evm/bin:$PATH"
- evm config path /tmp - evm config path /tmp
- evm install $EVM_EMACS --use --skip - evm install $EVM_EMACS --use --skip
- mkdir -p ~/.config/doom
- cp init.test.el ~/.config/doom/init.el
- bin/doom -y -i install
env: env:
- EVM_EMACS=emacs-25.3-travis - EVM_EMACS=emacs-25.3-travis
- EVM_EMACS=emacs-26.1-travis - EVM_EMACS=emacs-26.1-travis

View file

@ -1,5 +1,12 @@
;;; core/cli/test.el -*- lexical-binding: t; -*- ;;; core/cli/test.el -*- lexical-binding: t; -*-
(defun doom--emacs-binary ()
(let ((emacs-binary-path (doom-path invocation-directory invocation-name))
(runemacs-binary-path (if IS-WINDOWS (doom-path invocation-directory "runemacs.exe"))))
(if (and runemacs-binary-path (file-exists-p runemacs-binary-path))
runemacs-binary-path
emacs-binary-path)))
(defcli! test (&rest targets) (defcli! test (&rest targets)
"Run Doom unit tests." "Run Doom unit tests."
(let (files error) (let (files error)
@ -14,6 +21,7 @@
(cdr (doom-module-load-path))))))) (cdr (doom-module-load-path)))))))
(while targets (while targets
(let ((target (pop targets))) (let ((target (pop targets)))
;; FIXME Module targets don't work
(cond ((equal target ":core") (cond ((equal target ":core")
(appendq! files (nreverse (doom-glob doom-core-dir "test/test-*.el")))) (appendq! files (nreverse (doom-glob doom-core-dir "test/test-*.el"))))
((file-directory-p target) ((file-directory-p target)
@ -21,14 +29,13 @@
(appendq! files (nreverse (doom-glob target "test/test-*.el")))) (appendq! files (nreverse (doom-glob target "test/test-*.el"))))
((file-exists-p target) ((file-exists-p target)
(push target files))))) (push target files)))))
(require 'restart-emacs)
(with-temp-buffer (with-temp-buffer
(setenv "DOOMDIR" (concat doom-core-dir "test/")) (setenv "DOOMDIR" (concat doom-core-dir "test/"))
(setenv "DOOMLOCALDIR" (concat doom-local-dir "test/")) (setenv "DOOMLOCALDIR" (concat doom-local-dir "test/"))
(print! (start "Bootstrapping test environment, if necessary...")) (print! (start "Bootstrapping test environment, if necessary..."))
(if (zerop (if (zerop
(call-process (call-process
(restart-emacs--get-emacs-binary) (doom--emacs-binary)
nil t nil "--batch" nil t nil "--batch"
"-l" (concat doom-core-dir "core.el") "-l" (concat doom-core-dir "core.el")
"--eval" (prin1-to-string "--eval" (prin1-to-string
@ -49,18 +56,20 @@
(with-temp-buffer (with-temp-buffer
(unless (unless
(zerop (zerop
(call-process (apply #'call-process
(restart-emacs--get-emacs-binary) (doom--emacs-binary)
nil t nil "--batch" nil t nil "--batch"
"-l" (concat doom-core-dir "core.el") (append (list
"-l" (concat doom-core-dir "test/helpers.el") "-l" (concat doom-core-dir "core.el")
"--eval" (prin1-to-string `(doom-initialize 'force)) "-l" (concat doom-core-dir "test/helpers.el"))
"-l" "buttercup" (when (file-in-directory-p file doom-modules-dir)
"-l" file (list "-f" "doom-initialize-core"))
"-f" "buttercup-run")) (list
"-l" file
"-f" "buttercup-run"))))
(setq error t)) (setq error t))
(message "%s" (buffer-string))) (message "%s" (buffer-string)))
(print! (info "Ignoring %s" (relpath file))))) (print! (info "Ignoring %s" (relpath file)))))
(if error (if error
(error "A test failed") (user-error "A test failed")
t))) t)))

View file

@ -493,7 +493,7 @@ CATEGORY is a keyword, MODULE is a symbol and FLAGS are symbols.
This is for testing and internal use. This is not the correct way to enable a This is for testing and internal use. This is not the correct way to enable a
module." module."
`(let ((doom-modules ,doom-modules) `(let ((doom-modules (or ,doom-modules (doom-modules)))
(module-path (doom-module-locate-path ,category ',module))) (module-path (doom-module-locate-path ,category ',module)))
(doom-module-set (doom-module-set
,category ',module ,category ',module

View file

@ -1,6 +1,64 @@
;; -*- no-byte-compile: t; -*- ;; -*- lexical-binding: t; no-byte-compile: t; -*-
;;; core/test/helpers.el ;;; core/test/helpers.el
(eval-and-compile
(setq doom-interactive-mode 'test)
(doom-initialize 'force)
(require 'buttercup)
(setq split-width-threshold 0
split-height-threshold 0
window-min-width 0
window-min-height 0))
;;
;;; Buttercup extensions
(buttercup-define-matcher :to-expand-into (form expected)
(cl-destructuring-bind (form expected)
(mapcar #'funcall (list form expected))
(let ((expanded (macroexpand-1 form)))
(if (equal expanded expected)
(cons t (format "Expected `%S' to not expand to `%S'"
form expected))
(cons nil (format "Expected `%S' to not expand to `%S', but got `%S' instead"
form expected expanded))))))
(buttercup-define-matcher :to-output (form &optional expected-output)
(let ((expected-output (and (functionp expected-output)
(funcall expected-output)))
output)
(with-current-buffer (get-buffer "*Messages*")
(let ((standard-output (current-buffer))
(start (point)))
(let ((inhibit-message t))
(funcall form))
(setq output (buffer-substring-no-properties start (point-max)))
(with-silent-modifications (erase-buffer))))
(cond ((null expected-output)
(if (string-empty-p output)
(cons nil (format "Expected output %S, but got none"
expected-output))
(cons t (format "Expected no output, but got %S"
output))))
((not (equal expected-output output))
(cons nil (format "Expected output %S, but got %S instead"
expected-output output)))
((cons t (format "Expected to not get %S as output"
expected-output))))))
(buttercup-define-matcher :to-contain-items (items expected)
(cl-destructuring-bind (items expected)
(mapcar #'funcall (list items expected))
(if-let (missing (cl-set-difference expected items))
(cons nil (format "Expected list to contain %S, but it was missing %S"
expected missing))
(cons t (format "Expected list to not contain %S, but it did: %S"
expected items)))))
;;
;;; Helper macros
(defmacro insert!! (&rest text) (defmacro insert!! (&rest text)
"Insert TEXT in buffer, then move cursor to last {0} marker." "Insert TEXT in buffer, then move cursor to last {0} marker."
`(progn `(progn

View file

@ -1,16 +1,12 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; core/test/test-autoload-buffers.el ;;; core/test/test-autoload-buffers.el
(require 'core-projects)
(load! "autoload/buffers" doom-core-dir)
;;
(describe "core/autoload/buffers" (describe "core/autoload/buffers"
:var (a b c d) :var (a b c d)
(before-all
(spy-on 'buffer-list :and-call-fake (require 'core-projects)
(lambda (&optional _) (load! "autoload/buffers" doom-core-dir)
(cl-remove-if-not #'buffer-live-p (list a b c d)))))
(before-each (before-each
(delete-other-windows) (delete-other-windows)
(setq a (switch-to-buffer (get-buffer-create "a")) (setq a (switch-to-buffer (get-buffer-create "a"))
@ -25,7 +21,7 @@
(describe "buffer-list" (describe "buffer-list"
(it "should only see four buffers" (it "should only see four buffers"
(expect (doom-buffer-list) :to-have-same-items-as (list a b c d)))) (expect (doom-buffer-list) :to-contain-items (list a b c d))))
(describe "project-buffer-list" (describe "project-buffer-list"
:var (projectile-projects-cache-time projectile-projects-cache) :var (projectile-projects-cache-time projectile-projects-cache)
@ -34,7 +30,7 @@
(before-each (before-each
(with-current-buffer a (setq default-directory doom-emacs-dir)) (with-current-buffer a (setq default-directory doom-emacs-dir))
(with-current-buffer b (setq default-directory doom-emacs-dir)) (with-current-buffer b (setq default-directory doom-core-dir))
(with-current-buffer c (setq default-directory "/tmp/")) (with-current-buffer c (setq default-directory "/tmp/"))
(with-current-buffer d (setq default-directory "~")) (with-current-buffer d (setq default-directory "~"))
(projectile-mode +1)) (projectile-mode +1))
@ -44,7 +40,7 @@
(it "returns buffers in the same project" (it "returns buffers in the same project"
(with-current-buffer a (with-current-buffer a
(expect (doom-project-buffer-list) (expect (doom-project-buffer-list)
:to-have-same-items-as (list a b)))) :to-contain-items (list a b))))
(it "returns all buffers if not in a project" (it "returns all buffers if not in a project"
(with-current-buffer c (with-current-buffer c
@ -53,7 +49,10 @@
(describe "fallback-buffer" (describe "fallback-buffer"
(it "returns a live buffer" (it "returns a live buffer"
(expect (buffer-live-p (doom-fallback-buffer))))) (expect (buffer-live-p (doom-fallback-buffer))))
(it "returns the scratch buffer"
(expect (doom-fallback-buffer) :to-equal (get-buffer "*scratch*"))))
(describe "real buffers" (describe "real buffers"
(before-each (before-each
@ -72,7 +71,7 @@
(describe "real-buffer-list" (describe "real-buffer-list"
(it "returns only real buffers" (it "returns only real buffers"
(expect (doom-real-buffer-list) :to-have-same-items-as (list a b))))) (expect (doom-real-buffer-list) :to-contain-items (list a b)))))
(describe "buffer/window management" (describe "buffer/window management"
(describe "buffer search methods" (describe "buffer search methods"
@ -85,14 +84,17 @@
(it "can match buffers by regexp" (it "can match buffers by regexp"
(expect (doom-matching-buffers "^[ac]$") :to-have-same-items-as (list a c))) (expect (doom-matching-buffers "^[ac]$") :to-have-same-items-as (list a c)))
(it "can match buffers by major-mode" (it "can match buffers by major-mode"
(expect (doom-buffers-in-mode 'text-mode) :to-have-same-items-as (list b c))) (expect (doom-buffers-in-mode 'text-mode) :to-have-same-items-as (list b c)))
(it "can find all buried buffers" (it "can find all buried buffers"
(expect (doom-buried-buffers) (expect (doom-buried-buffers) :to-contain-items (list c d)))
:to-have-same-items-as (list c d)))
(it "can find all visible buffers" (it "can find all visible buffers"
(expect (doom-visible-buffers) (expect (doom-visible-buffers)
:to-have-same-items-as (list a b))) :to-have-same-items-as (list a b)))
(it "can find all visible windows" (it "can find all visible windows"
(expect (doom-visible-windows) (expect (doom-visible-windows)
:to-have-same-items-as :to-have-same-items-as
@ -109,7 +111,7 @@
(expect (length (doom-visible-windows)) :to-be 1))) (expect (length (doom-visible-windows)) :to-be 1)))
;; TODO ;; TODO
(describe "kill-all-buffers") (xdescribe "kill-all-buffers")
(describe "kill-other-buffers") (xdescribe "kill-other-buffers")
(describe "kill-matching-buffers") (xdescribe "kill-matching-buffers")
(describe "cleanup-session"))) (xdescribe "cleanup-session")))

View file

@ -1,54 +1,152 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; core/test/test-autoload-files.el ;;; core/test/test-autoload-files.el
;;;
(require 'core-projects)
(require 'projectile)
(describe "core/autoload/files" (describe "core/autoload/files"
:var (src dest projectile-projects-cache-time projectile-projects-cache)
(before-each
(setq src (make-temp-file "test-src")
existing (make-temp-file "test-existing")
dest (expand-file-name "test-dest" temporary-file-directory))
(quiet! (find-file-literally src))
(spy-on 'y-or-n-p :and-return-value nil)
(projectile-mode +1))
(after-each (load! "autoload/files" doom-core-dir)
(projectile-mode -1)
(switch-to-buffer (doom-fallback-buffer))
(ignore-errors (delete-file src))
(ignore-errors (delete-file existing))
(ignore-errors (delete-file dest)))
(describe "move-this-file" (xdescribe "doom-glob")
(it "won't move to itself" (xdescribe "doom-path")
(expect (quiet! (doom/move-this-file src)) :to-throw)) (xdescribe "doom-dir")
(it "will move to another file" (xdescribe "doom-files-in")
(expect (quiet! (doom/move-this-file dest t)))
(expect (file-exists-p dest))
(expect (file-exists-p src) :to-be nil))
(it "will prompt if overwriting a file"
(quiet! (doom/move-this-file existing))
(expect 'y-or-n-p :to-have-been-called-times 1)
(expect (file-exists-p src))))
(describe "copy-this-file" (describe "library"
(it "refuses to copy to itself" (describe "file-exists-p!"
(expect (quiet! (doom/copy-this-file src)) :to-throw)) (it "is a (quasi) drop-in replacement for `file-exists-p'"
(it "copies to another file" (let ((default-directory doom-emacs-dir)
(expect (quiet! (doom/copy-this-file dest t))) (init-file "init.el"))
(expect (file-exists-p! src dest))) (expect (file-exists-p "init.el"))
(it "prompts if overwriting a file" (expect (and (file-exists-p! "init.el")
(quiet! (doom/copy-this-file existing)) (file-exists-p "init.el")))
(expect 'y-or-n-p :to-have-been-called-times 1))) (expect (and (file-exists-p! init-file)
(file-exists-p init-file)))
(expect (and (file-exists-p! doom-emacs-dir)
(file-exists-p doom-emacs-dir)))
(expect (and (not (file-exists-p! "/cant/possibly/exist/please/dont/exist"))
(not (file-exists-p "/cant/possibly/exist/please/dont/exist"))))))
(describe "delete-this-file" (it "returns the file path if it exists"
(it "fails gracefully on non-existent files" (expect (file-exists-p! "init.example.el"
(expect (quiet! (doom/delete-this-file dest)) :to-throw)) doom-emacs-dir)
(it "deletes existing files" :to-equal (expand-file-name "init.example.el" doom-emacs-dir)))
(quiet! (doom/delete-this-file existing t))
(expect (file-exists-p existing) :to-be nil)) (it "understands compound statements"
(it "prompts to delete any existing file" (let ((default-directory doom-emacs-dir))
(quiet! (doom/delete-this-file existing)) (expect (file-exists-p! (and "init.el" "init.example.el")))
(expect 'y-or-n-p :to-have-been-called-times 1)))) (expect (file-exists-p! (or "doesnotexist" "init.example.el")))
(expect (not (file-exists-p! (or "doesnotexist" "DOESNOTEXIST")))))
(expect (file-exists-p! (and "init.el" "init.example.el")
doom-emacs-dir))
(expect (file-exists-p! (and "init.el" "init.example.el")
doom-emacs-dir))
(expect (file-exists-p! (or "doesnotexist" "init.example.el")
doom-emacs-dir))
(expect (not (file-exists-p! (or "doesnotexist" "DOESNOTEXIST")
doom-emacs-dir))))
(it "understands nested compound statements"
(expect (file-exists-p! (and "init.el" "init.example.el"
(or "doesnotexist" "LICENSE"))
doom-emacs-dir))
(expect (file-exists-p! (and "init.el" "init.example.el"
(and "LICENSE" "README.md"
(or "doesnotexist"
"early-init.el")))
doom-emacs-dir))
(expect (file-exists-p! (and "init.el" "init.example.el"
(or "edoesnotexist" "DOESNOTEXIST"
(and "idontexist"
"doanyofusexist?")))
doom-emacs-dir)
:to-be nil))
(it "returns the last form if a compound file check succeeds"
(expect (file-exists-p! (and "init.el" "init.example.el"
(or "doesnotexist" "LICENSE"))
doom-emacs-dir)
:to-equal (expand-file-name "LICENSE" doom-emacs-dir))
(expect (file-exists-p! (and "init.el" "init.example.el"
(or (or "doesnotexist" "DOESNOTEXIST")
"doanyofusreallyexist"
(or "cantexist" "LICENSE")))
doom-emacs-dir)
:to-equal (expand-file-name "LICENSE" doom-emacs-dir)))
(it "disregards the directory argument if given absolute path"
(expect (file-exists-p! "/tmp" "/directory/that/doesnt/exist"))
(expect (file-exists-p! doom-core-dir "/directory/that/doesnt/exist"))
(expect (file-exists-p! (and "/tmp" doom-core-dir) "/directory/that/doesnt/exist"))
(expect (file-exists-p! (or "/tmp" doom-core-dir) "/directory/that/doesnt/exist")))
(it "interpolates variables"
(let ((file-1 "init.el")
(file-2 "init.example.el")
(file-3 "LICENSE")
(file-404 "doesnotexistlikenoreally"))
(expect (file-exists-p! file-1 doom-emacs-dir))
(expect (file-exists-p! (and file-1 file-2) doom-emacs-dir))
(expect (file-exists-p! (and file-1 (or file-404 file-2)) doom-emacs-dir))
(expect (file-exists-p! (or (and file-404 file-2) (and file-3 file-1))
doom-emacs-dir))))
(it "interpolates forms"
(cl-letf (((symbol-function 'getfilename)
(lambda () "init.example.el")))
(expect (file-exists-p! (and (or (if nil "init.el" "doesnotexist")
(getfilename))
"LICENSE")
doom-emacs-dir)
:to-equal (expand-file-name "LICENSE" doom-emacs-dir))))))
(describe "interactive file operations"
:var (src dest projectile-projects-cache-time projectile-projects-cache)
(require 'core-projects)
(require 'projectile)
(before-each
(setq src (make-temp-file "test-src")
existing (make-temp-file "test-existing")
dest (expand-file-name "test-dest" temporary-file-directory))
(quiet! (find-file-literally src))
(spy-on 'y-or-n-p :and-return-value nil)
(projectile-mode +1))
(after-each
(projectile-mode -1)
(switch-to-buffer (doom-fallback-buffer))
(ignore-errors (delete-file src))
(ignore-errors (delete-file existing))
(ignore-errors (delete-file dest)))
(describe "move-this-file"
(it "won't move to itself"
(expect (quiet! (doom/move-this-file src)) :to-throw))
(it "will move to another file"
(expect (quiet! (doom/move-this-file dest t)))
(expect (file-exists-p dest))
(expect (file-exists-p src) :to-be nil))
(it "will prompt if overwriting a file"
(quiet! (doom/move-this-file existing))
(expect 'y-or-n-p :to-have-been-called-times 1)
(expect (file-exists-p src))))
(describe "copy-this-file"
(it "refuses to copy to itself"
(expect (quiet! (doom/copy-this-file src)) :to-throw))
(it "copies to another file"
(expect (quiet! (doom/copy-this-file dest t)))
(expect (file-exists-p! src dest)))
(it "prompts if overwriting a file"
(quiet! (doom/copy-this-file existing))
(expect 'y-or-n-p :to-have-been-called-times 1)))
(describe "delete-this-file"
(it "fails gracefully on non-existent files"
(expect (quiet! (doom/delete-this-file dest)) :to-throw))
(it "deletes existing files"
(quiet! (doom/delete-this-file existing t))
(expect (file-exists-p existing) :to-be nil))
(it "prompts to delete any existing file"
(quiet! (doom/delete-this-file existing))
(expect 'y-or-n-p :to-have-been-called-times 1)))))

View file

@ -1,11 +1,11 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; core/test/test-autoload-message.el ;;; core/test/test-autoload-message.el
(describe "core/autoload/message" (describe "core/autoload/format"
(describe "format!" (describe "format!"
:var (doom-message-backend) :var (doom-format-backend)
(before-all (before-all
(setq doom-message-backend 'ansi)) (setq doom-format-backend 'ansi))
(it "should be a drop-in replacement for `format'" (it "should be a drop-in replacement for `format'"
(expect (format! "Hello %s" "World") (expect (format! "Hello %s" "World")
@ -16,7 +16,7 @@
:to-equal "Hello World")) :to-equal "Hello World"))
(it "supports text properties in interactive sessions" (it "supports text properties in interactive sessions"
(let ((doom-message-backend 'text-properties)) (let ((doom-format-backend 'text-properties))
(expect (get-text-property 0 'face (format! (red "Hello %s") "World")) (expect (get-text-property 0 'face (format! (red "Hello %s") "World"))
:to-equal (list :foreground (face-foreground 'term-color-red))))) :to-equal (list :foreground (face-foreground 'term-color-red)))))
@ -35,4 +35,10 @@
(expect (format! (color 'red "Hello %s") "World") (expect (format! (color 'red "Hello %s") "World")
:to-equal (format! (red "Hello %s") "World")) :to-equal (format! (red "Hello %s") "World"))
(expect (format! (color (if nil 'red 'blue) "Hello %s") "World") (expect (format! (color (if nil 'red 'blue) "Hello %s") "World")
:to-equal (format! (blue "Hello %s") "World"))))) :to-equal (format! (blue "Hello %s") "World"))))
(xdescribe "insert!")
(xdescribe "print!")
(xdescribe "print-group!")
(xdescribe "error!")
(xdescribe "user-error!"))

View file

@ -1,10 +0,0 @@
;; -*- no-byte-compile: t; -*-
;;; core/test/test-autoload-help.el
;; (load! "autoload/help" doom-core-dir)
;;
;; (describe "core/autoload/help"
;; :var (a)
;; (before-each (setq a (switch-to-buffer (get-buffer-create "a"))))
;; (after-each (kill-buffer a)))

View file

@ -1,138 +1,5 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; core/test/test-autoload-package.el ;;; core/test/test-autoload-package.el
;;;###if nil
(describe "core/autoload/packages" (xdescribe "core/autoload/packages")
:var (package-alist
package-archive-contents
package-selected-packages
doom-packages
quelpa-cache
quelpa-initialized-p
doom-packages-dir
doom-core-packages
package-user-dir
quelpa-dir
pkg)
(before-all
(fset 'pkg
(lambda (name version &optional reqs)
(package-desc-create
:name name :version version :reqs reqs
:dir (expand-file-name (format "%s/" name) package-user-dir))))
(require 'package)
(require 'quelpa)
(setq doom-packages-dir (expand-file-name "packages/" (file-name-directory load-file-name))
package-user-dir (expand-file-name "elpa" doom-packages-dir)
quelpa-dir (expand-file-name "quelpa" doom-packages-dir)
quelpa-initialized-p t
doom-core-packages nil)
(spy-on #'package--user-installed-p :and-call-fake (lambda (_p) t))
(spy-on #'doom-initialize-packages :and-call-fake (lambda (&optional _)))
(spy-on #'package-refresh-contents :and-call-fake (lambda (&optional _)))
(spy-on #'quelpa-checkout :and-call-fake
(lambda (rcp _dir)
(when (eq (car rcp) 'doom-quelpa-dummy)
"20170405.1234"))))
(after-all
(unload-feature 'package t)
(unload-feature 'quelpa t))
(before-each
(setq package-alist
`((doom-dummy ,(pkg 'doom-dummy '(20160405 1234)))
(doom-uptodate-dummy ,(pkg 'doom-uptodate-dummy '(20160605 1234)))
(doom-unwanted-dummy ,(pkg 'doom-unwanted-dummy '(20160605 1234)))
(doom-quelpa-dummy ,(pkg 'doom-quelpa-dummy '(20160405 1234)))
(doom-noquelpa-dummy ,(pkg 'doom-noquelpa-dummy '(20160405 1234))))
package-archive-contents
`((doom-dummy ,(pkg 'doom-dummy '(20170405 1234)))
(doom-uptodate-dummy ,(pkg 'doom-uptodate-dummy '(20160605 1234))))
doom-packages
'((doom-dummy)
(doom-uptodate-dummy)
(doom-missing-dummy)
(doom-noquelpa-dummy)
(doom-disabled-dummy :disable t)
(doom-private-dummy :modules ((:private)))
(doom-disabled-private-dummy :modules ((:private)) :disable t)
(doom-quelpa-dummy :recipe (doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")))
quelpa-cache
'((doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")
(doom-noquelpa-dummy :fetcher github :repo "hlissner/does-not-exist-3")
(doom-new-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist-2"))
package-selected-packages (mapcar #'car doom-packages)))
(describe "package-backend"
(it "determines the correct backend of a package"
(expect (doom-package-backend 'doom-dummy) :to-be 'elpa)
(expect (doom-package-backend 'doom-quelpa-dummy) :to-be 'quelpa)
(expect (doom-package-backend 'org) :to-be 'emacs))
(it "errors out if package isn't installed"
(expect (doom-package-backend 'xyz) :to-throw)))
(describe "package-outdated-p (elpa)"
(it "detects outdated ELPA packages and returns both versions"
(expect (doom-package-outdated-p 'doom-dummy)
:to-equal '(doom-dummy (20160405 1234) (20170405 1234))))
(it "ignores up-to-date ELPA packages"
(expect (doom-package-outdated-p 'doom-uptodate-dummy) :to-be nil))
(it "detects outdated QUELPA packages and returns both versions"
(expect (doom-package-outdated-p 'doom-quelpa-dummy)
:to-equal '(doom-quelpa-dummy (20160405 1234) (20170405 1234))))
(it "ignores up-to-date QUELPA packages"
(expect (doom-package-outdated-p 'doom-uptodate-dummy) :to-be nil))
(it "returns nil if package isn't installed"
(expect (doom-package-outdated-p 'xyz) :to-be nil)))
(describe "get-packages"
(before-all
;; In addition to `package-installed-p', `doom-package-installed-p' does
;; file existence checks which won't work here, so we simplify it
(spy-on #'doom-package-installed-p :and-call-fake #'package-installed-p))
(it "returns all packages"
(expect (mapcar #'car (doom-find-packages))
:to-have-same-items-as
(mapcar #'car doom-packages)))
(it "returns only disabled packages"
(expect (mapcar #'car (doom-find-packages :disabled t))
:to-have-same-items-as
'(doom-disabled-dummy doom-disabled-private-dummy)))
(it "returns only non-disabled packages"
(expect (mapcar #'car (doom-find-packages :disabled nil))
:to-have-same-items-as
'(doom-dummy doom-uptodate-dummy doom-quelpa-dummy doom-missing-dummy doom-noquelpa-dummy doom-private-dummy)))
(it "returns only installed packages"
(expect (mapcar #'car (doom-find-packages :disabled nil :installed t))
:to-have-same-items-as
'(doom-dummy doom-uptodate-dummy doom-quelpa-dummy doom-noquelpa-dummy)))
(it "returns only non-installed packages"
(expect (mapcar #'car (doom-find-packages :disabled nil :installed nil))
:to-have-same-items-as
'(doom-missing-dummy doom-private-dummy)))
(it "returns only private packages"
(expect (mapcar #'car (doom-find-packages :private t))
:to-have-same-items-as
'(doom-private-dummy doom-disabled-private-dummy)))
(it "returns only disabled and private packages"
(expect (mapcar #'car (doom-find-packages :disabled t :private t))
:to-have-same-items-as
'(doom-disabled-private-dummy))))
(describe "get-orphaned-packages"
(it "returns orphaned packages"
(expect (doom-get-orphaned-packages) :to-contain 'doom-unwanted-dummy))
(it "returns packages that have changed backends"
(expect (doom-get-orphaned-packages) :to-contain 'doom-noquelpa-dummy)))
(describe "get-missing-packages"
(it "returns packages that haven't been installed"
(expect (mapcar #'car (doom-get-missing-packages))
:to-contain 'doom-missing-dummy))
(it "returns packages that have changed backends"
(expect (mapcar #'car (doom-get-missing-packages))
:to-contain 'doom-noquelpa-dummy))))

View file

@ -1,40 +1,34 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; core/test/test-core-keybinds.el ;;; core/test/test-core-keybinds.el
(require 'core-keybinds)
(buttercup-define-matcher :to-expand-into (src result)
(let ((src (funcall src))
(result (funcall result)))
(or (equal (macroexpand-1 src) result)
(error "'%s' expanded into '%s' instead of '%s'"
src (macroexpand-1 src) result))))
(describe "core/keybinds" (describe "core/keybinds"
(require 'core-keybinds)
(describe "map!" (describe "map!"
:var (doom--map-evil-p doom-map-states) :var (doom--map-evil-p states-alist)
(before-each (before-each
(setq doom--map-evil-p t (setq doom--map-evil-p t
doom-map-states '((:n . normal) states-alist '((:n . normal)
(:v . visual) (:v . visual)
(:i . insert) (:i . insert)
(:e . emacs) (:e . emacs)
(:o . operator) (:o . operator)
(:m . motion) (:m . motion)
(:r . replace)))) (:r . replace))))
(describe "Single keybinds" (describe "Single keybinds"
(it "binds a global key" (it "binds a global key"
(expect '(map! "C-." #'a) :to-expand-into '(general-define-key "C-." #'a))) (expect '(map! "C-." #'a)
:to-expand-into '(general-define-key "C-." #'a)))
(it "binds a key in one evil state" (it "binds a key in one evil state"
(dolist (state doom-map-states) (dolist (state states-alist)
(expect `(map! ,(car state) "C-." #'a) (expect `(map! ,(car state) "C-." #'a)
:to-expand-into :to-expand-into
`(general-define-key :states ',(cdr state) "C-." #'a)))) `(general-define-key :states ',(cdr state) "C-." #'a))))
(it "binds a key in multiple evil states" (it "binds a key in multiple evil states"
(expect `(map! :nvi "C-." #'a) (expect '(map! :nvi "C-." #'a)
:to-expand-into :to-expand-into
'(progn (general-define-key :states 'insert "C-." #'a) '(progn (general-define-key :states 'insert "C-." #'a)
(general-define-key :states 'visual "C-." #'a) (general-define-key :states 'visual "C-." #'a)
@ -54,7 +48,7 @@
'(general-define-key "C-." #'a "C-," #'b "C-/" #'c))) '(general-define-key "C-." #'a "C-," #'b "C-/" #'c)))
(it "binds multiple keybinds in an evil state and preserve order" (it "binds multiple keybinds in an evil state and preserve order"
(dolist (state doom-map-states) (dolist (state states-alist)
(expect `(map! ,(car state) "a" #'a (expect `(map! ,(car state) "a" #'a
,(car state) "b" #'b ,(car state) "b" #'b
,(car state) "c" #'c) ,(car state) "c" #'c)

View file

@ -1,28 +1,130 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; core/test/test-core-lib.el ;;; core/test/test-core-lib.el
(require 'core-lib) (describe "core-lib"
(before-all
(require 'core-lib))
(describe "core/lib"
;; --- Helpers ---------------------------- ;; --- Helpers ----------------------------
(describe "doom-unquote" (describe "doom-unquote"
(it "unquotes a quoted form" (it "unquotes a quoted form"
(expect (doom-unquote '(quote hello)) :to-be 'hello)) (expect (doom-unquote '(quote hello)) :to-be 'hello))
(it "unquotes nested-quoted forms" (it "unquotes nested quoted forms"
(expect (doom-unquote '(quote (quote (a b c)))) :to-equal '(a b c))) (expect (doom-unquote '(quote (quote (a b c)))) :to-equal '(a b c)))
(it "unquotes function-quoted forms" (it "unquotes function-quoted forms"
(expect (doom-unquote '(function a)) :to-be 'a)) (expect (doom-unquote '(function a)) :to-be 'a))
(it "does nothing to unquoted forms" (it "does nothing to unquoted forms"
(expect (doom-unquote 'hello) :to-be 'hello))) (expect (doom-unquote 'hello) :to-be 'hello)
(expect (doom-unquote 5) :to-be 5)
(expect (doom-unquote t) :to-be t)))
(describe "doom-enlist" (describe "doom-enlist"
(it "returns nil if given nil"
(expect (doom-enlist nil) :to-be nil))
(it "creates a list out of non-lists" (it "creates a list out of non-lists"
(expect (doom-enlist 'a) :to-equal '(a))) (expect (doom-enlist 'a) :to-equal '(a)))
(it "does nothing to lists" (it "returns lists as-is"
(expect (doom-enlist '(a)) :to-equal '(a)))) (expect (doom-enlist '(a)) :to-equal '(a))))
(describe "doom-keyword-intern"
(it "returns a keyword"
(expect (doom-keyword-intern "test") :to-equal :test))
(it "errors if given anything but a string"
(expect (doom-keyword-intern t) :to-throw 'wrong-type-argument)))
(describe "doom-keyword-name"
(it "returns the string name of a keyword"
(expect (doom-keyword-name :test) :to-equal "test"))
(it "errors if given anything but a keyword"
(expect (doom-keyword-name "test") :to-throw 'wrong-type-argument)))
(describe "doom-partial"
(it "returns a closure"
(expect (functionp (doom-partial #'+ 1))))
(it "returns a partial closure"
(expect (funcall (doom-partial #'+ 1) 2) :to-be 3)))
(describe "doom-rpartial"
(it "returns a closure"
(expect (functionp (doom-rpartial #'+ 1))))
(it "returns a partial closure with right-aligned arguments"
(expect (funcall (doom-rpartial #'/ 2) 10) :to-be 5)))
;; --- Sugars -----------------------------
(describe "lambda!"
(it "returns an interactive function"
(expect (commandp (lambda!)))
(expect (funcall (lambda! 5)) :to-equal 5)))
(describe "lambda!!"
(it "returns an interactive function with a prefix argument"
(expect (commandp (lambda! #'ignore t)))
(expect (funcall (lambda!! (lambda (arg)
(interactive "P")
arg)
5))
:to-equal 5)))
(describe "file!"
(it "returns the executing file"
(expect (eval-and-compile (file!))
:to-equal (expand-file-name "test/test-core-lib.el"
doom-core-dir))))
(describe "dir!"
(it "returns the executing directory"
(expect (eval-and-compile (dir!))
:to-equal (expand-file-name "test" doom-core-dir))))
(describe "pushnew!"
(it "pushes values onto a list symbol, in order"
(let ((a '(1 2 3)))
(expect (pushnew! a 9 8 7)
:to-equal '(7 8 9 1 2 3))))
(it "only adds values that aren't already in the list"
(let ((a '(1 symbol 3.14 "test")))
(expect (pushnew! a "test" 'symbol 3.14 1)
:to-equal '(1 symbol 3.14 "test")))))
(describe "prependq!"
(it "prepends a list to a list symbol"
(let ((list '(a b c)))
(expect (prependq! list '(d e f))
:to-equal '(d e f a b c)))))
(describe "append!"
(it "appends a list to a list symbol"
(let ((list '(a b c)))
(expect (appendq! list '(d e f))
:to-equal '(a b c d e f)))))
(describe "nconcq!"
(it "nconc's a list to a list symbol"
(let ((list '(a b c)))
(expect (nconcq! list '(d e f))
:to-equal '(a b c d e f)))))
(describe "delq!"
(it "delete's a symbol from a list"
(let ((list '(a b c)))
(delq! 'b list)
(expect list :to-equal '(a c))))
(it "delete's an element from an alist by key"
(let ((alist '((a 1) (b 2) (c 3))))
(delq! 'b alist 'assq)
(expect alist :to-equal '((a 1) (c 3))))))
(describe "delete!"
(it "delete's a string from a list"
(let ((list '("a" "b" "c")))
(delete! "b" list)
(expect list :to-equal '("a" "c"))))
(it "delete's an element from an alist by key"
(let ((alist '(("a" 1) ("b" 2) ("c" 3))))
(delete! (assoc "b" alist) alist)
(expect alist :to-equal '(("a" 1) ("c" 3))))))
;; --- Macros -----------------------------
(describe "hooks" (describe "hooks"
(describe "add-hook!" (describe "add-hook!"
:var (fake-mode-hook other-mode-hook some-mode-hook) :var (fake-mode-hook other-mode-hook some-mode-hook)
@ -31,15 +133,22 @@
other-mode-hook nil other-mode-hook nil
some-mode-hook '(first-hook second-hook))) some-mode-hook '(first-hook second-hook)))
(it "resolves quoted hooks literally"
(expect '(add-hook! 'fake-mode-hook #'ignore) :to-expand-into
`(add-hook 'fake-mode-hook #'ignore nil nil)))
(it "resolves unquoted modes to their hook variables"
(expect '(add-hook! fake-mode #'ignore) :to-expand-into
`(add-hook 'fake-mode-hook #'ignore nil nil)))
(it "adds one-to-one hook" (it "adds one-to-one hook"
(add-hook! fake-mode #'hook-2) (add-hook! fake-mode #'hook-2)
(add-hook! 'fake-mode-hook #'hook-1) (add-hook! 'fake-mode-hook #'hook-1)
(expect fake-mode-hook :to-equal '(hook-1 hook-2 first-hook))) (expect fake-mode-hook :to-equal '(hook-1 hook-2 first-hook)))
(it "adds many-to-one hook" (it "adds one-to-many hook"
(add-hook! (fake-mode other-mode some-mode) #'hook-2) (add-hook! (fake-mode other-mode some-mode) #'hook-2)
(add-hook! '(fake-mode-hook other-mode-hook some-mode-hook) #'hook-1) (add-hook! '(fake-mode-hook other-mode-hook some-mode-hook) #'hook-1)
(add-hook! :append (fake-mode other-mode some-mode) #'last-hook) (add-hook! (fake-mode other-mode some-mode) :append #'last-hook)
(expect fake-mode-hook :to-equal '(hook-1 hook-2 first-hook last-hook)) (expect fake-mode-hook :to-equal '(hook-1 hook-2 first-hook last-hook))
(expect other-mode-hook :to-equal '(hook-1 hook-2 last-hook)) (expect other-mode-hook :to-equal '(hook-1 hook-2 last-hook))
(expect some-mode-hook :to-equal '(hook-1 hook-2 first-hook second-hook last-hook))) (expect some-mode-hook :to-equal '(hook-1 hook-2 first-hook second-hook last-hook)))
@ -47,7 +156,7 @@
(it "adds many-to-many hooks and preserve provided order" (it "adds many-to-many hooks and preserve provided order"
(add-hook! (fake-mode other-mode some-mode) #'(hook-3 hook-4)) (add-hook! (fake-mode other-mode some-mode) #'(hook-3 hook-4))
(add-hook! '(fake-mode-hook other-mode-hook some-mode-hook) #'(hook-1 hook-2)) (add-hook! '(fake-mode-hook other-mode-hook some-mode-hook) #'(hook-1 hook-2))
(add-hook! :append '(fake-mode-hook other-mode-hook some-mode-hook) #'(last-hook-1 last-hook-2)) (add-hook! '(fake-mode-hook other-mode-hook some-mode-hook) :append #'(last-hook-1 last-hook-2))
(expect fake-mode-hook :to-equal '(hook-1 hook-2 hook-3 hook-4 first-hook last-hook-1 last-hook-2)) (expect fake-mode-hook :to-equal '(hook-1 hook-2 hook-3 hook-4 first-hook last-hook-1 last-hook-2))
(expect other-mode-hook :to-equal '(hook-1 hook-2 hook-3 hook-4 last-hook-1 last-hook-2)) (expect other-mode-hook :to-equal '(hook-1 hook-2 hook-3 hook-4 last-hook-1 last-hook-2))
(expect some-mode-hook :to-equal '(hook-1 hook-2 hook-3 hook-4 first-hook second-hook last-hook-1 last-hook-2))) (expect some-mode-hook :to-equal '(hook-1 hook-2 hook-3 hook-4 first-hook second-hook last-hook-1 last-hook-2)))
@ -55,10 +164,18 @@
(it "adds implicit lambda to one hook" (it "adds implicit lambda to one hook"
(add-hook! fake-mode (progn)) (add-hook! fake-mode (progn))
(add-hook! 'other-mode-hook (ignore)) (add-hook! 'other-mode-hook (ignore))
(add-hook! :append 'some-mode-hook (ignore)) (add-hook! 'some-mode-hook :append (ignore))
(expect (caar fake-mode-hook) :to-be 'lambda) (expect (caar fake-mode-hook) :to-be 'lambda)
(expect (caar other-mode-hook) :to-be 'lambda) (expect (caar other-mode-hook) :to-be 'lambda)
(expect (caar (last other-mode-hook)) :to-be 'lambda))) (expect (caar (last other-mode-hook)) :to-be 'lambda))
(it "handles inline defuns as hook symbols"
(add-hook! fake-mode (defun hook-a ()))
(add-hook! 'other-mode-hook
(defun hook-b ())
(defun hook-c ()))
(expect (car fake-mode-hook) :to-be 'hook-a)
(expect other-mode-hook :to-equal '(hook-b hook-c))))
(describe "remove-hook!" (describe "remove-hook!"
:var (fake-mode-hook) :var (fake-mode-hook)
@ -71,22 +188,92 @@
(it "removes multiple hooks" (it "removes multiple hooks"
(remove-hook! fake-mode #'(first-hook third-hook)) (remove-hook! fake-mode #'(first-hook third-hook))
(remove-hook! 'fake-mode-hook #'(second-hook fourth-hook)) (remove-hook! 'fake-mode-hook #'(second-hook fourth-hook))
(expect fake-mode-hook :to-be nil)))) (expect fake-mode-hook :to-be nil)))
(describe "add-transient-hook!" (describe "add-transient-hook!"
(it "adds a transient function to hooks" (it "adds a transient function to hooks"
(let (hooks value) (let (hooks value)
(add-transient-hook! 'hooks (setq value t)) (add-transient-hook! 'hooks (setq value t))
(run-hooks 'hooks) (run-hooks 'hooks)
(expect value) (expect value)
(expect hooks :to-be nil))) (expect hooks :to-be nil)))
(it "advises a function with a transient advisor" (it "advises a function with a transient advisor"
(let (value) (let (value)
(add-transient-hook! #'ignore (setq value (not value))) (add-transient-hook! #'ignore (setq value (not value)))
(ignore t) (ignore t)
(expect value) (expect value)
;; repeat to ensure it was only run once ;; repeat to ensure it was only run once
(ignore t) (ignore t)
(expect value)))) (expect value))))
(xdescribe "associate!")) ; TODO (describe "(un)setq-hook!"
:var (fake-hook x y z)
(before-each
(setq x 10 y 20 z 30))
(it "sets variables buffer-locally"
(setq-hook! 'fake-hook x 1)
(with-temp-buffer
(run-hooks 'fake-hook)
(expect (local-variable-p 'x))
(expect (= x 1)))
(expect (= x 10)))
(it "overwrites earlier hooks"
(setq-hook! 'fake-hook x 1 y 0)
(setq-hook! 'fake-hook x 5 y -1)
(with-temp-buffer
(run-hooks 'fake-hook)
(expect (= x 5))
(expect (= y -1))))
(it "unset setq hooks"
(setq-hook! 'fake-hook x 1 y 0)
(unsetq-hook! 'fake-hook y)
(with-temp-buffer
(run-hooks 'fake-hook)
(expect (local-variable-p 'x))
(expect (= x 1))
(expect (not (local-variable-p 'y)))
(expect (= y 20))))))
(describe "load!"
(before-each
(spy-on 'load :and-return-value t))
(it "loads a file relative to the current directory"
(load! "path")
(expect 'load :to-have-been-called)
(expect 'load :to-have-been-called-with (expand-file-name "path" (eval-when-compile (dir!))) nil t))
(it "loads a file relative to a specified directory"
(load! "path" doom-etc-dir)
(expect 'load :to-have-been-called-with (expand-file-name "path" doom-etc-dir) nil t)))
(describe "quiet!"
(it "suppresses output from message"
(expect (message "hello world") :to-output "hello world\n")
(expect (message "hello world") :to-output)
(let (doom-interactive-mode)
(expect (quiet! (message "hello world")) :not :to-output))
(let ((doom-interactive-mode t))
(expect (quiet! inhibit-message))
(expect (quiet! save-silently))))
(it "suppresses load messages from `load' & `load-file'"
(let ((tmpfile (make-temp-file "test" nil ".el")))
(with-temp-file tmpfile)
(let (doom-interactive-mode)
(expect (load-file tmpfile) :to-output (format "Loading %s (source)...\n" tmpfile))
(expect (quiet! (load-file tmpfile)) :not :to-output))
(delete-file tmpfile)))
(it "won't suppress output in debug mode"
(let ((doom-debug-mode t)
(tmpfile (make-temp-file "test" nil ".el")))
(dolist (doom-interactive-mode (list t nil))
(expect (quiet! (message "hello world"))
:to-output "hello world\n")
(with-temp-file tmpfile)
(expect (quiet! (load-file tmpfile))
:to-output (format "Loading %s (source)...\n" tmpfile)))))))

View file

@ -1,6 +1,7 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; core/test/test-core-modules.el ;;; core/test/test-core-modules.el
;;;###if nil
;; (require 'core-modules) ;; (require 'core-modules)
(describe "core-modules") (xdescribe "core-modules")

View file

@ -1,4 +1,5 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; core/test/test-core-packages.el ;;; core/test/test-core-packages.el
;;;###if nil
(describe "core-packages") (xdescribe "core-packages")

View file

@ -1,12 +1,17 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; ../core/test/test-core-projects.el ;;; core/test/test-core-projects.el
(require 'core-projects)
(require 'projectile)
(describe "core/projects" (describe "core/projects"
(before-each (projectile-mode +1)) :var (projectile-enable-caching)
(after-each (projectile-mode -1))
(require 'core-projects)
(require 'projectile)
(before-each
(setq projectile-enable-caching nil)
(projectile-mode +1))
(after-each
(projectile-mode -1))
(describe "project-p" (describe "project-p"
(it "Should detect when in a valid project" (it "Should detect when in a valid project"

View file

@ -1,17 +1,106 @@
;; -*- no-byte-compile: t; -*- ;; -*- no-byte-compile: t; -*-
;;; ../core/test/test-core-ui.el ;;; ../core/test/test-core-ui.el
(require 'core-ui)
(describe "core/ui" (describe "core/ui"
(describe "doom|protect-fallback-buffer" (before-all
:var (kill-buffer-query-functions a b) (with-demoted-errors "Import error: %s"
(require 'core-ui)))
(describe "doom-protect-fallback-buffer-h"
:var (kill-buffer-query-functions)
(before-all (before-all
(setq kill-buffer-query-functions '(doom|protect-fallback-buffer))) (setq kill-buffer-query-functions '(doom-protect-fallback-buffer-h)))
(it "should kill other buffers" (it "should kill other buffers"
(expect (kill-buffer (get-buffer-create "a")))) (expect (kill-buffer (get-buffer-create "a"))))
(it "shouldn't kill the fallback buffer" (it "shouldn't kill the fallback buffer"
(expect (not (kill-buffer (doom-fallback-buffer))))))) (expect (not (kill-buffer (doom-fallback-buffer))))))
(describe "custom hooks"
(describe "switch hooks"
:var (before-hook after-hook a b)
(before-each
(setq a (switch-to-buffer (get-buffer-create "a"))
b (get-buffer-create "b"))
(spy-on 'hook)
(add-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
(add-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
(dolist (fn '(switch-to-buffer display-buffer))
(advice-add fn :around #'doom-run-switch-buffer-hooks-a)))
(after-each
(remove-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
(remove-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
(dolist (fn '(switch-to-buffer display-buffer))
(advice-remove fn #'doom-run-switch-buffer-hooks-a))
(kill-buffer a)
(kill-buffer b))
(describe "switch-buffer"
:var (doom-switch-buffer-hook)
(before-each
(setq doom-switch-buffer-hook '(hook)))
(after-each
(setq doom-switch-buffer-hook nil))
(it "should trigger when switching buffers"
(switch-to-buffer b)
(switch-to-buffer a)
(switch-to-buffer b)
(expect 'hook :to-have-been-called-times 3))
(it "should trigger only once on the same buffer"
(switch-to-buffer b)
(switch-to-buffer b)
(switch-to-buffer a)
(expect 'hook :to-have-been-called-times 2)))
(describe "switch-window"
:var (doom-switch-window-hook x y)
(before-each
(delete-other-windows)
(setq x (get-buffer-window a)
y (save-selected-window (split-window)))
(with-selected-window y
(switch-to-buffer b))
(select-window x)
(spy-calls-reset 'hook)
(setq doom-switch-window-hook '(hook)))
(it "should trigger when switching windows"
(select-window y)
(select-window x)
(select-window y)
(expect 'hook :to-have-been-called-times 3))
(it "should trigger only once on the same window"
(select-window y)
(select-window y)
(select-window x)
(expect 'hook :to-have-been-called-times 2)))
(xdescribe "switch-frame"
:var (doom-switch-frame-hook x y)
(before-each
(delete-other-windows)
(setq x (get-buffer-window a)
y (save-selected-window (split-window)))
(with-selected-window y
(switch-to-buffer b))
(select-window x)
(spy-calls-reset 'hook)
(setq doom-switch-window-hook '(hook)))
(it "should trigger when switching windows"
(select-window y)
(select-window x)
(select-window y)
(expect 'hook :to-have-been-called-times 3))
(it "should trigger only once on the same window"
(select-window y)
(select-window y)
(select-window x)
(expect 'hook :to-have-been-called-times 2))))))

View file

@ -2,118 +2,116 @@
;;; core/test/test-core.el ;;; core/test/test-core.el
(describe "core" (describe "core"
(xdescribe "initialize" :var (doom-interactive-mode)
:var (doom-init-p doom-init-modules-p doom-private-dir) (before-each
(before-each (setq doom-interactive-mode nil))
(setq doom-init-p nil
doom-init-modules-p nil
doom-private-dir doom-emacs-dir)
(spy-on 'require) (describe "initialization"
(spy-on 'load) (describe "doom-initialize"
(spy-on 'doom-reload-doom-autoloads) :var (doom-init-p)
(spy-on 'doom-reload-package-autoloads)
(spy-on 'doom-initialize-autoloads)
(spy-on 'doom-ensure-core-directories)
(spy-on 'doom-ensure-core-packages)
(spy-on 'doom-ensure-packages-initialized)
(spy-on 'doom-ensure-same-emacs-version-p))
(describe "in interactive session"
:var (noninteractive)
(before-each (setq noninteractive t))
(it "initializes once, unless forced")
(it "does not initialize on consecutive invokations")
(it "loads all core libraries" )
(it "loads autoloads file" )
(it "does not load autoloads file if forced" )
(it "regenerates missing autoloads" ))
(describe "in non-interactive session"
:var (noninteractive)
(before-each (setq noninteractive nil))
(it "initializes once, unless forced")
(it "does not initialize on consecutive invokations")
(it "does not load all core libraries" )
(it "loads autoloads file" )
(it "does not load autoloads file if forced" )
(it "does not regenerate missing autoloads" )))
(xdescribe "initialize-packages"
(before-each (spy-on 'quelpa-setup-p))
(it "initializes package.el once, unless forced" )
(it "initializes quelpa once, unless forced" )
(it "initializes doom-packages once, unless forced" ))
(xdescribe "initialize-modules"
(it "loads private init.el once, unless forced" ))
(xdescribe "initialize-autoloads"
(it "loads autoloads file" )
(it "ignores autoloads file if cleared" ))
(describe "custom hooks"
(describe "switch hooks"
:var (before-hook after-hook a b)
(before-each (before-each
(setq a (switch-to-buffer (get-buffer-create "a")) (setq doom-init-p nil))
b (get-buffer-create "b"))
(spy-on 'hook)
(add-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
(add-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
(dolist (fn '(switch-to-buffer display-buffer))
(advice-add fn :around #'doom-run-switch-buffer-hooks-a)))
(after-each
(remove-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
(remove-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
(dolist (fn '(switch-to-buffer display-buffer))
(advice-remove fn #'doom-run-switch-buffer-hooks-a))
(kill-buffer a)
(kill-buffer b))
(describe "switch-buffer" (it "initializes once"
:var (doom-switch-buffer-hook) (expect (doom-initialize))
(expect (not (doom-initialize)))
(expect (not (doom-initialize)))
(expect doom-init-p))
(it "initializes multiple times, if forced"
(expect (doom-initialize))
(expect (not (doom-initialize)))
(expect (doom-initialize 'force)))
(describe "package initialization"
(before-each (before-each
(setq doom-switch-buffer-hook '(hook))) (spy-on 'doom-initialize-packages :and-return-value t))
(after-each
(setq doom-switch-buffer-hook nil))
(it "should trigger when switching buffers" (it "initializes packages if core autoload file doesn't exist"
(switch-to-buffer b) (let ((doom-autoload-file "doesnotexist"))
(switch-to-buffer a) (doom-initialize))
(switch-to-buffer b) (expect 'doom-initialize-packages :to-have-been-called))
(expect 'hook :to-have-been-called-times 3))
(it "should trigger only once on the same buffer" (it "doesn't initialize packages if core autoload file was loaded"
(switch-to-buffer b) (let ((doom-interactive-mode t))
(switch-to-buffer b) (spy-on 'doom-load-autoloads-file :and-return-value t)
(switch-to-buffer a) (doom-initialize)
(expect 'hook :to-have-been-called-times 2))) (expect 'doom-load-autoloads-file :to-have-been-called-with doom-package-autoload-file)
(expect 'doom-initialize-packages :to-have-been-called)))
(it "initializes packages when forced"
(doom-initialize 'force)
(expect 'doom-initialize-packages :to-have-been-called)))
(describe "switch-window" (describe "autoloads files"
:var (doom-switch-window-hook x y)
(before-each (before-each
(delete-other-windows) (spy-on 'doom-load-autoloads-file)
(setq x (get-buffer-window a) (spy-on 'warn :and-return-value t))
y (save-selected-window (split-window)))
(with-selected-window y
(switch-to-buffer b))
(select-window x)
(spy-calls-reset 'hook)
(setq doom-switch-window-hook '(hook)))
(it "should trigger when switching windows" (it "loads autoloads file"
(select-window y) (let ((doom-interactive-mode t))
(select-window x) (ignore-errors (doom-initialize)))
(select-window y) (expect 'doom-load-autoloads-file
(expect 'hook :to-have-been-called-times 3)) :to-have-been-called-with doom-autoload-file)
(expect 'doom-load-autoloads-file
:to-have-been-called-with doom-package-autoload-file))
(it "should trigger only once on the same window" (it "does not load package autoloads file if noninteractive"
(select-window y) (doom-initialize)
(select-window y) (expect 'doom-load-autoloads-file
(select-window x) :to-have-been-called-with doom-autoload-file)
(expect 'hook :to-have-been-called-times 2)))))) (expect 'doom-load-autoloads-file
:not :to-have-been-called-with doom-package-autoload-file))
(it "throws doom-autoload-error in interactive session where autoload files don't exist"
(let ((doom-interactive-mode t)
(doom-autoload-file "doesnotexist")
(doom-package-autoload-file "doesnotexist"))
(expect (doom-initialize) :to-throw 'doom-autoload-error)))))
(describe "doom-initialize-core"
(before-each
(spy-on 'require))
(it "loads all doom core libraries"
(doom-initialize-core)
(expect 'require :to-have-been-called-with 'core-keybinds)
(expect 'require :to-have-been-called-with 'core-ui)
(expect 'require :to-have-been-called-with 'core-projects)
(expect 'require :to-have-been-called-with 'core-editor))))
(describe "doom-load-autoloads-file"
(before-each
(spy-on 'load :and-return-value t))
(it "loads the autoloads file"
(doom-load-autoloads-file doom-autoload-file)
(expect 'load :to-have-been-called-with (file-name-sans-extension doom-autoload-file)
'noerror 'nomessage)))
(describe "doom-load-envvars-file"
:var (envvarfile process-environment)
(before-each
(setq process-environment (copy-sequence process-environment))
(with-temp-file doom-env-file
(insert "\n\n\nA=1\nB=2\nC=3\n")))
(after-each
(delete-file doom-env-file))
(it "throws a file-error if file doesn't exist"
(expect (doom-load-envvars-file "/tmp/envvardoesnotexist")
:to-throw 'file-error))
(it "to fail silently if NOERROR is non-nil"
(expect (doom-load-envvars-file "/tmp/envvardoesnotexist" 'noerror)
:not :to-throw))
(it "loads a well-formed envvar file"
(expect (getenv "A") :not :to-be-truthy)
(expect (doom-load-envvars-file doom-env-file)
:to-equal '(("A" . "1") ("B" . "2") ("C" . "3")))
(expect (getenv "A") :to-equal "1"))
(it "fails on an invalid envvar file"
(with-temp-file doom-env-file (insert "A=1\nB=2\nC=3\n"))
(expect (doom-load-envvars-file doom-env-file) :to-throw))))

View file

@ -3,12 +3,11 @@
(describe "feature/evil" (describe "feature/evil"
:var (resv project-root) :var (resv project-root)
(before-all
(require! :editor evil) (require! :editor evil)
(require 'evil) (require 'evil)
(load! "../autoload/evil")) (load! "../autoload/evil")
(after-all
(unload-feature 'evil t))
(before-each (before-each
(fset 'resv #'+evil-resolve-vim-path-a) (fset 'resv #'+evil-resolve-vim-path-a)
(spy-on 'doom-project-root :and-call-fake (lambda () project-root))) (spy-on 'doom-project-root :and-call-fake (lambda () project-root)))

View file

@ -19,33 +19,33 @@
(describe "headlines" (describe "headlines"
(it "appends first-level headlines with an extra newline" (it "appends first-level headlines with an extra newline"
(insert! "* {0}Header") (insert!! "* {0}Header")
(+org/insert-item-below 1) (+org/insert-item-below 1)
(expect (eobp)) (expect (eobp))
(expect (buffer-substring-no-properties (point-min) (point-max)) (expect (buffer-substring-no-properties (point-min) (point-max))
:to-equal "* Header\n\n* ")) :to-equal "* Header\n\n* "))
(it "prepends first-level headlines with an extra newline" (it "prepends first-level headlines with an extra newline"
(insert! "* {0}Header") (insert!! "* {0}Header")
(+org/insert-item-above 1) (+org/insert-item-above 1)
(expect (eolp)) (expect (eolp))
(expect (buffer-substring-no-properties (point-min) (point-max)) (expect (buffer-substring-no-properties (point-min) (point-max))
:to-equal "* \n\n* Header")) :to-equal "* \n\n* Header"))
(it "appends second-level headlines with an no extra newline" (it "appends second-level headlines with an no extra newline"
(insert! "** {0}Header") (insert!! "** {0}Header")
(+org/insert-item-below 1) (+org/insert-item-below 1)
(expect (eobp)) (expect (eobp))
(expect (buffer-substring-no-properties (point-min) (point-max)) (expect (buffer-substring-no-properties (point-min) (point-max))
:to-equal "** Header\n** ")) :to-equal "** Header\n** "))
(it "prepends second-level headlines with an no extra newline" (it "prepends second-level headlines with an no extra newline"
(insert! "** {0}Header") (insert!! "** {0}Header")
(+org/insert-item-above 1) (+org/insert-item-above 1)
(expect (eolp)) (expect (eolp))
(expect (buffer-substring-no-properties (point-min) (point-max)) (expect (buffer-substring-no-properties (point-min) (point-max))
:to-equal "** \n** Header")) :to-equal "** \n** Header"))
(it "appends headlines, skipping subtrees" (it "appends headlines, skipping subtrees"
(insert! "** {0}First\n" (insert!! "** {0}First\n"
"*** sub 1\n" "*** sub 1\n"
"*** sub 2\n" "*** sub 2\n"
"**** subsub 1\n" "**** subsub 1\n"
@ -63,7 +63,7 @@
"** Header") "** Header")
"\n"))) "\n")))
(it "prepends headlines, skipping subtrees" (it "prepends headlines, skipping subtrees"
(insert! "** First\n" (insert!! "** First\n"
"*** sub 1\n" "*** sub 1\n"
"*** sub 2\n" "*** sub 2\n"
"**** {0}subsub 1\n" "**** {0}subsub 1\n"
@ -83,18 +83,18 @@
(describe "plain lists" (describe "plain lists"
(it "appends items" (it "appends items"
(insert! "+ {0}List item") (insert!! "+ {0}List item")
(+org/insert-item-below 1) (+org/insert-item-below 1)
(expect (buffer-substring-no-properties (point-min) (point-max)) (expect (buffer-substring-no-properties (point-min) (point-max))
:to-equal "+ List item\n+ ")) :to-equal "+ List item\n+ "))
(it "prepends items" (it "prepends items"
(insert! "+ {0}List item") (insert!! "+ {0}List item")
(+org/insert-item-above 1) (+org/insert-item-above 1)
(expect (buffer-substring-no-properties (point-min) (point-max)) (expect (buffer-substring-no-properties (point-min) (point-max))
:to-equal "+ \n+ List item")) :to-equal "+ \n+ List item"))
(it "appends items, but skips over child items" (it "appends items, but skips over child items"
(insert! "+ {0}List item\n" (insert!! "+ {0}List item\n"
" + Sub item\n" " + Sub item\n"
"+ List item") "+ List item")
(+org/insert-item-below 1) (+org/insert-item-below 1)
@ -106,7 +106,7 @@
"+ List item") "+ List item")
"\n"))) "\n")))
(it "prepends items, but skips over child items" (it "prepends items, but skips over child items"
(insert! "+ List item\n" (insert!! "+ List item\n"
" + Sub item\n" " + Sub item\n"
"+ {0}List item") "+ {0}List item")
(+org/insert-item-above 1) (+org/insert-item-above 1)
@ -120,7 +120,7 @@
(describe "numbered lists" (describe "numbered lists"
(it "appends items and updates numbers" (it "appends items and updates numbers"
(insert! "1. {0}List item\n" (insert!! "1. {0}List item\n"
"2. Sub item\n" "2. Sub item\n"
"3. List item") "3. List item")
(+org/insert-item-below 1) (+org/insert-item-below 1)
@ -132,7 +132,7 @@
"4. List item") "4. List item")
"\n"))) "\n")))
(it "prepends items and updates numbers" (it "prepends items and updates numbers"
(insert! "1. List item\n" (insert!! "1. List item\n"
"2. Sub item\n" "2. Sub item\n"
"3. {0}List item") "3. {0}List item")
(+org/insert-item-above 1) (+org/insert-item-above 1)

View file

@ -51,20 +51,20 @@
(describe "css-mode" (describe "css-mode"
(it "converts inline statements into multiline blocks" (it "converts inline statements into multiline blocks"
(insert! "body { color: red{0}; font-size: 2em; }")) (insert!! "body { color: red{0}; font-size: 2em; }"))
(it "works when cursor is on closing brace" (it "works when cursor is on closing brace"
(insert! "body { color: red; font-size: 2em; {0}}")) (insert!! "body { color: red; font-size: 2em; {0}}"))
(it "works when cursor is on opening brace" (it "works when cursor is on opening brace"
(insert! "body {{0} color: red; font-size: 2em; }")) (insert!! "body {{0} color: red; font-size: 2em; }"))
(it "works when cursor is on same line" (it "works when cursor is on same line"
(insert! "{0}body { color: red; font-size: 2em; }")))) (insert!! "{0}body { color: red; font-size: 2em; }"))))
(describe "comment-indent-new-line" (describe "comment-indent-new-line"
(before-each (before-each
(delay-mode-hooks (scss-mode))) (delay-mode-hooks (scss-mode)))
(it "continues commented lines on newline" (it "continues commented lines on newline"
(insert! "// test{0}\n" (insert!! "// test{0}\n"
"body { color: red; font-size: 2em; }") "body { color: red; font-size: 2em; }")
(+css/comment-indent-new-line) (+css/comment-indent-new-line)
(expect (string-trim (buffer-string)) :to-equal (expect (string-trim (buffer-string)) :to-equal
@ -76,7 +76,7 @@
(expect (eolp)) (expect (eolp))
(expect (line-number-at-pos) :to-be 2)) (expect (line-number-at-pos) :to-be 2))
(it "preserves indentation within continued comments" (it "preserves indentation within continued comments"
(insert! "// test{0}\n" (insert!! "// test{0}\n"
"body { color: red; font-size: 2em; }") "body { color: red; font-size: 2em; }")
(+css/comment-indent-new-line) (+css/comment-indent-new-line)
(expect (string-trim (buffer-string)) :to-equal (expect (string-trim (buffer-string)) :to-equal

View file

@ -11,10 +11,11 @@
persp1 persp1-name persp2 persp2-name persp1 persp1-name persp2 persp2-name
wconf) wconf)
(require! :ui workspaces)
(require 'persp-mode)
(before-all (before-all
(delete-other-windows) (delete-other-windows))
(require! :ui workspaces)
(require 'persp-mode))
(before-each (before-each
(switch-to-buffer "*scratch*") (switch-to-buffer "*scratch*")