On 12/02/2012 12:14 PM, Greg Hendershott wrote:
I'd like to write a unit test that a syntax-parse expectation failure
elicits a certain error message. For instance, I'd do a regexp-match?
that "something" is present in a message like "expected something".

However it seems that syntax-parse expectation failures don't raise an
exception. In other words, this will never return 'caught:

(with-handlers ([exn? (lambda (exn) 'caught)])
   something-that-elicits-a-syntax-parse-expectation-failure)

(At first I'd tried exn:syntax?, and when that didn't work, I checked
to see if it was any kind of exception. Seems not.)

Is there another way to go about this?

No, that's how you do it. For example:

(require syntax/parse)

(with-handlers ([exn:fail:syntax? (lambda (e) 'caught)])
  (syntax-parse #'1 [x:id 'id]))
;; => 'caught

I suspect that what you actually want to do is test a macro that uses syntax-parse; in that case, the issue you're running into is that the macro raises a syntax error at compile time, but the with-handlers doesn't (or rather, wouldn't) get set up to catch the exception until run time.

There are two ways to fix the problem. One is to use eval or expand in your test:

(define testing-ns (make-base-namespace))
;; setup testing-ns
(with-handlers ([exn:fail:syntax? ___])
  (parameterize ((current-namespace testing-ns))
    (expand '(macro-using-syntax-parse ___))))

The other way is to wrap the macro call in something that catches the compile-time exception and produces code that raises a similar run-time exception:

(with-handler ([exn:fail:syntax? ___])
  (convert-syntax-error
    (macro-using-syntax-parse ___)))

The syntax-parse tests use the second technique. Here's the definition of convert-syntax-error from tests/stxparse/setup:

(define-syntax (convert-syntax-error stx)
  (syntax-case stx ()
    [(_ expr)
     (with-handlers ([exn:fail:syntax?
                      (lambda (e)
                        #`(error '#,(exn-message e)))])
       (parameterize ((error-print-source-location #f))
         (local-expand #'expr 'expression null)))]))

Ryan

____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to