diff options
| author | Gemini Lasswell | 2017-09-25 13:45:07 -0700 |
|---|---|---|
| committer | Gemini Lasswell | 2017-10-08 16:08:49 -0700 |
| commit | d79cf638f278e50c22feb53d6ba556f5ce9d7853 (patch) | |
| tree | 12d79738615603b2afe277bcbf74c19439e4568d /test | |
| parent | 06e452a57287c797cb96a6d4b45220358daab379 (diff) | |
| download | emacs-d79cf638f278e50c22feb53d6ba556f5ce9d7853.tar.gz emacs-d79cf638f278e50c22feb53d6ba556f5ce9d7853.zip | |
Rewrite Testcover's internals, fixing several bugs
* lisp/emacs-lisp/testcover.el: Rewrite the internals of Testcover
to analyze instrumented code instead of reinstrumenting it. Use new
hooks in Edebug to collect code coverage information at runtime
using Edebug's instrumentation.
Includes fixes for: (bug#11307) (bug#24509) (bug#24688) (bug#24743)
(bug#25316) (bug#25326).
(testcover-compose-functions): Remove mapcar.
(testcover-start, testcover-this-defun): Analyze code instead of
reinstrumenting it. Set edebug-behavior for each definition.
(testcover--read, testcover-1value, testcover-reinstrument)
(testcover-reinstrument-list, testcover-reinstrument-compose):
Deleted.
(testcover-after-instrumentation, testcover-init-definition)
(testcover-before): New functions.
(testcover-enter): Change call signature to match edebug-enter.
(testcover-after, testcover-mark): Add handling of 'maybe and
'noreturn.
(testcover-analyze-coverage, testcover-analyze-coverage-progn)
(testcover-analyze-coverage-edebug-after)
(testcover-analyze-coverage-wrapped-form)
(testcover-analyze-coverage-wrapped-application)
(testcover-analyze-coverage-compose)
(testcover-analyze-coverage-backquote)
(testcover-analyze-coverage-backquote-form)
(testcover-coverage-combine): New functions to analyze instrumented
code.
* lisp/emacs-lisp/gv.el: Modify edebug-after's gv-expander to
instrument in the setter as well as the getter.
* test/lisp/emacs-lisp/testcover-tests.el
(testcover-tests-run-test-case): Use `edebug-default-enter'
instead of `edebug-enter' to detect Edebug invocation
during tests.
* test/lisp/emacs-lisp/testcover-resources/testcases.el
(constants-bug-25316)
(customize-defcustom-bug-25326)
(1-value-symbol-bug-25316)
(quotes-within-backquotes-bug-25316)
(backquote-1value-bug-24509)
(pcase-bug-24688)
(defun-in-backquote-bug-11307-and-24743)
(closure-1value-bug)
(backquoted-vector-bug-25316)
(vector-in-macro-spec-bug-25316)
(mapcar-is-not-compose): Remove expected failure tags.
(function-with-edebug-spec-bug-25316): Remove expected failure tag
and modify expected result.
(quoted-backquote): New test.
* lisp/textmodes/rst.el: Remove workarounds for bugs in Testcover.
(rst-testcover-defcustom): Deleted.
* lisp/subr.el (1value): Remove incorrect description of
testcover-1value from docstring, replace with description of
Testcover's treatment of 1value.
Diffstat (limited to 'test')
| -rw-r--r-- | test/lisp/emacs-lisp/testcover-resources/testcases.el | 29 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/testcover-tests.el | 12 |
2 files changed, 18 insertions, 23 deletions
diff --git a/test/lisp/emacs-lisp/testcover-resources/testcases.el b/test/lisp/emacs-lisp/testcover-resources/testcases.el index edb539f4c27..d8b8192748d 100644 --- a/test/lisp/emacs-lisp/testcover-resources/testcases.el +++ b/test/lisp/emacs-lisp/testcover-resources/testcases.el | |||
| @@ -53,7 +53,6 @@ | |||
| 53 | 53 | ||
| 54 | ;; ==== constants-bug-25316 ==== | 54 | ;; ==== constants-bug-25316 ==== |
| 55 | "Testcover doesn't splotch constants." | 55 | "Testcover doesn't splotch constants." |
| 56 | :expected-result :failed | ||
| 57 | ;; ==== | 56 | ;; ==== |
| 58 | (defconst testcover-testcase-const "apples") | 57 | (defconst testcover-testcase-const "apples") |
| 59 | (defun testcover-testcase-zero () 0) | 58 | (defun testcover-testcase-zero () 0) |
| @@ -76,7 +75,6 @@ | |||
| 76 | 75 | ||
| 77 | ;; ==== customize-defcustom-bug-25326 ==== | 76 | ;; ==== customize-defcustom-bug-25326 ==== |
| 78 | "Testcover doesn't prevent testing of defcustom values." | 77 | "Testcover doesn't prevent testing of defcustom values." |
| 79 | :expected-result :failed | ||
| 80 | ;; ==== | 78 | ;; ==== |
| 81 | (defgroup testcover-testcase nil | 79 | (defgroup testcover-testcase nil |
| 82 | "Test case for testcover" | 80 | "Test case for testcover" |
| @@ -135,7 +133,6 @@ | |||
| 135 | 133 | ||
| 136 | ;; ==== 1-value-symbol-bug-25316 ==== | 134 | ;; ==== 1-value-symbol-bug-25316 ==== |
| 137 | "Wrapping a form with 1value prevents splotching." | 135 | "Wrapping a form with 1value prevents splotching." |
| 138 | :expected-result :failed | ||
| 139 | ;; ==== | 136 | ;; ==== |
| 140 | (defun testcover-testcase-always-zero (num) | 137 | (defun testcover-testcase-always-zero (num) |
| 141 | (- num%%% num%%%)%%%) | 138 | (- num%%% num%%%)%%%) |
| @@ -230,7 +227,6 @@ | |||
| 230 | 227 | ||
| 231 | ;; ==== quotes-within-backquotes-bug-25316 ==== | 228 | ;; ==== quotes-within-backquotes-bug-25316 ==== |
| 232 | "Forms to instrument are found within quotes within backquotes." | 229 | "Forms to instrument are found within quotes within backquotes." |
| 233 | :expected-result :failed | ||
| 234 | ;; ==== | 230 | ;; ==== |
| 235 | (defun testcover-testcase-make-list () | 231 | (defun testcover-testcase-make-list () |
| 236 | (list 'defun 'defvar)) | 232 | (list 'defun 'defvar)) |
| @@ -296,7 +292,6 @@ | |||
| 296 | 292 | ||
| 297 | ;; ==== backquote-1value-bug-24509 ==== | 293 | ;; ==== backquote-1value-bug-24509 ==== |
| 298 | "Commas within backquotes are recognized as non-1value." | 294 | "Commas within backquotes are recognized as non-1value." |
| 299 | :expected-result :failed | ||
| 300 | ;; ==== | 295 | ;; ==== |
| 301 | (defmacro testcover-testcase-lambda (&rest body) | 296 | (defmacro testcover-testcase-lambda (&rest body) |
| 302 | `(lambda () ,@body)) | 297 | `(lambda () ,@body)) |
| @@ -320,7 +315,6 @@ | |||
| 320 | 315 | ||
| 321 | ;; ==== pcase-bug-24688 ==== | 316 | ;; ==== pcase-bug-24688 ==== |
| 322 | "Testcover copes with condition-case within backquoted list." | 317 | "Testcover copes with condition-case within backquoted list." |
| 323 | :expected-result :failed | ||
| 324 | ;; ==== | 318 | ;; ==== |
| 325 | (defun testcover-testcase-pcase (form) | 319 | (defun testcover-testcase-pcase (form) |
| 326 | (pcase form%%% | 320 | (pcase form%%% |
| @@ -335,7 +329,6 @@ | |||
| 335 | 329 | ||
| 336 | ;; ==== defun-in-backquote-bug-11307-and-24743 ==== | 330 | ;; ==== defun-in-backquote-bug-11307-and-24743 ==== |
| 337 | "Testcover handles defun forms within backquoted list." | 331 | "Testcover handles defun forms within backquoted list." |
| 338 | :expected-result :failed | ||
| 339 | ;; ==== | 332 | ;; ==== |
| 340 | (defmacro testcover-testcase-defun (name &rest body) | 333 | (defmacro testcover-testcase-defun (name &rest body) |
| 341 | (declare (debug (symbolp def-body))) | 334 | (declare (debug (symbolp def-body))) |
| @@ -348,7 +341,6 @@ | |||
| 348 | 341 | ||
| 349 | ;; ==== closure-1value-bug ==== | 342 | ;; ==== closure-1value-bug ==== |
| 350 | "Testcover does not mark closures as 1value." | 343 | "Testcover does not mark closures as 1value." |
| 351 | :expected-result :failed | ||
| 352 | ;; ==== | 344 | ;; ==== |
| 353 | ;; -*- lexical-binding:t -*- | 345 | ;; -*- lexical-binding:t -*- |
| 354 | (setq testcover-testcase-foo nil) | 346 | (setq testcover-testcase-foo nil) |
| @@ -396,9 +388,16 @@ | |||
| 396 | (should (equal '(a b c) (testcover-testcase-dotted-bq nil '(d e)))) | 388 | (should (equal '(a b c) (testcover-testcase-dotted-bq nil '(d e)))) |
| 397 | (should (equal '(a b c d e) (testcover-testcase-dotted-bq t '(d e)))) | 389 | (should (equal '(a b c d e) (testcover-testcase-dotted-bq t '(d e)))) |
| 398 | 390 | ||
| 391 | ;; ==== quoted-backquote ==== | ||
| 392 | "Testcover correctly instruments the quoted backquote symbol." | ||
| 393 | ;; ==== | ||
| 394 | (defun testcover-testcase-special-symbols () | ||
| 395 | (list '\` '\, '\,@)) | ||
| 396 | |||
| 397 | (should (equal '(\` \, \,@) (testcover-testcase-special-symbols))) | ||
| 398 | |||
| 399 | ;; ==== backquoted-vector-bug-25316 ==== | 399 | ;; ==== backquoted-vector-bug-25316 ==== |
| 400 | "Testcover reinstruments within backquoted vectors." | 400 | "Testcover reinstruments within backquoted vectors." |
| 401 | :expected-result :failed | ||
| 402 | ;; ==== | 401 | ;; ==== |
| 403 | (defun testcover-testcase-vec (a b c) | 402 | (defun testcover-testcase-vec (a b c) |
| 404 | `[,a%%% ,(list b%%% c%%%)%%%]%%%) | 403 | `[,a%%% ,(list b%%% c%%%)%%%]%%%) |
| @@ -415,7 +414,6 @@ | |||
| 415 | 414 | ||
| 416 | ;; ==== vector-in-macro-spec-bug-25316 ==== | 415 | ;; ==== vector-in-macro-spec-bug-25316 ==== |
| 417 | "Testcover reinstruments within vectors." | 416 | "Testcover reinstruments within vectors." |
| 418 | :expected-result :failed | ||
| 419 | ;; ==== | 417 | ;; ==== |
| 420 | (defmacro testcover-testcase-nth-case (arg vec) | 418 | (defmacro testcover-testcase-nth-case (arg vec) |
| 421 | (declare (indent 1) | 419 | (declare (indent 1) |
| @@ -435,7 +433,6 @@ | |||
| 435 | 433 | ||
| 436 | ;; ==== mapcar-is-not-compose ==== | 434 | ;; ==== mapcar-is-not-compose ==== |
| 437 | "Mapcar with 1value arguments is not 1value." | 435 | "Mapcar with 1value arguments is not 1value." |
| 438 | :expected-result :failed | ||
| 439 | ;; ==== | 436 | ;; ==== |
| 440 | (defvar testcover-testcase-num 0) | 437 | (defvar testcover-testcase-num 0) |
| 441 | (defun testcover-testcase-add-num (n) | 438 | (defun testcover-testcase-add-num (n) |
| @@ -450,10 +447,10 @@ | |||
| 450 | 447 | ||
| 451 | ;; ==== function-with-edebug-spec-bug-25316 ==== | 448 | ;; ==== function-with-edebug-spec-bug-25316 ==== |
| 452 | "Functions can have edebug specs too. | 449 | "Functions can have edebug specs too. |
| 453 | See c-make-font-lock-search-function for an example in the Emacs | 450 | See `c-make-font-lock-search-function' for an example in the |
| 454 | sources. The other issue is that it's ok to use quote in an | 451 | Emacs sources. `c-make-font-lock-search-function''s Edebug spec |
| 455 | edebug spec, so testcover needs to cope with that." | 452 | also contains a quote. See comment in `testcover-analyze-coverage' |
| 456 | :expected-result :failed | 453 | regarding the odd-looking coverage result for the quoted form." |
| 457 | ;; ==== | 454 | ;; ==== |
| 458 | (defun testcover-testcase-make-function (forms) | 455 | (defun testcover-testcase-make-function (forms) |
| 459 | `(lambda (flag) (if flag 0 ,@forms%%%))%%%) | 456 | `(lambda (flag) (if flag 0 ,@forms%%%))%%%) |
| @@ -462,7 +459,7 @@ edebug spec, so testcover needs to cope with that." | |||
| 462 | (("quote" (&rest def-form)))) | 459 | (("quote" (&rest def-form)))) |
| 463 | 460 | ||
| 464 | (defun testcover-testcase-thing () | 461 | (defun testcover-testcase-thing () |
| 465 | (testcover-testcase-make-function '((+ 1 (+ 2 (+ 3 (+ 4 5))))))%%%) | 462 | (testcover-testcase-make-function '(!!!(+ 1 !!!(+ 2 !!!(+ 3 !!!(+ 4 5)%%%)%%%)%%%)%%%))%%%) |
| 466 | 463 | ||
| 467 | (defun testcover-testcase-use-thing () | 464 | (defun testcover-testcase-use-thing () |
| 468 | (funcall (testcover-testcase-thing)%%% nil)%%%) | 465 | (funcall (testcover-testcase-thing)%%% nil)%%%) |
diff --git a/test/lisp/emacs-lisp/testcover-tests.el b/test/lisp/emacs-lisp/testcover-tests.el index 0f0ee9a5095..2e03488b306 100644 --- a/test/lisp/emacs-lisp/testcover-tests.el +++ b/test/lisp/emacs-lisp/testcover-tests.el | |||
| @@ -124,14 +124,12 @@ arguments for `testcover-start'." | |||
| 124 | (save-current-buffer | 124 | (save-current-buffer |
| 125 | (set-buffer (find-file-noselect tempfile)) | 125 | (set-buffer (find-file-noselect tempfile)) |
| 126 | ;; Fail the test if the debugger tries to become active, | 126 | ;; Fail the test if the debugger tries to become active, |
| 127 | ;; which will happen if Testcover's reinstrumentation | 127 | ;; which can happen if Testcover fails to attach itself |
| 128 | ;; leaves an edebug-enter in the code. This will also | 128 | ;; correctly. Note that this will prevent debugging |
| 129 | ;; prevent debugging these tests using Edebug. | 129 | ;; these tests using Edebug. |
| 130 | (cl-letf (((symbol-function #'edebug-enter) | 130 | (cl-letf (((symbol-function #'edebug-default-enter) |
| 131 | (lambda (&rest _args) | 131 | (lambda (&rest _args) |
| 132 | (ert-fail | 132 | (ert-fail "Debugger invoked during test run")))) |
| 133 | (concat "Debugger invoked during test run " | ||
| 134 | "(possible edebug-enter not replaced)"))))) | ||
| 135 | (dolist (byte-compile '(t nil)) | 133 | (dolist (byte-compile '(t nil)) |
| 136 | (testcover-tests-unmarkup-region (point-min) (point-max)) | 134 | (testcover-tests-unmarkup-region (point-min) (point-max)) |
| 137 | (unwind-protect | 135 | (unwind-protect |