Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finalized Validation Rules #221

Merged
merged 32 commits into from Aug 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
29fac13
Added lead field selection rule implementation
michaelstaib Aug 24, 2018
6a44a3a
LeafFieldSelectionsRule Tests
michaelstaib Aug 24, 2018
57fc477
Merge branch 'master' into mst/validation
michaelstaib Aug 24, 2018
91a045e
updated roadmap
michaelstaib Aug 24, 2018
15250fc
updated roadmap
michaelstaib Aug 24, 2018
5014a80
Merge branch 'mst/validation' of https://github.com/ChilliCream/hotch…
michaelstaib Aug 24, 2018
d8c20dd
Started working on fragmnetoncompositetypesrule tests
michaelstaib Aug 24, 2018
dbc3afd
Added fragment type tests
michaelstaib Aug 24, 2018
bc3cbe2
Added integration test
michaelstaib Aug 24, 2018
d105fab
Added fragment spreads must not form cycles rule
michaelstaib Aug 24, 2018
7063efb
Updated Readme
michaelstaib Aug 24, 2018
545997b
Added fragment spread target defined rule
michaelstaib Aug 25, 2018
9e38d68
implemented FragmentSpreadIsPossible rule
michaelstaib Aug 25, 2018
d3d340d
Fixed sonar issues
michaelstaib Aug 25, 2018
1026eab
Fixed sonar issues
michaelstaib Aug 25, 2018
f3100e6
Disabled ValuesOfCorrectTypeRule
michaelstaib Aug 25, 2018
f168467
Added more tests for the lead field rule
michaelstaib Aug 25, 2018
d560b67
Fixed test schema
michaelstaib Aug 25, 2018
6d2fdaf
Fixed test schema
michaelstaib Aug 25, 2018
a992b32
Added support for inlinefragments without typecondition
michaelstaib Aug 25, 2018
3f2d07a
Added snapshot
michaelstaib Aug 25, 2018
f073575
[Fact]
michaelstaib Aug 25, 2018
f04ff06
Integrated Fragment Spread Type Existence rule into query validator c…
michaelstaib Aug 25, 2018
018183a
Fixed sonar issues
michaelstaib Aug 25, 2018
3671798
Implemented Input Object Field Names rule
michaelstaib Aug 25, 2018
067792a
Fixed sonar issue
michaelstaib Aug 25, 2018
5221858
Implemented InputObject required fields rule
michaelstaib Aug 26, 2018
19fcc06
Added input object field uniqueness rule
michaelstaib Aug 26, 2018
e2f77b6
Implemented directives are defined rule
michaelstaib Aug 26, 2018
b1c3f55
Implemented values of correct type rule
michaelstaib Aug 26, 2018
499009f
Fixed float type
michaelstaib Aug 26, 2018
df9b6a3
Added documentation
michaelstaib Aug 26, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 15 additions & 11 deletions README.md
Expand Up @@ -188,7 +188,7 @@ dotnet new graphql-server

## Features

We currently support the following parts of the current [draft spec](http://facebook.github.io/graphql/draft/) of GraphQL.
We currently support the following parts of the current [June 2018 specification](http://facebook.github.io/graphql/June2018/) of GraphQL.

### Types

Expand All @@ -210,33 +210,35 @@ We currently support the following parts of the current [draft spec](http://face

- [x] Skip
- [x] Continue
- [ ] Deprecated
- [ ] _Deprecated_ (in development - 0.5.0)

### Validation

- [ ] [Validation](https://github.com/ChilliCream/hotchocolate/projects/3)
- [x] [_Validation_](https://github.com/ChilliCream/hotchocolate/projects/3)

### Execution

- [x] Query
- [x] Mutation
- [ ] Subscription
- [ ] _Subscription_ (in development - 0.5.0)

### Introspection

- Fields
- [x] __typename
- [x] __type
- [x] __schema

- __Schema
- [x] \_\_typename
- [x] \_\_type
- [x] \_\_schema

- \_\_Schema

- [x] types
- [x] queryType
- [x] mutationType
- [x] subscriptionType
- [x] directives

- __Type
- \_\_Type
- [x] kind
- [x] name
- [x] fields
Expand All @@ -254,6 +256,7 @@ Moreover, we are working on the following parts that are not defined in the spec
- [x] Date
- [ ] Time
- [ ] URL
- [ ] UUID
- [x] Decimal
- [x] Short (Int16)
- [x] Long (Int64)
Expand All @@ -264,8 +267,8 @@ Moreover, we are working on the following parts that are not defined in the spec
- [ ] Export
- [ ] Defer
- [ ] Stream
- [ ] Custom Schema Directives
- [ ] Custom Execution Directives
- [ ] _Custom Schema Directives_ (in development - 0.5.0)
- [ ] _Custom Execution Directives_ (in development - 0.5.0)

### Execution Engine

Expand All @@ -280,6 +283,7 @@ Moreover, we are working on the following parts that are not defined in the spec
## Supported Frameworks

- [ ] ASP.NET Classic

- [ ] Get
- [ ] Post

Expand Down
Expand Up @@ -460,6 +460,28 @@ query op($ep: [Episode!]!)
Assert.Equal(Snapshot.Current(), Snapshot.New(result));
}

[Fact]
public void ConditionalInlineFragment()
{
// arrange
Schema schema = CreateSchema();
string query = @"
{
heroes(episodes: [EMPIRE]) {
name
... @include(if: true) {
height
}
}
}";

// act
IExecutionResult result = schema.Execute(query);

// assert
Assert.Equal(Snapshot.Current(), Snapshot.New(result));
}

private static Schema CreateSchema()
{
CharacterRepository repository = new CharacterRepository();
Expand Down
31 changes: 30 additions & 1 deletion src/Core.Tests/Types/FloatTypeTests.cs
Expand Up @@ -11,7 +11,7 @@ public class FloatTypeTests
new FloatValueNode("1.000000E+000");

protected override IValueNode GetWrongValueNode =>
new IntValueNode("1");
new StringValueNode("1");

protected override double GetValue => 1.0d;

Expand Down Expand Up @@ -54,5 +54,34 @@ public void ParseValue_Float_Min()
// assert
Assert.Equal("-3.402823E+038", literal.Value);
}

[Fact]
public void IsInstanceOfType_IntValueNode()
{
// arrange
FloatType type = new FloatType();
IntValueNode input = new IntValueNode("123");

// act
bool result = type.IsInstanceOfType(input);

// assert
Assert.True(result);
}

[Fact]
public void ParseLiteral_IntValueNode()
{
// arrange
FloatType type = new FloatType();
IntValueNode input = new IntValueNode("123");

// act
object result = type.ParseLiteral(input);

// assert
Assert.IsType<double>(result);
Assert.Equal(123d, result);
}
}
}
59 changes: 59 additions & 0 deletions src/Core.Tests/Validation/DirectivesAreDefinedRuleTests.cs
@@ -0,0 +1,59 @@
using HotChocolate.Language;
using Xunit;

namespace HotChocolate.Validation
{
public class DirectivesAreDefinedRuleTests
: ValidationTestBase
{
public DirectivesAreDefinedRuleTests()
: base(new DirectivesAreDefinedRule())
{
}

[Fact]
public void SupportedDirective()
{
// arrange
Schema schema = ValidationUtils.CreateSchema();
DocumentNode query = Parser.Default.Parse(@"
{
dog {
name @skip(if: true)
}
}
");

// act
QueryValidationResult result = Rule.Validate(schema, query);

// assert
Assert.False(result.HasErrors);
}

[Fact]
public void UnsupportedDirective()
{
// arrange
Schema schema = ValidationUtils.CreateSchema();
DocumentNode query = Parser.Default.Parse(@"
{
dog {
name @foo(bar: true)
}
}
");

// act
QueryValidationResult result = Rule.Validate(schema, query);

// assert
Assert.True(result.HasErrors);
Assert.Collection(result.Errors,
t => Assert.Equal(
"The specified directive `foo` " +
"is not supported by the current schema.",
t.Message));
}
}
}
114 changes: 114 additions & 0 deletions src/Core.Tests/Validation/FragmentSpreadIsPossibleRuleTests.cs
@@ -0,0 +1,114 @@
using HotChocolate.Language;
using Xunit;

namespace HotChocolate.Validation
{
public class FragmentSpreadIsPossibleRuleTests
: ValidationTestBase
{
public FragmentSpreadIsPossibleRuleTests()
: base(new FragmentSpreadIsPossibleRule())
{
}

[Fact]
public void FragmentDoesNotMatchType()
{
// arrange
Schema schema = ValidationUtils.CreateSchema();
DocumentNode query = Parser.Default.Parse(@"
{
dog {
...fragmentDoesNotMatchType
}
}

fragment fragmentDoesNotMatchType on Human {
name
}
");

// act
QueryValidationResult result = Rule.Validate(schema, query);

// assert
Assert.True(result.HasErrors);
Assert.Collection(result.Errors,
t => Assert.Equal(t.Message,
"The parent type does not match the type condition on " +
"the fragment `fragmentDoesNotMatchType`."));
}

[Fact]
public void InterfaceTypeDoesMatch()
{
// arrange
Schema schema = ValidationUtils.CreateSchema();
DocumentNode query = Parser.Default.Parse(@"
{
dog {
...interfaceTypeDoesMatch
}
}

fragment interfaceTypeDoesMatch on Pet {
name
}
");

// act
QueryValidationResult result = Rule.Validate(schema, query);

// assert
Assert.False(result.HasErrors);
}

[Fact]
public void UnionTypeDoesMatch()
{
// arrange
Schema schema = ValidationUtils.CreateSchema();
DocumentNode query = Parser.Default.Parse(@"
{
dog {
...unionTypeDoesMatch
}
}

fragment unionTypeDoesMatch on CatOrDog {
name
}
");

// act
QueryValidationResult result = Rule.Validate(schema, query);

// assert
Assert.False(result.HasErrors);
}

[Fact]
public void ObjectTypeDoesMatch()
{
// arrange
Schema schema = ValidationUtils.CreateSchema();
DocumentNode query = Parser.Default.Parse(@"
{
dog {
...objectTypeDoesMatch
}
}

fragment objectTypeDoesMatch on Dog {
name
}
");

// act
QueryValidationResult result = Rule.Validate(schema, query);

// assert
Assert.False(result.HasErrors);
}
}
}
62 changes: 62 additions & 0 deletions src/Core.Tests/Validation/FragmentSpreadTargetDefinedRuleTests.cs
@@ -0,0 +1,62 @@
using HotChocolate.Language;
using Xunit;

namespace HotChocolate.Validation
{
public class FragmentSpreadTargetDefinedRuleTests
: ValidationTestBase
{
public FragmentSpreadTargetDefinedRuleTests()
: base(new FragmentSpreadTargetDefinedRule())
{
}

[Fact]
public void UndefinedFragment()
{
// arrange
Schema schema = ValidationUtils.CreateSchema();
DocumentNode query = Parser.Default.Parse(@"
{
dog {
...undefinedFragment
}
}
");

// act
QueryValidationResult result = Rule.Validate(schema, query);

// assert
Assert.True(result.HasErrors);
Assert.Collection(result.Errors,
t => Assert.Equal(t.Message,
"The specified fragment `undefinedFragment` does not exist."));
}

[Fact]
public void DefinedFragment()
{
// arrange
Schema schema = ValidationUtils.CreateSchema();
DocumentNode query = Parser.Default.Parse(@"
{
dog {
...definedFragment
}
}

fragment definedFragment on Dog
{
barkVolume
}
");

// act
QueryValidationResult result = Rule.Validate(schema, query);

// assert
Assert.False(result.HasErrors);
}
}
}