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,155 @@
// 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.VB
{
public class VBAutoCompleteTest : VBHtmlCodeParserTestBase
{
[Fact]
public void FunctionsDirective_AutoComplete_At_EOF()
{
ParseBlockTest("@Functions",
new FunctionsBlock(
Factory.CodeTransition("@")
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("Functions")
.Accepts(AcceptedCharacters.None),
Factory.EmptyVB()
.AsFunctionsBody()
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString)
{
AutoCompleteString = SyntaxConstants.VB.EndFunctionsKeyword
})),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Functions", "End Functions"),
1, 0, 1));
}
[Fact]
public void HelperDirective_AutoComplete_At_EOF()
{
ParseBlockTest("@Helper Strong(value As String)",
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Strong(value As String)", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("Helper ")
.Accepts(AcceptedCharacters.None),
Factory.Code("Strong(value As String)")
.Hidden()
.Accepts(AcceptedCharacters.None)
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = SyntaxConstants.VB.EndHelperKeyword }),
new StatementBlock()),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Helper", "End Helper"),
1, 0, 1));
}
[Fact]
public void SectionDirective_AutoComplete_At_EOF()
{
ParseBlockTest("@Section Header",
new SectionBlock(new SectionCodeGenerator("Header"),
Factory.CodeTransition(),
Factory.MetaCode("Section Header")
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = SyntaxConstants.VB.EndSectionKeyword }),
new MarkupBlock()),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Section", "End Section"),
1, 0, 1));
}
[Fact]
public void VerbatimBlock_AutoComplete_At_EOF()
{
ParseBlockTest("@Code",
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Code, new VBSymbol(5, 0, 5, String.Empty, VBSymbolType.Unknown))
.With(new StatementCodeGenerator())
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = SyntaxConstants.VB.EndCodeKeyword })),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Code", "End Code"),
1, 0, 1));
}
[Fact]
public void FunctionsDirective_AutoComplete_At_StartOfFile()
{
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 = SyntaxConstants.VB.EndFunctionsKeyword
})),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Functions", "End Functions"),
1, 0, 1));
}
[Fact]
public void HelperDirective_AutoComplete_At_StartOfFile()
{
ParseBlockTest(@"@Helper Strong(value As String)
Foo",
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Strong(value As String)", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("Helper ")
.Accepts(AcceptedCharacters.None),
Factory.Code("Strong(value As String)")
.Hidden()
.Accepts(AcceptedCharacters.None)
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = SyntaxConstants.VB.EndHelperKeyword }),
new StatementBlock(
Factory.Code("\r\nFoo").AsStatement())),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Helper", "End Helper"),
1, 0, 1));
}
[Fact]
public void SectionDirective_AutoComplete_At_StartOfFile()
{
ParseBlockTest(@"@Section Header
Foo",
new SectionBlock(new SectionCodeGenerator("Header"),
Factory.CodeTransition(),
Factory.MetaCode("Section Header")
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = SyntaxConstants.VB.EndSectionKeyword }),
new MarkupBlock(
Factory.Markup("\r\nFoo")
.With(new MarkupCodeGenerator()))),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Section", "End Section"),
1, 0, 1));
}
[Fact]
public void VerbatimBlock_AutoComplete_At_StartOfFile()
{
ParseBlockTest(@"@Code
Foo",
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\nFoo")
.AsStatement()
.With(new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = SyntaxConstants.VB.EndCodeKeyword })),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Code", "End Code"),
1, 0, 1));
}
}
}

View File

@ -0,0 +1,374 @@
// 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;
using Xunit.Extensions;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Razor.Test.Parser.VB
{
public class VBBlockTest : VBHtmlCodeParserTestBase
{
[Fact]
public void ParseBlockMethodThrowsArgNullExceptionOnNullContext()
{
// Arrange
VBCodeParser parser = new VBCodeParser();
// Act and Assert
Assert.Throws<InvalidOperationException>(() => parser.ParseBlock(), RazorResources.Parser_Context_Not_Set);
}
[Fact]
public void ParseBlockAcceptsImplicitExpression()
{
ParseBlockTest(@"If True Then
@foo
End If",
new StatementBlock(
Factory.Code("If True Then\r\n ").AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo")
.AsImplicitExpression(VBCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Code("\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockAcceptsIfStatementWithinCodeBlockIfInDesignTimeMode()
{
ParseBlockTest(@"If True Then
@If True Then
End If
End If",
new StatementBlock(
Factory.Code("If True Then\r\n ").AsStatement(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If True Then\r\n End If\r\n")
.AsStatement()
.Accepts(AcceptedCharacters.None)),
Factory.Code(@"End If")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockSupportsSpacesInStrings()
{
ParseBlockTest(@"for each p in db.Query(""SELECT * FROM PRODUCTS"")
@<p>@p.Name</p>
next",
new StatementBlock(
Factory.Code("for each p in db.Query(\"SELECT * FROM PRODUCTS\")\r\n")
.AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.Markup("<p>"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("p.Name")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Markup("</p>\r\n").Accepts(AcceptedCharacters.None)),
Factory.Code("next")
.AsStatement()
.Accepts(AcceptedCharacters.WhiteSpace | AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void ParseBlockSupportsSimpleCodeBlock()
{
ParseBlockTest(@"Code
If foo IsNot Nothing
Bar(foo)
End If
End Code",
new StatementBlock(
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n If foo IsNot Nothing\r\n Bar(foo)\r\n End If\r\n")
.AsStatement(),
Factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockRejectsNewlineBetweenEndAndCodeIfNotPrefixedWithUnderscore()
{
ParseBlockTest(@"Code
If foo IsNot Nothing
Bar(foo)
End If
End
Code",
new StatementBlock(
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n If foo IsNot Nothing\r\n Bar(foo)\r\n End If\r\nEnd\r\nCode")
.AsStatement()),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Code", "End Code"),
SourceLocation.Zero));
}
[Fact]
public void ParseBlockAcceptsNewlineBetweenEndAndCodeIfPrefixedWithUnderscore()
{
ParseBlockTest(@"Code
If foo IsNot Nothing
Bar(foo)
End If
End _
_
_
Code",
new StatementBlock(
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n If foo IsNot Nothing\r\n Bar(foo)\r\n End If\r\n")
.AsStatement(),
Factory.MetaCode("End _\r\n_\r\n _\r\nCode").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockSupportsSimpleFunctionsBlock()
{
ParseBlockTest(@"Functions
Public Sub Foo()
Bar()
End Sub
Private Function Bar() As Object
Return Nothing
End Function
End Functions",
new FunctionsBlock(
Factory.MetaCode("Functions").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n Public Sub Foo()\r\n Bar()\r\n End Sub\r\n\r\n Private Function Bar() As Object\r\n Return Nothing\r\n End Function\r\n")
.AsFunctionsBody(),
Factory.MetaCode("End Functions").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockRejectsNewlineBetweenEndAndFunctionsIfNotPrefixedWithUnderscore()
{
ParseBlockTest(@"Functions
If foo IsNot Nothing
Bar(foo)
End If
End
Functions",
new FunctionsBlock(
Factory.MetaCode("Functions").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n If foo IsNot Nothing\r\n Bar(foo)\r\n End If\r\nEnd\r\nFunctions")
.AsFunctionsBody()),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Functions", "End Functions"),
SourceLocation.Zero));
}
[Fact]
public void ParseBlockAcceptsNewlineBetweenEndAndFunctionsIfPrefixedWithUnderscore()
{
ParseBlockTest(@"Functions
If foo IsNot Nothing
Bar(foo)
End If
End _
_
_
Functions",
new FunctionsBlock(
Factory.MetaCode("Functions").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n If foo IsNot Nothing\r\n Bar(foo)\r\n End If\r\n")
.AsFunctionsBody(),
Factory.MetaCode("End _\r\n_\r\n _\r\nFunctions").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockCorrectlyHandlesExtraEndsInEndCode()
{
ParseBlockTest(@"Code
Bar End
End Code",
new StatementBlock(
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n Bar End\r\n").AsStatement(),
Factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockCorrectlyHandlesExtraEndsInEndFunctions()
{
ParseBlockTest(@"Functions
Bar End
End Functions",
new FunctionsBlock(
Factory.MetaCode("Functions").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n Bar End\r\n").AsFunctionsBody().AutoCompleteWith(null, atEndOfSpan: false),
Factory.MetaCode("End Functions").Accepts(AcceptedCharacters.None)));
}
[Theory]
[InlineData("If", "End", "If")]
[InlineData("Try", "End", "Try")]
[InlineData("While", "End", "While")]
[InlineData("Using", "End", "Using")]
[InlineData("With", "End", "With")]
public void KeywordAllowsNewlinesIfPrefixedByUnderscore(string startKeyword, string endKeyword1, string endKeyword2)
{
string code = startKeyword + @"
' In the block
" + endKeyword1 + @" _
_
_
_
_
_
" + endKeyword2 + @"
";
ParseBlockTest(code + "foo bar baz",
new StatementBlock(
Factory.Code(code)
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Theory]
[InlineData("While", "EndWhile", "End While")]
[InlineData("If", "EndIf", "End If")]
[InlineData("Select", "EndSelect", "End Select")]
[InlineData("Try", "EndTry", "End Try")]
[InlineData("With", "EndWith", "End With")]
[InlineData("Using", "EndUsing", "End Using")]
public void EndTerminatedKeywordRequiresSpaceBetweenEndAndKeyword(string startKeyword, string wrongEndKeyword, string endKeyword)
{
string code = startKeyword + @"
' This should not end the code
" + wrongEndKeyword + @"
' But this should
" + endKeyword;
ParseBlockTest(code,
new StatementBlock(
Factory.Code(code)
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Theory]
[InlineData("While", "End While", false)]
[InlineData("Do", "Loop", true)]
[InlineData("If", "End If", false)]
[InlineData("Select", "End Select", false)]
[InlineData("For", "Next", true)]
[InlineData("Try", "End Try", false)]
[InlineData("With", "End With", false)]
[InlineData("Using", "End Using", false)]
public void EndSequenceInString(string keyword, string endSequence, bool acceptToEndOfLine)
{
string code = keyword + @"
""" + endSequence + @"""
" + endSequence + (acceptToEndOfLine ? @" foo bar baz" : "") + @"
";
ParseBlockTest(code + "biz boz",
new StatementBlock(
Factory.Code(code).AsStatement().Accepts(GetAcceptedCharacters(acceptToEndOfLine))));
}
[Theory]
[InlineData("While", "End While", false)]
[InlineData("Do", "Loop", true)]
[InlineData("If", "End If", false)]
[InlineData("Select", "End Select", false)]
[InlineData("For", "Next", true)]
[InlineData("Try", "End Try", false)]
[InlineData("With", "End With", false)]
[InlineData("Using", "End Using", false)]
private void CommentedEndSequence(string keyword, string endSequence, bool acceptToEndOfLine)
{
string code = keyword + @"
'" + endSequence + @"
" + endSequence + (acceptToEndOfLine ? @" foo bar baz" : "") + @"
";
ParseBlockTest(code + "biz boz",
new StatementBlock(
Factory.Code(code).AsStatement().Accepts(GetAcceptedCharacters(acceptToEndOfLine))));
}
[Theory]
[InlineData("While", "End While", false)]
[InlineData("Do", "Loop", true)]
[InlineData("If", "End If", false)]
[InlineData("Select", "End Select", false)]
[InlineData("For", "Next", true)]
[InlineData("Try", "End Try", false)]
[InlineData("With", "End With", false)]
[InlineData("SyncLock", "End SyncLock", false)]
[InlineData("Using", "End Using", false)]
private void NestedKeywordBlock(string keyword, string endSequence, bool acceptToEndOfLine)
{
string code = keyword + @"
" + keyword + @"
Bar(foo)
" + endSequence + @"
" + endSequence + (acceptToEndOfLine ? @" foo bar baz" : "") + @"
";
ParseBlockTest(code + "biz boz",
new StatementBlock(
Factory.Code(code).AsStatement().Accepts(GetAcceptedCharacters(acceptToEndOfLine))));
}
[Theory]
[InlineData("While True", "End While", false)]
[InlineData("Do", "Loop", true)]
[InlineData("If foo IsNot Nothing", "End If", false)]
[InlineData("Select Case foo", "End Select", false)]
[InlineData("For Each p in Products", "Next", true)]
[InlineData("Try", "End Try", false)]
[InlineData("With", "End With", false)]
[InlineData("SyncLock", "End SyncLock", false)]
[InlineData("Using", "End Using", false)]
private void SimpleKeywordBlock(string keyword, string endSequence, bool acceptToEndOfLine)
{
string code = keyword + @"
Bar(foo)
" + endSequence + (acceptToEndOfLine ? @" foo bar baz" : "") + @"
";
ParseBlockTest(code + "biz boz",
new StatementBlock(
Factory.Code(code).AsStatement().Accepts(GetAcceptedCharacters(acceptToEndOfLine))));
}
[Theory]
[InlineData("While True", "Exit While", "End While", false)]
[InlineData("Do", "Exit Do", "Loop", true)]
[InlineData("For Each p in Products", "Exit For", "Next", true)]
[InlineData("While True", "Continue While", "End While", false)]
[InlineData("Do", "Continue Do", "Loop", true)]
[InlineData("For Each p in Products", "Continue For", "Next", true)]
private void KeywordWithExitOrContinue(string startKeyword, string exitKeyword, string endKeyword, bool acceptToEndOfLine)
{
string code = startKeyword + @"
' This is before the exit
" + exitKeyword + @"
' This is after the exit
" + endKeyword + @"
";
ParseBlockTest(code + "foo bar baz",
new StatementBlock(
Factory.Code(code).AsStatement().Accepts(GetAcceptedCharacters(acceptToEndOfLine))));
}
private AcceptedCharacters GetAcceptedCharacters(bool acceptToEndOfLine)
{
return acceptToEndOfLine ?
AcceptedCharacters.WhiteSpace | AcceptedCharacters.NonWhiteSpace :
AcceptedCharacters.None;
}
}
}

View File

@ -0,0 +1,58 @@
// 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.Test.Framework;
using Xunit;
namespace System.Web.Razor.Test.Parser.VB
{
// VB Continue Statement: http://msdn.microsoft.com/en-us/library/801hyx6f.aspx
public class VBContinueStatementTest : VBHtmlCodeParserTestBase
{
[Fact]
public void VB_Do_Statement_With_Continue()
{
ParseBlockTest(@"@Do While True
Continue Do
Loop
' Not in the block!",
new StatementBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.Code("Do While True\r\n Continue Do\r\nLoop\r\n")
.AsStatement()
.Accepts(AcceptedCharacters.AnyExceptNewline)));
}
[Fact]
public void VB_For_Statement_With_Continue()
{
ParseBlockTest(@"@For i = 1 To 12
Continue For
Next i
' Not in the block!",
new StatementBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.Code("For i = 1 To 12\r\n Continue For\r\nNext i\r\n")
.AsStatement()
.Accepts(AcceptedCharacters.AnyExceptNewline)));
}
[Fact]
public void VB_While_Statement_With_Continue()
{
ParseBlockTest(@"@While True
Continue While
End While
' Not in the block!",
new StatementBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.Code("While True\r\n Continue While\r\nEnd While\r\n")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
}
}

View File

@ -0,0 +1,129 @@
// 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.VB
{
public class VBDirectiveTest : VBHtmlCodeParserTestBase
{
[Fact]
public void VB_Code_Directive()
{
ParseBlockTest(@"@Code
foo()
End Code
' Not part of the block",
new StatementBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("Code")
.Accepts(AcceptedCharacters.None),
Factory.Code("\r\n foo()\r\n")
.AsStatement()
.With(new AutoCompleteEditHandler(VBLanguageCharacteristics.Instance.TokenizeString)),
Factory.MetaCode("End Code")
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_Functions_Directive()
{
ParseBlockTest(@"@Functions
Public Function Foo() As String
Return ""Foo""
End Function
Public Sub Bar()
End Sub
End Functions
' Not part of the block",
new FunctionsBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("Functions")
.Accepts(AcceptedCharacters.None),
Factory.Code("\r\n Public Function Foo() As String\r\n Return \"Foo\"\r\n End Function\r\n\r\n Public Sub Bar()\r\n End Sub\r\n")
.AsFunctionsBody(),
Factory.MetaCode("End Functions")
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_Section_Directive()
{
ParseBlockTest(@"@Section Header
<p>Foo</p>
End Section",
new SectionBlock(new SectionCodeGenerator("Header"),
Factory.CodeTransition(SyntaxConstants.TransitionString),
Factory.MetaCode(@"Section Header"),
new MarkupBlock(
Factory.Markup("\r\n <p>Foo</p>\r\n")),
Factory.MetaCode("End Section")
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void SessionStateDirectiveWorks()
{
ParseBlockTest(@"@SessionState InProc
",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("SessionState ")
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("InProc\r\n")
.Accepts(AcceptedCharacters.None)
.With(new RazorDirectiveAttributeCodeGenerator("SessionState", "InProc"))
)
);
}
[Fact]
public void SessionStateDirectiveIsCaseInsensitive()
{
ParseBlockTest(@"@sessionstate disabled
",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("sessionstate ")
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("disabled\r\n")
.Accepts(AcceptedCharacters.None)
.With(new RazorDirectiveAttributeCodeGenerator("SessionState", "disabled"))
)
);
}
[Fact]
public void VB_Helper_Directive()
{
ParseBlockTest(@"@Helper Strong(s as String)
s = s.ToUpperCase()
@<strong>s</strong>
End Helper",
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Strong(s as String)", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(SyntaxConstants.TransitionString),
Factory.MetaCode("Helper ")
.Accepts(AcceptedCharacters.None),
Factory.Code("Strong(s as String)").Hidden(),
new StatementBlock(
Factory.Code("\r\n s = s.ToUpperCase()\r\n")
.AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(SyntaxConstants.TransitionString),
Factory.Markup("<strong>s</strong>\r\n")
.Accepts(AcceptedCharacters.None)),
Factory.EmptyVB()
.AsStatement(),
Factory.MetaCode("End Helper")
.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.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 Xunit;
using Xunit.Extensions;
namespace System.Web.Razor.Test.Parser.VB
{
public class VBErrorTest : VBHtmlCodeParserTestBase
{
[Fact]
public void ParserOutputsErrorAndRecoversToEndOfLineIfExplicitExpressionUnterminated()
{
ParseBlockTest(@"(foo
bar",
new ExpressionBlock(
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("foo").AsExpression()),
new RazorError(
String.Format(
RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
RazorResources.BlockName_ExplicitExpression,
")", "("),
SourceLocation.Zero));
}
[Fact]
public void ParserOutputsZeroLengthCodeSpanIfEofReachedAfterStartOfExplicitExpression()
{
ParseBlockTest("(",
new ExpressionBlock(
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.EmptyVB().AsExpression()),
new RazorError(
String.Format(RazorResources.ParseError_Expected_EndOfBlock_Before_EOF, "explicit expression", ")", "("),
SourceLocation.Zero));
}
[Fact]
public void ParserOutputsZeroLengthCodeSpanIfEofReachedAfterAtSign()
{
ParseBlockTest(String.Empty,
new ExpressionBlock(
Factory.EmptyVB().AsImplicitExpression(KeywordSet).Accepts(AcceptedCharacters.NonWhiteSpace)),
new RazorError(
RazorResources.ParseError_Unexpected_EndOfFile_At_Start_Of_CodeBlock,
SourceLocation.Zero));
}
[Fact]
public void ParserOutputsZeroLengthCodeSpanIfOnlyWhitespaceFoundAfterAtSign()
{
ParseBlockTest(" ",
new ExpressionBlock(
Factory.EmptyVB().AsImplicitExpression(KeywordSet).Accepts(AcceptedCharacters.NonWhiteSpace)),
new RazorError(
RazorResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_VB,
SourceLocation.Zero));
}
[Fact]
public void ParserOutputsZeroLengthCodeSpanIfInvalidCharacterFoundAfterAtSign()
{
ParseBlockTest("!!!",
new ExpressionBlock(
Factory.EmptyVB().AsImplicitExpression(KeywordSet).Accepts(AcceptedCharacters.NonWhiteSpace)),
new RazorError(
String.Format(RazorResources.ParseError_Unexpected_Character_At_Start_Of_CodeBlock_VB, "!"),
SourceLocation.Zero));
}
[Theory]
[InlineData("Code", "End Code", true, true)]
[InlineData("Do", "Loop", false, false)]
[InlineData("While", "End While", false, false)]
[InlineData("If", "End If", false, false)]
[InlineData("Select Case", "End Select", false, false)]
[InlineData("For", "Next", false, false)]
[InlineData("Try", "End Try", false, false)]
[InlineData("With", "End With", false, false)]
[InlineData("Using", "End Using", false, false)]
public void EofBlock(string keyword, string expectedTerminator, bool autoComplete, bool keywordIsMetaCode)
{
EofBlockCore(keyword, expectedTerminator, autoComplete, BlockType.Statement, keywordIsMetaCode, c => c.AsStatement());
}
[Fact]
public void EofFunctionsBlock()
{
EofBlockCore("Functions", "End Functions", true, BlockType.Functions, true, c => c.AsFunctionsBody());
}
private void EofBlockCore(string keyword, string expectedTerminator, bool autoComplete, BlockType blockType, bool keywordIsMetaCode, Func<UnclassifiedCodeSpanConstructor, SpanConstructor> classifier)
{
BlockBuilder expected = new BlockBuilder();
expected.Type = blockType;
if (keywordIsMetaCode)
{
expected.Children.Add(Factory.MetaCode(keyword).Accepts(AcceptedCharacters.None));
expected.Children.Add(
classifier(Factory.EmptyVB())
.With((SpanEditHandler)(
autoComplete ?
new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = expectedTerminator } :
SpanEditHandler.CreateDefault())));
}
else
{
expected.Children.Add(
classifier(Factory.Code(keyword))
.With((SpanEditHandler)(
autoComplete ?
new AutoCompleteEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString) { AutoCompleteString = expectedTerminator } :
SpanEditHandler.CreateDefault())));
}
ParseBlockTest(keyword,
expected.Build(),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, keyword, expectedTerminator),
SourceLocation.Zero));
}
[Theory]
[InlineData("Code", "End Code", true)]
[InlineData("Do", "Loop", false)]
[InlineData("While", "End While", false)]
[InlineData("If", "End If", false)]
[InlineData("Select Case", "End Select", false)]
[InlineData("For", "Next", false)]
[InlineData("Try", "End Try", false)]
[InlineData("With", "End With", false)]
[InlineData("Using", "End Using", false)]
public void UnterminatedBlock(string keyword, string expectedTerminator, bool keywordIsMetaCode)
{
UnterminatedBlockCore(keyword, expectedTerminator, BlockType.Statement, keywordIsMetaCode, c => c.AsStatement());
}
[Fact]
public void UnterminatedFunctionsBlock()
{
UnterminatedBlockCore("Functions", "End Functions", BlockType.Functions, true, c => c.AsFunctionsBody());
}
private void UnterminatedBlockCore(string keyword, string expectedTerminator, BlockType blockType, bool keywordIsMetaCode, Func<UnclassifiedCodeSpanConstructor, SpanConstructor> classifier)
{
const string blockBody = @"
' This block is not correctly terminated!";
BlockBuilder expected = new BlockBuilder();
expected.Type = blockType;
if (keywordIsMetaCode)
{
expected.Children.Add(Factory.MetaCode(keyword).Accepts(AcceptedCharacters.None));
expected.Children.Add(classifier(Factory.Code(blockBody)));
}
else
{
expected.Children.Add(classifier(Factory.Code(keyword + blockBody)));
}
ParseBlockTest(keyword + blockBody,
expected.Build(),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, keyword, expectedTerminator),
SourceLocation.Zero));
}
}
}

View File

@ -0,0 +1,96 @@
// 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.Test.Framework;
using Xunit;
namespace System.Web.Razor.Test.Parser.VB
{
// VB Exit Statement: http://msdn.microsoft.com/en-us/library/t2at9t47.aspx
public class VBExitStatementTest : VBHtmlCodeParserTestBase
{
[Fact]
public void VB_Do_Statement_With_Exit()
{
ParseBlockTest(@"@Do While True
Exit Do
Loop
' Not in the block!",
new StatementBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.Code("Do While True\r\n Exit Do\r\nLoop\r\n")
.AsStatement()
.Accepts(AcceptedCharacters.AnyExceptNewline)));
}
[Fact]
public void VB_For_Statement_With_Exit()
{
ParseBlockTest(@"@For i = 1 To 12
Exit For
Next i
' Not in the block!",
new StatementBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.Code("For i = 1 To 12\r\n Exit For\r\nNext i\r\n")
.AsStatement()
.Accepts(AcceptedCharacters.AnyExceptNewline)));
}
[Fact]
public void VB_Select_Statement_With_Exit()
{
ParseBlockTest(@"@Select Case Foo
Case 1
Exit Select
Case 2
Exit Select
End Select
' Not in the block!",
new StatementBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.Code("Select Case Foo\r\n Case 1\r\n Exit Select\r\n Case 2\r\n Exit Select\r\nEnd Select\r\n")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_Try_Statement_With_Exit()
{
ParseBlockTest(@"@Try
Foo()
Exit Try
Catch Bar
Throw Bar
Finally
Baz()
End Try
' Not in the block!",
new StatementBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.Code("Try\r\n Foo()\r\n Exit Try\r\nCatch Bar\r\n Throw Bar\r\nFinally\r\n Baz()\r\nEnd Try\r\n")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_While_Statement_With_Exit()
{
ParseBlockTest(@"@While True
Exit While
End While
' Not in the block!",
new StatementBlock(
Factory.CodeTransition(SyntaxConstants.TransitionString)
.Accepts(AcceptedCharacters.None),
Factory.Code("While True\r\n Exit While\r\nEnd While\r\n")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
}
}

View File

@ -0,0 +1,22 @@
// 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 Xunit;
namespace System.Web.Razor.Test.Parser.VB
{
public class VBExplicitExpressionTest : VBHtmlCodeParserTestBase
{
[Fact]
public void VB_Simple_ExplicitExpression()
{
ParseBlockTest("@(foo)",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("foo").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)));
}
}
}

View File

@ -0,0 +1,111 @@
// 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;
using Xunit.Extensions;
namespace System.Web.Razor.Test.Parser.VB
{
public class VBExpressionTest : VBHtmlCodeParserTestBase
{
[Fact]
public void ParseBlockCorrectlyHandlesCodeBlockInBodyOfExplicitExpressionDueToUnclosedExpression()
{
ParseBlockTest(@"(
@Code
Dim foo = bar
End Code",
new ExpressionBlock(
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.EmptyVB().AsExpression()),
new RazorError(
String.Format(
RazorResources.ParseError_Expected_EndOfBlock_Before_EOF,
RazorResources.BlockName_ExplicitExpression,
")", "("),
SourceLocation.Zero));
}
[Fact]
public void ParseBlockAcceptsNonEnglishCharactersThatAreValidIdentifiers()
{
ImplicitExpressionTest("हळूँजद॔.", "हळूँजद॔");
}
[Fact]
public void ParseBlockDoesNotTreatXmlAxisPropertyAsTransitionToMarkup()
{
SingleSpanBlockTest(
@"If foo Is Nothing Then
Dim bar As XElement
Dim foo = bar.<foo>
End If",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockDoesNotTreatXmlAttributePropertyAsTransitionToMarkup()
{
SingleSpanBlockTest(
@"If foo Is Nothing Then
Dim bar As XElement
Dim foo = bar.@foo
End If",
BlockType.Statement,
SpanKind.Code,
acceptedCharacters: AcceptedCharacters.None);
}
[Fact]
public void ParseBlockSupportsSimpleImplicitExpression()
{
ImplicitExpressionTest("Foo");
}
[Fact]
public void ParseBlockSupportsImplicitExpressionWithDots()
{
ImplicitExpressionTest("Foo.Bar.Baz");
}
[Fact]
public void ParseBlockSupportsImplicitExpressionWithParens()
{
ImplicitExpressionTest("Foo().Bar().Baz()");
}
[Fact]
public void ParseBlockSupportsImplicitExpressionWithStuffInParens()
{
ImplicitExpressionTest("Foo().Bar(sdfkhj sdfksdfjs \")\" sjdfkjsdf).Baz()");
}
[Fact]
public void ParseBlockSupportsImplicitExpressionWithCommentInParens()
{
ImplicitExpressionTest("Foo().Bar(sdfkhj sdfksdfjs \")\" '))))))))\r\nsjdfkjsdf).Baz()");
}
[Theory]
[InlineData("Foo")]
[InlineData("Foo(Of String).Bar(1, 2, 3).Biz")]
[InlineData("Foo(Of String).Bar(\")\").Biz")]
[InlineData("Foo(Of String).Bar(\"Foo\"\"Bar)\"\"Baz\").Biz")]
[InlineData("\"foo\r\nbar")]
[InlineData("Foo.Bar. _\r\nREM )\r\nBaz()\r\n")]
[InlineData("Foo.Bar. _\r\n' )\r\nBaz()\r\n")]
public void ValidExplicitExpressions(string body)
{
ParseBlockTest("(" + body + ")",
new ExpressionBlock(
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code(body).AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)));
}
}
}

View File

@ -0,0 +1,121 @@
// 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 Xunit;
using Xunit.Extensions;
namespace System.Web.Razor.Test.Parser.VB
{
public class VBExpressionsInCodeTest : VBHtmlCodeParserTestBase
{
[Fact]
public void InnerImplicitExpressionWithOnlySingleAtAcceptsSingleSpaceOrNewlineAtDesignTime()
{
ParseBlockTest(@"Code
@
End Code",
new StatementBlock(
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n ").AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.EmptyVB()
.AsImplicitExpression(VBCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Code("\r\n").AsStatement(),
Factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)),
designTimeParser: true,
expectedErrors: new[]
{
new RazorError(RazorResources.ParseError_Unexpected_WhiteSpace_At_Start_Of_CodeBlock_VB, 11, 1, 5)
});
}
[Fact]
public void InnerImplicitExpressionDoesNotAcceptDotAfterAt()
{
ParseBlockTest(@"Code
@.
End Code",
new StatementBlock(
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n ").AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.EmptyVB()
.AsImplicitExpression(VBCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Code(".\r\n").AsStatement(),
Factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)),
designTimeParser: true,
expectedErrors: new[]
{
new RazorError(
String.Format(RazorResources.ParseError_Unexpected_Character_At_Start_Of_CodeBlock_VB, "."),
11, 1, 5)
});
}
[Theory]
[InlineData("Foo.Bar.", true)]
[InlineData("Foo", true)]
[InlineData("Foo.Bar.Baz", true)]
[InlineData("Foo().Bar().Baz()", true)]
[InlineData("Foo().Bar(sdfkhj sdfksdfjs \")\" sjdfkjsdf).Baz()", true)]
[InlineData("Foo().Bar(sdfkhj sdfksdfjs \")\" '))))))))\r\nsjdfkjsdf).Baz()", true)]
[InlineData("Foo", false)]
[InlineData("Foo(Of String).Bar(1, 2, 3).Biz", false)]
[InlineData("Foo(Of String).Bar(\")\").Biz", false)]
[InlineData("Foo(Of String).Bar(\"Foo\"\"Bar)\"\"Baz\").Biz", false)]
[InlineData("Foo.Bar. _\r\nREM )\r\nBaz()\r\n", false)]
[InlineData("Foo.Bar. _\r\n' )\r\nBaz()\r\n", false)]
public void ExpressionInCode(string expression, bool isImplicit)
{
ExpressionBlock expressionBlock;
if (isImplicit)
{
expressionBlock =
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code(expression)
.AsImplicitExpression(VBCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace));
}
else
{
expressionBlock =
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code(expression).AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None));
}
string code;
if (isImplicit)
{
code = @"If foo IsNot Nothing Then
@" + expression + @"
End If";
}
else
{
code = @"If foo IsNot Nothing Then
@(" + expression + @")
End If";
}
ParseBlockTest(code,
new StatementBlock(
Factory.Code("If foo IsNot Nothing Then\r\n ")
.AsStatement(),
expressionBlock,
Factory.Code("\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
}
}

View File

@ -0,0 +1,324 @@
// 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.VB
{
public class VBHelperTest : VBHtmlMarkupParserTestBase
{
[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().AutoCompleteWith(SyntaxConstants.VB.EndHelperKeyword),
new StatementBlock())),
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_BlockNotTerminated, "Helper", "End 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.EmptyVB().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"))),
new RazorError(
String.Format(RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start, RazorResources.ErrorComponent_EndOfFile),
7, 0, 7));
}
[Fact]
public void ParseHelperStatementTerminatesEarlyIfHeaderNotComplete()
{
ParseDocumentTest(@"@Helper
@Helper",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(
Factory.CodeTransition(),
Factory.MetaCode("Helper\r\n").Accepts(AcceptedCharacters.None),
Factory.EmptyVB().Hidden()),
new HelperBlock(
Factory.CodeTransition(),
Factory.MetaCode("Helper"))),
designTimeParser: true,
expectedErrors: new[]
{
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start,
String.Format(RazorResources.ErrorComponent_Character, "@")),
9, 1, 0),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Helper_Name_Start,
RazorResources.ErrorComponent_EndOfFile),
16, 1, 7)
});
}
[Fact]
public void ParseHelperStatementTerminatesEarlyIfHeaderNotCompleteWithSpace()
{
ParseDocumentTest(@"@Helper @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.EmptyVB().Hidden()),
new HelperBlock(
Factory.CodeTransition(),
Factory.MetaCode("Helper").Accepts(AcceptedCharacters.Any))),
designTimeParser: true,
expectedErrors: new[]
{
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_Unexpected_Character_At_Helper_Name_Start,
RazorResources.ErrorComponent_EndOfFile),
15, 0, 15)
});
}
[Fact]
public void ParseHelperStatementAllowsDifferentlyCasedEndHelperKeyword()
{
ParseDocumentTest(@"@Helper Foo()
end helper",
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(),
new StatementBlock(
Factory.Code("\r\n").AsStatement(),
Factory.MetaCode("end helper").Accepts(AcceptedCharacters.None))),
Factory.EmptyHtml()));
}
[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(" ").Hidden()),
Factory.Markup("\r\n ")),
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 ").Hidden()),
Factory.Markup("\r\n ")),
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(foo as String)
",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(foo as String)", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("Helper ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo(foo as String)")
.Hidden()
.AutoCompleteWith(SyntaxConstants.VB.EndHelperKeyword),
new StatementBlock(
Factory.Code(" \r\n").AsStatement()))),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Helper", "End Helper"),
1, 0, 1));
}
[Fact]
public void ParseHelperStatementContinuesParsingHelperUntilEOF()
{
ParseDocumentTest(@"@Helper Foo(foo as String)
@<p>Foo</p>",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(foo as String)", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("Helper ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo(foo as String)")
.Hidden()
.AutoCompleteWith(SyntaxConstants.VB.EndHelperKeyword),
new StatementBlock(
Factory.Code("\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.Markup("<p>Foo</p>").Accepts(AcceptedCharacters.None)),
Factory.EmptyVB().AsStatement()))),
new RazorError(
String.Format(RazorResources.ParseError_BlockNotTerminated, "Helper", "End Helper"),
1, 0, 1));
}
[Fact]
public void ParseHelperStatementCorrectlyParsesHelperWithEmbeddedCode()
{
ParseDocumentTest(@"@Helper Foo(foo as String, bar as String)
@<p>@foo</p>
End Helper",
new MarkupBlock(
Factory.EmptyHtml(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Foo(foo as String, bar as String)", 8, 0, 8), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("Helper ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo(foo as String, bar as String)").Hidden(),
new StatementBlock(
Factory.Code("\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.Markup("<p>"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Markup("</p>\r\n").Accepts(AcceptedCharacters.None)),
Factory.EmptyVB().AsStatement(),
Factory.MetaCode("End Helper").Accepts(AcceptedCharacters.None))),
Factory.EmptyHtml()));
}
[Fact]
public void ParseHelperStatementGivesWhitespaceAfterCloseParenToMarkup()
{
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()
.AutoCompleteWith(SyntaxConstants.VB.EndHelperKeyword),
new StatementBlock(
Factory.Code(" \r\n ").AsStatement()))),
designTimeParser: true,
expectedErrors:
new RazorError(
String.Format(
RazorResources.ParseError_BlockNotTerminated,
"Helper", "End Helper"),
1, 0, 1));
}
[Fact]
public void ParseHelperAcceptsNestedHelpersButOutputsError()
{
ParseDocumentTest(@"@Helper Foo(string foo)
@Helper Bar(string baz)
End Helper
End Helper",
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(),
new StatementBlock(
Factory.Code("\r\n ").AsStatement(),
new HelperBlock(new HelperCodeGenerator(new LocationTagged<string>("Bar(string baz)", 37, 1, 12), headerComplete: true),
Factory.CodeTransition(),
Factory.MetaCode("Helper ").Accepts(AcceptedCharacters.None),
Factory.Code("Bar(string baz)").Hidden(),
new StatementBlock(
Factory.Code("\r\n ").AsStatement(),
Factory.MetaCode("End Helper").Accepts(AcceptedCharacters.None))),
Factory.Code("\r\n").AsStatement(),
Factory.MetaCode("End Helper").Accepts(AcceptedCharacters.None))),
Factory.EmptyHtml()),
designTimeParser: true,
expectedErrors: new[]
{
new RazorError(
RazorResources.ParseError_Helpers_Cannot_Be_Nested,
30, 1, 5)
});
}
}
}

View File

@ -0,0 +1,250 @@
// 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.VB
{
public class VBHtmlDocumentTest : VBHtmlMarkupParserTestBase
{
[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 Then
@* User is logged in! End If *@
Write(""Hello friend!"")
End If",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If Request.IsAuthenticated Then\r\n ").AsStatement(),
new CommentBlock(
Factory.CodeTransition(VBSymbolType.RazorCommentTransition),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment(" User is logged in! End If ", VBSymbolType.RazorComment),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(VBSymbolType.RazorCommentTransition)),
Factory.Code("\r\n Write(\"Hello friend!\")\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentInStatementInCodeBlockIsHandledCorrectly()
{
ParseDocumentTest(@"@If Request.IsAuthenticated Then
Dim foo = @* User is logged in! End If *@ bar
Write(""Hello friend!"")
End If",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If Request.IsAuthenticated Then\r\n Dim foo = ").AsStatement(),
new CommentBlock(
Factory.CodeTransition(VBSymbolType.RazorCommentTransition),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment(" User is logged in! End If ", VBSymbolType.RazorComment),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(VBSymbolType.RazorCommentTransition)),
Factory.Code(" bar\r\n Write(\"Hello friend!\")\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentInStringInCodeBlockIsIgnored()
{
ParseDocumentTest(@"@If Request.IsAuthenticated Then
Dim foo = ""@* User is logged in! End If *@ bar""
Write(""Hello friend!"")
End If",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If Request.IsAuthenticated Then\r\n Dim foo = \"@* User is logged in! End If *@ bar\"\r\n Write(\"Hello friend!\")\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentInTickCommentInCodeBlockIsIgnored()
{
ParseDocumentTest(@"@If Request.IsAuthenticated Then
Dim foo = '@* User is logged in! End If *@ bar
Write(""Hello friend!"")
End If",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If Request.IsAuthenticated Then\r\n Dim foo = '@* User is logged in! End If *@ bar\r\n Write(\"Hello friend!\")\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentInRemCommentInCodeBlockIsIgnored()
{
ParseDocumentTest(@"@If Request.IsAuthenticated Then
Dim foo = REM @* User is logged in! End If *@ bar
Write(""Hello friend!"")
End If",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If Request.IsAuthenticated Then\r\n Dim foo = REM @* User is logged in! End If *@ bar\r\n Write(\"Hello friend!\")\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentInImplicitExpressionIsHandledCorrectly()
{
ParseDocumentTest("@Html.Foo@*bar*@",
new MarkupBlock(
Factory.EmptyHtml(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("Html.Foo")
.AsImplicitExpression(KeywordSet)
.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(KeywordSet)
.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(KeywordSet)
.Accepts(AcceptedCharacters.Any),
new CommentBlock(
Factory.CodeTransition(VBSymbolType.RazorCommentTransition),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment("bar", VBSymbolType.RazorComment),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(VBSymbolType.RazorCommentTransition)),
Factory.Code(" 4)")
.AsImplicitExpression(KeywordSet)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.EmptyHtml()));
}
[Fact]
public void BlockCommentInConditionIsHandledCorrectly()
{
ParseDocumentTest("@If @*bar*@ Then End If",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If ").AsStatement(),
new CommentBlock(
Factory.CodeTransition(VBSymbolType.RazorCommentTransition),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment("bar", VBSymbolType.RazorComment),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(VBSymbolType.RazorCommentTransition)),
Factory.Code(" Then End If").AsStatement().Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[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(VBSymbolType.RazorCommentTransition),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.Comment("bar", VBSymbolType.RazorComment),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar).Accepts(AcceptedCharacters.None),
Factory.CodeTransition(VBSymbolType.RazorCommentTransition)
),
Factory.Code(" 1").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)
),
Factory.EmptyHtml()));
}
}
}

View File

@ -0,0 +1,79 @@
// 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.Test.Framework;
using Xunit;
namespace System.Web.Razor.Test.Parser.VB
{
public class VBImplicitExpressionTest : VBHtmlCodeParserTestBase
{
[Fact]
public void VB_Simple_ImplicitExpression()
{
ParseBlockTest("@foo not-part-of-the-block",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void VB_ImplicitExpression_With_Keyword_At_Start()
{
ParseBlockTest("@Partial",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("Partial")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void VB_ImplicitExpression_With_Keyword_In_Body()
{
ParseBlockTest("@Html.Partial",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("Html.Partial")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void VB_ImplicitExpression_With_MethodCallOrArrayIndex()
{
ParseBlockTest("@foo(42) not-part-of-the-block",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo(42)")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void VB_ImplicitExpression_Terminates_If_Trailing_Dot_Not_Followed_By_Valid_Token()
{
ParseBlockTest("@foo(42). ",
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("foo(42)")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void VB_ImplicitExpression_Supports_Complex_Expressions()
{
ParseBlockTest("@foo(42).bar(Biz.Boz / 42 * 8)(1).Burf not part of the block",
new ExpressionBlock(
Factory.CodeTransition()
.Accepts(AcceptedCharacters.None),
Factory.Code("foo(42).bar(Biz.Boz / 42 * 8)(1).Burf")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)));
}
}
}

View File

@ -0,0 +1,88 @@
// 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.SyntaxTree;
using System.Web.Razor.Test.Framework;
using Xunit;
using Xunit.Extensions;
namespace System.Web.Razor.Test.Parser.VB
{
public class VBLayoutDirectiveTest : VBHtmlCodeParserTestBase
{
[Theory]
[InlineData("layout")]
[InlineData("Layout")]
[InlineData("LAYOUT")]
[InlineData("layOut")]
[InlineData("LayOut")]
[InlineData("LaYoUt")]
[InlineData("lAyOuT")]
public void LayoutDirectiveSupportsAnyCasingOfKeyword(string keyword)
{
ParseBlockTest("@" + keyword,
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode(keyword)
)
);
}
[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.EmptyVB()
.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,169 @@
// 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.VB
{
public class VBNestedStatementsTest : VBHtmlCodeParserTestBase
{
[Fact]
public void VB_Nested_If_Statement()
{
ParseBlockTest(@"@If True Then
If False Then
End If
End If",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If True Then\r\n If False Then\r\n End If\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_Nested_Do_Statement()
{
ParseBlockTest(@"@Do While True
Do
Loop Until False
Loop",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("Do While True\r\n Do\r\n Loop Until False\r\nLoop")
.AsStatement()
.Accepts(AcceptedCharacters.AnyExceptNewline)));
}
[Fact]
public void VB_Nested_Markup_Statement_In_If()
{
ParseBlockTest(@"@If True Then
@<p>Tag</p>
End If",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If True Then\r\n")
.AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.Markup("<p>Tag</p>\r\n")
.Accepts(AcceptedCharacters.None)),
Factory.Code("End If")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_Nested_Markup_Statement_In_Code()
{
ParseBlockTest(@"@Code
Foo()
@<p>Tag</p>
Bar()
End Code",
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("Code")
.Accepts(AcceptedCharacters.None),
Factory.Code("\r\n Foo()\r\n")
.AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.Markup("<p>Tag</p>\r\n")
.Accepts(AcceptedCharacters.None)),
Factory.Code(" Bar()\r\n")
.AsStatement(),
Factory.MetaCode("End Code")
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_Nested_Markup_Statement_In_Do()
{
ParseBlockTest(@"@Do
@<p>Tag</p>
Loop While True",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("Do\r\n")
.AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.Markup("<p>Tag</p>\r\n")
.Accepts(AcceptedCharacters.None)),
Factory.Code("Loop While True")
.AsStatement()
.Accepts(AcceptedCharacters.AnyExceptNewline)));
}
[Fact]
public void VB_Nested_Single_Line_Markup_Statement_In_Do()
{
ParseBlockTest(@"@Do
@:<p>Tag
Loop While True",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("Do\r\n")
.AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition(),
Factory.MetaMarkup(":", HtmlSymbolType.Colon),
Factory.Markup("<p>Tag\r\n")
.Accepts(AcceptedCharacters.None)),
Factory.Code("Loop While True")
.AsStatement()
.Accepts(AcceptedCharacters.AnyExceptNewline)));
}
[Fact]
public void VB_Nested_Implicit_Expression_In_If()
{
ParseBlockTest(@"@If True Then
@Foo.Bar
End If",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If True Then\r\n ")
.AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("Foo.Bar")
.AsExpression()
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Code("\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_Nested_Explicit_Expression_In_If()
{
ParseBlockTest(@"@If True Then
@(Foo.Bar + 42)
End If",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If True Then\r\n ")
.AsStatement(),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(")
.Accepts(AcceptedCharacters.None),
Factory.Code("Foo.Bar + 42")
.AsExpression(),
Factory.MetaCode(")")
.Accepts(AcceptedCharacters.None)),
Factory.Code("\r\nEnd If")
.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.VB
{
public class VBRazorCommentsTest : VBHtmlMarkupParserTestBase
{
[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(")
.AsImplicitExpression(VBCodeParser.DefaultKeywords),
new CommentBlock(
Factory.CodeTransition(VBSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Comment, new VBSymbol(
Factory.LocationTracker.CurrentLocation,
String.Empty,
VBSymbolType.Unknown))
.Accepts(AcceptedCharacters.Any),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.CodeTransition(VBSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None)),
Factory.EmptyVB()
.AsImplicitExpression(VBCodeParser.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(VBCodeParser.DefaultKeywords),
new CommentBlock(
Factory.CodeTransition(VBSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Comment, new VBSymbol(
Factory.LocationTracker.CurrentLocation,
String.Empty,
VBSymbolType.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(@"@Code
@<text
@**@
End Code",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n").AsStatement(),
new MarkupBlock(
Factory.Markup(" "),
Factory.MarkupTransition("@"),
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\nEnd Code")))),
new RazorError(RazorResources.ParseError_TextTagCannotContainAttributes, 12, 1, 5),
new RazorError(String.Format(RazorResources.ParseError_MissingEndTag, "text"), 12, 1, 5),
new RazorError(String.Format(RazorResources.ParseError_BlockNotTerminated, SyntaxConstants.VB.CodeKeyword, SyntaxConstants.VB.EndCodeKeyword), 1, 0, 1));
}
[Fact]
public void UnterminatedRazorCommentInVerbatimBlock()
{
ParseDocumentTest(@"@Code
@*",
new MarkupBlock(
Factory.EmptyHtml(),
new StatementBlock(
Factory.CodeTransition(),
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n")
.AsStatement(),
new CommentBlock(
Factory.CodeTransition(VBSymbolType.RazorCommentTransition)
.Accepts(AcceptedCharacters.None),
Factory.MetaCode("*", VBSymbolType.RazorCommentStar)
.Accepts(AcceptedCharacters.None),
Factory.Span(SpanKind.Comment, new VBSymbol(Factory.LocationTracker.CurrentLocation,
String.Empty,
VBSymbolType.Unknown))
.Accepts(AcceptedCharacters.Any)))),
new RazorError(RazorResources.ParseError_RazorComment_Not_Terminated, 7, 1, 0),
new RazorError(String.Format(RazorResources.ParseError_BlockNotTerminated, SyntaxConstants.VB.CodeKeyword, SyntaxConstants.VB.EndCodeKeyword), 1, 0, 1));
}
}
}

View File

@ -0,0 +1,30 @@
// 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.Extensions;
namespace System.Web.Razor.Test.Parser.VB
{
public class VBReservedWordsTest : VBHtmlCodeParserTestBase
{
[Theory]
[InlineData("Namespace")]
[InlineData("Class")]
[InlineData("NAMESPACE")]
[InlineData("CLASS")]
[InlineData("NameSpace")]
[InlineData("nameSpace")]
private void ReservedWords(string word)
{
ParseBlockTest(word,
new DirectiveBlock(
Factory.MetaCode(word).Accepts(AcceptedCharacters.None)),
new RazorError(
String.Format(RazorResources.ParseError_ReservedWord, word),
SourceLocation.Zero));
}
}
}

View File

@ -0,0 +1,277 @@
// 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.VB
{
public class VBSectionTest : VBHtmlMarkupParserTestBase
{
[Fact]
public void ParseSectionBlockCapturesNewlineImmediatelyFollowing()
{
ParseDocumentTest(@"@Section
",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator(String.Empty),
Factory.CodeTransition(),
Factory.MetaCode("Section\r\n"),
new MarkupBlock())),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Section_Name_Start,
RazorResources.ErrorComponent_EndOfFile),
10, 1, 0),
new RazorError(
String.Format(
RazorResources.ParseError_BlockNotTerminated,
"Section", "End Section"),
1, 0, 1));
}
[Fact]
public void ParseSectionRequiresNameBeOnSameLineAsSectionKeyword()
{
ParseDocumentTest(@"@Section
Foo
<p>Body</p>
End Section",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator(String.Empty),
Factory.CodeTransition(),
Factory.MetaCode("Section "),
new MarkupBlock(
Factory.Markup("\r\nFoo\r\n <p>Body</p>\r\n")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Section_Name_Start,
RazorResources.ErrorComponent_Newline),
9, 0, 9));
}
[Fact]
public void ParseSectionAllowsNameToBeOnDifferentLineAsSectionKeywordIfUnderscoresUsed()
{
ParseDocumentTest(@"@Section _
_
Foo
<p>Body</p>
End Section",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("Foo"),
Factory.CodeTransition(),
Factory.MetaCode("Section _\r\n_\r\nFoo"),
new MarkupBlock(
Factory.Markup("\r\n <p>Body</p>\r\n")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void ParseSectionReportsErrorAndTerminatesSectionBlockIfKeywordNotFollowedByIdentifierStartCharacter()
{
ParseDocumentTest(@"@Section 9
<p>Foo</p>
End Section",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator(String.Empty),
Factory.CodeTransition(),
Factory.MetaCode("Section "),
new MarkupBlock(
Factory.Markup("9\r\n <p>Foo</p>\r\n")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()),
new RazorError(
String.Format(
RazorResources.ParseError_Unexpected_Character_At_Section_Name_Start,
String.Format(RazorResources.ErrorComponent_Character, "9")),
9, 0, 9));
}
[Fact]
public void ParserOutputsErrorOnNestedSections()
{
ParseDocumentTest(@"@Section foo
@Section bar
<p>Foo</p>
End Section
End Section",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("Section foo"),
new MarkupBlock(
Factory.Markup("\r\n"),
new SectionBlock(new SectionCodeGenerator("bar"),
Factory.Code(" ").AsStatement(),
Factory.CodeTransition(),
Factory.MetaCode("Section bar"),
new MarkupBlock(
Factory.Markup("\r\n <p>Foo</p>\r\n ")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.Markup("\r\n")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()),
new RazorError(
String.Format(
RazorResources.ParseError_Sections_Cannot_Be_Nested,
RazorResources.SectionExample_VB),
26, 1, 12));
}
[Fact]
public void ParseSectionHandlesEOFAfterIdentifier()
{
ParseDocumentTest("@Section foo",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("Section foo")
.AutoCompleteWith(SyntaxConstants.VB.EndSectionKeyword),
new MarkupBlock())),
new RazorError(
String.Format(
RazorResources.ParseError_BlockNotTerminated,
"Section", "End Section"),
1, 0, 1));
}
[Fact]
public void ParseSectionHandlesUnterminatedSection()
{
ParseDocumentTest(@"@Section foo
<p>Foo</p>",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("Section foo")
.AutoCompleteWith(SyntaxConstants.VB.EndSectionKeyword),
new MarkupBlock(
Factory.Markup("\r\n <p>Foo</p>")))),
new RazorError(
String.Format(
RazorResources.ParseError_BlockNotTerminated,
"Section", "End Section"),
1, 0, 1));
}
[Fact]
public void ParseDocumentParsesNamedSectionCorrectly()
{
ParseDocumentTest(@"@Section foo
<p>Foo</p>
End Section",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("Section foo"),
new MarkupBlock(
Factory.Markup("\r\n <p>Foo</p>\r\n")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void ParseSectionTerminatesOnFirstEndSection()
{
ParseDocumentTest(@"@Section foo
<p>End Section</p>",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("Section foo"),
new MarkupBlock(
Factory.Markup("\r\n <p>")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.Markup("</p>")));
}
[Fact]
public void ParseSectionAllowsEndSectionInVBExpression()
{
ParseDocumentTest(@"@Section foo
I really want to render the word @(""End Section""), so this is how I do it
End Section",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("foo"),
Factory.CodeTransition(),
Factory.MetaCode("Section foo"),
new MarkupBlock(
Factory.Markup("\r\n I really want to render the word "),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.MetaCode("(").Accepts(AcceptedCharacters.None),
Factory.Code("\"End Section\"").AsExpression(),
Factory.MetaCode(")").Accepts(AcceptedCharacters.None)),
Factory.Markup(", so this is how I do it\r\n")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
// These are tests that are normally in HtmlToCodeSwitchTest, but we want to verify them for VB
// since VB has slightly different section terminating behavior which follow slightly different
// code paths
[Fact]
public void SectionBodyTreatsTwoAtSignsAsEscapeSequence()
{
ParseDocumentTest(@"@Section Foo
<foo>@@bar</foo>
End Section",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("Foo"),
Factory.CodeTransition(),
Factory.MetaCode("Section Foo").AutoCompleteWith(null),
new MarkupBlock(
Factory.Markup("\r\n <foo>"),
Factory.Markup("@").Hidden(),
Factory.Markup("@bar</foo>\r\n")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
[Fact]
public void SectionBodyTreatsPairsOfAtSignsAsEscapeSequence()
{
ParseDocumentTest(@"@Section Foo
<foo>@@@@@bar</foo>
End Section",
new MarkupBlock(
Factory.EmptyHtml(),
new SectionBlock(new SectionCodeGenerator("Foo"),
Factory.CodeTransition(),
Factory.MetaCode("Section Foo").AutoCompleteWith(null),
new MarkupBlock(
Factory.Markup("\r\n <foo>"),
Factory.Markup("@").Hidden(),
Factory.Markup("@"),
Factory.Markup("@").Hidden(),
Factory.Markup("@"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("bar")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Markup("</foo>\r\n")),
Factory.MetaCode("End Section").Accepts(AcceptedCharacters.None)),
Factory.EmptyHtml()));
}
}
}

View File

@ -0,0 +1,171 @@
// 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.VB
{
public class VBSpecialKeywordsTest : VBHtmlCodeParserTestBase
{
[Fact]
public void ParseInheritsStatementMarksInheritsSpanAsCanGrowIfMissingTrailingSpace()
{
ParseBlockTest("inherits",
new DirectiveBlock(
Factory.MetaCode("inherits")),
new RazorError(
RazorResources.ParseError_InheritsKeyword_Must_Be_Followed_By_TypeName,
8, 0, 8));
}
[Fact]
public void InheritsBlockAcceptsMultipleGenericArguments()
{
ParseBlockTest("inherits Foo.Bar(Of Biz(Of Qux), String, Integer).Baz",
new DirectiveBlock(
Factory.MetaCode("inherits ").Accepts(AcceptedCharacters.None),
Factory.Code("Foo.Bar(Of Biz(Of Qux), String, Integer).Baz")
.AsBaseType("Foo.Bar(Of Biz(Of Qux), String, Integer).Baz")));
}
[Fact]
public void InheritsDirectiveSupportsVSTemplateTokens()
{
ParseBlockTest("@Inherits $rootnamespace$.MyBase",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("Inherits ")
.Accepts(AcceptedCharacters.None),
Factory.Code("$rootnamespace$.MyBase")
.AsBaseType("$rootnamespace$.MyBase")));
}
[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,
8, 0, 8));
}
[Fact]
public void ParseBlockShouldSupportNamespaceImports()
{
ParseBlockTest("Imports Foo.Bar.Baz.Biz.Boz",
new DirectiveBlock(
Factory.MetaCode("Imports Foo.Bar.Baz.Biz.Boz")
.With(new AddImportCodeGenerator(
ns: " Foo.Bar.Baz.Biz.Boz",
namespaceKeywordLength: SyntaxConstants.VB.ImportsKeywordLength))));
}
[Fact]
public void ParseBlockShowsErrorIfNamespaceNotOnSameLineAsImportsKeyword()
{
ParseBlockTest(@"Imports
Foo",
new DirectiveBlock(
Factory.MetaCode("Imports\r\n")
.With(new AddImportCodeGenerator(
ns: "\r\n",
namespaceKeywordLength: SyntaxConstants.VB.ImportsKeywordLength))),
new RazorError(
RazorResources.ParseError_NamespaceOrTypeAliasExpected,
7, 0, 7));
}
[Fact]
public void ParseBlockShowsErrorIfTypeBeingAliasedNotOnSameLineAsImportsKeyword()
{
ParseBlockTest(@"Imports Foo =
System.Bar",
new DirectiveBlock(
Factory.MetaCode("Imports Foo =\r\n")
.With(new AddImportCodeGenerator(
ns: " Foo =\r\n",
namespaceKeywordLength: SyntaxConstants.VB.ImportsKeywordLength))));
}
[Fact]
public void ParseBlockShouldSupportTypeAliases()
{
ParseBlockTest("Imports Foo = Bar.Baz.Biz.Boz",
new DirectiveBlock(
Factory.MetaCode("Imports Foo = Bar.Baz.Biz.Boz")
.With(new AddImportCodeGenerator(
ns: " Foo = Bar.Baz.Biz.Boz",
namespaceKeywordLength: SyntaxConstants.VB.ImportsKeywordLength))));
}
[Fact]
public void ParseBlockThrowsErrorIfOptionIsNotFollowedByStrictOrExplicit()
{
ParseBlockTest("Option FizzBuzz On",
new DirectiveBlock(
Factory.MetaCode("Option FizzBuzz On")
.With(new SetVBOptionCodeGenerator(optionName: null, value: true))),
new RazorError(
String.Format(RazorResources.ParseError_UnknownOption, "FizzBuzz"),
7, 0, 7));
}
[Fact]
public void ParseBlockThrowsErrorIfOptionStrictIsNotFollowedByOnOrOff()
{
ParseBlockTest("Option Strict Yes",
new DirectiveBlock(
Factory.MetaCode("Option Strict Yes")
.With(SetVBOptionCodeGenerator.Strict(true))),
new RazorError(
String.Format(
RazorResources.ParseError_InvalidOptionValue,
"Strict", "Yes"),
14, 0, 14));
}
[Fact]
public void ParseBlockReadsToAfterOnKeywordIfOptionStrictBlock()
{
ParseBlockTest("Option Strict On Foo Bar Baz",
new DirectiveBlock(
Factory.MetaCode("Option Strict On")
.With(SetVBOptionCodeGenerator.Strict(true))));
}
[Fact]
public void ParseBlockReadsToAfterOffKeywordIfOptionStrictBlock()
{
ParseBlockTest("Option Strict Off Foo Bar Baz",
new DirectiveBlock(
Factory.MetaCode("Option Strict Off")
.With(SetVBOptionCodeGenerator.Strict(false))));
}
[Fact]
public void ParseBlockReadsToAfterOnKeywordIfOptionExplicitBlock()
{
ParseBlockTest("Option Explicit On Foo Bar Baz",
new DirectiveBlock(
Factory.MetaCode("Option Explicit On")
.With(SetVBOptionCodeGenerator.Explicit(true))));
}
[Fact]
public void ParseBlockReadsToAfterOffKeywordIfOptionExplicitBlock()
{
ParseBlockTest("Option Explicit Off Foo Bar Baz",
new DirectiveBlock(
Factory.MetaCode("Option Explicit Off")
.With(SetVBOptionCodeGenerator.Explicit(false))));
}
}
}

View File

@ -0,0 +1,220 @@
// 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.VB
{
public class VBStatementTest : VBHtmlCodeParserTestBase
{
[Fact]
public void VB_Inherits_Statement()
{
ParseBlockTest(@"@Inherits System.Foo.Bar(Of Baz)",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("Inherits ").Accepts(AcceptedCharacters.None),
Factory.Code("System.Foo.Bar(Of Baz)")
.AsBaseType("System.Foo.Bar(Of Baz)")));
}
[Fact]
public void InheritsDirectiveSupportsArrays()
{
ParseBlockTest("@Inherits System.String(())()",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("Inherits ")
.Accepts(AcceptedCharacters.None),
Factory.Code("System.String(())()")
.AsBaseType("System.String(())()")));
}
[Fact]
public void InheritsDirectiveSupportsNestedGenerics()
{
ParseBlockTest("@Inherits System.Web.Mvc.WebViewPage(Of IEnumerable(Of MvcApplication2.Models.RegisterModel))",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("Inherits ")
.Accepts(AcceptedCharacters.None),
Factory.Code("System.Web.Mvc.WebViewPage(Of IEnumerable(Of MvcApplication2.Models.RegisterModel))")
.AsBaseType("System.Web.Mvc.WebViewPage(Of IEnumerable(Of MvcApplication2.Models.RegisterModel))")));
}
[Fact]
public void InheritsDirectiveSupportsTypeKeywords()
{
ParseBlockTest("@Inherits String",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("Inherits ").Accepts(AcceptedCharacters.None),
Factory.Code("String").AsBaseType("String")));
}
[Fact]
public void VB_Option_Strict_Statement()
{
ParseBlockTest(@"@Option Strict Off",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("Option Strict Off")
.With(SetVBOptionCodeGenerator.Strict(false))));
}
[Fact]
public void VB_Option_Explicit_Statement()
{
ParseBlockTest(@"@Option Explicit Off",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("Option Explicit Off")
.With(SetVBOptionCodeGenerator.Explicit(false))));
}
[Fact]
public void VB_Imports_Statement()
{
ParseBlockTest("@Imports Biz = System.Foo.Bar(Of Boz.Baz(Of Qux))",
new DirectiveBlock(
Factory.CodeTransition(),
Factory.MetaCode("Imports Biz = System.Foo.Bar(Of Boz.Baz(Of Qux))")
.With(new AddImportCodeGenerator(
ns: " Biz = System.Foo.Bar(Of Boz.Baz(Of Qux))",
namespaceKeywordLength: SyntaxConstants.VB.ImportsKeywordLength))));
}
[Fact]
public void VB_Using_Statement()
{
ParseBlockTest(@"@Using foo as Bar
foo()
End Using",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("Using foo as Bar\r\n foo()\r\nEnd Using")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_Do_Loop_Statement()
{
ParseBlockTest(@"@Do
foo()
Loop While True",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("Do\r\n foo()\r\nLoop While True")
.AsStatement()
.Accepts(AcceptedCharacters.AnyExceptNewline)));
}
[Fact]
public void VB_While_Statement()
{
ParseBlockTest(@"@While True
foo()
End While",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("While True\r\n foo()\r\nEnd While")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_If_Statement()
{
ParseBlockTest(@"@If True Then
foo()
ElseIf False Then
bar()
Else
baz()
End If",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("If True Then\r\n foo()\r\nElseIf False Then\r\n bar()\r\nElse\r\n baz()\r\nEnd If")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_Select_Statement()
{
ParseBlockTest(@"@Select Case foo
Case 1
foo()
Case 2
bar()
Case Else
baz()
End Select",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("Select Case foo\r\n Case 1\r\n foo()\r\n Case 2\r\n bar()\r\n Case Else\r\n baz()\r\nEnd Select")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_For_Statement()
{
ParseBlockTest(@"@For Each foo In bar
baz()
Next",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("For Each foo In bar\r\n baz()\r\nNext")
.AsStatement()
.Accepts(AcceptedCharacters.AnyExceptNewline)));
}
[Fact]
public void VB_Try_Statement()
{
ParseBlockTest(@"@Try
foo()
Catch ex as Exception
bar()
Finally
baz()
End Try",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("Try\r\n foo()\r\nCatch ex as Exception\r\n bar()\r\nFinally\r\n baz()\r\nEnd Try")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_With_Statement()
{
ParseBlockTest(@"@With foo
.bar()
End With",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("With foo\r\n .bar()\r\nEnd With")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
[Fact]
public void VB_SyncLock_Statement()
{
ParseBlockTest(@"@SyncLock foo
foo.bar()
End SyncLock",
new StatementBlock(
Factory.CodeTransition(),
Factory.Code("SyncLock foo\r\n foo.bar()\r\nEnd SyncLock")
.AsStatement()
.Accepts(AcceptedCharacters.None)));
}
}
}

View File

@ -0,0 +1,213 @@
// 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.VB
{
public class VBTemplateTest : VBHtmlCodeParserTestBase
{
private const string TestTemplateCode = "@@<p>Foo #@item</p>";
private TemplateBlock TestTemplate()
{
return new TemplateBlock(new TemplateBlockCodeGenerator(),
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup("@"),
Factory.Markup("<p>Foo #"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("item")
.AsImplicitExpression(VBCodeParser.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 TemplateBlockCodeGenerator(),
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup("@"),
Factory.Markup("<p>Foo #"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("Html.Repeat(10,")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.Any),
new TemplateBlock(new TemplateBlockCodeGenerator(),
new MarkupBlock(
Factory.MarkupTransition(),
Factory.MetaMarkup("@"),
Factory.Markup("<p>"),
new ExpressionBlock(
Factory.CodeTransition(),
Factory.Code("item")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Markup("</p>").Accepts(AcceptedCharacters.None))),
Factory.Code(")")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
Factory.Markup("</p>").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockHandlesSimpleAnonymousSectionInExplicitExpressionParens()
{
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 ParseBlockHandlesSimpleAnonymousSectionInImplicitExpressionParens()
{
ParseBlockTest("Html.Repeat(10," + TestTemplateCode + ")",
new ExpressionBlock(
Factory.Code("Html.Repeat(10,").AsImplicitExpression(KeywordSet),
TestTemplate(),
Factory.Code(")").AsImplicitExpression(KeywordSet).Accepts(AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void ParseBlockHandlesTwoAnonymousSectionsInImplicitExpressionParens()
{
ParseBlockTest("Html.Repeat(10," + TestTemplateCode + "," + TestTemplateCode + ")",
new ExpressionBlock(
Factory.Code("Html.Repeat(10,").AsImplicitExpression(KeywordSet),
TestTemplate(),
Factory.Code(",").AsImplicitExpression(KeywordSet),
TestTemplate(),
Factory.Code(")").AsImplicitExpression(KeywordSet).Accepts(AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void ParseBlockProducesErrorButCorrectlyParsesNestedAnonymousSectionInImplicitExpressionParens()
{
ParseBlockTest("Html.Repeat(10," + TestNestedTemplateCode + ")",
new ExpressionBlock(
Factory.Code("Html.Repeat(10,").AsImplicitExpression(KeywordSet),
TestNestedTemplate(),
Factory.Code(")").AsImplicitExpression(KeywordSet).Accepts(AcceptedCharacters.NonWhiteSpace)),
GetNestedSectionError(41, 0, 41));
}
[Fact]
public void ParseBlockHandlesSimpleAnonymousSectionInStatementWithinCodeBlock()
{
ParseBlockTest(@"For Each foo in Bar
Html.ExecuteTemplate(foo," + TestTemplateCode + @")
Next foo",
new StatementBlock(
Factory.Code("For Each foo in Bar \r\n Html.ExecuteTemplate(foo,")
.AsStatement(),
TestTemplate(),
Factory.Code(")\r\nNext foo")
.AsStatement()
.Accepts(AcceptedCharacters.WhiteSpace | AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void ParseBlockHandlesTwoAnonymousSectionsInStatementWithinCodeBlock()
{
ParseBlockTest(@"For Each foo in Bar
Html.ExecuteTemplate(foo," + TestTemplateCode + "," + TestTemplateCode + @")
Next foo",
new StatementBlock(
Factory.Code("For Each foo in Bar \r\n Html.ExecuteTemplate(foo,")
.AsStatement(),
TestTemplate(),
Factory.Code(",").AsStatement(),
TestTemplate(),
Factory.Code(")\r\nNext foo")
.AsStatement()
.Accepts(AcceptedCharacters.WhiteSpace | AcceptedCharacters.NonWhiteSpace)));
}
[Fact]
public void ParseBlockProducesErrorButCorrectlyParsesNestedAnonymousSectionInStatementWithinCodeBlock()
{
ParseBlockTest(@"For Each foo in Bar
Html.ExecuteTemplate(foo," + TestNestedTemplateCode + @")
Next foo",
new StatementBlock(
Factory.Code("For Each foo in Bar \r\n Html.ExecuteTemplate(foo,")
.AsStatement(),
TestNestedTemplate(),
Factory.Code(")\r\nNext foo")
.AsStatement()
.Accepts(AcceptedCharacters.WhiteSpace | AcceptedCharacters.NonWhiteSpace)),
GetNestedSectionError(77, 1, 55));
}
[Fact]
public void ParseBlockHandlesSimpleAnonymousSectionInStatementWithinStatementBlock()
{
ParseBlockTest(@"Code
Dim foo = bar
Html.ExecuteTemplate(foo," + TestTemplateCode + @")
End Code",
new StatementBlock(
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code(" \r\n Dim foo = bar\r\n Html.ExecuteTemplate(foo,")
.AsStatement(),
TestTemplate(),
Factory.Code(")\r\n").AsStatement(),
Factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockHandlessTwoAnonymousSectionsInStatementWithinStatementBlock()
{
ParseBlockTest(@"Code
Dim foo = bar
Html.ExecuteTemplate(foo," + TestTemplateCode + "," + TestTemplateCode + @")
End Code",
new StatementBlock(
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n Dim foo = bar\r\n Html.ExecuteTemplate(foo,")
.AsStatement(),
TestTemplate(),
Factory.Code(",").AsStatement(),
TestTemplate(),
Factory.Code(")\r\n").AsStatement(),
Factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)));
}
[Fact]
public void ParseBlockProducesErrorButCorrectlyParsesNestedAnonymousSectionInStatementWithinStatementBlock()
{
ParseBlockTest(@"Code
Dim foo = bar
Html.ExecuteTemplate(foo," + TestNestedTemplateCode + @")
End Code",
new StatementBlock(
Factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
Factory.Code("\r\n Dim foo = bar\r\n Html.ExecuteTemplate(foo,")
.AsStatement(),
TestNestedTemplate(),
Factory.Code(")\r\n").AsStatement(),
Factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)),
GetNestedSectionError(80, 2, 55));
}
private static RazorError GetNestedSectionError(int absoluteIndex, int lineIndex, int characterIndex)
{
return new RazorError(
RazorResources.ParseError_InlineMarkup_Blocks_Cannot_Be_Nested,
absoluteIndex, lineIndex, characterIndex);
}
}
}

Some files were not shown because too many files have changed in this diff Show More