Modify tests to use new ITagHelperDescriptorResolver signature.
- Updated all of the tests to use the new ITagHelperDescriptorResolver signature so instead of passing strings they now construct TagHelperDescriptorResolutionContexts. - Removed several tests from the AddOrRemoveTagHelperSpanVisitorTests. This was due to the change in responsibility of managing the found TagHelperDescriptors; the TagHelperDescriptorResolver now does this. - Added several new tests to verify the TagHelperDescriptorResolver manages resolved TagHelperDescriptors based on the given TagHelperDirectiveDescriptors. #214
This commit is contained in:
parent
c35d19142c
commit
c67ec264ed
|
|
@ -61,7 +61,8 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
}
|
||||
}
|
||||
|
||||
private static bool IsTagHelper(TypeInfo typeInfo)
|
||||
// Internal for testing.
|
||||
internal virtual bool IsTagHelper(TypeInfo typeInfo)
|
||||
{
|
||||
return typeInfo.IsPublic &&
|
||||
!typeInfo.IsAbstract &&
|
||||
|
|
|
|||
|
|
@ -15,44 +15,322 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
private static readonly string AssemblyName =
|
||||
typeof(TagHelperDescriptorFactoryTest).GetTypeInfo().Assembly.GetName().Name;
|
||||
|
||||
private static readonly Type Valid_PlainTagHelperType = typeof(Valid_PlainTagHelper);
|
||||
|
||||
private static readonly Type Valid_InheritedTagHelperType = typeof(Valid_InheritedTagHelper);
|
||||
|
||||
private static TagHelperDescriptor Valid_PlainTagHelperDescriptor
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TagHelperDescriptor("Valid_Plain",
|
||||
Valid_PlainTagHelperType.FullName,
|
||||
AssemblyName,
|
||||
ContentBehavior.None);
|
||||
}
|
||||
}
|
||||
|
||||
private static TagHelperDescriptor Valid_InheritedTagHelperDescriptor
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TagHelperDescriptor("Valid_Inherited",
|
||||
Valid_InheritedTagHelperType.FullName,
|
||||
AssemblyName,
|
||||
ContentBehavior.None);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("MyType, MyAssembly", "MyAssembly")]
|
||||
[InlineData("MyAssembly2", "MyAssembly2")]
|
||||
public void Resolve_AllowsOverridenResolveDescriptorsInAssembly(string lookupText, string expectedAssemblyName)
|
||||
{
|
||||
// Arrange
|
||||
var tagHelperDescriptorResolver = new TestTagHelperDescriptorResolver();
|
||||
var tagHelperDescriptorResolver = new AssemblyCheckingTagHelperDescriptorResolver();
|
||||
var context = new TagHelperDescriptorResolutionContext(
|
||||
new[] { new TagHelperDirectiveDescriptor(lookupText, TagHelperDirectiveType.AddTagHelper) });
|
||||
|
||||
// Act
|
||||
tagHelperDescriptorResolver.Resolve(lookupText);
|
||||
tagHelperDescriptorResolver.Resolve(context);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedAssemblyName, tagHelperDescriptorResolver.CalledWithAssemblyName);
|
||||
}
|
||||
|
||||
public static TheoryData ResolveDirectiveDescriptorsData
|
||||
{
|
||||
get
|
||||
{
|
||||
var assemblyA = AssemblyName;
|
||||
var stringType = typeof(string);
|
||||
|
||||
var assemblyB = stringType.GetTypeInfo().Assembly.GetName().Name;
|
||||
|
||||
// We're treating 'string' as a TagHelper so we can test TagHelpers in multiple assemblies without
|
||||
// building a separate assembly with a single TagHelper.
|
||||
var stringTagHelperDescriptor =
|
||||
new TagHelperDescriptor("string",
|
||||
"System.String",
|
||||
assemblyB,
|
||||
ContentBehavior.None);
|
||||
|
||||
return new TheoryData<Dictionary<string, IEnumerable<Type>>, // descriptorAssemblyLookups
|
||||
IEnumerable<TagHelperDirectiveDescriptor>, // directiveDescriptors
|
||||
IEnumerable<TagHelperDescriptor>> // expectedDescriptors
|
||||
{
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType } }
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper)
|
||||
},
|
||||
new [] { Valid_PlainTagHelperDescriptor }
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType } },
|
||||
{ assemblyB, new [] { stringType } }
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyB, TagHelperDirectiveType.AddTagHelper)
|
||||
},
|
||||
new [] { Valid_PlainTagHelperDescriptor, stringTagHelperDescriptor }
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType } },
|
||||
{ assemblyB, new [] { stringType } }
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyB, TagHelperDirectiveType.RemoveTagHelper)
|
||||
},
|
||||
new [] { Valid_PlainTagHelperDescriptor }
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType, Valid_InheritedTagHelperType } },
|
||||
{ assemblyB, new [] { stringType } }
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyB, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.RemoveTagHelper)
|
||||
},
|
||||
new [] { stringTagHelperDescriptor }
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType, Valid_InheritedTagHelperType } }
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(
|
||||
Valid_PlainTagHelperType.FullName + ", " + assemblyA,
|
||||
TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper)
|
||||
},
|
||||
new [] { Valid_PlainTagHelperDescriptor, Valid_InheritedTagHelperDescriptor }
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType, Valid_InheritedTagHelperType } }
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(
|
||||
Valid_PlainTagHelperType.FullName + ", " + assemblyA,
|
||||
TagHelperDirectiveType.RemoveTagHelper)
|
||||
},
|
||||
new [] { Valid_InheritedTagHelperDescriptor }
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType, Valid_InheritedTagHelperType } },
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(
|
||||
Valid_PlainTagHelperType.FullName + ", " + assemblyA,
|
||||
TagHelperDirectiveType.RemoveTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper)
|
||||
},
|
||||
new [] { Valid_InheritedTagHelperDescriptor, Valid_PlainTagHelperDescriptor }
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType, Valid_InheritedTagHelperType } },
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
},
|
||||
new [] { Valid_InheritedTagHelperDescriptor, Valid_PlainTagHelperDescriptor }
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ResolveDirectiveDescriptorsData))]
|
||||
public void Resolve_ReturnsDescriptorsBasedOnDirectiveDescriptors(
|
||||
Dictionary<string, IEnumerable<Type>> descriptorAssemblyLookups,
|
||||
IEnumerable<TagHelperDirectiveDescriptor> directiveDescriptors,
|
||||
IEnumerable<TagHelperDescriptor> expectedDescriptors)
|
||||
{
|
||||
// Arrange
|
||||
var tagHelperDescriptorResolver =
|
||||
new TestTagHelperDescriptorResolver(
|
||||
new LookupBasedTagHelperTypeResolver(descriptorAssemblyLookups));
|
||||
var resolutionContext = new TagHelperDescriptorResolutionContext(directiveDescriptors);
|
||||
|
||||
// Act
|
||||
var descriptors = tagHelperDescriptorResolver.Resolve(resolutionContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors.Count(), descriptors.Count());
|
||||
|
||||
foreach (var expectedDescriptor in expectedDescriptors)
|
||||
{
|
||||
Assert.Contains(expectedDescriptor, descriptors, TagHelperDescriptorComparer.Default);
|
||||
}
|
||||
}
|
||||
|
||||
public static TheoryData ResolveDirectiveDescriptorsData_EmptyResult
|
||||
{
|
||||
get
|
||||
{
|
||||
var assemblyA = AssemblyName;
|
||||
var stringType = typeof(string);
|
||||
|
||||
var assemblyB = stringType.GetTypeInfo().Assembly.GetName().Name;
|
||||
var stringTagHelperDescriptor =
|
||||
new TagHelperDescriptor("string",
|
||||
"System.String",
|
||||
assemblyB,
|
||||
ContentBehavior.None);
|
||||
|
||||
return new TheoryData<Dictionary<string, IEnumerable<Type>>, // descriptorAssemblyLookups
|
||||
IEnumerable<TagHelperDirectiveDescriptor>> // directiveDescriptors
|
||||
{
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType } },
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.RemoveTagHelper),
|
||||
}
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType, Valid_InheritedTagHelperType } },
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(Valid_PlainTagHelperType.FullName + ", " + assemblyA, TagHelperDirectiveType.RemoveTagHelper),
|
||||
new TagHelperDirectiveDescriptor(Valid_InheritedTagHelperType.FullName + ", " + assemblyA, TagHelperDirectiveType.RemoveTagHelper)
|
||||
}
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType, Valid_InheritedTagHelperType } },
|
||||
{ assemblyB, new [] { stringType } },
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyB, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.RemoveTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyB, TagHelperDirectiveType.RemoveTagHelper)
|
||||
}
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>
|
||||
{
|
||||
{ assemblyA, new [] { Valid_PlainTagHelperType, Valid_InheritedTagHelperType } },
|
||||
{ assemblyB, new [] { stringType } },
|
||||
},
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(assemblyB, TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor(Valid_PlainTagHelperType.FullName + ", " + assemblyA, TagHelperDirectiveType.RemoveTagHelper),
|
||||
new TagHelperDirectiveDescriptor(Valid_InheritedTagHelperType.FullName + ", " + assemblyA, TagHelperDirectiveType.RemoveTagHelper),
|
||||
new TagHelperDirectiveDescriptor(stringType.FullName + ", " + assemblyB, TagHelperDirectiveType.RemoveTagHelper)
|
||||
}
|
||||
},
|
||||
{
|
||||
new Dictionary<string, IEnumerable<Type>>(),
|
||||
new []
|
||||
{
|
||||
new TagHelperDirectiveDescriptor(assemblyA, TagHelperDirectiveType.RemoveTagHelper),
|
||||
new TagHelperDirectiveDescriptor(Valid_PlainTagHelperType.FullName + ", " + assemblyA, TagHelperDirectiveType.RemoveTagHelper),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ResolveDirectiveDescriptorsData_EmptyResult))]
|
||||
public void Resolve_CanReturnEmptyDescriptorsBasedOnDirectiveDescriptors(
|
||||
Dictionary<string, IEnumerable<Type>> descriptorAssemblyLookups,
|
||||
IEnumerable<TagHelperDirectiveDescriptor> directiveDescriptors)
|
||||
{
|
||||
// Arrange
|
||||
var tagHelperDescriptorResolver =
|
||||
new TestTagHelperDescriptorResolver(
|
||||
new LookupBasedTagHelperTypeResolver(descriptorAssemblyLookups));
|
||||
var resolutionContext = new TagHelperDescriptorResolutionContext(directiveDescriptors);
|
||||
|
||||
// Act
|
||||
var descriptors = tagHelperDescriptorResolver.Resolve(resolutionContext);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(descriptors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DescriptorResolver_DoesNotReturnInvalidTagHelpersWhenSpecified()
|
||||
{
|
||||
// Arrange
|
||||
var tagHelperDescriptorResolver =
|
||||
new TagHelperDescriptorResolver(
|
||||
new TestTagHelperDescriptorResolver(
|
||||
new TestTagHelperTypeResolver(TestableTagHelpers));
|
||||
|
||||
// Act
|
||||
var descriptors = tagHelperDescriptorResolver.Resolve(
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_AbstractTagHelper, MyAssembly");
|
||||
descriptors = descriptors.Concat(tagHelperDescriptorResolver.Resolve(
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_GenericTagHelper`, MyAssembly"));
|
||||
descriptors = descriptors.Concat(tagHelperDescriptorResolver.Resolve(
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_NestedPublicTagHelper, MyAssembly"));
|
||||
descriptors = descriptors.Concat(tagHelperDescriptorResolver.Resolve(
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_NestedInternalTagHelper, MyAssembly"));
|
||||
descriptors = descriptors.Concat(tagHelperDescriptorResolver.Resolve(
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_PrivateTagHelper, MyAssembly"));
|
||||
descriptors = descriptors.Concat(tagHelperDescriptorResolver.Resolve(
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_ProtectedTagHelper, MyAssembly"));
|
||||
descriptors = descriptors.Concat(tagHelperDescriptorResolver.Resolve(
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_InternalTagHelper, MyAssembly"));
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_AbstractTagHelper, " + AssemblyName,
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_GenericTagHelper`, " + AssemblyName,
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_NestedPublicTagHelper, " + AssemblyName,
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_NestedInternalTagHelper, " + AssemblyName,
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_PrivateTagHelper, " + AssemblyName,
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_ProtectedTagHelper, " + AssemblyName,
|
||||
"Microsoft.AspNet.Razor.Runtime.Test.TagHelpers.Invalid_InternalTagHelper, " + AssemblyName);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(descriptors);
|
||||
|
|
@ -78,84 +356,75 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
Assert.Equal("MyAssembly", assemblyName.Name);
|
||||
}
|
||||
};
|
||||
var tagHelperDescriptorResolver = new TagHelperDescriptorResolver(tagHelperTypeResolver);
|
||||
var expectedDescriptor = new TagHelperDescriptor("Valid_Plain",
|
||||
typeof(Valid_PlainTagHelper).FullName,
|
||||
AssemblyName,
|
||||
ContentBehavior.None);
|
||||
var tagHelperDescriptorResolver = new TestTagHelperDescriptorResolver(tagHelperTypeResolver);
|
||||
|
||||
// Act
|
||||
var descriptors = tagHelperDescriptorResolver.Resolve(lookupText);
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Empty(descriptors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DescriptorResolver_ResolvesOnlyTypeResolverProvidedTypes()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new TagHelperDescriptorResolver(
|
||||
var resolver = new TestTagHelperDescriptorResolver(
|
||||
new LookupBasedTagHelperTypeResolver(
|
||||
new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "lookupText1", ValidTestableTagHelpers },
|
||||
{ "lookupText2", new Type[]{ typeof(Valid_PlainTagHelper) } }
|
||||
{ AssemblyName, ValidTestableTagHelpers },
|
||||
{
|
||||
Valid_PlainTagHelperType.FullName + ", " + AssemblyName,
|
||||
new Type[] { Valid_PlainTagHelperType }
|
||||
}
|
||||
}));
|
||||
var expectedDescriptor = new TagHelperDescriptor("Valid_Plain",
|
||||
typeof(Valid_PlainTagHelper).FullName,
|
||||
AssemblyName,
|
||||
ContentBehavior.None);
|
||||
|
||||
// Act
|
||||
var descriptors = resolver.Resolve("lookupText2");
|
||||
var descriptors = resolver.Resolve(Valid_PlainTagHelperType + ", " + AssemblyName);
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(Valid_PlainTagHelperDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DescriptorResolver_ResolvesMultipleTypes()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new TagHelperDescriptorResolver(
|
||||
var resolver = new TestTagHelperDescriptorResolver(
|
||||
new LookupBasedTagHelperTypeResolver(
|
||||
new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "lookupText", new Type[]{ typeof(Valid_PlainTagHelper), typeof(Valid_InheritedTagHelper) } },
|
||||
{ AssemblyName, new Type[]{ Valid_PlainTagHelperType, Valid_InheritedTagHelperType } },
|
||||
}));
|
||||
var expectedDescriptors = new TagHelperDescriptor[]
|
||||
{
|
||||
new TagHelperDescriptor("Valid_Plain",
|
||||
typeof(Valid_PlainTagHelper).FullName,
|
||||
AssemblyName,
|
||||
ContentBehavior.None),
|
||||
new TagHelperDescriptor("Valid_Inherited",
|
||||
typeof(Valid_InheritedTagHelper).FullName,
|
||||
AssemblyName,
|
||||
ContentBehavior.None)
|
||||
Valid_PlainTagHelperDescriptor,
|
||||
Valid_InheritedTagHelperDescriptor
|
||||
};
|
||||
|
||||
// Act
|
||||
var descriptors = resolver.Resolve("lookupText").ToArray();
|
||||
var descriptors = resolver.Resolve(AssemblyName).ToArray();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(descriptors.Length, 2);
|
||||
Assert.Equal(descriptors, expectedDescriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DescriptorResolver_DoesNotResolveTypesForNoTypeResolvingLookupText()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new TagHelperDescriptorResolver(
|
||||
var resolver = new TestTagHelperDescriptorResolver(
|
||||
new LookupBasedTagHelperTypeResolver(
|
||||
new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "lookupText1", ValidTestableTagHelpers },
|
||||
{ "lookupText2", new Type[]{ typeof(Valid_PlainTagHelper) } }
|
||||
{ AssemblyName, ValidTestableTagHelpers },
|
||||
{
|
||||
Valid_PlainTagHelperType.FullName + ", " + AssemblyName,
|
||||
new Type[]{ Valid_PlainTagHelperType }
|
||||
}
|
||||
}));
|
||||
|
||||
// Act
|
||||
|
|
@ -172,7 +441,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
{
|
||||
// Arrange
|
||||
var tagHelperDescriptorResolver =
|
||||
new TagHelperDescriptorResolver(
|
||||
new TestTagHelperDescriptorResolver(
|
||||
new TestTagHelperTypeResolver(InvalidTestableTagHelpers));
|
||||
|
||||
var expectedMessage =
|
||||
|
|
@ -190,6 +459,23 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
Assert.Equal(expectedMessage, ex.Message);
|
||||
}
|
||||
|
||||
private class TestTagHelperDescriptorResolver : TagHelperDescriptorResolver
|
||||
{
|
||||
public TestTagHelperDescriptorResolver(TagHelperTypeResolver typeResolver)
|
||||
: base(typeResolver)
|
||||
{
|
||||
}
|
||||
|
||||
public IEnumerable<TagHelperDescriptor> Resolve(params string[] lookupTexts)
|
||||
{
|
||||
return Resolve(
|
||||
new TagHelperDescriptorResolutionContext(
|
||||
lookupTexts.Select(
|
||||
lookupText =>
|
||||
new TagHelperDirectiveDescriptor(lookupText, TagHelperDirectiveType.AddTagHelper))));
|
||||
}
|
||||
}
|
||||
|
||||
private class LookupBasedTagHelperTypeResolver : TagHelperTypeResolver
|
||||
{
|
||||
private Dictionary<string, IEnumerable<Type>> _lookupValues;
|
||||
|
|
@ -207,9 +493,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
return types?.Select(type => type.GetTypeInfo()) ?? Enumerable.Empty<TypeInfo>();
|
||||
}
|
||||
|
||||
internal override bool IsTagHelper(TypeInfo typeInfo)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestTagHelperDescriptorResolver : TagHelperDescriptorResolver
|
||||
private class AssemblyCheckingTagHelperDescriptorResolver : TagHelperDescriptorResolver
|
||||
{
|
||||
public string CalledWithAssemblyName { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -40,9 +40,26 @@ namespace Microsoft.AspNet.Razor.Test.Generator
|
|||
_tagHelperDescriptors = tagHelperDescriptors ?? Enumerable.Empty<TagHelperDescriptor>();
|
||||
}
|
||||
|
||||
public IEnumerable<TagHelperDescriptor> Resolve(string lookupText)
|
||||
public IEnumerable<TagHelperDescriptor> Resolve(TagHelperDescriptorResolutionContext resolutionContext)
|
||||
{
|
||||
return _tagHelperDescriptors;
|
||||
IEnumerable<TagHelperDescriptor> descriptors = null;
|
||||
|
||||
foreach (var directiveDescriptor in resolutionContext.DirectiveDescriptors)
|
||||
{
|
||||
if (directiveDescriptor.DirectiveType == TagHelperDirectiveType.RemoveTagHelper)
|
||||
{
|
||||
// We don't yet support "typeName, assemblyName" for @removetaghelper in this test class. Will
|
||||
// add that ability and add the corresponding end-to-end test verification in:
|
||||
// https://github.com/aspnet/Razor/issues/222
|
||||
descriptors = null;
|
||||
}
|
||||
else if (directiveDescriptor.DirectiveType == TagHelperDirectiveType.AddTagHelper)
|
||||
{
|
||||
descriptors = _tagHelperDescriptors;
|
||||
}
|
||||
}
|
||||
|
||||
return descriptors ?? Enumerable.Empty<TagHelperDescriptor>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Microsoft.AspNet.Razor.Parser;
|
|||
using Microsoft.AspNet.Razor.Parser.SyntaxTree;
|
||||
using Microsoft.AspNet.Razor.Parser.TagHelpers;
|
||||
using Microsoft.AspNet.Razor.Test.Framework;
|
||||
using Microsoft.Internal.Web.Utils;
|
||||
#if !ASPNETCORE50
|
||||
using Moq;
|
||||
#endif
|
||||
|
|
@ -19,29 +20,14 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
|||
{
|
||||
private static readonly SpanFactory Factory = SpanFactory.CreateCsHtml();
|
||||
|
||||
private static TagHelperDescriptor PTagHelperDescriptor
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TagHelperDescriptor("p", "PTagHelper", "SomeAssembly", ContentBehavior.None);
|
||||
}
|
||||
}
|
||||
|
||||
private static TagHelperDescriptor DivTagHelperDescriptor
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TagHelperDescriptor("div", "DivTagHelper", "SomeAssembly", ContentBehavior.None);
|
||||
}
|
||||
}
|
||||
|
||||
#if !ASPNETCORE50
|
||||
[Fact]
|
||||
public void GetDescriptors_InvokesResolveForEachLookup()
|
||||
public void GetDescriptors_InvokesResolveOnceForAllDirectives()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new Mock<ITagHelperDescriptorResolver>();
|
||||
resolver.Setup(mock => mock.Resolve(It.IsAny<string>())).Returns(Enumerable.Empty<TagHelperDescriptor>());
|
||||
resolver.Setup(mock => mock.Resolve(It.IsAny<TagHelperDescriptorResolutionContext>()))
|
||||
.Returns(Enumerable.Empty<TagHelperDescriptor>());
|
||||
var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor(resolver.Object);
|
||||
var document = new MarkupBlock(
|
||||
Factory.Code("\"one\"").AsAddTagHelper("one"),
|
||||
|
|
@ -49,23 +35,68 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
|||
Factory.Code("\"three\"").AsRemoveTagHelper("three"));
|
||||
|
||||
// Act
|
||||
var descriptors = addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(descriptors);
|
||||
resolver.Verify(mock => mock.Resolve(It.IsAny<string>()), Times.Exactly(3));
|
||||
resolver.Verify(mock => mock.Resolve(It.IsAny<TagHelperDescriptorResolutionContext>()), Times.Once);
|
||||
}
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public void GetDescriptors_LocatesTagHelperCodeGenerator_CreatesDirectiveDescriptors()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new TestTagHelperDescriptorResolver();
|
||||
var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor(resolver);
|
||||
var document = new MarkupBlock(
|
||||
Factory.Code("\"one\"").AsAddTagHelper("one"),
|
||||
Factory.Code("\"two\"").AsRemoveTagHelper("two"),
|
||||
Factory.Code("\"three\"").AsRemoveTagHelper("three"));
|
||||
var expectedRegistrations = new TagHelperDirectiveDescriptor[]
|
||||
{
|
||||
new TagHelperDirectiveDescriptor("one", TagHelperDirectiveType.AddTagHelper),
|
||||
new TagHelperDirectiveDescriptor("two", TagHelperDirectiveType.RemoveTagHelper),
|
||||
new TagHelperDirectiveDescriptor("three", TagHelperDirectiveType.RemoveTagHelper),
|
||||
};
|
||||
|
||||
// Act
|
||||
addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedRegistrations,
|
||||
resolver.DirectiveDescriptors,
|
||||
TagHelperDirectiveDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDescriptors_LocatesAddTagHelperCodeGenerator()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new TestTagHelperDescriptorResolver();
|
||||
var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor(resolver);
|
||||
var document = new MarkupBlock(
|
||||
new DirectiveBlock(
|
||||
Factory.CodeTransition(),
|
||||
Factory.MetaCode(SyntaxConstants.CSharp.RemoveTagHelperKeyword + " ")
|
||||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code("\"something\"").AsAddTagHelper("something"))
|
||||
);
|
||||
var expectedRegistration =
|
||||
new TagHelperDirectiveDescriptor("something", TagHelperDirectiveType.AddTagHelper);
|
||||
|
||||
// Act
|
||||
addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
|
||||
// Assert
|
||||
var directiveDescriptor = Assert.Single(resolver.DirectiveDescriptors);
|
||||
Assert.Equal(expectedRegistration, directiveDescriptor, TagHelperDirectiveDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDescriptors_LocatesNestedRemoveTagHelperCodeGenerator()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new TestTagHelperDescriptorResolver(
|
||||
new Dictionary<string, IEnumerable<TagHelperDescriptor>>
|
||||
{
|
||||
{ "something", new[] { PTagHelperDescriptor } }
|
||||
});
|
||||
var resolver = new TestTagHelperDescriptorResolver();
|
||||
var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor(resolver);
|
||||
var document = new MarkupBlock(
|
||||
new DirectiveBlock(
|
||||
|
|
@ -74,146 +105,73 @@ namespace Microsoft.AspNet.Razor.TagHelpers
|
|||
.Accepts(AcceptedCharacters.None),
|
||||
Factory.Code("\"something\"").AsRemoveTagHelper("something"))
|
||||
);
|
||||
var expectedRegistration =
|
||||
new TagHelperDirectiveDescriptor("something", TagHelperDirectiveType.RemoveTagHelper);
|
||||
|
||||
// Act
|
||||
var descriptors = addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(descriptors);
|
||||
var lookup = Assert.Single(resolver.Lookups);
|
||||
Assert.Equal("something", lookup);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDescriptors_RemovesSpecifiedTagHelper()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new TestTagHelperDescriptorResolver(
|
||||
new Dictionary<string, IEnumerable<TagHelperDescriptor>>
|
||||
{
|
||||
{ "twoTagHelpers", new[] { PTagHelperDescriptor, DivTagHelperDescriptor } },
|
||||
{ "singleTagHelper", new [] { PTagHelperDescriptor } }
|
||||
});
|
||||
var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor(resolver);
|
||||
var document = new MarkupBlock(
|
||||
Factory.Code("\"twoTagHelpers\"").AsAddTagHelper("twoTagHelpers"),
|
||||
Factory.Code("\"singleTagHelper\"").AsRemoveTagHelper("singleTagHelper"));
|
||||
|
||||
// Act
|
||||
var descriptors = addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(DivTagHelperDescriptor, descriptor, TagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(2, resolver.Lookups.Count);
|
||||
Assert.Contains("twoTagHelpers", resolver.Lookups);
|
||||
Assert.Contains("singleTagHelper", resolver.Lookups);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDescriptors_RemovesAddedTagHelpers()
|
||||
{
|
||||
// Arrange
|
||||
var resolver = new TestTagHelperDescriptorResolver(
|
||||
new Dictionary<string, IEnumerable<TagHelperDescriptor>>
|
||||
{
|
||||
{ "twoTagHelpers", new[] { PTagHelperDescriptor, DivTagHelperDescriptor } }
|
||||
});
|
||||
var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor(resolver);
|
||||
var document = new MarkupBlock(
|
||||
Factory.Code("\"twoTagHelpers\"").AsAddTagHelper("twoTagHelpers"),
|
||||
Factory.Code("\"twoTagHelpers\"").AsRemoveTagHelper("twoTagHelpers"));
|
||||
|
||||
// Act
|
||||
var descriptors = addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
|
||||
// Assert
|
||||
Assert.Empty(descriptors);
|
||||
Assert.Equal(Enumerable.Repeat("twoTagHelpers", 2), resolver.Lookups);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDescriptors_RemoveTagHelper_OrderMatters()
|
||||
{
|
||||
// Arrange
|
||||
var expectedDescriptors = new[] { PTagHelperDescriptor, DivTagHelperDescriptor };
|
||||
var resolver = new TestTagHelperDescriptorResolver(
|
||||
new Dictionary<string, IEnumerable<TagHelperDescriptor>>
|
||||
{
|
||||
{ "twoTagHelpers", expectedDescriptors }
|
||||
});
|
||||
var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor(resolver);
|
||||
var document = new MarkupBlock(
|
||||
Factory.Code("\"twoTagHelpers\"").AsRemoveTagHelper("twoTagHelpers"),
|
||||
Factory.Code("\"twoTagHelpers\"").AsAddTagHelper("twoTagHelpers"));
|
||||
|
||||
// Act
|
||||
var descriptors = addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, TagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(Enumerable.Repeat("twoTagHelpers", 2), resolver.Lookups);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDescriptors_RemoveTagHelperInDocument_ThrowsIfNullResolver()
|
||||
{
|
||||
// Arrange
|
||||
var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor(descriptorResolver: null);
|
||||
var document = new MarkupBlock(
|
||||
Factory.Code("\"something\"").AsRemoveTagHelper("something"));
|
||||
var expectedMessage = "Cannot use directive 'removetaghelper' when a Microsoft.AspNet.Razor.TagHelpers." +
|
||||
"ITagHelperDescriptorResolver has not been provided to the Microsoft.AspNet.Razor." +
|
||||
"Parser.RazorParser.";
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() =>
|
||||
{
|
||||
addOrRemoveTagHelperSpanVisitor.GetDescriptors(document);
|
||||
});
|
||||
|
||||
Assert.Equal(expectedMessage, ex.Message);
|
||||
var directiveDescriptor = Assert.Single(resolver.DirectiveDescriptors);
|
||||
Assert.Equal(expectedRegistration, directiveDescriptor, TagHelperDirectiveDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetDescriptors_RemoveTagHelperNotInDocument_DoesNotThrow()
|
||||
{
|
||||
// Arrange
|
||||
var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor(descriptorResolver: null);
|
||||
var addOrRemoveTagHelperSpanVisitor =
|
||||
new AddOrRemoveTagHelperSpanVisitor(
|
||||
new TestTagHelperDescriptorResolver());
|
||||
var document = new MarkupBlock(Factory.Markup("Hello World"));
|
||||
|
||||
// Act & Assert
|
||||
Assert.DoesNotThrow(() => addOrRemoveTagHelperSpanVisitor.GetDescriptors(document));
|
||||
}
|
||||
|
||||
// TODO: Add @addtaghelper directive unit tests. Tracked by https://github.com/aspnet/Razor/issues/202.
|
||||
|
||||
private class TestTagHelperDescriptorResolver : ITagHelperDescriptorResolver
|
||||
{
|
||||
private readonly IReadOnlyDictionary<string, IEnumerable<TagHelperDescriptor>> _lookupTable;
|
||||
|
||||
public TestTagHelperDescriptorResolver(
|
||||
IReadOnlyDictionary<string, IEnumerable<TagHelperDescriptor>> lookupTable)
|
||||
public TestTagHelperDescriptorResolver()
|
||||
{
|
||||
_lookupTable = lookupTable;
|
||||
|
||||
Lookups = new List<string>();
|
||||
DirectiveDescriptors = new List<TagHelperDirectiveDescriptor>();
|
||||
}
|
||||
|
||||
public List<string> Lookups { get; private set; }
|
||||
public List<TagHelperDirectiveDescriptor> DirectiveDescriptors { get; }
|
||||
|
||||
public IEnumerable<TagHelperDescriptor> Resolve(string lookupText)
|
||||
public IEnumerable<TagHelperDescriptor> Resolve(TagHelperDescriptorResolutionContext resolutionContext)
|
||||
{
|
||||
Lookups.Add(lookupText);
|
||||
|
||||
IEnumerable<TagHelperDescriptor> descriptors;
|
||||
if (_lookupTable.TryGetValue(lookupText, out descriptors))
|
||||
{
|
||||
return descriptors;
|
||||
}
|
||||
DirectiveDescriptors.AddRange(resolutionContext.DirectiveDescriptors);
|
||||
|
||||
return Enumerable.Empty<TagHelperDescriptor>();
|
||||
}
|
||||
}
|
||||
|
||||
private class TagHelperDirectiveDescriptorComparer : IEqualityComparer<TagHelperDirectiveDescriptor>
|
||||
{
|
||||
public static readonly TagHelperDirectiveDescriptorComparer Default =
|
||||
new TagHelperDirectiveDescriptorComparer();
|
||||
|
||||
private TagHelperDirectiveDescriptorComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Equals(TagHelperDirectiveDescriptor directiveDescriptorX,
|
||||
TagHelperDirectiveDescriptor directiveDescriptorY)
|
||||
{
|
||||
return string.Equals(directiveDescriptorX.LookupText,
|
||||
directiveDescriptorY.LookupText,
|
||||
StringComparison.Ordinal) &&
|
||||
directiveDescriptorX.DirectiveType == directiveDescriptorY.DirectiveType;
|
||||
}
|
||||
|
||||
public int GetHashCode(TagHelperDirectiveDescriptor directiveDescriptor)
|
||||
{
|
||||
return HashCodeCombiner.Start()
|
||||
.Add(base.GetHashCode())
|
||||
.Add(directiveDescriptor.LookupText)
|
||||
.Add(directiveDescriptor.DirectiveType)
|
||||
.CombinedHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue