2024-03-27 20:26:40 +00:00
|
|
|
module Test.Effect.Postgres.Client where
|
|
|
|
|
|
|
|
import Prelude
|
|
|
|
|
|
|
|
import Control.Monad.Error.Class (try)
|
2024-03-31 01:38:52 +00:00
|
|
|
import Data.Either (Either(..), isLeft)
|
|
|
|
import Data.Maybe (Maybe(..))
|
2024-03-28 20:18:06 +00:00
|
|
|
import Data.Newtype (wrap)
|
|
|
|
import Data.Postgres (JSON(..))
|
|
|
|
import Data.PreciseDateTime (fromRFC3339String, toDateTimeLossy)
|
2024-03-31 01:38:52 +00:00
|
|
|
import Effect (Effect)
|
|
|
|
import Effect.Aff (Aff, forkAff, joinFiber, makeAff)
|
2024-03-28 20:18:06 +00:00
|
|
|
import Effect.Aff.Postgres.Client (query)
|
2024-03-31 01:38:52 +00:00
|
|
|
import Effect.Aff.Postgres.Client as Client
|
|
|
|
import Effect.Exception as Error
|
|
|
|
import Effect.Uncurried (EffectFn1)
|
|
|
|
import Node.EventEmitter (EventHandle, once)
|
2024-03-29 19:52:05 +00:00
|
|
|
import Test.Common (withClient)
|
2024-03-28 20:18:06 +00:00
|
|
|
import Test.Spec (Spec, around, describe, it)
|
2024-03-27 20:26:40 +00:00
|
|
|
import Test.Spec.Assertions (shouldEqual)
|
|
|
|
|
|
|
|
spec :: Spec Unit
|
2024-03-28 20:18:06 +00:00
|
|
|
spec =
|
|
|
|
around withClient do
|
|
|
|
describe "Client" do
|
2024-03-31 01:38:52 +00:00
|
|
|
describe "events" do
|
|
|
|
let
|
|
|
|
once_ :: forall a b. EventHandle Client.Client (a -> Effect Unit) (EffectFn1 b Unit) -> Client.Client -> Aff a
|
|
|
|
once_ e c = makeAff \res -> mempty <$ once e (res <<< Right) c
|
|
|
|
it "end" \c -> do
|
|
|
|
endEvent <- forkAff $ makeAff \res -> mempty <$ once Client.endE (res $ Right unit) c
|
|
|
|
Client.end c
|
|
|
|
void $ joinFiber endEvent
|
|
|
|
it "notice" \c -> do
|
|
|
|
noticeEvent <- forkAff $ once_ Client.noticeE c
|
|
|
|
void $ Client.exec "do language plpgsql $$ begin raise notice 'hello'; end; $$;" c
|
|
|
|
e <- joinFiber noticeEvent
|
|
|
|
Error.message e `shouldEqual` "hello"
|
|
|
|
it "notification" \c -> do
|
|
|
|
void $ Client.exec "listen hello;" c
|
|
|
|
notifEvent <- forkAff $ once_ Client.notificationE c
|
|
|
|
void $ Client.exec "notify hello, 'world';" c
|
|
|
|
n <- joinFiber notifEvent
|
|
|
|
n.payload `shouldEqual` (Just "world")
|
2024-03-28 20:18:06 +00:00
|
|
|
it "connect & end do not throw" $ const $ pure unit
|
|
|
|
describe "query" do
|
|
|
|
it "ok if connected" \c -> shouldEqual [ 1, 2, 3 ] =<< query "select unnest(array[1, 2, 3])" c
|
|
|
|
it "throws if ended" \c -> do
|
2024-03-31 01:38:52 +00:00
|
|
|
Client.end c
|
2024-03-28 20:18:06 +00:00
|
|
|
res :: Either _ (Array Int) <- try $ query "select 1" c
|
|
|
|
isLeft res `shouldEqual` true
|
|
|
|
it "rowsAffected is correct" \c -> do
|
2024-03-31 01:38:52 +00:00
|
|
|
void $ Client.exec "create temp table foo (bar int);" c
|
|
|
|
shouldEqual 1 =<< Client.exec "insert into foo values (1);" c
|
|
|
|
shouldEqual 3 =<< Client.exec "insert into foo values (1), (2), (3);" c
|
|
|
|
shouldEqual 4 =<< Client.exec "update foo set bar = 10;" c
|
2024-03-28 20:18:06 +00:00
|
|
|
describe "timestamp" do
|
|
|
|
it "unmarshals" \c -> do
|
|
|
|
let exp = toDateTimeLossy <$> fromRFC3339String (wrap "2020-01-01T00:00:00Z")
|
|
|
|
shouldEqual [ exp ] =<< query "select '2020-01-01T00:00:00Z' :: timestamptz" c
|
|
|
|
it "is string" \c -> shouldEqual [ "2020-01-01 00:00:00+00" ] =<< query "select '2020-01-01T00:00:00Z' :: timestamptz" c
|
|
|
|
it "array is string" \c -> shouldEqual [ [ "2020-01-01 00:00:00+00" ] ] =<< query "select array['2020-01-01T00:00:00Z' :: timestamptz]" c
|
|
|
|
describe "json" do
|
|
|
|
it "unmarshals" \c -> shouldEqual [ JSON { foo: "bar" } ] =<< query "select '{\"foo\": \"bar\"}' :: json" c
|
|
|
|
it "is string" \c -> shouldEqual [ "{\"foo\": \"bar\"}" ] =<< query "select '{\"foo\": \"bar\"}' :: json" c
|
|
|
|
it "array is string" \c -> shouldEqual [ [ "{\"foo\": \"bar\"}" ] ] =<< query "select array['{\"foo\": \"bar\"}' :: json]" c
|