Skip to content

Commit

Permalink
support for repeatable directives
Browse files Browse the repository at this point in the history
  • Loading branch information
sungam3r committed Jan 19, 2020
1 parent 79d07d7 commit 09434ae
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 14 deletions.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 5.0.1.{build}
version: 5.1.0.{build}
pull_requests:
do_not_increment_build_number: true
skip_tags: true
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "graphql-parser",
"version": "5.0.1",
"version": "5.1.0",
"main": "index.js",
"repository": "git@github.com:graphql-dotnet/parser.git",
"author": "Joe McBride",
Expand Down
4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<Project>

<PropertyGroup>
<VersionPrefix>5.0.1</VersionPrefix>
<VersionPrefix>5.1.0</VersionPrefix>
<Authors>Marek Magdziak</Authors>
<NoWarn>$(NoWarn);1591</NoWarn>
<Copyright>Copyright 2016-2019 Marek Magdziak et al. All rights reserved.</Copyright>
<Copyright>Copyright 2016-2020 Marek Magdziak et al. All rights reserved.</Copyright>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<LangVersion>latest</LangVersion>
</PropertyGroup>
Expand Down
33 changes: 25 additions & 8 deletions src/GraphQLParser.Tests/ParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -395,22 +395,39 @@ private static GraphQLDocument ParseGraphQLFieldWithOperationTypeAndNameSource()
}

[Theory]
[InlineData("directive @dir on FIELD_DEFINITION | ENUM_VALUE")]
[InlineData("directive @dir on | FIELD_DEFINITION | ENUM_VALUE")]
[InlineData("directive @dir repeatable on FIELD_DEFINITION", true)]
[InlineData("directive @dir(a: Int) repeatable on FIELD_DEFINITION", true)]
[InlineData("directive @dir on FIELD_DEFINITION | ENUM_VALUE", false)]
[InlineData("directive @dir on | FIELD_DEFINITION | ENUM_VALUE", false)]
[InlineData(@"directive @dir on
FIELD_DEFINITION | ENUM_VALUE")]
FIELD_DEFINITION | ENUM_VALUE", false)]
[InlineData(@"directive @dir on
FIELD_DEFINITION
| ENUM_VALUE")]
| ENUM_VALUE", false)]
[InlineData(@"directive @dir on
| FIELD_DEFINITION
| ENUM_VALUE")]
| ENUM_VALUE", false)]
[InlineData(@"directive @dir on
| FIELD_DEFINITION
| ENUM_VALUE")]
public void Should_Parse_Directives(string text)
| ENUM_VALUE", false)]
public void Should_Parse_Directives(string text, bool repeatable)
{
new Parser(new Lexer()).Parse(new Source(text)).ShouldNotBeNull();
var document = new Parser(new Lexer()).Parse(new Source(text));
document.ShouldNotBeNull();
document.Definitions.Count.ShouldBe(1);
document.Definitions[0].ShouldBeOfType<GraphQLDirectiveDefinition>().Repeatable.ShouldBe(repeatable);
}

[Theory]
[InlineData("directive @dir On FIELD_DEFINITION")]
[InlineData("directive @dir onn FIELD_DEFINITION")]
[InlineData("directive @dir Repeatable on FIELD_DEFINITION")]
[InlineData("directive @dir repeatablee on FIELD_DEFINITION")]
[InlineData("directive @dir repeatable On FIELD_DEFINITION")]
[InlineData("directive @dir repeatable onn FIELD_DEFINITION")]
public void Should_Throw_GraphQLSyntaxErrorException(string text)
{
Should.Throw<GraphQLSyntaxErrorException>(() => new Parser(new Lexer()).Parse(new Source(text)));
}

[Theory]
Expand Down
2 changes: 2 additions & 0 deletions src/GraphQLParser/AST/GraphQLDirectiveDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ public class GraphQLDirectiveDefinition : GraphQLTypeDefinition
public override ASTNodeKind Kind => ASTNodeKind.DirectiveDefinition;

public List<GraphQLName> Locations { get; set; }

public bool Repeatable { get; set; }
}
}
31 changes: 29 additions & 2 deletions src/GraphQLParser/ParserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,14 @@ private GraphQLDirective ParseDirective()
Arguments = ParseArguments(),
Location = GetLocation(start)
};
}

}

/// <summary>
/// http://spec.graphql.org/draft/#DirectiveDefinition
/// DirectiveDefinition:
/// Description(opt) directive @ Name ArgumentsDefinition(opt) repeatable(opt) on DirectiveLocations
/// </summary>
/// <returns></returns>
private GraphQLDirectiveDefinition ParseDirectiveDefinition()
{
var comment = GetComment();
Expand All @@ -358,6 +364,7 @@ private GraphQLDirectiveDefinition ParseDirectiveDefinition()

var name = ParseName();
var args = ParseArgumentDefs();
var repeatable = ParseRepeatable();

ExpectKeyword("on");
var locations = ParseDirectiveLocations();
Expand All @@ -366,10 +373,30 @@ private GraphQLDirectiveDefinition ParseDirectiveDefinition()
{
Comment = comment,
Name = name,
Repeatable = repeatable,
Arguments = args,
Locations = locations,
Location = GetLocation(start)
};
}

private bool ParseRepeatable()
{
if (Peek(TokenKind.NAME))
{
switch (currentToken.Value)
{
case "repeatable":
Advance();
return true;
case "on":
return false;
default:
throw new GraphQLSyntaxErrorException($"Unexpected {currentToken}", source, currentToken.Start);
}
}

return false;
}

private List<GraphQLName> ParseDirectiveLocations()
Expand Down

0 comments on commit 09434ae

Please sign in to comment.