parent
94fa34ca41
commit
f8c7f1ab78
|
|
@ -97,7 +97,6 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
|
|||
{
|
||||
// Arrange
|
||||
var selector = CreateSelector();
|
||||
|
||||
var expected =
|
||||
"The view component name 'Ambiguous' matched multiple types:" + Environment.NewLine +
|
||||
$"Type: '{typeof(ViewComponentContainer.Ambiguous1)}' - " +
|
||||
|
|
@ -112,6 +111,27 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
|
|||
Assert.Equal(expected, ex.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Name")]
|
||||
[InlineData("Ambiguous.Name")]
|
||||
public void SelectComponent_AmbiguityDueToDerivation(string name)
|
||||
{
|
||||
// Arrange
|
||||
var selector = CreateSelector();
|
||||
var expected =
|
||||
$"The view component name '{name}' matched multiple types:" + Environment.NewLine +
|
||||
$"Type: '{typeof(ViewComponentContainer.AmbiguousBase)}' - " +
|
||||
"Name: 'Ambiguous.Name'" + Environment.NewLine +
|
||||
$"Type: '{typeof(ViewComponentContainer.DerivedAmbiguous)}' - " +
|
||||
"Name: 'Ambiguous.Name'";
|
||||
|
||||
// Act
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => selector.SelectComponent(name));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SelectComponent_FullNameToAvoidAmbiguity()
|
||||
{
|
||||
|
|
@ -125,6 +145,19 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
|
|||
Assert.Same(typeof(ViewComponentContainer.Ambiguous1).GetTypeInfo(), result.TypeInfo);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SelectComponent_OverrideNameToAvoidAmbiguity()
|
||||
{
|
||||
// Arrange
|
||||
var selector = CreateSelector();
|
||||
|
||||
// Act
|
||||
var result = selector.SelectComponent("NonAmbiguousName");
|
||||
|
||||
// Assert
|
||||
Assert.Same(typeof(ViewComponentContainer.DerivedAmbiguousWithOverriddenName).GetTypeInfo(), result.TypeInfo);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("FullNameInAttribute")]
|
||||
[InlineData("CoolNameSpace.FullNameInAttribute")]
|
||||
|
|
@ -143,7 +176,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
|
|||
private IViewComponentSelector CreateSelector()
|
||||
{
|
||||
var provider = new DefaultViewComponentDescriptorCollectionProvider(
|
||||
new FilteredViewComponentDescriptorProvider());
|
||||
new FilteredViewComponentDescriptorProvider());
|
||||
|
||||
return new DefaultViewComponentSelector(provider);
|
||||
}
|
||||
|
||||
|
|
@ -187,6 +221,21 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
|
|||
{
|
||||
public string Invoke() => "Hello";
|
||||
}
|
||||
|
||||
[ViewComponent(Name = "Ambiguous.Name")]
|
||||
public class AmbiguousBase
|
||||
{
|
||||
public string Invoke() => "Hello";
|
||||
}
|
||||
|
||||
public class DerivedAmbiguous : AmbiguousBase
|
||||
{
|
||||
}
|
||||
|
||||
[ViewComponent(Name = "NonAmbiguousName")]
|
||||
public class DerivedAmbiguousWithOverriddenName : AmbiguousBase
|
||||
{
|
||||
}
|
||||
}
|
||||
// This will only consider types nested inside this class as ViewComponent classes
|
||||
private class FilteredViewComponentDescriptorProvider : DefaultViewComponentDescriptorProvider
|
||||
|
|
@ -196,12 +245,13 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
|
|||
{
|
||||
}
|
||||
|
||||
// For error messages in tests above, ensure the TestApplicationPart returns types in a consistent order.
|
||||
public FilteredViewComponentDescriptorProvider(params Type[] allowedTypes)
|
||||
: base(GetApplicationPartManager(allowedTypes.Select(t => t.GetTypeInfo())))
|
||||
: base(GetApplicationPartManager(allowedTypes.OrderBy(type => type.Name, StringComparer.Ordinal)))
|
||||
{
|
||||
}
|
||||
|
||||
private static ApplicationPartManager GetApplicationPartManager(IEnumerable<TypeInfo> types)
|
||||
private static ApplicationPartManager GetApplicationPartManager(IEnumerable<Type> types)
|
||||
{
|
||||
var manager = new ApplicationPartManager();
|
||||
manager.ApplicationParts.Add(new TestApplicationPart(types));
|
||||
|
|
|
|||
|
|
@ -35,7 +35,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
|
|||
// The Attribute does apply to derived classes.
|
||||
[InlineData(typeof(WithAttribute), true)]
|
||||
[InlineData(typeof(DerivedWithAttribute), true)]
|
||||
|
||||
[InlineData(typeof(WithAttributeAndName), true)]
|
||||
[InlineData(typeof(DerivedWithAttributeAndName), true)]
|
||||
[InlineData(typeof(DerivedWithOverriddenAttributeName), true)]
|
||||
|
||||
// Value types cannot be view components
|
||||
[InlineData(typeof(int), false)]
|
||||
public void IsComponent(Type type, bool expected)
|
||||
|
|
@ -47,6 +50,44 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents
|
|||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(PublicClass), "PublicClass")]
|
||||
[InlineData(typeof(GenericViewComponent<string>), "GenericViewComponent`1")]
|
||||
[InlineData(typeof(NamingConventionViewComponent), "NamingConvention")]
|
||||
[InlineData(typeof(CaseInsensitiveNamingConventionVIEWCOMPONENT), "CaseInsensitiveNamingConvention")]
|
||||
[InlineData(typeof(WithAttribute), "WithAttribute")]
|
||||
[InlineData(typeof(DerivedWithAttribute), "DerivedWithAttribute")]
|
||||
[InlineData(typeof(WithAttributeAndName), "Name")]
|
||||
[InlineData(typeof(DerivedWithAttributeAndName), "Name")]
|
||||
[InlineData(typeof(DerivedWithOverriddenAttributeName), "Name")]
|
||||
public void GetComponentName(Type type, string expected)
|
||||
{
|
||||
// Arrange & Act
|
||||
var result = ViewComponentConventions.GetComponentName(type.GetTypeInfo());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(PublicClass), "Microsoft.AspNetCore.Mvc.ViewComponentConventionsTestClasses.PublicClass")]
|
||||
[InlineData(typeof(GenericViewComponent<string>), "Microsoft.AspNetCore.Mvc.ViewComponentConventionsTestClasses.GenericViewComponent`1")]
|
||||
[InlineData(typeof(NamingConventionViewComponent), "Microsoft.AspNetCore.Mvc.ViewComponentConventionsTestClasses.NamingConvention")]
|
||||
[InlineData(typeof(CaseInsensitiveNamingConventionVIEWCOMPONENT), "Microsoft.AspNetCore.Mvc.ViewComponentConventionsTestClasses.CaseInsensitiveNamingConvention")]
|
||||
[InlineData(typeof(WithAttribute), "Microsoft.AspNetCore.Mvc.ViewComponentConventionsTestClasses.WithAttribute")]
|
||||
[InlineData(typeof(DerivedWithAttribute), "Microsoft.AspNetCore.Mvc.ViewComponentConventionsTestClasses.DerivedWithAttribute")]
|
||||
[InlineData(typeof(WithAttributeAndName), "Name")]
|
||||
[InlineData(typeof(DerivedWithAttributeAndName), "Name")]
|
||||
[InlineData(typeof(DerivedWithOverriddenAttributeName), "New.Name")]
|
||||
public void GetComponentFullName(Type type, string expected)
|
||||
{
|
||||
// Arrange & Act
|
||||
var result = ViewComponentConventions.GetComponentFullName(type.GetTypeInfo());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, result);
|
||||
}
|
||||
|
||||
public class PublicNestedClass : ViewComponent
|
||||
{
|
||||
}
|
||||
|
|
@ -105,4 +146,18 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponentConventionsTestClasses
|
|||
public class DerivedWithAttribute : WithAttribute
|
||||
{
|
||||
}
|
||||
|
||||
[ViewComponent(Name = "Name")]
|
||||
public class WithAttributeAndName
|
||||
{
|
||||
}
|
||||
|
||||
public class DerivedWithAttributeAndName : WithAttributeAndName
|
||||
{
|
||||
}
|
||||
|
||||
[ViewComponent(Name = "New.Name")]
|
||||
public class DerivedWithOverriddenAttributeName : WithAttributeAndName
|
||||
{
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue