"""Step definitions for cli_renderers_coverage.feature. Tests the four shared renderer helpers (render_error, render_success, render_warning, render_empty) across all output formats to ensure full branch coverage of ``cleveragents.cli.renderers``. """ from __future__ import annotations import contextlib from io import StringIO from behave import given, then, when from behave.runner import Context from rich.console import Console from cleveragents.cli.renderers import ( render_empty, render_error, render_success, render_warning, ) @given("a captured console for renderers") def step_captured_console(context: Context) -> None: """Create a Rich Console that writes to a StringIO buffer.""" context.renderer_buf = StringIO() context.renderer_stdout = StringIO() context.renderer_console = Console( file=context.renderer_buf, width=200, no_color=True, highlight=False, force_terminal=False, ) context.renderer_recovery = None def _get_output(context: Context) -> str: """Combine Rich console buffer and any direct stdout writes.""" return context.renderer_buf.getvalue() + context.renderer_stdout.getvalue() @given('a recovery hint "{recovery}"') def step_set_recovery(context: Context, recovery: str) -> None: """Store a recovery hint for the next renderer call.""" context.renderer_recovery = recovery # --------------------------------------------------------------------------- # render_error # --------------------------------------------------------------------------- @when('I call render_error with label "{label}" message "{msg}" fmt "{fmt}"') def step_call_render_error(context: Context, label: str, msg: str, fmt: str) -> None: """Invoke render_error with the given parameters.""" recovery = getattr(context, "renderer_recovery", None) with contextlib.redirect_stdout(context.renderer_stdout): render_error( label, msg, fmt=fmt, recovery=recovery, console=context.renderer_console, ) # --------------------------------------------------------------------------- # render_success # --------------------------------------------------------------------------- @when('I call render_success with message "{msg}" fmt "{fmt}"') def step_call_render_success(context: Context, msg: str, fmt: str) -> None: """Invoke render_success with the given parameters.""" with contextlib.redirect_stdout(context.renderer_stdout): render_success(msg, fmt=fmt, console=context.renderer_console) # --------------------------------------------------------------------------- # render_warning # --------------------------------------------------------------------------- @when('I call render_warning with message "{msg}" fmt "{fmt}"') def step_call_render_warning(context: Context, msg: str, fmt: str) -> None: """Invoke render_warning with the given parameters.""" with contextlib.redirect_stdout(context.renderer_stdout): render_warning(msg, fmt=fmt, console=context.renderer_console) # --------------------------------------------------------------------------- # render_empty # --------------------------------------------------------------------------- @when('I call render_empty with entity_type "{etype}" fmt "{fmt}"') def step_call_render_empty(context: Context, etype: str, fmt: str) -> None: """Invoke render_empty with the given parameters.""" recovery = getattr(context, "renderer_recovery", None) with contextlib.redirect_stdout(context.renderer_stdout): render_empty( etype, fmt=fmt, recovery=recovery, console=context.renderer_console, ) # --------------------------------------------------------------------------- # THEN assertions # --------------------------------------------------------------------------- @then('the renderer output should contain "{expected}"') def step_renderer_output_contains(context: Context, expected: str) -> None: """Assert the captured output contains the expected text.""" output = _get_output(context) assert expected in output, ( f"Expected {expected!r} in renderer output, got:\n{output}" )