diff --git a/src/Microsoft.AspNet.Razor/Parser/TagHelpers/AddOrRemoveTagHelperSpanVisitor.cs b/src/Microsoft.AspNet.Razor/Parser/TagHelpers/AddOrRemoveTagHelperSpanVisitor.cs index 98283ee077..358ec5e8f4 100644 --- a/src/Microsoft.AspNet.Razor/Parser/TagHelpers/AddOrRemoveTagHelperSpanVisitor.cs +++ b/src/Microsoft.AspNet.Razor/Parser/TagHelpers/AddOrRemoveTagHelperSpanVisitor.cs @@ -32,12 +32,19 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers // This will recurse through the syntax tree. VisitBlock(root); - var resolutionContext = new TagHelperDescriptorResolutionContext(_directiveDescriptors); + var resolutionContext = GetTagHelperDescriptorResolutionContext(_directiveDescriptors); var descriptors = _descriptorResolver.Resolve(resolutionContext); return descriptors; } + // Allows MVC a chance to override the TagHelperDescriptorResolutionContext + protected virtual TagHelperDescriptorResolutionContext GetTagHelperDescriptorResolutionContext( + [NotNull] IEnumerable descriptors) + { + return new TagHelperDescriptorResolutionContext(descriptors); + } + public override void VisitSpan(Span span) { // We're only interested in spans with an AddOrRemoveTagHelperCodeGenerator. diff --git a/test/Microsoft.AspNet.Razor.Test/TagHelpers/AddOrRemoveTagHelperSpanVisitorTest.cs b/test/Microsoft.AspNet.Razor.Test/TagHelpers/AddOrRemoveTagHelperSpanVisitorTest.cs index 24c4d70750..68122afa1d 100644 --- a/test/Microsoft.AspNet.Razor.Test/TagHelpers/AddOrRemoveTagHelperSpanVisitorTest.cs +++ b/test/Microsoft.AspNet.Razor.Test/TagHelpers/AddOrRemoveTagHelperSpanVisitorTest.cs @@ -63,8 +63,48 @@ namespace Microsoft.AspNet.Razor.TagHelpers addOrRemoveTagHelperSpanVisitor.GetDescriptors(document); // Assert - Assert.Equal(expectedRegistrations, - resolver.DirectiveDescriptors, + Assert.Equal(expectedRegistrations, + resolver.DirectiveDescriptors, + TagHelperDirectiveDescriptorComparer.Default); + } + + [Fact] + public void GetDescriptors_CanOverrideResolutionContext() + { + // Arrange + var resolver = new TestTagHelperDescriptorResolver(); + var expectedInitialDirectiveDescriptors = new TagHelperDirectiveDescriptor[] + { + new TagHelperDirectiveDescriptor("one", TagHelperDirectiveType.AddTagHelper), + new TagHelperDirectiveDescriptor("two", TagHelperDirectiveType.RemoveTagHelper), + new TagHelperDirectiveDescriptor("three", TagHelperDirectiveType.RemoveTagHelper), + }; + var expectedEndDirectiveDescriptors = new TagHelperDirectiveDescriptor[] + { + new TagHelperDirectiveDescriptor("custom", TagHelperDirectiveType.AddTagHelper) + }; + var addOrRemoveTagHelperSpanVisitor = new CustomAddOrRemoveTagHelperSpanVisitor( + resolver, + (descriptors) => + { + Assert.Equal(expectedInitialDirectiveDescriptors, + descriptors, + TagHelperDirectiveDescriptorComparer.Default); + + return new TagHelperDescriptorResolutionContext(expectedEndDirectiveDescriptors); + }); + var document = new MarkupBlock( + Factory.Code("\"one\"").AsAddTagHelper("one"), + Factory.Code("\"two\"").AsRemoveTagHelper("two"), + Factory.Code("\"three\"").AsRemoveTagHelper("three")); + + + // Act + addOrRemoveTagHelperSpanVisitor.GetDescriptors(document); + + // Assert + Assert.Equal(expectedEndDirectiveDescriptors, + resolver.DirectiveDescriptors, TagHelperDirectiveDescriptorComparer.Default); } @@ -81,7 +121,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers .Accepts(AcceptedCharacters.None), Factory.Code("\"something\"").AsAddTagHelper("something")) ); - var expectedRegistration = + var expectedRegistration = new TagHelperDirectiveDescriptor("something", TagHelperDirectiveType.AddTagHelper); // Act @@ -105,7 +145,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers .Accepts(AcceptedCharacters.None), Factory.Code("\"something\"").AsRemoveTagHelper("something")) ); - var expectedRegistration = + var expectedRegistration = new TagHelperDirectiveDescriptor("something", TagHelperDirectiveType.RemoveTagHelper); // Act @@ -120,7 +160,7 @@ namespace Microsoft.AspNet.Razor.TagHelpers public void GetDescriptors_RemoveTagHelperNotInDocument_DoesNotThrow() { // Arrange - var addOrRemoveTagHelperSpanVisitor = + var addOrRemoveTagHelperSpanVisitor = new AddOrRemoveTagHelperSpanVisitor( new TestTagHelperDescriptorResolver()); var document = new MarkupBlock(Factory.Markup("Hello World")); @@ -155,11 +195,11 @@ namespace Microsoft.AspNet.Razor.TagHelpers { } - public bool Equals(TagHelperDirectiveDescriptor directiveDescriptorX, + public bool Equals(TagHelperDirectiveDescriptor directiveDescriptorX, TagHelperDirectiveDescriptor directiveDescriptorY) { - return string.Equals(directiveDescriptorX.LookupText, - directiveDescriptorY.LookupText, + return string.Equals(directiveDescriptorX.LookupText, + directiveDescriptorY.LookupText, StringComparison.Ordinal) && directiveDescriptorX.DirectiveType == directiveDescriptorY.DirectiveType; } @@ -173,5 +213,24 @@ namespace Microsoft.AspNet.Razor.TagHelpers .CombinedHash; } } + + private class CustomAddOrRemoveTagHelperSpanVisitor : AddOrRemoveTagHelperSpanVisitor + { + private Func, TagHelperDescriptorResolutionContext> _replacer; + + public CustomAddOrRemoveTagHelperSpanVisitor( + ITagHelperDescriptorResolver descriptorResolver, + Func, TagHelperDescriptorResolutionContext> replacer) + : base(descriptorResolver) + { + _replacer = replacer; + } + + protected override TagHelperDescriptorResolutionContext GetTagHelperDescriptorResolutionContext( + IEnumerable descriptors) + { + return _replacer(descriptors); + } + } } } \ No newline at end of file