Files
temp/features/steps/validation_pipeline_stream_coverage_steps.py
2026-02-25 10:03:57 +00:00

222 lines
6.6 KiB
Python

"""Step definitions for validation_pipeline_stream_coverage.feature.
Exercises the _ThreadLocalStream helper methods that lack coverage:
- encoding property (line 58)
- writable() method (line 61)
- readable() method (line 64)
- flush() with active buffer (line 75)
- isatty() method (line 79)
All tests use a simple mock original stream — no real I/O needed.
"""
from __future__ import annotations
from typing import Any
from behave import given, then, when
from behave.runner import Context
from cleveragents.application.services.validation_pipeline import (
_ThreadLocalStream,
)
# ---------------------------------------------------------------------------
# Mock original stream
# ---------------------------------------------------------------------------
class _MockOriginalStream:
"""Configurable mock that mimics a real stdout/stderr."""
def __init__(self) -> None:
self.encoding: str = "utf-8"
self._has_encoding: bool = True
self._isatty_return: bool = False
self._written: list[str] = []
self._flushed: bool = False
def write(self, s: str) -> int:
self._written.append(s)
return len(s)
def flush(self) -> None:
self._flushed = True
def isatty(self) -> bool:
return self._isatty_return
class _NoEncodingStream:
"""Mock stream without an encoding attribute."""
def write(self, s: str) -> int:
return len(s)
def flush(self) -> None:
pass
def isatty(self) -> bool:
return False
# ---------------------------------------------------------------------------
# Background
# ---------------------------------------------------------------------------
@given("a thread-local stream wrapping a mock original stream")
def step_given_tl_stream(context: Context) -> None:
context.tls_original = _MockOriginalStream()
context.tls_stream = _ThreadLocalStream(context.tls_original)
context.tls_result: Any = None
context.tls_captured: str = ""
context.tls_error: Exception | None = None
# ---------------------------------------------------------------------------
# Given steps
# ---------------------------------------------------------------------------
@given('the original stream has encoding "{enc}"')
def step_given_encoding(context: Context, enc: str) -> None:
context.tls_original.encoding = enc
@given("the original stream has no encoding attribute")
def step_given_no_encoding(context: Context) -> None:
context.tls_stream = _ThreadLocalStream(_NoEncodingStream())
@given("the original stream isatty returns True")
def step_given_isatty_true(context: Context) -> None:
context.tls_original._isatty_return = True
@given("the original stream isatty returns False")
def step_given_isatty_false(context: Context) -> None:
context.tls_original._isatty_return = False
@given("capture is started on the thread-local stream")
def step_given_capture_started(context: Context) -> None:
context.tls_stream.start_capture()
# ---------------------------------------------------------------------------
# When steps
# ---------------------------------------------------------------------------
@when("I read the thread-local stream encoding")
def step_when_read_encoding(context: Context) -> None:
context.tls_result = context.tls_stream.encoding
@when("I check if the thread-local stream is writable")
def step_when_check_writable(context: Context) -> None:
context.tls_result = context.tls_stream.writable()
@when("I check if the thread-local stream is readable")
def step_when_check_readable(context: Context) -> None:
context.tls_result = context.tls_stream.readable()
@when("I flush the thread-local stream")
def step_when_flush(context: Context) -> None:
try:
context.tls_stream.flush()
context.tls_error = None
except Exception as exc:
context.tls_error = exc
@when("I check if the thread-local stream isatty")
def step_when_check_isatty(context: Context) -> None:
context.tls_result = context.tls_stream.isatty()
@when('I write "{text}" to the thread-local stream')
def step_when_write(context: Context, text: str) -> None:
context.tls_stream.write(text)
@when("capture is stopped on the thread-local stream")
def step_when_stop_capture(context: Context) -> None:
context.tls_captured = context.tls_stream.stop_capture()
# ---------------------------------------------------------------------------
# Then steps
# ---------------------------------------------------------------------------
@then('the encoding should be "{enc}"')
def step_then_encoding(context: Context, enc: str) -> None:
assert context.tls_result == enc, (
f"Expected encoding '{enc}', got '{context.tls_result}'"
)
@then("writable should return True")
def step_then_writable_true(context: Context) -> None:
assert context.tls_result is True, (
f"Expected writable()=True, got {context.tls_result}"
)
@then("readable should return False")
def step_then_readable_false(context: Context) -> None:
assert context.tls_result is False, (
f"Expected readable()=False, got {context.tls_result}"
)
@then("the flush should succeed without error")
def step_then_flush_ok(context: Context) -> None:
assert context.tls_error is None, f"Expected no error, got {context.tls_error}"
@then("the original stream flush should be called")
def step_then_original_flushed(context: Context) -> None:
assert context.tls_original._flushed, (
"Expected original stream flush() to be called"
)
@then("isatty should return True")
def step_then_isatty_true(context: Context) -> None:
assert context.tls_result is True, (
f"Expected isatty()=True, got {context.tls_result}"
)
@then("isatty should return False")
def step_then_isatty_false(context: Context) -> None:
assert context.tls_result is False, (
f"Expected isatty()=False, got {context.tls_result}"
)
@then('the original stream should have received "{text}"')
def step_then_original_received(context: Context, text: str) -> None:
assert text in context.tls_original._written, (
f"Expected '{text}' in original writes, got {context.tls_original._written}"
)
@then('the captured text should be "{text}"')
def step_then_captured_text(context: Context, text: str) -> None:
assert context.tls_captured == text, (
f"Expected captured text '{text}', got '{context.tls_captured}'"
)
@then("the captured text should be empty")
def step_then_captured_text_empty(context: Context) -> None:
assert context.tls_captured == "", (
f"Expected empty captured text, got '{context.tls_captured}'"
)