Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Commit 7399531

Browse files
author
NTaylorMullen
committed
Add test for TagHelperAttributeValueCodeRenderer extensibility.
- Tested that we can successfully plugin our own TagHelperAttributeValueCodeRenderer. - Moved some existing TagHelper test logic into its own base type to enhance code reusability. #119
1 parent 15b7e15 commit 7399531

File tree

6 files changed

+261
-49
lines changed

6 files changed

+261
-49
lines changed

test/Microsoft.AspNet.Razor.Test/Generator/CSharpRazorCodeGeneratorTest.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,14 @@ public void CSharpCodeGeneratorDoesNotRenderLinePragmasIfGenerateLinePragmasIsSe
387387
[Fact]
388388
public void CSharpCodeGeneratorRendersHelpersBlockCorrectlyWhenInstanceHelperRequested()
389389
{
390-
RunTest("Helpers", baselineName: "Helpers.Instance", hostConfig: h => h.StaticHelpers = false);
390+
RunTest("Helpers",
391+
baselineName: "Helpers.Instance",
392+
hostConfig: host =>
393+
{
394+
host.StaticHelpers = false;
395+
396+
return host;
397+
});
391398
}
392399

393400
[Fact]
@@ -396,6 +403,8 @@ public void CSharpCodeGeneratorCorrectlyInstrumentsRazorCodeWhenInstrumentationR
396403
RunTest("Instrumented", hostConfig: host =>
397404
{
398405
host.InstrumentedSourceFilePath = string.Format("~/{0}.cshtml", host.DefaultClassName);
406+
407+
return host;
399408
});
400409
}
401410

test/Microsoft.AspNet.Razor.Test/Generator/CSharpTagHelperRenderingTest.cs

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4-
using System.Linq;
54
using System.Reflection;
6-
using Microsoft.AspNet.Razor.Parser;
7-
using Microsoft.AspNet.Razor.Parser.TagHelpers.Internal;
85
using Microsoft.AspNet.Razor.TagHelpers;
96
using Moq;
107
using Xunit;
118

129
namespace Microsoft.AspNet.Razor.Test.Generator
1310
{
14-
public class CSharpTagHelperRenderingTest : CSharpRazorCodeGeneratorTest
11+
public class CSharpTagHelperRenderingTest : TagHelperTestBase
1512
{
1613
[Theory]
1714
[InlineData("TagHelpersInSection")]
@@ -36,7 +33,7 @@ public void TagHelpers_WithinHelpersAndSections_GeneratesExpectedOutput(string t
3633
});
3734

3835
// Act & Assert
39-
RunTagHelperTest(testType, tagHelperDescriptorProvider);
36+
RunTagHelperTest(testType, tagHelperDescriptorProvider: tagHelperDescriptorProvider);
4037
}
4138

4239
[Theory]
@@ -80,7 +77,7 @@ public void TagHelpers_GenerateExpectedOutput(string testType)
8077
});
8178

8279
// Act & Assert
83-
RunTagHelperTest(testType, tagHelperDescriptorProvider);
80+
RunTagHelperTest(testType, tagHelperDescriptorProvider: tagHelperDescriptorProvider);
8481
}
8582

8683
[Fact]
@@ -98,45 +95,7 @@ public void TagHelpers_WithContentBehaviors_GenerateExpectedOutput()
9895
});
9996

10097
// Act & Assert
101-
RunTagHelperTest("ContentBehaviorTagHelpers", tagHelperDescriptorProvider);
102-
}
103-
104-
private void RunTagHelperTest(string testName, TagHelperDescriptorProvider tagHelperDescriptorProvider)
105-
{
106-
RunTest(
107-
name: testName,
108-
templateEngineConfig: (engine) =>
109-
{
110-
return new TagHelperTemplateEngine(engine, tagHelperDescriptorProvider);
111-
});
112-
}
113-
114-
private class TagHelperTemplateEngine : RazorTemplateEngine
115-
{
116-
private TagHelperDescriptorProvider _tagHelperDescriptorProvider;
117-
118-
public TagHelperTemplateEngine(RazorTemplateEngine engine, TagHelperDescriptorProvider tagHelperDescriptorProvider)
119-
: base(engine.Host)
120-
{
121-
_tagHelperDescriptorProvider = tagHelperDescriptorProvider;
122-
}
123-
124-
protected internal override RazorParser CreateParser()
125-
{
126-
var parser = base.CreateParser();
127-
var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(_tagHelperDescriptorProvider);
128-
129-
for (var i = 0; i < parser.Optimizers.Count; i++)
130-
{
131-
if (parser.Optimizers[i] is TagHelperParseTreeRewriter)
132-
{
133-
parser.Optimizers[i] = tagHelperParseTreeRewriter;
134-
break;
135-
}
136-
}
137-
138-
return parser;
139-
}
98+
RunTagHelperTest("ContentBehaviorTagHelpers", tagHelperDescriptorProvider: tagHelperDescriptorProvider);
14099
}
141100
}
142101
}

test/Microsoft.AspNet.Razor.Test/Generator/RazorCodeGeneratorTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ protected void RunTest(string name,
3737
IList<LineMapping> expectedDesignTimePragmas = null,
3838
TestSpan[] spans = null,
3939
TabTest tabTest = TabTest.Both,
40-
Action<RazorEngineHost> hostConfig = null,
40+
Func<RazorEngineHost, RazorEngineHost> hostConfig = null,
4141
Func<RazorTemplateEngine, RazorTemplateEngine> templateEngineConfig = null,
4242
Action<GeneratorResults> onResults = null)
4343
{
@@ -93,7 +93,7 @@ private void RunTestInternal(string name,
9393
IList<LineMapping> expectedDesignTimePragmas,
9494
TestSpan[] spans,
9595
bool withTabs,
96-
Action<RazorEngineHost> hostConfig,
96+
Func<RazorEngineHost, RazorEngineHost> hostConfig,
9797
Func<RazorTemplateEngine, RazorTemplateEngine> templateEngineConfig,
9898
Action<GeneratorResults> onResults = null)
9999
{
@@ -130,7 +130,7 @@ private void RunTestInternal(string name,
130130
};
131131
if (hostConfig != null)
132132
{
133-
hostConfig(host);
133+
host = hostConfig(host);
134134
}
135135

136136
host.IsIndentingWithTabs = withTabs;
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Reflection;
6+
using Microsoft.AspNet.Razor.Generator;
7+
using Microsoft.AspNet.Razor.Generator.Compiler;
8+
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
9+
using Microsoft.AspNet.Razor.TagHelpers;
10+
using Moq;
11+
using Xunit;
12+
13+
namespace Microsoft.AspNet.Razor.Test.Generator
14+
{
15+
public class TagHelperAttributeValueCodeRendererTest : TagHelperTestBase
16+
{
17+
[Fact]
18+
public void TagHelpers_CanReplaceAttributeCodeGeneratorLogic()
19+
{
20+
// Arrange
21+
var inputTypePropertyInfo = new Mock<PropertyInfo>();
22+
inputTypePropertyInfo.Setup(propertyInfo => propertyInfo.PropertyType).Returns(typeof(string));
23+
inputTypePropertyInfo.Setup(propertyInfo => propertyInfo.Name).Returns("Type");
24+
var checkedPropertyInfo = new Mock<PropertyInfo>();
25+
checkedPropertyInfo.Setup(propertyInfo => propertyInfo.PropertyType).Returns(typeof(bool));
26+
checkedPropertyInfo.Setup(propertyInfo => propertyInfo.Name).Returns("Checked");
27+
var tagHelperDescriptorProvider = new TagHelperDescriptorProvider(
28+
new TagHelperDescriptor[]
29+
{
30+
new TagHelperDescriptor("p", "PTagHelper", ContentBehavior.None),
31+
new TagHelperDescriptor("input",
32+
"InputTagHelper",
33+
ContentBehavior.None,
34+
new TagHelperAttributeDescriptor[] {
35+
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo.Object)
36+
}),
37+
new TagHelperDescriptor("input",
38+
"InputTagHelper2",
39+
ContentBehavior.None,
40+
new TagHelperAttributeDescriptor[] {
41+
new TagHelperAttributeDescriptor("type", inputTypePropertyInfo.Object),
42+
new TagHelperAttributeDescriptor("checked", checkedPropertyInfo.Object)
43+
}),
44+
});
45+
46+
// Act & Assert
47+
RunTagHelperTest(testName: "BasicTagHelpers",
48+
baseLineName: "BasicTagHelpers.CustomAttributeCodeGenerator",
49+
tagHelperDescriptorProvider: tagHelperDescriptorProvider,
50+
hostConfig: (host) =>
51+
{
52+
return new CodeBuilderReplacingHost(host);
53+
});
54+
}
55+
56+
private class CodeBuilderReplacingHost : RazorEngineHost
57+
{
58+
public CodeBuilderReplacingHost(RazorEngineHost originalHost)
59+
: base(new CSharpRazorCodeLanguage())
60+
{
61+
GeneratedClassContext = originalHost.GeneratedClassContext;
62+
}
63+
64+
public override CodeBuilder DecorateCodeBuilder(CodeBuilder incomingBuilder, CodeBuilderContext context)
65+
{
66+
return new AttributeCodeGeneratorReplacingCodeBuilder(context);
67+
}
68+
}
69+
70+
private class AttributeCodeGeneratorReplacingCodeBuilder : CSharpCodeBuilder
71+
{
72+
public AttributeCodeGeneratorReplacingCodeBuilder(CodeBuilderContext context)
73+
: base(context)
74+
{
75+
}
76+
77+
protected override CSharpCodeVisitor CreateCSharpCodeVisitor([NotNull] CSharpCodeWriter writer,
78+
[NotNull] CodeBuilderContext context)
79+
{
80+
var bodyVisitor = base.CreateCSharpCodeVisitor(writer, context);
81+
82+
bodyVisitor.TagHelperRenderer.AttributeValueCodeRenderer = new CustomTagHelperAttributeCodeRenderer();
83+
84+
return bodyVisitor;
85+
}
86+
}
87+
88+
private class CustomTagHelperAttributeCodeRenderer : TagHelperAttributeValueCodeRenderer
89+
{
90+
public override void RenderAttributeValue([NotNull] TagHelperAttributeDescriptor attributeInfo,
91+
[NotNull] CSharpCodeWriter writer,
92+
[NotNull] CodeBuilderContext context,
93+
[NotNull] Action<CSharpCodeWriter> renderAttributeValue)
94+
{
95+
writer.Write("**From custom attribute code renderer**: ");
96+
97+
base.RenderAttributeValue(attributeInfo, writer, context, renderAttributeValue);
98+
}
99+
}
100+
}
101+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Linq;
6+
using Microsoft.AspNet.Razor.Parser;
7+
using Microsoft.AspNet.Razor.Parser.TagHelpers.Internal;
8+
using Microsoft.AspNet.Razor.TagHelpers;
9+
10+
namespace Microsoft.AspNet.Razor.Test.Generator
11+
{
12+
public class TagHelperTestBase : CSharpRazorCodeGeneratorTest
13+
{
14+
protected void RunTagHelperTest(string testName,
15+
string baseLineName = null,
16+
TagHelperDescriptorProvider tagHelperDescriptorProvider = null,
17+
Func<RazorEngineHost, RazorEngineHost> hostConfig = null)
18+
{
19+
RunTest(name: testName,
20+
baselineName: baseLineName,
21+
templateEngineConfig: (engine) =>
22+
{
23+
return new TagHelperTemplateEngine(engine, tagHelperDescriptorProvider);
24+
},
25+
hostConfig: hostConfig);
26+
}
27+
28+
private class TagHelperTemplateEngine : RazorTemplateEngine
29+
{
30+
private TagHelperDescriptorProvider _tagHelperDescriptorProvider;
31+
32+
public TagHelperTemplateEngine(RazorTemplateEngine engine, TagHelperDescriptorProvider tagHelperDescriptorProvider)
33+
: base(engine.Host)
34+
{
35+
_tagHelperDescriptorProvider = tagHelperDescriptorProvider;
36+
}
37+
38+
protected internal override RazorParser CreateParser()
39+
{
40+
var parser = base.CreateParser();
41+
var tagHelperParseTreeRewriter = new TagHelperParseTreeRewriter(_tagHelperDescriptorProvider);
42+
43+
for (var i = 0; i < parser.Optimizers.Count; i++)
44+
{
45+
if (parser.Optimizers[i] is TagHelperParseTreeRewriter)
46+
{
47+
parser.Optimizers[i] = tagHelperParseTreeRewriter;
48+
break;
49+
}
50+
}
51+
52+
return parser;
53+
}
54+
}
55+
}
56+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#pragma checksum "BasicTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8d60e58d54168749dc71a0d6d3a95887b2adb5e7"
2+
namespace TestOutput
3+
{
4+
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
5+
using System.Threading.Tasks;
6+
7+
public class BasicTagHelpers
8+
{
9+
#line hidden
10+
private System.IO.TextWriter __tagHelperStringValueBuffer = null;
11+
private TagHelperExecutionContext __tagHelperExecutionContext = null;
12+
private TagHelperRunner __tagHelperRunner = new TagHelperRunner();
13+
private TagHelperScopeManager __tagHelperScopeManager = new TagHelperScopeManager();
14+
private PTagHelper __PTagHelper = null;
15+
private InputTagHelper __InputTagHelper = null;
16+
private InputTagHelper2 __InputTagHelper2 = null;
17+
#line hidden
18+
public BasicTagHelpers()
19+
{
20+
}
21+
22+
#pragma warning disable 1998
23+
public override async Task ExecuteAsync()
24+
{
25+
Instrumentation.BeginContext(0, 47, true);
26+
WriteLiteral("<div class=\"randomNonTagHelperAttribute\">\r\n ");
27+
Instrumentation.EndContext();
28+
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p");
29+
__PTagHelper = CreateTagHelper<PTagHelper>();
30+
__tagHelperExecutionContext.Add(__PTagHelper);
31+
__tagHelperExecutionContext.AddHtmlAttribute("class", "Hello World");
32+
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
33+
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
34+
Instrumentation.BeginContext(70, 10, true);
35+
WriteLiteral("\r\n ");
36+
Instrumentation.EndContext();
37+
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("p");
38+
__PTagHelper = CreateTagHelper<PTagHelper>();
39+
__tagHelperExecutionContext.Add(__PTagHelper);
40+
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
41+
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
42+
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
43+
__tagHelperExecutionContext = __tagHelperScopeManager.End();
44+
Instrumentation.BeginContext(87, 10, true);
45+
WriteLiteral("\r\n ");
46+
Instrumentation.EndContext();
47+
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input");
48+
__InputTagHelper = CreateTagHelper<InputTagHelper>();
49+
__tagHelperExecutionContext.Add(__InputTagHelper);
50+
__InputTagHelper.Type = **From custom attribute code renderer**: "text";
51+
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
52+
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
53+
__tagHelperExecutionContext.Add(__InputTagHelper2);
54+
__InputTagHelper2.Type = __InputTagHelper.Type;
55+
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
56+
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
57+
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
58+
__tagHelperExecutionContext = __tagHelperScopeManager.End();
59+
Instrumentation.BeginContext(118, 10, true);
60+
WriteLiteral("\r\n ");
61+
Instrumentation.EndContext();
62+
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("input");
63+
__InputTagHelper = CreateTagHelper<InputTagHelper>();
64+
__tagHelperExecutionContext.Add(__InputTagHelper);
65+
__InputTagHelper.Type = **From custom attribute code renderer**: "checkbox";
66+
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
67+
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
68+
__tagHelperExecutionContext.Add(__InputTagHelper2);
69+
__InputTagHelper2.Type = __InputTagHelper.Type;
70+
__InputTagHelper2.Checked = **From custom attribute code renderer**: true;
71+
__tagHelperExecutionContext.AddTagHelperAttribute("checked", __InputTagHelper2.Checked);
72+
__tagHelperExecutionContext.Output = __tagHelperRunner.RunAsync(__tagHelperExecutionContext).Result;
73+
WriteLiteral(__tagHelperExecutionContext.Output.GenerateStartTag());
74+
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
75+
__tagHelperExecutionContext = __tagHelperScopeManager.End();
76+
Instrumentation.BeginContext(167, 6, true);
77+
WriteLiteral("\r\n ");
78+
Instrumentation.EndContext();
79+
WriteLiteral(__tagHelperExecutionContext.Output.GenerateEndTag());
80+
__tagHelperExecutionContext = __tagHelperScopeManager.End();
81+
Instrumentation.BeginContext(177, 8, true);
82+
WriteLiteral("\r\n</div>");
83+
Instrumentation.EndContext();
84+
}
85+
#pragma warning restore 1998
86+
}
87+
}

0 commit comments

Comments
 (0)