(module test-harness mzscheme (require syntax/stx) (provide (all-defined)) (define (lst-bound-id=? x y) (andmap bound-identifier=? x y)) (define (stx-bound-id=? x y) (cond ((and (stx-pair? x) (not (syntax-e (stx-car x))) (identifier? (stx-cdr x))) (and (identifier? y) (not (module-identifier=? (stx-cdr x) y)))) ((and (stx-null? x) (stx-null? y)) #t) ((and (stx-pair? x) (stx-pair? y)) (and (stx-bound-id=? (stx-car x) (stx-car y)) (stx-bound-id=? (stx-cdr x) (stx-cdr y)))) ((and (identifier? x) (identifier? y)) (bound-identifier=? x y)) ((and (number? (syntax-e x)) (number? (syntax-e y))) (= (syntax-e x) (syntax-e y))) (else #f))) (define-syntax test-syntax-error (syntax-rules () ((_ err expr) (with-handlers ((exn:fail:syntax? (lambda (exn) (printf "syntax error \"~a\"~n got message \"~a\"~n~n" err (exn-message exn))))) (expand #'expr) (error 'test-syntax-error "expected syntax error \"~a\" on ~a, got none" err 'expr))))) (define-syntax test-runtime-error (syntax-rules () ((_ err-pred err expr) (with-handlers ((err-pred (lambda (exn) (printf "runtime error \"~a\"~n got message \"~a\"~n~n" err (exn-message exn))))) expr (error 'test-runtime-error "expected runtime error \"~a\" on ~a, got none" err 'expr))))) (define-syntax test (syntax-rules () ((_ expected-value expr) (test equal? expected-value expr)) ((_ cmp expected-value expr) (let ((v expr)) (unless (cmp expected-value v) (error 'test "expected ~a to evaluate to ~a, got ~a" 'expr 'expected-value v)))))))