Some checks failed
Test Suite / unit-tests (3.11) (push) Has been cancelled
Test Suite / unit-tests (3.12) (push) Has been cancelled
Test Suite / integration-tests (push) Has been cancelled
Test Suite / e2e-tests (push) Has been cancelled
Test Suite / performance-tests (push) Has been cancelled
Test Suite / code-quality (push) Has been cancelled
Test Suite / security-scan (push) Has been cancelled
Test Suite / test-summary (push) Has been cancelled
- Remove deprecated 'query' command (replaced by 'db-query') - Remove deprecated 'schema' command (replaced by 'db-schema') - Remove 4 obsolete tests that tested deprecated functionality - Update all remaining tests to use new db-prefixed command names - CLI now has clean, consistent command structure with proper prefixes - All 478 tests passing after cleanup This completes the CLI consistency convention implementation where all subsystem commands follow the "*-stats" pattern and use proper prefixes. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
287 lines
9.8 KiB
Python
287 lines
9.8 KiB
Python
"""
|
|
Test Database Command Reorganization for Issue #39.
|
|
|
|
This test validates the reorganization of CLI commands to prefix database
|
|
operations with 'db-' and adds new database management functionality.
|
|
|
|
Requirements tested:
|
|
- Command renaming: query → db-query, schema → db-schema
|
|
- New commands: db-delete, db-stats
|
|
- Global options enhancement: --database and --config without arguments
|
|
- Backward compatibility with deprecation warnings
|
|
- Comprehensive help and error handling
|
|
"""
|
|
|
|
import pytest
|
|
import json
|
|
from pathlib import Path
|
|
from tempfile import TemporaryDirectory
|
|
from click.testing import CliRunner
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
from markitect.cli import cli
|
|
|
|
|
|
class TestIssue39DatabaseCommandReorganization:
|
|
"""Test suite for database command reorganization."""
|
|
|
|
@pytest.fixture
|
|
def runner(self):
|
|
"""Create CLI test runner."""
|
|
return CliRunner()
|
|
|
|
@pytest.fixture
|
|
def temp_dir(self):
|
|
"""Create a temporary directory for testing."""
|
|
with TemporaryDirectory() as temp_dir:
|
|
yield Path(temp_dir)
|
|
|
|
def test_db_query_command_exists_and_works(self, runner):
|
|
"""
|
|
Test that db-query command exists and works as replacement for query.
|
|
|
|
Issue #39: Command reorganization with db- prefix
|
|
"""
|
|
with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
|
|
mock_db_instance = MagicMock()
|
|
mock_db_mgr.return_value = mock_db_instance
|
|
mock_db_instance.execute_query.return_value = [{'count': 5}]
|
|
|
|
result = runner.invoke(cli, [
|
|
'db-query', 'SELECT COUNT(*) as count FROM markdown_files'
|
|
])
|
|
|
|
assert result.exit_code == 0
|
|
assert 'count' in result.output
|
|
mock_db_instance.execute_query.assert_called_once()
|
|
|
|
def test_db_schema_command_exists_and_works(self, runner):
|
|
"""
|
|
Test that db-schema command exists and works as replacement for schema.
|
|
|
|
Issue #39: Command reorganization with db- prefix
|
|
"""
|
|
with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
|
|
mock_db_instance = MagicMock()
|
|
mock_db_mgr.return_value = mock_db_instance
|
|
mock_db_instance.get_schema.return_value = {
|
|
'markdown_files': {
|
|
'columns': [
|
|
{'name': 'id', 'type': 'INTEGER', 'primary_key': True}
|
|
]
|
|
}
|
|
}
|
|
|
|
result = runner.invoke(cli, ['db-schema'])
|
|
|
|
assert result.exit_code == 0
|
|
assert 'markdown_files' in result.output
|
|
mock_db_instance.get_schema.assert_called_once()
|
|
|
|
|
|
def test_db_delete_command_exists_and_requires_confirmation(self, runner, temp_dir):
|
|
"""
|
|
Test that db-delete command exists and requires user confirmation.
|
|
|
|
Issue #39: New db-delete command with confirmation
|
|
"""
|
|
db_file = temp_dir / "test.db"
|
|
|
|
# Create a proper SQLite database file
|
|
import sqlite3
|
|
conn = sqlite3.connect(str(db_file))
|
|
conn.execute("CREATE TABLE test (id INTEGER)")
|
|
conn.close()
|
|
|
|
# Test without confirmation (should not delete)
|
|
result = runner.invoke(cli, [
|
|
'db-delete', '--database', str(db_file)
|
|
], input='n\n')
|
|
|
|
# Should prompt for confirmation and not delete when user says no
|
|
assert 'confirm' in result.output.lower() or 'delete' in result.output.lower()
|
|
assert db_file.exists() # File should still exist
|
|
|
|
def test_db_delete_command_with_force_flag(self, runner, temp_dir):
|
|
"""
|
|
Test that db-delete --force bypasses confirmation.
|
|
|
|
Issue #39: New db-delete command with force option
|
|
"""
|
|
db_file = temp_dir / "test.db"
|
|
|
|
# Create a proper SQLite database file
|
|
import sqlite3
|
|
conn = sqlite3.connect(str(db_file))
|
|
conn.execute("CREATE TABLE test (id INTEGER)")
|
|
conn.close()
|
|
|
|
result = runner.invoke(cli, [
|
|
'db-delete', '--database', str(db_file), '--force'
|
|
])
|
|
|
|
if result.exit_code != 0:
|
|
print("Command output:", result.output)
|
|
print("Command exception:", result.exception)
|
|
assert result.exit_code == 0
|
|
assert not db_file.exists() # File should be deleted
|
|
|
|
def test_db_delete_handles_nonexistent_database_gracefully(self, runner, temp_dir):
|
|
"""
|
|
Test that db-delete handles non-existent database files gracefully.
|
|
|
|
Issue #39: Error handling for db-delete
|
|
"""
|
|
nonexistent_db = temp_dir / "nonexistent.db"
|
|
|
|
result = runner.invoke(cli, [
|
|
'db-delete', '--database', str(nonexistent_db), '--force'
|
|
])
|
|
|
|
# Should handle gracefully without crashing
|
|
assert result.exit_code == 0 or 'not found' in result.output.lower()
|
|
|
|
def test_db_stats_command_shows_database_statistics(self, runner, temp_dir):
|
|
"""
|
|
Test that db-stats command shows database statistics.
|
|
|
|
Issue #39: New db-stats command (renamed from db-status)
|
|
"""
|
|
# Create a test database file
|
|
db_file = temp_dir / "test.db"
|
|
import sqlite3
|
|
conn = sqlite3.connect(str(db_file))
|
|
conn.execute("CREATE TABLE test (id INTEGER)")
|
|
conn.close()
|
|
|
|
result = runner.invoke(cli, ['db-stats', '--database', str(db_file)])
|
|
|
|
assert result.exit_code == 0
|
|
assert 'size' in result.output.lower() or 'bytes' in result.output.lower()
|
|
assert 'accessible' in result.output.lower() or 'exists' in result.output.lower()
|
|
|
|
def test_db_stats_handles_nonexistent_database_gracefully(self, runner, temp_dir):
|
|
"""
|
|
Test that db-stats handles non-existent database gracefully.
|
|
|
|
Issue #39: Error handling for db-stats (renamed from db-status)
|
|
"""
|
|
nonexistent_db = temp_dir / "nonexistent.db"
|
|
|
|
result = runner.invoke(cli, ['db-stats', '--database', str(nonexistent_db)])
|
|
|
|
# Should handle gracefully
|
|
assert 'not found' in result.output.lower() or 'error' in result.output.lower()
|
|
|
|
|
|
def test_help_shows_new_command_structure(self, runner):
|
|
"""
|
|
Test that help output shows new db- prefixed commands.
|
|
|
|
Issue #39: Documentation update
|
|
"""
|
|
result = runner.invoke(cli, ['--help'])
|
|
|
|
assert result.exit_code == 0
|
|
assert 'db-query' in result.output
|
|
assert 'db-schema' in result.output
|
|
assert 'db-delete' in result.output
|
|
assert 'db-stats' in result.output
|
|
|
|
def test_db_commands_support_all_format_options(self, runner):
|
|
"""
|
|
Test that new db- commands support all format options.
|
|
|
|
Issue #39: Format compatibility
|
|
"""
|
|
formats = ['table', 'json', 'yaml', 'simple']
|
|
|
|
with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
|
|
mock_db_instance = MagicMock()
|
|
mock_db_mgr.return_value = mock_db_instance
|
|
mock_db_instance.execute_query.return_value = [{'test': 'data'}]
|
|
|
|
for fmt in formats:
|
|
result = runner.invoke(cli, [
|
|
'db-query', 'SELECT * FROM markdown_files', '--format', fmt
|
|
])
|
|
assert result.exit_code == 0, f"Format {fmt} failed"
|
|
|
|
def test_db_command_help_messages_are_comprehensive(self, runner):
|
|
"""
|
|
Test that all db- commands have comprehensive help messages.
|
|
|
|
Issue #39: Documentation completeness
|
|
"""
|
|
commands = ['db-query', 'db-schema', 'db-delete', 'db-stats']
|
|
|
|
for command in commands:
|
|
result = runner.invoke(cli, [command, '--help'])
|
|
assert result.exit_code == 0
|
|
assert len(result.output) > 100 # Should have substantial help text
|
|
assert 'usage' in result.output.lower() or 'help' in result.output.lower()
|
|
|
|
|
|
class TestIssue39BackwardCompatibility:
|
|
"""Test backward compatibility aspects."""
|
|
|
|
@pytest.fixture
|
|
def runner(self):
|
|
return CliRunner()
|
|
|
|
|
|
def test_no_breaking_changes_to_command_arguments(self, runner):
|
|
"""
|
|
Test that command arguments and options remain unchanged.
|
|
|
|
Issue #39: API compatibility
|
|
"""
|
|
with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
|
|
mock_db_instance = MagicMock()
|
|
mock_db_mgr.return_value = mock_db_instance
|
|
mock_db_instance.execute_query.return_value = []
|
|
|
|
# New commands should accept same arguments as old ones
|
|
result = runner.invoke(cli, [
|
|
'db-query', 'SELECT 1', '--format', 'json'
|
|
])
|
|
|
|
assert result.exit_code == 0
|
|
mock_db_instance.execute_query.assert_called_once()
|
|
|
|
|
|
class TestIssue39ErrorHandling:
|
|
"""Test error handling for new commands."""
|
|
|
|
@pytest.fixture
|
|
def runner(self):
|
|
return CliRunner()
|
|
|
|
def test_db_commands_handle_database_errors_gracefully(self, runner):
|
|
"""
|
|
Test that db- commands handle database errors gracefully.
|
|
|
|
Issue #39: Error handling robustness
|
|
"""
|
|
with patch('markitect.cli.DatabaseManager') as mock_db_mgr:
|
|
mock_db_instance = MagicMock()
|
|
mock_db_mgr.return_value = mock_db_instance
|
|
mock_db_instance.execute_query.side_effect = Exception("Database error")
|
|
|
|
result = runner.invoke(cli, ['db-query', 'SELECT invalid'])
|
|
|
|
# Should handle error gracefully, not crash
|
|
assert result.exit_code != 0
|
|
assert 'error' in result.output.lower()
|
|
|
|
def test_invalid_command_suggestions(self, runner):
|
|
"""
|
|
Test that invalid commands suggest correct alternatives.
|
|
|
|
Issue #39: User experience improvement
|
|
"""
|
|
result = runner.invoke(cli, ['nonexistent-command'])
|
|
|
|
# Should suggest available commands or show help
|
|
assert result.exit_code != 0
|
|
# CLI should provide helpful error or suggestion |