diff --git a/definition.go b/definition.go index c7aaa3be..bdaea5d3 100644 --- a/definition.go +++ b/definition.go @@ -1270,8 +1270,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_test.go b/executor_test.go index 7922d8c8..a54f6338 100644 --- a/executor_test.go +++ b/executor_test.go @@ -84,7 +84,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 d7d59105..94ae3898 100644 --- a/graphql_test.go +++ b/graphql_test.go @@ -171,3 +171,51 @@ func TestThreadsContextFromParamsThrough(t *testing.T) { } } + +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 eabcfc62..6c0c4c54 100644 --- a/introspection_test.go +++ b/introspection_test.go @@ -67,7 +67,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "queryType", @@ -81,7 +81,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "mutationType", @@ -91,7 +91,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "name": "__Type", }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "directives", @@ -113,7 +113,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -138,7 +138,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "name", @@ -149,7 +149,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -160,7 +160,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "fields", @@ -189,7 +189,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "interfaces", @@ -208,7 +208,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "possibleTypes", @@ -227,7 +227,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "enumValues", @@ -256,7 +256,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "inputFields", @@ -275,7 +275,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "ofType", @@ -286,7 +286,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -304,42 +304,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, @@ -379,7 +379,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -390,7 +390,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "args", @@ -412,7 +412,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "type", @@ -427,7 +427,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "isDeprecated", @@ -442,7 +442,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "deprecationReason", @@ -453,7 +453,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -478,7 +478,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -489,7 +489,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "type", @@ -504,7 +504,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "defaultValue", @@ -515,7 +515,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -540,7 +540,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -551,7 +551,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "isDeprecated", @@ -566,7 +566,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "deprecationReason", @@ -577,7 +577,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -602,7 +602,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "description", @@ -613,7 +613,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { "ofType": nil, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "args", @@ -635,7 +635,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "onOperation", @@ -650,7 +650,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "onFragment", @@ -665,7 +665,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "onField", @@ -680,7 +680,7 @@ func TestIntrospection_ExecutesAnIntrospectionQuery(t *testing.T) { }, }, "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, }, "inputFields": nil, @@ -934,7 +934,7 @@ func TestIntrospection_IdentifiesDeprecatedFields(t *testing.T) { map[string]interface{}{ "name": "nonDeprecated", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "deprecated", @@ -1073,7 +1073,7 @@ func TestIntrospection_IdentifiesDeprecatedEnumValues(t *testing.T) { map[string]interface{}{ "name": "NONDEPRECATED", "isDeprecated": false, - "deprecationReason": nil, + "deprecationReason": "", }, map[string]interface{}{ "name": "DEPRECATED", @@ -1083,7 +1083,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 6b3ff169..877f592b 100644 --- a/values.go +++ b/values.go @@ -274,9 +274,6 @@ func isValidInputValue(value interface{}, ttype Input) bool { // 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.(int); ok { return math.IsNaN(float64(value)) }