private void Register(TagHelperDescriptor descriptor) { HashSet <TagHelperDescriptor> descriptorSet; if (_tagHelperPrefix == null) { _tagHelperPrefix = descriptor.Prefix; } var registrationKey = string.Equals(descriptor.TagName, ElementCatchAllTarget, StringComparison.Ordinal) ? ElementCatchAllTarget : descriptor.FullTagName; // Ensure there's a HashSet to add the descriptor to. if (!_registrations.TryGetValue(registrationKey, out descriptorSet)) { descriptorSet = new HashSet <TagHelperDescriptor>(TagHelperDescriptorComparer.Default); _registrations[registrationKey] = descriptorSet; } descriptorSet.Add(descriptor); }
public void GetDescriptors_DuplicateDescriptorsAreNotPartOfTagHelperDescriptorPool() { // Arrange var divDescriptor = new TagHelperDescriptor { TagName = "div", TypeName = "foo1", AssemblyName = "SomeAssembly", }; var descriptors = new TagHelperDescriptor[] { divDescriptor, divDescriptor }; var provider = new TagHelperDescriptorProvider(descriptors); // Act var retrievedDescriptors = provider.GetDescriptors( tagName: "div", attributes: Enumerable.Empty <KeyValuePair <string, string> >(), parentTagName: "p"); // Assert var descriptor = Assert.Single(retrievedDescriptors); Assert.Same(divDescriptor, descriptor); }
public void Rewrite_RequiredAttributeDescriptorsCreateMalformedTagHelperBlocksCorrectly( string documentContent, MarkupBlock expectedOutput, RazorError[] expectedErrors) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "pTagHelper", AssemblyName = "SomeAssembly", RequiredAttributes = new[] { new TagHelperRequiredAttributeDescriptor { Name = "class" } } } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public void Rewrite_CanHandleWithoutEndTagTagStructure(string documentContent, MarkupBlock expectedOutput) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag, } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
public void TagHelperDescriptor_WithIndexerAttributes_CanBeSerialized() { // Arrange var descriptor = new TagHelperDescriptor { Prefix = "prefix:", TagName = "tag name", TypeName = "type name", AssemblyName = "assembly name", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "attribute one", PropertyName = "property name", TypeName = "property type name", IsIndexer = true, IsEnum = true, }, new TagHelperAttributeDescriptor { Name = "attribute two", PropertyName = "property name", TypeName = typeof(string).FullName, IsIndexer = true, IsEnum = false, IsStringProperty = true }, }, AllowedChildren = new[] { "allowed child one", "allowed child two" }, RequiredParent = "parent name" }; var expectedSerializedDescriptor = $"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," + $"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," + $"\"{ nameof(TagHelperDescriptor.FullTagName) }\":\"prefix:tag name\"," + $"\"{ nameof(TagHelperDescriptor.TypeName) }\":\"type name\"," + $"\"{ nameof(TagHelperDescriptor.AssemblyName) }\":\"assembly name\"," + $"\"{ nameof(TagHelperDescriptor.Attributes) }\":[" + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.IsEnum) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.IsEnum) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":[\"allowed child one\",\"allowed child two\"]," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":\"parent name\"," + $"\"{ nameof(TagHelperDescriptor.TagStructure) }\":0," + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}"; // Act var serializedDescriptor = JsonConvert.SerializeObject(descriptor); // Assert Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal); }
public void TagHelperDescriptor_CanBeDeserialized() { // Arrange var serializedDescriptor = $"{{\"{nameof(TagHelperDescriptor.Prefix)}\":\"prefix:\"," + $"\"{nameof(TagHelperDescriptor.TagName)}\":\"tag name\"," + $"\"{nameof(TagHelperDescriptor.FullTagName)}\":\"prefix:tag name\"," + $"\"{nameof(TagHelperDescriptor.TypeName)}\":\"type name\"," + $"\"{nameof(TagHelperDescriptor.AssemblyName)}\":\"assembly name\"," + $"\"{nameof(TagHelperDescriptor.Attributes)}\":[]," + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":" + $"[{{\"{ nameof(TagHelperRequiredAttributeDescriptor.Name)}\":\"required attribute one\"," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.NameComparison) }\":1," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.Value) }\":null," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.ValueComparison) }\":0}}," + $"{{\"{ nameof(TagHelperRequiredAttributeDescriptor.Name)}\":\"required attribute two\"," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.NameComparison) }\":0," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.Value) }\":\"something\"," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.ValueComparison) }\":2}}]," + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":[\"allowed child one\",\"allowed child two\"]," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":\"parent name\"," + $"\"{nameof(TagHelperDescriptor.TagStructure)}\":2," + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{" + $"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," + $"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," + $"\"{ nameof(TagHelperDesignTimeDescriptor.OutputElementHint) }\":\"some-tag\"}}}}"; var expectedDescriptor = new TagHelperDescriptor { Prefix = "prefix:", TagName = "tag name", TypeName = "type name", AssemblyName = "assembly name", RequiredAttributes = new[] { new TagHelperRequiredAttributeDescriptor { Name = "required attribute one", NameComparison = TagHelperRequiredAttributeNameComparison.PrefixMatch }, new TagHelperRequiredAttributeDescriptor { Name = "required attribute two", NameComparison = TagHelperRequiredAttributeNameComparison.FullMatch, Value = "something", ValueComparison = TagHelperRequiredAttributeValueComparison.PrefixMatch, } }, AllowedChildren = new[] { "allowed child one", "allowed child two" }, RequiredParent = "parent name", DesignTimeDescriptor = new TagHelperDesignTimeDescriptor { Summary = "usage summary", Remarks = "usage remarks", OutputElementHint = "some-tag" } }; // Act var descriptor = JsonConvert.DeserializeObject<TagHelperDescriptor>(serializedDescriptor); // Assert Assert.NotNull(descriptor); Assert.Equal(expectedDescriptor.Prefix, descriptor.Prefix, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TagName, descriptor.TagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.FullTagName, descriptor.FullTagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TypeName, descriptor.TypeName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.AssemblyName, descriptor.AssemblyName, StringComparer.Ordinal); Assert.Empty(descriptor.Attributes); Assert.Equal(expectedDescriptor.RequiredAttributes, descriptor.RequiredAttributes, TagHelperRequiredAttributeDescriptorComparer.Default); Assert.Equal( expectedDescriptor.DesignTimeDescriptor, descriptor.DesignTimeDescriptor, TagHelperDesignTimeDescriptorComparer.Default); }
public void TagHelperDescriptor_WithAttributes_CanBeDeserialized() { // Arrange var serializedDescriptor = $"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," + $"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," + $"\"{ nameof(TagHelperDescriptor.FullTagName) }\":\"prefix:tag name\"," + $"\"{ nameof(TagHelperDescriptor.TypeName) }\":\"type name\"," + $"\"{ nameof(TagHelperDescriptor.AssemblyName) }\":\"assembly name\"," + $"\"{ nameof(TagHelperDescriptor.Attributes) }\":[" + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsEnum) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsEnum) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":null," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":null," + $"\"{nameof(TagHelperDescriptor.TagStructure)}\":0," + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}"; var expectedDescriptor = new TagHelperDescriptor { Prefix = "prefix:", TagName = "tag name", TypeName = "type name", AssemblyName = "assembly name", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "attribute one", PropertyName = "property name", TypeName = "property type name", IsEnum = true, }, new TagHelperAttributeDescriptor { Name = "attribute two", PropertyName = "property name", TypeName = typeof(string).FullName, IsEnum = false, IsStringProperty = true }, }, AllowedChildren = new[] { "allowed child one", "allowed child two" } }; // Act var descriptor = JsonConvert.DeserializeObject <TagHelperDescriptor>(serializedDescriptor); // Assert Assert.NotNull(descriptor); Assert.Equal(expectedDescriptor.Prefix, descriptor.Prefix, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TagName, descriptor.TagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.FullTagName, descriptor.FullTagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TypeName, descriptor.TypeName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.AssemblyName, descriptor.AssemblyName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.Attributes, descriptor.Attributes, TagHelperAttributeDescriptorComparer.Default); Assert.Empty(descriptor.RequiredAttributes); }
public void Rewrite_CanHandleMultipleTagHelpersWithAllowedChildren() { // Arrange var factory = CreateDefaultSpanFactory(); var documentContent = "<p><strong>Hello World</strong><br></p>"; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("p", new MarkupTagHelperBlock("strong", factory.Markup("Hello World")), new MarkupTagHelperBlock("br", TagMode.StartTagOnly))); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper1", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "strong" } }, new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper2", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "br" } }, new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly" }, new TagHelperDescriptor { TagName = "br", TypeName = "BRTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
public void Rewrite_CanHandleInvalidChildrenWithWhitespace() { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var documentContent = $"<p>{Environment.NewLine} <strong>{Environment.NewLine} Hello" + $"{Environment.NewLine} </strong>{Environment.NewLine}</p>"; var newLineLength = Environment.NewLine.Length; var expectedErrors = new[] { new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_InvalidNestedTag("strong", "p", "br"), absoluteIndex: 8 + newLineLength, lineIndex: 1, columnIndex: 5, length: 6), }; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("p", factory.Markup(Environment.NewLine + " "), blockFactory.MarkupTagBlock("<strong>"), factory.Markup(Environment.NewLine + " Hello" + Environment.NewLine + " "), blockFactory.MarkupTagBlock("</strong>"), factory.Markup(Environment.NewLine))); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "br" }, } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
private void Register(TagHelperDescriptor descriptor) { HashSet<TagHelperDescriptor> descriptorSet; if (_tagHelperPrefix == null) { _tagHelperPrefix = descriptor.Prefix; } var registrationKey = string.Equals(descriptor.TagName, ElementCatchAllTarget, StringComparison.Ordinal) ? ElementCatchAllTarget : descriptor.FullTagName; // Ensure there's a HashSet to add the descriptor to. if (!_registrations.TryGetValue(registrationKey, out descriptorSet)) { descriptorSet = new HashSet<TagHelperDescriptor>(TagHelperDescriptorComparer.Default); _registrations[registrationKey] = descriptorSet; } descriptorSet.Add(descriptor); }
public void Rewrite_UnderstandsMinimizedAttributes( string documentContent, MarkupBlock expectedOutput, RazorError[] expectedErrors) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper1", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound-required-string", PropertyName = "BoundRequiredString", TypeName = typeof(string).FullName, IsStringProperty = true } }, RequiredAttributes = new[] { new TagHelperRequiredAttributeDescriptor { Name = "unbound-required" } } }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper1", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound-required-string", PropertyName = "BoundRequiredString", TypeName = typeof(string).FullName, IsStringProperty = true } }, RequiredAttributes = new[] { new TagHelperRequiredAttributeDescriptor { Name = "bound-required-string" } } }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper2", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound-required-int", PropertyName = "BoundRequiredInt", TypeName = typeof(int).FullName } }, RequiredAttributes = new[] { new TagHelperRequiredAttributeDescriptor { Name = "bound-required-int" } } }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper3", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "int-dictionary", PropertyName ="DictionaryOfIntProperty", TypeName = typeof(IDictionary<string, int>).FullName }, new TagHelperAttributeDescriptor { Name = "string-dictionary", PropertyName = "DictionaryOfStringProperty", TypeName = typeof(IDictionary<string, string>).FullName }, new TagHelperAttributeDescriptor { Name = "int-prefix-", PropertyName = "DictionaryOfIntProperty", TypeName = typeof(int).FullName, IsIndexer = true }, new TagHelperAttributeDescriptor { Name = "string-prefix-", PropertyName = "DictionaryOfStringProperty", TypeName = typeof(string).FullName, IsIndexer = true, IsStringProperty = true } } }, new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound-string", PropertyName = "BoundRequiredString", TypeName = typeof(string).FullName, IsStringProperty = true }, new TagHelperAttributeDescriptor { Name = "bound-int", PropertyName = "BoundRequiredString", TypeName = typeof(int).FullName } } } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public void Rewrite_AllowsCompatibleTagStructures( string documentContent, TagStructure structure1, TagStructure structure2, MarkupBlock expectedOutput) { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper1", AssemblyName = "SomeAssembly", TagStructure = structure1 }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper2", AssemblyName = "SomeAssembly", TagStructure = structure2 } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
public void Rewrite_CreatesErrorForEmptyTagHelperBoundAttributes( string documentContent, MarkupBlock expectedOutput, RazorError[] expectedErrors) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "myth", TypeName = "mythTagHelper", AssemblyName = "SomeAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "bound", PropertyName = "Bound", TypeName = typeof(bool).FullName }, new TagHelperAttributeDescriptor { Name = "name", PropertyName = "Name", TypeName = typeof(string).FullName, IsStringProperty = true } } } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public void Rewrite_UnderstandsNestedRequiredParent(string documentContent, MarkupBlock expectedOutput) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", RequiredParent = "p", }, new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", RequiredParent = "div", }, new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly" } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
internal static string GetVariableName(TagHelperDescriptor descriptor) { return "__" + descriptor.TypeName.Replace('.', '_'); }
public void Rewrite_UnderstandsTagHelperPrefixAndAllowedChildren() { // Arrange var documentContent = "<th:p><th:strong></th:strong></th:p>"; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("th:p", new MarkupTagHelperBlock("th:strong"))); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "strong" }, Prefix = "th:" }, new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", Prefix = "th:" } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData( descriptorProvider, documentContent, expectedOutput, expectedErrors: Enumerable.Empty<RazorError>()); }
public void Rewrite_UnderstandsAllowedChildren( string documentContent, IEnumerable<string> allowedChildren, MarkupBlock expectedOutput, RazorError[] expectedErrors) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = allowedChildren }, new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = allowedChildren }, new TagHelperDescriptor { TagName = "br", TypeName = "BRTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public void Rewrite_RecoversWhenRequiredAttributeMismatchAndRestrictedChildren() { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var documentContent = "<strong required><strong></strong></strong>"; var expectedErrors = new[] { new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_InvalidNestedTag("strong", "strong", "br"), absoluteIndex: 18, lineIndex: 0, columnIndex: 18, length: 6) }; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("strong", new List<TagHelperAttributeNode> { new TagHelperAttributeNode("required", null, HtmlAttributeValueStyle.Minimized) }, blockFactory.MarkupTagBlock("<strong>"), blockFactory.MarkupTagBlock("</strong>"))); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "strong", TypeName = "StrongTagHelper", AssemblyName = "SomeAssembly", RequiredAttributes = new[] { new TagHelperRequiredAttributeDescriptor { Name = "required" } }, AllowedChildren = new[] { "br" } } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public void Rewrite_UnderstandsNullTagNameWithAllowedChildrenForCatchAllWithPrefix() { // Arrange var documentContent = "<th:p></</th:p>"; var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "p", TypeName = "PTagHelper", AssemblyName = "SomeAssembly", AllowedChildren = new[] { "custom" }, Prefix = "th:", }, new TagHelperDescriptor { TagName = "*", TypeName = "CatchAllTagHelper", AssemblyName = "SomeAssembly", Prefix = "th:", } }; var expectedOutput = new MarkupBlock( new MarkupTagHelperBlock("th:p", BlockFactory.MarkupTagBlock("</"))); var descriptorProvider = new TagHelperDescriptorProvider(descriptors); var expectedErrors = new[] { new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_CannotHaveNonTagContent("th:p", "custom"), absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 2) }; // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors); }
public void TagHelperDescriptor_CanBeDeserialized() { // Arrange var serializedDescriptor = $"{{\"{nameof(TagHelperDescriptor.Prefix)}\":\"prefix:\"," + $"\"{nameof(TagHelperDescriptor.TagName)}\":\"tag name\"," + $"\"{nameof(TagHelperDescriptor.FullTagName)}\":\"prefix:tag name\"," + $"\"{nameof(TagHelperDescriptor.TypeName)}\":\"type name\"," + $"\"{nameof(TagHelperDescriptor.AssemblyName)}\":\"assembly name\"," + $"\"{nameof(TagHelperDescriptor.Attributes)}\":[]," + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":" + $"[{{\"{ nameof(TagHelperRequiredAttributeDescriptor.Name)}\":\"required attribute one\"," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.NameComparison) }\":1," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.Value) }\":null," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.ValueComparison) }\":0}}," + $"{{\"{ nameof(TagHelperRequiredAttributeDescriptor.Name)}\":\"required attribute two\"," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.NameComparison) }\":0," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.Value) }\":\"something\"," + $"\"{ nameof(TagHelperRequiredAttributeDescriptor.ValueComparison) }\":2}}]," + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":[\"allowed child one\",\"allowed child two\"]," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":\"parent name\"," + $"\"{nameof(TagHelperDescriptor.TagStructure)}\":2," + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{" + $"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," + $"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," + $"\"{ nameof(TagHelperDesignTimeDescriptor.OutputElementHint) }\":\"some-tag\"}}}}"; var expectedDescriptor = new TagHelperDescriptor { Prefix = "prefix:", TagName = "tag name", TypeName = "type name", AssemblyName = "assembly name", RequiredAttributes = new[] { new TagHelperRequiredAttributeDescriptor { Name = "required attribute one", NameComparison = TagHelperRequiredAttributeNameComparison.PrefixMatch }, new TagHelperRequiredAttributeDescriptor { Name = "required attribute two", NameComparison = TagHelperRequiredAttributeNameComparison.FullMatch, Value = "something", ValueComparison = TagHelperRequiredAttributeValueComparison.PrefixMatch, } }, AllowedChildren = new[] { "allowed child one", "allowed child two" }, RequiredParent = "parent name", DesignTimeDescriptor = new TagHelperDesignTimeDescriptor { Summary = "usage summary", Remarks = "usage remarks", OutputElementHint = "some-tag" } }; // Act var descriptor = JsonConvert.DeserializeObject <TagHelperDescriptor>(serializedDescriptor); // Assert Assert.NotNull(descriptor); Assert.Equal(expectedDescriptor.Prefix, descriptor.Prefix, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TagName, descriptor.TagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.FullTagName, descriptor.FullTagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TypeName, descriptor.TypeName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.AssemblyName, descriptor.AssemblyName, StringComparer.Ordinal); Assert.Empty(descriptor.Attributes); Assert.Equal(expectedDescriptor.RequiredAttributes, descriptor.RequiredAttributes, TagHelperRequiredAttributeDescriptorComparer.Default); Assert.Equal( expectedDescriptor.DesignTimeDescriptor, descriptor.DesignTimeDescriptor, TagHelperDesignTimeDescriptorComparer.Default); }
public void Rewrite_CanHandleStartTagOnlyTagTagMode() { // Arrange var documentContent = "<input>"; var expectedOutput = new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly)); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new RazorError[0]); }
public void TagHelperDescriptor_WithAttributes_CanBeSerialized() { // Arrange var descriptor = new TagHelperDescriptor { Prefix = "prefix:", TagName = "tag name", TypeName = "type name", AssemblyName = "assembly name", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "attribute one", PropertyName = "property name", TypeName = "property type name", IsEnum = true, }, new TagHelperAttributeDescriptor { Name = "attribute two", PropertyName = "property name", TypeName = typeof(string).FullName, IsStringProperty = true }, }, TagStructure = TagStructure.NormalOrSelfClosing }; var expectedSerializedDescriptor = $"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," + $"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," + $"\"{ nameof(TagHelperDescriptor.FullTagName) }\":\"prefix:tag name\"," + $"\"{ nameof(TagHelperDescriptor.TypeName) }\":\"type name\"," + $"\"{ nameof(TagHelperDescriptor.AssemblyName) }\":\"assembly name\"," + $"\"{ nameof(TagHelperDescriptor.Attributes) }\":[" + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsEnum) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsEnum) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":null," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":null," + $"\"{ nameof(TagHelperDescriptor.TagStructure) }\":1," + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}"; // Act var serializedDescriptor = JsonConvert.SerializeObject(descriptor); // Assert Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal); }
public void Rewrite_CreatesErrorForWithoutEndTagTagStructureForEndTags() { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var expectedError = new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_EndTagTagHelperMustNotHaveAnEndTag( "input", "InputTagHelper", TagStructure.WithoutEndTag), absoluteIndex: 2, lineIndex: 0, columnIndex: 2, length: 5); var documentContent = "</input>"; var expectedOutput = new MarkupBlock(blockFactory.MarkupTagBlock("</input>")); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new[] { expectedError }); }
public void TagHelperDescriptor_WithIndexerAttributes_CanBeDeserialized() { // Arrange var serializedDescriptor = $"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," + $"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," + $"\"{ nameof(TagHelperDescriptor.FullTagName) }\":\"prefix:tag name\"," + $"\"{ nameof(TagHelperDescriptor.TypeName) }\":\"type name\"," + $"\"{ nameof(TagHelperDescriptor.AssemblyName) }\":\"assembly name\"," + $"\"{ nameof(TagHelperDescriptor.Attributes) }\":[" + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.IsEnum) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute one\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"property type name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}," + $"{{\"{ nameof(TagHelperAttributeDescriptor.IsIndexer) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.IsEnum) }\":false," + $"\"{ nameof(TagHelperAttributeDescriptor.IsStringProperty) }\":true," + $"\"{ nameof(TagHelperAttributeDescriptor.Name) }\":\"attribute two\"," + $"\"{ nameof(TagHelperAttributeDescriptor.PropertyName) }\":\"property name\"," + $"\"{ nameof(TagHelperAttributeDescriptor.TypeName) }\":\"{ typeof(string).FullName }\"," + $"\"{ nameof(TagHelperAttributeDescriptor.DesignTimeDescriptor) }\":null}}]," + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":null," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":null," + $"\"{nameof(TagHelperDescriptor.TagStructure)}\":1," + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}"; var expectedDescriptor = new TagHelperDescriptor { Prefix = "prefix:", TagName = "tag name", TypeName = "type name", AssemblyName = "assembly name", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "attribute one", PropertyName = "property name", TypeName = "property type name", IsIndexer = true, IsEnum = true, }, new TagHelperAttributeDescriptor { Name = "attribute two", PropertyName = "property name", TypeName = typeof(string).FullName, IsIndexer = true, IsEnum = false, IsStringProperty = true } }, TagStructure = TagStructure.NormalOrSelfClosing }; // Act var descriptor = JsonConvert.DeserializeObject<TagHelperDescriptor>(serializedDescriptor); // Assert Assert.NotNull(descriptor); Assert.Equal(expectedDescriptor.Prefix, descriptor.Prefix, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TagName, descriptor.TagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.FullTagName, descriptor.FullTagName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.TypeName, descriptor.TypeName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.AssemblyName, descriptor.AssemblyName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.Attributes, descriptor.Attributes, TagHelperAttributeDescriptorComparer.Default); Assert.Empty(descriptor.RequiredAttributes); }
public void Rewrite_CreatesErrorForInconsistentTagStructures() { // Arrange var factory = CreateDefaultSpanFactory(); var blockFactory = new BlockFactory(factory); var expectedError = new RazorError( RazorResources.FormatTagHelperParseTreeRewriter_InconsistentTagStructure( "InputTagHelper1", "InputTagHelper2", "input", nameof(TagHelperDescriptor.TagStructure)), absoluteIndex: 0, lineIndex: 0, columnIndex: 0, length: 7); var documentContent = "<input>"; var expectedOutput = new MarkupBlock(new MarkupTagHelperBlock("input", TagMode.StartTagOnly)); var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper1", AssemblyName = "SomeAssembly", TagStructure = TagStructure.WithoutEndTag }, new TagHelperDescriptor { TagName = "input", TypeName = "InputTagHelper2", AssemblyName = "SomeAssembly", TagStructure = TagStructure.NormalOrSelfClosing } }; var descriptorProvider = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors: new[] { expectedError }); }
private static bool MatchesLookupInfo(TagHelperDescriptor descriptor, LookupInfo lookupInfo) { if (!string.Equals(descriptor.AssemblyName, lookupInfo.AssemblyName, StringComparison.Ordinal)) { return false; } if (lookupInfo.TypePattern.EndsWith("*", StringComparison.Ordinal)) { if (lookupInfo.TypePattern.Length == 1) { // TypePattern is "*". return true; } var lookupTypeName = lookupInfo.TypePattern.Substring(0, lookupInfo.TypePattern.Length - 1); return descriptor.TypeName.StartsWith(lookupTypeName, StringComparison.Ordinal); } return string.Equals(descriptor.TypeName, lookupInfo.TypePattern, StringComparison.Ordinal); }
public void TagHelperParseTreeRewriter_CreatesMarkupCodeSpansForNonStringTagHelperAttributes( string documentContent, MarkupBlock expectedOutput) { // Arrange var descriptors = new TagHelperDescriptor[] { new TagHelperDescriptor { TagName = "person", TypeName = "PersonTagHelper", AssemblyName = "personAssembly", Attributes = new[] { new TagHelperAttributeDescriptor { Name = "age", PropertyName = "Age", TypeName = typeof(int).FullName }, new TagHelperAttributeDescriptor { Name = "birthday", PropertyName = "BirthDay", TypeName = typeof(DateTime).FullName }, new TagHelperAttributeDescriptor { Name = "name", PropertyName = "Name", TypeName = typeof(string).FullName, IsStringProperty = true } } } }; var providerContext = new TagHelperDescriptorProvider(descriptors); // Act & Assert EvaluateData(providerContext, documentContent, expectedOutput, expectedErrors: Enumerable.Empty<RazorError>()); }