Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@ -0,0 +1,174 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Generator;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using System.Web.Razor.Tokenizer.Symbols;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpAutoCompleteTest : CsHtmlCodeParserTestBase
{
[Fact]
public void FunctionsDirectiveAutoCompleteAtEOF()
{
ParseBlockTest("@functions{",
new FunctionsBlock(
Factory.CodeTransition("@")
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("functions{")
.Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp()
.AsFunctionsBody()
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString)
{
AutoCompleteString = "}"
})),
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, "functions", "}", "{"),
1, 0, 1));
}
[Fact]
public void HelperDirectiveAutoCompleteAtEOF()
{
ParseBlockTest("@helper Strong(string value) {",
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Strong(string value) {", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ")
.Accepts(AcceptedCharacters.None),
Factory.Code("Strong(string value) {")
.Hidden()
.Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.EmptyCSharp()
.AsStatement()
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = "}" })
)
),
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, "helper", "}", "{"),
1, 0, 1));
}
[Fact]
public void SectionDirectiveAutoCompleteAtEOF()
{
ParseBlockTest("@section Header {",
new SectionBlock(new SectionCodeGenerator("Header"),
Factory.CodeTransition(),
Factory.MetaCode("section Header {")
.AutoCompleteWith("}", atEndOfSpan: true)
.Accepts(AcceptedCharacters.Any),
new MarkupBlock()),
new RazorError(
String.Format(RazorResources.ParseError_Expected_X, "}"),
17, 0, 17));
}
[Fact]
public void VerbatimBlockAutoCompleteAtEOF()
{
ParseBlockTest("@{",
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp()
.AsStatement()
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = "}" })
),
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, RazorResources.BlockName_Code, "}", "{"),
1, 0, 1));
}
[Fact]
public void FunctionsDirectiveAutoCompleteAtStartOfFile()
{
ParseBlockTest(@"@functions{
foo",
new FunctionsBlock(
Factory.CodeTransition("@")
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("functions{")
.Accepts(AcceptedCharacters.None),
Factory.Code("\r\nfoo")
.AsFunctionsBody()
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString)
{
AutoCompleteString = "}"
})),
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, "functions", "}", "{"),
1, 0, 1));
}
[Fact]
public void HelperDirectiveAutoCompleteAtStartOfFile()
{
ParseBlockTest(@"@helper Strong(string value) {
<p></p>",
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Strong(string value) {", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ")
.Accepts(AcceptedCharacters.None),
Factory.Code("Strong(string value) {")
.Hidden()
.Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.Code("\r\n")
.AsStatement()
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = "}" }),
new MarkupBlock(
Factory.Markup(@"<p></p>")
.With(new MarkupCodeGenerator())
.Accepts(AcceptedCharacters.None)
),
Factory.Span(SpanKind.Code, new CSharpSymbol(Factory.LocationTracker.CurrentLocation, String.Empty, CSharpSymbolType.Unknown))
.With(new StatementCodeGenerator())
)
),
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, "helper", "}", "{"),
1, 0, 1));
}
[Fact]
public void SectionDirectiveAutoCompleteAtStartOfFile()
{
ParseBlockTest(@"@section Header {
<p>Foo</p>",
new SectionBlock(new SectionCodeGenerator("Header"),
Factory.CodeTransition(),
Factory.MetaCode("section Header {")
.AutoCompleteWith("}", atEndOfSpan: true)
.Accepts(AcceptedCharacters.Any),
new MarkupBlock(
Factory.Markup("\r\n<p>Foo</p>"))),
new RazorError(String.Format(RazorResources.ParseError_Expected_X, "}"),
29, 1, 10));
}
[Fact]
public void VerbatimBlockAutoCompleteAtStartOfFile()
{
ParseBlockTest(@"@{
<p></p>",
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n")
.AsStatement()
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = "}" }),
new MarkupBlock(
Factory.Markup(@"<p></p>")
.With(new MarkupCodeGenerator())
.Accepts(AcceptedCharacters.None)
),
Factory.Span(SpanKind.Code, new CSharpSymbol(Factory.LocationTracker.CurrentLocation, String.Empty, CSharpSymbolType.Unknown))
.With(new StatementCodeGenerator())
),
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, RazorResources.BlockName_Code, "}", "{"),
1, 0, 1));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,163 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Generator;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpDirectivesTest : CsHtmlCodeParserTestBase
{
[Fact]
public void InheritsDirective()
{
ParseBlockTest("@inherits System.Web.WebPages.WebPage",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
.Accepts(AcceptedCharacters.None),
Factory.Code("System.Web.WebPages.WebPage")
.AsBaseType("System.Web.WebPages.WebPage")));
}
[Fact]
public void InheritsDirectiveSupportsArrays()
{
ParseBlockTest("@inherits string[[]][]",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
.Accepts(AcceptedCharacters.None),
Factory.Code("string[[]][]")
.AsBaseType("string[[]][]")));
}
[Fact]
public void InheritsDirectiveSupportsNestedGenerics()
{
ParseBlockTest("@inherits System.Web.Mvc.WebViewPage<IEnumerable<MvcApplication2.Models.RegisterModel>>",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
.Accepts(AcceptedCharacters.None),
Factory.Code("System.Web.Mvc.WebViewPage<IEnumerable<MvcApplication2.Models.RegisterModel>>")
.AsBaseType("System.Web.Mvc.WebViewPage<IEnumerable<MvcApplication2.Models.RegisterModel>>")));
}
[Fact]
public void InheritsDirectiveSupportsTypeKeywords()
{
ParseBlockTest("@inherits string",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
.Accepts(AcceptedCharacters.None),
Factory.Code("string")
.AsBaseType("string")));
}
[Fact]
public void InheritsDirectiveSupportsVSTemplateTokens()
{
ParseBlockTest("@inherits $rootnamespace$.MyBase",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode(SyntaxConstants.CSharp.InheritsKeyword + " ")
.Accepts(AcceptedCharacters.None),
Factory.Code("$rootnamespace$.MyBase")
.AsBaseType("$rootnamespace$.MyBase")));
}
[Fact]
public void SessionStateDirectiveWorks()
{
ParseBlockTest("@sessionstate InProc",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode(SyntaxConstants.CSharp.SessionStateKeyword + " ")
.Accepts(AcceptedCharacters.None),
Factory.Code("InProc")
.AsRazorDirectiveAttribute("sessionstate", "InProc")
));
}
[Fact]
public void SessionStateDirectiveParsesInvalidSessionValue()
{
ParseBlockTest("@sessionstate Blah",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode(SyntaxConstants.CSharp.SessionStateKeyword + " ")
.Accepts(AcceptedCharacters.None),
Factory.Code("Blah")
.AsRazorDirectiveAttribute("sessionstate", "Blah")
));
}
[Fact]
public void FunctionsDirective()
{
ParseBlockTest("@functions { foo(); bar(); }",
new FunctionsBlock(
Factory.CodeTransition(),
Factory.MetaCode(SyntaxConstants.CSharp.FunctionsKeyword + " {")
.Accepts(AcceptedCharacters.None),
Factory.Code(" foo(); bar(); ")
.AsFunctionsBody(),
Factory.MetaCode("}")
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void EmptyFunctionsDirective()
{
ParseBlockTest("@functions { }",
new FunctionsBlock(
Factory.CodeTransition(),
Factory.MetaCode(SyntaxConstants.CSharp.FunctionsKeyword + " {")
.Accepts(AcceptedCharacters.None),
Factory.Code(" ")
.AsFunctionsBody(),
Factory.MetaCode("}")
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void SectionDirective()
{
ParseBlockTest("@section Header { <p>F{o}o</p> }",
new SectionBlock(new SectionCodeGenerator("Header"),
Factory.CodeTransition(),
Factory.MetaCode("section Header {")
.AutoCompleteWith(null, atEndOfSpan: true)
.Accepts(AcceptedCharacters.Any),
new MarkupBlock(
Factory.Markup(" <p>F", "{", "o", "}", "o", "</p> ")),
Factory.MetaCode("}")
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void HelperDirective()
{
ParseBlockTest("@helper Strong(string value) { foo(); }",
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Strong(string value) {", new SourceLocation(8, 0, 8)), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ")
.Accepts(AcceptedCharacters.None),
Factory.Code("Strong(string value) {")
.Hidden()
.Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.Code(" foo(); ")
.AsStatement()
.With(new StatementCodeGenerator())),
Factory.Code("}")
.Hidden()
.Accepts(AcceptedCharacters.None)));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,141 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpExplicitExpressionTest : CsHtmlCodeParserTestBase
{
[Fact]
public void ParseBlockShouldOutputZeroLengthCodeSpanIfExplicitExpressionIsEmpty()
{
ParseBlockTest("@()",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp().AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockShouldOutputZeroLengthCodeSpanIfEOFOccursAfterStartOfExplicitExpression()
{
ParseBlockTest("@(",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp().AsExpression()
),
new RazorError(
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
RazorResources.BlockName_ExplicitExpression,
")", "("),
new SourceLocation(1, 0, 1)));
}
[Fact]
public void ParseBlockShouldAcceptEscapedQuoteInNonVerbatimStrings()
{
ParseBlockTest("@(\"\\\"\")",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("\"\\\"\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockShouldAcceptEscapedQuoteInVerbatimStrings()
{
ParseBlockTest("@(@\"\"\"\")",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("@\"\"\"\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockShouldAcceptMultipleRepeatedEscapedQuoteInVerbatimStrings()
{
ParseBlockTest("@(@\"\"\"\"\"\")",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("@\"\"\"\"\"\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockShouldAcceptMultiLineVerbatimStrings()
{
ParseBlockTest(@"@(@""
Foo
Bar
Baz
"")",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("@\"\r\nFoo\r\nBar\r\nBaz\r\n\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockShouldAcceptMultipleEscapedQuotesInNonVerbatimStrings()
{
ParseBlockTest("@(\"\\\"hello, world\\\"\")",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("\"\\\"hello, world\\\"\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockShouldAcceptMultipleEscapedQuotesInVerbatimStrings()
{
ParseBlockTest("@(@\"\"\"hello, world\"\"\")",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("@\"\"\"hello, world\"\"\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockShouldAcceptConsecutiveEscapedQuotesInNonVerbatimStrings()
{
ParseBlockTest("@(\"\\\"\\\"\")",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("\"\\\"\\\"\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockShouldAcceptConsecutiveEscapedQuotesInVerbatimStrings()
{
ParseBlockTest("@(@\"\"\"\"\"\")",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("@\"\"\"\"\"\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
}
}

View File

@ -0,0 +1,347 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Generator;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpHelperTest : CsHtmlMarkupParserTestBase
{
[Fact]
public void ParseHelperCorrectlyParsesHelperWithNoSpaceInBody()
{
ParseDocumentTest("@helper Foo(){@Bar()}",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(){", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo(){").Hidden().Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.EmptyCSharp().AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("Bar()")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.EmptyCSharp().AsStatement()),
Factory.Code("}").Hidden().Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void ParseHelperCorrectlyParsesIncompleteHelperPreceedingCodeBlock()
{
ParseDocumentTest(@"@helper
@{}",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(
Factory.CodeTransition(),
Factory.MetaCode("helper")),
Factory.Markup("\r\n"),
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp().AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start,
RazorResources.ErrorComponent_Newline),
7, 0, 7));
}
[Fact]
public void ParseHelperRequiresSpaceBeforeSignature()
{
ParseDocumentTest("@helper{",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(
Factory.CodeTransition(),
Factory.MetaCode("helper")),
Factory.Markup("{")),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start,
String.Format(RazorResources.ErrorComponent_Character, "{")),
7, 0, 7));
}
[Fact]
public void ParseHelperOutputsErrorButContinuesIfLParenFoundAfterHelperKeyword()
{
ParseDocumentTest("@helper () {",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("() {", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code("() {").Hidden().Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.EmptyCSharp()
.AsStatement()
.AutoCompleteWith("}")))),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start,
String.Format(RazorResources.ErrorComponent_Character, "(")),
8, 0, 8),
new RazorError(
String.Format(
RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
"helper", "}", "{"),
1, 0, 1));
}
[Fact]
public void ParseHelperStatementOutputsMarkerHelperHeaderSpanOnceKeywordComplete()
{
ParseDocumentTest("@helper ",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>(String.Empty, 8, 0, 8), headerComplete: false),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp().Hidden())),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start,
RazorResources.ErrorComponent_EndOfFile),
8, 0, 8));
}
[Fact]
public void ParseHelperStatementMarksHelperSpanAsCanGrowIfMissingTrailingSpace()
{
ParseDocumentTest("@helper",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(
Factory.CodeTransition(),
Factory.MetaCode("helper").Accepts(AcceptedCharacters.Any))),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start,
RazorResources.ErrorComponent_EndOfFile),
7, 0, 7));
}
[Fact]
public void ParseHelperStatementCapturesWhitespaceToEndOfLineIfHelperStatementMissingName()
{
ParseDocumentTest(@"@helper
",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>(" ", 8, 0, 8), headerComplete: false),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code(" \r\n").Hidden()),
Factory.Markup(@" ")),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start,
RazorResources.ErrorComponent_Newline),
30, 0, 30));
}
[Fact]
public void ParseHelperStatementCapturesWhitespaceToEndOfLineIfHelperStatementMissingOpenParen()
{
ParseDocumentTest(@"@helper Foo
",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo ", 8, 0, 8), headerComplete: false),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo \r\n").Hidden()),
Factory.Markup(" ")),
new RazorError(
String.Format(RazorResources.ParseError_MissingCharAfterHelperName, "("),
15, 0, 15));
}
[Fact]
public void ParseHelperStatementCapturesAllContentToEndOfFileIfHelperStatementMissingCloseParenInParameterList()
{
ParseDocumentTest(@"@helper Foo(Foo Bar
Biz
Boz",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(Foo Bar\r\nBiz\r\nBoz", 8, 0, 8), headerComplete: false),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo(Foo Bar\r\nBiz\r\nBoz").Hidden())),
new RazorError(
RazorResources.ParseError_UnterminatedHelperParameterList,
11, 0, 11));
}
[Fact]
public void ParseHelperStatementCapturesWhitespaceToEndOfLineIfHelperStatementMissingOpenBraceAfterParameterList()
{
ParseDocumentTest(@"@helper Foo(string foo)
",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(string foo) ", 8, 0, 8), headerComplete: false),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo(string foo) \r\n").Hidden())),
new RazorError(
String.Format(RazorResources.ParseError_MissingCharAfterHelperParameters, "{"),
29, 1, 0));
}
[Fact]
public void ParseHelperStatementContinuesParsingHelperUntilEOF()
{
ParseDocumentTest(@"@helper Foo(string foo) {
<p>Foo</p>",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(string foo) {", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code(@"Foo(string foo) {").Hidden().Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.Code(" \r\n")
.AsStatement()
.AutoCompleteWith("}"),
new MarkupBlock(
Factory.Markup(" <p>Foo</p>").Accepts(AcceptedCharacters.None)),
Factory.EmptyCSharp().AsStatement()))),
new RazorError(
String.Format(
RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
"helper", "}", "{"),
1, 0, 1));
}
[Fact]
public void ParseHelperStatementCorrectlyParsesHelperWithEmbeddedCode()
{
ParseDocumentTest(@"@helper Foo(string foo) {
<p>@foo</p>
}",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(string foo) {", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code(@"Foo(string foo) {").Hidden().Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.Code(" \r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Markup("</p>\r\n").Accepts(AcceptedCharacters.None)),
Factory.EmptyCSharp().AsStatement()),
Factory.Code("}").Hidden().Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void ParseHelperStatementCorrectlyParsesHelperWithNewlinesBetweenCloseParenAndOpenBrace()
{
ParseDocumentTest(@"@helper Foo(string foo)
{
<p>@foo</p>
}",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(string foo)\r\n\r\n\r\n\r\n{", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo(string foo)\r\n\r\n\r\n\r\n{").Hidden().Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.Code(" \r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(@" <p>"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Markup("</p>\r\n").Accepts(AcceptedCharacters.None)),
Factory.EmptyCSharp().AsStatement()),
Factory.Code("}").Hidden().Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void ParseHelperStatementGivesWhitespaceAfterOpenBraceToMarkupInDesignMode()
{
ParseDocumentTest(@"@helper Foo(string foo) {
",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(string foo) {", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code(@"Foo(string foo) {").Hidden().Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.Code(" \r\n ")
.AsStatement()
.AutoCompleteWith("}")))),
designTimeParser: true,
expectedErrors: new[]
{
new RazorError(
String.Format(
RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
"helper", "}", "{"),
new SourceLocation(1, 0, 1))
});
}
[Fact]
public void ParseHelperAcceptsNestedHelpersButOutputsError()
{
ParseDocumentTest(@"@helper Foo(string foo) {
@helper Bar(string baz) {
}
}",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(string foo) {", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code(@"Foo(string foo) {").Hidden().Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.Code("\r\n ").AsStatement(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Bar(string baz) {", 39, 1, 12), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("helper ").Accepts(AcceptedCharacters.None),
Factory.Code(@"Bar(string baz) {").Hidden().Accepts(AcceptedCharacters.None),
new StatementBlock(
Factory.Code("\r\n ").AsStatement()),
Factory.Code("}").Hidden().Accepts(AcceptedCharacters.None)),
Factory.Code("\r\n").AsStatement()),
Factory.Code("}").Hidden().Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()),
designTimeParser: true,
expectedErrors: new[]
{
new RazorError(RazorResources.ParseError_Helpers_Cannot_Be_Nested, 38, 1, 11)
});
}
}
}

View File

@ -0,0 +1,203 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpImplicitExpressionTest : CsHtmlCodeParserTestBase
{
private const string TestExtraKeyword = "model";
public override ParserBase CreateCodeParser()
{
return new CSharpCodeParser();
}
[Fact]
public void NestedImplicitExpression()
{
ParseBlockTest("if (true) { @foo }",
new StatementBlock(
Factory.Code("if (true) { ").AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Code(" }").AsStatement()));
}
[Fact]
public void ParseBlockAcceptsNonEnglishCharactersThatAreValidIdentifiers()
{
ImplicitExpressionTest("हळूँजद॔.", "हळूँजद॔");
}
[Fact]
public void ParseBlockOutputsZeroLengthCodeSpanIfInvalidCharacterFollowsTransition()
{
ParseBlockTest("@/",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.EmptyCSharp()
.AsImplicitExpression(KeywordSet)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
new RazorError(
String.Format(RazorResources.ParseError_Unexpected_Character_At_Start_Of_CodeBlock_CS, "/"),
new SourceLocation(1, 0, 1)));
}
[Fact]
public void ParseBlockOutputsZeroLengthCodeSpanIfEOFOccursAfterTransition()
{
ParseBlockTest("@",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.EmptyCSharp()
.AsImplicitExpression(KeywordSet)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
new RazorError(
RazorResources.ParseError_Unexpected_EndOfFile_At_Start_Of_CodeBlock,
new SourceLocation(1, 0, 1)));
}
[Fact]
public void ParseBlockSupportsSlashesWithinComplexImplicitExpressions()
{
ImplicitExpressionTest("DataGridColumn.Template(\"Years of Service\", e => (int)Math.Round((DateTime.Now - dt).TotalDays / 365))");
}
[Fact]
public void ParseBlockMethodParsesSingleIdentifierAsImplicitExpression()
{
ImplicitExpressionTest("foo");
}
[Fact]
public void ParseBlockMethodDoesNotAcceptSemicolonIfExpressionTerminatedByWhitespace()
{
ImplicitExpressionTest("foo ;", "foo");
}
[Fact]
public void ParseBlockMethodIgnoresSemicolonAtEndOfSimpleImplicitExpression()
{
RunTrailingSemicolonTest("foo");
}
[Fact]
public void ParseBlockMethodParsesDottedIdentifiersAsImplicitExpression()
{
ImplicitExpressionTest("foo.bar.baz");
}
[Fact]
public void ParseBlockMethodIgnoresSemicolonAtEndOfDottedIdentifiers()
{
RunTrailingSemicolonTest("foo.bar.baz");
}
[Fact]
public void ParseBlockMethodDoesNotIncludeDotAtEOFInImplicitExpression()
{
ImplicitExpressionTest("foo.bar.", "foo.bar");
}
[Fact]
public void ParseBlockMethodDoesNotIncludeDotFollowedByInvalidIdentifierCharacterInImplicitExpression()
{
ImplicitExpressionTest("foo.bar.0", "foo.bar");
ImplicitExpressionTest("foo.bar.</p>", "foo.bar");
}
[Fact]
public void ParseBlockMethodDoesNotIncludeSemicolonAfterDot()
{
ImplicitExpressionTest("foo.bar.;", "foo.bar");
}
[Fact]
public void ParseBlockMethodTerminatesAfterIdentifierUnlessFollowedByDotOrParenInImplicitExpression()
{
ImplicitExpressionTest("foo.bar</p>", "foo.bar");
}
[Fact]
public void ParseBlockProperlyParsesParenthesesAndBalancesThemInImplicitExpression()
{
ImplicitExpressionTest(@"foo().bar(""bi\""z"", 4)(""chained method; call"").baz(@""bo""""z"", '\'', () => { return 4; }, (4+5+new { foo = bar[4] }))");
}
[Fact]
public void ParseBlockProperlyParsesBracketsAndBalancesThemInImplicitExpression()
{
ImplicitExpressionTest(@"foo.bar[4 * (8 + 7)][""fo\""o""].baz");
}
[Fact]
public void ParseBlockTerminatesImplicitExpressionAtHtmlEndTag()
{
ImplicitExpressionTest("foo().bar.baz</p>zoop", "foo().bar.baz");
}
[Fact]
public void ParseBlockTerminatesImplicitExpressionAtHtmlStartTag()
{
ImplicitExpressionTest("foo().bar.baz<p>zoop", "foo().bar.baz");
}
[Fact]
public void ParseBlockTerminatesImplicitExpressionBeforeDotIfDotNotFollowedByIdentifierStartCharacter()
{
ImplicitExpressionTest("foo().bar.baz.42", "foo().bar.baz");
}
[Fact]
public void ParseBlockStopsBalancingParenthesesAtEOF()
{
ImplicitExpressionTest("foo(()", "foo(()",
acceptedCharacters: AcceptedCharacters.Any,
errors: new RazorError(String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF, "(", ")"), new SourceLocation(4, 0, 4)));
}
[Fact]
public void ParseBlockTerminatesImplicitExpressionIfCloseParenFollowedByAnyWhiteSpace()
{
ImplicitExpressionTest("foo.bar() (baz)", "foo.bar()");
}
[Fact]
public void ParseBlockTerminatesImplicitExpressionIfIdentifierFollowedByAnyWhiteSpace()
{
ImplicitExpressionTest("foo .bar() (baz)", "foo");
}
[Fact]
public void ParseBlockTerminatesImplicitExpressionAtLastValidPointIfDotFollowedByWhitespace()
{
ImplicitExpressionTest("foo. bar() (baz)", "foo");
}
[Fact]
public void ParseBlockOutputExpressionIfModuleTokenNotFollowedByBrace()
{
ImplicitExpressionTest("module.foo()");
}
private void RunTrailingSemicolonTest(string expr)
{
ParseBlockTest(SyntaxConstants.TransitionString + expr + ";",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code(expr)
.AsImplicitExpression(KeywordSet)
.Accepts(AcceptedCharacters.NonWhiteSpace)
));
}
}
}

View File

@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Editor;
using System.Web.Razor.Generator;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Test.Framework;
using Xunit;
using Xunit.Extensions;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpLayoutDirectiveTest : CsHtmlCodeParserTestBase
{
[Theory]
[InlineData("Layout")]
[InlineData("LAYOUT")]
[InlineData("layOut")]
[InlineData("LayOut")]
private void LayoutKeywordIsCaseSensitive(string word)
{
ParseBlockTest(word,
new ExpressionBlock(
Factory.Code(word)
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
));
}
[Fact]
public void LayoutDirectiveAcceptsAllTextToEndOfLine()
{
ParseBlockTest(@"@layout Foo Bar Baz",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("layout ").Accepts(AcceptedCharacters.None),
Factory.MetaCode("Foo Bar Baz")
.With(new SetLayoutCodeGenerator("Foo Bar Baz"))
.WithEditorHints(EditorHints.VirtualPath | EditorHints.LayoutPage)
)
);
}
[Fact]
public void LayoutDirectiveAcceptsAnyIfNoWhitespaceFollowingLayoutKeyword()
{
ParseBlockTest(@"@layout",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("layout")
)
);
}
[Fact]
public void LayoutDirectiveOutputsMarkerSpanIfAnyWhitespaceAfterLayoutKeyword()
{
ParseBlockTest(@"@layout ",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("layout ").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp()
.AsMetaCode()
.With(new SetLayoutCodeGenerator(String.Empty))
.WithEditorHints(EditorHints.VirtualPath | EditorHints.LayoutPage)
)
);
}
[Fact]
public void LayoutDirectiveAcceptsTrailingNewlineButDoesNotIncludeItInLayoutPath()
{
ParseBlockTest(@"@layout Foo
",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("layout ").Accepts(AcceptedCharacters.None),
Factory.MetaCode("Foo\r\n")
.With(new SetLayoutCodeGenerator("Foo"))
.Accepts(AcceptedCharacters.None)
.WithEditorHints(EditorHints.VirtualPath | EditorHints.LayoutPage)
)
);
}
}
}

View File

@ -0,0 +1,102 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Generator;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Test.Framework;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpNestedStatementsTest : CsHtmlCodeParserTestBase
{
[Fact]
public void NestedSimpleStatement()
{
ParseBlockTest("@while(true) { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("while(true) { foo(); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void NestedKeywordStatement()
{
ParseBlockTest("@while(true) { for(int i = 0; i < 10; i++) { foo(); } }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("while(true) { for(int i = 0; i < 10; i++) { foo(); } }")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void NestedCodeBlock()
{
ParseBlockTest("@while(true) { { { { foo(); } } } }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("while(true) { { { { foo(); } } } }")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void NestedImplicitExpression()
{
ParseBlockTest("@while(true) { @foo }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("while(true) { ")
.AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Code(" }")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void NestedExplicitExpression()
{
ParseBlockTest("@while(true) { @(foo) }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("while(true) { ")
.AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(")
.Accepts(AcceptedCharacters.None),
Factory.Code("foo")
.AsExpression(),
Factory.MetaCode(")")
.Accepts(AcceptedCharacters.None)),
Factory.Code(" }")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void NestedMarkupBlock()
{
ParseBlockTest("@while(true) { <p>Hello</p> }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("while(true) {")
.AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Hello</p> ")
.With(new MarkupCodeGenerator())
.Accepts(AcceptedCharacters.None)),
Factory.Code("}")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
}
}

View File

@ -0,0 +1,174 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Tokenizer.Symbols;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpRazorCommentsTest : CsHtmlMarkupParserTestBase
{
[Fact]
public void UnterminatedRazorComment()
{
ParseDocumentTest("@*",
new MarkupBlock(
Factory.EmptyHtml(),
new CommentBlock(
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Comment, new HtmlSymbol(
Factory.LocationTracker.CurrentLocation,
String.Empty,
HtmlSymbolType.Unknown))
.Accepts(AcceptedCharacters.Any))),
new RazorError(RazorResources.ParseError_RazorComment_Not_Terminated, 0, 0, 0));
}
[Fact]
public void EmptyRazorComment()
{
ParseDocumentTest("@**@",
new MarkupBlock(
Factory.EmptyHtml(),
new CommentBlock(
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Comment, new HtmlSymbol(
Factory.LocationTracker.CurrentLocation,
String.Empty,
HtmlSymbolType.Unknown))
.Accepts(AcceptedCharacters.Any),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void RazorCommentInImplicitExpressionMethodCall()
{
ParseDocumentTest(@"@foo(
@**@
",
new MarkupBlock(
Factory.EmptyHtml(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo(\r\n")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
new CommentBlock(
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Comment, new CSharpSymbol(
Factory.LocationTracker.CurrentLocation,
String.Empty,
CSharpSymbolType.Unknown))
.Accepts(AcceptedCharacters.Any),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None)),
Factory.Code("\r\n")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords))),
new RazorError(
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF, "(", ")"),
4, 0, 4));
}
[Fact]
public void UnterminatedRazorCommentInImplicitExpressionMethodCall()
{
ParseDocumentTest("@foo(@*",
new MarkupBlock(
Factory.EmptyHtml(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo(")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
new CommentBlock(
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Comment, new CSharpSymbol(
Factory.LocationTracker.CurrentLocation,
String.Empty,
CSharpSymbolType.Unknown))
.Accepts(AcceptedCharacters.Any)))),
new RazorError(RazorResources.ParseError_RazorComment_Not_Terminated, 5, 0, 5),
new RazorError(String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF, "(", ")"), 4, 0, 4));
}
[Fact]
public void RazorCommentInVerbatimBlock()
{
ParseDocumentTest(@"@{
<text
@**@
}",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition("<text").Accepts(AcceptedCharacters.Any),
Factory.Markup("\r\n "),
new CommentBlock(
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Comment, new HtmlSymbol(
Factory.LocationTracker.CurrentLocation,
String.Empty,
HtmlSymbolType.Unknown))
.Accepts(AcceptedCharacters.Any),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None)),
Factory.Markup("\r\n}")))),
new RazorError(RazorResources.ParseError_TextTagCannotContainAttributes, 8, 1, 4),
new RazorError(String.Format(RazorResources.ParseError_MissingEndTag, "text"), 8, 1, 4),
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, RazorResources.BlockName_Code, "}", "{"), 1, 0, 1));
}
[Fact]
public void UnterminatedRazorCommentInVerbatimBlock()
{
ParseDocumentTest("@{@*",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp()
.AsStatement(),
new CommentBlock(
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Comment, new CSharpSymbol(Factory.LocationTracker.CurrentLocation,
String.Empty,
CSharpSymbolType.Unknown))
.Accepts(AcceptedCharacters.Any)))),
new RazorError(RazorResources.ParseError_RazorComment_Not_Terminated, 2, 0, 2),
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, RazorResources.BlockName_Code, "}", "{"), 1, 0, 1));
}
}
}

View File

@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using Xunit.Extensions;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpReservedWordsTest : CsHtmlCodeParserTestBase
{
[Theory]
[InlineData("namespace")]
[InlineData("class")]
public void ReservedWords(string word)
{
ParseBlockTest(word,
new DirectiveBlock(
Factory.MetaCode(word).Accepts(AcceptedCharacters.None)
),
new RazorError(String.Format(RazorResources.ParseError_ReservedWord, word), SourceLocation.Zero));
}
[Theory]
[InlineData("Namespace")]
[InlineData("Class")]
[InlineData("NAMESPACE")]
[InlineData("CLASS")]
[InlineData("nameSpace")]
[InlineData("NameSpace")]
private void ReservedWordsAreCaseSensitive(string word)
{
ParseBlockTest(word,
new ExpressionBlock(
Factory.Code(word)
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
));
}
}
}

View File

@ -0,0 +1,300 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Generator;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpSectionTest : CsHtmlMarkupParserTestBase
{
[Fact]
public void ParseSectionBlockCapturesNewlineImmediatelyFollowing()
{
ParseDocumentTest(@"@section
",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator(String.Empty),
Factory.CodeTransition(),
Factory.MetaCode("section\r\n"))),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Section_Name_Start,
RazorResources.ErrorComponent_EndOfFile),
10, 1, 0));
}
[Fact]
public void ParseSectionBlockCapturesWhitespaceToEndOfLineInSectionStatementMissingOpenBrace()
{
ParseDocumentTest(@"@section Foo
",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("Foo"),
Factory.CodeTransition(),
Factory.MetaCode("section Foo \r\n")),
Factory.Markup(@" ")),
new RazorError(RazorResources.ParseError_MissingOpenBraceAfterSection, 12, 0, 12));
}
[Fact]
public void ParseSectionBlockCapturesWhitespaceToEndOfLineInSectionStatementMissingName()
{
ParseDocumentTest(@"@section
",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator(String.Empty),
Factory.CodeTransition(),
Factory.MetaCode("section \r\n")),
Factory.Markup(@" ")),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Section_Name_Start,
RazorResources.ErrorComponent_EndOfFile),
23, 1, 4));
}
[Fact]
public void ParseSectionBlockIgnoresSectionUnlessAllLowerCase()
{
ParseDocumentTest("@Section foo",
new MarkupBlock(
Factory.EmptyHtml(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("Section")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Markup(" foo")));
}
[Fact]
public void ParseSectionBlockReportsErrorAndTerminatesSectionBlockIfKeywordNotFollowedByIdentifierStartCharacter()
{
ParseDocumentTest("@section 9 { <p>Foo</p> }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator(String.Empty),
Factory.CodeTransition(),
Factory.MetaCode("section ")),
Factory.Markup("9 { <p>Foo</p> }")),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Section_Name_Start,
String.Format(RazorResources.ErrorComponent_Character, "9")),
9, 0, 9));
}
[Fact]
public void ParseSectionBlockReportsErrorAndTerminatesSectionBlockIfNameNotFollowedByOpenBrace()
{
ParseDocumentTest("@section foo-bar { <p>Foo</p> }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo")),
Factory.Markup("-bar { <p>Foo</p> }")),
new RazorError(RazorResources.ParseError_MissingOpenBraceAfterSection, 12, 0, 12));
}
[Fact]
public void ParserOutputsErrorOnNestedSections()
{
ParseDocumentTest("@section foo { @section bar { <p>Foo</p> } }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo {")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup(" "),
new SectionBlock(new SectionCodeGenerator("bar"),
Factory.CodeTransition(),
Factory.MetaCode("section bar {")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup(" <p>Foo</p> ")),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.Markup(" ")),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()),
new RazorError(
String.Format(
RazorResources.ParseError_Sections_Cannot_Be_Nested,
RazorResources.SectionExample_CS),
23, 0, 23));
}
[Fact]
public void ParseSectionBlockHandlesEOFAfterOpenBrace()
{
ParseDocumentTest("@section foo {",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo {")
.AutoCompleteWith("}", atEndOfSpan: true),
new MarkupBlock())),
new RazorError(
String.Format(RazorResources.ParseError_Expected_X, "}"),
14, 0, 14));
}
[Fact]
public void ParseSectionBlockHandlesUnterminatedSection()
{
ParseDocumentTest("@section foo { <p>Foo{}</p>",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo {")
.AutoCompleteWith("}", atEndOfSpan: true),
new MarkupBlock(
// Need to provide the markup span as fragments, since the parser will split the {} into separate symbols.
Factory.Markup(" <p>Foo", "{", "}", "</p>")))),
new RazorError(
String.Format(RazorResources.ParseError_Expected_X, "}"),
27, 0, 27));
}
[Fact]
public void ParseSectionBlockReportsErrorAndAcceptsWhitespaceToEndOfLineIfSectionNotFollowedByOpenBrace()
{
ParseDocumentTest(@"@section foo
",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo \r\n"))),
new RazorError(RazorResources.ParseError_MissingOpenBraceAfterSection, 12, 0, 12));
}
[Fact]
public void ParseSectionBlockAcceptsOpenBraceMultipleLinesBelowSectionName()
{
ParseDocumentTest(@"@section foo
{
<p>Foo</p>
}",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo \r\n\r\n\r\n\r\n\r\n\r\n{")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup("\r\n<p>Foo</p>\r\n")),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void ParseSectionBlockParsesNamedSectionCorrectly()
{
ParseDocumentTest("@section foo { <p>Foo</p> }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo {")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup(" <p>Foo</p> ")),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void ParseSectionBlockDoesNotRequireSpaceBetweenSectionNameAndOpenBrace()
{
ParseDocumentTest("@section foo{ <p>Foo</p> }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo{")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup(" <p>Foo</p> ")),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void ParseSectionBlockBalancesBraces()
{
ParseDocumentTest("@section foo { <script>(function foo() { return 1; })();</script> }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo {")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup(" <script>(function foo() { return 1; })();</script> ")),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void ParseSectionBlockAllowsBracesInCSharpExpression()
{
ParseDocumentTest("@section foo { I really want to render a close brace, so here I go: @(\"}\") }",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("section foo {")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup(" I really want to render a close brace, so here I go: "),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("\"}\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)),
Factory.Markup(" ")),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void SectionIsCorrectlyTerminatedWhenCloseBraceImmediatelyFollowsCodeBlock()
{
ParseDocumentTest(@"@section Foo {
@if(true) {
}
}",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("Foo"),
Factory.CodeTransition(),
Factory.MetaCode("section Foo {")
.AutoCompleteWith(null, atEndOfSpan: true),
new MarkupBlock(
Factory.Markup("\r\n"),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("if(true) {\r\n}\r\n").AsStatement()
)),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
}
}

View File

@ -0,0 +1,197 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpSpecialBlockTest : CsHtmlCodeParserTestBase
{
[Fact]
public void ParseInheritsStatementMarksInheritsSpanAsCanGrowIfMissingTrailingSpace()
{
ParseBlockTest("inherits",
new DirectiveBlock(
Factory.MetaCode("inherits").Accepts(AcceptedCharacters.Any)
),
new RazorError(
RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName,
new SourceLocation(8, 0, 8)));
}
[Fact]
public void InheritsBlockAcceptsMultipleGenericArguments()
{
ParseBlockTest("inherits Foo.Bar<Biz<Qux>, string, int>.Baz",
new DirectiveBlock(
Factory.MetaCode("inherits ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo.Bar<Biz<Qux>, string, int>.Baz")
.AsBaseType("Foo.Bar<Biz<Qux>, string, int>.Baz")
));
}
[Fact]
public void InheritsBlockOutputsErrorIfInheritsNotFollowedByTypeButAcceptsEntireLineAsCode()
{
ParseBlockTest(@"inherits
foo",
new DirectiveBlock(
Factory.MetaCode("inherits ").Accepts(AcceptedCharacters.None),
Factory.Code(" \r\n")
.AsBaseType(String.Empty)
),
new RazorError(RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName, 24, 0, 24));
}
[Fact]
public void NamespaceImportInsideCodeBlockCausesError()
{
ParseBlockTest("{ using Foo.Bar.Baz; var foo = bar; }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" using Foo.Bar.Baz; var foo = bar; ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
),
new RazorError(
RazorResources.ParseError_NamespaceImportAndTypeAlias_Cannot_Exist_Within_CodeBlock,
new SourceLocation(2, 0, 2)));
}
[Fact]
public void TypeAliasInsideCodeBlockIsNotHandledSpecially()
{
ParseBlockTest("{ using Foo = Bar.Baz; var foo = bar; }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" using Foo = Bar.Baz; var foo = bar; ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
),
new RazorError(
RazorResources.ParseError_NamespaceImportAndTypeAlias_Cannot_Exist_Within_CodeBlock,
new SourceLocation(2, 0, 2)));
}
[Fact]
public void Plan9FunctionsKeywordInsideCodeBlockIsNotHandledSpecially()
{
ParseBlockTest("{ functions Foo; }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" functions Foo; ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void NonKeywordStatementInCodeBlockIsHandledCorrectly()
{
ParseBlockTest(@"{
List<dynamic> photos = gallery.Photo.ToList();
}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n List<dynamic> photos = gallery.Photo.ToList();\r\n").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockBalancesBracesOutsideStringsIfFirstCharacterIsBraceAndReturnsSpanOfTypeCode()
{
// Arrange
const string code = "foo\"b}ar\" if(condition) { String.Format(\"{0}\"); } ";
// Act/Assert
ParseBlockTest("{" + code + "}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(code).AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockBalancesParensOutsideStringsIfFirstCharacterIsParenAndReturnsSpanOfTypeExpression()
{
// Arrange
const string code = "foo\"b)ar\" if(condition) { String.Format(\"{0}\"); } ";
// Act/Assert
ParseBlockTest("(" + code + ")",
new ExpressionBlock(
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code(code).AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockBalancesBracesAndOutputsContentAsClassLevelCodeSpanIfFirstIdentifierIsFunctionsKeyword()
{
const string code = " foo(); \"bar}baz\" ";
ParseBlockTest("functions {" + code + "} zoop",
new FunctionsBlock(
Factory.MetaCode("functions {").Accepts(AcceptedCharacters.None),
Factory.Code(code).AsFunctionsBody(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockDoesNoErrorRecoveryForFunctionsBlock()
{
ParseBlockTest("functions { { { { { } zoop",
new FunctionsBlock(
Factory.MetaCode("functions {").Accepts(AcceptedCharacters.None),
Factory.Code(" { { { { } zoop").AsFunctionsBody()
),
new RazorError(
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, "functions", "}", "{"),
SourceLocation.Zero));
}
[Fact]
public void ParseBlockIgnoresFunctionsUnlessAllLowerCase()
{
ParseBlockTest("Functions { foo() }",
new ExpressionBlock(
Factory.Code("Functions")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void ParseBlockIgnoresSingleSlashAtStart()
{
ParseBlockTest("@/ foo",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.EmptyCSharp()
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
new RazorError(
String.Format(RazorResources.ParseError_Unexpected_Character_At_Start_Of_CodeBlock_CS, "/"),
1, 0, 1));
}
[Fact]
public void ParseBlockTerminatesSingleLineCommentAtEndOfLine()
{
ParseBlockTest(@"if(!false) {
// Foo
<p>A real tag!</p>
}",
new StatementBlock(
Factory.Code("if(!false) {\r\n // Foo\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>A real tag!</p>\r\n")
.Accepts(AcceptedCharacters.None)),
Factory.Code("}").AsStatement()
));
}
}
}

View File

@ -0,0 +1,210 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Generator;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Test.Framework;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
// Basic Tests for C# Statements:
// * Basic case for each statement
// * Basic case for ALL clauses
// This class DOES NOT contain
// * Error cases
// * Tests for various types of nested statements
// * Comment tests
public class CSharpStatementTest : CsHtmlCodeParserTestBase
{
[Fact]
public void ForStatement()
{
ParseBlockTest("@for(int i = 0; i++; i < length) { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("for(int i = 0; i++; i < length) { foo(); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ForEachStatement()
{
ParseBlockTest("@foreach(var foo in bar) { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("foreach(var foo in bar) { foo(); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void WhileStatement()
{
ParseBlockTest("@while(true) { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("while(true) { foo(); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void SwitchStatement()
{
ParseBlockTest("@switch(foo) { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("switch(foo) { foo(); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void LockStatement()
{
ParseBlockTest("@lock(baz) { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("lock(baz) { foo(); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void IfStatement()
{
ParseBlockTest("@if(true) { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("if(true) { foo(); }")
.AsStatement()
));
}
[Fact]
public void ElseIfClause()
{
ParseBlockTest("@if(true) { foo(); } else if(false) { foo(); } else if(!false) { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("if(true) { foo(); } else if(false) { foo(); } else if(!false) { foo(); }")
.AsStatement()
));
}
[Fact]
public void ElseClause()
{
ParseBlockTest("@if(true) { foo(); } else { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("if(true) { foo(); } else { foo(); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void TryStatement()
{
ParseBlockTest("@try { foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("try { foo(); }")
.AsStatement()
));
}
[Fact]
public void CatchClause()
{
ParseBlockTest("@try { foo(); } catch(IOException ioex) { handleIO(); } catch(Exception ex) { handleOther(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("try { foo(); } catch(IOException ioex) { handleIO(); } catch(Exception ex) { handleOther(); }")
.AsStatement()
));
}
[Fact]
public void FinallyClause()
{
ParseBlockTest("@try { foo(); } finally { Dispose(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("try { foo(); } finally { Dispose(); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void UsingStatement()
{
ParseBlockTest("@using(var foo = new Foo()) { foo.Bar(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("using(var foo = new Foo()) { foo.Bar(); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void UsingTypeAlias()
{
ParseBlockTest("@using StringDictionary = System.Collections.Generic.Dictionary<string, string>",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.Code("using StringDictionary = System.Collections.Generic.Dictionary<string, string>")
.AsNamespaceImport(" StringDictionary = System.Collections.Generic.Dictionary<string, string>", 5)
.Accepts(AcceptedCharacters.AnyExceptNewline)
));
}
[Fact]
public void UsingNamespaceImport()
{
ParseBlockTest("@using System.Text.Encoding.ASCIIEncoding",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.Code("using System.Text.Encoding.ASCIIEncoding")
.AsNamespaceImport(" System.Text.Encoding.ASCIIEncoding", 5)
.Accepts(AcceptedCharacters.AnyExceptNewline)
));
}
[Fact]
public void DoStatement()
{
ParseBlockTest("@do { foo(); } while(true);",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("do { foo(); } while(true);")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void NonBlockKeywordTreatedAsImplicitExpression()
{
ParseBlockTest("@is foo",
new ExpressionBlock(new ExpressionCodeGenerator(),
Factory.CodeTransition(),
Factory.Code("is")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
));
}
}
}

View File

@ -0,0 +1,260 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Editor;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using System.Web.Razor.Tokenizer.Symbols;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpTemplateTest : CsHtmlCodeParserTestBase
{
private const string TestTemplateCode = " @<p>Foo #@item</p>";
private TemplateBlock TestTemplate()
{
return new TemplateBlock(
new MarkupBlock(
Factory.MarkupTransition(),
Factory.Markup("<p>Foo #"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("item")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.Markup("</p>").Accepts(AcceptedCharacters.None)
)
);
}
private const string TestNestedTemplateCode = " @<p>Foo #@Html.Repeat(10, @<p>@item</p>)</p>";
private TemplateBlock TestNestedTemplate()
{
return new TemplateBlock(
new MarkupBlock(
Factory.MarkupTransition(),
Factory.Markup("<p>Foo #"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("Html.Repeat(10, ")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
new TemplateBlock(
new MarkupBlock(
Factory.MarkupTransition(),
Factory.Markup("<p>"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("item")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.Markup("</p>").Accepts(AcceptedCharacters.None)
)
),
Factory.Code(")")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.Markup("</p>").Accepts(AcceptedCharacters.None)
)
);
}
[Fact]
public void ParseBlockHandlesSingleLineTemplate()
{
ParseBlockTest(@"{ var foo = @: bar
; }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" var foo = ").AsStatement(),
new TemplateBlock(
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup(" bar\r\n")
.With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString))
.Accepts(AcceptedCharacters.None)
)
),
Factory.Code("; ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockHandlesSingleLineImmediatelyFollowingStatementChar()
{
ParseBlockTest(@"{i@: bar
}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code("i").AsStatement(),
new TemplateBlock(
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup(" bar\r\n")
.With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString))
.Accepts(AcceptedCharacters.None)
)
),
Factory.EmptyCSharp().AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockHandlesSimpleTemplateInExplicitExpressionParens()
{
ParseBlockTest("(Html.Repeat(10," + TestTemplateCode + "))",
new ExpressionBlock(
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("Html.Repeat(10, ").AsExpression(),
TestTemplate(),
Factory.Code(")").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockHandlesSimpleTemplateInImplicitExpressionParens()
{
ParseBlockTest("Html.Repeat(10," + TestTemplateCode + ")",
new ExpressionBlock(
Factory.Code("Html.Repeat(10, ")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
TestTemplate(),
Factory.Code(")")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
));
}
[Fact]
public void ParseBlockHandlesTwoTemplatesInImplicitExpressionParens()
{
ParseBlockTest("Html.Repeat(10," + TestTemplateCode + "," + TestTemplateCode + ")",
new ExpressionBlock(
Factory.Code("Html.Repeat(10, ")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
TestTemplate(),
Factory.Code(", ")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
TestTemplate(),
Factory.Code(")")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)
));
}
[Fact]
public void ParseBlockProducesErrorButCorrectlyParsesNestedTemplateInImplicitExpressionParens()
{
ParseBlockTest("Html.Repeat(10," + TestNestedTemplateCode + ")",
new ExpressionBlock(
Factory.Code("Html.Repeat(10, ")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
TestNestedTemplate(),
Factory.Code(")")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
),
GetNestedTemplateError(42));
}
[Fact]
public void ParseBlockHandlesSimpleTemplateInStatementWithinCodeBlock()
{
ParseBlockTest("foreach(foo in Bar) { Html.ExecuteTemplate(foo," + TestTemplateCode + "); }",
new StatementBlock(
Factory.Code("foreach(foo in Bar) { Html.ExecuteTemplate(foo, ").AsStatement(),
TestTemplate(),
Factory.Code("); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockHandlesTwoTemplatesInStatementWithinCodeBlock()
{
ParseBlockTest("foreach(foo in Bar) { Html.ExecuteTemplate(foo," + TestTemplateCode + "," + TestTemplateCode + "); }",
new StatementBlock(
Factory.Code("foreach(foo in Bar) { Html.ExecuteTemplate(foo, ").AsStatement(),
TestTemplate(),
Factory.Code(", ").AsStatement(),
TestTemplate(),
Factory.Code("); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockProducesErrorButCorrectlyParsesNestedTemplateInStatementWithinCodeBlock()
{
ParseBlockTest("foreach(foo in Bar) { Html.ExecuteTemplate(foo," + TestNestedTemplateCode + "); }",
new StatementBlock(
Factory.Code("foreach(foo in Bar) { Html.ExecuteTemplate(foo, ").AsStatement(),
TestNestedTemplate(),
Factory.Code("); }")
.AsStatement()
.Accepts(AcceptedCharacters.None)
),
GetNestedTemplateError(74));
}
[Fact]
public void ParseBlockHandlesSimpleTemplateInStatementWithinStatementBlock()
{
ParseBlockTest("{ var foo = bar; Html.ExecuteTemplate(foo," + TestTemplateCode + "); }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" var foo = bar; Html.ExecuteTemplate(foo, ").AsStatement(),
TestTemplate(),
Factory.Code("); ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockHandlessTwoTemplatesInStatementWithinStatementBlock()
{
ParseBlockTest("{ var foo = bar; Html.ExecuteTemplate(foo," + TestTemplateCode + "," + TestTemplateCode + "); }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" var foo = bar; Html.ExecuteTemplate(foo, ").AsStatement(),
TestTemplate(),
Factory.Code(", ").AsStatement(),
TestTemplate(),
Factory.Code("); ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockProducesErrorButCorrectlyParsesNestedTemplateInStatementWithinStatementBlock()
{
ParseBlockTest("{ var foo = bar; Html.ExecuteTemplate(foo," + TestNestedTemplateCode + "); }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" var foo = bar; Html.ExecuteTemplate(foo, ").AsStatement(),
TestNestedTemplate(),
Factory.Code("); ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
),
GetNestedTemplateError(69));
}
private static RazorError GetNestedTemplateError(int characterIndex)
{
return new RazorError(RazorResources.ParseError_InlineMarkup_Blocks_Cannot_Be_Nested, new SourceLocation(characterIndex, 0, characterIndex));
}
}
}

View File

@ -0,0 +1,493 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Editor;
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Tokenizer.Symbols;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpToMarkupSwitchTest : CsHtmlCodeParserTestBase
{
[Fact]
public void SingleAngleBracketDoesNotCauseSwitchIfOuterBlockIsTerminated()
{
ParseBlockTest("{ List< }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" List< ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockGivesSpacesToCodeOnAtTagTemplateTransitionInDesignTimeMode()
{
ParseBlockTest(@"Foo( @<p>Foo</p> )",
new ExpressionBlock(
Factory.Code(@"Foo( ")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.Any),
new TemplateBlock(
new MarkupBlock(
Factory.MarkupTransition(),
Factory.Markup("<p>Foo</p>").Accepts(AcceptedCharacters.None)
)
),
Factory.Code(@" )")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
), designTimeParser: true);
}
[Fact]
public void ParseBlockGivesSpacesToCodeOnAtColonTemplateTransitionInDesignTimeMode()
{
ParseBlockTest(@"Foo(
@:<p>Foo</p>
)",
new ExpressionBlock(
Factory.Code("Foo( \r\n").AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
new TemplateBlock(
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("<p>Foo</p> \r\n")
.With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None))
)
),
Factory.Code(@")")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
), designTimeParser: true);
}
[Fact]
public void ParseBlockGivesSpacesToCodeOnTagTransitionInDesignTimeMode()
{
ParseBlockTest(@"{
<p>Foo</p>
}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n ").AsStatement(),
new MarkupBlock(
Factory.Markup("<p>Foo</p>").Accepts(AcceptedCharacters.None)
),
Factory.Code(" \r\n").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
), designTimeParser: true);
}
[Fact]
public void ParseBlockGivesSpacesToCodeOnInvalidAtTagTransitionInDesignTimeMode()
{
ParseBlockTest(@"{
@<p>Foo</p>
}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n ").AsStatement(),
new MarkupBlock(
Factory.MarkupTransition(),
Factory.Markup("<p>Foo</p>").Accepts(AcceptedCharacters.None)
),
Factory.Code(" \r\n").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
), true,
new RazorError(RazorResources.ParseError_AtInCode_Must_Be_Followed_By_Colon_Paren_Or_Identifier_Start, 7, 1, 4));
}
[Fact]
public void ParseBlockGivesSpacesToCodeOnAtColonTransitionInDesignTimeMode()
{
ParseBlockTest(@"{
@:<p>Foo</p>
}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n ").AsStatement(),
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("<p>Foo</p> \r\n")
.With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None))
),
Factory.EmptyCSharp().AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
), designTimeParser: true);
}
[Fact]
public void ParseBlockShouldSupportSingleLineMarkupContainingStatementBlock()
{
ParseBlockTest(@"Repeat(10,
@: @{}
)",
new ExpressionBlock(
Factory.Code("Repeat(10,\r\n ")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords),
new TemplateBlock(
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup(" ")
.With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString)),
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp().AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
),
Factory.Markup("\r\n")
.With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None))
)
),
Factory.Code(")")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)
));
}
[Fact]
public void ParseBlockShouldSupportMarkupWithoutPreceedingWhitespace()
{
ParseBlockTest(@"foreach(var file in files){
@:Baz
<br/>
<a>Foo</a>
@:Bar
}",
new StatementBlock(
Factory.Code("foreach(var file in files){\r\n\r\n\r\n").AsStatement(),
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("Baz\r\n")
.With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None))
),
new MarkupBlock(
Factory.Markup("<br/>\r\n")
.Accepts(AcceptedCharacters.None)
),
new MarkupBlock(
Factory.Markup("<a>Foo</a>\r\n")
.Accepts(AcceptedCharacters.None)
),
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("Bar\r\n")
.With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None))
),
Factory.Code("}").AsStatement().Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockGivesAllWhitespaceOnSameLineExcludingPreceedingNewlineButIncludingTrailingNewLineToMarkup()
{
ParseBlockTest(@"if(foo) {
var foo = ""After this statement there are 10 spaces"";
<p>
Foo
@bar
</p>
@:Hello!
var biz = boz;
}",
new StatementBlock(
Factory.Code("if(foo) {\r\n var foo = \"After this statement there are 10 spaces\"; \r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>\r\n Foo\r\n"),
new ExpressionBlock(
Factory.Code(" ").AsStatement(),
Factory.CodeTransition(),
Factory.Code(@"bar").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.Markup("\r\n </p>\r\n").Accepts(AcceptedCharacters.None)
),
new MarkupBlock(
Factory.Markup(@" "),
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("Hello!\r\n").With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None))
),
Factory.Code(" var biz = boz;\r\n}").AsStatement()));
}
[Fact]
public void ParseBlockAllowsMarkupInIfBodyWithBraces()
{
ParseBlockTest("if(foo) { <p>Bar</p> } else if(bar) { <p>Baz</p> } else { <p>Boz</p> }",
new StatementBlock(
Factory.Code("if(foo) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Bar</p> ").Accepts(AcceptedCharacters.None)
),
Factory.Code("} else if(bar) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Baz</p> ").Accepts(AcceptedCharacters.None)
),
Factory.Code("} else {").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Boz</p> ").Accepts(AcceptedCharacters.None)
),
Factory.Code("}").AsStatement().Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockAllowsMarkupInIfBodyWithBracesWithinCodeBlock()
{
ParseBlockTest("{ if(foo) { <p>Bar</p> } else if(bar) { <p>Baz</p> } else { <p>Boz</p> } }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" if(foo) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Bar</p> ").Accepts(AcceptedCharacters.None)
),
Factory.Code("} else if(bar) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Baz</p> ").Accepts(AcceptedCharacters.None)
),
Factory.Code("} else {").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Boz</p> ").Accepts(AcceptedCharacters.None)
),
Factory.Code("} ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockSupportsMarkupInCaseAndDefaultBranchesOfSwitch()
{
// Arrange
ParseBlockTest(@"switch(foo) {
case 0:
<p>Foo</p>
break;
case 1:
<p>Bar</p>
return;
case 2:
{
<p>Baz</p>
<p>Boz</p>
}
default:
<p>Biz</p>
}",
new StatementBlock(
Factory.Code("switch(foo) {\r\n case 0:\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Foo</p>\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code(" break;\r\n case 1:\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Bar</p>\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code(" return;\r\n case 2:\r\n {\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Baz</p>\r\n").Accepts(AcceptedCharacters.None)
),
new MarkupBlock(
Factory.Markup(" <p>Boz</p>\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code(" }\r\n default:\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Biz</p>\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code("}").AsStatement().Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockSupportsMarkupInCaseAndDefaultBranchesOfSwitchInCodeBlock()
{
// Arrange
ParseBlockTest(@"{ switch(foo) {
case 0:
<p>Foo</p>
break;
case 1:
<p>Bar</p>
return;
case 2:
{
<p>Baz</p>
<p>Boz</p>
}
default:
<p>Biz</p>
} }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" switch(foo) {\r\n case 0:\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Foo</p>\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code(" break;\r\n case 1:\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Bar</p>\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code(" return;\r\n case 2:\r\n {\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Baz</p>\r\n").Accepts(AcceptedCharacters.None)
),
new MarkupBlock(
Factory.Markup(" <p>Boz</p>\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code(" }\r\n default:\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Biz</p>\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code("} ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockParsesMarkupStatementOnOpenAngleBracket()
{
ParseBlockTest("for(int i = 0; i < 10; i++) { <p>Foo</p> }",
new StatementBlock(
Factory.Code("for(int i = 0; i < 10; i++) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Foo</p> ").Accepts(AcceptedCharacters.None)
),
Factory.Code("}").AsStatement().Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void ParseBlockParsesMarkupStatementOnOpenAngleBracketInCodeBlock()
{
ParseBlockTest("{ for(int i = 0; i < 10; i++) { <p>Foo</p> } }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" for(int i = 0; i < 10; i++) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>Foo</p> ").Accepts(AcceptedCharacters.None)
),
Factory.Code("} ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockParsesMarkupStatementOnSwitchCharacterFollowedByColon()
{
// Arrange
ParseBlockTest(@"if(foo) { @:Bar
} zoop",
new StatementBlock(
Factory.Code("if(foo) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("Bar\r\n").With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None))
),
Factory.Code("}").AsStatement()));
}
[Fact]
public void ParseBlockParsesMarkupStatementOnSwitchCharacterFollowedByColonInCodeBlock()
{
// Arrange
ParseBlockTest(@"{ if(foo) { @:Bar
} } zoop",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(" if(foo) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("Bar\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code("} ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockCorrectlyReturnsFromMarkupBlockWithPseudoTag()
{
ParseBlockTest(@"if (i > 0) { <text>;</text> }",
new StatementBlock(
Factory.Code(@"if (i > 0) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition("<text>").Accepts(AcceptedCharacters.None),
Factory.Markup(";"),
Factory.MarkupTransition("</text>").Accepts(AcceptedCharacters.None),
Factory.Markup(" ").Accepts(AcceptedCharacters.None)
),
Factory.Code(@"}").AsStatement()));
}
[Fact]
public void ParseBlockCorrectlyReturnsFromMarkupBlockWithPseudoTagInCodeBlock()
{
ParseBlockTest(@"{ if (i > 0) { <text>;</text> } }",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code(@" if (i > 0) {").AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition("<text>").Accepts(AcceptedCharacters.None),
Factory.Markup(";"),
Factory.MarkupTransition("</text>").Accepts(AcceptedCharacters.None),
Factory.Markup(" ").Accepts(AcceptedCharacters.None)
),
Factory.Code(@"} ").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockSupportsAllKindsOfImplicitMarkupInCodeBlock()
{
ParseBlockTest(@"{
if(true) {
@:Single Line Markup
}
foreach (var p in Enumerable.Range(1, 10)) {
<text>The number is @p</text>
}
if(!false) {
<p>A real tag!</p>
}
}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n if(true) {\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("Single Line Markup\r\n").With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None))
),
Factory.Code(" }\r\n foreach (var p in Enumerable.Range(1, 10)) {\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(@" "),
Factory.MarkupTransition("<text>").Accepts(AcceptedCharacters.None),
Factory.Markup("The number is "),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("p").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.MarkupTransition("</text>").Accepts(AcceptedCharacters.None),
Factory.Markup("\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code(" }\r\n if(!false) {\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" <p>A real tag!</p>\r\n").Accepts(AcceptedCharacters.None)
),
Factory.Code(" }\r\n").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
}
}
}

View File

@ -0,0 +1,120 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpVerbatimBlockTest : CsHtmlCodeParserTestBase
{
private const string TestExtraKeyword = "model";
[Fact]
public void VerbatimBlock()
{
ParseBlockTest("@{ foo(); }",
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("{")
.Accepts(AcceptedCharacters.None),
Factory.Code(" foo(); ")
.AsStatement(),
Factory.MetaCode("}")
.Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void InnerImplicitExpressionWithOnlySingleAtOutputsZeroLengthCodeSpan()
{
ParseBlockTest(@"{@}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp().AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.EmptyCSharp().AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.EmptyCSharp().AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
designTimeParser: true,
expectedErrors: new[]
{
new RazorError(String.Format(RazorResources.ParseError_Unexpected_Character_At_Start_Of_CodeBlock_CS, "}"), new SourceLocation(2, 0, 2))
});
}
[Fact]
public void InnerImplicitExpressionDoesNotAcceptDotAfterAt()
{
ParseBlockTest(@"{@.}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp().AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.EmptyCSharp().AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.Code(".").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
designTimeParser: true,
expectedErrors: new[]
{
new RazorError(String.Format(RazorResources.ParseError_Unexpected_Character_At_Start_Of_CodeBlock_CS, "."), new SourceLocation(2, 0, 2))
});
}
[Fact]
public void InnerImplicitExpressionWithOnlySingleAtAcceptsSingleSpaceOrNewlineAtDesignTime()
{
ParseBlockTest(@"{
@
}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n ").AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.EmptyCSharp().AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.Code("\r\n").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
/* designTimeParser */ true,
new RazorError(RazorResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_CS, 8, 1, 5));
}
[Fact]
public void InnerImplicitExpressionDoesNotAcceptTrailingNewlineInRunTimeMode()
{
ParseBlockTest(@"{@foo.
}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp().AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code(@"foo.").AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Code("\r\n").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void InnerImplicitExpressionAcceptsTrailingNewlineInDesignTimeMode()
{
ParseBlockTest(@"{@foo.
}",
new StatementBlock(
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
Factory.EmptyCSharp().AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code(@"foo.").AsImplicitExpression(KeywordSet, acceptTrailingDot: true).Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Code("\r\n").AsStatement(),
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
designTimeParser: true);
}
}
}

View File

@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Tokenizer.Symbols;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CSharpWhitespaceHandlingTest : CsHtmlMarkupParserTestBase
{
[Fact]
public void StatementBlockDoesNotAcceptTrailingNewlineIfNewlinesAreSignificantToAncestor()
{
ParseBlockTest(@"@: @if (true) { }
}",
new MarkupBlock(
Factory.MarkupTransition()
.Accepts(AcceptedCharacters.None),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup(" "),
new StatementBlock(
Factory.CodeTransition()
.Accepts(AcceptedCharacters.None),
Factory.Code("if (true) { }")
.AsStatement()
),
Factory.Markup("\r\n")
.Accepts(AcceptedCharacters.None)));
}
}
}

View File

@ -0,0 +1,288 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Resources;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using System.Web.Razor.Tokenizer.Symbols;
using Xunit;
namespace System.Web.Razor.Test.Parser.CSharp
{
public class CsHtmlDocumentTest : CsHtmlMarkupParserTestBase
{
[Fact]
public void UnterminatedBlockCommentCausesRazorError()
{
ParseDocumentTest(@"@* Foo Bar",
new MarkupBlock(
Factory.EmptyHtml(),
new CommentBlock(
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment(" Foo Bar", HtmlSymbolType.RazorComment)
)
),
new RazorError(RazorResources.ParseError_RazorComment_Not_Terminated, SourceLocation.Zero));
}
[Fact]
public void BlockCommentInMarkupDocumentIsHandledCorrectly()
{
ParseDocumentTest(@"<ul>
@* This is a block comment </ul> *@ foo",
new MarkupBlock(
Factory.Markup("<ul>\r\n "),
new CommentBlock(
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment(" This is a block comment </ul> ", HtmlSymbolType.RazorComment),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
),
Factory.Markup(" foo")
));
}
[Fact]
public void BlockCommentInMarkupBlockIsHandledCorrectly()
{
ParseBlockTest(@"<ul>
@* This is a block comment </ul> *@ foo </ul>",
new MarkupBlock(
Factory.Markup("<ul>\r\n "),
new CommentBlock(
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment(" This is a block comment </ul> ", HtmlSymbolType.RazorComment),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
),
Factory.Markup(" foo </ul>").Accepts(AcceptedCharacters.None)
));
}
[Fact]
public void BlockCommentAtStatementStartInCodeBlockIsHandledCorrectly()
{
ParseDocumentTest(@"@if(Request.IsAuthenticated) {
@* User is logged in! } *@
Write(""Hello friend!"");
}",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("if(Request.IsAuthenticated) {\r\n ").AsStatement(),
new CommentBlock(
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment(" User is logged in! } ", CSharpSymbolType.RazorComment),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
),
Factory.Code("\r\n Write(\"Hello friend!\");\r\n}").AsStatement())));
}
[Fact]
public void BlockCommentInStatementInCodeBlockIsHandledCorrectly()
{
ParseDocumentTest(@"@if(Request.IsAuthenticated) {
var foo = @* User is logged in! ; *@;
Write(""Hello friend!"");
}",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("if(Request.IsAuthenticated) {\r\n var foo = ").AsStatement(),
new CommentBlock(
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment(" User is logged in! ; ", CSharpSymbolType.RazorComment),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
),
Factory.Code(";\r\n Write(\"Hello friend!\");\r\n}").AsStatement())));
}
[Fact]
public void BlockCommentInStringIsIgnored()
{
ParseDocumentTest(@"@if(Request.IsAuthenticated) {
var foo = ""@* User is logged in! ; *@"";
Write(""Hello friend!"");
}",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code(@"if(Request.IsAuthenticated) {
var foo = ""@* User is logged in! ; *@"";
Write(""Hello friend!"");
}").AsStatement())));
}
[Fact]
public void BlockCommentInCSharpBlockCommentIsIgnored()
{
ParseDocumentTest(@"@if(Request.IsAuthenticated) {
var foo = /*@* User is logged in! */ *@ */;
Write(""Hello friend!"");
}",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code(@"if(Request.IsAuthenticated) {
var foo = /*@* User is logged in! */ *@ */;
Write(""Hello friend!"");
}").AsStatement())));
}
[Fact]
public void BlockCommentInCSharpLineCommentIsIgnored()
{
ParseDocumentTest(@"@if(Request.IsAuthenticated) {
var foo = //@* User is logged in! */ *@;
Write(""Hello friend!"");
}",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code(@"if(Request.IsAuthenticated) {
var foo = //@* User is logged in! */ *@;
Write(""Hello friend!"");
}").AsStatement())));
}
[Fact]
public void BlockCommentInImplicitExpressionIsHandledCorrectly()
{
ParseDocumentTest(@"@Html.Foo@*bar*@",
new MarkupBlock(
Factory.EmptyHtml(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("Html.Foo").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.EmptyHtml(),
new CommentBlock(
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment("bar", HtmlSymbolType.RazorComment),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentAfterDotOfImplicitExpressionIsHandledCorrectly()
{
ParseDocumentTest(@"@Html.@*bar*@",
new MarkupBlock(
Factory.EmptyHtml(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code(@"Html").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.Markup("."),
new CommentBlock(
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment("bar", HtmlSymbolType.RazorComment),
Factory.MetaMarkup("*", HtmlSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.MarkupTransition(HtmlSymbolType.RazorCommentTransition)
),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentInParensOfImplicitExpressionIsHandledCorrectly()
{
ParseDocumentTest(@"@Html.Foo(@*bar*@ 4)",
new MarkupBlock(
Factory.EmptyHtml(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code(@"Html.Foo(").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.Any),
new CommentBlock(
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment("bar", CSharpSymbolType.RazorComment),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
),
Factory.Code(" 4)").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentInBracketsOfImplicitExpressionIsHandledCorrectly()
{
ParseDocumentTest(@"@Html.Foo[@*bar*@ 4]",
new MarkupBlock(
Factory.EmptyHtml(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code(@"Html.Foo[").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.Any),
new CommentBlock(
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment("bar", CSharpSymbolType.RazorComment),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
),
Factory.Code(" 4]").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)
),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentInParensOfConditionIsHandledCorrectly()
{
ParseDocumentTest(@"@if(@*bar*@) {}",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code(@"if(").AsStatement(),
new CommentBlock(
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment("bar", CSharpSymbolType.RazorComment),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
),
Factory.Code(") {}").AsStatement()
)));
}
[Fact]
public void BlockCommentInExplicitExpressionIsHandledCorrectly()
{
ParseDocumentTest(@"@(1 + @*bar*@ 1)",
new MarkupBlock(
Factory.EmptyHtml(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code(@"1 + ").AsExpression(),
new CommentBlock(
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment("bar", CSharpSymbolType.RazorComment),
Factory.MetaCode("*", CSharpSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(CSharpSymbolType.RazorCommentTransition)
),
Factory.Code(" 1").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
),
Factory.EmptyHtml()));
}
}
}