|
1 | 1 | import pytest |
2 | 2 |
|
3 | | -from plotnine._mpl.layout_manager._grid import Grid |
| 3 | +from plotnine._mpl.layout_manager._grid import DesignGrid, Grid |
4 | 4 |
|
5 | 5 |
|
6 | 6 | def test_reduce_cols_basic(): |
@@ -107,3 +107,95 @@ def fn(n): |
107 | 107 | return n |
108 | 108 |
|
109 | 109 | grid.reduce_cols(fn, default=0) |
| 110 | + |
| 111 | + |
| 112 | +def test_design_grid_no_spans_matches_grid(): |
| 113 | + # Three single-cell items; each span is 1×1 so fn(item)/1 = fn(item). |
| 114 | + # Mirrors what a plain Grid would do. |
| 115 | + items = [1, 2, 3] |
| 116 | + rects = [(0, 0, 0, 0), (0, 0, 1, 1), (1, 1, 0, 0)] |
| 117 | + grid = DesignGrid[int](2, 2, items, rects) |
| 118 | + assert grid.reduce_cols(lambda n: n, default=0) == [3, 2] |
| 119 | + assert grid.reduce_rows(lambda n: n, default=0) == [2, 3] |
| 120 | + |
| 121 | + |
| 122 | +def test_design_grid_colspan_divides_contribution(): |
| 123 | + # Item spans both columns of a 1×2 grid. |
| 124 | + grid = DesignGrid[int](1, 2, [10], [(0, 0, 0, 1)]) |
| 125 | + assert grid.reduce_cols(lambda n: n, default=0) == [5.0, 5.0] |
| 126 | + assert grid.reduce_rows(lambda n: n, default=0) == [10.0] |
| 127 | + |
| 128 | + |
| 129 | +def test_design_grid_rowspan_divides_contribution(): |
| 130 | + # Item spans both rows of a 2×1 grid. |
| 131 | + grid = DesignGrid[int](2, 1, [10], [(0, 1, 0, 0)]) |
| 132 | + assert grid.reduce_rows(lambda n: n, default=0) == [5.0, 5.0] |
| 133 | + assert grid.reduce_cols(lambda n: n, default=0) == [10.0] |
| 134 | + |
| 135 | + |
| 136 | +def test_design_grid_square_span(): |
| 137 | + # Item spans the full 2×2 grid: fn / colspan = fn / rowspan = fn/2. |
| 138 | + grid = DesignGrid[int](2, 2, [12], [(0, 1, 0, 1)]) |
| 139 | + assert grid.reduce_cols(lambda n: n, default=0) == [6.0, 6.0] |
| 140 | + assert grid.reduce_rows(lambda n: n, default=0) == [6.0, 6.0] |
| 141 | + |
| 142 | + |
| 143 | +def test_design_grid_max_across_contributors(): |
| 144 | + # Col 0: contributions [10/1, 4/2] = [10, 2] → 10. |
| 145 | + # Col 1: contributions [4/2] = [2] → 2. |
| 146 | + items = [10, 4] |
| 147 | + rects = [(0, 0, 0, 0), (1, 1, 0, 1)] |
| 148 | + grid = DesignGrid[int](2, 2, items, rects) |
| 149 | + assert grid.reduce_cols(lambda n: n, default=0) == [10.0, 2.0] |
| 150 | + |
| 151 | + |
| 152 | +def test_design_grid_empty_row_default(): |
| 153 | + # Items only in row 0 of a 3×2 grid; rows 1 and 2 take the default. |
| 154 | + items = [1, 2] |
| 155 | + rects = [(0, 0, 0, 0), (0, 0, 1, 1)] |
| 156 | + grid = DesignGrid[int](3, 2, items, rects) |
| 157 | + assert grid.reduce_rows(lambda n: n, default=99) == [2, 99, 99] |
| 158 | + |
| 159 | + |
| 160 | +def test_design_grid_empty_column_default(): |
| 161 | + # Items only in col 0 of a 2×3 grid; cols 1 and 2 take the default. |
| 162 | + items = [1, 2] |
| 163 | + rects = [(0, 0, 0, 0), (1, 1, 0, 0)] |
| 164 | + grid = DesignGrid[int](2, 3, items, rects) |
| 165 | + assert grid.reduce_cols(lambda n: n, default=99) == [2, 99, 99] |
| 166 | + |
| 167 | + |
| 168 | +def test_design_grid_items_on_edge_top_uses_r0(): |
| 169 | + # Spanning item: top edge at r0=0, not r1=1. |
| 170 | + grid = DesignGrid[int](2, 1, [5], [(0, 1, 0, 0)]) |
| 171 | + assert grid.items_on_edge("top", 0) == [5] |
| 172 | + assert grid.items_on_edge("top", 1) == [] |
| 173 | + |
| 174 | + |
| 175 | +def test_design_grid_items_on_edge_bottom_uses_r1(): |
| 176 | + # Same item: bottom edge at r1=1, not r0=0. |
| 177 | + grid = DesignGrid[int](2, 1, [5], [(0, 1, 0, 0)]) |
| 178 | + assert grid.items_on_edge("bottom", 1) == [5] |
| 179 | + assert grid.items_on_edge("bottom", 0) == [] |
| 180 | + |
| 181 | + |
| 182 | +def test_design_grid_items_on_edge_left_right(): |
| 183 | + # Col-spanning item: left edge at c0=0, right edge at c1=2. |
| 184 | + grid = DesignGrid[int](1, 3, [7], [(0, 0, 0, 2)]) |
| 185 | + assert grid.items_on_edge("left", 0) == [7] |
| 186 | + assert grid.items_on_edge("left", 1) == [] |
| 187 | + assert grid.items_on_edge("right", 2) == [7] |
| 188 | + assert grid.items_on_edge("right", 0) == [] |
| 189 | + |
| 190 | + |
| 191 | +def test_design_grid_mismatched_lengths_raises(): |
| 192 | + with pytest.raises(ValueError, match="2 items but 1 rectangles"): |
| 193 | + DesignGrid[int](2, 2, [1, 2], [(0, 0, 0, 0)]) |
| 194 | + |
| 195 | + |
| 196 | +def test_design_grid_indexing_returns_item_at_every_spanned_cell(): |
| 197 | + # Spanning item must appear at every cell of its rect so that |
| 198 | + # base-class iter_rows / iter_cols continue to expose it. |
| 199 | + grid = DesignGrid[int](2, 1, [5], [(0, 1, 0, 0)]) |
| 200 | + assert grid[0, 0] == 5 |
| 201 | + assert grid[1, 0] == 5 |
0 commit comments