hackerbase/testing.scm

109 lines
3.3 KiB
Scheme

;;
;; testing.scm
;;
;; Infrastructure for sipmle unit tests.
;;
;; ISC License
;;
;; Copyright 2023 Brmlab, z.s.
;; Dominik Pantůček <dominik.pantucek@trustica.cz>
;;
;; Permission to use, copy, modify, and/or distribute this software
;; for any purpose with or without fee is hereby granted, provided
;; that the above copyright notice and this permission notice appear
;; in all copies.
;;
;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
;; WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
;; WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
;; AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
;; CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
;; OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
;; NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
;; CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
;;
(declare (unit testing))
(module
testing
(test-eq? test-equal? test-exn test-true test-false run-tests)
(import scheme
(chicken condition)
(chicken format))
;; Evaluates body ... expressions with exception handler installed.
(define-syntax with-handler
(syntax-rules ()
((_ handler body ...)
(call-with-current-continuation
(lambda (k)
(with-exception-handler
(lambda (x) (k (handler x)))
(lambda () body ...)))))))
;; Test passes if the-test does not raise an exception and the result
;; is eq? to expected-result.
(define-syntax test-eq?
(syntax-rules ()
((_ name expression expected-result)
(let ((result expression))
(if (equal? result expected-result)
(display ".")
(error 'test-eq? (sprintf "~A expression=~S expected-result=~S result=~S"
'name 'expression expected-result result)))))))
;; Test passes if the-test does not raise an exception and the result
;; is equal? to expected-result.
(define-syntax test-equal?
(syntax-rules ()
((_ name expression expected-result)
(let ((result expression))
(if (equal? result expected-result)
(display ".")
(error 'test-equal? (sprintf "~A expression=~S expected-result=~S result=~S"
'name 'expression expected-result result)))))))
;; Test passes if the expression evaluates to #t, raises exception
;; otherwise.
(define-syntax test-true
(syntax-rules ()
((_ name expression)
(let ((result expression))
(if (eq? result #t)
(display ".")
(error 'test-true (sprintf "~A expression=~S result=~S"
'name 'expression result)))))))
;; Test passes if the expression evaluates to #f, raises exception
;; otherwise.
(define-syntax test-false
(syntax-rules ()
((_ name expression)
(let ((result expression))
(if (eq? result #f)
(display ".")
(error 'test-true (sprintf "~A expression=~S result=~S"
'name 'expression result)))))))
;; Passes if the-test raises an exception
(define-syntax test-exn
(syntax-rules ()
((_ name the-test)
(if (with-handler (lambda (x) #t)
the-test #f)
(display ".")
(error 'unit-test name)))))
;; Displays test specification, evaluates all body ... expressions
;; and prints "ok." at the and of the line if all succeed.
(define-syntax run-tests
(syntax-rules ()
((_ name body ...)
(let ()
(display (sprintf "[test] ~A " 'name))
body ...
(print " ok.")))))
)