From f6c52666a789164d9efcc22473a5911c56c34b00 Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Sat, 9 Feb 2019 14:15:58 +1100 Subject: [PATCH] Add a test for aliasing different cases fixes #376 --- codegen/testserver/generated.go | 696 ++++++++++++++++---------- codegen/testserver/gqlgen.yml | 10 +- codegen/testserver/models-gen.go | 36 +- codegen/testserver/resolver.go | 5 +- codegen/testserver/schema.graphql | 61 --- codegen/testserver/stub.go | 10 +- codegen/testserver/validtypes.graphql | 68 +++ codegen/testserver/validtypes_test.go | 38 ++ 8 files changed, 563 insertions(+), 361 deletions(-) create mode 100644 codegen/testserver/validtypes.graphql create mode 100644 codegen/testserver/validtypes_test.go diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 3f1a3af81f9..4a79db8c945 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -102,7 +102,6 @@ type ComplexityRoot struct { Recursive func(childComplexity int, input *RecursiveInputSlice) int NestedInputs func(childComplexity int, input [][]*OuterInput) int NestedOutputs func(childComplexity int) int - Keywords func(childComplexity int, input *Keywords) int Shapes func(childComplexity int) int ErrorBubble func(childComplexity int) int ModelMethods func(childComplexity int) int @@ -115,7 +114,7 @@ type ComplexityRoot struct { DirectiveInput func(childComplexity int, arg InputDirectives) int InputSlice func(childComplexity int, arg []string) int ShapeUnion func(childComplexity int) int - KeywordArgs func(childComplexity int, breakArg string, defaultArg string, funcArg string, interfaceArg string, selectArg string, caseArg string, deferArg string, goArg string, mapArg string, structArg string, chanArg string, elseArg string, gotoArg string, packageArg string, switchArg string, constArg string, fallthroughArg string, ifArg string, rangeArg string, typeArg string, continueArg string, forArg string, importArg string, returnArg string, varArg string, _Arg string) int + ValidType func(childComplexity int) int } Rectangle struct { @@ -135,6 +134,13 @@ type ComplexityRoot struct { Created func(childComplexity int) int Updated func(childComplexity int) int } + + ValidType struct { + DifferentCase func(childComplexity int) int + DifferentCaseOld func(childComplexity int) int + ValidInputKeywords func(childComplexity int, input *ValidInput) int + ValidArgs func(childComplexity int, breakArg string, defaultArg string, funcArg string, interfaceArg string, selectArg string, caseArg string, deferArg string, goArg string, mapArg string, structArg string, chanArg string, elseArg string, gotoArg string, packageArg string, switchArg string, constArg string, fallthroughArg string, ifArg string, rangeArg string, typeArg string, continueArg string, forArg string, importArg string, returnArg string, varArg string, _Arg string) int + } } type ForcedResolverResolver interface { @@ -150,7 +156,6 @@ type QueryResolver interface { Recursive(ctx context.Context, input *RecursiveInputSlice) (*bool, error) NestedInputs(ctx context.Context, input [][]*OuterInput) (*bool, error) NestedOutputs(ctx context.Context) ([][]*OuterObject, error) - Keywords(ctx context.Context, input *Keywords) (bool, error) Shapes(ctx context.Context) ([]Shape, error) ErrorBubble(ctx context.Context) (*Error, error) ModelMethods(ctx context.Context) (*ModelMethods, error) @@ -163,7 +168,7 @@ type QueryResolver interface { DirectiveInput(ctx context.Context, arg InputDirectives) (*string, error) InputSlice(ctx context.Context, arg []string) (bool, error) ShapeUnion(ctx context.Context) (ShapeUnion, error) - KeywordArgs(ctx context.Context, breakArg string, defaultArg string, funcArg string, interfaceArg string, selectArg string, caseArg string, deferArg string, goArg string, mapArg string, structArg string, chanArg string, elseArg string, gotoArg string, packageArg string, switchArg string, constArg string, fallthroughArg string, ifArg string, rangeArg string, typeArg string, continueArg string, forArg string, importArg string, returnArg string, varArg string, _Arg string) (bool, error) + ValidType(ctx context.Context) (*ValidType, error) } type SubscriptionResolver interface { Updated(ctx context.Context) (<-chan string, error) @@ -357,18 +362,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.NestedOutputs(childComplexity), true - case "Query.Keywords": - if e.complexity.Query.Keywords == nil { - break - } - - args, err := ec.field_Query_keywords_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.Keywords(childComplexity, args["input"].(*Keywords)), true - case "Query.Shapes": if e.complexity.Query.Shapes == nil { break @@ -488,17 +481,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.ShapeUnion(childComplexity), true - case "Query.KeywordArgs": - if e.complexity.Query.KeywordArgs == nil { + case "Query.ValidType": + if e.complexity.Query.ValidType == nil { break } - args, err := ec.field_Query_keywordArgs_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.KeywordArgs(childComplexity, args["break"].(string), args["default"].(string), args["func"].(string), args["interface"].(string), args["select"].(string), args["case"].(string), args["defer"].(string), args["go"].(string), args["map"].(string), args["struct"].(string), args["chan"].(string), args["else"].(string), args["goto"].(string), args["package"].(string), args["switch"].(string), args["const"].(string), args["fallthrough"].(string), args["if"].(string), args["range"].(string), args["type"].(string), args["continue"].(string), args["for"].(string), args["import"].(string), args["return"].(string), args["var"].(string), args["_"].(string)), true + return e.complexity.Query.ValidType(childComplexity), true case "Rectangle.Length": if e.complexity.Rectangle.Length == nil { @@ -563,6 +551,44 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.User.Updated(childComplexity), true + case "ValidType.DifferentCase": + if e.complexity.ValidType.DifferentCase == nil { + break + } + + return e.complexity.ValidType.DifferentCase(childComplexity), true + + case "ValidType.DifferentCaseOld": + if e.complexity.ValidType.DifferentCaseOld == nil { + break + } + + return e.complexity.ValidType.DifferentCaseOld(childComplexity), true + + case "ValidType.ValidInputKeywords": + if e.complexity.ValidType.ValidInputKeywords == nil { + break + } + + args, err := ec.field_ValidType_validInputKeywords_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.ValidType.ValidInputKeywords(childComplexity, args["input"].(*ValidInput)), true + + case "ValidType.ValidArgs": + if e.complexity.ValidType.ValidArgs == nil { + break + } + + args, err := ec.field_ValidType_validArgs_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.ValidType.ValidArgs(childComplexity, args["break"].(string), args["default"].(string), args["func"].(string), args["interface"].(string), args["select"].(string), args["case"].(string), args["defer"].(string), args["go"].(string), args["map"].(string), args["struct"].(string), args["chan"].(string), args["else"].(string), args["goto"].(string), args["package"].(string), args["switch"].(string), args["const"].(string), args["fallthrough"].(string), args["if"].(string), args["range"].(string), args["type"].(string), args["continue"].(string), args["for"].(string), args["import"].(string), args["return"].(string), args["var"].(string), args["_"].(string)), true + } return 0, false } @@ -694,7 +720,6 @@ var parsedSchema = gqlparser.MustLoadSchema( recursive(input: RecursiveInputSlice): Boolean nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean nestedOutputs: [[OuterObject]] - keywords(input: Keywords): Boolean! shapes: [Shape] errorBubble: Error modelMethods: ModelMethods @@ -780,37 +805,49 @@ type InnerObject { id: Int! } -input Keywords { - break: String! - default: String! - func: String! - interface: String! - select: String! - case: String! - defer: String! - go: String! - map: String! - struct: String! - chan: String! - else: String! - goto: String! - package: String! - switch: String! - const: String! - fallthrough: String! - if: String! - range: String! - type: String! - continue: String! - for: String! - import: String! - return: String! - var: String! - _: String! +interface Shape { + area: Float +} +type Circle implements Shape { + radius: Float + area: Float +} +type Rectangle implements Shape { + length: Float + width: Float + area: Float +} +union ShapeUnion = Circle | Rectangle + +type ForcedResolver { + field: Circle } -extend type Query { - keywordArgs( +type EmbeddedPointer { + ID: String + Title: String +} + +directive @length(min: Int!, max: Int) on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION +directive @range(min: Int = 0, max: Int) on ARGUMENT_DEFINITION + +enum Status { + OK + ERROR +} + +scalar Time +`}, + &ast.Source{Name: "validtypes.graphql", Input: `extend type Query { + validType: ValidType +} + +""" These things are all valid, but without care generate invalid go code """ +type ValidType { + differentCase: String! + different_case: String! + validInputKeywords(input: ValidInput): Boolean! + validArgs( break: String!, default: String!, func: String!, @@ -840,38 +877,35 @@ extend type Query { ): Boolean! } -interface Shape { - area: Float -} -type Circle implements Shape { - radius: Float - area: Float -} -type Rectangle implements Shape { - length: Float - width: Float - area: Float -} -union ShapeUnion = Circle | Rectangle - -type ForcedResolver { - field: Circle -} - -type EmbeddedPointer { - ID: String - Title: String -} - -directive @length(min: Int!, max: Int) on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION -directive @range(min: Int = 0, max: Int) on ARGUMENT_DEFINITION - -enum Status { - OK - ERROR +input ValidInput { + break: String! + default: String! + func: String! + interface: String! + select: String! + case: String! + defer: String! + go: String! + map: String! + struct: String! + chan: String! + else: String! + goto: String! + package: String! + switch: String! + const: String! + fallthrough: String! + if: String! + range: String! + type: String! + continue: String! + for: String! + import: String! + return: String! + var: String! + _: String! } -scalar Time `}, ) @@ -1051,7 +1085,77 @@ func (ec *executionContext) field_Query_inputSlice_args(ctx context.Context, raw return args, nil } -func (ec *executionContext) field_Query_keywordArgs_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { +func (ec *executionContext) field_Query_mapInput_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 map[string]interface{} + if tmp, ok := rawArgs["input"]; ok { + arg0, err = ec.unmarshalOChanges2map(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_nestedInputs_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 [][]*OuterInput + if tmp, ok := rawArgs["input"]; ok { + arg0, err = ec.unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_nullableArg_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *int + if tmp, ok := rawArgs["arg"]; ok { + arg0, err = ec.unmarshalOInt2ᚖint(ctx, tmp) + if err != nil { + return nil, err + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_recursive_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *RecursiveInputSlice + if tmp, ok := rawArgs["input"]; ok { + arg0, err = ec.unmarshalORecursiveInputSlice2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_user_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 int + if tmp, ok := rawArgs["id"]; ok { + arg0, err = ec.unmarshalNInt2int(ctx, tmp) + if err != nil { + return nil, err + } + } + args["id"] = arg0 + return args, nil +} + +func (ec *executionContext) field_ValidType_validArgs_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} var arg0 string @@ -1265,40 +1369,12 @@ func (ec *executionContext) field_Query_keywordArgs_args(ctx context.Context, ra return args, nil } -func (ec *executionContext) field_Query_keywords_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *Keywords - if tmp, ok := rawArgs["input"]; ok { - arg0, err = ec.unmarshalOKeywords2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐKeywords(ctx, tmp) - if err != nil { - return nil, err - } - } - args["input"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_mapInput_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 map[string]interface{} - if tmp, ok := rawArgs["input"]; ok { - arg0, err = ec.unmarshalOChanges2map(ctx, tmp) - if err != nil { - return nil, err - } - } - args["input"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_nestedInputs_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { +func (ec *executionContext) field_ValidType_validInputKeywords_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} - var arg0 [][]*OuterInput + var arg0 *ValidInput if tmp, ok := rawArgs["input"]; ok { - arg0, err = ec.unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterInput(ctx, tmp) + arg0, err = ec.unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidInput(ctx, tmp) if err != nil { return nil, err } @@ -1307,48 +1383,6 @@ func (ec *executionContext) field_Query_nestedInputs_args(ctx context.Context, r return args, nil } -func (ec *executionContext) field_Query_nullableArg_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *int - if tmp, ok := rawArgs["arg"]; ok { - arg0, err = ec.unmarshalOInt2ᚖint(ctx, tmp) - if err != nil { - return nil, err - } - } - args["arg"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_recursive_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *RecursiveInputSlice - if tmp, ok := rawArgs["input"]; ok { - arg0, err = ec.unmarshalORecursiveInputSlice2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx, tmp) - if err != nil { - return nil, err - } - } - args["input"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_user_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 int - if tmp, ok := rawArgs["id"]; ok { - arg0, err = ec.unmarshalNInt2int(ctx, tmp) - if err != nil { - return nil, err - } - } - args["id"] = arg0 - return args, nil -} - func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1928,47 +1962,14 @@ func (ec *executionContext) _Query_nestedOutputs(ctx context.Context, field grap resTmp := ec.FieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children return ec.resolvers.Query().NestedOutputs(rctx) - }) - if resTmp == nil { - return graphql.Null - } - res := resTmp.([][]*OuterObject) - rctx.Result = res - ctx = ec.Tracer.StartFieldChildExecution(ctx) - return ec.marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterObject(ctx, field.Selections, res) -} - -func (ec *executionContext) _Query_keywords(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { - ctx = ec.Tracer.StartFieldExecution(ctx, field) - defer func() { ec.Tracer.EndFieldExecution(ctx) }() - rctx := &graphql.ResolverContext{ - Object: "Query", - Field: field, - Args: nil, - } - ctx = graphql.WithResolverContext(ctx, rctx) - rawArgs := field.ArgumentMap(ec.Variables) - args, err := ec.field_Query_keywords_args(ctx, rawArgs) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - rctx.Args = args - ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) - resTmp := ec.FieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().Keywords(rctx, args["input"].(*Keywords)) - }) - if resTmp == nil { - if !ec.HasError(rctx) { - ec.Errorf(ctx, "must not be null") - } + }) + if resTmp == nil { return graphql.Null } - res := resTmp.(bool) + res := resTmp.([][]*OuterObject) rctx.Result = res ctx = ec.Tracer.StartFieldChildExecution(ctx) - return ec.marshalNBoolean2bool(ctx, field.Selections, res) + return ec.marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterObject(ctx, field.Selections, res) } func (ec *executionContext) _Query_shapes(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { @@ -2308,7 +2309,7 @@ func (ec *executionContext) _Query_shapeUnion(ctx context.Context, field graphql return ec.marshalNShapeUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShapeUnion(ctx, field.Selections, res) } -func (ec *executionContext) _Query_keywordArgs(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { +func (ec *executionContext) _Query_validType(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { ctx = ec.Tracer.StartFieldExecution(ctx, field) defer func() { ec.Tracer.EndFieldExecution(ctx) }() rctx := &graphql.ResolverContext{ @@ -2317,28 +2318,18 @@ func (ec *executionContext) _Query_keywordArgs(ctx context.Context, field graphq Args: nil, } ctx = graphql.WithResolverContext(ctx, rctx) - rawArgs := field.ArgumentMap(ec.Variables) - args, err := ec.field_Query_keywordArgs_args(ctx, rawArgs) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - rctx.Args = args ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) resTmp := ec.FieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().KeywordArgs(rctx, args["break"].(string), args["default"].(string), args["func"].(string), args["interface"].(string), args["select"].(string), args["case"].(string), args["defer"].(string), args["go"].(string), args["map"].(string), args["struct"].(string), args["chan"].(string), args["else"].(string), args["goto"].(string), args["package"].(string), args["switch"].(string), args["const"].(string), args["fallthrough"].(string), args["if"].(string), args["range"].(string), args["type"].(string), args["continue"].(string), args["for"].(string), args["import"].(string), args["return"].(string), args["var"].(string), args["_"].(string)) + return ec.resolvers.Query().ValidType(rctx) }) if resTmp == nil { - if !ec.HasError(rctx) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(bool) + res := resTmp.(*ValidType) rctx.Result = res ctx = ec.Tracer.StartFieldChildExecution(ctx) - return ec.marshalNBoolean2bool(ctx, field.Selections, res) + return ec.marshalOValidType2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidType(ctx, field.Selections, res) } func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { @@ -2620,6 +2611,124 @@ func (ec *executionContext) _User_updated(ctx context.Context, field graphql.Col return ec.marshalOTime2ᚖtimeᚐTime(ctx, field.Selections, res) } +func (ec *executionContext) _ValidType_differentCase(ctx context.Context, field graphql.CollectedField, obj *ValidType) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { ec.Tracer.EndFieldExecution(ctx) }() + rctx := &graphql.ResolverContext{ + Object: "ValidType", + Field: field, + Args: nil, + } + ctx = graphql.WithResolverContext(ctx, rctx) + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DifferentCase, nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ValidType_different_case(ctx context.Context, field graphql.CollectedField, obj *ValidType) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { ec.Tracer.EndFieldExecution(ctx) }() + rctx := &graphql.ResolverContext{ + Object: "ValidType", + Field: field, + Args: nil, + } + ctx = graphql.WithResolverContext(ctx, rctx) + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DifferentCaseOld, nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ValidType_validInputKeywords(ctx context.Context, field graphql.CollectedField, obj *ValidType) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { ec.Tracer.EndFieldExecution(ctx) }() + rctx := &graphql.ResolverContext{ + Object: "ValidType", + Field: field, + Args: nil, + } + ctx = graphql.WithResolverContext(ctx, rctx) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_ValidType_validInputKeywords_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + rctx.Args = args + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ValidInputKeywords, nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) _ValidType_validArgs(ctx context.Context, field graphql.CollectedField, obj *ValidType) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { ec.Tracer.EndFieldExecution(ctx) }() + rctx := &graphql.ResolverContext{ + Object: "ValidType", + Field: field, + Args: nil, + } + ctx = graphql.WithResolverContext(ctx, rctx) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_ValidType_validArgs_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + rctx.Args = args + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ValidArgs, nil + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler { ctx = ec.Tracer.StartFieldExecution(ctx, field) defer func() { ec.Tracer.EndFieldExecution(ctx) }() @@ -3528,8 +3637,44 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, v return it, nil } -func (ec *executionContext) unmarshalInputKeywords(ctx context.Context, v interface{}) (Keywords, error) { - var it Keywords +func (ec *executionContext) unmarshalInputOuterInput(ctx context.Context, v interface{}) (OuterInput, error) { + var it OuterInput + var asMap = v.(map[string]interface{}) + + for k, v := range asMap { + switch k { + case "inner": + var err error + it.Inner, err = ec.unmarshalNInnerInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerInput(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputRecursiveInputSlice(ctx context.Context, v interface{}) (RecursiveInputSlice, error) { + var it RecursiveInputSlice + var asMap = v.(map[string]interface{}) + + for k, v := range asMap { + switch k { + case "self": + var err error + it.Self, err = ec.unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputValidInput(ctx context.Context, v interface{}) (ValidInput, error) { + var it ValidInput var asMap = v.(map[string]interface{}) for k, v := range asMap { @@ -3696,42 +3841,6 @@ func (ec *executionContext) unmarshalInputKeywords(ctx context.Context, v interf return it, nil } -func (ec *executionContext) unmarshalInputOuterInput(ctx context.Context, v interface{}) (OuterInput, error) { - var it OuterInput - var asMap = v.(map[string]interface{}) - - for k, v := range asMap { - switch k { - case "inner": - var err error - it.Inner, err = ec.unmarshalNInnerInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerInput(ctx, v) - if err != nil { - return it, err - } - } - } - - return it, nil -} - -func (ec *executionContext) unmarshalInputRecursiveInputSlice(ctx context.Context, v interface{}) (RecursiveInputSlice, error) { - var it RecursiveInputSlice - var asMap = v.(map[string]interface{}) - - for k, v := range asMap { - switch k { - case "self": - var err error - it.Self, err = ec.unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx, v) - if err != nil { - return it, err - } - } - } - - return it, nil -} - // endregion **************************** input.gotpl ***************************** // region ************************** interface.gotpl *************************** @@ -4089,15 +4198,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_nestedOutputs(ctx, field) return res }) - case "keywords": - field := field - out.Concurrently(i, func() (res graphql.Marshaler) { - res = ec._Query_keywords(ctx, field) - if res == graphql.Null { - invalid = true - } - return res - }) case "shapes": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -4182,13 +4282,10 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } return res }) - case "keywordArgs": + case "validType": field := field out.Concurrently(i, func() (res graphql.Marshaler) { - res = ec._Query_keywordArgs(ctx, field) - if res == graphql.Null { - invalid = true - } + res = ec._Query_validType(ctx, field) return res }) case "__type": @@ -4299,6 +4396,48 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj return out } +var validTypeImplementors = []string{"ValidType"} + +func (ec *executionContext) _ValidType(ctx context.Context, sel ast.SelectionSet, obj *ValidType) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, validTypeImplementors) + + out := graphql.NewFieldSet(fields) + invalid := false + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ValidType") + case "differentCase": + out.Values[i] = ec._ValidType_differentCase(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "different_case": + out.Values[i] = ec._ValidType_different_case(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "validInputKeywords": + out.Values[i] = ec._ValidType_validInputKeywords(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + case "validArgs": + out.Values[i] = ec._ValidType_validArgs(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalid = true + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalid { + return graphql.Null + } + return out +} + var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { @@ -5012,18 +5151,6 @@ func (ec *executionContext) marshalOIt2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋco return ec._It(ctx, sel, v) } -func (ec *executionContext) unmarshalOKeywords2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐKeywords(ctx context.Context, v interface{}) (Keywords, error) { - return ec.unmarshalInputKeywords(ctx, v) -} - -func (ec *executionContext) unmarshalOKeywords2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐKeywords(ctx context.Context, v interface{}) (*Keywords, error) { - if v == nil { - return nil, nil - } - res, err := ec.unmarshalOKeywords2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐKeywords(ctx, v) - return &res, err -} - func (ec *executionContext) marshalOModelMethods2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐModelMethods(ctx context.Context, sel ast.SelectionSet, v ModelMethods) graphql.Marshaler { return ec._ModelMethods(ctx, sel, &v) } @@ -5299,6 +5426,29 @@ func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel return ec.marshalOTime2timeᚐTime(ctx, sel, *v) } +func (ec *executionContext) unmarshalOValidInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidInput(ctx context.Context, v interface{}) (ValidInput, error) { + return ec.unmarshalInputValidInput(ctx, v) +} + +func (ec *executionContext) unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidInput(ctx context.Context, v interface{}) (*ValidInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalOValidInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidInput(ctx, v) + return &res, err +} + +func (ec *executionContext) marshalOValidType2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidType(ctx context.Context, sel ast.SelectionSet, v ValidType) graphql.Marshaler { + return ec._ValidType(ctx, sel, &v) +} + +func (ec *executionContext) marshalOValidType2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidType(ctx context.Context, sel ast.SelectionSet, v *ValidType) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._ValidType(ctx, sel, v) +} + func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup diff --git a/codegen/testserver/gqlgen.yml b/codegen/testserver/gqlgen.yml index 5cdf1bad5a8..c240e129ca9 100644 --- a/codegen/testserver/gqlgen.yml +++ b/codegen/testserver/gqlgen.yml @@ -1,4 +1,5 @@ -schema: schema.graphql +schema: + - "*.graphql" exec: filename: generated.go @@ -43,4 +44,9 @@ models: Keywords: fields: _: { fieldName: Underscore } - + ValidInput: + fields: + _: { fieldName: Underscore } + ValidType: + fields: + different_case: { fieldName: DifferentCaseOld } diff --git a/codegen/testserver/models-gen.go b/codegen/testserver/models-gen.go index 37774af1ea7..f0af1136297 100644 --- a/codegen/testserver/models-gen.go +++ b/codegen/testserver/models-gen.go @@ -28,7 +28,22 @@ type InputDirectives struct { ThirdParty *ThirdParty `json:"thirdParty"` } -type Keywords struct { +type OuterInput struct { + Inner InnerInput `json:"inner"` +} + +type OuterObject struct { + Inner InnerObject `json:"inner"` +} + +type User struct { + ID int `json:"id"` + Friends []User `json:"friends"` + Created time.Time `json:"created"` + Updated *time.Time `json:"updated"` +} + +type ValidInput struct { Break string `json:"break"` Default string `json:"default"` Func string `json:"func"` @@ -57,19 +72,12 @@ type Keywords struct { Underscore string `json:"_"` } -type OuterInput struct { - Inner InnerInput `json:"inner"` -} - -type OuterObject struct { - Inner InnerObject `json:"inner"` -} - -type User struct { - ID int `json:"id"` - Friends []User `json:"friends"` - Created time.Time `json:"created"` - Updated *time.Time `json:"updated"` +// These things are all valid, but without care generate invalid go code +type ValidType struct { + DifferentCase string `json:"differentCase"` + DifferentCaseOld string `json:"different_case"` + ValidInputKeywords bool `json:"validInputKeywords"` + ValidArgs bool `json:"validArgs"` } type Status string diff --git a/codegen/testserver/resolver.go b/codegen/testserver/resolver.go index f474d5e624d..190b6c84871 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/resolver.go @@ -59,9 +59,6 @@ func (r *queryResolver) NestedInputs(ctx context.Context, input [][]*OuterInput) func (r *queryResolver) NestedOutputs(ctx context.Context) ([][]*OuterObject, error) { panic("not implemented") } -func (r *queryResolver) Keywords(ctx context.Context, input *Keywords) (bool, error) { - panic("not implemented") -} func (r *queryResolver) Shapes(ctx context.Context) ([]Shape, error) { panic("not implemented") } @@ -98,7 +95,7 @@ func (r *queryResolver) InputSlice(ctx context.Context, arg []string) (bool, err func (r *queryResolver) ShapeUnion(ctx context.Context) (ShapeUnion, error) { panic("not implemented") } -func (r *queryResolver) KeywordArgs(ctx context.Context, breakArg string, defaultArg string, funcArg string, interfaceArg string, selectArg string, caseArg string, deferArg string, goArg string, mapArg string, structArg string, chanArg string, elseArg string, gotoArg string, packageArg string, switchArg string, constArg string, fallthroughArg string, ifArg string, rangeArg string, typeArg string, continueArg string, forArg string, importArg string, returnArg string, varArg string, _Arg string) (bool, error) { +func (r *queryResolver) ValidType(ctx context.Context) (*ValidType, error) { panic("not implemented") } diff --git a/codegen/testserver/schema.graphql b/codegen/testserver/schema.graphql index de4320ca065..c400847ad97 100644 --- a/codegen/testserver/schema.graphql +++ b/codegen/testserver/schema.graphql @@ -5,7 +5,6 @@ type Query { recursive(input: RecursiveInputSlice): Boolean nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean nestedOutputs: [[OuterObject]] - keywords(input: Keywords): Boolean! shapes: [Shape] errorBubble: Error modelMethods: ModelMethods @@ -91,66 +90,6 @@ type InnerObject { id: Int! } -input Keywords { - break: String! - default: String! - func: String! - interface: String! - select: String! - case: String! - defer: String! - go: String! - map: String! - struct: String! - chan: String! - else: String! - goto: String! - package: String! - switch: String! - const: String! - fallthrough: String! - if: String! - range: String! - type: String! - continue: String! - for: String! - import: String! - return: String! - var: String! - _: String! -} - -extend type Query { - keywordArgs( - break: String!, - default: String!, - func: String!, - interface: String!, - select: String!, - case: String!, - defer: String!, - go: String!, - map: String!, - struct: String!, - chan: String!, - else: String!, - goto: String!, - package: String!, - switch: String!, - const: String!, - fallthrough: String!, - if: String!, - range: String!, - type: String!, - continue: String!, - for: String!, - import: String!, - return: String!, - var: String!, - _: String!, - ): Boolean! -} - interface Shape { area: Float } diff --git a/codegen/testserver/stub.go b/codegen/testserver/stub.go index 7086569a523..0a80f2e6844 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/stub.go @@ -23,7 +23,6 @@ type Stub struct { Recursive func(ctx context.Context, input *RecursiveInputSlice) (*bool, error) NestedInputs func(ctx context.Context, input [][]*OuterInput) (*bool, error) NestedOutputs func(ctx context.Context) ([][]*OuterObject, error) - Keywords func(ctx context.Context, input *Keywords) (bool, error) Shapes func(ctx context.Context) ([]Shape, error) ErrorBubble func(ctx context.Context) (*Error, error) ModelMethods func(ctx context.Context) (*ModelMethods, error) @@ -36,7 +35,7 @@ type Stub struct { DirectiveInput func(ctx context.Context, arg InputDirectives) (*string, error) InputSlice func(ctx context.Context, arg []string) (bool, error) ShapeUnion func(ctx context.Context) (ShapeUnion, error) - KeywordArgs func(ctx context.Context, breakArg string, defaultArg string, funcArg string, interfaceArg string, selectArg string, caseArg string, deferArg string, goArg string, mapArg string, structArg string, chanArg string, elseArg string, gotoArg string, packageArg string, switchArg string, constArg string, fallthroughArg string, ifArg string, rangeArg string, typeArg string, continueArg string, forArg string, importArg string, returnArg string, varArg string, _Arg string) (bool, error) + ValidType func(ctx context.Context) (*ValidType, error) } SubscriptionResolver struct { Updated func(ctx context.Context) (<-chan string, error) @@ -95,9 +94,6 @@ func (r *stubQuery) NestedInputs(ctx context.Context, input [][]*OuterInput) (*b func (r *stubQuery) NestedOutputs(ctx context.Context) ([][]*OuterObject, error) { return r.QueryResolver.NestedOutputs(ctx) } -func (r *stubQuery) Keywords(ctx context.Context, input *Keywords) (bool, error) { - return r.QueryResolver.Keywords(ctx, input) -} func (r *stubQuery) Shapes(ctx context.Context) ([]Shape, error) { return r.QueryResolver.Shapes(ctx) } @@ -134,8 +130,8 @@ func (r *stubQuery) InputSlice(ctx context.Context, arg []string) (bool, error) func (r *stubQuery) ShapeUnion(ctx context.Context) (ShapeUnion, error) { return r.QueryResolver.ShapeUnion(ctx) } -func (r *stubQuery) KeywordArgs(ctx context.Context, breakArg string, defaultArg string, funcArg string, interfaceArg string, selectArg string, caseArg string, deferArg string, goArg string, mapArg string, structArg string, chanArg string, elseArg string, gotoArg string, packageArg string, switchArg string, constArg string, fallthroughArg string, ifArg string, rangeArg string, typeArg string, continueArg string, forArg string, importArg string, returnArg string, varArg string, _Arg string) (bool, error) { - return r.QueryResolver.KeywordArgs(ctx, breakArg, defaultArg, funcArg, interfaceArg, selectArg, caseArg, deferArg, goArg, mapArg, structArg, chanArg, elseArg, gotoArg, packageArg, switchArg, constArg, fallthroughArg, ifArg, rangeArg, typeArg, continueArg, forArg, importArg, returnArg, varArg, _Arg) +func (r *stubQuery) ValidType(ctx context.Context) (*ValidType, error) { + return r.QueryResolver.ValidType(ctx) } type stubSubscription struct{ *Stub } diff --git a/codegen/testserver/validtypes.graphql b/codegen/testserver/validtypes.graphql new file mode 100644 index 00000000000..f344a9f2de5 --- /dev/null +++ b/codegen/testserver/validtypes.graphql @@ -0,0 +1,68 @@ +extend type Query { + validType: ValidType +} + +""" These things are all valid, but without care generate invalid go code """ +type ValidType { + differentCase: String! + different_case: String! + validInputKeywords(input: ValidInput): Boolean! + validArgs( + break: String!, + default: String!, + func: String!, + interface: String!, + select: String!, + case: String!, + defer: String!, + go: String!, + map: String!, + struct: String!, + chan: String!, + else: String!, + goto: String!, + package: String!, + switch: String!, + const: String!, + fallthrough: String!, + if: String!, + range: String!, + type: String!, + continue: String!, + for: String!, + import: String!, + return: String!, + var: String!, + _: String!, + ): Boolean! +} + +input ValidInput { + break: String! + default: String! + func: String! + interface: String! + select: String! + case: String! + defer: String! + go: String! + map: String! + struct: String! + chan: String! + else: String! + goto: String! + package: String! + switch: String! + const: String! + fallthrough: String! + if: String! + range: String! + type: String! + continue: String! + for: String! + import: String! + return: String! + var: String! + _: String! +} + diff --git a/codegen/testserver/validtypes_test.go b/codegen/testserver/validtypes_test.go new file mode 100644 index 00000000000..7c6df2fafec --- /dev/null +++ b/codegen/testserver/validtypes_test.go @@ -0,0 +1,38 @@ +package testserver + +import ( + "context" + "net/http/httptest" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/handler" + "github.com/stretchr/testify/require" +) + +func TestValidType(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.ValidType = func(ctx context.Context) (validType *ValidType, e error) { + return &ValidType{ + DifferentCase: "new", + DifferentCaseOld: "old", + }, nil + } + + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(Config{Resolvers: resolvers}))) + c := client.New(srv.URL) + + t.Run("fields with differing cases can be distinguished", func(t *testing.T) { + var resp struct { + ValidType struct { + New string `json:"differentCase"` + Old string `json:"different_case"` + } + } + err := c.Post(`query { validType { differentCase, different_case } }`, &resp) + require.NoError(t, err) + + require.Equal(t, "new", resp.ValidType.New) + require.Equal(t, "old", resp.ValidType.Old) + }) +}