|
| 1 | +"""Test cases for the GridCell model.""" |
| 2 | + |
| 3 | +import pandas as pd |
| 4 | +import pytest |
| 5 | + |
| 6 | +from graphomotor.core import models |
| 7 | + |
| 8 | + |
| 9 | +@pytest.fixture |
| 10 | +def cell() -> models.GridCell: |
| 11 | + """Create a grid cell representing one letter region.""" |
| 12 | + return models.GridCell( |
| 13 | + x_min=10.0, x_max=25.0, y_min=80.0, y_max=97.0, index=0, label="A" |
| 14 | + ) |
| 15 | + |
| 16 | + |
| 17 | +@pytest.mark.parametrize( |
| 18 | + "x_min,x_max,y_min,y_max,expected_error", |
| 19 | + [ |
| 20 | + (10.0, 5.0, 0.0, 1.0, "x_min .* must be less than x_max"), |
| 21 | + (5.0, 5.0, 0.0, 1.0, "x_min .* must be less than x_max"), |
| 22 | + (0.0, 1.0, 10.0, 5.0, "y_min .* must be less than y_max"), |
| 23 | + (0.0, 1.0, 5.0, 5.0, "y_min .* must be less than y_max"), |
| 24 | + ], |
| 25 | +) |
| 26 | +def test_grid_cell_invalid_bounds( |
| 27 | + x_min: float, |
| 28 | + x_max: float, |
| 29 | + y_min: float, |
| 30 | + y_max: float, |
| 31 | + expected_error: str, |
| 32 | +) -> None: |
| 33 | + """Test that invalid or equal bounds raise ValueError.""" |
| 34 | + with pytest.raises(ValueError, match=expected_error): |
| 35 | + models.GridCell(x_min=x_min, x_max=x_max, y_min=y_min, y_max=y_max) |
| 36 | + |
| 37 | + |
| 38 | +def test_stroke_centroid_inside_cell(cell: models.GridCell) -> None: |
| 39 | + """Stroke whose centroid falls inside the cell should be contained.""" |
| 40 | + stroke_points = pd.DataFrame({"x": [15.0, 20.0, 17.0], "y": [85.0, 90.0, 95.0]}) |
| 41 | + assert cell.contains_points(stroke_points) |
| 42 | + |
| 43 | + |
| 44 | +def test_stroke_centroid_outside_cell(cell: models.GridCell) -> None: |
| 45 | + """Stroke whose centroid falls outside the cell should not be contained.""" |
| 46 | + stroke_points = pd.DataFrame({"x": [33.8, 37.8, 35.3], "y": [85.8, 95.4, 90.1]}) |
| 47 | + assert not cell.contains_points(stroke_points) |
| 48 | + |
| 49 | + |
| 50 | +def test_stroke_centroid_on_boundary(cell: models.GridCell) -> None: |
| 51 | + """Stroke whose centroid lands exactly on the cell boundary should be contained.""" |
| 52 | + stroke_points = pd.DataFrame({"x": [10.0, 10.0], "y": [88.0, 89.0]}) |
| 53 | + assert cell.contains_points(stroke_points) |
| 54 | + |
| 55 | + |
| 56 | +def test_stroke_points_span_outside_but_centroid_inside( |
| 57 | + cell: models.GridCell, |
| 58 | +) -> None: |
| 59 | + """Stroke with points outside the cell but centroid inside should be contained.""" |
| 60 | + stroke_points = pd.DataFrame({"x": [8.0, 22.0], "y": [78.0, 98.0]}) |
| 61 | + assert cell.contains_points(stroke_points) |
| 62 | + |
| 63 | + |
| 64 | +def test_single_point_stroke(cell: models.GridCell) -> None: |
| 65 | + """Single-point stroke should use that point as its centroid.""" |
| 66 | + stroke_points = pd.DataFrame({"x": [17.5], "y": [90.0]}) |
| 67 | + assert cell.contains_points(stroke_points) |
0 commit comments