diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/HtmlElementNameAttributeTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/HtmlElementNameAttributeTest.cs new file mode 100644 index 0000000000..43839a6cae --- /dev/null +++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/HtmlElementNameAttributeTest.cs @@ -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.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( + "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( + "additionalTags", + () => new HtmlElementNameAttribute("p", "div", "span", tagName)); + Assert.Equal(exception.Message, expectedExceptionMessage); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Razor.Test/Framework/BlockFactory.cs b/test/Microsoft.AspNet.Razor.Test/Framework/BlockFactory.cs index ede522a6e7..2af0a8916f 100644 --- a/test/Microsoft.AspNet.Razor.Test/Framework/BlockFactory.cs +++ b/test/Microsoft.AspNet.Razor.Test/Framework/BlockFactory.cs @@ -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); diff --git a/test/Microsoft.AspNet.Razor.Test/Framework/TestSpanBuilder.cs b/test/Microsoft.AspNet.Razor.Test/Framework/TestSpanBuilder.cs index 6cb98fc075..033b9f6e2b 100644 --- a/test/Microsoft.AspNet.Razor.Test/Framework/TestSpanBuilder.cs +++ b/test/Microsoft.AspNet.Razor.Test/Framework/TestSpanBuilder.cs @@ -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()); diff --git a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs index 1a64f286f5..33d241a318 100644 --- a/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs @@ -248,6 +248,39 @@ namespace Microsoft.AspNet.Razor.Test.Generator contentLength: 0) } }, + { + "EscapedTagHelpers", + "EscapedTagHelpers.DesignTime", + PAndInputTagHelperDescriptors, + new List + { + 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 }, }; } } diff --git a/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlDocumentTest.cs b/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlDocumentTest.cs index 463bb5a42b..41a2454bd6 100644 --- a/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlDocumentTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/Parser/Html/HtmlDocumentTest.cs @@ -199,7 +199,7 @@ namespace Microsoft.AspNet.Razor.Test.Parser.Html [Fact] public void ParseDocumentReturnsOneMarkupSegmentIfNoCodeBlocksEncountered() { - SingleSpanDocumentTest("Foo BazBar Qux", BlockType.Markup, SpanKind.Markup); + SingleSpanDocumentTest("Foo BazBar