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]);
        }
Example #5
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);
        }
Example #6
0
        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);
        }
Example #10
0
        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 });
        }
Example #24
0
        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 });
        }
Example #26
0
        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>());
        }