File size: 6,477 Bytes
b6ae7b8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#!/usr/bin/env python3
"""
Integration Tests for Stack 2.9 CLI
Full CLI workflow tests.
"""

import pytest
import sys
import os
import json
import argparse
from pathlib import Path
from unittest.mock import MagicMock, patch, AsyncMock

# Add stack_cli to path
sys.path.insert(0, str(Path(__file__).parent.parent / "stack_cli"))

from stack_cli.cli import (
    StackCLI,
    ChatMode,
    CommandMode,
    VoiceInterface,
    main,
    print_banner,
    print_colored,
    format_output
)


class TestCLIComponents:
    """Test CLI components."""

    def test_print_banner(self, capsys):
        """Test banner printing."""
        print_banner()
        captured = capsys.readouterr()
        assert "Stack" in captured.out

    def test_cli_creation(self):
        """Test CLI can be created."""
        with patch('stack_cli.cli.create_agent'):
            cli = StackCLI()
        
        assert cli is not None
        assert hasattr(cli, 'agent')
        assert hasattr(cli, 'chat_mode')
        assert hasattr(cli, 'command_mode')

    def test_chat_mode_creation(self):
        """Test chat mode can be created."""
        with patch('stack_cli.cli.create_agent') as mock_create:
            mock_agent = MagicMock()
            mock_create.return_value = mock_agent
            
            chat = ChatMode(mock_agent)
        
        assert chat is not None
        assert chat.agent == mock_agent
        assert chat.history == []

    def test_command_mode_creation(self):
        """Test command mode can be created."""
        with patch('stack_cli.cli.create_agent') as mock_create:
            mock_agent = MagicMock()
            mock_create.return_value = mock_agent
            
            cmd = CommandMode(mock_agent)
        
        assert cmd is not None
        assert cmd.agent == mock_agent

    def test_voice_interface_creation(self):
        """Test voice interface creation."""
        voice = VoiceInterface()
        
        assert voice is not None
        # available depends on dependencies


class TestCLIWorkflows:
    """Test CLI workflow integration."""

    @patch('stack_cli.cli.StackCLI')
    def test_run_interactive(self, mock_cli_class):
        """Test interactive mode."""
        mock_cli = MagicMock()
        mock_cli_class.return_value = mock_cli
        
        # This should not crash
        # Would need more complex mocking for full test

    @patch('stack_cli.cli.StackCLI')
    def test_run_command(self, mock_cli_class):
        """Test command execution mode."""
        mock_cli = MagicMock()
        mock_cli.run_command.return_value = "result"
        mock_cli_class.return_value = mock_cli
        
        cli = StackCLI()
        # Test would go here

    @patch('stack_cli.cli.StackCLI')
    def test_run_tools(self, mock_cli_class):
        """Test tool execution mode."""
        mock_cli = MagicMock()
        mock_cli.run_tools.return_value = "tool result"
        mock_cli_class.return_value = mock_cli
        
        cli = StackCLI()
        # Test would go here


class TestCLIArguments:
    """Test CLI argument parsing."""

    def test_cli_with_command_arg(self):
        """Test CLI with -c argument."""
        # Test that argparse works
        # Would need to mock sys.argv
        
    def test_cli_with_tools_arg(self):
        """Test CLI with -t argument."""
        pass

    def test_cli_with_output_arg(self):
        """Test CLI with -o argument."""
        pass

    def test_cli_with_format_arg(self):
        """Test CLI with -f argument."""
        pass


class TestOutputFormatting:
    """Test output formatting in CLI."""

    def test_format_text_output(self):
        """Test text format output."""
        data = {"key": "value", "number": 42}
        result = format_output(data, "text")
        
        assert "key" in result

    def test_format_json_output(self):
        """Test JSON format output."""
        data = {"key": "value"}
        result = format_output(data, "json")
        
        parsed = json.loads(result)
        assert parsed["key"] == "value"

    def test_format_list_output(self):
        """Test list format output."""
        data = ["item1", "item2", "item3"]
        result = format_output(data, "text")
        
        assert "item1" in result


class TestCLIColors:
    """Test CLI color utilities."""

    def test_colored_output_red(self, capsys):
        """Test red color output."""
        print_colored("error message", "red")
        captured = capsys.readouterr()
        assert "error message" in captured.out

    def test_colored_output_green(self, capsys):
        """Test green color output."""
        print_colored("success message", "green")
        captured = capsys.readouterr()
        assert "success message" in captured.out

    def test_colored_output_cyan(self, capsys):
        """Test cyan color output."""
        print_colored("info message", "cyan")
        captured = capsys.readouterr()
        assert "info message" in captured.out


class TestMainFunction:
    """Test main entry point."""

    @patch('sys.argv', ['stack.py'])
    @patch('stack_cli.cli.StackCLI')
    def test_main_defaults(self, mock_cli_class):
        """Test main with defaults."""
        mock_cli = MagicMock()
        mock_cli.run_interactive = MagicMock()
        mock_cli_class.return_value = mock_cli
        
        # Would need more complex setup for full test

    @patch('sys.argv', ['stack.py', '-c', 'test query'])
    @patch('stack_cli.cli.StackCLI')
    def test_main_with_command(self, mock_cli_class):
        """Test main with command."""
        mock_cli = MagicMock()
        mock_cli.run_command = MagicMock(return_value=True)
        mock_cli_class.return_value = mock_cli
        
        # Test would go here


class TestCLIErrors:
    """Test CLI error handling."""

    @patch('sys.argv', ['stack.py'])
    @patch('stack_cli.cli.create_agent')
    def test_cli_keyboard_interrupt(self, mock_create):
        """Test handling of keyboard interrupt."""
        mock_create.side_effect = KeyboardInterrupt()
        
        # Should handle gracefully

    @patch('sys.argv', ['stack.py'])
    @patch('stack_cli.cli.create_agent')
    def test_cli_general_exception(self, mock_create):
        """Test handling of general exceptions."""
        mock_create.side_effect = RuntimeError("test error")
        
        # Should handle gracefully


if __name__ == "__main__":
    pytest.main([__file__, "-v"])