code-puppy 0.0.153__py3-none-any.whl → 0.0.155__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.
Files changed (46) hide show
  1. code_puppy/agent.py +4 -3
  2. code_puppy/agents/agent_creator_agent.py +9 -2
  3. code_puppy/agents/runtime_manager.py +12 -4
  4. code_puppy/command_line/mcp/install_command.py +50 -1
  5. code_puppy/command_line/mcp/wizard_utils.py +88 -17
  6. code_puppy/config.py +8 -2
  7. code_puppy/main.py +17 -4
  8. code_puppy/mcp/__init__.py +2 -2
  9. code_puppy/mcp/config_wizard.py +1 -1
  10. code_puppy/message_history_processor.py +1 -9
  11. code_puppy/messaging/spinner/console_spinner.py +1 -1
  12. code_puppy/model_factory.py +13 -12
  13. code_puppy/models.json +26 -0
  14. code_puppy/round_robin_model.py +35 -18
  15. code_puppy/summarization_agent.py +1 -3
  16. code_puppy/tools/agent_tools.py +41 -138
  17. code_puppy/tools/file_operations.py +116 -96
  18. code_puppy/tui/app.py +1 -1
  19. {code_puppy-0.0.153.data → code_puppy-0.0.155.data}/data/code_puppy/models.json +26 -0
  20. {code_puppy-0.0.153.dist-info → code_puppy-0.0.155.dist-info}/METADATA +2 -2
  21. {code_puppy-0.0.153.dist-info → code_puppy-0.0.155.dist-info}/RECORD +24 -46
  22. code_puppy/token_utils.py +0 -67
  23. code_puppy/tools/token_check.py +0 -32
  24. code_puppy/tui/tests/__init__.py +0 -1
  25. code_puppy/tui/tests/test_agent_command.py +0 -79
  26. code_puppy/tui/tests/test_chat_message.py +0 -28
  27. code_puppy/tui/tests/test_chat_view.py +0 -88
  28. code_puppy/tui/tests/test_command_history.py +0 -89
  29. code_puppy/tui/tests/test_copy_button.py +0 -191
  30. code_puppy/tui/tests/test_custom_widgets.py +0 -27
  31. code_puppy/tui/tests/test_disclaimer.py +0 -27
  32. code_puppy/tui/tests/test_enums.py +0 -15
  33. code_puppy/tui/tests/test_file_browser.py +0 -60
  34. code_puppy/tui/tests/test_help.py +0 -38
  35. code_puppy/tui/tests/test_history_file_reader.py +0 -107
  36. code_puppy/tui/tests/test_input_area.py +0 -33
  37. code_puppy/tui/tests/test_settings.py +0 -44
  38. code_puppy/tui/tests/test_sidebar.py +0 -33
  39. code_puppy/tui/tests/test_sidebar_history.py +0 -153
  40. code_puppy/tui/tests/test_sidebar_history_navigation.py +0 -132
  41. code_puppy/tui/tests/test_status_bar.py +0 -54
  42. code_puppy/tui/tests/test_timestamped_history.py +0 -52
  43. code_puppy/tui/tests/test_tools.py +0 -82
  44. {code_puppy-0.0.153.dist-info → code_puppy-0.0.155.dist-info}/WHEEL +0 -0
  45. {code_puppy-0.0.153.dist-info → code_puppy-0.0.155.dist-info}/entry_points.txt +0 -0
  46. {code_puppy-0.0.153.dist-info → code_puppy-0.0.155.dist-info}/licenses/LICENSE +0 -0
code_puppy/token_utils.py DELETED
@@ -1,67 +0,0 @@
1
- import json
2
-
3
- import pydantic
4
- from pydantic_ai.messages import ModelMessage
5
-
6
-
7
- def estimate_token_count(text: str) -> int:
8
- """
9
- Simple token estimation using len(message) - 4.
10
- This replaces tiktoken with a much simpler approach.
11
- """
12
- return max(1, len(text) - 4)
13
-
14
-
15
- def stringify_message_part(part) -> str:
16
- """
17
- Convert a message part to a string representation for token estimation or other uses.
18
-
19
- Args:
20
- part: A message part that may contain content or be a tool call
21
-
22
- Returns:
23
- String representation of the message part
24
- """
25
- result = ""
26
- if hasattr(part, "part_kind"):
27
- result += part.part_kind + ": "
28
- else:
29
- result += str(type(part)) + ": "
30
-
31
- # Handle content
32
- if hasattr(part, "content") and part.content:
33
- # Handle different content types
34
- if isinstance(part.content, str):
35
- result = part.content
36
- elif isinstance(part.content, pydantic.BaseModel):
37
- result = json.dumps(part.content.model_dump())
38
- elif isinstance(part.content, dict):
39
- result = json.dumps(part.content)
40
- else:
41
- result = str(part.content)
42
-
43
- # Handle tool calls which may have additional token costs
44
- # If part also has content, we'll process tool calls separately
45
- if hasattr(part, "tool_name") and part.tool_name:
46
- # Estimate tokens for tool name and parameters
47
- tool_text = part.tool_name
48
- if hasattr(part, "args"):
49
- tool_text += f" {str(part.args)}"
50
- result += tool_text
51
-
52
- return result
53
-
54
-
55
- def estimate_tokens_for_message(message: ModelMessage) -> int:
56
- """
57
- Estimate the number of tokens in a message using len(message) - 4.
58
- Simple and fast replacement for tiktoken.
59
- """
60
- total_tokens = 0
61
-
62
- for part in message.parts:
63
- part_str = stringify_message_part(part)
64
- if part_str:
65
- total_tokens += estimate_token_count(part_str)
66
-
67
- return max(1, total_tokens)
@@ -1,32 +0,0 @@
1
- try:
2
- from code_puppy.token_utils import estimate_tokens_for_message
3
- from code_puppy.tools.common import get_model_context_length
4
- except ImportError:
5
- # Fallback if these modules aren't available in the internal version
6
- def get_model_context_length():
7
- return 128000 # Default context length
8
-
9
- def estimate_tokens_for_message(msg):
10
- # Simple fallback estimation
11
- return len(str(msg)) // 4 # Rough estimate: 4 chars per token
12
-
13
-
14
- def token_guard(num_tokens: int):
15
- try:
16
- from code_puppy import state_management
17
-
18
- current_history = state_management.get_message_history()
19
- message_hist_tokens = sum(
20
- estimate_tokens_for_message(msg) for msg in current_history
21
- )
22
-
23
- if message_hist_tokens + num_tokens > (get_model_context_length() * 0.9):
24
- raise ValueError(
25
- "Tokens produced by this tool call would exceed model capacity"
26
- )
27
- except ImportError:
28
- # Fallback: simple check against a reasonable limit
29
- if num_tokens > 10000:
30
- raise ValueError(
31
- f"Token count {num_tokens} exceeds safety limit of 10,000 tokens"
32
- )
@@ -1 +0,0 @@
1
- # Test package for tui
@@ -1,79 +0,0 @@
1
- """Tests for the /agent command handling in TUI mode."""
2
-
3
- from unittest.mock import MagicMock, patch
4
-
5
- from code_puppy.tui.app import CodePuppyTUI
6
-
7
-
8
- class TestTUIAgentCommand:
9
- """Test the TUI's handling of /agent commands."""
10
-
11
- @patch("code_puppy.tui.app.get_runtime_agent_manager")
12
- @patch("code_puppy.tui.app.handle_command")
13
- def test_tui_handles_agent_command(self, mock_handle_command, mock_get_manager):
14
- """Test that TUI properly delegates /agent commands to command handler."""
15
- # Create a TUI app instance
16
- app = CodePuppyTUI()
17
-
18
- # Mock the agent manager and agent
19
- mock_agent_instance = MagicMock()
20
- mock_manager = MagicMock()
21
- mock_manager.get_agent.return_value = mock_agent_instance
22
- mock_get_manager.return_value = mock_manager
23
-
24
- # Mock handle_command to simulate successful processing
25
- mock_handle_command.return_value = True
26
-
27
- # Simulate processing an /agent command
28
- message = "/agent code-puppy"
29
- app.agent = mock_agent_instance
30
-
31
- # Call the method that processes messages
32
- # We'll need to mock some UI elements to avoid complex setup
33
- with (
34
- patch.object(app, "add_user_message"),
35
- patch.object(app, "_update_submit_cancel_button"),
36
- patch.object(app, "start_agent_progress"),
37
- patch.object(app, "stop_agent_progress"),
38
- patch.object(app, "refresh_history_display"),
39
- ):
40
- import asyncio
41
-
42
- # Create an event loop for the async test
43
- loop = asyncio.get_event_loop()
44
- loop.run_until_complete(app.process_message(message))
45
-
46
- # Verify that handle_command was called with the correct argument
47
- mock_handle_command.assert_called_once_with(message)
48
-
49
- # Verify that agent manager's get_agent was called to refresh the agent instance
50
- mock_manager.get_agent.assert_called()
51
-
52
- @patch("code_puppy.tui.app.get_runtime_agent_manager")
53
- def test_tui_refreshes_agent_after_command(self, mock_get_manager):
54
- """Test that TUI refreshes its agent instance after processing /agent command."""
55
- # Create a TUI app instance
56
- app = CodePuppyTUI()
57
-
58
- # Mock the agent manager
59
- mock_manager = MagicMock()
60
- initial_agent = MagicMock()
61
- new_agent = MagicMock()
62
-
63
- # Set initial agent
64
- app.agent = initial_agent
65
- app.agent_manager = mock_manager
66
-
67
- # Mock manager to return a new agent instance
68
- mock_manager.get_agent.return_value = new_agent
69
- mock_get_manager.return_value = mock_manager
70
-
71
- # Simulate that an /agent command was processed
72
- with patch("code_puppy.tui.app.handle_command"):
73
- import asyncio
74
-
75
- loop = asyncio.get_event_loop()
76
- loop.run_until_complete(app.process_message("/agent code-puppy"))
77
-
78
- # Verify that the agent was refreshed through the manager
79
- mock_manager.get_agent.assert_called()
@@ -1,28 +0,0 @@
1
- import unittest
2
- from datetime import datetime
3
-
4
- from code_puppy.tui.models.chat_message import ChatMessage
5
- from code_puppy.tui.models.enums import MessageType
6
-
7
-
8
- class TestChatMessage(unittest.TestCase):
9
- def test_chat_message_defaults(self):
10
- msg = ChatMessage(
11
- id="1", type=MessageType.USER, content="hi", timestamp=datetime.now()
12
- )
13
- self.assertEqual(msg.metadata, {})
14
-
15
- def test_chat_message_with_metadata(self):
16
- meta = {"foo": "bar"}
17
- msg = ChatMessage(
18
- id="2",
19
- type=MessageType.AGENT,
20
- content="hello",
21
- timestamp=datetime.now(),
22
- metadata=meta,
23
- )
24
- self.assertEqual(msg.metadata, meta)
25
-
26
-
27
- if __name__ == "__main__":
28
- unittest.main()
@@ -1,88 +0,0 @@
1
- import unittest
2
- from datetime import datetime
3
- from unittest.mock import patch
4
-
5
- from code_puppy.tui.components.chat_view import ChatView
6
- from code_puppy.tui.models.chat_message import ChatMessage
7
- from code_puppy.tui.models.enums import MessageType
8
-
9
-
10
- class TestChatView(unittest.TestCase):
11
- def setUp(self):
12
- self.chat_view = ChatView()
13
-
14
- @patch.object(ChatView, "mount")
15
- def test_add_message_user(self, mock_mount):
16
- msg = ChatMessage(
17
- id="test-user-1",
18
- type=MessageType.USER,
19
- content="Hello",
20
- timestamp=datetime.now(),
21
- )
22
- self.chat_view.add_message(msg)
23
- self.assertIn(msg, self.chat_view.messages)
24
- mock_mount.assert_called_once()
25
-
26
- @patch.object(ChatView, "mount")
27
- def test_add_message_agent(self, mock_mount):
28
- msg = ChatMessage(
29
- id="test-agent-1",
30
- type=MessageType.AGENT,
31
- content="Hi there!",
32
- timestamp=datetime.now(),
33
- )
34
- self.chat_view.add_message(msg)
35
- self.assertIn(msg, self.chat_view.messages)
36
- mock_mount.assert_called_once()
37
-
38
- @patch.object(ChatView, "mount")
39
- def test_add_message_system(self, mock_mount):
40
- msg = ChatMessage(
41
- id="test-system-1",
42
- type=MessageType.SYSTEM,
43
- content="System message",
44
- timestamp=datetime.now(),
45
- )
46
- self.chat_view.add_message(msg)
47
- self.assertIn(msg, self.chat_view.messages)
48
- mock_mount.assert_called_once()
49
-
50
- @patch.object(ChatView, "mount")
51
- def test_add_message_error(self, mock_mount):
52
- msg = ChatMessage(
53
- id="test-error-1",
54
- type=MessageType.ERROR,
55
- content="Error occurred",
56
- timestamp=datetime.now(),
57
- )
58
- self.chat_view.add_message(msg)
59
- self.assertIn(msg, self.chat_view.messages)
60
- mock_mount.assert_called_once()
61
-
62
- @patch.object(ChatView, "mount")
63
- @patch.object(ChatView, "query")
64
- def test_clear_messages(self, mock_query, mock_mount):
65
- # Mock the query method to return empty iterables
66
- mock_query.return_value = []
67
-
68
- msg = ChatMessage(
69
- id="test-clear-1",
70
- type=MessageType.USER,
71
- content="Hello",
72
- timestamp=datetime.now(),
73
- )
74
- self.chat_view.add_message(msg)
75
- self.chat_view.clear_messages()
76
- self.assertEqual(len(self.chat_view.messages), 0)
77
- # Verify that query was called to find widgets to remove
78
- self.assertTrue(mock_query.called)
79
-
80
- def test_render_agent_message_with_syntax(self):
81
- prefix = "Agent: "
82
- content = "Some text\n```python\nprint('hi')\n```"
83
- group = self.chat_view._render_agent_message_with_syntax(prefix, content)
84
- self.assertIsNotNone(group)
85
-
86
-
87
- if __name__ == "__main__":
88
- unittest.main()
@@ -1,89 +0,0 @@
1
- import re
2
- import unittest
3
- from unittest.mock import MagicMock, patch
4
-
5
- from code_puppy.config import COMMAND_HISTORY_FILE
6
- from code_puppy.tui.app import CodePuppyTUI
7
- from code_puppy.tui.components.custom_widgets import CustomTextArea
8
-
9
-
10
- class TestCommandHistory(unittest.TestCase):
11
- def setUp(self):
12
- self.app = CodePuppyTUI()
13
-
14
- @patch("builtins.open", new_callable=unittest.mock.mock_open)
15
- def test_action_send_message_saves_to_history(self, mock_open):
16
- # Setup test mocks
17
- self.app.query_one = MagicMock()
18
- input_field_mock = MagicMock(spec=CustomTextArea)
19
- input_field_mock.text = "test command"
20
- self.app.query_one.return_value = input_field_mock
21
-
22
- # Mock other methods to prevent full execution
23
- self.app.add_user_message = MagicMock()
24
- self.app._update_submit_cancel_button = MagicMock()
25
- self.app.run_worker = MagicMock()
26
-
27
- # Execute
28
- self.app.action_send_message()
29
-
30
- # Assertions
31
- mock_open.assert_called_once_with(COMMAND_HISTORY_FILE, "a")
32
- # Check that write was called with timestamped format
33
- write_calls = mock_open().write.call_args_list
34
- self.assertEqual(len(write_calls), 1)
35
- written_content = write_calls[0][0][0]
36
- # Should match pattern: \n# YYYY-MM-DDTHH:MM:SS\ntest command\n
37
- self.assertTrue(
38
- re.match(
39
- r"^\n# \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\ntest command\n$",
40
- written_content,
41
- )
42
- )
43
- self.app.add_user_message.assert_called_once_with("test command")
44
-
45
- @patch("builtins.open", new_callable=unittest.mock.mock_open)
46
- def test_action_send_message_empty_command(self, mock_open):
47
- # Setup test mocks
48
- self.app.query_one = MagicMock()
49
- input_field_mock = MagicMock(spec=CustomTextArea)
50
- input_field_mock.text = " " # Empty or whitespace-only command
51
- self.app.query_one.return_value = input_field_mock
52
-
53
- # Mock other methods
54
- self.app.add_user_message = MagicMock()
55
-
56
- # Execute
57
- self.app.action_send_message()
58
-
59
- # Assertions - nothing should happen with empty commands
60
- mock_open.assert_not_called()
61
- self.app.add_user_message.assert_not_called()
62
-
63
- @patch("builtins.open")
64
- def test_action_send_message_handles_error(self, mock_open):
65
- # Setup test mocks
66
- self.app.query_one = MagicMock()
67
- input_field_mock = MagicMock(spec=CustomTextArea)
68
- input_field_mock.text = "test command"
69
- self.app.query_one.return_value = input_field_mock
70
-
71
- # Mock other methods to prevent full execution
72
- self.app.add_user_message = MagicMock()
73
- self.app._update_submit_cancel_button = MagicMock()
74
- self.app.run_worker = MagicMock()
75
- self.app.add_error_message = MagicMock()
76
-
77
- # Make open throw an exception
78
- mock_open.side_effect = Exception("File error")
79
-
80
- # Execute
81
- self.app.action_send_message()
82
-
83
- # Assertions - error is printed to stdout, not added to UI
84
- # Message should still be processed despite error saving to history
85
- self.app.add_user_message.assert_called_once_with("test command")
86
-
87
-
88
- if __name__ == "__main__":
89
- unittest.main()
@@ -1,191 +0,0 @@
1
- """
2
- Tests for the copy button component.
3
- """
4
-
5
- from unittest.mock import MagicMock, patch
6
-
7
- from code_puppy.tui.components.copy_button import CopyButton
8
-
9
-
10
- class TestCopyButton:
11
- """Test cases for the CopyButton widget."""
12
-
13
- def test_copy_button_creation(self):
14
- """Test that a copy button can be created with text."""
15
- test_text = "Hello, World!"
16
- button = CopyButton(test_text)
17
-
18
- assert button.text_to_copy == test_text
19
- assert button.label == "📋 Copy"
20
-
21
- def test_update_text_to_copy(self):
22
- """Test updating the text to copy."""
23
- button = CopyButton("Initial text")
24
- new_text = "Updated text"
25
-
26
- button.update_text_to_copy(new_text)
27
-
28
- assert button.text_to_copy == new_text
29
-
30
- @patch("subprocess.run")
31
- def test_copy_to_clipboard_macos_success(self, mock_run):
32
- """Test successful clipboard copy on macOS."""
33
- mock_run.return_value = MagicMock(returncode=0)
34
-
35
- with patch("sys.platform", "darwin"):
36
- button = CopyButton("test content")
37
- success, error = button.copy_to_clipboard("test content")
38
-
39
- assert success is True
40
- assert error is None
41
- mock_run.assert_called_once_with(
42
- ["pbcopy"],
43
- input="test content",
44
- text=True,
45
- check=True,
46
- capture_output=True,
47
- )
48
-
49
- @patch("subprocess.run")
50
- def test_copy_to_clipboard_windows_success(self, mock_run):
51
- """Test successful clipboard copy on Windows."""
52
- mock_run.return_value = MagicMock(returncode=0)
53
-
54
- with patch("sys.platform", "win32"):
55
- button = CopyButton("test content")
56
- success, error = button.copy_to_clipboard("test content")
57
-
58
- assert success is True
59
- assert error is None
60
- mock_run.assert_called_once_with(
61
- ["clip"],
62
- input="test content",
63
- text=True,
64
- check=True,
65
- capture_output=True,
66
- )
67
-
68
- @patch("subprocess.run")
69
- def test_copy_to_clipboard_linux_success(self, mock_run):
70
- """Test successful clipboard copy on Linux with xclip."""
71
- mock_run.return_value = MagicMock(returncode=0)
72
-
73
- with patch("sys.platform", "linux"):
74
- button = CopyButton("test content")
75
- success, error = button.copy_to_clipboard("test content")
76
-
77
- assert success is True
78
- assert error is None
79
- mock_run.assert_called_once_with(
80
- ["xclip", "-selection", "clipboard"],
81
- input="test content",
82
- text=True,
83
- check=True,
84
- capture_output=True,
85
- )
86
-
87
- @patch("subprocess.run")
88
- def test_copy_to_clipboard_linux_xsel_fallback(self, mock_run):
89
- """Test Linux clipboard copy falls back to xsel when xclip fails."""
90
- # First call (xclip) fails, second call (xsel) succeeds
91
- mock_run.side_effect = [
92
- FileNotFoundError("xclip not found"),
93
- MagicMock(returncode=0),
94
- ]
95
-
96
- with patch("sys.platform", "linux"):
97
- button = CopyButton("test content")
98
- success, error = button.copy_to_clipboard("test content")
99
-
100
- assert success is True
101
- assert error is None
102
- assert mock_run.call_count == 2
103
- # Check that xsel was called as fallback
104
- mock_run.assert_any_call(
105
- ["xsel", "--clipboard", "--input"],
106
- input="test content",
107
- text=True,
108
- check=True,
109
- capture_output=True,
110
- )
111
-
112
- @patch("subprocess.run")
113
- def test_copy_to_clipboard_failure(self, mock_run):
114
- """Test clipboard copy failure handling."""
115
- from subprocess import CalledProcessError
116
-
117
- mock_run.side_effect = CalledProcessError(1, "pbcopy", "Command failed")
118
-
119
- with patch("sys.platform", "darwin"):
120
- button = CopyButton("test content")
121
- success, error = button.copy_to_clipboard("test content")
122
-
123
- assert success is False
124
- assert "Clipboard command failed" in error
125
-
126
- @patch("subprocess.run")
127
- def test_copy_to_clipboard_no_utility(self, mock_run):
128
- """Test clipboard copy when utility is not found."""
129
- mock_run.side_effect = FileNotFoundError("Command not found")
130
-
131
- with patch("sys.platform", "linux"):
132
- button = CopyButton("test content")
133
- success, error = button.copy_to_clipboard("test content")
134
-
135
- assert success is False
136
- assert "Clipboard utilities not found" in error
137
-
138
- def test_copy_button_labels(self):
139
- """Test that copy button has correct labels."""
140
- button = CopyButton("test")
141
-
142
- assert button._original_label == "📋 Copy"
143
- assert button._copied_label == "✅ Copied!"
144
-
145
- def test_copy_completed_message(self):
146
- """Test CopyCompleted message creation."""
147
- # Test success message
148
- success_msg = CopyButton.CopyCompleted(True)
149
- assert success_msg.success is True
150
- assert success_msg.error is None
151
-
152
- # Test error message
153
- error_msg = CopyButton.CopyCompleted(False, "Test error")
154
- assert error_msg.success is False
155
- assert error_msg.error == "Test error"
156
-
157
- @patch.object(CopyButton, "copy_to_clipboard")
158
- @patch.object(CopyButton, "post_message")
159
- def test_action_press_success(self, mock_post_message, mock_copy):
160
- """Test action_press method with successful copy."""
161
- mock_copy.return_value = (True, None)
162
-
163
- button = CopyButton("test content")
164
- button.action_press()
165
-
166
- mock_copy.assert_called_once_with("test content")
167
- mock_post_message.assert_called_once()
168
- # Note: timer is currently commented out in implementation
169
-
170
- # Check that the message posted is a CopyCompleted with success=True
171
- call_args = mock_post_message.call_args[0][0]
172
- assert isinstance(call_args, CopyButton.CopyCompleted)
173
- assert call_args.success is True
174
-
175
- @patch.object(CopyButton, "copy_to_clipboard")
176
- @patch.object(CopyButton, "post_message")
177
- def test_action_press_failure(self, mock_post_message, mock_copy):
178
- """Test action_press method with failed copy."""
179
- mock_copy.return_value = (False, "Test error")
180
-
181
- button = CopyButton("test content")
182
- button.action_press()
183
-
184
- mock_copy.assert_called_once_with("test content")
185
- mock_post_message.assert_called_once()
186
-
187
- # Check that the message posted is a CopyCompleted with success=False
188
- call_args = mock_post_message.call_args[0][0]
189
- assert isinstance(call_args, CopyButton.CopyCompleted)
190
- assert call_args.success is False
191
- assert call_args.error == "Test error"
@@ -1,27 +0,0 @@
1
- import unittest
2
-
3
- from code_puppy.tui.components.custom_widgets import CustomTextArea
4
-
5
-
6
- class DummyEvent:
7
- def __init__(self, key):
8
- self.key = key
9
-
10
-
11
- class TestCustomTextArea(unittest.TestCase):
12
- def setUp(self):
13
- self.text_area = CustomTextArea()
14
-
15
- def test_message_sent_on_enter(self):
16
- # Simulate pressing Enter
17
- event = DummyEvent("enter")
18
- # Should not raise
19
- self.text_area._on_key(event)
20
-
21
- def test_message_sent_class(self):
22
- msg = CustomTextArea.MessageSent()
23
- self.assertIsInstance(msg, CustomTextArea.MessageSent)
24
-
25
-
26
- if __name__ == "__main__":
27
- unittest.main()
@@ -1,27 +0,0 @@
1
- import unittest
2
- from unittest.mock import MagicMock
3
-
4
- # Skip importing the non-existent module
5
- # Commenting out: from code_puppy.tui.screens.disclaimer import DisclaimerScreen
6
-
7
-
8
- # We'll use unittest.skip to skip the entire test class
9
- @unittest.skip("DisclaimerScreen has been removed from the codebase")
10
- class TestDisclaimerScreen(unittest.TestCase):
11
- def setUp(self):
12
- # Create a mock screen instead of the real one
13
- self.screen = MagicMock()
14
- self.screen.get_disclaimer_content.return_value = "Prompt responsibly"
15
- self.screen.compose.return_value = [MagicMock()]
16
-
17
- def test_get_disclaimer_content(self):
18
- content = self.screen.get_disclaimer_content()
19
- self.assertIn("Prompt responsibly", content)
20
-
21
- def test_compose(self):
22
- widgets = list(self.screen.compose())
23
- self.assertGreaterEqual(len(widgets), 1)
24
-
25
-
26
- if __name__ == "__main__":
27
- unittest.main()
@@ -1,15 +0,0 @@
1
- import unittest
2
-
3
- from code_puppy.tui.models.enums import MessageType
4
-
5
-
6
- class TestMessageType(unittest.TestCase):
7
- def test_enum_values(self):
8
- self.assertEqual(MessageType.USER.value, "user")
9
- self.assertEqual(MessageType.AGENT.value, "agent")
10
- self.assertEqual(MessageType.SYSTEM.value, "system")
11
- self.assertEqual(MessageType.ERROR.value, "error")
12
-
13
-
14
- if __name__ == "__main__":
15
- unittest.main()