| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- using System.Text;
- using UnitTests;
- using Xunit.Abstractions;
- namespace UnitTests_Parallelizable.ViewTests;
- public class ViewClearViewportTests () : FakeDriverBase
- {
- [Fact]
- public void ClearViewport_FillsViewportArea ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var view = new View
- {
- X = 1,
- Y = 1,
- Width = 20,
- Height = 20,
- Driver = driver
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // Clear the driver contents first
- driver.FillRect (driver.Screen, new Rune ('X'));
- view.ClearViewport ();
- // The viewport area should be filled with spaces
- Rectangle viewportScreen = view.ViewportToScreen (view.Viewport with { Location = new (0, 0) });
- for (int y = viewportScreen.Y; y < viewportScreen.Y + viewportScreen.Height; y++)
- {
- for (int x = viewportScreen.X; x < viewportScreen.X + viewportScreen.Width; x++)
- {
- Assert.Equal (" ", driver.Contents [y, x].Grapheme);
- }
- }
- }
- [Fact]
- public void ClearViewport_WithClearContentOnly_LimitsToVisibleContent ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var view = new View
- {
- X = 1,
- Y = 1,
- Width = 20,
- Height = 20,
- Driver = driver
- };
- view.SetContentSize (new Size (100, 100)); // Content larger than viewport
- view.ViewportSettings = ViewportSettingsFlags.ClearContentOnly;
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // Clear the driver contents first
- driver.FillRect (driver.Screen, new Rune ('X'));
- view.ClearViewport ();
- // The visible content area should be cleared
- Rectangle visibleContent = view.ViewportToScreen (new Rectangle (new (-view.Viewport.X, -view.Viewport.Y), view.GetContentSize ()));
- Rectangle viewportScreen = view.ViewportToScreen (view.Viewport with { Location = new (0, 0) });
- Rectangle toClear = Rectangle.Intersect (viewportScreen, visibleContent);
- for (int y = toClear.Y; y < toClear.Y + toClear.Height; y++)
- {
- for (int x = toClear.X; x < toClear.X + toClear.Width; x++)
- {
- Assert.Equal (" ", driver.Contents [y, x].Grapheme);
- }
- }
- }
- [Fact]
- public void ClearViewport_NullDriver_DoesNotThrow ()
- {
- var view = new View
- {
- X = 1,
- Y = 1,
- Width = 20,
- Height = 20
- };
- view.BeginInit ();
- view.EndInit ();
- var exception = Record.Exception (() => view.ClearViewport ());
- Assert.Null (exception);
- }
- [Fact]
- public void ClearViewport_SetsNeedsDraw ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var view = new View
- {
- X = 10,
- Y = 10,
- Width = 20,
- Height = 20,
- Driver = driver
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // Clear NeedsDraw first
- view.Draw ();
- Assert.False (view.NeedsDraw);
- view.ClearViewport ();
- Assert.True (view.NeedsDraw);
- }
- [Fact]
- public void ClearViewport_WithTransparentFlag_DoesNotClear ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var view = new View
- {
- X = 1,
- Y = 1,
- Width = 20,
- Height = 20,
- Driver = driver,
- ViewportSettings = ViewportSettingsFlags.Transparent
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // Fill driver with a character
- driver.FillRect (driver.Screen, new Rune ('X'));
- view.Draw ();
- // The viewport area should still have 'X' (not cleared)
- Rectangle viewportScreen = view.ViewportToScreen (view.Viewport with { Location = new (0, 0) });
- for (int y = viewportScreen.Y; y < viewportScreen.Y + viewportScreen.Height; y++)
- {
- for (int x = viewportScreen.X; x < viewportScreen.X + viewportScreen.Width; x++)
- {
- Assert.Equal ("X", driver.Contents [y, x].Grapheme);
- }
- }
- }
- [Fact]
- public void ClearingViewport_Event_Raised ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- bool eventRaised = false;
- Rectangle? receivedRect = null;
- var view = new View
- {
- X = 10,
- Y = 10,
- Width = 20,
- Height = 20,
- Driver = driver
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- view.ClearingViewport += (s, e) =>
- {
- eventRaised = true;
- receivedRect = e.NewViewport;
- };
- view.Draw ();
- Assert.True (eventRaised);
- Assert.NotNull (receivedRect);
- Assert.Equal (view.Viewport, receivedRect);
- }
- [Fact]
- public void ClearedViewport_Event_Raised ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- bool eventRaised = false;
- var view = new View
- {
- X = 10,
- Y = 10,
- Width = 20,
- Height = 20,
- Driver = driver
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- view.ClearedViewport += (s, e) => eventRaised = true;
- view.Draw ();
- Assert.True (eventRaised);
- }
- [Fact]
- public void OnClearingViewport_CanPreventClear ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- bool clearedCalled = false;
- var view = new TestView
- {
- X = 10,
- Y = 10,
- Width = 20,
- Height = 20,
- Driver = driver,
- PreventClear = true
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- view.ClearedViewport += (s, e) => clearedCalled = true;
- view.Draw ();
- Assert.False (clearedCalled);
- }
- [Fact]
- public void ClearViewport_EmptyViewport_DoesNotThrow ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var view = new View
- {
- X = 10,
- Y = 10,
- Width = 1,
- Height = 1,
- Driver = driver
- };
- view.Border!.Thickness = new Thickness (1);
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // With border of 1, viewport should be empty
- Assert.True (view.Viewport.Width == 0 || view.Viewport.Height == 0);
- var exception = Record.Exception (() => view.ClearViewport ());
- Assert.Null (exception);
- }
- [Fact]
- public void ClearViewport_WithScrolledViewport_ClearsCorrectArea ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var view = new View
- {
- X = 1,
- Y = 1,
- Width = 20,
- Height = 20,
- Driver = driver
- };
- view.SetContentSize (new Size (100, 100));
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // Scroll the viewport
- view.Viewport = view.Viewport with { X = 10, Y = 10 };
- // Fill driver with a character
- driver.FillRect (driver.Screen, new Rune ('X'));
- view.ClearViewport ();
- // The viewport area should be cleared (not the scrolled content area)
- Rectangle viewportScreen = view.ViewportToScreen (view.Viewport with { Location = new (0, 0) });
- for (int y = viewportScreen.Y; y < viewportScreen.Y + viewportScreen.Height; y++)
- {
- for (int x = viewportScreen.X; x < viewportScreen.X + viewportScreen.Width; x++)
- {
- Assert.Equal (" ", driver.Contents [y, x].Grapheme);
- }
- }
- }
- [Fact]
- public void ClearViewport_WithClearContentOnly_AndScrolledViewport_ClearsOnlyVisibleContent ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var view = new View
- {
- X = 10,
- Y = 10,
- Width = 20,
- Height = 20,
- Driver = driver
- };
- view.SetContentSize (new Size (15, 15)); // Content smaller than viewport
- view.ViewportSettings = ViewportSettingsFlags.ClearContentOnly;
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // Scroll past the content
- view.Viewport = view.Viewport with { X = 5, Y = 5 };
- // Fill driver with a character
- driver.FillRect (driver.Screen, new Rune ('X'));
- view.ClearViewport ();
- // Only the visible part of the content should be cleared
- Rectangle visibleContent = view.ViewportToScreen (new Rectangle (new (-view.Viewport.X, -view.Viewport.Y), view.GetContentSize ()));
- Rectangle viewportScreen = view.ViewportToScreen (view.Viewport with { Location = new (0, 0) });
- Rectangle toClear = Rectangle.Intersect (viewportScreen, visibleContent);
- if (toClear != Rectangle.Empty)
- {
- for (int y = toClear.Y; y < toClear.Y + toClear.Height; y++)
- {
- for (int x = toClear.X; x < toClear.X + toClear.Width; x++)
- {
- Assert.Equal (" ", driver.Contents[y, x].Grapheme);
- }
- }
- }
- }
- private class TestView : View
- {
- public bool PreventClear { get; set; }
- protected override bool OnClearingViewport ()
- {
- return PreventClear || base.OnClearingViewport ();
- }
- }
- }
|