123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- using System;
- using Avalonia.Controls.Primitives;
- using Avalonia.UnitTests;
- using Xunit;
- namespace Avalonia.Controls.UnitTests.Primitives
- {
- public class UniformGridTests : ScopedTestBase
- {
- [Fact]
- public void Grid_Columns_Equals_Rows_For_Auto_Columns_And_Rows()
- {
- var target = new UniformGrid
- {
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 80, Height = 90 }
- }
- };
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // 2 * 2 grid => each cell: 80 x 90
- // Final size => (2 * 80) x (2 * 90) = 160 x 180
- Assert.Equal(new Size(160, 180), target.Bounds.Size);
- }
- [Fact]
- public void Grid_Expands_Vertically_For_Columns_With_Auto_Rows()
- {
- var target = new UniformGrid
- {
- Columns = 2,
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 80, Height = 90 },
- new Border { Width = 20, Height = 30 },
- new Border { Width = 40, Height = 60 }
- }
- };
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // 2 * 3 grid => each cell: 80 x 90
- // Final size => (2 * 80) x (3 * 90) = 160 x 270
- Assert.Equal(new Size(160, 270), target.Bounds.Size);
- }
- [Fact]
- public void Grid_Extends_For_Columns_And_First_Column_With_Auto_Rows()
- {
- var target = new UniformGrid
- {
- Columns = 3,
- FirstColumn = 2,
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 80, Height = 90 },
- new Border { Width = 20, Height = 30 },
- new Border { Width = 40, Height = 60 }
- }
- };
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // 3 * 3 grid => each cell: 80 x 90
- // Final size => (3 * 80) x (3 * 90) = 240 x 270
- Assert.Equal(new Size(240, 270), target.Bounds.Size);
- }
- [Fact]
- public void Grid_Expands_Horizontally_For_Rows_With_Auto_Columns()
- {
- var target = new UniformGrid
- {
- Rows = 2,
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 80, Height = 90 },
- new Border { Width = 20, Height = 30 },
- new Border { Width = 40, Height = 60 }
- }
- };
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // 3 * 2 grid => each cell: 80 x 90
- // Final size => (3 * 80) x (2 * 90) = 240 x 180
- Assert.Equal(new Size(240, 180), target.Bounds.Size);
- }
- [Fact]
- public void Grid_Size_Is_Limited_By_Rows_And_Columns()
- {
- var target = new UniformGrid
- {
- Columns = 2,
- Rows = 2,
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 80, Height = 90 },
- new Border { Width = 20, Height = 30 },
- new Border { Width = 40, Height = 60 }
- }
- };
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // 2 * 2 grid => each cell: 80 x 90
- // Final size => (2 * 80) x (2 * 90) = 160 x 180
- Assert.Equal(new Size(160, 180), target.Bounds.Size);
- }
- [Fact]
- public void Not_Visible_Children_Are_Ignored()
- {
- var target = new UniformGrid
- {
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 80, Height = 90, IsVisible = false },
- new Border { Width = 20, Height = 30 },
- new Border { Width = 40, Height = 60 }
- }
- };
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // Visible children: 4
- // Auto => 2 x 2 grid => each cell: 50 x 70
- // Final size => (2 * 50) x (2 * 70) = 100 x 140
- Assert.Equal(new Size(100, 140), target.Bounds.Size);
- }
- //
- // New tests to cover RowSpacing and ColumnSpacing
- //
- [Fact]
- public void Grid_Respects_ColumnSpacing_For_Auto_Columns_And_Rows()
- {
- // We have 3 visible children and no fixed Rows/Columns => 2x2 grid
- // Largest child is 80 x 90. ColumnSpacing = 10, RowSpacing = 0
- var target = new UniformGrid
- {
- ColumnSpacing = 10,
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 80, Height = 90 }
- }
- };
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // Without spacing => width = 2*80 = 160, height = 2*90 = 180
- // With columnSpacing=10 => total width = 2*80 + 1*10 = 170
- // RowSpacing=0 => total height = 180
- Assert.Equal(new Size(170, 180), target.Bounds.Size);
- }
- [Fact]
- public void Grid_Respects_RowSpacing_For_Auto_Columns_And_Rows()
- {
- // 3 visible children => 2x2 grid again
- // Largest child is 80 x 90. RowSpacing = 15, ColumnSpacing = 0
- var target = new UniformGrid
- {
- RowSpacing = 15,
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 80, Height = 90 }
- }
- };
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // Without spacing => width = 160, height = 180
- // With rowSpacing=15 => total height = 2*90 + 1*15 = 195
- // ColumnSpacing=0 => total width = 160
- Assert.Equal(new Size(160, 195), target.Bounds.Size);
- }
- [Fact]
- public void Grid_Respects_Both_Row_And_Column_Spacing_For_Fixed_Grid()
- {
- // 4 visible children => 2 rows x 2 columns, each child is 50x70 or 80x90
- // We'll fix the Grid to 2x2 so the largest child dictates the cell size: 80x90
- // RowSpacing=10, ColumnSpacing=5
- var target = new UniformGrid
- {
- Rows = 2,
- Columns = 2,
- RowSpacing = 10,
- ColumnSpacing = 5,
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 80, Height = 90 },
- new Border { Width = 20, Height = 30 },
- }
- };
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // Each cell = 80 x 90
- // Final width = (2 * 80) + (1 * 5) = 160 + 5 = 165
- // Final height = (2 * 90) + (1 * 10) = 180 + 10 = 190
- Assert.Equal(new Size(165, 190), target.Bounds.Size);
- }
- [Fact]
- public void Grid_Respects_Spacing_When_Invisible_Child_Exists()
- {
- // 3 *visible* children => auto => 2x2 grid
- // Largest child is 80 x 90.
- // Add spacing so we can confirm it doesn't add extra columns/rows for invisible child.
- var target = new UniformGrid
- {
- RowSpacing = 5,
- ColumnSpacing = 5,
- Children =
- {
- new Border { Width = 50, Height = 70 },
- new Border { Width = 80, Height = 90, IsVisible = false },
- new Border { Width = 30, Height = 50 },
- new Border { Width = 40, Height = 60 }
- }
- };
- // Visible children: 3 => auto => sqrt(3) => 2x2
- // Largest visible child is 50x70 or 30x50 or 40x60 => the biggest is 50x70
- // Actually, let's ensure we have a child bigger than that:
- // (So let's modify the 40x60 to something bigger than 50x70, e.g. 80x90 for clarity)
- // We'll do that in the collection above if needed, but let's keep as is for example.
- target.Measure(Size.Infinity);
- target.Arrange(new Rect(target.DesiredSize));
- // The largest visible child is 50x70. So each cell is 50x70.
- // For a 2x2 grid with 3 visible children:
- // - total width = (2 * 50) + (1 * 5) = 100 + 5 = 105
- // - total height = (2 * 70) + (1 * 5) = 140 + 5 = 145
- Assert.Equal(new Size(105, 145), target.Bounds.Size);
- }
- /// <summary>
- /// Exposes MeasureOverride for testing inherited classes
- /// </summary>
- public class UniformGridExposeMeasureOverride : UniformGrid
- {
- public new Size MeasureOverride(Size availableSize)
- {
- return base.MeasureOverride(availableSize);
- }
- }
- [Fact]
- public void Measure_WithRowsAndColumnsZeroAndNonZeroSpacing_ProducesZeroDesiredSize()
- {
- // MeasureOverride() is called by Layoutable.MeasureCore() and it ensures that
- // the desired size is never negative. but in case of inherited classes MeasureOverride() may return negative values.
- var target = new UniformGridExposeMeasureOverride
- {
- Rows = 0,
- Columns = 0,
- RowSpacing = 10,
- ColumnSpacing = 20
- };
- var availableSize = new Size(100, 100);
- var desiredSize = target.MeasureOverride(availableSize);
- // Fail case:
- // Because _rows and _columns are 0, the calculation becomes:
- // totalWidth = maxWidth * 0 + ColumnSpacing * (0 - 1) = -ColumnSpacing
- // totalHeight = maxHeight * 0 + RowSpacing * (0 - 1) = -RowSpacing
- // Expected: (0, 0)
- Assert.Equal(0, desiredSize.Width);
- Assert.Equal(0, desiredSize.Height);
-
- }
- [Fact]
- public void Arrange_Does_Not_Throw_InvalidOperationException_When_Row_Spacing_Takes_All_Available_Height()
- {
- // Minimum required height = 20 (2 row gaps size 10)
- // Provide height of 19 so that row gaps take all available space
- // thus, available height for children may be negative.
- // In that case, UniformGrid should arrange its children with rects of height 0.
- var target = new UniformGrid
- {
- Columns = 1,
- RowSpacing = 10,
- Children =
- {
- new Border(),
- new Border(),
- new Border()
- }
- };
- var availableSize = new Size(100, 19);
- target.Measure(Size.Infinity);
- // Fail case:
- // Invalid operation will be thrown if any child rect contains a negative dimension
- try
- {
- target.Arrange(new Rect(availableSize));
- }
- catch (InvalidOperationException exception)
- {
- Assert.Fail("Arrange threw InvalidOperationException: " + exception.Message);
- }
- }
- [Fact]
- public void Arrange_Does_Not_Throw_InvalidOperationException_When_Column_Spacing_Takes_All_Available_Width()
- {
- // Minimum required width = 20 (2 row gaps size 10)
- // Provide width of 19 so that column gaps take all available space
- // thus, available width for children may be negative.
- // In that case, UniformGrid should arrange its children with rects of width 0.
- var target = new UniformGrid
- {
- Rows = 1,
- ColumnSpacing = 10,
- Children =
- {
- new Border(),
- new Border(),
- new Border()
- }
- };
- var availableSize = new Size(19, 100);
- target.Measure(Size.Infinity);
- // Fail case:
- // Invalid operation will be thrown if any child rect contains a negative dimension
- try
- {
- target.Arrange(new Rect(availableSize));
- }
- catch (InvalidOperationException exception)
- {
- Assert.Fail("Arrange threw InvalidOperationException: " + exception.Message);
- }
- }
- }
- }
|