Coerce variable values
This commit is contained in:
88
tests/Language/GraphQL/Execute/CoerceSpec.hs
Normal file
88
tests/Language/GraphQL/Execute/CoerceSpec.hs
Normal file
@ -0,0 +1,88 @@
|
||||
{-# 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
|
||||
import qualified Data.HashMap.Strict as HashMap
|
||||
import Data.Maybe (isNothing)
|
||||
import Data.Scientific (scientific)
|
||||
import Language.GraphQL.AST.Core
|
||||
import Language.GraphQL.Execute.Coerce
|
||||
import Language.GraphQL.Type.Definition
|
||||
import Prelude hiding (id)
|
||||
import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy)
|
||||
|
||||
singletonInputObject :: InputType
|
||||
singletonInputObject = ObjectInputType type'
|
||||
where
|
||||
type' = InputObjectType "ObjectName" Nothing inputFields
|
||||
inputFields = HashMap.singleton "field" field
|
||||
field = InputField Nothing (ScalarInputType string) Nothing
|
||||
|
||||
spec :: Spec
|
||||
spec =
|
||||
describe "ToGraphQL Aeson" $ do
|
||||
it "coerces strings" $
|
||||
let expected = Just (String "asdf")
|
||||
actual = coerceVariableValue
|
||||
(ScalarInputType string) (Aeson.String "asdf")
|
||||
in actual `shouldBe` expected
|
||||
it "coerces non-null strings" $
|
||||
let expected = Just (String "asdf")
|
||||
actual = coerceVariableValue
|
||||
(NonNullScalarInputType string) (Aeson.String "asdf")
|
||||
in actual `shouldBe` expected
|
||||
it "coerces booleans" $
|
||||
let expected = Just (Boolean True)
|
||||
actual = coerceVariableValue
|
||||
(ScalarInputType boolean) (Aeson.Bool True)
|
||||
in actual `shouldBe` expected
|
||||
it "coerces zero to an integer" $
|
||||
let expected = Just (Int 0)
|
||||
actual = coerceVariableValue
|
||||
(ScalarInputType int) (Aeson.Number 0)
|
||||
in actual `shouldBe` expected
|
||||
it "rejects fractional if an integer is expected" $
|
||||
let actual = coerceVariableValue
|
||||
(ScalarInputType int) (Aeson.Number $ scientific 14 (-1))
|
||||
in actual `shouldSatisfy` isNothing
|
||||
it "coerces float numbers" $
|
||||
let expected = Just (Float 1.4)
|
||||
actual = coerceVariableValue
|
||||
(ScalarInputType float) (Aeson.Number $ scientific 14 (-1))
|
||||
in actual `shouldBe` expected
|
||||
it "coerces IDs" $
|
||||
let expected = Just (String "1234")
|
||||
actual = coerceVariableValue
|
||||
(ScalarInputType id) (Aeson.String "1234")
|
||||
in actual `shouldBe` expected
|
||||
it "coerces input objects" $
|
||||
let actual = coerceVariableValue singletonInputObject
|
||||
$ Aeson.object ["field" .= ("asdf" :: Aeson.Value)]
|
||||
expected = Just $ Object $ HashMap.singleton "field" "asdf"
|
||||
in actual `shouldBe` expected
|
||||
it "skips the field if it is missing in the variables" $
|
||||
let actual = coerceVariableValue
|
||||
singletonInputObject Aeson.emptyObject
|
||||
expected = Just $ Object HashMap.empty
|
||||
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 (ScalarInputType id) Aeson.Null
|
||||
in actual `shouldBe` Just Null
|
||||
it "preserves list order" $
|
||||
let list = Aeson.toJSONList ["asdf" :: Aeson.Value, "qwer"]
|
||||
listType = (ListInputType $ ScalarInputType string)
|
||||
actual = coerceVariableValue listType list
|
||||
expected = Just $ List [String "asdf", String "qwer"]
|
||||
in actual `shouldBe` expected
|
@ -7,7 +7,6 @@ module Test.DirectiveSpec
|
||||
import Data.Aeson (Value(..), object, (.=))
|
||||
import qualified Data.HashMap.Strict as HashMap
|
||||
import Language.GraphQL
|
||||
import qualified Language.GraphQL.Schema as Schema
|
||||
import Language.GraphQL.Type.Definition
|
||||
import Language.GraphQL.Type.Schema (Schema(..))
|
||||
import Test.Hspec (Spec, describe, it, shouldBe)
|
||||
@ -16,11 +15,10 @@ import Text.RawString.QQ (r)
|
||||
experimentalResolver :: Schema IO
|
||||
experimentalResolver = Schema { query = queryType, mutation = Nothing }
|
||||
where
|
||||
resolver = ValueResolver $ pure $ Number 5
|
||||
queryType = ObjectType "Query"
|
||||
$ HashMap.singleton "experimentalField"
|
||||
$ Schema.ValueResolver
|
||||
$ pure
|
||||
$ Number 5
|
||||
$ Field Nothing (ScalarOutputType int) mempty resolver
|
||||
|
||||
emptyObject :: Value
|
||||
emptyObject = object
|
||||
|
@ -6,7 +6,6 @@ module Test.FragmentSpec
|
||||
|
||||
import Data.Aeson (Value(..), object, (.=))
|
||||
import qualified Data.HashMap.Strict as HashMap
|
||||
import Data.List.NonEmpty (NonEmpty(..))
|
||||
import Data.Text (Text)
|
||||
import Language.GraphQL
|
||||
import qualified Language.GraphQL.Schema as Schema
|
||||
@ -50,12 +49,28 @@ hasErrors :: Value -> Bool
|
||||
hasErrors (Object object') = HashMap.member "errors" object'
|
||||
hasErrors _ = True
|
||||
|
||||
toSchema :: Schema.Resolver IO -> Schema IO
|
||||
toSchema resolver = Schema { query = queryType, mutation = Nothing }
|
||||
shirtType :: ObjectType IO
|
||||
shirtType = ObjectType "Shirt"
|
||||
$ HashMap.singleton resolverName
|
||||
$ Field Nothing (ScalarOutputType string) mempty resolve
|
||||
where
|
||||
(Schema.Resolver resolverName resolve) = size
|
||||
|
||||
hatType :: ObjectType IO
|
||||
hatType = ObjectType "Hat"
|
||||
$ HashMap.singleton resolverName
|
||||
$ Field Nothing (ScalarOutputType int) mempty resolve
|
||||
where
|
||||
(Schema.Resolver resolverName resolve) = circumference
|
||||
|
||||
toSchema :: Schema.Resolver IO -> Schema IO
|
||||
toSchema (Schema.Resolver resolverName resolve) = Schema
|
||||
{ query = queryType, mutation = Nothing }
|
||||
where
|
||||
unionMember = if resolverName == "Hat" then hatType else shirtType
|
||||
queryType = ObjectType "Query"
|
||||
$ Schema.resolversToMap
|
||||
$ resolver :| []
|
||||
$ HashMap.singleton resolverName
|
||||
$ Field Nothing (ObjectOutputType unionMember) mempty resolve
|
||||
|
||||
spec :: Spec
|
||||
spec = do
|
||||
|
@ -5,6 +5,7 @@ module Test.RootOperationSpec
|
||||
) where
|
||||
|
||||
import Data.Aeson ((.=), object)
|
||||
import qualified Data.HashMap.Strict as HashMap
|
||||
import Data.List.NonEmpty (NonEmpty(..))
|
||||
import Language.GraphQL
|
||||
import qualified Language.GraphQL.Schema as Schema
|
||||
@ -13,10 +14,18 @@ import Text.RawString.QQ (r)
|
||||
import Language.GraphQL.Type.Definition
|
||||
import Language.GraphQL.Type.Schema
|
||||
|
||||
hatType :: ObjectType IO
|
||||
hatType = ObjectType "Hat"
|
||||
$ HashMap.singleton resolverName
|
||||
$ Field Nothing (ScalarOutputType int) mempty resolve
|
||||
where
|
||||
(Schema.Resolver resolverName resolve) =
|
||||
Schema.scalar "circumference" $ pure (60 :: Int)
|
||||
|
||||
schema :: Schema IO
|
||||
schema = Schema
|
||||
(ObjectType "Query" queryResolvers)
|
||||
(Just $ ObjectType "Mutation" mutationResolvers)
|
||||
(ObjectType "Query" hatField)
|
||||
(Just $ ObjectType "Mutation" incrementField)
|
||||
where
|
||||
queryResolvers = Schema.resolversToMap $ garment :| []
|
||||
mutationResolvers = Schema.resolversToMap $ increment :| []
|
||||
@ -25,6 +34,10 @@ schema = Schema
|
||||
]
|
||||
increment = Schema.scalar "incrementCircumference"
|
||||
$ pure (61 :: Int)
|
||||
incrementField = Field Nothing (ScalarOutputType int) mempty
|
||||
<$> mutationResolvers
|
||||
hatField = Field Nothing (ObjectOutputType hatType) mempty
|
||||
<$> queryResolvers
|
||||
|
||||
spec :: Spec
|
||||
spec =
|
||||
|
@ -10,7 +10,6 @@ import Data.Functor.Identity (Identity(..))
|
||||
import qualified Data.HashMap.Strict as HashMap
|
||||
import Data.Text (Text)
|
||||
import Language.GraphQL
|
||||
import Language.GraphQL.Schema (Subs)
|
||||
import Text.RawString.QQ (r)
|
||||
import Test.Hspec.Expectations (Expectation, shouldBe)
|
||||
import Test.Hspec (Spec, describe, it)
|
||||
@ -360,6 +359,6 @@ spec = describe "Star Wars Query Tests" $ do
|
||||
testQuery :: Text -> Aeson.Value -> Expectation
|
||||
testQuery q expected = runIdentity (graphql schema q) `shouldBe` expected
|
||||
|
||||
testQueryParams :: Subs -> Text -> Aeson.Value -> Expectation
|
||||
testQueryParams :: Aeson.Object -> Text -> Aeson.Value -> Expectation
|
||||
testQueryParams f q expected =
|
||||
runIdentity (graphqlSubs schema f q) `shouldBe` expected
|
||||
|
@ -25,8 +25,8 @@ schema :: Schema Identity
|
||||
schema = Schema { query = queryType, mutation = Nothing }
|
||||
where
|
||||
queryType = ObjectType "Query"
|
||||
$ Schema.resolversToMap
|
||||
$ hero :| [human, droid]
|
||||
$ Field Nothing (ScalarOutputType string) mempty
|
||||
<$> Schema.resolversToMap (hero :| [human, droid])
|
||||
|
||||
hero :: Schema.Resolver Identity
|
||||
hero = Schema.object "hero" $ do
|
||||
|
Reference in New Issue
Block a user