Improvements in fontification:
[docutils/kirr.git] / docutils / tools / editors / emacs / tests / tests-runner.el
blob3c42c63c80f0a6f93ccb7049e91bd4a9a9af56e8
1 ;; Authors: Martin Blais <blais@furius.ca>
2 ;; Date: $Date$
3 ;; Copyright: This module has been placed in the public domain.
4 ;;
5 ;; Simple generic test runner for test scripts.
6 ;;
7 ;; Run this with::
8 ;;
9 ;; emacs --script <file>.el
12 ;; There are mainly two useful functions from this pacakge:
14 ;; 1. regression-test-compare-expect-values : used to compare expected output
15 ;; values from running a function;
17 ;; 2. regression-test-compare-expect-buffer : used to compare expected output
18 ;; buffer contents after running the function.
20 ;; regression-test-compare-expect-values test format
21 ;; -------------------------------------------------
23 ;; The tests are a list of tuples, with the following entries:
25 ;; - a SYMBOL that uniquely identifies the test.
27 ;; - the input buffer CONTENTS to prepare and run the test on. If char @ is
28 ;; present in the buffer, it is removed and the cursor is placed at that
29 ;; position before running the tested function.
31 ;; - the expected OUTPUT value that the function should return. If the actual
32 ;; output is different from this, the test will fail.
34 ;; - an optional list of INPUT ARGUMENTS that the test function is called with
35 ;; for this test.
36 ;;
37 ;; regression-test-compare-expect-buffer test format
38 ;; -------------------------------------------------
40 ;; - a SYMBOL that uniquely identifies the test.
42 ;; - the input buffer CONTENTS to prepare and run the test on. Here too, char @
43 ;; is present in the buffer, it is removed and the cursor is placed at that
44 ;; position before running the tested function.
46 ;; - the EXPECTED buffer contents after the function has been run.
47 ;; Additionally, if char @ is present, it is checked that the cursor is
48 ;; located at that position in the buffer after the function is run (this is
49 ;; optional).
51 ;; - an optional list of PREFIX ARGUMENTS, which indicates to the test program
52 ;; to set those prefix arguments before running the given function. If there
53 ;; are multiple prefix args, the function is invoked many times.
57 (require 'cl)
59 (defvar regression-point-char "@"
60 "Special character used to mark the position of point in input
61 text and expected text.")
63 (defun regression-test-loop (suitename testfun testlist fun &optional continue)
64 "Loop over a series of tests in a buffer and run the 'testfun'
65 function."
67 (message (format "\n\n Test Suite: %s\n\n" suitename))
69 (let ((buf (get-buffer-create "regression-tests"))
70 errtxt
72 (dolist (curtest testlist)
74 ;; Print current text.
75 (message (format "========= %s" (prin1-to-string (car curtest))))
77 (setq errtxt (run-test buf (cadr curtest) testfun
78 (list (car curtest) (caddr curtest)
79 (cadddr curtest))))
81 (if errtxt
82 (if continue
83 (progn (message errtxt)
84 (message "(Continuing...)"))
85 (error errtxt)))
87 (message "Done."))
89 (defun run-test (buf input testfun args)
90 "Prepare BUF with the starting text INPUT, move the cursor
91 where the special character is located, run TESTFUN with ARGS and
92 return the error text."
93 (switch-to-buffer buf)
94 (erase-buffer)
95 (insert input)
97 (if (not (search-backward regression-point-char nil t))
98 (error (concat "Error: Badly formed test input, missing "
99 "the cursor position marker.")))
101 (delete-char 1)
102 (apply testfun args))
104 (defun run-test-filter (testfun &rest args)
105 "Run a test as a filter.
107 Can be used with \"emacs --batch -l tests-runner.el -l ../rst.el --eval \"(run-test-filter 'function-name 'arg1...)\""
108 (let (;; Input from stdin
109 (input (read-from-minibuffer "")))
110 ;; Output result to stderr
111 (message "%s" (run-test (get-buffer-create "test") input testfun args))
112 (insert regression-point-char)
113 ;; Output buffer to stdout
114 (princ (buffer-string))
115 (princ "\n")))
117 (defun regression-compare-buffers (testname expected testargs)
118 "Compare the buffer and expected text and return actual
119 contents if they do not match."
121 ;; Run the section title update command n times.
122 (dolist (x (or testargs (list nil)))
123 (let ((current-prefix-arg x))
124 (funcall fun)))
126 ;; Compare the buffer output with the expected text.
127 (let* (;; Get the actual buffer contents.
128 (actual (buffer-string))
129 ;; Get the expected location of point
130 (exppoint (string-match regression-point-char expected))
132 (expected-clean (if exppoint
133 (concat (substring expected 0 exppoint)
134 (substring expected (+ 1 exppoint)))
135 expected))
137 ;; Adjust position of point vs. string index.
138 (exppoint (and exppoint (+ exppoint 1)))
142 (if (not (string= expected-clean actual))
143 ;; Error! Test failed.
144 (format "Error: Test %s failed: \nexpected\n%s\ngot\n%s"
145 testname
146 (prin1-to-string expected-clean)
147 (prin1-to-string actual))
148 (if (and exppoint (not (equal exppoint (point))))
149 ;; Error! Test failed, final position of cursor is not the same.
150 (format "Error: Test %s failed: cursor badly placed." testname))
153 (defun regression-test-compare-expect-buffer
154 (suitename testlist fun &optional continue)
155 "Run the regression tests for the expected buffer contents."
156 (regression-test-loop
157 suitename 'regression-compare-buffers testlist fun continue))
160 (defun regression-compare-values (testname expected testargs)
161 "Compare the buffer and expected text and return actual
162 contents if they do not match."
164 (let (actual)
165 ;; Run the section title update command n times.
166 (setq actual (apply fun testargs))
168 ;; Compare the buffer output with the expected text.
169 (if (not (equal actual expected))
170 ;; Error! Test failed.
171 (format "Error: Test %s failed: expected '%s' got '%s'."
172 testname
173 (prin1-to-string expected)
174 (prin1-to-string actual))
177 (defun regression-test-compare-expect-values
178 (suitename testlist fun &optional continue)
179 "Run the regression tests for expected values comparison."
180 (regression-test-loop
181 suitename 'regression-compare-values testlist fun continue))