Add more tests covering `asp-format` use
- also add comments requested in PR #5109 and #5205
This commit is contained in:
parent
4bda1cbe6d
commit
34a4c8c191
|
|
@ -98,8 +98,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
/// attribute to that formatted <see cref="string"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used only the calculated "type" attribute is "text" (the most common value) e.g.
|
||||
/// <see cref="InputTypeName"/> is "String". That is, <see cref="Format"/> is used when calling
|
||||
/// Not used if the provided (see <see cref="InputTypeName"/>) or calculated "type" attribute value is
|
||||
/// <c>checkbox</c>, <c>password</c>, or <c>radio</c>. That is, <see cref="Format"/> is used when calling
|
||||
/// <see cref="IHtmlGenerator.GenerateTextBox"/>.
|
||||
/// </remarks>
|
||||
[HtmlAttributeName(FormatAttributeName)]
|
||||
|
|
@ -110,8 +110,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Passed through to the generated HTML in all cases. Also used to determine the <see cref="IHtmlGenerator"/>
|
||||
/// helper to call and the default <see cref="Format"/> value (when calling
|
||||
/// <see cref="IHtmlGenerator.GenerateTextBox"/>).
|
||||
/// helper to call and the default <see cref="Format"/> value. A default <see cref="Format"/> is not calculated
|
||||
/// if the provided (see <see cref="InputTypeName"/>) or calculated "type" attribute value is <c>checkbox</c>,
|
||||
/// <c>hidden</c>, <c>password</c>, or <c>radio</c>.
|
||||
/// </remarks>
|
||||
[HtmlAttributeName("type")]
|
||||
public string InputTypeName { get; set; }
|
||||
|
|
@ -358,6 +359,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
htmlAttributes: htmlAttributes);
|
||||
}
|
||||
|
||||
// Imitate Generator.GenerateHidden() using Generator.GenerateTextBox(). This adds support for asp-format that
|
||||
// is not available in Generator.GenerateHidden().
|
||||
private TagBuilder GenerateHidden(ModelExplorer modelExplorer)
|
||||
{
|
||||
var value = For.Model;
|
||||
|
|
@ -367,6 +370,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
value = Convert.ToBase64String(byteArrayValue);
|
||||
}
|
||||
|
||||
// In DefaultHtmlGenerator(), GenerateTextBox() calls GenerateInput() _almost_ identically to how
|
||||
// GenerateHidden() does and the main switch inside GenerateInput() handles InputType.Text and
|
||||
// InputType.Hidden identically. No behavior differences at all when a type HTML attribute already exists.
|
||||
var htmlAttributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "type", "hidden" }
|
||||
|
|
|
|||
|
|
@ -246,6 +246,75 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
Assert.Equal(expectedTagName, output.TagName);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, "datetime")]
|
||||
[InlineData("hidden", "hidden")]
|
||||
public void Process_GeneratesFormattedOutput(string specifiedType, string expectedType)
|
||||
{
|
||||
// Arrange
|
||||
var expectedAttributes = new TagHelperAttributeList
|
||||
{
|
||||
{ "type", expectedType },
|
||||
{ "id", "DateTimeOffset" },
|
||||
{ "name", "DateTimeOffset" },
|
||||
{ "valid", "from validation attributes" },
|
||||
{ "value", "datetime: 2011-08-31T05:30:45.0000000+03:00" },
|
||||
};
|
||||
var expectedTagName = "not-input";
|
||||
var container = new Model
|
||||
{
|
||||
DateTimeOffset = new DateTimeOffset(2011, 8, 31, hour: 5, minute: 30, second: 45, offset: TimeSpan.FromHours(3))
|
||||
};
|
||||
|
||||
var allAttributes = new TagHelperAttributeList
|
||||
{
|
||||
{ "type", specifiedType },
|
||||
};
|
||||
var context = new TagHelperContext(
|
||||
allAttributes: allAttributes,
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: "test");
|
||||
var output = new TagHelperOutput(
|
||||
expectedTagName,
|
||||
new TagHelperAttributeList(),
|
||||
getChildContentAsync: (useCachedResult, encoder) =>
|
||||
{
|
||||
throw new Exception("getChildContentAsync should not be called.");
|
||||
})
|
||||
{
|
||||
TagMode = TagMode.StartTagOnly,
|
||||
};
|
||||
|
||||
var htmlGenerator = new TestableHtmlGenerator(new EmptyModelMetadataProvider())
|
||||
{
|
||||
ValidationAttributes =
|
||||
{
|
||||
{ "valid", "from validation attributes" },
|
||||
}
|
||||
};
|
||||
|
||||
var tagHelper = GetTagHelper(
|
||||
htmlGenerator,
|
||||
container,
|
||||
typeof(Model),
|
||||
model: container.DateTimeOffset,
|
||||
propertyName: nameof(Model.DateTimeOffset),
|
||||
expressionName: nameof(Model.DateTimeOffset));
|
||||
tagHelper.Format = "datetime: {0:o}";
|
||||
tagHelper.InputTypeName = specifiedType;
|
||||
|
||||
// Act
|
||||
tagHelper.Process(context, output);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedAttributes, output.Attributes);
|
||||
Assert.Empty(output.PreContent.GetContent());
|
||||
Assert.Empty(output.Content.GetContent());
|
||||
Assert.Empty(output.PostContent.GetContent());
|
||||
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
|
||||
Assert.Equal(expectedTagName, output.TagName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ProcessAsync_CallsGenerateCheckBox_WithExpectedParameters()
|
||||
{
|
||||
|
|
@ -283,6 +352,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
var tagHelper = GetTagHelper(htmlGenerator.Object, model: false, propertyName: nameof(Model.IsACar));
|
||||
tagHelper.Format = "somewhat-less-null"; // ignored
|
||||
|
||||
var tagBuilder = new TagBuilder("input")
|
||||
{
|
||||
Attributes =
|
||||
|
|
@ -323,18 +394,19 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, "hidden", null)]
|
||||
[InlineData(null, "Hidden", "not-null")]
|
||||
[InlineData(null, "HIDden", null)]
|
||||
[InlineData(null, "HIDDEN", "not-null")]
|
||||
[InlineData("hiddeninput", null, null)]
|
||||
[InlineData("HiddenInput", null, "not-null")]
|
||||
[InlineData("hidDENinPUT", null, null)]
|
||||
[InlineData("HIDDENINPUT", null, "not-null")]
|
||||
public async Task ProcessAsync_CallsGenerateHidden_WithExpectedParameters(
|
||||
[InlineData(null, "hidden", null, null)]
|
||||
[InlineData(null, "Hidden", "not-null", "somewhat-less-null")]
|
||||
[InlineData(null, "HIDden", null, "somewhat-less-null")]
|
||||
[InlineData(null, "HIDDEN", "not-null", null)]
|
||||
[InlineData("hiddeninput", null, null, null)]
|
||||
[InlineData("HiddenInput", null, "not-null", null)]
|
||||
[InlineData("hidDENinPUT", null, null, "somewhat-less-null")]
|
||||
[InlineData("HIDDENINPUT", null, "not-null", "somewhat-less-null")]
|
||||
public async Task ProcessAsync_CallsGenerateTextBox_WithExpectedParametersForHidden(
|
||||
string dataTypeName,
|
||||
string inputTypeName,
|
||||
string model)
|
||||
string model,
|
||||
string format)
|
||||
{
|
||||
// Arrange
|
||||
var contextAttributes = new TagHelperAttributeList
|
||||
|
|
@ -389,6 +461,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
model,
|
||||
nameof(Model.Text),
|
||||
metadataProvider: metadataProvider);
|
||||
tagHelper.Format = format;
|
||||
tagHelper.InputTypeName = inputTypeName;
|
||||
|
||||
var tagBuilder = new TagBuilder("input")
|
||||
|
|
@ -399,13 +472,13 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
},
|
||||
};
|
||||
htmlGenerator
|
||||
.Setup(mock => mock.GenerateHidden(
|
||||
.Setup(mock => mock.GenerateTextBox(
|
||||
tagHelper.ViewContext,
|
||||
tagHelper.For.ModelExplorer,
|
||||
tagHelper.For.Name,
|
||||
model, // value
|
||||
false, // useViewData
|
||||
null)) // htmlAttributes
|
||||
model, // value
|
||||
format,
|
||||
new Dictionary<string, object> { { "type", "hidden" } })) // htmlAttributes
|
||||
.Returns(tagBuilder)
|
||||
.Verifiable();
|
||||
|
||||
|
|
@ -490,6 +563,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
model,
|
||||
nameof(Model.Text),
|
||||
metadataProvider: metadataProvider);
|
||||
tagHelper.Format = "somewhat-less-null"; // ignored
|
||||
tagHelper.InputTypeName = inputTypeName;
|
||||
|
||||
var tagBuilder = new TagBuilder("input")
|
||||
|
|
@ -581,6 +655,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
|
||||
var tagHelper = GetTagHelper(htmlGenerator.Object, model, nameof(Model.Text));
|
||||
tagHelper.Format = "somewhat-less-null"; // ignored
|
||||
tagHelper.InputTypeName = inputTypeName;
|
||||
tagHelper.Value = value;
|
||||
|
||||
|
|
@ -617,32 +692,33 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, null, null)]
|
||||
[InlineData(null, null, "not-null")]
|
||||
[InlineData(null, "string", null)]
|
||||
[InlineData(null, "String", "not-null")]
|
||||
[InlineData(null, "STRing", null)]
|
||||
[InlineData(null, "STRING", "not-null")]
|
||||
[InlineData(null, "text", null)]
|
||||
[InlineData(null, "Text", "not-null")]
|
||||
[InlineData(null, "TExt", null)]
|
||||
[InlineData(null, "TEXT", "not-null")]
|
||||
[InlineData("string", null, null)]
|
||||
[InlineData("String", null, "not-null")]
|
||||
[InlineData("STRing", null, null)]
|
||||
[InlineData("STRING", null, "not-null")]
|
||||
[InlineData("text", null, null)]
|
||||
[InlineData("Text", null, "not-null")]
|
||||
[InlineData("TExt", null, null)]
|
||||
[InlineData("TEXT", null, "not-null")]
|
||||
[InlineData("custom-datatype", null, null)]
|
||||
[InlineData(null, "unknown-input-type", "not-null")]
|
||||
[InlineData("Image", null, "not-null")]
|
||||
[InlineData(null, "image", "not-null")]
|
||||
[InlineData(null, null, null, "somewhat-less-null")]
|
||||
[InlineData(null, null, "not-null", null)]
|
||||
[InlineData(null, "string", null, null)]
|
||||
[InlineData(null, "String", "not-null", null)]
|
||||
[InlineData(null, "STRing", null, "somewhat-less-null")]
|
||||
[InlineData(null, "STRING", "not-null", null)]
|
||||
[InlineData(null, "text", null, null)]
|
||||
[InlineData(null, "Text", "not-null", "somewhat-less-null")]
|
||||
[InlineData(null, "TExt", null, null)]
|
||||
[InlineData(null, "TEXT", "not-null", null)]
|
||||
[InlineData("string", null, null, null)]
|
||||
[InlineData("String", null, "not-null", null)]
|
||||
[InlineData("STRing", null, null, null)]
|
||||
[InlineData("STRING", null, "not-null", null)]
|
||||
[InlineData("text", null, null, null)]
|
||||
[InlineData("Text", null, "not-null", null)]
|
||||
[InlineData("TExt", null, null, null)]
|
||||
[InlineData("TEXT", null, "not-null", null)]
|
||||
[InlineData("custom-datatype", null, null, null)]
|
||||
[InlineData(null, "unknown-input-type", "not-null", null)]
|
||||
[InlineData("Image", null, "not-null", "somewhat-less-null")]
|
||||
[InlineData(null, "image", "not-null", null)]
|
||||
public async Task ProcessAsync_CallsGenerateTextBox_WithExpectedParameters(
|
||||
string dataTypeName,
|
||||
string inputTypeName,
|
||||
string model)
|
||||
string model,
|
||||
string format)
|
||||
{
|
||||
// Arrange
|
||||
var contextAttributes = new TagHelperAttributeList
|
||||
|
|
@ -697,6 +773,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
model,
|
||||
nameof(Model.Text),
|
||||
metadataProvider: metadataProvider);
|
||||
tagHelper.Format = format;
|
||||
tagHelper.InputTypeName = inputTypeName;
|
||||
|
||||
var tagBuilder = new TagBuilder("input")
|
||||
|
|
@ -711,9 +788,9 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
tagHelper.ViewContext,
|
||||
tagHelper.For.ModelExplorer,
|
||||
tagHelper.For.Name,
|
||||
model, // value
|
||||
null, // format
|
||||
It.Is<Dictionary<string, object>>(m => m.ContainsKey("type")))) // htmlAttributes
|
||||
model, // value
|
||||
format,
|
||||
It.Is<Dictionary<string, object>>(m => m.ContainsKey("type")))) // htmlAttributes
|
||||
.Returns(tagBuilder)
|
||||
.Verifiable();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue