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

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Mon Dec 3 08:28:15 EST 2012

Can this be abstracted into a linguistic construct and supplied via rackunit? or syntax/rackunit? 




On Dec 2, 2012, at 1:34 PM, Ryan Culpepper 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
> 
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/users



Posted on the users mailing list.