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

Commit 6a99ea3

Browse files
author
N. Taylor Mullen
committed
Add test for TagHelperAttributeCodeGenerator extensibility.
- Tested that we can successfully plugin our own TagHelperAttributeCodeGenerator. - Moved some existing TagHelper test logic into its own base type to enhance code reusability. #119
1 parent bccc3d4 commit 6a99ea3

File tree

6 files changed

+235
-41
lines changed

6 files changed

+235
-41
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,14 @@ public void CSharpCodeGeneratorDoesNotRenderLinePragmasIfGenerateLinePragmasIsSe
390390
[Fact]
391391
public void CSharpCodeGeneratorRendersHelpersBlockCorrectlyWhenInstanceHelperRequested()
392392
{
393-
RunTest("Helpers", baselineName: "Helpers.Instance", hostConfig: h => h.StaticHelpers = false);
393+
RunTest("Helpers",
394+
baselineName: "Helpers.Instance",
395+
hostConfig: host =>
396+
{
397+
host.StaticHelpers = false;
398+
399+
return host;
400+
});
394401
}
395402

396403
// TODO: This should be re-added once instrumentation support has been added

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

Lines changed: 1 addition & 37 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("SingleTagHelper")]
@@ -74,38 +71,5 @@ public void TagHelpers_ContentBehavior()
7471
// Act & Assert
7572
RunTagHelperTest("ContentBehaviorTagHelpers", tagHelperProvider);
7673
}
77-
78-
private void RunTagHelperTest(string testName, TagHelperDescriptorProvider tagHelperProvider)
79-
{
80-
RunTest(
81-
name: testName,
82-
templateEngineConfig: (engine) =>
83-
{
84-
return new TagHelperTemplateEngine(engine, tagHelperProvider);
85-
});
86-
}
87-
88-
private class TagHelperTemplateEngine : RazorTemplateEngine
89-
{
90-
private TagHelperDescriptorProvider _tagHelperProvider;
91-
92-
public TagHelperTemplateEngine(RazorTemplateEngine engine, TagHelperDescriptorProvider tagHelperProvider)
93-
: base(engine.Host)
94-
{
95-
_tagHelperProvider = tagHelperProvider;
96-
}
97-
98-
protected internal override RazorParser CreateParser()
99-
{
100-
var parser = base.CreateParser();
101-
var optimizers = parser.Optimizers.Where(opmzr => !(opmzr is TagHelperParseTreeRewriter));
102-
103-
parser.Optimizers = optimizers.Concat(new[] {
104-
new TagHelperParseTreeRewriter(_tagHelperProvider)
105-
}).ToList();
106-
107-
return parser;
108-
}
109-
}
11074
}
11175
}

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
{
@@ -132,7 +132,7 @@ private void RunTestInternal(string name,
132132
};
133133
if (hostConfig != null)
134134
{
135-
hostConfig(host);
135+
host = hostConfig(host);
136136
}
137137

138138
host.IsIndentingWithTabs = withTabs;
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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 TagHelperAttributeCodeGeneratorTests : TagHelperTestBase
16+
{
17+
[Fact]
18+
public void TagHelpers_CanReplaceAttributeCodeGeneratorLogic()
19+
{
20+
var inputTypePropertyInfo = new Mock<PropertyInfo>();
21+
inputTypePropertyInfo.Setup(ipi => ipi.PropertyType).Returns(typeof(string));
22+
inputTypePropertyInfo.Setup(ipi => ipi.Name).Returns("Type");
23+
var checkedPropertyInfo = new Mock<PropertyInfo>();
24+
checkedPropertyInfo.Setup(ipi => ipi.PropertyType).Returns(typeof(bool));
25+
checkedPropertyInfo.Setup(ipi => ipi.Name).Returns("Checked");
26+
// Arrange
27+
var tagHelperProvider = 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+
tagHelperProvider: tagHelperProvider,
50+
hostConfig: (host) =>
51+
{
52+
return new CodeBuilderReplacingHost();
53+
});
54+
}
55+
56+
private class CodeBuilderReplacingHost : RazorEngineHost
57+
{
58+
public CodeBuilderReplacingHost()
59+
: base(new CSharpRazorCodeLanguage())
60+
{
61+
}
62+
63+
public override CodeBuilder DecorateCodeBuilder(CodeBuilder incomingBuilder, CodeBuilderContext context)
64+
{
65+
return new AttributeCodeGeneratorReplacingCodeBuilder(context);
66+
}
67+
}
68+
69+
private class AttributeCodeGeneratorReplacingCodeBuilder : CSharpCodeBuilder
70+
{
71+
public AttributeCodeGeneratorReplacingCodeBuilder(CodeBuilderContext context)
72+
: base(context)
73+
{
74+
}
75+
76+
protected override CSharpCodeVisitor DecorateCSharpCodeVisitor([NotNull] CSharpCodeWriter writer,
77+
[NotNull] CodeBuilderContext context,
78+
[NotNull] CSharpCodeVisitor incomingVisitor)
79+
{
80+
incomingVisitor.TagHelperRenderer =
81+
new CSharpTagHelperCodeRenderer(incomingVisitor,
82+
new CustomTagHelperAttributeCodeGenerator(),
83+
writer,
84+
context);
85+
86+
return base.DecorateCSharpCodeVisitor(writer, context, incomingVisitor);
87+
}
88+
}
89+
90+
private class CustomTagHelperAttributeCodeGenerator : TagHelperAttributeCodeGenerator
91+
{
92+
public override void GenerateCode([NotNull]TagHelperAttributeDescriptor attributeInfo,
93+
[NotNull]CSharpCodeWriter writer,
94+
[NotNull]CodeGeneratorContext context,
95+
[NotNull]Action<CSharpCodeWriter> renderAttributeValue)
96+
{
97+
writer.Write("**From custom attribute code generator**: ");
98+
99+
base.GenerateCode(attributeInfo, writer, context, renderAttributeValue);
100+
}
101+
}
102+
}
103+
}
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, TagHelperDescriptorProvider tagHelperProvider)
15+
{
16+
RunTagHelperTest(testName, testName, tagHelperProvider, (host) => host);
17+
}
18+
19+
protected void RunTagHelperTest(string testName,
20+
string baseLineName,
21+
TagHelperDescriptorProvider tagHelperProvider,
22+
Func<RazorEngineHost, RazorEngineHost> hostConfig)
23+
{
24+
RunTest(name: testName,
25+
baselineName: baseLineName,
26+
templateEngineConfig: (engine) =>
27+
{
28+
return new TagHelperTemplateEngine(engine, tagHelperProvider);
29+
},
30+
hostConfig: hostConfig);
31+
}
32+
33+
private class TagHelperTemplateEngine : RazorTemplateEngine
34+
{
35+
private TagHelperDescriptorProvider _tagHelperProvider;
36+
37+
public TagHelperTemplateEngine(RazorTemplateEngine engine, TagHelperDescriptorProvider tagHelperProvider)
38+
: base(engine.Host)
39+
{
40+
_tagHelperProvider = tagHelperProvider;
41+
}
42+
43+
protected internal override RazorParser CreateParser()
44+
{
45+
var parser = base.CreateParser();
46+
var optimizers = parser.Optimizers.Where(opmzr => !(opmzr is TagHelperParseTreeRewriter));
47+
48+
parser.Optimizers = optimizers.Concat(new[] {
49+
new TagHelperParseTreeRewriter(_tagHelperProvider)
50+
}).ToList();
51+
52+
return parser;
53+
}
54+
}
55+
}
56+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
namespace TestOutput
2+
{
3+
using System.Threading.Tasks;
4+
5+
public class BasicTagHelpers
6+
{
7+
private ITagHelperManager __tagHelperManager { get; set; }
8+
#line hidden
9+
public BasicTagHelpers()
10+
{
11+
}
12+
13+
#pragma warning disable 1998
14+
public override async Task ExecuteAsync()
15+
{
16+
var __tagHelperAttributeValue = string.Empty;
17+
PTagHelper __p_PTagHelper_None;
18+
InputTagHelper __input_InputTagHelper_None;
19+
InputTagHelper2 __input_InputTagHelper2_None;
20+
WriteLiteral("<div class=\"randomNonTagHelperAttribute\">\r\n ");
21+
__p_PTagHelper_None = __tagHelperManager.StartTagHelper<PTagHelper>();
22+
__tagHelperManager.AddHTMLAttribute("class", "Hello World");
23+
__tagHelperManager.StartActiveTagHelpers("p");
24+
__tagHelperManager.ExecuteTagHelpers();
25+
WriteLiteral(__tagHelperManager.GenerateTagStart());
26+
WriteLiteral("\r\n ");
27+
__p_PTagHelper_None = __tagHelperManager.StartTagHelper<PTagHelper>();
28+
__tagHelperManager.StartActiveTagHelpers("p");
29+
__tagHelperManager.ExecuteTagHelpers();
30+
WriteLiteral(__tagHelperManager.GenerateTagStart());
31+
WriteLiteral(__tagHelperManager.GenerateTagEnd());
32+
__tagHelperManager.EndTagHelpers();
33+
WriteLiteral("\r\n ");
34+
__input_InputTagHelper_None = __tagHelperManager.StartTagHelper<InputTagHelper>();
35+
__input_InputTagHelper_None.Type = **From custom attribute code generator**: "text";
36+
__tagHelperManager.AddTagHelperAttribute("type", __input_InputTagHelper_None.Type);
37+
__input_InputTagHelper2_None = __tagHelperManager.StartTagHelper<InputTagHelper2>();
38+
__input_InputTagHelper2_None.Type = __input_InputTagHelper_None.Type;
39+
__tagHelperManager.StartActiveTagHelpers("input");
40+
__tagHelperManager.ExecuteTagHelpers();
41+
WriteLiteral(__tagHelperManager.GenerateTagStart());
42+
WriteLiteral(__tagHelperManager.GenerateTagEnd());
43+
__tagHelperManager.EndTagHelpers();
44+
WriteLiteral("\r\n ");
45+
__input_InputTagHelper_None = __tagHelperManager.StartTagHelper<InputTagHelper>();
46+
__input_InputTagHelper_None.Type = **From custom attribute code generator**: "checkbox";
47+
__tagHelperManager.AddTagHelperAttribute("type", __input_InputTagHelper_None.Type);
48+
__input_InputTagHelper2_None = __tagHelperManager.StartTagHelper<InputTagHelper2>();
49+
__input_InputTagHelper2_None.Type = __input_InputTagHelper_None.Type;
50+
__input_InputTagHelper2_None.Checked = **From custom attribute code generator**: true;
51+
__tagHelperManager.AddTagHelperAttribute("checked", __input_InputTagHelper2_None.Checked);
52+
__tagHelperManager.StartActiveTagHelpers("input");
53+
__tagHelperManager.ExecuteTagHelpers();
54+
WriteLiteral(__tagHelperManager.GenerateTagStart());
55+
WriteLiteral(__tagHelperManager.GenerateTagEnd());
56+
__tagHelperManager.EndTagHelpers();
57+
WriteLiteral("\r\n ");
58+
WriteLiteral(__tagHelperManager.GenerateTagEnd());
59+
__tagHelperManager.EndTagHelpers();
60+
WriteLiteral("\r\n</div>");
61+
}
62+
#pragma warning restore 1998
63+
}
64+
}

0 commit comments

Comments
 (0)