Add kaizen-agentic feedback CLI, Gitea issue templates, CI workflow, pre-commit hooks, FEEDBACK/TELEMETRY docs, and cross-platform path tests. Improve CLI registry error messages; remove agents_backup scaffolding. Apply black formatting across src/tests for CI consistency. State Hub message sent to agentic-resources for Helix correlation doc link.
158 lines
4.8 KiB
Python
158 lines
4.8 KiB
Python
"""CLI tests for project-scoped metrics commands."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from click.testing import CliRunner
|
|
|
|
from kaizen_agentic.cli import cli
|
|
|
|
|
|
@pytest.fixture
|
|
def runner() -> CliRunner:
|
|
return CliRunner()
|
|
|
|
|
|
@pytest.fixture
|
|
def project_dir(tmp_path: Path) -> Path:
|
|
root = tmp_path / "demo-project"
|
|
root.mkdir()
|
|
return root
|
|
|
|
|
|
class TestMetricsCli:
|
|
def test_record_show_list_export_flow(self, runner: CliRunner, project_dir: Path):
|
|
target = str(project_dir)
|
|
|
|
record = runner.invoke(
|
|
cli,
|
|
[
|
|
"metrics",
|
|
"record",
|
|
"tdd-workflow",
|
|
"--target",
|
|
target,
|
|
"--success",
|
|
"--time",
|
|
"42",
|
|
"--quality",
|
|
"0.85",
|
|
],
|
|
)
|
|
assert record.exit_code == 0
|
|
assert "Recorded metrics" in record.output
|
|
|
|
show = runner.invoke(
|
|
cli, ["metrics", "show", "tdd-workflow", "--target", target]
|
|
)
|
|
assert show.exit_code == 0
|
|
assert '"execution_count": 1' in show.output
|
|
assert '"success": true' in show.output
|
|
|
|
listed = runner.invoke(cli, ["metrics", "list", "--target", target])
|
|
assert listed.exit_code == 0
|
|
assert "tdd-workflow" in listed.output
|
|
|
|
export = runner.invoke(
|
|
cli, ["metrics", "export", "tdd-workflow", "--target", target]
|
|
)
|
|
assert export.exit_code == 0
|
|
lines = [line for line in export.output.splitlines() if line.strip()]
|
|
assert len(lines) == 1
|
|
assert json.loads(lines[0])["quality_score"] == 0.85
|
|
|
|
def test_record_json_from_stdin(self, runner: CliRunner, project_dir: Path):
|
|
payload = json.dumps({"success": False, "execution_time_s": 9.5})
|
|
result = runner.invoke(
|
|
cli,
|
|
["metrics", "record", "coach", "--target", str(project_dir), "--json"],
|
|
input=payload,
|
|
)
|
|
assert result.exit_code == 0
|
|
|
|
show = runner.invoke(
|
|
cli, ["metrics", "show", "coach", "--target", str(project_dir)]
|
|
)
|
|
assert '"success": false' in show.output
|
|
|
|
def test_record_idempotency_key_skips_duplicate(
|
|
self, runner: CliRunner, project_dir: Path
|
|
):
|
|
args = [
|
|
"metrics",
|
|
"record",
|
|
"coach",
|
|
"--target",
|
|
str(project_dir),
|
|
"--success",
|
|
"--idempotency-key",
|
|
"sess-abc",
|
|
]
|
|
first = runner.invoke(cli, args)
|
|
second = runner.invoke(cli, args)
|
|
assert first.exit_code == 0
|
|
assert second.exit_code == 0
|
|
assert "Skipped duplicate" in second.output
|
|
|
|
export = runner.invoke(
|
|
cli, ["metrics", "export", "coach", "--target", str(project_dir)]
|
|
)
|
|
assert len(export.output.strip().splitlines()) == 1
|
|
|
|
def test_record_requires_outcome_without_json(
|
|
self, runner: CliRunner, project_dir: Path
|
|
):
|
|
result = runner.invoke(
|
|
cli,
|
|
["metrics", "record", "tdd-workflow", "--target", str(project_dir)],
|
|
)
|
|
assert result.exit_code != 0
|
|
assert "--success or --failure" in result.output
|
|
|
|
def test_memory_init_scaffolds_metrics(self, runner: CliRunner, project_dir: Path):
|
|
result = runner.invoke(
|
|
cli,
|
|
["memory", "init", "tdd-workflow", "--target", str(project_dir)],
|
|
)
|
|
assert result.exit_code == 0
|
|
metrics_dir = project_dir / ".kaizen" / "metrics" / "tdd-workflow"
|
|
assert metrics_dir.exists()
|
|
assert (metrics_dir / "executions.jsonl").exists()
|
|
|
|
def test_memory_brief_includes_performance_summary(
|
|
self, runner: CliRunner, project_dir: Path
|
|
):
|
|
target = str(project_dir)
|
|
runner.invoke(cli, ["memory", "init", "tdd-workflow", "--target", target])
|
|
runner.invoke(
|
|
cli,
|
|
[
|
|
"metrics",
|
|
"record",
|
|
"tdd-workflow",
|
|
"--target",
|
|
target,
|
|
"--success",
|
|
"--quality",
|
|
"0.9",
|
|
],
|
|
)
|
|
|
|
result = runner.invoke(
|
|
cli, ["memory", "brief", "tdd-workflow", "--target", target]
|
|
)
|
|
assert result.exit_code == 0
|
|
assert "## Performance Summary" in result.output
|
|
assert "Success rate: 100.0%" in result.output
|
|
|
|
def test_memory_init_no_metrics_flag(self, runner: CliRunner, project_dir: Path):
|
|
result = runner.invoke(
|
|
cli,
|
|
["memory", "init", "coach", "--target", str(project_dir), "--no-metrics"],
|
|
)
|
|
assert result.exit_code == 0
|
|
assert not (project_dir / ".kaizen" / "metrics" / "coach").exists()
|