public async Task OnComplete_can_be_used_to_act_on_completion_of_commands() { using var kernel = new FakeKernel(); using var events = kernel.KernelEvents.ToSubscribedList(); kernel.AddDirective(new Command("#!wrap") { Handler = CommandHandler.Create(async(KernelInvocationContext c) => { await c.DisplayAsync("hello!"); c.OnComplete(async context => { await context.DisplayAsync("goodbye!"); }); }) }); await kernel.SubmitCodeAsync("#!wrap"); events .OfType <DisplayedValueProduced>() .Select(e => e.Value) .Should() .BeEquivalentSequenceTo("hello!", "goodbye!"); }
public async Task When_command_handler_registered_in_child_kernel_and_command_sent_to_parent_then_handler_is_executed() { using var compositeKernel = new CompositeKernel(); var childKernel = new FakeKernel(); compositeKernel.Add(childKernel); CustomCommandTypes.FirstSubmission.MyCommand commandPassedToHandler = null; KernelInvocationContext contextPassedToHandler = null; childKernel.RegisterCommandHandler <CustomCommandTypes.FirstSubmission.MyCommand>( (command, context) => { commandPassedToHandler = command; contextPassedToHandler = context; return(Task.CompletedTask); }); var commandSentToCompositeKernel = new CustomCommandTypes.FirstSubmission.MyCommand("xyzzy"); await compositeKernel.SendAsync(commandSentToCompositeKernel); commandPassedToHandler .Should() .BeSameAs(commandSentToCompositeKernel); contextPassedToHandler .Should() .NotBeNull(); }
public async Task Middleware_is_only_executed_once_per_command() { var middeware1Count = 0; var middeware2Count = 0; var middeware3Count = 0; using var kernel = new FakeKernel(); kernel.AddMiddleware(async(command, context, next) => { middeware1Count++; await next(command, context); }, "one"); kernel.AddMiddleware(async(command, context, next) => { middeware2Count++; await next(command, context); }, "two"); kernel.AddMiddleware(async(command, context, next) => { middeware3Count++; await next(command, context); }, "three"); await kernel.SendAsync(new SubmitCode("123")); middeware1Count.Should().Be(1); middeware2Count.Should().Be(1); middeware3Count.Should().Be(1); }
public async Task Handling_kernel_can_be_specified_as_a_default_via_an_alias() { var receivedOnFakeKernel = new List <KernelCommand>(); var fakeKernel = new FakeKernel("fake") { Handle = (command, context) => { receivedOnFakeKernel.Add(command); return(Task.CompletedTask); } }; using var kernel = new CompositeKernel { new CSharpKernel() }; kernel.Add(fakeKernel, new[] { "totally-fake" }); kernel.DefaultKernelName = "totally-fake"; await kernel.SendAsync( new SubmitCode( @"hello!")); receivedOnFakeKernel .Should() .ContainSingle(c => c is SubmitCode) .Which .As <SubmitCode>() .Code .Should() .Be("hello!"); }
public async Task Queued_initialization_command_is_executed_on_to_first_submission() { var receivedCommands = new List <IKernelCommand>(); var kernel = new FakeKernel { Handle = (command, context) => { receivedCommands.Add(command); return(Task.CompletedTask); } }; using var events = kernel.KernelEvents.ToSubscribedList(); kernel.DeferCommand(new SubmitCode("one")); kernel.DeferCommand(new SubmitCode("two")); await kernel.SendAsync(new SubmitCode("three")); var x = receivedCommands .Select(c => c is SubmitCode submitCode ? submitCode.Code : c.ToString()) .Should() .BeEquivalentSequenceTo("one", "two", "three"); }
public void When_command_type_registered_then_kernel_registers_envelope_type_for_serialization(bool withHandler) { Microsoft.DotNet.Interactive.Server.KernelCommandEnvelope.ResetToDefaults(); using var kernel = new FakeKernel(); if (withHandler) { kernel.RegisterCommandHandler <CustomCommandTypes.FirstSubmission.MyCommand>( (_, _) => Task.CompletedTask); } else { kernel.RegisterCommandType <CustomCommandTypes.FirstSubmission.MyCommand>(); } var originalCommand = new CustomCommandTypes.FirstSubmission.MyCommand("xyzzy"); string envelopeJson = Microsoft.DotNet.Interactive.Server.KernelCommandEnvelope.Serialize(originalCommand); var roundTrippedCommandEnvelope = Microsoft.DotNet.Interactive.Server.KernelCommandEnvelope.Deserialize(envelopeJson); roundTrippedCommandEnvelope .Command .Should() .BeOfType <CustomCommandTypes.FirstSubmission.MyCommand>() .Which .Info .Should() .Be(originalCommand.Info); }
public async Task kernelEvents_sequence_completes_when_kernel_is_disposed() { var kernel = new FakeKernel(); var events = kernel.KernelEvents.Timeout(5.Seconds()).LastOrDefaultAsync(); kernel.Dispose(); var lastEvent = await events; lastEvent.Should().BeNull(); }
public void Return_the_list_of_supported_commands() { using var kernel = new FakeKernel(); kernel.RegisterCommandType <CustomCommandTypes.FirstSubmission.MyCommand>(); kernel.RegisterCommandType <CustomCommandTypes.SecondSubmission.MyCommand>(); var supportedCommands = kernel.SupportedCommands(); supportedCommands.Should().ContainInOrder(typeof(SubmitCode), typeof(CustomCommandTypes.FirstSubmission.MyCommand), typeof(CustomCommandTypes.SecondSubmission.MyCommand)); }
public async Task hover_on_unsupported_language_service_returns_nothing() { using var kernel = new FakeKernel(); var commandResult = await SendHoverRequest(kernel, "code", 0, 0); commandResult .KernelEvents .ToSubscribedList() .Should() .NotContain(kv => kv.GetType().IsSubclassOf(typeof(HoverTextProduced))); }
public async Task Split_non_referencing_directives_are_executed_in_textual_order() { var receivedCommands = new List <string>(); using var kernel = new FakeKernel { Handle = (command, context) => { receivedCommands.Add(((SubmitCode)command).Code); return(Task.CompletedTask); } }; kernel.AddDirective(new Command("#!one") { Handler = CommandHandler.Create(() => { receivedCommands.Add("#!one"); }) }); kernel.AddDirective(new Command("#!two") { Handler = CommandHandler.Create(() => { receivedCommands.Add("#!two"); }) }); var code1 = "var a = 1"; var code2 = "var b = 2"; var code3 = "var c = 3"; var directive1 = "#!one"; var directive2 = "#!two"; await kernel.SubmitCodeAsync($@" {code1} {directive1} {code2} {directive2} {code3} "); receivedCommands .Select(c => c.Trim()) .Should() .BeEquivalentSequenceTo( code1, directive1, code2, directive2, code3); }
public void FindKernel_finds_a_subkernel_of_a_composite_kernel_by_alias() { var one = new FakeKernel("one"); var two = new FakeKernel("two"); using var compositeKernel = new CompositeKernel(); compositeKernel.Add(one, aliases: new[] { "one-alias" }); compositeKernel.Add(two); var found = compositeKernel.FindKernel("one-alias"); found.Should().BeSameAs(one); }
private static Kernel CreateKernelWithConnectableFakeKernel(FakeKernel fakeKernel = null) { var compositeKernel = new CompositeKernel { new FakeKernel("x") }; compositeKernel.UseKernelClientConnection( new ConnectFakeKernel("fake", "Connects the fake kernel") { CreateKernel = (options, context) => Task.FromResult <Kernel>(fakeKernel ?? new FakeKernel()) }); return(compositeKernel); }
public void FindKernel_returns_null_for_unknown_kernel() { var one = new FakeKernel("one"); var two = new FakeKernel("two"); using var compositeKernel = new CompositeKernel { one, two, }; var found = compositeKernel.FindKernel("three"); found.Should().BeNull(); }
public void FindKernel_finds_a_subkernel_of_a_parent_composite_kernel_by_name() { var one = new FakeKernel("one"); var two = new FakeKernel("two"); using var compositeKernel = new CompositeKernel { one, two, }; var found = one.FindKernel("two"); found.Should().BeSameAs(two); }
public async Task Connected_kernels_are_disposed_when_composite_kernel_is_disposed() { var disposed = false; var fakeKernel = new FakeKernel(); fakeKernel.RegisterForDisposal(() => disposed = true); using var compositeKernel = CreateKernelWithConnectableFakeKernel(fakeKernel); await compositeKernel.SubmitCodeAsync("#!connect --kernel-name my-fake-kernel fake --fakeness-level 9000"); compositeKernel.Dispose(); disposed.Should().BeTrue(); }
public void Deferred_initialization_command_is_not_executed_prior_to_first_submission() { var receivedCommands = new List <IKernelCommand>(); using var kernel = new FakeKernel { Handle = (command, context) => { receivedCommands.Add(command); return(Task.CompletedTask); } }; kernel.DeferCommand(new SubmitCode("hello")); kernel.DeferCommand(new SubmitCode("world!")); receivedCommands.Should().BeEmpty(); }
public void When_command_type_reregistered_with_changed_type_command_then_kernel_registers_updated_envelope_type_for_serialization(bool withHandler) { // Notebook authors should be able to develop their custom commands experimentally and progressively, // so we don't want any "you have to restart your kernel now" situations just because you already // called RegisterCommandHandler once for a particular command type. Microsoft.DotNet.Interactive.Server.KernelCommandEnvelope.ResetToDefaults(); using var kernel = new FakeKernel(); if (withHandler) { kernel.RegisterCommandHandler <CustomCommandTypes.FirstSubmission.MyCommand>( (_, _) => Task.CompletedTask); kernel.RegisterCommandHandler <CustomCommandTypes.SecondSubmission.MyCommand>( (_, _) => Task.CompletedTask); } else { kernel.RegisterCommandType <CustomCommandTypes.FirstSubmission.MyCommand>(); kernel.RegisterCommandType <CustomCommandTypes.SecondSubmission.MyCommand>(); } var originalCommand = new CustomCommandTypes.SecondSubmission.MyCommand("xyzzy", 42); string envelopeJson = Microsoft.DotNet.Interactive.Server.KernelCommandEnvelope.Serialize(originalCommand); var roundTrippedCommandEnvelope = Microsoft.DotNet.Interactive.Server.KernelCommandEnvelope.Deserialize(envelopeJson); roundTrippedCommandEnvelope .Command .Should() .BeOfType <CustomCommandTypes.SecondSubmission.MyCommand>() .Which .Info .Should() .Be(originalCommand.Info); roundTrippedCommandEnvelope .Command .As <CustomCommandTypes.SecondSubmission.MyCommand>() .AdditionalProperty .Should() .Be(originalCommand.AdditionalProperty); }
public async Task When_a_new_kernel_is_connected_then_it_becomes_addressable_by_name() { var wasCalled = false; var fakeKernel = new FakeKernel { Handle = (command, context) => { wasCalled = true; return(Task.CompletedTask); } }; using var kernel = CreateKernelWithConnectableFakeKernel(fakeKernel); await kernel.SubmitCodeAsync("#!connect --kernel-name my-fake-kernel fake --fakeness-level 9000"); await kernel.SubmitCodeAsync(@" #!my-fake-kernel hello! "); wasCalled.Should().BeTrue(); }
public async Task Action_directives_are_routed_by_kernel_chooser_directives( string chooseKernelCommand, string expectedInvokedOnKernelName) { var received = new List <string>(); using var compositeKernel = new CompositeKernel(); var fakeKernel1 = new FakeKernel("fake1"); fakeKernel1.AddDirective(new Command("#!hi") { Handler = CommandHandler.Create(() => { received.Add("fake1"); }) }); var fakeKernel2 = new FakeKernel("fake2"); fakeKernel2.AddDirective(new Command("#!hi") { Handler = CommandHandler.Create(() => { received.Add("fake2"); }) }); compositeKernel.Add(fakeKernel1, new[] { "fake1-alias" }); compositeKernel.Add(fakeKernel2, new[] { "fake2-alias" }); var result = await compositeKernel.SubmitCodeAsync($"{chooseKernelCommand}\n#!hi"); result.KernelEvents.ToSubscribedList().Should().NotContainErrors(); received .Should() .ContainSingle() .Which .Should() .Be(expectedInvokedOnKernelName); }