aspnetcore/test/Microsoft.AspNetCore.Razor..../Legacy/HtmlBlockTest.cs

658 lines
31 KiB
C#

// Copyright (c) .NET Foundation. 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.AspNetCore.Razor.Language.Legacy
{
public class HtmlBlockTest : CsHtmlMarkupParserTestBase
{
[Fact]
public void ParseBlockHandlesUnbalancedTripleDashHTMLComments()
{
ParseDocumentTest(
@"@{
<!-- Hello, I'm a comment that shouldn't break razor --->
}",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
Factory.Code(Environment.NewLine).AsStatement().AutoCompleteWith(null),
new MarkupBlock(
Factory.Markup(" "),
BlockFactory.HtmlCommentBlock(" Hello, I'm a comment that shouldn't break razor -"),
Factory.Markup(Environment.NewLine).Accepts(AcceptedCharactersInternal.None)),
Factory.EmptyCSharp().AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
Factory.EmptyHtml()),
new RazorDiagnostic[0]);
}
[Fact]
public void ParseBlockHandlesOpenAngleAtEof()
{
ParseDocumentTest("@{" + Environment.NewLine
+ "<",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
Factory.Code(Environment.NewLine)
.AsStatement()
.AutoCompleteWith("}"),
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<"))))),
RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"));
}
[Fact]
public void ParseBlockHandlesOpenAngleWithProperTagFollowingIt()
{
ParseDocumentTest("@{" + Environment.NewLine
+ "<" + Environment.NewLine
+ "</html>",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
Factory.Code(Environment.NewLine)
.AsStatement()
.AutoCompleteWith("}"),
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<" + Environment.NewLine))
),
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("</html>").Accepts(AcceptedCharactersInternal.None))
),
Factory.EmptyCSharp().AsStatement()
)
),
designTime: true,
expectedErrors: new[]
{
RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
new SourceSpan(new SourceLocation(5 + Environment.NewLine.Length * 2, 2, 2), contentLength: 4), "html"),
RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), Resources.BlockName_Code, "}", "{"),
});
}
[Fact]
public void TagWithoutCloseAngleDoesNotTerminateBlock()
{
ParseBlockTest("< " + Environment.NewLine
+ " ",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup($"< {Environment.NewLine} "))),
designTime: true,
expectedErrors: RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 1), string.Empty));
}
[Fact]
public void ParseBlockAllowsStartAndEndTagsToDifferInCase()
{
ParseBlockTest("<li><p>Foo</P></lI>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<li>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<p>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("Foo"),
new MarkupTagBlock(
Factory.Markup("</P>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</lI>").Accepts(AcceptedCharactersInternal.None))
));
}
[Fact]
public void ParseBlockReadsToEndOfLineIfFirstCharacterAfterTransitionIsColon()
{
ParseBlockTest("@:<li>Foo Bar Baz" + Environment.NewLine
+ "bork",
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("<li>Foo Bar Baz" + Environment.NewLine)
.With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharactersInternal.None))
));
}
[Fact]
public void ParseBlockStopsParsingSingleLineBlockAtEOFIfNoEOLReached()
{
ParseBlockTest("@:foo bar",
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup(@"foo bar")
.With(new SpanEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString))
));
}
[Fact]
public void ParseBlockStopsAtMatchingCloseTagToStartTag()
{
ParseBlockTest("<a><b></b></a><c></c>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<a>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<b>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</b>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</a>").Accepts(AcceptedCharactersInternal.None))
));
}
[Fact]
public void ParseBlockParsesUntilMatchingEndTagIfFirstNonWhitespaceCharacterIsStartTag()
{
ParseBlockTest("<baz><boz><biz></biz></boz></baz>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<baz>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<boz>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<biz>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</biz>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</boz>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</baz>").Accepts(AcceptedCharactersInternal.None))
));
}
[Fact]
public void ParseBlockAllowsUnclosedTagsAsLongAsItCanRecoverToAnExpectedEndTag()
{
ParseBlockTest("<foo><bar><baz></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<bar>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<baz>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))
));
}
[Fact]
public void ParseBlockWithSelfClosingTagJustEmitsTag()
{
ParseBlockTest("<foo />",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo />").Accepts(AcceptedCharactersInternal.None))
));
}
[Fact]
public void ParseBlockCanHandleSelfClosingTagsWithinBlock()
{
ParseBlockTest("<foo><bar /></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<bar />").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))
));
}
[Fact]
public void ParseBlockSupportsTagsWithAttributes()
{
ParseBlockTest("<foo bar=\"baz\"><biz><boz zoop=zork/></biz></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo"),
new MarkupBlock(new AttributeBlockChunkGenerator("bar", new LocationTagged<string>(" bar=\"", 4, 0, 4), new LocationTagged<string>("\"", 13, 0, 13)),
Factory.Markup(" bar=\"").With(SpanChunkGenerator.Null),
Factory.Markup("baz").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 10, 0, 10), new LocationTagged<string>("baz", 10, 0, 10))),
Factory.Markup("\"").With(SpanChunkGenerator.Null)),
Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<biz>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<boz"),
new MarkupBlock(new AttributeBlockChunkGenerator("zoop", new LocationTagged<string>(" zoop=", 24, 0, 24), new LocationTagged<string>(string.Empty, 34, 0, 34)),
Factory.Markup(" zoop=").With(SpanChunkGenerator.Null),
Factory.Markup("zork").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 30, 0, 30), new LocationTagged<string>("zork", 30, 0, 30)))),
Factory.Markup("/>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</biz>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockAllowsCloseAngleBracketInAttributeValueIfDoubleQuoted()
{
ParseBlockTest("<foo><bar baz=\">\" /></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<bar"),
new MarkupBlock(new AttributeBlockChunkGenerator("baz", new LocationTagged<string>(" baz=\"", 9, 0, 9), new LocationTagged<string>("\"", 16, 0, 16)),
Factory.Markup(" baz=\"").With(SpanChunkGenerator.Null),
Factory.Markup(">").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>(">", 15, 0, 15))),
Factory.Markup("\"").With(SpanChunkGenerator.Null)),
Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockAllowsCloseAngleBracketInAttributeValueIfSingleQuoted()
{
ParseBlockTest("<foo><bar baz=\'>\' /></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<bar"),
new MarkupBlock(new AttributeBlockChunkGenerator("baz", new LocationTagged<string>(" baz='", 9, 0, 9), new LocationTagged<string>("'", 16, 0, 16)),
Factory.Markup(" baz='").With(SpanChunkGenerator.Null),
Factory.Markup(">").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>(">", 15, 0, 15))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(" />").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockAllowsSlashInAttributeValueIfDoubleQuoted()
{
ParseBlockTest("<foo><bar baz=\"/\"></bar></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<bar"),
new MarkupBlock(new AttributeBlockChunkGenerator("baz", new LocationTagged<string>(" baz=\"", 9, 0, 9), new LocationTagged<string>("\"", 16, 0, 16)),
Factory.Markup(" baz=\"").With(SpanChunkGenerator.Null),
Factory.Markup("/").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>("/", 15, 0, 15))),
Factory.Markup("\"").With(SpanChunkGenerator.Null)),
Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</bar>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockAllowsSlashInAttributeValueIfSingleQuoted()
{
ParseBlockTest("<foo><bar baz=\'/\'></bar></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<bar"),
new MarkupBlock(new AttributeBlockChunkGenerator("baz", new LocationTagged<string>(" baz='", 9, 0, 9), new LocationTagged<string>("'", 16, 0, 16)),
Factory.Markup(" baz='").With(SpanChunkGenerator.Null),
Factory.Markup("/").With(new LiteralAttributeChunkGenerator(new LocationTagged<string>(string.Empty, 15, 0, 15), new LocationTagged<string>("/", 15, 0, 15))),
Factory.Markup("'").With(SpanChunkGenerator.Null)),
Factory.Markup(">").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</bar>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockTerminatesAtEOF()
{
ParseBlockTest("<foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None))),
RazorDiagnosticFactory.CreateParsing_MissingEndTag(
new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 3), "foo"));
}
[Fact]
public void ParseBlockSupportsCommentAsBlock()
{
ParseBlockTest("<!-- foo -->", new MarkupBlock(BlockFactory.HtmlCommentBlock(" foo ")));
}
[Fact]
public void ParseBlockSupportsCommentWithExtraDashAsBlock()
{
ParseBlockTest("<!-- foo --->", new MarkupBlock(BlockFactory.HtmlCommentBlock(" foo -")));
}
[Fact]
public void ParseBlockSupportsCommentWithinBlock()
{
ParseBlockTest("<foo>bar<!-- zoop -->baz</foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("bar"),
BlockFactory.HtmlCommentBlock(" zoop "),
Factory.Markup("baz").Accepts(AcceptedCharactersInternal.None),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
public static TheoryData HtmlCommentSupportsMultipleDashesData
{
get
{
var factory = new SpanFactory();
var blockFactory = new BlockFactory(factory);
return new TheoryData<string, MarkupBlock>
{
{
"<div><!--- Hello World ---></div>",
new MarkupBlock(
new MarkupTagBlock(
factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
blockFactory.HtmlCommentBlock("- Hello World -"),
new MarkupTagBlock(
factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None)))
},
{
"<div><!---- Hello World ----></div>",
new MarkupBlock(
new MarkupTagBlock(
factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
blockFactory.HtmlCommentBlock("-- Hello World --"),
new MarkupTagBlock(
factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None)))
},
{
"<div><!----- Hello World -----></div>",
new MarkupBlock(
new MarkupTagBlock(
factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
blockFactory.HtmlCommentBlock("--- Hello World ---"),
new MarkupTagBlock(
factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None)))
},
{
"<div><!----- Hello < --- > World </div> -----></div>",
new MarkupBlock(
new MarkupTagBlock(
factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
blockFactory.HtmlCommentBlock("--- Hello < --- > World </div> ---"),
new MarkupTagBlock(
factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None)))
},
};
}
}
[Theory]
[MemberData(nameof(HtmlCommentSupportsMultipleDashesData))]
public void HtmlCommentSupportsMultipleDashes(string documentContent, object expectedOutput)
{
FixupSpans = true;
ParseBlockTest(documentContent, (MarkupBlock)expectedOutput);
}
[Fact]
public void ParseBlockProperlyBalancesCommentStartAndEndTags()
{
ParseBlockTest("<!--<foo></bar>-->", new MarkupBlock(BlockFactory.HtmlCommentBlock("<foo></bar>")));
}
[Fact]
public void ParseBlockTerminatesAtEOFWhenParsingComment()
{
ParseBlockTest(
"<!--<foo>",
new MarkupBlock(
Factory.Markup("<!--<foo>").Accepts(AcceptedCharactersInternal.None)));
}
[Fact]
public void ParseBlockOnlyTerminatesCommentOnFullEndSequence()
{
ParseBlockTest("<!--<foo>--</bar>-->", new MarkupBlock(BlockFactory.HtmlCommentBlock("<foo>--</bar>")));
}
[Fact]
public void ParseBlockTerminatesCommentAtFirstOccurrenceOfEndSequence()
{
ParseBlockTest("<foo><!--<foo></bar-->--></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
BlockFactory.HtmlCommentBlock("<foo></bar"),
Factory.Markup("-->").Accepts(AcceptedCharactersInternal.None),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockTreatsMalformedTagsAsContent()
{
ParseBlockTest("<foo></!-- bar --></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</!-- bar -->").Accepts(AcceptedCharactersInternal.None))),
RazorDiagnosticFactory.CreateParsing_MissingEndTag(
new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 3), "foo"));
}
[Fact]
public void ParseBlockParsesSGMLDeclarationAsEmptyTag()
{
ParseBlockTest("<foo><!DOCTYPE foo bar baz></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("<!DOCTYPE foo bar baz>").Accepts(AcceptedCharactersInternal.None),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockTerminatesSGMLDeclarationAtFirstCloseAngle()
{
ParseBlockTest("<foo><!DOCTYPE foo bar> baz></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("<!DOCTYPE foo bar>").Accepts(AcceptedCharactersInternal.None),
Factory.Markup(" baz>"),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockParsesXMLProcessingInstructionAsEmptyTag()
{
ParseBlockTest("<foo><?xml foo bar baz?></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("<?xml foo bar baz?>").Accepts(AcceptedCharactersInternal.None),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockTerminatesXMLProcessingInstructionAtQuestionMarkCloseAnglePair()
{
ParseBlockTest("<foo><?xml foo bar baz?> baz</foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("<?xml foo bar baz?>").Accepts(AcceptedCharactersInternal.None),
Factory.Markup(" baz"),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockDoesNotTerminateXMLProcessingInstructionAtCloseAngleUnlessPreceededByQuestionMark()
{
ParseBlockTest("<foo><?xml foo bar> baz?></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("<?xml foo bar> baz?>").Accepts(AcceptedCharactersInternal.None),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockSupportsScriptTagsWithLessThanSignsInThem()
{
ParseBlockTest(@"<script>if(foo<bar) { alert(""baz"");)</script>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<script>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup(@"if(foo<bar) { alert(""baz"");)"),
new MarkupTagBlock(
Factory.Markup("</script>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockSupportsScriptTagsWithSpacedLessThanSignsInThem()
{
ParseBlockTest(@"<script>if(foo < bar) { alert(""baz"");)</script>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<script>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup(@"if(foo < bar) { alert(""baz"");)"),
new MarkupTagBlock(
Factory.Markup("</script>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockAcceptsEmptyTextTag()
{
ParseBlockTest("<text/>",
new MarkupBlock(
new MarkupTagBlock(
Factory.MarkupTransition("<text/>"))
));
}
[Fact]
public void ParseBlockAcceptsTextTagAsOuterTagButDoesNotRender()
{
ParseBlockTest("<text>Foo Bar <foo> Baz</text> zoop",
new MarkupBlock(
new MarkupTagBlock(
Factory.MarkupTransition("<text>")),
Factory.Markup("Foo Bar ").Accepts(AcceptedCharactersInternal.None),
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup(" Baz"),
new MarkupTagBlock(
Factory.MarkupTransition("</text>"))));
}
[Fact]
public void ParseBlockRendersLiteralTextTagIfDoubled()
{
ParseBlockTest("<text><text>Foo Bar <foo> Baz</text></text> zoop",
new MarkupBlock(
new MarkupTagBlock(
Factory.MarkupTransition("<text>")),
new MarkupTagBlock(
Factory.Markup("<text>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("Foo Bar "),
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup(" Baz"),
new MarkupTagBlock(
Factory.Markup("</text>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.MarkupTransition("</text>"))));
}
[Fact]
public void ParseBlockDoesNotConsiderPsuedoTagWithinMarkupBlock()
{
ParseBlockTest("<foo><text><bar></bar></foo>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<foo>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<text>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("<bar>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</bar>").Accepts(AcceptedCharactersInternal.None)),
new MarkupTagBlock(
Factory.Markup("</foo>").Accepts(AcceptedCharactersInternal.None))
));
}
[Fact]
public void ParseBlockStopsParsingMidEmptyTagIfEOFReached()
{
ParseBlockTest("<br/",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<br/"))),
RazorDiagnosticFactory.CreateParsing_UnfinishedTag(
new SourceSpan(new SourceLocation(1, 0, 1), contentLength: 2), "br"));
}
[Fact]
public void ParseBlockCorrectlyHandlesSingleLineOfMarkupWithEmbeddedStatement()
{
ParseBlockTest("<div>Foo @if(true) {} Bar</div>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<div>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("Foo "),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("if(true) {}").AsStatement()),
Factory.Markup(" Bar"),
new MarkupTagBlock(
Factory.Markup("</div>").Accepts(AcceptedCharactersInternal.None))));
}
[Fact]
public void ParseBlockIgnoresTagsInContentsOfScriptTag()
{
ParseBlockTest(@"<script>foo<bar baz='@boz'></script>",
new MarkupBlock(
new MarkupTagBlock(
Factory.Markup("<script>").Accepts(AcceptedCharactersInternal.None)),
Factory.Markup("foo<bar baz='"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("boz")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false)
.Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
Factory.Markup("'>"),
new MarkupTagBlock(
Factory.Markup("</script>").Accepts(AcceptedCharactersInternal.None))));
}
}
}