;;;; utilitites ;;; unit tests (adapted from peter seiblel) (defvar *test-name* nil) (defmacro deftest (name parameters &body body) "Define a test function. Within a test function we can call other test functions or use 'check' to run individual test cases." `(defun ,name ,parameters (let ((*test-name* (append *test-name* (list ',name)))) ,@body))) (defmacro check (&body forms) "Run each expression in 'forms' as a test case." `(combine-results ,@(loop for f in forms collect `(report-result ,f ',f)))) (defmacro with-gensyms ((&rest names) &body body) `(let ,(loop for n in names collect `(,n (make-symbol ,(string n)))) ,@body)) (defmacro combine-results (&body forms) "Combine the results (as booleans) of evaluating 'forms' in order." (with-gensyms (result) `(let ((,result t)) ,@(loop for f in forms collect `(unless ,f (setf ,result nil))) ,result))) (defun report-result (result form) "Report the results of a single test case, but succinctly if it passes." (if result (format t "+") (format t "~%fail ... ~a: ~a~%" *test-name* form)) result) (defmacro samep (form string) `(string= (whiteout (format nil "~a" ,form)) (whiteout ,string))) ;; handling whitespace (defun whitespacep (char) "Returns true if the Lisp character CHAR is whitespace" (member char '(#\Space #\Tab #\Newline) :test #'char=)) (defun whiteout (seq) (remove-if #'whitespacep seq)) ;;;Added by Peter Santiago (defun between (x y z) (and (<= x y) (<= y z)))