[racket] How to write a unit test for syntax-parse expectation failure error message?

From: Greg Hendershott (greghendershott at gmail.com)
Date: Sun Dec 2 17:59:28 EST 2012

Perfect -- thank you!

On Sun, Dec 2, 2012 at 1:34 PM, Ryan Culpepper <ryan at cs.utah.edu> wrote:
> 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
>

Posted on the users mailing list.