diff --git a/src/openjd/model/_range_expr.py b/src/openjd/model/_range_expr.py index 7c789945..33df5288 100644 --- a/src/openjd/model/_range_expr.py +++ b/src/openjd/model/_range_expr.py @@ -150,6 +150,10 @@ def ranges(self) -> list[IntRange]: def _validate(self) -> None: """raises: ValueError - if not valid""" + if len(self) > 1024: + raise ValueError( + f"Range expression produces {len(self)} values, but the maximum is 1024." + ) # Validate that the ranges are not overlapping prev_range: IntRange | None = None for range_ in self.ranges: diff --git a/test/openjd/model/_internal/test_range_expr.py b/test/openjd/model/_internal/test_range_expr.py index f79d2ade..e8984fdc 100644 --- a/test/openjd/model/_internal/test_range_expr.py +++ b/test/openjd/model/_internal/test_range_expr.py @@ -362,6 +362,30 @@ def test_contains(self) -> None: assert -3 not in IntRangeExpr.from_str("-1--2:-1") assert 0 not in IntRangeExpr.from_str("-1--2:-1") + def test_range_expr_max_1024_items_succeeds(self): + expr = IntRangeExpr.from_str("1-1024") + assert len(expr) == 1024 + + def test_range_expr_1025_items_fails(self): + with pytest.raises(ExpressionError): + IntRangeExpr.from_str("1-1025") + + def test_range_expr_combined_subranges_exceed_1024_fails(self): + with pytest.raises(ExpressionError): + IntRangeExpr.from_str("1-600,700-1300") + + def test_range_expr_stepped_within_limit_succeeds(self): + expr = IntRangeExpr.from_str("1-2047:2") + assert len(expr) == 1024 + + def test_range_expr_stepped_exceeds_limit_fails(self): + with pytest.raises(ExpressionError): + IntRangeExpr.from_str("1-3000:2") + + def test_range_expr_negative_range_exceeds_limit_fails(self): + with pytest.raises(ExpressionError): + IntRangeExpr.from_str("-512-512") + class TestIntRange: def test_length(self):