Browse files

Add a cute lisp mocking utility found on stackoverflow.

  • Loading branch information...
kingcons committed Mar 13, 2012
1 parent f434ea1 commit 97b9c18f2aaf6611d1b7b9d6b90c55efb36c4586
Showing with 27 additions and 0 deletions.
  1. +27 −0 mock.lisp
@@ -0,0 +1,27 @@
+;; Lovingly stolen from 6502 on Stackoverflow
+;; See:
+;; (declaim (notinline function-to-patch)) ; may come in handy if with-function-patch appears busted
+(defpackage :easymock
+ (:use :cl)
+ (:export #:with-function-patch))
+(in-package :easymock)
+(defmacro with-function-patch (patch &rest body)
+ "Takes a PATCH form like a FLET clause, i.e. (fn-name (lambda-list) body),
+evaluates BODY in an environment with fn-name rebound to the PATCH form and
+uses UNWIND-PROTECT to safely restore the original definition afterwards."
+ (let ((oldfn (gensym))
+ (result (gensym))
+ (name (car patch))
+ (args (cadr patch))
+ (pbody (cddr patch)))
+ `(let ((,oldfn (symbol-function ',name)))
+ (setf (symbol-function ',name) (lambda ,args ,@pbody))
+ (unwind-protect (progn ,@body)
+ (setf (symbol-function ',name) ,oldfn))
+ ,result)))
+;; What about for other types? Compound Structures, Classes+Methods, Types themselves, etc?
+;; What if you need to mock a macro? o_O

0 comments on commit 97b9c18

Please sign in to comment.