test-framework.lisp 1.8 KB

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