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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return MarkupTagBlock(content, AcceptedCharacters.Any);
|
||||
|
|
|
|||
|
|
@ -104,6 +104,14 @@ namespace Microsoft.AspNet.Razor.Test.Framework
|
|||
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)
|
||||
{
|
||||
return self.Span(SpanKind.Markup, content, markup: true).With(new MarkupCodeGenerator());
|
||||
|
|
|
|||
|
|
@ -248,6 +248,39 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
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 },
|
||||
{ "ComplexTagHelpers", PAndInputTagHelperDescriptors },
|
||||
{ "EmptyAttributeTagHelpers", PAndInputTagHelperDescriptors },
|
||||
{ "EscapedTagHelpers", PAndInputTagHelperDescriptors },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html
|
|||
[Fact]
|
||||
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]
|
||||
|
|
|
|||
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