public void TagHelperDescriptor_CanBeSerialized()
        {
            // Arrange
            var descriptor = new TagHelperDescriptor(
                prefix: "prefix:",
                tagName: "tag name",
                typeName: "type name",
                assemblyName: "assembly name",
                attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
                requiredAttributes: new[] { "required attribute one", "required attribute two" });
            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(TagHelperDescriptor.RequiredAttributes) }\":" +
                "[\"required attribute one\",\"required attribute two\"]}";

            // Act
            var serializedDescriptor = JsonConvert.SerializeObject(descriptor);

            // Assert
            Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal);
        }
        public override int GetHashCode(TagHelperDescriptor descriptor)
        {
            var hashCodeCombiner = HashCodeCombiner.Start()
                .Add(base.GetHashCode(descriptor))
                .Add(descriptor.TagName, StringComparer.Ordinal)
                .Add(descriptor.Prefix, StringComparer.Ordinal);

            if (descriptor.DesignTimeDescriptor != null)
            {
                hashCodeCombiner.Add(
                    TagHelperDesignTimeDescriptorComparer.Default.GetHashCode(descriptor.DesignTimeDescriptor));
            }

            foreach (var requiredAttribute in descriptor.RequiredAttributes)
            {
                hashCodeCombiner.Add(requiredAttribute, StringComparer.Ordinal);
            }

            if (descriptor.AllowedChildren != null)
            {
                foreach (var child in descriptor.AllowedChildren)
                {
                    hashCodeCombiner.Add(child, StringComparer.Ordinal);
                }
            }

            foreach (var attribute in descriptor.Attributes)
            {
                hashCodeCombiner.Add(TagHelperAttributeDescriptorComparer.Default.GetHashCode(attribute));
            }

            return hashCodeCombiner.CombinedHash;
        }
Beispiel #3
0
        public void TagHelperDescriptor_CanBeSerialized()
        {
            // Arrange
            var descriptor = new TagHelperDescriptor(
                prefix: "prefix:",
                tagName: "tag name",
                typeName: "type name",
                assemblyName: "assembly name",
                attributes: Enumerable.Empty<TagHelperAttributeDescriptor>(),
                requiredAttributes: new[] { "required attribute one", "required attribute two" },
                designTimeDescriptor: new TagHelperDesignTimeDescriptor("usage summary", "usage remarks", "some-tag"));

            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(TagHelperDescriptor.RequiredAttributes) }\":" +
                "[\"required attribute one\",\"required attribute two\"]," +
                $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{"+
                $"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," +
                $"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," +
                $"\"{ nameof(TagHelperDesignTimeDescriptor.OutputElementHint) }\":\"some-tag\"}}}}";

            // Act
            var serializedDescriptor = JsonConvert.SerializeObject(descriptor);

            // Assert
            Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal);
        }
        public override bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
        {
            if (descriptorX == descriptorY)
            {
                return true;
            }

            return base.Equals(descriptorX, descriptorY) &&
                // Normal comparer doesn't care about the case, required attribute order, allowed children order,
                // attributes or prefixes. In tests we do.
                string.Equals(descriptorX.TagName, descriptorY.TagName, StringComparison.Ordinal) &&
                string.Equals(descriptorX.Prefix, descriptorY.Prefix, StringComparison.Ordinal) &&
                Enumerable.SequenceEqual(
                    descriptorX.RequiredAttributes,
                    descriptorY.RequiredAttributes,
                    StringComparer.Ordinal) &&
                (descriptorX.AllowedChildren == descriptorY.AllowedChildren ||
                Enumerable.SequenceEqual(
                    descriptorX.AllowedChildren,
                    descriptorY.AllowedChildren,
                    StringComparer.Ordinal)) &&
                descriptorX.Attributes.SequenceEqual(
                    descriptorY.Attributes,
                    TagHelperAttributeDescriptorComparer.Default) &&
                TagHelperDesignTimeDescriptorComparer.Default.Equals(
                    descriptorX.DesignTimeDescriptor,
                    descriptorY.DesignTimeDescriptor);
        }
        public void TagHelpers_CanReplaceAttributeCodeGeneratorLogic()
        {
            // Arrange
            var inputTypePropertyInfo = typeof(TestType).GetProperty("Type");
            var checkedPropertyInfo = typeof(TestType).GetProperty("Checked");
            var tagHelperDescriptors = new TagHelperDescriptor[]
            {
                new TagHelperDescriptor("p", "PTagHelper", "SomeAssembly"),
                new TagHelperDescriptor("input",
                                        "InputTagHelper",
                                        "SomeAssembly",
                                        new TagHelperAttributeDescriptor[] {
                                            new TagHelperAttributeDescriptor("type", inputTypePropertyInfo)
                                        }),
                new TagHelperDescriptor("input",
                                        "InputTagHelper2",
                                        "SomeAssembly",
                                        new TagHelperAttributeDescriptor[] {
                                            new TagHelperAttributeDescriptor("type", inputTypePropertyInfo),
                                            new TagHelperAttributeDescriptor("checked", checkedPropertyInfo)
                                        })
            };

            // Act & Assert
            RunTagHelperTest(testName: "BasicTagHelpers",
                             baseLineName: "BasicTagHelpers.CustomAttributeCodeGenerator",
                             tagHelperDescriptors: tagHelperDescriptors,
                             hostConfig: (host) =>
                             {
                                 return new CodeBuilderReplacingHost(host);
                             });
        }
        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"
                   },
                    new TagHelperAttributeDescriptor
                   {
                        Name = "attribute two",
                        PropertyName = "property name",
                        TypeName = typeof(string).FullName
                    },
                },
                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.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.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.TagStructure) }\":1," +
                $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}";

            // Act
            var serializedDescriptor = JsonConvert.SerializeObject(descriptor);

            // Assert
            Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal);
        }
Beispiel #7
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",
                        isIndexer: false,
                        designTimeDescriptor: null),
                    new TagHelperAttributeDescriptor(
                        name: "attribute two",
                        propertyName: "property name",
                        typeName: typeof(string).FullName,
                        isIndexer: false,
                        designTimeDescriptor: null),
                },
                requiredAttributes: Enumerable.Empty<string>(),
                designTimeDescriptor: null);
            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.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.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.DesignTimeDescriptor) }\":null}}";

            // Act
            var serializedDescriptor = JsonConvert.SerializeObject(descriptor);

            // Assert
            Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal);
        }
        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: 7 + newLineLength,
                    lineIndex: 1,
                    columnIndex: 9 + newLineLength,
                    length: 8),
                new RazorError(
                    RazorResources.FormatTagHelperParseTreeRewriter_CannotHaveNonTagContent("p", "br"),
                    absoluteIndex: 23 + newLineLength * 2,
                    lineIndex: 2,
                    columnIndex: 23 + newLineLength * 2,
                    length: 5),
                new RazorError(
                    RazorResources.FormatTagHelperParseTreeRewriter_InvalidNestedTag("strong", "p", "br"),
                    absoluteIndex: 32 + newLineLength * 3,
                    lineIndex: 3,
                    columnIndex: 32 + newLineLength * 3,
                    length: 9),
            };
            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);
        }
        public void TagHelperDescriptor_CanBeSerialized()
        {
            // Arrange
            var descriptor = new TagHelperDescriptor
            {
                Prefix = "prefix:",
                TagName = "tag name",
                TypeName = "type name",
                AssemblyName =  "assembly name",
                RequiredAttributes = new[] { "required attribute one", "required attribute two" },
                AllowedChildren = new[] { "allowed child one" },
                RequiredParent = "parent name",
                DesignTimeDescriptor = new TagHelperDesignTimeDescriptor
                {
                    Summary = "usage summary",
                    Remarks = "usage remarks",
                    OutputElementHint = "some-tag"
                },
            };

            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(TagHelperDescriptor.RequiredAttributes) }\":" +
                "[\"required attribute one\",\"required attribute two\"]," +
                $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":[\"allowed child one\"]," +
                $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":\"parent name\"," +
                $"\"{ nameof(TagHelperDescriptor.TagStructure) }\":0," +
                $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{"+
                $"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," +
                $"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," +
                $"\"{ nameof(TagHelperDesignTimeDescriptor.OutputElementHint) }\":\"some-tag\"}}}}";

            // Act
            var serializedDescriptor = JsonConvert.SerializeObject(descriptor);

            // Assert
            Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal);
        }
        public override int GetHashCode(TagHelperDescriptor descriptor)
        {
            var hashCodeCombiner = HashCodeCombiner.Start()
                .Add(base.GetHashCode(descriptor))
                .Add(descriptor.TagName, StringComparer.Ordinal)
                .Add(descriptor.Prefix);

            foreach (var requiredAttribute in descriptor.RequiredAttributes)
            {
                hashCodeCombiner.Add(requiredAttribute, StringComparer.Ordinal);
            }

            foreach (var attribute in descriptor.Attributes)
            {
                hashCodeCombiner.Add(CaseSensitiveTagHelperAttributeDescriptorComparer.Default.GetHashCode(attribute));
            }

            return hashCodeCombiner.CombinedHash;
        }
        public override bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
        {
            if (descriptorX == descriptorY)
            {
                return true;
            }

            return base.Equals(descriptorX, descriptorY) &&
                // Normal comparer doesn't care about the case, required attribute order, attributes or prefixes.
                // In tests we do.
                string.Equals(descriptorX.TagName, descriptorY.TagName, StringComparison.Ordinal) &&
                string.Equals(descriptorX.Prefix, descriptorY.Prefix, StringComparison.Ordinal) &&
                Enumerable.SequenceEqual(
                    descriptorX.RequiredAttributes,
                    descriptorY.RequiredAttributes,
                    StringComparer.Ordinal) &&
                descriptorX.Attributes.SequenceEqual(
                    descriptorY.Attributes,
                    CaseSensitiveTagHelperAttributeDescriptorComparer.Default);
        }
        public void GetDescriptors_ReturnsCatchAllsWithEveryTagName()
        {
            // Arrange
            var divDescriptor = new TagHelperDescriptor
            {
                TagName      = "div",
                TypeName     = "foo1",
                AssemblyName = "SomeAssembly",
            };
            var spanDescriptor = new TagHelperDescriptor
            {
                TagName      = "span",
                TypeName     = "foo2",
                AssemblyName = "SomeAssembly",
            };
            var catchAllDescriptor = new TagHelperDescriptor
            {
                TagName      = TagHelperDescriptorProvider.ElementCatchAllTarget,
                TypeName     = "foo3",
                AssemblyName = "SomeAssembly",
            };
            var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor };
            var provider    = new TagHelperDescriptorProvider(descriptors);

            // Act
            var divDescriptors  = provider.GetDescriptors("div", attributeNames: Enumerable.Empty <string>());
            var spanDescriptors = provider.GetDescriptors("span", attributeNames: Enumerable.Empty <string>());

            // Assert
            // For divs
            Assert.Equal(2, divDescriptors.Count());
            Assert.Contains(divDescriptor, divDescriptors);
            Assert.Contains(catchAllDescriptor, divDescriptors);

            // For spans
            Assert.Equal(2, spanDescriptors.Count());
            Assert.Contains(spanDescriptor, spanDescriptors);
            Assert.Contains(catchAllDescriptor, spanDescriptors);
        }
        private void Register(TagHelperDescriptor descriptor)
        {
            HashSet <TagHelperDescriptor> descriptorSet;

            if (_tagHelperPrefix == null)
            {
                _tagHelperPrefix = descriptor.Prefix;
            }

            var registrationKey =
                string.Equals(descriptor.TagName, CatchAllDescriptorTarget, StringComparison.Ordinal) ?
                CatchAllDescriptorTarget :
                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_ReturnsNothingForUnregisteredTags()
        {
            // Arrange
            var divDescriptor = new TagHelperDescriptor
            {
                TagName      = "div",
                TypeName     = "foo1",
                AssemblyName = "SomeAssembly",
            };
            var spanDescriptor = new TagHelperDescriptor
            {
                TagName      = "span",
                TypeName     = "foo2",
                AssemblyName = "SomeAssembly",
            };
            var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor };
            var provider    = new TagHelperDescriptorProvider(descriptors);

            // Act
            var retrievedDescriptors = provider.GetDescriptors("foo", attributeNames: Enumerable.Empty <string>());

            // Assert
            Assert.Empty(retrievedDescriptors);
        }
        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(
                                "bound-required-string",
                                "BoundRequiredString",
                                typeof(string).FullName,
                                isIndexer: false,
                                designTimeDescriptor: null)
                        },
                        requiredAttributes: new[] { "unbound-required" }),
                    new TagHelperDescriptor(
                        tagName: "input",
                        typeName: "InputTagHelper1",
                        assemblyName: "SomeAssembly",
                        attributes: new[]
                        {
                            new TagHelperAttributeDescriptor(
                                "bound-required-string",
                                "BoundRequiredString",
                                typeof(string).FullName,
                                isIndexer: false,
                                designTimeDescriptor: null)
                        },
                        requiredAttributes: new[] { "bound-required-string" }),
                    new TagHelperDescriptor(
                        tagName: "input",
                        typeName: "InputTagHelper2",
                        assemblyName: "SomeAssembly",
                        attributes: new[]
                        {
                            new TagHelperAttributeDescriptor(
                                "bound-required-int",
                                "BoundRequiredInt",
                                typeof(int).FullName,
                                isIndexer: false,
                                designTimeDescriptor: null)
                        },
                        requiredAttributes: new[] { "bound-required-int" }),
                    new TagHelperDescriptor(
                        tagName: "input",
                        typeName: "InputTagHelper3",
                        assemblyName: "SomeAssembly",
                        attributes: new[]
                        {
                            new TagHelperAttributeDescriptor(
                                "int-dictionary",
                                "DictionaryOfIntProperty",
                                typeof(IDictionary<string, int>).FullName,
                                isIndexer: false,
                                designTimeDescriptor: null),
                            new TagHelperAttributeDescriptor(
                                "string-dictionary",
                                "DictionaryOfStringProperty",
                                typeof(IDictionary<string, string>).FullName,
                                isIndexer: false,
                                designTimeDescriptor: null),
                            new TagHelperAttributeDescriptor(
                                "int-prefix-",
                                "DictionaryOfIntProperty",
                                typeof(int).FullName,
                                isIndexer: true,
                                designTimeDescriptor: null),
                            new TagHelperAttributeDescriptor(
                                "string-prefix-",
                                "DictionaryOfStringProperty",
                                typeof(string).FullName,
                                isIndexer: true,
                                designTimeDescriptor: null),
                        },
                        requiredAttributes: Enumerable.Empty<string>()),
                    new TagHelperDescriptor(
                        tagName: "p",
                        typeName: "PTagHelper",
                        assemblyName: "SomeAssembly",
                        attributes: new[]
                        {
                            new TagHelperAttributeDescriptor(
                                "bound-string",
                                "BoundRequiredString",
                                typeof(string).FullName,
                                isIndexer: false,
                                designTimeDescriptor: null),
                            new TagHelperAttributeDescriptor(
                                "bound-int",
                                "BoundRequiredString",
                                typeof(int).FullName,
                                isIndexer: false,
                                designTimeDescriptor: null)
                        },
                        requiredAttributes: Enumerable.Empty<string>()),
                };
            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, CatchAllDescriptorTarget, StringComparison.Ordinal) ?
                CatchAllDescriptorTarget :
                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 CreateDescriptors_CreatesDesignTimeDescriptorsWithOutputElementHint(
            Type tagHelperType,
            TagHelperDescriptor[] expectedDescriptors)
        {
            // Arrange
            var errorSink = new ErrorSink();

            // Act
            var descriptors = TagHelperDescriptorFactory.CreateDescriptors(
                AssemblyName,
                GetTypeInfo(tagHelperType),
                designTime: true,
                errorSink: errorSink);

            // Assert
            Assert.Empty(errorSink.Errors);

            // We don't care about order. Mono returns reflected attributes differently so we need to ensure order
            // doesn't matter by sorting.
            descriptors = descriptors.OrderBy(descriptor => descriptor.TagName);

            Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
        }
        private static bool MatchesLookupInfo(TagHelperDescriptor descriptor, LookupInfo lookupInfo)
        {
            if (!string.Equals(descriptor.AssemblyName, lookupInfo.AssemblyName, StringComparison.Ordinal))
            {
                return false;
            }

            // We need to escape the TypePattern so we can choose to only allow specific regex.
            var escaped = Regex.Escape(lookupInfo.TypePattern);

            // We surround the escaped with ^ and $ in order ot ensure a regex match matches the entire 
            // string. We also replace any '*' or '?' characters with regex to match appropriate content.
            // '*' matches 0 or more characters lazily and '?' matches 1 character.
            var pattern = "^" + escaped.Replace(@"\?", ".").Replace(@"\*", ".*?") + "$";
            var regex = new Regex(pattern, RegexOptions.Singleline);

            return regex.IsMatch(descriptor.TypeName);
        }
        public void GetDescriptors_ReturnsCatchAllsWithEveryTagName()
        {
            // Arrange
            var divDescriptor = new TagHelperDescriptor
            {
                TagName = "div",
                TypeName = "foo1",
                AssemblyName = "SomeAssembly",
            };
            var spanDescriptor = new TagHelperDescriptor
            {
                TagName = "span",
                TypeName = "foo2",
                AssemblyName = "SomeAssembly",
            };
            var catchAllDescriptor = new TagHelperDescriptor
            {
                TagName = TagHelperDescriptorProvider.ElementCatchAllTarget,
                TypeName = "foo3",
                AssemblyName = "SomeAssembly",
            };
            var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor, catchAllDescriptor };
            var provider = new TagHelperDescriptorProvider(descriptors);

            // Act
            var divDescriptors = provider.GetDescriptors("div", attributeNames: Enumerable.Empty<string>());
            var spanDescriptors = provider.GetDescriptors("span", attributeNames: Enumerable.Empty<string>());

            // Assert
            // For divs
            Assert.Equal(2, divDescriptors.Count());
            Assert.Contains(divDescriptor, divDescriptors);
            Assert.Contains(catchAllDescriptor, divDescriptors);

            // For spans
            Assert.Equal(2, spanDescriptors.Count());
            Assert.Contains(spanDescriptor, spanDescriptors);
            Assert.Contains(catchAllDescriptor, spanDescriptors);
        }
        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.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.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.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
                    },
                    new TagHelperAttributeDescriptor
                    {
                        Name         = "attribute two",
                        PropertyName = "property name",
                        TypeName     = typeof(string).FullName,
                        IsIndexer    = 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_RequiredAttributeDescriptorsCreateMalformedTagHelperBlocksCorrectly(
            string documentContent,
            MarkupBlock expectedOutput,
            RazorError[] expectedErrors)
        {
            // Arrange
            var descriptors = new TagHelperDescriptor[]
                {
                    new TagHelperDescriptor(
                        tagName: "p",
                        typeName: "pTagHelper",
                        assemblyName: "SomeAssembly",
                        attributes: new TagHelperAttributeDescriptor[0],
                        requiredAttributes: new[] { "class" })
                };
            var descriptorProvider = new TagHelperDescriptorProvider(descriptors);

            // Act & Assert
            EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors);
        }
        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,
                                isIndexer: false),
                            new TagHelperAttributeDescriptor(
                                name: "name",
                                propertyName: "Name",
                                typeName: typeof(string).FullName,
                                isIndexer: false)
                        })
                };
            var descriptorProvider = new TagHelperDescriptorProvider(descriptors);

            // Act & Assert
            EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors);
        }
        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
                        }
                    }
                }
            };
            var providerContext = new TagHelperDescriptorProvider(descriptors);

            // Act & Assert
            EvaluateData(providerContext,
                         documentContent,
                         expectedOutput,
                         expectedErrors: Enumerable.Empty<RazorError>());
        }
 internal static string GetVariableName(TagHelperDescriptor descriptor)
 {
     return "__" + descriptor.TypeName.Replace('.', '_');
 }
Beispiel #25
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.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.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.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,
                    designTimeDescriptor: null),
                new TagHelperAttributeDescriptor(
                    name: "attribute two",
                    propertyName: "property name",
                    typeName: typeof(string).FullName,
                    isIndexer: true,
                    designTimeDescriptor: null),
            },
                requiredAttributes: Enumerable.Empty <string>(),
                designTimeDescriptor: null);

            // 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(2, descriptor.Attributes.Count);
            Assert.Equal(expectedDescriptor.Attributes[0].IsIndexer, descriptor.Attributes[0].IsIndexer);
            Assert.Equal(expectedDescriptor.Attributes[0].IsStringProperty, descriptor.Attributes[0].IsStringProperty);
            Assert.Equal(expectedDescriptor.Attributes[0].Name, descriptor.Attributes[0].Name, StringComparer.Ordinal);
            Assert.Equal(
                expectedDescriptor.Attributes[0].PropertyName,
                descriptor.Attributes[0].PropertyName,
                StringComparer.Ordinal);
            Assert.Equal(
                expectedDescriptor.Attributes[0].TypeName,
                descriptor.Attributes[0].TypeName,
                StringComparer.Ordinal);

            Assert.Equal(expectedDescriptor.Attributes[1].IsIndexer, descriptor.Attributes[1].IsIndexer);
            Assert.Equal(expectedDescriptor.Attributes[1].IsStringProperty, descriptor.Attributes[1].IsStringProperty);
            Assert.Equal(expectedDescriptor.Attributes[1].Name, descriptor.Attributes[1].Name, StringComparer.Ordinal);
            Assert.Equal(
                expectedDescriptor.Attributes[1].PropertyName,
                descriptor.Attributes[1].PropertyName,
                StringComparer.Ordinal);
            Assert.Equal(
                expectedDescriptor.Attributes[1].TypeName,
                descriptor.Attributes[1].TypeName,
                StringComparer.Ordinal);

            Assert.Empty(descriptor.RequiredAttributes);
        }
        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 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.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.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.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"
                    },
                    new TagHelperAttributeDescriptor
                   {
                        Name = "attribute two",
                        PropertyName = "property name",
                        TypeName = typeof(string).FullName
                    },
                },
                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 TagHelperParseTreeRewriter_CreatesMarkupCodeSpansForNonStringTagHelperAttributes(
            string documentContent,
            MarkupBlock expectedOutput)
        {
            // Arrange
            var descriptors = new TagHelperDescriptor[]
            {
                new TagHelperDescriptor("person", "PersonTagHelper", "personAssembly",
                    attributes: new[]
                    {
                        new TagHelperAttributeDescriptor("age", "Age", typeof(int).FullName, isIndexer: false),
                        new TagHelperAttributeDescriptor(
                            "birthday",
                            "BirthDay",
                            typeof(DateTime).FullName,
                            isIndexer: false),
                        new TagHelperAttributeDescriptor("name", "Name", typeof(string).FullName, isIndexer: false),
                    })
            };
            var providerContext = new TagHelperDescriptorProvider(descriptors);

            // Act & Assert
            EvaluateData(providerContext,
                         documentContent,
                         expectedOutput,
                         expectedErrors: Enumerable.Empty<RazorError>());
        }
        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
                            }
                        }
                    }
                };
            var descriptorProvider = new TagHelperDescriptorProvider(descriptors);

            // Act & Assert
            EvaluateData(descriptorProvider, documentContent, expectedOutput, expectedErrors);
        }
        public void TagHelpers_WithinHelpersAndSections_GeneratesExpectedOutput()
        {
            // Arrange
            var propertyInfo = typeof(TestType).GetProperty("BoundProperty");
            var tagHelperDescriptors = new TagHelperDescriptor[]
            {
                new TagHelperDescriptor
                {
                    TagName = "MyTagHelper",
                    TypeName = "MyTagHelper",
                    AssemblyName = "SomeAssembly",
                    Attributes = new []
                    {
                        new TagHelperAttributeDescriptor("BoundProperty", propertyInfo)
                    }
                },
                new TagHelperDescriptor
                {
                    TagName = "NestedTagHelper",
                    TypeName = "NestedTagHelper",
                    AssemblyName = "SomeAssembly"
                }
            };

            // Act & Assert
            RunTagHelperTest("TagHelpersInSection", tagHelperDescriptors: tagHelperDescriptors);
        }
        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
                            }
                        },
                        RequiredAttributes = new[] { "unbound-required" }
                    },
                    new TagHelperDescriptor
                    {
                        TagName = "input",
                        TypeName = "InputTagHelper1",
                        AssemblyName = "SomeAssembly",
                        Attributes = new[]
                        {
                            new TagHelperAttributeDescriptor
                            {
                                Name = "bound-required-string",
                                PropertyName = "BoundRequiredString",
                                TypeName = typeof(string).FullName
                            }
                        },
                        RequiredAttributes = new[] { "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[] { "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
                            }
                        }
                    },
                    new TagHelperDescriptor
                    {
                        TagName = "p",
                        TypeName = "PTagHelper",
                        AssemblyName = "SomeAssembly",
                        Attributes = new[]
                        {
                            new TagHelperAttributeDescriptor
                            {
                                Name = "bound-string",
                                PropertyName = "BoundRequiredString",
                                TypeName = typeof(string).FullName
                            },
                            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 GetDescriptors_ReturnsNothingForUnregisteredTags()
        {
            // Arrange
            var divDescriptor = new TagHelperDescriptor
            {
                TagName = "div",
                TypeName = "foo1",
                AssemblyName = "SomeAssembly",
            };
            var spanDescriptor = new TagHelperDescriptor
            {
                TagName = "span",
                TypeName = "foo2",
                AssemblyName = "SomeAssembly",
            };
            var descriptors = new TagHelperDescriptor[] { divDescriptor, spanDescriptor };
            var provider = new TagHelperDescriptorProvider(descriptors);

            // Act
            var retrievedDescriptors = provider.GetDescriptors("foo", attributeNames: Enumerable.Empty<string>());

            // Assert
            Assert.Empty(retrievedDescriptors);
        }
        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 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("div", attributeNames: Enumerable.Empty<string>());

            // Assert
            var descriptor = Assert.Single(retrievedDescriptors);
            Assert.Same(divDescriptor, descriptor);
        }
        public void DescriptorResolver_ResolvesMultipleTypes()
        {
            // Arrange
            var resolver = new TestTagHelperDescriptorResolver(
                new LookupBasedTagHelperTypeResolver(
                    new Dictionary<string, IEnumerable<Type>>(StringComparer.OrdinalIgnoreCase)
                    {
                        { AssemblyName, new Type[]{ Valid_PlainTagHelperType, Valid_InheritedTagHelperType } },
                    }));
            var expectedDescriptors = new TagHelperDescriptor[]
            {
                Valid_PlainTagHelperDescriptor,
                Valid_InheritedTagHelperDescriptor
            };

            // Act
            var descriptors = resolver.Resolve("*, " + AssemblyName).ToArray();

            // Assert
            Assert.Equal(descriptors.Length, 2);
            Assert.Equal(expectedDescriptors, descriptors, CaseSensitiveTagHelperDescriptorComparer.Default);
        }