diff --git a/src/StrawberryShake/Client/src/Core/OperationExecutor.Observable.cs b/src/StrawberryShake/Client/src/Core/OperationExecutor.Observable.cs index 8b92f082dff..3de7e558200 100644 --- a/src/StrawberryShake/Client/src/Core/OperationExecutor.Observable.cs +++ b/src/StrawberryShake/Client/src/Core/OperationExecutor.Observable.cs @@ -129,6 +129,10 @@ public IDisposable Subscribe(IObserver> observer) } finally { + // call observer's OnCompleted method to notify observer + // there is no further data is available. + observer.OnCompleted(); + // after all the transport logic is finished we will dispose // the request session. session.RequestSession.Dispose(); diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/StarWarsOnReviewSubCompletionTest.Client.cs b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/StarWarsOnReviewSubCompletionTest.Client.cs new file mode 100644 index 00000000000..7c17e8957a2 --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/StarWarsOnReviewSubCompletionTest.Client.cs @@ -0,0 +1,651 @@ +// ReSharper disable BuiltInTypeReferenceStyle +// ReSharper disable RedundantNameQualifier +// ReSharper disable ArrangeObjectCreationWhenTypeEvident +// ReSharper disable UnusedType.Global +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable UnusedMethodReturnValue.Local +// ReSharper disable ConvertToAutoProperty +// ReSharper disable UnusedMember.Global +// ReSharper disable SuggestVarOrType_SimpleTypes +// ReSharper disable InconsistentNaming + +// StarWarsOnReviewSubCompletionClient + +// +#nullable enable + +namespace Microsoft.Extensions.DependencyInjection +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.DependencyInjectionGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public static partial class StarWarsOnReviewSubCompletionClientServiceCollectionExtensions + { + public static global::StrawberryShake.IClientBuilder AddStarWarsOnReviewSubCompletionClient(this global::Microsoft.Extensions.DependencyInjection.IServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly, global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.StarWarsOnReviewSubCompletionClientProfileKind profile = global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.StarWarsOnReviewSubCompletionClientProfileKind.InMemory) + { + var serviceCollection = new global::Microsoft.Extensions.DependencyInjection.ServiceCollection(); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + if (profile == global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.StarWarsOnReviewSubCompletionClientProfileKind.InMemory) + { + ConfigureClientInMemory(sp, serviceCollection, strategy); + } + else if (profile == global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.StarWarsOnReviewSubCompletionClientProfileKind.Default) + { + ConfigureClientDefault(sp, serviceCollection, strategy); + } + + return new ClientServiceProvider(global::Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(serviceCollection)); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.StarWarsOnReviewSubCompletionClientStoreAccessor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + return new global::StrawberryShake.ClientBuilder("StarWarsOnReviewSubCompletionClient", services, serviceCollection); + } + + private static global::Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureClientInMemory(global::System.IServiceProvider parentServices, global::Microsoft.Extensions.DependencyInjection.ServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services, sp => new global::StrawberryShake.OperationStore(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + var clientFactory = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(parentServices); + return new global::StrawberryShake.Transport.InMemory.InMemoryConnection(async ct => await clientFactory.CreateAsync("StarWarsOnReviewSubCompletionClient", ct)); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::StrawberryShake.Serialization.SerializerResolver(global::System.Linq.Enumerable.Concat(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(parentServices), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.OnReviewSubResultFactory>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.OnReviewSubBuilder>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, sp => new global::StrawberryShake.OperationExecutor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), strategy)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.Json.JsonResultPatcher>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + return services; + } + + private static global::Microsoft.Extensions.DependencyInjection.IServiceCollection ConfigureClientDefault(global::System.IServiceProvider parentServices, global::Microsoft.Extensions.DependencyInjection.ServiceCollection services, global::StrawberryShake.ExecutionStrategy strategy = global::StrawberryShake.ExecutionStrategy.NetworkOnly) + { + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton(services, sp => new global::StrawberryShake.OperationStore(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => + { + var sessionPool = global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(parentServices); + return new global::StrawberryShake.Transport.WebSockets.WebSocketConnection(async ct => await sessionPool.CreateAsync("StarWarsOnReviewSubCompletionClient", ct)); + }); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => new global::StrawberryShake.Serialization.SerializerResolver(global::System.Linq.Enumerable.Concat(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(parentServices), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)))); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.OnReviewSubResultFactory>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.OnReviewSubBuilder>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, sp => new global::StrawberryShake.OperationExecutor(global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), () => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService>(sp), global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp), strategy)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton, global::StrawberryShake.Json.JsonResultPatcher>(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services); + global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(services, sp => global::Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(sp)); + return services; + } + + private sealed class ClientServiceProvider : System.IServiceProvider, System.IDisposable + { + private readonly System.IServiceProvider _provider; + public ClientServiceProvider(System.IServiceProvider provider) + { + _provider = provider; + } + + public object? GetService(System.Type serviceType) + { + return _provider.GetService(serviceType); + } + + public void Dispose() + { + if (_provider is System.IDisposable d) + { + d.Dispose(); + } + } + } + } +} + +namespace StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class OnReviewSubResult : global::System.IEquatable, IOnReviewSubResult + { + public OnReviewSubResult(global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSub_OnReview onReview) + { + OnReview = onReview; + } + + public global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSub_OnReview OnReview { get; } + + public virtual global::System.Boolean Equals(OnReviewSubResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (OnReview.Equals(other.OnReview)); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((OnReviewSubResult)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * OnReview.GetHashCode(); + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class OnReviewSub_OnReview_Review : global::System.IEquatable, IOnReviewSub_OnReview_Review + { + public OnReviewSub_OnReview_Review(global::System.String __typename, global::System.Int32 stars, global::System.String? commentary) + { + this.__typename = __typename; + Stars = stars; + Commentary = commentary; + } + + /// + /// The name of the current Object type at runtime. + /// + public global::System.String __typename { get; } + + public global::System.Int32 Stars { get; } + + public global::System.String? Commentary { get; } + + public virtual global::System.Boolean Equals(OnReviewSub_OnReview_Review? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != GetType()) + { + return false; + } + + return (__typename.Equals(other.__typename)) && Stars == other.Stars && ((Commentary is null && other.Commentary is null) || Commentary != null && Commentary.Equals(other.Commentary)); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + if (ReferenceEquals(null, obj)) + { + return false; + } + + if (ReferenceEquals(this, obj)) + { + return true; + } + + if (obj.GetType() != GetType()) + { + return false; + } + + return Equals((OnReviewSub_OnReview_Review)obj); + } + + public override global::System.Int32 GetHashCode() + { + unchecked + { + int hash = 5; + hash ^= 397 * __typename.GetHashCode(); + hash ^= 397 * Stars.GetHashCode(); + if (Commentary != null) + { + hash ^= 397 * Commentary.GetHashCode(); + } + + return hash; + } + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IOnReviewSubResult + { + public global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSub_OnReview OnReview { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IOnReviewSub_OnReview + { + /// + /// The name of the current Object type at runtime. + /// + public global::System.String __typename { get; } + + public global::System.Int32 Stars { get; } + + public global::System.String? Commentary { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInterfaceGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IOnReviewSub_OnReview_Review : IOnReviewSub_OnReview + { + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationDocumentGenerator + /// + /// Represents the operation service of the OnReviewSub GraphQL operation + /// + /// subscription OnReviewSub { + /// onReview(episode: NEW_HOPE) { + /// __typename + /// stars + /// commentary + /// } + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class OnReviewSubSubscriptionDocument : global::StrawberryShake.IDocument + { + private OnReviewSubSubscriptionDocument() + { + } + + public static OnReviewSubSubscriptionDocument Instance { get; } = new OnReviewSubSubscriptionDocument(); + public global::StrawberryShake.OperationKind Kind => global::StrawberryShake.OperationKind.Subscription; + public global::System.ReadOnlySpan Body => new global::System.Byte[]{0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x6e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x53, 0x75, 0x62, 0x20, 0x7b, 0x20, 0x6f, 0x6e, 0x52, 0x65, 0x76, 0x69, 0x65, 0x77, 0x28, 0x65, 0x70, 0x69, 0x73, 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x4e, 0x45, 0x57, 0x5f, 0x48, 0x4f, 0x50, 0x45, 0x29, 0x20, 0x7b, 0x20, 0x5f, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x20, 0x7d, 0x20, 0x7d}; + public global::StrawberryShake.DocumentHash Hash { get; } = new global::StrawberryShake.DocumentHash("sha1Hash", "92220fce37342d7ade3d63a2a81342eb1fb14bac"); + public override global::System.String ToString() + { +#if NETCOREAPP3_1_OR_GREATER + return global::System.Text.Encoding.UTF8.GetString(Body); +#else + return global::System.Text.Encoding.UTF8.GetString(Body.ToArray()); +#endif + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceGenerator + /// + /// Represents the operation service of the OnReviewSub GraphQL operation + /// + /// subscription OnReviewSub { + /// onReview(episode: NEW_HOPE) { + /// __typename + /// stars + /// commentary + /// } + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class OnReviewSubSubscription : global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSubSubscription + { + private readonly global::StrawberryShake.IOperationExecutor _operationExecutor; + public OnReviewSubSubscription(global::StrawberryShake.IOperationExecutor operationExecutor) + { + _operationExecutor = operationExecutor ?? throw new global::System.ArgumentNullException(nameof(operationExecutor)); + } + + global::System.Type global::StrawberryShake.IOperationRequestFactory.ResultType => typeof(IOnReviewSubResult); + public global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null) + { + var request = CreateRequest(); + return _operationExecutor.Watch(request, strategy); + } + + private global::StrawberryShake.OperationRequest CreateRequest() + { + return CreateRequest(null); + } + + private global::StrawberryShake.OperationRequest CreateRequest(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return new global::StrawberryShake.OperationRequest(id: OnReviewSubSubscriptionDocument.Instance.Hash.Value, name: "OnReviewSub", document: OnReviewSubSubscriptionDocument.Instance, strategy: global::StrawberryShake.RequestStrategy.Default); + } + + global::StrawberryShake.OperationRequest global::StrawberryShake.IOperationRequestFactory.Create(global::System.Collections.Generic.IReadOnlyDictionary? variables) + { + return CreateRequest(); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.OperationServiceInterfaceGenerator + /// + /// Represents the operation service of the OnReviewSub GraphQL operation + /// + /// subscription OnReviewSub { + /// onReview(episode: NEW_HOPE) { + /// __typename + /// stars + /// commentary + /// } + /// } + /// + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IOnReviewSubSubscription : global::StrawberryShake.IOperationRequestFactory + { + global::System.IObservable> Watch(global::StrawberryShake.ExecutionStrategy? strategy = null); + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientGenerator + /// + /// Represents the StarWarsOnReviewSubCompletionClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class StarWarsOnReviewSubCompletionClient : global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IStarWarsOnReviewSubCompletionClient + { + private readonly global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSubSubscription _onReviewSub; + public StarWarsOnReviewSubCompletionClient(global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSubSubscription onReviewSub) + { + _onReviewSub = onReviewSub ?? throw new global::System.ArgumentNullException(nameof(onReviewSub)); + } + + public static global::System.String ClientName => "StarWarsOnReviewSubCompletionClient"; + public global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSubSubscription OnReviewSub => _onReviewSub; + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ClientInterfaceGenerator + /// + /// Represents the StarWarsOnReviewSubCompletionClient GraphQL client + /// + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial interface IStarWarsOnReviewSubCompletionClient + { + global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSubSubscription OnReviewSub { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.TransportProfileEnumGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public enum StarWarsOnReviewSubCompletionClientProfileKind + { + InMemory, + Default + } +} + +namespace StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State +{ + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultDataFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class OnReviewSubResultFactory : global::StrawberryShake.IOperationResultDataFactory + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + public OnReviewSubResultFactory(global::StrawberryShake.IEntityStore entityStore) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + } + + global::System.Type global::StrawberryShake.IOperationResultDataFactory.ResultType => typeof(global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSubResult); + public OnReviewSubResult Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot = null) + { + if (snapshot is null) + { + snapshot = _entityStore.CurrentSnapshot; + } + + if (dataInfo is OnReviewSubResultInfo info) + { + return new OnReviewSubResult(MapNonNullableIOnReviewSub_OnReview(info.OnReview, snapshot)); + } + + throw new global::System.ArgumentException("OnReviewSubResultInfo expected."); + } + + private global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.IOnReviewSub_OnReview MapNonNullableIOnReviewSub_OnReview(global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.ReviewData data, global::StrawberryShake.IEntityStoreSnapshot snapshot) + { + IOnReviewSub_OnReview returnValue = default !; + if (data.__typename.Equals("Review", global::System.StringComparison.Ordinal)) + { + returnValue = new OnReviewSub_OnReview_Review(data.__typename ?? throw new global::System.ArgumentNullException(), data.Stars ?? throw new global::System.ArgumentNullException(), data.Commentary); + } + else + { + throw new global::System.NotSupportedException(); + } + + return returnValue; + } + + global::System.Object global::StrawberryShake.IOperationResultDataFactory.Create(global::StrawberryShake.IOperationResultDataInfo dataInfo, global::StrawberryShake.IEntityStoreSnapshot? snapshot) + { + return Create(dataInfo, snapshot); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.ResultInfoGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class OnReviewSubResultInfo : global::StrawberryShake.IOperationResultDataInfo + { + private readonly global::System.Collections.Generic.IReadOnlyCollection _entityIds; + private readonly global::System.UInt64 _version; + public OnReviewSubResultInfo(global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.ReviewData onReview, global::System.Collections.Generic.IReadOnlyCollection entityIds, global::System.UInt64 version) + { + OnReview = onReview; + _entityIds = entityIds ?? throw new global::System.ArgumentNullException(nameof(entityIds)); + _version = version; + } + + public global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.ReviewData OnReview { get; } + + public global::System.Collections.Generic.IReadOnlyCollection EntityIds => _entityIds; + public global::System.UInt64 Version => _version; + public global::StrawberryShake.IOperationResultDataInfo WithVersion(global::System.UInt64 version) + { + return new OnReviewSubResultInfo(OnReview, _entityIds, version); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.JsonResultBuilderGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class OnReviewSubBuilder : global::StrawberryShake.OperationResultBuilder + { + private readonly global::StrawberryShake.IEntityStore _entityStore; + private readonly global::StrawberryShake.IEntityIdSerializer _idSerializer; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _stringParser; + private readonly global::StrawberryShake.Serialization.ILeafValueParser _intParser; + public OnReviewSubBuilder(global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer idSerializer, global::StrawberryShake.IOperationResultDataFactory resultDataFactory, global::StrawberryShake.Serialization.ISerializerResolver serializerResolver) + { + _entityStore = entityStore ?? throw new global::System.ArgumentNullException(nameof(entityStore)); + _idSerializer = idSerializer ?? throw new global::System.ArgumentNullException(nameof(idSerializer)); + ResultDataFactory = resultDataFactory ?? throw new global::System.ArgumentNullException(nameof(resultDataFactory)); + _stringParser = serializerResolver.GetLeafValueParser("String") ?? throw new global::System.ArgumentException("No serializer for type `String` found."); + _intParser = serializerResolver.GetLeafValueParser("Int") ?? throw new global::System.ArgumentException("No serializer for type `Int` found."); + } + + protected override global::StrawberryShake.IOperationResultDataFactory ResultDataFactory { get; } + + protected override global::StrawberryShake.IOperationResultDataInfo BuildData(global::System.Text.Json.JsonElement obj) + { + var entityIds = new global::System.Collections.Generic.HashSet(); + global::StrawberryShake.IEntityStoreSnapshot snapshot = default !; + _entityStore.Update(session => + { + snapshot = session.CurrentSnapshot; + }); + return new OnReviewSubResultInfo(Deserialize_NonNullableIOnReviewSub_OnReview(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "onReview")), entityIds, snapshot.Version); + } + + private global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.ReviewData Deserialize_NonNullableIOnReviewSub_OnReview(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + throw new global::System.ArgumentNullException(); + } + + var typename = obj.Value.GetProperty("__typename").GetString(); + if (typename?.Equals("Review", global::System.StringComparison.Ordinal) ?? false) + { + return new global::StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion.State.ReviewData(typename, stars: Deserialize_NonNullableInt32(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "stars")), commentary: Deserialize_String(global::StrawberryShake.Json.JsonElementExtensions.GetPropertyOrNull(obj, "commentary"))); + } + + throw new global::System.NotSupportedException(); + } + + private global::System.String Deserialize_NonNullableString(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + throw new global::System.ArgumentNullException(); + } + + return _stringParser.Parse(obj.Value.GetString()!); + } + + private global::System.Int32 Deserialize_NonNullableInt32(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + throw new global::System.ArgumentNullException(); + } + + return _intParser.Parse(obj.Value.GetInt32()!); + } + + private global::System.String? Deserialize_String(global::System.Text.Json.JsonElement? obj) + { + if (!obj.HasValue) + { + return null; + } + + return _stringParser.Parse(obj.Value.GetString()!); + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.DataTypeGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "0.0.0.0")] + public partial class ReviewData + { + public ReviewData(global::System.String __typename, global::System.Int32? stars = default !, global::System.String? commentary = default !) + { + this.__typename = __typename ?? throw new global::System.ArgumentNullException(nameof(__typename)); + Stars = stars; + Commentary = commentary; + } + + public global::System.String __typename { get; } + + public global::System.Int32? Stars { get; } + + public global::System.String? Commentary { get; } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.EntityIdFactoryGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class StarWarsOnReviewSubCompletionClientEntityIdFactory : global::StrawberryShake.IEntityIdSerializer + { + private static readonly global::System.Text.Json.JsonWriterOptions _options = new global::System.Text.Json.JsonWriterOptions() + {Indented = false}; + public global::StrawberryShake.EntityId Parse(global::System.Text.Json.JsonElement obj) + { + global::System.String __typename = obj.GetProperty("__typename").GetString()!; + return __typename switch + { + _ => throw new global::System.NotSupportedException()}; + } + + public global::System.String Format(global::StrawberryShake.EntityId entityId) + { + return entityId.Name switch + { + _ => throw new global::System.NotSupportedException()}; + } + } + + // StrawberryShake.CodeGeneration.CSharp.Generators.StoreAccessorGenerator + [global::System.CodeDom.Compiler.GeneratedCode("StrawberryShake", "11.0.0")] + public partial class StarWarsOnReviewSubCompletionClientStoreAccessor : global::StrawberryShake.StoreAccessor + { + public StarWarsOnReviewSubCompletionClientStoreAccessor(global::StrawberryShake.IOperationStore operationStore, global::StrawberryShake.IEntityStore entityStore, global::StrawberryShake.IEntityIdSerializer entityIdSerializer, global::System.Collections.Generic.IEnumerable requestFactories, global::System.Collections.Generic.IEnumerable resultDataFactories) : base(operationStore, entityStore, entityIdSerializer, requestFactories, resultDataFactories) + { + } + } +} + + diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/StarWarsOnReviewSubCompletionTest.cs b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/StarWarsOnReviewSubCompletionTest.cs new file mode 100644 index 00000000000..a57596b140c --- /dev/null +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/StarWarsOnReviewSubCompletionTest.cs @@ -0,0 +1,73 @@ +using System; +using System.Threading.Tasks; +using HotChocolate.AspNetCore.Tests.Utilities; +using HotChocolate.StarWars.Models; +using HotChocolate.Subscriptions; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using StrawberryShake.Transport.WebSockets; +using Xunit; + +namespace StrawberryShake.CodeGeneration.CSharp.Integration.StarWarsOnReviewSubCompletion +{ + public class StarWarsOnReviewSubCompletionTest : ServerTestBase + { + public StarWarsOnReviewSubCompletionTest(TestServerFactory serverFactory) : base(serverFactory) + { + } + + [Fact] + public async Task Watch_StarWarsOnReviewSubCompletion_Test() + { + // arrange + using IWebHost host = TestServerHelper.CreateServer( + _ => { }, + out var port); + var topicEventSender = host.Services.GetRequiredService(); + + var serviceCollection = new ServiceCollection(); + serviceCollection.AddStarWarsOnReviewSubCompletionClient( + profile: StarWarsOnReviewSubCompletionClientProfileKind.Default) + .ConfigureHttpClient( + c => c.BaseAddress = new Uri("http://localhost:" + port + "/graphql")) + .ConfigureWebSocketClient( + c => c.Uri = new Uri("ws://localhost:" + port + "/graphql")); + + // act + IServiceProvider services = serviceCollection.BuildServiceProvider(); + IStarWarsOnReviewSubCompletionClient client = services.GetRequiredService(); + + string? commentary = null; + bool completionTriggered = false; + + var sub = client.OnReviewSub.Watch(); + var session = sub.Subscribe( + result => commentary = result.Data?.OnReview?.Commentary, + () => completionTriggered = true); + + var topic = Episode.NewHope; + + // try to send message 10 times + // make sure the subscription connection is successful + for(int times = 0; commentary is null && times < 10; times++) + { + await topicEventSender.SendAsync(topic, new Review { Stars = 1, Commentary = "Commentary" }); + await Task.Delay(1_000); + } + + // complete the topic of subscription from server + await topicEventSender.CompleteAsync(topic); + + // waiting for completion message sent + for (int times = 0; !completionTriggered && times < 10; times++) + { + await Task.Delay(1_000); + } + + session.Dispose(); + + // assert + Assert.True(commentary is not null && completionTriggered); + } + } +} diff --git a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/TestGeneration.cs b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/TestGeneration.cs index 0b534fde5f4..bbecf2f29f3 100644 --- a/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/TestGeneration.cs +++ b/src/StrawberryShake/CodeGeneration/test/CodeGeneration.CSharp.Tests/Integration/TestGeneration.cs @@ -226,6 +226,22 @@ public class TestGeneration name }"); + [Fact] + public void StarWarsOnReviewSubCompletion() => + AssertStarWarsResult( + CreateIntegrationTest(profiles: new[] + { + new TransportProfile("InMemory", TransportType.InMemory), + TransportProfile.Default + }), + @"subscription OnReviewSub { + onReview(episode: NEW_HOPE) { + __typename + stars + commentary + } + }"); + /* [Fact] public void StarWarsGetFriendsDeferredData() =>