;;; Provides a few helper macros for testing facilities. (export (assert assert-eq assert-not run-tests)) ;; Panics with a nice error message if the condition is false. (macro (assert pred) `(if (not ,pred) (panic ,(format "assertion `~s` failed" pred)))) ;; Panics with a nice error message if the condition is true. (macro (assert-not pred) `(if ,pred (panic ,(format "assertion `not ~s` failed" pred)))) ;; Panics with a nice error message if the two arguments are not equal. (macro (assert-eq a b) `(let ((assert-lhs ,a) (assert-rhs ,b)) (if (/= assert-lhs assert-rhs) (panic (format ,(format "assertion `~s == ~s` failed; ~~s /= ~~s" a b) assert-lhs assert-rhs))))) ;; Given a set of `(define (name) ...)` expressions, runs each test function. (macro (run-tests :rest test-defs) `(do ,@test-defs (define (run-test name fn) (do (print "Running test ~25a ... " name) (fn) (println "ok"))) ,@(map-into () (lambda (def) (let ((name (first (second def)))) `(run-test ',name ,name))) test-defs))) ; We can't depend on the list module, so we duplicate this definition here. (define (map-into out fn li) (if (null li) out (map-into (append out (fn (first li))) fn (tail li))))