Skip to content

Commit 0920ded

Browse files
authored
fix(cli): use click.Choice in cf proof capture (#723) (#795)
* fix(cli): use click.Choice in cf proof capture (typer.Choice doesn't exist) (#723) The interactive capture path prompted severity/source with type=typer.Choice(), but typer has no Choice attribute — any 'cf proof capture' run without --severity/--source raised AttributeError with an uncaught traceback, breaking the command's own documented interactive usage. typer.prompt delegates to click.prompt, so use click.Choice. Closes #723 * test: also assert source from interactive Choice prompt (#723 review)
1 parent 6760473 commit 0920ded

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

codeframe/cli/proof_commands.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from pathlib import Path
99
from typing import Optional
1010

11+
import click
1112
import typer
1213
from rich.console import Console
1314
from rich.table import Table
@@ -75,12 +76,14 @@ def capture(
7576
if not severity:
7677
severity = typer.prompt(
7778
"Severity", default="medium",
78-
type=typer.Choice(["critical", "high", "medium", "low"]),
79+
# click.Choice — typer has no Choice; typer.prompt delegates to
80+
# click.prompt, so this constrains the interactive input (#723).
81+
type=click.Choice(["critical", "high", "medium", "low"]),
7982
)
8083
if not source:
8184
source = typer.prompt(
8285
"Source", default="qa",
83-
type=typer.Choice(["production", "qa", "dogfooding", "monitoring", "user_report"]),
86+
type=click.Choice(["production", "qa", "dogfooding", "monitoring", "user_report"]),
8487
)
8588

8689
try:

tests/cli/test_proof_commands.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,28 @@ def test_capture_creates_req_and_persists(self, ws):
7878
assert req.title == "Login rejects valid credentials"
7979
assert req.status == ReqStatus.OPEN
8080

81+
def test_capture_interactive_prompts_do_not_crash(self, ws):
82+
"""#723: severity/source were prompted with the nonexistent typer.Choice,
83+
so any interactive `cf proof capture` (no --severity/--source) raised
84+
AttributeError. Drive the interactive branch via stdin and assert it
85+
captures cleanly."""
86+
workspace, workspace_path = ws
87+
result = runner.invoke(
88+
app,
89+
[
90+
"proof", "capture", "-w", str(workspace_path),
91+
"--title", "T", "--description", "D", "--where", "src/x.py",
92+
],
93+
input="high\nqa\n", # severity Choice, then source Choice
94+
)
95+
assert result.exit_code == 0, result.output
96+
assert "REQ-0001" in result.output
97+
req = ledger.get_requirement(workspace, "REQ-0001")
98+
assert req is not None
99+
# Both repaired Choice prompts (severity + source) took effect.
100+
assert req.severity.value == "high"
101+
assert req.source.value == "qa"
102+
81103
def test_capture_second_req_increments_id(self, ws_with_req):
82104
"""A second capture should produce REQ-0002."""
83105
workspace, workspace_path = ws_with_req

0 commit comments

Comments
 (0)