racket / rackunit

Other
18 stars 32 forks source link

rackunit handling of exceptions #177

Open rfindler opened 1 week ago

rfindler commented 1 week ago

This program:

#lang racket
(require rackunit)
(check-equal?
 (match 1
   [2 #f])
 2)

doesn't say what line the match is on, but match, in general, includes that information, as in this example:

#lang racket
(match 1
  [2 #f])

where it produces something like:

match: no matching clause for 1
  location...:
   /Users/robby/tmp2.rkt:2:0

I think it should work to have rackunit simply call the error display handler but maybe there is something else to this?

rfindler commented 1 week ago

It looks like changing the function display-raised-message in rackunit/private/format to this function:

(define (display-raised-message v)
  (cond
    [(exn? v)
     (parameterize ([current-error-port (current-output-port)])
       ((error-display-handler) (exn-message v) v))]
    [else
     (printf "\nA value other than an exception was raised: ~e\n" v)]))

gets better printfs.

It may be that these should be indented, in which case this might be better:

(define (display-raised-message v)
  (cond
    [(exn? v)
     (define sp (open-output-string))
     (parameterize ([current-error-port sp])
       ((error-display-handler) (exn-message v) v))
     (display "  ")
     (display (regexp-replace* #rx"\n(.)" (get-output-string sp) "\n  \\1"))]
    [else
     (printf "\nA value other than an exception was raised: ~e\n" v)]))
rfindler commented 1 week ago

Actually, it looks like rackunit is using exceptions that are below exn:fail? internally to handle control flow when a test case fails. (I'm not sure that's a good idea, actually, but maybe an issue beyond this one.)

So this is a better replacement function:

(define (display-raised-message v)
  (cond
    [(exn:test? v)
     (when (not (equal? (exn-message v) ""))
       (newline)
       (displayln (exn-message v)))]
    [(exn:fail? v)
     (define sp (open-output-string))
     (parameterize ([current-error-port sp])
       ((error-display-handler) (exn-message v) v))
     (display "  ")
     (display (regexp-replace* #rx"\n(.)" (get-output-string sp) "\n  \\1"))]
    [else
     (printf "\nA value other than an exception was raised: ~e\n" v)]))