repl-toolkit 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,174 @@
1
+ """
2
+ Tests for protocol compliance and type checking.
3
+ """
4
+
5
+ from typing import Protocol
6
+ from unittest.mock import AsyncMock, Mock
7
+
8
+ import pytest
9
+
10
+ from repl_toolkit.actions import ActionRegistry
11
+ from repl_toolkit.ptypes import ActionHandler, AsyncBackend, Completer
12
+
13
+
14
+ class TestProtocolCompliance:
15
+ """Test protocol compliance for various interfaces."""
16
+
17
+ def test_async_backend_protocol(self):
18
+ """Test AsyncBackend protocol compliance."""
19
+
20
+ class TestAsyncBackend:
21
+ async def handle_input(self, user_input: str) -> bool:
22
+ return True
23
+
24
+ backend = TestAsyncBackend()
25
+ assert isinstance(backend, AsyncBackend)
26
+ assert hasattr(backend, "handle_input")
27
+
28
+ def test_action_handler_protocol(self):
29
+ """Test ActionHandler protocol compliance."""
30
+
31
+ class TestActionHandler:
32
+ def execute_action(self, action_name: str, context) -> None:
33
+ pass
34
+
35
+ def handle_command(self, command: str) -> None:
36
+ pass
37
+
38
+ def validate_action(self, action_name: str) -> bool:
39
+ return True
40
+
41
+ def list_actions(self) -> list:
42
+ return []
43
+
44
+ handler = TestActionHandler()
45
+ assert isinstance(handler, ActionHandler)
46
+ assert hasattr(handler, "execute_action")
47
+ assert hasattr(handler, "handle_command")
48
+ assert hasattr(handler, "validate_action")
49
+ assert hasattr(handler, "list_actions")
50
+
51
+ def test_completer_protocol(self):
52
+ """Test Completer protocol compliance."""
53
+
54
+ class TestCompleter:
55
+ def get_completions(self, document, complete_event):
56
+ return []
57
+
58
+ completer = TestCompleter()
59
+ assert isinstance(completer, Completer)
60
+ assert hasattr(completer, "get_completions")
61
+
62
+
63
+ class TestMockBackendCompliance:
64
+ """Test mock backend implementations for protocol compliance."""
65
+
66
+ def test_mock_backend_async_protocol(self):
67
+ """Test mock backend implements AsyncBackend protocol."""
68
+ mock_backend = Mock(spec=AsyncBackend)
69
+ mock_backend.handle_input = AsyncMock(return_value=True)
70
+
71
+ # Should have required method
72
+ assert hasattr(mock_backend, "handle_input")
73
+ assert callable(mock_backend.handle_input)
74
+
75
+ @pytest.mark.asyncio
76
+ async def test_mock_backend_functionality(self):
77
+ """Test mock backend functionality."""
78
+ mock_backend = Mock(spec=AsyncBackend)
79
+ mock_backend.handle_input = AsyncMock(return_value=True)
80
+
81
+ result = await mock_backend.handle_input("test input")
82
+ assert result is True
83
+ mock_backend.handle_input.assert_called_once_with("test input")
84
+
85
+
86
+ class TestRegistryProtocolCompliance:
87
+ """Test ActionRegistry protocol compliance."""
88
+
89
+ def setup_method(self):
90
+ """Set up test registry."""
91
+ self.registry = ActionRegistry()
92
+
93
+ def test_implements_action_handler(self):
94
+ """Test registry implements ActionHandler protocol."""
95
+ assert isinstance(self.registry, ActionHandler)
96
+
97
+ def test_execute_action_method(self):
98
+ """Test execute_action method signature."""
99
+ from repl_toolkit.actions import ActionContext
100
+
101
+ context = ActionContext(registry=self.registry)
102
+
103
+ # Should not raise error for built-in action
104
+ self.registry.execute_action("show_help", context)
105
+
106
+ def test_handle_command_method(self):
107
+ """Test handle_command method signature."""
108
+ # Should not raise error for unknown command (now synchronous)
109
+ self.registry.handle_command("/unknown")
110
+
111
+ def test_validate_action_method(self):
112
+ """Test validate_action method signature."""
113
+ assert self.registry.validate_action("show_help") is True
114
+ assert self.registry.validate_action("nonexistent") is False
115
+
116
+ def test_list_actions_method(self):
117
+ """Test list_actions method signature."""
118
+ actions = self.registry.list_actions()
119
+ assert isinstance(actions, list)
120
+ assert len(actions) > 0
121
+
122
+
123
+ class TestBackendUsagePatterns:
124
+ """Test common backend usage patterns for both interactive and headless modes."""
125
+
126
+ def test_backend_for_interactive_mode(self):
127
+ """Test backend suitable for interactive mode."""
128
+
129
+ class InteractiveBackend:
130
+ async def handle_input(self, user_input: str) -> bool:
131
+ # Interactive backends might do complex processing
132
+ print(f"Processing: {user_input}")
133
+ return True
134
+
135
+ backend = InteractiveBackend()
136
+ assert isinstance(backend, AsyncBackend)
137
+
138
+ def test_backend_for_headless_mode(self):
139
+ """Test backend suitable for headless mode."""
140
+
141
+ class HeadlessBackend:
142
+ def __init__(self):
143
+ self.results = []
144
+
145
+ async def handle_input(self, user_input: str) -> bool:
146
+ # Headless backends might accumulate results
147
+ self.results.append(f"Processed: {user_input}")
148
+ return True
149
+
150
+ backend = HeadlessBackend()
151
+ assert isinstance(backend, AsyncBackend)
152
+ assert hasattr(backend, "results")
153
+
154
+ def test_unified_backend_for_both_modes(self):
155
+ """Test backend that works for both interactive and headless modes."""
156
+
157
+ class UnifiedBackend:
158
+ def __init__(self, mode="interactive"):
159
+ self.mode = mode
160
+ self.results = []
161
+
162
+ async def handle_input(self, user_input: str) -> bool:
163
+ if self.mode == "interactive":
164
+ print(f"Interactive: {user_input}")
165
+ else:
166
+ self.results.append(user_input)
167
+ return True
168
+
169
+ # Same backend class works for both modes
170
+ interactive_backend = UnifiedBackend("interactive")
171
+ headless_backend = UnifiedBackend("headless")
172
+
173
+ assert isinstance(interactive_backend, AsyncBackend)
174
+ assert isinstance(headless_backend, AsyncBackend)