Пример #1
0
        public void GetExportedTypes_WorksIfAttributesAreMalformedErrors()
        {
            // Arrange
            var compilation       = CompilationUtility.GetCompilation("BadFiles.TypeWithMalformedAttribute");
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var actual = Assert.Single(exportedTypes);
            var targetElementAttribute = Assert.Single(actual.GetCustomAttributes <HtmlTargetElementAttribute>());

            Assert.Equal("img", targetElementAttribute.Tag);
            Assert.Null(targetElementAttribute.Attributes);

            Assert.Empty(actual.GetCustomAttributes <EditorBrowsableAttribute>());
            var ex = Assert.Throws <InvalidOperationException>(
                () => actual.GetCustomAttributes <CustomValidationAttribute>());

            Assert.Equal($"Unable to find a suitable constructor for type '{typeof(CustomValidationAttribute).FullName}'.",
                         ex.Message);

            ex = Assert.Throws <InvalidOperationException>(
                () => actual.GetCustomAttributes <RestrictChildrenAttribute>());
            Assert.Equal($"Unable to find a suitable constructor for type '{typeof(RestrictChildrenAttribute).FullName}'.",
                         ex.Message);
        }
Пример #2
0
        public void GetExportedTypes_WorksForPropertiesWithErrors()
        {
            // Arrange
            var compilation       = CompilationUtility.GetCompilation("BadFiles.TypeWithMalformedProperties");
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var actual = Assert.Single(exportedTypes);

            Assert.Collection(actual.Properties,
                              property =>
            {
                Assert.Equal("DateTime", property.Name);
                Assert.Equal(typeof(DateTime).Name, property.PropertyType.Name);
                Assert.True(property.HasPublicGetter);
                Assert.False(property.HasPublicSetter);
            },
                              property =>
            {
                Assert.Equal("DateTime2", property.Name);
                Assert.Equal(typeof(int).Name, property.PropertyType.Name);
                Assert.True(property.HasPublicGetter);
                Assert.False(property.HasPublicSetter);
            },
                              property =>
            {
                Assert.Equal("CustomOrder", property.Name);
                Assert.Equal(typeof(string).Name, property.PropertyType.Name);
                Assert.True(property.HasPublicGetter);
                Assert.True(property.HasPublicSetter);
            });
        }
Пример #3
0
        public void GetExportedTypes_WorksIfAttributeConstructorArgumentsAreOutOfOrder()
        {
            // Arrange
            var expectedType      = typeof(TypeWithNamedAttributes);
            var compilation       = CompilationUtility.GetCompilation(expectedType.Name);
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var exportedType = Assert.Single(exportedTypes);

            AssertEqual(expectedType, exportedType);

            var attributes = exportedType.GetCustomAttributes <MultipleConstructorArgumentsAttribute>();

            AssertAttributes <MultipleConstructorArgumentsAttribute>(
                expectedType.GetTypeInfo(),
                exportedType,
                (expectedAttribute, actualAttribute) =>
            {
                Assert.Equal(expectedAttribute.FirstArgument, actualAttribute.FirstArgument);
                Assert.Equal(expectedAttribute.SecondArgument, actualAttribute.SecondArgument);
                Assert.Equal(expectedAttribute.ThirdArgument, actualAttribute.ThirdArgument);
            },
                discoveredAttributes => discoveredAttributes.OrderBy(attribute => attribute.FirstArgument));
        }
Пример #4
0
        public void TypesReturnedFromGetTopLevelExportedTypes_ReturnsTopLevelTypeInfo(Type expected)
        {
            // Arrange
            var compilation       = CompilationUtility.GetCompilation("TagHelperDescriptorFactoryTagHelpers");
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var actual = Assert.Single(exportedTypes, type => type.FullName == expected.FullName);

            AssertEqual(expected, actual);
        }
Пример #5
0
        public void GetExportedTypes_CorrectlyIdentifiesIfTypeDerivesFromDictionary()
        {
            // Arrange
            var compilation       = CompilationUtility.GetCompilation(nameof(TypeWithDictionaryProperties));
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var exportedType = Assert.Single(exportedTypes);

            AssertEqual(typeof(TypeWithDictionaryProperties), exportedType);
        }
        public override ITypeInfo GetTypeInfo(Type tagHelperType)
        {
            var paths = new[]
            {
                $"TagHelperDescriptorFactoryTagHelpers",
                $"CommonTagHelpers",
            };

            var compilation = CompilationUtility.GetCompilation(paths);
            var typeResolver = new PrecompilationTagHelperTypeResolver(compilation);

            return Assert.Single(typeResolver.GetExportedTypes(CompilationUtility.GeneratedAssemblyName),
                generatedType => string.Equals(generatedType.FullName, tagHelperType.FullName, StringComparison.Ordinal));
        }
Пример #7
0
        public override ITypeInfo GetTypeInfo(Type tagHelperType)
        {
            var paths = new[]
            {
                $"TagHelperDescriptorFactoryTagHelpers",
                $"CommonTagHelpers",
            };

            var compilation  = CompilationUtility.GetCompilation(paths);
            var typeResolver = new PrecompilationTagHelperTypeResolver(compilation);

            return(Assert.Single(typeResolver.GetExportedTypes(CompilationUtility.GeneratedAssemblyName),
                                 generatedType => string.Equals(generatedType.FullName, tagHelperType.FullName, StringComparison.Ordinal)));
        }
Пример #8
0
        public void GetExportedTypes_WorksForTypesWithErrors()
        {
            // Arrange
            var compilation       = CompilationUtility.GetCompilation("BadFiles.TypeWithMissingReferences");
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var type = Assert.Single(exportedTypes);

            Assert.False(type.ImplementsInterface(TagHelperTypeInfo));
        }
Пример #9
0
        public void PropertyNamesForComplexPropertiesAreGeneratedCorrectly()
        {
            // Arrange
            var expectedType      = typeof(TypeWithComplexPropertyFullNames);
            var compilation       = CompilationUtility.GetCompilation(expectedType.Name);
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var actual = Assert.Single(exportedTypes);

            AssertEqual(expectedType, actual);
        }
Пример #10
0
        public void ImplementsInterface_ReturnsFalseIfTypeDoesNotDerivesFromInterface(Type interfaceType)
        {
            // Arrange
            var interfaceTypeInfo = new RuntimeTypeInfo(interfaceType.GetTypeInfo());
            var compilation       = CompilationUtility.GetCompilation("TagHelperDescriptorFactoryTagHelpers");
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var actual = Assert.Single(exportedTypes, type => type.Name == nameof(RequiredParentTagHelper));

            Assert.False(actual.ImplementsInterface(interfaceTypeInfo));
        }
Пример #11
0
        public void ImplementsInterface_ReturnsTrueIfTypeDerivesFromInterface(Type expected)
        {
            // Arrange
            var interfaceType     = new RuntimeTypeInfo(typeof(IEnumerable <string>).GetTypeInfo());
            var compilation       = CompilationUtility.GetCompilation(expected.Name);
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var actual = Assert.Single(exportedTypes);

            Assert.True(actual.ImplementsInterface(interfaceType));
        }
Пример #12
0
        public void GetExportedTypes_WithDerivedAttributes()
        {
            // Arrange
            var expected          = typeof(DerivedTagHelper);
            var compilation       = CompilationUtility.GetCompilation("TagHelperDescriptorFactoryTagHelpers");
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var actual = Assert.Single(exportedTypes, type => type.Name == expected.Name);

            AssertEqual(expected, actual);

            var expectedProperties = expected.GetProperties();

            AssertAttributes <BaseAttribute>(
                expectedProperties.First(p => p.Name == nameof(DerivedTagHelper.DerivedProperty)),
                actual.Properties.First(p => p.Name == nameof(DerivedTagHelper.DerivedProperty)),
                (expectedAttribute, actualAttribute) =>
            {
                Assert.Equal(expectedAttribute.BaseProperty, actualAttribute.BaseProperty);
            });

            AssertAttributes <HtmlAttributeNameAttribute>(
                expectedProperties.First(p => p.Name == nameof(DerivedTagHelper.NewProperty) &&
                                         p.PropertyType == typeof(Type)),
                actual.Properties.First(p => p.Name == nameof(DerivedTagHelper.NewProperty) &&
                                        p.PropertyType.Name == typeof(Type).Name),
                (expectedAttribute, actualAttribute) =>
            {
                Assert.Equal(expectedAttribute.Name, actualAttribute.Name);
                Assert.Equal(
                    expectedAttribute.DictionaryAttributePrefix,
                    actualAttribute.DictionaryAttributePrefix);
            });

            var expectedVirtualProperty = expectedProperties.First(
                p => p.Name == nameof(DerivedTagHelper.VirtualProperty));
            var actualVirtualProperty = actual.Properties.First(
                p => p.Name == nameof(DerivedTagHelper.VirtualProperty));

            Assert.Empty(expectedVirtualProperty.GetCustomAttributes <HtmlAttributeNotBoundAttribute>());
            Assert.Empty(actualVirtualProperty.GetCustomAttributes <HtmlAttributeNotBoundAttribute>());
        }
Пример #13
0
        public void ImplementsInterface_ThrowsIfPassedInParameterIsNotRuntimeTypeOrCodeAnalysisBasedTypeInfo()
        {
            // Arrange
            var interfaceType     = new TestTypeInfo();
            var compilation       = CompilationUtility.GetCompilation(nameof(DerivingFromList));
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var actual = Assert.Single(exportedTypes);

            ExceptionAssert.ThrowsArgument(() => actual.ImplementsInterface(interfaceType),
                                           "interfaceTypeInfo",
                                           $"Argument must be an instance of '{typeof(RuntimeTypeInfo)}' or '{typeof(CodeAnalysisSymbolBasedTypeInfo)}'.");
        }
Пример #14
0
        public void GetTopLevelExportedTypes_DoesNotReturnNonPublicOrNestedTypes()
        {
            // Arrange
            var compilation       = CompilationUtility.GetCompilation("AssemblyWithNonPublicTypes");
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            Assert.Collection(exportedTypes,
                              typeInfo =>
            {
                AssertEqual(typeof(PublicType), typeInfo);
            },
                              typeInfo =>
            {
                AssertEqual(typeof(ContainerType), typeInfo);
            },
                              typeInfo =>
            {
                AssertEqual(typeof(GenericType <>), typeInfo);
            });
        }
Пример #15
0
        public void GetTopLevelExportedTypes_DoesNotReturnValueTypesOrInterfaces()
        {
            // Arrange
            var compilation       = CompilationUtility.GetCompilation("AssemblyWithNonTypes");
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            Assert.Collection(exportedTypes,
                              typeInfo =>
            {
                AssertEqual(typeof(MyAbstractClass), typeInfo);
            },
                              typeInfo =>
            {
                AssertEqual(typeof(MyPartialClass), typeInfo);
            },
                              typeInfo =>
            {
                AssertEqual(typeof(MySealedClass), typeInfo);
            });
        }
Пример #16
0
        public void GetExportedTypes_WorksCorrectlyForOverridenProperties()
        {
            // Arrange
            var compilation       = CompilationUtility.GetCompilation("TypesWithInheritedProperties");
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            Assert.Collection(exportedTypes,
                              typeInfo =>
            {
                AssertEqual(typeof(Animal), typeInfo);
            },
                              typeInfo =>
            {
                AssertEqual(typeof(Mammal), typeInfo);
            },
                              typeInfo =>
            {
                AssertEqual(typeof(Dog), typeInfo);
            });
        }
Пример #17
0
        public void GetExportedTypes_PopulatesAttributes()
        {
            // Arrange
            var expected          = typeof(TypeWithAttributes).GetTypeInfo();
            var compilation       = CompilationUtility.GetCompilation(expected.Name);
            var tagHelperResolver = new PrecompilationTagHelperTypeResolver(compilation);

            // Act
            var exportedTypes = tagHelperResolver.GetExportedTypes(compilation.AssemblyName);

            // Assert
            var actual = Assert.Single(exportedTypes);

            AssertEqual(expected.AsType(), actual);

            AssertAttributes <HtmlTargetElementAttribute>(
                expected,
                actual,
                (expectedAttribute, actualAttribute) =>
            {
                Assert.Equal(expectedAttribute.Tag, actualAttribute.Tag);
                Assert.Equal(expectedAttribute.Attributes, actualAttribute.Attributes);
            },
                discoveredAttributes => discoveredAttributes.OrderBy(attribute => attribute.Tag));

            // Verify if enum in attribute constructors works.
            AssertAttributes <EditorBrowsableAttribute>(
                expected,
                actual,
                (expectedAttribute, actualAttribute) =>
            {
                Assert.Equal(expectedAttribute.State, actualAttribute.State);
            });

            // Verify if enum in attribute property works.
            AssertAttributes <EnumPropertyAttribute>(
                expected,
                actual,
                (expectedAttribute, actualAttribute) =>
            {
                Assert.Equal(expectedAttribute.DayOfWeek, actualAttribute.DayOfWeek);
            });

            // Verify if Type in attribute constructor and property works.
            AssertAttributes <CustomValidationAttribute>(
                expected,
                actual,
                (expectedAttribute, actualAttribute) =>
            {
                Assert.Same(expectedAttribute.ValidatorType, actualAttribute.ValidatorType);
                Assert.Equal(expectedAttribute.Method, actualAttribute.Method);
                Assert.Same(
                    expectedAttribute.ErrorMessageResourceType,
                    actualAttribute.ErrorMessageResourceType);
            });

            // Verify if array arguments work in constructor.
            AssertAttributes <RestrictChildrenAttribute>(
                expected,
                actual,
                (expectedAttribute, actualAttribute) =>
            {
                Assert.Equal(
                    expectedAttribute.ChildTags,
                    actualAttribute.ChildTags);
            });

            // Complex array bindings
            AssertAttributes <ArrayPropertiesAttribute>(
                expected,
                actual,
                (expectedAttribute, actualAttribute) =>
            {
                Assert.Equal(expectedAttribute.ArrayOfTypes, actualAttribute.ArrayOfTypes);
                Assert.Equal(expectedAttribute.ArrayOfInts, actualAttribute.ArrayOfInts);
                Assert.Equal(expectedAttribute.Days, actualAttribute.Days);
            });

            var expectedProperties = expected.DeclaredProperties;

            Assert.Collection(actual.Properties,
                              property =>
            {
                Assert.Equal(nameof(TypeWithAttributes.Src), property.Name);
                var expectedProperty = Assert.Single(expectedProperties, p => p.Name == property.Name);
                AssertAttributes <HtmlAttributeNameAttribute>(
                    expectedProperty,
                    property,
                    (expectedAttribute, actualAttribute) =>
                {
                    Assert.Equal(expectedAttribute.Name, actualAttribute.Name);
                    Assert.Equal(expectedAttribute.DictionaryAttributePrefix, actualAttribute.DictionaryAttributePrefix);
                });

                // Verify boolean values bind.
                AssertAttributes <RequiredAttribute>(
                    expectedProperty,
                    property,
                    (expectedAttribute, actualAttribute) =>
                {
                    Assert.Equal(expectedAttribute.AllowEmptyStrings, actualAttribute.AllowEmptyStrings);
                });
            },
                              property =>
            {
                Assert.Equal(nameof(TypeWithAttributes.AppendVersion), property.Name);
                var expectedProperty = Assert.Single(expectedProperties, p => p.Name == property.Name);
                AssertAttributes <HtmlAttributeNameAttribute>(
                    expectedProperty,
                    property,
                    (expectedAttribute, actualAttribute) =>
                {
                    Assert.Equal(expectedAttribute.Name, actualAttribute.Name);
                    Assert.Equal(expectedAttribute.DictionaryAttributePrefix, actualAttribute.DictionaryAttributePrefix);
                });

                // Attribute without constructor arguments or properties.
                Assert.Single(expectedProperty.GetCustomAttributes <HtmlAttributeNotBoundAttribute>());
                Assert.Single(property.GetCustomAttributes <HtmlAttributeNotBoundAttribute>());
            },
                              property =>
            {
                Assert.Equal(nameof(TypeWithAttributes.ViewContext), property.Name);
                var expectedProperty = Assert.Single(expectedProperties, p => p.Name == property.Name);

                AssertAttributes <EditorBrowsableAttribute>(
                    expectedProperty,
                    property,
                    (expectedAttribute, actualAttribute) =>
                {
                    Assert.Equal(expectedAttribute.State, actualAttribute.State);
                });

                // Complex array bindings in properties
                AssertAttributes <ArrayPropertiesAttribute>(
                    expected,
                    actual,
                    (expectedAttribute, actualAttribute) =>
                {
                    Assert.Equal(expectedAttribute.ArrayOfTypes, actualAttribute.ArrayOfTypes);
                    Assert.Equal(expectedAttribute.ArrayOfInts, actualAttribute.ArrayOfInts);
                    Assert.Equal(expectedAttribute.Days, actualAttribute.Days);
                });
            },
                              property =>
            {
                Assert.Equal("HostingEnvironment", property.Name);
                Assert.Single(expectedProperties, p => p.Name == property.Name);

                // Complex array bindings in constructor arguments
                AssertAttributes <AttributesWithArrayConstructorArgumentsAttribute>(
                    expected,
                    actual,
                    (expectedAttribute, actualAttribute) =>
                {
                    Assert.Equal(expectedAttribute.StringArgs, actualAttribute.StringArgs);
                    Assert.Equal(expectedAttribute.IntArgs, actualAttribute.IntArgs);
                    Assert.Equal(expectedAttribute.TypeArgs, actualAttribute.TypeArgs);
                });
            });
        }