Add tests to validate TagHelper escape functionality.
- Added extensive unit tests. - Added functional test to validate output for runtime and design time. #187
This commit is contained in:
parent
94230a5a14
commit
cf3d049272
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||||
|
{
|
||||||
|
public class HtmlElementNameAttributeTest
|
||||||
|
{
|
||||||
|
public static TheoryData InvalidTagNameData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var invalidTagNameError =
|
||||||
|
"Tag helpers cannot target element name '{0}' because it contains a '{1}' character.";
|
||||||
|
var nullOrWhitespaceTagNameError =
|
||||||
|
"Tag name cannot be null or whitespace.";
|
||||||
|
|
||||||
|
// tagName, expectedExceptionMessage
|
||||||
|
return new TheoryData<string, string>
|
||||||
|
{
|
||||||
|
{ "!", string.Format(invalidTagNameError, "!", "!") },
|
||||||
|
{ "hello!", string.Format(invalidTagNameError, "hello!", "!") },
|
||||||
|
{ "!hello", string.Format(invalidTagNameError, "!hello", "!") },
|
||||||
|
{ "he!lo", string.Format(invalidTagNameError, "he!lo", "!") },
|
||||||
|
{ "!he!lo!", string.Format(invalidTagNameError, "!he!lo!", "!") },
|
||||||
|
{ string.Empty, nullOrWhitespaceTagNameError },
|
||||||
|
{ Environment.NewLine, nullOrWhitespaceTagNameError },
|
||||||
|
{ "\t", nullOrWhitespaceTagNameError },
|
||||||
|
{ " \t ", nullOrWhitespaceTagNameError },
|
||||||
|
{ " ", nullOrWhitespaceTagNameError },
|
||||||
|
{ Environment.NewLine + " ", nullOrWhitespaceTagNameError },
|
||||||
|
{ null, nullOrWhitespaceTagNameError },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(InvalidTagNameData))]
|
||||||
|
public void SingleArgumentConstructor_ThrowsOnInvalidTagNames(
|
||||||
|
string tagName,
|
||||||
|
string expectedExceptionMessage)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
expectedExceptionMessage += Environment.NewLine + "Parameter name: tag";
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var exception = Assert.Throws<ArgumentException>(
|
||||||
|
"tag",
|
||||||
|
() => new HtmlElementNameAttribute(tagName));
|
||||||
|
Assert.Equal(exception.Message, expectedExceptionMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(InvalidTagNameData))]
|
||||||
|
public void MultipleArgumentConstructor_ThrowsOnInvalidTagNames(
|
||||||
|
string tagName,
|
||||||
|
string expectedExceptionMessage)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
expectedExceptionMessage += Environment.NewLine + "Parameter name: additionalTags";
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
var exception = Assert.Throws<ArgumentException>(
|
||||||
|
"additionalTags",
|
||||||
|
() => new HtmlElementNameAttribute("p", "div", "span", tagName));
|
||||||
|
Assert.Equal(exception.Message, expectedExceptionMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,19 @@ namespace Microsoft.AspNet.Razor.Test.Framework
|
||||||
_factory = factory;
|
_factory = factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Block EscapedMarkupTagBlock(string prefix, string suffix)
|
||||||
|
{
|
||||||
|
return EscapedMarkupTagBlock(prefix, suffix, AcceptedCharacters.Any);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block EscapedMarkupTagBlock(string prefix, string suffix, AcceptedCharacters acceptedCharacters)
|
||||||
|
{
|
||||||
|
return new MarkupTagBlock(
|
||||||
|
_factory.Markup(prefix),
|
||||||
|
_factory.BangEscape(),
|
||||||
|
_factory.Markup(suffix).Accepts(acceptedCharacters));
|
||||||
|
}
|
||||||
|
|
||||||
public Block MarkupTagBlock(string content)
|
public Block MarkupTagBlock(string content)
|
||||||
{
|
{
|
||||||
return MarkupTagBlock(content, AcceptedCharacters.Any);
|
return MarkupTagBlock(content, AcceptedCharacters.Any);
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,14 @@ namespace Microsoft.AspNet.Razor.Test.Framework
|
||||||
return self.Span(SpanKind.Comment, content, type);
|
return self.Span(SpanKind.Comment, content, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SpanConstructor BangEscape(this SpanFactory self)
|
||||||
|
{
|
||||||
|
return self
|
||||||
|
.Span(SpanKind.MetaCode, "!", markup: true)
|
||||||
|
.With(SpanCodeGenerator.Null)
|
||||||
|
.Accepts(AcceptedCharacters.None);
|
||||||
|
}
|
||||||
|
|
||||||
public static SpanConstructor Markup(this SpanFactory self, string content)
|
public static SpanConstructor Markup(this SpanFactory self, string content)
|
||||||
{
|
{
|
||||||
return self.Span(SpanKind.Markup, content, markup: true).With(new MarkupCodeGenerator());
|
return self.Span(SpanKind.Markup, content, markup: true).With(new MarkupCodeGenerator());
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,39 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
||||||
contentLength: 0)
|
contentLength: 0)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"EscapedTagHelpers",
|
||||||
|
"EscapedTagHelpers.DesignTime",
|
||||||
|
PAndInputTagHelperDescriptors,
|
||||||
|
new List<LineMapping>
|
||||||
|
{
|
||||||
|
BuildLineMapping(documentAbsoluteIndex: 14,
|
||||||
|
documentLineIndex: 0,
|
||||||
|
generatedAbsoluteIndex: 479,
|
||||||
|
generatedLineIndex: 15,
|
||||||
|
characterOffsetIndex: 14,
|
||||||
|
contentLength: 11),
|
||||||
|
BuildLineMapping(documentAbsoluteIndex: 102,
|
||||||
|
documentLineIndex: 3,
|
||||||
|
generatedAbsoluteIndex: 975,
|
||||||
|
generatedLineIndex: 34,
|
||||||
|
characterOffsetIndex: 29,
|
||||||
|
contentLength: 12),
|
||||||
|
BuildLineMapping(documentAbsoluteIndex: 200,
|
||||||
|
documentLineIndex: 5,
|
||||||
|
documentCharacterOffsetIndex: 51,
|
||||||
|
generatedAbsoluteIndex: 1130,
|
||||||
|
generatedLineIndex: 40,
|
||||||
|
generatedCharacterOffsetIndex: 6,
|
||||||
|
contentLength: 12),
|
||||||
|
BuildLineMapping(documentAbsoluteIndex: 223,
|
||||||
|
documentLineIndex: 5,
|
||||||
|
generatedAbsoluteIndex: 1467,
|
||||||
|
generatedLineIndex: 48,
|
||||||
|
characterOffsetIndex: 74,
|
||||||
|
contentLength: 4)
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -280,6 +313,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
||||||
{ "BasicTagHelpers.RemoveTagHelper", PAndInputTagHelperDescriptors },
|
{ "BasicTagHelpers.RemoveTagHelper", PAndInputTagHelperDescriptors },
|
||||||
{ "ComplexTagHelpers", PAndInputTagHelperDescriptors },
|
{ "ComplexTagHelpers", PAndInputTagHelperDescriptors },
|
||||||
{ "EmptyAttributeTagHelpers", PAndInputTagHelperDescriptors },
|
{ "EmptyAttributeTagHelpers", PAndInputTagHelperDescriptors },
|
||||||
|
{ "EscapedTagHelpers", PAndInputTagHelperDescriptors },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ParseDocumentReturnsOneMarkupSegmentIfNoCodeBlocksEncountered()
|
public void ParseDocumentReturnsOneMarkupSegmentIfNoCodeBlocksEncountered()
|
||||||
{
|
{
|
||||||
SingleSpanDocumentTest("Foo Baz<!--Foo-->Bar<!-F> Qux", BlockType.Markup, SpanKind.Markup);
|
SingleSpanDocumentTest("Foo Baz<!--Foo-->Bar<!--F> Qux", BlockType.Markup, SpanKind.Markup);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,56 @@
|
||||||
|
namespace TestOutput
|
||||||
|
{
|
||||||
|
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class EscapedTagHelpers
|
||||||
|
{
|
||||||
|
private static object @__o;
|
||||||
|
private void @__RazorDesignTimeHelpers__()
|
||||||
|
{
|
||||||
|
#pragma warning disable 219
|
||||||
|
string __tagHelperDirectiveSyntaxHelper = null;
|
||||||
|
__tagHelperDirectiveSyntaxHelper =
|
||||||
|
#line 1 "EscapedTagHelpers.cshtml"
|
||||||
|
"something"
|
||||||
|
|
||||||
|
#line default
|
||||||
|
#line hidden
|
||||||
|
;
|
||||||
|
#pragma warning restore 219
|
||||||
|
}
|
||||||
|
#line hidden
|
||||||
|
private InputTagHelper __InputTagHelper = null;
|
||||||
|
private InputTagHelper2 __InputTagHelper2 = null;
|
||||||
|
#line hidden
|
||||||
|
public EscapedTagHelpers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable 1998
|
||||||
|
public override async Task ExecuteAsync()
|
||||||
|
{
|
||||||
|
#line 4 "EscapedTagHelpers.cshtml"
|
||||||
|
__o = DateTime.Now;
|
||||||
|
|
||||||
|
#line default
|
||||||
|
#line hidden
|
||||||
|
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||||
|
#line 6 "EscapedTagHelpers.cshtml"
|
||||||
|
__o = DateTime.Now;
|
||||||
|
|
||||||
|
#line default
|
||||||
|
#line hidden
|
||||||
|
__InputTagHelper.Type = string.Empty;
|
||||||
|
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||||
|
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||||
|
#line 6 "EscapedTagHelpers.cshtml"
|
||||||
|
__InputTagHelper2.Checked = true;
|
||||||
|
|
||||||
|
#line default
|
||||||
|
#line hidden
|
||||||
|
}
|
||||||
|
#pragma warning restore 1998
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
#pragma checksum "EscapedTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "f1f93dcc77691cc626112fe0475f5c350e5fa802"
|
||||||
|
namespace TestOutput
|
||||||
|
{
|
||||||
|
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
public class EscapedTagHelpers
|
||||||
|
{
|
||||||
|
#line hidden
|
||||||
|
#pragma warning disable 0414
|
||||||
|
private System.IO.TextWriter __tagHelperStringValueBuffer = null;
|
||||||
|
#pragma warning restore 0414
|
||||||
|
private TagHelperExecutionContext __tagHelperExecutionContext = null;
|
||||||
|
private TagHelperRunner __tagHelperRunner = new TagHelperRunner();
|
||||||
|
private TagHelperScopeManager __tagHelperScopeManager = new TagHelperScopeManager();
|
||||||
|
private InputTagHelper __InputTagHelper = null;
|
||||||
|
private InputTagHelper2 __InputTagHelper2 = null;
|
||||||
|
#line hidden
|
||||||
|
public EscapedTagHelpers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable 1998
|
||||||
|
public override async Task ExecuteAsync()
|
||||||
|
{
|
||||||
|
Instrumentation.BeginContext(27, 72, true);
|
||||||
|
WriteLiteral("\r\n<div class=\"randomNonTagHelperAttribute\">\r\n <p class=\"Hello World\" ");
|
||||||
|
Instrumentation.EndContext();
|
||||||
|
Instrumentation.BeginContext(102, 12, false);
|
||||||
|
#line 4 "EscapedTagHelpers.cshtml"
|
||||||
|
Write(DateTime.Now);
|
||||||
|
|
||||||
|
#line default
|
||||||
|
#line hidden
|
||||||
|
Instrumentation.EndContext();
|
||||||
|
Instrumentation.BeginContext(114, 69, true);
|
||||||
|
WriteLiteral(">\r\n <input type=\"text\" />\r\n <em>Not a TagHelper: </em> ");
|
||||||
|
Instrumentation.EndContext();
|
||||||
|
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input", "test", async() => {
|
||||||
|
}
|
||||||
|
, StartWritingScope, EndWritingScope);
|
||||||
|
__InputTagHelper = CreateTagHelper<InputTagHelper>();
|
||||||
|
__tagHelperExecutionContext.Add(__InputTagHelper);
|
||||||
|
StartWritingScope();
|
||||||
|
#line 6 "EscapedTagHelpers.cshtml"
|
||||||
|
Write(DateTime.Now);
|
||||||
|
|
||||||
|
#line default
|
||||||
|
#line hidden
|
||||||
|
__tagHelperStringValueBuffer = EndWritingScope();
|
||||||
|
__InputTagHelper.Type = __tagHelperStringValueBuffer.ToString();
|
||||||
|
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
|
||||||
|
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
|
||||||
|
__tagHelperExecutionContext.Add(__InputTagHelper2);
|
||||||
|
__InputTagHelper2.Type = __InputTagHelper.Type;
|
||||||
|
#line 6 "EscapedTagHelpers.cshtml"
|
||||||
|
__InputTagHelper2.Checked = true;
|
||||||
|
|
||||||
|
#line default
|
||||||
|
#line hidden
|
||||||
|
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
|
||||||
|
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
|
||||||
|
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
|
||||||
|
WriteLiteral(__tagHelperExecutionContext.Output.GeneratePreContent());
|
||||||
|
if (__tagHelperExecutionContext.Output.ContentSet)
|
||||||
|
{
|
||||||
|
WriteLiteral(__tagHelperExecutionContext.Output.GenerateContent());
|
||||||
|
}
|
||||||
|
else if (__tagHelperExecutionContext.ChildContentRetrieved)
|
||||||
|
{
|
||||||
|
WriteLiteral(__tagHelperExecutionContext.GetChildContentAsync().Result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__tagHelperExecutionContext.ExecuteChildContentAsync().Wait();
|
||||||
|
}
|
||||||
|
WriteLiteral(__tagHelperExecutionContext.Output.GeneratePostContent());
|
||||||
|
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
|
||||||
|
__tagHelperExecutionContext = __tagHelperScopeManager.End();
|
||||||
|
Instrumentation.BeginContext(231, 18, true);
|
||||||
|
WriteLiteral("\r\n </p>\r\n</div>");
|
||||||
|
Instrumentation.EndContext();
|
||||||
|
}
|
||||||
|
#pragma warning restore 1998
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
@addtaghelper "something"
|
||||||
|
|
||||||
|
<!div class="randomNonTagHelperAttribute">
|
||||||
|
<!p class="Hello World" @DateTime.Now>
|
||||||
|
<!input type="text" />
|
||||||
|
<!em>Not a TagHelper: </!em> <input type="@DateTime.Now" checked="true" />
|
||||||
|
</!p>
|
||||||
|
</!div>
|
||||||
Loading…
Reference in New Issue