using Xunit.Abstractions; namespace Terminal.Gui.LayoutTests; public class LayoutTests (ITestOutputHelper output) { private readonly ITestOutputHelper _output = output; [Fact] public void LayoutSubviews_No_SuperView () { var root = new View (); var first = new View { Id = "first", X = 1, Y = 2, Height = 3, Width = 4 }; root.Add (first); var second = new View { Id = "second" }; root.Add (second); second.X = Pos.Right (first) + 1; root.LayoutSubviews (); Assert.Equal (6, second.Frame.X); root.Dispose (); first.Dispose (); second.Dispose (); } [Fact] public void LayoutSubviews_RootHas_SuperView () { var top = new View (); var root = new View (); top.Add (root); var first = new View { Id = "first", X = 1, Y = 2, Height = 3, Width = 4 }; root.Add (first); var second = new View { Id = "second" }; root.Add (second); second.X = Pos.Right (first) + 1; root.LayoutSubviews (); Assert.Equal (6, second.Frame.X); root.Dispose (); top.Dispose (); first.Dispose (); second.Dispose (); } [Fact] public void LayoutSubviews_ViewThatRefsSubView_Throws () { var root = new View (); var super = new View (); root.Add (super); var sub = new View (); super.Add (sub); super.Width = Dim.Width (sub); Assert.Throws (() => root.LayoutSubviews ()); root.Dispose (); super.Dispose (); } [Fact] public void TopologicalSort_Missing_Add () { var root = new View (); var sub1 = new View (); root.Add (sub1); var sub2 = new View (); sub1.Width = Dim.Width (sub2); Assert.Throws (() => root.LayoutSubviews ()); sub2.Width = Dim.Width (sub1); Assert.Throws (() => root.LayoutSubviews ()); root.Dispose (); sub1.Dispose (); sub2.Dispose (); } [Fact] public void TopologicalSort_Recursive_Ref () { var root = new View (); var sub1 = new View (); root.Add (sub1); var sub2 = new View (); root.Add (sub2); sub2.Width = Dim.Width (sub2); Exception exception = Record.Exception (root.LayoutSubviews); Assert.Null (exception); root.Dispose (); sub1.Dispose (); sub2.Dispose (); } [Fact] public void LayoutSubviews_Uses_ContentSize () { var superView = new View () { Width = 5, Height = 5, }; superView.SetContentSize (new (10, 10)); var view = new View () { X = Pos.Center () }; superView.Add (view); superView.LayoutSubviews (); Assert.Equal (5, view.Frame.X); superView.Dispose (); } // Test OnLayoutStarted/OnLayoutComplete - ensure that they are called at right times [Fact] public void LayoutSubviews_LayoutStarted_Complete () { var superView = new View (); var view = new View (); superView.Add (view); superView.BeginInit (); superView.EndInit (); var layoutStarted = false; var layoutComplete = false; var borderLayoutStarted = false; var borderLayoutComplete = false; view.LayoutStarted += (sender, e) => layoutStarted = true; view.LayoutComplete += (sender, e) => layoutComplete = true; view.Border.LayoutStarted += (sender, e) => { Assert.True (layoutStarted); borderLayoutStarted = true; }; view.Border.LayoutComplete += (sender, e) => { Assert.True (layoutStarted); Assert.False (layoutComplete); borderLayoutComplete = true; }; superView.LayoutSubviews (); Assert.True (borderLayoutStarted); Assert.True (borderLayoutComplete); Assert.True (layoutStarted); Assert.True (layoutComplete); superView.Dispose (); } }