From 873c5124c70d51f6e79cae867c5cd77a811677da Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 15:00:06 +0100 Subject: [PATCH 01/14] command serializer to output camlCase as events --- .../StreamKernelCommand.cs | 12 +++++++++++- .../StreamKernelExtensions.cs | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Microsoft.DotNet.Interactive/StreamKernelCommand.cs b/Microsoft.DotNet.Interactive/StreamKernelCommand.cs index 9c4750dd2..b50e2f0bd 100644 --- a/Microsoft.DotNet.Interactive/StreamKernelCommand.cs +++ b/Microsoft.DotNet.Interactive/StreamKernelCommand.cs @@ -1,9 +1,19 @@ -namespace Microsoft.DotNet.Interactive +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Newtonsoft.Json; + +namespace Microsoft.DotNet.Interactive { public class StreamKernelCommand { + [JsonProperty("id")] public int Id { get; set; } + + [JsonProperty("commandType")] public string CommandType { get; set; } + + [JsonProperty("command")] public object Command { get; set; } } } diff --git a/Microsoft.DotNet.Interactive/StreamKernelExtensions.cs b/Microsoft.DotNet.Interactive/StreamKernelExtensions.cs index 314d33ae7..e84d1e37a 100644 --- a/Microsoft.DotNet.Interactive/StreamKernelExtensions.cs +++ b/Microsoft.DotNet.Interactive/StreamKernelExtensions.cs @@ -1,24 +1,32 @@ -using System.IO; +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.IO; using System.Threading; using Microsoft.DotNet.Interactive.Commands; using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; namespace Microsoft.DotNet.Interactive { public static class StreamKernelExtensions { - static int id = 0; + private static int _id = 0; + private static readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; public static int WriteMessage(this StreamWriter writer, IKernelCommand command) { var message = new StreamKernelCommand() { - Id = Interlocked.Increment(ref id), + Id = Interlocked.Increment(ref _id), CommandType = command.GetType().Name, Command = command }; - writer.WriteLine(JsonConvert.SerializeObject(message)); + writer.WriteLine(JsonConvert.SerializeObject(message, _jsonSerializerSettings)); writer.Flush(); return message.Id; } From 410274752e720b4800f7235e3c01a16f5c6604c5 Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 15:25:39 +0100 Subject: [PATCH 02/14] typo in comment --- Microsoft.DotNet.Interactive.Rendering/PocketView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Microsoft.DotNet.Interactive.Rendering/PocketView.cs b/Microsoft.DotNet.Interactive.Rendering/PocketView.cs index a47ef33c4..0a0d1b57b 100644 --- a/Microsoft.DotNet.Interactive.Rendering/PocketView.cs +++ b/Microsoft.DotNet.Interactive.Rendering/PocketView.cs @@ -13,7 +13,7 @@ namespace Microsoft.DotNet.Interactive.Rendering { /// - /// Writes HTML using a C# DSL, bypasing the need for specialized parser and compiler infrastructure such as Razor or WebForms require. + /// Writes HTML using a C# DSL, bypassing the need for specialized parser and compiler infrastructure such as Razor or WebForms require. /// public class PocketView : DynamicObject, ITag { From 43232b43b433df675176798e81ccf00f10450baa Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 15:28:30 +0100 Subject: [PATCH 03/14] formatting --- Microsoft.DotNet.Interactive/StreamKernelEvent.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Microsoft.DotNet.Interactive/StreamKernelEvent.cs b/Microsoft.DotNet.Interactive/StreamKernelEvent.cs index e6013dfac..4686d80f5 100644 --- a/Microsoft.DotNet.Interactive/StreamKernelEvent.cs +++ b/Microsoft.DotNet.Interactive/StreamKernelEvent.cs @@ -9,8 +9,10 @@ public class StreamKernelEvent { [JsonProperty("id")] public int Id { get; set; } + [JsonProperty("eventType")] public string EventType { get; set; } + [JsonProperty("event")] public string Event { get; set; } } From f9160425480bd3559290e38491bc96aca1553fcb Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 15:32:39 +0100 Subject: [PATCH 04/14] fix tests --- Microsoft.DotNet.Interactive/KernelStreamClient.cs | 2 +- WorkspaceServer.Tests/Kernel/KernelClientTests.cs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Microsoft.DotNet.Interactive/KernelStreamClient.cs b/Microsoft.DotNet.Interactive/KernelStreamClient.cs index 33d896afd..e238daee7 100644 --- a/Microsoft.DotNet.Interactive/KernelStreamClient.cs +++ b/Microsoft.DotNet.Interactive/KernelStreamClient.cs @@ -51,7 +51,7 @@ public Task Start() streamKernelCommand = obj.ToObject(); IKernelCommand command = null; - if (obj.TryGetValue("Command", out var commandValue)) + if (obj.TryGetValue("command", out var commandValue)) { command = DeserializeCommand(streamKernelCommand.CommandType, commandValue); } diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs index 884deb1d6..1eeb3deec 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs @@ -29,8 +29,7 @@ public async Task Kernel_can_be_interacted_using_kernel_client() var input = new MemoryStream(); var writer = new StreamWriter(input, Encoding.UTF8); - writer.WriteMessage(new SubmitCode(@"var x = -123;")); + writer.WriteMessage(new SubmitCode(@"var x = 123;")); writer.WriteMessage(new SubmitCode("x")); writer.WriteMessage(new Quit()); From 8f2ae0d938d095414b59c85d98b64ba2fdc2905f Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 15:38:15 +0100 Subject: [PATCH 05/14] lookup using case insensitive match --- Microsoft.DotNet.Interactive/KernelStreamClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Microsoft.DotNet.Interactive/KernelStreamClient.cs b/Microsoft.DotNet.Interactive/KernelStreamClient.cs index e238daee7..a4e371697 100644 --- a/Microsoft.DotNet.Interactive/KernelStreamClient.cs +++ b/Microsoft.DotNet.Interactive/KernelStreamClient.cs @@ -51,12 +51,12 @@ public Task Start() streamKernelCommand = obj.ToObject(); IKernelCommand command = null; - if (obj.TryGetValue("command", out var commandValue)) + if (obj.TryGetValue("command", StringComparison.InvariantCultureIgnoreCase ,out var commandValue)) { command = DeserializeCommand(streamKernelCommand.CommandType, commandValue); } - if (streamKernelCommand.CommandType == "Quit") + if (streamKernelCommand.CommandType == nameof(Quit)) { return; } From 9c6084c5ce6d6bc2eeb62fd443bb695b94a3ecbf Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 16:50:18 +0100 Subject: [PATCH 06/14] fix fsharp project load in ncrunch --- .../Microsoft.DotNet.Interactive.FSharp.Tests.fsproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Microsoft.DotNet.Interactive.FSharp.Tests/Microsoft.DotNet.Interactive.FSharp.Tests.fsproj b/Microsoft.DotNet.Interactive.FSharp.Tests/Microsoft.DotNet.Interactive.FSharp.Tests.fsproj index 6f79f8386..6237ece5c 100644 --- a/Microsoft.DotNet.Interactive.FSharp.Tests/Microsoft.DotNet.Interactive.FSharp.Tests.fsproj +++ b/Microsoft.DotNet.Interactive.FSharp.Tests/Microsoft.DotNet.Interactive.FSharp.Tests.fsproj @@ -2,6 +2,12 @@ netcoreapp3.0 + false + + + + + false From 68aeebcc66593c722be539a40ec57fc3332c087f Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 17:05:07 +0100 Subject: [PATCH 07/14] serialization classes internal and tests via assent --- .../StreamKernelCommand.cs | 2 +- .../StreamKernelEvent.cs | 2 +- ...teracted_using_kernel_client.approved.json | 7 ++++ ..._r_nuget_using_kernel_client.approved.json | 2 ++ ..._client_surfaces_json_errors.approved.json | 1 + .../Kernel/KernelClientTests.cs | 36 ++++++++----------- 6 files changed, 27 insertions(+), 23 deletions(-) create mode 100644 WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_be_interacted_using_kernel_client.approved.json create mode 100644 WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json create mode 100644 WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_json_errors.approved.json diff --git a/Microsoft.DotNet.Interactive/StreamKernelCommand.cs b/Microsoft.DotNet.Interactive/StreamKernelCommand.cs index b50e2f0bd..49cfa5987 100644 --- a/Microsoft.DotNet.Interactive/StreamKernelCommand.cs +++ b/Microsoft.DotNet.Interactive/StreamKernelCommand.cs @@ -5,7 +5,7 @@ namespace Microsoft.DotNet.Interactive { - public class StreamKernelCommand + internal class StreamKernelCommand { [JsonProperty("id")] public int Id { get; set; } diff --git a/Microsoft.DotNet.Interactive/StreamKernelEvent.cs b/Microsoft.DotNet.Interactive/StreamKernelEvent.cs index 4686d80f5..f1bcfcb25 100644 --- a/Microsoft.DotNet.Interactive/StreamKernelEvent.cs +++ b/Microsoft.DotNet.Interactive/StreamKernelEvent.cs @@ -5,7 +5,7 @@ namespace Microsoft.DotNet.Interactive { - public class StreamKernelEvent + internal class StreamKernelEvent { [JsonProperty("id")] public int Id { get; set; } diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_be_interacted_using_kernel_client.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_be_interacted_using_kernel_client.approved.json new file mode 100644 index 000000000..d3b4b131a --- /dev/null +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_be_interacted_using_kernel_client.approved.json @@ -0,0 +1,7 @@ +{"id":1,"eventType":"CodeSubmissionReceived","event":"{\"Code\":\"var x = 123;\",\"Value\":\"var x = 123;\",\"Command\":{\"Code\":\"var x = 123;\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} +{"id":1,"eventType":"CompleteCodeSubmissionReceived","event":"{\"Code\":\"var x = 123;\",\"Command\":{\"Code\":\"var x = 123;\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} +{"id":1,"eventType":"CodeSubmissionEvaluated","event":"{\"Code\":\"var x = 123;\",\"Command\":{\"Code\":\"var x = 123;\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} +{"id":2,"eventType":"CodeSubmissionReceived","event":"{\"Code\":\"x\",\"Value\":\"x\",\"Command\":{\"Code\":\"x\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} +{"id":2,"eventType":"CompleteCodeSubmissionReceived","event":"{\"Code\":\"x\",\"Command\":{\"Code\":\"x\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} +{"id":2,"eventType":"ReturnValueProduced","event":"{\"Value\":123,\"FormattedValues\":[{\"MimeType\":\"text/plain\",\"Value\":\"123\"}],\"ValueId\":null,\"Command\":{\"Code\":\"x\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} +{"id":2,"eventType":"CodeSubmissionEvaluated","event":"{\"Code\":\"x\",\"Command\":{\"Code\":\"x\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json new file mode 100644 index 000000000..c1301d08c --- /dev/null +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json @@ -0,0 +1,2 @@ +{"id":1,"eventType":"NuGetPackageAdded","event":"{\"PackageReference\":{\"PackageName\":\"Microsoft.Spark\",\"PackageVersion\":\"0.4.0\"},\"Command\":{\"PackageReference\":{\"PackageName\":\"Microsoft.Spark\",\"PackageVersion\":\"0.4.0\"}}}"} +{"id":1,"eventType":"CodeSubmissionEvaluated","event":"{\"Code\":\"#r \\\"nuget:Microsoft.Spark, 0.4.0\\\"\",\"Command\":{\"Code\":\"#r \\\"nuget:Microsoft.Spark, 0.4.0\\\"\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_json_errors.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_json_errors.approved.json new file mode 100644 index 000000000..565b74689 --- /dev/null +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_json_errors.approved.json @@ -0,0 +1 @@ +{"id":-1,"eventType":"CommandParseFailure","event":"{\"Command\":null,\"Body\":\"{ hello\"}"} diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs index 1eeb3deec..b112d09b4 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs @@ -1,17 +1,13 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; -using FluentAssertions; +using Assent; using Microsoft.DotNet.Interactive; using Microsoft.DotNet.Interactive.Commands; -using Microsoft.DotNet.Interactive.Events; using Microsoft.DotNet.Interactive.Tests; -using Newtonsoft.Json; using WorkspaceServer.Kernel; using Xunit; @@ -19,6 +15,17 @@ namespace WorkspaceServer.Tests.Kernel { public class KernelClientTests { + + private readonly Configuration _configuration; + + public KernelClientTests() + { + _configuration = new Configuration() + .UsingExtension("json"); + + _configuration = _configuration.SetInteractive(true); + } + [Fact] public async Task Kernel_can_be_interacted_using_kernel_client() { @@ -48,10 +55,7 @@ public async Task Kernel_can_be_interacted_using_kernel_client() var reader = new StreamReader(output, Encoding.UTF8); var text = reader.ReadToEnd(); - var events = text.Split(Environment.NewLine) - .Select(JsonConvert.DeserializeObject); - - events.Should().Contain(e => e.EventType == "ReturnValueProduced"); + this.Assent(text, _configuration); } [Fact] @@ -87,10 +91,7 @@ public async Task Kernel_client_surfaces_json_errors() var reader = new StreamReader(output, Encoding.UTF8); var text = reader.ReadToEnd(); - var events = text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) - .Select(JsonConvert.DeserializeObject); - - events.Should().Contain(e => e.EventType == "CommandParseFailure"); + this.Assent(text, _configuration); } [Fact] @@ -121,14 +122,7 @@ public async Task Kernel_can_pound_r_nuget_using_kernel_client() var reader = new StreamReader(output, Encoding.UTF8); var text = reader.ReadToEnd(); - var events = text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) - .Select(JsonConvert.DeserializeObject).ToList(); - - events.Should() - .Contain(e => e.EventType == nameof(NuGetPackageAdded)); - - events.Should() - .NotContain(e => e.EventType == nameof(CommandNotRecognized)); + this.Assent(text, _configuration); } } } \ No newline at end of file From c26d53ceea482699d2e42d4e724fc0f131bbe9a6 Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 17:11:30 +0100 Subject: [PATCH 08/14] correct assent tests --- Microsoft.DotNet.Interactive/KernelStreamClient.cs | 2 +- Microsoft.DotNet.Interactive/StreamKernelEvent.cs | 2 +- ...be_interacted_using_kernel_client.approved.json | 14 +++++++------- ...pound_r_nuget_using_kernel_client.approved.json | 4 ++-- ...ernel_client_surfaces_json_errors.approved.json | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Microsoft.DotNet.Interactive/KernelStreamClient.cs b/Microsoft.DotNet.Interactive/KernelStreamClient.cs index a4e371697..cfde7ffe2 100644 --- a/Microsoft.DotNet.Interactive/KernelStreamClient.cs +++ b/Microsoft.DotNet.Interactive/KernelStreamClient.cs @@ -102,7 +102,7 @@ private void Write(IKernelEvent e, int id) var wrapper = new StreamKernelEvent { Id = id, - Event = JsonConvert.SerializeObject(e), + Event = e, EventType = e.GetType().Name }; var serialized = JsonConvert.SerializeObject(wrapper, _jsonSerializerSettings); diff --git a/Microsoft.DotNet.Interactive/StreamKernelEvent.cs b/Microsoft.DotNet.Interactive/StreamKernelEvent.cs index f1bcfcb25..c332ab1ab 100644 --- a/Microsoft.DotNet.Interactive/StreamKernelEvent.cs +++ b/Microsoft.DotNet.Interactive/StreamKernelEvent.cs @@ -14,6 +14,6 @@ internal class StreamKernelEvent public string EventType { get; set; } [JsonProperty("event")] - public string Event { get; set; } + public object Event { get; set; } } } diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_be_interacted_using_kernel_client.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_be_interacted_using_kernel_client.approved.json index d3b4b131a..b839010f0 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_be_interacted_using_kernel_client.approved.json +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_be_interacted_using_kernel_client.approved.json @@ -1,7 +1,7 @@ -{"id":1,"eventType":"CodeSubmissionReceived","event":"{\"Code\":\"var x = 123;\",\"Value\":\"var x = 123;\",\"Command\":{\"Code\":\"var x = 123;\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} -{"id":1,"eventType":"CompleteCodeSubmissionReceived","event":"{\"Code\":\"var x = 123;\",\"Command\":{\"Code\":\"var x = 123;\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} -{"id":1,"eventType":"CodeSubmissionEvaluated","event":"{\"Code\":\"var x = 123;\",\"Command\":{\"Code\":\"var x = 123;\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} -{"id":2,"eventType":"CodeSubmissionReceived","event":"{\"Code\":\"x\",\"Value\":\"x\",\"Command\":{\"Code\":\"x\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} -{"id":2,"eventType":"CompleteCodeSubmissionReceived","event":"{\"Code\":\"x\",\"Command\":{\"Code\":\"x\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} -{"id":2,"eventType":"ReturnValueProduced","event":"{\"Value\":123,\"FormattedValues\":[{\"MimeType\":\"text/plain\",\"Value\":\"123\"}],\"ValueId\":null,\"Command\":{\"Code\":\"x\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} -{"id":2,"eventType":"CodeSubmissionEvaluated","event":"{\"Code\":\"x\",\"Command\":{\"Code\":\"x\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} +{"id":1,"eventType":"CodeSubmissionReceived","event":{"code":"var x = 123;","value":"var x = 123;","command":{"code":"var x = 123;","targetKernelName":null,"submissionType":0}}} +{"id":1,"eventType":"CompleteCodeSubmissionReceived","event":{"code":"var x = 123;","command":{"code":"var x = 123;","targetKernelName":null,"submissionType":0}}} +{"id":1,"eventType":"CodeSubmissionEvaluated","event":{"code":"var x = 123;","command":{"code":"var x = 123;","targetKernelName":null,"submissionType":0}}} +{"id":2,"eventType":"CodeSubmissionReceived","event":{"code":"x","value":"x","command":{"code":"x","targetKernelName":null,"submissionType":0}}} +{"id":2,"eventType":"CompleteCodeSubmissionReceived","event":{"code":"x","command":{"code":"x","targetKernelName":null,"submissionType":0}}} +{"id":2,"eventType":"ReturnValueProduced","event":{"value":123,"formattedValues":[{"mimeType":"text/plain","value":"123"}],"valueId":null,"command":{"code":"x","targetKernelName":null,"submissionType":0}}} +{"id":2,"eventType":"CodeSubmissionEvaluated","event":{"code":"x","command":{"code":"x","targetKernelName":null,"submissionType":0}}} diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json index c1301d08c..3194f3053 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json @@ -1,2 +1,2 @@ -{"id":1,"eventType":"NuGetPackageAdded","event":"{\"PackageReference\":{\"PackageName\":\"Microsoft.Spark\",\"PackageVersion\":\"0.4.0\"},\"Command\":{\"PackageReference\":{\"PackageName\":\"Microsoft.Spark\",\"PackageVersion\":\"0.4.0\"}}}"} -{"id":1,"eventType":"CodeSubmissionEvaluated","event":"{\"Code\":\"#r \\\"nuget:Microsoft.Spark, 0.4.0\\\"\",\"Command\":{\"Code\":\"#r \\\"nuget:Microsoft.Spark, 0.4.0\\\"\",\"TargetKernelName\":null,\"SubmissionType\":0}}"} +{"id":2,"eventType":"NuGetPackageAdded","event":{"packageReference":{"packageName":"Microsoft.Spark","packageVersion":"0.4.0"},"command":{"packageReference":{"packageName":"Microsoft.Spark","packageVersion":"0.4.0"}}}} +{"id":2,"eventType":"CodeSubmissionEvaluated","event":{"code":"#r \"nuget:Microsoft.Spark, 0.4.0\"","command":{"code":"#r \"nuget:Microsoft.Spark, 0.4.0\"","targetKernelName":null,"submissionType":0}}} diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_json_errors.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_json_errors.approved.json index 565b74689..bd35e1da2 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_json_errors.approved.json +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_json_errors.approved.json @@ -1 +1 @@ -{"id":-1,"eventType":"CommandParseFailure","event":"{\"Command\":null,\"Body\":\"{ hello\"}"} +{"id":-1,"eventType":"CommandParseFailure","event":{"command":null,"body":"{ hello"}} From 7b71181f13cd27b0972386add070405089e24d88 Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 17:31:07 +0100 Subject: [PATCH 09/14] set correlationId for messages during tests --- Microsoft.DotNet.Interactive/StreamKernelExtensions.cs | 8 ++++---- ...el_can_pound_r_nuget_using_kernel_client.approved.json | 4 ++-- WorkspaceServer.Tests/Kernel/KernelClientTests.cs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Microsoft.DotNet.Interactive/StreamKernelExtensions.cs b/Microsoft.DotNet.Interactive/StreamKernelExtensions.cs index e84d1e37a..bdaf0060a 100644 --- a/Microsoft.DotNet.Interactive/StreamKernelExtensions.cs +++ b/Microsoft.DotNet.Interactive/StreamKernelExtensions.cs @@ -11,17 +11,17 @@ namespace Microsoft.DotNet.Interactive { public static class StreamKernelExtensions { - private static int _id = 0; + private static int _id; private static readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; - public static int WriteMessage(this StreamWriter writer, IKernelCommand command) + public static int WriteMessage(this StreamWriter writer, IKernelCommand command, int? correlationId = null) { - var message = new StreamKernelCommand() + var message = new StreamKernelCommand { - Id = Interlocked.Increment(ref _id), + Id = correlationId?? Interlocked.Increment(ref _id), CommandType = command.GetType().Name, Command = command }; diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json index 3194f3053..3a107b082 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json @@ -1,2 +1,2 @@ -{"id":2,"eventType":"NuGetPackageAdded","event":{"packageReference":{"packageName":"Microsoft.Spark","packageVersion":"0.4.0"},"command":{"packageReference":{"packageName":"Microsoft.Spark","packageVersion":"0.4.0"}}}} -{"id":2,"eventType":"CodeSubmissionEvaluated","event":{"code":"#r \"nuget:Microsoft.Spark, 0.4.0\"","command":{"code":"#r \"nuget:Microsoft.Spark, 0.4.0\"","targetKernelName":null,"submissionType":0}}} +{"id":1,"eventType":"NuGetPackageAdded","event":{"packageReference":{"packageName":"Microsoft.Spark","packageVersion":"0.4.0"},"command":{"packageReference":{"packageName":"Microsoft.Spark","packageVersion":"0.4.0"}}}} +{"id":1,"eventType":"CodeSubmissionEvaluated","event":{"code":"#r \"nuget:Microsoft.Spark, 0.4.0\"","command":{"code":"#r \"nuget:Microsoft.Spark, 0.4.0\"","targetKernelName":null,"submissionType":0}}} diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs index b112d09b4..577f574f2 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs @@ -104,8 +104,8 @@ public async Task Kernel_can_pound_r_nuget_using_kernel_client() var input = new MemoryStream(); var writer = new StreamWriter(input, Encoding.UTF8); - writer.WriteMessage(new SubmitCode(@"#r ""nuget:Microsoft.Spark, 0.4.0""")); - writer.WriteMessage(new Quit()); + writer.WriteMessage(new SubmitCode(@"#r ""nuget:Microsoft.Spark, 0.4.0"""),1); + writer.WriteMessage(new Quit(),2); input.Position = 0; From 334a7acb28da06c58da65931acfbc632edf2142a Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 17:43:10 +0100 Subject: [PATCH 10/14] using seed in tests --- WorkspaceServer.Tests/Kernel/KernelClientTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs index 577f574f2..cee9b3df9 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs @@ -36,9 +36,9 @@ public async Task Kernel_can_be_interacted_using_kernel_client() var input = new MemoryStream(); var writer = new StreamWriter(input, Encoding.UTF8); - writer.WriteMessage(new SubmitCode(@"var x = 123;")); - writer.WriteMessage(new SubmitCode("x")); - writer.WriteMessage(new Quit()); + writer.WriteMessage(new SubmitCode(@"var x = 123;"),1); + writer.WriteMessage(new SubmitCode("x"),2); + writer.WriteMessage(new Quit(),3); input.Position = 0; @@ -73,7 +73,7 @@ public async Task Kernel_client_surfaces_json_errors() var input = new MemoryStream(); var writer = new StreamWriter(input, Encoding.UTF8); writer.WriteLine("{ hello"); - writer.WriteMessage(new Quit()); + writer.WriteMessage(new Quit(),2); writer.Flush(); input.Position = 0; From 7c4478cb622d890a3bdd0f13389989225d3eb855 Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 18:25:01 +0100 Subject: [PATCH 11/14] exceptions dot produce unknown command message --- .../KernelStreamClient.cs | 8 --- ...faces_code_submission_Errors.approved.json | 3 ++ .../Kernel/KernelClientTests.cs | 50 ++++++++++++++++--- WorkspaceServer/Kernel/CSharpKernel.cs | 3 +- 4 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_code_submission_Errors.approved.json diff --git a/Microsoft.DotNet.Interactive/KernelStreamClient.cs b/Microsoft.DotNet.Interactive/KernelStreamClient.cs index cfde7ffe2..a0d8affb3 100644 --- a/Microsoft.DotNet.Interactive/KernelStreamClient.cs +++ b/Microsoft.DotNet.Interactive/KernelStreamClient.cs @@ -85,14 +85,6 @@ public Task Start() }, streamKernelCommand?.Id ?? -1); } - catch - { - Write(new CommandNotRecognized - { - Body = obj ?? (object)line - }, streamKernelCommand?.Id ?? -1); - } - } }); } diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_code_submission_Errors.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_code_submission_Errors.approved.json new file mode 100644 index 000000000..3a8214048 --- /dev/null +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_code_submission_Errors.approved.json @@ -0,0 +1,3 @@ +{"id":1,"eventType":"CodeSubmissionReceived","event":{"code":"var a = 12","value":"var a = 12","command":{"code":"var a = 12","targetKernelName":null,"submissionType":0}}} +{"id":1,"eventType":"IncompleteCodeSubmissionReceived","event":{"command":{"code":"var a = 12","targetKernelName":null,"submissionType":0}}} +{"id":1,"eventType":"CommandFailed","event":{"exception":{"diagnostics":[{"location":{"kind":1,"sourceSpan":{"start":10,"end":10,"length":0,"isEmpty":true},"sourceTree":{"filePath":"","encoding":null,"length":10,"hasCompilationUnitRoot":true,"options":{"languageVersion":703,"specifiedLanguageVersion":2147483647,"preprocessorSymbolNames":[],"language":"C#","features":{},"kind":1,"specifiedKind":1,"documentationMode":1,"errors":[]},"diagnosticOptions":{}},"isInSource":true,"isInMetadata":false,"metadataModule":null},"additionalLocations":[],"descriptor":{"id":"CS1002","title":{},"description":{},"helpLinkUri":"","messageFormat":{},"category":"Compiler","defaultSeverity":3,"isEnabledByDefault":true,"customTags":["Compiler","Telemetry","NotConfigurable"]},"id":"CS1002","severity":3,"defaultSeverity":3,"isSuppressed":false,"warningLevel":0,"info":{"code":1002,"descriptor":{"id":"CS1002","title":{},"description":{},"helpLinkUri":"","messageFormat":{},"category":"Compiler","defaultSeverity":3,"isEnabledByDefault":true,"customTags":["Compiler","Telemetry","NotConfigurable"]},"severity":3,"defaultSeverity":3,"warningLevel":0,"isWarningAsError":false,"category":"Compiler","additionalLocations":[],"messageIdentifier":"CS1002"},"isWarningAsError":false,"properties":{}}],"stackTrace":" at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter) in /_/src/Scripting/Core/ScriptBuilder.cs:line 113\r\n at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, Boolean emitDebugInformation, CancellationToken cancellationToken) in /_/src/Scripting/Core/ScriptBuilder.cs:line 82\r\n at Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 359\r\n at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 463\r\n at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 437\r\n at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync[T](String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken) in /_/src/Scripting/CSharp/CSharpScript.cs:line 91\r\n at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync(String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken) in /_/src/Scripting/CSharp/CSharpScript.cs:line 105\r\n at WorkspaceServer.Kernel.CSharpKernel.HandleSubmitCode(SubmitCode submitCode, KernelInvocationContext context) in C:\\Users\\dicolomb\\source\\repos\\Public\\try\\WorkspaceServer\\Kernel\\CSharpKernel.cs:line 135","message":"(1,11): error CS1002: ; expected","data":{},"innerException":null,"helpLink":null,"source":"Microsoft.CodeAnalysis.Scripting","hResult":-2146233088},"message":"(1,11): error CS1002: ; expected","command":{"code":"var a = 12","targetKernelName":null,"submissionType":0}}} diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs index cee9b3df9..262dc44c5 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs @@ -36,9 +36,9 @@ public async Task Kernel_can_be_interacted_using_kernel_client() var input = new MemoryStream(); var writer = new StreamWriter(input, Encoding.UTF8); - writer.WriteMessage(new SubmitCode(@"var x = 123;"),1); - writer.WriteMessage(new SubmitCode("x"),2); - writer.WriteMessage(new Quit(),3); + writer.WriteMessage(new SubmitCode(@"var x = 123;"), 1); + writer.WriteMessage(new SubmitCode("x"), 2); + writer.WriteMessage(new Quit(), 3); input.Position = 0; @@ -73,7 +73,45 @@ public async Task Kernel_client_surfaces_json_errors() var input = new MemoryStream(); var writer = new StreamWriter(input, Encoding.UTF8); writer.WriteLine("{ hello"); - writer.WriteMessage(new Quit(),2); + writer.WriteMessage(new Quit(), 2); + writer.Flush(); + + input.Position = 0; + + var output = new MemoryStream(); + + var streamKernel = new KernelStreamClient(kernel, + new StreamReader(input), + new StreamWriter(output)); + + var task = streamKernel.Start(); + await task; + + output.Position = 0; + var reader = new StreamReader(output, Encoding.UTF8); + + var text = reader.ReadToEnd(); + this.Assent(text, _configuration); + } + + [Fact] + public async Task Kernel_client_surfaces_code_submission_Errors() + { + var kernel = new CompositeKernel() + { + new CSharpKernel(), + new FakeKernel("fake") + { + Handle = context => Task.CompletedTask + } + }; + + kernel.DefaultKernelName = "csharp"; + + var input = new MemoryStream(); + var writer = new StreamWriter(input, Encoding.UTF8); + writer.WriteMessage(new SubmitCode(@"var a = 12"), 1); + writer.WriteMessage(new Quit(), 2); writer.Flush(); input.Position = 0; @@ -104,8 +142,8 @@ public async Task Kernel_can_pound_r_nuget_using_kernel_client() var input = new MemoryStream(); var writer = new StreamWriter(input, Encoding.UTF8); - writer.WriteMessage(new SubmitCode(@"#r ""nuget:Microsoft.Spark, 0.4.0"""),1); - writer.WriteMessage(new Quit(),2); + writer.WriteMessage(new SubmitCode(@"#r ""nuget:Microsoft.Spark, 0.4.0"""), 1); + writer.WriteMessage(new Quit(), 2); input.Position = 0; diff --git a/WorkspaceServer/Kernel/CSharpKernel.cs b/WorkspaceServer/Kernel/CSharpKernel.cs index c63049b30..df13f4670 100644 --- a/WorkspaceServer/Kernel/CSharpKernel.cs +++ b/WorkspaceServer/Kernel/CSharpKernel.cs @@ -165,7 +165,7 @@ private async Task HandleSubmitCode( } context.OnNext(new CommandFailed(exception, submitCode, message)); - context.OnError(exception); + context.OnCompleted(); } else { @@ -180,7 +180,6 @@ private async Task HandleSubmitCode( } context.OnNext(new CodeSubmissionEvaluated(submitCode)); - context.OnCompleted(); } } From 5e9cca62030b700fb986c3328f693dacb0c2ec46 Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 18:36:55 +0100 Subject: [PATCH 12/14] do not publish user exceptions in the context, --- .../FSharpKernel.fs | 10 ++++----- .../KernelExtensions.cs | 10 ++++----- Microsoft.DotNet.Interactive/KernelBase.cs | 14 ++++++------ .../KernelCommandPipeline.cs | 2 +- .../KernelInvocationContext.cs | 8 +++---- WorkspaceServer/Kernel/CSharpKernel.cs | 22 +++++++++---------- .../Kernel/CSharpKernelExtensions.cs | 4 ++-- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs index cc9c9de75..429709bcc 100644 --- a/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs +++ b/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs @@ -16,7 +16,7 @@ type FSharpKernel() = let handleSubmitCode (codeSubmission: SubmitCode) (context: KernelInvocationContext) = async { let codeSubmissionReceived = CodeSubmissionReceived(codeSubmission.Code, codeSubmission) - context.OnNext(codeSubmissionReceived) + context.Publish(codeSubmissionReceived) let result, errors = try script.Eval(codeSubmission.Code) @@ -24,16 +24,16 @@ type FSharpKernel() = | ex -> Error(ex), [||] if errors.Length > 0 then let aggregateErrorMessage = System.String.Join("\n", errors) - context.OnNext(CommandFailed(aggregateErrorMessage, codeSubmission)) + context.Publish(CommandFailed(aggregateErrorMessage, codeSubmission)) match result with | Ok(Some(value)) -> let value = value.ReflectionValue let formattedValues = FormattedValue.FromObject(value) - context.OnNext(ReturnValueProduced(value, codeSubmission, formattedValues)) + context.Publish(ReturnValueProduced(value, codeSubmission, formattedValues)) | Ok(None) -> () | Error(ex) -> context.OnError(ex) - context.OnNext(CodeSubmissionEvaluated(codeSubmission)) - context.OnCompleted() + context.Publish(CodeSubmissionEvaluated(codeSubmission)) + context.Complete() } override __.HandleAsync(command: IKernelCommand, _context: KernelInvocationContext): Task = async { diff --git a/Microsoft.DotNet.Interactive.Jupyter/KernelExtensions.cs b/Microsoft.DotNet.Interactive.Jupyter/KernelExtensions.cs index c1300c330..f8fcb977a 100644 --- a/Microsoft.DotNet.Interactive.Jupyter/KernelExtensions.cs +++ b/Microsoft.DotNet.Interactive.Jupyter/KernelExtensions.cs @@ -42,7 +42,7 @@ private static T UseHtml(this T kernel) .Trim(); - context.OnNext(new Events.DisplayedValueProduced( + context.Publish(new Events.DisplayedValueProduced( htmlContent, context.Command, formattedValues: new[] @@ -50,7 +50,7 @@ private static T UseHtml(this T kernel) new FormattedValue("text/html", htmlContent) })); - context.OnCompleted(); + context.Complete(); } }) }); @@ -106,7 +106,7 @@ private static Command lsmagic() supportedDirectives.Commands.AddRange(context.CurrentKernel.Directives); - context.OnNext(new Events.DisplayedValueProduced(supportedDirectives)); + context.Publish(new Events.DisplayedValueProduced(supportedDirectives)); await context.CurrentKernel.VisitSubkernelsAsync(async k => { @@ -137,7 +137,7 @@ private static Command javascript() scriptContent)) .ToString(); - context.OnNext(new Events.DisplayedValueProduced( + context.Publish(new Events.DisplayedValueProduced( scriptContent, context.Command, formattedValues: new[] @@ -145,7 +145,7 @@ private static Command javascript() new FormattedValue("text/html", value) })); - context.OnCompleted(); + context.Complete(); } }) }; diff --git a/Microsoft.DotNet.Interactive/KernelBase.cs b/Microsoft.DotNet.Interactive/KernelBase.cs index 147a75153..1d0a380a4 100644 --- a/Microsoft.DotNet.Interactive/KernelBase.cs +++ b/Microsoft.DotNet.Interactive/KernelBase.cs @@ -109,7 +109,7 @@ private async Task HandleLoadExtension( await extension.OnLoadAsync(invocationContext.HandlingKernel); } - context.OnCompleted(); + context.Complete(); }; await next(loadExtension, invocationContext); @@ -155,8 +155,8 @@ private async Task HandleDirectivesAndSubmitCode( { submitCode.Handler = context => { - context.OnNext(new CodeSubmissionEvaluated(submitCode)); - context.OnCompleted(); + context.Publish(new CodeSubmissionEvaluated(submitCode)); + context.Complete(); return Task.CompletedTask; }; @@ -178,14 +178,14 @@ private async Task HandleDisplayValue( { displayValue.Handler = invocationContext => { - invocationContext.OnNext( + invocationContext.Publish( new Events.DisplayedValueProduced( displayValue.FormattedValue, displayValue, formattedValues: new[] { displayValue.FormattedValue }, valueId: displayValue.ValueId)); - invocationContext.OnCompleted(); + invocationContext.Complete(); return Task.CompletedTask; }; @@ -200,7 +200,7 @@ private async Task HandleUpdateDisplayValue( { displayedValue.Handler = invocationContext => { - invocationContext.OnNext( + invocationContext.Publish( new DisplayedValueUpdated( displayedValue.FormattedValue, valueId: displayedValue.ValueId, @@ -208,7 +208,7 @@ private async Task HandleUpdateDisplayValue( formattedValues: new[] { displayedValue.FormattedValue } )); - invocationContext.OnCompleted(); + invocationContext.Complete(); return Task.CompletedTask; }; diff --git a/Microsoft.DotNet.Interactive/KernelCommandPipeline.cs b/Microsoft.DotNet.Interactive/KernelCommandPipeline.cs index 836ad5d77..a530f6805 100644 --- a/Microsoft.DotNet.Interactive/KernelCommandPipeline.cs +++ b/Microsoft.DotNet.Interactive/KernelCommandPipeline.cs @@ -43,7 +43,7 @@ public async Task SendAsync( } catch (Exception exception) { - context.OnNext( + context.Publish( new CommandFailed( exception, command)); diff --git a/Microsoft.DotNet.Interactive/KernelInvocationContext.cs b/Microsoft.DotNet.Interactive/KernelInvocationContext.cs index 0b75fbc3d..e51cb61e5 100644 --- a/Microsoft.DotNet.Interactive/KernelInvocationContext.cs +++ b/Microsoft.DotNet.Interactive/KernelInvocationContext.cs @@ -11,7 +11,7 @@ namespace Microsoft.DotNet.Interactive { - public class KernelInvocationContext : IObserver, IDisposable + public class KernelInvocationContext : IDisposable { private readonly KernelInvocationContext _parentContext; private static readonly AsyncLocal> _currentStack = new AsyncLocal>(); @@ -30,7 +30,7 @@ private KernelInvocationContext( public IKernelCommand Command { get; } - public void OnCompleted() + public void Complete() { IsCompleted = true; _events.OnCompleted(); @@ -41,11 +41,11 @@ public void OnError(Exception exception) _events.OnError(exception); } - public void OnNext(IKernelEvent @event) + public void Publish(IKernelEvent @event) { if (_parentContext != null) { - _parentContext.OnNext(@event); + _parentContext.Publish(@event); } else { diff --git a/WorkspaceServer/Kernel/CSharpKernel.cs b/WorkspaceServer/Kernel/CSharpKernel.cs index df13f4670..f21f7a56e 100644 --- a/WorkspaceServer/Kernel/CSharpKernel.cs +++ b/WorkspaceServer/Kernel/CSharpKernel.cs @@ -105,17 +105,17 @@ private async Task HandleSubmitCode( submitCode.Code, submitCode); - context.OnNext(codeSubmissionReceived); + context.Publish(codeSubmissionReceived); var code = submitCode.Code; var isComplete = await IsCompleteSubmissionAsync(submitCode.Code); if(isComplete) { - context.OnNext(new CompleteCodeSubmissionReceived(submitCode)); + context.Publish(new CompleteCodeSubmissionReceived(submitCode)); } else { - context.OnNext(new IncompleteCodeSubmissionReceived(submitCode)); + context.Publish(new IncompleteCodeSubmissionReceived(submitCode)); } if (submitCode.SubmissionType == SubmissionType.Diagnose) @@ -164,23 +164,23 @@ private async Task HandleSubmitCode( compilationError.Diagnostics.Select(d => d.ToString())); } - context.OnNext(new CommandFailed(exception, submitCode, message)); - context.OnCompleted(); + context.Publish(new CommandFailed(exception, submitCode, message)); + context.Complete(); } else { if (HasReturnValue) { var formattedValues = FormattedValue.FromObject(_scriptState.ReturnValue); - context.OnNext( + context.Publish( new ReturnValueProduced( _scriptState.ReturnValue, submitCode, formattedValues)); } - context.OnNext(new CodeSubmissionEvaluated(submitCode)); - context.OnCompleted(); + context.Publish(new CodeSubmissionEvaluated(submitCode)); + context.Complete(); } } @@ -195,7 +195,7 @@ private void PublishOutput( PlainTextFormatter.MimeType, output) }; - context.OnNext( + context.Publish( new DisplayedValueProduced( output, command, @@ -209,12 +209,12 @@ private async Task HandleRequestCompletion( { var completionRequestReceived = new CompletionRequestReceived(requestCompletion); - context.OnNext(completionRequestReceived); + context.Publish(completionRequestReceived); var completionList = await GetCompletionList(requestCompletion.Code, requestCompletion.CursorPosition, scriptState); - context.OnNext(new CompletionRequestCompleted(completionList, requestCompletion)); + context.Publish(new CompletionRequestCompleted(completionList, requestCompletion)); } public void AddMetatadaReferences(IEnumerable references) diff --git a/WorkspaceServer/Kernel/CSharpKernelExtensions.cs b/WorkspaceServer/Kernel/CSharpKernelExtensions.cs index c6b32019d..354d97e16 100644 --- a/WorkspaceServer/Kernel/CSharpKernelExtensions.cs +++ b/WorkspaceServer/Kernel/CSharpKernelExtensions.cs @@ -66,8 +66,8 @@ public static CSharpKernel UseNugetDirective(this CSharpKernel kernel) kernel.AddMetatadaReferences(refs); } - context.OnNext(new NuGetPackageAdded(package)); - context.OnCompleted(); + context.Publish(new NuGetPackageAdded(package)); + context.Complete(); } }; From 7348d2596c40c603cf23d7dc515b7a9791c00487 Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 19:23:30 +0100 Subject: [PATCH 13/14] change test to assert events in the text --- ..._r_nuget_using_kernel_client.approved.json | 2 -- ...faces_code_submission_Errors.approved.json | 3 -- .../Kernel/KernelClientTests.cs | 30 +++++++++++-------- 3 files changed, 18 insertions(+), 17 deletions(-) delete mode 100644 WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json delete mode 100644 WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_code_submission_Errors.approved.json diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json deleted file mode 100644 index 3a107b082..000000000 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_can_pound_r_nuget_using_kernel_client.approved.json +++ /dev/null @@ -1,2 +0,0 @@ -{"id":1,"eventType":"NuGetPackageAdded","event":{"packageReference":{"packageName":"Microsoft.Spark","packageVersion":"0.4.0"},"command":{"packageReference":{"packageName":"Microsoft.Spark","packageVersion":"0.4.0"}}}} -{"id":1,"eventType":"CodeSubmissionEvaluated","event":{"code":"#r \"nuget:Microsoft.Spark, 0.4.0\"","command":{"code":"#r \"nuget:Microsoft.Spark, 0.4.0\"","targetKernelName":null,"submissionType":0}}} diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_code_submission_Errors.approved.json b/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_code_submission_Errors.approved.json deleted file mode 100644 index 3a8214048..000000000 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.Kernel_client_surfaces_code_submission_Errors.approved.json +++ /dev/null @@ -1,3 +0,0 @@ -{"id":1,"eventType":"CodeSubmissionReceived","event":{"code":"var a = 12","value":"var a = 12","command":{"code":"var a = 12","targetKernelName":null,"submissionType":0}}} -{"id":1,"eventType":"IncompleteCodeSubmissionReceived","event":{"command":{"code":"var a = 12","targetKernelName":null,"submissionType":0}}} -{"id":1,"eventType":"CommandFailed","event":{"exception":{"diagnostics":[{"location":{"kind":1,"sourceSpan":{"start":10,"end":10,"length":0,"isEmpty":true},"sourceTree":{"filePath":"","encoding":null,"length":10,"hasCompilationUnitRoot":true,"options":{"languageVersion":703,"specifiedLanguageVersion":2147483647,"preprocessorSymbolNames":[],"language":"C#","features":{},"kind":1,"specifiedKind":1,"documentationMode":1,"errors":[]},"diagnosticOptions":{}},"isInSource":true,"isInMetadata":false,"metadataModule":null},"additionalLocations":[],"descriptor":{"id":"CS1002","title":{},"description":{},"helpLinkUri":"","messageFormat":{},"category":"Compiler","defaultSeverity":3,"isEnabledByDefault":true,"customTags":["Compiler","Telemetry","NotConfigurable"]},"id":"CS1002","severity":3,"defaultSeverity":3,"isSuppressed":false,"warningLevel":0,"info":{"code":1002,"descriptor":{"id":"CS1002","title":{},"description":{},"helpLinkUri":"","messageFormat":{},"category":"Compiler","defaultSeverity":3,"isEnabledByDefault":true,"customTags":["Compiler","Telemetry","NotConfigurable"]},"severity":3,"defaultSeverity":3,"warningLevel":0,"isWarningAsError":false,"category":"Compiler","additionalLocations":[],"messageIdentifier":"CS1002"},"isWarningAsError":false,"properties":{}}],"stackTrace":" at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter) in /_/src/Scripting/Core/ScriptBuilder.cs:line 113\r\n at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, Boolean emitDebugInformation, CancellationToken cancellationToken) in /_/src/Scripting/Core/ScriptBuilder.cs:line 82\r\n at Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 359\r\n at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 463\r\n at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 437\r\n at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync[T](String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken) in /_/src/Scripting/CSharp/CSharpScript.cs:line 91\r\n at Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.RunAsync(String code, ScriptOptions options, Object globals, Type globalsType, CancellationToken cancellationToken) in /_/src/Scripting/CSharp/CSharpScript.cs:line 105\r\n at WorkspaceServer.Kernel.CSharpKernel.HandleSubmitCode(SubmitCode submitCode, KernelInvocationContext context) in C:\\Users\\dicolomb\\source\\repos\\Public\\try\\WorkspaceServer\\Kernel\\CSharpKernel.cs:line 135","message":"(1,11): error CS1002: ; expected","data":{},"innerException":null,"helpLink":null,"source":"Microsoft.CodeAnalysis.Scripting","hResult":-2146233088},"message":"(1,11): error CS1002: ; expected","command":{"code":"var a = 12","targetKernelName":null,"submissionType":0}}} diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs index 262dc44c5..73d902ef2 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs @@ -1,13 +1,19 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.IO; +using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Assent; +using FluentAssertions; using Microsoft.DotNet.Interactive; using Microsoft.DotNet.Interactive.Commands; +using Microsoft.DotNet.Interactive.Events; using Microsoft.DotNet.Interactive.Tests; +using Newtonsoft.Json.Linq; using WorkspaceServer.Kernel; using Xunit; @@ -97,16 +103,7 @@ public async Task Kernel_client_surfaces_json_errors() [Fact] public async Task Kernel_client_surfaces_code_submission_Errors() { - var kernel = new CompositeKernel() - { - new CSharpKernel(), - new FakeKernel("fake") - { - Handle = context => Task.CompletedTask - } - }; - - kernel.DefaultKernelName = "csharp"; + var kernel = new CSharpKernel(); var input = new MemoryStream(); var writer = new StreamWriter(input, Encoding.UTF8); @@ -129,7 +126,13 @@ public async Task Kernel_client_surfaces_code_submission_Errors() var reader = new StreamReader(output, Encoding.UTF8); var text = reader.ReadToEnd(); - this.Assent(text, _configuration); + var events = text.Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries) + .Select(JObject.Parse).ToList(); + + events.Should() + .Contain(e => e["eventType"].Value() == nameof(IncompleteCodeSubmissionReceived)) + .And + .Contain(e => e["eventType"].Value() == nameof(CommandFailed)); } [Fact] @@ -160,7 +163,10 @@ public async Task Kernel_can_pound_r_nuget_using_kernel_client() var reader = new StreamReader(output, Encoding.UTF8); var text = reader.ReadToEnd(); - this.Assent(text, _configuration); + var events = text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) + .Select(JObject.Parse).ToList(); + + events.Should().Contain(e => e["eventType"].Value() == nameof(NuGetPackageAdded)); } } } \ No newline at end of file From 8cfd828eaa962e91ec49797f8d830a46b79eb630 Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 30 Aug 2019 19:39:06 +0100 Subject: [PATCH 14/14] assent as not interactive if not debugging --- WorkspaceServer.Tests/Kernel/KernelClientTests.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs index 73d902ef2..8362b36a3 100644 --- a/WorkspaceServer.Tests/Kernel/KernelClientTests.cs +++ b/WorkspaceServer.Tests/Kernel/KernelClientTests.cs @@ -2,10 +2,10 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; -using System.Text.RegularExpressions; using System.Threading.Tasks; using Assent; using FluentAssertions; @@ -28,8 +28,7 @@ public KernelClientTests() { _configuration = new Configuration() .UsingExtension("json"); - - _configuration = _configuration.SetInteractive(true); + _configuration = _configuration.SetInteractive(Debugger.IsAttached); } [Fact]