Browse Source

Moar tests

Krzysztof Krysiński 1 year ago
parent
commit
34ad78fd6b

+ 100 - 0
src/PixiEditor.Extensions.Tests/LayoutBuilderElementsTests.cs

@@ -0,0 +1,100 @@
+using Avalonia.Controls;
+using PixiEditor.Extensions.LayoutBuilding.Elements;
+
+namespace PixiEditor.Extensions.Test;
+
+public class LayoutBuilderElementsTests
+{
+    [Fact]
+    public void TestThatRowLayoutIsBuildCorrectly()
+    {
+        Layout layout = new Layout(
+            body: new Row(
+                new Text("Hello"),
+                new Text("World")));
+
+        Control result = layout.BuildNative();
+
+        Assert.IsType<Panel>(result);
+        Panel grid = (Panel)result;
+        Assert.Single(grid.Children);
+
+        Assert.IsType<StackPanel>(grid.Children[0]);
+        Panel childGrid = (StackPanel)grid.Children[0];
+
+        Assert.Equal(Avalonia.Layout.HorizontalAlignment.Stretch, childGrid.HorizontalAlignment);
+        Assert.Equal(Avalonia.Layout.VerticalAlignment.Stretch, childGrid.VerticalAlignment);
+
+        Assert.Equal(2, childGrid.Children.Count);
+
+        Assert.IsType<TextBlock>(childGrid.Children[0]);
+        TextBlock textBlock = (TextBlock)childGrid.Children[0];
+
+        Assert.Equal("Hello", textBlock.Text);
+
+        Assert.IsType<TextBlock>(childGrid.Children[1]);
+        TextBlock textBlock2 = (TextBlock)childGrid.Children[1];
+
+        Assert.Equal("World", textBlock2.Text);
+    }
+
+    [Fact]
+    public void TestThatColumnLayoutIsBuildCorrectly()
+    {
+        Layout layout = new Layout(
+            body: new Column(
+                new Text("Hello"),
+                new Text("World")));
+
+        Control result = layout.BuildNative();
+
+        Assert.IsType<Panel>(result);
+        Panel grid = (Panel)result;
+        Assert.Single(grid.Children);
+
+        Assert.IsType<StackPanel>(grid.Children[0]);
+        Panel childGrid = (StackPanel)grid.Children[0];
+
+        Assert.Equal(Avalonia.Layout.HorizontalAlignment.Stretch, childGrid.HorizontalAlignment);
+        Assert.Equal(Avalonia.Layout.VerticalAlignment.Stretch, childGrid.VerticalAlignment);
+
+        Assert.Equal(2, childGrid.Children.Count);
+
+        Assert.IsType<TextBlock>(childGrid.Children[0]);
+        TextBlock textBlock = (TextBlock)childGrid.Children[0];
+
+        Assert.Equal("Hello", textBlock.Text);
+
+        Assert.IsType<TextBlock>(childGrid.Children[1]);
+        TextBlock textBlock2 = (TextBlock)childGrid.Children[1];
+
+        Assert.Equal("World", textBlock2.Text);
+    }
+
+    [Fact]
+    public void TestCenteredTextLayoutIsBuildCorrectly()
+    {
+        Layout layout = new Layout(
+            body: new Center(
+                child: new Text("Hello")));
+
+        object result = layout.BuildNative();
+
+        Assert.IsType<Panel>(result);
+        Panel grid = (Panel)result;
+        Assert.Single(grid.Children);
+
+        Assert.IsType<Panel>(grid.Children[0]);
+        Panel childGrid = (Panel)grid.Children[0];
+
+        Assert.Equal(Avalonia.Layout.HorizontalAlignment.Center, childGrid.HorizontalAlignment);
+        Assert.Equal(Avalonia.Layout.VerticalAlignment.Center, childGrid.VerticalAlignment);
+
+        Assert.Single(childGrid.Children);
+
+        Assert.IsType<TextBlock>(childGrid.Children[0]);
+        TextBlock textBlock = (TextBlock)childGrid.Children[0];
+
+        Assert.Equal("Hello", textBlock.Text);
+    }
+}

+ 32 - 27
src/PixiEditor.Extensions.Tests/LayoutBuilderTests.cs

@@ -10,33 +10,6 @@ namespace PixiEditor.Extensions.Test;
 
 public class LayoutBuilderTests
 {
-    [Fact]
-    public void TestCenteredTextLayoutIsBuildCorrectly()
-    {
-        Layout layout = new Layout(
-            body: new Center(
-                child: new Text("Hello")));
-
-        object result = layout.BuildNative();
-
-        Assert.IsType<Panel>(result);
-        Panel grid = (Panel)result;
-        Assert.Single(grid.Children);
-
-        Assert.IsType<Panel>(grid.Children[0]);
-        Panel childGrid = (Panel)grid.Children[0];
-
-        Assert.Equal(Avalonia.Layout.HorizontalAlignment.Center, childGrid.HorizontalAlignment);
-        Assert.Equal(Avalonia.Layout.VerticalAlignment.Center, childGrid.VerticalAlignment);
-
-        Assert.Single(childGrid.Children);
-
-        Assert.IsType<TextBlock>(childGrid.Children[0]);
-        TextBlock textBlock = (TextBlock)childGrid.Children[0];
-
-        Assert.Equal("Hello", textBlock.Text);
-    }
-
     [Fact]
     public void TestThatButtonClickEventFiresCallback()
     {
@@ -136,4 +109,36 @@ public class LayoutBuilderTests
         Assert.NotNull(button.Content); // Old layout is updated and text is added
         Assert.IsType<TextBlock>(button.Content);
     }
+
+    [Fact]
+    public void TestThatMultiChildLayoutStateUpdatesTreeCorrectly()
+    {
+        TestMultiChildStatefulElement testStatefulElement = new TestMultiChildStatefulElement();
+        testStatefulElement.CreateState();
+
+        var native = testStatefulElement.BuildNative();
+
+        Assert.IsType<ContentPresenter>(native);
+        Assert.IsType<StackPanel>((native as ContentPresenter).Content);
+        StackPanel panel = (native as ContentPresenter).Content as StackPanel;
+
+        Assert.Equal(2, panel.Children.Count);
+
+        Assert.IsType<Avalonia.Controls.Button>(panel.Children[0]);
+        Assert.IsType<StackPanel>(panel.Children[1]);
+
+        Assert.Empty((panel.Children[1] as StackPanel).Children);
+
+        Avalonia.Controls.Button button = (Avalonia.Controls.Button)panel.Children[0];
+        StackPanel innerPanel = (StackPanel)panel.Children[1];
+
+        button.RaiseEvent(new RoutedEventArgs(Avalonia.Controls.Button.ClickEvent));
+
+        Assert.Single(innerPanel.Children);
+        Assert.IsType<TextBlock>(innerPanel.Children[0]);
+
+        button.RaiseEvent(new RoutedEventArgs(Avalonia.Controls.Button.ClickEvent));
+
+        Assert.Equal(2, innerPanel.Children.Count);
+    }
 }

+ 23 - 0
src/PixiEditor.Extensions.Tests/TestMultiChildState.cs

@@ -0,0 +1,23 @@
+using PixiEditor.Extensions.CommonApi.LayoutBuilding.Events;
+using PixiEditor.Extensions.LayoutBuilding.Elements;
+
+namespace PixiEditor.Extensions.Test;
+
+public class TestMultiChildState : State
+{
+    private LayoutElement[] rows = Array.Empty<LayoutElement>();
+    public override LayoutElement BuildElement()
+    {
+        return new Column(
+            new Button(new Text("Add row"), OnClick),
+            new Row(rows));
+    }
+
+    private void OnClick(ElementEventArgs args)
+    {
+        SetState(() =>
+        {
+            rows = rows.Append(new Text("Row " + rows.Length)).ToArray();
+        });
+    }
+}

+ 11 - 0
src/PixiEditor.Extensions.Tests/TestMultiChildStatefulElement.cs

@@ -0,0 +1,11 @@
+using PixiEditor.Extensions.LayoutBuilding.Elements;
+
+namespace PixiEditor.Extensions.Test;
+
+public class TestMultiChildStatefulElement : StatefulElement<TestMultiChildState>
+{
+    public override TestMultiChildState CreateState()
+    {
+        return new TestMultiChildState();
+    }
+}

+ 12 - 0
src/PixiEditor.Extensions.Wasm/Api/LayoutBuilding/Column.cs

@@ -0,0 +1,12 @@
+namespace PixiEditor.Extensions.Wasm.Api.LayoutBuilding;
+
+public class Column : MultiChildLayoutElement
+{
+    public override CompiledControl BuildNative()
+    {
+        CompiledControl control = new CompiledControl(UniqueId, "Column");
+        control.Children.AddRange(Children.Select(x => x.BuildNative()));
+
+        return control;
+    }
+}

+ 17 - 0
src/PixiEditor.Extensions.Wasm/Api/LayoutBuilding/MultiChildLayoutElement.cs

@@ -0,0 +1,17 @@
+using PixiEditor.Extensions.CommonApi.LayoutBuilding;
+
+namespace PixiEditor.Extensions.Wasm.Api.LayoutBuilding;
+
+public abstract class MultiChildLayoutElement : LayoutElement, IMultiChildLayoutElement<CompiledControl>
+{
+    List<ILayoutElement<CompiledControl>> IMultiChildLayoutElement<CompiledControl>.Children
+    {
+        get => Children.Cast<ILayoutElement<CompiledControl>>().ToList();
+        set => Children = value.Cast<LayoutElement>().ToList();
+    }
+
+    public List<LayoutElement> Children { get; set; }
+
+    public abstract override CompiledControl BuildNative();
+
+}

+ 12 - 0
src/PixiEditor.Extensions.Wasm/Api/LayoutBuilding/Row.cs

@@ -0,0 +1,12 @@
+namespace PixiEditor.Extensions.Wasm.Api.LayoutBuilding;
+
+public class Row : MultiChildLayoutElement
+{
+    public override CompiledControl BuildNative()
+    {
+        CompiledControl control = new CompiledControl(UniqueId, "Row");
+        control.Children.AddRange(Children.Select(x => x.BuildNative()));
+
+        return control;
+    }
+}

+ 29 - 2
src/PixiEditor.Extensions/LayoutBuilding/Elements/Row.cs

@@ -1,9 +1,12 @@
-using Avalonia.Controls;
+using System.Collections.Specialized;
+using Avalonia.Controls;
+using Avalonia.Threading;
 
 namespace PixiEditor.Extensions.LayoutBuilding.Elements;
 
 public class Row : MultiChildLayoutElement
 {
+    private StackPanel panel;
     public Row()
     {
     }
@@ -11,10 +14,34 @@ public class Row : MultiChildLayoutElement
     public Row(params LayoutElement[] children)
     {
         Children = new(children);
+        Children.CollectionChanged += ChildrenOnCollectionChanged;
     }
+
+    private void ChildrenOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
+    {
+        Dispatcher.UIThread.Invoke(() =>
+        {
+            if (e.Action == NotifyCollectionChangedAction.Add)
+            {
+                foreach (LayoutElement? item in e.NewItems)
+                {
+                    var newChild = item.BuildNative();
+                    panel.Children.Add(newChild);
+                }
+            }
+            else if (e.Action == NotifyCollectionChangedAction.Remove)
+            {
+                foreach (LayoutElement? item in e.OldItems)
+                {
+                    panel.Children.RemoveAt(e.OldStartingIndex);
+                }
+            }
+        });
+    }
+
     public override Control BuildNative()
     {
-        StackPanel panel = new StackPanel
+        panel = new StackPanel
         {
             Orientation = Avalonia.Layout.Orientation.Horizontal
         };

+ 6 - 4
src/PixiEditor.sln

@@ -102,6 +102,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PixiEditor.DevTools", "Pixi
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PixiEditor.Extensions.Runtime", "PixiEditor.Extensions.Runtime\PixiEditor.Extensions.Runtime.csproj", "{5848FCF1-E127-4CE3-8A25-F37032819F8D}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F1FDFA82-0C74-446A-AD7D-DE17EC2CF1E8}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -1772,19 +1774,19 @@ Global
 		{F2E992CA-12E3-49F3-B16F-2CEF5B191493} = {1E816135-76C1-4255-BE3C-BF17895A65AA}
 		{19704B2E-5EED-47CA-9258-89F246F50F19} = {1E816135-76C1-4255-BE3C-BF17895A65AA}
 		{8F4FFC91-BE9F-4476-A372-FBD952865F15} = {1E816135-76C1-4255-BE3C-BF17895A65AA}
-		{427CE098-4B13-4E46-8C66-D924140B6CAE} = {1E816135-76C1-4255-BE3C-BF17895A65AA}
 		{F4436A16-9488-4BAB-B2F6-C1806278CE16} = {E4FF4CE6-5831-450D-8006-0539353C030B}
 		{13DD041C-EE2D-4AF8-B43E-D7BFC7415E4D} = {1E816135-76C1-4255-BE3C-BF17895A65AA}
 		{71907779-F1D1-4AA6-BA11-E990DB089841} = {13DD041C-EE2D-4AF8-B43E-D7BFC7415E4D}
 		{B30622ED-9177-4930-8E64-2B2352D4D8DC} = {13DD041C-EE2D-4AF8-B43E-D7BFC7415E4D}
 		{1249EE2B-EB0D-411C-B311-53A7A22B7743} = {13DD041C-EE2D-4AF8-B43E-D7BFC7415E4D}
-		{221E745C-D21F-4725-BBB8-DFB2DE5CF61D} = {13DD041C-EE2D-4AF8-B43E-D7BFC7415E4D}
-		{9C1A500D-7A3D-49E3-BD39-05867B1D37F1} = {13DD041C-EE2D-4AF8-B43E-D7BFC7415E4D}
-		{C16EF6F1-4E40-4CC4-9320-99C3C97929D7} = {13DD041C-EE2D-4AF8-B43E-D7BFC7415E4D}
 		{43C03D0E-EF50-4225-A268-CB9B8E0E8622} = {13DD041C-EE2D-4AF8-B43E-D7BFC7415E4D}
 		{6C74CC1F-B514-4150-A46C-84FEA6F9ED7F} = {E4FF4CE6-5831-450D-8006-0539353C030B}
 		{A0C4E418-467E-40E2-BAD6-35F953BA69E5} = {DF94111B-9D40-42D7-9416-4875E846FE8A}
 		{5848FCF1-E127-4CE3-8A25-F37032819F8D} = {13DD041C-EE2D-4AF8-B43E-D7BFC7415E4D}
+		{221E745C-D21F-4725-BBB8-DFB2DE5CF61D} = {F1FDFA82-0C74-446A-AD7D-DE17EC2CF1E8}
+		{9C1A500D-7A3D-49E3-BD39-05867B1D37F1} = {F1FDFA82-0C74-446A-AD7D-DE17EC2CF1E8}
+		{C16EF6F1-4E40-4CC4-9320-99C3C97929D7} = {F1FDFA82-0C74-446A-AD7D-DE17EC2CF1E8}
+		{427CE098-4B13-4E46-8C66-D924140B6CAE} = {F1FDFA82-0C74-446A-AD7D-DE17EC2CF1E8}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {D04B4AB0-CA33-42FD-A909-79966F9255C5}