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

Commit

Permalink
Add tests to validate @addtaghelper directive.
Browse files Browse the repository at this point in the history
- Fixed existing tests to work with new RazorParser.
- Validated directive syntax tree creation, errors and code generation.

#111
  • Loading branch information
NTaylorMullen committed Sep 25, 2014
1 parent f1196df commit 369a300
Show file tree
Hide file tree
Showing 20 changed files with 320 additions and 95 deletions.
1 change: 1 addition & 0 deletions src/Microsoft.AspNet.Razor/Parser/CSharpCodeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public partial class CSharpCodeParser : TokenizerBackedParser<CSharpTokenizer, C

internal static ISet<string> DefaultKeywords = new HashSet<string>()
{
"addtaghelper",
"if",
"do",
"try",
Expand Down
5 changes: 5 additions & 0 deletions test/Microsoft.AspNet.Razor.Test/Framework/TestSpanBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,11 @@ public SpanConstructor AsRazorDirectiveAttribute(string key, string value)
return _self.With(new RazorDirectiveAttributeCodeGenerator(key, value));
}

public SpanConstructor AsAddTagHelper(string lookupText)
{
return _self.With(new AddTagHelperCodeGenerator(lookupText));
}

public SpanConstructor As(ISpanCodeGenerator codeGenerator)
{
return _self.With(codeGenerator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,16 +459,41 @@ private void OpenedIf(bool withTabs)
});
}

private static LineMapping BuildLineMapping(int documentAbsoluteIndex, int documentLineIndex, int generatedAbsoluteIndex, int generatedLineIndex, int characterOffsetIndex, int contentLength)
{
return BuildLineMapping(documentAbsoluteIndex, documentLineIndex, characterOffsetIndex, generatedAbsoluteIndex, generatedLineIndex, characterOffsetIndex, contentLength);
}

private static LineMapping BuildLineMapping(int documentAbsoluteIndex, int documentLineIndex, int documentCharacterOffsetIndex, int generatedAbsoluteIndex, int generatedLineIndex, int generatedCharacterOffsetIndex, int contentLength)
protected static LineMapping BuildLineMapping(int documentAbsoluteIndex,
int documentLineIndex,
int generatedAbsoluteIndex,
int generatedLineIndex,
int characterOffsetIndex,
int contentLength)
{
return BuildLineMapping(documentAbsoluteIndex,
documentLineIndex,
characterOffsetIndex,
generatedAbsoluteIndex,
generatedLineIndex,
characterOffsetIndex,
contentLength);
}

protected static LineMapping BuildLineMapping(int documentAbsoluteIndex,
int documentLineIndex,
int documentCharacterOffsetIndex,
int generatedAbsoluteIndex,
int generatedLineIndex,
int generatedCharacterOffsetIndex,
int contentLength)
{
return new LineMapping(
documentLocation: new MappingLocation(new SourceLocation(documentAbsoluteIndex, documentLineIndex, documentCharacterOffsetIndex), contentLength),
generatedLocation: new MappingLocation(new SourceLocation(generatedAbsoluteIndex, generatedLineIndex, generatedCharacterOffsetIndex), contentLength)
documentLocation: new MappingLocation(
new SourceLocation(documentAbsoluteIndex,
documentLineIndex,
documentCharacterOffsetIndex),
contentLength),
generatedLocation: new MappingLocation(
new SourceLocation(generatedAbsoluteIndex,
generatedLineIndex,
generatedCharacterOffsetIndex),
contentLength)
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// 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.Collections.Generic;
using System.Reflection;
using Microsoft.AspNet.Razor.Generator.Compiler;
using Microsoft.AspNet.Razor.TagHelpers;
using Moq;
using Xunit;
Expand All @@ -10,6 +12,29 @@ namespace Microsoft.AspNet.Razor.Test.Generator
{
public class CSharpTagHelperRenderingTest : TagHelperTestBase
{
[Fact]
public void CSharpCodeGeneratorCorrectlyGeneratesMappingsForAddTagHelperDirective()
{
RunTest("AddTagHelperDirective",
designTimeMode: true,
tabTest: TabTest.NoTabs,
expectedDesignTimePragmas: new List<LineMapping>()
{
BuildLineMapping(14, 0, 440, 14, 14, 11)
});
}

[Fact]
public void TagHelpers_DirectivesGenerateDesignTimeMappings()
{
// Act & Assert
RunTagHelperTest(testName: "AddTagHelperDirective",
designTimeMode: true,
tagHelperDescriptors: new[] {
new TagHelperDescriptor("p", "pTagHelper", ContentBehavior.None)
});
}

[Theory]
[InlineData("SingleTagHelper")]
[InlineData("BasicTagHelpers")]
Expand All @@ -26,50 +51,48 @@ public void TagHelpers_ChangeGeneratedOutput(string testType)
checkedPropertyInfo.Setup(ipi => ipi.PropertyType).Returns(typeof(bool));
checkedPropertyInfo.Setup(ipi => ipi.Name).Returns("Checked");
// Arrange
var tagHelperProvider = 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)
}),
});
var tagHelperDescriptors = 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, tagHelperProvider);
RunTagHelperTest(testType, tagHelperDescriptors);
}

[Fact]
public void TagHelpers_ContentBehavior()
{
// Arrange
var tagHelperProvider = new TagHelperDescriptorProvider(
new TagHelperDescriptor[]
{
var tagHelperDescriptors = 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", tagHelperProvider);
RunTagHelperTest("ContentBehaviorTagHelpers", tagHelperDescriptors);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.AspNet.Razor.Generator.Compiler.CSharp;
using Microsoft.AspNet.Razor.Parser;
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
using Microsoft.AspNet.Razor.TagHelpers;
using Xunit;

namespace Microsoft.AspNet.Razor.Test.Generator
Expand Down Expand Up @@ -221,7 +222,9 @@ private static Span[] GenerateSpans(string text, SpanKind spanKind, int spanInde
{
Assert.True(spanIndex > 0);

var parser = new RazorParser(new CSharpCodeParser(), new HtmlMarkupParser());
var parser = new RazorParser(new TagHelperDescriptorResolver(),
new CSharpCodeParser(),
new HtmlMarkupParser());

Span[] spans;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,28 @@ public void TagHelpers_CanReplaceAttributeCodeGeneratorLogic()
var checkedPropertyInfo = new Mock<PropertyInfo>();
checkedPropertyInfo.Setup(ipi => ipi.PropertyType).Returns(typeof(bool));
checkedPropertyInfo.Setup(ipi => ipi.Name).Returns("Checked");
var tagHelperProvider = 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)
}),
});
var tagHelperDescriptors = 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",
tagHelperProvider: tagHelperProvider,
tagHelperDescriptors: tagHelperDescriptors,
hostConfig: (host) =>
{
return new CodeBuilderReplacingHost();
Expand Down
85 changes: 71 additions & 14 deletions test/Microsoft.AspNet.Razor.Test/Generator/TagHelperTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,111 @@
// 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.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, TagHelperDescriptorProvider tagHelperProvider)
protected void RunTagHelperTest(string testName, IEnumerable<TagHelperDescriptor> tagHelperDescriptors)
{
RunTagHelperTest(testName, testName, tagHelperProvider, (host) => host);
RunTagHelperTest(testName, testName, tagHelperDescriptors, host => host);
}

protected void RunTagHelperTest(string testName,
bool designTimeMode,
IEnumerable<TagHelperDescriptor> tagHelperDescriptors)
{
RunTagHelperTest(testName, testName, designTimeMode, tagHelperDescriptors);
}

protected void RunTagHelperTest(string testName,
string baseLineName,
TagHelperDescriptorProvider tagHelperProvider,
IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
Func<RazorEngineHost, RazorEngineHost> hostConfig)
{
RunTagHelperTest(testName,
baseLineName,
designTimeMode: false,
tagHelperDescriptors: tagHelperDescriptors,
hostConfig: hostConfig);
}

protected void RunTagHelperTest(string testName,
string baseLineName,
bool designTimeMode,
IEnumerable<TagHelperDescriptor> tagHelperDescriptors)
{
RunTagHelperTest(testName,
baseLineName,
designTimeMode,
tagHelperDescriptors,
hostConfig: host => host);
}

protected void RunTagHelperTest(string testName,
string baseLineName,
bool designTimeMode,
IEnumerable<TagHelperDescriptor> tagHelperDescriptors,
Func<RazorEngineHost, RazorEngineHost> hostConfig)
{
RunTest(name: testName,
baselineName: baseLineName,
designTimeMode: designTimeMode,
tabTest: TabTest.NoTabs,
templateEngineConfig: (engine) =>
{
return new TagHelperTemplateEngine(engine, tagHelperProvider);
return new TagHelperTemplateEngine(engine, tagHelperDescriptors);
},
hostConfig: hostConfig);
}

private class CustomTagHelperDescriptorResolver : ITagHelperDescriptorResolver
{
private IEnumerable<TagHelperDescriptor> _tagHelperDescriptors;
private bool _resolved;

public CustomTagHelperDescriptorResolver(IEnumerable<TagHelperDescriptor> tagHelperDescriptors)
{
_tagHelperDescriptors = tagHelperDescriptors;
}

public IEnumerable<TagHelperDescriptor> Resolve(string lookupText)
{
if (!_resolved)
{
_resolved = true;

return _tagHelperDescriptors;
}
else
{
return Enumerable.Empty<TagHelperDescriptor>();
}
}
}

private class TagHelperTemplateEngine : RazorTemplateEngine
{
private TagHelperDescriptorProvider _tagHelperProvider;
private IEnumerable<TagHelperDescriptor> _tagHelperDescriptors;

public TagHelperTemplateEngine(RazorTemplateEngine engine, TagHelperDescriptorProvider tagHelperProvider)
public TagHelperTemplateEngine(RazorTemplateEngine engine,
IEnumerable<TagHelperDescriptor> tagHelperDescriptors)
: base(engine.Host)
{
_tagHelperProvider = tagHelperProvider;
_tagHelperDescriptors = tagHelperDescriptors;
}

protected internal override RazorParser CreateParser()
{
var parser = base.CreateParser();
var optimizers = parser.Optimizers.Where(opmzr => !(opmzr is TagHelperParseTreeRewriter));

parser.Optimizers = optimizers.Concat(new[] {
new TagHelperParseTreeRewriter(_tagHelperProvider)
}).ToList();

return parser;
return new RazorParser(new CustomTagHelperDescriptorResolver(_tagHelperDescriptors),
parser.CodeParser,
parser.MarkupParser);
}
}
}
Expand Down
Loading

0 comments on commit 369a300

Please sign in to comment.