mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
Merge branch 'v2_develop' into copilot/enable-menubar-replacement
This commit is contained in:
@@ -17,14 +17,14 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Empty_Canvas_ToString_Returns_EmptyString ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
Assert.Equal (string.Empty, canvas.ToString ());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Clear_Removes_All_Lines ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
canvas.AddLine (new (0, 0), 3, Orientation.Vertical, LineStyle.Single);
|
||||
|
||||
@@ -38,7 +38,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Lines_Property_Returns_ReadOnly_Collection ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
Assert.Single (canvas.Lines);
|
||||
@@ -48,7 +48,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void AddLine_Adds_Line_To_Collection ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
Assert.Empty (canvas.Lines);
|
||||
|
||||
canvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
@@ -94,7 +94,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
int expectedHeight
|
||||
)
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (x, y), length, Orientation.Horizontal, LineStyle.Single);
|
||||
canvas.AddLine (new (x, y), length, Orientation.Vertical, LineStyle.Single);
|
||||
|
||||
@@ -119,7 +119,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
int expectedHeight
|
||||
)
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (x, y), length, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
Assert.Equal (new (expectedX, expectedY, expectedWidth, expectedHeight), canvas.Bounds);
|
||||
@@ -128,7 +128,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Bounds_Specific_Coordinates ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (5, 5), 3, Orientation.Horizontal, LineStyle.Single);
|
||||
Assert.Equal (new (5, 5, 3, 1), canvas.Bounds);
|
||||
}
|
||||
@@ -136,14 +136,14 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Bounds_Empty_Canvas_Returns_Empty_Rectangle ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
Assert.Equal (Rectangle.Empty, canvas.Bounds);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Bounds_Single_Point_Zero_Length ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (5, 5), 0, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
Assert.Equal (new (5, 5, 1, 1), canvas.Bounds);
|
||||
@@ -152,7 +152,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Bounds_Horizontal_Line ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (2, 3), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
Assert.Equal (new (2, 3, 5, 1), canvas.Bounds);
|
||||
@@ -161,7 +161,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Bounds_Vertical_Line ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (2, 3), 5, Orientation.Vertical, LineStyle.Single);
|
||||
|
||||
Assert.Equal (new (2, 3, 1, 5), canvas.Bounds);
|
||||
@@ -170,7 +170,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Bounds_Multiple_Lines_Returns_Union ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
canvas.AddLine (new (0, 0), 3, Orientation.Vertical, LineStyle.Single);
|
||||
|
||||
@@ -180,7 +180,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Bounds_Negative_Length_Line ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (5, 5), -3, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
// Line from (5,5) going left 3 positions: includes points 3, 4, 5 (width 3, X starts at 3)
|
||||
@@ -190,7 +190,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Bounds_Complex_Box ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
|
||||
// top
|
||||
canvas.AddLine (new (0, 0), 3, Orientation.Horizontal, LineStyle.Single);
|
||||
@@ -214,7 +214,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void ClearExclusions_Clears_Exclusion_Region ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
var region = new Region (new (0, 0, 2, 1));
|
||||
@@ -229,7 +229,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Exclude_Removes_Points_From_Map ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
var region = new Region (new (0, 0, 2, 1));
|
||||
@@ -260,7 +260,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Fill_Property_Defaults_To_Null ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
Assert.Null (canvas.Fill);
|
||||
}
|
||||
|
||||
@@ -688,7 +688,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Theory]
|
||||
public void Length_0_Is_1_Long (int x, int y, Orientation orientation, string expected)
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
|
||||
// Add a line at 5, 5 that's has length of 1
|
||||
canvas.AddLine (new (x, y), 1, orientation, LineStyle.Single);
|
||||
@@ -741,9 +741,10 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[InlineData (-1, 0, -2, Orientation.Vertical, "│\r\n│")]
|
||||
[InlineData (0, -1, -2, Orientation.Vertical, "│\r\n│")]
|
||||
[InlineData (-1, -1, -2, Orientation.Vertical, "│\r\n│")]
|
||||
[Theory] public void Length_n_Is_n_Long (int x, int y, int length, Orientation orientation, string expected)
|
||||
[Theory]
|
||||
public void Length_n_Is_n_Long (int x, int y, int length, Orientation orientation, string expected)
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new (x, y), length, orientation, LineStyle.Single);
|
||||
|
||||
var result = canvas.ToString ();
|
||||
@@ -755,7 +756,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
{
|
||||
var offset = new Point (5, 5);
|
||||
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (offset, -3, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
var looksLike = "───";
|
||||
@@ -820,7 +821,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void TestLineCanvas_LeaveMargin_Top1_Left1 ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
|
||||
// Upper box
|
||||
canvas.AddLine (Point.Empty, 2, Orientation.Horizontal, LineStyle.Single);
|
||||
@@ -927,7 +928,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Top_Left_From_TopRight_LeftUp ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
|
||||
// Upper box
|
||||
canvas.AddLine (Point.Empty, 2, Orientation.Horizontal, LineStyle.Single);
|
||||
@@ -943,7 +944,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Top_With_1Down ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
|
||||
// Top ─
|
||||
canvas.AddLine (Point.Empty, 1, Orientation.Horizontal, LineStyle.Single);
|
||||
@@ -1328,7 +1329,7 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
[Fact]
|
||||
public void Window ()
|
||||
{
|
||||
var canvas = new LineCanvas ();
|
||||
LineCanvas canvas = new ();
|
||||
|
||||
// Frame
|
||||
canvas.AddLine (Point.Empty, 10, Orientation.Horizontal, LineStyle.Single);
|
||||
@@ -1507,4 +1508,360 @@ public class LineCanvasTests (ITestOutputHelper output) : FakeDriverBase
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
#region GetRegion Tests
|
||||
|
||||
[Fact]
|
||||
public void GetRegion_EmptyCellMap_ReturnsEmptyRegion ()
|
||||
{
|
||||
Dictionary<Point, Cell?> cellMap = new ();
|
||||
Region region = LineCanvas.GetRegion (cellMap);
|
||||
|
||||
Assert.NotNull (region);
|
||||
Assert.True (region.IsEmpty ());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetRegion_SingleCell_ReturnsSingleRectangle ()
|
||||
{
|
||||
Dictionary<Point, Cell?> cellMap = new ()
|
||||
{
|
||||
{ new Point (5, 10), new Cell { Grapheme = "X" } }
|
||||
};
|
||||
|
||||
Region region = LineCanvas.GetRegion (cellMap);
|
||||
|
||||
Assert.NotNull (region);
|
||||
Assert.False (region.IsEmpty ());
|
||||
Assert.True (region.Contains (5, 10));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetRegion_HorizontalLine_CreatesHorizontalSpan ()
|
||||
{
|
||||
Dictionary<Point, Cell?> cellMap = new ();
|
||||
// Horizontal line from (5, 10) to (9, 10)
|
||||
for (int x = 5; x <= 9; x++)
|
||||
{
|
||||
cellMap.Add (new Point (x, 10), new Cell { Grapheme = "─" });
|
||||
}
|
||||
|
||||
Region region = LineCanvas.GetRegion (cellMap);
|
||||
|
||||
Assert.NotNull (region);
|
||||
// All cells in the horizontal span should be in the region
|
||||
for (int x = 5; x <= 9; x++)
|
||||
{
|
||||
Assert.True (region.Contains (x, 10), $"Expected ({x}, 10) to be in region");
|
||||
}
|
||||
// Cells outside the span should not be in the region
|
||||
Assert.False (region.Contains (4, 10));
|
||||
Assert.False (region.Contains (10, 10));
|
||||
Assert.False (region.Contains (7, 9));
|
||||
Assert.False (region.Contains (7, 11));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetRegion_VerticalLine_CreatesMultipleHorizontalSpans ()
|
||||
{
|
||||
Dictionary<Point, Cell?> cellMap = new ();
|
||||
// Vertical line from (5, 10) to (5, 14)
|
||||
for (int y = 10; y <= 14; y++)
|
||||
{
|
||||
cellMap.Add (new Point (5, y), new Cell { Grapheme = "│" });
|
||||
}
|
||||
|
||||
Region region = LineCanvas.GetRegion (cellMap);
|
||||
|
||||
Assert.NotNull (region);
|
||||
// All cells in the vertical line should be in the region
|
||||
for (int y = 10; y <= 14; y++)
|
||||
{
|
||||
Assert.True (region.Contains (5, y), $"Expected (5, {y}) to be in region");
|
||||
}
|
||||
// Cells outside should not be in the region
|
||||
Assert.False (region.Contains (4, 12));
|
||||
Assert.False (region.Contains (6, 12));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetRegion_LShape_CreatesCorrectSpans ()
|
||||
{
|
||||
Dictionary<Point, Cell?> cellMap = new ();
|
||||
// L-shape: horizontal line from (0, 0) to (5, 0), then vertical to (5, 3)
|
||||
for (int x = 0; x <= 5; x++)
|
||||
{
|
||||
cellMap.Add (new Point (x, 0), new Cell { Grapheme = "─" });
|
||||
}
|
||||
for (int y = 1; y <= 3; y++)
|
||||
{
|
||||
cellMap.Add (new Point (5, y), new Cell { Grapheme = "│" });
|
||||
}
|
||||
|
||||
Region region = LineCanvas.GetRegion (cellMap);
|
||||
|
||||
// Horizontal part
|
||||
for (int x = 0; x <= 5; x++)
|
||||
{
|
||||
Assert.True (region.Contains (x, 0), $"Expected ({x}, 0) to be in region");
|
||||
}
|
||||
// Vertical part
|
||||
for (int y = 1; y <= 3; y++)
|
||||
{
|
||||
Assert.True (region.Contains (5, y), $"Expected (5, {y}) to be in region");
|
||||
}
|
||||
// Empty cells should not be in region
|
||||
Assert.False (region.Contains (1, 1));
|
||||
Assert.False (region.Contains (4, 2));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetRegion_DiscontiguousHorizontalCells_CreatesSeparateSpans ()
|
||||
{
|
||||
Dictionary<Point, Cell?> cellMap = new ()
|
||||
{
|
||||
{ new Point (0, 5), new Cell { Grapheme = "X" } },
|
||||
{ new Point (1, 5), new Cell { Grapheme = "X" } },
|
||||
// Gap at (2, 5)
|
||||
{ new Point (3, 5), new Cell { Grapheme = "X" } },
|
||||
{ new Point (4, 5), new Cell { Grapheme = "X" } }
|
||||
};
|
||||
|
||||
Region region = LineCanvas.GetRegion (cellMap);
|
||||
|
||||
Assert.True (region.Contains (0, 5));
|
||||
Assert.True (region.Contains (1, 5));
|
||||
Assert.False (region.Contains (2, 5)); // Gap
|
||||
Assert.True (region.Contains (3, 5));
|
||||
Assert.True (region.Contains (4, 5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetRegion_IntersectingLines_CreatesCorrectRegion ()
|
||||
{
|
||||
Dictionary<Point, Cell?> cellMap = new ();
|
||||
// Horizontal line
|
||||
for (int x = 0; x <= 4; x++)
|
||||
{
|
||||
cellMap.Add (new Point (x, 2), new Cell { Grapheme = "─" });
|
||||
}
|
||||
// Vertical line intersecting at (2, 2)
|
||||
for (int y = 0; y <= 4; y++)
|
||||
{
|
||||
cellMap [new Point (2, y)] = new Cell { Grapheme = "┼" };
|
||||
}
|
||||
|
||||
Region region = LineCanvas.GetRegion (cellMap);
|
||||
|
||||
// Horizontal line
|
||||
for (int x = 0; x <= 4; x++)
|
||||
{
|
||||
Assert.True (region.Contains (x, 2), $"Expected ({x}, 2) to be in region");
|
||||
}
|
||||
// Vertical line
|
||||
for (int y = 0; y <= 4; y++)
|
||||
{
|
||||
Assert.True (region.Contains (2, y), $"Expected (2, {y}) to be in region");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetCellMapWithRegion Tests
|
||||
|
||||
[Fact]
|
||||
public void GetCellMapWithRegion_EmptyCanvas_ReturnsEmptyMapAndRegion ()
|
||||
{
|
||||
LineCanvas canvas = new ();
|
||||
|
||||
(Dictionary<Point, Cell?> cellMap, Region region) = canvas.GetCellMapWithRegion ();
|
||||
|
||||
Assert.NotNull (cellMap);
|
||||
Assert.Empty (cellMap);
|
||||
Assert.NotNull (region);
|
||||
Assert.True (region.IsEmpty ());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCellMapWithRegion_SingleHorizontalLine_ReturnsCellMapAndRegion ()
|
||||
{
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new Point (5, 10), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
(Dictionary<Point, Cell?> cellMap, Region region) = canvas.GetCellMapWithRegion ();
|
||||
|
||||
Assert.NotNull (cellMap);
|
||||
Assert.NotEmpty (cellMap);
|
||||
Assert.NotNull (region);
|
||||
Assert.False (region.IsEmpty ());
|
||||
|
||||
// Both cellMap and region should contain the same cells
|
||||
foreach (Point p in cellMap.Keys)
|
||||
{
|
||||
Assert.True (region.Contains (p.X, p.Y), $"Expected ({p.X}, {p.Y}) to be in region");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCellMapWithRegion_SingleVerticalLine_ReturnsCellMapAndRegion ()
|
||||
{
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new Point (5, 10), 5, Orientation.Vertical, LineStyle.Single);
|
||||
|
||||
(Dictionary<Point, Cell?> cellMap, Region region) = canvas.GetCellMapWithRegion ();
|
||||
|
||||
Assert.NotNull (cellMap);
|
||||
Assert.NotEmpty (cellMap);
|
||||
Assert.NotNull (region);
|
||||
Assert.False (region.IsEmpty ());
|
||||
|
||||
// Both cellMap and region should contain the same cells
|
||||
foreach (Point p in cellMap.Keys)
|
||||
{
|
||||
Assert.True (region.Contains (p.X, p.Y), $"Expected ({p.X}, {p.Y}) to be in region");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCellMapWithRegion_IntersectingLines_CorrectlyHandlesIntersection ()
|
||||
{
|
||||
LineCanvas canvas = new ();
|
||||
// Create a cross pattern
|
||||
canvas.AddLine (new Point (0, 2), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
canvas.AddLine (new Point (2, 0), 5, Orientation.Vertical, LineStyle.Single);
|
||||
|
||||
(Dictionary<Point, Cell?> cellMap, Region region) = canvas.GetCellMapWithRegion ();
|
||||
|
||||
Assert.NotNull (cellMap);
|
||||
Assert.NotEmpty (cellMap);
|
||||
Assert.NotNull (region);
|
||||
|
||||
// Verify intersection point is in both
|
||||
Assert.True (cellMap.ContainsKey (new Point (2, 2)), "Intersection should be in cellMap");
|
||||
Assert.True (region.Contains (2, 2), "Intersection should be in region");
|
||||
|
||||
// All cells should be in both structures
|
||||
foreach (Point p in cellMap.Keys)
|
||||
{
|
||||
Assert.True (region.Contains (p.X, p.Y), $"Expected ({p.X}, {p.Y}) to be in region");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCellMapWithRegion_ComplexShape_RegionMatchesCellMap ()
|
||||
{
|
||||
LineCanvas canvas = new ();
|
||||
// Create a box
|
||||
canvas.AddLine (new Point (0, 0), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
canvas.AddLine (new Point (0, 3), 5, Orientation.Horizontal, LineStyle.Single);
|
||||
canvas.AddLine (new Point (0, 0), 4, Orientation.Vertical, LineStyle.Single);
|
||||
canvas.AddLine (new Point (4, 0), 4, Orientation.Vertical, LineStyle.Single);
|
||||
|
||||
(Dictionary<Point, Cell?> cellMap, Region region) = canvas.GetCellMapWithRegion ();
|
||||
|
||||
Assert.NotNull (cellMap);
|
||||
Assert.NotEmpty (cellMap);
|
||||
Assert.NotNull (region);
|
||||
|
||||
// Every cell in the map should be in the region
|
||||
foreach (Point p in cellMap.Keys)
|
||||
{
|
||||
Assert.True (region.Contains (p.X, p.Y), $"Expected ({p.X}, {p.Y}) to be in region");
|
||||
}
|
||||
|
||||
// Cells not in the map should not be in the region (interior of box)
|
||||
Assert.False (cellMap.ContainsKey (new Point (2, 1)));
|
||||
// Note: Region might contain interior if it's filled, so we just verify consistency
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCellMapWithRegion_ResultsMatchSeparateCalls ()
|
||||
{
|
||||
LineCanvas canvas = new ();
|
||||
// Create a complex pattern
|
||||
canvas.AddLine (new Point (0, 0), 10, Orientation.Horizontal, LineStyle.Single);
|
||||
canvas.AddLine (new Point (5, 0), 10, Orientation.Vertical, LineStyle.Single);
|
||||
canvas.AddLine (new Point (0, 5), 10, Orientation.Horizontal, LineStyle.Double);
|
||||
|
||||
// Get results from combined method
|
||||
(Dictionary<Point, Cell?> combinedCellMap, Region combinedRegion) = canvas.GetCellMapWithRegion ();
|
||||
|
||||
// Get results from separate calls
|
||||
Dictionary<Point, Cell?> separateCellMap = canvas.GetCellMap ();
|
||||
Region separateRegion = LineCanvas.GetRegion (separateCellMap);
|
||||
|
||||
// Cell maps should be identical
|
||||
Assert.Equal (separateCellMap.Count, combinedCellMap.Count);
|
||||
foreach (KeyValuePair<Point, Cell?> kvp in separateCellMap)
|
||||
{
|
||||
Assert.True (combinedCellMap.ContainsKey (kvp.Key), $"Combined map missing key {kvp.Key}");
|
||||
}
|
||||
|
||||
// Regions should contain the same points
|
||||
foreach (Point p in combinedCellMap.Keys)
|
||||
{
|
||||
Assert.True (combinedRegion.Contains (p.X, p.Y), $"Combined region missing ({p.X}, {p.Y})");
|
||||
Assert.True (separateRegion.Contains (p.X, p.Y), $"Separate region missing ({p.X}, {p.Y})");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCellMapWithRegion_NegativeCoordinates_HandlesCorrectly ()
|
||||
{
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new Point (-5, -5), 10, Orientation.Horizontal, LineStyle.Single);
|
||||
canvas.AddLine (new Point (0, -5), 10, Orientation.Vertical, LineStyle.Single);
|
||||
|
||||
(Dictionary<Point, Cell?> cellMap, Region region) = canvas.GetCellMapWithRegion ();
|
||||
|
||||
Assert.NotNull (cellMap);
|
||||
Assert.NotEmpty (cellMap);
|
||||
Assert.NotNull (region);
|
||||
|
||||
// Verify negative coordinates are handled
|
||||
Assert.True (cellMap.Keys.Any (p => p.X < 0 || p.Y < 0), "Should have negative coordinates");
|
||||
|
||||
// All cells should be in region
|
||||
foreach (Point p in cellMap.Keys)
|
||||
{
|
||||
Assert.True (region.Contains (p.X, p.Y), $"Expected ({p.X}, {p.Y}) to be in region");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetCellMapWithRegion_WithExclusion_RegionExcludesExcludedCells ()
|
||||
{
|
||||
LineCanvas canvas = new ();
|
||||
canvas.AddLine (new Point (0, 0), 10, Orientation.Horizontal, LineStyle.Single);
|
||||
|
||||
// Exclude middle section
|
||||
Region exclusionRegion = new ();
|
||||
exclusionRegion.Combine (new Rectangle (3, 0, 4, 1), RegionOp.Union);
|
||||
canvas.Exclude (exclusionRegion);
|
||||
|
||||
(Dictionary<Point, Cell?> cellMap, Region region) = canvas.GetCellMapWithRegion ();
|
||||
|
||||
Assert.NotNull (cellMap);
|
||||
Assert.NotEmpty (cellMap);
|
||||
|
||||
// Excluded cells should not be in cellMap
|
||||
for (int x = 3; x < 7; x++)
|
||||
{
|
||||
Assert.False (cellMap.ContainsKey (new Point (x, 0)), $"({x}, 0) should be excluded from cellMap");
|
||||
}
|
||||
|
||||
// Region should match cellMap
|
||||
foreach (Point p in cellMap.Keys)
|
||||
{
|
||||
Assert.True (region.Contains (p.X, p.Y), $"Expected ({p.X}, {p.Y}) to be in region");
|
||||
}
|
||||
|
||||
// Excluded points should not be in region
|
||||
for (int x = 3; x < 7; x++)
|
||||
{
|
||||
Assert.False (region.Contains (x, 0), $"({x}, 0) should be excluded from region");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ public class KeyBindingsTests
|
||||
|
||||
view.HandlingHotKey += (s, e) => hotKeyRaised = true;
|
||||
view.Accepting += (s, e) => acceptRaised = true;
|
||||
view.Selecting += (s, e) => selectRaised = true;
|
||||
view.Activating += (s, e) => selectRaised = true;
|
||||
|
||||
Assert.Equal (KeyCode.T, view.HotKey);
|
||||
Assert.True (app.Keyboard.RaiseKeyDownEvent (Key.T));
|
||||
|
||||
@@ -194,8 +194,8 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
|
||||
|
||||
superView.Add (subView);
|
||||
|
||||
int selectingCount = 0;
|
||||
subView.Selecting += (_, _) => selectingCount++;
|
||||
int activatingCount = 0;
|
||||
subView.Activating += (_, _) => activatingCount++;
|
||||
|
||||
MouseEventArgs mouseEvent = new ()
|
||||
{
|
||||
@@ -207,7 +207,7 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
|
||||
subView.NewMouseEvent (mouseEvent);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (1, selectingCount);
|
||||
Assert.Equal (1, activatingCount);
|
||||
|
||||
subView.Dispose ();
|
||||
superView.Dispose ();
|
||||
@@ -395,7 +395,7 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
|
||||
};
|
||||
|
||||
bool selectingCalled = false;
|
||||
view.Selecting += (_, _) => { selectingCalled = true; };
|
||||
view.Activating += (_, _) => { selectingCalled = true; };
|
||||
|
||||
MouseEventArgs mouseEvent = new ()
|
||||
{
|
||||
@@ -467,8 +467,8 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
|
||||
|
||||
superView.Add (view);
|
||||
|
||||
int selectingCount = 0;
|
||||
view.Selecting += (_, _) => selectingCount++;
|
||||
int activatingCount = 0;
|
||||
view.Activating += (_, _) => activatingCount++;
|
||||
|
||||
MouseEventArgs mouseEvent = new ()
|
||||
{
|
||||
@@ -480,7 +480,7 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
|
||||
view.NewMouseEvent (mouseEvent);
|
||||
|
||||
// Assert
|
||||
Assert.Equal (1, selectingCount);
|
||||
Assert.Equal (1, activatingCount);
|
||||
|
||||
view.Dispose ();
|
||||
superView.Dispose ();
|
||||
|
||||
@@ -3,11 +3,20 @@ using Xunit.Abstractions;
|
||||
|
||||
namespace ViewBaseTests.Mouse;
|
||||
|
||||
|
||||
[Collection ("Global Test Setup")]
|
||||
[Trait ("Category", "Input")]
|
||||
public class MouseTests (ITestOutputHelper output) : TestsAllViews
|
||||
{
|
||||
[Fact]
|
||||
public void Default_MouseBindings ()
|
||||
{
|
||||
var testView = new View ();
|
||||
|
||||
Assert.Contains (MouseFlags.Button1Clicked, testView.MouseBindings.GetAllFromCommands (Command.Activate));
|
||||
// Assert.Contains (MouseFlags.Button1DoubleClicked, testView.MouseBindings.GetAllFromCommands (Command.Accept));
|
||||
|
||||
Assert.Equal (5, testView.MouseBindings.GetBindings ().Count ());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData (false, false, false)]
|
||||
[InlineData (true, false, true)]
|
||||
@@ -39,7 +48,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews
|
||||
[InlineData (false, false, 1)]
|
||||
[InlineData (true, false, 1)]
|
||||
[InlineData (true, true, 1)]
|
||||
public void MouseClick_Raises_Selecting (bool canFocus, bool setFocus, int expectedSelectingCount)
|
||||
public void MouseClick_Raises_Activating (bool canFocus, bool setFocus, int expectedActivatingCount)
|
||||
{
|
||||
var superView = new View { CanFocus = true, Height = 1, Width = 15 };
|
||||
var focusedView = new View { CanFocus = true, Width = 1, Height = 1 };
|
||||
@@ -57,12 +66,12 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews
|
||||
testView.SetFocus ();
|
||||
}
|
||||
|
||||
var selectingCount = 0;
|
||||
testView.Selecting += (sender, args) => selectingCount++;
|
||||
var activatingCount = 0;
|
||||
testView.Activating += (sender, args) => activatingCount++;
|
||||
|
||||
testView.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked });
|
||||
Assert.True (superView.HasFocus);
|
||||
Assert.Equal (expectedSelectingCount, selectingCount);
|
||||
Assert.Equal (expectedActivatingCount, activatingCount);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
||||
@@ -242,11 +242,11 @@ public class ViewCommandTests
|
||||
|
||||
#endregion Accepted tests
|
||||
|
||||
#region OnSelect/Select tests
|
||||
#region OnActivating/Activating tests
|
||||
|
||||
[Theory]
|
||||
[CombinatorialData]
|
||||
public void Select_Command_Raises_SetsFocus (bool canFocus)
|
||||
public void Activate_Command_Raises_SetsFocus (bool canFocus)
|
||||
{
|
||||
var view = new ViewEventTester
|
||||
{
|
||||
@@ -256,76 +256,76 @@ public class ViewCommandTests
|
||||
Assert.Equal (canFocus, view.CanFocus);
|
||||
Assert.False (view.HasFocus);
|
||||
|
||||
view.InvokeCommand (Command.Select);
|
||||
view.InvokeCommand (Command.Activate);
|
||||
|
||||
Assert.Equal (1, view.OnSelectingCount);
|
||||
Assert.Equal (1, view.OnActivatingCount);
|
||||
|
||||
Assert.Equal (1, view.SelectingCount);
|
||||
Assert.Equal (1, view.ActivatingCount);
|
||||
|
||||
Assert.Equal (canFocus, view.HasFocus);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Select_Command_Handle_OnSelecting_NoEvent ()
|
||||
public void Activate_Command_Handle_OnActivating_NoEvent ()
|
||||
{
|
||||
var view = new ViewEventTester ();
|
||||
Assert.False (view.HasFocus);
|
||||
|
||||
view.HandleOnSelecting = true;
|
||||
Assert.True (view.InvokeCommand (Command.Select));
|
||||
view.HandleOnActivating = true;
|
||||
Assert.True (view.InvokeCommand (Command.Activate));
|
||||
|
||||
Assert.Equal (1, view.OnSelectingCount);
|
||||
Assert.Equal (1, view.OnActivatingCount);
|
||||
|
||||
Assert.Equal (0, view.SelectingCount);
|
||||
Assert.Equal (0, view.ActivatingCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Select_Handle_Event_OnSelecting_Returns_True ()
|
||||
public void Activate_Command_Handle_Event_OnActivating_Returns_True ()
|
||||
{
|
||||
var view = new View ();
|
||||
var selectingInvoked = false;
|
||||
var activatingInvoked = false;
|
||||
|
||||
view.Selecting += ViewOnSelect;
|
||||
view.Activating += ViewOnActivating;
|
||||
|
||||
bool? ret = view.InvokeCommand (Command.Select);
|
||||
bool? ret = view.InvokeCommand (Command.Activate);
|
||||
Assert.True (ret);
|
||||
Assert.True (selectingInvoked);
|
||||
Assert.True (activatingInvoked);
|
||||
|
||||
return;
|
||||
|
||||
void ViewOnSelect (object? sender, CommandEventArgs e)
|
||||
void ViewOnActivating (object? sender, CommandEventArgs e)
|
||||
{
|
||||
selectingInvoked = true;
|
||||
activatingInvoked = true;
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Select_Command_Invokes_Selecting_Event ()
|
||||
public void Activate_Command_Invokes_Activating_Event ()
|
||||
{
|
||||
var view = new View ();
|
||||
var selecting = false;
|
||||
var activating = false;
|
||||
|
||||
view.Selecting += ViewOnSelecting;
|
||||
view.Activating += ViewOnActivating;
|
||||
|
||||
view.InvokeCommand (Command.Select);
|
||||
Assert.True (selecting);
|
||||
view.InvokeCommand (Command.Activate);
|
||||
Assert.True (activating);
|
||||
|
||||
return;
|
||||
|
||||
void ViewOnSelecting (object? sender, CommandEventArgs e) { selecting = true; }
|
||||
void ViewOnActivating (object? sender, CommandEventArgs e) { activating = true; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MouseClick_Invokes_Select_Command ()
|
||||
public void MouseClick_Invokes_Activate_Command ()
|
||||
{
|
||||
var view = new ViewEventTester ();
|
||||
view.NewMouseEvent (new () { Flags = MouseFlags.Button1Clicked, Position = Point.Empty, View = view });
|
||||
|
||||
Assert.Equal (1, view.OnSelectingCount);
|
||||
Assert.Equal (1, view.OnActivatingCount);
|
||||
}
|
||||
|
||||
#endregion OnSelect/Select tests
|
||||
#endregion OnActivating/Activating tests
|
||||
|
||||
#region OnHotKey/HotKey tests
|
||||
|
||||
@@ -390,25 +390,25 @@ public class ViewCommandTests
|
||||
Id = "viewEventTester";
|
||||
CanFocus = true;
|
||||
|
||||
Accepting += (s, a) =>
|
||||
Accepting += (_, a) =>
|
||||
{
|
||||
a.Handled = HandleAccepted;
|
||||
AcceptedCount++;
|
||||
};
|
||||
|
||||
HandlingHotKey += (s, a) =>
|
||||
HandlingHotKey += (_, a) =>
|
||||
{
|
||||
a.Handled = HandleHandlingHotKey;
|
||||
HandlingHotKeyCount++;
|
||||
};
|
||||
|
||||
Selecting += (s, a) =>
|
||||
Activating += (_, a) =>
|
||||
{
|
||||
a.Handled = HandleSelecting;
|
||||
SelectingCount++;
|
||||
a.Handled = HandleActivating;
|
||||
ActivatingCount++;
|
||||
};
|
||||
|
||||
CommandNotBound += (s, a) =>
|
||||
CommandNotBound += (_, a) =>
|
||||
{
|
||||
a.Handled = HandleCommandNotBound;
|
||||
CommandNotBoundCount++;
|
||||
@@ -443,18 +443,18 @@ public class ViewCommandTests
|
||||
|
||||
public bool HandleHandlingHotKey { get; set; }
|
||||
|
||||
public int OnSelectingCount { get; set; }
|
||||
public int SelectingCount { get; set; }
|
||||
public bool HandleOnSelecting { get; set; }
|
||||
public bool HandleSelecting { get; set; }
|
||||
public int OnActivatingCount { get; set; }
|
||||
public int ActivatingCount { get; set; }
|
||||
public bool HandleOnActivating { get; set; }
|
||||
public bool HandleActivating { get; set; }
|
||||
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool OnSelecting (CommandEventArgs args)
|
||||
protected override bool OnActivating (CommandEventArgs args)
|
||||
{
|
||||
OnSelectingCount++;
|
||||
OnActivatingCount++;
|
||||
|
||||
return HandleOnSelecting;
|
||||
return HandleOnActivating;
|
||||
}
|
||||
|
||||
public int OnCommandNotBoundCount { get; set; }
|
||||
|
||||
@@ -146,15 +146,15 @@ public class AllViewsTests (ITestOutputHelper output) : TestsAllViews
|
||||
designable.EnableForDesign ();
|
||||
}
|
||||
|
||||
var selectingCount = 0;
|
||||
view.Selecting += (s, e) => selectingCount++;
|
||||
var activatingCount = 0;
|
||||
view.Activating += (s, e) => activatingCount++;
|
||||
|
||||
var acceptedCount = 0;
|
||||
view.Accepting += (s, e) => { acceptedCount++; };
|
||||
|
||||
if (view.InvokeCommand (Command.Select) == true)
|
||||
if (view.InvokeCommand (Command.Activate) == true)
|
||||
{
|
||||
Assert.Equal (1, selectingCount);
|
||||
Assert.Equal (1, activatingCount);
|
||||
Assert.Equal (0, acceptedCount);
|
||||
}
|
||||
view?.Dispose ();
|
||||
@@ -178,15 +178,15 @@ public class AllViewsTests (ITestOutputHelper output) : TestsAllViews
|
||||
designable.EnableForDesign ();
|
||||
}
|
||||
|
||||
var selectingCount = 0;
|
||||
view.Selecting += (s, e) => selectingCount++;
|
||||
var activatingCount = 0;
|
||||
view.Activating += (s, e) => activatingCount++;
|
||||
|
||||
var acceptingCount = 0;
|
||||
view.Accepting += (s, e) => { acceptingCount++; };
|
||||
|
||||
if (view.InvokeCommand (Command.Accept) == true)
|
||||
{
|
||||
Assert.Equal (0, selectingCount);
|
||||
Assert.Equal (0, activatingCount);
|
||||
Assert.Equal (1, acceptingCount);
|
||||
}
|
||||
view?.Dispose ();
|
||||
|
||||
@@ -22,7 +22,7 @@ public class CheckBoxTests ()
|
||||
ckb.CheckedStateChanging += (s, e) => checkedStateChangingCount++;
|
||||
|
||||
var selectCount = 0;
|
||||
ckb.Selecting += (s, e) => selectCount++;
|
||||
ckb.Activating += (s, e) => selectCount++;
|
||||
|
||||
var acceptCount = 0;
|
||||
ckb.Accepting += (s, e) => acceptCount++;
|
||||
@@ -250,7 +250,7 @@ public class CheckBoxTests ()
|
||||
checkBox.CheckedStateChanging += (s, e) => checkedStateChangingCount++;
|
||||
|
||||
var selectCount = 0;
|
||||
checkBox.Selecting += (s, e) => selectCount++;
|
||||
checkBox.Activating += (s, e) => selectCount++;
|
||||
|
||||
var acceptCount = 0;
|
||||
checkBox.Accepting += (s, e) => acceptCount++;
|
||||
@@ -292,7 +292,7 @@ public class CheckBoxTests ()
|
||||
checkBox.CheckedStateChanging += (s, e) => checkedStateChangingCount++;
|
||||
|
||||
var selectCount = 0;
|
||||
checkBox.Selecting += (s, e) => selectCount++;
|
||||
checkBox.Activating += (s, e) => selectCount++;
|
||||
|
||||
var acceptCount = 0;
|
||||
|
||||
|
||||
@@ -484,7 +484,7 @@ public class ShortcutTests
|
||||
};
|
||||
|
||||
var selected = 0;
|
||||
shortcut.Selecting += (s, e) => selected++;
|
||||
shortcut.Activating += (s, e) => selected++;
|
||||
|
||||
app.Keyboard.RaiseKeyDownEvent (key);
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public class TextFieldTests (ITestOutputHelper output) : FakeDriverBase
|
||||
{
|
||||
TextField tf = new ();
|
||||
|
||||
tf.Selecting += (sender, args) => Assert.Fail ("Selected should not be raied.");
|
||||
tf.Activating += (sender, args) => Assert.Fail ("Activating should not be raised.");
|
||||
|
||||
Runnable top = new ();
|
||||
top.Add (tf);
|
||||
@@ -64,15 +64,15 @@ public class TextFieldTests (ITestOutputHelper output) : FakeDriverBase
|
||||
{
|
||||
TextField tf = new ();
|
||||
|
||||
var selectingCount = 0;
|
||||
tf.Selecting += (sender, args) => selectingCount++;
|
||||
var activatingCount = 0;
|
||||
tf.Activating += (sender, args) => activatingCount++;
|
||||
|
||||
Runnable top = new ();
|
||||
top.Add (tf);
|
||||
tf.SetFocus ();
|
||||
top.NewKeyDownEvent (Key.Enter);
|
||||
|
||||
Assert.Equal (0, selectingCount);
|
||||
Assert.Equal (0, activatingCount);
|
||||
|
||||
top.Dispose ();
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
"parallelizeTestCollections": true,
|
||||
"parallelizeAssembly": true,
|
||||
"stopOnFail": false,
|
||||
"maxParallelThreads": "4x"
|
||||
"maxParallelThreads": "default"
|
||||
}
|
||||
Reference in New Issue
Block a user