mirror of
https://github.com/github/spec-kit.git
synced 2026-07-03 12:28:06 +08:00
fix(workflows): reject bool max_iterations in while/do-while validation (#3237)
* fix(workflows): reject bool max_iterations in while/do-while validation while/do-while validate() checked 'not isinstance(max_iter, int) or max_iter < 1'. Since bool is a subclass of int, isinstance(True, int) is True and True < 1 is False, so 'max_iterations: true' passed validation and then ran as a single iteration (range(True) == range(1)) instead of being reported as a type error. Reject bools explicitly, matching the fail-fast-on-bool handling already used for number inputs and gate options. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: assert empty error list for the valid do-while max_iterations case Address Copilot review: the accepted-config assertion only checked that no error mentioned 'max_iterations', which could let an unrelated validation error pass unnoticed. For a known-good config, assert the entire error list is empty (consistent with the other validate tests in this file). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1822,6 +1822,12 @@ class TestWhileStep:
|
||||
step = WhileStep()
|
||||
errors = step.validate({"id": "test", "condition": "{{ true }}", "max_iterations": 0, "steps": []})
|
||||
assert any("must be an integer >= 1" in e for e in errors)
|
||||
# bool is an int subclass; `max_iterations: true` must be rejected, not
|
||||
# silently treated as a single iteration.
|
||||
bool_errors = step.validate(
|
||||
{"id": "test", "condition": "{{ true }}", "max_iterations": True, "steps": []}
|
||||
)
|
||||
assert any("must be an integer >= 1" in e for e in bool_errors)
|
||||
|
||||
|
||||
class TestDoWhileStep:
|
||||
@@ -1861,6 +1867,21 @@ class TestDoWhileStep:
|
||||
assert len(result.next_steps) == 1
|
||||
assert result.output["max_iterations"] == 5
|
||||
|
||||
def test_validate_rejects_bool_max_iterations(self):
|
||||
from specify_cli.workflows.steps.do_while import DoWhileStep
|
||||
|
||||
step = DoWhileStep()
|
||||
# bool is an int subclass; `max_iterations: true` must be rejected.
|
||||
errors = step.validate(
|
||||
{"id": "test", "condition": "{{ true }}", "max_iterations": True, "steps": []}
|
||||
)
|
||||
assert any("must be an integer >= 1" in e for e in errors)
|
||||
# a real positive integer is fully valid (no errors at all).
|
||||
ok = step.validate(
|
||||
{"id": "test", "condition": "{{ true }}", "max_iterations": 3, "steps": []}
|
||||
)
|
||||
assert ok == [], ok
|
||||
|
||||
def test_execute_empty_steps(self):
|
||||
from specify_cli.workflows.steps.do_while import DoWhileStep
|
||||
from specify_cli.workflows.base import StepContext
|
||||
|
||||
Reference in New Issue
Block a user