""" 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