diff --git a/definition.go b/definition.go index 1738f67d..934c2d01 100644 --- a/definition.go +++ b/definition.go @@ -1262,8 +1262,7 @@ func (gl *List) Error() error { // // Note: the enforcement of non-nullability occurs within the executor. type NonNull struct { - PrivateName string `json:"name"` // added to conform with introspection for NonNull.Name = nil - OfType Type `json:"ofType"` + OfType Type `json:"ofType"` err error } diff --git a/executor_resolve_test.go b/executor_resolve_test.go index 1617e0d0..7430cd86 100644 --- a/executor_resolve_test.go +++ b/executor_resolve_test.go @@ -147,7 +147,7 @@ func TestExecutesResolveFunction_UsesProvidedResolveFunction_SourceIsStruct_With expected := map[string]interface{}{ "test": map[string]interface{}{ - "Str": nil, + "Str": "", "Int": 0, }, } @@ -223,7 +223,7 @@ func TestExecutesResolveFunction_UsesProvidedResolveFunction_SourceIsStruct_With expected := map[string]interface{}{ "test": map[string]interface{}{ - "str": nil, + "str": "", "int": 0, }, } diff --git a/executor_test.go b/executor_test.go index ebf1933f..2c898f88 100644 --- a/executor_test.go +++ b/executor_test.go @@ -85,7 +85,7 @@ func TestExecutesArbitraryCode(t *testing.T) { "b": "Boring", "c": []interface{}{ "Contrived", - nil, + "", "Confusing", }, "deeper": []interface{}{ diff --git a/graphql_test.go b/graphql_test.go index ee736f58..4b24c5f7 100644 --- a/graphql_test.go +++ b/graphql_test.go @@ -198,3 +198,51 @@ func TestNewErrorChecksNilNodes(t *testing.T) { t.Fatalf("expected errors, got: %v", result) } } + +func TestEmptyStringIsNotNull(t *testing.T) { + checkForEmptyString := func(p graphql.ResolveParams) (interface{}, error) { + arg := p.Args["arg"] + if arg == nil || arg.(string) != "" { + t.Errorf("Expected empty string for input arg, got %#v", arg) + } + return "yay", nil + } + returnEmptyString := func(p graphql.ResolveParams) (interface{}, error) { + return "", nil + } + + schema, err := graphql.NewSchema(graphql.SchemaConfig{ + Query: graphql.NewObject(graphql.ObjectConfig{ + Name: "Query", + Fields: graphql.Fields{ + "checkEmptyArg": &graphql.Field{ + Type: graphql.String, + Args: graphql.FieldConfigArgument{ + "arg": &graphql.ArgumentConfig{Type: graphql.String}, + }, + Resolve: checkForEmptyString, + }, + "checkEmptyResult": &graphql.Field{ + Type: graphql.String, + Resolve: returnEmptyString, + }, + }, + }), + }) + if err != nil { + t.Fatalf("wrong result, unexpected errors: %v", err.Error()) + } + query := `{ checkEmptyArg(arg:"") checkEmptyResult }` + + result := graphql.Do(graphql.Params{ + Schema: schema, + RequestString: query, + }) + if len(result.Errors) > 0 { + t.Fatalf("wrong result, unexpected errors: %v", result.Errors) + } + expected := map[string]interface{}{"checkEmptyArg": "yay", "checkEmptyResult": ""} + if !reflect.DeepEqual(result.Data, expected) { + t.Errorf("wrong result, query: %v, graphql result diff: %v", query, testutil.Diff(expected, result)) + } +} diff --git a/introspection_test.go b/introspection_test.go index 3b4f2a46..64158859 100644 --- a/introspection_test.go +++ b/introspection_test.go @@ -68,7 +68,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "queryType", @@ -82,7 +82,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "mutationType", @@ -92,7 +92,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "name": "__Type", }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "subscriptionType", @@ -102,7 +102,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "name": "__Type", }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "directives", @@ -124,7 +124,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -149,7 +149,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "name", @@ -160,7 +160,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -171,7 +171,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "fields", @@ -200,7 +200,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "interfaces", @@ -219,7 +219,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "possibleTypes", @@ -238,7 +238,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "enumValues", @@ -267,7 +267,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "inputFields", @@ -286,7 +286,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "ofType", @@ -297,7 +297,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -315,42 +315,42 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { map[string]interface{}{ "name": "SCALAR", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "OBJECT", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "INTERFACE", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "UNION", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "ENUM", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "INPUT_OBJECT", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "LIST", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "NON_NULL", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "possibleTypes": nil, @@ -390,7 +390,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -401,7 +401,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "args", @@ -423,7 +423,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "type", @@ -438,7 +438,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "isDeprecated", @@ -453,7 +453,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "deprecationReason", @@ -464,7 +464,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -489,7 +489,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -500,7 +500,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "type", @@ -515,7 +515,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "defaultValue", @@ -526,7 +526,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -551,7 +551,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -562,7 +562,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "isDeprecated", @@ -577,7 +577,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "deprecationReason", @@ -588,7 +588,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -613,7 +613,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -624,7 +624,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "locations", @@ -646,7 +646,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "args", @@ -668,7 +668,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "onOperation", @@ -731,37 +731,37 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { map[string]interface{}{ "name": "QUERY", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "MUTATION", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "SUBSCRIPTION", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "FIELD", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "FRAGMENT_DEFINITION", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "FRAGMENT_SPREAD", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "INLINE_FRAGMENT", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "possibleTypes": nil, @@ -1024,7 +1024,7 @@ func TestIntrospection_IdentifiesDeprecatedFields(t *testing.T) { map[string]interface{}{ "name": "nonDeprecated", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "deprecated", @@ -1163,7 +1163,7 @@ func TestIntrospection_IdentifiesDeprecatedEnumValues(t *testing.T) { map[string]interface{}{ "name": "NONDEPRECATED", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "DEPRECATED", @@ -1173,7 +1173,7 @@ func TestIntrospection_IdentifiesDeprecatedEnumValues(t *testing.T) { map[string]interface{}{ "name": "ALSONONDEPRECATED", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, }, diff --git a/values.go b/values.go index b5ae1975..c01c9735 100644 --- a/values.go +++ b/values.go @@ -317,9 +317,6 @@ func isValidInputValue(value interface{}, ttype Input) (bool, []string) { // Returns true if a value is null, undefined, or NaN. func isNullish(value interface{}) bool { - if value, ok := value.(string); ok { - return value == "" - } if value, ok := value.(*string); ok { if value == nil { return true