graphql/tests/Language/GraphQL/Execute/CoerceSpec.hs

120 lines
5.2 KiB
Haskell
Raw Normal View History

2020-05-21 10:20:59 +02:00
{-# LANGUAGE OverloadedStrings #-}
module Language.GraphQL.Execute.CoerceSpec
( spec
) where
import Data.Aeson as Aeson ((.=))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Types as Aeson
2020-05-22 10:11:48 +02:00
import Data.HashMap.Strict (HashMap)
2020-05-21 10:20:59 +02:00
import qualified Data.HashMap.Strict as HashMap
import Data.Maybe (isNothing)
import Data.Scientific (scientific)
2020-05-22 10:11:48 +02:00
import qualified Data.Set as Set
2020-05-21 10:20:59 +02:00
import Language.GraphQL.AST.Core
import Language.GraphQL.Execute.Coerce
2020-05-22 10:11:48 +02:00
import Language.GraphQL.Schema
2020-05-21 10:20:59 +02:00
import Language.GraphQL.Type.Definition
2020-05-24 13:51:00 +02:00
import qualified Language.GraphQL.Type.In as In
2020-05-21 10:20:59 +02:00
import Prelude hiding (id)
import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy)
2020-05-22 10:11:48 +02:00
direction :: EnumType
direction = EnumType "Direction" Nothing
$ Set.fromList ["NORTH", "EAST", "SOUTH", "WEST"]
coerceInputLiteral :: In.Type -> In.Value -> Maybe Subs
2020-05-22 10:11:48 +02:00
coerceInputLiteral input value = coerceInputLiterals
(HashMap.singleton "variableName" input)
(HashMap.singleton "variableName" value)
2020-05-24 13:51:00 +02:00
lookupActual :: Maybe (HashMap Name In.Value) -> Maybe In.Value
2020-05-22 10:11:48 +02:00
lookupActual = (HashMap.lookup "variableName" =<<)
singletonInputObject :: In.Type
singletonInputObject = In.NamedInputObjectType type'
2020-05-21 10:20:59 +02:00
where
type' = In.InputObjectType "ObjectName" Nothing inputFields
2020-05-21 10:20:59 +02:00
inputFields = HashMap.singleton "field" field
field = In.InputField Nothing (In.NamedScalarType string) Nothing
2020-05-21 10:20:59 +02:00
spec :: Spec
2020-05-22 10:11:48 +02:00
spec = do
2020-05-21 10:20:59 +02:00
describe "ToGraphQL Aeson" $ do
it "coerces strings" $
2020-05-24 13:51:00 +02:00
let expected = Just (In.String "asdf")
2020-05-21 10:20:59 +02:00
actual = coerceVariableValue
(In.NamedScalarType string) (Aeson.String "asdf")
2020-05-21 10:20:59 +02:00
in actual `shouldBe` expected
it "coerces non-null strings" $
2020-05-24 13:51:00 +02:00
let expected = Just (In.String "asdf")
2020-05-21 10:20:59 +02:00
actual = coerceVariableValue
(In.NonNullScalarType string) (Aeson.String "asdf")
2020-05-21 10:20:59 +02:00
in actual `shouldBe` expected
it "coerces booleans" $
2020-05-24 13:51:00 +02:00
let expected = Just (In.Boolean True)
2020-05-21 10:20:59 +02:00
actual = coerceVariableValue
(In.NamedScalarType boolean) (Aeson.Bool True)
2020-05-21 10:20:59 +02:00
in actual `shouldBe` expected
it "coerces zero to an integer" $
2020-05-24 13:51:00 +02:00
let expected = Just (In.Int 0)
2020-05-21 10:20:59 +02:00
actual = coerceVariableValue
(In.NamedScalarType int) (Aeson.Number 0)
2020-05-21 10:20:59 +02:00
in actual `shouldBe` expected
it "rejects fractional if an integer is expected" $
let actual = coerceVariableValue
(In.NamedScalarType int) (Aeson.Number $ scientific 14 (-1))
2020-05-21 10:20:59 +02:00
in actual `shouldSatisfy` isNothing
it "coerces float numbers" $
2020-05-24 13:51:00 +02:00
let expected = Just (In.Float 1.4)
2020-05-21 10:20:59 +02:00
actual = coerceVariableValue
(In.NamedScalarType float) (Aeson.Number $ scientific 14 (-1))
2020-05-21 10:20:59 +02:00
in actual `shouldBe` expected
it "coerces IDs" $
2020-05-24 13:51:00 +02:00
let expected = Just (In.String "1234")
2020-05-21 10:20:59 +02:00
actual = coerceVariableValue
(In.NamedScalarType id) (Aeson.String "1234")
2020-05-21 10:20:59 +02:00
in actual `shouldBe` expected
it "coerces input objects" $
let actual = coerceVariableValue singletonInputObject
$ Aeson.object ["field" .= ("asdf" :: Aeson.Value)]
2020-05-24 13:51:00 +02:00
expected = Just $ In.Object $ HashMap.singleton "field" "asdf"
2020-05-21 10:20:59 +02:00
in actual `shouldBe` expected
it "skips the field if it is missing in the variables" $
let actual = coerceVariableValue
singletonInputObject Aeson.emptyObject
2020-05-24 13:51:00 +02:00
expected = Just $ In.Object HashMap.empty
2020-05-21 10:20:59 +02:00
in actual `shouldBe` expected
it "fails if input object value contains extra fields" $
let actual = coerceVariableValue singletonInputObject
$ Aeson.object variableFields
variableFields =
[ "field" .= ("asdf" :: Aeson.Value)
, "extra" .= ("qwer" :: Aeson.Value)
]
in actual `shouldSatisfy` isNothing
it "preserves null" $
let actual = coerceVariableValue (In.NamedScalarType id) Aeson.Null
2020-05-24 13:51:00 +02:00
in actual `shouldBe` Just In.Null
2020-05-21 10:20:59 +02:00
it "preserves list order" $
let list = Aeson.toJSONList ["asdf" :: Aeson.Value, "qwer"]
listType = (In.ListType $ In.NamedScalarType string)
2020-05-21 10:20:59 +02:00
actual = coerceVariableValue listType list
2020-05-24 13:51:00 +02:00
expected = Just $ In.List [In.String "asdf", In.String "qwer"]
2020-05-21 10:20:59 +02:00
in actual `shouldBe` expected
2020-05-22 10:11:48 +02:00
describe "coerceInputLiterals" $ do
it "coerces enums" $
2020-05-24 13:51:00 +02:00
let expected = Just (In.Enum "NORTH")
2020-05-22 10:11:48 +02:00
actual = coerceInputLiteral
(In.NamedEnumType direction) (In.Enum "NORTH")
2020-05-22 10:11:48 +02:00
in lookupActual actual `shouldBe` expected
it "fails with non-existing enum value" $
let actual = coerceInputLiteral
(In.NamedEnumType direction) (In.Enum "NORTH_EAST")
2020-05-22 10:11:48 +02:00
in actual `shouldSatisfy` isNothing
it "coerces integers to IDs" $
2020-05-24 13:51:00 +02:00
let expected = Just (In.String "1234")
actual = coerceInputLiteral (In.NamedScalarType id) (In.Int 1234)
2020-05-22 10:11:48 +02:00
in lookupActual actual `shouldBe` expected