Without taking the effort to actually clone JUnit or something, I'm throwing together a few utility functions to help test some SML code. I do know about QCheck, but it can't do this one thing either and isn't what I want generally. (But if you know of another automated-testing framework for SML, please speak up.)
I'd like to be able to assert that some function will throw an exception, e.g., given a function
fun broken x = raise Fail
I'd like to be able to write something like
throws ("ERROR: function is not broken enough!", fn () => broken 1, Fail)
and have it throw an error if the given function does not raise the expected exception.
I tried to write a throws
function with type (string * exn * (unit -> unit)) -> unit
like so:
fun throws (msg, e, func) = func ()
handle e' => if e = e'
then ()
else raise ERROR (SOME msg)
But this generates a bunch of compile-time errors, apparently because ML does not define equality over exceptions:
sexp-tests.sml:54.31-57.49 Error: types of rules don't agree [equality type required]
earlier rule(s): ''Z -> unit
this rule: exn -> 'Y
in rule:
exn => raise exn
sexp-tests.sml:54.31-57.49 Error: handler domain is not exn [equality type required]
handler domain: ''Z
in expression:
func ()
handle
e' => if e = e' then () else raise (ERROR <exp>)
| exn => raise exn
As a workaround, I suspect I could just reuse an existing assert
function I have:
assert ((broken 1; false) handle Fail => true | _ => false)
But it's a bit more thinking and typing.
So, is there any way to write that throws
function in SML?