Skip to content

Commit

Permalink
Merge pull request #62 from graphql-dotnet/null-literals
Browse files Browse the repository at this point in the history
Null literals
  • Loading branch information
tlil authored Aug 16, 2017
2 parents 1eecb44 + 5f973fa commit f64f1b5
Show file tree
Hide file tree
Showing 12 changed files with 210 additions and 20 deletions.
155 changes: 155 additions & 0 deletions deps/graphql-dotnet/src/GraphQL.Tests/Bugs/NullArgumentTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
using GraphQL.Types;
using Shouldly;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;

namespace GraphQL.Tests.Bugs
{
public class NullArguments : QueryTestBase<NullMutationSchema>
{
[Fact]
public void Supports_partially_nullable_fields_on_arguments()
{
var query = @"
mutation {
run(input: {id:null, foo:null,bar:null})
}
";
var expected = @"{
""run"": ""idfoobar""
}";
AssertQuerySuccess(query, expected, null);
}

[Fact]
public void Supports_non_null_int()
{
var query = @"
mutation {
run(input: {id:105, foo:null,bar:{id: null, foo:""a"", bar:{id:101}}})
}
";

var result = AssertQueryWithErrors(query, null, null, expectedErrorCount: 1);

var caughtError = result.Errors.Single();
caughtError.ShouldNotBeNull();
caughtError?.InnerException.ShouldBeNull();
caughtError?.Message.Contains("In field \"bar\": In field \"id\": Expected \"Int!\", found null.");
}

[Fact]
public void Supports_non_null_string()
{
var query = @"
mutation {
run(input: {id:105, foo:null,bar:{id: 1, foo:null, bar:{id:101}}})
}
";

var result = AssertQueryWithErrors(query, null, null, expectedErrorCount: 1);

var caughtError = result.Errors.Single();
caughtError.ShouldNotBeNull();
caughtError?.InnerException.ShouldBeNull();
caughtError?.Message.Contains("In field \"foo\": Expected \"String!\", found null.");
}

[Fact]
public void Supports_non_null_object()
{
var query = @"
mutation {
run(input: {id:105, foo:null,bar:{id: 1, foo:""abc"", bar:null}})
}
";

var result = AssertQueryWithErrors(query, null, null, expectedErrorCount: 1);

var caughtError = result.Errors.Single();
caughtError.ShouldNotBeNull();
caughtError?.InnerException.ShouldBeNull();
caughtError?.Message.Contains("In field \"bar\": Expected \"NonNullSubChild!\", found null.");
}
}

public class NullMutationSchema : Schema
{
public NullMutationSchema()
{
Mutation = new NullMutation();
}
}

public class NullMutation : ObjectGraphType
{
public NullMutation()
{
Name = "MyMutation";
Field<StringGraphType>(
"run",
arguments: new QueryArguments(new QueryArgument<NullInputRoot> { Name = "input" }),
resolve: ctx =>
{
var arg = ctx.GetArgument<NullInputClass>("input");
var r= (arg.Id == null ? "id" : string.Empty) +
(arg.Foo == null ? "foo" : string.Empty) +
(arg.Bar == null ? "bar" : string.Empty);
return r;
});
}
}

public class NullInputClass
{
public int? Id { get; set; }
public string Foo { get; set; }
public NullInputChildClass Bar { get; set; }
}

public class NullInputChildClass
{
public int? Id { get; set; }
public string Foo { get; set; }
public NullInputSubChildClass Bar { get; set; }
}

public class NullInputSubChildClass
{
public int? Id { get; set; }
}

public class NullInputRoot : InputObjectGraphType
{
public NullInputRoot()
{
Name = "NullInputRoot";
Field<IntGraphType>("id");
Field<StringGraphType>("foo");
Field<NonNullChild>("bar");
}
}

public class NonNullChild : InputObjectGraphType
{
public NonNullChild()
{
Name = "NonNullChild";
Field<NonNullGraphType<IntGraphType>>("id");
Field<NonNullGraphType<StringGraphType>>("foo");
Field<NonNullGraphType<NonNullSubChild>>("bar");
}
}

public class NonNullSubChild : InputObjectGraphType
{
public NonNullSubChild()
{
Name = "NonNullSubChild";
Field<NonNullGraphType<IntGraphType>>("id");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public void converts_null_to_null()
{
object value = null;
var result = value.AstFromValue(null, null);
result.ShouldBeNull();
result.ShouldBeOfType<NullValue>();
}

[Fact]
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ query SchemaIntrospectionQuery {
'kind': 'SCALAR'
}
},
'defaultValue': null
'defaultValue': 'null'
}
]
},
Expand All @@ -387,7 +387,7 @@ query SchemaIntrospectionQuery {
'kind': 'SCALAR'
}
},
'defaultValue': null
'defaultValue': 'null'
}
]
}
Expand Down
8 changes: 6 additions & 2 deletions deps/graphql-dotnet/src/GraphQL/GraphQLExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static IEnumerable<string> IsValidLiteralValue(this IGraphType type, IVal
var nonNull = (NonNullGraphType) type;
var ofType = nonNull.ResolvedType;

if (valueAst == null)
if (valueAst == null || valueAst is NullValue)
{
if (ofType != null)
{
Expand All @@ -116,6 +116,10 @@ public static IEnumerable<string> IsValidLiteralValue(this IGraphType type, IVal

return IsValidLiteralValue(ofType, valueAst, schema);
}
else if (valueAst is NullValue)
{
return new string[] { };
}

if (valueAst == null)
{
Expand Down Expand Up @@ -308,7 +312,7 @@ public static IValue AstFromValue(this object value, ISchema schema, IGraphType

if (value == null || type == null)
{
return null;
return new NullValue();
}

// Convert IEnumerable to GraphQL list. If the GraphQLType is a list, but
Expand Down
21 changes: 21 additions & 0 deletions deps/graphql-dotnet/src/GraphQL/Language/AST/NullValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace GraphQL.Language.AST
{
public class NullValue : AbstractNode, IValue
{
public override string ToString()
{
return "null";
}

public override bool IsEqualTo(INode obj)
{
if (ReferenceEquals(null, obj)) return true;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == this.GetType();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ public IValue Value(GraphQLValue source)
var values = list.Values.Select(Value);
return new ListValue(values).WithLocation(list, _body);
}
case ASTNodeKind.NullValue:
{
var str = source as GraphQLScalarValue;
return new NullValue().WithLocation(str, _body);
}
}

throw new ExecutionError($"Unmapped value type {source.Kind}");
Expand Down
5 changes: 5 additions & 0 deletions deps/graphql-dotnet/src/GraphQL/Utilities/AstPrinter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ public AstPrintVisitor()
c.Print(p => $"${p.Arg(x => x.Name)}");
});

Config<NullValue>(c =>
{
c.Print(f => "null");
});

Config<IntValue>(c =>
{
c.Field(x => x.Value);
Expand Down
16 changes: 8 additions & 8 deletions deps/parser/src/GraphQLParser/ParserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ private GraphQLEnumTypeDefinition ParseEnumTypeDefinition()
{
Name = this.ParseName(),
Directives = this.ParseDirectives(),
Values = this.Many(TokenKind.BRACE_L, () => this.ParseEnumValueDefinition(), TokenKind.BRACE_R),
Values = this.Many(TokenKind.BRACE_L, this.ParseEnumValueDefinition, TokenKind.BRACE_R),
Location = this.GetLocation(start)
};
}
Expand All @@ -367,7 +367,7 @@ private GraphQLValue ParseEnumValue(Token token)
this.Advance();
return new GraphQLScalarValue(ASTNodeKind.EnumValue)
{
Value = token.Value.ToString(),
Value = token.Value,
Location = this.GetLocation(token.Start)
};
}
Expand Down Expand Up @@ -614,13 +614,13 @@ private GraphQLValue ParseNameValue(bool isConstant)
var token = this.currentToken;

if (token.Value.Equals("true") || token.Value.Equals("false"))
return this.ParseBooleanValue(token);
return this.ParseBooleanValue(token);
else if (token.Value != null)
{
if (token.Value.Equals("null"))
return this.ParseNullValue(token);
else
return this.ParseEnumValue(token);
{
if (token.Value.Equals("null"))
return this.ParseNullValue(token);
else
return this.ParseEnumValue(token);
}

throw new GraphQLSyntaxErrorException(
Expand Down
4 changes: 2 additions & 2 deletions src/GraphQL.Conventions/CommonAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
[assembly: AssemblyCopyright("Copyright 2016-2017 Tommy Lillehagen. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.2.16")]
[assembly: AssemblyInformationalVersion("1.2.16")]
[assembly: AssemblyFileVersion("1.3.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]
[assembly: CLSCompliant(false)]

[assembly: InternalsVisibleTo("Tests")]
6 changes: 3 additions & 3 deletions src/GraphQL.Conventions/GraphQL.Conventions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<Description>GraphQL Conventions for .NET</Description>
<VersionPrefix>1.2.16</VersionPrefix>
<VersionPrefix>1.3.0</VersionPrefix>
<Authors>Tommy Lillehagen</Authors>
<TargetFrameworks>netstandard1.5;net45</TargetFrameworks>
<DebugType>portable</DebugType>
Expand All @@ -27,12 +27,12 @@

<ItemGroup>
<Compile Remove="../../deps/graphql-dotnet/src/GraphQL/bin/**;../../deps/graphql-dotnet/src/GraphQL/obj/**" />
<Compile Include="../../deps/graphql-dotnet/src/GraphQL/**/*.cs" Exclude="..\..\deps\graphql-dotnet\src\GraphQL\bin\**;..\..\deps\graphql-dotnet\src\GraphQL\obj\**;bin\**;obj\**;**\*.xproj;packages\**" />
<Compile Include="../../deps/graphql-dotnet/src/GraphQL/**/*.cs" Exclude="../../deps/graphql-dotnet/src/GraphQL/bin/**;../../deps/graphql-dotnet/src/GraphQL/obj/**;bin/**;obj/**;**/*.xproj;packages/**" />
</ItemGroup>

<ItemGroup>
<Compile Remove="../../deps/parser/src/GraphQLParser/bin/**;../../deps/parser/src/GraphQLParser/obj/**" />
<Compile Include="../../deps/parser/src/GraphQLParser/**/*.cs" Exclude="..\..\deps\parser\src\GraphQLParser\bin\**;..\..\deps\parser\src\GraphQLParser\obj\**;bin\**;obj\**;**\*.xproj;packages\**" />
<Compile Include="../../deps/parser/src/GraphQLParser/**/*.cs" Exclude="../../deps/parser/src/GraphQLParser/bin/**;../../deps/parser/src/GraphQLParser/obj/**;bin/**;obj/**;**/*.xproj;packages/**" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQL.Conventions/project.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.2.16-*",
"version": "1.3.0-*",
"description": "GraphQL Conventions for .NET",
"authors": [
"Tommy Lillehagen"
Expand Down

0 comments on commit f64f1b5

Please sign in to comment.