markitect-main/tests/test_issue_6_cli_integration.py

188 lines
7.3 KiB
Python
Raw Permalink Normal View History

2025-09-30 03:31:48 +02:00
"""
CLI Integration Tests for Issue #6: Generate Markdown Stub from Schema.
Tests the CLI commands for stub generation functionality.
"""
import json
import pytest
from pathlib import Path
from tempfile import NamedTemporaryFile, TemporaryDirectory
from click.testing import CliRunner
from markitect.cli import cli
class TestIssue6CLIIntegration:
"""Test CLI integration for stub generation."""
@pytest.fixture
def runner(self):
"""Create CLI test runner."""
return CliRunner()
@pytest.fixture
def sample_schema_file(self):
"""Create a temporary schema file for testing."""
schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "Test Schema",
"properties": {
"headings": {
"type": "object",
"properties": {
"level_1": {
"type": "array",
"minItems": 1,
"maxItems": 1
},
"level_2": {
"type": "array",
"minItems": 2,
"maxItems": 2
}
}
}
}
}
with NamedTemporaryFile(mode='w', suffix='.json', delete=False) as temp_file:
json.dump(schema, temp_file)
temp_file.flush()
yield Path(temp_file.name)
Path(temp_file.name).unlink()
def test_generate_stub_command_exists(self, runner):
"""The generate-stub command should exist in CLI."""
result = runner.invoke(cli, ['--help'])
assert result.exit_code == 0
assert 'generate-stub' in result.output or 'stub-generate' in result.output
def test_generate_stub_requires_schema_argument(self, runner):
"""generate-stub command should require schema file argument."""
result = runner.invoke(cli, ['generate-stub'])
assert result.exit_code != 0
# Should indicate missing argument
def test_generate_stub_outputs_to_stdout(self, runner, sample_schema_file):
"""generate-stub should output markdown to stdout by default."""
result = runner.invoke(cli, ['generate-stub', str(sample_schema_file)])
assert result.exit_code == 0
assert result.output is not None
assert len(result.output.strip()) > 0
# Should contain markdown heading syntax
assert '# ' in result.output
# Should contain some placeholder content
assert any(keyword in result.output.lower() for keyword in ['todo', 'placeholder', 'content'])
def test_generate_stub_with_output_file(self, runner, sample_schema_file):
"""generate-stub should save to file when --output specified."""
with TemporaryDirectory() as temp_dir:
output_file = Path(temp_dir) / "output.md"
result = runner.invoke(cli, [
'generate-stub', str(sample_schema_file),
'--output', str(output_file)
])
assert result.exit_code == 0
assert output_file.exists()
content = output_file.read_text()
assert '# ' in content
assert len(content.strip()) > 0
def test_generate_stub_with_different_formats(self, runner, sample_schema_file):
"""generate-stub should support different placeholder styles."""
# Test default style
result = runner.invoke(cli, ['generate-stub', str(sample_schema_file)])
assert result.exit_code == 0
default_output = result.output
# Test custom style (if supported)
result = runner.invoke(cli, [
'generate-stub', str(sample_schema_file),
'--style', 'detailed'
])
# Should not fail regardless of whether style is implemented
assert result.exit_code == 0
def test_generate_stub_handles_nonexistent_file(self, runner):
"""generate-stub should handle nonexistent schema files gracefully."""
result = runner.invoke(cli, ['generate-stub', 'nonexistent.json'])
assert result.exit_code != 0
assert 'not found' in result.output.lower() or 'error' in result.output.lower()
def test_generate_stub_handles_invalid_json(self, runner):
"""generate-stub should handle invalid JSON files gracefully."""
with NamedTemporaryFile(mode='w', suffix='.json', delete=False) as temp_file:
temp_file.write("invalid json content")
temp_file.flush()
try:
result = runner.invoke(cli, ['generate-stub', temp_file.name])
assert result.exit_code != 0
assert 'error' in result.output.lower() or 'invalid' in result.output.lower()
finally:
Path(temp_file.name).unlink()
def test_generate_stub_verbose_mode(self, runner, sample_schema_file):
"""generate-stub should provide verbose output when requested."""
result = runner.invoke(cli, [
'--verbose', 'generate-stub', str(sample_schema_file)
])
assert result.exit_code == 0
# In verbose mode, should show some processing information on stderr
# while main output goes to stdout
def test_generate_stub_with_custom_title(self, runner, sample_schema_file):
"""generate-stub should support custom document titles."""
result = runner.invoke(cli, [
'generate-stub', str(sample_schema_file),
'--title', 'My Custom Document'
])
assert result.exit_code == 0
assert 'My Custom Document' in result.output
def test_generate_stub_help_message(self, runner):
"""generate-stub should provide helpful usage information."""
result = runner.invoke(cli, ['generate-stub', '--help'])
assert result.exit_code == 0
assert 'schema' in result.output.lower()
assert 'generate' in result.output.lower()
assert 'stub' in result.output.lower() or 'template' in result.output.lower()
def test_integration_with_schema_generation(self, runner):
"""Should integrate with existing schema generation workflow."""
# Use the sample blog file we created
sample_file = Path("sample_blog.md")
if sample_file.exists():
with TemporaryDirectory() as temp_dir:
schema_file = Path(temp_dir) / "generated_schema.json"
stub_file = Path(temp_dir) / "generated_stub.md"
# First generate a schema
result1 = runner.invoke(cli, [
'schema-generate', str(sample_file),
'--output', str(schema_file)
])
assert result1.exit_code == 0
assert schema_file.exists()
# Then generate a stub from that schema
result2 = runner.invoke(cli, [
'generate-stub', str(schema_file),
'--output', str(stub_file)
])
assert result2.exit_code == 0
assert stub_file.exists()
# Stub should have meaningful content
stub_content = stub_file.read_text()
assert '# ' in stub_content
assert len(stub_content.strip()) > 10