Files
cleveragents-core/features/tui_materializer.feature
T
HAL9000 5e71221f61
CI / load-versions (push) Successful in 16s
CI / push-validation (push) Successful in 28s
CI / build (push) Successful in 33s
CI / lint (push) Successful in 50s
CI / typecheck (push) Successful in 1m0s
CI / quality (push) Successful in 1m8s
CI / security (push) Successful in 1m17s
CI / helm (push) Successful in 39s
CI / unit_tests (push) Successful in 6m53s
CI / docker (push) Successful in 1m55s
CI / integration_tests (push) Successful in 10m43s
CI / coverage (push) Successful in 13m43s
CI / status-check (push) Successful in 3s
CI / load-versions (pull_request) Successful in 13s
CI / push-validation (pull_request) Successful in 34s
CI / lint (pull_request) Successful in 48s
CI / quality (pull_request) Successful in 54s
CI / typecheck (pull_request) Successful in 59s
CI / security (pull_request) Successful in 1m12s
CI / build (pull_request) Successful in 51s
CI / helm (pull_request) Successful in 58s
CI / unit_tests (pull_request) Successful in 6m37s
CI / integration_tests (pull_request) Successful in 10m35s
CI / benchmark-publish (push) Has been cancelled
CI / benchmark-regression (push) Has been cancelled
CI / docker (pull_request) Failing after 13m18s
CI / coverage (pull_request) Failing after 28m20s
CI / status-check (pull_request) Has been cancelled
fix(tui): resolve lint and AmbiguousStep errors in TuiMaterializer
- Fix ruff format violations: collapse list comprehension in
  materializer.py, collapse function signature, collapse decorators
  and assertion in tui_materializer_steps.py, remove trailing
  whitespace in vulture_whitelist.py
- Remove duplicate Behave step definitions from tui_materializer_steps.py
  that conflicted with output_rendering_steps.py and
  project_commands_coverage_steps.py: create status handle,
  create code handle, close panel handle, close status handle,
  no error should be raised
- Rename render_element_for_tui step texts to avoid conflict with
  tui_first_run_steps.py: rendered text should contain/be empty ->
  render output should contain/be empty
- Update tui_materializer.feature to use renamed step texts and
  replace no error should be raised with materializer still running

ISSUES CLOSED: #11164
2026-06-15 11:14:31 +00:00

234 lines
12 KiB
Gherkin

Feature: TUI Materializer
As a TUI developer
I want a TuiMaterializer that bridges the Output Rendering Framework to Textual widgets
So that all CLI command producers can render in the TUI without modification
Background:
Given the tui materializer module is imported
# ── Module exports ────────────────────────────────────────────────────────
Scenario: TuiMaterializer is importable from tui.materializer
Then TuiMaterializer should be importable from tui.materializer
And TuiWidgetEvent should be importable from tui.materializer
And TuiWidgetEventType should be importable from tui.materializer
And render_element_for_tui should be importable from tui.materializer
# ── TuiMaterializer instantiation ────────────────────────────────────────
Scenario: TuiMaterializer can be instantiated without arguments
When I create a TuiMaterializer without a callback
Then the materializer strategy_name should be "tui"
And the materializer supports_incremental_updates should be True
And the materializer events list should be empty
Scenario: TuiMaterializer can be instantiated with a callback
When I create a TuiMaterializer with a callback
Then the materializer strategy_name should be "tui"
# ── MaterializationStrategy protocol ─────────────────────────────────────
Scenario: TuiMaterializer implements on_session_begin
When I create a TuiMaterializer without a callback
And I call on_session_begin with a mock session
Then the materializer should still be running
Scenario: TuiMaterializer emits element_created event for panel
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create a panel handle titled "Test Panel"
Then an element_created event should be emitted
And the event element_kind should be "panel"
And the event rendered_text should contain "Test Panel"
Scenario: TuiMaterializer emits element_created event for table
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create a table handle titled "Results"
Then an element_created event should be emitted
And the event element_kind should be "table"
And the event rendered_text should contain "Results"
Scenario: TuiMaterializer emits element_created event for status
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create a status handle with message "Operation complete"
Then an element_created event should be emitted
And the event element_kind should be "status"
And the event rendered_text should contain "Operation complete"
Scenario: TuiMaterializer emits element_created event for progress
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create a progress handle with label "Loading"
Then an element_created event should be emitted
And the event element_kind should be "progress"
And the event rendered_text should contain "Loading"
Scenario: TuiMaterializer emits element_created event for code block
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create a code handle with content "print('hello')" and language "python"
Then an element_created event should be emitted
And the event element_kind should be "code"
And the event rendered_text should contain "print('hello')"
Scenario: TuiMaterializer emits element_created event for separator
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create a separator handle
Then an element_created event should be emitted
And the event element_kind should be "separator"
Scenario: TuiMaterializer emits element_created event for action hint
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create an action hint handle with command "agents plan list"
Then an element_created event should be emitted
And the event element_kind should be "action_hint"
And the event rendered_text should contain "agents plan list"
Scenario: TuiMaterializer emits element_closed event when handle is closed
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create a panel handle titled "Closing Panel"
And I close the panel handle
Then an element_closed event should be emitted
And the closed event rendered_text should contain "Closing Panel"
Scenario: TuiMaterializer emits session_end event when session ends
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create a status handle with message "Done"
And I close the session
Then a session_end event should be emitted
# ── Callback invocation ───────────────────────────────────────────────────
Scenario: TuiMaterializer invokes callback on element_created
When I create a TuiMaterializer with a callback
And I use the materializer with an OutputSession
And I create a status handle with message "Callback test"
Then the callback should have been called
And the callback event type should be "element_created"
Scenario: TuiMaterializer invokes callback on element_closed
When I create a TuiMaterializer with a callback
And I use the materializer with an OutputSession
And I create a status handle with message "Close callback test"
And I close the status handle
Then the callback should have been called with event_type "element_closed"
Scenario: TuiMaterializer invokes callback on session_end
When I create a TuiMaterializer with a callback
And I use the materializer with an OutputSession
And I close the session
Then the callback should have been called with event_type "session_end"
# ── rendered_output property ──────────────────────────────────────────────
Scenario: rendered_output returns empty string when no elements
When I create a TuiMaterializer without a callback
Then the materializer rendered_output should be empty
Scenario: rendered_output accumulates closed element text
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create and close a status handle with message "Accumulated"
Then the materializer rendered_output should contain "Accumulated"
# ── render_element_for_tui ────────────────────────────────────────────────
Scenario: render_element_for_tui renders Panel with title and entries
When I render a Panel element with title "Info" and entry "key" "value"
Then the render output should contain "Info"
And the render output should contain "key"
And the render output should contain "value"
Scenario: render_element_for_tui renders Table with columns and rows
When I render a Table element with title "Data" and column "Name"
Then the render output should contain "Data"
And the render output should contain "Name"
Scenario: render_element_for_tui renders StatusMessage ok level
When I render a StatusMessage element with level "ok" and message "Success"
Then the render output should contain "ok"
And the render output should contain "Success"
Scenario: render_element_for_tui renders StatusMessage error level
When I render a StatusMessage element with level "error" and message "Failed"
Then the render output should contain "error"
And the render output should contain "Failed"
Scenario: render_element_for_tui renders indeterminate ProgressIndicator
When I render an indeterminate ProgressIndicator with label "Thinking"
Then the render output should contain "Thinking"
Scenario: render_element_for_tui renders determinate ProgressIndicator
When I render a determinate ProgressIndicator with label "Loading" current 5 total 10
Then the render output should contain "Loading"
And the render output should contain "50%"
Scenario: render_element_for_tui renders Tree with root and children
When I render a Tree element with root "root" and child "child1"
Then the render output should contain "root"
And the render output should contain "child1"
Scenario: render_element_for_tui renders CodeBlock with language
When I render a CodeBlock element with language "python" and content "x = 1"
Then the render output should contain "python"
And the render output should contain "x = 1"
Scenario: render_element_for_tui renders DiffBlock with hunks
When I render a DiffBlock element with file_a "old.py" and file_b "new.py"
Then the render output should contain "old.py"
And the render output should contain "new.py"
Scenario: render_element_for_tui renders Separator line style
When I render a Separator element with style "line"
Then the render output should contain "-"
Scenario: render_element_for_tui renders Separator blank style
When I render a Separator element with style "blank"
Then the render output should be empty
Scenario: render_element_for_tui renders Separator double style
When I render a Separator element with style "double"
Then the render output should contain "="
Scenario: render_element_for_tui renders ActionHint with commands
When I render an ActionHint element with command "agents plan list"
Then the render output should contain "agents plan list"
Scenario: render_element_for_tui renders TextBlock content
When I render a TextBlock element with content "Hello world"
Then the render output should contain "Hello world"
Scenario: render_element_for_tui renders TextBlock with indent
When I render a TextBlock element with content "indented" and indent 4
Then the render output should contain " indented"
# ── A2A event routing ─────────────────────────────────────────────────────
Scenario: route_permission_request emits permission_request event
When I create a TuiMaterializer without a callback
And I route a permission request for "src/main.py" with type "file_write"
Then a permission_request event should be emitted
And the permission event extra should be the InlinePermissionQuestion
And the permission event rendered_text should contain "src/main.py"
Scenario: route_thought_block emits thought_block event
When I create a TuiMaterializer without a callback
And I route a thought block with content "I am thinking"
Then a thought_block event should be emitted
And the thought event extra should be the ThoughtBlock
And the thought event rendered_text should contain "I am thinking"
# ── Thread safety ─────────────────────────────────────────────────────────
Scenario: TuiMaterializer events list is thread-safe
When I create a TuiMaterializer without a callback
And I use the materializer with an OutputSession
And I create multiple status handles concurrently
Then all events should be recorded without data corruption