I currently have the following test code:
testUpdate :: Test
testUpdate = testCase "update does change artist" $ do
(created, Just revised, parents) <- mbTest $ do
Just editor <- fmap entityRef <$> findEditorByName "acid2"
created <- create editor startWith
let artistId = coreMbid created
newRev <- update editor (coreRevision created) expected
editId <- openEdit
includeRevision editId newRev
apply editId
found <- findLatest artistId
parents <- revisionParents newRev
return (created, found, parents)
coreData revised @?= expected
assertBool "The old revision is a direct parent of the new revision" $
parents == [coreRevision created]
where
startWith = ...
expected = ...
This kinda works, but it's messy. I'd much rather be able to write something without having to return the various things under test, and instead have the assertions where they make sense.
I see there is the Assertable
class, but it seems like I'd probably have to end up reinventing a bunch of stuff.
Why not just have your monad return an IO computation of type IO a
, which is a pure value?
Since as in your comment, the case where the monad is an instance of MonadIO is trivial,
assume that the monad allows pure computation:
newtype M a = M {runM :: ....}
instance Monad M where
...
makeTest :: M Assertion
makeTest = do
created <- ..
found <- ..
parents <- ..
let test1 = coreData revised @?= expected
...
let test2 = assertBool "The old revision..." $
parents == [coreRevision create]
return $ test1 >> test2
testUpdate :: Test
testUpdate = testCase "update does change artist" $ runM makeTest
A bonus is that you could return a collection of tests by one monadic computation, just as you would in the list monad.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With