Add unit tests and reimplement FromField
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module Database.PostgreSQL.Opium.FromFieldSpec (spec) where
|
||||
|
||||
import Data.ByteString (ByteString)
|
||||
import Data.Text (Text)
|
||||
import Database.PostgreSQL.LibPQ (Connection)
|
||||
import Database.PostgreSQL.Opium (FromRow)
|
||||
import GHC.Generics (Generic)
|
||||
import Test.Hspec (SpecWith, describe, it, shouldBe)
|
||||
|
||||
import qualified Database.PostgreSQL.Opium as Opium
|
||||
|
||||
newtype SingleInt = SingleInt
|
||||
{ int :: Int
|
||||
} deriving (Eq, Generic, Show)
|
||||
|
||||
instance FromRow SingleInt where
|
||||
|
||||
newtype SingleText = SingleText
|
||||
{ text :: Text
|
||||
} deriving (Eq, Generic, Show)
|
||||
|
||||
instance FromRow SingleText where
|
||||
|
||||
newtype SingleString = SingleString
|
||||
{ string :: String
|
||||
} deriving (Eq, Generic, Show)
|
||||
|
||||
instance FromRow SingleString where
|
||||
|
||||
shouldFetch :: (Eq a, FromRow a, Show a) => Connection -> ByteString -> [a] -> IO ()
|
||||
shouldFetch conn query expectedRows = do
|
||||
Just actualRows <- Opium.fetch_ conn query
|
||||
actualRows `shouldBe` expectedRows
|
||||
|
||||
spec :: SpecWith Connection
|
||||
spec = do
|
||||
describe "FromField Int" $ do
|
||||
it "Decodes smallint" $ \conn -> do
|
||||
shouldFetch conn "SELECT 42::SMALLINT AS int" [SingleInt 42]
|
||||
|
||||
it "Decodes integer" $ \conn -> do
|
||||
shouldFetch conn "SELECT 42::INTEGER AS int" [SingleInt 42]
|
||||
|
||||
it "Decodes bigint" $ \conn -> do
|
||||
shouldFetch conn "SELECT 42::BIGINT AS int" [SingleInt 42]
|
||||
|
||||
describe "FromField Text" $ do
|
||||
it "Decodes text" $ \conn -> do
|
||||
shouldFetch conn "SELECT 'Hello, World!'::TEXT AS text" [SingleText "Hello, World!"]
|
||||
|
||||
it "Decodes character" $ \conn -> do
|
||||
shouldFetch conn "SELECT 'Hello, World!'::CHARACTER(10) AS text" [SingleText "Hello, Wor"]
|
||||
shouldFetch conn "SELECT 'Hello, World!'::CHARACTER(20) AS text" [SingleText "Hello, World! "]
|
||||
|
||||
it "Decodes character varying" $ \conn -> do
|
||||
shouldFetch conn "SELECT 'Hello, World!'::CHARACTER VARYING (20) AS text" [SingleText "Hello, World!"]
|
||||
|
||||
describe "FromField String" $ do
|
||||
it "Decodes text" $ \conn -> do
|
||||
shouldFetch conn "SELECT 'Hello, World!'::TEXT AS string" [SingleString "Hello, World!"]
|
||||
|
||||
it "Decodes character" $ \conn -> do
|
||||
shouldFetch conn "SELECT 'Hello, World!'::CHARACTER(10) AS string" [SingleString "Hello, Wor"]
|
||||
shouldFetch conn "SELECT 'Hello, World!'::CHARACTER(20) AS string" [SingleString "Hello, World! "]
|
||||
|
||||
it "Decodes character varying" $ \conn -> do
|
||||
shouldFetch conn "SELECT 'Hello, World!'::CHARACTER VARYING (20) AS string" [SingleString "Hello, World!"]
|
||||
@@ -0,0 +1,37 @@
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE TypeApplications #-}
|
||||
|
||||
module Database.PostgreSQL.OpiumSpec (spec) where
|
||||
|
||||
import Data.Text (Text)
|
||||
import Database.PostgreSQL.LibPQ (Connection)
|
||||
import GHC.Generics (Generic)
|
||||
import Test.Hspec (SpecWith, describe, it, shouldBe)
|
||||
|
||||
import qualified Database.PostgreSQL.LibPQ as LibPQ
|
||||
import qualified Database.PostgreSQL.Opium as Opium
|
||||
|
||||
data Person = Person
|
||||
{ name :: Text
|
||||
, age :: Int
|
||||
} deriving (Eq, Generic, Show)
|
||||
|
||||
instance Opium.FromRow Person where
|
||||
|
||||
spec :: SpecWith Connection
|
||||
spec = do
|
||||
describe "fromRow" $ do
|
||||
it "decodes rows in a Result" $ \conn -> do
|
||||
Just result <- LibPQ.execParams conn "SELECT * FROM person" [] LibPQ.Text
|
||||
|
||||
row0 <- Opium.fromRow @Person (LibPQ.Row 0) result
|
||||
row0 `shouldBe` Just (Person "paul" 25)
|
||||
|
||||
row1 <- Opium.fromRow @Person (LibPQ.Row 1) result
|
||||
row1 `shouldBe` Just (Person "albus" 103)
|
||||
|
||||
describe "fetch_" $ do
|
||||
it "retrieves a list of rows" $ \conn -> do
|
||||
rows <- Opium.fetch_ conn "SELECT * FROM person"
|
||||
rows `shouldBe` Just [Person "paul" 25, Person "albus" 103]
|
||||
+1
-18
@@ -1,18 +1 @@
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
|
||||
module Main (main) where
|
||||
|
||||
import GHC.Generics (Generic)
|
||||
|
||||
import Database.PostgreSQL.Opium (FromRow)
|
||||
|
||||
data Person = Person
|
||||
{ name :: String
|
||||
, age :: Int
|
||||
-- , lovesCats :: Bool
|
||||
} deriving (Generic)
|
||||
|
||||
instance FromRow Person where
|
||||
|
||||
main :: IO ()
|
||||
main = putStrLn "TBD"
|
||||
{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module SpecHook (hook) where
|
||||
|
||||
import Control.Exception (bracket)
|
||||
import Database.PostgreSQL.LibPQ (Connection)
|
||||
import System.Environment (lookupEnv)
|
||||
import Test.Hspec (Spec, SpecWith, around)
|
||||
import Text.Printf (printf)
|
||||
|
||||
import qualified Data.Text as Text
|
||||
import qualified Data.Text.Encoding as Encoding
|
||||
import qualified Database.PostgreSQL.LibPQ as LibPQ
|
||||
|
||||
setupConnection :: IO Connection
|
||||
setupConnection = do
|
||||
Just dbUser <- lookupEnv "DB_USER"
|
||||
Just dbPass <- lookupEnv "DB_PASS"
|
||||
Just dbName <- lookupEnv "DB_NAME"
|
||||
Just dbPort <- lookupEnv "DB_PORT"
|
||||
|
||||
let dsn = printf "host=localhost user=%s password=%s dbname=%s port=%s" dbUser dbPass dbName dbPort
|
||||
conn <- LibPQ.connectdb $ Encoding.encodeUtf8 $ Text.pack dsn
|
||||
_ <- LibPQ.setClientEncoding conn "UTF8"
|
||||
|
||||
_ <- LibPQ.exec conn "CREATE TABLE person (name TEXT NOT NULL, age INT NOT NULL)"
|
||||
_ <- LibPQ.exec conn "INSERT INTO person VALUES ('paul', 25), ('albus', 103)"
|
||||
|
||||
pure conn
|
||||
|
||||
teardownConnection :: Connection -> IO ()
|
||||
teardownConnection conn = do
|
||||
_ <- LibPQ.exec conn "DROP TABLE person"
|
||||
LibPQ.finish conn
|
||||
|
||||
class SpecInput a where
|
||||
hook :: SpecWith a -> Spec
|
||||
|
||||
instance SpecInput Connection where
|
||||
hook = around $ bracket setupConnection teardownConnection
|
||||
|
||||
instance SpecInput () where
|
||||
hook = id
|
||||
Reference in New Issue
Block a user