Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/codeweaver/providers/config/profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,9 @@ def _recommended_default(
),
data=(TavilyProviderSettings(provider=Provider.TAVILY),)
if Provider.TAVILY.has_env_auth and has_package("tavily")
else (DuckDuckGoProviderSettings(provider=Provider.DUCKDUCKGO),),
else (DuckDuckGoProviderSettings(provider=Provider.DUCKDUCKGO),)
if has_package("ddgs")
else (),
Comment on lines +271 to +273
vector_store=(
QdrantVectorStoreProviderSettings(
provider=Provider.QDRANT,
Expand Down
47 changes: 17 additions & 30 deletions tests/integration/chunker/config/test_client_factory_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@
from codeweaver.core import Provider, ProviderCategory


def make_lazy_provider_mock(name: str, resolved_class: Mock, instance: Mock | None = None) -> Mock:
"""Helper to create and configure a lazy provider mock."""
lazy_mock = Mock()
lazy_mock.__name__ = name
lazy_mock._resolve.return_value = resolved_class
# mock_provider_lazy is invoked like the provider class
lazy_mock.return_value = instance if instance is not None else Mock()
return lazy_mock


pytestmark = [
pytest.mark.integration,
pytest.mark.skip(reason="ProviderRegistry removed - functionality tested through DI container"),
Expand Down Expand Up @@ -75,13 +85,8 @@ def test_create_provider_with_client_from_map(self, registry):

mock_provider_class = Mock()
mock_provider_instance = Mock()
mock_provider_lazy = Mock()
mock_provider_lazy.__name__ = (
"MockVoyageProvider" # Fix: Add __name__ to lazy mock (not resolved class)
)
mock_provider_lazy._resolve.return_value = mock_provider_class
mock_provider_lazy.return_value = (
mock_provider_instance # Fix: mock_provider_lazy is called at line 959
mock_provider_lazy = make_lazy_provider_mock(
"MockVoyageProvider", mock_provider_class, mock_provider_instance
)
mock_provider_class.return_value = mock_provider_instance

Expand Down Expand Up @@ -124,12 +129,7 @@ def test_create_provider_skips_client_if_provided(self, registry):
mock_lateimport._resolve.return_value = mock_client_class

mock_provider_class = Mock()
mock_provider_lazy = Mock()
mock_provider_lazy.__name__ = (
"MockVoyageProvider" # Fix: Add __name__ to lazy mock (not resolved class)
)
mock_provider_lazy._resolve.return_value = mock_provider_class
mock_provider_lazy.return_value = Mock() # Fix: mock_provider_lazy is called at line 959
mock_provider_lazy = make_lazy_provider_mock("MockVoyageProvider", mock_provider_class)

mock_client_map = {
Provider.VOYAGE: (
Expand Down Expand Up @@ -168,12 +168,7 @@ def test_create_provider_handles_client_creation_failure(self, registry):
mock_lateimport._resolve.return_value = mock_client_class

mock_provider_class = Mock(return_value=Mock())
mock_provider_lazy = Mock()
mock_provider_lazy.__name__ = (
"MockVoyageProvider" # Fix: Add __name__ to lazy mock (not resolved class)
)
mock_provider_lazy._resolve.return_value = mock_provider_class
mock_provider_lazy.return_value = Mock() # Fix: mock_provider_lazy is called at line 959
mock_provider_lazy = make_lazy_provider_mock("MockVoyageProvider", mock_provider_class)

mock_client_map = {
Provider.VOYAGE: (
Expand Down Expand Up @@ -246,9 +241,7 @@ def test_qdrant_provider_with_memory_mode(self, registry):
mock_lateimport._resolve.return_value = mock_client_class

mock_provider_class = Mock(return_value=Mock())
mock_provider_lazy = Mock()
mock_provider_lazy._resolve.return_value = mock_provider_class
mock_provider_lazy.return_value = Mock() # Fix: mock_provider_lazy is what gets called
mock_provider_lazy = make_lazy_provider_mock("MockQdrantProvider", mock_provider_class)

mock_client_map = {
Provider.QDRANT: (
Expand Down Expand Up @@ -288,8 +281,7 @@ def test_qdrant_provider_with_url_mode(self, registry):
mock_lateimport._resolve.return_value = mock_client_class

mock_provider_class = Mock(return_value=Mock())
mock_provider_lazy = Mock()
mock_provider_lazy._resolve.return_value = mock_provider_class
mock_provider_lazy = make_lazy_provider_mock("MockQdrantProvider", mock_provider_class)

mock_client_map = {
Provider.QDRANT: (
Expand Down Expand Up @@ -383,12 +375,7 @@ def test_string_provider_category_in_create_provider(self, registry):
mock_lateimport._resolve.return_value = mock_client_class

mock_provider_class = Mock(return_value=Mock())
mock_provider_lazy = Mock()
mock_provider_lazy.__name__ = (
"MockVoyageProvider" # Fix: Add __name__ to lazy mock (not resolved class)
)
mock_provider_lazy._resolve.return_value = mock_provider_class
mock_provider_lazy.return_value = Mock() # Fix: mock_provider_lazy is called at line 959
mock_provider_lazy = make_lazy_provider_mock("MockVoyageProvider", mock_provider_class)

mock_client_map = {
Provider.VOYAGE: (
Expand Down
53 changes: 53 additions & 0 deletions tests/unit/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# SPDX-FileCopyrightText: 2025 Knitli Inc.
# SPDX-FileContributor: Adam Poulemanos <adam@knit.li>
#
# SPDX-License-Identifier: MIT OR Apache-2.0

from unittest.mock import patch
import signal
import pytest

from codeweaver.main import _setup_signal_handler

def test_setup_signal_handler_first_interrupt():
"""Test that the first interrupt raises KeyboardInterrupt."""
Comment on lines +10 to +13
with patch("signal.signal") as mock_signal:
_setup_signal_handler()

# Get the registered handler
mock_signal.assert_called_with(signal.SIGINT, mock_signal.call_args[0][1])
force_shutdown_handler = mock_signal.call_args[0][1]
Comment on lines +18 to +19
Comment on lines +17 to +19
Comment on lines +12 to +19
Comment on lines +18 to +19

# Test first call raises KeyboardInterrupt
with pytest.raises(KeyboardInterrupt):
force_shutdown_handler(signal.SIGINT, None)

def test_setup_signal_handler_second_interrupt():
"""Test that the second interrupt exits immediately."""
with patch("signal.signal") as mock_signal:
_setup_signal_handler()

force_shutdown_handler = mock_signal.call_args[0][1]

# First call raises KeyboardInterrupt
with pytest.raises(KeyboardInterrupt):
force_shutdown_handler(signal.SIGINT, None)

# Second call exits with 1
with patch("sys.exit") as mock_exit, patch("codeweaver.main.logger.warning") as mock_warning:
force_shutdown_handler(signal.SIGINT, None)
Comment on lines +36 to +38

Comment on lines +36 to +39
mock_warning.assert_called_with("Force shutdown requested, exiting immediately...")
mock_exit.assert_called_with(1)

def test_setup_signal_handler_suppress_errors():
"""Test that ValueError and OSError are suppressed when setting the signal."""
# Test ValueError
with patch("signal.signal", side_effect=ValueError):
original_handler = _setup_signal_handler()
assert original_handler is None

# Test OSError
with patch("signal.signal", side_effect=OSError):
original_handler = _setup_signal_handler()
assert original_handler is None
Loading