mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* Initial plan * Add comprehensive analysis of Line implementation status Co-authored-by: tig <585482+tig@users.noreply.github.com> * Complete Line implementation with documentation, example, and tests Co-authored-by: tig <585482+tig@users.noreply.github.com> * Add PR summary documenting Line implementation completion Co-authored-by: tig <585482+tig@users.noreply.github.com> * Add comprehensive completion report for Issue 4150 Co-authored-by: tig <585482+tig@users.noreply.github.com> * Fix Line rendering: use SuperView's LineCanvas instead of own Co-authored-by: tig <585482+tig@users.noreply.github.com> * Redesign Line to use Border instead of manual LineCanvas Co-authored-by: tig <585482+tig@users.noreply.github.com> * Add Line.Style property to avoid BorderStyle conflict Co-authored-by: tig <585482+tig@users.noreply.github.com> * Add SetWidth/SetHeight methods to preserve dimensions on Orientation change Co-authored-by: tig <585482+tig@users.noreply.github.com> * Implement CWP events for Width/Height properties; update Line to use events Co-authored-by: tig <585482+tig@users.noreply.github.com> * WIP: Updating Line. Cleaned up Layout tests. * Made Height/Width non-nullable * Add doWork stage to CWPPropertyHelper to execute between Changing and Changed events Co-authored-by: tig <585482+tig@users.noreply.github.com> * Move ViewLayoutEventTests to parallelizable tests without AutoInitShutdown Co-authored-by: tig <585482+tig@users.noreply.github.com> * Replace tracking fields with Length property for thread-safe Line implementation Co-authored-by: tig <585482+tig@users.noreply.github.com> * Fix orientation handling to preserve user-set dimensions in object initializers Co-authored-by: tig <585482+tig@users.noreply.github.com> * Simplify orientation handling with dimension swapping - all tests passing Co-authored-by: tig <585482+tig@users.noreply.github.com> * Add Length backing field and fix object initializer dimension handling Co-authored-by: tig <585482+tig@users.noreply.github.com> * Use CWP OnChanging events to manage dimensions instead of OnChanged Co-authored-by: tig <585482+tig@users.noreply.github.com> * Move LineTests to parallelizable; simplify tests with GetAnchor; fix Length property Co-authored-by: tig <585482+tig@users.noreply.github.com> * Code cleanup. * Code cleanup. * Update Terminal.Gui/ViewBase/View.Layout.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Terminal.Gui/ViewBase/View.Layout.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Terminal.Gui/ViewBase/View.Layout.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update Terminal.Gui/ViewBase/View.Layout.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fixed nullable warning in test * Removed PR files and updated copilot guidance * Reverted .gitignore change --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Tig <tig@users.noreply.github.com> Co-authored-by: tig <585482+tig@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -418,7 +418,7 @@ public partial class DimAutoTests
|
||||
var otherView = new View
|
||||
{
|
||||
Text = "01234\n01234\n01234\n01234\n01234",
|
||||
Width = Dim.Auto(),
|
||||
Width = Dim.Auto (),
|
||||
Height = Dim.Auto ()
|
||||
};
|
||||
view.Add (otherView);
|
||||
@@ -478,8 +478,8 @@ public partial class DimAutoTests
|
||||
|
||||
var posViewView = new View
|
||||
{
|
||||
X = Pos.Bottom(otherView),
|
||||
Y = Pos.Right(otherView),
|
||||
X = Pos.Bottom (otherView),
|
||||
Y = Pos.Right (otherView),
|
||||
Width = 5,
|
||||
Height = 5,
|
||||
};
|
||||
@@ -639,7 +639,11 @@ public partial class DimAutoTests
|
||||
Width = Dim.Auto (),
|
||||
Height = Dim.Auto (),
|
||||
};
|
||||
var subview = new View { X = Pos.Func (_ => 20), Y = Pos.Func (_ => 25) };
|
||||
var subview = new View
|
||||
{
|
||||
X = Pos.Func (_ => 20),
|
||||
Y = Pos.Func (_ => 25)
|
||||
};
|
||||
view.Add (subview);
|
||||
|
||||
view.SetRelativeLayout (new (100, 100));
|
||||
|
||||
@@ -243,6 +243,25 @@ public class FrameTests
|
||||
Assert.Equal (view.Height, frame.Height);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void Frame_Set_Sets_Viewport_Without_Layout ()
|
||||
{
|
||||
Rectangle frame = new (1, 2, 3, 4);
|
||||
|
||||
View v = new () { Frame = frame };
|
||||
Assert.Equal (frame, v.Frame);
|
||||
|
||||
Assert.Equal (
|
||||
new (0, 0, frame.Width, frame.Height),
|
||||
v.Viewport
|
||||
); // With Absolute Viewport *is* deterministic before Layout
|
||||
Assert.Equal (Pos.Absolute (1), v.X);
|
||||
Assert.Equal (Pos.Absolute (2), v.Y);
|
||||
Assert.Equal (Dim.Absolute (3), v.Width);
|
||||
Assert.Equal (Dim.Absolute (4), v.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FrameChanged_Event_Raised_When_Frame_Changes ()
|
||||
{
|
||||
|
||||
@@ -2,8 +2,61 @@
|
||||
|
||||
namespace Terminal.Gui.LayoutTests;
|
||||
|
||||
public class SetLayoutTests : GlobalTestSetup
|
||||
public class LayoutTests : GlobalTestSetup
|
||||
{
|
||||
#region Constructor Tests
|
||||
|
||||
[Fact]
|
||||
public void Constructor_Dispose_DoesNotThrow ()
|
||||
{
|
||||
var v = new View ();
|
||||
v.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_Defaults_Are_Correct ()
|
||||
{
|
||||
// Tests defaults
|
||||
View v = new ();
|
||||
Assert.Equal (new (0, 0, 0, 0), v.Frame);
|
||||
Assert.Equal (new (0, 0, 0, 0), v.Viewport);
|
||||
Assert.Equal (Pos.Absolute (0), v.X);
|
||||
Assert.Equal (Pos.Absolute (0), v.Y);
|
||||
Assert.Equal (Dim.Absolute (0), v.Width);
|
||||
Assert.Equal (Dim.Absolute (0), v.Height);
|
||||
|
||||
v.Layout ();
|
||||
Assert.Equal (new (0, 0, 0, 0), v.Frame);
|
||||
Assert.Equal (new (0, 0, 0, 0), v.Viewport);
|
||||
Assert.Equal (Pos.Absolute (0), v.X);
|
||||
Assert.Equal (Pos.Absolute (0), v.Y);
|
||||
Assert.Equal (Dim.Absolute (0), v.Width);
|
||||
Assert.Equal (Dim.Absolute (0), v.Height);
|
||||
}
|
||||
|
||||
#endregion Constructor Tests
|
||||
|
||||
[Fact]
|
||||
public void Set_All_Absolute_Sets_Correctly ()
|
||||
{
|
||||
Rectangle frame = new (1, 2, 3, 4);
|
||||
View v = new () { X = frame.X, Y = frame.Y, Width = frame.Width, Height = frame.Height };
|
||||
Assert.Equal (new (frame.X, frame.Y, 3, 4), v.Frame);
|
||||
Assert.Equal (new (0, 0, 3, 4), v.Viewport);
|
||||
Assert.Equal (Pos.Absolute (1), v.X);
|
||||
Assert.Equal (Pos.Absolute (2), v.Y);
|
||||
Assert.Equal (Dim.Absolute (3), v.Width);
|
||||
Assert.Equal (Dim.Absolute (4), v.Height);
|
||||
|
||||
v.Layout ();
|
||||
Assert.Equal (new (frame.X, frame.Y, 3, 4), v.Frame);
|
||||
Assert.Equal (new (0, 0, 3, 4), v.Viewport);
|
||||
Assert.Equal (Pos.Absolute (1), v.X);
|
||||
Assert.Equal (Pos.Absolute (2), v.Y);
|
||||
Assert.Equal (Dim.Absolute (3), v.Width);
|
||||
Assert.Equal (Dim.Absolute (4), v.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Add_Does_Not_Call_Layout ()
|
||||
{
|
||||
@@ -28,12 +81,26 @@ public class SetLayoutTests : GlobalTestSetup
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Change_Height_or_Width_MakesComputed ()
|
||||
public void Set_X_Y_Does_Not_Impact_Dimensions ()
|
||||
{
|
||||
var v = new View { Frame = Rectangle.Empty };
|
||||
v.Height = Dim.Fill ();
|
||||
v.Width = Dim.Fill ();
|
||||
v.Dispose ();
|
||||
// Tests that setting X & Y does not change Frame, Viewport, Width, or Height
|
||||
Rectangle frame = new (1, 2, 3, 4);
|
||||
|
||||
View v = new () { X = frame.X, Y = frame.Y };
|
||||
Assert.Equal (new (frame.X, frame.Y, 0, 0), v.Frame);
|
||||
Assert.Equal (new (0, 0, 0, 0), v.Viewport);
|
||||
Assert.Equal (Pos.Absolute (1), v.X);
|
||||
Assert.Equal (Pos.Absolute (2), v.Y);
|
||||
Assert.Equal (Dim.Absolute (0), v.Width);
|
||||
Assert.Equal (Dim.Absolute (0), v.Height);
|
||||
|
||||
v.Layout ();
|
||||
Assert.Equal (new (frame.X, frame.Y, 0, 0), v.Frame);
|
||||
Assert.Equal (new (0, 0, 0, 0), v.Viewport);
|
||||
Assert.Equal (Pos.Absolute (1), v.X);
|
||||
Assert.Equal (Pos.Absolute (2), v.Y);
|
||||
Assert.Equal (Dim.Absolute (0), v.Width);
|
||||
Assert.Equal (Dim.Absolute (0), v.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -59,15 +126,6 @@ public class SetLayoutTests : GlobalTestSetup
|
||||
v.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Change_X_or_Y_MakesComputed ()
|
||||
{
|
||||
var v = new View { Frame = Rectangle.Empty };
|
||||
v.X = Pos.Center ();
|
||||
v.Y = Pos.Center ();
|
||||
v.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Change_X_Y_Height_Width_Absolute ()
|
||||
{
|
||||
@@ -134,87 +192,6 @@ public class SetLayoutTests : GlobalTestSetup
|
||||
v.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor ()
|
||||
{
|
||||
var v = new View ();
|
||||
v.Dispose ();
|
||||
|
||||
var frame = Rectangle.Empty;
|
||||
v = new () { Frame = frame };
|
||||
v.Layout ();
|
||||
Assert.Equal (frame, v.Frame);
|
||||
|
||||
Assert.Equal (
|
||||
new (0, 0, frame.Width, frame.Height),
|
||||
v.Viewport
|
||||
); // With Absolute Viewport *is* deterministic before Layout
|
||||
Assert.Equal (Pos.Absolute (0), v.X);
|
||||
Assert.Equal (Pos.Absolute (0), v.Y);
|
||||
Assert.Equal (Dim.Absolute (0), v.Width);
|
||||
Assert.Equal (Dim.Absolute (0), v.Height);
|
||||
v.Dispose ();
|
||||
|
||||
frame = new (1, 2, 3, 4);
|
||||
v = new () { Frame = frame };
|
||||
v.Layout ();
|
||||
Assert.Equal (frame, v.Frame);
|
||||
|
||||
Assert.Equal (
|
||||
new (0, 0, frame.Width, frame.Height),
|
||||
v.Viewport
|
||||
); // With Absolute Viewport *is* deterministic before Layout
|
||||
Assert.Equal (Pos.Absolute (1), v.X);
|
||||
Assert.Equal (Pos.Absolute (2), v.Y);
|
||||
Assert.Equal (Dim.Absolute (3), v.Width);
|
||||
Assert.Equal (Dim.Absolute (4), v.Height);
|
||||
v.Dispose ();
|
||||
|
||||
v = new () { Frame = frame, Text = "v" };
|
||||
v.Layout ();
|
||||
Assert.Equal (frame, v.Frame);
|
||||
|
||||
Assert.Equal (
|
||||
new (0, 0, frame.Width, frame.Height),
|
||||
v.Viewport
|
||||
); // With Absolute Viewport *is* deterministic before Layout
|
||||
Assert.Equal (Pos.Absolute (1), v.X);
|
||||
Assert.Equal (Pos.Absolute (2), v.Y);
|
||||
Assert.Equal (Dim.Absolute (3), v.Width);
|
||||
Assert.Equal (Dim.Absolute (4), v.Height);
|
||||
v.Dispose ();
|
||||
|
||||
v = new () { X = frame.X, Y = frame.Y, Text = "v" };
|
||||
v.Layout ();
|
||||
Assert.Equal (new (frame.X, frame.Y, 0, 0), v.Frame);
|
||||
Assert.Equal (new (0, 0, 0, 0), v.Viewport); // With Absolute Viewport *is* deterministic before Layout
|
||||
Assert.Equal (Pos.Absolute (1), v.X);
|
||||
Assert.Equal (Pos.Absolute (2), v.Y);
|
||||
Assert.Equal (Dim.Absolute (0), v.Width);
|
||||
Assert.Equal (Dim.Absolute (0), v.Height);
|
||||
v.Dispose ();
|
||||
|
||||
v = new ();
|
||||
v.Layout ();
|
||||
Assert.Equal (new (0, 0, 0, 0), v.Frame);
|
||||
Assert.Equal (new (0, 0, 0, 0), v.Viewport); // With Absolute Viewport *is* deterministic before Layout
|
||||
Assert.Equal (Pos.Absolute (0), v.X);
|
||||
Assert.Equal (Pos.Absolute (0), v.Y);
|
||||
Assert.Equal (Dim.Absolute (0), v.Width);
|
||||
Assert.Equal (Dim.Absolute (0), v.Height);
|
||||
v.Dispose ();
|
||||
|
||||
v = new () { X = frame.X, Y = frame.Y, Width = frame.Width, Height = frame.Height };
|
||||
v.Layout ();
|
||||
Assert.Equal (new (frame.X, frame.Y, 3, 4), v.Frame);
|
||||
Assert.Equal (new (0, 0, 3, 4), v.Viewport); // With Absolute Viewport *is* deterministic before Layout
|
||||
Assert.Equal (Pos.Absolute (1), v.X);
|
||||
Assert.Equal (Pos.Absolute (2), v.Y);
|
||||
Assert.Equal (Dim.Absolute (3), v.Width);
|
||||
Assert.Equal (Dim.Absolute (4), v.Height);
|
||||
v.Dispose ();
|
||||
}
|
||||
|
||||
/// <summary>This is an intentionally obtuse test. See https://github.com/gui-cs/Terminal.Gui/issues/2461</summary>
|
||||
[Fact]
|
||||
public void Does_Not_Throw_If_Nested_SubViews_Ref_Topmost_SuperView ()
|
||||
@@ -0,0 +1,253 @@
|
||||
#nullable enable
|
||||
using UnitTests.Parallelizable;
|
||||
|
||||
namespace Terminal.Gui.ViewLayoutEventTests;
|
||||
|
||||
public class ViewLayoutEventTests : GlobalTestSetup
|
||||
{
|
||||
[Fact]
|
||||
public void View_WidthChanging_Event_Fires ()
|
||||
{
|
||||
var view = new View ();
|
||||
bool eventFired = false;
|
||||
Dim? oldValue = null;
|
||||
Dim? newValue = null;
|
||||
|
||||
view.WidthChanging += (sender, args) =>
|
||||
{
|
||||
eventFired = true;
|
||||
oldValue = args.CurrentValue;
|
||||
newValue = args.NewValue;
|
||||
};
|
||||
|
||||
view.Width = 10;
|
||||
|
||||
Assert.True (eventFired);
|
||||
Assert.NotNull (oldValue);
|
||||
Assert.NotNull (newValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_WidthChanged_Event_Fires ()
|
||||
{
|
||||
var view = new View ();
|
||||
bool eventFired = false;
|
||||
Dim? oldValue = null;
|
||||
Dim? newValue = null;
|
||||
|
||||
view.WidthChanged += (sender, args) =>
|
||||
{
|
||||
eventFired = true;
|
||||
oldValue = args.OldValue;
|
||||
newValue = args.NewValue;
|
||||
};
|
||||
|
||||
view.Width = 10;
|
||||
|
||||
Assert.True (eventFired);
|
||||
Assert.NotNull (oldValue);
|
||||
Assert.NotNull (newValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_WidthChanging_CanCancel ()
|
||||
{
|
||||
var view = new View ();
|
||||
Dim? originalWidth = view.Width;
|
||||
|
||||
view.WidthChanging += (sender, args) =>
|
||||
{
|
||||
args.Handled = true; // Cancel the change
|
||||
};
|
||||
|
||||
view.Width = 10;
|
||||
|
||||
// Width should not have changed
|
||||
Assert.Equal (originalWidth, view.Width);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_WidthChanging_CanModify ()
|
||||
{
|
||||
var view = new View ();
|
||||
|
||||
view.WidthChanging += (sender, args) =>
|
||||
{
|
||||
// Modify the proposed value
|
||||
args.NewValue = 20;
|
||||
};
|
||||
|
||||
view.Width = 10;
|
||||
|
||||
// Width should be 20 (the modified value), not 10
|
||||
var container = new View { Width = 50, Height = 20 };
|
||||
container.Add (view);
|
||||
container.Layout ();
|
||||
Assert.Equal (20, view.Frame.Width);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_HeightChanging_Event_Fires ()
|
||||
{
|
||||
var view = new View ();
|
||||
bool eventFired = false;
|
||||
Dim? oldValue = null;
|
||||
Dim? newValue = null;
|
||||
|
||||
view.HeightChanging += (sender, args) =>
|
||||
{
|
||||
eventFired = true;
|
||||
oldValue = args.CurrentValue;
|
||||
newValue = args.NewValue;
|
||||
};
|
||||
|
||||
view.Height = 10;
|
||||
|
||||
Assert.True (eventFired);
|
||||
Assert.NotNull (oldValue);
|
||||
Assert.NotNull (newValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_HeightChanged_Event_Fires ()
|
||||
{
|
||||
var view = new View ();
|
||||
bool eventFired = false;
|
||||
Dim? oldValue = null;
|
||||
Dim? newValue = null;
|
||||
|
||||
view.HeightChanged += (sender, args) =>
|
||||
{
|
||||
eventFired = true;
|
||||
oldValue = args.OldValue;
|
||||
newValue = args.NewValue;
|
||||
};
|
||||
|
||||
view.Height = 10;
|
||||
|
||||
Assert.True (eventFired);
|
||||
Assert.NotNull (oldValue);
|
||||
Assert.NotNull (newValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_HeightChanging_CanCancel ()
|
||||
{
|
||||
var view = new View ();
|
||||
Dim? originalHeight = view.Height;
|
||||
|
||||
view.HeightChanging += (sender, args) =>
|
||||
{
|
||||
args.Handled = true; // Cancel the change
|
||||
};
|
||||
|
||||
view.Height = 10;
|
||||
|
||||
// Height should not have changed
|
||||
Assert.Equal (originalHeight, view.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_HeightChanging_CanModify ()
|
||||
{
|
||||
var view = new View ();
|
||||
|
||||
view.HeightChanging += (sender, args) =>
|
||||
{
|
||||
// Modify the proposed value
|
||||
args.NewValue = 20;
|
||||
};
|
||||
|
||||
view.Height = 10;
|
||||
|
||||
// Height should be 20 (the modified value), not 10
|
||||
var container = new View { Width = 50, Height = 40 };
|
||||
container.Add (view);
|
||||
container.Layout ();
|
||||
Assert.Equal (20, view.Frame.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_OnWidthChanging_CanCancel ()
|
||||
{
|
||||
var testView = new TestView ();
|
||||
testView.CancelWidthChange = true;
|
||||
Dim? originalWidth = testView.Width;
|
||||
|
||||
testView.Width = 10;
|
||||
|
||||
// Width should not have changed
|
||||
Assert.Equal (originalWidth, testView.Width);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_OnHeightChanging_CanCancel ()
|
||||
{
|
||||
var testView = new TestView ();
|
||||
testView.CancelHeightChange = true;
|
||||
Dim originalHeight = testView.Height;
|
||||
|
||||
testView.Height = 10;
|
||||
|
||||
// Height should not have changed
|
||||
Assert.Equal (originalHeight, testView.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_WidthChanged_BackingFieldSetBeforeEvent ()
|
||||
{
|
||||
var view = new View ();
|
||||
Dim? widthInChangedEvent = null;
|
||||
|
||||
view.WidthChanged += (sender, args) =>
|
||||
{
|
||||
// The backing field should already be set when Changed event fires
|
||||
widthInChangedEvent = view.Width;
|
||||
};
|
||||
|
||||
view.Width = 25;
|
||||
|
||||
// The width seen in the Changed event should be the new value
|
||||
var container = new View { Width = 50, Height = 20 };
|
||||
container.Add (view);
|
||||
container.Layout ();
|
||||
Assert.Equal (25, view.Frame.Width);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void View_HeightChanged_BackingFieldSetBeforeEvent ()
|
||||
{
|
||||
var view = new View ();
|
||||
Dim? heightInChangedEvent = null;
|
||||
|
||||
view.HeightChanged += (sender, args) =>
|
||||
{
|
||||
// The backing field should already be set when Changed event fires
|
||||
heightInChangedEvent = view.Height;
|
||||
};
|
||||
|
||||
view.Height = 30;
|
||||
|
||||
// The height seen in the Changed event should be the new value
|
||||
var container = new View { Width = 50, Height = 40 };
|
||||
container.Add (view);
|
||||
container.Layout ();
|
||||
Assert.Equal (30, view.Frame.Height);
|
||||
}
|
||||
|
||||
private class TestView : View
|
||||
{
|
||||
public bool CancelWidthChange { get; set; }
|
||||
public bool CancelHeightChange { get; set; }
|
||||
|
||||
protected override bool OnWidthChanging (App.ValueChangingEventArgs<Dim> args)
|
||||
{
|
||||
return CancelWidthChange;
|
||||
}
|
||||
|
||||
protected override bool OnHeightChanging (App.ValueChangingEventArgs<Dim> args)
|
||||
{
|
||||
return CancelHeightChange;
|
||||
}
|
||||
}
|
||||
}
|
||||
274
Tests/UnitTestsParallelizable/Views/LineTests.cs
Normal file
274
Tests/UnitTestsParallelizable/Views/LineTests.cs
Normal file
@@ -0,0 +1,274 @@
|
||||
namespace Terminal.Gui.ViewsTests;
|
||||
|
||||
public class LineTests
|
||||
{
|
||||
[Fact]
|
||||
public void Line_DefaultConstructor_Horizontal ()
|
||||
{
|
||||
var line = new Line ();
|
||||
|
||||
Assert.Equal (Orientation.Horizontal, line.Orientation);
|
||||
Assert.Equal (Dim.Fill (), line.Width);
|
||||
Assert.Equal (LineStyle.Single, line.Style);
|
||||
Assert.True (line.SuperViewRendersLineCanvas);
|
||||
Assert.False (line.CanFocus);
|
||||
|
||||
line.Layout ();
|
||||
Assert.Equal (1, line.Frame.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_Horizontal_FillsWidth ()
|
||||
{
|
||||
var line = new Line { Orientation = Orientation.Horizontal };
|
||||
var container = new View { Width = 50, Height = 10 };
|
||||
container.Add (line);
|
||||
|
||||
container.Layout ();
|
||||
|
||||
Assert.Equal (50, line.Frame.Width);
|
||||
Assert.Equal (1, line.Frame.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_Vertical_FillsHeight ()
|
||||
{
|
||||
var line = new Line { Orientation = Orientation.Vertical };
|
||||
var container = new View { Width = 50, Height = 10 };
|
||||
container.Add (line);
|
||||
|
||||
container.Layout ();
|
||||
|
||||
Assert.Equal (1, line.Frame.Width);
|
||||
Assert.Equal (10, line.Frame.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_ChangeOrientation_UpdatesDimensions ()
|
||||
{
|
||||
var line = new Line { Orientation = Orientation.Horizontal };
|
||||
var container = new View { Width = 50, Height = 20 };
|
||||
container.Add (line);
|
||||
container.Layout ();
|
||||
|
||||
Assert.Equal (50, line.Frame.Width);
|
||||
Assert.Equal (1, line.Frame.Height);
|
||||
|
||||
// Change to vertical
|
||||
line.Orientation = Orientation.Vertical;
|
||||
container.Layout ();
|
||||
|
||||
Assert.Equal (1, line.Frame.Width);
|
||||
Assert.Equal (20, line.Frame.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_Style_CanBeSet ()
|
||||
{
|
||||
var line = new Line { Style = LineStyle.Double };
|
||||
|
||||
Assert.Equal (LineStyle.Double, line.Style);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (LineStyle.Single)]
|
||||
[InlineData (LineStyle.Double)]
|
||||
[InlineData (LineStyle.Heavy)]
|
||||
[InlineData (LineStyle.Rounded)]
|
||||
[InlineData (LineStyle.Dashed)]
|
||||
[InlineData (LineStyle.Dotted)]
|
||||
public void Line_SupportsDifferentLineStyles (LineStyle style)
|
||||
{
|
||||
var line = new Line { Style = style };
|
||||
|
||||
Assert.Equal (style, line.Style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_DrawsCalled_Successfully ()
|
||||
{
|
||||
var app = new Window ();
|
||||
var line = new Line { Y = 1, Width = 10 };
|
||||
app.Add (line);
|
||||
|
||||
app.BeginInit ();
|
||||
app.EndInit ();
|
||||
app.Layout ();
|
||||
|
||||
// Just verify the line can be drawn without errors
|
||||
Exception exception = Record.Exception (() => app.Draw ());
|
||||
Assert.Null (exception);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_WithBorder_DrawsSuccessfully ()
|
||||
{
|
||||
var app = new Window { Width = 20, Height = 10, BorderStyle = LineStyle.Single };
|
||||
|
||||
// Add a line that intersects with the window border
|
||||
var line = new Line { X = 5, Y = 0, Height = Dim.Fill (), Orientation = Orientation.Vertical };
|
||||
app.Add (line);
|
||||
|
||||
app.BeginInit ();
|
||||
app.EndInit ();
|
||||
app.Layout ();
|
||||
|
||||
// Just verify the line and border can be drawn together without errors
|
||||
Exception exception = Record.Exception (() => app.Draw ());
|
||||
Assert.Null (exception);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_MultipleIntersecting_DrawsSuccessfully ()
|
||||
{
|
||||
var app = new Window { Width = 30, Height = 15 };
|
||||
|
||||
// Create intersecting lines
|
||||
var hLine = new Line { X = 5, Y = 5, Width = 15, Style = LineStyle.Single };
|
||||
|
||||
var vLine = new Line
|
||||
{
|
||||
X = 12, Y = 2, Height = 8, Orientation = Orientation.Vertical, Style = LineStyle.Single
|
||||
};
|
||||
|
||||
app.Add (hLine, vLine);
|
||||
|
||||
app.BeginInit ();
|
||||
app.EndInit ();
|
||||
app.Layout ();
|
||||
|
||||
// Just verify multiple intersecting lines can be drawn without errors
|
||||
Exception exception = Record.Exception (() => app.Draw ());
|
||||
Assert.Null (exception);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_ExplicitWidthAndHeight_RespectValues ()
|
||||
{
|
||||
var line = new Line { Width = 10, Height = 1 };
|
||||
var container = new View { Width = 50, Height = 20 };
|
||||
container.Add (line);
|
||||
|
||||
container.Layout ();
|
||||
|
||||
Assert.Equal (10, line.Frame.Width);
|
||||
Assert.Equal (1, line.Frame.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_VerticalWithExplicitHeight_RespectValues ()
|
||||
{
|
||||
var line = new Line { Orientation = Orientation.Vertical };
|
||||
|
||||
// Set height AFTER orientation to avoid it being reset
|
||||
line.Width = 1;
|
||||
line.Height = 8;
|
||||
|
||||
var container = new View { Width = 50, Height = 20 };
|
||||
container.Add (line);
|
||||
|
||||
container.Layout ();
|
||||
|
||||
Assert.Equal (1, line.Frame.Width);
|
||||
Assert.Equal (8, line.Frame.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_SuperViewRendersLineCanvas_IsTrue ()
|
||||
{
|
||||
var line = new Line ();
|
||||
|
||||
Assert.True (line.SuperViewRendersLineCanvas);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_CannotFocus ()
|
||||
{
|
||||
var line = new Line ();
|
||||
|
||||
Assert.False (line.CanFocus);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_ImplementsIOrientation ()
|
||||
{
|
||||
var line = new Line ();
|
||||
|
||||
Assert.IsAssignableFrom<IOrientation> (line);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_Length_Get_ReturnsCorrectDimension ()
|
||||
{
|
||||
var line = new Line { Width = 20, Height = 1 };
|
||||
|
||||
// For horizontal, Length should be Width
|
||||
line.Orientation = Orientation.Horizontal;
|
||||
Assert.Equal (line.Width, line.Length);
|
||||
Assert.Equal (1, line.Height.GetAnchor (0));
|
||||
|
||||
// For vertical, Length should be Height
|
||||
line.Orientation = Orientation.Vertical;
|
||||
Assert.Equal (line.Height, line.Length);
|
||||
Assert.Equal (1, line.Width.GetAnchor (0));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_OrientationChange_SwapsDimensions ()
|
||||
{
|
||||
var line = new Line ();
|
||||
var container = new View { Width = 50, Height = 20 };
|
||||
container.Add (line);
|
||||
|
||||
// Start horizontal with custom dimensions
|
||||
line.Orientation = Orientation.Horizontal;
|
||||
line.Width = 30;
|
||||
line.Height = 1;
|
||||
container.Layout ();
|
||||
|
||||
Assert.Equal (30, line.Frame.Width);
|
||||
Assert.Equal (1, line.Frame.Height);
|
||||
|
||||
// Change to vertical - dimensions should swap
|
||||
line.Orientation = Orientation.Vertical;
|
||||
container.Layout ();
|
||||
|
||||
Assert.Equal (1, line.Frame.Width);
|
||||
Assert.Equal (30, line.Frame.Height); // Width became Height
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Line_Dimensions_WorkSameAsInitializers ()
|
||||
{
|
||||
// Object initializers work same as sequential assignment
|
||||
// Test: new Line { Width = 15, Orientation = Orientation.Horizontal }
|
||||
// Expected: Width=15, Height=1
|
||||
Line line = new () { Width = 15, Orientation = Orientation.Horizontal };
|
||||
|
||||
Assert.Equal (15, line.Width.GetAnchor (0));
|
||||
Assert.Equal (1, line.Height.GetAnchor (0));
|
||||
Assert.Equal (line.Length, line.Width); // Length should be Width for horizontal
|
||||
|
||||
line = new ();
|
||||
line.Width = 15;
|
||||
line.Orientation = Orientation.Horizontal;
|
||||
Assert.Equal (15, line.Width.GetAnchor (0));
|
||||
Assert.Equal (1, line.Height.GetAnchor (0));
|
||||
Assert.Equal (line.Length, line.Width); // Length should be Width for horizontal
|
||||
|
||||
// Test: new Line { Height = 9, Orientation = Orientation.Vertical }
|
||||
// Expected: Width=1, Height=9
|
||||
line = new() { Height = 9, Orientation = Orientation.Vertical };
|
||||
|
||||
Assert.Equal (1, line.Width.GetAnchor (0));
|
||||
Assert.Equal (9, line.Height.GetAnchor (0));
|
||||
Assert.Equal (line.Length, line.Height); // Length should be Height for vertical
|
||||
|
||||
line = new ();
|
||||
line.Height = 9;
|
||||
line.Orientation = Orientation.Vertical;
|
||||
Assert.Equal (1, line.Width.GetAnchor (0));
|
||||
Assert.Equal (9, line.Height.GetAnchor (0));
|
||||
Assert.Equal (line.Length, line.Height); // Length should be Height for vertical
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user