public void Render_BindToComponent_SpecifiesValueAndChangeEvent_WithMatchingProperties() { // Arrange AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@" using System; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { public int Value { get; set; } public 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), frame => AssertFrame.Whitespace(frame, 3)); }
public void SupportsAttributeFramesEvaluatedInline() { // Arrange/Act var component = CompileToComponent( @"<elem @onclick(MyHandler) /> @functions { public bool DidInvokeCode { get; set; } = false; void MyHandler() { DidInvokeCode = true; } }"); var didInvokeCodeProperty = component.GetType().GetProperty("DidInvokeCode"); // Assert Assert.False((bool)didInvokeCodeProperty.GetValue(component)); Assert.Collection(GetRenderTree(component), frame => AssertFrame.Element(frame, "elem", 2, 0), frame => { Assert.Equal(RenderTreeFrameType.Attribute, frame.FrameType); Assert.NotNull(frame.AttributeValue); Assert.Equal(1, frame.Sequence); ((UIEventHandler)frame.AttributeValue)(null); Assert.True((bool)didInvokeCodeProperty.GetValue(component)); }, frame => AssertFrame.Whitespace(frame, 2)); }
public void SupportsEventHandlerWithLambda() { // Arrange var component = CompileToComponent(@" <button onclick=""@(x => Clicked = true)"" /> @functions { public bool Clicked { get; set; } }"); var clicked = component.GetType().GetProperty("Clicked"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection(frames, frame => AssertFrame.Element(frame, "button", 2, 0), frame => { AssertFrame.Attribute(frame, "onclick", 1); var func = Assert.IsType <UIEventHandler>(frame.AttributeValue); Assert.False((bool)clicked.GetValue(component)); func(new UIMouseEventArgs()); Assert.True((bool)clicked.GetValue(component)); }, frame => AssertFrame.Whitespace(frame, 2)); }
public void SupportsAttributesWithEventHandlerValues() { // Arrange/Act var component = CompileToComponent( @"<elem attr=@MyHandleEvent /> @functions { public bool HandlerWasCalled { get; set; } = false; void MyHandleEvent(Microsoft.AspNetCore.Blazor.UIEventArgs eventArgs) { HandlerWasCalled = true; } }"); var handlerWasCalledProperty = component.GetType().GetProperty("HandlerWasCalled"); // Assert Assert.False((bool)handlerWasCalledProperty.GetValue(component)); Assert.Collection(GetRenderTree(component), frame => AssertFrame.Element(frame, "elem", 2, 0), frame => { Assert.Equal(RenderTreeFrameType.Attribute, frame.FrameType); Assert.Equal(1, frame.Sequence); Assert.NotNull(frame.AttributeValue); ((UIEventHandler)frame.AttributeValue)(null); Assert.True((bool)handlerWasCalledProperty.GetValue(component)); }, frame => AssertFrame.Whitespace(frame, 2)); }
[Fact] // Additional coverage of OrphanTagHelperLoweringPass public void Render_BindToElementFallback_SpecifiesValueAndChangeEvent_BodyContent() { // Arrange var component = CompileToComponent(@" @addTagHelper *, TestAssembly <div bind-value-onchange=""@ParentValue""> <span>@(42.ToString())</span> </div> @functions { public int ParentValue { get; set; } = 42; }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Element(frame, "div", 7, 0), frame => AssertFrame.Attribute(frame, "value", "42", 1), frame => AssertFrame.Attribute(frame, "onchange", typeof(Action <UIEventArgs>), 2), frame => AssertFrame.Whitespace(frame, 3), frame => AssertFrame.Element(frame, "span", 2, 4), frame => AssertFrame.Text(frame, "42", 5), frame => AssertFrame.Whitespace(frame, 6)); }
public void Render_GenericComponent_WithChildContent() { // Arrange AdditionalSyntaxTrees.Add(GenericContextComponent); var component = CompileToComponent(@" @addTagHelper *, TestAssembly <GenericContext TItem=int Items=""@(new List<int>() { 1, 2, })""> <div>@(context.Item * context.Index)</div> </GenericContext>"); // Act var frames = GetRenderTree(component); // Assert var genericComponentType = component.GetType().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", typeof(List <int>), 1), frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 2), frame => AssertFrame.Whitespace(frame, 3), frame => AssertFrame.Element(frame, "div", 2, 4), frame => AssertFrame.Text(frame, "0", 5), frame => AssertFrame.Whitespace(frame, 6), frame => AssertFrame.Whitespace(frame, 3), frame => AssertFrame.Element(frame, "div", 2, 4), frame => AssertFrame.Text(frame, "2", 5), frame => AssertFrame.Whitespace(frame, 6)); }
public void Render_BindToElementWithSuffix_WritesAttributes() { // Arrange AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@" using System; using Microsoft.AspNetCore.Blazor.Components; namespace Test { [BindElement(""div"", ""value"", ""myvalue"", ""myevent"")] public static class BindAttributes { } }")); var component = CompileToComponent(@" @addTagHelper *, TestAssembly <div bind-value=""@ParentValue"" /> @functions { public string ParentValue { get; set; } = ""hi""; }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Element(frame, "div", 3, 0), frame => AssertFrame.Attribute(frame, "myvalue", "hi", 1), frame => AssertFrame.Attribute(frame, "myevent", typeof(UIEventHandler), 2), frame => AssertFrame.Whitespace(frame, 3)); }
public void SupportsEventHandlerWithMethodGroup() { // Arrange var component = CompileToComponent(@" @using Microsoft.AspNetCore.Blazor <button onclick=""@OnClick"" @onclick(OnClick)/> @functions { public void OnClick(UIMouseEventArgs e) { Clicked = true; } public bool Clicked { get; set; } }"); var clicked = component.GetType().GetProperty("Clicked"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection(frames, frame => AssertFrame.Element(frame, "button", 2, 0), frame => { AssertFrame.Attribute(frame, "onclick", 1); var func = Assert.IsType <UIEventHandler>(frame.AttributeValue); Assert.False((bool)clicked.GetValue(component)); func(new UIMouseEventArgs()); Assert.True((bool)clicked.GetValue(component)); }, frame => AssertFrame.Whitespace(frame, 2)); }
public void Render_BodyChildContent_Generic() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentStringComponent); var component = CompileToComponent(@" @addTagHelper *, TestAssembly <RenderChildContentString Value=""HI""> <div>@context.ToLowerInvariant()</div> </RenderChildContentString>"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Component(frame, "Test.RenderChildContentString", 3, 0), frame => AssertFrame.Attribute(frame, "Value", "HI", 1), frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 2), frame => AssertFrame.Whitespace(frame, 3), frame => AssertFrame.Element(frame, "div", 2, 4), frame => AssertFrame.Text(frame, "hi", 5), frame => AssertFrame.Whitespace(frame, 6)); }
public void Render_BodyChildContent_Recursive() { // Arrange AdditionalSyntaxTrees.Add(RenderChildContentComponent); var component = CompileToComponent(@" @addTagHelper *, TestAssembly <RenderChildContent> <RenderChildContent> <div></div> </RenderChildContent> </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.Whitespace(frame, 2), frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 3), frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 4), frame => AssertFrame.Whitespace(frame, 6), frame => AssertFrame.Markup(frame, "\n <div></div>\n ", 5)); }
public void SupportsUsingStatements() { // Arrange/Act var component = CompileToComponent( @"@using System.Collections.Generic @(typeof(List<string>).FullName)"); var frames = GetRenderTree(component); // Assert Assert.Collection(frames, frame => AssertFrame.Whitespace(frame, 0), frame => AssertFrame.Text(frame, typeof(List <string>).FullName, 1)); }
public void Render_ChildComponent_WithExplicitEventHandler() { // Arrange AdditionalSyntaxTrees.Add(CSharpSyntaxTree.ParseText(@" using System; using Microsoft.AspNetCore.Blazor; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { public UIEventHandler OnClick { get; set; } } } ")); var component = CompileToComponent(@" @addTagHelper *, TestAssembly @using Microsoft.AspNetCore.Blazor <MyComponent OnClick=""@Increment""/> @functions { private int counter; private void Increment(UIEventArgs 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 <UIEventHandler>(frame.AttributeValue); Assert.Equal("Test.TestComponent", handler.Target.GetType().FullName); Assert.Equal("Increment", handler.Method.Name); }, frame => AssertFrame.Whitespace(frame, 2)); }
public void SupportsUsingStatements() { // Arrange var treeBuilder = new RenderTreeBuilder(new TestRenderer()); // Arrange/Act var component = CompileToComponent( @"@using System.Collections.Generic @(typeof(List<string>).FullName)"); component.BuildRenderTree(treeBuilder); // Assert Assert.Collection(treeBuilder.GetFrames(), frame => AssertFrame.Whitespace(frame, 0), frame => AssertFrame.Text(frame, typeof(List <string>).FullName, 1)); }
public void Render_BuiltIn_BindToInputCheckbox_WritesAttributes() { // Arrange var component = CompileToComponent(@" @addTagHelper *, TestAssembly <input type=""checkbox"" bind=""@Enabled"" /> @functions { public bool Enabled { get; set; } }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Element(frame, "input", 3, 0), frame => AssertFrame.Attribute(frame, "type", "checkbox", 1), frame => AssertFrame.Attribute(frame, "onchange", typeof(UIEventHandler), 3), frame => AssertFrame.Whitespace(frame, 4)); }
public void Render_BuiltIn_BindToInputWithoutType_WritesAttributes() { // Arrange var component = CompileToComponent(@" @addTagHelper *, TestAssembly <input bind=""@ParentValue"" /> @functions { public int ParentValue { get; set; } = 42; }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Element(frame, "input", 3, 0), frame => AssertFrame.Attribute(frame, "value", "42", 1), frame => AssertFrame.Attribute(frame, "onchange", typeof(UIEventHandler), 2), frame => AssertFrame.Whitespace(frame, 3)); }
public void SupportsCSharpFunctionsBlock() { // Arrange/Act var component = CompileToComponent(@" @foreach(var item in items) { @item } @functions { string[] items = new[] { ""First"", ""Second"", ""Third"" }; } "); // Assert var frames = GetRenderTree(component); Assert.Collection(frames, frame => AssertFrame.Text(frame, "First", 0), frame => AssertFrame.Text(frame, "Second", 0), frame => AssertFrame.Text(frame, "Third", 0), frame => AssertFrame.Whitespace(frame, 1), frame => AssertFrame.Whitespace(frame, 2)); }
public void Render_BindToElementFallback_WithFormat_WritesAttributes() { // Arrange var component = CompileToComponent(@" @addTagHelper *, TestAssembly <input type=""text"" bind-value-onchange=""@CurrentDate"" format-value=""MM/dd"" /> @functions { public DateTime CurrentDate { get; set; } = new DateTime(2018, 1, 1); }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Element(frame, "input", 4, 0), frame => AssertFrame.Attribute(frame, "type", "text", 1), frame => AssertFrame.Attribute(frame, "value", new DateTime(2018, 1, 1).ToString("MM/dd"), 2), frame => AssertFrame.Attribute(frame, "onchange", typeof(UIEventHandler), 3), frame => AssertFrame.Whitespace(frame, 4)); }
public void Render_BindToElementFallback_WritesAttributes() { // Arrange var component = CompileToComponent(@" @addTagHelper *, TestAssembly <input type=""text"" bind-value-onchange=""@ParentValue"" /> @functions { public int ParentValue { get; set; } = 42; }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Element(frame, "input", 4, 0), frame => AssertFrame.Attribute(frame, "type", "text", 1), frame => AssertFrame.Attribute(frame, "value", "42", 2), frame => AssertFrame.Attribute(frame, "onchange", typeof(UIEventHandler), 3), frame => AssertFrame.Whitespace(frame, 4)); }
public void SupportsCSharpExpressions() { // Arrange/Act var component = CompileToComponent(@" @(""Hello"") @((object)null) @(123) @(new object()) "); // Assert var frames = GetRenderTree(component); Assert.Collection(frames, frame => AssertFrame.Text(frame, "Hello", 0), frame => AssertFrame.Whitespace(frame, 1), frame => AssertFrame.Whitespace(frame, 2), // @((object)null) frame => AssertFrame.Whitespace(frame, 3), frame => AssertFrame.Text(frame, "123", 4), frame => AssertFrame.Whitespace(frame, 5), frame => AssertFrame.Text(frame, new object().ToString(), 6)); }
[Fact] // Additional coverage of OrphanTagHelperLoweringPass public void Render_BindToElementFallback_SpecifiesValueAndChangeEvent_WithCSharpAttribute() { // Arrange var component = CompileToComponent(@" @addTagHelper *, TestAssembly <input type=""@(""text"")"" bind-value-onchange=""@ParentValue"" visible /> @functions { public int ParentValue { get; set; } = 42; }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Element(frame, "input", 5, 0), frame => AssertFrame.Attribute(frame, "visible", 1), // This gets reordered in the node writer frame => AssertFrame.Attribute(frame, "type", "text", 2), frame => AssertFrame.Attribute(frame, "value", "42", 3), frame => AssertFrame.Attribute(frame, "onchange", typeof(UIEventHandler), 4), frame => AssertFrame.Whitespace(frame, 5)); }
public void Render_BuiltIn_BindToInputText_WithFormatFromProperty_WritesAttributes() { // Arrange var component = CompileToComponent(@" @addTagHelper *, TestAssembly <input type=""text"" bind=""@CurrentDate"" format-value=""@Format""/> @functions { public DateTime CurrentDate { get; set; } = new DateTime(2018, 1, 1); public string Format { get; set; } = ""MM/dd/yyyy""; }"); // Act var frames = GetRenderTree(component); // Assert Assert.Collection( frames, frame => AssertFrame.Element(frame, "input", 4, 0), frame => AssertFrame.Attribute(frame, "type", "text", 1), frame => AssertFrame.Attribute(frame, "value", "01/01/2018", 2), frame => AssertFrame.Attribute(frame, "onchange", typeof(UIEventHandler), 3), frame => AssertFrame.Whitespace(frame, 4)); }
public void Render_HtmlBlock_Integration() { // Arrange AdditionalSyntaxTrees.Add(Parse(@" using Microsoft.AspNetCore.Blazor; using Microsoft.AspNetCore.Blazor.Components; namespace Test { public class MyComponent : BlazorComponent { [Parameter] RenderFragment ChildContent { get; set; } } } ")); var component = CompileToComponent(@" @addTagHelper *, TestAssembly <html> <head><meta><meta></head> <body> <MyComponent> <div><span></span><span></span></div> <div>@(""hi"")</div> <div><span></span><span></span></div> <div></div> <div>@(""hi"")</div> <div></div> </MyComponent> </body> </html>"); // Act var frames = GetRenderTree(component); // Assert: component frames are correct Assert.Collection( frames, frame => AssertFrame.Element(frame, "html", 9, 0), frame => AssertFrame.Whitespace(frame, 1), frame => AssertFrame.Markup(frame, "<head><meta><meta></head>\n ", 2), frame => AssertFrame.Element(frame, "body", 5, 3), frame => AssertFrame.Whitespace(frame, 4), frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 5), frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 6), frame => AssertFrame.Whitespace(frame, 16), frame => AssertFrame.Whitespace(frame, 17)); // Assert: Captured ChildContent frames are correct var childFrames = GetFrames((RenderFragment)frames[6].AttributeValue); Assert.Collection( childFrames, frame => AssertFrame.Whitespace(frame, 7), frame => AssertFrame.Markup(frame, "<div><span></span><span></span></div>\n ", 8), frame => AssertFrame.Element(frame, "div", 2, 9), frame => AssertFrame.Text(frame, "hi", 10), frame => AssertFrame.Whitespace(frame, 11), frame => AssertFrame.Markup(frame, "<div><span></span><span></span></div>\n <div></div>\n ", 12), frame => AssertFrame.Element(frame, "div", 2, 13), frame => AssertFrame.Text(frame, "hi", 14), frame => AssertFrame.Markup(frame, "\n <div></div>\n ", 15)); }