walidsobhie-code
refactor: Squeeze folders further - cleaner structure
65888d5
#!/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"])