Change type of `expectationFailure` to `IO a`
That makes expectationFailure more general, but it hurts type inference, e.g. the following will need a type annotation:
it "foobar" $ do
expectationFailure "foobar" :: Expectation
However, expectationFailure is not very useful in cases where you only have one code branch. When you have two code branches, the other branch will unify a to (). So I don't see a big issue here.
I see this was closed in 2016, but the type of expectationFailure is still Expectation ~ IO (). I came here to ask for the same feature.
I find it extremely useful to write test helpers that deal with typed failure as expectation failures in tests. For example:
case result of
Left err -> expectationFailure $ "Expected whatever to succeed, got: " <> err
Right a -> pure a
The utility of this far outweighs any inference issues in our experience.
So I don't see a big issue here
Can confirm. Many of my team's apps have re-defined:
expectationFailure :: String -> IO a
expectationFailure msg = do
Hspec.expectationFailure msg
error "unreachable"
And yet, no problems.
We also use Test.Hspec.Expectations.Lifted in many places, which introduces similar inference "problems". I think its popularity is evidence that it is an acceptable trade-off in the community.
And lastly, there is always example (which maybe didn't exist in 2016)?
It's becoming a bit of a bore to re-write our own expectationFailure in all our projects, so I wonder: would you reconsider the idea?
expectationFailure :: String -> IO a expectationFailure msg = do Hspec.expectationFailure msg error "unreachable"
- You probably want to use
Test.HUnit.assertFailureinstead of rolling your own definition. - There's an open PR, and I agree this is something we'd want. I think it will land eventually. My only gripe with it is that it introduces a "breaking" change to
Test.Hspec, an interface for which I provide very stringent stability guarantees.