"""Step definitions for materializers_coverage_r3.feature. These steps target uncovered lines in materializers.py: - Line 344: _BaseBufferStrategy.on_element_closed with final_state=None - Line 473: _LiveMaterializationStrategy._render_element base class - Lines 486-487: _LiveMaterializationStrategy.on_element_created with initial_state=None - Line 495: _LiveMaterializationStrategy.on_element_updated with unknown handle_id - Line 497: _LiveMaterializationStrategy.on_element_updated for frozen element - Line 509: _LiveMaterializationStrategy.on_element_closed with unknown handle_id - Line 550: _LiveMaterializationStrategy._render_frame with empty dirty set - Line 610: _AccumulateStrategy.on_element_updated returns immediately """ from __future__ import annotations from unittest.mock import patch from behave import given, then, when from behave.runner import Context from cleveragents.cli.output.handles import ( ElementClosed, ElementCreated, ElementUpdated, Panel, StatusMessage, ) from cleveragents.cli.output.materializers import ( JsonMaterializer, PlainMaterializer, _LiveMaterializationStrategy, ) # =========================================================================== # Line 344: _BaseBufferStrategy.on_element_closed with final_state=None # =========================================================================== @given("matcov3 a PlainMaterializer instance") def step_matcov3_given_plain(context: Context) -> None: context.matcov3_plain = PlainMaterializer() @given('matcov3 the strategy has a registered handle "{handle_id}" at index {idx:d}') def step_matcov3_register_handle(context: Context, handle_id: str, idx: int) -> None: # Simulate on_element_created so the handle is registered in _index_map event = ElementCreated( event_type="created", handle_id=handle_id, element_kind="panel", declaration_index=idx, initial_state=Panel(title="Placeholder"), ) context.matcov3_plain.on_element_created(event) @when( 'matcov3 an ElementClosed event with handle "{handle_id}" and no final state is dispatched' ) def step_matcov3_close_no_final_state(context: Context, handle_id: str) -> None: event = ElementClosed( event_type="closed", handle_id=handle_id, element_kind="panel", final_state=None, # This triggers the early return on line 344 ) try: context.matcov3_plain.on_element_closed(event) context.matcov3_error = None except Exception as exc: context.matcov3_error = exc @then("matcov3 the plain strategy output is empty") def step_matcov3_plain_output_empty(context: Context) -> None: output = context.matcov3_plain.get_output() assert output == "", f"Expected empty output, got {output!r}" assert context.matcov3_error is None, f"Unexpected error: {context.matcov3_error}" # =========================================================================== # Line 473: _LiveMaterializationStrategy._render_element base class # =========================================================================== @given("matcov3 a raw LiveMaterializationStrategy instance") def step_matcov3_given_live_strategy(context: Context) -> None: context.matcov3_live = _LiveMaterializationStrategy() @given('matcov3 a StatusMessage element with message "{msg}"') def step_matcov3_given_status_element(context: Context, msg: str) -> None: context.matcov3_status_element = StatusMessage(message=msg, level="info") @when("matcov3 I call the live base class _render_element") def step_matcov3_call_live_render(context: Context) -> None: try: context.matcov3_live_render_result = context.matcov3_live._render_element( context.matcov3_status_element ) context.matcov3_error = None except Exception as exc: context.matcov3_error = exc context.matcov3_live_render_result = "" @then('matcov3 the rendered text contains "{text}"') def step_matcov3_rendered_contains(context: Context, text: str) -> None: assert context.matcov3_error is None, f"Unexpected error: {context.matcov3_error}" assert text in context.matcov3_live_render_result, ( f"Expected {text!r} in {context.matcov3_live_render_result!r}" ) # =========================================================================== # Lines 486-487: _LiveMaterializationStrategy.on_element_created # with initial_state=None # =========================================================================== @when( "matcov3 an ElementCreated event with no initial state is dispatched to the live strategy" ) def step_matcov3_live_created_no_initial(context: Context) -> None: context.matcov3_decl_idx = 3 event = ElementCreated( event_type="created", handle_id="hdl-no-initial", element_kind="panel", declaration_index=context.matcov3_decl_idx, initial_state=None, # Triggers lines 486-487 ) # Mock time.monotonic so _maybe_render_frame triggers a frame render patcher = patch("time.monotonic", return_value=999999.0) patcher.start() context.add_cleanup(patcher.stop) try: context.matcov3_live.on_element_created(event) context.matcov3_error = None except Exception as exc: context.matcov3_error = exc @then("matcov3 the live strategy has an empty rendered entry at the declaration index") def step_matcov3_live_empty_rendered(context: Context) -> None: assert context.matcov3_error is None, f"Unexpected error: {context.matcov3_error}" idx = context.matcov3_decl_idx assert idx in context.matcov3_live._rendered, ( f"Declaration index {idx} not in _rendered" ) assert context.matcov3_live._rendered[idx] == "", ( f"Expected empty string at index {idx}, got {context.matcov3_live._rendered[idx]!r}" ) @then("matcov3 the live strategy has height zero at the declaration index") def step_matcov3_live_zero_height(context: Context) -> None: idx = context.matcov3_decl_idx assert idx in context.matcov3_live._heights, ( f"Declaration index {idx} not in _heights" ) assert context.matcov3_live._heights[idx] == 0, ( f"Expected height 0 at index {idx}, got {context.matcov3_live._heights[idx]}" ) # =========================================================================== # Line 495: _LiveMaterializationStrategy.on_element_updated # with unknown handle_id # =========================================================================== @when( 'matcov3 an ElementUpdated event for unknown handle "{handle_id}" is dispatched to the live strategy' ) def step_matcov3_live_update_unknown(context: Context, handle_id: str) -> None: event = ElementUpdated( event_type="updated", handle_id=handle_id, element_kind="panel", update_type="content", element_snapshot=StatusMessage(message="ghost update"), ) try: context.matcov3_live.on_element_updated(event) context.matcov3_error = None except Exception as exc: context.matcov3_error = exc @then("matcov3 the live strategy rendered dict is empty") def step_matcov3_live_rendered_empty(context: Context) -> None: assert context.matcov3_error is None, f"Unexpected error: {context.matcov3_error}" assert len(context.matcov3_live._rendered) == 0, ( f"Expected empty _rendered, got {context.matcov3_live._rendered}" ) # =========================================================================== # Line 497: _LiveMaterializationStrategy.on_element_updated # for a frozen (closed) element # =========================================================================== @given( 'matcov3 a live element "{handle_id}" is created and then closed at index {idx:d}' ) def step_matcov3_live_create_and_close( context: Context, handle_id: str, idx: int ) -> None: context.matcov3_frozen_handle_id = handle_id context.matcov3_frozen_idx = idx # Mock time to allow frames to render patcher = patch("time.monotonic", return_value=999999.0) patcher.start() context.add_cleanup(patcher.stop) # Create the element create_event = ElementCreated( event_type="created", handle_id=handle_id, element_kind="status", declaration_index=idx, initial_state=StatusMessage(message="frozen-element"), ) context.matcov3_live.on_element_created(create_event) # Close the element (adds to _closed_indices) close_event = ElementClosed( event_type="closed", handle_id=handle_id, element_kind="status", final_state=StatusMessage(message="frozen-element-final"), ) context.matcov3_live.on_element_closed(close_event) @when( 'matcov3 an ElementUpdated event for handle "{handle_id}" is dispatched to the live strategy' ) def step_matcov3_live_update_frozen(context: Context, handle_id: str) -> None: event = ElementUpdated( event_type="updated", handle_id=handle_id, element_kind="status", update_type="content", element_snapshot=StatusMessage(message="should-be-ignored"), ) try: context.matcov3_live.on_element_updated(event) context.matcov3_error = None except Exception as exc: context.matcov3_error = exc @then("matcov3 no error is raised for the frozen update") def step_matcov3_no_error_frozen(context: Context) -> None: assert context.matcov3_error is None, f"Unexpected error: {context.matcov3_error}" # Verify the update was ignored - rendered content should still be the final state idx = context.matcov3_frozen_idx rendered = context.matcov3_live._rendered.get(idx, "") assert "should-be-ignored" not in rendered, ( f"Frozen element should not have been updated, but got: {rendered!r}" ) # =========================================================================== # Line 509: _LiveMaterializationStrategy.on_element_closed # with unknown handle_id # =========================================================================== @when( 'matcov3 an ElementClosed event for unknown handle "{handle_id}" is dispatched to the live strategy' ) def step_matcov3_live_close_unknown(context: Context, handle_id: str) -> None: event = ElementClosed( event_type="closed", handle_id=handle_id, element_kind="panel", final_state=Panel(title="Ghost Close"), ) try: context.matcov3_live.on_element_closed(event) context.matcov3_error = None except Exception as exc: context.matcov3_error = exc @then("matcov3 the live strategy closed indices set is empty") def step_matcov3_live_closed_indices_empty(context: Context) -> None: assert context.matcov3_error is None, f"Unexpected error: {context.matcov3_error}" assert len(context.matcov3_live._closed_indices) == 0, ( f"Expected empty _closed_indices, got {context.matcov3_live._closed_indices}" ) # =========================================================================== # Line 550: _LiveMaterializationStrategy._render_frame with empty dirty set # =========================================================================== @when("matcov3 I call _render_frame on the live strategy with an empty dirty set") def step_matcov3_live_render_frame_empty_dirty(context: Context) -> None: # Ensure dirty set is empty (it is by default on a fresh instance) assert len(context.matcov3_live._dirty) == 0, ( f"Expected empty dirty set, got {context.matcov3_live._dirty}" ) try: # _render_frame expects caller to hold the lock with context.matcov3_live._lock: context.matcov3_live._render_frame() context.matcov3_error = None except Exception as exc: context.matcov3_error = exc @then("matcov3 the live strategy stream is still empty") def step_matcov3_live_stream_empty(context: Context) -> None: assert context.matcov3_error is None, f"Unexpected error: {context.matcov3_error}" output = context.matcov3_live.get_output() assert output == "", f"Expected empty stream output, got {output!r}" # =========================================================================== # Line 610: _AccumulateStrategy.on_element_updated returns immediately # =========================================================================== @given("matcov3 a JsonMaterializer instance") def step_matcov3_given_json_materializer(context: Context) -> None: context.matcov3_json = JsonMaterializer() @when("matcov3 an ElementUpdated event is dispatched to the accumulate strategy") def step_matcov3_accum_update(context: Context) -> None: event = ElementUpdated( event_type="updated", handle_id="hdl-accum-test", element_kind="status", update_type="content", element_snapshot=StatusMessage(message="accum update ignored"), ) try: result = context.matcov3_json.on_element_updated(event) context.matcov3_accum_result = result context.matcov3_error = None except Exception as exc: context.matcov3_error = exc @then("matcov3 no error is raised for the accumulate update") def step_matcov3_no_error_accum(context: Context) -> None: assert context.matcov3_error is None, f"Unexpected error: {context.matcov3_error}"