[Fact] // This component has lots of properties that don't become components. public void Execute_IgnoredProperties_CreatesDescriptor() { // Arrange var compilation = BaseCompilation.AddSyntaxTrees(Parse(@" using Microsoft.AspNetCore.Blazor.Components; namespace Test { public abstract class MyBase : BlazorComponent { [Parameter] protected string Hidden { get; set; } } public class MyComponent : MyBase { [Parameter] string NoSetter { get; } [Parameter] static string StaticProperty { get; set; } public string NoParameterAttribute { get; set; } // No attribute here, hides base-class property of the same name. protected new int Hidden { get; set; } public string this[int i] { get { throw null; } set { throw null; } } } } ")); Assert.Empty(compilation.GetDiagnostics()); var context = TagHelperDescriptorProviderContext.Create(); context.SetCompilation(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act provider.Execute(context); // Assert var components = ExcludeBuiltInComponents(context); var component = Assert.Single(components); Assert.Equal("TestAssembly", component.AssemblyName); Assert.Equal("Test.MyComponent", component.Name); Assert.Empty(component.BoundAttributes); }
[Fact] // enum properties have some special intellisense behavior public void Excecute_EnumProperty_CreatesDescriptor() { // Arrange var compilation = BaseCompilation.AddSyntaxTrees(Parse(@" using Microsoft.AspNetCore.Blazor.Components; namespace Test { public enum MyEnum { One, Two } public class MyComponent : BlazorComponent { [Parameter] MyEnum MyProperty { get; set; } } } ")); Assert.Empty(compilation.GetDiagnostics()); var context = TagHelperDescriptorProviderContext.Create(); context.SetCompilation(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act provider.Execute(context); // Assert var components = ExcludeBuiltInComponents(context); var component = Assert.Single(components); Assert.Equal("TestAssembly", component.AssemblyName); Assert.Equal("Test.MyComponent", component.Name); var attribute = Assert.Single(component.BoundAttributes); Assert.Equal("MyProperty", attribute.Name); Assert.Equal("Test.MyEnum", attribute.TypeName); Assert.False(attribute.HasIndexer); Assert.False(attribute.IsBooleanProperty); Assert.True(attribute.IsEnum); Assert.False(attribute.IsStringProperty); }
public void Execute_NoMatchedPropertiesOnComponent_IgnoresComponent() { // Arrange var compilation = BaseCompilation.AddSyntaxTrees(Parse(@" using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; namespace Test { public class MyComponent : IComponent { public void Attach(RenderHandle renderHandle) { } public Task SetParametersAsync(ParameterView parameters) { return Task.CompletedTask; } public string MyProperty { get; set; } public Action<string> MyPropertyChangedNotMatch { get; set; } } } ")); Assert.Empty(compilation.GetDiagnostics()); var context = TagHelperDescriptorProviderContext.Create(); context.SetCompilation(compilation); // We run after component discovery and depend on the results. var componentProvider = new ComponentTagHelperDescriptorProvider(); componentProvider.Execute(context); var provider = new BindTagHelperDescriptorProvider(); // Act provider.Execute(context); // Assert var matches = GetBindTagHelpers(context); matches = AssertAndExcludeFullyQualifiedNameMatchComponents(matches, expectedCount: 0); Assert.Empty(matches); }
public void Execute_DelegateProperty_CreatesDescriptor() { // Arrange var compilation = BaseCompilation.AddSyntaxTrees(Parse(@" using System; using Microsoft.AspNetCore.Blazor; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { public Action<UIMouseEventArgs> OnClick { get; set; } } } ")); Assert.Empty(compilation.GetDiagnostics()); var context = TagHelperDescriptorProviderContext.Create(); context.SetCompilation(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act provider.Execute(context); // Assert var components = ExcludeBuiltInComponents(context); var component = Assert.Single(components); Assert.Equal("TestAssembly", component.AssemblyName); Assert.Equal("Test.MyComponent", component.Name); var attribute = Assert.Single(component.BoundAttributes); Assert.Equal("OnClick", attribute.Name); Assert.Equal("System.Action<Microsoft.AspNetCore.Blazor.UIMouseEventArgs>", attribute.TypeName); Assert.False(attribute.HasIndexer); Assert.False(attribute.IsBooleanProperty); Assert.False(attribute.IsEnum); Assert.False(attribute.IsStringProperty); Assert.True(attribute.IsDelegateProperty()); }
public void Excecute_NoMatchedPropertiesOnComponent_IgnoresComponent() { // Arrange var compilation = BaseCompilation.AddSyntaxTrees(Parse(@" using System; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : IComponent { public void Init(RenderHandle renderHandle) { } public void SetParameters(ParameterCollection parameters) { } public string MyProperty { get; set; } public Action<string> MyPropertyChangedNotMatch { get; set; } } } ")); Assert.Empty(compilation.GetDiagnostics()); var context = TagHelperDescriptorProviderContext.Create(); context.SetCompilation(compilation); // We run after component discovery and depend on the results. var componentProvider = new ComponentTagHelperDescriptorProvider(); componentProvider.Execute(context); var provider = new BindTagHelperDescriptorProvider(); // Act provider.Execute(context); // Assert var matches = GetBindTagHelpers(context); Assert.Empty(matches); }
public void Excecute_FindsBlazorComponentType_CreatesDescriptor() { // Arrange var compilation = BaseCompilation.AddSyntaxTrees(Parse(@" using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { [Parameter] string MyProperty { get; set; } } } ")); Assert.Empty(compilation.GetDiagnostics()); var context = TagHelperDescriptorProviderContext.Create(); context.SetCompilation(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act provider.Execute(context); // Assert var components = ExcludeBuiltInComponents(context); var component = Assert.Single(components); Assert.Equal("TestAssembly", component.AssemblyName); Assert.Equal("Test.MyComponent", component.Name); var attribute = Assert.Single(component.BoundAttributes); Assert.Equal("MyProperty", attribute.Name); Assert.Equal("System.String", attribute.TypeName); }
public void Excecute_FindsBindTagHelperOnComponentType_CreatesDescriptor() { // Arrange var compilation = BaseCompilation.AddSyntaxTrees(Parse(@" using System; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : IComponent { public void Init(RenderHandle renderHandle) { } public void SetParameters(ParameterCollection parameters) { } [Parameter] string MyProperty { get; set; } [Parameter] Action<string> MyPropertyChanged { get; set; } } } ")); Assert.Empty(compilation.GetDiagnostics()); var context = TagHelperDescriptorProviderContext.Create(); context.SetCompilation(compilation); // We run after component discovery and depend on the results. var componentProvider = new ComponentTagHelperDescriptorProvider(); componentProvider.Execute(context); var provider = new BindTagHelperDescriptorProvider(); // Act provider.Execute(context); // Assert var matches = GetBindTagHelpers(context); var bind = Assert.Single(matches); // These are features Bind Tags Helpers don't use. Verifying them once here and // then ignoring them. Assert.Empty(bind.AllowedChildTags); Assert.Null(bind.TagOutputHint); // These are features that are invariants of all Bind Tag Helpers. Verifying them once // here and then ignoring them. Assert.Empty(bind.Diagnostics); Assert.False(bind.HasErrors); Assert.Equal(BlazorMetadata.Bind.TagHelperKind, bind.Kind); Assert.Equal(BlazorMetadata.Bind.RuntimeName, bind.Metadata[TagHelperMetadata.Runtime.Name]); Assert.False(bind.IsDefaultKind()); Assert.False(bind.KindUsesDefaultTagHelperRuntime()); Assert.Equal("MyProperty", bind.Metadata[BlazorMetadata.Bind.ValueAttribute]); Assert.Equal("MyPropertyChanged", bind.Metadata[BlazorMetadata.Bind.ChangeAttribute]); Assert.Equal( "Binds the provided expression to the 'MyProperty' property and a change event " + "delegate to the 'MyPropertyChanged' property of the component.", bind.Documentation); // These are all trivally derived from the assembly/namespace/type name Assert.Equal("TestAssembly", bind.AssemblyName); Assert.Equal("Test.MyComponent", bind.Name); Assert.Equal("Test.MyComponent", bind.DisplayName); Assert.Equal("Test.MyComponent", bind.GetTypeName()); var rule = Assert.Single(bind.TagMatchingRules); Assert.Empty(rule.Diagnostics); Assert.False(rule.HasErrors); Assert.Null(rule.ParentTag); Assert.Equal("MyComponent", rule.TagName); Assert.Equal(TagStructure.Unspecified, rule.TagStructure); var requiredAttribute = Assert.Single(rule.Attributes); Assert.Empty(requiredAttribute.Diagnostics); Assert.Equal("bind-MyProperty", requiredAttribute.DisplayName); Assert.Equal("bind-MyProperty", requiredAttribute.Name); Assert.Equal(RequiredAttributeDescriptor.NameComparisonMode.FullMatch, requiredAttribute.NameComparison); Assert.Null(requiredAttribute.Value); Assert.Equal(RequiredAttributeDescriptor.ValueComparisonMode.None, requiredAttribute.ValueComparison); var attribute = Assert.Single(bind.BoundAttributes); // Invariants Assert.Empty(attribute.Diagnostics); Assert.False(attribute.HasErrors); Assert.Equal(BlazorMetadata.Bind.TagHelperKind, attribute.Kind); Assert.False(attribute.IsDefaultKind()); Assert.False(attribute.HasIndexer); Assert.Null(attribute.IndexerNamePrefix); Assert.Null(attribute.IndexerTypeName); Assert.False(attribute.IsIndexerBooleanProperty); Assert.False(attribute.IsIndexerStringProperty); Assert.Equal( "Binds the provided expression to the 'MyProperty' property and a change event " + "delegate to the 'MyPropertyChanged' property of the component.", attribute.Documentation); Assert.Equal("bind-MyProperty", attribute.Name); Assert.Equal("MyProperty", attribute.GetPropertyName()); Assert.Equal("string Test.MyComponent.MyProperty", attribute.DisplayName); // Defined from the property type Assert.Equal("System.String", attribute.TypeName); Assert.True(attribute.IsStringProperty); Assert.False(attribute.IsBooleanProperty); Assert.False(attribute.IsEnum); }
public void Excecute_FindsIComponentType_CreatesDescriptor() { // Arrange var compilation = BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(@" using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : IComponent { public void Init(RenderHandle renderHandle) { } public void SetParameters(ParameterCollection parameters) { } public string MyProperty { get; set; } } } ")); Assert.Empty(compilation.GetDiagnostics()); var context = TagHelperDescriptorProviderContext.Create(); context.SetCompilation(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act provider.Execute(context); // Assert var components = ExcludeBuiltInComponents(context); var component = Assert.Single(components); // These are features Components don't use. Verifying them once here and // then ignoring them. Assert.Empty(component.AllowedChildTags); Assert.Null(component.TagOutputHint); // These are features that are invariants of all Components. Verifying them once // here and then ignoring them. Assert.Empty(component.Diagnostics); Assert.False(component.HasErrors); Assert.Equal(ComponentTagHelperDescriptorProvider.ComponentTagHelperKind, component.Kind); Assert.Equal("Blazor.Component-0.1", component.Kind); Assert.False(component.IsDefaultKind()); Assert.False(component.KindUsesDefaultTagHelperRuntime()); // No documentation in this test Assert.Null(component.Documentation); // These are all trivally derived from the assembly/namespace/type name Assert.Equal("TestAssembly", component.AssemblyName); Assert.Equal("Test.MyComponent", component.Name); Assert.Equal("Test.MyComponent", component.DisplayName); Assert.Equal("Test.MyComponent", component.GetTypeName()); // Our use of matching rules is also very simple, and derived from the name. Veriying // it once in detail here and then ignoring it. var rule = Assert.Single(component.TagMatchingRules); Assert.Empty(rule.Attributes); Assert.Empty(rule.Diagnostics); Assert.False(rule.HasErrors); Assert.Null(rule.ParentTag); Assert.Equal("MyComponent", rule.TagName); Assert.Equal(TagStructure.Unspecified, rule.TagStructure); // Our use of metadata is also (for now) an invariant for all Components - other than the type name // which is trivial. Verifying it once in detail and then ignoring it. Assert.Collection( component.Metadata.OrderBy(kvp => kvp.Key), kvp => { Assert.Equal(TagHelperMetadata.Common.TypeName, kvp.Key); Assert.Equal("Test.MyComponent", kvp.Value); }, kvp => { Assert.Equal(TagHelperMetadata.Runtime.Name, kvp.Key); Assert.Equal("Blazor.IComponent", kvp.Value); }); // Our use of bound attributes is what tests will focus on. As you might expect right now, this test // is going to cover a lot of trivial stuff that will be true for all components/component-properties. var attribute = Assert.Single(component.BoundAttributes); // Invariants Assert.Empty(attribute.Diagnostics); Assert.False(attribute.HasErrors); Assert.Equal("Blazor.Component-0.1", attribute.Kind); Assert.False(attribute.IsDefaultKind()); // Related to dictionaries/indexers, not supported currently, not sure if we ever will Assert.False(attribute.HasIndexer); Assert.Null(attribute.IndexerNamePrefix); Assert.Null(attribute.IndexerTypeName); Assert.False(attribute.IsIndexerBooleanProperty); Assert.False(attribute.IsIndexerStringProperty); // No documentation in this test Assert.Null(attribute.Documentation); // Names are trivially derived from the property name Assert.Equal("MyProperty", attribute.Name); Assert.Equal("MyProperty", attribute.GetPropertyName()); Assert.Equal("string Test.MyComponent.MyProperty", attribute.DisplayName); // Defined from the property type Assert.Equal("System.String", attribute.TypeName); Assert.True(attribute.IsStringProperty); Assert.False(attribute.IsBooleanProperty); Assert.False(attribute.IsEnum); // Our use of metadata is also (for now) an invariant for all Component properties - other than the type name // which is trivial. Verifying it once in detail and then ignoring it. Assert.Collection( attribute.Metadata.OrderBy(kvp => kvp.Key), kvp => { Assert.Equal(TagHelperMetadata.Common.PropertyName, kvp.Key); Assert.Equal("MyProperty", kvp.Value); }); }