hasql-class-0.0.0.0: test/Hasql/ClassSpec.hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
module Hasql.ClassSpec (spec) where
import Data.String.QQ (s)
import Data.Int
import Data.Text (Text)
import qualified Data.Text as Text
import GHC.Generics (Generic)
import Hasql.Connection (acquire, release)
import Hasql.Session (query, Session, Error, sql, run)
import System.Process (callCommand)
import Test.Hspec (describe, it, Spec, shouldBe)
import Test.QuickCheck (Arbitrary(..), property, (==>))
import Test.QuickCheck.Instances ()
import Hasql.Class
spec :: Spec
spec = describe "Encodable" $ do
it "works for the generic instance"
$ property $ \(test :: Test) -> noNullBytes test ==> do
result <- withDB $ do
() <- query test $ stmtUnit [s|
INSERT INTO hasql_class_test_table
VALUES ($1, $2, $3, $4) |] True
query () $ stmtList "SELECT * FROM hasql_class_test_table" True
result `shouldBe` Right [test]
-- postgres drops null bytes
noNullBytes :: Test -> Bool
noNullBytes t
= not (Text.any (== '\NUL') $ t_text t)
&& not (t_char t == '\NUL')
data Test = Test
{ t_int :: Int16
, t_text :: Text
, t_char :: Char
, t_bool :: Bool
} deriving (Eq, Show, Read, Generic, Encodable, Decodable)
instance Arbitrary Test where
arbitrary = Test <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
withDB :: Session b -> IO (Either Error b)
withDB sess = do
callCommand createCmd
conn <- acquire info >>= \i -> case i of
Left err -> error $ show err
Right v -> return v
result <- flip run conn $ do
sql createTbl
s' <- sess
sql deleteTbl
return s'
release conn
return result
where
info = "dbname=hasql-class-test"
createCmd = "createdb hasql-class-test >/dev/null 2>/dev/null || true"
createTbl = [s|
CREATE TABLE IF NOT EXISTS hasql_class_test_table (
t_int integer NOT NULL,
t_text text NOT NULL,
t_char char NOT NULL,
t_bool bool NOT NULL
)
|]
deleteTbl = "DROP TABLE hasql_class_test_table "