-
-
Notifications
You must be signed in to change notification settings - Fork 35
check-compile-time-exn implementation for compile time exception testing #114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
32fa162
59a0ca7
338cb67
7f2478b
d9e7178
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,7 @@ doc/ | |
.DS_Store | ||
*.bak | ||
TAGS | ||
|
||
pkgs-catalog | ||
|
||
catalog-config.txt |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be better to not try and reuse the |
||
(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 ...+) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use the (syntax-parse stx
[(_ body:expr ...+)
...]) That way, a usage like |
||
(with-syntax ([loc (datum->syntax #f 'loc stx)]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use the (syntax-parse stx
[(_ body ...+)
#:with loc (datum->syntax #f 'loc stx)
(syntax/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 ...) ...)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these shortcut forms should be skipped, actually. They won't work quite right for |
||
(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)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's some more test cases: (test-case "check-compile-time-exn should allow multiple body forms"
(check-compile-time-exn
(define foo 1)
(define bar 2)
(define kaboom)))
(test-case "check-compile-time-exn should allow raising non-exception values"
(check-compile-time-exn
(define-syntax foo (raise "not an exception"))))
(test-case "check-compile-time-exn should not evaluate its body"
(define evaluated? (box #f))
(check-compile-time-exn
(set-box! evaluated? #t)
(define kaboom))
(check-false (unbox evaluated?)))
(test-case "check-compile-time-exn should return the raised value"
(define raised-value (check-compile-time-exn (define-syntax foo (raise 42)))
(check-equal? raised-value 42)) |
||
;; 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! | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if I was being unclear. I think:
1.
body
should be renamed toexpr
; and2. It should not be in
#:contracts
.For the first one, there's a convention to use the name
body
as described here. Because this operand only allows an expression, it should be namedexpr
instead.For the second one, I would hope that it is possible to write
(check-compile-time-exn #rx"foo" 1)
, but1
would not satisfy(-> any/c)
as it's not a function. Switching from(-> any/c)
toany/c
wouldn't work either because (I would hope that) it's possible to write(check-compile-time-exn #rx"foo" (values 1 2 3))
, but again,(values 1 2 3)
would not satisfyany/c
. So just leave it out from#:contracts
.