diff --git a/definition.go b/definition.go index b5f0048b..ef6ef949 100644 --- a/definition.go +++ b/definition.go @@ -656,6 +656,13 @@ func (st *Argument) Error() error { return nil } +// IsRequired returns if an argument is required, +// i.e. cannot be omitted. +func (st *Argument) IsRequired() bool { + _, isOfTypeNonNull := st.Type.(*NonNull) + return isOfTypeNonNull && st.DefaultValue == nil +} + // Interface Type Definition // // When a field can return one of a heterogeneous set of types, a Interface type diff --git a/rules.go b/rules.go index ae0c75b9..e6ca8f14 100644 --- a/rules.go +++ b/rules.go @@ -1271,7 +1271,7 @@ func ProvidedNonNullArgumentsRule(context *ValidationContext) *ValidationRuleIns for _, argDef := range fieldDef.Args { argAST, _ := argASTMap[argDef.Name()] if argAST == nil { - if argDefType, ok := argDef.Type.(*NonNull); ok { + if argDef.IsRequired() { fieldName := "" if fieldAST.Name != nil { fieldName = fieldAST.Name.Value @@ -1279,7 +1279,7 @@ func ProvidedNonNullArgumentsRule(context *ValidationContext) *ValidationRuleIns reportError( context, fmt.Sprintf(`Field "%v" argument "%v" of type "%v" `+ - `is required but not provided.`, fieldName, argDef.Name(), argDefType), + `is required but not provided.`, fieldName, argDef.Name(), argDef.Type), []ast.Node{fieldAST}, ) } @@ -1312,7 +1312,7 @@ func ProvidedNonNullArgumentsRule(context *ValidationContext) *ValidationRuleIns for _, argDef := range directiveDef.Args { argAST, _ := argASTMap[argDef.Name()] if argAST == nil { - if argDefType, ok := argDef.Type.(*NonNull); ok { + if argDef.IsRequired() { directiveName := "" if directiveAST.Name != nil { directiveName = directiveAST.Name.Value @@ -1320,7 +1320,7 @@ func ProvidedNonNullArgumentsRule(context *ValidationContext) *ValidationRuleIns reportError( context, fmt.Sprintf(`Directive "@%v" argument "%v" of type `+ - `"%v" is required but not provided.`, directiveName, argDef.Name(), argDefType), + `"%v" is required but not provided.`, directiveName, argDef.Name(), argDef.Type), []ast.Node{directiveAST}, ) } diff --git a/rules_provided_non_null_arguments_test.go b/rules_provided_non_null_arguments_test.go index fed6c008..c70d4099 100644 --- a/rules_provided_non_null_arguments_test.go +++ b/rules_provided_non_null_arguments_test.go @@ -36,6 +36,24 @@ func TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_NoArgOnOptional } `) } +func TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_WithDefault(t *testing.T) { + testutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, ` + { + complicatedArgs { + nonNullFieldWithDefault + } + } + `) +} +func TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_WithDefaultAndValue(t *testing.T) { + testutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, ` + { + complicatedArgs { + nonNullFieldWithDefault(arg:1) + } + } + `) +} func TestValidate_ProvidedNonNullArguments_ValidNonNullableValue_MultipleArgs(t *testing.T) { testutil.ExpectPassesRule(t, graphql.ProvidedNonNullArgumentsRule, ` { diff --git a/testutil/rules_test_harness.go b/testutil/rules_test_harness.go index 384f447e..e042d3eb 100644 --- a/testutil/rules_test_harness.go +++ b/testutil/rules_test_harness.go @@ -383,6 +383,15 @@ func init() { }, }, }, + "nonNullFieldWithDefault": &graphql.Field{ + Type: graphql.String, + Args: graphql.FieldConfigArgument{ + "arg": &graphql.ArgumentConfig{ + Type: graphql.NewNonNull(graphql.Int), + DefaultValue: 0, + }, + }, + }, "multipleOpts": &graphql.Field{ Type: graphql.String, Args: graphql.FieldConfigArgument{