Add tests to validate @tagHelperPrefix inheritance.
- Updated some naming bits that were still using the ViewStart name. - Updated MvcRazorParserTests to test more cases of the parser, especially with @tagHelperPrefix. #2110
This commit is contained in:
parent
f49d52b5fc
commit
2a28e6f4ce
|
|
@ -53,38 +53,62 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
Assert.Equal(expectedContent, responseContent);
|
Assert.Equal(expectedContent, responseContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<object[]> TagHelpersAreInheritedFromViewStartPagesData
|
public static TheoryData TagHelpersAreInheritedFromGlobalImportPagesData
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var expected1 =
|
// action, expected
|
||||||
@"<root>root-content</root>
|
return new TheoryData<string, string>
|
||||||
|
{
|
||||||
|
{
|
||||||
<nested>nested-content</nested>";
|
"NestedGlobalImportTagHelper",
|
||||||
yield return new[] { "NestedViewStartTagHelper", expected1 };
|
string.Format(
|
||||||
|
"<root>root-content</root>{0}{0}{0}<nested>nested-content</nested>",
|
||||||
var expected2 =
|
Environment.NewLine)
|
||||||
@"layout:<root>root-content</root>
|
},
|
||||||
|
{
|
||||||
|
"ViewWithLayoutAndNestedTagHelper",
|
||||||
<nested>nested-content</nested>";
|
string.Format(
|
||||||
|
"layout:<root>root-content</root>{0}{0}{0}<nested>nested-content</nested>",
|
||||||
yield return new[] { "ViewWithLayoutAndNestedTagHelper", expected2 };
|
Environment.NewLine)
|
||||||
|
},
|
||||||
var expected3 =
|
{
|
||||||
@"layout:<root>root-content</root>
|
"ViewWithInheritedRemoveTagHelper",
|
||||||
|
string.Format(
|
||||||
|
"layout:<root>root-content</root>{0}{0}{0}page:<root/>{0}<nested>nested-content</nested>",
|
||||||
page:<root/>
|
Environment.NewLine)
|
||||||
<nested>nested-content</nested>";
|
},
|
||||||
yield return new[] { "ViewWithInheritedRemoveTagHelper", expected3 };
|
{
|
||||||
|
"ViewWithInheritedTagHelperPrefix",
|
||||||
|
string.Format(
|
||||||
|
"layout:<root>root-content</root>{0}{0}{0}page:<root>root-content</root>",
|
||||||
|
Environment.NewLine)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ViewWithOverriddenTagHelperPrefix",
|
||||||
|
string.Format(
|
||||||
|
"layout:<root>root-content</root>{0}{0}{0}{0}page:<root>root-content</root>",
|
||||||
|
Environment.NewLine)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ViewWithNestedInheritedTagHelperPrefix",
|
||||||
|
string.Format(
|
||||||
|
"layout:<root>root-content</root>{0}{0}{0}page:<root>root-content</root>",
|
||||||
|
Environment.NewLine)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ViewWithNestedOverriddenTagHelperPrefix",
|
||||||
|
string.Format(
|
||||||
|
"layout:<root>root-content</root>{0}{0}{0}{0}page:<root>root-content</root>",
|
||||||
|
Environment.NewLine)
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(TagHelpersAreInheritedFromViewStartPagesData))]
|
[MemberData(nameof(TagHelpersAreInheritedFromGlobalImportPagesData))]
|
||||||
public async Task TagHelpersAreInheritedFromViewStartPages(string action, string expected)
|
public async Task TagHelpersAreInheritedFromGlobalImportPages(string action, string expected)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var server = TestHelper.CreateServer(_app, SiteName);
|
var server = TestHelper.CreateServer(_app, SiteName);
|
||||||
|
|
@ -158,7 +182,7 @@ page:<root/>
|
||||||
{ "Age", "1000" },
|
{ "Age", "1000" },
|
||||||
{ "EmployeeId", "0" },
|
{ "EmployeeId", "0" },
|
||||||
{ "Email", "a@b.com" },
|
{ "Email", "a@b.com" },
|
||||||
{ "Salary", "z" },
|
{ "Salary", "z" },
|
||||||
};
|
};
|
||||||
var postContent = new FormUrlEncodedContent(validPostValues);
|
var postContent = new FormUrlEncodedContent(validPostValues);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNet.Razor.Generator.Compiler;
|
using Microsoft.AspNet.Razor.Generator.Compiler;
|
||||||
|
|
@ -15,30 +16,132 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
{
|
{
|
||||||
public class MvcRazorCodeParserTest
|
public class MvcRazorCodeParserTest
|
||||||
{
|
{
|
||||||
[Fact]
|
public static TheoryData GlobalImportData
|
||||||
public void GetTagHelperDescriptors_ReturnsDescriptorsFromViewStart()
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// codeTrees, expectedDirectiveDescriptors
|
||||||
|
return new TheoryData<CodeTree[], TagHelperDirectiveDescriptor[]>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
new[] { CreateCodeTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP" }) },
|
||||||
|
new[] { CreateDirectiveDescriptor("THP", TagHelperDirectiveType.TagHelperPrefix) }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new[] { CreateCodeTree(new AddTagHelperChunk { LookupText = "ATH" }) },
|
||||||
|
new[] { CreateDirectiveDescriptor("ATH", TagHelperDirectiveType.AddTagHelper) }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateCodeTree(
|
||||||
|
new AddTagHelperChunk { LookupText = "ATH1" },
|
||||||
|
new AddTagHelperChunk { LookupText = "ATH2" })
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateDirectiveDescriptor("ATH1", TagHelperDirectiveType.AddTagHelper),
|
||||||
|
CreateDirectiveDescriptor("ATH2", TagHelperDirectiveType.AddTagHelper)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new[] { CreateCodeTree(new RemoveTagHelperChunk { LookupText = "RTH" }) },
|
||||||
|
new[] { CreateDirectiveDescriptor("RTH", TagHelperDirectiveType.RemoveTagHelper) }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateCodeTree(
|
||||||
|
new RemoveTagHelperChunk { LookupText = "RTH1" },
|
||||||
|
new RemoveTagHelperChunk { LookupText = "RTH2" })
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateDirectiveDescriptor("RTH1", TagHelperDirectiveType.RemoveTagHelper),
|
||||||
|
CreateDirectiveDescriptor("RTH2", TagHelperDirectiveType.RemoveTagHelper)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateCodeTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP1" }),
|
||||||
|
CreateCodeTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP2" }),
|
||||||
|
},
|
||||||
|
new[] { CreateDirectiveDescriptor("THP1", TagHelperDirectiveType.TagHelperPrefix) }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateCodeTree(
|
||||||
|
new TagHelperPrefixDirectiveChunk { Prefix = "THP" },
|
||||||
|
new RemoveTagHelperChunk { LookupText = "RTH" },
|
||||||
|
new AddTagHelperChunk { LookupText = "ATH" })
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateDirectiveDescriptor("RTH", TagHelperDirectiveType.RemoveTagHelper),
|
||||||
|
CreateDirectiveDescriptor("ATH", TagHelperDirectiveType.AddTagHelper),
|
||||||
|
CreateDirectiveDescriptor("THP", TagHelperDirectiveType.TagHelperPrefix),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateCodeTree(
|
||||||
|
new LiteralChunk { Text = "Hello world" },
|
||||||
|
new AddTagHelperChunk { LookupText = "ATH" }),
|
||||||
|
CreateCodeTree(new RemoveTagHelperChunk { LookupText = "RTH" })
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateDirectiveDescriptor("RTH", TagHelperDirectiveType.RemoveTagHelper),
|
||||||
|
CreateDirectiveDescriptor("ATH", TagHelperDirectiveType.AddTagHelper),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateCodeTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP" }),
|
||||||
|
CreateCodeTree(
|
||||||
|
new LiteralChunk { Text = "Hello world" },
|
||||||
|
new AddTagHelperChunk { LookupText = "ATH" }),
|
||||||
|
CreateCodeTree(new RemoveTagHelperChunk { LookupText = "RTH" })
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateDirectiveDescriptor("RTH", TagHelperDirectiveType.RemoveTagHelper),
|
||||||
|
CreateDirectiveDescriptor("ATH", TagHelperDirectiveType.AddTagHelper),
|
||||||
|
CreateDirectiveDescriptor("THP", TagHelperDirectiveType.TagHelperPrefix),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateCodeTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP1" }),
|
||||||
|
CreateCodeTree(new AddTagHelperChunk { LookupText = "ATH" }),
|
||||||
|
CreateCodeTree(new RemoveTagHelperChunk { LookupText = "RTH" }),
|
||||||
|
CreateCodeTree(new TagHelperPrefixDirectiveChunk { Prefix = "THP2" }),
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
CreateDirectiveDescriptor("RTH", TagHelperDirectiveType.RemoveTagHelper),
|
||||||
|
CreateDirectiveDescriptor("ATH", TagHelperDirectiveType.AddTagHelper),
|
||||||
|
CreateDirectiveDescriptor("THP1", TagHelperDirectiveType.TagHelperPrefix),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(GlobalImportData))]
|
||||||
|
public void GetTagHelperDescriptors_ReturnsExpectedDirectiveDescriptors(
|
||||||
|
CodeTree[] codeTrees,
|
||||||
|
TagHelperDirectiveDescriptor[] expectedDirectiveDescriptors)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var builder = new BlockBuilder { Type = BlockType.Comment };
|
var builder = new BlockBuilder { Type = BlockType.Comment };
|
||||||
var block = new Block(builder);
|
var block = new Block(builder);
|
||||||
var codeTrees = new[]
|
|
||||||
{
|
|
||||||
new CodeTree
|
|
||||||
{
|
|
||||||
Chunks = new Chunk[]
|
|
||||||
{
|
|
||||||
new LiteralChunk { Text = "Hello world" },
|
|
||||||
new AddTagHelperChunk { LookupText = "Add Tag Helper" },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new CodeTree
|
|
||||||
{
|
|
||||||
Chunks = new[]
|
|
||||||
{
|
|
||||||
new RemoveTagHelperChunk { LookupText = "Remove Tag Helper" },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
IList<TagHelperDirectiveDescriptor> descriptors = null;
|
IList<TagHelperDirectiveDescriptor> descriptors = null;
|
||||||
var resolver = new Mock<ITagHelperDescriptorResolver>();
|
var resolver = new Mock<ITagHelperDescriptorResolver>();
|
||||||
|
|
@ -50,25 +153,43 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
.Returns(Enumerable.Empty<TagHelperDescriptor>())
|
.Returns(Enumerable.Empty<TagHelperDescriptor>())
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
|
|
||||||
var baseParser = new RazorParser(new CSharpCodeParser(),
|
var baseParser = new RazorParser(
|
||||||
new HtmlMarkupParser(),
|
new CSharpCodeParser(),
|
||||||
resolver.Object);
|
new HtmlMarkupParser(),
|
||||||
var parser = new TestableMvcRazorParser(baseParser, codeTrees, new Chunk[0]);
|
tagHelperDescriptorResolver: resolver.Object);
|
||||||
var sink = new ParserErrorSink();
|
var parser = new TestableMvcRazorParser(baseParser, codeTrees, defaultInheritedChunks: new Chunk[0]);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = parser.GetTagHelperDescriptorsPublic(block, sink).ToArray();
|
parser.GetTagHelperDescriptorsPublic(block, errorSink: new ParserErrorSink()).ToArray();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(descriptors);
|
Assert.NotNull(descriptors);
|
||||||
Assert.Equal(2, descriptors.Count);
|
Assert.Equal(expectedDirectiveDescriptors.Length, descriptors.Count);
|
||||||
|
|
||||||
Assert.Equal("Remove Tag Helper", descriptors[0].DirectiveText);
|
for (var i = 0; i < expectedDirectiveDescriptors.Length; i++)
|
||||||
Assert.Equal(SourceLocation.Undefined, descriptors[0].Location);
|
{
|
||||||
|
var expected = expectedDirectiveDescriptors[i];
|
||||||
|
var actual = descriptors[i];
|
||||||
|
|
||||||
Assert.Equal("Add Tag Helper", descriptors[1].DirectiveText);
|
Assert.Equal(expected.DirectiveText, actual.DirectiveText, StringComparer.Ordinal);
|
||||||
Assert.Equal(TagHelperDirectiveType.AddTagHelper, descriptors[1].DirectiveType);
|
Assert.Equal(expected.Location, actual.Location);
|
||||||
Assert.Equal(SourceLocation.Undefined, descriptors[1].Location);
|
Assert.Equal(expected.DirectiveType, actual.DirectiveType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CodeTree CreateCodeTree(params Chunk[] chunks)
|
||||||
|
{
|
||||||
|
return new CodeTree
|
||||||
|
{
|
||||||
|
Chunks = chunks
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TagHelperDirectiveDescriptor CreateDirectiveDescriptor(
|
||||||
|
string directiveText,
|
||||||
|
TagHelperDirectiveType directiveType)
|
||||||
|
{
|
||||||
|
return new TagHelperDirectiveDescriptor(directiveText, SourceLocation.Undefined, directiveType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestableMvcRazorParser : MvcRazorParser
|
private class TestableMvcRazorParser : MvcRazorParser
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ namespace TagHelpersWebSite.Controllers
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ViewResult NestedViewStartTagHelper()
|
public ViewResult NestedGlobalImportTagHelper()
|
||||||
{
|
{
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
|
|
@ -44,5 +44,29 @@ namespace TagHelpersWebSite.Controllers
|
||||||
{
|
{
|
||||||
return View("/Views/RemoveInheritedTagHelpers/ViewWithInheritedRemoveTagHelper.cshtml");
|
return View("/Views/RemoveInheritedTagHelpers/ViewWithInheritedRemoveTagHelper.cshtml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ViewResult ViewWithInheritedTagHelperPrefix()
|
||||||
|
{
|
||||||
|
return View("/Views/InheritedTagHelperPrefix/InheritedTagHelperPrefix.cshtml");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViewResult ViewWithOverriddenTagHelperPrefix()
|
||||||
|
{
|
||||||
|
return View("/Views/InheritedTagHelperPrefix/OverriddenTagHelperPrefix.cshtml");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViewResult ViewWithNestedInheritedTagHelperPrefix()
|
||||||
|
{
|
||||||
|
return View(
|
||||||
|
"/Views/InheritedTagHelperPrefix/NestedInheritedTagHelperPrefix/" +
|
||||||
|
"NestedInheritedTagHelperPrefix.cshtml");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViewResult ViewWithNestedOverriddenTagHelperPrefix()
|
||||||
|
{
|
||||||
|
return View(
|
||||||
|
"/Views/InheritedTagHelperPrefix/NestedInheritedTagHelperPrefix/" +
|
||||||
|
"NestedOverriddenTagHelperPrefix.cshtml");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ using Microsoft.AspNet.Razor.TagHelpers;
|
||||||
namespace TagHelpersWebSite.TagHelpers
|
namespace TagHelpersWebSite.TagHelpers
|
||||||
{
|
{
|
||||||
[HtmlElementName("nested")]
|
[HtmlElementName("nested")]
|
||||||
public class NestedViewStartTagHelper : TagHelper
|
public class NestedGlobalImportTagHelper : TagHelper
|
||||||
{
|
{
|
||||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
public override void Process(TagHelperContext context, TagHelperOutput output)
|
||||||
{
|
{
|
||||||
|
|
@ -1 +1 @@
|
||||||
@addTagHelper "TagHelpersWebSite.TagHelpers.NestedViewStartTagHelper, TagHelpersWebSite"
|
@addTagHelper "TagHelpersWebSite.TagHelpers.NestedGlobalImportTagHelper, TagHelpersWebSite"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
page:<inherited:root></inherited:root>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
page:<nested-root></nested-root>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
@tagHelperPrefix "nested-overridden"
|
||||||
|
|
||||||
|
page:<nested-overriddenroot></nested-overriddenroot>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
@tagHelperPrefix "nested-"
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
@tagHelperPrefix "overridden"
|
||||||
|
|
||||||
|
page:<overriddenroot></overriddenroot>
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
@tagHelperPrefix "inherited:"
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
@{
|
||||||
|
Layout = "~/Views/Shared/_LayoutWithRootTagHelper.cshtml";
|
||||||
|
}
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
@removeTagHelper "TagHelpersWebSite.TagHelpers.RootViewStartTagHelper, TagHelpersWebSite"
|
@removeTagHelper "TagHelpersWebSite.TagHelpers.RootViewStartTagHelper, TagHelpersWebSite"
|
||||||
@addTagHelper "TagHelpersWebSite.TagHelpers.NestedViewStartTagHelper, TagHelpersWebSite"
|
@addTagHelper "TagHelpersWebSite.TagHelpers.NestedGlobalImportTagHelper, TagHelpersWebSite"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
@{
|
@{
|
||||||
Layout = "~/Views/Shared/_LayoutWithRootTagHelper.cshtml";
|
Layout = "~/Views/Shared/_LayoutWithRootTagHelper.cshtml";
|
||||||
}
|
}
|
||||||
@addTagHelper "TagHelpersWebSite.TagHelpers.NestedViewStartTagHelper, TagHelpersWebSite"
|
@addTagHelper "TagHelpersWebSite.TagHelpers.NestedGlobalImportTagHelper, TagHelpersWebSite"
|
||||||
<nested>some-content</nested>
|
<nested>some-content</nested>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue