Co-authored-by: Claude (Opus 4.6) <claude@hermes.local> Co-committed-by: Claude (Opus 4.6) <claude@hermes.local>
95 lines
3.0 KiB
Python
95 lines
3.0 KiB
Python
"""Tests for the `timmy learn` CLI command (autoresearch entry point)."""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from typer.testing import CliRunner
|
|
|
|
from timmy.cli import app
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
class TestLearnCommand:
|
|
"""Tests for `timmy learn`."""
|
|
|
|
def test_requires_target(self):
|
|
result = runner.invoke(app, ["learn"])
|
|
assert result.exit_code != 0
|
|
assert "target" in result.output.lower() or "target" in (result.stderr or "").lower()
|
|
|
|
def test_dry_run_shows_hypothesis_no_tox(self, tmp_path):
|
|
program_file = tmp_path / "program.md"
|
|
program_file.write_text("Improve logging coverage in agent module")
|
|
|
|
with patch("timmy.autoresearch.subprocess.run") as mock_run:
|
|
result = runner.invoke(
|
|
app,
|
|
[
|
|
"learn",
|
|
"--target",
|
|
"src/timmy/agent.py",
|
|
"--program",
|
|
str(program_file),
|
|
"--max-experiments",
|
|
"2",
|
|
"--dry-run",
|
|
],
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
# tox should never be called in dry-run
|
|
mock_run.assert_not_called()
|
|
assert "agent.py" in result.output
|
|
|
|
def test_missing_program_md_warns_but_continues(self, tmp_path):
|
|
with patch("timmy.autoresearch.subprocess.run") as mock_run:
|
|
mock_run.return_value = MagicMock(returncode=0, stdout="3 passed", stderr="")
|
|
result = runner.invoke(
|
|
app,
|
|
[
|
|
"learn",
|
|
"--target",
|
|
"src/timmy/agent.py",
|
|
"--program",
|
|
str(tmp_path / "nonexistent.md"),
|
|
"--max-experiments",
|
|
"1",
|
|
"--dry-run",
|
|
],
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
|
|
def test_dry_run_prints_max_experiments_hypotheses(self, tmp_path):
|
|
program_file = tmp_path / "program.md"
|
|
program_file.write_text("Fix edge case in parser")
|
|
|
|
result = runner.invoke(
|
|
app,
|
|
[
|
|
"learn",
|
|
"--target",
|
|
"src/timmy/parser.py",
|
|
"--program",
|
|
str(program_file),
|
|
"--max-experiments",
|
|
"3",
|
|
"--dry-run",
|
|
],
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
# Should show 3 experiment headers
|
|
assert result.output.count("[1/3]") == 1
|
|
assert result.output.count("[2/3]") == 1
|
|
assert result.output.count("[3/3]") == 1
|
|
|
|
def test_help_text_present(self):
|
|
result = runner.invoke(app, ["learn", "--help"])
|
|
assert result.exit_code == 0
|
|
assert "--target" in result.output
|
|
assert "--metric" in result.output
|
|
assert "--budget" in result.output
|
|
assert "--max-experiments" in result.output
|
|
assert "--dry-run" in result.output
|