 We'll use HUnit's trick of throwing an IOError when an assertion fails.
-- This will terminate the test case, obviously, but we catch the exception
-- and record that it haa failed so that we can continue with other
-- test cases.

-- Unlike HUnit, we catch all exceptions; any that are not thrown by
-- failed assertions are recorded as test errors (as opposed to test failures),
-- and the testing continues...

-- When an assertion fails, we throw an IOException with a special
-- text prefix, which the exception handler will detect.
assertFailure :: CaughtMonadIO m => String -> m ()
assertFailure msg = throwUserError (exceptionPrefix ++ msg)

assertFailure :: CaughtMonadIO m => String -> m ()
assertFailure msg = throwUserError (exceptionPrefix ++ msg)
assertFailure msg = throwUserError (exceptionPrefix ++ msg)