Files
cleveragents-core/features/cli_output_formats.feature
T
brent.edwards f2be43dcc2 chore(cli): polish help and output
Centralize CLI output through shared renderers module with get_console()
and get_err_console() accessors. Introduce ColumnSpec-based table rendering
for plan list, resource list, and actor list commands. Add _FORMAT_HELP
constant and fmt= parameter threading for consistent format handling.

Includes Behave BDD tests for format output validation, Robot Framework
integration tests for CLI formatting consistency, and CHANGELOG entry.

ISSUES CLOSED: #210
2026-03-20 00:25:44 +00:00

279 lines
12 KiB
Gherkin

Feature: CLI output formats parity
As a developer using the CleverAgents CLI
I want all action and plan commands to support --format json|yaml|plain|table|rich
So that I can integrate CLI output with external tooling
Background:
Given a CLI output format test runner
And a mocked lifecycle service for format tests
# Action list --format json
Scenario: Action list outputs valid JSON
Given there are actions for format testing
When I run action list with --format json
Then the output should be valid JSON
And the JSON should contain key "namespaced_name"
# Action show --format yaml
Scenario: Action show outputs valid YAML
Given there is a single action for format testing
When I run action show with --format yaml
Then the output should be valid YAML
And the YAML should contain key "namespaced_name"
# Plan list --format json
Scenario: Plan lifecycle-list outputs valid JSON
Given there are plans for format testing
When I run plan lifecycle-list with --format json
Then the output should be valid JSON
And the JSON should contain key "plan_id"
# Plan status --format json (single plan)
Scenario: Plan status single plan outputs valid JSON
Given there is a single plan for format testing
When I run plan status with plan id and --format json
Then the output should be valid JSON
And the JSON should contain key "processing_state"
# Plan status --format plain (single plan)
Scenario: Plan status single plan outputs plain text
Given there is a single plan for format testing
When I run plan status with plan id and --format plain
Then the format output should contain "plan_id:"
And the format output should contain "processing_state:"
# Action list --format table
Scenario: Action list outputs table format
Given there are actions for format testing
When I run action list with --format table
Then the format output should contain "namespaced_name"
# Action list --format plain
Scenario: Action list outputs plain format
Given there are actions for format testing
When I run action list with --format plain
Then the format output should contain "namespaced_name:"
# Action archive --format json
Scenario: Action archive outputs valid JSON
Given there is an archivable action for format testing
When I run action archive with --format json
Then the output should be valid JSON
And the JSON should contain key "archived"
# Plan status list all --format json
Scenario: Plan status no args outputs valid JSON for list
Given there are plans for format status listing
When I run plan status without id and --format json
Then the output should be valid JSON
And the JSON should contain key "plan_id"
# Plan use --format json
Scenario: Plan use outputs valid JSON
Given there is an action for plan use format test
When I run plan use with --format json
Then the output should be valid JSON
And the JSON should contain key "plan_id"
# Plan cancel --format json
Scenario: Plan cancel outputs valid JSON
Given there is a plan for cancel format test
When I run plan cancel with --format json
Then the output should be valid JSON
And the JSON should contain key "processing_state"
# Format consistency: same data, different renders
Scenario: JSON and YAML contain the same action keys
Given there is a single action for format testing
When I run action show with --format json
And I save the output keys as json_keys
And I run action show with --format yaml
And I save the output keys as yaml_keys
Then json_keys and yaml_keys should match
# Direct formatting module tests
Scenario: Format output handles all format types for dict
When I call format_output with a dict and format json
Then the format result should be valid JSON dict
When I call format_output with a dict and format yaml
Then the format result should be valid YAML dict
When I call format_output with a dict and format plain
Then the format result should contain plain key-value pairs
When I call format_output with a dict and format table
Then the format result should contain table output
When I call format_output with a dict and format rich
Then the format result should be valid JSON dict
Scenario: Format output handles list data
When I call format_output with a list and format plain
Then the format result should contain separator lines
Scenario: Serialize value handles enums and nested dicts
When I call serialize_value with enum and nested data
Then the serialized result should have string enum values
# -- Renderer consolidation tests (issue #210) --
Scenario: render_detail produces valid JSON for non-rich format
When I call render_detail with a sample dict and format json
Then the captured output should be valid JSON
And the captured JSON should contain field "name"
Scenario: render_detail produces valid YAML for non-rich format
When I call render_detail with a sample dict and format yaml
Then the captured output should be valid YAML
And the captured YAML should contain field "name"
Scenario: render_detail produces plain key-value for plain format
When I call render_detail with a sample dict and format plain
Then the captured plain output should contain "name:"
Scenario: render_list produces valid JSON with stable column order
When I call render_list with sample rows columns and format json
Then the captured output should be valid JSON list
And each JSON item should have keys in column order
Scenario: render_list produces valid YAML with stable column order
When I call render_list with sample rows columns and format yaml
Then the captured output should be valid YAML list
Scenario: render_list produces rich table for rich format
When I call render_list with sample rows columns and format rich
Then the captured output should contain a table header
Scenario: render_error writes to stderr with label and message
When I call render_error with label "NotFound" and message "missing item"
Then the stderr should contain "NotFound"
And the stderr should contain "missing item"
Scenario: render_error produces JSON envelope for json format
When I call render_error with label "NotFound" and message "missing" and format json
Then the stderr should be valid JSON
And the JSON should contain nested key "error.code"
Scenario: render_success produces green checkmark for rich format
When I call render_success with message "Done" and format rich
Then the captured output should contain "Done"
Scenario: render_success produces ASCII OK for plain format
When I call render_success with message "Done" and format plain
Then the captured output should contain "OK: Done"
Scenario: render_empty produces yellow message for rich format
When I call render_empty with entity "actions" and format rich
Then the captured output should contain "No actions found"
Scenario: render_empty produces JSON empty array for json format
When I call render_empty with entity "actions" and format json
Then the captured output should be valid JSON
And the JSON should be an empty list
Scenario: render_warning produces yellow message for rich format
When I call render_warning with message "Check config" and format rich
Then the captured output should contain "Check config"
Scenario: render_warning produces JSON for json format
When I call render_warning with message "Check config" and format json
Then the captured output should be valid JSON
And the captured JSON should contain field "status"
Scenario: render_warning produces YAML for yaml format
When I call render_warning with message "Check config" and format yaml
Then the captured output should be valid YAML
And the captured YAML should contain field "status"
Scenario: render_warning produces ASCII for plain format
When I call render_warning with message "Check config" and format plain
Then the captured plain output should contain "WARNING: Check config"
Scenario: render_success produces JSON for json format without data
When I call render_success with message "Done" and format json
Then the captured output should be valid JSON
And the captured JSON should contain field "status"
Scenario: Color format produces plain-like output for format_output
When I call format_output with a dict and format color
Then the format result should contain plain key-value pairs
Scenario: Plain format output is ASCII-only
When I call render_detail with unicode data and format plain
Then the captured plain output should be pure ASCII
Scenario: FORMAT_HELP constant is consistent
Then the FORMAT_HELP string should mention all six formats
# -- PR #787 regression tests (P2-5, P2-6, P2-7) --
Scenario: render_detail FieldSpec accessor returning zero displays "0" not blank
When I call render_detail with a FieldSpec accessor returning 0 and format rich
Then the captured output should contain "0"
Scenario: render_detail FieldSpec accessor returning False displays "False"
When I call render_detail with a FieldSpec accessor returning False and format rich
Then the captured output should contain "False"
Scenario: render_error plain format contains label and message without Rich markup
When I call render_error with label "Test Error" and message "Something failed" and format plain
Then the stderr should contain "Test Error"
And the stderr should contain "Something failed"
And the stderr should not contain Rich markup
Scenario: render_detail with FieldSpec fields and rich format produces output
When I call render_detail with FieldSpec fields and format rich
Then the captured output should contain "Item Detail"
And the captured output should contain "test-item"
# -- PR #787 additional coverage (T1-T9, M10-M12) --
Scenario: render_error with recovery and details produces JSON envelope with details
When I call render_error with details and recovery and format json
Then the stderr should be valid JSON
And the JSON should contain nested key "error.details"
And the JSON should contain nested key "error.recovery"
Scenario: render_error with empty details emits empty details object
When I call render_error with no details and format json
Then the stderr should be valid JSON
And the JSON should contain nested key "error.details"
Scenario: render_list with plain format outputs key-value pairs
When I call render_list with sample rows columns and format plain
Then the captured plain output should contain "name:"
Scenario: render_list with table format outputs table
When I call render_list with sample rows columns and format table
Then the captured plain output should contain "name"
Scenario: render_empty with plain format shows message
When I call render_empty with entity "items" and format plain
Then the captured plain output should contain "No items found"
Scenario: render_empty with yaml format shows empty list
When I call render_empty with entity "items" and format yaml
Then the captured output should be valid YAML
Scenario: render_empty with table format shows message
When I call render_empty with entity "items" and format table
Then the captured plain output should contain "No items found"
Scenario: render_success with yaml format produces structured output
When I call render_success with message "Done" and format yaml
Then the captured output should be valid YAML
And the captured YAML should contain field "status"
Scenario: render_detail with None accessor value shows empty string
When I call render_detail with a FieldSpec accessor returning None and format rich
Then the captured output should contain "Name"
Scenario: render_list with empty dict value shows empty cell
When I call render_list with None cell values and format rich
Then the captured output should contain "Results"
Scenario: render_warning with color format shows warning text
When I call render_warning with message "Heads up" and format color
Then the captured output should contain "Heads up"
Scenario: render_detail with color format produces output
When I call render_detail with a sample dict and format color
Then the captured plain output should contain "name:"