[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 054c198 1/8: Catch argument and macroexpansion erro
From: |
Noam Postavsky |
Subject: |
[Emacs-diffs] master 054c198 1/8: Catch argument and macroexpansion errors in ert |
Date: |
Mon, 7 Aug 2017 21:09:40 -0400 (EDT) |
branch: master
commit 054c198c120c1f01a8ff753892d52710b740acc6
Author: Alexander Gramiak <address@hidden>
Commit: Noam Postavsky <address@hidden>
Catch argument and macroexpansion errors in ert
This kludge catches errors caused by evaluating arguments in ert's
should, should-not, and should-error macros; it also catches
macroexpansion errors inside of the above macros (Bug#24402).
* lisp/emacs-lisp/ert.el: (ert--should-signal-hook): New function.
(ert--expand-should-1): Catch macroexpansion errors.
* test/lisp/emacs-lisp/ert-tests.el (ert-test-should-error-argument)
(ert-test-should-error-macroexpansion): Tests for argument and
expansion errors.
---
lisp/emacs-lisp/ert.el | 41 ++++++++++++++++++++++++++++++---------
test/lisp/emacs-lisp/ert-tests.el | 9 +++++++++
2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index d7bd331..c232b08 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -260,6 +260,14 @@ DATA is displayed to the user and should state the reason
for skipping."
(when ert--should-execution-observer
(funcall ert--should-execution-observer form-description)))
+;; See Bug#24402 for why this exists
+(defun ert--should-signal-hook (error-symbol data)
+ "Stupid hack to stop `condition-case' from catching ert signals.
+It should only be stopped when ran from inside ert--run-test-internal."
+ (when (and (not (symbolp debugger)) ; only run on anonymous debugger
+ (memq error-symbol '(ert-test-failed ert-test-skipped)))
+ (funcall debugger 'error data)))
+
(defun ert--special-operator-p (thing)
"Return non-nil if THING is a symbol naming a special operator."
(and (symbolp thing)
@@ -267,16 +275,22 @@ DATA is displayed to the user and should state the reason
for skipping."
(and (subrp definition)
(eql (cdr (subr-arity definition)) 'unevalled)))))
+;; FIXME: Code inside of here should probably be evaluated like it is
+;; outside of tests, with the sole exception of error handling
(defun ert--expand-should-1 (whole form inner-expander)
"Helper function for the `should' macro and its variants."
(let ((form
- (macroexpand form (append (bound-and-true-p
- byte-compile-macro-environment)
- (cond
- ((boundp 'macroexpand-all-environment)
- macroexpand-all-environment)
- ((boundp 'cl-macro-environment)
- cl-macro-environment))))))
+ ;; catch macroexpansion errors
+ (condition-case err
+ (macroexpand-all form
+ (append (bound-and-true-p
+ byte-compile-macro-environment)
+ (cond
+ ((boundp 'macroexpand-all-environment)
+ macroexpand-all-environment)
+ ((boundp 'cl-macro-environment)
+ cl-macro-environment))))
+ (error `(signal ',(car err) ',(cdr err))))))
(cond
((or (atom form) (ert--special-operator-p (car form)))
(let ((value (cl-gensym "value-")))
@@ -297,8 +311,13 @@ DATA is displayed to the user and should state the reason
for skipping."
(args (cl-gensym "args-"))
(value (cl-gensym "value-"))
(default-value (cl-gensym "ert-form-evaluation-aborted-")))
- `(let ((,fn (function ,fn-name))
- (,args (list ,@arg-forms)))
+ `(let* ((,fn (function ,fn-name))
+ (,args (condition-case err
+ (let ((signal-hook-function
#'ert--should-signal-hook))
+ (list ,@arg-forms))
+ (error (progn (setq ,fn #'signal)
+ (list (car err)
+ (cdr err)))))))
(let ((,value ',default-value))
,(funcall inner-expander
`(setq ,value (apply ,fn ,args))
@@ -760,6 +779,10 @@ This mainly sets up debugger-related bindings."
;; too expensive, we can remove it.
(with-temp-buffer
(save-window-excursion
+ ;; FIXME: Use `signal-hook-function' instead of `debugger' to
+ ;; handle ert errors. Once that's done, remove
+ ;; `ert--should-signal-hook'. See Bug#24402 and Bug#11218 for
+ ;; details.
(let ((debugger (lambda (&rest args)
(ert--run-test-debugger test-execution-info
args)))
diff --git a/test/lisp/emacs-lisp/ert-tests.el
b/test/lisp/emacs-lisp/ert-tests.el
index 57463ad..2fbc188 100644
--- a/test/lisp/emacs-lisp/ert-tests.el
+++ b/test/lisp/emacs-lisp/ert-tests.el
@@ -294,6 +294,15 @@ failed or if there was a problem."
"the error signaled was a subtype of the expected type")))))
))
+(ert-deftest ert-test-should-error-argument ()
+ "Errors due to evaluating arguments should not break tests."
+ (should-error (identity (/ 1 0))))
+
+(ert-deftest ert-test-should-error-macroexpansion ()
+ "Errors due to expanding macros should not break tests."
+ (cl-macrolet ((test () (error "Foo")))
+ (should-error (test))))
+
(ert-deftest ert-test-skip-unless ()
;; Don't skip.
(let ((test (make-ert-test :body (lambda () (skip-unless t)))))
- [Emacs-diffs] master updated (e6fa083 -> bec5b60), Noam Postavsky, 2017/08/07
- [Emacs-diffs] master 00f7e31 4/8: Add a test of handling of circular values to testcover-tests, Noam Postavsky, 2017/08/07
- [Emacs-diffs] master 95a04fd 2/8: ; Avoid test failures when running from compiled test files, Noam Postavsky, 2017/08/07
- [Emacs-diffs] master cc30d77 5/8: Let `define-symbol-prop' take effect during compilation, Noam Postavsky, 2017/08/07
- [Emacs-diffs] master b5c8e98 6/8: Let the cl-typep effects of defclass work during compilation (Bug#27718), Noam Postavsky, 2017/08/07
- [Emacs-diffs] master 054c198 1/8: Catch argument and macroexpansion errors in ert,
Noam Postavsky <=
- [Emacs-diffs] master 0508045 3/8: Don't error on circular values in testcover, Noam Postavsky, 2017/08/07
- [Emacs-diffs] master 79a7456 7/8: Don't define gv expanders in compiler's runtime (Bug#27016), Noam Postavsky, 2017/08/07
- [Emacs-diffs] master bec5b60 8/8: ; Merge: Fixes for macroexpansion and compilation, Noam Postavsky, 2017/08/07