React to aspnet/Razor#358.
- Removed `WriteTagHelperAsync` methods from `RazorPage`. - Moved `WriteTagHelperAsync` tests into Razor since `TagHelperOutput` is now an `IHtmlContent`. - Updated code generation test files. aspnet/Razor#358
This commit is contained in:
parent
d78abf267e
commit
2dc13b523d
|
|
@ -103,9 +103,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
StartTagHelperWritingScopeMethodName = "StartTagHelperWritingScope",
|
||||
EndTagHelperWritingScopeMethodName = "EndTagHelperWritingScope",
|
||||
|
||||
WriteTagHelperAsyncMethodName = "WriteTagHelperAsync",
|
||||
WriteTagHelperToAsyncMethodName = "WriteTagHelperToAsync",
|
||||
|
||||
// Can't use nameof because IHtmlHelper is (also) not accessible here.
|
||||
MarkAsHtmlEncodedMethodName = HtmlHelperPropertyName + ".Raw",
|
||||
BeginAddHtmlAttributeValuesMethodName = "BeginAddHtmlAttributeValues",
|
||||
|
|
@ -113,6 +110,9 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
AddHtmlAttributeValueMethodName = "AddHtmlAttributeValue",
|
||||
HtmlEncoderPropertyName = "HtmlEncoder",
|
||||
TagHelperContentGetContentMethodName = nameof(TagHelperContent.GetContent),
|
||||
TagHelperOutputIsContentModifiedPropertyName = nameof(TagHelperOutput.IsContentModified),
|
||||
TagHelperOutputContentPropertyName = nameof(TagHelperOutput.Content),
|
||||
TagHelperOutputGetChildContentAsyncMethodName = nameof(TagHelperExecutionContext.GetChildContentAsync)
|
||||
})
|
||||
{
|
||||
BeginContextMethodName = "BeginContext",
|
||||
|
|
|
|||
|
|
@ -310,106 +310,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
return tagHelperContentWrapperTextWriter.Content;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the content of a specified <paramref name="tagHelperExecutionContext"/>.
|
||||
/// </summary>
|
||||
/// <param name="tagHelperExecutionContext">The execution context containing the content.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="Task"/> that on completion writes the <paramref name="tagHelperExecutionContext"/> content.
|
||||
/// </returns>
|
||||
public Task WriteTagHelperAsync(TagHelperExecutionContext tagHelperExecutionContext)
|
||||
{
|
||||
if (tagHelperExecutionContext == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(tagHelperExecutionContext));
|
||||
}
|
||||
|
||||
return WriteTagHelperToAsync(Output, tagHelperExecutionContext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the content of a specified <paramref name="tagHelperExecutionContext"/> to the specified
|
||||
/// <paramref name="writer"/>.
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="TextWriter"/> instance to write to.</param>
|
||||
/// <param name="tagHelperExecutionContext">The execution context containing the content.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="Task"/> that on completion writes the <paramref name="tagHelperExecutionContext"/> content
|
||||
/// to the <paramref name="writer"/>.
|
||||
/// </returns>
|
||||
public async Task WriteTagHelperToAsync(
|
||||
TextWriter writer,
|
||||
TagHelperExecutionContext tagHelperExecutionContext)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(writer));
|
||||
}
|
||||
|
||||
if (tagHelperExecutionContext == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(tagHelperExecutionContext));
|
||||
}
|
||||
|
||||
var tagHelperOutput = tagHelperExecutionContext.Output;
|
||||
var isTagNameNullOrWhitespace = string.IsNullOrWhiteSpace(tagHelperOutput.TagName);
|
||||
|
||||
WriteTo(writer, tagHelperOutput.PreElement);
|
||||
|
||||
if (!isTagNameNullOrWhitespace)
|
||||
{
|
||||
writer.Write('<');
|
||||
writer.Write(tagHelperOutput.TagName);
|
||||
|
||||
foreach (var attribute in tagHelperOutput.Attributes)
|
||||
{
|
||||
writer.Write(' ');
|
||||
writer.Write(attribute.Name);
|
||||
|
||||
if (!attribute.Minimized)
|
||||
{
|
||||
writer.Write("=\"");
|
||||
WriteTo(writer, HtmlEncoder, attribute.Value, escapeQuotes: true);
|
||||
writer.Write('"');
|
||||
}
|
||||
}
|
||||
|
||||
if (tagHelperOutput.TagMode == TagMode.SelfClosing)
|
||||
{
|
||||
writer.Write(" /");
|
||||
}
|
||||
|
||||
writer.Write('>');
|
||||
}
|
||||
|
||||
if (isTagNameNullOrWhitespace || tagHelperOutput.TagMode == TagMode.StartTagAndEndTag)
|
||||
{
|
||||
WriteTo(writer, tagHelperOutput.PreContent);
|
||||
if (tagHelperOutput.IsContentModified)
|
||||
{
|
||||
WriteTo(writer, tagHelperOutput.Content);
|
||||
}
|
||||
else if (tagHelperExecutionContext.ChildContentRetrieved)
|
||||
{
|
||||
var childContent = await tagHelperExecutionContext.GetChildContentAsync(useCachedResult: true);
|
||||
WriteTo(writer, childContent);
|
||||
}
|
||||
else
|
||||
{
|
||||
await tagHelperExecutionContext.ExecuteChildContentAsync();
|
||||
}
|
||||
|
||||
WriteTo(writer, tagHelperOutput.PostContent);
|
||||
}
|
||||
|
||||
if (!isTagNameNullOrWhitespace && tagHelperOutput.TagMode == TagMode.StartTagAndEndTag)
|
||||
{
|
||||
writer.Write(string.Format(CultureInfo.InvariantCulture, "</{0}>", tagHelperOutput.TagName));
|
||||
}
|
||||
|
||||
WriteTo(writer, tagHelperOutput.PostElement);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the specified <paramref name="value"/> with HTML encoding to <see cref="Output"/>.
|
||||
/// </summary>
|
||||
|
|
@ -437,7 +337,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
throw new ArgumentNullException(nameof(writer));
|
||||
}
|
||||
|
||||
WriteTo(writer, HtmlEncoder, value, escapeQuotes: false);
|
||||
WriteTo(writer, HtmlEncoder, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -446,21 +346,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// <param name="writer">The <see cref="TextWriter"/> instance to write to.</param>
|
||||
/// <param name="encoder">The <see cref="HtmlEncoder"/> to use when encoding <paramref name="value"/>.</param>
|
||||
/// <param name="value">The <see cref="object"/> to write.</param>
|
||||
/// <param name="escapeQuotes">
|
||||
/// If <c>true</c> escapes double quotes in a <paramref name="value"/> of type <see cref="HtmlString"/>.
|
||||
/// Otherwise writes <see cref="HtmlString"/> values as-is.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// <paramref name="value"/>s of type <see cref="IHtmlContent"/> are written using
|
||||
/// <see cref="IHtmlContent.WriteTo(TextWriter, HtmlEncoder)"/>.
|
||||
/// For all other types, the encoded result of <see cref="object.ToString"/> is written to the
|
||||
/// <paramref name="writer"/>.
|
||||
/// </remarks>
|
||||
public static void WriteTo(
|
||||
TextWriter writer,
|
||||
HtmlEncoder encoder,
|
||||
object value,
|
||||
bool escapeQuotes)
|
||||
public static void WriteTo(TextWriter writer, HtmlEncoder encoder, object value)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
|
|
@ -480,28 +372,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
var htmlContent = value as IHtmlContent;
|
||||
if (htmlContent != null)
|
||||
{
|
||||
if (escapeQuotes)
|
||||
{
|
||||
// In this case the text likely came directly from the Razor source. Since the original string is
|
||||
// an attribute value that may have been quoted with single quotes, must handle any double quotes
|
||||
// in the value. Writing the value out surrounded by double quotes.
|
||||
//
|
||||
// This is really not optimal from a perf point of view, but it's the best we can do for right now.
|
||||
using (var stringWriter = new StringWriter())
|
||||
{
|
||||
htmlContent.WriteTo(stringWriter, encoder);
|
||||
|
||||
var stringValue = stringWriter.ToString();
|
||||
if (stringValue.Contains("\""))
|
||||
{
|
||||
stringValue = stringValue.Replace("\"", """);
|
||||
}
|
||||
|
||||
writer.Write(stringValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var htmlTextWriter = writer as HtmlTextWriter;
|
||||
if (htmlTextWriter == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNet.Mvc.Razor;
|
||||
|
|
@ -23,7 +24,7 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
/// <param name="value">The <see cref="object"/> to write.</param>
|
||||
/// <returns><paramref name="content"/> after the write operation has completed.</returns>
|
||||
/// <remarks>
|
||||
/// <paramref name="value"/>s of type <see cref="Html.Abstractions.IHtmlContent"/> are written using
|
||||
/// <paramref name="value"/>s of type <see cref="Html.Abstractions.IHtmlContent"/> are written using
|
||||
/// <see cref="Html.Abstractions.IHtmlContent.WriteTo(System.IO.TextWriter, HtmlEncoder)"/>.
|
||||
/// For all other types, the encoded result of <see cref="object.ToString"/>
|
||||
/// is written to the <paramref name="content"/>.
|
||||
|
|
@ -51,7 +52,16 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
|
|||
|
||||
using (var writer = new TagHelperContentWrapperTextWriter(encoding, content))
|
||||
{
|
||||
RazorPage.WriteTo(writer, encoder, value, escapeQuotes: true);
|
||||
using (var stringWriter = new StringWriter())
|
||||
{
|
||||
RazorPage.WriteTo(stringWriter, encoder, value);
|
||||
|
||||
// In this case the text likely came directly from the Razor source. Since the original string is
|
||||
// an attribute value that may have been quoted with single quotes, must handle any double quotes
|
||||
// in the value. Writing the value out surrounded by double quotes.
|
||||
var stringValue = stringWriter.ToString().Replace("\"", """);
|
||||
writer.Write(stringValue);
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ __Microsoft_AspNet_Mvc_Razor_InputTestTagHelper.For = CreateModelExpression(__mo
|
|||
__tagHelperExecutionContext.AddTagHelperAttribute("for", __Microsoft_AspNet_Mvc_Razor_InputTestTagHelper.For);
|
||||
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
|
||||
BeginContext(120, 24, false);
|
||||
await WriteTagHelperAsync(__tagHelperExecutionContext);
|
||||
Write(__tagHelperExecutionContext.Output);
|
||||
EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
BeginContext(144, 2, true);
|
||||
|
|
@ -73,7 +73,7 @@ __Microsoft_AspNet_Mvc_Razor_InputTestTagHelper.For = CreateModelExpression(__mo
|
|||
__tagHelperExecutionContext.AddTagHelperAttribute("for", __Microsoft_AspNet_Mvc_Razor_InputTestTagHelper.For);
|
||||
__tagHelperExecutionContext.Output = await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
|
||||
BeginContext(146, 27, false);
|
||||
await WriteTagHelperAsync(__tagHelperExecutionContext);
|
||||
Write(__tagHelperExecutionContext.Output);
|
||||
EndContext();
|
||||
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1222,767 +1222,6 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
Assert.Equal("Hello world", HtmlContentUtilities.HtmlContentToString(((IHtmlContent)buffer[0])));
|
||||
}
|
||||
|
||||
public static TheoryData<TagHelperOutput, string> WriteTagHelper_InputData
|
||||
{
|
||||
get
|
||||
{
|
||||
// parameters: TagHelperOutput, expectedOutput
|
||||
return new TheoryData<TagHelperOutput, string>
|
||||
{
|
||||
{
|
||||
// parameters: TagName, Attributes, SelfClosing, PreContent, Content, PostContent
|
||||
GetTagHelperOutput(
|
||||
tagName: "div",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<div>Hello World!</div>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Hello World!"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: " ",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Hello World!"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList() { { "test", "testVal" } },
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p test=\"HtmlEncode[[testVal]]\">Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList() { { "test", "testVal" }, { "something", " spaced " } },
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p test=\"HtmlEncode[[testVal]]\" something=\"HtmlEncode[[ spaced ]]\">Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList()
|
||||
{
|
||||
["test"] = new TagHelperAttribute
|
||||
{
|
||||
Name = "test",
|
||||
Minimized = true
|
||||
},
|
||||
},
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p test>Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList()
|
||||
{
|
||||
["test"] = new TagHelperAttribute
|
||||
{
|
||||
Name = "test",
|
||||
Minimized = true
|
||||
},
|
||||
["test2"] = new TagHelperAttribute
|
||||
{
|
||||
Name = "test2",
|
||||
Minimized = true
|
||||
},
|
||||
},
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p test test2>Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList()
|
||||
{
|
||||
["first"] = "unminimized",
|
||||
["test"] = new TagHelperAttribute
|
||||
{
|
||||
Name = "test",
|
||||
Minimized = true
|
||||
},
|
||||
},
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p first=\"HtmlEncode[[unminimized]]\" test>Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList()
|
||||
{
|
||||
["test"] = new TagHelperAttribute
|
||||
{
|
||||
Name = "test",
|
||||
Minimized = true
|
||||
},
|
||||
["last"] = "unminimized",
|
||||
},
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p test last=\"HtmlEncode[[unminimized]]\">Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList() { { "test", "testVal" } },
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p test=\"HtmlEncode[[testVal]]\" />"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList() { { "test", "testVal" }, { "something", " spaced " } },
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p test=\"HtmlEncode[[testVal]]\" something=\"HtmlEncode[[ spaced ]]\" />"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList() { { "test", "testVal" } },
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p test=\"HtmlEncode[[testVal]]\">"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList() { { "test", "testVal" }, { "something", " spaced " } },
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p test=\"HtmlEncode[[testVal]]\" something=\"HtmlEncode[[ spaced ]]\">"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: "Hello World!",
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p>Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: "Hello World!",
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"<p>Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: "Hello World!",
|
||||
postElement: null),
|
||||
"<p>Hello World!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: null),
|
||||
"<p>HelloTestWorld!</p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: null,
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: null),
|
||||
"<p />"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: null,
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: null),
|
||||
"<p>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: null),
|
||||
"<custom>HelloTestWorld!</custom>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "random",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: null,
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: null),
|
||||
"<random />"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "random",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: null,
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: null),
|
||||
"<random>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: "Before",
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Before<custom></custom>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: "Before",
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Before"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: "Before",
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Before"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: "Before",
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Before<custom test=\"HtmlEncode[[testVal]]\" />"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: "Before",
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Before<custom />"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: "Before",
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Before"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: "Before",
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Before<custom test=\"HtmlEncode[[testVal]]\">"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: "Before",
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: null),
|
||||
"Before<custom>"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: "After"),
|
||||
"<custom></custom>After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: "After"),
|
||||
"After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: "After"),
|
||||
"After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: "After"),
|
||||
"<custom test=\"HtmlEncode[[testVal]]\" />After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: "After"),
|
||||
"<custom />After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: "After"),
|
||||
"After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: "After"),
|
||||
"<custom test=\"HtmlEncode[[testVal]]\">After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: null,
|
||||
preContent: null,
|
||||
content: null,
|
||||
postContent: null,
|
||||
postElement: "After"),
|
||||
"<custom>After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: "Before",
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: "After"),
|
||||
"Before<custom>HelloTestWorld!</custom>After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: "Before",
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: "After"),
|
||||
"Before<custom test=\"HtmlEncode[[testVal]]\">HelloTestWorld!</custom>After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: "Before",
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: "After"),
|
||||
"Before<custom />After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.SelfClosing,
|
||||
preElement: "Before",
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: "After"),
|
||||
"BeforeHelloTestWorld!After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: "custom",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: "Before",
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: "After"),
|
||||
"Before<custom>After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagOnly,
|
||||
preElement: "Before",
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: "After"),
|
||||
"BeforeHelloTestWorld!After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList(),
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: "Before",
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: "After"),
|
||||
"BeforeHelloTestWorld!After"
|
||||
},
|
||||
{
|
||||
GetTagHelperOutput(
|
||||
tagName: string.Empty,
|
||||
attributes: new TagHelperAttributeList { { "test", "testVal" } },
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
preElement: "Before",
|
||||
preContent: "Hello",
|
||||
content: "Test",
|
||||
postContent: "World!",
|
||||
postElement: "After"),
|
||||
"BeforeHelloTestWorld!After"
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(WriteTagHelper_InputData))]
|
||||
public async Task WriteTagHelperAsync_WritesFormattedTagHelper(TagHelperOutput output, string expected)
|
||||
{
|
||||
// Arrange
|
||||
var writer = new StringCollectionTextWriter(Encoding.UTF8);
|
||||
var context = CreateViewContext(writer);
|
||||
var tagHelperExecutionContext = new TagHelperExecutionContext(
|
||||
tagName: output.TagName,
|
||||
tagMode: output.TagMode,
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: string.Empty,
|
||||
executeChildContentAsync: () => Task.FromResult(result: true),
|
||||
startTagHelperWritingScope: () => { },
|
||||
endTagHelperWritingScope: () => new DefaultTagHelperContent());
|
||||
tagHelperExecutionContext.Output = output;
|
||||
|
||||
// Act
|
||||
var page = CreatePage(p =>
|
||||
{
|
||||
p.HtmlEncoder = new HtmlTestEncoder();
|
||||
p.WriteTagHelperAsync(tagHelperExecutionContext).Wait();
|
||||
}, context);
|
||||
await page.ExecuteAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(writer.Content));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
// This is a scenario where GetChildContentAsync is called.
|
||||
[InlineData(true, "HelloWorld!", "<p>HelloWorld!</p>")]
|
||||
// This is a scenario where ExecuteChildContentAsync is called.
|
||||
[InlineData(false, "HelloWorld!", "<p></p>")]
|
||||
public async Task WriteTagHelperAsync_WritesContentAppropriately(
|
||||
bool childContentRetrieved, string input, string expected)
|
||||
{
|
||||
// Arrange
|
||||
var defaultTagHelperContent = new DefaultTagHelperContent();
|
||||
var writer = new StringCollectionTextWriter(Encoding.UTF8);
|
||||
var context = CreateViewContext(writer);
|
||||
var tagHelperExecutionContext = new TagHelperExecutionContext(
|
||||
tagName: "p",
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: string.Empty,
|
||||
executeChildContentAsync: () =>
|
||||
{
|
||||
defaultTagHelperContent.AppendHtml(input);
|
||||
return Task.FromResult(result: true);
|
||||
},
|
||||
startTagHelperWritingScope: () => { },
|
||||
endTagHelperWritingScope: () => defaultTagHelperContent);
|
||||
tagHelperExecutionContext.Output = new TagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (_) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent()));
|
||||
if (childContentRetrieved)
|
||||
{
|
||||
await tagHelperExecutionContext.GetChildContentAsync(useCachedResult: true);
|
||||
}
|
||||
|
||||
// Act
|
||||
var page = CreatePage(p =>
|
||||
{
|
||||
p.HtmlEncoder = new HtmlTestEncoder();
|
||||
p.WriteTagHelperAsync(tagHelperExecutionContext).Wait();
|
||||
}, context);
|
||||
await page.ExecuteAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(writer.Content));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteTagHelperToAsync_WritesToSpecifiedWriter()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new StringCollectionTextWriter(Encoding.UTF8);
|
||||
var context = CreateViewContext(new StringWriter());
|
||||
var tagHelperExecutionContext = new TagHelperExecutionContext(
|
||||
tagName: "p",
|
||||
tagMode: TagMode.StartTagAndEndTag,
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: string.Empty,
|
||||
executeChildContentAsync: () => { return Task.FromResult(result: true); },
|
||||
startTagHelperWritingScope: () => { },
|
||||
endTagHelperWritingScope: () => new DefaultTagHelperContent());
|
||||
tagHelperExecutionContext.Output = new TagHelperOutput(
|
||||
tagName: "p",
|
||||
attributes: new TagHelperAttributeList(),
|
||||
getChildContentAsync: (_) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent()));
|
||||
tagHelperExecutionContext.Output.Content.AppendHtml("Hello World!");
|
||||
|
||||
// Act
|
||||
var page = CreatePage(p =>
|
||||
{
|
||||
p.HtmlEncoder = new HtmlTestEncoder();
|
||||
p.WriteTagHelperToAsync(writer, tagHelperExecutionContext).Wait();
|
||||
}, context);
|
||||
await page.ExecuteAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal("<p>Hello World!</p>", HtmlContentUtilities.HtmlContentToString(writer.Content));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(WriteTagHelper_InputData))]
|
||||
public async Task WriteTagHelperToAsync_WritesFormattedTagHelper(TagHelperOutput output, string expected)
|
||||
{
|
||||
// Arrange
|
||||
var writer = new StringCollectionTextWriter(Encoding.UTF8);
|
||||
var context = CreateViewContext(new StringWriter());
|
||||
var tagHelperExecutionContext = new TagHelperExecutionContext(
|
||||
tagName: output.TagName,
|
||||
tagMode: output.TagMode,
|
||||
items: new Dictionary<object, object>(),
|
||||
uniqueId: string.Empty,
|
||||
executeChildContentAsync: () => Task.FromResult(result: true),
|
||||
startTagHelperWritingScope: () => { },
|
||||
endTagHelperWritingScope: () => new DefaultTagHelperContent());
|
||||
tagHelperExecutionContext.Output = output;
|
||||
|
||||
// Act
|
||||
var page = CreatePage(p =>
|
||||
{
|
||||
p.HtmlEncoder = new HtmlTestEncoder();
|
||||
p.WriteTagHelperToAsync(writer, tagHelperExecutionContext).Wait();
|
||||
}, context);
|
||||
await page.ExecuteAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(writer.Content));
|
||||
}
|
||||
|
||||
private static TagHelperOutput GetTagHelperOutput(
|
||||
string tagName,
|
||||
TagHelperAttributeList attributes,
|
||||
TagMode tagMode,
|
||||
string preElement,
|
||||
string preContent,
|
||||
string content,
|
||||
string postContent,
|
||||
string postElement)
|
||||
{
|
||||
var output = new TagHelperOutput(
|
||||
tagName,
|
||||
attributes,
|
||||
getChildContentAsync: (_) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent()))
|
||||
{
|
||||
TagMode = tagMode
|
||||
};
|
||||
|
||||
output.PreElement.AppendHtml(preElement);
|
||||
output.PreContent.AppendHtml(preContent);
|
||||
output.Content.AppendHtml(content);
|
||||
output.PostContent.AppendHtml(postContent);
|
||||
output.PostElement.AppendHtml(postElement);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private static TestableRazorPage CreatePage(
|
||||
Action<TestableRazorPage> executeAction,
|
||||
ViewContext context = null)
|
||||
|
|
|
|||
Loading…
Reference in New Issue