HMock Matcher Predicates
In HMock
and Impredicative Polymorphism (Part 2), I wrote about how passing
an insufficient number of Predicate
arguments to a Matcher
was the cause of the impredicative
polymorphism errors that I described in HMock and
Impredicative Polymorphism. I fixed the problem by passing anything
as the arguments and pattern matched against the actual values in the Rule
.
I have since realized that this is not the correct way to do this. The
arguments should be matched in the predicates!
I defined the minimal test as follows. In this code, the predicates match any path and mode values, but the rule pattern matches against specific values. Note that this can cause non-exhaustive pattern matching warnings.
main :: IO ()
= defaultMain . testCase "experiment" $ do
main <- runMockT $ do
isEmpty $ WithFile_ anything anything anything
expect |=> \(WithFile "test.txt" ReadMode _action) -> pure True
"test.txt"
isFileEmpty True @=? isEmpty
The predicates for the path and mode parameters should check for the
expected values instead. This is done using the eq
predicate. In this example, the rule does not use any of the parameters,
so they can all be ignored.
main :: IO ()
= defaultMain . testCase "experiment" $ do
main <- runMockT $ do
isEmpty $ WithFile_ (eq "test.txt") (eq ReadMode) anything
expect |=> \(WithFile _path _mode _action) -> pure True
"test.txt"
isFileEmpty True @=? isEmpty
The updated code is available on GitHub. Note that the typed example can be changed in the same way.