| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032 |
- using Xunit.Abstractions;
- namespace ViewBaseTests.Arrangement;
- public class ArrangementTests (ITestOutputHelper output)
- {
- private readonly ITestOutputHelper _output = output;
- #region ViewArrangement Enum Tests
- [Fact]
- public void ViewArrangement_Fixed_IsZero ()
- {
- Assert.Equal (0, (int)ViewArrangement.Fixed);
- }
- [Fact]
- public void ViewArrangement_Flags_HaveCorrectValues ()
- {
- Assert.Equal (1, (int)ViewArrangement.Movable);
- Assert.Equal (2, (int)ViewArrangement.LeftResizable);
- Assert.Equal (4, (int)ViewArrangement.RightResizable);
- Assert.Equal (8, (int)ViewArrangement.TopResizable);
- Assert.Equal (16, (int)ViewArrangement.BottomResizable);
- Assert.Equal (32, (int)ViewArrangement.Overlapped);
- }
- [Fact]
- public void ViewArrangement_Resizable_IsCombinationOfAllResizableFlags ()
- {
- ViewArrangement expected = ViewArrangement.LeftResizable
- | ViewArrangement.RightResizable
- | ViewArrangement.TopResizable
- | ViewArrangement.BottomResizable;
- Assert.Equal (ViewArrangement.Resizable, expected);
- }
- [Fact]
- public void ViewArrangement_CanCombineFlags ()
- {
- ViewArrangement arrangement = ViewArrangement.Movable | ViewArrangement.LeftResizable;
- Assert.True (arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.False (arrangement.HasFlag (ViewArrangement.RightResizable));
- }
- #endregion
- #region View.Arrangement Property Tests
- [Fact]
- public void View_Arrangement_DefaultsToFixed ()
- {
- var view = new View ();
- Assert.Equal (ViewArrangement.Fixed, view.Arrangement);
- }
- [Fact]
- public void View_Arrangement_CanBeSet ()
- {
- var view = new View { Arrangement = ViewArrangement.Movable };
- Assert.Equal (ViewArrangement.Movable, view.Arrangement);
- }
- [Fact]
- public void View_Arrangement_CanSetMultipleFlags ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- }
- [Fact]
- public void View_Arrangement_Overlapped_CanBeSetIndependently ()
- {
- var view = new View { Arrangement = ViewArrangement.Overlapped };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Overlapped));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.Movable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.Resizable));
- }
- [Fact]
- public void View_Arrangement_CanCombineOverlappedWithOtherFlags ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Overlapped));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Movable));
- }
- #endregion
- #region TopResizable and Movable Mutual Exclusivity Tests
- [Fact]
- public void TopResizable_WithoutMovable_IsAllowed ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.TopResizable,
- BorderStyle = LineStyle.Single
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.Movable));
- }
- [Fact]
- public void Movable_WithTopResizable_MovableWins ()
- {
- // According to docs and Border.Arrangment.cs line 569:
- // TopResizable is only checked if NOT Movable
- var view = new View
- {
- Arrangement = ViewArrangement.Movable | ViewArrangement.TopResizable,
- BorderStyle = LineStyle.Single
- };
- // Both flags can be set on the property
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- // But the behavior in Border.DetermineArrangeModeFromClick
- // will prioritize Movable over TopResizable
- }
- [Fact]
- public void Resizable_WithMovable_IncludesTopResizable ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Resizable | ViewArrangement.Movable,
- BorderStyle = LineStyle.Single
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- }
- #endregion
- #region Border Arrangement Tests
- [Fact]
- public void Border_WithNoArrangement_HasNoArrangementOptions ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Fixed,
- BorderStyle = LineStyle.Single
- };
- Assert.NotNull (view.Border);
- Assert.Equal (ViewArrangement.Fixed, view.Arrangement);
- }
- [Fact]
- public void Border_WithMovableArrangement_CanEnterArrangeMode ()
- {
- var superView = new View ();
- var view = new View
- {
- Arrangement = ViewArrangement.Movable,
- BorderStyle = LineStyle.Single,
- X = 0,
- Y = 0,
- Width = 10,
- Height = 10
- };
- superView.Add (view);
- Assert.NotNull (view.Border);
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Movable));
- }
- [Fact]
- public void Border_WithResizableArrangement_HasResizableOptions ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Resizable,
- BorderStyle = LineStyle.Single
- };
- Assert.NotNull (view.Border);
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- }
- [Theory]
- [InlineData (ViewArrangement.LeftResizable)]
- [InlineData (ViewArrangement.RightResizable)]
- [InlineData (ViewArrangement.TopResizable)]
- [InlineData (ViewArrangement.BottomResizable)]
- public void Border_WithSingleResizableDirection_OnlyHasThatOption (ViewArrangement arrangement)
- {
- var view = new View
- {
- Arrangement = arrangement,
- BorderStyle = LineStyle.Single
- };
- Assert.NotNull (view.Border);
- Assert.True (view.Arrangement.HasFlag (arrangement));
- // Verify other directions are not set
- if (arrangement != ViewArrangement.LeftResizable)
- {
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- }
- if (arrangement != ViewArrangement.RightResizable)
- {
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- }
- if (arrangement != ViewArrangement.TopResizable)
- {
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- }
- if (arrangement != ViewArrangement.BottomResizable)
- {
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- }
- }
- #endregion
- #region Corner Resizing Tests
- [Fact]
- public void Border_BottomRightResizable_CombinesBothFlags ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.BottomResizable | ViewArrangement.RightResizable,
- BorderStyle = LineStyle.Single
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- }
- [Fact]
- public void Border_BottomLeftResizable_CombinesBothFlags ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.BottomResizable | ViewArrangement.LeftResizable,
- BorderStyle = LineStyle.Single
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- }
- [Fact]
- public void Border_TopRightResizable_CombinesBothFlags ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.TopResizable | ViewArrangement.RightResizable,
- BorderStyle = LineStyle.Single
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- }
- [Fact]
- public void Border_TopLeftResizable_CombinesBothFlags ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.TopResizable | ViewArrangement.LeftResizable,
- BorderStyle = LineStyle.Single
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- }
- #endregion
- #region Overlapped Layout Tests
- [Theory]
- [InlineData (ViewArrangement.Fixed)]
- [InlineData (ViewArrangement.Overlapped)]
- public void MoveSubViewToEnd_ViewArrangement (ViewArrangement arrangement)
- {
- View superView = new () { Arrangement = arrangement };
- var subview1 = new View { Id = "subview1" };
- var subview2 = new View { Id = "subview2" };
- var subview3 = new View { Id = "subview3" };
- superView.Add (subview1, subview2, subview3);
- superView.MoveSubViewToEnd (subview1);
- Assert.Equal ([subview2, subview3, subview1], superView.SubViews.ToArray ());
- superView.MoveSubViewToEnd (subview2);
- Assert.Equal ([subview3, subview1, subview2], superView.SubViews.ToArray ());
- superView.MoveSubViewToEnd (subview3);
- Assert.Equal ([subview1, subview2, subview3], superView.SubViews.ToArray ());
- }
- [Fact]
- public void Overlapped_AllowsSubViewsToOverlap ()
- {
- var superView = new View
- {
- Arrangement = ViewArrangement.Overlapped,
- Width = 20,
- Height = 20
- };
- var view1 = new View { X = 0, Y = 0, Width = 10, Height = 10 };
- var view2 = new View { X = 5, Y = 5, Width = 10, Height = 10 };
- superView.Add (view1, view2);
- // Both views can exist at overlapping positions
- Assert.Equal (2, superView.SubViews.Count);
- Assert.True (view1.Frame.IntersectsWith (view2.Frame));
- }
- #endregion
- #region Splitter Pattern Tests
- [Fact]
- public void LeftResizable_CanBeUsedForHorizontalSplitter ()
- {
- var container = new View { Width = 80, Height = 25 };
- var leftPane = new View
- {
- X = 0,
- Y = 0,
- Width = 40,
- Height = Dim.Fill ()
- };
- var rightPane = new View
- {
- X = 40,
- Y = 0,
- Width = Dim.Fill (),
- Height = Dim.Fill (),
- Arrangement = ViewArrangement.LeftResizable,
- BorderStyle = LineStyle.Single
- };
- container.Add (leftPane, rightPane);
- Assert.True (rightPane.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.NotNull (rightPane.Border);
- }
- [Fact]
- public void TopResizable_CanBeUsedForVerticalSplitter ()
- {
- var container = new View { Width = 80, Height = 25 };
- var topPane = new View
- {
- X = 0,
- Y = 0,
- Width = Dim.Fill (),
- Height = 10
- };
- var bottomPane = new View
- {
- X = 0,
- Y = 10,
- Width = Dim.Fill (),
- Height = Dim.Fill (),
- Arrangement = ViewArrangement.TopResizable,
- BorderStyle = LineStyle.Single
- };
- container.Add (topPane, bottomPane);
- Assert.True (bottomPane.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.NotNull (bottomPane.Border);
- }
- #endregion
- #region View Without Border Tests
- [Fact]
- public void View_WithoutBorderStyle_CanHaveArrangement ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Movable
- };
- // Arrangement can be set even without a border style
- // Border object still exists but has no visible style
- Assert.Equal (ViewArrangement.Movable, view.Arrangement);
- Assert.NotNull (view.Border);
- Assert.Equal (LineStyle.None, view.BorderStyle);
- }
- [Fact]
- public void View_WithNoBorderStyle_ResizableCanBeSet ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Resizable
- };
- // Arrangement is set but has limited effect without a visible border style
- Assert.Equal (ViewArrangement.Resizable, view.Arrangement);
- Assert.NotNull (view.Border);
- Assert.Equal (LineStyle.None, view.BorderStyle);
- }
- #endregion
- #region Integration Tests - Border DetermineArrangeModeFromClick Behavior
- [Fact]
- public void DetermineArrangeModeFromClick_TopResizableIgnoredWhenMovable ()
- {
- // This test verifies the documented behavior that TopResizable is ignored
- // when Movable is also set (line 569 in Border.Arrangment.cs)
- var superView = new View { Width = 80, Height = 25 };
- var view = new View
- {
- Arrangement = ViewArrangement.TopResizable | ViewArrangement.Movable,
- BorderStyle = LineStyle.Single,
- X = 10,
- Y = 10,
- Width = 20,
- Height = 10
- };
- superView.Add (view);
- // The view has both flags set
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Movable));
- // But Movable takes precedence in Border.DetermineArrangeModeFromClick
- // This is verified by the code at line 569 checking !Parent!.Arrangement.HasFlag(ViewArrangement.Movable)
- }
- [Fact]
- public void DetermineArrangeModeFromClick_TopResizableWorksWithoutMovable ()
- {
- var superView = new View { Width = 80, Height = 25 };
- var view = new View
- {
- Arrangement = ViewArrangement.TopResizable,
- BorderStyle = LineStyle.Single,
- X = 10,
- Y = 10,
- Width = 20,
- Height = 10
- };
- superView.Add (view);
- // Only TopResizable is set
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.Movable));
- }
- [Fact]
- public void DetermineArrangeModeFromClick_AllCornerCombinationsSupported ()
- {
- var superView = new View { Width = 80, Height = 25 };
- // Test that all 4 corner combinations are recognized
- var cornerCombinations = new []
- {
- ViewArrangement.BottomResizable | ViewArrangement.RightResizable,
- ViewArrangement.BottomResizable | ViewArrangement.LeftResizable,
- ViewArrangement.TopResizable | ViewArrangement.RightResizable,
- ViewArrangement.TopResizable | ViewArrangement.LeftResizable
- };
- foreach (var arrangement in cornerCombinations)
- {
- var view = new View
- {
- Arrangement = arrangement,
- BorderStyle = LineStyle.Single,
- X = 10,
- Y = 10,
- Width = 20,
- Height = 10
- };
- superView.Add (view);
- // Verify the flags are set correctly
- Assert.True (view.Arrangement == arrangement);
- superView.Remove (view);
- }
- }
- #endregion
- #region ViewArrangement Property Change Tests
- [Fact]
- public void View_Arrangement_CanBeChangedAfterCreation ()
- {
- var view = new View { Arrangement = ViewArrangement.Fixed };
- Assert.Equal (ViewArrangement.Fixed, view.Arrangement);
- view.Arrangement = ViewArrangement.Movable;
- Assert.Equal (ViewArrangement.Movable, view.Arrangement);
- view.Arrangement = ViewArrangement.Resizable;
- Assert.Equal (ViewArrangement.Resizable, view.Arrangement);
- }
- [Fact]
- public void View_Arrangement_CanAddFlags ()
- {
- var view = new View { Arrangement = ViewArrangement.Movable };
- view.Arrangement |= ViewArrangement.LeftResizable;
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- }
- [Fact]
- public void View_Arrangement_CanRemoveFlags ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable
- };
- view.Arrangement &= ~ViewArrangement.Movable;
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Resizable));
- }
- #endregion
- #region Multiple SubViews Arrangement Tests
- [Fact]
- public void SuperView_CanHaveMultipleArrangeableSubViews ()
- {
- var superView = new View
- {
- Arrangement = ViewArrangement.Overlapped,
- Width = 80,
- Height = 25
- };
- var movableView = new View
- {
- Arrangement = ViewArrangement.Movable,
- BorderStyle = LineStyle.Single,
- X = 0,
- Y = 0,
- Width = 20,
- Height = 10
- };
- var resizableView = new View
- {
- Arrangement = ViewArrangement.Resizable,
- BorderStyle = LineStyle.Single,
- X = 25,
- Y = 0,
- Width = 20,
- Height = 10
- };
- var fixedView = new View
- {
- Arrangement = ViewArrangement.Fixed,
- BorderStyle = LineStyle.Single,
- X = 50,
- Y = 0,
- Width = 20,
- Height = 10
- };
- superView.Add (movableView, resizableView, fixedView);
- Assert.Equal (3, superView.SubViews.Count);
- Assert.Equal (ViewArrangement.Movable, movableView.Arrangement);
- Assert.Equal (ViewArrangement.Resizable, resizableView.Arrangement);
- Assert.Equal (ViewArrangement.Fixed, fixedView.Arrangement);
- }
- [Fact]
- public void SubView_ArrangementIndependentOfSuperView ()
- {
- var superView = new View { Arrangement = ViewArrangement.Fixed };
- var subView = new View { Arrangement = ViewArrangement.Movable };
- superView.Add (subView);
- // SubView arrangement is independent of SuperView arrangement
- Assert.Equal (ViewArrangement.Fixed, superView.Arrangement);
- Assert.Equal (ViewArrangement.Movable, subView.Arrangement);
- }
- #endregion
- #region Border Thickness Tests
- [Fact]
- public void Border_WithDefaultThickness_SupportsArrangement ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Movable,
- BorderStyle = LineStyle.Single
- };
- Assert.NotNull (view.Border);
- // Default thickness should be (1,1,1,1) for Single line style
- Assert.True (view.Border.Thickness.Left > 0 || view.Border.Thickness.Right > 0
- || view.Border.Thickness.Top > 0 || view.Border.Thickness.Bottom > 0);
- }
- [Fact]
- public void Border_WithCustomThickness_SupportsArrangement ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.LeftResizable,
- BorderStyle = LineStyle.Single
- };
- // Set custom thickness - only left border
- view.Border!.Thickness = new Thickness (2, 0, 0, 0);
- Assert.Equal (2, view.Border.Thickness.Left);
- Assert.Equal (0, view.Border.Thickness.Top);
- Assert.Equal (0, view.Border.Thickness.Right);
- Assert.Equal (0, view.Border.Thickness.Bottom);
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- }
- #endregion
- #region View-Specific Arrangement Tests
- [Fact]
- public void Runnable_DefaultsToOverlapped ()
- {
- var runnable = new Runnable ();
- Assert.True (runnable.Arrangement.HasFlag (ViewArrangement.Overlapped));
- }
- [Fact]
- public void Window_DefaultsToOverlapped ()
- {
- var window = new Window ();
- Assert.True (window.Arrangement.HasFlag (ViewArrangement.Overlapped));
- }
- [Fact]
- public void Dialog_DefaultsToMovableAndOverlapped ()
- {
- var dialog = new Dialog ();
- Assert.True (dialog.Arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (dialog.Arrangement.HasFlag (ViewArrangement.Overlapped));
- }
- [Fact]
- public void View_Navigation_RespectsOverlappedFlag ()
- {
- // View.Navigation.cs checks Arrangement.HasFlag(ViewArrangement.Overlapped)
- var overlappedView = new View { Arrangement = ViewArrangement.Overlapped };
- var tiledView = new View { Arrangement = ViewArrangement.Fixed };
- Assert.True (overlappedView.Arrangement.HasFlag (ViewArrangement.Overlapped));
- Assert.False (tiledView.Arrangement.HasFlag (ViewArrangement.Overlapped));
- }
- [Fact]
- public void View_Hierarchy_RespectsOverlappedFlag ()
- {
- // View.Hierarchy.cs checks Arrangement.HasFlag(ViewArrangement.Overlapped)
- var parent = new View { Arrangement = ViewArrangement.Overlapped };
- var child1 = new View { X = 0, Y = 0, Width = 10, Height = 10 };
- var child2 = new View { X = 5, Y = 5, Width = 10, Height = 10 };
- parent.Add (child1, child2);
- Assert.True (parent.Arrangement.HasFlag (ViewArrangement.Overlapped));
- Assert.Equal (2, parent.SubViews.Count);
- }
- #endregion
- #region Mouse Interaction Tests
- // Not parallelizable due to Application.Mouse dependency in MouseGrabHandler
- #endregion
- #region Summary and Limitations
- // NOTE: The original concern that Border.OnMouseEvent depends on Application.Mouse
- // has been addressed. The tests above prove that MouseGrabHandler works correctly in
- // parallelizable tests when using NewMouseEvent directly on views.
- //
- // Remaining functionality that still requires Application.Init:
- // 1. Border.EnterArrangeMode() with keyboard mode - depends on Application.ArrangeKey
- // 2. Border.HandleDragOperation() - depends on Application.Top for screen refresh
- // 3. Application-level mouse event routing through Application.RaiseMouseEvent
- //
- // The tests in this file demonstrate:
- // - ViewArrangement enum and flag behavior
- // - View.Arrangement property behavior
- // - Border existence and configuration with arrangements
- // - MouseGrabHandler interaction with arrangeable views
- // - Logical combinations of arrangement flags
- // - Mutual exclusivity rules (TopResizable vs Movable)
- // - Multiple subview scenarios
- //
- // This provides comprehensive coverage of arrangement functionality using
- // parallelizable tests with NewMouseEvent.
- [Fact]
- public void AllArrangementTests_AreParallelizable ()
- {
- // This test verifies that all the arrangement tests in this file
- // can run without Application.Init, making them parallelizable.
- // If this test passes, it confirms no Application dependencies leaked in.
- var view = new View
- {
- Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable,
- BorderStyle = LineStyle.Single
- };
- Assert.NotNull (view);
- Assert.NotNull (view.Border);
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Resizable));
- }
- #endregion
- #region ViewArrangement Advanced Flag Tests
- [Fact]
- public void ViewArrangement_CanCombineAllResizableDirections ()
- {
- ViewArrangement arrangement = ViewArrangement.TopResizable
- | ViewArrangement.BottomResizable
- | ViewArrangement.LeftResizable
- | ViewArrangement.RightResizable;
- Assert.True (arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (arrangement.HasFlag (ViewArrangement.BottomResizable));
- Assert.True (arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.True (arrangement.HasFlag (ViewArrangement.RightResizable));
- Assert.True (arrangement.HasFlag (ViewArrangement.Resizable)); // Resizable is all four combined
- }
- [Fact]
- public void ViewArrangement_MovableAndResizable_CanCoexist ()
- {
- ViewArrangement arrangement = ViewArrangement.Movable | ViewArrangement.Resizable;
- Assert.True (arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (arrangement.HasFlag (ViewArrangement.Resizable));
- Assert.True (arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (arrangement.HasFlag (ViewArrangement.BottomResizable));
- Assert.True (arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.True (arrangement.HasFlag (ViewArrangement.RightResizable));
- }
- [Fact]
- public void ViewArrangement_OverlappedWithMovableAndResizable_AllFlagsWork ()
- {
- ViewArrangement arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable | ViewArrangement.Resizable;
- Assert.True (arrangement.HasFlag (ViewArrangement.Overlapped));
- Assert.True (arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (arrangement.HasFlag (ViewArrangement.Resizable));
- }
- [Fact]
- public void View_Arrangement_CanBeSetToCompositeFlagValue ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable | ViewArrangement.Overlapped
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Movable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Resizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.Overlapped));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- }
- #endregion
- #region View Arrangement Edge Cases
- [Fact]
- public void View_ArrangementWithNoBorder_CanStillHaveArrangementValue ()
- {
- // A view can have Arrangement set even if BorderStyle is None
- var view = new View
- {
- Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable,
- BorderStyle = LineStyle.None
- };
- // Border exists but has no visible style
- Assert.NotNull (view.Border);
- Assert.Equal (LineStyle.None, view.BorderStyle);
- Assert.Equal (ViewArrangement.Movable | ViewArrangement.Resizable, view.Arrangement);
- }
- [Fact]
- public void View_ChangingBorderStyle_PreservesArrangement ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Movable,
- BorderStyle = LineStyle.Single
- };
- Assert.NotNull (view.Border);
- Assert.Equal (ViewArrangement.Movable, view.Arrangement);
- // Change border style
- view.BorderStyle = LineStyle.Double;
- Assert.NotNull (view.Border);
- Assert.Equal (ViewArrangement.Movable, view.Arrangement);
- }
- [Fact]
- public void View_ChangingToNoBorderStyle_PreservesArrangement ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.Movable,
- BorderStyle = LineStyle.Single
- };
- Assert.NotNull (view.Border);
- Assert.Equal (LineStyle.Single, view.BorderStyle);
- // Change to no border style
- view.BorderStyle = LineStyle.None;
- // Border still exists but has no visible style
- Assert.NotNull (view.Border);
- Assert.Equal (LineStyle.None, view.BorderStyle);
- Assert.Equal (ViewArrangement.Movable, view.Arrangement); // Arrangement value is preserved
- }
- [Fact]
- public void View_MultipleSubviewsWithDifferentArrangements_EachIndependent ()
- {
- var container = new View ();
- var fixedView = new View { Id = "fixed", Arrangement = ViewArrangement.Fixed };
- var movableView = new View { Id = "movable", Arrangement = ViewArrangement.Movable };
- var resizableView = new View { Id = "resizable", Arrangement = ViewArrangement.Resizable };
- var overlappedView = new View { Id = "overlapped", Arrangement = ViewArrangement.Overlapped };
- container.Add (fixedView, movableView, resizableView, overlappedView);
- Assert.Equal (ViewArrangement.Fixed, fixedView.Arrangement);
- Assert.Equal (ViewArrangement.Movable, movableView.Arrangement);
- Assert.Equal (ViewArrangement.Resizable, resizableView.Arrangement);
- Assert.Equal (ViewArrangement.Overlapped, overlappedView.Arrangement);
- }
- #endregion
- #region Overlapped Layout Advanced Tests
- [Fact]
- public void Overlapped_ViewCanBeMovedToFront ()
- {
- var container = new View { Arrangement = ViewArrangement.Overlapped };
- var view1 = new View { Id = "view1" };
- var view2 = new View { Id = "view2" };
- var view3 = new View { Id = "view3" };
- container.Add (view1, view2, view3);
- // Initially view3 is on top (last added)
- Assert.Equal (view3, container.SubViews.ToArray () [^1]);
- // Move view1 to end (top of Z-order)
- container.MoveSubViewToEnd (view1);
- Assert.Equal (view1, container.SubViews.ToArray () [^1]);
- Assert.Equal ([view2, view3, view1], container.SubViews.ToArray ());
- }
- [Fact]
- public void Overlapped_ViewCanBeMovedToBack ()
- {
- var container = new View { Arrangement = ViewArrangement.Overlapped };
- var view1 = new View { Id = "view1" };
- var view2 = new View { Id = "view2" };
- var view3 = new View { Id = "view3" };
- container.Add (view1, view2, view3);
- // Initial order: [view1, view2, view3]
- Assert.Equal ([view1, view2, view3], container.SubViews.ToArray ());
- // Move view3 to end (top of Z-order)
- container.MoveSubViewToEnd (view3);
- Assert.Equal (view3, container.SubViews.ToArray () [^1]);
- Assert.Equal ([view1, view2, view3], container.SubViews.ToArray ());
- // Now move view1 to end (making it on top, pushing view3 down)
- container.MoveSubViewToEnd (view1);
- Assert.Equal ([view2, view3, view1], container.SubViews.ToArray ());
- }
- [Fact]
- public void Fixed_ViewAddOrderMattersForLayout ()
- {
- var container = new View { Arrangement = ViewArrangement.Fixed };
- var view1 = new View { Id = "view1", X = 0, Y = 0, Width = 10, Height = 5 };
- var view2 = new View { Id = "view2", X = 5, Y = 2, Width = 10, Height = 5 };
- container.Add (view1, view2);
- // In Fixed arrangement, views don't overlap in the same way
- // The order determines paint/draw order but not logical overlap
- Assert.Equal (view1, container.SubViews.ToArray () [0]);
- Assert.Equal (view2, container.SubViews.ToArray () [1]);
- }
- #endregion
- #region Resizable Edge Cases
- [Fact]
- public void Border_OnlyLeftResizable_OtherDirectionsNotResizable ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.LeftResizable,
- BorderStyle = LineStyle.Single
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- }
- [Fact]
- public void Border_TwoOppositeDirections_CanBeResizable ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.LeftResizable | ViewArrangement.RightResizable,
- BorderStyle = LineStyle.Single
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- }
- [Fact]
- public void Border_ThreeDirections_CanBeResizable ()
- {
- var view = new View
- {
- Arrangement = ViewArrangement.LeftResizable | ViewArrangement.RightResizable | ViewArrangement.BottomResizable,
- BorderStyle = LineStyle.Single
- };
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.LeftResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.RightResizable));
- Assert.False (view.Arrangement.HasFlag (ViewArrangement.TopResizable));
- Assert.True (view.Arrangement.HasFlag (ViewArrangement.BottomResizable));
- }
- #endregion
- }
|