2.1.0 (#317)
Co-authored-by: Quentin Torroba <quentin.torroba@mistral.ai> 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: Clément Siriex <clement.sirieix@mistral.ai> Co-authored-by: Kim-Adeline Miguel <kimadeline.miguel@mistral.ai> Co-authored-by: Nicolas Karolak <nicolas@karolak.fr>
This commit is contained in:
parent
9809cfc831
commit
51fecc67d9
176 changed files with 8652 additions and 4451 deletions
|
|
@ -1,14 +1,15 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
import time
|
||||
from typing import Protocol
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from textual.app import Notification
|
||||
|
||||
from tests.conftest import build_test_vibe_app, build_test_vibe_config
|
||||
from tests.update_notifier.adapters.fake_update_cache_repository import (
|
||||
FakeUpdateCacheRepository,
|
||||
)
|
||||
|
|
@ -18,12 +19,35 @@ from vibe.cli.textual_ui.widgets.messages import WhatsNewMessage
|
|||
from vibe.cli.update_notifier import (
|
||||
Update,
|
||||
UpdateCache,
|
||||
UpdateCacheRepository,
|
||||
UpdateGateway,
|
||||
UpdateGatewayCause,
|
||||
UpdateGatewayError,
|
||||
)
|
||||
from vibe.core.agent_loop import AgentLoop
|
||||
from vibe.core.agents.models import BuiltinAgentName
|
||||
from vibe.core.config import SessionLoggingConfig, VibeConfig
|
||||
from vibe.core.config import VibeConfig
|
||||
|
||||
TEST_CURRENT_VERSION = "0.1.0"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def build_update_test_app(
|
||||
vibe_config_with_update_checks_enabled: VibeConfig,
|
||||
) -> Callable[..., VibeApp]:
|
||||
def _build(
|
||||
*,
|
||||
update_notifier: UpdateGateway | None = None,
|
||||
update_cache_repository: UpdateCacheRepository | None = None,
|
||||
config: VibeConfig | None = None,
|
||||
current_version: str = TEST_CURRENT_VERSION,
|
||||
) -> VibeApp:
|
||||
return build_test_vibe_app(
|
||||
update_notifier=update_notifier,
|
||||
update_cache_repository=update_cache_repository,
|
||||
config=config or vibe_config_with_update_checks_enabled,
|
||||
current_version=current_version,
|
||||
)
|
||||
|
||||
return _build
|
||||
|
||||
|
||||
async def _wait_for_notification(
|
||||
|
|
@ -57,54 +81,15 @@ async def _assert_no_notifications(
|
|||
|
||||
@pytest.fixture
|
||||
def vibe_config_with_update_checks_enabled() -> VibeConfig:
|
||||
return VibeConfig(
|
||||
session_logging=SessionLoggingConfig(enabled=False), enable_update_checks=True
|
||||
)
|
||||
|
||||
|
||||
class VibeAppFactory(Protocol):
|
||||
def __call__(
|
||||
self,
|
||||
*,
|
||||
notifier: FakeUpdateGateway,
|
||||
update_cache_repository: FakeUpdateCacheRepository | None = None,
|
||||
config: VibeConfig | None = None,
|
||||
initial_agent_name: str = BuiltinAgentName.DEFAULT,
|
||||
current_version: str = "0.1.0",
|
||||
) -> VibeApp: ...
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def make_vibe_app(vibe_config_with_update_checks_enabled: VibeConfig) -> VibeAppFactory:
|
||||
update_cache_repository = FakeUpdateCacheRepository()
|
||||
|
||||
def _make_app(
|
||||
*,
|
||||
notifier: FakeUpdateGateway,
|
||||
update_cache_repository: FakeUpdateCacheRepository
|
||||
| None = update_cache_repository,
|
||||
config: VibeConfig | None = None,
|
||||
initial_agent_name: str = BuiltinAgentName.DEFAULT,
|
||||
current_version: str = "0.1.0",
|
||||
) -> VibeApp:
|
||||
app_config = config or vibe_config_with_update_checks_enabled
|
||||
agent_loop = AgentLoop(
|
||||
app_config, agent_name=initial_agent_name, enable_streaming=False
|
||||
)
|
||||
return VibeApp(
|
||||
agent_loop=agent_loop,
|
||||
update_notifier=notifier,
|
||||
update_cache_repository=update_cache_repository,
|
||||
current_version=current_version,
|
||||
)
|
||||
|
||||
return _make_app
|
||||
return build_test_vibe_config(enable_update_checks=True)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_displays_update_notification(make_vibe_app: VibeAppFactory) -> None:
|
||||
async def test_ui_displays_update_notification(
|
||||
build_update_test_app: Callable[..., VibeApp],
|
||||
) -> None:
|
||||
notifier = FakeUpdateGateway(update=Update(latest_version="0.2.0"))
|
||||
app = make_vibe_app(notifier=notifier)
|
||||
app = build_update_test_app(update_notifier=notifier)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
notification = await _wait_for_notification(app, pilot, timeout=0.3)
|
||||
|
|
@ -119,10 +104,10 @@ async def test_ui_displays_update_notification(make_vibe_app: VibeAppFactory) ->
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_does_not_display_update_notification_when_not_available(
|
||||
make_vibe_app: VibeAppFactory,
|
||||
build_update_test_app: Callable[..., VibeApp],
|
||||
) -> None:
|
||||
notifier = FakeUpdateGateway(update=None)
|
||||
app = make_vibe_app(notifier=notifier)
|
||||
app = build_update_test_app(update_notifier=notifier)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
await _assert_no_notifications(app, pilot, timeout=0.3)
|
||||
|
|
@ -131,12 +116,12 @@ async def test_ui_does_not_display_update_notification_when_not_available(
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_displays_warning_toast_when_check_fails(
|
||||
make_vibe_app: VibeAppFactory,
|
||||
build_update_test_app: Callable[..., VibeApp],
|
||||
) -> None:
|
||||
notifier = FakeUpdateGateway(
|
||||
error=UpdateGatewayError(cause=UpdateGatewayCause.FORBIDDEN)
|
||||
)
|
||||
app = make_vibe_app(notifier=notifier)
|
||||
app = build_update_test_app(update_notifier=notifier)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
await pilot.pause(0.3)
|
||||
|
|
@ -150,12 +135,10 @@ async def test_ui_displays_warning_toast_when_check_fails(
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_does_not_invoke_gateway_nor_show_error_notification_when_update_checks_are_disabled(
|
||||
vibe_config_with_update_checks_enabled: VibeConfig, make_vibe_app: VibeAppFactory
|
||||
build_update_test_app: Callable[..., VibeApp], vibe_config: VibeConfig
|
||||
) -> None:
|
||||
config = vibe_config_with_update_checks_enabled
|
||||
config.enable_update_checks = False
|
||||
notifier = FakeUpdateGateway(update=Update(latest_version="0.2.0"))
|
||||
app = make_vibe_app(notifier=notifier, config=config)
|
||||
app = build_update_test_app(update_notifier=notifier, config=vibe_config)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
await _assert_no_notifications(app, pilot, timeout=0.3)
|
||||
|
|
@ -165,16 +148,16 @@ async def test_ui_does_not_invoke_gateway_nor_show_error_notification_when_updat
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_does_not_show_toast_when_update_is_known_in_recent_cache_already(
|
||||
make_vibe_app: VibeAppFactory,
|
||||
) -> None:
|
||||
build_update_test_app: Callable[..., VibeApp],
|
||||
):
|
||||
timestamp_two_hours_ago = int(time.time()) - 2 * 60 * 60
|
||||
notifier = FakeUpdateGateway(update=Update(latest_version="0.2.0"))
|
||||
update_cache = UpdateCache(
|
||||
latest_version="0.2.0", stored_at_timestamp=timestamp_two_hours_ago
|
||||
)
|
||||
update_cache_repository = FakeUpdateCacheRepository(update_cache=update_cache)
|
||||
app = make_vibe_app(
|
||||
notifier=notifier, update_cache_repository=update_cache_repository
|
||||
app = build_update_test_app(
|
||||
update_notifier=notifier, update_cache_repository=update_cache_repository
|
||||
)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
|
|
@ -185,7 +168,7 @@ async def test_ui_does_not_show_toast_when_update_is_known_in_recent_cache_alrea
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_does_show_toast_when_cache_entry_is_too_old(
|
||||
make_vibe_app: VibeAppFactory,
|
||||
build_update_test_app: Callable[..., VibeApp],
|
||||
) -> None:
|
||||
timestamp_two_days_ago = int(time.time()) - 2 * 24 * 60 * 60
|
||||
notifier = FakeUpdateGateway(update=Update(latest_version="0.2.0"))
|
||||
|
|
@ -193,8 +176,8 @@ async def test_ui_does_show_toast_when_cache_entry_is_too_old(
|
|||
latest_version="0.2.0", stored_at_timestamp=timestamp_two_days_ago
|
||||
)
|
||||
update_cache_repository = FakeUpdateCacheRepository(update_cache=update_cache)
|
||||
app = make_vibe_app(
|
||||
notifier=notifier, update_cache_repository=update_cache_repository
|
||||
app = build_update_test_app(
|
||||
update_notifier=notifier, update_cache_repository=update_cache_repository
|
||||
)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
|
|
@ -232,7 +215,7 @@ async def _wait_for_whats_new_message(
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_displays_whats_new_message_when_content_exists(
|
||||
make_vibe_app: VibeAppFactory, tmp_path: Path
|
||||
build_update_test_app: Callable[..., VibeApp], tmp_path: Path
|
||||
) -> None:
|
||||
notifier = FakeUpdateGateway(update=None)
|
||||
cache = UpdateCache(
|
||||
|
|
@ -241,8 +224,10 @@ async def test_ui_displays_whats_new_message_when_content_exists(
|
|||
seen_whats_new_version=None,
|
||||
)
|
||||
repository = FakeUpdateCacheRepository(update_cache=cache)
|
||||
app = make_vibe_app(
|
||||
notifier=notifier, update_cache_repository=repository, current_version="1.0.0"
|
||||
app = build_update_test_app(
|
||||
update_notifier=notifier,
|
||||
update_cache_repository=repository,
|
||||
current_version="1.0.0",
|
||||
)
|
||||
|
||||
whats_new_content = "# What's New\n\n- Feature 1\n- Feature 2"
|
||||
|
|
@ -262,7 +247,7 @@ async def test_ui_displays_whats_new_message_when_content_exists(
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_does_not_display_whats_new_when_seen_whats_new_version_matches(
|
||||
make_vibe_app: VibeAppFactory, tmp_path: Path
|
||||
build_update_test_app: Callable[..., VibeApp], tmp_path: Path
|
||||
) -> None:
|
||||
notifier = FakeUpdateGateway(update=None)
|
||||
cache = UpdateCache(
|
||||
|
|
@ -271,8 +256,10 @@ async def test_ui_does_not_display_whats_new_when_seen_whats_new_version_matches
|
|||
seen_whats_new_version="1.0.0",
|
||||
)
|
||||
repository = FakeUpdateCacheRepository(update_cache=cache)
|
||||
app = make_vibe_app(
|
||||
notifier=notifier, update_cache_repository=repository, current_version="1.0.0"
|
||||
app = build_update_test_app(
|
||||
update_notifier=notifier,
|
||||
update_cache_repository=repository,
|
||||
current_version="1.0.0",
|
||||
)
|
||||
|
||||
with patch("vibe.cli.update_notifier.whats_new.VIBE_ROOT", tmp_path):
|
||||
|
|
@ -291,7 +278,7 @@ async def test_ui_does_not_display_whats_new_when_seen_whats_new_version_matches
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_does_not_display_whats_new_when_file_is_empty(
|
||||
make_vibe_app: VibeAppFactory, tmp_path: Path
|
||||
build_update_test_app: Callable[..., VibeApp], tmp_path: Path
|
||||
) -> None:
|
||||
notifier = FakeUpdateGateway(update=None)
|
||||
cache = UpdateCache(
|
||||
|
|
@ -300,8 +287,10 @@ async def test_ui_does_not_display_whats_new_when_file_is_empty(
|
|||
seen_whats_new_version=None,
|
||||
)
|
||||
repository = FakeUpdateCacheRepository(update_cache=cache)
|
||||
app = make_vibe_app(
|
||||
notifier=notifier, update_cache_repository=repository, current_version="1.0.0"
|
||||
app = build_update_test_app(
|
||||
update_notifier=notifier,
|
||||
update_cache_repository=repository,
|
||||
current_version="1.0.0",
|
||||
)
|
||||
|
||||
with patch("vibe.cli.update_notifier.whats_new.VIBE_ROOT", tmp_path):
|
||||
|
|
@ -323,7 +312,7 @@ async def test_ui_does_not_display_whats_new_when_file_is_empty(
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_does_not_display_whats_new_when_file_does_not_exist(
|
||||
make_vibe_app: VibeAppFactory, tmp_path: Path
|
||||
build_update_test_app: Callable[..., VibeApp], tmp_path: Path
|
||||
) -> None:
|
||||
notifier = FakeUpdateGateway(update=None)
|
||||
cache = UpdateCache(
|
||||
|
|
@ -332,8 +321,10 @@ async def test_ui_does_not_display_whats_new_when_file_does_not_exist(
|
|||
seen_whats_new_version=None,
|
||||
)
|
||||
repository = FakeUpdateCacheRepository(update_cache=cache)
|
||||
app = make_vibe_app(
|
||||
notifier=notifier, update_cache_repository=repository, current_version="1.0.0"
|
||||
app = build_update_test_app(
|
||||
update_notifier=notifier,
|
||||
update_cache_repository=repository,
|
||||
current_version="1.0.0",
|
||||
)
|
||||
|
||||
with patch("vibe.cli.update_notifier.whats_new.VIBE_ROOT", tmp_path):
|
||||
|
|
@ -352,17 +343,13 @@ async def test_ui_does_not_display_whats_new_when_file_does_not_exist(
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_displays_success_notification_when_auto_update_succeeds(
|
||||
make_vibe_app: VibeAppFactory,
|
||||
build_update_test_app: Callable[..., VibeApp],
|
||||
) -> None:
|
||||
config = VibeConfig(
|
||||
session_logging=SessionLoggingConfig(enabled=False),
|
||||
enable_update_checks=True,
|
||||
enable_auto_update=True,
|
||||
)
|
||||
config = build_test_vibe_config(enable_update_checks=True, enable_auto_update=True)
|
||||
notifier = FakeUpdateGateway(update=Update(latest_version="0.2.0"))
|
||||
|
||||
with patch("vibe.cli.update_notifier.update.UPDATE_COMMANDS", ["true"]):
|
||||
app = make_vibe_app(notifier=notifier, config=config)
|
||||
app = build_update_test_app(update_notifier=notifier, config=config)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
await pilot.pause(0.3)
|
||||
|
|
@ -380,17 +367,13 @@ async def test_ui_displays_success_notification_when_auto_update_succeeds(
|
|||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ui_displays_update_notification_when_auto_update_fails(
|
||||
make_vibe_app: VibeAppFactory,
|
||||
build_update_test_app: Callable[..., VibeApp],
|
||||
) -> None:
|
||||
config = VibeConfig(
|
||||
session_logging=SessionLoggingConfig(enabled=False),
|
||||
enable_update_checks=True,
|
||||
enable_auto_update=True,
|
||||
)
|
||||
config = build_test_vibe_config(enable_update_checks=True, enable_auto_update=True)
|
||||
notifier = FakeUpdateGateway(update=Update(latest_version="0.2.0"))
|
||||
|
||||
with patch("vibe.cli.update_notifier.update.UPDATE_COMMANDS", ["false"]):
|
||||
app = make_vibe_app(notifier=notifier, config=config)
|
||||
app = build_update_test_app(update_notifier=notifier, config=config)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
await pilot.pause(0.3)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue