{- This Source Code Form is subject to the terms of the Mozilla Public License,
   v. 2.0. If a copy of the MPL was not distributed with this file, You can
   obtain one at https://mozilla.org/MPL/2.0/. -}

{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DuplicateRecordFields #-}

-- | Test helpers.
module Test.Hspec.GraphQL
    ( shouldResolve
    , shouldResolveTo
    ) where

import Control.Monad.Catch (MonadCatch)
import qualified Data.Sequence as Seq
import Data.Text (Text)
import Language.GraphQL.Error
import Language.GraphQL.Execute
import Test.Hspec.Expectations
    ( Expectation
    , expectationFailure
    , shouldBe
    , shouldSatisfy
    )

-- | Asserts that a query resolves to some value.
shouldResolveTo :: (MonadCatch m, Serialize b, Eq b, Show b)
    => Either (ResponseEventStream m b) (Response b)
    -> b
    -> Expectation
shouldResolveTo :: forall (m :: * -> *) b.
(MonadCatch m, Serialize b, Eq b, Show b) =>
Either (ResponseEventStream m b) (Response b) -> b -> Expectation
shouldResolveTo (Right Response{ $sel:errors:Response :: forall a. Response a -> Seq Error
errors = Seq Error
Seq.Empty, b
$sel:data':Response :: forall a. Response a -> a
data' :: b
data' }) b
expected =
    b
data' forall a. (HasCallStack, Show a, Eq a) => a -> a -> Expectation
`shouldBe` b
expected
shouldResolveTo Either (ResponseEventStream m b) (Response b)
_ b
_ = HasCallStack => String -> Expectation
expectationFailure
    String
"the query is expected to resolve to a value, but it resolved to an event stream"

-- | Asserts that the response doesn't contain any errors.
shouldResolve :: (MonadCatch m, Serialize b)
    => (Text -> IO (Either (ResponseEventStream m b) (Response b)))
    -> Text
    -> Expectation
shouldResolve :: forall (m :: * -> *) b.
(MonadCatch m, Serialize b) =>
(Text -> IO (Either (ResponseEventStream m b) (Response b)))
-> Text -> Expectation
shouldResolve Text -> IO (Either (ResponseEventStream m b) (Response b))
executor Text
query = do
    Either (ResponseEventStream m b) (Response b)
actual <- Text -> IO (Either (ResponseEventStream m b) (Response b))
executor Text
query
    case Either (ResponseEventStream m b) (Response b)
actual of
        Right Response{ Seq Error
errors :: Seq Error
$sel:errors:Response :: forall a. Response a -> Seq Error
errors } -> Seq Error
errors forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> Expectation
`shouldSatisfy` forall a. Seq a -> Bool
Seq.null
        Either (ResponseEventStream m b) (Response b)
_ -> HasCallStack => String -> Expectation
expectationFailure
            String
"the query is expected to resolve to a value, but it resolved to an event stream"