-
Notifications
You must be signed in to change notification settings - Fork 390
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add DisplayTable method #3098
add DisplayTable method #3098
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,7 +62,7 @@ internal static PocketView TagWithPlainTextStyling( | |
internal static FormatterMapByType FormattersForAnyObject; | ||
|
||
internal static FormatterMapByType FormattersForAnyEnumerable = | ||
new(typeof(HtmlFormatter<>), nameof(HtmlFormatter<object>.CreateTableFormatterForAnyEnumerable)); | ||
new(typeof(HtmlFormatter<>), nameof(HtmlFormatter<object>.CreateTreeViewFormatterForAnyEnumerable)); | ||
|
||
internal static readonly ITypeFormatter[] DefaultFormatters = | ||
{ | ||
|
@@ -212,11 +212,11 @@ type.FullName is not null && | |
return true; | ||
}), | ||
|
||
new HtmlFormatter<decimal>((value, context) => | ||
{ | ||
FormatAndStyleAsPlainText(value, context); | ||
return true; | ||
}), | ||
new HtmlFormatter<decimal>((value, context) => | ||
{ | ||
FormatAndStyleAsPlainText(value, context); | ||
return true; | ||
}), | ||
|
||
new HtmlFormatter<object>((value, context) => | ||
{ | ||
|
@@ -226,22 +226,7 @@ type.FullName is not null && | |
var formatter = GetDefaultFormatterForAnyObject(type); | ||
return formatter.Format(value, context); | ||
}), | ||
|
||
// Final last resort is to convert to plain text | ||
new HtmlFormatter<object>((value, context) => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this removed because it was redundant? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. There were two different registrations for the same type. This one had no test coverage so it wasn't important. |
||
{ | ||
if (value is null) | ||
{ | ||
FormatAndStyleAsPlainText(Formatter.NullString, context); | ||
} | ||
else | ||
{ | ||
FormatAndStyleAsPlainText(value, context); | ||
} | ||
|
||
return true; | ||
}), | ||
|
||
|
||
new HtmlFormatter<JsonDocument>((doc, context) => | ||
{ | ||
doc.RootElement.FormatTo(context, MimeType); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,16 @@ | ||
// 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.Linq; | ||
using System.Reactive.Linq; | ||
using System.Threading.Tasks; | ||
using FluentAssertions; | ||
using Microsoft.DotNet.Interactive.Commands; | ||
using Microsoft.DotNet.Interactive.CSharp; | ||
using Microsoft.DotNet.Interactive.Events; | ||
using Microsoft.DotNet.Interactive.Formatting; | ||
using Microsoft.DotNet.Interactive.Tests.Utility; | ||
using Microsoft.DotNet.Interactive.Formatting.Tests.Utility; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
using static Microsoft.DotNet.Interactive.Formatting.Tests.Tags; | ||
|
@@ -116,7 +117,7 @@ public async Task String_is_rendered_as_plain_text_via_implicit_return( | |
[Theory] | ||
[InlineData(Language.CSharp, "{ \"hello\": 123 ", "application/json")] | ||
[InlineData(Language.CSharp, "<span class=\"test\">hello! </span>", "text/html")] | ||
public async Task String_is_rendered_as_specified_mime_type_DisplayAs( | ||
public async Task DisplayAs_renders_string_as_specified_mime_type( | ||
Language language, | ||
string stringValue, | ||
string mimeType) | ||
|
@@ -145,7 +146,69 @@ await kernel.FindKernelByName("csharp").As<CSharpKernel>() | |
[Theory] | ||
[InlineData(Language.CSharp)] | ||
[InlineData(Language.FSharp)] | ||
public async Task Display_helper_can_be_called_without_specifying_class_name(Language language) | ||
public async Task DisplayTable_produces_tabular_HTML_output_for_IEnumerable_T(Language language) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should there be another test to validate what happens when the collection contains instances with heterogeneous types? |
||
{ | ||
var kernel = CreateKernel(language, openTestingNamespaces: true); | ||
|
||
var code = language switch | ||
{ | ||
Language.CSharp => """ | ||
new[] { | ||
new { Title = "Troll 2", Stars = 0.25 }, | ||
new { Title = "The Room", Stars = 0.4 } }.DisplayTable(); | ||
""", | ||
Language.FSharp => """ | ||
type MovieRating = { Title: string; Stars: float } | ||
let ratings = | ||
[ { Title = "Troll 2"; Stars = 0.25 }; | ||
{ Title = "The Room"; Stars = 0.4 } ] | ||
ratings.DisplayTable() | ||
""" | ||
}; | ||
|
||
var result = await kernel.SendAsync(new SubmitCode(code)); | ||
|
||
result.Events.Should().NotContainErrors(); | ||
|
||
result.Events | ||
.Should().ContainSingle<DisplayedValueProduced>() | ||
.Which | ||
.FormattedValues.Should().ContainSingle() | ||
.Which | ||
.Value.Should().ContainEquivalentHtmlFragments(""" | ||
<table> | ||
<thead> | ||
<tr> | ||
<td><span>Title</span></td> | ||
<td><span>Stars</span></td> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td>Troll 2</td> | ||
<td> | ||
<div class="dni-plaintext"> | ||
<pre>0.25</pre> | ||
</div> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td>The Room</td> | ||
<td> | ||
<div class="dni-plaintext"> | ||
<pre>0.4</pre> | ||
</div> | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
"""); | ||
} | ||
|
||
[Theory] | ||
[InlineData(Language.CSharp)] | ||
[InlineData(Language.FSharp)] | ||
public async Task display_can_be_called_without_specifying_class_name(Language language) | ||
{ | ||
var kernel = CreateKernel(language, openTestingNamespaces: true); | ||
|
||
|
@@ -189,7 +252,6 @@ public async Task Displayed_value_can_be_updated(Language language) | |
v.MimeType == "text/html" && | ||
v.Value.ToString().Contains("<b>hello</b>")); | ||
|
||
|
||
KernelEvents | ||
.OfType<DisplayedValueUpdated>() | ||
.SelectMany(v => v.FormattedValues) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -134,15 +134,24 @@ public void Directive_parsing_errors_are_available_as_diagnostics() | |
.Should() | ||
.ContainSingle<DirectiveNode>() | ||
.Which; | ||
node | ||
.GetDiagnostics() | ||
|
||
var diagnostics = node.GetDiagnostics(); | ||
|
||
diagnostics | ||
.Should() | ||
.ContainSingle(d => d.Severity == CodeAnalysis.DiagnosticSeverity.Error) | ||
.Which | ||
.LinePositionSpan.End.Character | ||
.Should() | ||
.Be(node.Span.End); | ||
|
||
diagnostics | ||
.Should() | ||
.ContainSingle(d => d.Severity == DiagnosticSeverity.Error) | ||
.ContainSingle(d => d.Severity == CodeAnalysis.DiagnosticSeverity.Error) | ||
.Which | ||
.Location | ||
.SourceSpan | ||
.LinePositionSpan.Start.Character | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Considering creating a local for the LinePositionSpan so that the code to select the diagnostic need not be repeated across the 2 assertions. |
||
.Should() | ||
.BeEquivalentTo(node.Span); | ||
.Be(node.Span.Start); | ||
} | ||
|
||
[Theory] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like most lambdas in this collection don't guard against the
value
beingnull
(although the removed last resort one below was checking for this). Is this intentional or does some other piece of code else already filter out nulls before these lambdas are invoked?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Matching is done based on the runtime type and the formatter provides a universal early out for
null
.