|
| 1 | +"""Property-based tests: random byte sequences must never crash the input parser |
| 2 | +or the transcript layout engine. Uses Hypothesis for fuzz-style testing. |
| 3 | +""" |
| 4 | + |
| 5 | +from __future__ import annotations |
| 6 | + |
| 7 | +from hypothesis import given, strategies as st, settings |
| 8 | + |
| 9 | +from minicode.tui.input_parser import parse_input_chunk |
| 10 | +from minicode.tui.types import TranscriptEntry |
| 11 | + |
| 12 | + |
| 13 | +# Strategy: any mix of printable + control + escape + CJK bytes |
| 14 | +arbitrary_text = st.text( |
| 15 | + alphabet=st.characters(min_codepoint=0, max_codepoint=0xFFFF), |
| 16 | + max_size=200, |
| 17 | +) |
| 18 | + |
| 19 | + |
| 20 | +@given(arbitrary_text) |
| 21 | +@settings(max_examples=500) |
| 22 | +def test_parse_input_chunk_never_crashes(chunk: str) -> None: |
| 23 | + """parse_input_chunk must never raise on any arbitrary string input.""" |
| 24 | + result = parse_input_chunk(chunk) |
| 25 | + assert isinstance(result.events, list) |
| 26 | + assert isinstance(result.rest, str) |
| 27 | + # Second pass with remainder (simulates chunked input) |
| 28 | + if result.rest: |
| 29 | + parse_input_chunk(result.rest) |
| 30 | + |
| 31 | + |
| 32 | +@given(arbitrary_text) |
| 33 | +@settings(max_examples=200) |
| 34 | +def test_transcript_layout_never_crashes(body: str) -> None: |
| 35 | + """Transcript layout computation must never crash on any body text, |
| 36 | + including CJK, control chars, and very long lines.""" |
| 37 | + from minicode.tui import transcript as t |
| 38 | + t._cached_terminal_size = lambda: (80, 24) # type: ignore[attr-defined] |
| 39 | + entries = [TranscriptEntry(id=1, kind="assistant", body=body)] |
| 40 | + offset = t.get_transcript_max_scroll_offset(entries, window_size=4) |
| 41 | + assert isinstance(offset, int) |
| 42 | + assert offset >= 0 |
0 commit comments