Moved all describes tests into their own functions.
Factored out the db specific tests and kept the macros as placeholders. Import everything in the cabal file for now. Only using the flags to test that everything still works.
This commit is contained in:
parent
352fca204c
commit
fe4a78d4b6
@ -107,18 +107,16 @@ test-suite test
|
|||||||
-- This library
|
-- This library
|
||||||
, esqueleto
|
, esqueleto
|
||||||
|
|
||||||
if flag(postgresql)
|
, postgresql-simple >= 0.2
|
||||||
build-depends:
|
|
||||||
postgresql-simple >= 0.2
|
|
||||||
, postgresql-libpq >= 0.6
|
, postgresql-libpq >= 0.6
|
||||||
, persistent-postgresql >= 2.0
|
, persistent-postgresql >= 2.0
|
||||||
|
|
||||||
cpp-options: -DWITH_POSTGRESQL
|
, mysql-simple >= 0.2.2.3
|
||||||
|
|
||||||
if flag(mysql)
|
|
||||||
build-depends:
|
|
||||||
mysql-simple >= 0.2.2.3
|
|
||||||
, mysql >= 0.1.1.3
|
, mysql >= 0.1.1.3
|
||||||
, persistent-mysql >= 2.0
|
, persistent-mysql >= 2.0
|
||||||
|
|
||||||
|
if flag(postgresql)
|
||||||
|
cpp-options: -DWITH_POSTGRESQL
|
||||||
|
|
||||||
|
if flag(mysql)
|
||||||
cpp-options: -DWITH_MYSQL
|
cpp-options: -DWITH_MYSQL
|
||||||
|
|||||||
530
test/Test.hs
530
test/Test.hs
@ -26,19 +26,16 @@ import Control.Monad.Trans.Reader (ReaderT)
|
|||||||
import Data.Char (toLower, toUpper)
|
import Data.Char (toLower, toUpper)
|
||||||
import Data.Monoid ((<>))
|
import Data.Monoid ((<>))
|
||||||
import Database.Esqueleto
|
import Database.Esqueleto
|
||||||
#if defined (WITH_POSTGRESQL)
|
|
||||||
import Database.Persist.Postgresql (withPostgresqlConn)
|
import Database.Persist.Postgresql (withPostgresqlConn)
|
||||||
import Data.Ord (comparing)
|
import Data.Ord (comparing)
|
||||||
import Control.Arrow ((&&&))
|
import Control.Arrow ((&&&))
|
||||||
import qualified Database.Esqueleto.PostgreSQL as EP
|
import qualified Database.Esqueleto.PostgreSQL as EP
|
||||||
#elif defined (WITH_MYSQL)
|
|
||||||
import Database.Persist.MySQL ( withMySQLConn
|
import Database.Persist.MySQL ( withMySQLConn
|
||||||
, connectHost
|
, connectHost
|
||||||
, connectDatabase
|
, connectDatabase
|
||||||
, connectUser
|
, connectUser
|
||||||
, connectPassword
|
, connectPassword
|
||||||
, defaultConnectInfo)
|
, defaultConnectInfo)
|
||||||
#endif
|
|
||||||
import Database.Persist.Sqlite (withSqliteConn)
|
import Database.Persist.Sqlite (withSqliteConn)
|
||||||
import Database.Sqlite (SqliteException)
|
import Database.Sqlite (SqliteException)
|
||||||
import Database.Persist.TH
|
import Database.Persist.TH
|
||||||
@ -51,9 +48,10 @@ import qualified Data.List as L
|
|||||||
import qualified Data.Set as S
|
import qualified Data.Set as S
|
||||||
import qualified Data.Text.Lazy.Builder as TLB
|
import qualified Data.Text.Lazy.Builder as TLB
|
||||||
import qualified Database.Esqueleto.Internal.Sql as EI
|
import qualified Database.Esqueleto.Internal.Sql as EI
|
||||||
import Data.Time.Clock (getCurrentTime, diffUTCTime, NominalDiffTime)
|
import Data.Time.Clock (getCurrentTime, diffUTCTime)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
-- Test schema
|
-- Test schema
|
||||||
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
|
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
|
||||||
Foo
|
Foo
|
||||||
@ -133,23 +131,45 @@ share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
|
|||||||
double Double
|
double Double
|
||||||
|]
|
|]
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
-- | this could be achieved with S.fromList, but not all lists
|
-- | this could be achieved with S.fromList, but not all lists
|
||||||
-- have Ord instances
|
-- have Ord instances
|
||||||
sameElementsAs :: Eq a => [a] -> [a] -> Bool
|
sameElementsAs :: Eq a => [a] -> [a] -> Bool
|
||||||
sameElementsAs l1 l2 = null (l1 L.\\ l2)
|
sameElementsAs l1 l2 = null (l1 L.\\ l2)
|
||||||
|
|
||||||
main :: IO ()
|
p1 :: Person
|
||||||
main = do
|
p1 = Person "John" (Just 36) Nothing 1
|
||||||
let p1 = Person "John" (Just 36) Nothing 1
|
|
||||||
p2 = Person "Rachel" Nothing (Just 37) 2
|
|
||||||
p3 = Person "Mike" (Just 17) Nothing 3
|
|
||||||
p4 = Person "Livia" (Just 17) (Just 18) 4
|
|
||||||
p5 = Person "Mitch" Nothing Nothing 5
|
|
||||||
l1 = Lord "Cornwall" (Just 36)
|
|
||||||
l2 = Lord "Dorset" Nothing
|
|
||||||
l3 = Lord "Chester" (Just 17)
|
|
||||||
|
|
||||||
hspec $ do
|
p2 :: Person
|
||||||
|
p2 = Person "Rachel" Nothing (Just 37) 2
|
||||||
|
|
||||||
|
p3 :: Person
|
||||||
|
p3 = Person "Mike" (Just 17) Nothing 3
|
||||||
|
|
||||||
|
p4 :: Person
|
||||||
|
p4 = Person "Livia" (Just 17) (Just 18) 4
|
||||||
|
|
||||||
|
p5 :: Person
|
||||||
|
p5 = Person "Mitch" Nothing Nothing 5
|
||||||
|
|
||||||
|
l1 :: Lord
|
||||||
|
l1 = Lord "Cornwall" (Just 36)
|
||||||
|
|
||||||
|
l2 :: Lord
|
||||||
|
l2 = Lord "Dorset" Nothing
|
||||||
|
|
||||||
|
l3 :: Lord
|
||||||
|
l3 = Lord "Chester" (Just 17)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testSelect :: SpecWith (Arg (IO ()))
|
||||||
|
testSelect = do
|
||||||
describe "select" $ do
|
describe "select" $ do
|
||||||
it "works for a single value" $
|
it "works for a single value" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -171,6 +191,12 @@ main = do
|
|||||||
ret <- select $ return nothing
|
ret <- select $ return nothing
|
||||||
liftIO $ ret `shouldBe` [ Value (Nothing :: Maybe Int) ]
|
liftIO $ ret `shouldBe` [ Value (Nothing :: Maybe Int) ]
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testSelectSource :: SpecWith (Arg (IO ()))
|
||||||
|
testSelectSource = do
|
||||||
describe "selectSource" $ do
|
describe "selectSource" $ do
|
||||||
it "works for a simple example" $
|
it "works for a simple example" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -209,6 +235,11 @@ main = do
|
|||||||
r2 `shouldBe` [ entityKey p2e ]
|
r2 `shouldBe` [ entityKey p2e ]
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testSelectFrom :: SpecWith (Arg (IO ()))
|
||||||
|
testSelectFrom = do
|
||||||
describe "select/from" $ do
|
describe "select/from" $ do
|
||||||
it "works for a simple example" $
|
it "works for a simple example" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -365,6 +396,11 @@ main = do
|
|||||||
liftIO $ ppk `shouldBe` thePk
|
liftIO $ ppk `shouldBe` thePk
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testSelectJoin :: SpecWith (Arg (IO ()))
|
||||||
|
testSelectJoin = do
|
||||||
describe "select/JOIN" $ do
|
describe "select/JOIN" $ do
|
||||||
it "works with a LEFT OUTER JOIN" $
|
it "works with a LEFT OUTER JOIN" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -522,6 +558,71 @@ main = do
|
|||||||
return p
|
return p
|
||||||
liftIO $ (entityVal <$> ps) `shouldBe` [p1]
|
liftIO $ (entityVal <$> ps) `shouldBe` [p1]
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
testPostgresqlRandom :: SpecWith (Arg (IO ()))
|
||||||
|
testPostgresqlRandom = do
|
||||||
|
it "works with random_" $
|
||||||
|
run $ do
|
||||||
|
_ <- select $ return (random_ :: SqlExpr (Value Double))
|
||||||
|
return ()
|
||||||
|
|
||||||
|
testMysqlRandom :: SpecWith (Arg (IO ()))
|
||||||
|
testMysqlRandom = do
|
||||||
|
it "works with random_" $
|
||||||
|
run $ do
|
||||||
|
_ <- select $ return (random_ :: SqlExpr (Value Double))
|
||||||
|
return ()
|
||||||
|
|
||||||
|
testSqliteRandom :: SpecWith (Arg (IO ()))
|
||||||
|
testSqliteRandom = do
|
||||||
|
it "works with random_" $
|
||||||
|
run $ do
|
||||||
|
_ <- select $ return (random_ :: SqlExpr (Value Int))
|
||||||
|
return ()
|
||||||
|
|
||||||
|
testPostgresqlSum :: SpecWith (Arg (IO ()))
|
||||||
|
testPostgresqlSum = do
|
||||||
|
it "works with sum_" $
|
||||||
|
run $ do
|
||||||
|
_ <- insert' p1
|
||||||
|
_ <- insert' p2
|
||||||
|
_ <- insert' p3
|
||||||
|
_ <- insert' p4
|
||||||
|
ret <- select $
|
||||||
|
from $ \p->
|
||||||
|
return $ joinV $ sum_ (p ^. PersonAge)
|
||||||
|
liftIO $ ret `shouldBe` [ Value $ Just (36 + 17 + 17 :: Rational ) ]
|
||||||
|
|
||||||
|
testMysqlSum :: SpecWith (Arg (IO ()))
|
||||||
|
testMysqlSum = do
|
||||||
|
it "works with sum_" $
|
||||||
|
run $ do
|
||||||
|
_ <- insert' p1
|
||||||
|
_ <- insert' p2
|
||||||
|
_ <- insert' p3
|
||||||
|
_ <- insert' p4
|
||||||
|
ret <- select $
|
||||||
|
from $ \p->
|
||||||
|
return $ joinV $ sum_ (p ^. PersonAge)
|
||||||
|
liftIO $ ret `shouldBe` [ Value $ Just (36 + 17 + 17 :: Double ) ]
|
||||||
|
|
||||||
|
testSqliteSum :: SpecWith (Arg (IO ()))
|
||||||
|
testSqliteSum = do
|
||||||
|
it "works with sum_" $
|
||||||
|
run $ do
|
||||||
|
_ <- insert' p1
|
||||||
|
_ <- insert' p2
|
||||||
|
_ <- insert' p3
|
||||||
|
_ <- insert' p4
|
||||||
|
ret <- select $
|
||||||
|
from $ \p->
|
||||||
|
return $ joinV $ sum_ (p ^. PersonAge)
|
||||||
|
liftIO $ ret `shouldBe` [ Value $ Just (36 + 17 + 17 :: Int) ]
|
||||||
|
|
||||||
|
testSelectWhere :: SpecWith (Arg (IO ()))
|
||||||
|
testSelectWhere = do
|
||||||
describe "select/where_" $ do
|
describe "select/where_" $ do
|
||||||
it "works for a simple example with (==.)" $
|
it "works for a simple example with (==.)" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -567,21 +668,12 @@ main = do
|
|||||||
return p
|
return p
|
||||||
liftIO $ ret `shouldBe` [ p3e ]
|
liftIO $ ret `shouldBe` [ p3e ]
|
||||||
|
|
||||||
it "works with sum_" $
|
|
||||||
run $ do
|
|
||||||
_ <- insert' p1
|
|
||||||
_ <- insert' p2
|
|
||||||
_ <- insert' p3
|
|
||||||
_ <- insert' p4
|
|
||||||
ret <- select $
|
|
||||||
from $ \p->
|
|
||||||
return $ joinV $ sum_ (p ^. PersonAge)
|
|
||||||
#if defined(WITH_POSTGRESQL)
|
#if defined(WITH_POSTGRESQL)
|
||||||
liftIO $ ret `shouldBe` [ Value $ Just (36 + 17 + 17 :: Rational ) ]
|
testPostgresqlSum
|
||||||
#elif defined(WITH_MYSQL)
|
#elif defined(WITH_MYSQL)
|
||||||
liftIO $ ret `shouldBe` [ Value $ Just (36 + 17 + 17 :: Double ) ]
|
testMysqlSum
|
||||||
#else
|
#else
|
||||||
liftIO $ ret `shouldBe` [ Value $ Just (36 + 17 + 17 :: Int) ]
|
testSqliteSum
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
it "works with avg_" $
|
it "works with avg_" $
|
||||||
@ -636,30 +728,10 @@ main = do
|
|||||||
return p
|
return p
|
||||||
liftIO $ ret2 `shouldBe` [ p2e ]
|
liftIO $ ret2 `shouldBe` [ p2e ]
|
||||||
|
|
||||||
it "works with random_" $
|
|
||||||
run $ do
|
|
||||||
#if defined(WITH_POSTGRESQL) || defined(WITH_MYSQL)
|
#if defined(WITH_POSTGRESQL) || defined(WITH_MYSQL)
|
||||||
_ <- select $ return (random_ :: SqlExpr (Value Double))
|
testPostgresqlRandom >> testMysqlRandom
|
||||||
#else
|
#else
|
||||||
_ <- select $ return (random_ :: SqlExpr (Value Int))
|
testSqliteRandom
|
||||||
#endif
|
|
||||||
return ()
|
|
||||||
|
|
||||||
#if defined(WITH_POSTGRESQL)
|
|
||||||
it "works with now" $
|
|
||||||
run $ do
|
|
||||||
nowDb <- select $ return EP.now_
|
|
||||||
nowUtc <- liftIO getCurrentTime
|
|
||||||
let halfSecond = realToFrac 0.5 :: NominalDiffTime
|
|
||||||
|
|
||||||
-- | Check the result is not null
|
|
||||||
liftIO $ nowDb `shouldSatisfy` (not . null)
|
|
||||||
|
|
||||||
-- | Unpack the now value
|
|
||||||
let (Value now: _) = nowDb
|
|
||||||
|
|
||||||
-- | Get the time diff and check it's less than half a second
|
|
||||||
liftIO $ diffUTCTime nowUtc now `shouldSatisfy` (< halfSecond)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
it "works with round_" $
|
it "works with round_" $
|
||||||
@ -770,6 +842,100 @@ main = do
|
|||||||
pPk `shouldBe` thePk
|
pPk `shouldBe` thePk
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
testPostgresqlTwoAscFields :: SpecWith (Arg (IO ()))
|
||||||
|
testPostgresqlTwoAscFields = do
|
||||||
|
it "works with two ASC fields (one call)" $
|
||||||
|
run $ do
|
||||||
|
p1e <- insert' p1
|
||||||
|
p2e <- insert' p2
|
||||||
|
p3e <- insert' p3
|
||||||
|
p4e <- insert' p4
|
||||||
|
ret <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [asc (p ^. PersonAge), asc (p ^. PersonName)]
|
||||||
|
return p
|
||||||
|
-- in PostgreSQL nulls are bigger than everything
|
||||||
|
liftIO $ ret `shouldBe` [ p4e, p3e, p1e , p2e ]
|
||||||
|
|
||||||
|
testMysqlTwoAscFields :: SpecWith (Arg (IO ()))
|
||||||
|
testMysqlTwoAscFields = do
|
||||||
|
it "works with two ASC fields (one call)" $
|
||||||
|
run $ do
|
||||||
|
p1e <- insert' p1
|
||||||
|
p2e <- insert' p2
|
||||||
|
p3e <- insert' p3
|
||||||
|
p4e <- insert' p4
|
||||||
|
ret <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [asc (p ^. PersonAge), asc (p ^. PersonName)]
|
||||||
|
return p
|
||||||
|
-- in SQLite and MySQL, its the reverse
|
||||||
|
liftIO $ ret `shouldBe` [ p2e, p4e, p3e, p1e ]
|
||||||
|
|
||||||
|
testSqliteTwoAscFields :: SpecWith (Arg (IO ()))
|
||||||
|
testSqliteTwoAscFields = do
|
||||||
|
it "works with two ASC fields (one call)" $
|
||||||
|
run $ do
|
||||||
|
p1e <- insert' p1
|
||||||
|
p2e <- insert' p2
|
||||||
|
p3e <- insert' p3
|
||||||
|
p4e <- insert' p4
|
||||||
|
ret <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [asc (p ^. PersonAge), asc (p ^. PersonName)]
|
||||||
|
return p
|
||||||
|
-- in SQLite and MySQL, its the reverse
|
||||||
|
liftIO $ ret `shouldBe` [ p2e, p4e, p3e, p1e ]
|
||||||
|
|
||||||
|
testPostgresqlOneAscOneDesc :: SpecWith (Arg (IO ()))
|
||||||
|
testPostgresqlOneAscOneDesc = do
|
||||||
|
it "works with one ASC and one DESC field (two calls)" $
|
||||||
|
run $ do
|
||||||
|
p1e <- insert' p1
|
||||||
|
p2e <- insert' p2
|
||||||
|
p3e <- insert' p3
|
||||||
|
p4e <- insert' p4
|
||||||
|
ret <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [desc (p ^. PersonAge)]
|
||||||
|
orderBy [asc (p ^. PersonName)]
|
||||||
|
return p
|
||||||
|
liftIO $ ret `shouldBe` [ p2e, p1e, p4e, p3e ]
|
||||||
|
|
||||||
|
testMysqlOneAscOneDesc :: SpecWith (Arg (IO ()))
|
||||||
|
testMysqlOneAscOneDesc = do
|
||||||
|
it "works with one ASC and one DESC field (two calls)" $
|
||||||
|
run $ do
|
||||||
|
p1e <- insert' p1
|
||||||
|
p2e <- insert' p2
|
||||||
|
p3e <- insert' p3
|
||||||
|
p4e <- insert' p4
|
||||||
|
ret <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [desc (p ^. PersonAge)]
|
||||||
|
orderBy [asc (p ^. PersonName)]
|
||||||
|
return p
|
||||||
|
liftIO $ ret `shouldBe` [ p1e, p4e, p3e, p2e ]
|
||||||
|
|
||||||
|
testSqliteOneAscOneDesc :: SpecWith (Arg (IO ()))
|
||||||
|
testSqliteOneAscOneDesc = do
|
||||||
|
it "works with one ASC and one DESC field (two calls)" $
|
||||||
|
run $ do
|
||||||
|
p1e <- insert' p1
|
||||||
|
p2e <- insert' p2
|
||||||
|
p3e <- insert' p3
|
||||||
|
p4e <- insert' p4
|
||||||
|
ret <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [desc (p ^. PersonAge)]
|
||||||
|
orderBy [asc (p ^. PersonName)]
|
||||||
|
return p
|
||||||
|
liftIO $ ret `shouldBe` [ p1e, p4e, p3e, p2e ]
|
||||||
|
|
||||||
|
testSelectOrderBy :: SpecWith (Arg (IO ()))
|
||||||
|
testSelectOrderBy = do
|
||||||
describe "select/orderBy" $ do
|
describe "select/orderBy" $ do
|
||||||
it "works with a single ASC field" $
|
it "works with a single ASC field" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -782,39 +948,16 @@ main = do
|
|||||||
return p
|
return p
|
||||||
liftIO $ ret `shouldBe` [ p1e, p3e, p2e ]
|
liftIO $ ret `shouldBe` [ p1e, p3e, p2e ]
|
||||||
|
|
||||||
it "works with two ASC fields (one call)" $
|
|
||||||
run $ do
|
|
||||||
p1e <- insert' p1
|
|
||||||
p2e <- insert' p2
|
|
||||||
p3e <- insert' p3
|
|
||||||
p4e <- insert' p4
|
|
||||||
ret <- select $
|
|
||||||
from $ \p -> do
|
|
||||||
orderBy [asc (p ^. PersonAge), asc (p ^. PersonName)]
|
|
||||||
return p
|
|
||||||
-- in PostgreSQL nulls are bigger than everything
|
|
||||||
#ifdef WITH_POSTGRESQL
|
#ifdef WITH_POSTGRESQL
|
||||||
liftIO $ ret `shouldBe` [ p4e, p3e, p1e , p2e ]
|
testPostgresqlTwoAscFields
|
||||||
#else
|
#else
|
||||||
-- in SQLite and MySQL, its the reverse
|
testMysqlTwoAscFields >> testSqliteTwoAscFields
|
||||||
liftIO $ ret `shouldBe` [ p2e, p4e, p3e, p1e ]
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
it "works with one ASC and one DESC field (two calls)" $
|
|
||||||
run $ do
|
|
||||||
p1e <- insert' p1
|
|
||||||
p2e <- insert' p2
|
|
||||||
p3e <- insert' p3
|
|
||||||
p4e <- insert' p4
|
|
||||||
ret <- select $
|
|
||||||
from $ \p -> do
|
|
||||||
orderBy [desc (p ^. PersonAge)]
|
|
||||||
orderBy [asc (p ^. PersonName)]
|
|
||||||
return p
|
|
||||||
#ifdef WITH_POSTGRESQL
|
#ifdef WITH_POSTGRESQL
|
||||||
liftIO $ ret `shouldBe` [ p2e, p1e, p4e, p3e ]
|
testPostgresqlOneAscOneDesc
|
||||||
#else
|
#else
|
||||||
liftIO $ ret `shouldBe` [ p1e, p4e, p3e, p2e ]
|
testMysqlOneAscOneDesc >> testSqliteOneAscOneDesc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
it "works with a sub_select" $
|
it "works with a sub_select" $
|
||||||
@ -860,14 +1003,18 @@ main = do
|
|||||||
liftIO $ map entityVal eps `shouldBe` reverse ps
|
liftIO $ map entityVal eps `shouldBe` reverse ps
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testSelectDistinct :: SpecWith (Arg (IO ()))
|
||||||
|
testSelectDistinct = do
|
||||||
describe "SELECT DISTINCT" $ do
|
describe "SELECT DISTINCT" $ do
|
||||||
let selDistTest
|
let selDistTest
|
||||||
:: ( forall m. RunDbMonad m
|
:: ( forall m. RunDbMonad m
|
||||||
=> SqlQuery (SqlExpr (Value String))
|
=> SqlQuery (SqlExpr (Value String))
|
||||||
-> SqlPersistT (R.ResourceT m) [Value String])
|
-> SqlPersistT (R.ResourceT m) [Value String])
|
||||||
-> IO ()
|
-> IO ()
|
||||||
selDistTest q =
|
selDistTest q = run $ do
|
||||||
run $ do
|
|
||||||
p1k <- insert p1
|
p1k <- insert p1
|
||||||
let (t1, t2, t3) = ("a", "b", "c")
|
let (t1, t2, t3) = ("a", "b", "c")
|
||||||
mapM_ (insert . flip BlogPost p1k) [t1, t3, t2, t2, t1]
|
mapM_ (insert . flip BlogPost p1k) [t1, t3, t2, t2, t1]
|
||||||
@ -877,6 +1024,7 @@ main = do
|
|||||||
orderBy [asc title]
|
orderBy [asc title]
|
||||||
return title
|
return title
|
||||||
liftIO $ ret `shouldBe` [ Value t1, Value t2, Value t3 ]
|
liftIO $ ret `shouldBe` [ Value t1, Value t2, Value t3 ]
|
||||||
|
|
||||||
it "works on a simple example (selectDistinct)" $
|
it "works on a simple example (selectDistinct)" $
|
||||||
selDistTest selectDistinct
|
selDistTest selectDistinct
|
||||||
|
|
||||||
@ -886,7 +1034,12 @@ main = do
|
|||||||
it "works on a simple example (distinct (return ()))" $
|
it "works on a simple example (distinct (return ()))" $
|
||||||
selDistTest (\act -> select $ distinct (return ()) >> act)
|
selDistTest (\act -> select $ distinct (return ()) >> act)
|
||||||
|
|
||||||
#if defined(WITH_POSTGRESQL)
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testSelectDistinctOn :: SpecWith (Arg (IO ()))
|
||||||
|
testSelectDistinctOn = do
|
||||||
describe "SELECT DISTINCT ON" $ do
|
describe "SELECT DISTINCT ON" $ do
|
||||||
it "works on a simple example" $ do
|
it "works on a simple example" $ do
|
||||||
run $ do
|
run $ do
|
||||||
@ -914,22 +1067,30 @@ main = do
|
|||||||
q bp $ return bp
|
q bp $ return bp
|
||||||
let cmp = (blogPostAuthorId &&& blogPostTitle) . entityVal
|
let cmp = (blogPostAuthorId &&& blogPostTitle) . entityVal
|
||||||
liftIO $ ret `shouldBe` L.sortBy (comparing cmp) [bpA, bpB, bpC]
|
liftIO $ ret `shouldBe` L.sortBy (comparing cmp) [bpA, bpB, bpC]
|
||||||
|
|
||||||
it "works on a slightly less simple example (two distinctOn calls, orderBy)" $
|
it "works on a slightly less simple example (two distinctOn calls, orderBy)" $
|
||||||
slightlyLessSimpleTest $ \bp act ->
|
slightlyLessSimpleTest $ \bp act ->
|
||||||
distinctOn [don (bp ^. BlogPostAuthorId)] $
|
distinctOn [don (bp ^. BlogPostAuthorId)] $
|
||||||
distinctOn [don (bp ^. BlogPostTitle)] $ do
|
distinctOn [don (bp ^. BlogPostTitle)] $ do
|
||||||
orderBy [asc (bp ^. BlogPostAuthorId), asc (bp ^. BlogPostTitle)]
|
orderBy [asc (bp ^. BlogPostAuthorId), asc (bp ^. BlogPostTitle)]
|
||||||
act
|
act
|
||||||
|
|
||||||
it "works on a slightly less simple example (one distinctOn call, orderBy)" $ do
|
it "works on a slightly less simple example (one distinctOn call, orderBy)" $ do
|
||||||
slightlyLessSimpleTest $ \bp act ->
|
slightlyLessSimpleTest $ \bp act ->
|
||||||
distinctOn [don (bp ^. BlogPostAuthorId), don (bp ^. BlogPostTitle)] $ do
|
distinctOn [don (bp ^. BlogPostAuthorId), don (bp ^. BlogPostTitle)] $ do
|
||||||
orderBy [asc (bp ^. BlogPostAuthorId), asc (bp ^. BlogPostTitle)]
|
orderBy [asc (bp ^. BlogPostAuthorId), asc (bp ^. BlogPostTitle)]
|
||||||
act
|
act
|
||||||
|
|
||||||
it "works on a slightly less simple example (distinctOnOrderBy)" $ do
|
it "works on a slightly less simple example (distinctOnOrderBy)" $ do
|
||||||
slightlyLessSimpleTest $ \bp ->
|
slightlyLessSimpleTest $ \bp ->
|
||||||
distinctOnOrderBy [asc (bp ^. BlogPostAuthorId), asc (bp ^. BlogPostTitle)]
|
distinctOnOrderBy [asc (bp ^. BlogPostAuthorId), asc (bp ^. BlogPostTitle)]
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testCoasleceDefault :: SpecWith (Arg (IO ()))
|
||||||
|
testCoasleceDefault = do
|
||||||
describe "coalesce/coalesceDefault" $ do
|
describe "coalesce/coalesceDefault" $ do
|
||||||
it "works on a simple example" $
|
it "works on a simple example" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -979,6 +1140,13 @@ main = do
|
|||||||
]
|
]
|
||||||
|
|
||||||
#if defined(WITH_POSTGRESQL) || defined(WITH_MYSQL)
|
#if defined(WITH_POSTGRESQL) || defined(WITH_MYSQL)
|
||||||
|
testPostgresqlCoalesce >> testMysqlCoalesce
|
||||||
|
#else
|
||||||
|
testSqliteCoalesce
|
||||||
|
#endif
|
||||||
|
|
||||||
|
testPostgresqlCoalesce :: SpecWith (Arg (IO ()))
|
||||||
|
testPostgresqlCoalesce = do
|
||||||
it "works on PostgreSQL and MySQL with <2 arguments" $
|
it "works on PostgreSQL and MySQL with <2 arguments" $
|
||||||
run $ do
|
run $ do
|
||||||
_ :: [Value (Maybe Int)] <-
|
_ :: [Value (Maybe Int)] <-
|
||||||
@ -986,14 +1154,30 @@ main = do
|
|||||||
from $ \p -> do
|
from $ \p -> do
|
||||||
return (coalesce [p ^. PersonAge])
|
return (coalesce [p ^. PersonAge])
|
||||||
return ()
|
return ()
|
||||||
#else
|
|
||||||
|
testMysqlCoalesce :: SpecWith (Arg (IO ()))
|
||||||
|
testMysqlCoalesce = do
|
||||||
|
it "works on PostgreSQL and MySQL with <2 arguments" $
|
||||||
|
run $ do
|
||||||
|
_ :: [Value (Maybe Int)] <-
|
||||||
|
select $
|
||||||
|
from $ \p -> do
|
||||||
|
return (coalesce [p ^. PersonAge])
|
||||||
|
return ()
|
||||||
|
|
||||||
|
testSqliteCoalesce :: SpecWith (Arg (IO ()))
|
||||||
|
testSqliteCoalesce = do
|
||||||
it "throws an exception on SQLite with <2 arguments" $
|
it "throws an exception on SQLite with <2 arguments" $
|
||||||
run (select $
|
run (select $
|
||||||
from $ \p -> do
|
from $ \p -> do
|
||||||
return (coalesce [p ^. PersonAge]) :: SqlQuery (SqlExpr (Value (Maybe Int))))
|
return (coalesce [p ^. PersonAge]) :: SqlQuery (SqlExpr (Value (Maybe Int))))
|
||||||
`shouldThrow` (\(_ :: SqliteException) -> True)
|
`shouldThrow` (\(_ :: SqliteException) -> True)
|
||||||
#endif
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testTextFunctions :: SpecWith (Arg (IO ()))
|
||||||
|
testTextFunctions = do
|
||||||
describe "text functions" $ do
|
describe "text functions" $ do
|
||||||
it "like, (%) and (++.) work on a simple example" $
|
it "like, (%) and (++.) work on a simple example" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -1010,6 +1194,11 @@ main = do
|
|||||||
nameContains "iv" [p4e]
|
nameContains "iv" [p4e]
|
||||||
|
|
||||||
#if defined(WITH_POSTGRESQL)
|
#if defined(WITH_POSTGRESQL)
|
||||||
|
testPostgresqlTextFunction
|
||||||
|
#endif
|
||||||
|
|
||||||
|
testPostgresqlTextFunction :: SpecWith (Arg (IO ()))
|
||||||
|
testPostgresqlTextFunction = do
|
||||||
it "ilike, (%) and (++.) work on a simple example on PostgreSQL" $
|
it "ilike, (%) and (++.) work on a simple example on PostgreSQL" $
|
||||||
run $ do
|
run $ do
|
||||||
[p1e, _, p3e, _, p5e] <- mapM insert' [p1, p2, p3, p4, p5]
|
[p1e, _, p3e, _, p5e] <- mapM insert' [p1, p2, p3, p4, p5]
|
||||||
@ -1022,8 +1211,13 @@ main = do
|
|||||||
liftIO $ ret `shouldBe` expected
|
liftIO $ ret `shouldBe` expected
|
||||||
nameContains "mi" [p3e, p5e]
|
nameContains "mi" [p3e, p5e]
|
||||||
nameContains "JOHN" [p1e]
|
nameContains "JOHN" [p1e]
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testDelete :: SpecWith (Arg (IO ()))
|
||||||
|
testDelete = do
|
||||||
describe "delete" $
|
describe "delete" $
|
||||||
it "works on a simple example" $
|
it "works on a simple example" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -1047,7 +1241,11 @@ main = do
|
|||||||
ret3 <- getAll
|
ret3 <- getAll
|
||||||
liftIO $ (n, ret3) `shouldBe` (2, [])
|
liftIO $ (n, ret3) `shouldBe` (2, [])
|
||||||
|
|
||||||
describe "update" $ do
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
testPostgresqlUpdate :: SpecWith (Arg (IO ()))
|
||||||
|
testPostgresqlUpdate = do
|
||||||
it "works on a simple example" $
|
it "works on a simple example" $
|
||||||
run $ do
|
run $ do
|
||||||
p1k <- insert p1
|
p1k <- insert p1
|
||||||
@ -1067,24 +1265,71 @@ main = do
|
|||||||
return p
|
return p
|
||||||
-- PostgreSQL: nulls are bigger than data, and update returns
|
-- PostgreSQL: nulls are bigger than data, and update returns
|
||||||
-- matched rows, not actually changed rows.
|
-- matched rows, not actually changed rows.
|
||||||
#if defined(WITH_POSTGRESQL)
|
|
||||||
liftIO $ n `shouldBe` 2
|
liftIO $ n `shouldBe` 2
|
||||||
liftIO $ ret `shouldBe` [ Entity p1k (Person anon (Just 73) Nothing 1)
|
liftIO $ ret `shouldBe` [ Entity p1k (Person anon (Just 73) Nothing 1)
|
||||||
, Entity p2k (Person anon Nothing (Just 37) 2)
|
, Entity p2k (Person anon Nothing (Just 37) 2)
|
||||||
, Entity p3k p3 ]
|
, Entity p3k p3 ]
|
||||||
|
|
||||||
|
testMysqlUpdate :: SpecWith (Arg (IO ()))
|
||||||
|
testMysqlUpdate = do
|
||||||
|
it "works on a simple example" $
|
||||||
|
run $ do
|
||||||
|
p1k <- insert p1
|
||||||
|
p2k <- insert p2
|
||||||
|
p3k <- insert p3
|
||||||
|
let anon = "Anonymous"
|
||||||
|
() <- update $ \p -> do
|
||||||
|
set p [ PersonName =. val anon
|
||||||
|
, PersonAge *=. just (val 2) ]
|
||||||
|
where_ (p ^. PersonName !=. val "Mike")
|
||||||
|
n <- updateCount $ \p -> do
|
||||||
|
set p [ PersonAge +=. just (val 1) ]
|
||||||
|
where_ (p ^. PersonName !=. val "Mike")
|
||||||
|
ret <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [ asc (p ^. PersonName), asc (p ^. PersonAge) ]
|
||||||
|
return p
|
||||||
-- MySQL: nulls appear first, and update returns actual number
|
-- MySQL: nulls appear first, and update returns actual number
|
||||||
-- of changed rows
|
-- of changed rows
|
||||||
#elif defined(WITH_MYSQL)
|
|
||||||
liftIO $ n `shouldBe` 1
|
liftIO $ n `shouldBe` 1
|
||||||
liftIO $ ret `shouldBe` [ Entity p2k (Person anon Nothing (Just 37) 2)
|
liftIO $ ret `shouldBe` [ Entity p2k (Person anon Nothing (Just 37) 2)
|
||||||
, Entity p1k (Person anon (Just 73) Nothing 1)
|
, Entity p1k (Person anon (Just 73) Nothing 1)
|
||||||
, Entity p3k p3 ]
|
, Entity p3k p3 ]
|
||||||
#else
|
|
||||||
|
testSqliteUpdate :: SpecWith (Arg (IO ()))
|
||||||
|
testSqliteUpdate = do
|
||||||
|
it "works on a simple example" $
|
||||||
|
run $ do
|
||||||
|
p1k <- insert p1
|
||||||
|
p2k <- insert p2
|
||||||
|
p3k <- insert p3
|
||||||
|
let anon = "Anonymous"
|
||||||
|
() <- update $ \p -> do
|
||||||
|
set p [ PersonName =. val anon
|
||||||
|
, PersonAge *=. just (val 2) ]
|
||||||
|
where_ (p ^. PersonName !=. val "Mike")
|
||||||
|
n <- updateCount $ \p -> do
|
||||||
|
set p [ PersonAge +=. just (val 1) ]
|
||||||
|
where_ (p ^. PersonName !=. val "Mike")
|
||||||
|
ret <- select $
|
||||||
|
from $ \p -> do
|
||||||
|
orderBy [ asc (p ^. PersonName), asc (p ^. PersonAge) ]
|
||||||
|
return p
|
||||||
-- SQLite: nulls appear first, update returns matched rows.
|
-- SQLite: nulls appear first, update returns matched rows.
|
||||||
liftIO $ n `shouldBe` 2
|
liftIO $ n `shouldBe` 2
|
||||||
liftIO $ ret `shouldBe` [ Entity p2k (Person anon Nothing (Just 37) 2)
|
liftIO $ ret `shouldBe` [ Entity p2k (Person anon Nothing (Just 37) 2)
|
||||||
, Entity p1k (Person anon (Just 73) Nothing 1)
|
, Entity p1k (Person anon (Just 73) Nothing 1)
|
||||||
, Entity p3k p3 ]
|
, Entity p3k p3 ]
|
||||||
|
|
||||||
|
testUpdate :: SpecWith (Arg (IO ()))
|
||||||
|
testUpdate = do
|
||||||
|
describe "update" $ do
|
||||||
|
#if defined(WITH_POSTGRESQL)
|
||||||
|
testPostgresqlUpdate
|
||||||
|
#elif defined(WITH_MYSQL)
|
||||||
|
testMysqlUpdate
|
||||||
|
#else
|
||||||
|
testSqliteUpdate
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
it "works with a subexpression having COUNT(*)" $
|
it "works with a subexpression having COUNT(*)" $
|
||||||
@ -1149,9 +1394,9 @@ main = do
|
|||||||
l1k <- insert l1
|
l1k <- insert l1
|
||||||
l2k <- insert l2
|
l2k <- insert l2
|
||||||
l3k <- insert l3
|
l3k <- insert l3
|
||||||
mapM_ (\k -> insert $ Deed k l1k) (map show [1..3])
|
mapM_ (\k -> insert $ Deed k l1k) (map show [1..3 :: Int])
|
||||||
|
|
||||||
mapM_ (\k -> insert $ Deed k l3k) (map show [4..10])
|
mapM_ (\k -> insert $ Deed k l3k) (map show [4..10 :: Int])
|
||||||
|
|
||||||
(ret :: [(Value (Key Lord), Value Int)]) <- select $ from $
|
(ret :: [(Value (Key Lord), Value Int)]) <- select $ from $
|
||||||
\ ( lord `InnerJoin` deed ) -> do
|
\ ( lord `InnerJoin` deed ) -> do
|
||||||
@ -1178,6 +1423,12 @@ main = do
|
|||||||
liftIO $ ret `shouldBe` [ (Entity p1k p1, Value (3 :: Int))
|
liftIO $ ret `shouldBe` [ (Entity p1k p1, Value (3 :: Int))
|
||||||
, (Entity p3k p3, Value 7) ]
|
, (Entity p3k p3, Value 7) ]
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testListOfValues :: SpecWith (Arg (IO ()))
|
||||||
|
testListOfValues = do
|
||||||
describe "lists of values" $ do
|
describe "lists of values" $ do
|
||||||
it "IN works for valList" $
|
it "IN works for valList" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -1268,6 +1519,12 @@ main = do
|
|||||||
return p
|
return p
|
||||||
liftIO $ ret `shouldBe` [ Entity p2k p2 ]
|
liftIO $ ret `shouldBe` [ Entity p2k p2 ]
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testListFields :: SpecWith (Arg (IO ()))
|
||||||
|
testListFields = do
|
||||||
describe "list fields" $ do
|
describe "list fields" $ do
|
||||||
-- <https://github.com/prowdsponsor/esqueleto/issues/100>
|
-- <https://github.com/prowdsponsor/esqueleto/issues/100>
|
||||||
it "can update list fields" $
|
it "can update list fields" $
|
||||||
@ -1277,6 +1534,12 @@ main = do
|
|||||||
set p [ CcListNames =. val ["fred"]]
|
set p [ CcListNames =. val ["fred"]]
|
||||||
where_ (p ^. CcListId ==. val cclist)
|
where_ (p ^. CcListId ==. val cclist)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testInsertsBySelect :: SpecWith (Arg (IO ()))
|
||||||
|
testInsertsBySelect = do
|
||||||
describe "inserts by select" $ do
|
describe "inserts by select" $ do
|
||||||
it "IN works for insertSelect" $
|
it "IN works for insertSelect" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -1288,6 +1551,12 @@ main = do
|
|||||||
ret <- select $ from (\(_::(SqlExpr (Entity BlogPost))) -> return countRows)
|
ret <- select $ from (\(_::(SqlExpr (Entity BlogPost))) -> return countRows)
|
||||||
liftIO $ ret `shouldBe` [Value (3::Int)]
|
liftIO $ ret `shouldBe` [Value (3::Int)]
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testInsertsBySelectReturnsCount :: SpecWith (Arg (IO ()))
|
||||||
|
testInsertsBySelectReturnsCount = do
|
||||||
describe "inserts by select, returns count" $ do
|
describe "inserts by select, returns count" $ do
|
||||||
it "IN works for insertSelectCount" $
|
it "IN works for insertSelectCount" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -1300,6 +1569,12 @@ main = do
|
|||||||
liftIO $ ret `shouldBe` [Value (3::Int)]
|
liftIO $ ret `shouldBe` [Value (3::Int)]
|
||||||
liftIO $ cnt `shouldBe` 3
|
liftIO $ cnt `shouldBe` 3
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testMathFunctions :: SpecWith (Arg (IO ()))
|
||||||
|
testMathFunctions = do
|
||||||
describe "Math-related functions" $ do
|
describe "Math-related functions" $ do
|
||||||
it "rand returns result in random order" $
|
it "rand returns result in random order" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -1334,6 +1609,12 @@ main = do
|
|||||||
let [Value a, Value b] = ret
|
let [Value a, Value b] = ret
|
||||||
liftIO $ max (abs (a - 6.8)) (abs (b - 7.7)) `shouldSatisfy` (< 0.01)
|
liftIO $ max (abs (a - 6.8)) (abs (b - 7.7)) `shouldSatisfy` (< 0.01)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testCase :: SpecWith (Arg (IO ()))
|
||||||
|
testCase = do
|
||||||
describe "case" $ do
|
describe "case" $ do
|
||||||
it "Works for a simple value based when - False" $
|
it "Works for a simple value based when - False" $
|
||||||
run $ do
|
run $ do
|
||||||
@ -1380,6 +1661,12 @@ main = do
|
|||||||
|
|
||||||
liftIO $ ret `shouldBe` [ Value (3) ]
|
liftIO $ ret `shouldBe` [ Value (3) ]
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testLocking :: SpecWith (Arg (IO ()))
|
||||||
|
testLocking = do
|
||||||
describe "locking" $ do
|
describe "locking" $ do
|
||||||
-- The locking clause is the last one, so try to use many
|
-- The locking clause is the last one, so try to use many
|
||||||
-- others to test if it's at the right position. We don't
|
-- others to test if it's at the right position. We don't
|
||||||
@ -1422,6 +1709,12 @@ main = do
|
|||||||
it "looks sane for ForShare" $ sanityCheck ForShare "FOR SHARE"
|
it "looks sane for ForShare" $ sanityCheck ForShare "FOR SHARE"
|
||||||
it "looks sane for LockInShareMode" $ sanityCheck LockInShareMode "LOCK IN SHARE MODE"
|
it "looks sane for LockInShareMode" $ sanityCheck LockInShareMode "LOCK IN SHARE MODE"
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testCountingRows :: SpecWith (Arg (IO ()))
|
||||||
|
testCountingRows = do
|
||||||
describe "counting rows" $ do
|
describe "counting rows" $ do
|
||||||
forM_ [ ("count (test A)", count . (^. PersonAge), 4)
|
forM_ [ ("count (test A)", count . (^. PersonAge), 4)
|
||||||
, ("count (test B)", count . (^. PersonWeight), 5)
|
, ("count (test B)", count . (^. PersonWeight), 5)
|
||||||
@ -1439,13 +1732,13 @@ main = do
|
|||||||
[Value n] <- select $ from $ return . countKind
|
[Value n] <- select $ from $ return . countKind
|
||||||
liftIO $ (n :: Int) `shouldBe` expected
|
liftIO $ (n :: Int) `shouldBe` expected
|
||||||
|
|
||||||
describe "PostgreSQL module" $ do
|
|
||||||
it "should be tested on the PostgreSQL database" $
|
|
||||||
#if !defined(WITH_POSTGRESQL)
|
|
||||||
pendingWith "test suite not running under PostgreSQL, skipping"
|
|
||||||
#else
|
|
||||||
(return () :: IO ())
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
testPostgresModule :: SpecWith (Arg (IO ()))
|
||||||
|
testPostgresModule = do
|
||||||
|
describe "PostgreSQL module" $ do
|
||||||
it "arrayAgg looks sane" $
|
it "arrayAgg looks sane" $
|
||||||
run $ do
|
run $ do
|
||||||
let people = [p1, p2, p3, p4, p5]
|
let people = [p1, p2, p3, p4, p5]
|
||||||
@ -1468,8 +1761,53 @@ main = do
|
|||||||
run $ do
|
run $ do
|
||||||
[Value (ret :: String)] <- select $ return (EP.chr (val 65))
|
[Value (ret :: String)] <- select $ return (EP.chr (val 65))
|
||||||
liftIO $ ret `shouldBe` "A"
|
liftIO $ ret `shouldBe` "A"
|
||||||
|
|
||||||
|
it "works with now" $
|
||||||
|
run $ do
|
||||||
|
nowDb <- select $ return EP.now_
|
||||||
|
nowUtc <- liftIO getCurrentTime
|
||||||
|
let halfSecond = realToFrac (0.5 :: Double)
|
||||||
|
|
||||||
|
-- | Check the result is not null
|
||||||
|
liftIO $ nowDb `shouldSatisfy` (not . null)
|
||||||
|
|
||||||
|
-- | Unpack the now value
|
||||||
|
let (Value now: _) = nowDb
|
||||||
|
|
||||||
|
-- | Get the time diff and check it's less than half a second
|
||||||
|
liftIO $ diffUTCTime nowUtc now `shouldSatisfy` (< halfSecond)
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
hspec $ do
|
||||||
|
testSelect
|
||||||
|
testSelectSource
|
||||||
|
testSelectFrom
|
||||||
|
testSelectJoin
|
||||||
|
testSelectWhere
|
||||||
|
testSelectOrderBy
|
||||||
|
testSelectDistinct
|
||||||
|
|
||||||
|
#if defined(WITH_POSTGRESQL)
|
||||||
|
testSelectDistinctOn
|
||||||
|
testPostgresModule
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
testCoasleceDefault
|
||||||
|
testTextFunctions
|
||||||
|
testDelete
|
||||||
|
testUpdate
|
||||||
|
testListOfValues
|
||||||
|
testListFields
|
||||||
|
testInsertsBySelect
|
||||||
|
testMathFunctions
|
||||||
|
testCase
|
||||||
|
testLocking
|
||||||
|
testCountingRows
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@ -1485,7 +1823,6 @@ insert' v = flip Entity v <$> insert v
|
|||||||
type RunDbMonad m = ( MonadBaseControl IO m, MonadIO m, MonadLogger m
|
type RunDbMonad m = ( MonadBaseControl IO m, MonadIO m, MonadLogger m
|
||||||
, R.MonadThrow m )
|
, R.MonadThrow m )
|
||||||
|
|
||||||
#if defined (WITH_POSTGRESQL) || defined (WITH_MYSQL)
|
|
||||||
-- With SQLite and in-memory databases, a separate connection implies a
|
-- With SQLite and in-memory databases, a separate connection implies a
|
||||||
-- separate database. With 'actual databases', the data is persistent and
|
-- separate database. With 'actual databases', the data is persistent and
|
||||||
-- thus must be cleaned after each test.
|
-- thus must be cleaned after each test.
|
||||||
@ -1516,7 +1853,6 @@ cleanDB = do
|
|||||||
delete $ from $ \(_ :: SqlExpr (Entity Point)) -> return ()
|
delete $ from $ \(_ :: SqlExpr (Entity Point)) -> return ()
|
||||||
|
|
||||||
delete $ from $ \(_ :: SqlExpr (Entity Numbers)) -> return ()
|
delete $ from $ \(_ :: SqlExpr (Entity Numbers)) -> return ()
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
run, runSilent, runVerbose :: (forall m. RunDbMonad m => SqlPersistT (R.ResourceT m) a) -> IO a
|
run, runSilent, runVerbose :: (forall m. RunDbMonad m => SqlPersistT (R.ResourceT m) a) -> IO a
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user