generalized check-exn so that you can supply a regular expression as the predicate (which matches the exception message)

This commit is contained in:
Robby Findler 2010-08-14 21:32:13 -05:00
parent 12b345dc99
commit b56019c275
2 changed files with 39 additions and 34 deletions

View File

@ -195,32 +195,35 @@
#t #t
(fail-check)))))])) (fail-check)))))]))
(define-check (check-exn pred thunk) (define-check (check-exn raw-pred thunk)
(let/ec succeed (let ([pred (if (regexp? raw-pred)
(with-handlers (λ (x) (and (exn:fail? x) (regexp-match raw-pred (exn-message x))))
(;; catch the exception we are looking for and raw-pred)])
;; succeed (let/ec succeed
[pred (with-handlers
(lambda (exn) (succeed #t))] (;; catch the exception we are looking for and
;; rethrow check failures if we aren't looking ;; succeed
;; for them [pred
[exn:test:check? (lambda (exn) (succeed #t))]
(lambda (exn) ;; rethrow check failures if we aren't looking
(refail-check exn))] ;; for them
;; catch any other exception and raise an check [exn:test:check?
;; failure (lambda (exn)
[exn:fail? (refail-check exn))]
(lambda (exn) ;; catch any other exception and raise an check
(with-check-info* ;; failure
(list [exn:fail?
(make-check-message "Wrong exception raised") (lambda (exn)
(make-check-info 'exn-message (exn-message exn)) (with-check-info*
(make-check-info 'exn exn)) (list
(lambda () (fail-check))))]) (make-check-message "Wrong exception raised")
(thunk)) (make-check-info 'exn-message (exn-message exn))
(with-check-info* (make-check-info 'exn exn))
(list (make-check-message "No exception raised")) (lambda () (fail-check))))])
(lambda () (fail-check))))) (thunk))
(with-check-info*
(list (make-check-message "No exception raised"))
(lambda () (fail-check))))))
(define-check (check-not-exn thunk) (define-check (check-not-exn thunk)
(with-handlers (with-handlers

View File

@ -98,11 +98,14 @@ For example, the following checks all fail:
] ]
@defproc[(check-exn (exn-predicate (-> any (or/c #t #f))) (thunk (-> any)) (message string? "")) @defproc[(check-exn (exn-predicate (or/c (-> any (or/c #t #f)) regexp?)) (thunk (-> any)) (message string? ""))
#t]{ #t]{
Checks that @racket[thunk] raises an exception and that
Checks that @racket[thunk] raises an exception for which either @racket[exn-predicate] returns @racket[#t] if it is a function,
@racket[exn-predicate] returns @racket[#t]. The optional 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?].
The optional
@racket[message] is included in the output if the check @racket[message] is included in the output if the check
fails. A common error is to use an expression instead of a fails. A common error is to use an expression instead of a
function of no arguments for @racket[thunk]. Remember that function of no arguments for @racket[thunk]. Remember that
@ -111,14 +114,13 @@ checks are conceptually functions.}
Here are two example, one showing a test that succeeds, and one showing a common error: Here are two example, one showing a test that succeeds, and one showing a common error:
@racketblock[ @racketblock[
(check-exn exn? (check-exn exn:fail?
(lambda () (lambda ()
(raise (make-exn "Hi there" (raise (make-exn "Hi there"
(current-continuation-marks))))) (current-continuation-marks)))))
(code:comment "Forgot to wrap the expression in a thunk. Don't do this!") (code:comment "Forgot to wrap the expression in a thunk. Don't do this!")
(check-exn exn? (check-exn exn:fail?
(raise (make-exn "Hi there" (error 'hi "there"))
(current-continuation-marks))))
] ]
@defproc[(check-not-exn (thunk (-> any)) (message string? "")) #t]{ @defproc[(check-not-exn (thunk (-> any)) (message string? "")) #t]{