;; ;; testing.scm ;; ;; Infrastructure for sipmle unit tests. ;; ;; ISC License ;; ;; Copyright 2023 Brmlab, z.s. ;; Dominik Pantůček ;; ;; 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. ;; (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."))))) )