;;; Code:
+(require 'cl-lib)
(require 'context-coloring)
-(require 'ert-async)
+(require 'ert)
(require 'js2-mode)
(insert (context-coloring-test-read-file ,fixture))
,@body)))
-(defun context-coloring-test-with-temp-buffer-async (callback)
- "Create a temporary buffer, and evaluate CALLBACK there. A
-teardown callback is passed to CALLBACK for it to invoke when it
-is done."
- (let ((previous-buffer (current-buffer))
- (temp-buffer (generate-new-buffer " *temp*")))
- (set-buffer temp-buffer)
- (funcall
- callback
- (lambda ()
- (and (buffer-name temp-buffer)
- (kill-buffer temp-buffer))
- (set-buffer previous-buffer)))))
-
-(defun context-coloring-test-with-fixture-async (fixture callback)
- "With the relative FIXTURE, evaluate CALLBACK in a temporary
-buffer. A teardown callback is passed to CALLBACK for it to
-invoke when it is done."
- (context-coloring-test-with-temp-buffer-async
- (lambda (done-with-temp-buffer)
- (insert (context-coloring-test-read-file fixture))
- (funcall
- callback
- (lambda ()
- (funcall done-with-temp-buffer))))))
-
;;; Test defining utilities
&key mode
&key extension
&key no-fixture
- &key async
- &key post-colorization
&key enable-context-coloring-mode
- &key get-args
&key before-each
&key after-each)
- "Define a deftest defmacro for tests prefixed with NAME. MODE
+ "Define a deftest defmacro for tests prefixed with NAME. MODE
is called to set up tests' environments. EXTENSION denotes the
suffix for tests' fixture files. If NO-FIXTURE is non-nil, don't
-use a fixture. If ASYNC is non-nil, pass a callback to the
-defined tests' bodies for them to call when they are done. If
-POST-COLORIZATION is non-nil, the tests run after
-`context-coloring-colorize' finishes asynchronously. If
-ENABLE-CONTEXT-COLORING-MODE is non-nil, `context-coloring-mode'
-is activated before tests. GET-ARGS provides arguments to apply
-to BEFORE-EACH, AFTER-EACH, and each tests' body, before and
-after functions. Functions BEFORE-EACH and AFTER-EACH run before
-the major mode is activated before each test, and after each
-test, even if an error is signaled."
+use a fixture. If ENABLE-CONTEXT-COLORING-MODE is non-nil,
+`context-coloring-mode' is activated before tests. Functions
+BEFORE-EACH and AFTER-EACH run before the major mode is activated
+before each test, and after each test, even if an error is
+signaled."
(declare (indent defun))
(let ((macro-name (intern (format "context-coloring-test-deftest%s"
(cond
&key fixture
&key before
&key after)
- ,(format "Define a test for `%s' suffixed with NAME.
-
-Function BODY makes assertions.
-%s
-
-Functions BEFORE and AFTER run before and after the test, even if
-an error is signaled.
-
-BODY is run after `context-coloring-mode' is activated, or after
-initial colorization if colorization should occur."
- (cadr mode)
- (cond
- (no-fixture "
-There is no fixture, unless FIXTURE is specified.")
- (t
- (format "
-The default fixture has a filename matching NAME (plus the
-filetype extension, \"%s\"), unless FIXTURE is specified to
-override it."
- extension))))
(declare (indent defun))
;; Commas in nested backquotes are not evaluated. Binding the variables
;; here is probably the cleanest workaround.
(let ((mode ,mode)
- (get-args ',(cond
- (get-args get-args)
- (t '(lambda () (list)))))
- (args (make-symbol "args"))
(before-each ',before-each)
(after-each ',after-each)
(test-name (intern (format ,(format "%s-%%s"
(cond
(name)
- (t "sync"))) name)))
+ (t "generic"))) name)))
(fixture (cond
(fixture (format "./fixtures/%s" fixture))
(,no-fixture "./fixtures/empty")
(t (format ,(format "./fixtures/%%s.%s" extension) name)))))
- ,@(cond
- ((or async post-colorization)
- `((let ((post-colorization ,post-colorization))
- `(ert-deftest-async ,test-name (done)
- (let ((,args (funcall ,get-args)))
- (context-coloring-test-with-fixture-async
- ,fixture
- (lambda (done-with-fixture)
- (when ,before-each (apply ,before-each ,args))
- (,mode)
- (when ,before (apply ,before ,args))
- (cond
- (,post-colorization
- (context-coloring-colorize
- (lambda ()
- (unwind-protect
- (progn
- (apply ,body ,args))
- (when ,after (apply ,after ,args))
- (when ,after-each (apply ,after-each ,args))
- (funcall done-with-fixture))
- (funcall done))))
- (t
- ;; Leave error handling up to the user.
- (apply ,body (append
- (list (lambda ()
- (when ,after (apply ,after ,args))
- (when ,after-each (apply ,after-each ,args))
- (funcall done-with-fixture)
- (funcall done)))
- ,args)))))))))))
- (t
- `((let ((enable-context-coloring-mode ,enable-context-coloring-mode))
- `(ert-deftest ,test-name ()
- (let ((,args (funcall ,get-args)))
- (context-coloring-test-with-fixture
- ,fixture
- (when ,before-each (apply ,before-each ,args))
- (,mode)
- (when ,before (apply ,before ,args))
- (when ,enable-context-coloring-mode (context-coloring-mode))
- (unwind-protect
- (progn
- (apply ,body ,args))
- (when ,after (apply ,after ,args))
- (when ,after-each (apply ,after-each ,args))))))))))))))
+ ,@`((let ((enable-context-coloring-mode ,enable-context-coloring-mode))
+ `(ert-deftest ,test-name ()
+ (context-coloring-test-with-fixture
+ ,fixture
+ (when ,before-each (funcall ,before-each))
+ (,mode)
+ (when ,before (funcall ,before))
+ (when ,enable-context-coloring-mode (context-coloring-mode))
+ (unwind-protect
+ (progn
+ (funcall ,body))
+ (when ,after (funcall ,after))
+ (when ,after-each (funcall ,after-each)))))))))))
(context-coloring-test-define-deftest nil
- :mode 'fundamental-mode
+ :mode #'fundamental-mode
:no-fixture t)
-(context-coloring-test-define-deftest async
- :mode 'fundamental-mode
- :no-fixture t
- :async t)
-
-(context-coloring-test-define-deftest js
- :mode 'js-mode
- :extension "js"
- :post-colorization t)
-
-(context-coloring-test-define-deftest js2
- :mode 'js2-mode
+(context-coloring-test-define-deftest javascript
+ :mode #'js2-mode
:extension "js"
:enable-context-coloring-mode t
:before-each (lambda ()
(setq js2-mode-show-parse-errors nil)
(setq js2-mode-show-strict-warnings nil)))
-(defmacro context-coloring-test-deftest-js-js2 (&rest args)
- "Simultaneously define the same test for js and js2."
- (declare (indent defun))
- `(progn
- (context-coloring-test-deftest-js ,@args)
- (context-coloring-test-deftest-js2 ,@args)))
-
(context-coloring-test-define-deftest emacs-lisp
- :mode 'emacs-lisp-mode
+ :mode #'emacs-lisp-mode
:extension "el"
:enable-context-coloring-mode t)
-(context-coloring-test-define-deftest define-theme
- :mode 'fundamental-mode
- :no-fixture t
- :get-args (lambda ()
- (list (context-coloring-test-get-next-theme)))
- :after-each (lambda (theme)
- (setq context-coloring-maximum-face 7)
- (setq context-coloring-original-maximum-face
- context-coloring-maximum-face)
- (disable-theme theme)
- (context-coloring-test-kill-buffer "*Warnings*")))
+(context-coloring-test-define-deftest eval-expression
+ :mode #'fundamental-mode
+ :no-fixture t)
;;; Assertion functions
"but it did")
buffer expected)))))))
-(defun context-coloring-test-assert-no-message (buffer)
- "Assert that BUFFER has no message."
- (when (get-buffer buffer)
- (ert-fail (format (concat "Expected buffer `%s' to have no messages, "
- "but it did: `%s'")
- buffer
- (with-current-buffer buffer
- (buffer-string))))))
-
(defun context-coloring-test-assert-error (body error-message)
"Assert that BODY signals ERROR-MESSAGE."
(let ((error-signaled-p nil))
;;; Miscellaneous tests
-(defun context-coloring-test-assert-trimmed (result expected)
- "Assert that RESULT is trimmed like EXPECTED."
- (when (not (string-equal result expected))
- (ert-fail "Expected string to be trimmed, but it wasn't.")))
-
-(context-coloring-test-deftest trim
- (lambda ()
- (context-coloring-test-assert-trimmed (context-coloring-trim "") "")
- (context-coloring-test-assert-trimmed (context-coloring-trim " ") "")
- (context-coloring-test-assert-trimmed (context-coloring-trim "a") "a")
- (context-coloring-test-assert-trimmed (context-coloring-trim " a") "a")
- (context-coloring-test-assert-trimmed (context-coloring-trim "a ") "a")
- (context-coloring-test-assert-trimmed (context-coloring-trim " a ") "a")))
-
-(context-coloring-test-deftest-async mode-startup
- (lambda (done)
- (js-mode)
- (add-hook
- 'context-coloring-colorize-hook
- (lambda ()
- ;; If this runs we are implicitly successful; this test only confirms
- ;; that colorization occurs on mode startup.
- (funcall done)))
- (context-coloring-mode))
- :after (lambda ()
- ;; TODO: This won't run if there is a timeout. Will probably have to
- ;; roll our own `ert-deftest-async'.
- (setq context-coloring-colorize-hook nil)))
-
(defmacro context-coloring-test-define-derived-mode (name)
- "Define a derived mode exclusively for tests."
+ "Define a derived mode exclusively for any test with NAME."
(let ((name (intern (format "context-coloring-test-%s-mode" name))))
`(define-derived-mode ,name fundamental-mode "Testing")))
+(defvar context-coloring-test-caused-p nil
+ "Dumb flag tracking for lambdas inside old advice definitions
+which don't seem to have lexical binding.")
+
+(defmacro context-coloring-test-assert-causes-coloring (&rest body)
+ "Assert that BODY causes coloring."
+ `(progn
+ ;; Gross, but I want this to pass on 24.3.
+ (ad-add-advice #'context-coloring-colorize
+ '(assert-causes-coloring
+ nil t
+ (advice . (lambda ()
+ (setq context-coloring-test-caused-p t))))
+ 'after
+ 0)
+ (ad-activate #'context-coloring-colorize)
+ ,@body
+ (when (not context-coloring-test-caused-p)
+ (ert-fail "Expected to have colorized, but it didn't."))))
+
+(defun context-coloring-test-cleanup-assert-causes-coloring ()
+ (ad-unadvise #'context-coloring-colorize)
+ (setq context-coloring-test-caused-p nil))
+
+(context-coloring-test-define-derived-mode mode-startup)
+
+(context-coloring-test-deftest mode-startup
+ (lambda ()
+ (context-coloring-define-dispatch
+ 'mode-startup
+ :modes '(context-coloring-test-mode-startup-mode)
+ :colorizer #'ignore)
+ (context-coloring-test-mode-startup-mode)
+ (context-coloring-test-assert-causes-coloring
+ (context-coloring-mode)))
+ :after (lambda ()
+ (context-coloring-test-cleanup-assert-causes-coloring)))
+
(context-coloring-test-define-derived-mode change-detection)
-;; Simply cannot figure out how to trigger an idle timer; would much rather test
-;; that. But (current-idle-time) always returns nil in these tests.
-(context-coloring-test-deftest-async change-detection
- (lambda (done)
+(context-coloring-test-deftest change-detection
+ (lambda ()
(context-coloring-define-dispatch
'idle-change
:modes '(context-coloring-test-change-detection-mode)
- :executable "node"
- :command "node test/binaries/noop")
+ :colorizer #'ignore
+ :setup #'context-coloring-setup-idle-change-detection
+ :teardown #'context-coloring-teardown-idle-change-detection)
(context-coloring-test-change-detection-mode)
- (add-hook
- 'context-coloring-colorize-hook
- (lambda ()
- (setq context-coloring-colorize-hook nil)
- (add-hook
- 'context-coloring-colorize-hook
- (lambda ()
- (funcall done)))
- (insert " ")
- (set-window-buffer (selected-window) (current-buffer))
- (context-coloring-maybe-colorize (current-buffer))))
- (context-coloring-mode))
+ (context-coloring-mode)
+ (context-coloring-test-assert-causes-coloring
+ (insert " ")
+ ;; Simply cannot figure out how to trigger an idle timer; would much rather
+ ;; test that. But (current-idle-time) always returns nil in these tests.
+ (context-coloring-maybe-colorize-with-buffer (current-buffer))))
:after (lambda ()
- (setq context-coloring-colorize-hook nil)))
-
-(context-coloring-test-deftest check-version
- (lambda ()
- (when (not (context-coloring-check-version "2.1.3" "3.0.1"))
- (ert-fail "Expected version 3.0.1 to satisfy 2.1.3, but it didn't."))
- (when (context-coloring-check-version "3.0.1" "2.1.3")
- (ert-fail "Expected version 2.1.3 not to satisfy 3.0.1, but it did."))))
+ (context-coloring-test-cleanup-assert-causes-coloring)))
(context-coloring-test-deftest unsupported-mode
(lambda ()
(lambda ()
(context-coloring-define-dispatch
'define-dispatch-no-modes))
- "No mode defined for dispatch")
+ "No mode or predicate defined for dispatch")
(context-coloring-test-assert-error
(lambda ()
(context-coloring-define-dispatch
'define-dispatch-no-strategy
:modes '(context-coloring-test-define-dispatch-error-mode)))
- "No colorizer, scopifier or command defined for dispatch")))
-
-(context-coloring-test-define-derived-mode define-dispatch-scopifier)
-
-(context-coloring-test-deftest define-dispatch-scopifier
- (lambda ()
- (context-coloring-define-dispatch
- 'define-dispatch-scopifier
- :modes '(context-coloring-test-define-dispatch-scopifier-mode)
- :scopifier (lambda () (vector)))
- (context-coloring-test-define-dispatch-scopifier-mode)
- (context-coloring-mode)
- (context-coloring-colorize)))
-
-(context-coloring-test-define-derived-mode missing-executable)
-
-(context-coloring-test-deftest missing-executable
- (lambda ()
- (context-coloring-define-dispatch
- 'scopifier
- :modes '(context-coloring-test-missing-executable-mode)
- :command ""
- :executable "__should_not_exist__")
- (context-coloring-test-missing-executable-mode)
- (context-coloring-mode)))
-
-(context-coloring-test-define-derived-mode unsupported-version)
-
-(context-coloring-test-deftest-async unsupported-version
- (lambda (done)
- (context-coloring-define-dispatch
- 'outta-date
- :modes '(context-coloring-test-unsupported-version-mode)
- :executable "node"
- :command "node test/binaries/outta-date"
- :version "v2.1.3")
- (context-coloring-test-unsupported-version-mode)
- (add-hook
- 'context-coloring-check-scopifier-version-hook
- (lambda ()
- (unwind-protect
- (progn
- ;; Normally the executable would be something like "outta-date"
- ;; rather than "node".
- (context-coloring-test-assert-message
- "Update to the minimum version of \"node\" (v2.1.3)"
- "*Messages*"))
- (funcall done))))
- (context-coloring-mode))
- :after (lambda ()
- (setq context-coloring-check-scopifier-version-hook nil)))
+ "No colorizer defined for dispatch")))
(context-coloring-test-define-derived-mode disable-mode)
-(context-coloring-test-deftest-async disable-mode
- (lambda (done)
+(context-coloring-test-deftest disable-mode
+ (lambda ()
(let (torn-down)
(context-coloring-define-dispatch
'disable-mode
:modes '(context-coloring-test-disable-mode-mode)
- :executable "node"
- :command "node test/binaries/noop"
+ :colorizer #'ignore
:teardown (lambda ()
(setq torn-down t)))
- (unwind-protect
- (progn
- (context-coloring-test-disable-mode-mode)
- (context-coloring-mode)
- (context-coloring-mode -1)
- (when (not torn-down)
- (ert-fail "Expected teardown function to have been called, but it wasn't.")))
- (funcall done)))))
-
-
-;;; Theme tests
-
-(defvar context-coloring-test-theme-index 0
- "Unique index for unique theme names.")
-
-(defun context-coloring-test-get-next-theme ()
- "Return a unique symbol for a throwaway theme."
- (prog1
- (intern (format "context-coloring-test-theme-%s"
- context-coloring-test-theme-index))
- (setq context-coloring-test-theme-index
- (+ context-coloring-test-theme-index 1))))
-
-(defun context-coloring-test-assert-face (level foreground &optional negate)
- "Assert that a face for LEVEL exists and that its `:foreground'
-is FOREGROUND, or the inverse if NEGATE is non-nil."
- (let* ((face (context-coloring-level-face level))
- actual-foreground)
- (when (not (or negate
- face))
- (ert-fail (format (concat "Expected face for level `%s' to exist; "
- "but it didn't")
- level)))
- (setq actual-foreground (face-attribute face :foreground))
- (when (funcall (if negate 'identity 'not)
- (string-equal foreground actual-foreground))
- (ert-fail (format (concat "Expected face for level `%s' "
- "%sto have foreground `%s'; "
- "but it %s.")
- level
- (if negate "not " "") foreground
- (if negate
- "did" (format "was `%s'" actual-foreground)))))))
-
-(defun context-coloring-test-assert-not-face (&rest arguments)
- "Assert that LEVEL does not have a face with `:foreground'
-FOREGROUND. Apply ARGUMENTS to
-`context-coloring-test-assert-face', see that function."
- (apply 'context-coloring-test-assert-face
- (append arguments '(t))))
-
-(defun context-coloring-test-assert-theme-originally-set-p
- (settings &optional negate)
- "Assert that `context-coloring-theme-originally-set-p' returns
-t for a theme with SETTINGS, or the inverse if NEGATE is
-non-nil."
- (let ((theme (context-coloring-test-get-next-theme)))
- (put theme 'theme-settings settings)
- (when (funcall (if negate 'identity 'not)
- (context-coloring-theme-originally-set-p theme))
- (ert-fail (format (concat "Expected theme `%s' with settings `%s' "
- "%sto be considered to have defined a level, "
- "but it %s.")
- theme settings
- (if negate "not " "")
- (if negate "was" "wasn't"))))))
-
-(defun context-coloring-test-assert-not-theme-originally-set-p (&rest arguments)
- "Assert that `context-coloring-theme-originally-set-p' does not
-return t for a theme with SETTINGS. Apply ARGUMENTS to
-`context-coloring-test-assert-theme-originally-set-p', see that
-function."
- (apply 'context-coloring-test-assert-theme-originally-set-p
- (append arguments '(t))))
-
-(context-coloring-test-deftest theme-originally-set-p
- (lambda ()
- (context-coloring-test-assert-theme-originally-set-p
- '((theme-face context-coloring-level-0-face)))
- (context-coloring-test-assert-theme-originally-set-p
- '((theme-face face)
- (theme-face context-coloring-level-0-face)))
- (context-coloring-test-assert-theme-originally-set-p
- '((theme-face context-coloring-level-0-face)
- (theme-face face)))
- (context-coloring-test-assert-not-theme-originally-set-p
- '((theme-face face)))))
-
-(defun context-coloring-test-assert-theme-settings-highest-level
- (settings expected-level)
- "Assert that a theme with SETTINGS has the highest level
-EXPECTED-LEVEL."
- (let ((theme (context-coloring-test-get-next-theme)))
- (put theme 'theme-settings settings)
- (context-coloring-test-assert-theme-highest-level theme expected-level)))
-
-(defun context-coloring-test-assert-theme-highest-level
- (theme expected-level &optional negate)
- "Assert that THEME has the highest level EXPECTED-LEVEL, or the
-inverse if NEGATE is non-nil."
- (let ((highest-level (context-coloring-theme-highest-level theme)))
- (when (funcall (if negate 'identity 'not) (eq highest-level expected-level))
- (ert-fail (format (concat "Expected theme with settings `%s' "
- "%sto have a highest level of `%s', "
- "but it %s.")
- (get theme 'theme-settings)
- (if negate "not " "") expected-level
- (if negate "did" (format "was %s" highest-level)))))))
-
-(defun context-coloring-test-assert-theme-not-highest-level (&rest arguments)
- "Assert that THEME's highest level is not EXPECTED-LEVEL.
-Apply ARGUMENTS to
-`context-coloring-test-assert-theme-highest-level', see that
-function."
- (apply 'context-coloring-test-assert-theme-highest-level
- (append arguments '(t))))
-
-(context-coloring-test-deftest theme-highest-level
- (lambda ()
- (context-coloring-test-assert-theme-settings-highest-level
- '((theme-face foo))
- -1)
- (context-coloring-test-assert-theme-settings-highest-level
- '((theme-face context-coloring-level-0-face))
- 0)
- (context-coloring-test-assert-theme-settings-highest-level
- '((theme-face context-coloring-level-1-face))
- 1)
- (context-coloring-test-assert-theme-settings-highest-level
- '((theme-face context-coloring-level-1-face)
- (theme-face context-coloring-level-0-face))
- 1)
- (context-coloring-test-assert-theme-settings-highest-level
- '((theme-face context-coloring-level-0-face)
- (theme-face context-coloring-level-1-face))
- 1)))
-
-(defun context-coloring-test-kill-buffer (buffer)
- "Kill BUFFER if it exists."
- (when (get-buffer buffer) (kill-buffer buffer)))
-
-(defun context-coloring-test-deftheme (theme)
- "Dynamically define theme THEME."
- (eval (macroexpand `(deftheme ,theme))))
-
-(context-coloring-test-deftest-define-theme additive
- (lambda (theme)
- (context-coloring-test-deftheme theme)
- (context-coloring-define-theme
- theme
- :colors '("#aaaaaa"
- "#bbbbbb"))
- (context-coloring-test-assert-no-message "*Warnings*")
- (enable-theme theme)
- (context-coloring-test-assert-no-message "*Warnings*")
- (context-coloring-test-assert-face 0 "#aaaaaa")
- (context-coloring-test-assert-face 1 "#bbbbbb")))
-
-(defun context-coloring-test-assert-defined-warning (theme)
- "Assert that a warning about colors already being defined for
-theme THEME is signaled."
- (context-coloring-test-assert-message
- (format (concat "Warning (emacs): Context coloring colors for theme "
- "`%s' are already defined")
- theme)
- "*Warnings*"))
-
-(context-coloring-test-deftest-define-theme unintentional-override
- (lambda (theme)
- (context-coloring-test-deftheme theme)
- (custom-theme-set-faces
- theme
- '(context-coloring-level-0-face ((t (:foreground "#aaaaaa"))))
- '(context-coloring-level-1-face ((t (:foreground "#bbbbbb")))))
- (context-coloring-define-theme
- theme
- :colors '("#cccccc"
- "#dddddd"))
- (context-coloring-test-assert-defined-warning theme)
- (context-coloring-test-kill-buffer "*Warnings*")
- (enable-theme theme)
- (context-coloring-test-assert-defined-warning theme)
- (context-coloring-test-assert-face 0 "#cccccc")
- (context-coloring-test-assert-face 1 "#dddddd")))
-
-(context-coloring-test-deftest-define-theme intentional-override
- (lambda (theme)
- (context-coloring-test-deftheme theme)
- (custom-theme-set-faces
- theme
- '(context-coloring-level-0-face ((t (:foreground "#aaaaaa"))))
- '(context-coloring-level-1-face ((t (:foreground "#bbbbbb")))))
- (context-coloring-define-theme
- theme
- :override t
- :colors '("#cccccc"
- "#dddddd"))
- (context-coloring-test-assert-no-message "*Warnings*")
- (enable-theme theme)
- (context-coloring-test-assert-no-message "*Warnings*")
- (context-coloring-test-assert-face 0 "#cccccc")
- (context-coloring-test-assert-face 1 "#dddddd")))
-
-(context-coloring-test-deftest-define-theme pre-recede
- (lambda (theme)
- (context-coloring-define-theme
- theme
- :recede t
- :colors '("#aaaaaa"
- "#bbbbbb"))
- (context-coloring-test-deftheme theme)
- (custom-theme-set-faces
- theme
- '(context-coloring-level-0-face ((t (:foreground "#cccccc"))))
- '(context-coloring-level-1-face ((t (:foreground "#dddddd")))))
- (enable-theme theme)
- (context-coloring-test-assert-no-message "*Warnings*")
- (context-coloring-test-assert-face 0 "#cccccc")
- (context-coloring-test-assert-face 1 "#dddddd")))
-
-(context-coloring-test-deftest-define-theme pre-recede-delayed-application
- (lambda (theme)
- (context-coloring-define-theme
- theme
- :recede t
- :colors '("#aaaaaa"
- "#bbbbbb"))
- (context-coloring-test-deftheme theme)
- (enable-theme theme)
- (context-coloring-test-assert-no-message "*Warnings*")
- (context-coloring-test-assert-face 0 "#aaaaaa")
- (context-coloring-test-assert-face 1 "#bbbbbb")))
-
-(context-coloring-test-deftest-define-theme post-recede
- (lambda (theme)
- (context-coloring-test-deftheme theme)
- (custom-theme-set-faces
- theme
- '(context-coloring-level-0-face ((t (:foreground "#aaaaaa"))))
- '(context-coloring-level-1-face ((t (:foreground "#bbbbbb")))))
- (context-coloring-define-theme
- theme
- :recede t
- :colors '("#cccccc"
- "#dddddd"))
- (context-coloring-test-assert-no-message "*Warnings*")
- (context-coloring-test-assert-face 0 "#aaaaaa")
- (context-coloring-test-assert-face 1 "#bbbbbb")
- (enable-theme theme)
- (context-coloring-test-assert-no-message "*Warnings*")
- (context-coloring-test-assert-face 0 "#aaaaaa")
- (context-coloring-test-assert-face 1 "#bbbbbb")))
-
-(context-coloring-test-deftest-define-theme recede-not-defined
- (lambda (theme)
- (context-coloring-test-deftheme theme)
- (custom-theme-set-faces
- theme
- '(foo-face ((t (:foreground "#ffffff")))))
- (context-coloring-define-theme
- theme
- :recede t
- :colors '("#aaaaaa"
- "#bbbbbb"))
- (context-coloring-test-assert-no-message "*Warnings*")
- (context-coloring-test-assert-face 0 "#aaaaaa")
- (context-coloring-test-assert-face 1 "#bbbbbb")
- (enable-theme theme)
- (context-coloring-test-assert-no-message "*Warnings*")
- (context-coloring-test-assert-face 0 "#aaaaaa")
- (context-coloring-test-assert-face 1 "#bbbbbb")))
-
-(context-coloring-test-deftest-define-theme unintentional-obstinance
- (lambda (theme)
- (context-coloring-define-theme
- theme
- :colors '("#aaaaaa"
- "#bbbbbb"))
- (context-coloring-test-deftheme theme)
- (custom-theme-set-faces
- theme
- '(context-coloring-level-0-face ((t (:foreground "#cccccc"))))
- '(context-coloring-level-1-face ((t (:foreground "#dddddd")))))
- (enable-theme theme)
- (context-coloring-test-assert-defined-warning theme)
- (context-coloring-test-assert-face 0 "#aaaaaa")
- (context-coloring-test-assert-face 1 "#bbbbbb")))
-
-(context-coloring-test-deftest-define-theme intentional-obstinance
- (lambda (theme)
- (context-coloring-define-theme
- theme
- :override t
- :colors '("#aaaaaa"
- "#bbbbbb"))
- (context-coloring-test-deftheme theme)
- (custom-theme-set-faces
- theme
- '(context-coloring-level-0-face ((t (:foreground "#cccccc"))))
- '(context-coloring-level-1-face ((t (:foreground "#dddddd")))))
- (enable-theme theme)
- (context-coloring-test-assert-no-message "*Warnings*")
- (context-coloring-test-assert-face 0 "#aaaaaa")
- (context-coloring-test-assert-face 1 "#bbbbbb")))
-
-(defun context-coloring-test-assert-maximum-face (maximum &optional negate)
- "Assert that `context-coloring-maximum-face' is MAXIMUM, or the
-inverse if NEGATE is non-nil."
- (when (funcall (if negate 'identity 'not)
- (eq context-coloring-maximum-face maximum))
- (ert-fail (format (concat "Expected `context-coloring-maximum-face' "
- "%sto be `%s', "
- "but it %s.")
- (if negate "not " "") maximum
- (if negate
- "was"
- (format "was `%s'" context-coloring-maximum-face))))))
-
-(defun context-coloring-test-assert-not-maximum-face (&rest arguments)
- "Assert that `context-coloring-maximum-face' is not MAXIMUM.
-Apply ARGUMENTS to `context-coloring-test-assert-maximum-face',
-see that function."
- (apply 'context-coloring-test-assert-maximum-face
- (append arguments '(t))))
-
-(context-coloring-test-deftest-define-theme disable-cascade
- (lambda (theme)
- (let ((maximum-face-value 9999))
- (setq context-coloring-maximum-face maximum-face-value)
- (context-coloring-test-deftheme theme)
- (context-coloring-define-theme
- theme
- :colors '("#aaaaaa"
- "#bbbbbb"))
- (let ((second-theme (context-coloring-test-get-next-theme)))
- (context-coloring-test-deftheme second-theme)
- (context-coloring-define-theme
- second-theme
- :colors '("#cccccc"
- "#dddddd"
- "#eeeeee"))
- (let ((third-theme (context-coloring-test-get-next-theme)))
- (context-coloring-test-deftheme third-theme)
- (context-coloring-define-theme
- third-theme
- :colors '("#111111"
- "#222222"
- "#333333"
- "#444444"))
- (enable-theme theme)
- (enable-theme second-theme)
- (enable-theme third-theme)
- (disable-theme third-theme)
- (context-coloring-test-assert-face 0 "#cccccc")
- (context-coloring-test-assert-face 1 "#dddddd")
- (context-coloring-test-assert-face 2 "#eeeeee")
- (context-coloring-test-assert-maximum-face 2))
- (disable-theme second-theme)
- (context-coloring-test-assert-face 0 "#aaaaaa")
- (context-coloring-test-assert-face 1 "#bbbbbb")
- (context-coloring-test-assert-maximum-face 1))
- (disable-theme theme)
- (context-coloring-test-assert-not-face 0 "#aaaaaa")
- (context-coloring-test-assert-not-face 1 "#bbbbbb")
- (context-coloring-test-assert-maximum-face
- maximum-face-value))))
+ (context-coloring-test-disable-mode-mode)
+ (context-coloring-mode)
+ (context-coloring-mode -1)
+ (when (not torn-down)
+ (ert-fail "Expected teardown function to have been called, but it wasn't.")))))
;;; Coloring tests
(when (not (and face
(let* ((face-string (symbol-name face))
(matches (string-match
- context-coloring-level-face-regexp
+ "context-coloring-level-\\([[:digit:]]+\\)-face"
face-string)))
(when matches
(setq actual-level (string-to-number
(context-coloring-test-assert-position-face position nil))
(defun context-coloring-test-assert-coloring (map)
- "Assert that the current buffer's coloring matches MAP.
+ "Assert that the current buffer's coloring will match MAP.
MAP's newlines should correspond to the current fixture.
(forward-char)))
(setq index (1+ index)))))
-(context-coloring-test-deftest-js-js2 function-scopes
+(context-coloring-test-deftest-javascript function-scopes
(lambda ()
(context-coloring-test-assert-coloring "
000 0 0 11111111 11 110
22222222 122 22
1")))
-(context-coloring-test-deftest-js-js2 global
+(context-coloring-test-deftest-javascript global
(lambda ()
(context-coloring-test-assert-coloring "
(xxxxxxxx () {
111 1 1 00000001xxx11
}());")))
-(context-coloring-test-deftest-js2 block-scopes
+(context-coloring-test-deftest-javascript block-scopes
(lambda ()
(context-coloring-test-assert-coloring "
(xxxxxxxx () {
2
}());"))
:before (lambda ()
- (setq context-coloring-js-block-scopes t))
+ (setq context-coloring-javascript-block-scopes t))
:after (lambda ()
- (setq context-coloring-js-block-scopes nil)))
+ (setq context-coloring-javascript-block-scopes nil)))
-(context-coloring-test-deftest-js-js2 catch
+(context-coloring-test-deftest-javascript catch
(lambda ()
(context-coloring-test-assert-coloring "
(xxxxxxxx () {
2
}());")))
-(context-coloring-test-deftest-js-js2 key-names
+(context-coloring-test-deftest-javascript key-names
(lambda ()
(context-coloring-test-assert-coloring "
(xxxxxxxx () {
11
}());")))
-(context-coloring-test-deftest-js-js2 property-lookup
+(context-coloring-test-deftest-javascript property-lookup
(lambda ()
(context-coloring-test-assert-coloring "
(xxxxxxxx () {
00000011111111111
}());")))
-(context-coloring-test-deftest-js-js2 key-values
+(context-coloring-test-deftest-javascript key-values
(lambda ()
(context-coloring-test-assert-coloring "
(xxxxxxxx () {
}());
}());")))
-(context-coloring-test-deftest-js-js2 syntactic-comments-and-strings
+(context-coloring-test-deftest-javascript syntactic-comments-and-strings
(lambda ()
(context-coloring-test-assert-coloring "
0000 00
ssssssssssss0"))
:fixture "comments-and-strings.js")
-(context-coloring-test-deftest-js-js2 syntactic-comments
+(context-coloring-test-deftest-javascript syntactic-comments
(lambda ()
(context-coloring-test-assert-coloring "
0000 00
:after (lambda ()
(setq context-coloring-syntactic-strings t)))
-(context-coloring-test-deftest-js-js2 syntactic-strings
+(context-coloring-test-deftest-javascript syntactic-strings
(lambda ()
(context-coloring-test-assert-coloring "
0000 00
:after (lambda ()
(setq context-coloring-syntactic-comments t)))
-(context-coloring-test-deftest-js2 unterminated-comment
+(context-coloring-test-deftest-javascript unterminated-comment
;; As long as `add-text-properties' doesn't signal an error, this test passes.
(lambda ()))
0000 0 0 00
111111 01
-111111 111")))
+111111 111
+111111 0 1sss11")))
+
+(context-coloring-test-deftest-emacs-lisp defadvice
+ (lambda ()
+ (context-coloring-test-assert-coloring "
+1111111111 0 1111111 111111 11111 111 111111111
+ 2222 222 122
+ 22 1 2221")))
(context-coloring-test-deftest-emacs-lisp lambda
(lambda ()
(context-coloring-test-deftest-emacs-lisp quote
(lambda ()
(context-coloring-test-assert-coloring "
+(xxxxx 0000000 00 00000)
+(xxx () (xxxxxxxxx (,0000)))
+
(xxxxx x (x)
(xx (xx x 111
111111 1 111 111
(lambda ()
(context-coloring-test-assert-coloring "
(xxxxx x ()
- (x x 1 11 11 111 111 11 1 111 (1 1 1)))")))
+ (x x 1 11 11 111 111 11 11 11 1 111 (1 1 1)))")))
+
+(context-coloring-test-deftest-emacs-lisp sexp
+ (lambda ()
+ (context-coloring-test-assert-coloring "
+(xxx ()
+ `,@sss
+ `,@11
+ `,@11)")))
(context-coloring-test-deftest-emacs-lisp let
(lambda ()
(context-coloring-test-assert-coloring "
1111 11
- cccccccccc
- 11 sss1
11 01
11 00001
11 2222 22
22 02
22 000022
2222 2 2 2 00002211
- 1111 1 1 1 000011")))
+ 1111 1 1 1 000011
+
+1111 cc ccccccc
+ 1sss11")))
(context-coloring-test-deftest-emacs-lisp let*
(lambda ()
2222 1 1 2 2 2 000022
1111 1 1 1 0 0 000011")))
+(context-coloring-test-deftest-emacs-lisp cond
+ (lambda ()
+ (context-coloring-test-assert-coloring "
+(xxx (x)
+ 11111
+ 11 11
+ 10000 11
+ 1111 1 00001 11
+ 11 11111 1 000011
+ cc c
+ sss1)")))
+
+(context-coloring-test-deftest-emacs-lisp condition-case
+ (lambda ()
+ (context-coloring-test-assert-coloring "
+1111111111-1111 111
+ 111111 000 00001
+ 111111 111 00001
+ 1111111 111111 111 000011
+
+(111111111-1111-111111-11111 111
+ cc c
+ (xxx () 222)
+ (11111 (xxx () 222))
+ sss)")))
+
+(context-coloring-test-deftest-emacs-lisp dolist
+ (lambda ()
+ (context-coloring-test-assert-coloring "
+1111111 111111
+ 2222222 2222 1111 2222222
+ 3333333 33 33 222 1111 2222223321")))
+
(defun context-coloring-test-insert-unread-space ()
"Simulate the insertion of a space as if by a user."
(setq unread-command-events (cons '(t . 32)
cc `CC' `CC'
nnnnnn n nnn"))))
+(context-coloring-test-deftest-emacs-lisp changed
+ (lambda ()
+ (context-coloring-test-remove-faces)
+ ;; Goto line 3.
+ (goto-char (point-min))
+ (forward-line (1- 3))
+ (insert " ")
+ ;; Mock `pos-visible-in-window-p' because in batch mode `get-buffer-window'
+ ;; returns nil. Emacs must not have a window in that environment.
+ (cl-letf (((symbol-function 'pos-visible-in-window-p)
+ (let ((calls 0))
+ (lambda ()
+ (prog1
+ ;; First and third calls start from center. Second and
+ ;; fourth calls are made immediately after moving past
+ ;; the first defun in either direction "off screen".
+ (cond
+ ((= calls 0) t)
+ ((= calls 1) nil)
+ ((= calls 2) t)
+ ((= calls 4) nil))
+ (setq calls (1+ calls)))))))
+ (context-coloring-colorize))
+ (context-coloring-test-assert-coloring "
+nnnn n nnn nnnnnnnn
+0000
+
+0000
+nnnnn n nnn nnnnnnnn")))
+
+(context-coloring-test-deftest-emacs-lisp unbalanced-parenthesis
+ (lambda ()
+ (context-coloring-test-assert-coloring "
+1111 111
+nnnn nn")))
+
+(context-coloring-test-deftest-eval-expression let
+ (lambda ()
+ (minibuffer-with-setup-hook
+ (lambda ()
+ ;; Perform the test in a hook as it's the only way I know of examining
+ ;; the minibuffer's contents. The contents are implicitly submitted,
+ ;; so we have to ignore the errors in the arbitrary test subject code.
+ (insert "(ignore-errors (let (a) (message a free)))")
+ (context-coloring-colorize)
+ (context-coloring-test-assert-coloring "
+xxxx: 0000000-000000 1111 111 11111111 1 0000110"))
+ ;; Simulate user input because `call-interactively' is blocking and
+ ;; doesn't seem to run the hook.
+ (execute-kbd-macro
+ (vconcat
+ [?\C-u] ;; Don't output the result of the arbitrary test subject code.
+ [?\M-:])))))
+
(provide 'context-coloring-test)
;;; context-coloring-test.el ends here