Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Projection attributes should change type (#2562)
- Loading branch information
1 parent
19eada8
commit f73cdfa
Showing
7 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,4 +14,5 @@ | |
<ItemGroup> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
106 changes: 106 additions & 0 deletions
106
src/HotChocolate/Data/test/Data.Projections.Tests/ProjectionsAttributeTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using HotChocolate.Types; | ||
using Snapshooter.Xunit; | ||
using Xunit; | ||
|
||
namespace HotChocolate.Data | ||
{ | ||
public class ProjectionAttributeTests | ||
{ | ||
[Fact] | ||
public void FirstOrDefault_Attribute() | ||
{ | ||
// arrange | ||
// act | ||
ISchema schema = SchemaBuilder.New() | ||
.AddQueryType<FirstOrDefaultQuery>() | ||
.AddProjections() | ||
.Create(); | ||
|
||
// assert | ||
schema.ToString().MatchSnapshot(); | ||
} | ||
|
||
[Fact] | ||
public void SingleOrDefault_Attribute() | ||
{ | ||
// arrange | ||
// act | ||
ISchema schema = SchemaBuilder.New() | ||
.AddQueryType<SingleOrDefaultQuery>() | ||
.AddProjections() | ||
.Create(); | ||
|
||
// assert | ||
schema.ToString().MatchSnapshot(); | ||
} | ||
|
||
[Fact] | ||
public void FirstOrDefault_Attribute_CustomType() | ||
{ | ||
// arrange | ||
// act | ||
ISchema schema = SchemaBuilder.New() | ||
.AddQueryType<FirstOrDefaultQuery>() | ||
.AddType<FooType>() | ||
.AddProjections() | ||
.Create(); | ||
|
||
// assert | ||
schema.ToString().MatchSnapshot(); | ||
} | ||
|
||
[Fact] | ||
public void SingleOrDefault_Attribute_CustomType() | ||
{ | ||
// arrange | ||
// act | ||
ISchema schema = SchemaBuilder.New() | ||
.AddQueryType<SingleOrDefaultQuery>() | ||
.AddType<FooType>() | ||
.AddProjections() | ||
.Create(); | ||
|
||
// assert | ||
schema.ToString().MatchSnapshot(); | ||
} | ||
|
||
public class FooType : ObjectType<Foo> | ||
{ | ||
protected override void Configure(IObjectTypeDescriptor<Foo> descriptor) | ||
{ | ||
descriptor.Name("Renamed"); | ||
descriptor.Field(x => x.Bar).Name("renamed"); | ||
} | ||
} | ||
|
||
public class FirstOrDefaultQuery | ||
{ | ||
[UseFirstOrDefault] | ||
[UseProjection] | ||
public IQueryable<Foo> GetFooQueryable() => throw new NotImplementedException(); | ||
|
||
[UseFirstOrDefault] | ||
[UseProjection] | ||
public IEnumerable<Foo> GetFooEnumerable() => throw new NotImplementedException(); | ||
} | ||
|
||
public class SingleOrDefaultQuery | ||
{ | ||
[UseFirstOrDefault] | ||
[UseProjection] | ||
public IQueryable<Foo> GetFooQueryable() => throw new NotImplementedException(); | ||
|
||
[UseFirstOrDefault] | ||
[UseProjection] | ||
public IEnumerable<Foo> GetFooEnumerable() => throw new NotImplementedException(); | ||
} | ||
|
||
public class Foo | ||
{ | ||
public string Bar { get; set; } | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
...ta.Projections.Tests/__snapshots__/ProjectionAttributeTests.FirstOrDefault_Attribute.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
schema { | ||
query: FirstOrDefaultQuery | ||
} | ||
|
||
type FirstOrDefaultQuery { | ||
fooQueryable: Foo | ||
fooEnumerable: Foo | ||
} | ||
|
||
type Foo { | ||
bar: String! | ||
} | ||
|
||
"The `@defer` directive may be provided for fragment spreads and inline fragments to inform the executor to delay the execution of the current fragment to indicate deprioritization of the current fragment. A query with `@defer` directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred is delivered in a subsequent response. `@include` and `@skip` take precedence over `@defer`." | ||
directive @defer("If this argument label has a value other than null, it will be passed on to the result of this defer directive. This label is intended to give client applications a way to identify to which fragment a deferred result belongs to." label: String "Deferred when true." if: Boolean) on FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"The @deprecated directive is used within the type system definition language to indicate deprecated portions of a GraphQL service’s schema,such as deprecated fields on a type or deprecated enum values." | ||
directive @deprecated("Deprecations include a reason for why it is deprecated, which is formatted using Markdown syntax (as specified by CommonMark)." reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE | ||
|
||
"Directs the executor to include this field or fragment only when the `if` argument is true." | ||
directive @include("Included when true." if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"Directs the executor to skip this field or fragment when the `if` argument is true." | ||
directive @skip("Skipped when true." if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"The `@stream` directive may be provided for a field of `List` type so that the backend can leverage technology such as asynchronous iterators to provide a partial list in the initial response, and additional list items in subsequent responses. `@include` and `@skip` take precedence over `@stream`." | ||
directive @stream("If this argument label has a value other than null, it will be passed on to the result of this stream directive. This label is intended to give client applications a way to identify to which fragment a streamed result belongs to." label: String "The initial elements that shall be send down to the consumer." initialCount: Int! "Streamed when true." if: Boolean!) on FIELD |
27 changes: 27 additions & 0 deletions
27
...ons.Tests/__snapshots__/ProjectionAttributeTests.FirstOrDefault_Attribute_CustomType.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
schema { | ||
query: FirstOrDefaultQuery | ||
} | ||
|
||
type FirstOrDefaultQuery { | ||
fooQueryable: Renamed | ||
fooEnumerable: Renamed | ||
} | ||
|
||
type Renamed { | ||
renamed: String! | ||
} | ||
|
||
"The `@defer` directive may be provided for fragment spreads and inline fragments to inform the executor to delay the execution of the current fragment to indicate deprioritization of the current fragment. A query with `@defer` directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred is delivered in a subsequent response. `@include` and `@skip` take precedence over `@defer`." | ||
directive @defer("If this argument label has a value other than null, it will be passed on to the result of this defer directive. This label is intended to give client applications a way to identify to which fragment a deferred result belongs to." label: String "Deferred when true." if: Boolean) on FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"The @deprecated directive is used within the type system definition language to indicate deprecated portions of a GraphQL service’s schema,such as deprecated fields on a type or deprecated enum values." | ||
directive @deprecated("Deprecations include a reason for why it is deprecated, which is formatted using Markdown syntax (as specified by CommonMark)." reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE | ||
|
||
"Directs the executor to include this field or fragment only when the `if` argument is true." | ||
directive @include("Included when true." if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"Directs the executor to skip this field or fragment when the `if` argument is true." | ||
directive @skip("Skipped when true." if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"The `@stream` directive may be provided for a field of `List` type so that the backend can leverage technology such as asynchronous iterators to provide a partial list in the initial response, and additional list items in subsequent responses. `@include` and `@skip` take precedence over `@stream`." | ||
directive @stream("If this argument label has a value other than null, it will be passed on to the result of this stream directive. This label is intended to give client applications a way to identify to which fragment a streamed result belongs to." label: String "The initial elements that shall be send down to the consumer." initialCount: Int! "Streamed when true." if: Boolean!) on FIELD |
27 changes: 27 additions & 0 deletions
27
...a.Projections.Tests/__snapshots__/ProjectionAttributeTests.SingleOrDefault_Attribute.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
schema { | ||
query: SingleOrDefaultQuery | ||
} | ||
|
||
type Foo { | ||
bar: String! | ||
} | ||
|
||
type SingleOrDefaultQuery { | ||
fooQueryable: Foo | ||
fooEnumerable: Foo | ||
} | ||
|
||
"The `@defer` directive may be provided for fragment spreads and inline fragments to inform the executor to delay the execution of the current fragment to indicate deprioritization of the current fragment. A query with `@defer` directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred is delivered in a subsequent response. `@include` and `@skip` take precedence over `@defer`." | ||
directive @defer("If this argument label has a value other than null, it will be passed on to the result of this defer directive. This label is intended to give client applications a way to identify to which fragment a deferred result belongs to." label: String "Deferred when true." if: Boolean) on FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"The @deprecated directive is used within the type system definition language to indicate deprecated portions of a GraphQL service’s schema,such as deprecated fields on a type or deprecated enum values." | ||
directive @deprecated("Deprecations include a reason for why it is deprecated, which is formatted using Markdown syntax (as specified by CommonMark)." reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE | ||
|
||
"Directs the executor to include this field or fragment only when the `if` argument is true." | ||
directive @include("Included when true." if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"Directs the executor to skip this field or fragment when the `if` argument is true." | ||
directive @skip("Skipped when true." if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"The `@stream` directive may be provided for a field of `List` type so that the backend can leverage technology such as asynchronous iterators to provide a partial list in the initial response, and additional list items in subsequent responses. `@include` and `@skip` take precedence over `@stream`." | ||
directive @stream("If this argument label has a value other than null, it will be passed on to the result of this stream directive. This label is intended to give client applications a way to identify to which fragment a streamed result belongs to." label: String "The initial elements that shall be send down to the consumer." initialCount: Int! "Streamed when true." if: Boolean!) on FIELD |
27 changes: 27 additions & 0 deletions
27
...ns.Tests/__snapshots__/ProjectionAttributeTests.SingleOrDefault_Attribute_CustomType.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
schema { | ||
query: SingleOrDefaultQuery | ||
} | ||
|
||
type Renamed { | ||
renamed: String! | ||
} | ||
|
||
type SingleOrDefaultQuery { | ||
fooQueryable: Renamed | ||
fooEnumerable: Renamed | ||
} | ||
|
||
"The `@defer` directive may be provided for fragment spreads and inline fragments to inform the executor to delay the execution of the current fragment to indicate deprioritization of the current fragment. A query with `@defer` directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred is delivered in a subsequent response. `@include` and `@skip` take precedence over `@defer`." | ||
directive @defer("If this argument label has a value other than null, it will be passed on to the result of this defer directive. This label is intended to give client applications a way to identify to which fragment a deferred result belongs to." label: String "Deferred when true." if: Boolean) on FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"The @deprecated directive is used within the type system definition language to indicate deprecated portions of a GraphQL service’s schema,such as deprecated fields on a type or deprecated enum values." | ||
directive @deprecated("Deprecations include a reason for why it is deprecated, which is formatted using Markdown syntax (as specified by CommonMark)." reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE | ||
|
||
"Directs the executor to include this field or fragment only when the `if` argument is true." | ||
directive @include("Included when true." if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"Directs the executor to skip this field or fragment when the `if` argument is true." | ||
directive @skip("Skipped when true." if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
||
"The `@stream` directive may be provided for a field of `List` type so that the backend can leverage technology such as asynchronous iterators to provide a partial list in the initial response, and additional list items in subsequent responses. `@include` and `@skip` take precedence over `@stream`." | ||
directive @stream("If this argument label has a value other than null, it will be passed on to the result of this stream directive. This label is intended to give client applications a way to identify to which fragment a streamed result belongs to." label: String "The initial elements that shall be send down to the consumer." initialCount: Int! "Streamed when true." if: Boolean!) on FIELD |