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
This commit is contained in:
NTaylorMullen 2014-09-28 23:03:55 -07:00 committed by N. Taylor Mullen
parent 2b6b437952
commit 05d8193775
6 changed files with 261 additions and 49 deletions

View File

@ -387,7 +387,14 @@ namespace Microsoft.AspNet.Razor.Test.Generator
[Fact]
public void CSharpCodeGeneratorRendersHelpersBlockCorrectlyWhenInstanceHelperRequested()
{
RunTest("Helpers", baselineName: "Helpers.Instance", hostConfig: h => h.StaticHelpers = false);
RunTest("Helpers",
baselineName: "Helpers.Instance",
hostConfig: host =>
{
host.StaticHelpers = false;
return host;
});
}
[Fact]
@ -396,6 +403,8 @@ namespace Microsoft.AspNet.Razor.Test.Generator
RunTest("Instrumented", hostConfig: host =>
{
host.InstrumentedSourceFilePath = string.Format("~/{0}.cshtml", host.DefaultClassName);
return host;
});
}

View File

@ -1,17 +1,14 @@
// 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
public class CSharpTagHelperRenderingTest : TagHelperTestBase
{
[Theory]
[InlineData("TagHelpersInSection")]
@ -36,7 +33,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
});
// Act & Assert
RunTagHelperTest(testType, tagHelperDescriptorProvider);
RunTagHelperTest(testType, tagHelperDescriptorProvider: tagHelperDescriptorProvider);
}
[Theory]
@ -80,7 +77,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
});
// Act & Assert
RunTagHelperTest(testType, tagHelperDescriptorProvider);
RunTagHelperTest(testType, tagHelperDescriptorProvider: tagHelperDescriptorProvider);
}
[Fact]
@ -98,45 +95,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
});
// 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;
}
}
return parser;
}
RunTagHelperTest("ContentBehaviorTagHelpers", tagHelperDescriptorProvider: tagHelperDescriptorProvider);
}
}
}

View File

@ -37,7 +37,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
IList<LineMapping> expectedDesignTimePragmas = null,
TestSpan[] spans = null,
TabTest tabTest = TabTest.Both,
Action<RazorEngineHost> hostConfig = null,
Func<RazorEngineHost, RazorEngineHost> hostConfig = null,
Func<RazorTemplateEngine, RazorTemplateEngine> templateEngineConfig = null,
Action<GeneratorResults> onResults = null)
{
@ -93,7 +93,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
IList<LineMapping> expectedDesignTimePragmas,
TestSpan[] spans,
bool withTabs,
Action<RazorEngineHost> hostConfig,
Func<RazorEngineHost, RazorEngineHost> hostConfig,
Func<RazorTemplateEngine, RazorTemplateEngine> templateEngineConfig,
Action<GeneratorResults> onResults = null)
{
@ -130,7 +130,7 @@ namespace Microsoft.AspNet.Razor.Test.Generator
};
if (hostConfig != null)
{
hostConfig(host);
host = hostConfig(host);
}
host.IsIndentingWithTabs = withTabs;

View File

@ -0,0 +1,101 @@
// 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;
using System.Reflection;
using Microsoft.AspNet.Razor.Generator;
using Microsoft.AspNet.Razor.Generator.Compiler;
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
using Microsoft.AspNet.Razor.TagHelpers;
using Moq;
using Xunit;
namespace Microsoft.AspNet.Razor.Test.Generator
{
public class TagHelperAttributeValueCodeRendererTest : TagHelperTestBase
{
[Fact]
public void TagHelpers_CanReplaceAttributeCodeGeneratorLogic()
{
// Arrange
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 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(testName: "BasicTagHelpers",
baseLineName: "BasicTagHelpers.CustomAttributeCodeGenerator",
tagHelperDescriptorProvider: tagHelperDescriptorProvider,
hostConfig: (host) =>
{
return new CodeBuilderReplacingHost(host);
});
}
private class CodeBuilderReplacingHost : RazorEngineHost
{
public CodeBuilderReplacingHost(RazorEngineHost originalHost)
: base(new CSharpRazorCodeLanguage())
{
GeneratedClassContext = originalHost.GeneratedClassContext;
}
public override CodeBuilder DecorateCodeBuilder(CodeBuilder incomingBuilder, CodeBuilderContext context)
{
return new AttributeCodeGeneratorReplacingCodeBuilder(context);
}
}
private class AttributeCodeGeneratorReplacingCodeBuilder : CSharpCodeBuilder
{
public AttributeCodeGeneratorReplacingCodeBuilder(CodeBuilderContext context)
: base(context)
{
}
protected override CSharpCodeVisitor CreateCSharpCodeVisitor([NotNull] CSharpCodeWriter writer,
[NotNull] CodeBuilderContext context)
{
var bodyVisitor = base.CreateCSharpCodeVisitor(writer, context);
bodyVisitor.TagHelperRenderer.AttributeValueCodeRenderer = new CustomTagHelperAttributeCodeRenderer();
return bodyVisitor;
}
}
private class CustomTagHelperAttributeCodeRenderer : TagHelperAttributeValueCodeRenderer
{
public override void RenderAttributeValue([NotNull] TagHelperAttributeDescriptor attributeInfo,
[NotNull] CSharpCodeWriter writer,
[NotNull] CodeBuilderContext context,
[NotNull] Action<CSharpCodeWriter> renderAttributeValue)
{
writer.Write("**From custom attribute code renderer**: ");
base.RenderAttributeValue(attributeInfo, writer, context, renderAttributeValue);
}
}
}
}

View File

@ -0,0 +1,56 @@
// 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;
using System.Linq;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.TagHelpers.Internal;
using Microsoft.AspNet.Razor.TagHelpers;
namespace Microsoft.AspNet.Razor.Test.Generator
{
public class TagHelperTestBase : CSharpRazorCodeGeneratorTest
{
protected void RunTagHelperTest(string testName,
string baseLineName = null,
TagHelperDescriptorProvider tagHelperDescriptorProvider = null,
Func<RazorEngineHost, RazorEngineHost> hostConfig = null)
{
RunTest(name: testName,
baselineName: baseLineName,
templateEngineConfig: (engine) =>
{
return new TagHelperTemplateEngine(engine, tagHelperDescriptorProvider);
},
hostConfig: hostConfig);
}
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;
}
}
return parser;
}
}
}
}

View File

@ -0,0 +1,87 @@
#pragma checksum "BasicTagHelpers.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8d60e58d54168749dc71a0d6d3a95887b2adb5e7"
namespace TestOutput
{
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
using System.Threading.Tasks;
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();
private PTagHelper __PTagHelper = null;
private InputTagHelper __InputTagHelper = null;
private InputTagHelper2 __InputTagHelper2 = null;
#line hidden
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 = **From custom attribute code renderer**: "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 = **From custom attribute code renderer**: "checkbox";
__tagHelperExecutionContext.AddTagHelperAttribute("type", __InputTagHelper.Type);
__InputTagHelper2 = CreateTagHelper<InputTagHelper2>();
__tagHelperExecutionContext.Add(__InputTagHelper2);
__InputTagHelper2.Type = __InputTagHelper.Type;
__InputTagHelper2.Checked = **From custom attribute code renderer**: 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
}
}