test-framework.lisp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. (in-package :trivial-gray-streams-test)
  2. ;;; test framework
  3. #|
  4. Used like this:
  5. (list (test (a) (assert (= 1 2)))
  6. (test (b) (assert (= 2 2)))
  7. (test (c) (assert (= 2 3))))
  8. => ;; list of test results, 2 failed 1 passed
  9. (#<TEST-RESULT A :FAIL Failed assertion: (= 1 2)> #<TEST-RESULT B :OK> #<TEST-RESULT C :FAIL Failed assertion: (= 2 3)>)
  10. |#
  11. (defclass test-result ()
  12. ((name :type symbol
  13. :initarg :name
  14. :initform (error ":name is requierd")
  15. :accessor name)
  16. (status :type (or (eql :ok) (eql :fail))
  17. :initform :ok
  18. :initarg :status
  19. :accessor status)
  20. (cause :type (or null condition)
  21. :initform nil
  22. :initarg :cause
  23. :accessor cause)))
  24. (defun failed-p (test-result)
  25. (eq (status test-result) :ok))
  26. (defmethod print-object ((r test-result) stream)
  27. (print-unreadable-object (r stream :type t)
  28. (format stream "~S ~S~@[ ~A~]" (name r) (status r) (cause r))))
  29. (defparameter *allow-debugger* nil)
  30. (defun test-impl (name body-fn)
  31. (flet ((make-result (status &optional cause)
  32. (make-instance 'test-result :name name :status status :cause cause)))
  33. (handler-bind ((serious-condition
  34. (lambda (c)
  35. (unless *allow-debugger*
  36. (format t "FAIL: ~A~%" c)
  37. (return-from test-impl
  38. (make-result :fail c))))))
  39. (format t "Running test ~S... " name)
  40. (funcall body-fn)
  41. (format t "OK~%")
  42. (make-result :ok))))
  43. (defmacro test ((name) &body body)
  44. "If the BODY signals a SERIOUS-CONDITION
  45. this macro returns a failed TEST-RESULT; otherwise
  46. returns a successfull TEST-RESULT."
  47. `(test-impl (quote ,name) (lambda () ,@body)))