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-27 23:18:35 +02:00
|
|
|
import Language.GraphQL.AST.Document (Name)
|
2020-05-21 10:20:59 +02:00
|
|
|
import Language.GraphQL.Execute.Coerce
|
|
|
|
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"]
|
|
|
|
|
2020-05-27 23:18:35 +02:00
|
|
|
coerceInputLiteral :: In.Type -> 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-27 23:18:35 +02:00
|
|
|
lookupActual :: Maybe (HashMap Name Value) -> Maybe Value
|
2020-05-22 10:11:48 +02:00
|
|
|
lookupActual = (HashMap.lookup "variableName" =<<)
|
|
|
|
|
2020-05-25 07:41:21 +02:00
|
|
|
singletonInputObject :: In.Type
|
|
|
|
singletonInputObject = In.NamedInputObjectType type'
|
2020-05-21 10:20:59 +02:00
|
|
|
where
|
2020-05-25 07:41:21 +02:00
|
|
|
type' = In.InputObjectType "ObjectName" Nothing inputFields
|
2020-05-21 10:20:59 +02:00
|
|
|
inputFields = HashMap.singleton "field" field
|
2020-05-25 07:41:21 +02:00
|
|
|
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-27 23:18:35 +02:00
|
|
|
let expected = Just (String "asdf")
|
2020-05-21 10:20:59 +02:00
|
|
|
actual = coerceVariableValue
|
2020-05-25 07:41:21 +02:00
|
|
|
(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-27 23:18:35 +02:00
|
|
|
let expected = Just (String "asdf")
|
2020-05-21 10:20:59 +02:00
|
|
|
actual = coerceVariableValue
|
2020-05-25 07:41:21 +02:00
|
|
|
(In.NonNullScalarType string) (Aeson.String "asdf")
|
2020-05-21 10:20:59 +02:00
|
|
|
in actual `shouldBe` expected
|
|
|
|
it "coerces booleans" $
|
2020-05-27 23:18:35 +02:00
|
|
|
let expected = Just (Boolean True)
|
2020-05-21 10:20:59 +02:00
|
|
|
actual = coerceVariableValue
|
2020-05-25 07:41:21 +02:00
|
|
|
(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-27 23:18:35 +02:00
|
|
|
let expected = Just (Int 0)
|
2020-05-21 10:20:59 +02:00
|
|
|
actual = coerceVariableValue
|
2020-05-25 07:41:21 +02:00
|
|
|
(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
|
2020-05-25 07:41:21 +02:00
|
|
|
(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-27 23:18:35 +02:00
|
|
|
let expected = Just (Float 1.4)
|
2020-05-21 10:20:59 +02:00
|
|
|
actual = coerceVariableValue
|
2020-05-25 07:41:21 +02:00
|
|
|
(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-27 23:18:35 +02:00
|
|
|
let expected = Just (String "1234")
|
2020-05-21 10:20:59 +02:00
|
|
|
actual = coerceVariableValue
|
2020-05-25 07:41:21 +02:00
|
|
|
(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-27 23:18:35 +02:00
|
|
|
expected = Just $ 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-27 23:18:35 +02:00
|
|
|
expected = Just $ 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" $
|
2020-05-25 07:41:21 +02:00
|
|
|
let actual = coerceVariableValue (In.NamedScalarType id) Aeson.Null
|
2020-05-27 23:18:35 +02:00
|
|
|
in actual `shouldBe` Just Null
|
2020-05-21 10:20:59 +02:00
|
|
|
it "preserves list order" $
|
|
|
|
let list = Aeson.toJSONList ["asdf" :: Aeson.Value, "qwer"]
|
2020-05-25 07:41:21 +02:00
|
|
|
listType = (In.ListType $ In.NamedScalarType string)
|
2020-05-21 10:20:59 +02:00
|
|
|
actual = coerceVariableValue listType list
|
2020-05-27 23:18:35 +02:00
|
|
|
expected = Just $ List [String "asdf", 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-27 23:18:35 +02:00
|
|
|
let expected = Just (Enum "NORTH")
|
2020-05-22 10:11:48 +02:00
|
|
|
actual = coerceInputLiteral
|
2020-05-27 23:18:35 +02:00
|
|
|
(In.NamedEnumType direction) (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
|
2020-05-27 23:18:35 +02:00
|
|
|
(In.NamedEnumType direction) (Enum "NORTH_EAST")
|
2020-05-22 10:11:48 +02:00
|
|
|
in actual `shouldSatisfy` isNothing
|
|
|
|
it "coerces integers to IDs" $
|
2020-05-27 23:18:35 +02:00
|
|
|
let expected = Just (String "1234")
|
|
|
|
actual = coerceInputLiteral (In.NamedScalarType id) (Int 1234)
|
2020-05-22 10:11:48 +02:00
|
|
|
in lookupActual actual `shouldBe` expected
|