diff options
Diffstat (limited to 'testiere.lisp')
-rw-r--r-- | testiere.lisp | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/testiere.lisp b/testiere.lisp index 3ec8a03..ea22b80 100644 --- a/testiere.lisp +++ b/testiere.lisp @@ -2,8 +2,6 @@ (in-package #:testiere) -(defun stub-names (stubs) (mapcar 'first stubs)) - (defun build-test (name spec) (match spec ((list :fails inputs) @@ -17,6 +15,9 @@ (,condition (c) (declare (ignore c)) t) (condition (c) (declare (ignore c)) nil)))) + ((list* :program function-name args) + `(funcall ',function-name ,@args)) + ((list* :with-stubs redefs more-specs) (let* ((assoc-vars (loop for (stub-name . more) in redefs @@ -59,6 +60,34 @@ (list (mapcar (lambda (spec) (build-test name spec)) specs) (append before after)))))) +(defmacro with-stub ((name lambda-list &body body) &body forms) + "Runs forms in a context where NAME is temporarily rebound to a +different function. If NAME is not FBOUNDP then it is temporarily +defined." + (let ((cached (gensym))) + `(let ((,cached + (when (fboundp ',name) + (fdefinition ',name)))) + (unwind-protect + (progn + (setf (fdefinition ',name) + (lambda ,lambda-list ,@body)) + ,@forms) + (if ,cached + (setf (fdefinition ',name) + ,cached) + (fmakunbound ',name)))))) + +(defmacro with-stubs (redefinitions &body forms) + "Like WITH-STUB, but REDEFINITIONS is a list of (NAME LAMBDA-LIST +. BODY) list, suitable for defining a function." + (loop + with inner = `(progn ,@forms) + for (name lambda-list . body) in (reverse redefinitions) + do (setf inner `(with-stub (,name ,lambda-list ,@body) + ,inner)) + finally (return inner))) + (defmacro defun/t (name lambda-list &body body) "Like regular DEFUN, but with embedded unit tests. If those tests @@ -82,6 +111,3 @@ - - - |