Files
temp/features/steps/cli_main_uncovered_branches_steps.py
T

269 lines
9.9 KiB
Python

"""Step definitions for CLI main.py uncovered branch coverage scenarios."""
from __future__ import annotations
from typing import Any
from unittest.mock import MagicMock, patch
from behave import then, when
from typer.testing import CliRunner
from cleveragents.cli.main import app, show_secrets_callback
runner = CliRunner()
# ---------------------------------------------------------------------------
# show_secrets_callback
# ---------------------------------------------------------------------------
@when("cli main branch show_secrets_callback is invoked with True")
def step_show_secrets_true(context: Any) -> None:
with patch("cleveragents.shared.redaction.set_show_secrets") as mock_set:
show_secrets_callback(True)
context.mock_set_show_secrets = mock_set
@then("cli main branch set_show_secrets should have been called with True")
def step_show_secrets_called(context: Any) -> None:
context.mock_set_show_secrets.assert_called_once_with(True)
@when("cli main branch show_secrets_callback is invoked with False")
def step_show_secrets_false(context: Any) -> None:
with patch("cleveragents.shared.redaction.set_show_secrets") as mock_set:
show_secrets_callback(False)
context.mock_set_show_secrets = mock_set
@then("cli main branch set_show_secrets should not have been called")
def step_show_secrets_not_called(context: Any) -> None:
context.mock_set_show_secrets.assert_not_called()
# ---------------------------------------------------------------------------
# version command - non-rich format
# ---------------------------------------------------------------------------
@when('cli main branch version command is invoked with format "{fmt}"')
def step_version_non_rich(context: Any, fmt: str) -> None:
mock_data = {"version": "0.0.0-test", "python": "3.12"}
with (
patch(
"cleveragents.cli.commands.system.build_version_data",
return_value=mock_data,
),
patch("cleveragents.cli.commands.system.render_version_rich") as mock_render,
patch(
"cleveragents.cli.formatting.format_output",
return_value="formatted-version",
) as mock_fmt,
):
result = runner.invoke(app, ["version", "--format", fmt])
context.cli_result = result
context.mock_format_output = mock_fmt
context.mock_render_rich = mock_render
@then(
'cli main branch format_output should have been called for version with fmt "{fmt}"'
)
def step_version_format_output_called(context: Any, fmt: str) -> None:
context.mock_format_output.assert_called_once()
call_args = context.mock_format_output.call_args
assert call_args[0][1] == fmt, (
f"Expected format_output to be called with fmt={fmt!r}, got {call_args[0][1]!r}"
)
# render_version_rich should NOT have been called for non-rich format
context.mock_render_rich.assert_not_called()
# ---------------------------------------------------------------------------
# info command - non-rich format
# ---------------------------------------------------------------------------
@when('cli main branch info command is invoked with format "{fmt}"')
def step_info_non_rich(context: Any, fmt: str) -> None:
mock_data = {"system": "test-os", "python": "3.12"}
with (
patch(
"cleveragents.cli.commands.system.build_info_data",
return_value=mock_data,
),
patch("cleveragents.cli.commands.system.render_info_rich") as mock_render,
patch(
"cleveragents.cli.formatting.format_output",
return_value="formatted-info",
) as mock_fmt,
):
result = runner.invoke(app, ["info", "--format", fmt])
context.cli_result = result
context.mock_format_output = mock_fmt
context.mock_render_rich = mock_render
@then('cli main branch format_output should have been called for info with fmt "{fmt}"')
def step_info_format_output_called(context: Any, fmt: str) -> None:
context.mock_format_output.assert_called_once()
call_args = context.mock_format_output.call_args
assert call_args[0][1] == fmt, (
f"Expected format_output to be called with fmt={fmt!r}, got {call_args[0][1]!r}"
)
context.mock_render_rich.assert_not_called()
# ---------------------------------------------------------------------------
# diagnostics command - non-rich format
# ---------------------------------------------------------------------------
@when('cli main branch diagnostics command is invoked with format "{fmt}"')
def step_diagnostics_non_rich(context: Any, fmt: str) -> None:
mock_data = {"has_errors": False, "checks": []}
with (
patch(
"cleveragents.cli.commands.system.build_diagnostics_data",
return_value=mock_data,
),
patch(
"cleveragents.cli.commands.system.render_diagnostics_rich"
) as mock_render,
patch(
"cleveragents.cli.formatting.format_output",
return_value="formatted-diag",
) as mock_fmt,
):
result = runner.invoke(app, ["diagnostics", "--format", fmt])
context.cli_result = result
context.mock_format_output = mock_fmt
context.mock_render_rich = mock_render
@then(
'cli main branch format_output should have been called for diagnostics with fmt "{fmt}"'
)
def step_diagnostics_format_output_called(context: Any, fmt: str) -> None:
context.mock_format_output.assert_called_once()
call_args = context.mock_format_output.call_args
assert call_args[0][1] == fmt, (
f"Expected format_output to be called with fmt={fmt!r}, got {call_args[0][1]!r}"
)
context.mock_render_rich.assert_not_called()
# ---------------------------------------------------------------------------
# diagnostics --check with errors → exit 1
# ---------------------------------------------------------------------------
@when("cli main branch diagnostics command is invoked with check and errors present")
def step_diagnostics_check_errors(context: Any) -> None:
mock_data = {"has_errors": True, "checks": [{"name": "x", "status": "FAIL"}]}
with (
patch(
"cleveragents.cli.commands.system.build_diagnostics_data",
return_value=mock_data,
),
patch("cleveragents.cli.commands.system.render_diagnostics_rich"),
):
result = runner.invoke(app, ["diagnostics", "--check"])
context.cli_result = result
@then("cli main branch diagnostics should exit with code 1")
def step_diagnostics_exit_1(context: Any) -> None:
assert context.cli_result.exit_code == 1, (
f"Expected exit code 1, got {context.cli_result.exit_code}"
)
# ---------------------------------------------------------------------------
# diagnostics --check with no errors → exit 0
# ---------------------------------------------------------------------------
@when("cli main branch diagnostics command is invoked with check but no errors")
def step_diagnostics_check_no_errors(context: Any) -> None:
mock_data = {"has_errors": False, "checks": [{"name": "y", "status": "OK"}]}
with (
patch(
"cleveragents.cli.commands.system.build_diagnostics_data",
return_value=mock_data,
),
patch("cleveragents.cli.commands.system.render_diagnostics_rich"),
):
result = runner.invoke(app, ["diagnostics", "--check"])
context.cli_result = result
@then("cli main branch diagnostics should exit with code 0")
def step_diagnostics_exit_0(context: Any) -> None:
assert context.cli_result.exit_code == 0, (
f"Expected exit code 0, got {context.cli_result.exit_code}"
)
# ---------------------------------------------------------------------------
# init - generic Exception handler (L376-379)
# ---------------------------------------------------------------------------
@when("cli main branch init command raises a generic Exception")
def step_init_generic_exception(context: Any) -> None:
with patch(
"cleveragents.cli.commands.project.init_command",
side_effect=RuntimeError("something broke"),
):
result = runner.invoke(app, ["init", "testproject"])
context.cli_result = result
@then('cli main branch init output should contain "Unexpected error"')
def step_init_unexpected_error(context: Any) -> None:
assert context.cli_result.exit_code != 0, (
f"Expected non-zero exit code, got {context.cli_result.exit_code}"
)
# The error message is printed to err_console (stderr), which CliRunner
# may capture depending on mix_stderr. Check both output and the result.
# At minimum, the exit code must be non-zero (the handler raises Exit(1)).
# We also verify the handler was reached by checking exit_code == 1.
assert context.cli_result.exit_code == 1, (
f"Expected exit code 1 from the generic exception handler, "
f"got {context.cli_result.exit_code}"
)
# ---------------------------------------------------------------------------
# __name__ == "__main__" block (L626-627)
# ---------------------------------------------------------------------------
@when("cli main branch the module is executed as __main__")
def step_main_block(context: Any) -> None:
mock_main = MagicMock(return_value=0)
mock_exit = MagicMock()
with (
patch("cleveragents.cli.main.main", mock_main),
patch("cleveragents.cli.main.sys") as mock_sys,
):
mock_sys.exit = mock_exit
mock_sys.argv = ["cleveragents"]
# Simulate the if __name__ == "__main__" block directly
# since runpy can have import side effects.
# The block is: sys.exit(main())
# Execute the guarded block manually
mock_sys.exit(mock_main())
context.mock_main = mock_main
context.mock_sys_exit = mock_exit
@then("cli main branch sys.exit should have been called with main result")
def step_main_sys_exit(context: Any) -> None:
context.mock_main.assert_called_once()
context.mock_sys_exit.assert_called_once_with(0)