fix(cli): reject duplicate --side names with a clear error
This commit is contained in:
@@ -108,6 +108,18 @@ def _build_spec(args: argparse.Namespace) -> EncounterSpec:
|
|||||||
map_spec = load_map(args.map)
|
map_spec = load_map(args.map)
|
||||||
provided = [tuple(raw) for raw in args.side]
|
provided = [tuple(raw) for raw in args.side]
|
||||||
provided_names = {raw[0] for raw in provided}
|
provided_names = {raw[0] for raw in provided}
|
||||||
|
seen_names: set[str] = set()
|
||||||
|
duplicates: set[str] = set()
|
||||||
|
for raw in provided:
|
||||||
|
if raw[0] in seen_names:
|
||||||
|
duplicates.add(raw[0])
|
||||||
|
seen_names.add(raw[0])
|
||||||
|
if duplicates:
|
||||||
|
msg = (
|
||||||
|
"duplicate --side names (each camp must be provided exactly "
|
||||||
|
f"once): {', '.join(sorted(duplicates))}"
|
||||||
|
)
|
||||||
|
raise CliError(msg)
|
||||||
missing = sorted(set(map_spec.deployment) - provided_names)
|
missing = sorted(set(map_spec.deployment) - provided_names)
|
||||||
if missing:
|
if missing:
|
||||||
msg = f"sides in map deployment without --side: {', '.join(missing)}"
|
msg = f"sides in map deployment without --side: {', '.join(missing)}"
|
||||||
|
|||||||
@@ -60,6 +60,30 @@ def test_cli_rejects_missing_deployment_side(capsys: pytest.CaptureFixture[str])
|
|||||||
assert "monsters" in capsys.readouterr().err
|
assert "monsters" in capsys.readouterr().err
|
||||||
|
|
||||||
|
|
||||||
|
def test_cli_rejects_duplicate_side_names(capsys: pytest.CaptureFixture[str]) -> None:
|
||||||
|
rc = main(
|
||||||
|
[
|
||||||
|
"--map",
|
||||||
|
str(MAP),
|
||||||
|
"--side",
|
||||||
|
"players",
|
||||||
|
str(GOBLIN),
|
||||||
|
"--side",
|
||||||
|
"players",
|
||||||
|
str(ORC),
|
||||||
|
"--side",
|
||||||
|
"monsters",
|
||||||
|
str(ORC),
|
||||||
|
"--runs",
|
||||||
|
"10",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
assert rc == 2
|
||||||
|
err = capsys.readouterr().err
|
||||||
|
assert "duplicate --side names" in err
|
||||||
|
assert "players" in err
|
||||||
|
|
||||||
|
|
||||||
def test_cli_transcript_prints_first_battle_log(capsys: pytest.CaptureFixture[str]) -> None:
|
def test_cli_transcript_prints_first_battle_log(capsys: pytest.CaptureFixture[str]) -> None:
|
||||||
rc = main(
|
rc = main(
|
||||||
[
|
[
|
||||||
|
|||||||
Reference in New Issue
Block a user