diff --git a/pr_split/config.py b/pr_split/config.py index 9c4abca..b803fa8 100644 --- a/pr_split/config.py +++ b/pr_split/config.py @@ -59,7 +59,9 @@ def set_default_model(self): @model_validator(mode="after") def auto_derive_min_loc(self): if self.min_loc is None and self.max_refinement_iterations > 0: - self.min_loc = self.max_loc // DEFAULT_MIN_LOC_RATIO + # Floor at 1 so a tiny max_loc cannot derive a min_loc that the + # explicit field constraint (ge=1) would have rejected. + self.min_loc = max(1, self.max_loc // DEFAULT_MIN_LOC_RATIO) return self @model_validator(mode="after") diff --git a/tests/test_config.py b/tests/test_config.py index 06d3ff9..1ea04f0 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -182,3 +182,24 @@ def test_empty_string_key_raises_openai(self, monkeypatch: pytest.MonkeyPatch) - monkeypatch.setenv("OPENAI_API_KEY", "") with pytest.raises(ValidationError, match="OPENAI_API_KEY"): Settings(provider=Provider.OPENAI) + + +class TestDerivedMinLocFloor: + @pytest.mark.parametrize("max_loc", [2, 3]) + def test_tiny_max_loc_derives_min_loc_of_one( + self, monkeypatch: pytest.MonkeyPatch, max_loc: int + ) -> None: + monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-test") + settings = Settings(max_loc=max_loc, max_refinement_iterations=1) + assert settings.min_loc == 1 + + def test_max_loc_of_one_with_refinement_is_rejected( + self, monkeypatch: pytest.MonkeyPatch + ) -> None: + monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-test") + with pytest.raises(ValueError, match="min_loc 1 must be less than max_loc 1"): + Settings(max_loc=1, max_refinement_iterations=1) + + def test_normal_max_loc_uses_ratio(self, monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-test") + assert Settings(max_loc=400, max_refinement_iterations=1).min_loc == 100