0be3f85c56
CI / lint (push) Successful in 23s
CI / quality (push) Successful in 47s
CI / typecheck (push) Successful in 50s
CI / security (push) Successful in 52s
CI / helm (push) Successful in 28s
CI / build (push) Successful in 42s
CI / unit_tests (push) Failing after 6m55s
CI / docker (push) Has been skipped
CI / coverage (push) Successful in 10m26s
CI / e2e_tests (push) Failing after 13m59s
CI / benchmark-regression (push) Has been skipped
CI / integration_tests (push) Failing after 22m11s
CI / status-check (push) Failing after 1s
CI / benchmark-publish (push) Has been cancelled
Implement inline permission question widget for quick allow/reject decisions within the conversation stream with file diff context. ISSUES CLOSED: #997
221 lines
7.1 KiB
Python
221 lines
7.1 KiB
Python
"""Step definitions for tui_thought_block.feature."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from behave import then, when
|
|
|
|
from cleveragents.domain.models.thought.thought_block import ThoughtBlock
|
|
from cleveragents.tui.widgets.thought_block import ThoughtBlockWidget
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Helpers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def _make_lines(n: int) -> str:
|
|
"""Return a string with *n* numbered lines."""
|
|
return "\n".join(f"Line {i + 1}" for i in range(n))
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ThoughtBlock domain model steps
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@when('I create a thought block with content "{content}"')
|
|
def step_create_thought_block(context, content):
|
|
context.thought = ThoughtBlock(content=content)
|
|
|
|
|
|
@when('I create a thought block with content "{content}" and max_lines {n:d}')
|
|
def step_create_thought_block_custom_max(context, content, n):
|
|
context.thought = ThoughtBlock(content=content, max_lines=n)
|
|
|
|
|
|
@when("I create a thought block with {n:d} lines of content")
|
|
def step_create_thought_block_n_lines(context, n):
|
|
context.thought = ThoughtBlock(content=_make_lines(n))
|
|
|
|
|
|
@when("I create a thought block with exactly {n:d} lines of content")
|
|
def step_create_thought_block_exactly_n_lines(context, n):
|
|
context.thought = ThoughtBlock(content=_make_lines(n))
|
|
|
|
|
|
@when("I create a thought block with empty content")
|
|
def step_create_thought_block_empty(context):
|
|
context.thought = ThoughtBlock(content="")
|
|
|
|
|
|
@when("I expand the thought block")
|
|
def step_expand_thought_block(context):
|
|
context.thought.expand()
|
|
|
|
|
|
@when("I collapse the thought block")
|
|
def step_collapse_thought_block(context):
|
|
context.thought.collapse()
|
|
|
|
|
|
@when("I toggle the thought block")
|
|
def step_toggle_thought_block(context):
|
|
context.thought.toggle()
|
|
|
|
|
|
@then('the thought block content should be "{expected}"')
|
|
def step_thought_block_content(context, expected):
|
|
assert context.thought.content == expected, (
|
|
f"Expected content {expected!r}, got {context.thought.content!r}"
|
|
)
|
|
|
|
|
|
@then("the thought block max_lines should be {n:d}")
|
|
def step_thought_block_max_lines(context, n):
|
|
assert context.thought.max_lines == n, (
|
|
f"Expected max_lines {n}, got {context.thought.max_lines}"
|
|
)
|
|
|
|
|
|
@then("the thought block should be collapsed by default")
|
|
def step_thought_block_collapsed_default(context):
|
|
assert context.thought.expanded is False, "Expected thought block to be collapsed"
|
|
|
|
|
|
@then("the thought block should be collapsed")
|
|
def step_thought_block_collapsed(context):
|
|
assert context.thought.expanded is False, "Expected thought block to be collapsed"
|
|
|
|
|
|
@then("the thought block should be expanded")
|
|
def step_thought_block_expanded(context):
|
|
assert context.thought.expanded is True, "Expected thought block to be expanded"
|
|
|
|
|
|
@then("the thought block should not be truncated")
|
|
def step_thought_block_not_truncated(context):
|
|
assert context.thought.is_truncated() is False, (
|
|
"Expected thought block to not be truncated"
|
|
)
|
|
|
|
|
|
@then("the thought block should be truncated")
|
|
def step_thought_block_truncated(context):
|
|
assert context.thought.is_truncated() is True, (
|
|
"Expected thought block to be truncated"
|
|
)
|
|
|
|
|
|
@then("the thought block visible lines count should be {n:d}")
|
|
def step_thought_block_visible_lines_count(context, n):
|
|
actual = len(context.thought.visible_lines())
|
|
assert actual == n, f"Expected {n} visible lines, got {actual}"
|
|
|
|
|
|
@then("the thought block hidden line count should be {n:d}")
|
|
def step_thought_block_hidden_line_count(context, n):
|
|
actual = context.thought.hidden_line_count()
|
|
assert actual == n, f"Expected {n} hidden lines, got {actual}"
|
|
|
|
|
|
@then("the thought block lines count should be {n:d}")
|
|
def step_thought_block_lines_count(context, n):
|
|
actual = len(context.thought.lines())
|
|
assert actual == n, f"Expected {n} lines, got {actual}"
|
|
|
|
|
|
@then('the thought block rendered text should contain "{text}"')
|
|
def step_thought_block_rendered_text_contains(context, text):
|
|
rendered = context.thought.rendered_text()
|
|
assert text in rendered, f"Expected {text!r} in rendered text, got: {rendered!r}"
|
|
|
|
|
|
@then('the thought block rendered text should not contain "{text}"')
|
|
def step_thought_block_rendered_text_not_contains(context, text):
|
|
rendered = context.thought.rendered_text()
|
|
assert text not in rendered, (
|
|
f"Expected {text!r} NOT in rendered text, got: {rendered!r}"
|
|
)
|
|
|
|
|
|
@then("the thought block rendered text should be empty")
|
|
def step_thought_block_rendered_text_empty(context):
|
|
rendered = context.thought.rendered_text()
|
|
assert rendered == "", f"Expected empty rendered text, got: {rendered!r}"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ThoughtBlockWidget steps
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@when('I create a thought block widget with content "{content}"')
|
|
def step_create_widget(context, content):
|
|
thought = ThoughtBlock(content=content)
|
|
context.widget = ThoughtBlockWidget(thought=thought)
|
|
|
|
|
|
@when("I create a thought block widget with {n:d} lines of content")
|
|
def step_create_widget_n_lines(context, n):
|
|
thought = ThoughtBlock(content=_make_lines(n))
|
|
context.widget = ThoughtBlockWidget(thought=thought)
|
|
|
|
|
|
@when("I create a thought block widget with empty content")
|
|
def step_create_widget_empty(context):
|
|
thought = ThoughtBlock(content="")
|
|
context.widget = ThoughtBlockWidget(thought=thought)
|
|
|
|
|
|
@when("I toggle the thought block widget")
|
|
def step_toggle_widget(context):
|
|
context.widget.toggle()
|
|
|
|
|
|
@when("I expand the thought block widget")
|
|
def step_expand_widget(context):
|
|
context.widget.expand()
|
|
|
|
|
|
@when("I collapse the thought block widget")
|
|
def step_collapse_widget(context):
|
|
context.widget.collapse()
|
|
|
|
|
|
@then('the widget thought content should be "{expected}"')
|
|
def step_widget_thought_content(context, expected):
|
|
assert context.widget.thought.content == expected, (
|
|
f"Expected widget thought content {expected!r}, "
|
|
f"got {context.widget.thought.content!r}"
|
|
)
|
|
|
|
|
|
@then("the widget should be collapsed")
|
|
def step_widget_collapsed(context):
|
|
assert context.widget.is_expanded is False, "Expected widget to be collapsed"
|
|
|
|
|
|
@then("the widget should be expanded")
|
|
def step_widget_expanded(context):
|
|
assert context.widget.is_expanded is True, "Expected widget to be expanded"
|
|
|
|
|
|
@then('the widget display text should contain "{text}"')
|
|
def step_widget_display_text_contains(context, text):
|
|
assert text in context.widget._text, (
|
|
f"Expected {text!r} in widget text, got: {context.widget._text!r}"
|
|
)
|
|
|
|
|
|
@then('the widget CSS classes should contain "{cls}"')
|
|
def step_widget_css_class_contains(context, cls):
|
|
assert cls in context.widget._classes, (
|
|
f"Expected CSS class {cls!r} in {context.widget._classes}"
|
|
)
|
|
|
|
|
|
@then('the widget CSS classes should not contain "{cls}"')
|
|
def step_widget_css_class_not_contains(context, cls):
|
|
assert cls not in context.widget._classes, (
|
|
f"Expected CSS class {cls!r} NOT in {context.widget._classes}"
|
|
)
|