graphql-api-0.4.0: tests/SchemaSpec.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
module SchemaSpec (spec) where
import Protolude hiding (Down, Enum)
import Test.Hspec
import GraphQL.API
( Field
, Enum
, List
, getAnnotatedInputType
, getDefinition
)
import qualified GraphQL.Internal.Syntax.AST as AST
import GraphQL.Internal.API
( getAnnotatedType
, getFieldDefinition
, getInterfaceDefinition
)
import GraphQL.Internal.Schema
( EnumTypeDefinition(..)
, EnumValueDefinition(..)
, FieldDefinition(..)
, ObjectTypeDefinition(..)
, InterfaceTypeDefinition(..)
, AnnotatedType(..)
, ListType(..)
, UnionTypeDefinition(..)
, GType(..)
, TypeDefinition(..)
, InputTypeDefinition(..)
, InputObjectTypeDefinition(..)
, InputObjectFieldDefinition(..)
, ScalarTypeDefinition(..)
, AnnotatedType(..)
, NonNullType(..)
, Builtin(..)
, InputType(..)
, getInputTypeDefinition
, builtinFromName
, astAnnotationToSchemaAnnotation
)
import ExampleSchema
spec :: Spec
spec = describe "Type" $ do
describe "Field" $
it "encodes correctly" $ do
getFieldDefinition @(Field "hello" Int) `shouldBe` Right (FieldDefinition "hello" [] (TypeNonNull (NonNullTypeNamed (BuiltinType GInt))))
describe "Interface" $
it "encodes correctly" $ do
getInterfaceDefinition @Sentient `shouldBe`
Right (InterfaceTypeDefinition
"Sentient"
(FieldDefinition "name" [] (TypeNonNull (NonNullTypeNamed (BuiltinType GString))) :| []))
describe "full example" $
it "encodes correctly" $ do
getDefinition @Human `shouldBe`
Right (ObjectTypeDefinition "Human"
[ InterfaceTypeDefinition "Sentient" (
FieldDefinition "name" [] (TypeNonNull (NonNullTypeNamed (BuiltinType GString))) :| [])
]
(FieldDefinition "name" [] (TypeNonNull (NonNullTypeNamed (BuiltinType GString))) :| []))
describe "output Enum" $
it "encodes correctly" $ do
getAnnotatedType @(Enum "DogCommand" DogCommand) `shouldBe`
Right (TypeNonNull (NonNullTypeNamed (DefinedType (TypeDefinitionEnum (EnumTypeDefinition "DogCommand"
[ EnumValueDefinition "Sit"
, EnumValueDefinition "Down"
, EnumValueDefinition "Heel"
])))))
describe "Union type" $
it "encodes correctly" $ do
getAnnotatedType @CatOrDog `shouldBe`
TypeNamed . DefinedType . TypeDefinitionUnion . UnionTypeDefinition "CatOrDog"
<$> sequence (getDefinition @Cat :| [getDefinition @Dog])
describe "List" $
it "encodes correctly" $ do
getAnnotatedType @(List Int) `shouldBe` Right (TypeList (ListType (TypeNonNull (NonNullTypeNamed (BuiltinType GInt)))))
getAnnotatedInputType @(List Int) `shouldBe` Right (TypeList (ListType (TypeNonNull (NonNullTypeNamed (BuiltinInputType GInt)))))
describe "TypeDefinition accepted as InputTypes" $
it "Enum/InputObject/Scalar" $ do
getInputTypeDefinition (TypeDefinitionEnum (EnumTypeDefinition "DogCommand"
[ EnumValueDefinition "Sit"
, EnumValueDefinition "Down"
, EnumValueDefinition "Heel"
])) `shouldBe` Just (InputTypeDefinitionEnum (EnumTypeDefinition "DogCommand"
[ EnumValueDefinition "Sit"
, EnumValueDefinition "Down"
, EnumValueDefinition "Heel"
]))
getInputTypeDefinition (TypeDefinitionInputObject (InputObjectTypeDefinition "Human"
(InputObjectFieldDefinition "name" (TypeNonNull (NonNullTypeNamed (BuiltinInputType GString))) Nothing :| [])
)) `shouldBe` Just (InputTypeDefinitionObject (InputObjectTypeDefinition "Human"
(InputObjectFieldDefinition "name" (TypeNonNull (NonNullTypeNamed (BuiltinInputType GString))) Nothing :| [])
))
getInputTypeDefinition (TypeDefinitionScalar (ScalarTypeDefinition "Human")) `shouldBe` Just (InputTypeDefinitionScalar (ScalarTypeDefinition "Human"))
describe "TypeDefinition refused as InputTypes" $
-- todo: add all the others (union type, ..?)
it "Object" $ do
getInputTypeDefinition (TypeDefinitionObject (ObjectTypeDefinition "Human" []
(FieldDefinition "name" [] (TypeNonNull (NonNullTypeNamed (BuiltinType GString))) :| []))) `shouldBe` Nothing
describe "Builtin types from name" $
it "Int/Bool/String/Float/ID" $ do
builtinFromName "Int" `shouldBe` Just GInt
builtinFromName "Boolean" `shouldBe` Just GBool
builtinFromName "String" `shouldBe` Just GString
builtinFromName "Float" `shouldBe` Just GFloat
builtinFromName "ID" `shouldBe` Just GID
builtinFromName "RANDOMSTRING" `shouldBe` Nothing
describe "Annotations from AST" $
it "annotation like [[ScalarType!]]!" $ do
let typeDefinitionScalar = (TypeDefinitionScalar (ScalarTypeDefinition "ScalarType"))
astAnnotationToSchemaAnnotation (
AST.TypeNonNull (
AST.NonNullTypeList (
AST.ListType (
AST.TypeList (
AST.ListType (
AST.TypeNonNull (
AST.NonNullTypeNamed (AST.NamedType "ScalarType")
))))))) typeDefinitionScalar `shouldBe` (
TypeNonNull (
NonNullTypeList (
ListType (
TypeList (
ListType (
TypeNonNull (
NonNullTypeNamed typeDefinitionScalar
)))))))