a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
627 lines
29 KiB
C#
627 lines
29 KiB
C#
// 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 CSharpErrorTest : CsHtmlCodeParserTestBase
|
|
{
|
|
[Fact]
|
|
public void ParseBlockHandlesQuotesAfterTransition()
|
|
{
|
|
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, '"'),
|
|
1, 0, 1));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockCapturesWhitespaceToEndOfLineInInvalidUsingStatementAndTreatsAsFileCode()
|
|
{
|
|
ParseBlockTest(@"using
|
|
|
|
",
|
|
new StatementBlock(
|
|
Factory.Code("using \r\n").AsStatement()
|
|
));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockMethodOutputsOpenCurlyAsCodeSpanIfEofFoundAfterOpenCurlyBrace()
|
|
{
|
|
ParseBlockTest("{",
|
|
new StatementBlock(
|
|
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,
|
|
"}", "{"),
|
|
SourceLocation.Zero));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockMethodOutputsZeroLengthCodeSpanIfStatementBlockEmpty()
|
|
{
|
|
ParseBlockTest("{}",
|
|
new StatementBlock(
|
|
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
|
|
Factory.EmptyCSharp().AsStatement(),
|
|
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
|
|
));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockMethodProducesErrorIfNewlineFollowsTransition()
|
|
{
|
|
ParseBlockTest(@"@
|
|
",
|
|
new ExpressionBlock(
|
|
Factory.CodeTransition(),
|
|
Factory.EmptyCSharp()
|
|
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
|
.Accepts(AcceptedCharacters.NonWhiteSpace)),
|
|
new RazorError(RazorResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_CS, new SourceLocation(1, 0, 1)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockMethodProducesErrorIfWhitespaceBetweenTransitionAndBlockStartInEmbeddedExpression()
|
|
{
|
|
ParseBlockTest(@"{
|
|
@ {}
|
|
}",
|
|
new StatementBlock(
|
|
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
|
|
Factory.Code("\r\n ").AsStatement(),
|
|
new ExpressionBlock(
|
|
Factory.CodeTransition(),
|
|
Factory.EmptyCSharp()
|
|
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
|
|
.Accepts(AcceptedCharacters.NonWhiteSpace)),
|
|
Factory.Code(" {}\r\n").AsStatement(),
|
|
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)
|
|
),
|
|
new RazorError(RazorResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_CS, 8, 1, 5));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockMethodProducesErrorIfEOFAfterTransitionInEmbeddedExpression()
|
|
{
|
|
ParseBlockTest(@"{
|
|
@",
|
|
new StatementBlock(
|
|
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
|
|
Factory.Code("\r\n ").AsStatement(),
|
|
new ExpressionBlock(
|
|
Factory.CodeTransition(),
|
|
Factory.EmptyCSharp()
|
|
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
|
|
.Accepts(AcceptedCharacters.NonWhiteSpace)),
|
|
Factory.EmptyCSharp().AsStatement()
|
|
),
|
|
new RazorError(RazorResources.ParseError_Unexpected_EndOfFile_At_Start_Of_CodeBlock, 8, 1, 5),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, RazorResources.BlockName_Code, "}", "{"),
|
|
SourceLocation.Zero));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockMethodParsesNothingIfFirstCharacterIsNotIdentifierStartOrParenOrBrace()
|
|
{
|
|
ParseBlockTest("@!!!",
|
|
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 ParseBlockShouldReportErrorAndTerminateAtEOFIfIfParenInExplicitExpressionUnclosed()
|
|
{
|
|
ParseBlockTest(@"(foo bar
|
|
baz",
|
|
new ExpressionBlock(
|
|
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
|
|
Factory.Code("foo bar\r\nbaz").AsExpression()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
RazorResources.BlockName_ExplicitExpression, ')', '('),
|
|
new SourceLocation(0, 0, 0)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockShouldReportErrorAndTerminateAtMarkupIfIfParenInExplicitExpressionUnclosed()
|
|
{
|
|
ParseBlockTest(@"(foo bar
|
|
<html>
|
|
baz
|
|
</html",
|
|
new ExpressionBlock(
|
|
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
|
|
Factory.Code("foo bar\r\n").AsExpression()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
RazorResources.BlockName_ExplicitExpression, ')', '('),
|
|
new SourceLocation(0, 0, 0)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockCorrectlyHandlesInCorrectTransitionsIfImplicitExpressionParensUnclosed()
|
|
{
|
|
ParseBlockTest(@"Href(
|
|
<h1>@Html.Foo(Bar);</h1>
|
|
",
|
|
new ExpressionBlock(
|
|
Factory.Code("Href(\r\n")
|
|
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"(", ")"),
|
|
new SourceLocation(4, 0, 4)));
|
|
}
|
|
|
|
[Fact]
|
|
// Test for fix to Dev10 884975 - Incorrect Error Messaging
|
|
public void ParseBlockShouldReportErrorAndTerminateAtEOFIfParenInImplicitExpressionUnclosed()
|
|
{
|
|
ParseBlockTest(@"Foo(Bar(Baz)
|
|
Biz
|
|
Boz",
|
|
new ExpressionBlock(
|
|
Factory.Code("Foo(Bar(Baz)\r\nBiz\r\nBoz")
|
|
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
|
),
|
|
new RazorError(String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"(", ")"),
|
|
new SourceLocation(3, 0, 3)));
|
|
}
|
|
|
|
[Fact]
|
|
// Test for fix to Dev10 884975 - Incorrect Error Messaging
|
|
public void ParseBlockShouldReportErrorAndTerminateAtMarkupIfParenInImplicitExpressionUnclosed()
|
|
{
|
|
ParseBlockTest(@"Foo(Bar(Baz)
|
|
Biz
|
|
<html>
|
|
Boz
|
|
</html>",
|
|
new ExpressionBlock(
|
|
Factory.Code("Foo(Bar(Baz)\r\nBiz\r\n")
|
|
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
|
),
|
|
new RazorError(String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"(", ")"),
|
|
new SourceLocation(3, 0, 3)));
|
|
}
|
|
|
|
[Fact]
|
|
// Test for fix to Dev10 884975 - Incorrect Error Messaging
|
|
public void ParseBlockShouldReportErrorAndTerminateAtEOFIfBracketInImplicitExpressionUnclosed()
|
|
{
|
|
ParseBlockTest(@"Foo[Bar[Baz]
|
|
Biz
|
|
Boz",
|
|
new ExpressionBlock(
|
|
Factory.Code("Foo[Bar[Baz]\r\nBiz\r\nBoz")
|
|
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"[", "]"),
|
|
new SourceLocation(3, 0, 3)));
|
|
}
|
|
|
|
[Fact]
|
|
// Test for fix to Dev10 884975 - Incorrect Error Messaging
|
|
public void ParseBlockShouldReportErrorAndTerminateAtMarkupIfBracketInImplicitExpressionUnclosed()
|
|
{
|
|
ParseBlockTest(@"Foo[Bar[Baz]
|
|
Biz
|
|
<b>
|
|
Boz
|
|
</b>",
|
|
new ExpressionBlock(
|
|
Factory.Code("Foo[Bar[Baz]\r\nBiz\r\n")
|
|
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"[", "]"),
|
|
new SourceLocation(3, 0, 3)));
|
|
}
|
|
|
|
// Simple EOF handling errors:
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfExplicitCodeBlockUnterminatedAtEOF()
|
|
{
|
|
ParseBlockTest("{ var foo = bar; if(foo != null) { bar(); } ",
|
|
new StatementBlock(
|
|
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
|
|
Factory.Code(" var foo = bar; if(foo != null) { bar(); } ").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
RazorResources.BlockName_Code, '}', '{'),
|
|
SourceLocation.Zero));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfClassBlockUnterminatedAtEOF()
|
|
{
|
|
ParseBlockTest("functions { var foo = bar; if(foo != null) { bar(); } ",
|
|
new FunctionsBlock(
|
|
Factory.MetaCode("functions {").Accepts(AcceptedCharacters.None),
|
|
Factory.Code(" var foo = bar; if(foo != null) { bar(); } ").AsFunctionsBody()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
"functions", '}', '{'),
|
|
SourceLocation.Zero));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfIfBlockUnterminatedAtEOF()
|
|
{
|
|
RunUnterminatedSimpleKeywordBlock("if");
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfElseBlockUnterminatedAtEOF()
|
|
{
|
|
ParseBlockTest("if(foo) { baz(); } else { var foo = bar; if(foo != null) { bar(); } ",
|
|
new StatementBlock(
|
|
Factory.Code("if(foo) { baz(); } else { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
"else", '}', '{'),
|
|
new SourceLocation(19, 0, 19)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfElseIfBlockUnterminatedAtEOF()
|
|
{
|
|
ParseBlockTest("if(foo) { baz(); } else if { var foo = bar; if(foo != null) { bar(); } ",
|
|
new StatementBlock(
|
|
Factory.Code("if(foo) { baz(); } else if { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
"else if", '}', '{'),
|
|
new SourceLocation(19, 0, 19)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfDoBlockUnterminatedAtEOF()
|
|
{
|
|
ParseBlockTest("do { var foo = bar; if(foo != null) { bar(); } ",
|
|
new StatementBlock(
|
|
Factory.Code("do { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
"do", '}', '{'),
|
|
SourceLocation.Zero));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfTryBlockUnterminatedAtEOF()
|
|
{
|
|
ParseBlockTest("try { var foo = bar; if(foo != null) { bar(); } ",
|
|
new StatementBlock(
|
|
Factory.Code("try { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
"try", '}', '{'),
|
|
SourceLocation.Zero));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfCatchBlockUnterminatedAtEOF()
|
|
{
|
|
ParseBlockTest("try { baz(); } catch(Foo) { var foo = bar; if(foo != null) { bar(); } ",
|
|
new StatementBlock(
|
|
Factory.Code("try { baz(); } catch(Foo) { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
"catch", '}', '{'),
|
|
new SourceLocation(15, 0, 15)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfFinallyBlockUnterminatedAtEOF()
|
|
{
|
|
ParseBlockTest("try { baz(); } finally { var foo = bar; if(foo != null) { bar(); } ",
|
|
new StatementBlock(
|
|
Factory.Code("try { baz(); } finally { var foo = bar; if(foo != null) { bar(); } ").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
|
|
"finally", '}', '{'),
|
|
new SourceLocation(15, 0, 15)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfForBlockUnterminatedAtEOF()
|
|
{
|
|
RunUnterminatedSimpleKeywordBlock("for");
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfForeachBlockUnterminatedAtEOF()
|
|
{
|
|
RunUnterminatedSimpleKeywordBlock("foreach");
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfWhileBlockUnterminatedAtEOF()
|
|
{
|
|
RunUnterminatedSimpleKeywordBlock("while");
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfSwitchBlockUnterminatedAtEOF()
|
|
{
|
|
RunUnterminatedSimpleKeywordBlock("switch");
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfLockBlockUnterminatedAtEOF()
|
|
{
|
|
RunUnterminatedSimpleKeywordBlock("lock");
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockReportsErrorIfUsingBlockUnterminatedAtEOF()
|
|
{
|
|
RunUnterminatedSimpleKeywordBlock("using");
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockRequiresControlFlowStatementsToHaveBraces()
|
|
{
|
|
string expectedMessage = String.Format(RazorResources.ParseError_SingleLine_ControlFlowStatements_Not_Allowed, "{", "<");
|
|
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.EmptyCSharp().AsStatement()
|
|
),
|
|
new RazorError(expectedMessage, 8, 0, 8),
|
|
new RazorError(expectedMessage, 32, 0, 32),
|
|
new RazorError(expectedMessage, 48, 0, 48));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockIncludesUnexpectedCharacterInSingleStatementControlFlowStatementError()
|
|
{
|
|
ParseBlockTest("if(foo)) { var bar = foo; }",
|
|
new StatementBlock(
|
|
Factory.Code("if(foo)) { var bar = foo; }").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_SingleLine_ControlFlowStatements_Not_Allowed,
|
|
"{", ")"),
|
|
new SourceLocation(7, 0, 7)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockOutputsErrorIfAtSignFollowedByLessThanSignAtStatementStart()
|
|
{
|
|
ParseBlockTest("if(foo) { @<p>Bar</p> }",
|
|
new StatementBlock(
|
|
Factory.Code("if(foo) {").AsStatement(),
|
|
new MarkupBlock(
|
|
Factory.Markup(" "),
|
|
Factory.MarkupTransition(),
|
|
Factory.Markup("<p>Bar</p> ").Accepts(AcceptedCharacters.None)
|
|
),
|
|
Factory.Code("}").AsStatement()
|
|
),
|
|
new RazorError(
|
|
RazorResources.ParseError_AtInCode_Must_Be_Followed_By_Colon_Paren_Or_Identifier_Start,
|
|
10, 0, 10));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockTerminatesIfBlockAtEOLWhenRecoveringFromMissingCloseParen()
|
|
{
|
|
ParseBlockTest(@"if(foo bar
|
|
baz",
|
|
new StatementBlock(
|
|
Factory.Code("if(foo bar\r\n").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"(", ")"),
|
|
new SourceLocation(2, 0, 2)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockTerminatesForeachBlockAtEOLWhenRecoveringFromMissingCloseParen()
|
|
{
|
|
ParseBlockTest(@"foreach(foo bar
|
|
baz",
|
|
new StatementBlock(
|
|
Factory.Code("foreach(foo bar\r\n").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"(", ")"),
|
|
new SourceLocation(7, 0, 7)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockTerminatesWhileClauseInDoStatementAtEOLWhenRecoveringFromMissingCloseParen()
|
|
{
|
|
ParseBlockTest(@"do { } while(foo bar
|
|
baz",
|
|
new StatementBlock(
|
|
Factory.Code("do { } while(foo bar\r\n").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"(", ")"),
|
|
new SourceLocation(12, 0, 12)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockTerminatesUsingBlockAtEOLWhenRecoveringFromMissingCloseParen()
|
|
{
|
|
ParseBlockTest(@"using(foo bar
|
|
baz",
|
|
new StatementBlock(
|
|
Factory.Code("using(foo bar\r\n").AsStatement()
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"(", ")"),
|
|
new SourceLocation(5, 0, 5)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockResumesIfStatementAfterOpenParen()
|
|
{
|
|
ParseBlockTest(@"if(
|
|
else { <p>Foo</p> }",
|
|
new StatementBlock(
|
|
Factory.Code("if(\r\nelse {").AsStatement(),
|
|
new MarkupBlock(
|
|
Factory.Markup(" <p>Foo</p> ").Accepts(AcceptedCharacters.None)
|
|
),
|
|
Factory.Code("}").AsStatement().Accepts(AcceptedCharacters.None)
|
|
),
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF,
|
|
"(", ")"),
|
|
new SourceLocation(2, 0, 2)));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockTerminatesNormalCSharpStringsAtEOLIfEndQuoteMissing()
|
|
{
|
|
SingleSpanBlockTest(@"if(foo) {
|
|
var p = ""foo bar baz
|
|
;
|
|
}",
|
|
BlockType.Statement, SpanKind.Code,
|
|
new RazorError(RazorResources.ParseError_Unterminated_String_Literal, 23, 1, 12));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockTerminatesNormalStringAtEndOfFile()
|
|
{
|
|
SingleSpanBlockTest("if(foo) { var foo = \"blah blah blah blah blah", BlockType.Statement, SpanKind.Code,
|
|
new RazorError(RazorResources.ParseError_Unterminated_String_Literal, 20, 0, 20),
|
|
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, "if", '}', '{'), SourceLocation.Zero));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockTerminatesVerbatimStringAtEndOfFile()
|
|
{
|
|
SingleSpanBlockTest(@"if(foo) { var foo = @""blah
|
|
blah;
|
|
<p>Foo</p>
|
|
blah
|
|
blah",
|
|
BlockType.Statement, SpanKind.Code,
|
|
new RazorError(RazorResources.ParseError_Unterminated_String_Literal, 20, 0, 20),
|
|
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, "if", '}', '{'), SourceLocation.Zero));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockCorrectlyParsesMarkupIncorrectyAssumedToBeWithinAStatement()
|
|
{
|
|
ParseBlockTest(@"if(foo) {
|
|
var foo = ""foo bar baz
|
|
<p>Foo is @foo</p>
|
|
}",
|
|
new StatementBlock(
|
|
Factory.Code("if(foo) {\r\n var foo = \"foo bar baz\r\n ").AsStatement(),
|
|
new MarkupBlock(
|
|
Factory.Markup("<p>Foo is "),
|
|
new ExpressionBlock(
|
|
Factory.CodeTransition(),
|
|
Factory.Code("foo")
|
|
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
|
|
.Accepts(AcceptedCharacters.NonWhiteSpace)),
|
|
Factory.Markup("</p>\r\n").Accepts(AcceptedCharacters.None)),
|
|
Factory.Code("}").AsStatement()
|
|
),
|
|
new RazorError(
|
|
RazorResources.ParseError_Unterminated_String_Literal,
|
|
25, 1, 14));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockCorrectlyParsesAtSignInDelimitedBlock()
|
|
{
|
|
ParseBlockTest("(Request[\"description\"] ?? @photo.Description)",
|
|
new ExpressionBlock(
|
|
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
|
|
Factory.Code("Request[\"description\"] ?? @photo.Description").AsExpression(),
|
|
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
|
|
));
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseBlockCorrectlyRecoversFromMissingCloseParenInExpressionWithinCode()
|
|
{
|
|
ParseBlockTest(@"{String.Format(<html></html>}",
|
|
new StatementBlock(
|
|
Factory.MetaCode("{").Accepts(AcceptedCharacters.None),
|
|
Factory.Code("String.Format(")
|
|
.AsStatement(),
|
|
new MarkupBlock(
|
|
Factory.Markup("<html></html>").Accepts(AcceptedCharacters.None)),
|
|
Factory.EmptyCSharp().AsStatement(),
|
|
Factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
|
|
expectedErrors: new [] {
|
|
new RazorError(
|
|
String.Format(RazorResources.ParseError_Expected_CloseBracket_Before_EOF, "(", ")"),
|
|
14, 0, 14)
|
|
});
|
|
|
|
}
|
|
|
|
private void RunUnterminatedSimpleKeywordBlock(string keyword)
|
|
{
|
|
SingleSpanBlockTest(keyword + " (foo) { var foo = bar; if(foo != null) { bar(); } ", BlockType.Statement, SpanKind.Code,
|
|
new RazorError(String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, keyword, '}', '{'), SourceLocation.Zero));
|
|
}
|
|
}
|
|
}
|