Without actually trying to clone JUnit or anything else, I am compiling several utility functions to help test some SML code. I really know about QCheck, but it cannot do this alone and not what I want at all. (But if you know one more automated testing framework for SML, please talk.)
I would like to be able to assert that some function throws an exception, for example, when defining a function
fun broken x = raise Fail
I would like to write something like
throws ("ERROR: function is not broken enough!", fn () => broken 1, Fail)
and raise an error if this function does not raise the expected exception.
I tried to write a throws function with type (string * exn * (unit -> unit)) -> unit as follows:
fun throws (msg, e, func) = func () handle e' => if e = e' then () else raise ERROR (SOME msg)
But this creates a bunch of compile-time errors, apparently because ML does not define equality by exception:
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 that I can simply reuse the existing assert function that I have:
assert ((broken 1; false) handle Fail => true | _ => false)
But this is a little more thinking and typing.
So, is there a way to write this throws function in SML?