(defmacro defun (name args &rest body)
`(progn
+
(fset ',name
(named-lambda ,(symbol-name name) ,args
,@(if (and (stringp (car body)) (not (null (cdr body))))
(write-line " seconds.")
(cond
- ((zerop *failed-tests*)
- (write-string "All tests (")
- (write-string (prin1-to-string *passed-tests*))
- (write-line ") passed successfully"))
+ ((= *passed-tests* *total-tests*)
+ (write-line "All the tests (")
+ (write-string (prin1-to-string *total-tests*))
+ (write-line ") passed successfully."))
(t
- (write-string (prin1-to-string *failed-tests*))
+ (write-string (prin1-to-string *passed-tests*))
(write-string "/")
- (write-string (prin1-to-string (+ *passed-tests* *failed-tests*)))
- (write-line " failed.")))
+ (write-string (prin1-to-string *total-tests*))
+ (write-line " test(s) passed successfully.")))
+
+(unless (zerop *expected-failures*)
+ (write-string (prin1-to-string *expected-failures*))
+ (write-line " test(s) failed expectedly."))
+
+(unless (zerop *unexpected-passes*)
+ (write-string (prin1-to-string *unexpected-passes*))
+ (write-line " test(s) passed unexpectedly."))
+(defvar *total-tests* 0)
(defvar *passed-tests* 0)
(defvar *failed-tests* 0)
+
+(defvar *expected-failures* 0)
+(defvar *unexpected-passes* 0)
+
(defvar *timestamp* nil)
(defmacro test (condition)
- `(cond
- (,condition
- (write-line ,(concat "Test `" (prin1-to-string condition) "' passed"))
- (incf *passed-tests*))
- (t
- (write-line ,(concat "Test `" (prin1-to-string condition) "' failed."))
- (incf *failed-tests*))))
+ `(progn
+ (cond
+ (,condition
+ (write-line ,(concat "Test `" (prin1-to-string condition) "' passed"))
+ (incf *passed-tests*))
+ (t
+ (write-line ,(concat "Test `" (prin1-to-string condition) "' failed."))
+ (incf *failed-tests*)))
+ (incf *total-tests*)))
+
+(defmacro expected-failure (condition)
+ `(progn
+ (cond
+ (,condition
+ (write-line ,(concat "Test `" (prin1-to-string condition) "' passed unexpectedly!"))
+ (incf *unexpected-passes*))
+ (t
+ (write-line ,(concat "Test `" (prin1-to-string condition) "' failed expectedly."))
+ (incf *expected-failures*)))
+ (incf *total-tests*)))
(write-line "Running tests...")
(write-line "")
;; TODO: Uncomment when either read-from-string supports all these parameters
;; or when test macro supports error handling, whichever comes first
;; (test (equal (read-from-string " 1 3 5" t nil :start 2) (values 3 5)))
-(test (equal (read-from-string "(a b c)") (values '(A B C) 7)))
+(expected-failure
+ (equal (read-from-string "(a b c)") (values '(A B C) 7)))