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

Commit 1f61154

Browse files
author
N. Taylor Mullen
committed
Add tests to verify TagHelperDescriptorResolver functionality.
#99
1 parent ac7d5aa commit 1f61154

File tree

5 files changed

+271
-5
lines changed

5 files changed

+271
-5
lines changed
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
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.Collections.Generic;
6+
using System.Globalization;
7+
using System.Linq;
8+
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
9+
using Microsoft.AspNet.Razor.TagHelpers;
10+
using Microsoft.Internal.Web.Utils;
11+
using Xunit;
12+
13+
namespace Microsoft.AspNet.Razor.Runtime.Test.TagHelpers
14+
{
15+
public class TagHelperDescriptorResolverTest
16+
{
17+
private static readonly CompleteTagHelperDescriptorComparer DefaultDescriptorComparer =
18+
new CompleteTagHelperDescriptorComparer();
19+
20+
[Fact]
21+
public void DescriptorResolver_ResolvesOnlyTypeResolverProvidedTypes()
22+
{
23+
// Arrange
24+
var resolver = new TagHelperDescriptorResolver(
25+
new CustomTagHelperTypeResolver(
26+
new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
27+
{
28+
{ "lookupText1", new Type[]{ typeof(string), typeof(int) } },
29+
{ "lookupText2", new Type[]{ typeof(object) } }
30+
}));
31+
var expectedDescriptor = new TagHelperDescriptor("Object", "System.Object", ContentBehavior.None);
32+
33+
// Act
34+
var descriptors = resolver.Resolve("lookupText2");
35+
36+
// Assert
37+
var descriptor = Assert.Single(descriptors);
38+
Assert.Equal(descriptor, expectedDescriptor, DefaultDescriptorComparer);
39+
}
40+
41+
[Fact]
42+
public void DescriptorResolver_ResolvesMultipleTypes()
43+
{
44+
// Arrange
45+
var resolver = new TagHelperDescriptorResolver(
46+
new CustomTagHelperTypeResolver(
47+
new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
48+
{
49+
{ "lookupText", new Type[]{ typeof(string), typeof(int) } },
50+
}));
51+
var expectedDescriptors = new TagHelperDescriptor[]
52+
{
53+
new TagHelperDescriptor("String", "System.String", ContentBehavior.None),
54+
new TagHelperDescriptor("Int32", "System.Int32", ContentBehavior.None),
55+
};
56+
57+
// Act
58+
var descriptors = resolver.Resolve("lookupText").ToArray();
59+
60+
// Assert
61+
Assert.Equal(descriptors.Length, 2);
62+
Assert.Equal(descriptors, expectedDescriptors, DefaultDescriptorComparer);
63+
}
64+
65+
[Fact]
66+
public void DescriptorResolver_ResolvesCustomTypeWithConventionName()
67+
{
68+
// Arrange
69+
var resolver = new TagHelperDescriptorResolver(
70+
new CustomTagHelperTypeResolver(
71+
new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
72+
{
73+
{ "lookupText", new Type[]{ typeof(SingleAttributeTagHelper) } },
74+
}));
75+
var intProp = typeof(SingleAttributeTagHelper).GetProperty(nameof(SingleAttributeTagHelper.IntAttribute));
76+
var expectedDescriptor = new TagHelperDescriptor(
77+
"SingleAttribute",
78+
typeof(SingleAttributeTagHelper).FullName,
79+
ContentBehavior.None,
80+
new[] {
81+
new TagHelperAttributeDescriptor(nameof(SingleAttributeTagHelper.IntAttribute), intProp)
82+
});
83+
84+
// Act
85+
var descriptors = resolver.Resolve("lookupText").ToArray();
86+
87+
// Assert
88+
var descriptor = Assert.Single(descriptors);
89+
Assert.Equal(descriptor, expectedDescriptor, DefaultDescriptorComparer);
90+
}
91+
92+
[Fact]
93+
public void DescriptorResolver_OnlyResolvesPropertiesWithGetAndSet()
94+
{
95+
// Arrange
96+
var resolver = new TagHelperDescriptorResolver(
97+
new CustomTagHelperTypeResolver(
98+
new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
99+
{
100+
{ "lookupText", new Type[]{ typeof(TwoInvalidAttributeTagHelper) } },
101+
}));
102+
var validProp = typeof(TwoInvalidAttributeTagHelper).GetProperty(nameof(TwoInvalidAttributeTagHelper.ValidAttribute));
103+
var expectedDescriptor = new TagHelperDescriptor(
104+
"TwoInvalidAttribute",
105+
typeof(TwoInvalidAttributeTagHelper).FullName,
106+
ContentBehavior.None,
107+
new[] {
108+
new TagHelperAttributeDescriptor(nameof(TwoInvalidAttributeTagHelper.ValidAttribute), validProp)
109+
});
110+
111+
// Act
112+
var descriptors = resolver.Resolve("lookupText").ToArray();
113+
114+
// Assert
115+
var descriptor = Assert.Single(descriptors);
116+
Assert.Equal(descriptor, expectedDescriptor, DefaultDescriptorComparer);
117+
}
118+
119+
[Fact]
120+
public void DescriptorResolver_DoesntResolveTypesForInvalidLookupText()
121+
{
122+
// Arrange
123+
var resolver = new TagHelperDescriptorResolver(
124+
new CustomTagHelperTypeResolver(
125+
new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
126+
{
127+
{ "lookupText1", new Type[]{ typeof(string), typeof(int) } },
128+
{ "lookupText2", new Type[]{ typeof(object) } }
129+
}));
130+
131+
// Act
132+
var descriptors = resolver.Resolve("lookupText").ToArray();
133+
134+
// Assert
135+
Assert.Empty(descriptors);
136+
}
137+
138+
[Fact]
139+
public void DescriptorResolver_ThrowsWhenAttributesConflict()
140+
{
141+
// Arrange
142+
var resolver = new TagHelperDescriptorResolver(
143+
new CustomTagHelperTypeResolver(
144+
new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
145+
{
146+
{ "lookupText", new Type[]{ typeof(SingleAttributeTagHelper),
147+
typeof(TestingNamespace.SingleAttributeTagHelper) } },
148+
}));
149+
var expectedError = string.Format(
150+
CultureInfo.InvariantCulture,
151+
"You cannot have multiple TagHelpers that target the same HTML attribute name with " +
152+
"different types. TagHelper '{0}' targets the '{1}' HTML attribute with type '{2}' " +
153+
"which conflicts with TagHelper '{3}' that expects the '{1}' attribute to be of type '{4}'.",
154+
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.TestingNamespace.SingleAttributeTagHelper",
155+
"IntAttribute",
156+
"System.String",
157+
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.TagHelperDescriptorResolverTest" +
158+
"+SingleAttributeTagHelper",
159+
"System.Int32");
160+
161+
// Act & Assert
162+
var ex = Assert.Throws<InvalidOperationException>(() =>
163+
{
164+
resolver.Resolve("lookupText");
165+
});
166+
Assert.Equal(expectedError, ex.Message);
167+
}
168+
169+
private class CustomTagHelperTypeResolver : ITagHelperTypeResolver
170+
{
171+
private Dictionary<string, IEnumerable<Type>> _lookupValues;
172+
173+
public CustomTagHelperTypeResolver(Dictionary<string, IEnumerable<Type>> lookupValues)
174+
{
175+
_lookupValues = lookupValues;
176+
}
177+
178+
public IEnumerable<Type> Resolve(string lookupText)
179+
{
180+
IEnumerable<Type> types;
181+
182+
_lookupValues.TryGetValue(lookupText, out types);
183+
184+
return types ?? Enumerable.Empty<Type>();
185+
}
186+
}
187+
188+
private class SingleAttributeTagHelper
189+
{
190+
public int IntAttribute { get; set; }
191+
}
192+
193+
private class TwoInvalidAttributeTagHelper
194+
{
195+
public string ValidAttribute { get; set; }
196+
public string InvalidNoGetAttribute { set { } }
197+
public string InvalidNoSetAttribute { get { return string.Empty; } }
198+
}
199+
200+
private class CompleteTagHelperDescriptorComparer : TagHelperDescriptorComparer
201+
{
202+
public new bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
203+
{
204+
return base.Equals(descriptorX, descriptorY) &&
205+
descriptorX.Attributes.SequenceEqual(descriptorY.Attributes,
206+
CompleteTagHelperAttributeDescriptorComparer.Default);
207+
}
208+
209+
public new int GetHashCode(TagHelperDescriptor descriptor)
210+
{
211+
return HashCodeCombiner.Start()
212+
.Add(base.GetHashCode())
213+
.Add(descriptor.Attributes)
214+
.CombinedHash;
215+
}
216+
}
217+
218+
private class CompleteTagHelperAttributeDescriptorComparer : IEqualityComparer<TagHelperAttributeDescriptor>
219+
{
220+
public static readonly CompleteTagHelperAttributeDescriptorComparer Default =
221+
new CompleteTagHelperAttributeDescriptorComparer();
222+
223+
public bool Equals(TagHelperAttributeDescriptor descriptorX, TagHelperAttributeDescriptor descriptorY)
224+
{
225+
return descriptorX.AttributeName == descriptorY.AttributeName &&
226+
descriptorX.AttributePropertyName == descriptorY.AttributePropertyName;
227+
}
228+
229+
public int GetHashCode(TagHelperAttributeDescriptor descriptor)
230+
{
231+
return HashCodeCombiner.Start()
232+
.Add(descriptor.AttributeName)
233+
.Add(descriptor.AttributePropertyName)
234+
.CombinedHash;
235+
}
236+
}
237+
}
238+
239+
namespace TestingNamespace
240+
{
241+
public class SingleAttributeTagHelper
242+
{
243+
// Conflicts with the SingleAttributeTagHelper in the namespace above.
244+
public string IntAttribute { get; set; }
245+
}
246+
}
247+
}

test/Microsoft.AspNet.Razor.Runtime.Test/project.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"dependencies": {
3+
"Microsoft.AspNet.Razor.Runtime": "",
34
"Microsoft.AspNet.Razor.Test": ""
45
},
56
"commands": {

test/Microsoft.AspNet.Razor.Test/Generator/CodeTree/CSharpPaddingBuilderTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Microsoft.AspNet.Razor.Parser;
1010
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
1111
using Microsoft.AspNet.Razor.TagHelpers;
12+
using Microsoft.AspNet.Razor.Test.TagHelpers;
1213
using Xunit;
1314

1415
namespace Microsoft.AspNet.Razor.Test.Generator
@@ -222,7 +223,7 @@ private static Span[] GenerateSpans(string text, SpanKind spanKind, int spanInde
222223
{
223224
Assert.True(spanIndex > 0);
224225

225-
var parser = new RazorParser(new TagHelperDescriptorResolver(),
226+
var parser = new RazorParser(new TestTagHelperDescriptorResolver(),
226227
new CSharpCodeParser(),
227228
new HtmlMarkupParser());
228229

test/Microsoft.AspNet.Razor.Test/Parser/RazorParserTest.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
using System.IO;
66
using Microsoft.AspNet.Razor.Parser;
77
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
8-
using Microsoft.AspNet.Razor.TagHelpers;
98
using Microsoft.AspNet.Razor.Test.Framework;
9+
using Microsoft.AspNet.Razor.Test.TagHelpers;
1010
using Xunit;
1111

1212
namespace Microsoft.AspNet.Razor.Test.Parser
@@ -42,7 +42,7 @@ public void ParseMethodCallsParseDocumentOnMarkupParserAndReturnsResults()
4242
var factory = SpanFactory.CreateCsHtml();
4343

4444
// Arrange
45-
RazorParser parser = new RazorParser(new TagHelperDescriptorResolver(),
45+
RazorParser parser = new RazorParser(new TestTagHelperDescriptorResolver(),
4646
new CSharpCodeParser(),
4747
new HtmlMarkupParser());
4848

@@ -64,7 +64,7 @@ public void ParseMethodUsesProvidedParserListenerIfSpecified()
6464
var factory = SpanFactory.CreateCsHtml();
6565

6666
// Arrange
67-
RazorParser parser = new RazorParser(new TagHelperDescriptorResolver(),
67+
RazorParser parser = new RazorParser(new TestTagHelperDescriptorResolver(),
6868
new CSharpCodeParser(),
6969
new HtmlMarkupParser());
7070

@@ -94,7 +94,7 @@ private static void RunParseWithListenerTest(Action<RazorParser, TextReader> par
9494
// Arrange
9595
ParserBase markupParser = new MockMarkupParser();
9696
ParserBase codeParser = new CSharpCodeParser();
97-
RazorParser parser = new RazorParser(new TagHelperDescriptorResolver(), codeParser, markupParser);
97+
RazorParser parser = new RazorParser(new TestTagHelperDescriptorResolver(), codeParser, markupParser);
9898
TextReader expectedReader = new StringReader("foo");
9999

100100
// Act
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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.Collections.Generic;
5+
using System.Linq;
6+
using Microsoft.AspNet.Razor.TagHelpers;
7+
8+
namespace Microsoft.AspNet.Razor.Test.TagHelpers
9+
{
10+
internal class TestTagHelperDescriptorResolver : ITagHelperDescriptorResolver
11+
{
12+
public IEnumerable<TagHelperDescriptor> Resolve(string lookupText)
13+
{
14+
return Enumerable.Empty<TagHelperDescriptor>();
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)