test_cli.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. """Tests for CLI option parsing."""
  2. from __future__ import annotations
  3. from click.testing import CliRunner
  4. from drill.cli import main
  5. class TestRunCommand:
  6. def test_backend_required_without_models(self) -> None:
  7. runner = CliRunner()
  8. result = runner.invoke(main, ["run", "nonexistent"])
  9. assert result.exit_code != 0
  10. def test_n_default_is_1(self) -> None:
  11. runner = CliRunner()
  12. result = runner.invoke(main, ["run", "nonexistent", "--backend", "claude", "--n", "1"])
  13. assert "Scenario not found" in result.output or result.exit_code != 0
  14. def test_models_flag_accepted(self) -> None:
  15. runner = CliRunner()
  16. result = runner.invoke(main, ["run", "nonexistent", "--models", "claude,codex"])
  17. assert "Scenario not found" in result.output or result.exit_code != 0
  18. def test_n_must_be_positive(self) -> None:
  19. runner = CliRunner()
  20. result = runner.invoke(main, ["run", "nonexistent", "--backend", "claude", "--n", "0"])
  21. assert result.exit_code != 0
  22. class TestListCommand:
  23. def test_lists_scenarios(self, tmp_path):
  24. scenarios_dir = tmp_path / "scenarios"
  25. scenarios_dir.mkdir()
  26. (scenarios_dir / "test-scenario.yaml").write_text("""
  27. scenario: test-scenario
  28. description: "A test scenario"
  29. user_posture: naive
  30. setup:
  31. helpers: []
  32. assertions: []
  33. turns: []
  34. limits:
  35. max_turns: 5
  36. turn_timeout: 30
  37. verify:
  38. criteria: []
  39. observe: false
  40. """)
  41. runner = CliRunner()
  42. result = runner.invoke(main, ["list", "--scenarios-dir", str(scenarios_dir)])
  43. assert result.exit_code == 0
  44. assert "test-scenario" in result.output
  45. class TestCompareCommand:
  46. def test_sweep_flag_accepted(self) -> None:
  47. runner = CliRunner()
  48. result = runner.invoke(main, ["compare", "nonexistent", "--sweep", "abc123"])
  49. assert result.exit_code != 0 # No results dir, but flag is parsed
  50. def test_set_superpowers_root_default_when_unset(monkeypatch, tmp_path):
  51. """When SUPERPOWERS_ROOT is unset, helper sets it to PROJECT_ROOT.parent."""
  52. monkeypatch.delenv("SUPERPOWERS_ROOT", raising=False)
  53. from drill.cli import PROJECT_ROOT, _set_superpowers_root_default
  54. _set_superpowers_root_default()
  55. import os
  56. assert os.environ["SUPERPOWERS_ROOT"] == str(PROJECT_ROOT.parent)
  57. def test_set_superpowers_root_default_respects_existing(monkeypatch):
  58. """When SUPERPOWERS_ROOT is already set, helper does not override."""
  59. monkeypatch.setenv("SUPERPOWERS_ROOT", "/custom/path")
  60. from drill.cli import _set_superpowers_root_default
  61. _set_superpowers_root_default()
  62. import os
  63. assert os.environ["SUPERPOWERS_ROOT"] == "/custom/path"