From de9309ca431b375e134deb2e06ac9b579348d9a3 Mon Sep 17 00:00:00 2001 From: ctan Date: Sun, 20 Sep 2026 17:29:10 +0200 Subject: [PATCH] fix(cli): reject duplicate --side names with a clear error --- src/pf1e_simulator/cli.py | 12 ++++++++++++ tests/test_cli.py | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/pf1e_simulator/cli.py b/src/pf1e_simulator/cli.py index 6b4a353..c22039b 100644 --- a/src/pf1e_simulator/cli.py +++ b/src/pf1e_simulator/cli.py @@ -108,6 +108,18 @@ def _build_spec(args: argparse.Namespace) -> EncounterSpec: map_spec = load_map(args.map) provided = [tuple(raw) for raw in args.side] 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) if missing: msg = f"sides in map deployment without --side: {', '.join(missing)}" diff --git a/tests/test_cli.py b/tests/test_cli.py index 8384739..ac4eaac 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -60,6 +60,30 @@ def test_cli_rejects_missing_deployment_side(capsys: pytest.CaptureFixture[str]) 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: rc = main( [