diff options
| author | Christian Ohler | 2011-01-13 03:08:24 +1100 |
|---|---|---|
| committer | Christian Ohler | 2011-01-13 03:08:24 +1100 |
| commit | d221e7808c01fdc9234734f95ecf49e902085ddd (patch) | |
| tree | 09d270adbfdeada366ecd2328b2660a75358dd0c /test | |
| parent | 03d32f1b2263270b75a0b3324c52c39965345665 (diff) | |
| download | emacs-d221e7808c01fdc9234734f95ecf49e902085ddd.tar.gz emacs-d221e7808c01fdc9234734f95ecf49e902085ddd.zip | |
Add ERT, a tool for automated testing in Emacs Lisp.
* Makefile.in, configure.in, doc/misc/Makefile.in, doc/misc/makefile.w32-in:
Add ERT. Make "make check" run tests in test/automated.
* doc/misc/ert.texi, lisp/emacs-lisp/ert.el, lisp/emacs-lisp/ert-x.el:
New files.
* test/automated: New directory.
Diffstat (limited to 'test')
| -rw-r--r-- | test/ChangeLog | 8 | ||||
| -rw-r--r-- | test/automated/Makefile.in | 158 | ||||
| -rw-r--r-- | test/automated/ert-tests.el | 949 | ||||
| -rw-r--r-- | test/automated/ert-x-tests.el | 273 |
4 files changed, 1388 insertions, 0 deletions
diff --git a/test/ChangeLog b/test/ChangeLog index 3b1921c5987..695a51b7f4f 100644 --- a/test/ChangeLog +++ b/test/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2011-01-13 Christian Ohler <ohler@gnu.org> | ||
| 2 | |||
| 3 | * automated: New directory for automated tests. | ||
| 4 | |||
| 5 | * automated/ert-tests.el, automated/ert-x-tests.el: New files. | ||
| 6 | |||
| 7 | * automated/Makefile.in: New file. | ||
| 8 | |||
| 1 | 2010-11-11 Stefan Monnier <monnier@iro.umontreal.ca> | 9 | 2010-11-11 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 10 | ||
| 3 | * indent/modula2.mod: New file. | 11 | * indent/modula2.mod: New file. |
diff --git a/test/automated/Makefile.in b/test/automated/Makefile.in new file mode 100644 index 00000000000..80a853056b1 --- /dev/null +++ b/test/automated/Makefile.in | |||
| @@ -0,0 +1,158 @@ | |||
| 1 | # Maintenance productions for the automated test directory | ||
| 2 | # Copyright (C) 2010, 2011 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | # This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | # GNU Emacs is free software: you can redistribute it and/or modify | ||
| 7 | # it under the terms of the GNU General Public License as published by | ||
| 8 | # the Free Software Foundation, either version 3 of the License, or | ||
| 9 | # (at your option) any later version. | ||
| 10 | |||
| 11 | # GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | # GNU General Public License for more details. | ||
| 15 | |||
| 16 | # You should have received a copy of the GNU General Public License | ||
| 17 | # along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | |||
| 19 | SHELL = /bin/sh | ||
| 20 | |||
| 21 | srcdir = @srcdir@ | ||
| 22 | top_srcdir = @top_srcdir@ | ||
| 23 | abs_top_builddir = @abs_top_builddir@ | ||
| 24 | test = $(srcdir) | ||
| 25 | VPATH = $(srcdir) | ||
| 26 | lispsrc = $(top_srcdir)/lisp | ||
| 27 | lisp = ${abs_top_builddir}/lisp | ||
| 28 | |||
| 29 | # You can specify a different executable on the make command line, | ||
| 30 | # e.g. "make EMACS=../src/emacs ...". | ||
| 31 | |||
| 32 | # We sometimes change directory before running Emacs (typically when | ||
| 33 | # building out-of-tree, we chdir to the source directory), so we need | ||
| 34 | # to use an absolute file name. | ||
| 35 | EMACS = ${abs_top_builddir}/src/emacs | ||
| 36 | |||
| 37 | # Command line flags for Emacs. | ||
| 38 | |||
| 39 | EMACSOPT = -batch --no-site-file --no-site-lisp | ||
| 40 | |||
| 41 | # Extra flags to pass to the byte compiler | ||
| 42 | BYTE_COMPILE_EXTRA_FLAGS = | ||
| 43 | # For example to not display the undefined function warnings you can use this: | ||
| 44 | # BYTE_COMPILE_EXTRA_FLAGS = --eval '(setq byte-compile-warnings (quote (not unresolved)))' | ||
| 45 | # The example above is just for developers, it should not be used by default. | ||
| 46 | |||
| 47 | # The actual Emacs command run in the targets below. | ||
| 48 | emacs = EMACSLOADPATH=$(lispsrc):$(test) LC_ALL=C $(EMACS) $(EMACSOPT) | ||
| 49 | |||
| 50 | # Common command to find subdirectories | ||
| 51 | setwins=subdirs=`(find . -type d -print)`; \ | ||
| 52 | for file in $$subdirs; do \ | ||
| 53 | case $$file in */.* | */.*/* | */=* ) ;; \ | ||
| 54 | *) wins="$$wins $$file" ;; \ | ||
| 55 | esac; \ | ||
| 56 | done | ||
| 57 | |||
| 58 | all: test | ||
| 59 | |||
| 60 | doit: | ||
| 61 | |||
| 62 | |||
| 63 | # Files MUST be compiled one by one. If we compile several files in a | ||
| 64 | # row (i.e., in the same instance of Emacs) we can't make sure that | ||
| 65 | # the compilation environment is clean. We also set the load-path of | ||
| 66 | # the Emacs used for compilation to the current directory and its | ||
| 67 | # subdirectories, to make sure require's and load's in the files being | ||
| 68 | # compiled find the right files. | ||
| 69 | |||
| 70 | .SUFFIXES: .elc .el | ||
| 71 | |||
| 72 | # An old-fashioned suffix rule, which, according to the GNU Make manual, | ||
| 73 | # cannot have prerequisites. | ||
| 74 | .el.elc: | ||
| 75 | @echo Compiling $< | ||
| 76 | @$(emacs) $(BYTE_COMPILE_EXTRA_FLAGS) -f batch-byte-compile $< | ||
| 77 | |||
| 78 | .PHONY: lisp-compile compile-main compile compile-always | ||
| 79 | |||
| 80 | lisp-compile: | ||
| 81 | cd $(lisp); $(MAKE) $(MFLAGS) compile EMACS=$(EMACS) | ||
| 82 | |||
| 83 | # In `compile-main' we could directly do | ||
| 84 | # ... | xargs $(MAKE) $(MFLAGS) EMACS="$(EMACS)" | ||
| 85 | # and it works, but it generates a lot of messages like | ||
| 86 | # make[2]: « gnus/gnus-mlspl.elc » is up to date. | ||
| 87 | # so instead, we use "xargs echo" to split the list of file into manageable | ||
| 88 | # chunks and then use an intermediate `compile-targets' target so the | ||
| 89 | # actual targets (the .elc files) are not mentioned as targets on the | ||
| 90 | # make command line. | ||
| 91 | |||
| 92 | |||
| 93 | .PHONY: compile-targets | ||
| 94 | # TARGETS is set dynamically in the recursive call from `compile-main'. | ||
| 95 | compile-targets: $(TARGETS) | ||
| 96 | |||
| 97 | # Compile all the Elisp files that need it. Beware: it approximates | ||
| 98 | # `no-byte-compile', so watch out for false-positives! | ||
| 99 | compile-main: compile-clean lisp-compile | ||
| 100 | @(cd $(test); $(setwins); \ | ||
| 101 | els=`echo "$$wins " | sed -e 's|/\./|/|g' -e 's|/\. | |g' -e 's| |/*.el |g'`; \ | ||
| 102 | for el in $$els; do \ | ||
| 103 | test -f $$el || continue; \ | ||
| 104 | test ! -f $${el}c && GREP_OPTIONS= grep '^;.*no-byte-compile: t' $$el > /dev/null && continue; \ | ||
| 105 | echo "$${el}c"; \ | ||
| 106 | done | xargs echo) | \ | ||
| 107 | while read chunk; do \ | ||
| 108 | $(MAKE) $(MFLAGS) compile-targets EMACS="$(EMACS)" TARGETS="$$chunk"; \ | ||
| 109 | done | ||
| 110 | |||
| 111 | .PHONY: compile-clean | ||
| 112 | # Erase left-over .elc files that do not have a corresponding .el file. | ||
| 113 | compile-clean: | ||
| 114 | @cd $(test); $(setwins); \ | ||
| 115 | elcs=`echo "$$wins " | sed -e 's|/\./|/|g' -e 's|/\. | |g' -e 's| |/*.elc |g'`; \ | ||
| 116 | for el in $$(echo $$elcs | sed -e 's/\.elc/\.el/g'); do \ | ||
| 117 | if test -f "$$el" -o \! -f "$${el}c"; then :; else \ | ||
| 118 | echo rm "$${el}c"; \ | ||
| 119 | rm "$${el}c"; \ | ||
| 120 | fi \ | ||
| 121 | done | ||
| 122 | |||
| 123 | # Compile all Lisp files, but don't recompile those that are up to | ||
| 124 | # date. Some .el files don't get compiled because they set the | ||
| 125 | # local variable no-byte-compile. | ||
| 126 | # Calling make recursively because suffix rule cannot have prerequisites. | ||
| 127 | # Explicitly pass EMACS (sometimes ../src/bootstrap-emacs) to those | ||
| 128 | # sub-makes that run rules that use it, for the sake of some non-GNU makes. | ||
| 129 | compile: $(LOADDEFS) autoloads compile-first | ||
| 130 | $(MAKE) $(MFLAGS) compile-main EMACS=$(EMACS) | ||
| 131 | |||
| 132 | # Compile all Lisp files. This is like `compile' but compiles files | ||
| 133 | # unconditionally. Some files don't actually get compiled because they | ||
| 134 | # set the local variable no-byte-compile. | ||
| 135 | compile-always: doit | ||
| 136 | cd $(test); rm -f *.elc */*.elc */*/*.elc */*/*/*.elc | ||
| 137 | $(MAKE) $(MFLAGS) compile EMACS=$(EMACS) | ||
| 138 | |||
| 139 | bootstrap-clean: | ||
| 140 | cd $(test); rm -f *.elc */*.elc */*/*.elc */*/*/*.elc | ||
| 141 | |||
| 142 | distclean: | ||
| 143 | -rm -f ./Makefile | ||
| 144 | |||
| 145 | maintainer-clean: distclean bootstrap-clean | ||
| 146 | |||
| 147 | check: compile-main | ||
| 148 | @(cd $(test); $(setwins); \ | ||
| 149 | pattern=`echo "$$wins " | sed -e 's|/\./|/|g' -e 's|/\. | |g' -e 's| |/*.el |g'`; \ | ||
| 150 | for el in $$pattern; do \ | ||
| 151 | test -f $$el || continue; \ | ||
| 152 | args="$$args -l $$el"; \ | ||
| 153 | els="$$els $$el"; \ | ||
| 154 | done; \ | ||
| 155 | echo Testing $$els; \ | ||
| 156 | $(emacs) $$args -f ert-run-tests-batch-and-exit) | ||
| 157 | |||
| 158 | # Makefile ends here. | ||
diff --git a/test/automated/ert-tests.el b/test/automated/ert-tests.el new file mode 100644 index 00000000000..3c9e2fef0c7 --- /dev/null +++ b/test/automated/ert-tests.el | |||
| @@ -0,0 +1,949 @@ | |||
| 1 | ;;; ert-tests.el --- ERT's self-tests | ||
| 2 | |||
| 3 | ;; Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Christian Ohler <ohler@gnu.org> | ||
| 6 | |||
| 7 | ;; This file is part of GNU Emacs. | ||
| 8 | |||
| 9 | ;; This program is free software: you can redistribute it and/or | ||
| 10 | ;; modify it under the terms of the GNU General Public License as | ||
| 11 | ;; published by the Free Software Foundation, either version 3 of the | ||
| 12 | ;; License, or (at your option) any later version. | ||
| 13 | ;; | ||
| 14 | ;; This program is distributed in the hope that it will be useful, but | ||
| 15 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | ;; General Public License for more details. | ||
| 18 | ;; | ||
| 19 | ;; You should have received a copy of the GNU General Public License | ||
| 20 | ;; along with this program. If not, see `http://www.gnu.org/licenses/'. | ||
| 21 | |||
| 22 | ;;; Commentary: | ||
| 23 | |||
| 24 | ;; This file is part of ERT, the Emacs Lisp Regression Testing tool. | ||
| 25 | ;; See ert.el or the texinfo manual for more details. | ||
| 26 | |||
| 27 | ;;; Code: | ||
| 28 | |||
| 29 | (eval-when-compile | ||
| 30 | (require 'cl)) | ||
| 31 | (require 'ert) | ||
| 32 | |||
| 33 | |||
| 34 | ;;; Self-test that doesn't rely on ERT, for bootstrapping. | ||
| 35 | |||
| 36 | ;; This is used to test that bodies actually run. | ||
| 37 | (defvar ert--test-body-was-run) | ||
| 38 | (ert-deftest ert-test-body-runs () | ||
| 39 | (setq ert--test-body-was-run t)) | ||
| 40 | |||
| 41 | (defun ert-self-test () | ||
| 42 | "Run ERT's self-tests and make sure they actually ran." | ||
| 43 | (let ((window-configuration (current-window-configuration))) | ||
| 44 | (let ((ert--test-body-was-run nil)) | ||
| 45 | ;; The buffer name chosen here should not compete with the default | ||
| 46 | ;; results buffer name for completion in `switch-to-buffer'. | ||
| 47 | (let ((stats (ert-run-tests-interactively "^ert-" " *ert self-tests*"))) | ||
| 48 | (assert ert--test-body-was-run) | ||
| 49 | (if (zerop (ert-stats-completed-unexpected stats)) | ||
| 50 | ;; Hide results window only when everything went well. | ||
| 51 | (set-window-configuration window-configuration) | ||
| 52 | (error "ERT self-test failed")))))) | ||
| 53 | |||
| 54 | (defun ert-self-test-and-exit () | ||
| 55 | "Run ERT's self-tests and exit Emacs. | ||
| 56 | |||
| 57 | The exit code will be zero if the tests passed, nonzero if they | ||
| 58 | failed or if there was a problem." | ||
| 59 | (unwind-protect | ||
| 60 | (progn | ||
| 61 | (ert-self-test) | ||
| 62 | (kill-emacs 0)) | ||
| 63 | (unwind-protect | ||
| 64 | (progn | ||
| 65 | (message "Error running tests") | ||
| 66 | (backtrace)) | ||
| 67 | (kill-emacs 1)))) | ||
| 68 | |||
| 69 | |||
| 70 | ;;; Further tests are defined using ERT. | ||
| 71 | |||
| 72 | (ert-deftest ert-test-nested-test-body-runs () | ||
| 73 | "Test that nested test bodies run." | ||
| 74 | (lexical-let ((was-run nil)) | ||
| 75 | (let ((test (make-ert-test :body (lambda () | ||
| 76 | (setq was-run t))))) | ||
| 77 | (assert (not was-run)) | ||
| 78 | (ert-run-test test) | ||
| 79 | (assert was-run)))) | ||
| 80 | |||
| 81 | |||
| 82 | ;;; Test that pass/fail works. | ||
| 83 | (ert-deftest ert-test-pass () | ||
| 84 | (let ((test (make-ert-test :body (lambda ())))) | ||
| 85 | (let ((result (ert-run-test test))) | ||
| 86 | (assert (ert-test-passed-p result))))) | ||
| 87 | |||
| 88 | (ert-deftest ert-test-fail () | ||
| 89 | (let ((test (make-ert-test :body (lambda () (ert-fail "failure message"))))) | ||
| 90 | (let ((result (let ((ert-debug-on-error nil)) | ||
| 91 | (ert-run-test test)))) | ||
| 92 | (assert (ert-test-failed-p result) t) | ||
| 93 | (assert (equal (ert-test-result-with-condition-condition result) | ||
| 94 | '(ert-test-failed "failure message")) | ||
| 95 | t)))) | ||
| 96 | |||
| 97 | (ert-deftest ert-test-fail-debug-with-condition-case () | ||
| 98 | (let ((test (make-ert-test :body (lambda () (ert-fail "failure message"))))) | ||
| 99 | (condition-case condition | ||
| 100 | (progn | ||
| 101 | (let ((ert-debug-on-error t)) | ||
| 102 | (ert-run-test test)) | ||
| 103 | (assert nil)) | ||
| 104 | ((error) | ||
| 105 | (assert (equal condition '(ert-test-failed "failure message")) t))))) | ||
| 106 | |||
| 107 | (ert-deftest ert-test-fail-debug-with-debugger-1 () | ||
| 108 | (let ((test (make-ert-test :body (lambda () (ert-fail "failure message"))))) | ||
| 109 | (let ((debugger (lambda (&rest debugger-args) | ||
| 110 | (assert nil)))) | ||
| 111 | (let ((ert-debug-on-error nil)) | ||
| 112 | (ert-run-test test))))) | ||
| 113 | |||
| 114 | (ert-deftest ert-test-fail-debug-with-debugger-2 () | ||
| 115 | (let ((test (make-ert-test :body (lambda () (ert-fail "failure message"))))) | ||
| 116 | (block nil | ||
| 117 | (let ((debugger (lambda (&rest debugger-args) | ||
| 118 | (return-from nil nil)))) | ||
| 119 | (let ((ert-debug-on-error t)) | ||
| 120 | (ert-run-test test)) | ||
| 121 | (assert nil))))) | ||
| 122 | |||
| 123 | (ert-deftest ert-test-fail-debug-nested-with-debugger () | ||
| 124 | (let ((test (make-ert-test :body (lambda () | ||
| 125 | (let ((ert-debug-on-error t)) | ||
| 126 | (ert-fail "failure message")))))) | ||
| 127 | (let ((debugger (lambda (&rest debugger-args) | ||
| 128 | (assert nil nil "Assertion a")))) | ||
| 129 | (let ((ert-debug-on-error nil)) | ||
| 130 | (ert-run-test test)))) | ||
| 131 | (let ((test (make-ert-test :body (lambda () | ||
| 132 | (let ((ert-debug-on-error nil)) | ||
| 133 | (ert-fail "failure message")))))) | ||
| 134 | (block nil | ||
| 135 | (let ((debugger (lambda (&rest debugger-args) | ||
| 136 | (return-from nil nil)))) | ||
| 137 | (let ((ert-debug-on-error t)) | ||
| 138 | (ert-run-test test)) | ||
| 139 | (assert nil nil "Assertion b"))))) | ||
| 140 | |||
| 141 | (ert-deftest ert-test-error () | ||
| 142 | (let ((test (make-ert-test :body (lambda () (error "Error message"))))) | ||
| 143 | (let ((result (let ((ert-debug-on-error nil)) | ||
| 144 | (ert-run-test test)))) | ||
| 145 | (assert (ert-test-failed-p result) t) | ||
| 146 | (assert (equal (ert-test-result-with-condition-condition result) | ||
| 147 | '(error "Error message")) | ||
| 148 | t)))) | ||
| 149 | |||
| 150 | (ert-deftest ert-test-error-debug () | ||
| 151 | (let ((test (make-ert-test :body (lambda () (error "Error message"))))) | ||
| 152 | (condition-case condition | ||
| 153 | (progn | ||
| 154 | (let ((ert-debug-on-error t)) | ||
| 155 | (ert-run-test test)) | ||
| 156 | (assert nil)) | ||
| 157 | ((error) | ||
| 158 | (assert (equal condition '(error "Error message")) t))))) | ||
| 159 | |||
| 160 | |||
| 161 | ;;; Test that `should' works. | ||
| 162 | (ert-deftest ert-test-should () | ||
| 163 | (let ((test (make-ert-test :body (lambda () (should nil))))) | ||
| 164 | (let ((result (let ((ert-debug-on-error nil)) | ||
| 165 | (ert-run-test test)))) | ||
| 166 | (assert (ert-test-failed-p result) t) | ||
| 167 | (assert (equal (ert-test-result-with-condition-condition result) | ||
| 168 | '(ert-test-failed ((should nil) :form nil :value nil))) | ||
| 169 | t))) | ||
| 170 | (let ((test (make-ert-test :body (lambda () (should t))))) | ||
| 171 | (let ((result (ert-run-test test))) | ||
| 172 | (assert (ert-test-passed-p result) t)))) | ||
| 173 | |||
| 174 | (ert-deftest ert-test-should-value () | ||
| 175 | (should (eql (should 'foo) 'foo)) | ||
| 176 | (should (eql (should 'bar) 'bar))) | ||
| 177 | |||
| 178 | (ert-deftest ert-test-should-not () | ||
| 179 | (let ((test (make-ert-test :body (lambda () (should-not t))))) | ||
| 180 | (let ((result (let ((ert-debug-on-error nil)) | ||
| 181 | (ert-run-test test)))) | ||
| 182 | (assert (ert-test-failed-p result) t) | ||
| 183 | (assert (equal (ert-test-result-with-condition-condition result) | ||
| 184 | '(ert-test-failed ((should-not t) :form t :value t))) | ||
| 185 | t))) | ||
| 186 | (let ((test (make-ert-test :body (lambda () (should-not nil))))) | ||
| 187 | (let ((result (ert-run-test test))) | ||
| 188 | (assert (ert-test-passed-p result))))) | ||
| 189 | |||
| 190 | (ert-deftest ert-test-should-with-macrolet () | ||
| 191 | (let ((test (make-ert-test :body (lambda () | ||
| 192 | (macrolet ((foo () `(progn t nil))) | ||
| 193 | (should (foo))))))) | ||
| 194 | (let ((result (let ((ert-debug-on-error nil)) | ||
| 195 | (ert-run-test test)))) | ||
| 196 | (should (ert-test-failed-p result)) | ||
| 197 | (should (equal | ||
| 198 | (ert-test-result-with-condition-condition result) | ||
| 199 | '(ert-test-failed ((should (foo)) | ||
| 200 | :form (progn t nil) | ||
| 201 | :value nil))))))) | ||
| 202 | |||
| 203 | (ert-deftest ert-test-should-error () | ||
| 204 | ;; No error. | ||
| 205 | (let ((test (make-ert-test :body (lambda () (should-error (progn)))))) | ||
| 206 | (let ((result (let ((ert-debug-on-error nil)) | ||
| 207 | (ert-run-test test)))) | ||
| 208 | (should (ert-test-failed-p result)) | ||
| 209 | (should (equal (ert-test-result-with-condition-condition result) | ||
| 210 | '(ert-test-failed | ||
| 211 | ((should-error (progn)) | ||
| 212 | :form (progn) | ||
| 213 | :value nil | ||
| 214 | :fail-reason "did not signal an error")))))) | ||
| 215 | ;; A simple error. | ||
| 216 | (should (equal (should-error (error "Foo")) | ||
| 217 | '(error "Foo"))) | ||
| 218 | ;; Error of unexpected type. | ||
| 219 | (let ((test (make-ert-test :body (lambda () | ||
| 220 | (should-error (error "Foo") | ||
| 221 | :type 'singularity-error))))) | ||
| 222 | (let ((result (ert-run-test test))) | ||
| 223 | (should (ert-test-failed-p result)) | ||
| 224 | (should (equal | ||
| 225 | (ert-test-result-with-condition-condition result) | ||
| 226 | '(ert-test-failed | ||
| 227 | ((should-error (error "Foo") :type 'singularity-error) | ||
| 228 | :form (error "Foo") | ||
| 229 | :condition (error "Foo") | ||
| 230 | :fail-reason | ||
| 231 | "the error signalled did not have the expected type")))))) | ||
| 232 | ;; Error of the expected type. | ||
| 233 | (let* ((error nil) | ||
| 234 | (test (make-ert-test | ||
| 235 | :body (lambda () | ||
| 236 | (setq error | ||
| 237 | (should-error (signal 'singularity-error nil) | ||
| 238 | :type 'singularity-error)))))) | ||
| 239 | (let ((result (ert-run-test test))) | ||
| 240 | (should (ert-test-passed-p result)) | ||
| 241 | (should (equal error '(singularity-error)))))) | ||
| 242 | |||
| 243 | (ert-deftest ert-test-should-error-subtypes () | ||
| 244 | (should-error (signal 'singularity-error nil) | ||
| 245 | :type 'singularity-error | ||
| 246 | :exclude-subtypes t) | ||
| 247 | (let ((test (make-ert-test | ||
| 248 | :body (lambda () | ||
| 249 | (should-error (signal 'arith-error nil) | ||
| 250 | :type 'singularity-error))))) | ||
| 251 | (let ((result (ert-run-test test))) | ||
| 252 | (should (ert-test-failed-p result)) | ||
| 253 | (should (equal | ||
| 254 | (ert-test-result-with-condition-condition result) | ||
| 255 | '(ert-test-failed | ||
| 256 | ((should-error (signal 'arith-error nil) | ||
| 257 | :type 'singularity-error) | ||
| 258 | :form (signal arith-error nil) | ||
| 259 | :condition (arith-error) | ||
| 260 | :fail-reason | ||
| 261 | "the error signalled did not have the expected type")))))) | ||
| 262 | (let ((test (make-ert-test | ||
| 263 | :body (lambda () | ||
| 264 | (should-error (signal 'arith-error nil) | ||
| 265 | :type 'singularity-error | ||
| 266 | :exclude-subtypes t))))) | ||
| 267 | (let ((result (ert-run-test test))) | ||
| 268 | (should (ert-test-failed-p result)) | ||
| 269 | (should (equal | ||
| 270 | (ert-test-result-with-condition-condition result) | ||
| 271 | '(ert-test-failed | ||
| 272 | ((should-error (signal 'arith-error nil) | ||
| 273 | :type 'singularity-error | ||
| 274 | :exclude-subtypes t) | ||
| 275 | :form (signal arith-error nil) | ||
| 276 | :condition (arith-error) | ||
| 277 | :fail-reason | ||
| 278 | "the error signalled did not have the expected type")))))) | ||
| 279 | (let ((test (make-ert-test | ||
| 280 | :body (lambda () | ||
| 281 | (should-error (signal 'singularity-error nil) | ||
| 282 | :type 'arith-error | ||
| 283 | :exclude-subtypes t))))) | ||
| 284 | (let ((result (ert-run-test test))) | ||
| 285 | (should (ert-test-failed-p result)) | ||
| 286 | (should (equal | ||
| 287 | (ert-test-result-with-condition-condition result) | ||
| 288 | '(ert-test-failed | ||
| 289 | ((should-error (signal 'singularity-error nil) | ||
| 290 | :type 'arith-error | ||
| 291 | :exclude-subtypes t) | ||
| 292 | :form (signal singularity-error nil) | ||
| 293 | :condition (singularity-error) | ||
| 294 | :fail-reason | ||
| 295 | "the error signalled was a subtype of the expected type"))))) | ||
| 296 | )) | ||
| 297 | |||
| 298 | (defmacro ert--test-my-list (&rest args) | ||
| 299 | "Don't use this. Instead, call `list' with ARGS, it does the same thing. | ||
| 300 | |||
| 301 | This macro is used to test if macroexpansion in `should' works." | ||
| 302 | `(list ,@args)) | ||
| 303 | |||
| 304 | (ert-deftest ert-test-should-failure-debugging () | ||
| 305 | "Test that `should' errors contain the information we expect them to." | ||
| 306 | (loop for (body expected-condition) in | ||
| 307 | `((,(lambda () (let ((x nil)) (should x))) | ||
| 308 | (ert-test-failed ((should x) :form x :value nil))) | ||
| 309 | (,(lambda () (let ((x t)) (should-not x))) | ||
| 310 | (ert-test-failed ((should-not x) :form x :value t))) | ||
| 311 | (,(lambda () (let ((x t)) (should (not x)))) | ||
| 312 | (ert-test-failed ((should (not x)) :form (not t) :value nil))) | ||
| 313 | (,(lambda () (let ((x nil)) (should-not (not x)))) | ||
| 314 | (ert-test-failed ((should-not (not x)) :form (not nil) :value t))) | ||
| 315 | (,(lambda () (let ((x t) (y nil)) (should-not | ||
| 316 | (ert--test-my-list x y)))) | ||
| 317 | (ert-test-failed | ||
| 318 | ((should-not (ert--test-my-list x y)) | ||
| 319 | :form (list t nil) | ||
| 320 | :value (t nil)))) | ||
| 321 | (,(lambda () (let ((x t)) (should (error "Foo")))) | ||
| 322 | (error "Foo"))) | ||
| 323 | do | ||
| 324 | (let ((test (make-ert-test :body body))) | ||
| 325 | (condition-case actual-condition | ||
| 326 | (progn | ||
| 327 | (let ((ert-debug-on-error t)) | ||
| 328 | (ert-run-test test)) | ||
| 329 | (assert nil)) | ||
| 330 | ((error) | ||
| 331 | (should (equal actual-condition expected-condition))))))) | ||
| 332 | |||
| 333 | (ert-deftest ert-test-deftest () | ||
| 334 | (should (equal (macroexpand '(ert-deftest abc () "foo" :tags '(bar))) | ||
| 335 | '(progn | ||
| 336 | (ert-set-test 'abc | ||
| 337 | (make-ert-test :name 'abc | ||
| 338 | :documentation "foo" | ||
| 339 | :tags '(bar) | ||
| 340 | :body (lambda ()))) | ||
| 341 | (push '(ert-deftest . abc) current-load-list) | ||
| 342 | 'abc))) | ||
| 343 | (should (equal (macroexpand '(ert-deftest def () | ||
| 344 | :expected-result ':passed)) | ||
| 345 | '(progn | ||
| 346 | (ert-set-test 'def | ||
| 347 | (make-ert-test :name 'def | ||
| 348 | :expected-result-type ':passed | ||
| 349 | :body (lambda ()))) | ||
| 350 | (push '(ert-deftest . def) current-load-list) | ||
| 351 | 'def))) | ||
| 352 | ;; :documentation keyword is forbidden | ||
| 353 | (should-error (macroexpand '(ert-deftest ghi () | ||
| 354 | :documentation "foo")))) | ||
| 355 | |||
| 356 | (ert-deftest ert-test-record-backtrace () | ||
| 357 | (let ((test (make-ert-test :body (lambda () (ert-fail "foo"))))) | ||
| 358 | (let ((result (ert-run-test test))) | ||
| 359 | (should (ert-test-failed-p result)) | ||
| 360 | (with-temp-buffer | ||
| 361 | (ert--print-backtrace (ert-test-failed-backtrace result)) | ||
| 362 | (goto-char (point-min)) | ||
| 363 | (end-of-line) | ||
| 364 | (let ((first-line (buffer-substring-no-properties (point-min) (point)))) | ||
| 365 | (should (equal first-line " signal(ert-test-failed (\"foo\"))"))))))) | ||
| 366 | |||
| 367 | (ert-deftest ert-test-messages () | ||
| 368 | :tags '(:causes-redisplay) | ||
| 369 | (let* ((message-string "Test message") | ||
| 370 | (messages-buffer (get-buffer-create "*Messages*")) | ||
| 371 | (test (make-ert-test :body (lambda () (message "%s" message-string))))) | ||
| 372 | (with-current-buffer messages-buffer | ||
| 373 | (let ((result (ert-run-test test))) | ||
| 374 | (should (equal (concat message-string "\n") | ||
| 375 | (ert-test-result-messages result))))))) | ||
| 376 | |||
| 377 | (ert-deftest ert-test-running-tests () | ||
| 378 | (let ((outer-test (ert-get-test 'ert-test-running-tests))) | ||
| 379 | (should (equal (ert-running-test) outer-test)) | ||
| 380 | (let (test1 test2 test3) | ||
| 381 | (setq test1 (make-ert-test | ||
| 382 | :name "1" | ||
| 383 | :body (lambda () | ||
| 384 | (should (equal (ert-running-test) outer-test)) | ||
| 385 | (should (equal ert--running-tests | ||
| 386 | (list test1 test2 test3 | ||
| 387 | outer-test))))) | ||
| 388 | test2 (make-ert-test | ||
| 389 | :name "2" | ||
| 390 | :body (lambda () | ||
| 391 | (should (equal (ert-running-test) outer-test)) | ||
| 392 | (should (equal ert--running-tests | ||
| 393 | (list test3 test2 outer-test))) | ||
| 394 | (ert-run-test test1))) | ||
| 395 | test3 (make-ert-test | ||
| 396 | :name "3" | ||
| 397 | :body (lambda () | ||
| 398 | (should (equal (ert-running-test) outer-test)) | ||
| 399 | (should (equal ert--running-tests | ||
| 400 | (list test3 outer-test))) | ||
| 401 | (ert-run-test test2)))) | ||
| 402 | (should (ert-test-passed-p (ert-run-test test3)))))) | ||
| 403 | |||
| 404 | (ert-deftest ert-test-test-result-expected-p () | ||
| 405 | "Test `ert-test-result-expected-p' and (implicitly) `ert-test-result-type-p'." | ||
| 406 | ;; passing test | ||
| 407 | (let ((test (make-ert-test :body (lambda ())))) | ||
| 408 | (should (ert-test-result-expected-p test (ert-run-test test)))) | ||
| 409 | ;; unexpected failure | ||
| 410 | (let ((test (make-ert-test :body (lambda () (ert-fail "failed"))))) | ||
| 411 | (should-not (ert-test-result-expected-p test (ert-run-test test)))) | ||
| 412 | ;; expected failure | ||
| 413 | (let ((test (make-ert-test :body (lambda () (ert-fail "failed")) | ||
| 414 | :expected-result-type ':failed))) | ||
| 415 | (should (ert-test-result-expected-p test (ert-run-test test)))) | ||
| 416 | ;; `not' expected type | ||
| 417 | (let ((test (make-ert-test :body (lambda ()) | ||
| 418 | :expected-result-type '(not :failed)))) | ||
| 419 | (should (ert-test-result-expected-p test (ert-run-test test)))) | ||
| 420 | (let ((test (make-ert-test :body (lambda ()) | ||
| 421 | :expected-result-type '(not :passed)))) | ||
| 422 | (should-not (ert-test-result-expected-p test (ert-run-test test)))) | ||
| 423 | ;; `and' expected type | ||
| 424 | (let ((test (make-ert-test :body (lambda ()) | ||
| 425 | :expected-result-type '(and :passed :failed)))) | ||
| 426 | (should-not (ert-test-result-expected-p test (ert-run-test test)))) | ||
| 427 | (let ((test (make-ert-test :body (lambda ()) | ||
| 428 | :expected-result-type '(and :passed | ||
| 429 | (not :failed))))) | ||
| 430 | (should (ert-test-result-expected-p test (ert-run-test test)))) | ||
| 431 | ;; `or' expected type | ||
| 432 | (let ((test (make-ert-test :body (lambda ()) | ||
| 433 | :expected-result-type '(or (and :passed :failed) | ||
| 434 | :passed)))) | ||
| 435 | (should (ert-test-result-expected-p test (ert-run-test test)))) | ||
| 436 | (let ((test (make-ert-test :body (lambda ()) | ||
| 437 | :expected-result-type '(or (and :passed :failed) | ||
| 438 | nil (not t))))) | ||
| 439 | (should-not (ert-test-result-expected-p test (ert-run-test test))))) | ||
| 440 | |||
| 441 | ;;; Test `ert-select-tests'. | ||
| 442 | (ert-deftest ert-test-select-regexp () | ||
| 443 | (should (equal (ert-select-tests "^ert-test-select-regexp$" t) | ||
| 444 | (list (ert-get-test 'ert-test-select-regexp))))) | ||
| 445 | |||
| 446 | (ert-deftest ert-test-test-boundp () | ||
| 447 | (should (ert-test-boundp 'ert-test-test-boundp)) | ||
| 448 | (should-not (ert-test-boundp (make-symbol "ert-not-a-test")))) | ||
| 449 | |||
| 450 | (ert-deftest ert-test-select-member () | ||
| 451 | (should (equal (ert-select-tests '(member ert-test-select-member) t) | ||
| 452 | (list (ert-get-test 'ert-test-select-member))))) | ||
| 453 | |||
| 454 | (ert-deftest ert-test-select-test () | ||
| 455 | (should (equal (ert-select-tests (ert-get-test 'ert-test-select-test) t) | ||
| 456 | (list (ert-get-test 'ert-test-select-test))))) | ||
| 457 | |||
| 458 | (ert-deftest ert-test-select-symbol () | ||
| 459 | (should (equal (ert-select-tests 'ert-test-select-symbol t) | ||
| 460 | (list (ert-get-test 'ert-test-select-symbol))))) | ||
| 461 | |||
| 462 | (ert-deftest ert-test-select-and () | ||
| 463 | (let ((test (make-ert-test | ||
| 464 | :name nil | ||
| 465 | :body nil | ||
| 466 | :most-recent-result (make-ert-test-failed | ||
| 467 | :condition nil | ||
| 468 | :backtrace nil | ||
| 469 | :infos nil)))) | ||
| 470 | (should (equal (ert-select-tests `(and (member ,test) :failed) t) | ||
| 471 | (list test))))) | ||
| 472 | |||
| 473 | (ert-deftest ert-test-select-tag () | ||
| 474 | (let ((test (make-ert-test | ||
| 475 | :name nil | ||
| 476 | :body nil | ||
| 477 | :tags '(a b)))) | ||
| 478 | (should (equal (ert-select-tests `(tag a) (list test)) (list test))) | ||
| 479 | (should (equal (ert-select-tests `(tag b) (list test)) (list test))) | ||
| 480 | (should (equal (ert-select-tests `(tag c) (list test)) '())))) | ||
| 481 | |||
| 482 | |||
| 483 | ;;; Tests for utility functions. | ||
| 484 | (ert-deftest ert-test-proper-list-p () | ||
| 485 | (should (ert--proper-list-p '())) | ||
| 486 | (should (ert--proper-list-p '(1))) | ||
| 487 | (should (ert--proper-list-p '(1 2))) | ||
| 488 | (should (ert--proper-list-p '(1 2 3))) | ||
| 489 | (should (ert--proper-list-p '(1 2 3 4))) | ||
| 490 | (should (not (ert--proper-list-p 'a))) | ||
| 491 | (should (not (ert--proper-list-p '(1 . a)))) | ||
| 492 | (should (not (ert--proper-list-p '(1 2 . a)))) | ||
| 493 | (should (not (ert--proper-list-p '(1 2 3 . a)))) | ||
| 494 | (should (not (ert--proper-list-p '(1 2 3 4 . a)))) | ||
| 495 | (let ((a (list 1))) | ||
| 496 | (setf (cdr (last a)) a) | ||
| 497 | (should (not (ert--proper-list-p a)))) | ||
| 498 | (let ((a (list 1 2))) | ||
| 499 | (setf (cdr (last a)) a) | ||
| 500 | (should (not (ert--proper-list-p a)))) | ||
| 501 | (let ((a (list 1 2 3))) | ||
| 502 | (setf (cdr (last a)) a) | ||
| 503 | (should (not (ert--proper-list-p a)))) | ||
| 504 | (let ((a (list 1 2 3 4))) | ||
| 505 | (setf (cdr (last a)) a) | ||
| 506 | (should (not (ert--proper-list-p a)))) | ||
| 507 | (let ((a (list 1 2))) | ||
| 508 | (setf (cdr (last a)) (cdr a)) | ||
| 509 | (should (not (ert--proper-list-p a)))) | ||
| 510 | (let ((a (list 1 2 3))) | ||
| 511 | (setf (cdr (last a)) (cdr a)) | ||
| 512 | (should (not (ert--proper-list-p a)))) | ||
| 513 | (let ((a (list 1 2 3 4))) | ||
| 514 | (setf (cdr (last a)) (cdr a)) | ||
| 515 | (should (not (ert--proper-list-p a)))) | ||
| 516 | (let ((a (list 1 2 3))) | ||
| 517 | (setf (cdr (last a)) (cddr a)) | ||
| 518 | (should (not (ert--proper-list-p a)))) | ||
| 519 | (let ((a (list 1 2 3 4))) | ||
| 520 | (setf (cdr (last a)) (cddr a)) | ||
| 521 | (should (not (ert--proper-list-p a)))) | ||
| 522 | (let ((a (list 1 2 3 4))) | ||
| 523 | (setf (cdr (last a)) (cdddr a)) | ||
| 524 | (should (not (ert--proper-list-p a))))) | ||
| 525 | |||
| 526 | (ert-deftest ert-test-parse-keys-and-body () | ||
| 527 | (should (equal (ert--parse-keys-and-body '(foo)) '(nil (foo)))) | ||
| 528 | (should (equal (ert--parse-keys-and-body '(:bar foo)) '((:bar foo) nil))) | ||
| 529 | (should (equal (ert--parse-keys-and-body '(:bar foo a (b))) | ||
| 530 | '((:bar foo) (a (b))))) | ||
| 531 | (should (equal (ert--parse-keys-and-body '(:bar foo :a (b))) | ||
| 532 | '((:bar foo :a (b)) nil))) | ||
| 533 | (should (equal (ert--parse-keys-and-body '(bar foo :a (b))) | ||
| 534 | '(nil (bar foo :a (b))))) | ||
| 535 | (should-error (ert--parse-keys-and-body '(:bar foo :a)))) | ||
| 536 | |||
| 537 | |||
| 538 | (ert-deftest ert-test-run-tests-interactively () | ||
| 539 | :tags '(:causes-redisplay) | ||
| 540 | (let ((passing-test (make-ert-test :name 'passing-test | ||
| 541 | :body (lambda () (ert-pass)))) | ||
| 542 | (failing-test (make-ert-test :name 'failing-test | ||
| 543 | :body (lambda () (ert-fail | ||
| 544 | "failure message"))))) | ||
| 545 | (let ((ert-debug-on-error nil)) | ||
| 546 | (let* ((buffer-name (generate-new-buffer-name " *ert-test-run-tests*")) | ||
| 547 | (messages nil) | ||
| 548 | (mock-message-fn | ||
| 549 | (lambda (format-string &rest args) | ||
| 550 | (push (apply #'format format-string args) messages)))) | ||
| 551 | (save-window-excursion | ||
| 552 | (unwind-protect | ||
| 553 | (let ((case-fold-search nil)) | ||
| 554 | (ert-run-tests-interactively | ||
| 555 | `(member ,passing-test ,failing-test) buffer-name | ||
| 556 | mock-message-fn) | ||
| 557 | (should (equal messages `(,(concat | ||
| 558 | "Ran 2 tests, 1 results were " | ||
| 559 | "as expected, 1 unexpected")))) | ||
| 560 | (with-current-buffer buffer-name | ||
| 561 | (goto-char (point-min)) | ||
| 562 | (should (equal | ||
| 563 | (buffer-substring (point-min) | ||
| 564 | (save-excursion | ||
| 565 | (forward-line 4) | ||
| 566 | (point))) | ||
| 567 | (concat | ||
| 568 | "Selector: (member <passing-test> <failing-test>)\n" | ||
| 569 | "Passed: 1\n" | ||
| 570 | "Failed: 1 (1 unexpected)\n" | ||
| 571 | "Total: 2/2\n"))))) | ||
| 572 | (when (get-buffer buffer-name) | ||
| 573 | (kill-buffer buffer-name)))))))) | ||
| 574 | |||
| 575 | (ert-deftest ert-test-special-operator-p () | ||
| 576 | (should (ert--special-operator-p 'if)) | ||
| 577 | (should-not (ert--special-operator-p 'car)) | ||
| 578 | (should-not (ert--special-operator-p 'ert--special-operator-p)) | ||
| 579 | (let ((b (ert--gensym))) | ||
| 580 | (should-not (ert--special-operator-p b)) | ||
| 581 | (fset b 'if) | ||
| 582 | (should (ert--special-operator-p b)))) | ||
| 583 | |||
| 584 | (ert-deftest ert-test-list-of-should-forms () | ||
| 585 | (let ((test (make-ert-test :body (lambda () | ||
| 586 | (should t) | ||
| 587 | (should (null '())) | ||
| 588 | (should nil) | ||
| 589 | (should t))))) | ||
| 590 | (let ((result (let ((ert-debug-on-error nil)) | ||
| 591 | (ert-run-test test)))) | ||
| 592 | (should (equal (ert-test-result-should-forms result) | ||
| 593 | '(((should t) :form t :value t) | ||
| 594 | ((should (null '())) :form (null nil) :value t) | ||
| 595 | ((should nil) :form nil :value nil))))))) | ||
| 596 | |||
| 597 | (ert-deftest ert-test-list-of-should-forms-observers-should-not-stack () | ||
| 598 | (let ((test (make-ert-test | ||
| 599 | :body (lambda () | ||
| 600 | (let ((test2 (make-ert-test | ||
| 601 | :body (lambda () | ||
| 602 | (should t))))) | ||
| 603 | (let ((result (ert-run-test test2))) | ||
| 604 | (should (ert-test-passed-p result)))))))) | ||
| 605 | (let ((result (let ((ert-debug-on-error nil)) | ||
| 606 | (ert-run-test test)))) | ||
| 607 | (should (ert-test-passed-p result)) | ||
| 608 | (should (eql (length (ert-test-result-should-forms result)) | ||
| 609 | 1))))) | ||
| 610 | |||
| 611 | (ert-deftest ert-test-list-of-should-forms-no-deep-copy () | ||
| 612 | (let ((test (make-ert-test :body (lambda () | ||
| 613 | (let ((obj (list 'a))) | ||
| 614 | (should (equal obj '(a))) | ||
| 615 | (setf (car obj) 'b) | ||
| 616 | (should (equal obj '(b)))))))) | ||
| 617 | (let ((result (let ((ert-debug-on-error nil)) | ||
| 618 | (ert-run-test test)))) | ||
| 619 | (should (ert-test-passed-p result)) | ||
| 620 | (should (equal (ert-test-result-should-forms result) | ||
| 621 | '(((should (equal obj '(a))) :form (equal (b) (a)) :value t | ||
| 622 | :explanation nil) | ||
| 623 | ((should (equal obj '(b))) :form (equal (b) (b)) :value t | ||
| 624 | :explanation nil) | ||
| 625 | )))))) | ||
| 626 | |||
| 627 | (ert-deftest ert-test-remprop () | ||
| 628 | (let ((x (ert--gensym))) | ||
| 629 | (should (equal (symbol-plist x) '())) | ||
| 630 | ;; Remove nonexistent property on empty plist. | ||
| 631 | (ert--remprop x 'b) | ||
| 632 | (should (equal (symbol-plist x) '())) | ||
| 633 | (put x 'a 1) | ||
| 634 | (should (equal (symbol-plist x) '(a 1))) | ||
| 635 | ;; Remove nonexistent property on nonempty plist. | ||
| 636 | (ert--remprop x 'b) | ||
| 637 | (should (equal (symbol-plist x) '(a 1))) | ||
| 638 | (put x 'b 2) | ||
| 639 | (put x 'c 3) | ||
| 640 | (put x 'd 4) | ||
| 641 | (should (equal (symbol-plist x) '(a 1 b 2 c 3 d 4))) | ||
| 642 | ;; Remove property that is neither first nor last. | ||
| 643 | (ert--remprop x 'c) | ||
| 644 | (should (equal (symbol-plist x) '(a 1 b 2 d 4))) | ||
| 645 | ;; Remove last property from a plist of length >1. | ||
| 646 | (ert--remprop x 'd) | ||
| 647 | (should (equal (symbol-plist x) '(a 1 b 2))) | ||
| 648 | ;; Remove first property from a plist of length >1. | ||
| 649 | (ert--remprop x 'a) | ||
| 650 | (should (equal (symbol-plist x) '(b 2))) | ||
| 651 | ;; Remove property when there is only one. | ||
| 652 | (ert--remprop x 'b) | ||
| 653 | (should (equal (symbol-plist x) '())))) | ||
| 654 | |||
| 655 | (ert-deftest ert-test-remove-if-not () | ||
| 656 | (let ((list (list 'a 'b 'c 'd)) | ||
| 657 | (i 0)) | ||
| 658 | (let ((result (ert--remove-if-not (lambda (x) | ||
| 659 | (should (eql x (nth i list))) | ||
| 660 | (incf i) | ||
| 661 | (member i '(2 3))) | ||
| 662 | list))) | ||
| 663 | (should (equal i 4)) | ||
| 664 | (should (equal result '(b c))) | ||
| 665 | (should (equal list '(a b c d))))) | ||
| 666 | (should (equal '() | ||
| 667 | (ert--remove-if-not (lambda (x) (should nil)) '())))) | ||
| 668 | |||
| 669 | (ert-deftest ert-test-remove* () | ||
| 670 | (let ((list (list 'a 'b 'c 'd)) | ||
| 671 | (key-index 0) | ||
| 672 | (test-index 0)) | ||
| 673 | (let ((result | ||
| 674 | (ert--remove* 'foo list | ||
| 675 | :key (lambda (x) | ||
| 676 | (should (eql x (nth key-index list))) | ||
| 677 | (prog1 | ||
| 678 | (list key-index x) | ||
| 679 | (incf key-index))) | ||
| 680 | :test | ||
| 681 | (lambda (a b) | ||
| 682 | (should (eql a 'foo)) | ||
| 683 | (should (equal b (list test-index | ||
| 684 | (nth test-index list)))) | ||
| 685 | (incf test-index) | ||
| 686 | (member test-index '(2 3)))))) | ||
| 687 | (should (equal key-index 4)) | ||
| 688 | (should (equal test-index 4)) | ||
| 689 | (should (equal result '(a d))) | ||
| 690 | (should (equal list '(a b c d))))) | ||
| 691 | (let ((x (cons nil nil)) | ||
| 692 | (y (cons nil nil))) | ||
| 693 | (should (equal (ert--remove* x (list x y)) | ||
| 694 | ;; or (list x), since we use `equal' -- the | ||
| 695 | ;; important thing is that only one element got | ||
| 696 | ;; removed, this proves that the default test is | ||
| 697 | ;; `eql', not `equal' | ||
| 698 | (list y))))) | ||
| 699 | |||
| 700 | |||
| 701 | (ert-deftest ert-test-set-functions () | ||
| 702 | (let ((c1 (cons nil nil)) | ||
| 703 | (c2 (cons nil nil)) | ||
| 704 | (sym (make-symbol "a"))) | ||
| 705 | (let ((e '()) | ||
| 706 | (a (list 'a 'b sym nil "" "x" c1 c2)) | ||
| 707 | (b (list c1 'y 'b sym 'x))) | ||
| 708 | (should (equal (ert--set-difference e e) e)) | ||
| 709 | (should (equal (ert--set-difference a e) a)) | ||
| 710 | (should (equal (ert--set-difference e a) e)) | ||
| 711 | (should (equal (ert--set-difference a a) e)) | ||
| 712 | (should (equal (ert--set-difference b e) b)) | ||
| 713 | (should (equal (ert--set-difference e b) e)) | ||
| 714 | (should (equal (ert--set-difference b b) e)) | ||
| 715 | (should (equal (ert--set-difference a b) (list 'a nil "" "x" c2))) | ||
| 716 | (should (equal (ert--set-difference b a) (list 'y 'x))) | ||
| 717 | |||
| 718 | ;; We aren't testing whether this is really using `eq' rather than `eql'. | ||
| 719 | (should (equal (ert--set-difference-eq e e) e)) | ||
| 720 | (should (equal (ert--set-difference-eq a e) a)) | ||
| 721 | (should (equal (ert--set-difference-eq e a) e)) | ||
| 722 | (should (equal (ert--set-difference-eq a a) e)) | ||
| 723 | (should (equal (ert--set-difference-eq b e) b)) | ||
| 724 | (should (equal (ert--set-difference-eq e b) e)) | ||
| 725 | (should (equal (ert--set-difference-eq b b) e)) | ||
| 726 | (should (equal (ert--set-difference-eq a b) (list 'a nil "" "x" c2))) | ||
| 727 | (should (equal (ert--set-difference-eq b a) (list 'y 'x))) | ||
| 728 | |||
| 729 | (should (equal (ert--union e e) e)) | ||
| 730 | (should (equal (ert--union a e) a)) | ||
| 731 | (should (equal (ert--union e a) a)) | ||
| 732 | (should (equal (ert--union a a) a)) | ||
| 733 | (should (equal (ert--union b e) b)) | ||
| 734 | (should (equal (ert--union e b) b)) | ||
| 735 | (should (equal (ert--union b b) b)) | ||
| 736 | (should (equal (ert--union a b) (list 'a 'b sym nil "" "x" c1 c2 'y 'x))) | ||
| 737 | (should (equal (ert--union b a) (list c1 'y 'b sym 'x 'a nil "" "x" c2))) | ||
| 738 | |||
| 739 | (should (equal (ert--intersection e e) e)) | ||
| 740 | (should (equal (ert--intersection a e) e)) | ||
| 741 | (should (equal (ert--intersection e a) e)) | ||
| 742 | (should (equal (ert--intersection a a) a)) | ||
| 743 | (should (equal (ert--intersection b e) e)) | ||
| 744 | (should (equal (ert--intersection e b) e)) | ||
| 745 | (should (equal (ert--intersection b b) b)) | ||
| 746 | (should (equal (ert--intersection a b) (list 'b sym c1))) | ||
| 747 | (should (equal (ert--intersection b a) (list c1 'b sym)))))) | ||
| 748 | |||
| 749 | (ert-deftest ert-test-gensym () | ||
| 750 | ;; Since the expansion of `should' calls `ert--gensym' and thus has a | ||
| 751 | ;; side-effect on `ert--gensym-counter', we have to make sure all | ||
| 752 | ;; macros in our test body are expanded before we rebind | ||
| 753 | ;; `ert--gensym-counter' and run the body. Otherwise, the test would | ||
| 754 | ;; fail if run interpreted. | ||
| 755 | (let ((body (byte-compile | ||
| 756 | '(lambda () | ||
| 757 | (should (equal (symbol-name (ert--gensym)) "G0")) | ||
| 758 | (should (equal (symbol-name (ert--gensym)) "G1")) | ||
| 759 | (should (equal (symbol-name (ert--gensym)) "G2")) | ||
| 760 | (should (equal (symbol-name (ert--gensym "foo")) "foo3")) | ||
| 761 | (should (equal (symbol-name (ert--gensym "bar")) "bar4")) | ||
| 762 | (should (equal ert--gensym-counter 5)))))) | ||
| 763 | (let ((ert--gensym-counter 0)) | ||
| 764 | (funcall body)))) | ||
| 765 | |||
| 766 | (ert-deftest ert-test-coerce-to-vector () | ||
| 767 | (let* ((a (vector)) | ||
| 768 | (b (vector 1 a 3)) | ||
| 769 | (c (list)) | ||
| 770 | (d (list b a))) | ||
| 771 | (should (eql (ert--coerce-to-vector a) a)) | ||
| 772 | (should (eql (ert--coerce-to-vector b) b)) | ||
| 773 | (should (equal (ert--coerce-to-vector c) (vector))) | ||
| 774 | (should (equal (ert--coerce-to-vector d) (vector b a))))) | ||
| 775 | |||
| 776 | (ert-deftest ert-test-string-position () | ||
| 777 | (should (eql (ert--string-position ?x "") nil)) | ||
| 778 | (should (eql (ert--string-position ?a "abc") 0)) | ||
| 779 | (should (eql (ert--string-position ?b "abc") 1)) | ||
| 780 | (should (eql (ert--string-position ?c "abc") 2)) | ||
| 781 | (should (eql (ert--string-position ?d "abc") nil)) | ||
| 782 | (should (eql (ert--string-position ?A "abc") nil))) | ||
| 783 | |||
| 784 | (ert-deftest ert-test-mismatch () | ||
| 785 | (should (eql (ert--mismatch "" "") nil)) | ||
| 786 | (should (eql (ert--mismatch "" "a") 0)) | ||
| 787 | (should (eql (ert--mismatch "a" "a") nil)) | ||
| 788 | (should (eql (ert--mismatch "ab" "a") 1)) | ||
| 789 | (should (eql (ert--mismatch "Aa" "aA") 0)) | ||
| 790 | (should (eql (ert--mismatch '(a b c) '(a b d)) 2))) | ||
| 791 | |||
| 792 | (ert-deftest ert-test-string-first-line () | ||
| 793 | (should (equal (ert--string-first-line "") "")) | ||
| 794 | (should (equal (ert--string-first-line "abc") "abc")) | ||
| 795 | (should (equal (ert--string-first-line "abc\n") "abc")) | ||
| 796 | (should (equal (ert--string-first-line "foo\nbar") "foo")) | ||
| 797 | (should (equal (ert--string-first-line " foo\nbar\nbaz\n") " foo"))) | ||
| 798 | |||
| 799 | (ert-deftest ert-test-explain-not-equal () | ||
| 800 | (should (equal (ert--explain-not-equal nil 'foo) | ||
| 801 | '(different-atoms nil foo))) | ||
| 802 | (should (equal (ert--explain-not-equal '(a a) '(a b)) | ||
| 803 | '(list-elt 1 (different-atoms a b)))) | ||
| 804 | (should (equal (ert--explain-not-equal '(1 48) '(1 49)) | ||
| 805 | '(list-elt 1 (different-atoms (48 "#x30" "?0") | ||
| 806 | (49 "#x31" "?1"))))) | ||
| 807 | (should (equal (ert--explain-not-equal 'nil '(a)) | ||
| 808 | '(different-types nil (a)))) | ||
| 809 | (should (equal (ert--explain-not-equal '(a b c) '(a b c d)) | ||
| 810 | '(proper-lists-of-different-length 3 4 (a b c) (a b c d) | ||
| 811 | first-mismatch-at 3))) | ||
| 812 | (let ((sym (make-symbol "a"))) | ||
| 813 | (should (equal (ert--explain-not-equal 'a sym) | ||
| 814 | `(different-symbols-with-the-same-name a ,sym))))) | ||
| 815 | |||
| 816 | (ert-deftest ert-test-explain-not-equal-improper-list () | ||
| 817 | (should (equal (ert--explain-not-equal '(a . b) '(a . c)) | ||
| 818 | '(cdr (different-atoms b c))))) | ||
| 819 | |||
| 820 | (ert-deftest ert-test-significant-plist-keys () | ||
| 821 | (should (equal (ert--significant-plist-keys '()) '())) | ||
| 822 | (should (equal (ert--significant-plist-keys '(a b c d e f c g p q r nil s t)) | ||
| 823 | '(a c e p s)))) | ||
| 824 | |||
| 825 | (ert-deftest ert-test-plist-difference-explanation () | ||
| 826 | (should (equal (ert--plist-difference-explanation | ||
| 827 | '(a b c nil) '(a b)) | ||
| 828 | nil)) | ||
| 829 | (should (equal (ert--plist-difference-explanation | ||
| 830 | '(a b c t) '(a b)) | ||
| 831 | '(different-properties-for-key c (different-atoms t nil)))) | ||
| 832 | (should (equal (ert--plist-difference-explanation | ||
| 833 | '(a b c t) '(c nil a b)) | ||
| 834 | '(different-properties-for-key c (different-atoms t nil)))) | ||
| 835 | (should (equal (ert--plist-difference-explanation | ||
| 836 | '(a b c (foo . bar)) '(c (foo . baz) a b)) | ||
| 837 | '(different-properties-for-key c | ||
| 838 | (cdr | ||
| 839 | (different-atoms bar baz)))))) | ||
| 840 | |||
| 841 | (ert-deftest ert-test-abbreviate-string () | ||
| 842 | (should (equal (ert--abbreviate-string "foo" 4 nil) "foo")) | ||
| 843 | (should (equal (ert--abbreviate-string "foo" 3 nil) "foo")) | ||
| 844 | (should (equal (ert--abbreviate-string "foo" 3 nil) "foo")) | ||
| 845 | (should (equal (ert--abbreviate-string "foo" 2 nil) "fo")) | ||
| 846 | (should (equal (ert--abbreviate-string "foo" 1 nil) "f")) | ||
| 847 | (should (equal (ert--abbreviate-string "foo" 0 nil) "")) | ||
| 848 | (should (equal (ert--abbreviate-string "bar" 4 t) "bar")) | ||
| 849 | (should (equal (ert--abbreviate-string "bar" 3 t) "bar")) | ||
| 850 | (should (equal (ert--abbreviate-string "bar" 3 t) "bar")) | ||
| 851 | (should (equal (ert--abbreviate-string "bar" 2 t) "ar")) | ||
| 852 | (should (equal (ert--abbreviate-string "bar" 1 t) "r")) | ||
| 853 | (should (equal (ert--abbreviate-string "bar" 0 t) ""))) | ||
| 854 | |||
| 855 | (ert-deftest ert-test-explain-not-equal-string-properties () | ||
| 856 | (should | ||
| 857 | (equal (ert--explain-not-equal-including-properties #("foo" 0 1 (a b)) | ||
| 858 | "foo") | ||
| 859 | '(char 0 "f" | ||
| 860 | (different-properties-for-key a (different-atoms b nil)) | ||
| 861 | context-before "" | ||
| 862 | context-after "oo"))) | ||
| 863 | (should (equal (ert--explain-not-equal-including-properties | ||
| 864 | #("foo" 1 3 (a b)) | ||
| 865 | #("goo" 0 1 (c d))) | ||
| 866 | '(array-elt 0 (different-atoms (?f "#x66" "?f") | ||
| 867 | (?g "#x67" "?g"))))) | ||
| 868 | (should | ||
| 869 | (equal (ert--explain-not-equal-including-properties | ||
| 870 | #("foo" 0 1 (a b c d) 1 3 (a b)) | ||
| 871 | #("foo" 0 1 (c d a b) 1 2 (a foo))) | ||
| 872 | '(char 1 "o" (different-properties-for-key a (different-atoms b foo)) | ||
| 873 | context-before "f" context-after "o")))) | ||
| 874 | |||
| 875 | (ert-deftest ert-test-equal-including-properties () | ||
| 876 | (should (equal-including-properties "foo" "foo")) | ||
| 877 | (should (ert-equal-including-properties "foo" "foo")) | ||
| 878 | |||
| 879 | (should (equal-including-properties #("foo" 0 3 (a b)) | ||
| 880 | (propertize "foo" 'a 'b))) | ||
| 881 | (should (ert-equal-including-properties #("foo" 0 3 (a b)) | ||
| 882 | (propertize "foo" 'a 'b))) | ||
| 883 | |||
| 884 | (should (equal-including-properties #("foo" 0 3 (a b c d)) | ||
| 885 | (propertize "foo" 'a 'b 'c 'd))) | ||
| 886 | (should (ert-equal-including-properties #("foo" 0 3 (a b c d)) | ||
| 887 | (propertize "foo" 'a 'b 'c 'd))) | ||
| 888 | |||
| 889 | (should-not (equal-including-properties #("foo" 0 3 (a b c e)) | ||
| 890 | (propertize "foo" 'a 'b 'c 'd))) | ||
| 891 | (should-not (ert-equal-including-properties #("foo" 0 3 (a b c e)) | ||
| 892 | (propertize "foo" 'a 'b 'c 'd))) | ||
| 893 | |||
| 894 | ;; This is bug 6581. | ||
| 895 | (should-not (equal-including-properties #("foo" 0 3 (a (t))) | ||
| 896 | (propertize "foo" 'a (list t)))) | ||
| 897 | (should (ert-equal-including-properties #("foo" 0 3 (a (t))) | ||
| 898 | (propertize "foo" 'a (list t))))) | ||
| 899 | |||
| 900 | (ert-deftest ert-test-stats-set-test-and-result () | ||
| 901 | (let* ((test-1 (make-ert-test :name 'test-1 | ||
| 902 | :body (lambda () nil))) | ||
| 903 | (test-2 (make-ert-test :name 'test-2 | ||
| 904 | :body (lambda () nil))) | ||
| 905 | (test-3 (make-ert-test :name 'test-2 | ||
| 906 | :body (lambda () nil))) | ||
| 907 | (stats (ert--make-stats (list test-1 test-2) 't)) | ||
| 908 | (failed (make-ert-test-failed :condition nil | ||
| 909 | :backtrace nil | ||
| 910 | :infos nil))) | ||
| 911 | (should (eql 2 (ert-stats-total stats))) | ||
| 912 | (should (eql 0 (ert-stats-completed stats))) | ||
| 913 | (should (eql 0 (ert-stats-completed-expected stats))) | ||
| 914 | (should (eql 0 (ert-stats-completed-unexpected stats))) | ||
| 915 | (ert--stats-set-test-and-result stats 0 test-1 (make-ert-test-passed)) | ||
| 916 | (should (eql 2 (ert-stats-total stats))) | ||
| 917 | (should (eql 1 (ert-stats-completed stats))) | ||
| 918 | (should (eql 1 (ert-stats-completed-expected stats))) | ||
| 919 | (should (eql 0 (ert-stats-completed-unexpected stats))) | ||
| 920 | (ert--stats-set-test-and-result stats 0 test-1 failed) | ||
| 921 | (should (eql 2 (ert-stats-total stats))) | ||
| 922 | (should (eql 1 (ert-stats-completed stats))) | ||
| 923 | (should (eql 0 (ert-stats-completed-expected stats))) | ||
| 924 | (should (eql 1 (ert-stats-completed-unexpected stats))) | ||
| 925 | (ert--stats-set-test-and-result stats 0 test-1 nil) | ||
| 926 | (should (eql 2 (ert-stats-total stats))) | ||
| 927 | (should (eql 0 (ert-stats-completed stats))) | ||
| 928 | (should (eql 0 (ert-stats-completed-expected stats))) | ||
| 929 | (should (eql 0 (ert-stats-completed-unexpected stats))) | ||
| 930 | (ert--stats-set-test-and-result stats 0 test-3 failed) | ||
| 931 | (should (eql 2 (ert-stats-total stats))) | ||
| 932 | (should (eql 1 (ert-stats-completed stats))) | ||
| 933 | (should (eql 0 (ert-stats-completed-expected stats))) | ||
| 934 | (should (eql 1 (ert-stats-completed-unexpected stats))) | ||
| 935 | (ert--stats-set-test-and-result stats 1 test-2 (make-ert-test-passed)) | ||
| 936 | (should (eql 2 (ert-stats-total stats))) | ||
| 937 | (should (eql 2 (ert-stats-completed stats))) | ||
| 938 | (should (eql 1 (ert-stats-completed-expected stats))) | ||
| 939 | (should (eql 1 (ert-stats-completed-unexpected stats))) | ||
| 940 | (ert--stats-set-test-and-result stats 0 test-1 (make-ert-test-passed)) | ||
| 941 | (should (eql 2 (ert-stats-total stats))) | ||
| 942 | (should (eql 2 (ert-stats-completed stats))) | ||
| 943 | (should (eql 2 (ert-stats-completed-expected stats))) | ||
| 944 | (should (eql 0 (ert-stats-completed-unexpected stats))))) | ||
| 945 | |||
| 946 | |||
| 947 | (provide 'ert-tests) | ||
| 948 | |||
| 949 | ;;; ert-tests.el ends here | ||
diff --git a/test/automated/ert-x-tests.el b/test/automated/ert-x-tests.el new file mode 100644 index 00000000000..80fff40d86a --- /dev/null +++ b/test/automated/ert-x-tests.el | |||
| @@ -0,0 +1,273 @@ | |||
| 1 | ;;; ert-x-tests.el --- Tests for ert-x.el | ||
| 2 | |||
| 3 | ;; Copyright (C) 2008, 2010, 2011 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Phil Hagelberg | ||
| 6 | ;; Author: Christian Ohler <ohler@gnu.org> | ||
| 7 | |||
| 8 | ;; This file is part of GNU Emacs. | ||
| 9 | |||
| 10 | ;; This program is free software: you can redistribute it and/or | ||
| 11 | ;; modify it under the terms of the GNU General Public License as | ||
| 12 | ;; published by the Free Software Foundation, either version 3 of the | ||
| 13 | ;; License, or (at your option) any later version. | ||
| 14 | ;; | ||
| 15 | ;; This program is distributed in the hope that it will be useful, but | ||
| 16 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | ;; General Public License for more details. | ||
| 19 | ;; | ||
| 20 | ;; You should have received a copy of the GNU General Public License | ||
| 21 | ;; along with this program. If not, see `http://www.gnu.org/licenses/'. | ||
| 22 | |||
| 23 | ;;; Commentary: | ||
| 24 | |||
| 25 | ;; This file is part of ERT, the Emacs Lisp Regression Testing tool. | ||
| 26 | ;; See ert.el or the texinfo manual for more details. | ||
| 27 | |||
| 28 | ;;; Code: | ||
| 29 | |||
| 30 | (eval-when-compile | ||
| 31 | (require 'cl)) | ||
| 32 | (require 'ert) | ||
| 33 | (require 'ert-x) | ||
| 34 | |||
| 35 | ;;; Utilities | ||
| 36 | |||
| 37 | (ert-deftest ert-test-buffer-string-reindented () | ||
| 38 | (ert-with-test-buffer (:name "well-indented") | ||
| 39 | (insert (concat "(hello (world\n" | ||
| 40 | " 'elisp)\n")) | ||
| 41 | (emacs-lisp-mode) | ||
| 42 | (should (equal (ert-buffer-string-reindented) (buffer-string)))) | ||
| 43 | (ert-with-test-buffer (:name "badly-indented") | ||
| 44 | (insert (concat "(hello\n" | ||
| 45 | " world)")) | ||
| 46 | (emacs-lisp-mode) | ||
| 47 | (should-not (equal (ert-buffer-string-reindented) (buffer-string))))) | ||
| 48 | |||
| 49 | (defun ert--hash-table-to-alist (table) | ||
| 50 | (let ((accu nil)) | ||
| 51 | (maphash (lambda (key value) | ||
| 52 | (push (cons key value) accu)) | ||
| 53 | table) | ||
| 54 | (nreverse accu))) | ||
| 55 | |||
| 56 | (ert-deftest ert-test-test-buffers () | ||
| 57 | (let (buffer-1 | ||
| 58 | buffer-2) | ||
| 59 | (let ((test-1 | ||
| 60 | (make-ert-test | ||
| 61 | :name 'test-1 | ||
| 62 | :body (lambda () | ||
| 63 | (ert-with-test-buffer (:name "foo") | ||
| 64 | (should (string-match | ||
| 65 | "[*]Test buffer (ert-test-test-buffers): foo[*]" | ||
| 66 | (buffer-name))) | ||
| 67 | (setq buffer-1 (current-buffer)))))) | ||
| 68 | (test-2 | ||
| 69 | (make-ert-test | ||
| 70 | :name 'test-2 | ||
| 71 | :body (lambda () | ||
| 72 | (ert-with-test-buffer (:name "bar") | ||
| 73 | (should (string-match | ||
| 74 | "[*]Test buffer (ert-test-test-buffers): bar[*]" | ||
| 75 | (buffer-name))) | ||
| 76 | (setq buffer-2 (current-buffer)) | ||
| 77 | (ert-fail "fail for test")))))) | ||
| 78 | (let ((ert--test-buffers (make-hash-table :weakness t))) | ||
| 79 | (ert-run-tests `(member ,test-1 ,test-2) #'ignore) | ||
| 80 | (should (equal (ert--hash-table-to-alist ert--test-buffers) | ||
| 81 | `((,buffer-2 . t)))) | ||
| 82 | (should-not (buffer-live-p buffer-1)) | ||
| 83 | (should (buffer-live-p buffer-2)))))) | ||
| 84 | |||
| 85 | |||
| 86 | (ert-deftest ert-filter-string () | ||
| 87 | (should (equal (ert-filter-string "foo bar baz" "quux") | ||
| 88 | "foo bar baz")) | ||
| 89 | (should (equal (ert-filter-string "foo bar baz" "bar") | ||
| 90 | "foo baz"))) | ||
| 91 | |||
| 92 | (ert-deftest ert-propertized-string () | ||
| 93 | (should (ert-equal-including-properties | ||
| 94 | (ert-propertized-string "a" '(a b) "b" '(c t) "cd") | ||
| 95 | #("abcd" 1 2 (a b) 2 4 (c t)))) | ||
| 96 | (should (ert-equal-including-properties | ||
| 97 | (ert-propertized-string "foo " '(face italic) "bar" " baz" nil | ||
| 98 | " quux") | ||
| 99 | #("foo bar baz quux" 4 11 (face italic))))) | ||
| 100 | |||
| 101 | |||
| 102 | ;;; Tests for ERT itself that require test features from ert-x.el. | ||
| 103 | |||
| 104 | (ert-deftest ert-test-run-tests-interactively-2 () | ||
| 105 | :tags '(:causes-redisplay) | ||
| 106 | (let ((passing-test (make-ert-test :name 'passing-test | ||
| 107 | :body (lambda () (ert-pass)))) | ||
| 108 | (failing-test (make-ert-test :name 'failing-test | ||
| 109 | :body (lambda () | ||
| 110 | (ert-info ((propertize "foo\nbar" | ||
| 111 | 'a 'b)) | ||
| 112 | (ert-fail | ||
| 113 | "failure message")))))) | ||
| 114 | (let ((ert-debug-on-error nil)) | ||
| 115 | (let* ((buffer-name (generate-new-buffer-name "*ert-test-run-tests*")) | ||
| 116 | (messages nil) | ||
| 117 | (mock-message-fn | ||
| 118 | (lambda (format-string &rest args) | ||
| 119 | (push (apply #'format format-string args) messages)))) | ||
| 120 | (flet ((expected-string (with-font-lock-p) | ||
| 121 | (ert-propertized-string | ||
| 122 | "Selector: (member <passing-test> <failing-test>)\n" | ||
| 123 | "Passed: 1\n" | ||
| 124 | "Failed: 1 (1 unexpected)\n" | ||
| 125 | "Total: 2/2\n\n" | ||
| 126 | "Started at:\n" | ||
| 127 | "Finished.\n" | ||
| 128 | "Finished at:\n\n" | ||
| 129 | `(category ,(button-category-symbol | ||
| 130 | 'ert--results-progress-bar-button) | ||
| 131 | button (t) | ||
| 132 | face ,(if with-font-lock-p | ||
| 133 | 'ert-test-result-unexpected | ||
| 134 | 'button)) | ||
| 135 | ".F" nil "\n\n" | ||
| 136 | `(category ,(button-category-symbol | ||
| 137 | 'ert--results-expand-collapse-button) | ||
| 138 | button (t) | ||
| 139 | face ,(if with-font-lock-p | ||
| 140 | 'ert-test-result-unexpected | ||
| 141 | 'button)) | ||
| 142 | "F" nil " " | ||
| 143 | `(category ,(button-category-symbol | ||
| 144 | 'ert--test-name-button) | ||
| 145 | button (t) | ||
| 146 | ert-test-name failing-test) | ||
| 147 | "failing-test" | ||
| 148 | nil "\n Info: " '(a b) "foo\n" | ||
| 149 | nil " " '(a b) "bar" | ||
| 150 | nil "\n (ert-test-failed \"failure message\")\n\n\n" | ||
| 151 | ))) | ||
| 152 | (save-window-excursion | ||
| 153 | (unwind-protect | ||
| 154 | (let ((case-fold-search nil)) | ||
| 155 | (ert-run-tests-interactively | ||
| 156 | `(member ,passing-test ,failing-test) buffer-name | ||
| 157 | mock-message-fn) | ||
| 158 | (should (equal messages `(,(concat | ||
| 159 | "Ran 2 tests, 1 results were " | ||
| 160 | "as expected, 1 unexpected")))) | ||
| 161 | (with-current-buffer buffer-name | ||
| 162 | (font-lock-mode 0) | ||
| 163 | (should (ert-equal-including-properties | ||
| 164 | (ert-filter-string (buffer-string) | ||
| 165 | '("Started at:\\(.*\\)$" 1) | ||
| 166 | '("Finished at:\\(.*\\)$" 1)) | ||
| 167 | (expected-string nil))) | ||
| 168 | ;; `font-lock-mode' only works if interactive, so | ||
| 169 | ;; pretend we are. | ||
| 170 | (let ((noninteractive nil)) | ||
| 171 | (font-lock-mode 1)) | ||
| 172 | (should (ert-equal-including-properties | ||
| 173 | (ert-filter-string (buffer-string) | ||
| 174 | '("Started at:\\(.*\\)$" 1) | ||
| 175 | '("Finished at:\\(.*\\)$" 1)) | ||
| 176 | (expected-string t))))) | ||
| 177 | (when (get-buffer buffer-name) | ||
| 178 | (kill-buffer buffer-name))))))))) | ||
| 179 | |||
| 180 | (ert-deftest ert-test-describe-test () | ||
| 181 | "Tests `ert-describe-test'." | ||
| 182 | (save-window-excursion | ||
| 183 | (ert-with-buffer-renamed ("*Help*") | ||
| 184 | (if (< emacs-major-version 24) | ||
| 185 | (should (equal (should-error (ert-describe-test 'ert-describe-test)) | ||
| 186 | '(error "Requires Emacs 24"))) | ||
| 187 | (ert-describe-test 'ert-test-describe-test) | ||
| 188 | (with-current-buffer "*Help*" | ||
| 189 | (let ((case-fold-search nil)) | ||
| 190 | (should (string-match (concat | ||
| 191 | "\\`ert-test-describe-test is a test" | ||
| 192 | " defined in `ert-x-tests.elc?'\\.\n\n" | ||
| 193 | "Tests `ert-describe-test'\\.\n\\'") | ||
| 194 | (buffer-string))))))))) | ||
| 195 | |||
| 196 | (ert-deftest ert-test-message-log-truncation () | ||
| 197 | :tags '(:causes-redisplay) | ||
| 198 | (let ((test (make-ert-test | ||
| 199 | :body (lambda () | ||
| 200 | ;; Emacs would combine messages if we | ||
| 201 | ;; generate the same message multiple | ||
| 202 | ;; times. | ||
| 203 | (message "a") | ||
| 204 | (message "b") | ||
| 205 | (message "c") | ||
| 206 | (message "d"))))) | ||
| 207 | (let (result) | ||
| 208 | (ert-with-buffer-renamed ("*Messages*") | ||
| 209 | (let ((message-log-max 2)) | ||
| 210 | (setq result (ert-run-test test))) | ||
| 211 | (should (equal (with-current-buffer "*Messages*" | ||
| 212 | (buffer-string)) | ||
| 213 | "c\nd\n"))) | ||
| 214 | (should (equal (ert-test-result-messages result) "a\nb\nc\nd\n"))))) | ||
| 215 | |||
| 216 | (ert-deftest ert-test-builtin-message-log-flushing () | ||
| 217 | "This test attempts to demonstrate that there is no way to | ||
| 218 | force immediate truncation of the *Messages* buffer from Lisp | ||
| 219 | \(and hence justifies the existence of | ||
| 220 | `ert--force-message-log-buffer-truncation'\): The only way that | ||
| 221 | came to my mind was \(message \"\"\), which doesn't have the | ||
| 222 | desired effect." | ||
| 223 | :tags '(:causes-redisplay) | ||
| 224 | (ert-with-buffer-renamed ("*Messages*") | ||
| 225 | (with-current-buffer "*Messages*" | ||
| 226 | (should (equal (buffer-string) "")) | ||
| 227 | ;; We used to get sporadic failures in this test that involved | ||
| 228 | ;; a spurious newline at the beginning of the buffer, before | ||
| 229 | ;; the first message. Below, we print a message and erase the | ||
| 230 | ;; buffer since this seems to eliminate the sporadic failures. | ||
| 231 | (message "foo") | ||
| 232 | (erase-buffer) | ||
| 233 | (should (equal (buffer-string) "")) | ||
| 234 | (let ((message-log-max 2)) | ||
| 235 | (let ((message-log-max t)) | ||
| 236 | (loop for i below 4 do | ||
| 237 | (message "%s" i)) | ||
| 238 | (should (equal (buffer-string) "0\n1\n2\n3\n"))) | ||
| 239 | (should (equal (buffer-string) "0\n1\n2\n3\n")) | ||
| 240 | (message "") | ||
| 241 | (should (equal (buffer-string) "0\n1\n2\n3\n")) | ||
| 242 | (message "Test message") | ||
| 243 | (should (equal (buffer-string) "3\nTest message\n")))))) | ||
| 244 | |||
| 245 | (ert-deftest ert-test-force-message-log-buffer-truncation () | ||
| 246 | :tags '(:causes-redisplay) | ||
| 247 | (labels ((body () | ||
| 248 | (loop for i below 3 do | ||
| 249 | (message "%s" i))) | ||
| 250 | ;; Uses the implicit messages buffer truncation implemented | ||
| 251 | ;; in Emacs' C core. | ||
| 252 | (c (x) | ||
| 253 | (ert-with-buffer-renamed ("*Messages*") | ||
| 254 | (let ((message-log-max x)) | ||
| 255 | (body)) | ||
| 256 | (with-current-buffer "*Messages*" | ||
| 257 | (buffer-string)))) | ||
| 258 | ;; Uses our lisp reimplementation. | ||
| 259 | (lisp (x) | ||
| 260 | (ert-with-buffer-renamed ("*Messages*") | ||
| 261 | (let ((message-log-max t)) | ||
| 262 | (body)) | ||
| 263 | (let ((message-log-max x)) | ||
| 264 | (ert--force-message-log-buffer-truncation)) | ||
| 265 | (with-current-buffer "*Messages*" | ||
| 266 | (buffer-string))))) | ||
| 267 | (loop for x in '(0 1 2 3 4 t) do | ||
| 268 | (should (equal (c x) (lisp x)))))) | ||
| 269 | |||
| 270 | |||
| 271 | (provide 'ert-x-tests) | ||
| 272 | |||
| 273 | ;;; ert-x-tests.el ends here | ||