123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893 |
- namespace Terminal.Gui.DrawingTests;
- public class RegionTests
- {
- [Fact]
- public void Clone_CreatesExactCopy ()
- {
- var region = new Region (new (10, 10, 50, 50));
- Region clone = region.Clone ();
- Assert.True (clone.Contains (20, 20));
- Assert.Equal (region.GetRectangles (), clone.GetRectangles ());
- }
- [Fact]
- public void Combine_EmptyRectangles_ProducesEmptyRegion ()
- {
- // Arrange: Create region and combine with empty rectangles
- var region = new Region ();
- region.Combine (new Rectangle (0, 0, 0, 0), RegionOp.Union); // Empty rectangle
- region.Combine (new Region (), RegionOp.Union); // Empty region
- // Assert: Region is empty
- Assert.Empty (region.GetRectangles ());
- }
- [Fact]
- public void Complement_Rectangle_ComplementsRegion ()
- {
- var region = new Region (new (10, 10, 50, 50));
- region.Complement (new (0, 0, 100, 100));
- Assert.True (region.Contains (5, 5));
- Assert.False (region.Contains (20, 20));
- }
- [Theory]
- [MemberData (nameof (Complement_TestData))]
- public void Complement_Region_Success (Region region, Rectangle [] rectangles, Rectangle [] expectedScans)
- {
- foreach (Rectangle rect in rectangles)
- {
- region.Complement (rect);
- }
- Rectangle [] actualScans = region.GetRectangles ();
- Assert.Equal (expectedScans, actualScans);
- }
- public static IEnumerable<object []> Complement_TestData ()
- {
- yield return new object []
- {
- new Region (new (10, 10, 100, 100)),
- new Rectangle [] { new (40, 60, 100, 20) },
- new Rectangle [] { new (110, 60, 30, 20) }
- };
- yield return new object []
- {
- new Region (new (70, 10, 100, 100)),
- new Rectangle [] { new (40, 60, 100, 20) },
- new Rectangle [] { new (40, 60, 30, 20) }
- };
- yield return new object []
- {
- new Region (new (40, 100, 100, 100)),
- new Rectangle [] { new (70, 80, 50, 40) },
- new Rectangle [] { new (70, 80, 50, 20) }
- };
- yield return new object []
- {
- new Region (new (40, 10, 100, 100)),
- new Rectangle [] { new (70, 80, 50, 40) },
- new Rectangle [] { new (70, 110, 50, 10) }
- };
- yield return new object []
- {
- new Region (new (30, 30, 80, 80)),
- new Rectangle []
- {
- new (45, 45, 200, 200),
- new (160, 260, 10, 10),
- new (170, 260, 10, 10)
- },
- new Rectangle [] { new (170, 260, 10, 10) }
- };
- yield return new object []
- {
- new Region (),
- new [] { Rectangle.Empty },
- new Rectangle[0]
- };
- yield return new object []
- {
- new Region (),
- new Rectangle [] { new (1, 2, 3, 4) },
- new Rectangle[0]
- };
- }
- [Fact]
- public void Complement_WithRectangle_ComplementsRegion ()
- {
- var region = new Region (new (10, 10, 50, 50));
- var rect = new Rectangle (0, 0, 100, 100);
- region.Complement (rect);
- // Points that were inside the original region should now be outside
- Assert.False (region.Contains (35, 35));
- // Points that were outside the original region but inside bounds should now be inside
- Assert.True (region.Contains (5, 5));
- Assert.True (region.Contains (95, 95));
- }
- [Fact]
- public void Complement_WithRegion_ComplementsRegion ()
- {
- var region = new Region (new (10, 10, 50, 50));
- var bounds = new Rectangle (0, 0, 100, 100);
- region.Complement (bounds);
- // Points that were inside the original region should now be outside
- Assert.False (region.Contains (35, 35));
- // Points that were outside the original region but inside bounds should now be inside
- Assert.True (region.Contains (5, 5));
- Assert.True (region.Contains (95, 95));
- }
- [Fact]
- public void Constructor_EmptyRegion_IsEmpty ()
- {
- var region = new Region ();
- Assert.True (region.IsEmpty ());
- }
- [Fact]
- public void Constructor_WithRectangle_IsNotEmpty ()
- {
- var region = new Region (new (10, 10, 50, 50));
- Assert.False (region.IsEmpty ());
- }
- [Fact]
- public void Contains_Point_ReturnsCorrectResult ()
- {
- var region = new Region (new (10, 10, 50, 50));
- Assert.True (region.Contains (20, 20));
- Assert.False (region.Contains (100, 100));
- }
- [Fact]
- public void Contains_PointInsideRegion_ReturnsTrue ()
- {
- var region = new Region (new (10, 10, 50, 50));
- Assert.True (region.Contains (20, 20));
- }
- [Fact]
- public void Contains_RectangleInsideRegion_ReturnsTrue ()
- {
- var region = new Region (new (10, 10, 50, 50));
- Assert.True (region.Contains (new (20, 20, 10, 10)));
- }
- [Fact]
- public void Equals_NullRegion_ReturnsFalse ()
- {
- var region = new Region ();
- Assert.False (region.Equals (null));
- }
- [Fact]
- public void Equals_SameRegion_ReturnsTrue ()
- {
- var region = new Region (new (1, 2, 3, 4));
- Assert.True (region.Equals (region));
- }
- public static IEnumerable<object []> Equals_TestData ()
- {
- static Region Empty ()
- {
- Region emptyRegion = new ();
- emptyRegion.Intersect (Rectangle.Empty);
- return emptyRegion;
- }
- yield return new object [] { new Region (), new Region (), true };
- yield return new object [] { new Region (), Empty (), true };
- yield return new object [] { new Region (), new Region (new (1, 2, 3, 4)), false };
- yield return new object [] { Empty (), Empty (), true };
- yield return new object [] { Empty (), new Region (new (0, 0, 0, 0)), true };
- yield return new object [] { Empty (), new Region (new (1, 2, 3, 3)), false };
- yield return new object [] { new Region (new (1, 2, 3, 4)), new Region (new (1, 2, 3, 4)), true };
- yield return new object [] { new Region (new (1, 2, 3, 4)), new Region (new (2, 2, 3, 4)), false };
- yield return new object [] { new Region (new (1, 2, 3, 4)), new Region (new (1, 3, 3, 4)), false };
- yield return new object [] { new Region (new (1, 2, 3, 4)), new Region (new (1, 2, 4, 4)), false };
- yield return new object [] { new Region (new (1, 2, 3, 4)), new Region (new (1, 2, 3, 5)), false };
- }
- [Theory]
- [MemberData (nameof (Equals_TestData))]
- public void Equals_Valid_ReturnsExpected (Region region1, Region region2, bool expected) { Assert.Equal (expected, region1.Equals (region2)); }
- [Fact]
- public void GetBounds_ReturnsBoundingRectangle ()
- {
- var region = new Region (new (10, 10, 50, 50));
- region.Union (new Rectangle (100, 100, 20, 20));
- Rectangle bounds = region.GetBounds ();
- Assert.Equal (new (10, 10, 110, 110), bounds);
- }
- [Fact]
- public void GetBounds_ReturnsCorrectBounds ()
- {
- var region = new Region ();
- region.Union (new Rectangle (10, 10, 50, 50));
- region.Union (new Rectangle (30, 30, 50, 50));
- Rectangle bounds = region.GetBounds ();
- Assert.Equal (new (10, 10, 70, 70), bounds);
- }
- [Fact]
- public void GetRegionScans_ReturnsAllRectangles ()
- {
- var region = new Region (new (10, 10, 50, 50));
- region.Union (new Rectangle (100, 100, 20, 20));
- Rectangle [] scans = region.GetRectangles ();
- Assert.Equal (2, scans.Length);
- Assert.Contains (new (10, 10, 50, 50), scans);
- Assert.Contains (new (100, 100, 20, 20), scans);
- }
- [Fact]
- public void Intersect_Rectangle_IntersectsRegion ()
- {
- var region = new Region (new (10, 10, 50, 50));
- region.Intersect (new Rectangle (30, 30, 50, 50));
- Assert.False (region.Contains (20, 20));
- Assert.True (region.Contains (40, 40));
- }
- [Fact]
- public void Intersect_Region_IntersectsRegions ()
- {
- var region1 = new Region (new (10, 10, 50, 50));
- var region2 = new Region (new (30, 30, 50, 50));
- region1.Intersect (region2);
- Assert.False (region1.Contains (20, 20));
- Assert.True (region1.Contains (40, 40));
- }
- [Fact]
- public void Intersect_WithEmptyRectangle_ResultsInEmptyRegion ()
- {
- // Arrange
- var region = new Region (new (0, 0, 10, 10));
- var rectangle = Rectangle.Empty; // Use Empty instead of 0-size
- // Act
- region.Intersect (rectangle);
- // Assert
- Assert.True (region.IsEmpty ());
- }
- [Theory]
- [InlineData (0, 0, 0, 0)] // Empty by zero size
- [InlineData (0, 0, 0, 10)] // Empty by zero width
- [InlineData (0, 0, 10, 0)] // Empty by zero height
- [InlineData (-5, -5, 0, 0)] // Empty by zero size at negative coords
- [InlineData (10, 10, -5, -5)] // Empty by negative size
- public void Intersect_WithEmptyRegion_ResultsInEmptyRegion (int x, int y, int width, int height)
- {
- // Arrange
- var region = new Region ();
- region.Union (new Rectangle (0, 0, 10, 10));
- region.Union (new Rectangle (20, 0, 10, 10));
- // Create a region that should be considered empty
- var emptyRegion = new Region ();
- if (width <= 0 || height <= 0)
- {
- // For negative or zero dimensions, use an empty region
- emptyRegion = new ();
- }
- else
- {
- emptyRegion = new (new (x, y, width, height));
- }
- // Verify initial states
- Assert.Equal (2, region.GetRectangles ().Length);
- Assert.True (emptyRegion.IsEmpty ());
- // Act
- region.Intersect (emptyRegion);
- // Assert
- Assert.True (region.IsEmpty ());
- Assert.Empty (region.GetRectangles ());
- }
- [Fact]
- public void Intersect_WithFullyContainedRectangle_ResultsInSmallerRegion ()
- {
- // Arrange
- var region = new Region (new (0, 0, 10, 10));
- var rectangle = new Rectangle (2, 2, 4, 4);
- // Act
- region.Intersect (rectangle);
- // Assert
- Assert.Single (region.GetRectangles ());
- Assert.Equal (new (2, 2, 4, 4), region.GetRectangles () [0]);
- }
- [Fact]
- public void Intersect_WithMultipleRectanglesInRegion_IntersectsAll ()
- {
- // Arrange
- var region = new Region ();
- region.Union (new Rectangle (0, 0, 5, 5));
- region.Union (new Rectangle (10, 0, 5, 5));
- var rectangle = new Rectangle (2, 2, 10, 2);
- // Act
- region.Intersect (rectangle);
- // Assert
- Assert.Equal (2, region.GetRectangles ().Length);
- Assert.Contains (new (2, 2, 3, 2), region.GetRectangles ());
- Assert.Contains (new (10, 2, 2, 2), region.GetRectangles ());
- }
- //[Fact]
- //public void Intersect_WithEmptyRegion_ResultsInEmptyRegion ()
- //{
- // // Arrange
- // var region = new Region ();
- // var rectangle = new Rectangle (0, 0, 10, 10);
- // // Act
- // region.Intersect (rectangle);
- // // Assert
- // Assert.True (region.IsEmpty ());
- //}
- [Fact]
- public void Intersect_WithNonOverlappingRectangle_ResultsInEmptyRegion ()
- {
- // Arrange
- var region = new Region (new (0, 0, 5, 5));
- var rectangle = new Rectangle (10, 10, 5, 5);
- // Act
- region.Intersect (rectangle);
- // Assert
- Assert.True (region.IsEmpty ());
- }
- [Fact]
- public void Intersect_WithNullRegion_ResultsInEmptyRegion ()
- {
- // Arrange
- var region = new Region ();
- region.Union (new Rectangle (0, 0, 10, 10));
- region.Union (new Rectangle (20, 0, 10, 10));
- // Verify initial state
- Assert.Equal (2, region.GetRectangles ().Length);
- // Act
- region.Intersect (null);
- // Assert
- Assert.True (region.IsEmpty ());
- Assert.Empty (region.GetRectangles ());
- }
- [Fact]
- public void Intersect_WithPartiallyOverlappingRectangle_ResultsInIntersectedRegion ()
- {
- // Arrange
- var region = new Region (new (0, 0, 5, 5));
- var rectangle = new Rectangle (2, 2, 5, 5);
- // Act
- region.Intersect (rectangle);
- // Assert
- Assert.Single (region.GetRectangles ());
- Assert.Equal (new (2, 2, 3, 3), region.GetRectangles () [0]);
- }
- [Fact]
- public void Intersect_WithRectangle_IntersectsRectangles ()
- {
- var region = new Region (new (10, 10, 50, 50));
- var rect = new Rectangle (30, 30, 50, 50);
- region.Intersect (rect);
- Assert.True (region.Contains (35, 35));
- Assert.False (region.Contains (20, 20));
- }
- [Fact]
- public void Intersect_WithRegion_IntersectsRegions ()
- {
- var region1 = new Region (new (10, 10, 50, 50));
- var region2 = new Region (new (30, 30, 50, 50));
- region1.Intersect (region2.GetBounds ());
- Assert.True (region1.Contains (35, 35));
- Assert.False (region1.Contains (20, 20));
- }
- [Fact]
- public void Intersect_ImmediateNormalization_AffectsRectangleOrder ()
- {
- // Create a region with two overlapping rectangles
- var region1 = new Region (new (0, 0, 4, 4)); // 0,0 to 4,4
- // Intersect with a region that partially overlaps
- var region2 = new Region (new (2, 2, 4, 4)); // 2,2 to 6,6
- region1.Intersect (region2);
- // Get the resulting rectangles
- Rectangle [] result = region1.GetRectangles ();
- // Expected behavior from original Region:
- // Intersect immediately produces a single rectangle (2,2,2,2)
- Assert.Single (result); // Original has 1 rectangle due to immediate processing
- Assert.Equal (new (2, 2, 2, 2), result [0]);
- // My updated Region defers normalization after Intersect,
- // so GetRectangles() might merge differently or preserve order differently,
- // potentially failing the exact match or count due to _isDirty
- }
- [Fact]
- public void IsEmpty_AfterClear_ReturnsTrue ()
- {
- // Arrange
- var region = new Region (new (0, 0, 10, 10));
- // Act
- region.Intersect (Rectangle.Empty);
- // Assert
- Assert.True (region.IsEmpty ());
- Assert.Empty (region.GetRectangles ());
- }
- [Fact]
- public void IsEmpty_AfterComplement_ReturnsCorrectState ()
- {
- // Test 1: Complement a region with bounds that fully contain it
- var region = new Region (new (2, 2, 5, 5)); // Small inner rectangle
- region.Complement (new (0, 0, 10, 10)); // Larger outer bounds
- Assert.False (region.IsEmpty ()); // Should have area around the original rectangle
- // Test 2: Complement with bounds equal to the region
- region = new (new (0, 0, 10, 10));
- region.Complement (new (0, 0, 10, 10));
- Assert.True (region.IsEmpty ()); // Should be empty as there's no area left
- // Test 3: Complement with empty bounds
- region = new (new (0, 0, 10, 10));
- region.Complement (Rectangle.Empty);
- Assert.True (region.IsEmpty ()); // Should be empty as there's no bounds
- }
- [Fact]
- public void IsEmpty_AfterExclude_ReturnsTrue ()
- {
- // Arrange
- var region = new Region (new (0, 0, 10, 10));
- // Act
- region.Exclude (new Rectangle (0, 0, 10, 10));
- // Assert
- Assert.True (region.IsEmpty ());
- Assert.Empty (region.GetRectangles ());
- }
- [Fact]
- public void IsEmpty_AfterUnion_ReturnsFalse ()
- {
- // Arrange
- var region = new Region ();
- region.Union (new Rectangle (0, 0, 10, 10));
- // Assert
- Assert.False (region.IsEmpty ());
- Assert.Single (region.GetRectangles ());
- }
- [Fact]
- public void IsEmpty_EmptyRegion_ReturnsTrue ()
- {
- var region = new Region ();
- Assert.True (region.IsEmpty ());
- }
- [Fact]
- public void IsEmpty_MultipleOperations_ReturnsExpectedResult ()
- {
- // Arrange
- var region = new Region ();
- // Act & Assert - Should be empty initially
- Assert.True (region.IsEmpty ());
- // Add a rectangle - Should not be empty
- region.Union (new Rectangle (0, 0, 10, 10));
- Assert.False (region.IsEmpty ());
- // Exclude the same rectangle - Should be empty again
- region.Exclude (new Rectangle (0, 0, 10, 10));
- Assert.True (region.IsEmpty ());
- // Add two rectangles - Should not be empty
- region.Union (new Rectangle (0, 0, 5, 5));
- region.Union (new Rectangle (10, 10, 5, 5));
- Assert.False (region.IsEmpty ());
- }
- [Fact]
- public void IsEmpty_NewRegion_ReturnsTrue ()
- {
- // Arrange
- var region = new Region ();
- // Act & Assert
- Assert.True (region.IsEmpty ());
- Assert.Empty (region.GetRectangles ());
- }
- [Fact]
- public void IsEmpty_ReturnsCorrectResult ()
- {
- var region = new Region ();
- Assert.True (region.IsEmpty ());
- region.Union (new Rectangle (10, 10, 50, 50));
- Assert.False (region.IsEmpty ());
- }
- [Theory]
- [InlineData (0, 0, 1, 1)] // 1x1 at origin
- [InlineData (10, 10, 5, 5)] // 5x5 at (10,10)
- [InlineData (-5, -5, 10, 10)] // Negative coordinates
- public void IsEmpty_ValidRectangle_ReturnsFalse (int x, int y, int width, int height)
- {
- // Arrange
- var region = new Region (new (x, y, width, height));
- // Assert
- Assert.False (region.IsEmpty ());
- Assert.Single (region.GetRectangles ());
- }
- [Theory]
- [InlineData (0, 0, 0, 0)] // Zero size
- [InlineData (0, 0, 0, 10)] // Zero width
- [InlineData (0, 0, 10, 0)] // Zero height
- [InlineData (-5, -5, 0, 0)] // Zero size at negative coords
- public void IsEmpty_ZeroSizeRectangle_ReturnsCorrectState (int x, int y, int width, int height)
- {
- var region = new Region (new (x, y, width, height));
- // Only check IsEmpty() since Rectangle(0,0,0,0) is still stored
- Assert.True (region.IsEmpty ());
- }
- //[Fact]
- //public void MinimalUnion_SingleRectangle_DoesNotChange ()
- //{
- // var region = new Region (new Rectangle (0, 0, 10, 10));
- // region.MinimalUnion (new Rectangle (0, 0, 10, 10));
- // Assert.Single (region.GetRectangles ());
- // Assert.Equal (new Rectangle (0, 0, 10, 10), region.GetRectangles ().First ());
- //}
- //[Fact]
- //public void MinimalUnion_OverlappingRectangles_MergesIntoOne ()
- //{
- // var region = new Region (new Rectangle (0, 0, 10, 10));
- // region.MinimalUnion (new Rectangle (5, 0, 10, 10));
- // Assert.Single (region.GetRectangles ());
- // Assert.Equal (new Rectangle (0, 0, 15, 10), region.GetRectangles ().First ());
- //}
- //[Fact]
- //public void MinimalUnion_AdjacentRectangles_MergesIntoOne ()
- //{
- // var region = new Region (new Rectangle (0, 0, 10, 10));
- // region.MinimalUnion (new Rectangle (10, 0, 10, 10));
- // Assert.Single (region.GetRectangles ());
- // Assert.Equal (new Rectangle (0, 0, 20, 10), region.GetRectangles ().First ());
- //}
- //[Fact]
- //public void MinimalUnion_SeparateRectangles_KeepsBoth ()
- //{
- // var region = new Region (new Rectangle (0, 0, 10, 10));
- // region.MinimalUnion (new Rectangle (20, 20, 10, 10));
- // Assert.Equal (2, region.GetRectangles ().Length);
- // Assert.Contains (new Rectangle (0, 0, 10, 10), region.GetRectangles ());
- // Assert.Contains (new Rectangle (20, 20, 10, 10), region.GetRectangles ());
- //}
- //[Fact]
- //public void MinimalUnion_ComplexMerging_ProducesMinimalSet ()
- //{
- // var region = new Region (new Rectangle (0, 0, 10, 10));
- // region.MinimalUnion (new Rectangle (10, 0, 10, 10));
- // region.MinimalUnion (new Rectangle (0, 10, 10, 10));
- // region.MinimalUnion (new Rectangle (10, 10, 10, 10));
- // Assert.Single (region.GetRectangles ());
- // Assert.Equal (new Rectangle (0, 0, 20, 20), region.GetRectangles ().First ());
- //}
- [Fact]
- public void Intersect_ViewportLimitsDrawnRegion ()
- {
- // Arrange: Create regions for viewport and drawn content
- var viewport = new Region (new Rectangle (0, 0, 100, 100)); // Viewport
- var drawnRegion = new Region (new Rectangle (50, 50, 200, 200)); // Larger drawn content
- // Act: Intersect drawn region with viewport
- drawnRegion.Intersect (viewport);
- // Assert: Drawn region should be limited to viewport
- var rectangles = drawnRegion.GetRectangles ();
- Assert.Single (rectangles);
- Assert.Equal (new Rectangle (50, 50, 50, 50), rectangles [0]); // Limited to viewport bounds
- }
- //[Fact]
- //public void MinimalUnion_HorizontalMerge_MergesToSingleRectangle ()
- //{
- // // Arrange: Create a region with a rectangle at (0,0,5,5)
- // var region = new Region (new Rectangle (0, 0, 5, 5));
- // // Act: Merge an adjacent rectangle on the right using MinimalUnion
- // region.MinimalUnion (new Rectangle (5, 0, 5, 5));
- // var result = region.GetRectangles ();
- // // Assert: Expect a single merged rectangle covering (0,0,10,5)
- // Assert.Single (result);
- // Assert.Equal (new Rectangle (0, 0, 10, 5), result [0]);
- //}
- //[Fact]
- //public void MinimalUnion_VerticalMerge_MergesToSingleRectangle ()
- //{
- // // Arrange: Create a region with a rectangle at (0,0,5,5)
- // var region = new Region (new Rectangle (0, 0, 5, 5));
- // // Act: Merge an adjacent rectangle below using MinimalUnion
- // region.MinimalUnion (new Rectangle (0, 5, 5, 5));
- // var result = region.GetRectangles ();
- // // Assert: Expect a single merged rectangle covering (0,0,5,10)
- // Assert.Single (result);
- // Assert.Equal (new Rectangle (0, 0, 5, 10), result [0]);
- //}
- //[Fact]
- //public void MinimalUnion_OverlappingMerge_MergesToSingleRectangle ()
- //{
- // // Arrange: Create a region with a rectangle that overlaps with the next one horizontally
- // var region = new Region (new Rectangle (0, 0, 6, 5));
- // // Act: Merge an overlapping rectangle using MinimalUnion
- // region.MinimalUnion (new Rectangle (4, 0, 6, 5));
- // var result = region.GetRectangles ();
- // // Assert: Expect a single merged rectangle covering (0,0,10,5)
- // Assert.Single (result);
- // Assert.Equal (new Rectangle (0, 0, 10, 5), result [0]);
- //}
- //[Fact]
- //public void MinimalUnion_NonAdjacentRectangles_NoMergeOccurs ()
- //{
- // // Arrange: Create a region with one rectangle
- // var region = new Region (new Rectangle (0, 0, 5, 5));
- // // Act: Merge with a rectangle that does not touch the first
- // region.MinimalUnion (new Rectangle (6, 0, 5, 5));
- // var result = region.GetRectangles ();
- // // Assert: Expect two separate rectangles since they are not adjacent
- // Assert.Equal (2, result.Length);
- // Assert.Contains (new Rectangle (0, 0, 5, 5), result);
- // Assert.Contains (new Rectangle (6, 0, 5, 5), result);
- //}
- //[Fact]
- //public void MinimalUnion_MultipleMerge_FormsSingleContiguousRectangle ()
- //{
- // // Arrange: Four small rectangles that form a contiguous 6x6 block
- // var region = new Region (new Rectangle (0, 0, 3, 3));
- // // Act: Merge adjacent rectangles one by one using MinimalUnion
- // region.MinimalUnion (new Rectangle (3, 0, 3, 3)); // Now covers (0,0,6,3)
- // region.MinimalUnion (new Rectangle (0, 3, 3, 3)); // Add bottom-left
- // region.MinimalUnion (new Rectangle (3, 3, 3, 3)); // Add bottom-right to complete block
- // var result = region.GetRectangles ();
- // // Assert: Expect a single merged rectangle covering (0,0,6,6)
- // Assert.Single (result);
- // Assert.Equal (new Rectangle (0, 0, 6, 6), result [0]);
- //}
- [Fact]
- public void Translate_EmptyRegionAfterEmptyCombine_NoEffect ()
- {
- // Arrange: Create region and combine with empty rectangles
- var region = new Region ();
- region.Combine (new Rectangle (0, 0, 0, 0), RegionOp.Union); // Empty rectangle
- region.Combine (new Region (), RegionOp.Union); // Empty region
- // Act: Translate by (10, 20)
- region.Translate (10, 20);
- // Assert: Still empty
- Assert.Empty (region.GetRectangles ());
- }
- [Fact]
- public void Union_Rectangle_AddsToRegion ()
- {
- var region = new Region ();
- region.Union (new Rectangle (10, 10, 50, 50));
- Assert.False (region.IsEmpty ());
- Assert.True (region.Contains (20, 20));
- }
- [Fact]
- public void Union_Region_MergesRegions ()
- {
- var region1 = new Region (new (10, 10, 50, 50));
- var region2 = new Region (new (30, 30, 50, 50));
- region1.Union (region2);
- Assert.True (region1.Contains (20, 20));
- Assert.True (region1.Contains (40, 40));
- }
- /// <summary>
- /// Proves MergeRegion does not overly combine regions.
- /// </summary>
- [Fact]
- public void Union_Region_MergesRegions_NonOverlapping ()
- {
- // 012345
- // 0+++
- // 1+ +
- // 2+++
- // 3 ***
- // 4 * *
- // 5 ***
- var region1 = new Region (new (0, 0, 3, 3));
- var region2 = new Region (new (3, 3, 3, 3));
- region1.Union (region2);
- // Positive
- Assert.True (region1.Contains (0, 0));
- Assert.True (region1.Contains (1, 1));
- Assert.True (region1.Contains (2, 2));
- Assert.True (region1.Contains (4, 4));
- Assert.True (region1.Contains (5, 5));
- // Negative
- Assert.False (region1.Contains (0, 3));
- Assert.False (region1.Contains (3, 0));
- Assert.False (region1.Contains (6, 6));
- }
- /// <summary>
- /// Proves MergeRegion does not overly combine regions.
- /// </summary>
- [Fact]
- public void Union_Region_MergesRegions_Overlapping ()
- {
- // 01234567
- // 0+++++
- // 1+ +
- // 2+ +
- // 3+ *****
- // 4+++* *
- // 5 * *
- // 6 * *
- // 7 *****
- var region1 = new Region (new (0, 0, 5, 5));
- var region2 = new Region (new (3, 3, 5, 5));
- region1.Union (region2);
- // Positive
- Assert.True (region1.Contains (0, 0));
- Assert.True (region1.Contains (1, 1));
- Assert.True (region1.Contains (4, 4));
- Assert.True (region1.Contains (7, 7));
- // Negative
- Assert.False (region1.Contains (0, 5));
- Assert.False (region1.Contains (5, 0));
- Assert.False (region1.Contains (8, 8));
- Assert.False (region1.Contains (8, 8));
- }
- [Fact]
- public void Union_WithRectangle_AddsRectangle ()
- {
- var region = new Region ();
- var rect = new Rectangle (10, 10, 50, 50);
- region.Union (rect);
- Assert.True (region.Contains (20, 20));
- Assert.False (region.Contains (100, 100));
- }
- [Fact]
- public void Union_WithRegion_AddsRegion ()
- {
- var region1 = new Region (new (10, 10, 50, 50));
- var region2 = new Region (new (30, 30, 50, 50));
- region1.Union (region2.GetBounds ());
- Assert.True (region1.Contains (20, 20));
- Assert.True (region1.Contains (40, 40));
- }
- [Fact]
- public void Intersect_DeferredNormalization_PreservesSegments ()
- {
- var region = new Region (new (0, 0, 3, 1)); // Horizontal
- region.Union (new Rectangle (1, 0, 1, 2)); // Vertical
- region.Intersect (new Rectangle (0, 0, 2, 2)); // Clip
- Rectangle [] result = region.GetRectangles ();
- // Original & Updated (with normalization disabled) behavior:
- // Produces [(0,0,1,1), (1,0,1,2), (2,0,0,1)]
- Assert.Equal (3, result.Length);
- Assert.Contains (new (0, 0, 1, 1), result);
- Assert.Contains (new (1, 0, 1, 2), result);
- Assert.Contains (new (2, 0, 0, 1), result);
- }
- }
|