v2.3.0 (#429)
Co-authored-by: Carlo <carloantonio.patti@mistral.ai> Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai> Co-authored-by: Clement Sirieix <clem.sirieix@gmail.com> Co-authored-by: Michel Thomazo <michel.thomazo@mistral.ai> Co-authored-by: Clément Drouin <clement.drouin@mistral.ai> Co-authored-by: Vincent Guilloux <vincent.guilloux@mistral.ai> Co-authored-by: Thomas Kenbeek <thomas.kenbeek@mistral.ai> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
a560a47ce8
commit
5d2e01a6d7
139 changed files with 7152 additions and 1457 deletions
151
tests/cli/test_bell_notifications.py
Normal file
151
tests/cli/test_bell_notifications.py
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import MagicMock, PropertyMock
|
||||
|
||||
import pytest
|
||||
|
||||
from vibe.cli.textual_ui.notifications import (
|
||||
NotificationContext,
|
||||
TextualNotificationAdapter,
|
||||
)
|
||||
|
||||
|
||||
def _make_fake_app(*, is_headless: bool = False) -> MagicMock:
|
||||
app = MagicMock()
|
||||
type(app).is_headless = PropertyMock(return_value=is_headless)
|
||||
return app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fake_app() -> MagicMock:
|
||||
return _make_fake_app()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def adapter_enabled(fake_app: MagicMock) -> TextualNotificationAdapter:
|
||||
return TextualNotificationAdapter(
|
||||
fake_app, get_enabled=lambda: True, default_title="Vibe"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def adapter_disabled(fake_app: MagicMock) -> TextualNotificationAdapter:
|
||||
return TextualNotificationAdapter(
|
||||
fake_app, get_enabled=lambda: False, default_title="Vibe"
|
||||
)
|
||||
|
||||
|
||||
class TestTextualNotificationAdapter:
|
||||
def test_no_notification_when_disabled(
|
||||
self, adapter_disabled: TextualNotificationAdapter, fake_app: MagicMock
|
||||
) -> None:
|
||||
adapter_disabled.on_blur()
|
||||
|
||||
adapter_disabled.notify(NotificationContext.ACTION_REQUIRED)
|
||||
|
||||
fake_app.bell.assert_not_called()
|
||||
|
||||
def test_no_notification_when_focused(
|
||||
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
|
||||
) -> None:
|
||||
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
|
||||
|
||||
fake_app.bell.assert_not_called()
|
||||
|
||||
def test_notification_sent_when_unfocused_and_enabled(
|
||||
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
|
||||
) -> None:
|
||||
adapter_enabled.on_blur()
|
||||
|
||||
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
|
||||
|
||||
fake_app.bell.assert_called_once()
|
||||
fake_app._driver.write.assert_called_once_with(
|
||||
"\x1b]0;Vibe - Action Required\x07"
|
||||
)
|
||||
|
||||
def test_throttle_prevents_rapid_notifications(
|
||||
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
|
||||
) -> None:
|
||||
adapter_enabled.on_blur()
|
||||
|
||||
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
|
||||
assert fake_app.bell.call_count == 1
|
||||
|
||||
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
|
||||
assert fake_app.bell.call_count == 1
|
||||
|
||||
def test_contextual_title_for_action_required(
|
||||
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
|
||||
) -> None:
|
||||
adapter_enabled.on_blur()
|
||||
|
||||
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
|
||||
|
||||
fake_app._driver.write.assert_called_once_with(
|
||||
"\x1b]0;Vibe - Action Required\x07"
|
||||
)
|
||||
|
||||
def test_contextual_title_for_complete(
|
||||
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
|
||||
) -> None:
|
||||
adapter_enabled.on_blur()
|
||||
|
||||
adapter_enabled.notify(NotificationContext.COMPLETE)
|
||||
|
||||
fake_app._driver.write.assert_called_once_with(
|
||||
"\x1b]0;Vibe - Task Complete\x07"
|
||||
)
|
||||
|
||||
def test_restore_sets_default_title(
|
||||
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
|
||||
) -> None:
|
||||
adapter_enabled.restore()
|
||||
|
||||
fake_app._driver.write.assert_called_once_with("\x1b]0;Vibe\x07")
|
||||
|
||||
def test_on_focus_restores_title(
|
||||
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
|
||||
) -> None:
|
||||
adapter_enabled.on_blur()
|
||||
adapter_enabled.on_focus()
|
||||
|
||||
fake_app._driver.write.assert_called_once_with("\x1b]0;Vibe\x07")
|
||||
|
||||
def test_on_focus_prevents_notifications(
|
||||
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
|
||||
) -> None:
|
||||
adapter_enabled.on_blur()
|
||||
adapter_enabled.on_focus()
|
||||
fake_app.reset_mock()
|
||||
|
||||
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
|
||||
|
||||
fake_app.bell.assert_not_called()
|
||||
|
||||
def test_no_title_write_when_headless(self) -> None:
|
||||
app = _make_fake_app(is_headless=True)
|
||||
adapter = TextualNotificationAdapter(
|
||||
app, get_enabled=lambda: True, default_title="Vibe"
|
||||
)
|
||||
adapter.on_blur()
|
||||
|
||||
adapter.notify(NotificationContext.ACTION_REQUIRED)
|
||||
|
||||
app.bell.assert_called_once()
|
||||
app._driver.write.assert_not_called()
|
||||
|
||||
def test_enabled_callback_reads_live_value(self, fake_app: MagicMock) -> None:
|
||||
enabled = True
|
||||
adapter = TextualNotificationAdapter(
|
||||
fake_app, get_enabled=lambda: enabled, default_title="Vibe"
|
||||
)
|
||||
adapter.on_blur()
|
||||
|
||||
adapter.notify(NotificationContext.ACTION_REQUIRED)
|
||||
assert fake_app.bell.call_count == 1
|
||||
|
||||
enabled = False
|
||||
adapter._last_notification_time = 0.0
|
||||
adapter.notify(NotificationContext.ACTION_REQUIRED)
|
||||
assert fake_app.bell.call_count == 1
|
||||
Loading…
Add table
Add a link
Reference in a new issue