branch: elpa/buttercup
commit add32f8cbf34373644f55da99ef990f285b80451
Author: Ola Nilsson <ola.nils...@gmail.com>
Commit: Ola Nilsson <ola.nils...@gmail.com>

    Collect stacktraces for errors in matchers
    
    Fake the last frame to show the matchers name.
---
 buttercup.el            | 44 +++++++++++++++++++++++++++++++++++++++++++-
 tests/test-buttercup.el | 22 ++++++++++++++++++++++
 2 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/buttercup.el b/buttercup.el
index b1107a9df1..1558ef749d 100644
--- a/buttercup.el
+++ b/buttercup.el
@@ -2143,9 +2143,51 @@ ARGS according to `debugger'."
                 (eq 'let (cadr frame))
                 (equal '((buttercup--stackframe-marker 1)) (car (cddr frame)))
                 )
-           ;; TODO: What about an error in a matcher?
            ;; TODO: What about :to-throw?
+           ;; buttercup--update-with-funcall (spec ...
+           ;;  apply buttercup--funcall
+           ;;   buttercup--funcall   -- sets the debugger
+           ;;    apply FUNCTION
+           ;;     FUNCTION -- spec body function
+           ;;      condition-case -- from buttercup-with-converted-ert-signals
+           ;;       (let ((buttercup--stackframe-marker 1))
+           ;;        (buttercup-expect
+           ;;         (buttercup--apply-matcher
+           ;;          (apply to-throw-matcher
+           ;;           (to-throw-matcher
+           ;;             We need a new debugger here, the
+           ;;             condition-case can not be used to collect
+           ;;             backtrace.
+           ;; When the error happens in the matcher function
+           ;;  (buttercup-expect
+           ;;   (buttercup--apply-matcher
+           ;;    (apply some-kind-of-function
+           ;;     (matcher
+           ;;      ACTUAL CODE
+           (and (eq 'buttercup--apply-matcher (cadr frame))
+                ;; The two preceeding frames are not of user interest
+                (pop frame-list) (pop frame-list)
+                ;; Add a fake frame for the matcher function
+                (push (cons t
+                            (cons (car (cddr frame))
+                                  (mapcar (lambda (x)
+                                            (if (buttercup--wrapper-fun-p x)
+                                                (buttercup--enclosed-expr x)
+                                              x))
+                                          (cadr (cddr frame)))))
+                      frame-list))
            ;; TODO: What about signals in before and after blocks?
+           ;; BEFORE-EACH:
+           ;; buttercup--run-suite
+           ;;  (let* ...
+           ;;   (dolist (f (buttercup-suite-before-all ...
+           ;;    (buttercup--update-with-funcall suite f
+           ;;     (apply buttercup--funcall
+           ;;      (buttercup-funcall f
+           ;;       (f)
+           ;; Currently, buttercup silently ignores error in
+           ;; (before|after)-(all|each). As long as that is the case,
+           ;; there is nothing we can do about stacktraces.
            )
       (cl-return frame-list))
     (push frame frame-list)))
diff --git a/tests/test-buttercup.el b/tests/test-buttercup.el
index 17d2da7602..6aa4cf35c7 100644
--- a/tests/test-buttercup.el
+++ b/tests/test-buttercup.el
@@ -2028,6 +2028,28 @@ before it's processed by other functions."
                         (mapcar #'buttercup-spec-failure-stack
                                 (buttercup-suite-children (car test-suites)))))
       (expect (buttercup-output) :to-equal "")))
+  (describe "should be collected for errors in"
+    (it "matchers"
+      (put :--failing-matcher 'buttercup-matcher
+           (lambda (&rest _) (/ 1 0)))
+      (with-local-buttercup
+       :reporter #'backtrace-reporter
+       (describe "One suite with"
+         (it "a bad matcher"
+           (expect 1 :--failing-matcher 1)))
+       (buttercup-run :no-error))
+      (put :--failing-matcher 'buttercup-matcher nil)
+      (expect (buttercup-output) :to-equal
+              (concat
+                (make-string 40 ?=) "\n"
+                "One suite with a bad matcher\n"
+                "\n"
+                "Traceback (most recent call last):\n"
+                "  :--failing-matcher(1 1)\n"
+                "  /(1 0)\n"
+                "error: (arith-error)\n\n"
+                )))
+    )
   (describe "with style"
     :var (test-suites long-string)
     ;; Set up tests to test

Reply via email to