From 0bd2c532ce47ca36f6e2008ef010a3b9276e5ede Mon Sep 17 00:00:00 2001 From: Pascal Senn Date: Fri, 16 Oct 2020 15:33:00 +0200 Subject: [PATCH 1/5] add query abstraction --- .../Core/src/Abstractions/IQuery.cs | 12 ++++ .../Core/src/Abstractions/IQuery~1.cs | 11 +++ .../src/Execution/Processing/ResolverTask.cs | 4 ++ .../src/Types/Internal/ExtendedType.Helper.cs | 3 +- .../Types/Internal/ExtendedType.Members.cs | 4 +- .../Types/Internal/ExtendedType.SystemType.cs | 4 +- .../test/Execution.Tests/CodeFirstTests.cs | 66 ++++++++++++++++-- ...nCompilerTests.Field_Based_Optimizers.snap | 18 ----- ...eld_Visibility_Is_Correctly_Inherited.snap | 16 ----- ...d_Visibility_Is_Correctly_Inherited_2.snap | 16 ----- ...d_Visibility_Is_Correctly_Inherited_3.snap | 12 ---- ...ilerTests.Prepare_Fragment_Definition.snap | 14 ---- ...CompilerTests.Prepare_Inline_Fragment.snap | 14 ---- ...perationCompilerTests.Reuse_Selection.snap | 36 ---------- ...esult_SimpleResultSet_SnapshotMatches.snap | 5 -- ..._ReviewInput_Variable_With_Dictionary.snap | 1 - ...viewInput_Variable_With_Review_Object.snap | 1 - ...Default_Where_Plain_Value_Is_Provided.snap | 1 - ...Has_Different_Properties_Than_Defined.snap | 13 ---- ...ainValue_Is_Null_On_Non_Null_Variable.snap | 13 ---- ...lue_Type_Does_Not_Match_Variable_Type.snap | 13 ---- ...en_Value_Is_Null_On_Non_Null_Variable.snap | 13 ---- ...lue_Type_Does_Not_Match_Variable_Type.snap | 13 ---- ...ts.Variable_Type_Is_Not_An_Input_Type.snap | 14 ---- ...stTests.ExecuteOneFieldQueryWithQuery.snap | 14 ++++ .../Types.Tests/Internal/ExtendedTypeTests.cs | 30 ++++++-- .../Types.Tests/Internal/TypeInfoTests.cs | 69 ++++++++++++++++++- 27 files changed, 199 insertions(+), 231 deletions(-) create mode 100644 src/HotChocolate/Core/src/Abstractions/IQuery.cs create mode 100644 src/HotChocolate/Core/src/Abstractions/IQuery~1.cs delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Field_Based_Optimizers.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited_2.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited_3.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Prepare_Fragment_Definition.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Prepare_Inline_Fragment.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Reuse_Selection.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/ResultHelperTests.BuildResult_SimpleResultSet_SnapshotMatches.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_ReviewInput_Variable_With_Dictionary.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_ReviewInput_Variable_With_Review_Object.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_String_Variable_With_Default_Where_Plain_Value_Is_Provided.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Input_Field_Has_Different_Properties_Than_Defined.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_PlainValue_Is_Null_On_Non_Null_Variable.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_PlainValue_Type_Does_Not_Match_Variable_Type.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Value_Is_Null_On_Non_Null_Variable.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Value_Type_Does_Not_Match_Variable_Type.snap delete mode 100644 src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Variable_Type_Is_Not_An_Input_Type.snap create mode 100644 src/HotChocolate/Core/test/Execution.Tests/__snapshots__/CodeFirstTests.ExecuteOneFieldQueryWithQuery.snap diff --git a/src/HotChocolate/Core/src/Abstractions/IQuery.cs b/src/HotChocolate/Core/src/Abstractions/IQuery.cs new file mode 100644 index 00000000000..d3efa640fad --- /dev/null +++ b/src/HotChocolate/Core/src/Abstractions/IQuery.cs @@ -0,0 +1,12 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace HotChocolate +{ + public interface IQuery + { + ValueTask ExecuteAsync(CancellationToken cancellationToken); + + string Print(); + } +} diff --git a/src/HotChocolate/Core/src/Abstractions/IQuery~1.cs b/src/HotChocolate/Core/src/Abstractions/IQuery~1.cs new file mode 100644 index 00000000000..dcb68f93469 --- /dev/null +++ b/src/HotChocolate/Core/src/Abstractions/IQuery~1.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace HotChocolate +{ + public interface IQuery : IQuery + { + new ValueTask> ExecuteAsync(CancellationToken cancellationToken); + } +} diff --git a/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs b/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs index d03b6abfd99..249c87941b7 100644 --- a/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs +++ b/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs @@ -66,6 +66,10 @@ private async ValueTask ExecuteResolverPipelineAsync() switch (_context.Result) { + case HotChocolate.IQuery query: + _context.Result = await query.ExecuteAsync(_context); + break; + case IQueryable queryable: _context.Result = await Task.Run(() => { diff --git a/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Helper.cs b/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Helper.cs index 095c5465896..a2e2d0d80c1 100644 --- a/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Helper.cs +++ b/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Helper.cs @@ -166,7 +166,8 @@ public static bool IsSupportedCollectionInterface(Type type) || typeDefinition == typeof(ImmutableList<>) || typeDefinition == typeof(ImmutableQueue<>) || typeDefinition == typeof(ImmutableStack<>) - || typeDefinition == typeof(ImmutableHashSet<>)) + || typeDefinition == typeof(ImmutableHashSet<>) + || typeDefinition == typeof(IQuery<>)) { return true; } diff --git a/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Members.cs b/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Members.cs index 026c9f24a5d..90c5a506c0f 100644 --- a/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Members.cs +++ b/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Members.cs @@ -40,7 +40,8 @@ public static ExtendedMethodInfo FromMethod(MethodInfo method, TypeCache cache) method, () => Rewrite( CreateExtendedType(context, helper.GetFlags(method), method.ReturnType), - method, cache)); + method, + cache)); ParameterInfo[] parameters = method.GetParameters(); var parameterTypes = new Dictionary(); @@ -203,6 +204,7 @@ public static ExtendedMethodInfo FromMethod(MethodInfo method, TypeCache cache) state = flags[0]; } } + return state; } } diff --git a/src/HotChocolate/Core/src/Types/Internal/ExtendedType.SystemType.cs b/src/HotChocolate/Core/src/Types/Internal/ExtendedType.SystemType.cs index 1a513799c76..d13fc99df33 100644 --- a/src/HotChocolate/Core/src/Types/Internal/ExtendedType.SystemType.cs +++ b/src/HotChocolate/Core/src/Types/Internal/ExtendedType.SystemType.cs @@ -20,7 +20,7 @@ private static ExtendedType FromTypeInternal(Type type, TypeCache cache) && type.GetGenericTypeDefinition() == typeof(Nullable<>)) { Type inner = type.GetGenericArguments()[0]; - + return new ExtendedType( inner, ExtendedTypeKind.Runtime, @@ -50,7 +50,7 @@ private static ExtendedType FromTypeInternal(Type type, TypeCache cache) } public static IReadOnlyList GetGenericArguments( - Type type, + Type type, TypeCache cache) { if (type.IsGenericType) diff --git a/src/HotChocolate/Core/test/Execution.Tests/CodeFirstTests.cs b/src/HotChocolate/Core/test/Execution.Tests/CodeFirstTests.cs index 9c9c0c7d977..f63067690c4 100644 --- a/src/HotChocolate/Core/test/Execution.Tests/CodeFirstTests.cs +++ b/src/HotChocolate/Core/test/Execution.Tests/CodeFirstTests.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.Linq; +using System.Threading; using System.Threading.Tasks; using HotChocolate.Execution; using HotChocolate.Resolvers; @@ -43,6 +45,22 @@ public async Task ExecuteOneFieldQueryWithMethod() result.MatchSnapshot(); } + [Fact] + public async Task ExecuteOneFieldQueryWithQuery() + { + // arrange + var schema = Schema.Create( + c => c.RegisterType()); + + // act + IExecutionResult result = + await schema.MakeExecutable().ExecuteAsync("{ query }"); + + // assert + Assert.Null(result.Errors); + result.MatchSnapshot(); + } + [Fact] public async Task ExecuteWithUnionType() { @@ -51,13 +69,16 @@ public async Task ExecuteWithUnionType() // act IExecutionResult result = - await schema.MakeExecutable().ExecuteAsync( - @"{ - fooOrBar { - ... on Bar { nameBar } - ... on Foo { nameFoo } + await schema.MakeExecutable() + .ExecuteAsync( + @" + { + fooOrBar { + ... on Bar { nameBar } + ... on Foo { nameFoo } + } } - }"); + "); // assert Assert.Null(result.Errors); @@ -263,6 +284,11 @@ public string GetTest() return "Hello World!"; } + public IQuery GetQuery() + { + return MockQuery.From("foo", "bar"); + } + public string TestProp => "Hello World!"; } @@ -285,6 +311,7 @@ public class QueryTypeWithMethod { descriptor.Name("Query"); descriptor.Field(t => t.GetTest()).Name("test"); + descriptor.Field(t => t.GetQuery()).Name("query"); } } @@ -434,5 +461,32 @@ public class DogType .Type>(); } } + + public class MockQuery : IQuery + { + private readonly IReadOnlyList _list; + + private MockQuery(IEnumerable list) + { + _list = list.ToArray(); + } + + async ValueTask IQuery.ExecuteAsync(CancellationToken cancellationToken) + { + return await ExecuteAsync(cancellationToken); + } + + public ValueTask> ExecuteAsync(CancellationToken cancellationToken) + { + return new ValueTask>(_list); + } + + public string Print() + { + return _list.ToString(); + } + + public static MockQuery From(params T[] items) => new MockQuery(items); + } } } diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Field_Based_Optimizers.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Field_Based_Optimizers.snap deleted file mode 100644 index b768114f5bc..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Field_Based_Optimizers.snap +++ /dev/null @@ -1,18 +0,0 @@ -{ - ... on Query { - root { - ... on Foo { - bar { - ... on Bar { - text - baz @_internal { - ... on Baz { - text @_internal - } - } - } - } - } - } - } -} diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited.snap deleted file mode 100644 index 455eeecf475..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited.snap +++ /dev/null @@ -1,16 +0,0 @@ -query foo($v: Boolean) { - ... on Query { - hero(episode: EMPIRE) { - ... on Human { - name @include(if: $v) - id - height @include(if: $v) - } - ... on Droid { - name @include(if: $v) - id - height @include(if: $v) - } - } - } -} diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited_2.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited_2.snap deleted file mode 100644 index 2683f5d8d1d..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited_2.snap +++ /dev/null @@ -1,16 +0,0 @@ -query foo($v: Boolean, $q: Boolean) { - ... on Query { - hero(episode: EMPIRE) { - ... on Human { - name @include(if: $q) - id - height @include(if: $v) - } - ... on Droid { - name @include(if: $q) - id - height @include(if: $v) - } - } - } -} diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited_3.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited_3.snap deleted file mode 100644 index 65e23a43199..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Object_Field_Visibility_Is_Correctly_Inherited_3.snap +++ /dev/null @@ -1,12 +0,0 @@ -query foo($v: Boolean, $q: Boolean) { - ... on Query { - hero(episode: EMPIRE) @include(if: $v) { - ... on Human { - name @include(if: $q) - } - ... on Droid { - name @include(if: $q) - } - } - } -} diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Prepare_Fragment_Definition.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Prepare_Fragment_Definition.snap deleted file mode 100644 index bc679f1ab1d..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Prepare_Fragment_Definition.snap +++ /dev/null @@ -1,14 +0,0 @@ -{ - ... on Query { - hero(episode: EMPIRE) { - ... on Human { - name - homePlanet - } - ... on Droid { - name - primaryFunction - } - } - } -} diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Prepare_Inline_Fragment.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Prepare_Inline_Fragment.snap deleted file mode 100644 index bc679f1ab1d..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Prepare_Inline_Fragment.snap +++ /dev/null @@ -1,14 +0,0 @@ -{ - ... on Query { - hero(episode: EMPIRE) { - ... on Human { - name - homePlanet - } - ... on Droid { - name - primaryFunction - } - } - } -} diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Reuse_Selection.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Reuse_Selection.snap deleted file mode 100644 index 5f48a964030..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/OperationCompilerTests.Reuse_Selection.snap +++ /dev/null @@ -1,36 +0,0 @@ -query Hero($episode: Episode, $withFriends: Boolean!) { - ... on Query { - hero(episode: $episode) { - ... on Human { - name - friends @include(if: $withFriends) { - ... on CharacterConnection { - nodes @include(if: $withFriends) { - ... on Human { - id @include(if: $withFriends) - } - ... on Droid { - id @include(if: $withFriends) - } - } - } - } - } - ... on Droid { - name - friends @include(if: $withFriends) { - ... on CharacterConnection { - nodes @include(if: $withFriends) { - ... on Human { - id @include(if: $withFriends) - } - ... on Droid { - id @include(if: $withFriends) - } - } - } - } - } - } - } -} diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/ResultHelperTests.BuildResult_SimpleResultSet_SnapshotMatches.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/ResultHelperTests.BuildResult_SimpleResultSet_SnapshotMatches.snap deleted file mode 100644 index 769cd361886..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/ResultHelperTests.BuildResult_SimpleResultSet_SnapshotMatches.snap +++ /dev/null @@ -1,5 +0,0 @@ -{ - "data": { - "abc": "def" - } -} diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_ReviewInput_Variable_With_Dictionary.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_ReviewInput_Variable_With_Dictionary.snap deleted file mode 100644 index dd91f5e3fe1..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_ReviewInput_Variable_With_Dictionary.snap +++ /dev/null @@ -1 +0,0 @@ -{ stars: 5 } diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_ReviewInput_Variable_With_Review_Object.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_ReviewInput_Variable_With_Review_Object.snap deleted file mode 100644 index a729e82ec41..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_ReviewInput_Variable_With_Review_Object.snap +++ /dev/null @@ -1 +0,0 @@ -{ stars: 5, commentary: null } diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_String_Variable_With_Default_Where_Plain_Value_Is_Provided.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_String_Variable_With_Default_Where_Plain_Value_Is_Provided.snap deleted file mode 100644 index 5f4269fe6dd..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Coerce_Nullable_String_Variable_With_Default_Where_Plain_Value_Is_Provided.snap +++ /dev/null @@ -1 +0,0 @@ -"xyz" diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Input_Field_Has_Different_Properties_Than_Defined.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Input_Field_Has_Different_Properties_Than_Defined.snap deleted file mode 100644 index c9550aabfd2..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Input_Field_Has_Different_Properties_Than_Defined.snap +++ /dev/null @@ -1,13 +0,0 @@ -[ - { - "Message": "Variable `abc` got an invalid value.", - "Code": "EXEC_INVALID_TYPE", - "Path": null, - "Locations": null, - "Extensions": { - "code": "EXEC_INVALID_TYPE", - "variable": "abc" - }, - "Exception": null - } -] diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_PlainValue_Is_Null_On_Non_Null_Variable.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_PlainValue_Is_Null_On_Non_Null_Variable.snap deleted file mode 100644 index ce5cb5dc04b..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_PlainValue_Is_Null_On_Non_Null_Variable.snap +++ /dev/null @@ -1,13 +0,0 @@ -[ - { - "Message": "Variable `abc` is required.", - "Code": "EXEC_NON_NULL_VIOLATION", - "Path": null, - "Locations": null, - "Extensions": { - "code": "EXEC_NON_NULL_VIOLATION", - "variable": "abc" - }, - "Exception": null - } -] diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_PlainValue_Type_Does_Not_Match_Variable_Type.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_PlainValue_Type_Does_Not_Match_Variable_Type.snap deleted file mode 100644 index c9550aabfd2..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_PlainValue_Type_Does_Not_Match_Variable_Type.snap +++ /dev/null @@ -1,13 +0,0 @@ -[ - { - "Message": "Variable `abc` got an invalid value.", - "Code": "EXEC_INVALID_TYPE", - "Path": null, - "Locations": null, - "Extensions": { - "code": "EXEC_INVALID_TYPE", - "variable": "abc" - }, - "Exception": null - } -] diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Value_Is_Null_On_Non_Null_Variable.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Value_Is_Null_On_Non_Null_Variable.snap deleted file mode 100644 index ce5cb5dc04b..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Value_Is_Null_On_Non_Null_Variable.snap +++ /dev/null @@ -1,13 +0,0 @@ -[ - { - "Message": "Variable `abc` is required.", - "Code": "EXEC_NON_NULL_VIOLATION", - "Path": null, - "Locations": null, - "Extensions": { - "code": "EXEC_NON_NULL_VIOLATION", - "variable": "abc" - }, - "Exception": null - } -] diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Value_Type_Does_Not_Match_Variable_Type.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Value_Type_Does_Not_Match_Variable_Type.snap deleted file mode 100644 index c9550aabfd2..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Error_When_Value_Type_Does_Not_Match_Variable_Type.snap +++ /dev/null @@ -1,13 +0,0 @@ -[ - { - "Message": "Variable `abc` got an invalid value.", - "Code": "EXEC_INVALID_TYPE", - "Path": null, - "Locations": null, - "Extensions": { - "code": "EXEC_INVALID_TYPE", - "variable": "abc" - }, - "Exception": null - } -] diff --git a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Variable_Type_Is_Not_An_Input_Type.snap b/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Variable_Type_Is_Not_An_Input_Type.snap deleted file mode 100644 index 9edc6374ead..00000000000 --- a/src/HotChocolate/Core/test/Execution.Tests/Utilities/__snapshots__/VariableCoercionHelperTests.Variable_Type_Is_Not_An_Input_Type.snap +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "Message": "Variable `abc` is not an input type.", - "Code": "EXEC_NON_NULL_VIOLATION", - "Path": null, - "Locations": null, - "Extensions": { - "code": "EXEC_NON_NULL_VIOLATION", - "variable": "abc", - "type": "Human" - }, - "Exception": null - } -] diff --git a/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/CodeFirstTests.ExecuteOneFieldQueryWithQuery.snap b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/CodeFirstTests.ExecuteOneFieldQueryWithQuery.snap new file mode 100644 index 00000000000..f9bb2f97588 --- /dev/null +++ b/src/HotChocolate/Core/test/Execution.Tests/__snapshots__/CodeFirstTests.ExecuteOneFieldQueryWithQuery.snap @@ -0,0 +1,14 @@ +{ + "Label": null, + "Path": null, + "Data": { + "query": [ + "foo", + "bar" + ] + }, + "Errors": null, + "Extensions": null, + "ContextData": null, + "HasNext": null +} diff --git a/src/HotChocolate/Core/test/Types.Tests/Internal/ExtendedTypeTests.cs b/src/HotChocolate/Core/test/Types.Tests/Internal/ExtendedTypeTests.cs index 169e2c6bc85..b94e8855042 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Internal/ExtendedTypeTests.cs +++ b/src/HotChocolate/Core/test/Types.Tests/Internal/ExtendedTypeTests.cs @@ -301,6 +301,7 @@ public void IsEqual_Object_Byte_String_False() [InlineData(typeof(IEnumerable), "IEnumerable", "String")] [InlineData(typeof(IReadOnlyCollection), "IReadOnlyCollection", "String")] [InlineData(typeof(IReadOnlyList), "IReadOnlyList", "String")] + [InlineData(typeof(IQuery), "IQuery", "String")] [InlineData(typeof(string[]), "[String]", "String")] [InlineData( typeof(Task>), @@ -328,6 +329,7 @@ public void SupportedListTypes(Type type, string listTypeName, string elementTyp [InlineData(typeof(CustomStringList2))] [InlineData(typeof(ImmutableArray))] [InlineData(typeof(IEnumerable))] + [InlineData(typeof(IQuery))] [InlineData(typeof(Task>))] [InlineData(typeof(ValueTask>))] [Theory] @@ -345,10 +347,10 @@ public void ChangeNullability_From_ElementType(Type listType) } [Fact] - public void NullableOptionalNullableString() + public void NullableOptionalNullableString() { // arrange - MethodInfo member = + MethodInfo member = typeof(Nullability).GetMethod(nameof(Nullability.NullableOptionalNullableString))!; // act @@ -359,10 +361,10 @@ public void NullableOptionalNullableString() } [Fact] - public void OptionalNullableOptionalNullableString() + public void OptionalNullableOptionalNullableString() { // arrange - MethodInfo member = + MethodInfo member = typeof(Nullability) .GetMethod(nameof(Nullability.OptionalNullableOptionalNullableString))!; @@ -373,6 +375,20 @@ public void OptionalNullableOptionalNullableString() Assert.Equal("Optional>!", type.ToString()); } + [Fact] + public void From_IQueryScalar() + { + // arrange + // act + ExtendedType dict = ExtendedType.FromType( + typeof(IQuery), + _cache); + + // assert + Assert.True(dict.IsList); + Assert.True(dict.IsArrayOrList); + } + private class CustomStringList1 : List { @@ -394,11 +410,11 @@ private class CustomStringList3 #nullable enable public class Nullability - { - public Nullable> NullableOptionalNullableString() => + { + public Nullable> NullableOptionalNullableString() => throw new NotImplementedException(); - public Optional>> OptionalNullableOptionalNullableString() => + public Optional>> OptionalNullableOptionalNullableString() => throw new NotImplementedException(); } diff --git a/src/HotChocolate/Core/test/Types.Tests/Internal/TypeInfoTests.cs b/src/HotChocolate/Core/test/Types.Tests/Internal/TypeInfoTests.cs index 6505d463c90..f81bcd64a5d 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Internal/TypeInfoTests.cs +++ b/src/HotChocolate/Core/test/Types.Tests/Internal/TypeInfoTests.cs @@ -60,6 +60,9 @@ public class TypeInfoTests [InlineData(typeof(IAsyncEnumerable), "[String]")] [InlineData(typeof(IEnumerable), "[String]")] [InlineData(typeof(IQueryable), "[String]")] + [InlineData(typeof(IQuery), "[String]")] + [InlineData(typeof(IQuery), "[String!]")] + [InlineData(typeof(IQuery), "[String]")] [Theory] public void CreateTypeInfoFromRuntimeType( Type clrType, @@ -84,6 +87,7 @@ public class TypeInfoTests [InlineData(typeof(IEnumerable), "[String]")] [InlineData(typeof(IReadOnlyCollection), "[String]")] [InlineData(typeof(IReadOnlyList), "[String]")] + [InlineData(typeof(IQuery), "[String]")] [InlineData(typeof(string[]), "[String]")] [Theory] public void SupportedListTypes(Type clrType, string expectedTypeName) @@ -152,6 +156,61 @@ public void NullableListNonNullElement() Assert.Equal("[String!]", typeInfo.CreateType(new StringType()).Print()); } + [Fact] + public void NonNullQueryNonNullElement() + { + // arrange + MethodInfo methodInfo = + typeof(Nullability).GetMethod(nameof(Nullability.NonNullQueryNonNullElement)); + + // act + var typeInfo = TypeInfo.Create(_typeInspector.GetReturnType(methodInfo!), _cache); + + // assert + Assert.Equal("[String!]!", typeInfo.CreateType(new StringType()).Print()); + } + + [Fact] + public void NonNullQueryNullableElement() + { + // arrange + MethodInfo methodInfo = + typeof(Nullability).GetMethod(nameof(Nullability.NonNullQueryNullableElement)); + + // act + var typeInfo = TypeInfo.Create(_typeInspector.GetReturnType(methodInfo!), _cache); + + // assert + Assert.Equal("[String]!", typeInfo.CreateType(new StringType()).Print()); + } + + [Fact] + public void NullableQueryNullableElement() + { + // arrange + MethodInfo methodInfo = + typeof(Nullability).GetMethod(nameof(Nullability.NullableQueryNullableElement)); + + // act + var typeInfo = TypeInfo.Create(_typeInspector.GetReturnType(methodInfo!), _cache); + + // assert + Assert.Equal("[String]", typeInfo.CreateType(new StringType()).Print()); + } + + [Fact] + public void NullableQueryNonNullElement() + { + // arrange + MethodInfo methodInfo = + typeof(Nullability).GetMethod(nameof(Nullability.NullableQueryNonNullElement)); + + // act + var typeInfo = TypeInfo.Create(_typeInspector.GetReturnType(methodInfo!), _cache); + + // assert + Assert.Equal("[String!]", typeInfo.CreateType(new StringType()).Print()); + } [Fact] public void NonNullCollectionNonNullElement() { @@ -538,6 +597,14 @@ public class Nullability public ICollection? NullableCollectionNonNullElement() => default; + public IQuery NonNullQueryNonNullElement() => default!; + + public IQuery NonNullQueryNullableElement() => default!; + + public IQuery? NullableQueryNullableElement() => default; + + public IQuery? NullableQueryNonNullElement() => default; + public string[] NonNullArrayNonNullElement() => default!; public string?[] NonNullArrayNullableElement() => default!; @@ -549,7 +616,7 @@ public class Nullability public List?>? NestedList() => default; public Optional OptionalNullableString() => default; - + public Nullable> NullableOptionalNullableString() => default; } From b44f9998ff25e1231198c35396f1b708eb9c9cc2 Mon Sep 17 00:00:00 2001 From: Pascal Senn Date: Fri, 16 Oct 2020 15:38:48 +0200 Subject: [PATCH 2/5] fix refactoring issue --- src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs b/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs index 249c87941b7..c1db8ad6cf9 100644 --- a/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs +++ b/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs @@ -67,7 +67,7 @@ private async ValueTask ExecuteResolverPipelineAsync() switch (_context.Result) { case HotChocolate.IQuery query: - _context.Result = await query.ExecuteAsync(_context); + _context.Result = await query.ExecuteAsync(_context.RequestAborted); break; case IQueryable queryable: From 3ca2178e8c9cabad1e9f0680d42332c9d0b1620a Mon Sep 17 00:00:00 2001 From: Pascal Senn Date: Fri, 16 Oct 2020 17:10:52 +0200 Subject: [PATCH 3/5] rename to executable --- .../Core/src/Abstractions/{IQuery.cs => IExecutable.cs} | 0 .../Core/src/Abstractions/{IQuery~1.cs => IExecutable~1.cs} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/HotChocolate/Core/src/Abstractions/{IQuery.cs => IExecutable.cs} (100%) rename src/HotChocolate/Core/src/Abstractions/{IQuery~1.cs => IExecutable~1.cs} (81%) diff --git a/src/HotChocolate/Core/src/Abstractions/IQuery.cs b/src/HotChocolate/Core/src/Abstractions/IExecutable.cs similarity index 100% rename from src/HotChocolate/Core/src/Abstractions/IQuery.cs rename to src/HotChocolate/Core/src/Abstractions/IExecutable.cs diff --git a/src/HotChocolate/Core/src/Abstractions/IQuery~1.cs b/src/HotChocolate/Core/src/Abstractions/IExecutable~1.cs similarity index 81% rename from src/HotChocolate/Core/src/Abstractions/IQuery~1.cs rename to src/HotChocolate/Core/src/Abstractions/IExecutable~1.cs index dcb68f93469..fbe7a0df091 100644 --- a/src/HotChocolate/Core/src/Abstractions/IQuery~1.cs +++ b/src/HotChocolate/Core/src/Abstractions/IExecutable~1.cs @@ -4,7 +4,7 @@ namespace HotChocolate { - public interface IQuery : IQuery + public interface IExecutable : IExecutable { new ValueTask> ExecuteAsync(CancellationToken cancellationToken); } From b902c2a3a0fbfa77a5dadeb642f8086b87657e63 Mon Sep 17 00:00:00 2001 From: Pascal Senn Date: Fri, 16 Oct 2020 17:11:15 +0200 Subject: [PATCH 4/5] rename to executable --- src/HotChocolate/Core/src/Abstractions/IExecutable.cs | 2 +- src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs | 2 +- src/HotChocolate/Core/src/Types/Internal/ExtendedType.Helper.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/HotChocolate/Core/src/Abstractions/IExecutable.cs b/src/HotChocolate/Core/src/Abstractions/IExecutable.cs index d3efa640fad..34bf6a02b72 100644 --- a/src/HotChocolate/Core/src/Abstractions/IExecutable.cs +++ b/src/HotChocolate/Core/src/Abstractions/IExecutable.cs @@ -3,7 +3,7 @@ namespace HotChocolate { - public interface IQuery + public interface IExecutable { ValueTask ExecuteAsync(CancellationToken cancellationToken); diff --git a/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs b/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs index c1db8ad6cf9..c7665f518ff 100644 --- a/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs +++ b/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs @@ -66,7 +66,7 @@ private async ValueTask ExecuteResolverPipelineAsync() switch (_context.Result) { - case HotChocolate.IQuery query: + case IExecutable query: _context.Result = await query.ExecuteAsync(_context.RequestAborted); break; diff --git a/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Helper.cs b/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Helper.cs index a2e2d0d80c1..72931324be9 100644 --- a/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Helper.cs +++ b/src/HotChocolate/Core/src/Types/Internal/ExtendedType.Helper.cs @@ -167,7 +167,7 @@ public static bool IsSupportedCollectionInterface(Type type) || typeDefinition == typeof(ImmutableQueue<>) || typeDefinition == typeof(ImmutableStack<>) || typeDefinition == typeof(ImmutableHashSet<>) - || typeDefinition == typeof(IQuery<>)) + || typeDefinition == typeof(IExecutable<>)) { return true; } From 70a4741f6c9bfe044286c8ee3e2d6448277cdd4a Mon Sep 17 00:00:00 2001 From: Pascal Senn Date: Fri, 16 Oct 2020 19:09:09 +0200 Subject: [PATCH 5/5] fix tests --- .../src/Execution/Processing/ResolverTask.cs | 4 ++-- .../Core/test/Execution.Tests/CodeFirstTests.cs | 6 +++--- .../Types.Tests/Internal/ExtendedTypeTests.cs | 8 ++++---- .../test/Types.Tests/Internal/TypeInfoTests.cs | 16 ++++++++-------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs b/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs index c7665f518ff..54260923ae9 100644 --- a/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs +++ b/src/HotChocolate/Core/src/Execution/Processing/ResolverTask.cs @@ -66,8 +66,8 @@ private async ValueTask ExecuteResolverPipelineAsync() switch (_context.Result) { - case IExecutable query: - _context.Result = await query.ExecuteAsync(_context.RequestAborted); + case IExecutable executable: + _context.Result = await executable.ExecuteAsync(_context.RequestAborted); break; case IQueryable queryable: diff --git a/src/HotChocolate/Core/test/Execution.Tests/CodeFirstTests.cs b/src/HotChocolate/Core/test/Execution.Tests/CodeFirstTests.cs index f63067690c4..e42c2661a84 100644 --- a/src/HotChocolate/Core/test/Execution.Tests/CodeFirstTests.cs +++ b/src/HotChocolate/Core/test/Execution.Tests/CodeFirstTests.cs @@ -284,7 +284,7 @@ public string GetTest() return "Hello World!"; } - public IQuery GetQuery() + public IExecutable GetQuery() { return MockQuery.From("foo", "bar"); } @@ -462,7 +462,7 @@ public class DogType } } - public class MockQuery : IQuery + public class MockQuery : IExecutable { private readonly IReadOnlyList _list; @@ -471,7 +471,7 @@ private MockQuery(IEnumerable list) _list = list.ToArray(); } - async ValueTask IQuery.ExecuteAsync(CancellationToken cancellationToken) + async ValueTask IExecutable.ExecuteAsync(CancellationToken cancellationToken) { return await ExecuteAsync(cancellationToken); } diff --git a/src/HotChocolate/Core/test/Types.Tests/Internal/ExtendedTypeTests.cs b/src/HotChocolate/Core/test/Types.Tests/Internal/ExtendedTypeTests.cs index b94e8855042..050b70a47e8 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Internal/ExtendedTypeTests.cs +++ b/src/HotChocolate/Core/test/Types.Tests/Internal/ExtendedTypeTests.cs @@ -301,7 +301,7 @@ public void IsEqual_Object_Byte_String_False() [InlineData(typeof(IEnumerable), "IEnumerable", "String")] [InlineData(typeof(IReadOnlyCollection), "IReadOnlyCollection", "String")] [InlineData(typeof(IReadOnlyList), "IReadOnlyList", "String")] - [InlineData(typeof(IQuery), "IQuery", "String")] + [InlineData(typeof(IExecutable), "IExecutable", "String")] [InlineData(typeof(string[]), "[String]", "String")] [InlineData( typeof(Task>), @@ -329,7 +329,7 @@ public void SupportedListTypes(Type type, string listTypeName, string elementTyp [InlineData(typeof(CustomStringList2))] [InlineData(typeof(ImmutableArray))] [InlineData(typeof(IEnumerable))] - [InlineData(typeof(IQuery))] + [InlineData(typeof(IExecutable))] [InlineData(typeof(Task>))] [InlineData(typeof(ValueTask>))] [Theory] @@ -376,12 +376,12 @@ public void OptionalNullableOptionalNullableString() } [Fact] - public void From_IQueryScalar() + public void From_IExecutableScalar() { // arrange // act ExtendedType dict = ExtendedType.FromType( - typeof(IQuery), + typeof(IExecutable), _cache); // assert diff --git a/src/HotChocolate/Core/test/Types.Tests/Internal/TypeInfoTests.cs b/src/HotChocolate/Core/test/Types.Tests/Internal/TypeInfoTests.cs index f81bcd64a5d..04a27c2e1ba 100644 --- a/src/HotChocolate/Core/test/Types.Tests/Internal/TypeInfoTests.cs +++ b/src/HotChocolate/Core/test/Types.Tests/Internal/TypeInfoTests.cs @@ -60,9 +60,9 @@ public class TypeInfoTests [InlineData(typeof(IAsyncEnumerable), "[String]")] [InlineData(typeof(IEnumerable), "[String]")] [InlineData(typeof(IQueryable), "[String]")] - [InlineData(typeof(IQuery), "[String]")] - [InlineData(typeof(IQuery), "[String!]")] - [InlineData(typeof(IQuery), "[String]")] + [InlineData(typeof(IExecutable), "[String]")] + [InlineData(typeof(IExecutable), "[String!]")] + [InlineData(typeof(IExecutable), "[String]")] [Theory] public void CreateTypeInfoFromRuntimeType( Type clrType, @@ -87,7 +87,7 @@ public class TypeInfoTests [InlineData(typeof(IEnumerable), "[String]")] [InlineData(typeof(IReadOnlyCollection), "[String]")] [InlineData(typeof(IReadOnlyList), "[String]")] - [InlineData(typeof(IQuery), "[String]")] + [InlineData(typeof(IExecutable), "[String]")] [InlineData(typeof(string[]), "[String]")] [Theory] public void SupportedListTypes(Type clrType, string expectedTypeName) @@ -597,13 +597,13 @@ public class Nullability public ICollection? NullableCollectionNonNullElement() => default; - public IQuery NonNullQueryNonNullElement() => default!; + public IExecutable NonNullQueryNonNullElement() => default!; - public IQuery NonNullQueryNullableElement() => default!; + public IExecutable NonNullQueryNullableElement() => default!; - public IQuery? NullableQueryNullableElement() => default; + public IExecutable? NullableQueryNullableElement() => default; - public IQuery? NullableQueryNonNullElement() => default; + public IExecutable? NullableQueryNonNullElement() => default; public string[] NonNullArrayNonNullElement() => default!;