| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- using System.Text;
- using UnitTests;
- using Xunit.Abstractions;
- namespace ViewBaseTests.Drawing;
- public class ViewDrawTextAndLineCanvasTests () : FakeDriverBase
- {
- #region DrawText Tests
- [Fact]
- public void DrawText_EmptyText_DoesNotThrow ()
- {
- 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,
- Text = ""
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- var exception = Record.Exception (() => view.Draw ());
- Assert.Null (exception);
- }
- [Fact]
- public void DrawText_NullText_DoesNotThrow ()
- {
- 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,
- Text = null!
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- var exception = Record.Exception (() => view.Draw ());
- Assert.Null (exception);
- }
- [Fact]
- public void DrawText_DrawsTextToDriver ()
- {
- 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,
- Text = "Test"
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- view.Draw ();
- // Text should appear at the content location
- Point screenPos = view.ContentToScreen (Point.Empty);
- Assert.Equal ("T", driver.Contents! [screenPos.Y, screenPos.X].Grapheme);
- Assert.Equal ("e", driver.Contents [screenPos.Y, screenPos.X + 1].Grapheme);
- Assert.Equal ("s", driver.Contents [screenPos.Y, screenPos.X + 2].Grapheme);
- Assert.Equal ("t", driver.Contents [screenPos.Y, screenPos.X + 3].Grapheme);
- }
- [Fact]
- public void DrawText_WithFocus_UsesFocusAttribute ()
- {
- 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,
- Text = "Test",
- CanFocus = true
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- view.SetFocus ();
- view.Draw ();
- // Text should use focus attribute
- Point screenPos = view.ContentToScreen (Point.Empty);
- Attribute expectedAttr = view.GetAttributeForRole (VisualRole.Focus);
- Assert.Equal (expectedAttr, driver.Contents! [screenPos.Y, screenPos.X].Attribute);
- }
- [Fact]
- public void DrawText_WithoutFocus_UsesNormalAttribute ()
- {
- 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,
- Text = "Test",
- CanFocus = true
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- view.Draw ();
- // Text should use normal attribute
- Point screenPos = view.ContentToScreen (Point.Empty);
- Attribute expectedAttr = view.GetAttributeForRole (VisualRole.Normal);
- Assert.Equal (expectedAttr, driver.Contents! [screenPos.Y, screenPos.X].Attribute);
- }
- [Fact]
- public void DrawText_SetsSubViewNeedsDraw ()
- {
- 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,
- Text = "Test"
- };
- var child = new View { X = 0, Y = 0, Width = 10, Height = 10 };
- view.Add (child);
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // Clear SubViewNeedsDraw
- view.Draw ();
- Assert.False (view.SubViewNeedsDraw);
- // Call DrawText directly which should set SubViewNeedsDraw
- view.DrawText ();
- // SubViews need to be redrawn since text was drawn over them
- Assert.True (view.SubViewNeedsDraw);
- }
- [Fact]
- public void DrawingText_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,
- Text = "Test"
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- view.DrawingText += (s, e) => eventRaised = true;
- view.Draw ();
- Assert.True (eventRaised);
- }
- #endregion
- #region LineCanvas Tests
- [Fact]
- public void LineCanvas_InitiallyEmpty ()
- {
- var view = new View ();
- Assert.NotNull (view.LineCanvas);
- Assert.Equal (Rectangle.Empty, view.LineCanvas.Bounds);
- }
- [Fact]
- public void RenderLineCanvas_DrawsLines ()
- {
- 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 ();
- // Add a line to the canvas
- Point screenPos = new Point (15, 15);
- view.LineCanvas.AddLine (screenPos, 5, Orientation.Horizontal, LineStyle.Single);
- view.RenderLineCanvas ();
- // Verify the line was drawn (check for horizontal line character)
- for (int i = 0; i < 5; i++)
- {
- Assert.NotEqual (" ", driver.Contents! [screenPos.Y, screenPos.X + i].Grapheme);
- }
- }
- [Fact]
- public void RenderLineCanvas_ClearsAfterRendering ()
- {
- 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 ();
- // Add a line to the canvas
- view.LineCanvas.AddLine (new Point (15, 15), 5, Orientation.Horizontal, LineStyle.Single);
- Assert.NotEqual (Rectangle.Empty, view.LineCanvas.Bounds);
- view.RenderLineCanvas ();
- // LineCanvas should be cleared after rendering
- Assert.Equal (Rectangle.Empty, view.LineCanvas.Bounds);
- }
- [Fact]
- public void RenderLineCanvas_WithSuperViewRendersLineCanvas_DoesNotClear ()
- {
- 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,
- SuperViewRendersLineCanvas = true
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // Add a line to the canvas
- view.LineCanvas.AddLine (new Point (15, 15), 5, Orientation.Horizontal, LineStyle.Single);
- Rectangle boundsBefore = view.LineCanvas.Bounds;
- view.RenderLineCanvas ();
- // LineCanvas should NOT be cleared when SuperViewRendersLineCanvas is true
- Assert.Equal (boundsBefore, view.LineCanvas.Bounds);
- }
- [Fact]
- public void SuperViewRendersLineCanvas_MergesWithParentCanvas ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var parent = new View
- {
- X = 10,
- Y = 10,
- Width = 50,
- Height = 50,
- Driver = driver
- };
- var child = new View
- {
- X = 5,
- Y = 5,
- Width = 30,
- Height = 30,
- SuperViewRendersLineCanvas = true
- };
- parent.Add (child);
- parent.BeginInit ();
- parent.EndInit ();
- parent.LayoutSubViews ();
- // Add a line to child's canvas
- child.LineCanvas.AddLine (new Point (20, 20), 5, Orientation.Horizontal, LineStyle.Single);
- Assert.NotEqual (Rectangle.Empty, child.LineCanvas.Bounds);
- Assert.Equal (Rectangle.Empty, parent.LineCanvas.Bounds);
- parent.Draw ();
- // Child's canvas should have been merged into parent's
- // and child's canvas should be cleared
- Assert.Equal (Rectangle.Empty, child.LineCanvas.Bounds);
- }
- [Fact]
- public void OnRenderingLineCanvas_CanPreventRendering ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var view = new TestView
- {
- X = 10,
- Y = 10,
- Width = 20,
- Height = 20,
- Driver = driver,
- PreventRenderLineCanvas = true
- };
- view.BeginInit ();
- view.EndInit ();
- view.LayoutSubViews ();
- // Add a line to the canvas
- Point screenPos = new Point (15, 15);
- view.LineCanvas.AddLine (screenPos, 5, Orientation.Horizontal, LineStyle.Single);
- view.Draw ();
- // When OnRenderingLineCanvas returns true, RenderLineCanvas is not called
- // So the LineCanvas should still have lines (not cleared)
- // BUT because SuperViewRendersLineCanvas is false (default), the LineCanvas
- // gets cleared during the draw cycle anyway. We need to check that the
- // line was NOT actually rendered to the driver.
- bool lineRendered = true;
- for (int i = 0; i < 5; i++)
- {
- if (driver.Contents! [screenPos.Y, screenPos.X + i].Grapheme == " ")
- {
- lineRendered = false;
- break;
- }
- }
- Assert.False (lineRendered);
- }
- #endregion
- #region SuperViewRendersLineCanvas Tests
- [Fact]
- public void SuperViewRendersLineCanvas_DefaultFalse ()
- {
- var view = new View ();
- Assert.False (view.SuperViewRendersLineCanvas);
- }
- [Fact]
- public void SuperViewRendersLineCanvas_CanBeSet ()
- {
- var view = new View { SuperViewRendersLineCanvas = true };
- Assert.True (view.SuperViewRendersLineCanvas);
- }
- [Fact]
- public void Draw_WithSuperViewRendersLineCanvas_SetsNeedsDraw ()
- {
- IDriver driver = CreateFakeDriver (80, 25);
- driver.Clip = new Region (driver.Screen);
- var parent = new View
- {
- X = 10,
- Y = 10,
- Width = 50,
- Height = 50,
- Driver = driver
- };
- var child = new View
- {
- X = 5,
- Y = 5,
- Width = 30,
- Height = 30,
- SuperViewRendersLineCanvas = true
- };
- parent.Add (child);
- parent.BeginInit ();
- parent.EndInit ();
- parent.LayoutSubViews ();
- // Draw once to clear NeedsDraw
- parent.Draw ();
- Assert.False (child.NeedsDraw);
- // Draw again - child with SuperViewRendersLineCanvas should be redrawn
- parent.Draw ();
- // The child should have been set to NeedsDraw during DrawSubViews
- // This is verified by the fact that it was drawn (we can't check NeedsDraw after Draw)
- }
- #endregion
- #region Helper Test View
- private class TestView : View
- {
- public bool PreventRenderLineCanvas { get; set; }
- protected override bool OnRenderingLineCanvas ()
- {
- return PreventRenderLineCanvas || base.OnRenderingLineCanvas ();
- }
- }
- #endregion
- }
|