- 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:
N. Taylor Mullen 2015-11-19 16:46:48 -08:00
parent d78abf267e
commit 2dc13b523d
5 changed files with 19 additions and 900 deletions

View File

@ -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",

View File

@ -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("\"", "&quot;");
}
writer.Write(stringValue);
return;
}
}
var htmlTextWriter = writer as HtmlTextWriter;
if (htmlTextWriter == null)
{

View File

@ -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("\"", "&quot;");
writer.Write(stringValue);
}
}
return content;

View File

@ -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();
}

View File

@ -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)