emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/buttercup bb3fba3 227/340: Properly handle return values a


From: ELPA Syncer
Subject: [nongnu] elpa/buttercup bb3fba3 227/340: Properly handle return values and thrown signals in spies
Date: Thu, 16 Dec 2021 14:59:39 -0500 (EST)

branch: elpa/buttercup
commit bb3fba35c38567e336243b8810d4baec6be44a38
Author: Ryan C. Thompson <rct@thompsonclan.org>
Commit: Ryan C. Thompson <rct@thompsonclan.org>

    Properly handle return values and thrown signals in spies
    
    Attempting to access the return valye of a spy context representing a
    call that threw a signal now throws an error. Similarly, attempting to
    access the thrown signal of a successful function call also throws an
    error.
    
    This is implemented by using two new structs derived from the
    spy-context struct: one for successful calls and one for errors.
    Ideally, we would use cl-defgeneric, but it is not available prior to
    Emacs 25.1.
    
    Tests are added for the new behavior, and several existing tests are
    modified to accommodate it.
---
 buttercup.el            | 26 ++++++++++++++------------
 docs/writing-tests.md   | 35 +++++++++++++++++++++++++----------
 tests/test-buttercup.el |  2 +-
 3 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/buttercup.el b/buttercup.el
index a360a4b..29d8a16 100644
--- a/buttercup.el
+++ b/buttercup.el
@@ -1023,10 +1023,14 @@ DESCRIPTION has the same meaning as in `xit'. FUNCTION 
is ignored."
   "A mapping of currently-defined spies to their contexts.")
 
 (cl-defstruct spy-context
-  args
-  return-value
-  thrown-signal
-  current-buffer)
+  args current-buffer)
+;; The struct and slot names are kind of a cheat so that the accessor
+;; function names remain unchanged: `spy-context-return-value' and
+;; `spy-context-thrown-signal'.
+(cl-defstruct (spy-context-return (:include spy-context))
+  value)
+(cl-defstruct (spy-context-thrown (:include spy-context))
+  signal)
 
 (defun spy-on (symbol &optional keyword arg)
   "Create a spy (mock) for the function SYMBOL.
@@ -1118,10 +1122,9 @@ responsibility to ensure ARG is a command."
                      returned t)
                (buttercup--spy-calls-add
                 this-spy-function
-                (make-spy-context :args args
-                                  :return-value return-value
-                                  :thrown-signal nil
-                                  :current-buffer (current-buffer)))
+                (make-spy-context-return :args args
+                                         :value return-value
+                                         :current-buffer (current-buffer)))
                return-value)
            (error
             ;; If returned is non-nil, then the error we caught
@@ -1129,10 +1132,9 @@ responsibility to ensure ARG is a command."
             (unless returned
               (buttercup--spy-calls-add
                this-spy-function
-               (make-spy-context :args args
-                                 :return-value nil
-                                 :thrown-signal err
-                                 :current-buffer (current-buffer))))
+               (make-spy-context-thrown :args args
+                                        :signal err
+                                        :current-buffer (current-buffer))))
             ;; Regardless, we only caught this error in order to
             ;; record it, so we need to re-throw it.
             (signal (car err) (cdr err)))))))
diff --git a/docs/writing-tests.md b/docs/writing-tests.md
index 643303c..9307f43 100644
--- a/docs/writing-tests.md
+++ b/docs/writing-tests.md
@@ -600,9 +600,9 @@ Finally, `spy-calls-reset` clears all tracking for a spy.
 
     (expect (spy-calls-all 'set-foo)
             :to-equal
-            `(,(make-spy-context :current-buffer (current-buffer)
-                                 :args '(123)
-                                 :return-value nil))))
+            `(,(make-spy-context-return :current-buffer (current-buffer)
+                                        :args '(123)
+                                        :value nil))))
 
   (it "has a shortcut to the most recent call"
     (set-foo 123)
@@ -610,9 +610,9 @@ Finally, `spy-calls-reset` clears all tracking for a spy.
 
     (expect (spy-calls-most-recent 'set-foo)
             :to-equal
-            (make-spy-context :current-buffer (current-buffer)
-                              :args '(456 "baz")
-                              :return-value nil)))
+            (make-spy-context-return :current-buffer (current-buffer)
+                                     :args '(456 "baz")
+                                     :value nil)))
 
   (it "has a shortcut to the first call"
     (set-foo 123)
@@ -620,9 +620,9 @@ Finally, `spy-calls-reset` clears all tracking for a spy.
 
     (expect (spy-calls-first 'set-foo)
             :to-equal
-            (make-spy-context :current-buffer (current-buffer)
-                              :args '(123)
-                              :return-value nil)))
+            (make-spy-context-return :current-buffer (current-buffer)
+                                     :args '(123)
+                                     :value nil)))
 
   (it "tracks the return values and error signals of each call"
     ;; Set up `set-foo' so that it can either return a value or throw
@@ -634,13 +634,28 @@ Finally, `spy-calls-reset` clears all tracking for a spy.
                 (error "Value must not be negative"))))
     (expect (set-foo 1) :to-be 1)
     (expect (set-foo -1) :to-throw 'error)
+    (expect (spy-context-return-p (spy-calls-first 'set-foo)))
     (expect
      (spy-context-return-value (spy-calls-first 'set-foo))
      :to-be 1)
+    ;; Trying to get the thrown signal from a call that didn't throw a
+    ;; signal is an error
     (expect
      (spy-context-thrown-signal
+      (spy-calls-first 'set-foo))
+     :to-throw)
+
+    (expect (spy-context-thrown-p (spy-calls-most-recent 'set-foo)))
+    (expect
+     (spy-context-thrown-signal
+      (spy-calls-most-recent 'set-foo))
+     :to-equal '(error "Value must not be negative"))
+    ;; Trying to get the return value from a call that threw a signal
+    ;; raises an error
+    (expect
+     (spy-context-return-value
       (spy-calls-most-recent 'set-foo))
-     :to-equal (list 'error "Value must not be negative")))
+     :to-throw))
 
   (it "can be reset"
     (set-foo 123)
diff --git a/tests/test-buttercup.el b/tests/test-buttercup.el
index c2e8317..6368202 100644
--- a/tests/test-buttercup.el
+++ b/tests/test-buttercup.el
@@ -933,7 +933,7 @@
         (expect (test-function-throws-on-negative -5) :to-throw 'error)
         (expect (spy-context-thrown-signal
                  (spy-calls-first 'test-function-throws-on-negative))
-                :to-be nil)
+                :to-throw)
         (expect (spy-context-thrown-signal
                  (spy-calls-most-recent 'test-function-throws-on-negative))
                 :to-equal '(error "x is less than zero"))))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]