I need to test a lot of functions that access the database (via Persistent). While I can do this using monadicIO
and withSqlitePool
it will result in inefficient tests. Each test, not property, but test, will create and destroy the DB pool. How do I prevent this?
Important: Forget about efficiency or elegance. I haven't been able to make the QuickCheck
and Persistent
types to even compose.
instance (Monad a) => MonadThrow (PropertyM a)
instance (MonadThrow a) => MonadCatch (PropertyM a)
type NwApp = SqlPersistT IO
prop_childCreation :: PropertyM NwApp Bool
prop_childCreation = do
uid <- pick $ UserKey <$> arbitrary
lid <- pick $ LogKey <$> arbitrary
gid <- pick $ Aria2Gid <$> arbitrary
let createDownload_ = createDownload gid lid uid []
(Entity pid _) <- run $ createDownload_ Nothing
dstatus <- pick arbitrary
parent <- run $ updateGet pid [DownloadStatus =. dstatus]
let test = do
(Entity cid child) <- run $ createDownload_ (Just pid)
case (parent ^. status, child ^. status) of
(DownloadComplete ChildrenComplete, DownloadComplete ChildrenNone) -> return True
(DownloadComplete ChildrenIncomplete, DownloadIncomplete) -> return True
_ -> return False
test `catches` [
Handler (\ (e :: SanityException) -> return True),
Handler (\ (e :: SomeException) -> return False)
]
-- How do I write this function?
runTests = monadicIO $ runSqlite ":memory:" $ do
-- whatever I do, this function fails to typecheck
withSqlitePool
outside of the call tomonadicIO
? E.g.,tests = withSqlitePool $ \pool -> do monadicIO (test1 pool); monadicIO (test2 pool)
. – Gwenn:memory:
(I think that's more or less just an in-memory SQLite database). It seems to work well enough, certainly enough to never be a bottleneck, but perhaps you are moving more data around than we are. The slow arduous thing you could do is create your own instance ofPersistStore
and implement it with (for example) a bunch ofData.Map
s. But that absolutely prevents you from using anything inDatabase.Persist.Sql
, in which case you would need to spend an arm and a leg to construct aSqlBackend
value. – SkylightConnectionPool
manually. Can you help me with some PoC code? I'm fine even if it type-checks (I'll tackle the elegance later). – Implant