{-# LANGUAGE RecordWildCards #-} 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