mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
250 lines
8.5 KiB
Python
250 lines
8.5 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
|
# Copyright (c) 2025 Allaun
|
|
|
|
"""CLI Tests - Basic CLI functionality and argument parsing.
|
|
|
|
This module tests the core CLI functionality including:
|
|
- Argument parsing
|
|
- Help system
|
|
- Version command
|
|
- Tool command
|
|
- Error handling
|
|
"""
|
|
|
|
import pytest
|
|
import sys
|
|
from unittest.mock import patch, MagicMock
|
|
from nodupe.core.main import CLIHandler, main
|
|
from nodupe.core.loader import bootstrap
|
|
import argparse
|
|
|
|
class TestCLIArgumentParsing:
|
|
"""Test CLI argument parsing functionality."""
|
|
|
|
def test_cli_initialization(self):
|
|
"""Test that CLI handler initializes correctly."""
|
|
mock_loader = MagicMock()
|
|
cli = CLIHandler(mock_loader)
|
|
assert cli.loader == mock_loader
|
|
assert cli.parser is not None
|
|
|
|
def test_help_flag(self):
|
|
"""Test that help flag works."""
|
|
with patch('sys.argv', ['nodupe', '--help']):
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
main()
|
|
assert excinfo.value.code == 0
|
|
|
|
def test_version_command(self):
|
|
"""Test version command."""
|
|
with patch('sys.argv', ['nodupe', 'version']):
|
|
result = main()
|
|
assert result == 0
|
|
|
|
def test_tool_command_list(self):
|
|
"""Test tool command with list flag."""
|
|
with patch('sys.argv', ['nodupe', 'tool', '--list']):
|
|
result = main()
|
|
assert result == 0
|
|
|
|
def test_invalid_command(self):
|
|
"""Test invalid command handling."""
|
|
with patch('sys.argv', ['nodupe', 'invalid_command']):
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
main()
|
|
assert excinfo.value.code != 0
|
|
|
|
def test_debug_flag(self):
|
|
"""Test debug flag functionality."""
|
|
with patch('sys.argv', ['nodupe', '--debug', 'version']):
|
|
result = main()
|
|
assert result == 0
|
|
|
|
def test_performance_overrides(self):
|
|
"""Test performance override flags."""
|
|
with patch('sys.argv', ['nodupe', '--cores', '4', '--max-workers', '8', 'version']):
|
|
result = main()
|
|
assert result == 0
|
|
|
|
class TestCLIHelpSystem:
|
|
"""Test CLI help system functionality."""
|
|
|
|
def test_help_output_contains_commands(self):
|
|
"""Test that help output contains expected commands."""
|
|
with patch('sys.argv', ['nodupe', '--help']):
|
|
with pytest.raises(SystemExit):
|
|
main()
|
|
|
|
def test_version_help(self):
|
|
"""Test version command help."""
|
|
with patch('sys.argv', ['nodupe', 'version', '--help']):
|
|
with pytest.raises(SystemExit):
|
|
main()
|
|
|
|
def test_tool_help(self):
|
|
"""Test tool command help."""
|
|
with patch('sys.argv', ['nodupe', 'tool', '--help']):
|
|
with pytest.raises(SystemExit):
|
|
main()
|
|
|
|
class TestCLIErrorHandling:
|
|
"""Test CLI error handling."""
|
|
|
|
def test_missing_required_args(self):
|
|
"""Test missing required arguments."""
|
|
with patch('sys.argv', ['nodupe', 'scan']):
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
main()
|
|
assert excinfo.value.code != 0
|
|
|
|
def test_invalid_file_path(self):
|
|
"""Test invalid file path handling."""
|
|
with patch('sys.argv', ['nodupe', 'scan', '/nonexistent/path']):
|
|
result = main()
|
|
assert result != 0
|
|
|
|
def test_permission_error_handling(self):
|
|
"""Test permission error handling."""
|
|
with patch('sys.argv', ['nodupe', 'scan', '/root']):
|
|
result = main()
|
|
# This might succeed on some systems, so we just check it doesn't crash
|
|
assert isinstance(result, int)
|
|
|
|
class TestCLICommandRegistration:
|
|
"""Test command registration functionality."""
|
|
|
|
def test_builtin_commands_registered(self):
|
|
"""Test that built-in commands are registered."""
|
|
mock_loader = MagicMock()
|
|
mock_loader.tool_registry = MagicMock()
|
|
mock_loader.tool_registry.get_tools.return_value = []
|
|
|
|
cli = CLIHandler(mock_loader)
|
|
|
|
# Check that version and tool commands are available
|
|
with patch('sys.argv', ['nodupe', 'version']):
|
|
result = cli.run()
|
|
assert result == 0
|
|
|
|
with patch('sys.argv', ['nodupe', 'tool']):
|
|
result = cli.run()
|
|
assert result == 0
|
|
|
|
def test_tool_commands_registered(self):
|
|
"""Test that tool commands are registered."""
|
|
mock_tool = MagicMock()
|
|
mock_tool.name = "test_tool"
|
|
mock_tool.register_commands = MagicMock()
|
|
|
|
mock_loader = MagicMock()
|
|
mock_loader.tool_registry = MagicMock()
|
|
mock_loader.tool_registry.get_tools.return_value = [mock_tool]
|
|
|
|
cli = CLIHandler(mock_loader)
|
|
|
|
# This should call the tool's register_commands method
|
|
assert mock_tool.register_commands.called
|
|
|
|
def test_command_dispatch(self):
|
|
"""Test command dispatch functionality."""
|
|
mock_loader = MagicMock()
|
|
cli = CLIHandler(mock_loader)
|
|
|
|
# Test that commands are properly dispatched
|
|
with patch('sys.argv', ['nodupe', 'version']):
|
|
result = cli.run()
|
|
assert result == 0
|
|
|
|
with patch('sys.argv', ['nodupe', 'tool', '--list']):
|
|
result = cli.run()
|
|
assert result == 0
|
|
|
|
class TestCLIPerformanceOverrides:
|
|
"""Test performance override functionality."""
|
|
|
|
def test_cores_override(self):
|
|
"""Test cores override."""
|
|
mock_loader = MagicMock()
|
|
mock_loader.config = MagicMock()
|
|
mock_loader.config.config = {'cpu_cores': 2}
|
|
|
|
cli = CLIHandler(mock_loader)
|
|
|
|
with patch('sys.argv', ['nodupe', '--cores', '8', 'version']):
|
|
result = cli.run()
|
|
assert result == 0
|
|
assert mock_loader.config.config['cpu_cores'] == 8
|
|
|
|
def test_max_workers_override(self):
|
|
"""Test max workers override."""
|
|
mock_loader = MagicMock()
|
|
mock_loader.config = MagicMock()
|
|
mock_loader.config.config = {'max_workers': 4}
|
|
|
|
cli = CLIHandler(mock_loader)
|
|
|
|
with patch('sys.argv', ['nodupe', '--max-workers', '16', 'version']):
|
|
result = cli.run()
|
|
assert result == 0
|
|
assert mock_loader.config.config['max_workers'] == 16
|
|
|
|
def test_batch_size_override(self):
|
|
"""Test batch size override."""
|
|
mock_loader = MagicMock()
|
|
mock_loader.config = MagicMock()
|
|
mock_loader.config.config = {'batch_size': 100}
|
|
|
|
cli = CLIHandler(mock_loader)
|
|
|
|
with patch('sys.argv', ['nodupe', '--batch-size', '500', 'version']):
|
|
result = cli.run()
|
|
assert result == 0
|
|
assert mock_loader.config.config['batch_size'] == 500
|
|
|
|
class TestCLIDebugLogging:
|
|
"""Test debug logging functionality."""
|
|
|
|
def test_debug_logging_enabled(self):
|
|
"""Test that debug logging is enabled with --debug flag."""
|
|
import logging
|
|
with patch('sys.argv', ['nodupe', '--debug', 'version']):
|
|
with patch('nodupe.core.main.logging.getLogger') as mock_logger:
|
|
result = main()
|
|
assert result == 0
|
|
# Check that debug logging was set up
|
|
mock_logger.return_value.setLevel.assert_called_with(logging.DEBUG)
|
|
|
|
def test_debug_logging_disabled(self):
|
|
"""Test that debug logging is not enabled without --debug flag."""
|
|
with patch('sys.argv', ['nodupe', 'version']):
|
|
with patch('nodupe.core.main.logging.getLogger') as mock_logger:
|
|
result = main()
|
|
assert result == 0
|
|
# Debug logging should not be set up
|
|
mock_logger.return_value.setLevel.assert_not_called()
|
|
|
|
class TestCLIIntegration:
|
|
"""Test CLI integration with core components."""
|
|
|
|
def test_cli_with_bootstrap(self):
|
|
"""Test CLI with actual bootstrap."""
|
|
with patch('sys.argv', ['nodupe', 'version']):
|
|
result = main()
|
|
assert result == 0
|
|
|
|
def test_cli_error_handling_integration(self):
|
|
"""Test CLI error handling with real bootstrap."""
|
|
with patch('sys.argv', ['nodupe', 'invalid_command']):
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
main()
|
|
assert excinfo.value.code != 0
|
|
|
|
def test_cli_help_integration(self):
|
|
"""Test CLI help with real bootstrap."""
|
|
with patch('sys.argv', ['nodupe', '--help']):
|
|
with pytest.raises(SystemExit) as excinfo:
|
|
main()
|
|
assert excinfo.value.code == 0
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__, "-v"])
|