diff --git a/Terminal.Gui/View/View.Drawing.cs b/Terminal.Gui/View/View.Drawing.cs index f55dcc867..bb2fa7b27 100644 --- a/Terminal.Gui/View/View.Drawing.cs +++ b/Terminal.Gui/View/View.Drawing.cs @@ -235,10 +235,7 @@ public partial class View // Drawing APIs return; } - if (NeedsDisplay) - { - OnDrawAdornments (); - } + OnDrawAdornments (); if (ColorScheme is { }) { @@ -486,6 +483,7 @@ public partial class View // Drawing APIs // Each of these renders lines to either this View's LineCanvas // Those lines will be finally rendered in OnRenderLineCanvas + // QUESTION: Why are we not calling Draw here? Margin?.OnDrawContent (Margin.Viewport); Border?.OnDrawContent (Border.Viewport); Padding?.OnDrawContent (Padding.Viewport); diff --git a/Terminal.Gui/View/View.Layout.cs b/Terminal.Gui/View/View.Layout.cs index 3625344ae..362236b09 100644 --- a/Terminal.Gui/View/View.Layout.cs +++ b/Terminal.Gui/View/View.Layout.cs @@ -707,12 +707,13 @@ public partial class View // Layout APIs } // If the 'to' is rooted to 'from' it's a special-case. - // Use LayoutSubview with the Frame of the 'from'. - if (SuperView is { } && GetTopSuperView () is { } && IsLayoutNeeded () && edges.Count > 0) + // Use Layout with the ContentSize of the 'from'. + // See the Nested_SubViews_Ref_Topmost_SuperView unit test + if (edges.Count > 0 && GetTopSuperView () is { }) { foreach ((View from, View to) in edges) { - Debug.Fail ("This is dead code?"); + // QUESTION: Do we test this with adornments well enough? to.Layout (from.GetContentSize ()); } } diff --git a/UnitTests/TestHelpers.cs b/UnitTests/TestHelpers.cs index acc367e9a..c27ab3da9 100644 --- a/UnitTests/TestHelpers.cs +++ b/UnitTests/TestHelpers.cs @@ -111,10 +111,10 @@ public class AutoInitShutdownAttribute : BeforeAfterTestAttribute // Reset to defaults Locations = ConfigLocations.DefaultOnly; - Reset(); + Reset (); // Enable subsequent tests that call Init to get all config files (the default). - //Locations = ConfigLocations.All; + //Locations = ConfigLocations.All; } public override void Before (MethodInfo methodUnderTest) @@ -244,10 +244,12 @@ internal partial class TestHelpers /// Numbers between 0 and 9 for each row/col of the console. Must be valid indexes into /// . /// + /// /// The ConsoleDriver to use. If null will be used. /// public static void AssertDriverAttributesAre ( string expectedLook, + ITestOutputHelper output, ConsoleDriver driver = null, params Attribute [] expectedAttributes ) @@ -277,12 +279,14 @@ internal partial class TestHelpers switch (match.Count) { case 0: - throw new ( - $"{Application.ToString (driver)}\n" - + $"Expected Attribute {val} (PlatformColor = {val.Value.PlatformColor}) at Contents[{line},{c}] {contents [line, c]} ((PlatformColor = {contents [line, c].Attribute.Value.PlatformColor}) was not found.\n" - + $" Expected: {string.Join (",", expectedAttributes.Select (c => c))}\n" - + $" But Was: " - ); + output.WriteLine ( + $"{Application.ToString (driver)}\n" + + $"Expected Attribute {val} (PlatformColor = {val.Value.PlatformColor}) at Contents[{line},{c}] {contents [line, c]} ((PlatformColor = {contents [line, c].Attribute.Value.PlatformColor}) was not found.\n" + + $" Expected: {string.Join (",", expectedAttributes.Select (c => c))}\n" + + $" But Was: " + ); + Assert.Empty (match); + return; case > 1: throw new ArgumentException ( $"Bad value for expectedColors, {match.Count} Attributes had the same Value" @@ -294,12 +298,12 @@ internal partial class TestHelpers if (colorUsed != userExpected) { - throw new ( - $"{Application.ToString (driver)}\n" - + $"Unexpected Attribute at Contents[{line},{c}] {contents [line, c]}.\n" - + $" Expected: {userExpected} ({expectedAttributes [int.Parse (userExpected.ToString ())]})\n" - + $" But Was: {colorUsed} ({val})\n" - ); + output.WriteLine ($"{Application.ToString (driver)}"); + output.WriteLine ($"Unexpected Attribute at Contents[{line},{c}] {contents [line, c]}."); + output.WriteLine ($" Expected: {userExpected} ({expectedAttributes [int.Parse (userExpected.ToString ())]})"); + output.WriteLine ($" But Was: {colorUsed} ({val})"); + Assert.Equal (userExpected, colorUsed); + return; } } @@ -735,7 +739,7 @@ public class TestsAllViews public static IEnumerable AllViewTypes => typeof (View).Assembly .GetTypes () - .Where (type => type.IsClass && !type.IsAbstract && type.IsPublic && (type.IsSubclassOf (typeof (View)) || type == typeof(View))) + .Where (type => type.IsClass && !type.IsAbstract && type.IsPublic && (type.IsSubclassOf (typeof (View)) || type == typeof (View))) .Select (type => new object [] { type }); public static View CreateInstanceIfNotGeneric (Type type) diff --git a/UnitTests/Text/TextFormatterTests.cs b/UnitTests/Text/TextFormatterTests.cs index ffb6967dc..d83ab398f 100644 --- a/UnitTests/Text/TextFormatterTests.cs +++ b/UnitTests/Text/TextFormatterTests.cs @@ -4187,6 +4187,7 @@ ssb 011111111100000000000 011111111111111000000 000000000000000000000", + _output, null, attrs); @@ -4204,6 +4205,7 @@ ssb 011111111111111111110 011111111111111111110 000000000000000000000", + _output, null, attrs); } diff --git a/UnitTests/View/Adornment/AdornmentSubViewTests.cs b/UnitTests/View/Adornment/AdornmentSubViewTests.cs index 1e063cc5e..4a6f8bc41 100644 --- a/UnitTests/View/Adornment/AdornmentSubViewTests.cs +++ b/UnitTests/View/Adornment/AdornmentSubViewTests.cs @@ -30,6 +30,7 @@ public class AdornmentSubViewTests (ITestOutputHelper output) }; subView.Margin.Thickness = new Thickness (subViewMargin); Application.Top.Margin.Add (subView); + Application.Top.Layout (); var foundView = View.GetViewsUnderMouse (new Point(0, 0)).LastOrDefault (); @@ -58,6 +59,7 @@ public class AdornmentSubViewTests (ITestOutputHelper output) Visible = false }; Application.Top.Padding.Add (subView); + Application.Top.Layout (); Assert.Equal (Application.Top.Padding, View.GetViewsUnderMouse (new Point(0, 0)).LastOrDefault ()); Application.Top?.Dispose (); @@ -76,6 +78,7 @@ public class AdornmentSubViewTests (ITestOutputHelper output) subView.LayoutStarted += LayoutStarted; view.Margin.Thickness = new Thickness (1, 2, 3, 4); + view.Layout (); Assert.True (raised); return; diff --git a/UnitTests/View/Adornment/AdornmentTests.cs b/UnitTests/View/Adornment/AdornmentTests.cs index dca89772a..3cfe79e8a 100644 --- a/UnitTests/View/Adornment/AdornmentTests.cs +++ b/UnitTests/View/Adornment/AdornmentTests.cs @@ -335,13 +335,16 @@ public class AdornmentTests (ITestOutputHelper output) [Fact] public void Setting_Thickness_Causes_Parent_Layout () { - var view = new View (); + var parent = new View (); var raised = false; - view.BeginInit (); - view.EndInit (); + parent.BeginInit (); + parent.EndInit (); - view.LayoutStarted += LayoutStarted; - view.Margin.Thickness = new Thickness (1, 2, 3, 4); + parent.LayoutStarted += LayoutStarted; + parent.Margin.Thickness = new Thickness (1, 2, 3, 4); + Assert.True (parent.IsLayoutNeeded()); + Assert.True (parent.Margin.IsLayoutNeeded ()); + parent.Layout (); Assert.True (raised); return; @@ -355,13 +358,16 @@ public class AdornmentTests (ITestOutputHelper output) [Fact] public void Setting_Thickness_Causes_Adornment_Layout () { - var view = new View (); + var parent = new View (); var raised = false; - view.BeginInit (); - view.EndInit (); + parent.BeginInit (); + parent.EndInit (); - view.Margin.LayoutStarted += LayoutStarted; - view.Margin.Thickness = new Thickness (1, 2, 3, 4); + parent.Margin.LayoutStarted += LayoutStarted; + parent.Margin.Thickness = new Thickness (1, 2, 3, 4); + Assert.True (parent.IsLayoutNeeded ()); + Assert.True (parent.Margin.IsLayoutNeeded ()); + parent.Layout (); Assert.True (raised); return; diff --git a/UnitTests/View/Adornment/BorderTests.cs b/UnitTests/View/Adornment/BorderTests.cs index 29882235f..ccba117a8 100644 --- a/UnitTests/View/Adornment/BorderTests.cs +++ b/UnitTests/View/Adornment/BorderTests.cs @@ -34,7 +34,7 @@ public class BorderTests (ITestOutputHelper output) var expected = @"─┤A├─"; TestHelpers.AssertDriverContentsAre (expected, output); - TestHelpers.AssertDriverAttributesAre ("00000", null, view.ColorScheme.Normal); + TestHelpers.AssertDriverAttributesAre ("00000", output, null, view.ColorScheme.Normal); view.CanFocus = true; view.SetFocus (); @@ -42,7 +42,7 @@ public class BorderTests (ITestOutputHelper output) Assert.Equal (view.GetFocusColor (), view.Border.GetFocusColor ()); Assert.Equal (view.ColorScheme.Focus.Foreground, view.Border.GetFocusColor ().Foreground); Assert.Equal (view.ColorScheme.Normal.Foreground, view.Border.GetNormalColor ().Foreground); - TestHelpers.AssertDriverAttributesAre ("00100", null, view.ColorScheme.Normal, view.GetFocusColor ()); + TestHelpers.AssertDriverAttributesAre ("00100", output, null, view.ColorScheme.Normal, view.GetFocusColor ()); } [Fact] @@ -68,7 +68,7 @@ public class BorderTests (ITestOutputHelper output) var expected = @"─┤A├─"; TestHelpers.AssertDriverContentsAre (expected, output); - TestHelpers.AssertDriverAttributesAre ("00000", null, view.ColorScheme.Normal); + TestHelpers.AssertDriverAttributesAre ("00000", output, null, view.ColorScheme.Normal); } [Theory] @@ -677,6 +677,8 @@ public class BorderTests (ITestOutputHelper output) var view = new View { X = frameX, Y = frameY, Width = 10, Height = 10 }; super.Add (view); + superSuper.Layout (); + var expected = new Rectangle (expectedScreenX, expectedScreenY, 10, 10); Rectangle actual = view.FrameToScreen (); Assert.Equal (expected, actual); @@ -709,6 +711,8 @@ public class BorderTests (ITestOutputHelper output) var view = new View { X = frameX, Y = frameY, Width = 10, Height = 10 }; super.Add (view); + super.Layout (); + var expected = new Rectangle (expectedScreenX, expectedScreenY, 10, 10); Rectangle actual = view.FrameToScreen (); Assert.Equal (expected, actual); diff --git a/UnitTests/View/Adornment/MarginTests.cs b/UnitTests/View/Adornment/MarginTests.cs index 049d0d050..39d2afd8d 100644 --- a/UnitTests/View/Adornment/MarginTests.cs +++ b/UnitTests/View/Adornment/MarginTests.cs @@ -28,6 +28,7 @@ public class MarginTests (ITestOutputHelper output) superView.BeginInit (); superView.EndInit (); View.Diagnostics = ViewDiagnosticFlags.Padding; + view.SetNeedsDisplay(); view.Draw (); View.Diagnostics = ViewDiagnosticFlags.Off; @@ -38,6 +39,6 @@ M M MMM", output ); - TestHelpers.AssertDriverAttributesAre ("0", null, superView.GetNormalColor ()); + TestHelpers.AssertDriverAttributesAre ("0", output, null, superView.GetNormalColor ()); } } diff --git a/UnitTests/View/Adornment/PaddingTests.cs b/UnitTests/View/Adornment/PaddingTests.cs index fdcb5b457..9c1fe21ea 100644 --- a/UnitTests/View/Adornment/PaddingTests.cs +++ b/UnitTests/View/Adornment/PaddingTests.cs @@ -33,6 +33,6 @@ P P PPP", output ); - TestHelpers.AssertDriverAttributesAre ("0", null, view.GetNormalColor ()); + TestHelpers.AssertDriverAttributesAre ("0", output, null, view.GetNormalColor ()); } } diff --git a/UnitTests/View/Adornment/ShadowStyletests.cs b/UnitTests/View/Adornment/ShadowStyletests.cs index 60924f688..320fdf2dc 100644 --- a/UnitTests/View/Adornment/ShadowStyletests.cs +++ b/UnitTests/View/Adornment/ShadowStyletests.cs @@ -2,7 +2,7 @@ namespace Terminal.Gui.ViewTests; -public class ShadowStyleTests (ITestOutputHelper _output) +public class ShadowStyleTests (ITestOutputHelper output) { [Fact] public void Default_None () @@ -150,7 +150,7 @@ public class ShadowStyleTests (ITestOutputHelper _output) superView.EndInit (); superView.Draw (); - TestHelpers.AssertDriverAttributesAre (expectedAttrs, Application.Driver, attributes); + TestHelpers.AssertDriverAttributesAre (expectedAttrs, output, Application.Driver, attributes); } [Theory] @@ -218,7 +218,7 @@ public class ShadowStyleTests (ITestOutputHelper _output) superView.EndInit (); superView.Draw (); - TestHelpers.AssertDriverContentsWithFrameAre (expected, _output); + TestHelpers.AssertDriverContentsWithFrameAre (expected, output); view.Dispose (); } } diff --git a/UnitTests/View/DrawTests.cs b/UnitTests/View/DrawTests.cs index faf728884..cc5f72d89 100644 --- a/UnitTests/View/DrawTests.cs +++ b/UnitTests/View/DrawTests.cs @@ -525,6 +525,7 @@ public class DrawTests (ITestOutputHelper _output) 0 0 """, + _output, Application.Driver, Colors.ColorSchemes ["Base"]!.Normal ); diff --git a/UnitTests/View/Layout/Dim.AutoTests.MinMax.cs b/UnitTests/View/Layout/Dim.AutoTests.MinMax.cs index f184f5ee9..3bb23e4e1 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.MinMax.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.MinMax.cs @@ -51,8 +51,8 @@ public partial class DimAutoTests BorderStyle = LineStyle.Single, // a 1 thick adornment ValidatePosDim = true }; - view.SetContentSize (new (contentSize, 0)); + view.Layout (); Assert.Equal (expected, view.Frame.Width); } diff --git a/UnitTests/View/Layout/Dim.AutoTests.cs b/UnitTests/View/Layout/Dim.AutoTests.cs index 27efad835..338abcbf1 100644 --- a/UnitTests/View/Layout/Dim.AutoTests.cs +++ b/UnitTests/View/Layout/Dim.AutoTests.cs @@ -89,6 +89,7 @@ public partial class DimAutoTests (ITestOutputHelper output) Width = Auto (), Height = 1 }; + view.Layout (); Assert.Equal (4, view.TextFormatter.ConstrainToWidth); Assert.Equal (1, view.TextFormatter.ConstrainToHeight); @@ -100,6 +101,7 @@ public partial class DimAutoTests (ITestOutputHelper output) Width = 1, Height = Auto () }; + view.Layout (); Assert.Equal (1, view.TextFormatter.ConstrainToWidth); Assert.Equal (4, view.TextFormatter.ConstrainToHeight); } @@ -114,6 +116,7 @@ public partial class DimAutoTests (ITestOutputHelper output) Height = 1, Width = Auto () }; + view.Layout (); Assert.Equal (4, view.TextFormatter.ConstrainToWidth); Assert.Equal (1, view.TextFormatter.ConstrainToHeight); } @@ -272,10 +275,11 @@ public partial class DimAutoTests (ITestOutputHelper output) Text = "_1234", Width = Auto () }; + view.Layout (); Assert.Equal (new (4, 0), view.Frame.Size); view.Height = 1; - view.SetRelativeLayout (Application.Screen.Size); + view.Layout (); Assert.Equal (new (4, 1), view.Frame.Size); Size lastSize = view.Frame.Size; @@ -288,8 +292,7 @@ public partial class DimAutoTests (ITestOutputHelper output) Width = Auto (), Height = 1 }; - view.SetRelativeLayout (Application.Screen.Size); - + view.Layout (); lastSize = view.Frame.Size; view.VerticalTextAlignment = Alignment.Center; Assert.Equal (lastSize, view.Frame.Size); @@ -783,13 +786,14 @@ public partial class DimAutoTests (ITestOutputHelper output) }; super.Add (view); + super.Layout (); Rectangle expectedViewport = new (0, 0, 8, 1); Assert.Equal (expectedViewport.Size, view.GetContentSize ()); Assert.Equal (expectedViewport, view.Frame); Assert.Equal (expectedViewport, view.Viewport); - super.LayoutSubviews (); + super.Layout (); Assert.Equal (expectedViewport, view.Viewport); super.Dispose (); @@ -845,6 +849,7 @@ public partial class DimAutoTests (ITestOutputHelper output) view.Width = Auto (DimAutoStyle.Text, maximumContentDim: maxWidth); view.Height = Auto (DimAutoStyle.Text); view.Text = text; + view.Layout (); Assert.Equal (new (expectedW, expectedH), view.Frame.Size); } @@ -862,7 +867,7 @@ public partial class DimAutoTests (ITestOutputHelper output) view.Height = Auto (DimAutoStyle.Text); view.SetContentSize (new (1, 1)); view.Text = text; - view.SetRelativeLayout (Application.Screen.Size); + view.Layout (); Assert.Equal (new (expectedW, expectedH), view.Frame.Size); } @@ -886,7 +891,7 @@ public partial class DimAutoTests (ITestOutputHelper output) view.Text = text; superView.Add (view); - superView.SetRelativeLayout (Application.Screen.Size); + superView.Layout (); Assert.Equal (new (expectedW, expectedH), view.Frame.Size); } diff --git a/UnitTests/View/Layout/Dim.CombineTests.cs b/UnitTests/View/Layout/Dim.CombineTests.cs index 4a39c5478..6dd68c41e 100644 --- a/UnitTests/View/Layout/Dim.CombineTests.cs +++ b/UnitTests/View/Layout/Dim.CombineTests.cs @@ -19,110 +19,6 @@ public class DimCombineTests (ITestOutputHelper output) } - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - [Fact] - [TestRespondersDisposed] - public void DimCombine_ObtuseScenario_Does_Not_Throw_If_Two_SubViews_Refs_The_Same_SuperView () - { - var t = new View { Width = 80, Height = 25, Text = "top" }; - - var w = new Window - { - Width = Dim.Width (t) - 2, // 78 - Height = Dim.Height (t) - 2 // 23 - }; - var f = new FrameView (); - - var v1 = new View - { - Width = Dim.Width (w) - 2, // 76 - Height = Dim.Height (w) - 2 // 21 - }; - - var v2 = new View - { - Width = Dim.Width (v1) - 2, // 74 - Height = Dim.Height (v1) - 2 // 19 - }; - - f.Add (v1, v2); - w.Add (f); - t.Add (w); - t.BeginInit (); - t.EndInit (); - - f.Width = Dim.Width (t) - Dim.Width (w) + 4; // 80 - 74 = 6 - f.Height = Dim.Height (t) - Dim.Height (w) + 4; // 25 - 19 = 6 - - // BUGBUG: v2 - f references t and w here; t is f's super-superview and w is f's superview. This is supported! - Exception exception = Record.Exception (t.LayoutSubviews); - Assert.Null (exception); - Assert.Equal (80, t.Frame.Width); - Assert.Equal (25, t.Frame.Height); - Assert.Equal (78, w.Frame.Width); - Assert.Equal (23, w.Frame.Height); - Assert.Equal (6, f.Frame.Width); - Assert.Equal (6, f.Frame.Height); - Assert.Equal (76, v1.Frame.Width); - Assert.Equal (21, v1.Frame.Height); - Assert.Equal (74, v2.Frame.Width); - Assert.Equal (19, v2.Frame.Height); - t.Dispose (); - } - - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved - // TODO: A new test that calls SetRelativeLayout directly is needed. - - /// This is an intentionally obtuse test. See https://github.com/gui-cs/Terminal.Gui/issues/2461 - [Fact] - [TestRespondersDisposed] - public void DimCombine_ObtuseScenario_Throw_If_SuperView_Refs_SubView () - { - var t = new View { Width = 80, Height = 25 }; - - var w = new Window - { - Width = Dim.Width (t) - 2, // 78 - Height = Dim.Height (t) - 2 // 23 - }; - var f = new FrameView (); - - var v1 = new View - { - Width = Dim.Width (w) - 2, // 76 - Height = Dim.Height (w) - 2 // 21 - }; - - var v2 = new View - { - Width = Dim.Width (v1) - 2, // 74 - Height = Dim.Height (v1) - 2 // 19 - }; - - f.Add (v1, v2); - w.Add (f); - t.Add (w); - t.BeginInit (); - t.EndInit (); - - f.Width = Dim.Width (t) - Dim.Width (v2); // 80 - 74 = 6 - f.Height = Dim.Height (t) - Dim.Height (v2); // 25 - 19 = 6 - - Assert.Throws (t.LayoutSubviews); - Assert.Equal (80, t.Frame.Width); - Assert.Equal (25, t.Frame.Height); - Assert.Equal (78, w.Frame.Width); - Assert.Equal (23, w.Frame.Height); - Assert.Equal (6, f.Frame.Width); - Assert.Equal (6, f.Frame.Height); - Assert.Equal (76, v1.Frame.Width); - Assert.Equal (21, v1.Frame.Height); - Assert.Equal (74, v2.Frame.Width); - Assert.Equal (19, v2.Frame.Height); - t.Dispose (); - } - // TODO: This actually a SetRelativeLayout/LayoutSubViews test and should be moved // TODO: A new test that calls SetRelativeLayout directly is needed. [Fact] diff --git a/UnitTests/View/Layout/LayoutTests.cs b/UnitTests/View/Layout/LayoutTests.cs index d0482654c..b7fa14d15 100644 --- a/UnitTests/View/Layout/LayoutTests.cs +++ b/UnitTests/View/Layout/LayoutTests.cs @@ -608,4 +608,143 @@ public class LayoutTests (ITestOutputHelper output) v.Dispose (); } + /// + /// This tests the special case in LayoutSubviews. See https://github.com/gui-cs/Terminal.Gui/issues/2461 + [Fact] + public void Nested_SubViews_Ref_Topmost_SuperView () + { + var superView = new View { Width = 80, Height = 25, Text = "superView" }; + + var subView1 = new View + { + Id = "subView1 - refs superView", + Width = Dim.Width (superView) - 2, // 78 + Height = Dim.Height (superView) - 2 // 23 + }; + superView.Add (subView1); + + var subView1OfSubView1 = new View () + { + Id = "subView1OfSubView1 - refs superView", + Width = Dim.Width (superView) - 4, // 76 + Height = Dim.Height (superView) - 4 // 21 + }; + subView1.Add (subView1OfSubView1); + + superView.Layout (); + + Assert.Equal (80, superView.Frame.Width); + Assert.Equal (25, superView.Frame.Height); + Assert.Equal (78, subView1.Frame.Width); + Assert.Equal (23, subView1.Frame.Height); + //Assert.Equal (76, subView2.Frame.Width); + //Assert.Equal (21, subView2.Frame.Height); + + Assert.Equal (76, subView1OfSubView1.Frame.Width); + Assert.Equal (21, subView1OfSubView1.Frame.Height); + + superView.Dispose (); + } + + /// This is an intentionally obtuse test. See https://github.com/gui-cs/Terminal.Gui/issues/2461 + [Fact] + public void Does_Not_Throw_If_Nested_SubViews_Ref_Topmost_SuperView () + { + var t = new View { Width = 80, Height = 25, Text = "top" }; + + var w = new Window + { + Width = Dim.Width (t) - 2, // 78 + Height = Dim.Height (t) - 2 // 23 + }; + var f = new FrameView (); + + var v1 = new View + { + Width = Dim.Width (w) - 2, // 76 + Height = Dim.Height (w) - 2 // 21 + }; + + var v2 = new View + { + Width = Dim.Width (v1) - 2, // 74 + Height = Dim.Height (v1) - 2 // 19 + }; + + f.Width = Dim.Width (t) - Dim.Width (w) + 4; // 80 - 74 = 6 + f.Height = Dim.Height (t) - Dim.Height (w) + 4; // 25 - 19 = 6 + + f.Add (v1, v2); + w.Add (f); + t.Add (w); + t.BeginInit (); + t.EndInit (); + + // f references t and w here; t is f's super-superview and w is f's superview. This is supported! + Exception exception = Record.Exception (() => t.Layout ()); + Assert.Null (exception); + Assert.Equal (80, t.Frame.Width); + Assert.Equal (25, t.Frame.Height); + Assert.Equal (78, w.Frame.Width); + Assert.Equal (23, w.Frame.Height); + Assert.Equal (6, f.Frame.Width); + Assert.Equal (6, f.Frame.Height); + Assert.Equal (76, v1.Frame.Width); + Assert.Equal (21, v1.Frame.Height); + Assert.Equal (74, v2.Frame.Width); + Assert.Equal (19, v2.Frame.Height); + t.Dispose (); + } + + + /// This is an intentionally obtuse test. See https://github.com/gui-cs/Terminal.Gui/issues/2461 + [Fact] + [TestRespondersDisposed] + public void Throw_If_SuperView_Refs_SubView () + { + var topSuperView = new View { Width = 80, Height = 25 }; + + var superViewRefsTopSuperView = new Window + { + Width = Dim.Width (topSuperView) - 2, // 78 + Height = Dim.Height (topSuperView) - 2 // 23 + }; + + var v1 = new View + { + Width = Dim.Width (superViewRefsTopSuperView) - 2, // 76 + Height = Dim.Height (superViewRefsTopSuperView) - 2 // 21 + }; + + var v2 = new View + { + Width = Dim.Width (v1) - 2, // 74 + Height = Dim.Height (v1) - 2 // 19 + }; + + var superView = new FrameView (); + superView.Width = Dim.Width (topSuperView) - Dim.Width (v2); // 80 - 74 = 6 + superView.Height = Dim.Height (topSuperView) - Dim.Height (v2); // 25 - 19 = 6 + superView.Add (v1, v2); + + superViewRefsTopSuperView.Add (superView); + + topSuperView.Add (superViewRefsTopSuperView); + + topSuperView.SetRelativeLayout (new (100, 100)); + + Assert.Throws (() => topSuperView.LayoutSubviews()); + Assert.Equal (80, topSuperView.Frame.Width); + Assert.Equal (25, topSuperView.Frame.Height); + Assert.Equal (78, superViewRefsTopSuperView.Frame.Width); + Assert.Equal (23, superViewRefsTopSuperView.Frame.Height); + Assert.Equal (6, superView.Frame.Width); + Assert.Equal (6, superView.Frame.Height); + Assert.Equal (76, v1.Frame.Width); + Assert.Equal (21, v1.Frame.Height); + Assert.Equal (74, v2.Frame.Width); + Assert.Equal (19, v2.Frame.Height); + topSuperView.Dispose (); + } + } diff --git a/UnitTests/View/Layout/ScreenToTests.cs b/UnitTests/View/Layout/ScreenToTests.cs index 43b60ad99..c2de37443 100644 --- a/UnitTests/View/Layout/ScreenToTests.cs +++ b/UnitTests/View/Layout/ScreenToTests.cs @@ -31,6 +31,7 @@ public class ScreenToTests Height = 10, BorderStyle = LineStyle.Single }; + view.Layout (); Point actual = view.ScreenToViewport (new (x, y)); Assert.Equal (expectedX, actual.X); @@ -53,6 +54,7 @@ public class ScreenToTests public void ScreenToViewport_NoSuper_NoAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) { var view = new View { X = viewX, Y = viewY, Width = 10, Height = 10 }; + view.Layout (); Point actual = view.ScreenToViewport (new (x, y)); Assert.Equal (expectedX, actual.X); @@ -81,6 +83,7 @@ public class ScreenToTests }; var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; super.Add (view); + super.Layout (); Point actual = view.ScreenToViewport (new (x, y)); Assert.Equal (expectedX, actual.X); @@ -110,6 +113,7 @@ public class ScreenToTests var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; view.SetContentSize (new (6, 6)); super.Add (view); + super.Layout (); view.Viewport = new (1, 1, 5, 5); @@ -133,6 +137,7 @@ public class ScreenToTests var super = new View { X = 0, Y = 0, Width = 10, Height = 10 }; var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; super.Add (view); + super.Layout (); Point actual = view.ScreenToViewport (new (x, y)); Assert.Equal (expectedX, actual.X); @@ -166,6 +171,7 @@ public class ScreenToTests }; view.SetContentSize (new (10, 10)); super.Add (view); + super.Layout (); view.Viewport = view.Viewport with { Location = new (1, 1) }; @@ -197,6 +203,7 @@ public class ScreenToTests Height = 10, BorderStyle = LineStyle.Single }; + view.Layout (); Point actual = view.ScreenToFrame (new (x, y)); Assert.Equal (expectedX, actual.X); @@ -219,6 +226,7 @@ public class ScreenToTests public void ScreenToFrame_NoSuper_NoAdornments (int viewX, int viewY, int x, int y, int expectedX, int expectedY) { var view = new View { X = viewX, Y = viewY, Width = 10, Height = 10 }; + view.Layout (); Point actual = view.ScreenToFrame (new (x, y)); Assert.Equal (expectedX, actual.X); @@ -247,6 +255,7 @@ public class ScreenToTests }; var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; super.Add (view); + super.Layout (); Point actual = view.ScreenToFrame (new (x, y)); Assert.Equal (expectedX, actual.X); @@ -268,6 +277,7 @@ public class ScreenToTests var super = new View { X = 0, Y = 0, Width = 10, Height = 10 }; var view = new View { X = viewX, Y = viewY, Width = 5, Height = 5 }; super.Add (view); + super.Layout (); Point actual = view.ScreenToFrame (new (x, y)); Assert.Equal (expectedX, actual.X); diff --git a/UnitTests/View/Layout/SetRelativeLayoutTests.cs b/UnitTests/View/Layout/SetRelativeLayoutTests.cs index 556b77f3a..547700de2 100644 --- a/UnitTests/View/Layout/SetRelativeLayoutTests.cs +++ b/UnitTests/View/Layout/SetRelativeLayoutTests.cs @@ -429,4 +429,7 @@ public class SetRelativeLayoutTests Assert.Equal (26, tf.Frame.Width); Assert.Equal (1, tf.Frame.Height); } + + + } diff --git a/UnitTests/View/ViewTests.cs b/UnitTests/View/ViewTests.cs index 3c10f3d72..27a5d6b60 100644 --- a/UnitTests/View/ViewTests.cs +++ b/UnitTests/View/ViewTests.cs @@ -187,6 +187,7 @@ cccccccccccccccccccc", @" 111111111111111111110 111111111111111111110", + output, Application.Driver, attributes ); @@ -197,6 +198,7 @@ cccccccccccccccccccc", @" 222222222222222222220 111111111111111111110", + output, Application.Driver, attributes ); @@ -215,6 +217,7 @@ cccccccccccccccccccc", @" 222222222222222222220 111111111111111111110", + output, Application.Driver, attributes ); diff --git a/UnitTests/Views/ComboBoxTests.cs b/UnitTests/Views/ComboBoxTests.cs index afc435ca4..468a3929f 100644 --- a/UnitTests/Views/ComboBoxTests.cs +++ b/UnitTests/Views/ComboBoxTests.cs @@ -551,6 +551,7 @@ Three ", 222222 222222 222222", + output, Application.Driver, attributes ); @@ -568,6 +569,7 @@ Three ", 222222 000002 222222", + output, Application.Driver, attributes ); @@ -585,6 +587,7 @@ Three ", 222222 222222 000002", + output, Application.Driver, attributes ); @@ -608,6 +611,7 @@ Three ", 222222 222222 000002", + output, Application.Driver, attributes ); @@ -625,6 +629,7 @@ Three ", 222222 000002 111112", + output, Application.Driver, attributes ); @@ -642,6 +647,7 @@ Three ", 000002 222222 111112", + output, Application.Driver, attributes ); diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs index c2ba406f7..32732b096 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/UnitTests/Views/MenuBarTests.cs @@ -380,6 +380,7 @@ public class MenuBarTests (ITestOutputHelper output) TestHelpers.AssertDriverAttributesAre ( @" 00000000000000", + output, Application.Driver, attributes ); @@ -400,6 +401,7 @@ public class MenuBarTests (ITestOutputHelper output) 00000000000000 00000000000000 00000000000000", + output, Application.Driver, attributes ); @@ -421,6 +423,7 @@ public class MenuBarTests (ITestOutputHelper output) 00000000000000 00000000000000 00000000000000", + output, Application.Driver, attributes ); @@ -442,6 +445,7 @@ public class MenuBarTests (ITestOutputHelper output) 00000000000000 00000000000000 00000000000000", + output, Application.Driver, attributes ); diff --git a/UnitTests/Views/ScrollViewTests.cs b/UnitTests/Views/ScrollViewTests.cs index e7caf1d31..e9196fe53 100644 --- a/UnitTests/Views/ScrollViewTests.cs +++ b/UnitTests/Views/ScrollViewTests.cs @@ -239,6 +239,7 @@ public class ScrollViewTests (ITestOutputHelper output) 00000000000000000000000 00000000000000000000000 00000000000000000000000", + output, null, attributes ); @@ -286,6 +287,7 @@ public class ScrollViewTests (ITestOutputHelper output) 00000000000000000000000 00000000000000000000000 00000000000000000000000", + output, null, attributes ); @@ -332,6 +334,7 @@ public class ScrollViewTests (ITestOutputHelper output) 00000000000000000000000 00000000000000000000000 00000000000000000000000", + output, null, attributes ); @@ -432,6 +435,7 @@ public class ScrollViewTests (ITestOutputHelper output) 022222222210 011111111110 000000000000", + output, null, attrs ); diff --git a/UnitTests/Views/TableViewTests.cs b/UnitTests/Views/TableViewTests.cs index 5c6a3c204..7ae39badf 100644 --- a/UnitTests/Views/TableViewTests.cs +++ b/UnitTests/Views/TableViewTests.cs @@ -115,7 +115,7 @@ public class TableViewTests (ITestOutputHelper output) 00000000000000000000 01111101101111111110 "; - TestHelpers.AssertDriverAttributesAre (expected, Application.Driver, tv.ColorScheme.Normal, color); + TestHelpers.AssertDriverAttributesAre (expected, output, Application.Driver, tv.ColorScheme.Normal, color); top.Dispose (); } @@ -1094,6 +1094,7 @@ public class TableViewTests (ITestOutputHelper output) TestHelpers.AssertDriverAttributesAre ( expectedColors, + output, Application.Driver, tv.ColorScheme.Normal, focused ? tv.ColorScheme.Focus : tv.ColorScheme.HotNormal, @@ -1129,6 +1130,7 @@ public class TableViewTests (ITestOutputHelper output) // (now that the cell value is 5 - which does not match the conditional) TestHelpers.AssertDriverAttributesAre ( expectedColors, + output, Application.Driver, tv.ColorScheme.Normal, focused ? tv.ColorScheme.Focus : tv.ColorScheme.HotNormal @@ -1187,6 +1189,7 @@ public class TableViewTests (ITestOutputHelper output) TestHelpers.AssertDriverAttributesAre ( expectedColors, + output, Application.Driver, tv.ColorScheme.Normal, focused ? rowHighlight.Focus : rowHighlight.HotNormal, @@ -1222,6 +1225,7 @@ public class TableViewTests (ITestOutputHelper output) // (now that the cell value is 5 - which does not match the conditional) TestHelpers.AssertDriverAttributesAre ( expectedColors, + output, Application.Driver, tv.ColorScheme.Normal, focused ? tv.ColorScheme.Focus : tv.ColorScheme.HotNormal @@ -1267,6 +1271,7 @@ public class TableViewTests (ITestOutputHelper output) TestHelpers.AssertDriverAttributesAre ( expectedColors, + output, Application.Driver, tv.ColorScheme.Normal, focused ? tv.ColorScheme.Focus : tv.ColorScheme.HotNormal @@ -1312,6 +1317,7 @@ public class TableViewTests (ITestOutputHelper output) TestHelpers.AssertDriverAttributesAre ( expectedColors, + output, Application.Driver, tv.ColorScheme.Normal, focused ? invertFocus : invertHotNormal @@ -2291,7 +2297,7 @@ public class TableViewTests (ITestOutputHelper output) 0101010 0000000"; - TestHelpers.AssertDriverAttributesAre (expected, Application.Driver, normal, focus); + TestHelpers.AssertDriverAttributesAre (expected, output, Application.Driver, normal, focus); } [Fact] @@ -2344,7 +2350,7 @@ A B C 000000 111111"; - TestHelpers.AssertDriverAttributesAre (expected, Application.Driver, normal, focus); + TestHelpers.AssertDriverAttributesAre (expected, output, Application.Driver, normal, focus); } [Fact] @@ -2400,7 +2406,7 @@ A B C 0111110 0000000"; - TestHelpers.AssertDriverAttributesAre (expected, Application.Driver, normal, focus); + TestHelpers.AssertDriverAttributesAre (expected, output, Application.Driver, normal, focus); } [Theory] diff --git a/UnitTests/Views/TextFieldTests.cs b/UnitTests/Views/TextFieldTests.cs index 216b10fd0..5de01651c 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/UnitTests/Views/TextFieldTests.cs @@ -1074,7 +1074,7 @@ public class TextFieldTests (ITestOutputHelper output) }; // TAB to jump between text fields. - TestHelpers.AssertDriverAttributesAre ("0000000", Application.Driver, attributes); + TestHelpers.AssertDriverAttributesAre ("0000000", output, Application.Driver, attributes); // Cursor is at the end Assert.Equal (32, _textField.CursorPosition); @@ -1085,7 +1085,7 @@ public class TextFieldTests (ITestOutputHelper output) Assert.Equal (4, _textField.CursorPosition); // TAB to jump between text fields. - TestHelpers.AssertDriverAttributesAre ("1111000", Application.Driver, attributes); + TestHelpers.AssertDriverAttributesAre ("1111000", output, Application.Driver, attributes); top.Dispose (); } diff --git a/UnitTests/Views/TextViewTests.cs b/UnitTests/Views/TextViewTests.cs index 3e574d843..72e5a4f13 100644 --- a/UnitTests/Views/TextViewTests.cs +++ b/UnitTests/Views/TextViewTests.cs @@ -6359,7 +6359,7 @@ This is the second line. }; // TAB to jump between text fields. - TestHelpers.AssertDriverAttributesAre ("0000000", Application.Driver, attributes); + TestHelpers.AssertDriverAttributesAre ("0000000", _output, Application.Driver, attributes); Assert.Empty (_textView.SelectedCellsList); _textView.NewKeyDownEvent (Key.CursorRight.WithCtrl.WithShift); @@ -6368,7 +6368,7 @@ This is the second line. Assert.Equal (new Point (4, 0), _textView.CursorPosition); // TAB to jump between text fields. - TestHelpers.AssertDriverAttributesAre ("1111000", Application.Driver, attributes); + TestHelpers.AssertDriverAttributesAre ("1111000", _output, Application.Driver, attributes); Assert.Equal ("TAB ", Cell.ToString (_textView.SelectedCellsList [^1])); top.Dispose (); } @@ -8993,12 +8993,12 @@ Error "; 2222225555 3333555555 4444455555"; - TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes); + TestHelpers.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); tv.WordWrap = true; Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (expectedText, _output); - TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes); + TestHelpers.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); tv.CursorPosition = new (6, 2); tv.SelectionStartColumn = 0; @@ -9028,7 +9028,7 @@ Dialogror "; 4400000000 1111555555 2222224445"; - TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes); + TestHelpers.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); tv.Undo (); tv.CursorPosition = new (0, 3); @@ -9065,7 +9065,7 @@ ror "; 1111555555 2222225555 4445555555"; - TestHelpers.AssertDriverAttributesAre (expectedColor, Application.Driver, attributes); + TestHelpers.AssertDriverAttributesAre (expectedColor, _output, Application.Driver, attributes); Application.End (rs); top.Dispose (); diff --git a/UnitTests/Views/TreeViewTests.cs b/UnitTests/Views/TreeViewTests.cs index 12d1ecf97..b8d7fe48d 100644 --- a/UnitTests/Views/TreeViewTests.cs +++ b/UnitTests/Views/TreeViewTests.cs @@ -1229,6 +1229,7 @@ oot two 0000000000 0000000000 ", + _output, Application.Driver, tv.ColorScheme.Normal, pink @@ -1265,6 +1266,7 @@ oot two 0000000000 001111 ", + _output, Application.Driver, tv.ColorScheme.Normal, pink