From fd9cb08790bcbbb2d7017dbaef31d5b2f80c6bb6 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Fri, 15 Sep 2017 13:54:26 -0700 Subject: [PATCH] Add Switch.Microsoft.AspNetCore.Mvc.UseDateTimeTypeForDateTimeOffset quirks mode - patch recipients can use switch to undo the #6648 fix --- .../InputTagHelper.cs | 17 +- .../ViewFeatures/TemplateRenderer.cs | 11 +- .../HtmlHelperOptionsTest.cs | 20 ++- .../InputTagHelperTest.cs | 69 ++++++-- .../Internal/DefaultEditorTemplatesTest.cs | 153 +++++++++++++----- 5 files changed, 208 insertions(+), 62 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/InputTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/InputTagHelper.cs index 18407ace88..6177a42729 100644 --- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/InputTagHelper.cs +++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/InputTagHelper.cs @@ -18,6 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers [HtmlTargetElement("input", Attributes = ForAttributeName, TagStructure = TagStructure.WithoutEndTag)] public class InputTagHelper : TagHelper { + internal const string UseDateTimeLocalTypeForDateTimeOffsetSwitch = "Switch.Microsoft.AspNetCore.Mvc.UseDateTimeLocalTypeForDateTimeOffset"; private const string ForAttributeName = "asp-for"; private const string FormatAttributeName = "asp-format"; @@ -63,6 +64,14 @@ public class InputTagHelper : TagHelper { "time", "{0:HH:mm:ss.fff}" }, }; + static InputTagHelper() + { + if (AppContext.TryGetSwitch(UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled) && enabled) + { + _defaultInputTypes.Remove(nameof(DateTimeOffset)); + } + } + /// /// Creates a new . /// @@ -393,8 +402,14 @@ private string GetFormat(ModelExplorer modelExplorer, string inputTypeHint, stri { // Rfc3339 mode _may_ override EditFormatString in a limited number of cases. Happens only when // EditFormatString has a default format i.e. came from a [DataType] attribute. + // + // First condition may occur when Switch.Microsoft.AspNetCore.Mvc.UseDateTimeLocalTypeForDateTimeOffset + // is true in extremely rare cases: The element for a DateTimeOffset expression must have + // type ="text". Checking the switch again to remove that case. if (string.Equals("text", inputType) && - string.Equals(nameof(DateTimeOffset), inputTypeHint, StringComparison.OrdinalIgnoreCase)) + string.Equals(nameof(DateTimeOffset), inputTypeHint, StringComparison.OrdinalIgnoreCase) && + !(AppContext.TryGetSwitch(UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled) && + enabled)) { // Auto-select a format that round-trips Offset and sub-Second values in a DateTimeOffset. Not // done if user chose the "text" type in .cshtml file or with data annotations i.e. when diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/TemplateRenderer.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/TemplateRenderer.cs index 9ccc1cd361..a7a3073e1e 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/TemplateRenderer.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewFeatures/TemplateRenderer.cs @@ -17,9 +17,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal { public class TemplateRenderer { + public const string IEnumerableOfIFormFileName = "IEnumerable`" + nameof(IFormFile); + internal const string UseDateTimeLocalTypeForDateTimeOffsetSwitch = "Switch.Microsoft.AspNetCore.Mvc.UseDateTimeLocalTypeForDateTimeOffset"; private const string DisplayTemplateViewPath = "DisplayTemplates"; private const string EditorTemplateViewPath = "EditorTemplates"; - public const string IEnumerableOfIFormFileName = "IEnumerable`" + nameof(IFormFile); private static readonly Dictionary> _defaultDisplayActions = new Dictionary>(StringComparer.OrdinalIgnoreCase) @@ -75,6 +76,14 @@ public class TemplateRenderer private readonly string _templateName; private readonly bool _readOnly; + static TemplateRenderer() + { + if (AppContext.TryGetSwitch(UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled) && enabled) + { + _defaultEditorActions.Remove(nameof(DateTimeOffset)); + } + } + public TemplateRenderer( IViewEngine viewEngine, IViewBufferScope bufferScope, diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/HtmlHelperOptionsTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/HtmlHelperOptionsTest.cs index 76faef248d..855a4ae8ed 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/HtmlHelperOptionsTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/HtmlHelperOptionsTest.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Testing; @@ -10,6 +11,8 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests { public class HtmlHelperOptionsTest : IClassFixture> { + private const string UseDateTimeLocalTypeForDateTimeOffsetSwitch = "Switch.Microsoft.AspNetCore.Mvc.UseDateTimeLocalTypeForDateTimeOffset"; + public HtmlHelperOptionsTest(MvcTestFixture fixture) { Client = fixture.Client; @@ -21,14 +24,17 @@ public HtmlHelperOptionsTest(MvcTestFixture fixture) public async Task AppWideDefaultsInViewAndPartialView() { // Arrange + AppContext.TryGetSwitch(UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + var expectedType = enabled ? "datetime-local" : "text"; + var expectedOffset = enabled ? string.Empty : "+00:00"; var expected = -@"
MySummary +$@"
MySummary
  • A model error occurred.
An error occurred.
-
+
MySummary
  • A model error occurred.
  • @@ -36,7 +42,7 @@ public async Task AppWideDefaultsInViewAndPartialView() An error occurred.
    -
    +
    False"; @@ -52,14 +58,16 @@ public async Task AppWideDefaultsInViewAndPartialView() public async Task OverrideAppWideDefaultsInViewAndPartialView() { // Arrange + AppContext.TryGetSwitch(UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + var expectedType = enabled ? "datetime-local" : "text"; var expected = -@"
    MySummary +$@"
    MySummary
    • A model error occurred.
    An error occurred.
    -
    +
    True
    MySummary @@ -68,7 +76,7 @@ public async Task OverrideAppWideDefaultsInViewAndPartialView() An error occurred.
    -
    +
    True"; diff --git a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/InputTagHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/InputTagHelperTest.cs index 987623ac57..c6ccda9244 100644 --- a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/InputTagHelperTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/InputTagHelperTest.cs @@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers { public class InputTagHelperTest { - public static TheoryData MultiAttributeCheckBoxData + public static TheoryData MultiAttributeCheckBoxData { get { @@ -386,10 +386,22 @@ public async Task ProcessAsync_GeneratesExpectedOutput( Assert.Equal(expectedTagName, output.TagName); } + public static TheoryData Process_GeneratesFormattedOutputData + { + get + { + AppContext.TryGetSwitch(InputTagHelper.UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + return new TheoryData + { + { "datetime", "datetime" }, + { null, enabled ? "datetime-local" : "text" }, + { "hidden", "hidden" }, + }; + } + } + [Theory] - [InlineData("datetime", "datetime")] - [InlineData(null, "text")] - [InlineData("hidden", "hidden")] + [MemberData(nameof(Process_GeneratesFormattedOutputData))] public void Process_GeneratesFormattedOutput(string specifiedType, string expectedType) { // Arrange @@ -1206,20 +1218,43 @@ public async Task ProcessAsync_CallsGenerateTextBox_InputTypeDateTime_RendersAsD Assert.Equal(expectedTagName, output.TagName); } + public static TheoryData ProcessAsync_CallsGenerateTextBox_AddsExpectedAttributesForRfc3339Data + { + get + { + AppContext.TryGetSwitch(InputTagHelper.UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + var expectedK = enabled ? string.Empty : "K"; + return new TheoryData + { + { "Date", Html5DateRenderingMode.CurrentCulture, "{0:d}", "date" }, // Format from [DataType]. + { "Date", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date" }, + { "DateTime", Html5DateRenderingMode.CurrentCulture, null, "datetime-local" }, + { "DateTime", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local" }, + { "DateTimeOffset", Html5DateRenderingMode.CurrentCulture, null, enabled ? "datetime-local" : "text" }, + { + "DateTimeOffset", + Html5DateRenderingMode.Rfc3339, + $"{{0:yyyy-MM-ddTHH:mm:ss.fff{expectedK}}}", + enabled ? "datetime-local" : "text" + }, + { "DateTimeLocal", Html5DateRenderingMode.CurrentCulture, null, "datetime-local" }, + { "DateTimeLocal", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local" }, + { "Time", Html5DateRenderingMode.CurrentCulture, "{0:t}", "time" }, // Format from [DataType]. + { "Time", Html5DateRenderingMode.Rfc3339, "{0:HH:mm:ss.fff}", "time" }, + { "NullableDate", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date" }, + { "NullableDateTime", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local" }, + { + "NullableDateTimeOffset", + Html5DateRenderingMode.Rfc3339, + $"{{0:yyyy-MM-ddTHH:mm:ss.fff{expectedK}}}", + enabled ? "datetime-local" : "text" + }, + }; + } + } + [Theory] - [InlineData("Date", Html5DateRenderingMode.CurrentCulture, "{0:d}", "date")] // Format from [DataType]. - [InlineData("Date", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date")] - [InlineData("DateTime", Html5DateRenderingMode.CurrentCulture, null, "datetime-local")] - [InlineData("DateTime", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local")] - [InlineData("DateTimeOffset", Html5DateRenderingMode.CurrentCulture, null, "text")] - [InlineData("DateTimeOffset", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fffK}", "text")] - [InlineData("DateTimeLocal", Html5DateRenderingMode.CurrentCulture, null, "datetime-local")] - [InlineData("DateTimeLocal", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local")] - [InlineData("Time", Html5DateRenderingMode.CurrentCulture, "{0:t}", "time")] // Format from [DataType]. - [InlineData("Time", Html5DateRenderingMode.Rfc3339, "{0:HH:mm:ss.fff}", "time")] - [InlineData("NullableDate", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-dd}", "date")] - [InlineData("NullableDateTime", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fff}", "datetime-local")] - [InlineData("NullableDateTimeOffset", Html5DateRenderingMode.Rfc3339, "{0:yyyy-MM-ddTHH:mm:ss.fffK}", "text")] + [MemberData(nameof(ProcessAsync_CallsGenerateTextBox_AddsExpectedAttributesForRfc3339Data))] public async Task ProcessAsync_CallsGenerateTextBox_AddsExpectedAttributesForRfc3339( string propertyName, Html5DateRenderingMode dateRenderingMode, diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs index aaff2c2877..aed6e75320 100644 --- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/DefaultEditorTemplatesTest.cs @@ -29,6 +29,10 @@ public static TheoryData TemplateNameData { get { + AppContext.TryGetSwitch(TemplateRenderer.UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + + // Tests use string properties and fall back to text template (no type attribute) when quirk is enabled. + var dateTimeOffsetType = enabled ? string.Empty : " type='text'"; return new TheoryData { { null, "__TextBox__ class='text-box single-line'" }, @@ -53,8 +57,8 @@ public static TheoryData TemplateNameData { "datetime", "__TextBox__ class='text-box single-line' type='datetime-local'" }, { "DateTime-local", "__TextBox__ class='text-box single-line' type='datetime-local'" }, { "DATETIME-LOCAL", "__TextBox__ class='text-box single-line' type='datetime-local'" }, - { "datetimeoffset", "__TextBox__ class='text-box single-line' type='text'" }, - { "DateTimeOffset", "__TextBox__ class='text-box single-line' type='text'" }, + { "datetimeoffset", $"__TextBox__ class='text-box single-line'{dateTimeOffsetType}" }, + { "DateTimeOffset", $"__TextBox__ class='text-box single-line'{dateTimeOffsetType}" }, { "Time", "__TextBox__ class='text-box single-line' type='time'" }, { "time", "__TextBox__ class='text-box single-line' type='time'" }, { "Byte", "__TextBox__ class='text-box single-line' type='number'" }, @@ -774,9 +778,12 @@ public void Editor_InputTypeDateTime_RendersAsDateTime() { // Arrange var requiredMessage = ValidationAttributeUtil.GetRequiredErrorMessage("DateTimeOffset"); + AppContext.TryGetSwitch(TemplateRenderer.UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + var expectedOffset = enabled ? string.Empty : "+00:00"; var expectedInput = ""; + "name=\"HtmlEncode[[FieldPrefix]]\" type=\"HtmlEncode[[datetime]]\" " + + $"value=\"HtmlEncode[[2000-01-02T03:04:05.060{expectedOffset}]]\" />"; var offset = TimeSpan.FromHours(0); var model = new DateTimeOffset( @@ -814,14 +821,32 @@ public void Editor_InputTypeDateTime_RendersAsDateTime() Assert.Equal(expectedInput, HtmlContentUtilities.HtmlContentToString(result)); } + public static TheoryData Editor_FindsCorrectDateOrTimeTemplateData + { + get + { + AppContext.TryGetSwitch(TemplateRenderer.UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + var expectedOffset = enabled ? string.Empty : "-05:00"; + return new TheoryData + { + { null, null, $"2000-01-02T03:04:05.060{expectedOffset}", enabled ? "datetime-local" : "text" }, + { "date", "{0:d}", "2000-01-02", "date" }, + { "datetime", null, "2000-01-02T03:04:05.060", "datetime-local" }, + { "datetime-local", null, "2000-01-02T03:04:05.060", "datetime-local" }, + { + "DateTimeOffset", + "{0:o}", + $"2000-01-02T03:04:05.060{expectedOffset}", + enabled ? "datetime-local" : "text" + }, + { "time", "{0:t}", "03:04:05.060", "time" }, + }; + } + } + // Html5DateRenderingMode.Rfc3339 is enabled by default. [Theory] - [InlineData(null, null, "2000-01-02T03:04:05.060-05:00", "text")] - [InlineData("date", "{0:d}", "2000-01-02", "date")] - [InlineData("datetime", null, "2000-01-02T03:04:05.060", "datetime-local")] - [InlineData("datetime-local", null, "2000-01-02T03:04:05.060", "datetime-local")] - [InlineData("DateTimeOffset", "{0:o}", "2000-01-02T03:04:05.060-05:00", "text")] - [InlineData("time", "{0:t}", "03:04:05.060", "time")] + [MemberData(nameof(Editor_FindsCorrectDateOrTimeTemplateData))] public void Editor_FindsCorrectDateOrTimeTemplate( string dataTypeName, string editFormatString, @@ -875,14 +900,26 @@ public void Editor_FindsCorrectDateOrTimeTemplate( Assert.Equal(expectedInput, HtmlContentUtilities.HtmlContentToString(result)); } + public static TheoryData Editor_FindsCorrectDateOrTimeTemplate_NotRfc3339Data + { + get + { + AppContext.TryGetSwitch(TemplateRenderer.UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + return new TheoryData + { + { null, null, "02/01/2000 03:04:05 -05:00", enabled ? "datetime-local" : "text" }, + { "date", "{0:d}", "02/01/2000", "date" }, + { "datetime", null, "02/01/2000 03:04:05 -05:00", "datetime-local" }, + { "datetime-local", null, "02/01/2000 03:04:05 -05:00", "datetime-local" }, + { "DateTimeOffset", "{0:o}", "2000-01-02T03:04:05.0600000-05:00", enabled ? "datetime-local" : "text" }, + { "time", "{0:t}", "03:04", "time" }, + }; + } + } + // Html5DateRenderingMode.Rfc3339 can be disabled. [Theory] - [InlineData(null, null, "02/01/2000 03:04:05 -05:00", "text")] - [InlineData("date", "{0:d}", "02/01/2000", "date")] - [InlineData("datetime", null, "02/01/2000 03:04:05 -05:00", "datetime-local")] - [InlineData("datetime-local", null, "02/01/2000 03:04:05 -05:00", "datetime-local")] - [InlineData("DateTimeOffset", "{0:o}", "2000-01-02T03:04:05.0600000-05:00", "text")] - [InlineData("time", "{0:t}", "03:04", "time")] + [MemberData(nameof(Editor_FindsCorrectDateOrTimeTemplate_NotRfc3339Data))] [ReplaceCulture] public void Editor_FindsCorrectDateOrTimeTemplate_NotRfc3339( string dataTypeName, @@ -939,14 +976,32 @@ public void Editor_FindsCorrectDateOrTimeTemplate_NotRfc3339( Assert.Equal(expectedInput, HtmlContentUtilities.HtmlContentToString(result)); } + public static TheoryData Editor_FindsCorrectDateOrTimeTemplate_ForDateTimeData + { + get + { + AppContext.TryGetSwitch(TemplateRenderer.UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + var expectedZ = enabled ? string.Empty : "Z"; + return new TheoryData + { + { null, null, "2000-01-02T03:04:05.060", "datetime-local" }, + { "date", "{0:d}", "2000-01-02", "date" }, + { "datetime", null, "2000-01-02T03:04:05.060", "datetime-local" }, + { "datetime-local", null, "2000-01-02T03:04:05.060", "datetime-local" }, + { + "DateTimeOffset", + "{0:o}", + $"2000-01-02T03:04:05.060{expectedZ}", + enabled ? "datetime-local" : "text" + }, + { "time", "{0:t}", "03:04:05.060", "time" }, + }; + } + } + // Html5DateRenderingMode.Rfc3339 is enabled by default. [Theory] - [InlineData(null, null, "2000-01-02T03:04:05.060", "datetime-local")] - [InlineData("date", "{0:d}", "2000-01-02", "date")] - [InlineData("datetime", null, "2000-01-02T03:04:05.060", "datetime-local")] - [InlineData("datetime-local", null, "2000-01-02T03:04:05.060", "datetime-local")] - [InlineData("DateTimeOffset", "{0:o}", "2000-01-02T03:04:05.060Z", "text")] - [InlineData("time", "{0:t}", "03:04:05.060", "time")] + [MemberData(nameof(Editor_FindsCorrectDateOrTimeTemplate_ForDateTimeData))] public void Editor_FindsCorrectDateOrTimeTemplate_ForDateTime( string dataTypeName, string editFormatString, @@ -999,14 +1054,26 @@ public void Editor_FindsCorrectDateOrTimeTemplate_ForDateTime( Assert.Equal(expectedInput, HtmlContentUtilities.HtmlContentToString(result)); } + public static TheoryData Editor_FindsCorrectDateOrTimeTemplate_ForDateTimeNotRfc3339Data + { + get + { + AppContext.TryGetSwitch(TemplateRenderer.UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + return new TheoryData + { + { null, null, "02/01/2000 03:04:05", "datetime-local" }, + { "date", "{0:d}", "02/01/2000", "date" }, + { "datetime", null, "02/01/2000 03:04:05", "datetime-local" }, + { "datetime-local", null, "02/01/2000 03:04:05", "datetime-local" }, + { "DateTimeOffset", "{0:o}", "2000-01-02T03:04:05.0600000Z", enabled ? "datetime-local" : "text" }, + { "time", "{0:t}", "03:04", "time" }, + }; + } + } + // Html5DateRenderingMode.Rfc3339 can be disabled. [Theory] - [InlineData(null, null, "02/01/2000 03:04:05", "datetime-local")] - [InlineData("date", "{0:d}", "02/01/2000", "date")] - [InlineData("datetime", null, "02/01/2000 03:04:05", "datetime-local")] - [InlineData("datetime-local", null, "02/01/2000 03:04:05", "datetime-local")] - [InlineData("DateTimeOffset", "{0:o}", "2000-01-02T03:04:05.0600000Z", "text")] - [InlineData("time", "{0:t}", "03:04", "time")] + [MemberData(nameof(Editor_FindsCorrectDateOrTimeTemplate_ForDateTimeNotRfc3339Data))] [ReplaceCulture] public void Editor_FindsCorrectDateOrTimeTemplate_ForDateTimeNotRfc3339( string dataTypeName, @@ -1062,17 +1129,29 @@ public void Editor_FindsCorrectDateOrTimeTemplate_ForDateTimeNotRfc3339( Assert.Equal(expectedInput, HtmlContentUtilities.HtmlContentToString(result)); } + public static TheoryData Editor_AppliesNonDefaultEditFormatData + { + get + { + AppContext.TryGetSwitch(TemplateRenderer.UseDateTimeLocalTypeForDateTimeOffsetSwitch, out var enabled); + return new TheoryData + { + { null, Html5DateRenderingMode.CurrentCulture, enabled ? "datetime-local" : "text" }, + { null, Html5DateRenderingMode.Rfc3339, enabled ? "datetime-local" : "text" }, + { "date", Html5DateRenderingMode.CurrentCulture, "date" }, + { "date", Html5DateRenderingMode.Rfc3339, "date" }, + { "datetime", Html5DateRenderingMode.CurrentCulture, "datetime-local" }, + { "datetime", Html5DateRenderingMode.Rfc3339, "datetime-local" }, + { "datetime-local", Html5DateRenderingMode.CurrentCulture, "datetime-local" }, + { "datetime-local", Html5DateRenderingMode.Rfc3339, "datetime-local" }, + { "time", Html5DateRenderingMode.CurrentCulture, "time" }, + { "time", Html5DateRenderingMode.Rfc3339, "time" }, + }; + } + } + [Theory] - [InlineData(null, Html5DateRenderingMode.CurrentCulture, "text")] - [InlineData(null, Html5DateRenderingMode.Rfc3339, "text")] - [InlineData("date", Html5DateRenderingMode.CurrentCulture, "date")] - [InlineData("date", Html5DateRenderingMode.Rfc3339, "date")] - [InlineData("datetime", Html5DateRenderingMode.CurrentCulture, "datetime-local")] - [InlineData("datetime", Html5DateRenderingMode.Rfc3339, "datetime-local")] - [InlineData("datetime-local", Html5DateRenderingMode.CurrentCulture, "datetime-local")] - [InlineData("datetime-local", Html5DateRenderingMode.Rfc3339, "datetime-local")] - [InlineData("time", Html5DateRenderingMode.CurrentCulture, "time")] - [InlineData("time", Html5DateRenderingMode.Rfc3339, "time")] + [MemberData(nameof(Editor_AppliesNonDefaultEditFormatData))] public void Editor_AppliesNonDefaultEditFormat(string dataTypeName, Html5DateRenderingMode renderingMode, string expectedType) { // Arrange