func TestVariables_ObjectsAndNullability_UsingInlineStructs_ProperlyParsesSingleValueToList(t *testing.T) { doc := ` { fieldWithObjectInput(input: {a: "foo", b: "bar", c: "baz"}) } ` expected := &graphql.Result{ Data: map[string]interface{}{ "fieldWithObjectInput": `{"a":"foo","b":["bar"],"c":"baz"}`, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_ObjectsAndNullability_UsingInlineStructs_DoesNotUseIncorrectValue(t *testing.T) { doc := ` { fieldWithObjectInput(input: ["foo", "bar", "baz"]) } ` expected := &graphql.Result{ Data: map[string]interface{}{ "fieldWithObjectInput": nil, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_NullableScalars_AllowsNullableInputsToBeOmittedInAnUnlistedVariable(t *testing.T) { doc := ` query SetsNullable { fieldWithNullableStringInput(input: $value) } ` expected := &graphql.Result{ Data: map[string]interface{}{ "fieldWithNullableStringInput": nil, }, } ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_ObjectsAndNullability_UsingVariables_UsesDefaultValueWhenNotProvided(t *testing.T) { doc := ` query q($input: TestInputObject = {a: "foo", b: ["bar"], c: "baz"}) { fieldWithObjectInput(input: $input) } ` expected := &graphql.Result{ Data: map[string]interface{}{ "fieldWithObjectInput": `{"a":"foo","b":["bar"],"c":"baz"}`, }, } withDefaultsAST := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: withDefaultsAST, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_NonNullableScalars_AllowsNonNullableInputsToBeSetToAValueDirectly(t *testing.T) { doc := ` { fieldWithNonNullableStringInput(input: "a") } ` params := map[string]interface{}{ "value": "a", } expected := &graphql.Result{ Data: map[string]interface{}{ "fieldWithNonNullableStringInput": `"a"`, }, } ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, Args: params, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestNonNull_NullsANullableFieldThatSynchronouslyReturnsNullInAPromise(t *testing.T) { doc := ` query Q { promise } ` expected := &graphql.Result{ Data: map[string]interface{}{ "promise": nil, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: nonNullTestSchema, AST: ast, Root: nullingData, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected.Data, result.Data) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected.Data, result.Data)) } if !reflect.DeepEqual(expected.Errors, result.Errors) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } }
func TestVariables_NonNullableScalars_PassesAlongNullForNonNullableInputsIfExplicitlySetInTheQuery(t *testing.T) { doc := ` { fieldWithNonNullableStringInput } ` params := map[string]interface{}{ "value": "a", } expected := &graphql.Result{ Data: map[string]interface{}{ "fieldWithNonNullableStringInput": nil, }, } ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, Args: params, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestNonNull_NullsTheTopLevelIfSyncNonNullableFieldResolvesNull(t *testing.T) { doc := ` query Q { nonNullPromise } ` expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: `Cannot return null for non-nullable field DataType.nonNullPromise.`, Locations: []location.SourceLocation{ location.SourceLocation{Line: 2, Column: 17}, }, }, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: nonNullTestSchema, AST: ast, Root: nullingData, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_ListsAndNullability_DoesNotAllowNonNullListsToBeNull(t *testing.T) { doc := ` query q($input: [String]!) { nnList(input: $input) } ` expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: `Variable "$input" of required type "[String]!" was not provided.`, Locations: []location.SourceLocation{ location.SourceLocation{ Line: 2, Column: 17, }, }, }, }, } ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_UsesArgumentDefaultValues_WhenArgumentProvidedCannotBeParsed(t *testing.T) { doc := ` { fieldWithDefaultArgumentValue(input: WRONG_TYPE) } ` expected := &graphql.Result{ Data: map[string]interface{}{ "fieldWithDefaultArgumentValue": `"Hello World"`, }, } ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_ListsAndNullability_AllowsNonNullListsToContainValues(t *testing.T) { doc := ` query q($input: [String]!) { nnList(input: $input) } ` params := map[string]interface{}{ "input": []interface{}{"A"}, } expected := &graphql.Result{ Data: map[string]interface{}{ "nnList": `["A"]`, }, } ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, Args: params, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func testVariables_ObjectsAndNullability_UsingVariables_GetAST(t *testing.T) *ast.Document { doc := ` query q($input: TestInputObject) { fieldWithObjectInput(input: $input) } ` return testutil.TestParse(t, doc) }
func TestCorrectlyThreadsArguments(t *testing.T) { query := ` query Example { b(numArg: 123, stringArg: "foo") } ` var resolvedArgs map[string]interface{} schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: graphql.NewObject(graphql.ObjectConfig{ Name: "Type", Fields: graphql.Fields{ "b": &graphql.Field{ Args: graphql.FieldConfigArgument{ "numArg": &graphql.ArgumentConfig{ Type: graphql.Int, }, "stringArg": &graphql.ArgumentConfig{ Type: graphql.String, }, }, Type: graphql.String, Resolve: func(p graphql.ResolveParams) interface{} { resolvedArgs = p.Args return resolvedArgs }, }, }, }), }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } // parse query ast := testutil.TestParse(t, query) // execute ep := graphql.ExecuteParams{ Schema: schema, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } expectedNum := 123 expectedString := "foo" if resolvedArgs["numArg"] != expectedNum { t.Fatalf("Expected args.numArg to equal `%v`, got `%v`", expectedNum, resolvedArgs["numArg"]) } if resolvedArgs["stringArg"] != expectedString { t.Fatalf("Expected args.stringArg to equal `%v`, got `%v`", expectedNum, resolvedArgs["stringArg"]) } }
func TestAvoidsRecursion(t *testing.T) { doc := ` query Q { a ...Frag ...Frag } fragment Frag on Type { a, ...Frag } ` data := map[string]interface{}{ "a": "b", } expected := &graphql.Result{ Data: map[string]interface{}{ "a": "b", }, } schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: graphql.NewObject(graphql.ObjectConfig{ Name: "Type", Fields: graphql.Fields{ "a": &graphql.Field{ Type: graphql.String, }, }, }), }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: schema, AST: ast, Root: data, OperationName: "Q", } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func executeDirectivesTestQuery(t *testing.T, doc string) *graphql.Result { ast := testutil.TestParse(t, doc) ep := graphql.ExecuteParams{ Schema: directivesTestSchema, AST: ast, Root: directivesTestData, } return testutil.TestExecute(t, ep) }
func TestMutations_ExecutionOrdering_EvaluatesMutationsSerially(t *testing.T) { root := newTestRoot(6) doc := `mutation M { first: immediatelyChangeTheNumber(newNumber: 1) { theNumber }, second: promiseToChangeTheNumber(newNumber: 2) { theNumber }, third: immediatelyChangeTheNumber(newNumber: 3) { theNumber } fourth: promiseToChangeTheNumber(newNumber: 4) { theNumber }, fifth: immediatelyChangeTheNumber(newNumber: 5) { theNumber } }` expected := &graphql.Result{ Data: map[string]interface{}{ "first": map[string]interface{}{ "theNumber": 1, }, "second": map[string]interface{}{ "theNumber": 2, }, "third": map[string]interface{}{ "theNumber": 3, }, "fourth": map[string]interface{}{ "theNumber": 4, }, "fifth": map[string]interface{}{ "theNumber": 5, }, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: mutationsTestSchema, AST: ast, Root: root, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestUnionIntersectionTypes_ExecutesUnionTypesWithInlineFragments(t *testing.T) { // This is the valid version of the query in the above test. doc := ` { __typename name pets { __typename ... on Dog { name barks } ... on Cat { name meows } } } ` expected := &graphql.Result{ Data: map[string]interface{}{ "__typename": "Person", "name": "John", "pets": []interface{}{ map[string]interface{}{ "__typename": "Cat", "name": "Garfield", "meows": false, }, map[string]interface{}{ "__typename": "Dog", "name": "Odie", "barks": true, }, }, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: unionInterfaceTestSchema, AST: ast, Root: john, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestUnionIntersectionTypes_ExecutesUsingInterfaceTypes(t *testing.T) { // NOTE: This is an *invalid* query, but it should be an *executable* query. doc := ` { __typename name friends { __typename name barks meows } } ` expected := &graphql.Result{ Data: map[string]interface{}{ "__typename": "Person", "name": "John", "friends": []interface{}{ map[string]interface{}{ "__typename": "Person", "name": "Liz", }, map[string]interface{}{ "__typename": "Dog", "name": "Odie", "barks": true, }, }, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: unionInterfaceTestSchema, AST: ast, Root: john, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestThreadsContextCorrectly(t *testing.T) { query := ` query Example { a } ` data := map[string]interface{}{ "contextThing": "thing", } var resolvedContext map[string]interface{} schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: graphql.NewObject(graphql.ObjectConfig{ Name: "Type", Fields: graphql.Fields{ "a": &graphql.Field{ Type: graphql.String, Resolve: func(p graphql.ResolveParams) interface{} { resolvedContext = p.Source.(map[string]interface{}) return resolvedContext }, }, }, }), }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } // parse query ast := testutil.TestParse(t, query) // execute ep := graphql.ExecuteParams{ Schema: schema, Root: data, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } expected := "thing" if resolvedContext["contextThing"] != expected { t.Fatalf("Expected context.contextThing to equal %v, got %v", expected, resolvedContext["contextThing"]) } }
func TestThrowsIfNoOperationIsProvidedWithMultipleOperations(t *testing.T) { doc := `query Example { a } query OtherExample { a }` data := map[string]interface{}{ "a": "b", } expectedErrors := []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: "Must provide operation name if query contains multiple operations.", Locations: []location.SourceLocation{}, }, } schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: graphql.NewObject(graphql.ObjectConfig{ Name: "Type", Fields: graphql.Fields{ "a": &graphql.Field{ Type: graphql.String, }, }, }), }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: schema, AST: ast, Root: data, } result := testutil.TestExecute(t, ep) if len(result.Errors) != 1 { t.Fatalf("wrong result, expected len(1) unexpected len: %v", len(result.Errors)) } if result.Data != nil { t.Fatalf("wrong result, expected nil result.Data, got %v", result.Data) } if !reflect.DeepEqual(expectedErrors, result.Errors) { t.Fatalf("unexpected result, Diff: %v", testutil.Diff(expectedErrors, result.Errors)) } }
func TestDoesNotIncludeIllegalFieldsInOutput(t *testing.T) { doc := `mutation M { thisIsIllegalDontIncludeMe }` expected := &graphql.Result{ Data: map[string]interface{}{}, } schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: graphql.NewObject(graphql.ObjectConfig{ Name: "Q", Fields: graphql.Fields{ "a": &graphql.Field{ Type: graphql.String, }, }, }), Mutation: graphql.NewObject(graphql.ObjectConfig{ Name: "M", Fields: graphql.Fields{ "c": &graphql.Field{ Type: graphql.String, }, }, }), }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: schema, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) != 0 { t.Fatalf("wrong result, expected len(%v) errors, got len(%v)", len(expected.Errors), len(result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestFailsToExecuteQueryContainingATypeDefinition(t *testing.T) { query := ` { foo } type Query { foo: String } ` expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: "GraphQL cannot execute a request containing a ObjectDefinition", Locations: []location.SourceLocation{}, }, }, } schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: graphql.NewObject(graphql.ObjectConfig{ Name: "Query", Fields: graphql.Fields{ "foo": &graphql.Field{ Type: graphql.String, }, }, }), }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } // parse query ast := testutil.TestParse(t, query) // execute ep := graphql.ExecuteParams{ Schema: schema, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) != 1 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func checkList(t *testing.T, testType graphql.Type, testData interface{}, expected *graphql.Result) { data := map[string]interface{}{ "test": testData, } dataType := graphql.NewObject(graphql.ObjectConfig{ Name: "DataType", Fields: graphql.Fields{ "test": &graphql.Field{ Type: testType, }, }, }) dataType.AddFieldConfig("nest", &graphql.Field{ Type: dataType, Resolve: func(p graphql.ResolveParams) interface{} { return data }, }) schema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: dataType, }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } // parse query ast := testutil.TestParse(t, `{ nest { test } }`) // execute ep := graphql.ExecuteParams{ Schema: schema, AST: ast, Root: data, } result := testutil.TestExecute(t, ep) if len(expected.Errors) != len(result.Errors) { t.Fatalf("wrong result, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestNonNull_NullsAnObjectReturnedInAPromiseThatContainsANonNullableFieldThatThrowsInAPromise(t *testing.T) { doc := ` query Q { promiseNest { nonNullPromise, } } ` expected := &graphql.Result{ Data: map[string]interface{}{ "promiseNest": nil, }, Errors: []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: nonNullPromiseError, Locations: []location.SourceLocation{ location.SourceLocation{ Line: 4, Column: 11, }, }, }, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: nonNullTestSchema, AST: ast, Root: throwingData, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_NonNullableScalars_DoesNotAllowNonNullableInputsToBeSetToNullInAVariable(t *testing.T) { doc := ` query SetsNonNullable($value: String!) { fieldWithNonNullableStringInput(input: $value) } ` params := map[string]interface{}{ "value": nil, } expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: `Variable "$value" of required type "String!" was not provided.`, Locations: []location.SourceLocation{ location.SourceLocation{ Line: 2, Column: 31, }, }, }, }, } ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, Args: params, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_ListsAndNullability_DoesNotAllowInvalidTypesToBeUsedAsValues(t *testing.T) { doc := ` query q($input: TestType!) { fieldWithObjectInput(input: $input) } ` params := map[string]interface{}{ "input": map[string]interface{}{ "list": []interface{}{"A", "B"}, }, } expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: `Variable "$input" expected value of type "TestType!" which cannot be used as an input type.`, Locations: []location.SourceLocation{ location.SourceLocation{ Line: 2, Column: 17, }, }, }, }, } ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, Args: params, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestVariables_ListsAndNullability_DoesNotAllowNonNullListOfNonNullsToContainNull(t *testing.T) { doc := ` query q($input: [String!]!) { nnListNN(input: $input) } ` params := map[string]interface{}{ "input": []interface{}{"A", nil, "B"}, } expected := &graphql.Result{ Data: nil, Errors: []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: `Variable "$input" expected value of type "[String!]!" but got: ` + `["A",null,"B"].`, Locations: []location.SourceLocation{ location.SourceLocation{ Line: 2, Column: 17, }, }, }, }, } ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: variablesTestSchema, AST: ast, Args: params, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
// nulls a nullable field that panics func TestNonNull_NullsANullableFieldThatThrowsSynchronously(t *testing.T) { doc := ` query Q { sync } ` expected := &graphql.Result{ Data: map[string]interface{}{ "sync": nil, }, Errors: []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: syncError, Locations: []location.SourceLocation{ location.SourceLocation{ Line: 3, Column: 9, }, }, }, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: nonNullTestSchema, AST: ast, Root: throwingData, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestNonNull_NullsASynchronouslyReturnedObjectThatContainsANonNullableFieldThatReturnsNullInAPromise(t *testing.T) { doc := ` query Q { nest { nonNullPromise, } } ` expected := &graphql.Result{ Data: map[string]interface{}{ "nest": nil, }, Errors: []gqlerrors.FormattedError{ gqlerrors.FormattedError{ Message: `Cannot return null for non-nullable field DataType.nonNullPromise.`, Locations: []location.SourceLocation{ location.SourceLocation{Line: 4, Column: 11}, }, }, }, } // parse query ast := testutil.TestParse(t, doc) // execute ep := graphql.ExecuteParams{ Schema: nonNullTestSchema, AST: ast, Root: nullingData, } result := testutil.TestExecute(t, ep) if len(result.Errors) != len(expected.Errors) { t.Fatalf("Unexpected errors, Diff: %v", testutil.Diff(expected.Errors, result.Errors)) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }
func TestExecutesUsingAComplexSchema(t *testing.T) { johnSmith = &testAuthor{ Id: 123, Name: "John Smith", Pic: func(width string, height string) *testPic { return getPic(123, width, height) }, RecentArticle: article("1"), } 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, }, }, }) 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, }, }, Resolve: func(p graphql.ResolveParams) interface{} { if author, ok := p.Source.(*testAuthor); ok { width := fmt.Sprintf("%v", p.Args["width"]) height := fmt.Sprintf("%v", p.Args["height"]) return author.Pic(width, height) } return nil }, }, "recentArticle": &graphql.Field{}, }, }) blogArticle := graphql.NewObject(graphql.ObjectConfig{ Name: "Article", Fields: graphql.Fields{ "id": &graphql.Field{ Type: graphql.NewNonNull(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, }, "keywords": &graphql.Field{ Type: graphql.NewList(graphql.String), }, }, }) blogAuthor.AddFieldConfig("recentArticle", &graphql.Field{ Type: blogArticle, }) blogQuery := graphql.NewObject(graphql.ObjectConfig{ Name: "Query", Fields: graphql.Fields{ "article": &graphql.Field{ Type: blogArticle, Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{ Type: graphql.ID, }, }, Resolve: func(p graphql.ResolveParams) interface{} { id := p.Args["id"] return article(id) }, }, "feed": &graphql.Field{ Type: graphql.NewList(blogArticle), Resolve: func(p graphql.ResolveParams) interface{} { return []*testArticle{ article(1), article(2), article(3), article(4), article(5), article(6), article(7), article(8), article(9), article(10), } }, }, }, }) blogSchema, err := graphql.NewSchema(graphql.SchemaConfig{ Query: blogQuery, }) if err != nil { t.Fatalf("Error in schema %v", err.Error()) } request := ` { feed { id, title }, article(id: "1") { ...articleFields, author { id, name, pic(width: 640, height: 480) { url, width, height }, recentArticle { ...articleFields, keywords } } } } fragment articleFields on Article { id, isPublished, title, body, hidden, notdefined } ` expected := &graphql.Result{ Data: map[string]interface{}{ "article": map[string]interface{}{ "title": "My Article 1", "body": "This is a post", "author": map[string]interface{}{ "id": "123", "name": "John Smith", "pic": map[string]interface{}{ "url": "cdn://123", "width": 640, "height": 480, }, "recentArticle": map[string]interface{}{ "id": "1", "isPublished": bool(true), "title": "My Article 1", "body": "This is a post", "keywords": []interface{}{ "foo", "bar", "1", "true", nil, }, }, }, "id": "1", "isPublished": bool(true), }, "feed": []interface{}{ map[string]interface{}{ "id": "1", "title": "My Article 1", }, map[string]interface{}{ "id": "2", "title": "My Article 2", }, map[string]interface{}{ "id": "3", "title": "My Article 3", }, map[string]interface{}{ "id": "4", "title": "My Article 4", }, map[string]interface{}{ "id": "5", "title": "My Article 5", }, map[string]interface{}{ "id": "6", "title": "My Article 6", }, map[string]interface{}{ "id": "7", "title": "My Article 7", }, map[string]interface{}{ "id": "8", "title": "My Article 8", }, map[string]interface{}{ "id": "9", "title": "My Article 9", }, map[string]interface{}{ "id": "10", "title": "My Article 10", }, }, }, } // parse query ast := testutil.TestParse(t, request) // execute ep := graphql.ExecuteParams{ Schema: blogSchema, AST: ast, } result := testutil.TestExecute(t, ep) if len(result.Errors) > 0 { t.Fatalf("wrong result, unexpected errors: %v", result.Errors) } if !reflect.DeepEqual(expected, result) { t.Fatalf("Unexpected result, Diff: %v", testutil.Diff(expected, result)) } }