Ai
1 Star 0 Fork 0

麦冬果果/graphql-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
definition_test.go 18.24 KB
一键复制 编辑 原始数据 按行查看 历史
Robert Roland 提交于 2018-06-12 05:32 +08:00 . Adds an AddFieldConfig method to InputObjects
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
package graphql_test
import (
"fmt"
"reflect"
"testing"
"github.com/graphql-go/graphql"
"github.com/graphql-go/graphql/testutil"
)
var blogImage = graphql.NewObject(graphql.ObjectConfig{
Name: "Image",
Fields: graphql.Fields{
"url": &graphql.Field{
Type: graphql.String,
},
"width": &graphql.Field{
Type: graphql.Int,
},
"height": &graphql.Field{
Type: graphql.Int,
},
},
})
var blogAuthor = graphql.NewObject(graphql.ObjectConfig{
Name: "Author",
Fields: graphql.Fields{
"id": &graphql.Field{
Type: graphql.String,
},
"name": &graphql.Field{
Type: graphql.String,
},
"pic": &graphql.Field{
Type: blogImage,
Args: graphql.FieldConfigArgument{
"width": &graphql.ArgumentConfig{
Type: graphql.Int,
},
"height": &graphql.ArgumentConfig{
Type: graphql.Int,
},
},
},
"recentArticle": &graphql.Field{},
},
})
var blogArticle = graphql.NewObject(graphql.ObjectConfig{
Name: "Article",
Fields: graphql.Fields{
"id": &graphql.Field{
Type: graphql.String,
},
"isPublished": &graphql.Field{
Type: graphql.Boolean,
},
"author": &graphql.Field{
Type: blogAuthor,
},
"title": &graphql.Field{
Type: graphql.String,
},
"body": &graphql.Field{
Type: graphql.String,
},
},
})
var blogQuery = graphql.NewObject(graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"article": &graphql.Field{
Type: blogArticle,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
},
"feed": &graphql.Field{
Type: graphql.NewList(blogArticle),
},
},
})
var blogMutation = graphql.NewObject(graphql.ObjectConfig{
Name: "Mutation",
Fields: graphql.Fields{
"writeArticle": &graphql.Field{
Type: blogArticle,
Args: graphql.FieldConfigArgument{
"title": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
},
},
})
var blogSubscription = graphql.NewObject(graphql.ObjectConfig{
Name: "Subscription",
Fields: graphql.Fields{
"articleSubscribe": &graphql.Field{
Type: blogArticle,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
},
},
})
var objectType = graphql.NewObject(graphql.ObjectConfig{
Name: "Object",
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
return true
},
})
var interfaceType = graphql.NewInterface(graphql.InterfaceConfig{
Name: "Interface",
})
var unionType = graphql.NewUnion(graphql.UnionConfig{
Name: "Union",
Types: []*graphql.Object{
objectType,
},
})
var enumType = graphql.NewEnum(graphql.EnumConfig{
Name: "Enum",
Values: graphql.EnumValueConfigMap{
"foo": &graphql.EnumValueConfig{},
},
})
var inputObjectType = graphql.NewInputObject(graphql.InputObjectConfig{
Name: "InputObject",
})
func init() {
blogAuthor.AddFieldConfig("recentArticle", &graphql.Field{
Type: blogArticle,
})
}
func TestTypeSystem_DefinitionExample_DefinesAQueryOnlySchema(t *testing.T) {
blogSchema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: blogQuery,
})
if err != nil {
t.Fatalf("unexpected error, got: %v", err)
}
if blogSchema.QueryType() != blogQuery {
t.Fatalf("expected blogSchema.GetQueryType() == blogQuery")
}
articleField, _ := blogQuery.Fields()["article"]
if articleField == nil {
t.Fatalf("articleField is nil")
}
articleFieldType := articleField.Type
if articleFieldType != blogArticle {
t.Fatalf("articleFieldType expected to equal blogArticle, got: %v", articleField.Type)
}
if articleFieldType.Name() != "Article" {
t.Fatalf("articleFieldType.Name expected to equal `Article`, got: %v", articleField.Type.Name())
}
if articleField.Name != "article" {
t.Fatalf("articleField.Name expected to equal `article`, got: %v", articleField.Name)
}
articleFieldTypeObject, ok := articleFieldType.(*graphql.Object)
if !ok {
t.Fatalf("expected articleFieldType to be graphql.Object`, got: %v", articleField)
}
// TODO: expose a Object.GetField(key string), instead of this ghetto way of accessing a field map?
titleField := articleFieldTypeObject.Fields()["title"]
if titleField == nil {
t.Fatalf("titleField is nil")
}
if titleField.Name != "title" {
t.Fatalf("titleField.Name expected to equal title, got: %v", titleField.Name)
}
if titleField.Type != graphql.String {
t.Fatalf("titleField.Type expected to equal graphql.String, got: %v", titleField.Type)
}
if titleField.Type.Name() != "String" {
t.Fatalf("titleField.Type.GetName() expected to equal `String`, got: %v", titleField.Type.Name())
}
authorField := articleFieldTypeObject.Fields()["author"]
if authorField == nil {
t.Fatalf("authorField is nil")
}
authorFieldObject, ok := authorField.Type.(*graphql.Object)
if !ok {
t.Fatalf("expected authorField.Type to be Object`, got: %v", authorField)
}
recentArticleField := authorFieldObject.Fields()["recentArticle"]
if recentArticleField == nil {
t.Fatalf("recentArticleField is nil")
}
if recentArticleField.Type != blogArticle {
t.Fatalf("recentArticleField.Type expected to equal blogArticle, got: %v", recentArticleField.Type)
}
feedField := blogQuery.Fields()["feed"]
feedFieldList, ok := feedField.Type.(*graphql.List)
if !ok {
t.Fatalf("expected feedFieldList to be List`, got: %v", authorField)
}
if feedFieldList.OfType != blogArticle {
t.Fatalf("feedFieldList.OfType expected to equal blogArticle, got: %v", feedFieldList.OfType)
}
if feedField.Name != "feed" {
t.Fatalf("feedField.Name expected to equal `feed`, got: %v", feedField.Name)
}
}
func TestTypeSystem_DefinitionExample_DefinesAMutationScheme(t *testing.T) {
blogSchema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: blogQuery,
Mutation: blogMutation,
})
if err != nil {
t.Fatalf("unexpected error, got: %v", err)
}
if blogSchema.MutationType() != blogMutation {
t.Fatalf("expected blogSchema.GetMutationType() == blogMutation")
}
writeMutation, _ := blogMutation.Fields()["writeArticle"]
if writeMutation == nil {
t.Fatalf("writeMutation is nil")
}
writeMutationType := writeMutation.Type
if writeMutationType != blogArticle {
t.Fatalf("writeMutationType expected to equal blogArticle, got: %v", writeMutationType)
}
if writeMutationType.Name() != "Article" {
t.Fatalf("writeMutationType.Name expected to equal `Article`, got: %v", writeMutationType.Name())
}
if writeMutation.Name != "writeArticle" {
t.Fatalf("writeMutation.Name expected to equal `writeArticle`, got: %v", writeMutation.Name)
}
}
func TestTypeSystem_DefinitionExample_DefinesASubscriptionScheme(t *testing.T) {
blogSchema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: blogQuery,
Subscription: blogSubscription,
})
if err != nil {
t.Fatalf("unexpected error, got: %v", err)
}
if blogSchema.SubscriptionType() != blogSubscription {
t.Fatalf("expected blogSchema.SubscriptionType() == blogSubscription")
}
subMutation, _ := blogSubscription.Fields()["articleSubscribe"]
if subMutation == nil {
t.Fatalf("subMutation is nil")
}
subMutationType := subMutation.Type
if subMutationType != blogArticle {
t.Fatalf("subMutationType expected to equal blogArticle, got: %v", subMutationType)
}
if subMutationType.Name() != "Article" {
t.Fatalf("subMutationType.Name expected to equal `Article`, got: %v", subMutationType.Name())
}
if subMutation.Name != "articleSubscribe" {
t.Fatalf("subMutation.Name expected to equal `articleSubscribe`, got: %v", subMutation.Name)
}
}
func TestTypeSystem_DefinitionExample_IncludesNestedInputObjectsInTheMap(t *testing.T) {
nestedInputObject := graphql.NewInputObject(graphql.InputObjectConfig{
Name: "NestedInputObject",
Fields: graphql.InputObjectConfigFieldMap{
"value": &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
},
})
someInputObject := graphql.NewInputObject(graphql.InputObjectConfig{
Name: "SomeInputObject",
Fields: graphql.InputObjectConfigFieldMap{
"nested": &graphql.InputObjectFieldConfig{
Type: nestedInputObject,
},
},
})
someMutation := graphql.NewObject(graphql.ObjectConfig{
Name: "SomeMutation",
Fields: graphql.Fields{
"mutateSomething": &graphql.Field{
Type: blogArticle,
Args: graphql.FieldConfigArgument{
"input": &graphql.ArgumentConfig{
Type: someInputObject,
},
},
},
},
})
someSubscription := graphql.NewObject(graphql.ObjectConfig{
Name: "SomeSubscription",
Fields: graphql.Fields{
"subscribeToSomething": &graphql.Field{
Type: blogArticle,
Args: graphql.FieldConfigArgument{
"input": &graphql.ArgumentConfig{
Type: someInputObject,
},
},
},
},
})
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: blogQuery,
Mutation: someMutation,
Subscription: someSubscription,
})
if err != nil {
t.Fatalf("unexpected error, got: %v", err)
}
if schema.Type("NestedInputObject") != nestedInputObject {
t.Fatalf(`schema.GetType("NestedInputObject") expected to equal nestedInputObject, got: %v`, schema.Type("NestedInputObject"))
}
}
func TestTypeSystem_DefinitionExample_IncludesInterfacesSubTypesInTheTypeMap(t *testing.T) {
someInterface := graphql.NewInterface(graphql.InterfaceConfig{
Name: "SomeInterface",
Fields: graphql.Fields{
"f": &graphql.Field{
Type: graphql.Int,
},
},
})
someSubType := graphql.NewObject(graphql.ObjectConfig{
Name: "SomeSubtype",
Fields: graphql.Fields{
"f": &graphql.Field{
Type: graphql.Int,
},
},
Interfaces: []*graphql.Interface{someInterface},
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
return true
},
})
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: graphql.NewObject(graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"iface": &graphql.Field{
Type: someInterface,
},
},
}),
Types: []graphql.Type{someSubType},
})
if err != nil {
t.Fatalf("unexpected error, got: %v", err)
}
if schema.Type("SomeSubtype") != someSubType {
t.Fatalf(`schema.GetType("SomeSubtype") expected to equal someSubType, got: %v`, schema.Type("SomeSubtype"))
}
}
func TestTypeSystem_DefinitionExample_IncludesInterfacesThunkSubtypesInTheTypeMap(t *testing.T) {
someInterface := graphql.NewInterface(graphql.InterfaceConfig{
Name: "SomeInterface",
Fields: graphql.Fields{
"f": &graphql.Field{
Type: graphql.Int,
},
},
})
someSubType := graphql.NewObject(graphql.ObjectConfig{
Name: "SomeSubtype",
Fields: graphql.Fields{
"f": &graphql.Field{
Type: graphql.Int,
},
},
Interfaces: (graphql.InterfacesThunk)(func() []*graphql.Interface {
return []*graphql.Interface{someInterface}
}),
IsTypeOf: func(p graphql.IsTypeOfParams) bool {
return true
},
})
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: graphql.NewObject(graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"iface": &graphql.Field{
Type: someInterface,
},
},
}),
Types: []graphql.Type{someSubType},
})
if err != nil {
t.Fatalf("unexpected error, got: %v", err)
}
if schema.Type("SomeSubtype") != someSubType {
t.Fatalf(`schema.GetType("SomeSubtype") expected to equal someSubType, got: %v`, schema.Type("SomeSubtype"))
}
}
func TestTypeSystem_DefinitionExample_StringifiesSimpleTypes(t *testing.T) {
type Test struct {
ttype graphql.Type
expected string
}
tests := []Test{
{graphql.Int, "Int"},
{blogArticle, "Article"},
{interfaceType, "Interface"},
{unionType, "Union"},
{enumType, "Enum"},
{inputObjectType, "InputObject"},
{graphql.NewNonNull(graphql.Int), "Int!"},
{graphql.NewList(graphql.Int), "[Int]"},
{graphql.NewNonNull(graphql.NewList(graphql.Int)), "[Int]!"},
{graphql.NewList(graphql.NewNonNull(graphql.Int)), "[Int!]"},
{graphql.NewList(graphql.NewList(graphql.Int)), "[[Int]]"},
}
for _, test := range tests {
ttypeStr := fmt.Sprintf("%v", test.ttype)
if ttypeStr != test.expected {
t.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)
}
}
}
func TestTypeSystem_DefinitionExample_IdentifiesInputTypes(t *testing.T) {
type Test struct {
ttype graphql.Type
expected bool
}
tests := []Test{
{graphql.Int, true},
{objectType, false},
{interfaceType, false},
{unionType, false},
{enumType, true},
{inputObjectType, true},
}
for _, test := range tests {
ttypeStr := fmt.Sprintf("%v", test.ttype)
if graphql.IsInputType(test.ttype) != test.expected {
t.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)
}
if graphql.IsInputType(graphql.NewList(test.ttype)) != test.expected {
t.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)
}
if graphql.IsInputType(graphql.NewNonNull(test.ttype)) != test.expected {
t.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)
}
}
}
func TestTypeSystem_DefinitionExample_IdentifiesOutputTypes(t *testing.T) {
type Test struct {
ttype graphql.Type
expected bool
}
tests := []Test{
{graphql.Int, true},
{objectType, true},
{interfaceType, true},
{unionType, true},
{enumType, true},
{inputObjectType, false},
}
for _, test := range tests {
ttypeStr := fmt.Sprintf("%v", test.ttype)
if graphql.IsOutputType(test.ttype) != test.expected {
t.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)
}
if graphql.IsOutputType(graphql.NewList(test.ttype)) != test.expected {
t.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)
}
if graphql.IsOutputType(graphql.NewNonNull(test.ttype)) != test.expected {
t.Fatalf(`expected %v , got: %v`, test.expected, ttypeStr)
}
}
}
func TestTypeSystem_DefinitionExample_ProhibitsNestingNonNullInsideNonNull(t *testing.T) {
ttype := graphql.NewNonNull(graphql.NewNonNull(graphql.Int))
expected := `Can only create NonNull of a Nullable Type but got: Int!.`
if ttype.Error().Error() != expected {
t.Fatalf(`expected %v , got: %v`, expected, ttype.Error())
}
}
func TestTypeSystem_DefinitionExample_ProhibitsNilInNonNull(t *testing.T) {
ttype := graphql.NewNonNull(nil)
expected := `Can only create NonNull of a Nullable Type but got: <nil>.`
if ttype.Error().Error() != expected {
t.Fatalf(`expected %v , got: %v`, expected, ttype.Error())
}
}
func TestTypeSystem_DefinitionExample_ProhibitsNilTypeInUnions(t *testing.T) {
ttype := graphql.NewUnion(graphql.UnionConfig{
Name: "BadUnion",
Types: []*graphql.Object{nil},
})
expected := `BadUnion may only contain Object types, it cannot contain: <nil>.`
if ttype.Error().Error() != expected {
t.Fatalf(`expected %v , got: %v`, expected, ttype.Error())
}
}
func TestTypeSystem_DefinitionExample_DoesNotMutatePassedFieldDefinitions(t *testing.T) {
fields := graphql.Fields{
"field1": &graphql.Field{
Type: graphql.String,
},
"field2": &graphql.Field{
Type: graphql.String,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
},
}
testObject1 := graphql.NewObject(graphql.ObjectConfig{
Name: "Test1",
Fields: fields,
})
testObject2 := graphql.NewObject(graphql.ObjectConfig{
Name: "Test2",
Fields: fields,
})
if !reflect.DeepEqual(testObject1.Fields(), testObject2.Fields()) {
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(testObject1.Fields(), testObject2.Fields()))
}
expectedFields := graphql.Fields{
"field1": &graphql.Field{
Type: graphql.String,
},
"field2": &graphql.Field{
Type: graphql.String,
Args: graphql.FieldConfigArgument{
"id": &graphql.ArgumentConfig{
Type: graphql.String,
},
},
},
}
if !reflect.DeepEqual(fields, expectedFields) {
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expectedFields, fields))
}
inputFields := graphql.InputObjectConfigFieldMap{
"field1": &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
"field2": &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
}
expectedInputFields := graphql.InputObjectConfigFieldMap{
"field1": &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
"field2": &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
}
testInputObject1 := graphql.NewInputObject(graphql.InputObjectConfig{
Name: "Test1",
Fields: inputFields,
})
testInputObject2 := graphql.NewInputObject(graphql.InputObjectConfig{
Name: "Test2",
Fields: inputFields,
})
if !reflect.DeepEqual(testInputObject1.Fields(), testInputObject2.Fields()) {
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(testInputObject1.Fields(), testInputObject2.Fields()))
}
if !reflect.DeepEqual(inputFields, expectedInputFields) {
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expectedInputFields, fields))
}
}
func TestTypeSystem_DefinitionExample_IncludesFieldsThunk(t *testing.T) {
var someObject *graphql.Object
someObject = graphql.NewObject(graphql.ObjectConfig{
Name: "SomeObject",
Fields: (graphql.FieldsThunk)(func() graphql.Fields {
return graphql.Fields{
"f": &graphql.Field{
Type: graphql.Int,
},
"s": &graphql.Field{
Type: someObject,
},
}
}),
})
fieldMap := someObject.Fields()
if !reflect.DeepEqual(fieldMap["s"].Type, someObject) {
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(fieldMap["s"].Type, someObject))
}
}
func TestTypeSystem_DefinitionExampe_AllowsCyclicFieldTypes(t *testing.T) {
personType := graphql.NewObject(graphql.ObjectConfig{
Name: "Person",
Fields: (graphql.FieldsThunk)(func() graphql.Fields {
return graphql.Fields{
"name": &graphql.Field{
Type: graphql.String,
},
"bestFriend": &graphql.Field{
Type: personType,
},
}
}),
})
fieldMap := personType.Fields()
if !reflect.DeepEqual(fieldMap["name"].Type, graphql.String) {
t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(fieldMap["bestFriend"].Type, personType))
}
}
func TestTypeSystem_DefinitionExample_CanAddInputObjectField(t *testing.T) {
io := graphql.NewInputObject(graphql.InputObjectConfig{
Name: "inputObject",
Fields: graphql.InputObjectConfigFieldMap{
"value": &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
},
})
io.AddFieldConfig("newValue", &graphql.InputObjectFieldConfig{
Type: graphql.Int,
})
fieldMap := io.Fields()
if len(fieldMap) < 2 {
t.Fatalf("Unexpected result, inputObject should have two fields, has %d", len(fieldMap))
}
if _, ok := fieldMap["value"]; !ok {
t.Fatal("Unexpected result, inputObject should have a field named 'value'")
}
if _, ok := fieldMap["newValue"]; !ok {
t.Fatal("Unexpected result, inputObject should have a field named 'newValue'")
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/mdgg0816/graphql-go.git
git@gitee.com:mdgg0816/graphql-go.git
mdgg0816
graphql-go
graphql-go
v0.7.6

搜索帮助