| |
| """ |
| 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 |
|
|
| |
| 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 |
| |
|
|
|
|
| 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 |
| |
| |
| |
|
|
| @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() |
| |
|
|
| @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() |
| |
|
|
|
|
| class TestCLIArguments: |
| """Test CLI argument parsing.""" |
|
|
| def test_cli_with_command_arg(self): |
| """Test CLI with -c argument.""" |
| |
| |
| |
| 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 |
| |
| |
|
|
| @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 |
| |
| |
|
|
|
|
| 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() |
| |
| |
|
|
| @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") |
| |
| |
|
|
|
|
| if __name__ == "__main__": |
| pytest.main([__file__, "-v"]) |
|
|