v2.4.0 (#470)
Co-authored-by: Quentin Torroba <quentin.torroba@mistral.ai> Co-authored-by: Kim-Adeline Miguel <kimadeline.miguel@mistral.ai> Co-authored-by: Vincent Guilloux <vincent.guilloux@mistral.ai> Co-authored-by: Clement Sirieix <clem.sirieix@gmail.com> Co-authored-by: Antoine W <antoine.wronka@mistral.ai> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
5d2e01a6d7
commit
dd372ce494
89 changed files with 2086 additions and 596 deletions
|
|
@ -117,3 +117,169 @@ async def test_ui_resumes_arrow_down_after_manual_move(
|
|||
await pilot.press("down")
|
||||
assert textarea.cursor_location[0] == 1
|
||||
assert chat_input.value == "first line\nsecond line"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_does_not_intercept_arrow_down_inside_wrapped_single_line_input(
|
||||
vibe_app: VibeApp,
|
||||
) -> None:
|
||||
long_input = "0123456789 " * 20
|
||||
|
||||
async with vibe_app.run_test(size=(40, 20)) as pilot:
|
||||
chat_input = vibe_app.query_one(ChatInputContainer)
|
||||
textarea = chat_input.input_widget
|
||||
assert textarea is not None
|
||||
|
||||
textarea.insert(long_input)
|
||||
assert chat_input.value == long_input
|
||||
assert textarea.wrapped_document.height > 1
|
||||
|
||||
textarea.action_cursor_up()
|
||||
location_after_up = textarea.cursor_location
|
||||
assert textarea.get_cursor_down_location() != location_after_up
|
||||
|
||||
await pilot.press("down")
|
||||
|
||||
assert chat_input.value == long_input
|
||||
assert textarea.cursor_location != location_after_up
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_intercepts_arrow_up_only_on_first_wrapped_row(
|
||||
vibe_app: VibeApp, history_file: Path
|
||||
) -> None:
|
||||
long_input = "abcdefghij " * 20
|
||||
|
||||
async with vibe_app.run_test(size=(40, 20)) as pilot:
|
||||
inject_history_file(vibe_app, history_file)
|
||||
chat_input = vibe_app.query_one(ChatInputContainer)
|
||||
textarea = chat_input.input_widget
|
||||
assert textarea is not None
|
||||
|
||||
textarea.insert(long_input)
|
||||
assert chat_input.value == long_input
|
||||
assert textarea.wrapped_document.height > 1
|
||||
|
||||
textarea.action_cursor_up()
|
||||
assert chat_input.value == long_input
|
||||
|
||||
while textarea.get_cursor_up_location() != textarea.cursor_location:
|
||||
textarea.action_cursor_up()
|
||||
|
||||
await pilot.press("up")
|
||||
assert chat_input.value == "how are you?"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_up_from_wrapped_top_loads_history_after_down_at_wrapped_bottom(
|
||||
vibe_app: VibeApp, history_file: Path
|
||||
) -> None:
|
||||
long_input = "LONG " + ("x" * 160)
|
||||
|
||||
async with vibe_app.run_test(size=(40, 20)) as pilot:
|
||||
inject_history_file(vibe_app, history_file)
|
||||
chat_input = vibe_app.query_one(ChatInputContainer)
|
||||
textarea = chat_input.input_widget
|
||||
assert textarea is not None
|
||||
|
||||
textarea.insert(long_input)
|
||||
assert chat_input.value == long_input
|
||||
assert not textarea.navigator.is_first_wrapped_line(textarea.cursor_location)
|
||||
assert textarea.navigator.is_last_wrapped_line(textarea.cursor_location)
|
||||
|
||||
await pilot.press("down")
|
||||
textarea.move_cursor((0, 0))
|
||||
assert textarea.navigator.is_first_wrapped_line(textarea.cursor_location)
|
||||
|
||||
await pilot.press("up")
|
||||
|
||||
assert chat_input.value == "how are you?"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_down_cycles_to_next_history_without_manual_move_after_loading_multiline_entry(
|
||||
vibe_app: VibeApp, tmp_path: Path
|
||||
) -> None:
|
||||
long_first_line = "abcdefghij " * 20
|
||||
history_entry = f"{long_first_line}\nsecond line"
|
||||
history_path = tmp_path / "history.jsonl"
|
||||
history_path.write_text(json.dumps(history_entry) + "\n", encoding="utf-8")
|
||||
|
||||
async with vibe_app.run_test(size=(40, 20)) as pilot:
|
||||
inject_history_file(vibe_app, history_path)
|
||||
chat_input = vibe_app.query_one(ChatInputContainer)
|
||||
textarea = chat_input.input_widget
|
||||
assert textarea is not None
|
||||
|
||||
await pilot.press("up")
|
||||
assert chat_input.value == history_entry
|
||||
assert not textarea.navigator.is_first_wrapped_line(textarea.cursor_location)
|
||||
assert not textarea.navigator.is_last_wrapped_line(textarea.cursor_location)
|
||||
|
||||
await pilot.press("down")
|
||||
assert chat_input.value == ""
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_up_continues_history_cycle_after_loading_wrapped_multiline_entry(
|
||||
vibe_app: VibeApp, tmp_path: Path
|
||||
) -> None:
|
||||
long_first_line = "abcdefghij " * 20
|
||||
wrapped_multiline = f"{long_first_line}\nsecond line"
|
||||
history_path = tmp_path / "history.jsonl"
|
||||
history_entries = ["older message", wrapped_multiline, "Hi there"]
|
||||
history_path.write_text(
|
||||
"\n".join(json.dumps(entry) for entry in history_entries) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
async with vibe_app.run_test(size=(40, 20)) as pilot:
|
||||
inject_history_file(vibe_app, history_path)
|
||||
chat_input = vibe_app.query_one(ChatInputContainer)
|
||||
textarea = chat_input.input_widget
|
||||
assert textarea is not None
|
||||
|
||||
await pilot.press("up")
|
||||
assert chat_input.value == "Hi there"
|
||||
|
||||
await pilot.press("up")
|
||||
assert chat_input.value == wrapped_multiline
|
||||
assert not textarea.navigator.is_first_wrapped_line(textarea.cursor_location)
|
||||
|
||||
await pilot.press("up")
|
||||
assert chat_input.value == "older message"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_down_at_visual_end_resumes_history_after_manual_cursor_move(
|
||||
vibe_app: VibeApp, tmp_path: Path
|
||||
) -> None:
|
||||
long_first_line = "abcdefghij " * 20
|
||||
wrapped_multiline = f"{long_first_line}\nsecond line"
|
||||
history_path = tmp_path / "history.jsonl"
|
||||
history_entries = ["older message", wrapped_multiline, "Hi there"]
|
||||
history_path.write_text(
|
||||
"\n".join(json.dumps(entry) for entry in history_entries) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
async with vibe_app.run_test(size=(40, 20)) as pilot:
|
||||
inject_history_file(vibe_app, history_path)
|
||||
chat_input = vibe_app.query_one(ChatInputContainer)
|
||||
textarea = chat_input.input_widget
|
||||
assert textarea is not None
|
||||
|
||||
await pilot.press("up")
|
||||
await pilot.press("up")
|
||||
assert chat_input.value == wrapped_multiline
|
||||
|
||||
await pilot.press("left")
|
||||
assert textarea.cursor_location != (0, len(long_first_line))
|
||||
|
||||
while not textarea.navigator.is_last_wrapped_line(textarea.cursor_location):
|
||||
textarea.action_cursor_down()
|
||||
textarea.move_cursor((1, len("second line")))
|
||||
assert textarea.navigator.is_last_wrapped_line(textarea.cursor_location)
|
||||
|
||||
await pilot.press("down")
|
||||
assert chat_input.value == "Hi there"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue