public void Render_ChildComponent_WithChildContent() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Blazor; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { [Parameter] string MyAttr { get; set; } [Parameter] RenderFragment ChildContent { get; set; } } } ")); var component = CompileToComponent(@" @addTagHelper *, TestAssembly <MyComponent MyAttr=""abc"">Some text<some-child a='1'>Nested text @(""Hello"")</some-child></MyComponent>"); // Act var frames = GetRenderTree(component); // Assert: component frames are correct Assert.Collection( frames, frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0), frame => AssertFrame.Attribute(frame, "MyAttr", "abc", 1), frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 2)); // Assert: Captured ChildContent frames are correct var childFrames = GetFrames((RenderFragment)frames[2].AttributeValue); Assert.Collection( childFrames, frame => AssertFrame.Text(frame, "Some text", 3), frame => AssertFrame.Element(frame, "some-child", 4, 4), frame => AssertFrame.Attribute(frame, "a", "1", 5), frame => AssertFrame.Text(frame, "Nested text ", 6), frame => AssertFrame.Text(frame, "Hello", 7)); }
public void Render_ChildComponent_WithExplicitEventHandler() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using System; using Microsoft.AspNetCore.Components; namespace Test { public class MyComponent : ComponentBase { [Parameter] public Action<EventArgs> OnClick { get; set; } } } ")); var component = CompileToComponent(@" <MyComponent OnClick=""@Increment""/> @code { private int counter; private void Increment(EventArgs e) { counter++; } }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 0), frame => { AssertFrame.Attribute(frame, "OnClick", 1); // The handler will have been assigned to a lambda var handler = Assert.IsType <Action <EventArgs> >(frame.AttributeValue); Assert.Equal("Test.TestComponent", handler.Target.GetType().FullName); Assert.Equal("Increment", handler.Method.Name); }); }
public void Render_ChildContent_ContextParameterNameOnComponent_Invalid_ProducesDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentStringComponent); // Act var generated = CompileToCSharp(@" @addTagHelper *, TestAssembly <RenderChildContentString Context=""@Foo()""> </RenderChildContentString>"); // Assert var diagnostic = Assert.Single(generated.Diagnostics); Assert.Same(BlazorDiagnosticFactory.ChildContentHasInvalidParameterOnComponent.Id, diagnostic.Id); Assert.Equal( "Invalid parameter name. The parameter name attribute 'Context' on component 'RenderChildContentString' can only include literal text.", diagnostic.GetMessage()); }
public void ChildContent_ExplicitChildContent_StartsWithCharThatIsOtherLetterCategory_WhenLocalizedComponentNamesIsAllowed() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); // Act var generated = CompileToCSharp(@$ " <RenderChildContent> <ChildContent> </ChildContent> <繁体字></繁体字> </RenderChildContent>", supportLocalizedComponentNames: true); // Assert Assert.Collection( generated.Diagnostics, d => Assert.Equal("RZ10012", d.Id), d => Assert.Equal("RZ9996", d.Id)); }
private IReadOnlyList <TagHelperDescriptor> GetSurveyPrompt() { AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Components; namespace Test { public class SurveyPrompt : ComponentBase { [Parameter] public string Title { get; set; } } } ")); var generated = CompileToCSharp("SurveyPrompt.razor", string.Empty, throwOnFailure: false, fileKind: FileKinds.Component); var tagHelpers = generated.CodeDocument.GetTagHelperContext().TagHelpers; return(tagHelpers); }
public void GenericComponent_WithMissingTypeParameters_TriggersDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(MultipleGenericParameterComponent); // Act var generated = CompileToCSharp(@" @addTagHelper *, TestAssembly <MultipleGenericParameter TItem1=int />"); // Assert var diagnostic = Assert.Single(generated.Diagnostics); Assert.Same(BlazorDiagnosticFactory.GenericComponentMissingTypeArgument.Id, diagnostic.Id); Assert.Equal( "The component 'MultipleGenericParameter' is missing required type arguments. " + "Specify the missing types using the attributes: 'TItem2', 'TItem3'.", diagnostic.GetMessage()); }
public void ChildContent_ExplicitChildContent_UnrecogizedElement_ProducesDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); // Act var generated = CompileToCSharp(@" <RenderChildContent> <ChildContent> </ChildContent> <UnrecognizedChildContent></UnrecognizedChildContent> </RenderChildContent>"); // Assert Assert.Collection( generated.Diagnostics, d => Assert.Equal("RZ10012", d.Id), d => Assert.Equal("RZ9996", d.Id)); }
public void GenericComponent_WithoutAnyTypeParameters_TriggersDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(GenericContextComponent); // Act var generated = CompileToCSharp(@" @addTagHelper *, TestAssembly <GenericContext />"); // Assert var diagnostic = Assert.Single(generated.Diagnostics); Assert.Same(BlazorDiagnosticFactory.GenericComponentTypeInferenceUnderspecified.Id, diagnostic.Id); Assert.Equal( "The type of component 'GenericContext' cannot be inferred based on the values provided. Consider " + "specifying the type arguments directly using the following attributes: 'TItem'.", diagnostic.GetMessage()); }
public void Render_ChildContent_ExplicitChildContent_UnrecogizedElement_ProducesDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); // Act var generated = CompileToCSharp(@" @addTagHelper *, TestAssembly <RenderChildContent> <ChildContent> </ChildContent> <UnrecognizedChildContent></UnrecognizedChildContent> </RenderChildContent>"); // Assert var diagnostic = Assert.Single(generated.Diagnostics); Assert.Same(BlazorDiagnosticFactory.ChildContentMixedWithExplicitChildContent.Id, diagnostic.Id); }
public void ChildContent_AttributeAndExplicitChildContent_ProducesDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); // Act var generated = CompileToCSharp(@" @{ RenderFragment<string> template = @<div>@context.ToLowerInvariant()</div>; } <RenderChildContent ChildContent=""@template.WithValue(""HI"")""> <ChildContent> Some Content </ChildContent> </RenderChildContent>"); // Assert var diagnostic = Assert.Single(generated.Diagnostics); Assert.Same(ComponentDiagnosticFactory.ChildContentSetByAttributeAndBody.Id, diagnostic.Id); }
public void Render_AttributeChildContent_NoArgTemplate() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); var component = CompileToComponent(@" @{ RenderFragment template = @<div>@(""HI"".ToLowerInvariant())</div>; } <RenderChildContent ChildContent=""@template"" />"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 2), frame => AssertFrame.Attribute(frame, "ChildContent", 3), frame => AssertFrame.Element(frame, "div", 2, 0), frame => AssertFrame.Text(frame, "hi", 1)); }
public void Render_BodyChildContent() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); var component = CompileToComponent(@" <RenderChildContent> <div></div> </RenderChildContent>"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 0), frame => AssertFrame.Attribute(frame, "ChildContent", 1), frame => AssertFrame.Markup(frame, "\n <div></div>\n", 2)); }
public void ChildContent_ExplicitChildContent_ContainsDirectiveAttribute_ProducesDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentStringComponent); // Act var generated = CompileToCSharp(@" <RenderChildContentString> <ChildContent Context=""items"" @key=""Hello""> </ChildContent> </RenderChildContentString>"); // Assert var diagnostic = Assert.Single(generated.Diagnostics); Assert.Same(ComponentDiagnosticFactory.ChildContentHasInvalidAttribute.Id, diagnostic.Id); Assert.Equal( "Unrecognized attribute '@key' on child content element 'ChildContent'.", diagnostic.GetMessage(CultureInfo.CurrentCulture)); }
public void Render_AttributeChildContent_IgnoresEmptyBody() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); var component = CompileToComponent(@" @{ RenderFragment<string> template = (context) => @<div>@context.ToLowerInvariant()</div>; } <RenderChildContent ChildContent=""@template(""HI"")""></RenderChildContent>"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 2), frame => AssertFrame.Attribute(frame, "ChildContent", 3), frame => AssertFrame.Element(frame, "div", 2, 0), frame => AssertFrame.Text(frame, "hi", 1)); }
public void Render_AttributeChildContent_RenderFragmentOfString() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentStringComponent); var component = CompileToComponent(@" @{ RenderFragment<string> template = (context) => @<div>@context.ToLowerInvariant()</div>; } <RenderChildContentString ChildContent=""@template"" Value=""HI"" />"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Component(frame, "Test.RenderChildContentString", 3, 2), frame => AssertFrame.Attribute(frame, "ChildContent", 3), frame => AssertFrame.Attribute(frame, "Value", "HI", 4), frame => AssertFrame.Element(frame, "div", 2, 0), frame => AssertFrame.Text(frame, "hi", 1)); }
public void Template_ExplicitExpressionInComponentAttribute_CreatesDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Components; namespace Test { public class MyComponent : ComponentBase { } } ")); // Act var generated = CompileToCSharp(@"<MyComponent attr=""@(@<div></div>)"" />"); // Assert var diagnostic = Assert.Single(generated.Diagnostics); Assert.Equal("RZ9994", diagnostic.Id); }
public void RejectsTagHelperDirectives() { // Arrange/Act AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Components; namespace Test { public class MyComponent : ComponentBase { } } ")); var result = CompileToCSharp(@" @addTagHelper *, TestAssembly @tagHelperPrefix th <MyComponent /> "); // Assert Assert.Collection(result.Diagnostics, item => { Assert.Equal("RZ9978", item.Id); Assert.Equal("The directives @addTagHelper, @removeTagHelper and @tagHelperPrefix are not valid in a component document. " + "Use '@using <namespace>' directive instead.", item.GetMessage(CultureInfo.CurrentCulture)); Assert.Equal(0, item.Span.LineIndex); Assert.Equal(0, item.Span.CharacterIndex); }, item => { Assert.Equal("RZ9978", item.Id); Assert.Equal("The directives @addTagHelper, @removeTagHelper and @tagHelperPrefix are not valid in a component document. " + "Use '@using <namespace>' directive instead.", item.GetMessage(CultureInfo.CurrentCulture)); Assert.Equal(1, item.Span.LineIndex); Assert.Equal(0, item.Span.CharacterIndex); }); }
public void ComponentDiscovery_CanFindComponent_DefinedinCSharp() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Components; namespace Test { public class MyComponent : ComponentBase { } } ")); // Act var result = CompileToCSharp(string.Empty); // Assert var bindings = result.CodeDocument.GetTagHelperContext(); Assert.Contains(bindings.TagHelpers, t => t.Name == "Test.MyComponent"); }
public void ComponentDiscovery_CanFindComponent_WithNamespace_DefinedinCSharp() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Blazor.Components; namespace Test.AnotherNamespace { public class MyComponent : BlazorComponent { } } ")); // Act var result = CompileToCSharp("@addTagHelper *, TestAssembly"); // Assert var bindings = result.CodeDocument.GetTagHelperContext(); Assert.Single(bindings.TagHelpers, t => t.Name == "Test.AnotherNamespace.MyComponent"); }
public void ChildContent_ExplicitChildContent_UnrecogizedContent_ProducesDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); // Act var generated = CompileToCSharp(@" <RenderChildContent> <ChildContent> </ChildContent> @somethingElse </RenderChildContent>"); // Assert var diagnostic = Assert.Single(generated.Diagnostics); Assert.Same(ComponentDiagnosticFactory.ChildContentMixedWithExplicitChildContent.Id, diagnostic.Id); Assert.Equal( "Unrecognized child content inside component 'RenderChildContent'. The component 'RenderChildContent' accepts " + "child content through the following top-level items: 'ChildContent'.", diagnostic.GetMessage()); }
public void BindToComponent_TypeChecked_WithMatchingProperties() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using System; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { [Parameter] int Value { get; set; } [Parameter] Action<int> ValueChanged { get; set; } } }")); // Act var generated = CompileToCSharp(@" @addTagHelper *, TestAssembly <MyComponent bind-Value=""ParentValue"" /> @functions { public string ParentValue { get; set; } = ""42""; }"); // Assert AssertDocumentNodeMatchesBaseline(generated.CodeDocument); AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); var assembly = CompileToAssembly(generated, throwOnFailure: false); // This has some errors Assert.Collection( assembly.Diagnostics.OrderBy(d => d.Id), d => Assert.Equal("CS0029", d.Id), d => Assert.Equal("CS1503", d.Id)); }
public void Render_ExplicitChildContent() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); var component = CompileToComponent(@" @addTagHelper *, TestAssembly <RenderChildContent> <ChildContent> <div></div> </ChildContent> </RenderChildContent>"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 0), frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 1), frame => AssertFrame.Markup(frame, "\n <div></div>\n ", 2)); }
public void Template_ImplicitExpressionInComponentAttribute_CreatesDiagnostic() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Components; namespace Test { public class MyComponent : ComponentBase { } } ")); // Act var generated = CompileToCSharp(@"<MyComponent attr=""@<div></div>"" />", throwOnFailure: false); // Assert Assert.Collection( generated.Diagnostics, d => Assert.Equal("RZ9986", d.Id), d => Assert.Equal("RZ1005", d.Id)); }
public void BodyAndExplicitChildContent() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Blazor; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { [Parameter] RenderFragment<string> Header { get; set; } [Parameter] RenderFragment ChildContent { get; set; } [Parameter] RenderFragment Footer { get; set; } } } ")); // Act var generated = CompileToCSharp(@" @addTagHelper *, TestAssembly @{ RenderFragment<string> header = (context) => @<div>@context.ToLowerInvariant()</div>; } <MyComponent Header=@header> <ChildContent>Some Content</ChildContent> <Footer>Bye!</Footer> </MyComponent>"); // Assert AssertDocumentNodeMatchesBaseline(generated.CodeDocument); AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); CompileToAssembly(generated); }
private IReadOnlyList <TagHelperDescriptor> GetComponents() { AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Components; namespace Test { public class Counter : ComponentBase { [Parameter] public int IncrementAmount { get; set; } } public class GridTable : ComponentBase { [Parameter] public RenderFragment ChildContent { get; set; } } public class GridRow : ComponentBase { [Parameter] public RenderFragment ChildContent { get; set; } } public class GridCell : ComponentBase { [Parameter] public RenderFragment ChildContent { get; set; } } } ")); var generated = CompileToCSharp("Test.razor", string.Empty, throwOnFailure: false, fileKind: FileKinds.Component); var tagHelpers = generated.CodeDocument.GetTagHelperContext().TagHelpers; return(tagHelpers); }
public void Render_GenericComponent_TypeInference_WithRef_Recursive() { // Arrange AdditionalSyntaxTrees.Add(GenericContextComponent); var assembly = CompileToAssembly("Test.cshtml", @" @addTagHelper *, TestAssembly @typeparam TItem <GenericContext Items=""@MyItems"" ref=""_my"" /> @functions { [Parameter] List<TItem> MyItems { get; set; } GenericContext<TItem> _my; void Foo() { GC.KeepAlive(_my); } }"); var componentType = assembly.Assembly.DefinedTypes .Where(t => t.Name == "Test`1") .Single() .MakeGenericType(typeof(int)); var component = (IComponent)Activator.CreateInstance(componentType); // Act var frames = GetRenderTree(component); // Assert var genericComponentType = assembly.Assembly.DefinedTypes .Where(t => t.Name == "GenericContext`1") .Single() .MakeGenericType(typeof(int)); Assert.Collection( frames, frame => AssertFrame.Component(frame, genericComponentType.FullName, 3, 0), frame => AssertFrame.Attribute(frame, "Items", 1), frame => AssertFrame.ComponentReferenceCapture(frame, 2)); }
[Fact] // https://github.com/aspnet/Blazor/issues/772 public void Regression_772() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class SurveyPrompt : BlazorComponent { [Parameter] private string Title { get; set; } } } ")); // Act var generated = CompileToCSharp(@" @addTagHelper *, TestAssembly @page ""/"" <h1>Hello, world!</h1> Welcome to your new app. <SurveyPrompt Title="" "); // Assert AssertDocumentNodeMatchesBaseline(generated.CodeDocument); AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); // This has some errors Assert.Collection( generated.Diagnostics.OrderBy(d => d.Id), d => Assert.Equal("RZ1034", d.Id), d => Assert.Equal("RZ1035", d.Id)); }
public void RazorTemplate_FollowedByComponent() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { [Parameter] string Name { get; set; } } } ")); // Act var generated = CompileToCSharp(@" @addTagHelper ""*, TestAssembly"" @{ RenderFragment<Person> p = (person) => @<div><MyComponent Name=""@person.Name""/></div>; } <MyComponent> @(""hello, world!"") </MyComponent> @functions { class Person { public string Name { get; set; } } }"); // Assert AssertDocumentNodeMatchesBaseline(generated.CodeDocument); AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); CompileToAssembly(generated); }
public void Render_BindToComponent_SpecifiesValueAndChangeEvent_WithMatchingProperties() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using System; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { [Parameter] int Value { get; set; } [Parameter] Action<int> OnChanged { get; set; } } }")); var component = CompileToComponent(@" @addTagHelper *, TestAssembly <MyComponent bind-Value-OnChanged=""ParentValue"" /> @functions { public int ParentValue { get; set; } = 42; }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0), frame => AssertFrame.Attribute(frame, "Value", 42, 1), frame => AssertFrame.Attribute(frame, "OnChanged", typeof(Action <int>), 2)); }
public void ChildComponent_WithParameters() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class SomeType { } public class MyComponent : BlazorComponent { [Parameter] int IntProperty { get; set; } [Parameter] bool BoolProperty { get; set; } [Parameter] string StringProperty { get; set; } [Parameter] SomeType ObjectProperty { get; set; } } } ")); // Act var generated = CompileToCSharp(@" @addTagHelper *, TestAssembly <MyComponent IntProperty=""123"" BoolProperty=""true"" StringProperty=""My string"" ObjectProperty=""new SomeType()""/>"); // Assert AssertDocumentNodeMatchesBaseline(generated.CodeDocument); AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); CompileToAssembly(generated); }