aboutsummaryrefslogtreecommitdiffstats
path: root/test/lisp/emacs-lisp/testcover-tests.el
diff options
context:
space:
mode:
authorAlan Mackenzie2017-02-12 10:59:03 +0000
committerAlan Mackenzie2017-02-12 10:59:03 +0000
commitf4d5b687150810129b7a1d5b006e31ccf82b691b (patch)
tree4229b13800349032697daae3904dc3773e6b7a80 /test/lisp/emacs-lisp/testcover-tests.el
parentd5514332d4a6092673ce1f78fadcae0c57f7be64 (diff)
parent148100d98319499f0ac6f57b8be08cbd14884a5c (diff)
downloademacs-comment-cache.tar.gz
emacs-comment-cache.zip
Merge branch 'master' into comment-cachecomment-cache
Diffstat (limited to 'test/lisp/emacs-lisp/testcover-tests.el')
-rw-r--r--test/lisp/emacs-lisp/testcover-tests.el186
1 files changed, 186 insertions, 0 deletions
diff --git a/test/lisp/emacs-lisp/testcover-tests.el b/test/lisp/emacs-lisp/testcover-tests.el
new file mode 100644
index 00000000000..d31379c3aa2
--- /dev/null
+++ b/test/lisp/emacs-lisp/testcover-tests.el
@@ -0,0 +1,186 @@
1;;; testcover-tests.el --- Testcover test suite -*- lexical-binding:t -*-
2
3;; Copyright (C) 2017 Free Software Foundation, Inc.
4
5;; Author: Gemini Lasswell
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;; Testcover test suite.
25;; * All the test cases are in testcover-resources/testcover-cases.el.
26;; See that file for an explanation of the test case format.
27;; * `testcover-tests-define-tests', which is run when this file is
28;; loaded, reads testcover-resources/testcover-cases.el and defines
29;; ERT tests for each test case.
30
31;;; Code:
32
33(require 'ert)
34(require 'testcover)
35(require 'skeleton)
36
37;; Use `eval-and-compile' around all these definitions because they're
38;; used by the macro `testcover-tests-define-tests'.
39
40(eval-and-compile
41 (defvar testcover-tests-file-dir
42 (expand-file-name
43 "testcover-resources/"
44 (file-name-directory (or (bound-and-true-p byte-compile-current-file)
45 load-file-name
46 buffer-file-name)))
47 "Directory of the \"testcover-tests.el\" file."))
48
49(eval-and-compile
50 (defvar testcover-tests-test-cases
51 (expand-file-name "testcases.el" testcover-tests-file-dir)
52 "File containing marked up code to instrument and check."))
53
54;; Convert Testcover's overlays to plain text.
55
56(eval-and-compile
57 (defun testcover-tests-markup-region (beg end &rest optargs)
58 "Mark up test code within region between BEG and END.
59Convert Testcover's tan and red splotches to %%% and !!! for
60testcases.el. This can be used to create test cases if Testcover
61is working correctly on a code sample. OPTARGS are optional
62arguments for `testcover-start'."
63 (interactive "r")
64 (let ((tempfile (make-temp-file "testcover-tests-" nil ".el"))
65 (code (buffer-substring beg end))
66 (marked-up-code))
67 (unwind-protect
68 (progn
69 (with-temp-file tempfile
70 (insert code))
71 (save-current-buffer
72 (let ((buf (find-file-noselect tempfile)))
73 (set-buffer buf)
74 (apply 'testcover-start (cons tempfile optargs))
75 (testcover-mark-all buf)
76 (dolist (overlay (overlays-in (point-min) (point-max)))
77 (let ((ov-face (overlay-get overlay 'face)))
78 (goto-char (overlay-end overlay))
79 (cond
80 ((eq ov-face 'testcover-nohits) (insert "!!!"))
81 ((eq ov-face 'testcover-1value) (insert "%%%"))
82 (t nil))))
83 (setq marked-up-code (buffer-string)))
84 (set-buffer-modified-p nil)))
85 (ignore-errors (kill-buffer (find-file-noselect tempfile)))
86 (ignore-errors (delete-file tempfile)))
87
88 ;; Now replace the original code with the marked up code.
89 (delete-region beg end)
90 (insert marked-up-code))))
91
92(eval-and-compile
93 (defun testcover-tests-unmarkup-region (beg end)
94 "Remove the markup used in testcases.el between BEG and END."
95 (interactive "r")
96 (save-excursion
97 (save-restriction
98 (narrow-to-region beg end)
99 (goto-char (point-min))
100 (while (re-search-forward "!!!\\|%%%" nil t)
101 (replace-match ""))))))
102
103(define-skeleton testcover-tests-skeleton
104 "Write a testcase for testcover-tests.el."
105 "Enter name of test: "
106 ";; ==== " str " ====\n"
107 "\"docstring\"\n"
108 ";; Directives for ERT should go here, if any.\n"
109 ";; ====\n"
110 ";; Replace this line with annotated test code.\n")
111
112;; Check a test case.
113
114(eval-and-compile
115 (defun testcover-tests-run-test-case (marked-up-code)
116 "Test the operation of Testcover on the string MARKED-UP-CODE."
117 (let ((tempfile (make-temp-file "testcover-tests-" nil ".el")))
118 (unwind-protect
119 (progn
120 (with-temp-file tempfile
121 (insert marked-up-code))
122 ;; Remove the marks and mark the code up again. The original
123 ;; and recreated versions should match.
124 (save-current-buffer
125 (set-buffer (find-file-noselect tempfile))
126 ;; Fail the test if the debugger tries to become active,
127 ;; which will happen if Testcover's reinstrumentation
128 ;; leaves an edebug-enter in the code. This will also
129 ;; prevent debugging these tests using Edebug.
130 (cl-letf (((symbol-function #'edebug-enter)
131 (lambda (&rest _args)
132 (ert-fail
133 (concat "Debugger invoked during test run "
134 "(possible edebug-enter not replaced)")))))
135 (dolist (byte-compile '(t nil))
136 (testcover-tests-unmarkup-region (point-min) (point-max))
137 (unwind-protect
138 (testcover-tests-markup-region (point-min) (point-max) byte-compile)
139 (set-buffer-modified-p nil))
140 (should (string= marked-up-code
141 (buffer-string)))))))
142 (ignore-errors (kill-buffer (find-file-noselect tempfile)))
143 (ignore-errors (delete-file tempfile))))))
144
145;; Convert test case file to ert-defmethod.
146
147(eval-and-compile
148 (defun testcover-tests-build-test-cases ()
149 "Parse the test case file and return a list of ERT test definitions.
150Construct and return a list of `ert-deftest' forms. See testcases.el
151for documentation of the test definition format."
152 (let (results)
153 (with-temp-buffer
154 (insert-file-contents testcover-tests-test-cases)
155 (goto-char (point-min))
156 (while (re-search-forward
157 (concat "^;; ==== \\([^ ]+?\\) ====\n"
158 "\\(\\(?:.*\n\\)*?\\)"
159 ";; ====\n"
160 "\\(\\(?:.*\n\\)*?\\)"
161 "\\(\\'\\|;; ====\\)")
162 nil t)
163 (let ((name (match-string 1))
164 (splice (car (read-from-string
165 (format "(%s)" (match-string 2)))))
166 (code (match-string 3)))
167 (push
168 `(ert-deftest ,(intern (concat "testcover-tests-" name)) ()
169 ,@splice
170 (testcover-tests-run-test-case ,code))
171 results))
172 (beginning-of-line)))
173 results)))
174
175;; Define all the tests.
176
177(defmacro testcover-tests-define-tests ()
178 "Construct and define ERT test methods using the test case file."
179 (let* ((test-cases (testcover-tests-build-test-cases)))
180 `(progn ,@test-cases)))
181
182(testcover-tests-define-tests)
183
184(provide 'testcover-tests)
185
186;;; testcover-tests.el ends here