From 17fdde66d94155fc62a034fa6658995bef6fd6e5 Mon Sep 17 00:00:00 2001 From: Jason Smith Date: Tue, 22 Mar 2016 13:02:25 -0700 Subject: Initial import --- .../RelativeLayoutTests.cs | 516 +++++++++++++++++++++ 1 file changed, 516 insertions(+) create mode 100644 Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs (limited to 'Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs') diff --git a/Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs b/Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs new file mode 100644 index 00000000..96b3dfc8 --- /dev/null +++ b/Xamarin.Forms.Core.UnitTests/RelativeLayoutTests.cs @@ -0,0 +1,516 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using NUnit.Framework; + +namespace Xamarin.Forms.Core.UnitTests +{ + [TestFixture] + public class RelativeLayoutTests : BaseTestFixture + { + class UnitExpressionSearch : ExpressionVisitor, IExpressionSearch + { + List results; + Type targeType; + public List FindObjects(Expression expression) where T : class + { + results = new List (); + targeType = typeof (T); + Visit (expression); + return results.Select (o => o as T).ToList (); + } + + protected override Expression VisitMember(MemberExpression node) + { + if (node.Expression is ConstantExpression && node.Member is FieldInfo) { + var container = ((ConstantExpression)node.Expression).Value; + var value = ((FieldInfo)node.Member).GetValue (container); + + if (targeType.IsInstanceOfType (value)) { + results.Add (value); + } + } + return base.VisitMember (node); + } + } + + [SetUp] + public override void Setup() + { + base.Setup (); + ExpressionSearch.Default = new UnitExpressionSearch (); + } + + [TearDown] + public override void TearDown() + { + base.TearDown (); + ExpressionSearch.Default = new UnitExpressionSearch (); + } + + [Test] + public void SimpleLayout () + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child, + Constraint.Constant (30), + Constraint.Constant (20), + Constraint.RelativeToParent (parent => parent.Height / 2), + Constraint.RelativeToParent (parent => parent.Height / 4)); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 50, 25), child.Bounds); + } + + [Test] + public void SimpleExpressionLayout () + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child, + () => 30, + () => 20, + () => relativeLayout.Height / 2, + () => relativeLayout.Height / 4); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 50, 25), child.Bounds); + } + + [Test] + public void SimpleBoundsSizing () + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child, () => new Rectangle (30, 20, relativeLayout.Height / 2, relativeLayout.Height / 4)); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 50, 25), child.Bounds); + } + + [Test] + public void UnconstrainedSize() + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child = new View { + IsPlatformEnabled = true, + WidthRequest = 25, + HeightRequest = 50 + }; + + relativeLayout.Children.Add (child, Constraint.Constant (30), Constraint.Constant (20)); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 25, 50), child.Bounds); + } + + [Test] + public void ViewRelativeLayout () + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child1 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child1, + Constraint.Constant (30), + Constraint.Constant (20), + Constraint.RelativeToParent (parent => parent.Height / 5), + Constraint.RelativeToParent (parent => parent.Height / 10)); + + var child2 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child2, + Constraint.RelativeToView (child1, (layout, view) => view.Bounds.Right + 10), + Constraint.RelativeToView (child1, (layout, view) => view.Y), + Constraint.RelativeToView (child1, (layout, view) => view.Width), + Constraint.RelativeToView (child1, (layout, view) => view.Height)); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 20, 10), child1.Bounds); + Assert.AreEqual (new Rectangle (60, 20, 20, 10), child2.Bounds); + } + + [Test] + public void ViewRelativeLayoutWithExpressions() + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child1 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child1, + () => 30, + () => 20, + () => relativeLayout.Height / 5, + () => relativeLayout.Height / 10); + + var child2 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child2, + () => child1.Bounds.Right + 10, + () => child1.Y, + () => child1.Width, + () => child1.Height); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 20, 10), child1.Bounds); + Assert.AreEqual (new Rectangle (60, 20, 20, 10), child2.Bounds); + } + + [Test] + public void ViewRelativeToMultipleViews () + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child1 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child1, + Constraint.Constant (30), + Constraint.Constant (20), + Constraint.RelativeToParent (parent => parent.Height / 5), + Constraint.RelativeToParent (parent => parent.Height / 10)); + + var child2 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child2, + Constraint.Constant (30), + Constraint.Constant (50), + Constraint.RelativeToParent (parent => parent.Height / 4), + Constraint.RelativeToParent (parent => parent.Height / 5)); + + var child3 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child3, + Constraint.RelativeToView (child1, (layout, view) => view.Bounds.Right + 10), + Constraint.RelativeToView (child2, (layout, view) => view.Y), + Constraint.RelativeToView (child1, (layout, view) => view.Width), + Constraint.RelativeToView (child2, (layout, view) => view.Height * 2)); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 20, 10), child1.Bounds); + Assert.AreEqual (new Rectangle (30, 50, 25, 20), child2.Bounds); + Assert.AreEqual (new Rectangle (60, 50, 20, 40), child3.Bounds); + } + + [Test] + public void ExpressionRelativeToMultipleViews() + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child1 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child1, + Constraint.Constant (30), + Constraint.Constant (20), + Constraint.RelativeToParent (parent => parent.Height / 5), + Constraint.RelativeToParent (parent => parent.Height / 10)); + + var child2 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child2, + Constraint.Constant (30), + Constraint.Constant (50), + Constraint.RelativeToParent (parent => parent.Height / 4), + Constraint.RelativeToParent (parent => parent.Height / 5)); + + var child3 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child3, + () => child1.Bounds.Right + 10, + () => child1.Y, + () => child1.Width + child2.Width, + () => child1.Height * 2 + child2.Height); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 20, 10), child1.Bounds); + Assert.AreEqual (new Rectangle (30, 50, 25, 20), child2.Bounds); + Assert.AreEqual (new Rectangle (60, 20, 45, 40), child3.Bounds); + } + + [Test] + public void ThreePassLayout () + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child1 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child1, + Constraint.Constant (30), + Constraint.Constant (20), + Constraint.RelativeToParent (parent => parent.Height / 5), + Constraint.RelativeToParent (parent => parent.Height / 10)); + + var child2 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child2, + Constraint.Constant (30), + Constraint.Constant (50), + Constraint.RelativeToParent (parent => parent.Height / 4), + Constraint.RelativeToParent (parent => parent.Height / 5)); + + var child3 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child3, + Constraint.RelativeToView (child1, (layout, view) => view.Bounds.Right + 10), + Constraint.RelativeToView (child2, (layout, view) => view.Y), + Constraint.RelativeToView (child1, (layout, view) => view.Width), + Constraint.RelativeToView (child2, (layout, view) => view.Height * 2)); + + var child4 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child4, + Constraint.RelativeToView (child1, (layout, view) => view.Bounds.Right + 10), + Constraint.RelativeToView (child2, (layout, view) => view.Y), + Constraint.RelativeToView (child1, (layout, view) => view.Width), + Constraint.RelativeToView (child3, (layout, view) => view.Height * 2)); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 20, 10), child1.Bounds); + Assert.AreEqual (new Rectangle (30, 50, 25, 20), child2.Bounds); + Assert.AreEqual (new Rectangle (60, 50, 20, 40), child3.Bounds); + Assert.AreEqual (new Rectangle (60, 50, 20, 80), child4.Bounds); + } + + [Test] + public void ThreePassLayoutWithExpressions() + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child1 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child1, + x: () => 30, + y: () => 20, + width: () => relativeLayout.Height / 5, + height: () => relativeLayout.Height / 10); + + var child2 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child2, + x: () => 30, + y: () => 50, + width: () => relativeLayout.Height / 4, + height: () => relativeLayout.Height / 5); + + var child3 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child3, + x: () => child1.Bounds.Right + 10, + y: () => child2.Y, + width: () => child1.Width, + height: () => child2.Height * 2); + + var child4 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child4, + x: () => child1.Bounds.Right + 10, + y: () => child2.Y, + width: () => child1.Width, + height: () => child3.Height * 2); + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.AreEqual (new Rectangle (30, 20, 20, 10), child1.Bounds); + Assert.AreEqual (new Rectangle (30, 50, 25, 20), child2.Bounds); + Assert.AreEqual (new Rectangle (60, 50, 20, 40), child3.Bounds); + Assert.AreEqual (new Rectangle (60, 50, 20, 80), child4.Bounds); + } + + [Test] + public void ThrowsWithUnsolvableConstraints () + { + var relativeLayout = new RelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child1 = new View { + IsPlatformEnabled = true + }; + + var child2 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child1, + () => 30, + () => 20, + () => child2.Height / 5, + () => relativeLayout.Height / 10); + + relativeLayout.Children.Add (child2, + () => child1.Bounds.Right + 10, + () => child1.Y, + () => child1.Width, + () => child1.Height); + + Assert.Throws (() => relativeLayout.Layout (new Rectangle (0, 0, 100, 100))); + } + + [Test] + public void ChildAddedBeforeLayoutChildrenAfterInitialLayout () + { + var relativeLayout = new MockRelativeLayout { + Platform = new UnitPlatform (), + IsPlatformEnabled = true + }; + + var child = new View { + IsPlatformEnabled = true + }; + + var child1 = new View { + IsPlatformEnabled = true + }; + + relativeLayout.Children.Add (child, + Constraint.Constant (30), + Constraint.Constant (20), + Constraint.RelativeToParent (parent => parent.Height / 2), + Constraint.RelativeToParent (parent => parent.Height / 4)); + + + relativeLayout.Layout (new Rectangle (0, 0, 100, 100)); + + Assert.IsTrue (relativeLayout.childAdded); + Assert.IsTrue (relativeLayout.added); + Assert.IsTrue (relativeLayout.layoutChildren); + + relativeLayout.layoutChildren = relativeLayout.added = relativeLayout.childAdded = false; + + Assert.IsFalse (relativeLayout.childAdded); + Assert.IsFalse (relativeLayout.added); + Assert.IsFalse (relativeLayout.layoutChildren); + + relativeLayout.Children.Add (child1, + Constraint.Constant (30), + Constraint.Constant (20), + Constraint.RelativeToParent (parent => parent.Height / 2), + Constraint.RelativeToParent (parent => parent.Height / 4)); + + Assert.IsTrue (relativeLayout.childAdded); + Assert.IsTrue (relativeLayout.added); + Assert.IsTrue (relativeLayout.layoutChildren); + + } + } + + internal class MockRelativeLayout : RelativeLayout + { + internal bool layoutChildren; + internal bool childAdded; + internal bool added; + + protected override void LayoutChildren (double x, double y, double width, double height) + { + if(added) + layoutChildren = true; + + base.LayoutChildren (x, y, width, height); + } + + protected override void OnAdded (View view) + { + if(childAdded) + added = true; + base.OnAdded (view); + } + + protected override void OnChildAdded (Element child) + { + childAdded = true; + base.OnChildAdded (child); + } + } +} -- cgit v1.2.3