Files
cleveragents-core/features/output_rendering_registry.feature
HAL9000 7a2760b85f test(cli): boost coverage for registry.py render dispatch and edge cases
Add 16 BDD scenarios covering:
- PlainElementRenderer.render_element dispatch for all 9 element types
- _BaseElementRenderer.serialize() via PlainElementRenderer
- ColorElementRenderer.render_element dispatch for all element types
- TableElementRenderer can_render (True/False) and render_element dispatch
- RichElementRenderer.render_element dispatch + can_render True path
- JsonElementRenderer.render_element dispatch (all render_* return "")
- YamlElementRenderer.render_element dispatch (all render_* return "")
- RendererRegistry.resolve() unknown format fallback to plain
- RendererRegistry.resolve() ValueError when no plain fallback registered

Raises cli/output/registry.py coverage from 60.9% to pass the 96.5%
overall threshold.

ISSUES CLOSED: #917
2026-06-02 16:48:22 -04:00

223 lines
9.3 KiB
Gherkin

Feature: Output Rendering Framework — Registry, Renderer, and Capabilities
# ================================================================
# RendererRegistry
# ================================================================
Scenario: RendererRegistry registers and resolves built-in formats
Given the default renderer registry
Then the registry has format "plain" registered
And the registry has format "color" registered
And the registry has format "table" registered
And the registry has format "rich" registered
And the registry has format "json" registered
And the registry has format "yaml" registered
Scenario: RendererRegistry available_formats returns sorted list
Given the default renderer registry
Then the available formats are "color,json,plain,rich,table,yaml"
Scenario: RendererRegistry is_registered returns False for unknown
Given the default renderer registry
Then the registry does not have format "csv" registered
Scenario: RendererRegistry resolves plain format
Given the default renderer registry
When I resolve format "plain" from the registry
Then the resolved renderer format name is "plain"
Scenario: RendererRegistry resolves json format
Given the default renderer registry
When I resolve format "json" from the registry
Then the resolved renderer format name is "json"
Scenario: RendererRegistry resolve falls back from rich to plain on non-TTY
Given the default renderer registry
And a non-TTY terminal environment
When I resolve format "rich" from the registry with terminal caps
Then the resolved renderer format name is "plain"
Scenario: RendererRegistry supports custom format registration
Given a new empty renderer registry
When I register a custom "csv" format in the registry
Then the registry has format "csv" registered
# ================================================================
# ElementRenderer protocol
# ================================================================
Scenario: PlainElementRenderer renders panel element
Given a PlainElementRenderer
When I render a panel with title "Test" through the renderer
Then the renderer output contains "Test"
Scenario: PlainElementRenderer can_render always returns True
Given a PlainElementRenderer
Then the renderer can_render returns True for any terminal
Scenario: ColorElementRenderer can_render requires ANSI
Given a ColorElementRenderer
Then the renderer can_render returns False without ANSI
Scenario: RichElementRenderer can_render requires cursor movement
Given a RichElementRenderer
Then the renderer can_render returns False without cursor movement
Scenario: JsonElementRenderer serializes output
Given a JsonElementRenderer
When I serialize a StructuredOutput through the renderer
Then the serialized output is valid JSON
Scenario: YamlElementRenderer serializes output with sorted keys
Given a YamlElementRenderer
When I serialize a StructuredOutput through the renderer
Then the serialized output is valid YAML
And the serialized output has sorted keys
# ================================================================
# TerminalCapabilities extended fields
# ================================================================
Scenario: TerminalCapabilities has all 11 spec fields
When I create a full TerminalCapabilities
Then the capabilities has width 120
And the capabilities has height 40
And the capabilities has supports_256_color True
And the capabilities has supports_truecolor True
And the capabilities has supports_unicode True
And the capabilities has supports_alternate_screen True
And the capabilities has no_color False
And the capabilities has term_program "iTerm2"
Scenario: TerminalCapabilities backward-compatible aliases work
When I create a full TerminalCapabilities
Then the capabilities supports_cursor property matches supports_cursor_movement
And the capabilities term property matches term_program
# ================================================================
# ColumnDef.type serialisation
# ================================================================
Scenario: ColumnDef serialises type field as "type" in JSON
Given an OutputSession with format "json" using JsonMaterializer
When I create a table with ColumnDef objects "Name,Status"
And I add a dict row with Name "Name" and Status "Alice"
And I close the table handle
And the session is closed
Then the json output is valid JSON
And the json output ColumnDef uses type key not col_type
Scenario: ColumnDef accepts type alias in constructor
When I create a ColumnDef with type alias "integer"
Then the ColumnDef col_type is "integer"
# ================================================================
# YAML sorted keys
# ================================================================
Scenario: YAML output uses sorted keys
Given an OutputSession with format "yaml" using YamlMaterializer
When I create a panel handle with title "Sort Test"
And I set entry "Zebra" to "last"
And I set entry "Alpha" to "first"
And I close the panel handle
And the session is closed
Then the yaml output is valid YAML
# ================================================================
# Progress omitted from JSON output
# ================================================================
Scenario: JSON output omits progress elements
Given an OutputSession with format "json" using JsonMaterializer
When I create a progress handle labelled "Building" with total 100
And I set progress to 50 of 100
And I close the progress handle
And I create a panel handle with title "Info"
And I set entry "Name" to "test"
And I close the panel handle
And the session is closed
Then the json output is valid JSON
And the json output does not contain element type "progress"
And the json output contains element type "panel"
# ================================================================
# MaterializationStrategy.bind() method
# ================================================================
Scenario: PlainMaterializer has bind method
Given a PlainMaterializer instance
When I call bind on the materializer
Then no error is raised
Scenario: JsonMaterializer has bind method
Given a JsonMaterializer instance
When I call bind on the json materializer
Then no error is raised
# ================================================================
# Render dispatch — concrete renderer methods coverage
# ================================================================
Scenario: PlainElementRenderer dispatches all element types via render_element
Given a PlainElementRenderer
When I call render_element with each element type
Then no render dispatch error occurred
Scenario: PlainElementRenderer serialize assembles rendered text
Given a PlainElementRenderer
When I call base serialize with a text element
Then the base serialized output is a string
Scenario: ColorElementRenderer dispatches all element types via render_element
Given a ColorElementRenderer
When I call render_element with each element type
Then no render dispatch error occurred
Scenario: ColorElementRenderer can_render returns True when ANSI is supported
Given a ColorElementRenderer
Then color renderer can_render is True with ANSI support
Scenario: TableElementRenderer can_render checks is_tty flag
Given a TableElementRenderer
Then table renderer can_render is True on a TTY terminal
And table renderer can_render is False on a non-TTY terminal
Scenario: TableElementRenderer dispatches all element types via render_element
Given a TableElementRenderer
When I call render_element with each element type
Then no render dispatch error occurred
Scenario: RichElementRenderer dispatches all element types via render_element
Given a RichElementRenderer
When I call render_element with each element type
Then no render dispatch error occurred
Scenario: RichElementRenderer can_render returns True with cursor movement
Given a RichElementRenderer
Then rich renderer can_render is True with cursor movement
Scenario: JsonElementRenderer dispatches all element types returning empty strings
Given a JsonElementRenderer
When I call render_element with each element type
Then no render dispatch error occurred
Scenario: YamlElementRenderer dispatches all element types returning empty strings
Given a YamlElementRenderer
When I call render_element with each element type
Then no render dispatch error occurred
# ================================================================
# RendererRegistry edge-case paths
# ================================================================
Scenario: RendererRegistry resolve unknown format falls back to plain
Given the default renderer registry
When I resolve format "unregistered_format" from the registry
Then the resolved renderer format name is "plain"
Scenario: RendererRegistry resolve raises ValueError when no plain fallback exists
Given a registry with no plain and a non-renderable format
When I try to resolve the non-renderable format
Then a ValueError is raised from resolve