branch: elpa/buttercup
commit 205e18e700301ea0b672c1564330c4658556d042
Author: Ryan C. Thompson <r...@thompsonclan.org>
Commit: Ryan C. Thompson <r...@thompsonclan.org>

    Warn when :var is used with a special variable
    
    Buttercup's ":var" and ":var*" forms only support lexical variables,
    so using a special variable in these forms will almost certainly not
    do what the test author expects.
    
    See #127.
---
 buttercup.el | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/buttercup.el b/buttercup.el
index f7349f357f..e05dad32f0 100644
--- a/buttercup.el
+++ b/buttercup.el
@@ -951,19 +951,33 @@ mainly calls to `describe', `it' and `before-each'."
   (unless lexical-binding
     (signal 'buttercup-dynamic-binding-error
             "buttercup requires `lexical-binding' to be t"))
-  (let ((new-body
-         (cond
-          ((eq (elt body 0) :var)
-           `((let ,(elt body 1)
-               ,@(cddr body))))
-          ((eq (elt body 0) :var*)
-           `((let* ,(elt body 1)
-               ,@(cddr body))))
-          (t body))))
-    (if (or (memq :var new-body)
-              (memq :var* new-body))
+  ;; Convert `:var' or `:var*' to a lexical let form
+  (when
+      (memq (elt body 0) '(:var :var*))
+    (let ((let-form-to-use (if (eq (elt body 0) :var) 'let 'let*))
+          (let-bindings (elt body 1))
+          (let-body (cddr body)))
+      ;; Verify that all the specified variables are lexical
+      (cl-loop
+       for binding in let-bindings
+       for var = (if (symbolp binding) binding (car binding))
+       when (special-variable-p var)
+       do (display-warning
+           'buttercup-describe
+           (concat "Possible erroneous use of special variable `"
+                   (symbol-name var)
+                   "' in :var(*) form")))
+      ;; Wrap new body in the appropriate let form
+      (setq body
+            `((,let-form-to-use
+               ;; Let bindings
+               ,let-bindings
+               ;; Let body
+               ,@let-body)))))
+  (if (or (memq :var body)
+          (memq :var* body))
       `(error "buttercup: :var(*) found in invalid position of describe form 
\"%s\"" ,description)
-    `(buttercup-describe ,description (lambda () ,@new-body)))))
+    `(buttercup-describe ,description (lambda () ,@body))))
 
 (defun buttercup-describe (description body-function)
   "Function to handle a `describe' form.

Reply via email to