diff --git a/src/Microsoft.DotNet.Interactive.CSharp/CSharpKernel.cs b/src/Microsoft.DotNet.Interactive.CSharp/CSharpKernel.cs index 4786082034..1591203b81 100644 --- a/src/Microsoft.DotNet.Interactive.CSharp/CSharpKernel.cs +++ b/src/Microsoft.DotNet.Interactive.CSharp/CSharpKernel.cs @@ -336,7 +336,12 @@ await RunAsync( { if (ScriptState is not null && HasReturnValue) { - var formattedValues = FormattedValue.CreateManyFromObject(ScriptState.ReturnValue); + IReadOnlyList formattedValues = ScriptState.ReturnValue switch + { + FormattedValue formattedValue => new[] { formattedValue }, + IEnumerable formattedValueEnumerable => formattedValueEnumerable.ToArray(), + _ => FormattedValue.CreateManyFromObject(ScriptState.ReturnValue) + }; context.Publish( new ReturnValueProduced( ScriptState.ReturnValue, diff --git a/src/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs b/src/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs index a626d9158f..7165989e81 100644 --- a/src/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs +++ b/src/Microsoft.DotNet.Interactive.FSharp/FSharpKernel.fs @@ -215,9 +215,13 @@ type FSharpKernel () as this = | Ok(result) when not isError -> match result with | Some(value) when value.ReflectionType <> typeof -> - let value = value.ReflectionValue - let formattedValues = FormattedValue.CreateManyFromObject(value) - context.Publish(ReturnValueProduced(value, codeSubmission, formattedValues)) + let resultValue = value.ReflectionValue + let formattedValues : IReadOnlyList = + match resultValue with + | :? FormattedValue as formattedValue -> Seq.singleton( formattedValue ).ToImmutableList() + | :? IEnumerable as formattedValueEnumerable -> formattedValueEnumerable.ToImmutableList() + | _ -> FormattedValue.CreateManyFromObject(resultValue) + context.Publish(ReturnValueProduced(resultValue, codeSubmission, formattedValues)) | Some _ | None -> () | _ -> diff --git a/src/Microsoft.DotNet.Interactive.Tests/LanguageKernelTests.cs b/src/Microsoft.DotNet.Interactive.Tests/LanguageKernelTests.cs index fe13df204f..dc7ebc69ea 100644 --- a/src/Microsoft.DotNet.Interactive.Tests/LanguageKernelTests.cs +++ b/src/Microsoft.DotNet.Interactive.Tests/LanguageKernelTests.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Collections.Generic; using System.CommandLine; using System.CommandLine.NamingConventionBinder; using System.Linq; @@ -865,6 +866,42 @@ public async Task it_returns_a_result_for_a_if_expressions(Language language, st .Be(25); } + [Theory] + [InlineData(Language.CSharp, """ + using Microsoft.DotNet.Interactive; + FormattedValue.CreateSingleFromObject(1) + """)] + [InlineData(Language.FSharp, """ + open Microsoft.DotNet.Interactive + FormattedValue.CreateSingleFromObject(1) + """)] + + [InlineData(Language.CSharp, """ + using Microsoft.DotNet.Interactive; + FormattedValue.CreateManyFromObject(1, "text/plain","application/json") + """)] + [InlineData(Language.FSharp, """ + open Microsoft.DotNet.Interactive + FormattedValue.CreateManyFromObject(1, "text/plain","application/json") + """)] + + public async Task it_returns_formattedValue_without_additional_formatting(Language language, string expression) + { + var kernel = CreateKernel(language); + + await SubmitCode(kernel, expression); + + var returnValueProduced = KernelEvents.Should().ContainSingle().Which; + + var returnedValues = returnValueProduced.Value switch + { + IEnumerable formattedValues => formattedValues, + FormattedValue formattedValue => new[] { formattedValue }, + _ => throw new InvalidOperationException() + }; + returnValueProduced.FormattedValues.Should().BeEquivalentTo(returnedValues); + } + [Theory] [InlineData(Language.CSharp)]