-
Notifications
You must be signed in to change notification settings - Fork 220
Add code generation tests for tag helpers. #135
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| // 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. | ||
|
|
||
| using System.Linq; | ||
| using System.Reflection; | ||
| using Microsoft.AspNet.Razor.Parser; | ||
| using Microsoft.AspNet.Razor.Parser.TagHelpers.Internal; | ||
| using Microsoft.AspNet.Razor.TagHelpers; | ||
| using Moq; | ||
| using Xunit; | ||
|
|
||
| namespace Microsoft.AspNet.Razor.Test.Generator | ||
| { | ||
| public class CSharpTagHelperRenderingTest : CSharpRazorCodeGeneratorTest | ||
| { | ||
| [Theory] | ||
| [InlineData("TagHelpersInSection")] | ||
| [InlineData("TagHelpersInHelper")] | ||
| public void TagHelpers_WithinHelpersAndSections_GeneratesExpectedOutput(string testType) | ||
| { | ||
| // Arrange | ||
| var propertyInfoMock = new Mock<PropertyInfo>(); | ||
| propertyInfoMock.Setup(propertyInfo => propertyInfo.PropertyType).Returns(typeof(string)); | ||
| propertyInfoMock.Setup(propertyInfo => propertyInfo.Name).Returns("BoundProperty"); | ||
| var tagHelperDescriptorProvider = new TagHelperDescriptorProvider( | ||
| new TagHelperDescriptor[] | ||
| { | ||
| new TagHelperDescriptor("MyTagHelper", | ||
| "MyTagHelper", | ||
| ContentBehavior.None, | ||
| new [] { | ||
| new TagHelperAttributeDescriptor("BoundProperty", | ||
| propertyInfoMock.Object) | ||
| }), | ||
| new TagHelperDescriptor("NestedTagHelper", "NestedTagHelper", ContentBehavior.Modify) | ||
| }); | ||
|
|
||
| // Act & Assert | ||
| RunTagHelperTest(testType, tagHelperDescriptorProvider); | ||
| } | ||
|
|
||
| [Theory] | ||
| [InlineData("SingleTagHelper")] | ||
| [InlineData("BasicTagHelpers")] | ||
| [InlineData("ComplexTagHelpers")] | ||
| public void TagHelpers_GenerateExpectedOutput(string testType) | ||
| { | ||
| // Arrange | ||
| var pFooPropertyInfo = new Mock<PropertyInfo>(); | ||
| pFooPropertyInfo.Setup(propertyInfo => propertyInfo.PropertyType).Returns(typeof(int)); | ||
| pFooPropertyInfo.Setup(propertyInfo => propertyInfo.Name).Returns("Foo"); | ||
| var inputTypePropertyInfo = new Mock<PropertyInfo>(); | ||
| inputTypePropertyInfo.Setup(propertyInfo => propertyInfo.PropertyType).Returns(typeof(string)); | ||
| inputTypePropertyInfo.Setup(propertyInfo => propertyInfo.Name).Returns("Type"); | ||
| var checkedPropertyInfo = new Mock<PropertyInfo>(); | ||
| checkedPropertyInfo.Setup(propertyInfo => propertyInfo.PropertyType).Returns(typeof(bool)); | ||
| checkedPropertyInfo.Setup(propertyInfo => propertyInfo.Name).Returns("Checked"); | ||
| var tagHelperDescriptorProvider = new TagHelperDescriptorProvider( | ||
| new TagHelperDescriptor[] | ||
| { | ||
| new TagHelperDescriptor("p", | ||
| "PTagHelper", | ||
| ContentBehavior.None, | ||
| new [] { | ||
| new TagHelperAttributeDescriptor("foo", pFooPropertyInfo.Object) | ||
| }), | ||
| new TagHelperDescriptor("input", | ||
| "InputTagHelper", | ||
| ContentBehavior.None, | ||
| new TagHelperAttributeDescriptor[] { | ||
| new TagHelperAttributeDescriptor("type", inputTypePropertyInfo.Object) | ||
| }), | ||
| new TagHelperDescriptor("input", | ||
| "InputTagHelper2", | ||
| ContentBehavior.None, | ||
| new TagHelperAttributeDescriptor[] { | ||
| new TagHelperAttributeDescriptor("type", inputTypePropertyInfo.Object), | ||
| new TagHelperAttributeDescriptor("checked", checkedPropertyInfo.Object) | ||
| }), | ||
| }); | ||
|
|
||
| // Act & Assert | ||
| RunTagHelperTest(testType, tagHelperDescriptorProvider); | ||
| } | ||
|
|
||
| [Fact] | ||
| public void TagHelpers_WithContentBehaviors_GenerateExpectedOutput() | ||
| { | ||
| // Arrange | ||
| var tagHelperDescriptorProvider = new TagHelperDescriptorProvider( | ||
| new TagHelperDescriptor[] | ||
| { | ||
| new TagHelperDescriptor("modify", "ModifyTagHelper", ContentBehavior.Modify), | ||
| new TagHelperDescriptor("none", "NoneTagHelper", ContentBehavior.None), | ||
| new TagHelperDescriptor("append", "AppendTagHelper", ContentBehavior.Append), | ||
| new TagHelperDescriptor("prepend", "PrependTagHelper", ContentBehavior.Prepend), | ||
| new TagHelperDescriptor("replace", "ReplaceTagHelper", ContentBehavior.Replace), | ||
| }); | ||
|
|
||
| // Act & Assert | ||
| RunTagHelperTest("ContentBehaviorTagHelpers", tagHelperDescriptorProvider); | ||
| } | ||
|
|
||
| private void RunTagHelperTest(string testName, TagHelperDescriptorProvider tagHelperDescriptorProvider) | ||
| { | ||
| RunTest( | ||
| name: testName, | ||
| templateEngineConfig: (engine) => | ||
| { | ||
| return new TagHelperTemplateEngine(engine, tagHelperDescriptorProvider); | ||
| }); | ||
| } | ||
|
|
||
| private class TagHelperTemplateEngine : RazorTemplateEngine | ||
| { | ||
| private TagHelperDescriptorProvider _tagHelperDescriptorProvider; | ||
|
|
||
| public TagHelperTemplateEngine(RazorTemplateEngine engine, TagHelperDescriptorProvider tagHelperDescriptorProvider) | ||
| : base(engine.Host) | ||
| { | ||
| _tagHelperDescriptorProvider = tagHelperDescriptorProvider; | ||
| } | ||
|
|
||
| protected internal override RazorParser CreateParser() | ||
| { | ||
| var parser = base.CreateParser(); | ||
| var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(_tagHelperDescriptorProvider); | ||
|
|
||
| for (var i = 0; i < parser.Optimizers.Count; i++) | ||
| { | ||
| if (parser.Optimizers[i] is TagHelperParseTreeRewriter) | ||
| { | ||
| parser.Optimizers[i] = tagHelperParseTreeRewriter; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This all goes away in the PR from |
||
| return parser; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| #pragma checksum "BasicTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8d60e58d54168749dc71a0d6d3a95887b2adb5e7" | ||
| namespace TestOutput | ||
| { | ||
| using Microsoft.AspNet.Razor.Runtime.TagHelpers; | ||
| using System; | ||
| using System.Threading.Tasks; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Razor needs to add a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, this is a comment on #134 |
||
|
|
||
| public class BasicTagHelpers | ||
| { | ||
| #line hidden | ||
| private System.IO.TextWriter __tagHelperStringValueBuffer = null; | ||
| private TagHelperExecutionContext __tagHelperExecutionContext = null; | ||
| private TagHelperRunner __tagHelperRunner = new TagHelperRunner(); | ||
| private TagHelperScopeManager __tagHelperScopeManager = new TagHelperScopeManager(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment on #134: make
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm not sure I follow your comment on the scope manager. The variable name is singular |
||
| private PTagHelper __PTagHelper = null; | ||
| private InputTagHelper __InputTagHelper = null; | ||
| private InputTagHelper2 __InputTagHelper2 = null; | ||
| #line hidden | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: should this directive be generated above line 10? none of the field declarations were in the .cshtml file
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added an extra one above the fields to separate. |
||
| public BasicTagHelpers() | ||
| { | ||
| } | ||
|
|
||
| #pragma warning disable 1998 | ||
| public override async Task ExecuteAsync() | ||
| { | ||
| Instrumentation.BeginContext(0, 47, true); | ||
| WriteLiteral("<div class=\"randomNonTagHelperAttribute\">\r\n "); | ||
| Instrumentation.EndContext(); | ||
| __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p"); | ||
| __PTagHelper = CreateTagHelper<PTagHelper>(); | ||
| __tagHelperExecutionContext.Add(__PTagHelper); | ||
| __tagHelperExecutionContext.AddHtmlAttribute("class", "Hello World"); | ||
| __tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result; | ||
| WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag()); | ||
| Instrumentation.BeginContext(70, 10, true); | ||
| WriteLiteral("\r\n "); | ||
| Instrumentation.EndContext(); | ||
| __tagHelperExecutionContext = __tagHelperScopeManager.Begin("p"); | ||
| __PTagHelper = CreateTagHelper<PTagHelper>(); | ||
| __tagHelperExecutionContext.Add(__PTagHelper); | ||
| __tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result; | ||
| WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag()); | ||
| WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag()); | ||
| __tagHelperExecutionContext = __tagHelperScopeManager.End(); | ||
| Instrumentation.BeginContext(87, 10, true); | ||
| WriteLiteral("\r\n "); | ||
| Instrumentation.EndContext(); | ||
| __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input"); | ||
| __InputTagHelper = CreateTagHelper<InputTagHelper>(); | ||
| __tagHelperExecutionContext.Add(__InputTagHelper); | ||
| __InputTagHelper.Type = "text"; | ||
| __tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type); | ||
| __InputTagHelper2 = CreateTagHelper<InputTagHelper2>(); | ||
| __tagHelperExecutionContext.Add(__InputTagHelper2); | ||
| __InputTagHelper2.Type = __InputTagHelper.Type; | ||
| __tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result; | ||
| WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag()); | ||
| WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag()); | ||
| __tagHelperExecutionContext = __tagHelperScopeManager.End(); | ||
| Instrumentation.BeginContext(118, 10, true); | ||
| WriteLiteral("\r\n "); | ||
| Instrumentation.EndContext(); | ||
| __tagHelperExecutionContext = __tagHelperScopeManager.Begin("input"); | ||
| __InputTagHelper = CreateTagHelper<InputTagHelper>(); | ||
| __tagHelperExecutionContext.Add(__InputTagHelper); | ||
| __InputTagHelper.Type = "checkbox"; | ||
| __tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type); | ||
| __InputTagHelper2 = CreateTagHelper<InputTagHelper2>(); | ||
| __tagHelperExecutionContext.Add(__InputTagHelper2); | ||
| __InputTagHelper2.Type = __InputTagHelper.Type; | ||
| __InputTagHelper2.Checked = true; | ||
| __tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked); | ||
| __tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result; | ||
| WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag()); | ||
| WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag()); | ||
| __tagHelperExecutionContext = __tagHelperScopeManager.End(); | ||
| Instrumentation.BeginContext(167, 6, true); | ||
| WriteLiteral("\r\n "); | ||
| Instrumentation.EndContext(); | ||
| WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag()); | ||
| __tagHelperExecutionContext = __tagHelperScopeManager.End(); | ||
| Instrumentation.BeginContext(177, 8, true); | ||
| WriteLiteral("\r\n</div>"); | ||
| Instrumentation.EndContext(); | ||
| } | ||
| #pragma warning restore 1998 | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a few tag helper samples that should cover most of the use-cases for tag helper implementations. I'll add more attribute related tag helper tests with #102 since that will be its focus.