module Test.Hspec.DB where
import Control.Exception
import Control.Monad
import qualified Data.ByteString.Char8 as BSC
import Data.Pool
import qualified Database.Postgres.Temp as Temp
import Database.PostgreSQL.Simple
import Database.PostgreSQL.Transact
import Test.Hspec
data TestDB = TestDB
{ tempDB :: Temp.DB
, pool :: Pool Connection
}
setupDB :: (Connection -> IO ()) -> IO TestDB
setupDB migrate = do
tempDB <- either throwIO return =<< Temp.startAndLogToTmp []
putStrLn $ Temp.connectionString tempDB
pool <- createPool
(connectPostgreSQL (BSC.pack $ Temp.connectionString tempDB))
close
1
100000000
50
withResource pool migrate
return TestDB {..}
teardownDB :: TestDB -> IO ()
teardownDB TestDB {..} = do
destroyAllResources pool
void $ Temp.stop tempDB
withPool :: TestDB -> (Connection -> IO a) -> IO a
withPool testDB = withResource (pool testDB)
withDB :: DB a -> TestDB -> IO a
withDB action testDB =
withResource (pool testDB) (runDBTSerializable action)
runDB :: TestDB -> DB a -> IO a
runDB = flip withDB
itDB :: String -> DB a -> SpecWith TestDB
itDB msg action = it msg $ void . withDB action
describeDB :: (Connection -> IO ()) -> String -> SpecWith TestDB -> Spec
describeDB migrate str =
beforeAll (setupDB migrate) . afterAll teardownDB . describe str