"""Integration tests for ConfigForge CLI.""" import json import os import tempfile import pytest from click.testing import CliRunner from configforge.cli import main class TestCLIValidateCommand: """Integration tests for the validate command.""" def test_validate_command_help(self): """Test validate command help output.""" runner = CliRunner() result = runner.invoke(main, ["validate", "--help"]) assert result.exit_code == 0 assert "CONFIG_FILE" in result.output assert "SCHEMA_FILE" in result.output def test_validate_missing_config_file(self): """Test validate with missing config file.""" runner = CliRunner() result = runner.invoke(main, ["validate", "nonexistent.json", "schema.json"]) assert result.exit_code != 0 assert "not found" in result.output.lower() or result.exit_code != 0 def test_validate_missing_schema_file(self): """Test validate with missing schema file.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: json.dump({"key": "value"}, f) config_file = f.name try: runner = CliRunner() result = runner.invoke(main, ["validate", config_file, "nonexistent.json"]) assert result.exit_code != 0 finally: os.unlink(config_file) class TestCLIConvertCommand: """Integration tests for the convert command.""" def test_convert_command_help(self): """Test convert command help output.""" runner = CliRunner() result = runner.invoke(main, ["convert", "--help"]) assert result.exit_code == 0 assert "INPUT_FILE" in result.output def test_convert_json_to_yaml(self, sample_json_config): """Test converting JSON to YAML.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: json.dump(sample_json_config, f) input_file = f.name try: runner = CliRunner() result = runner.invoke(main, ["convert", input_file, "--format", "yaml"]) assert result.exit_code == 0 assert "database:" in result.output finally: os.unlink(input_file) def test_convert_json_to_toml(self, sample_json_config): """Test converting JSON to TOML.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: json.dump(sample_json_config, f) input_file = f.name try: runner = CliRunner() result = runner.invoke(main, ["convert", input_file, "--format", "toml"]) assert result.exit_code == 0 assert "[database]" in result.output finally: os.unlink(input_file) def test_convert_json_to_env(self, sample_json_config): """Test converting JSON to ENV.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: json.dump(sample_json_config, f) input_file = f.name try: runner = CliRunner() result = runner.invoke(main, ["convert", input_file, "--format", "env"]) assert result.exit_code == 0 assert "host" in result.output finally: os.unlink(input_file) def test_convert_with_output_file(self, sample_json_config): """Test converting with output file.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: json.dump(sample_json_config, f) input_file = f.name with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f: output_file = f.name try: runner = CliRunner() result = runner.invoke(main, ["convert", input_file, "-o", output_file]) assert result.exit_code == 0 assert os.path.exists(output_file) with open(output_file) as f: content = f.read() assert "database:" in content finally: os.unlink(input_file) if os.path.exists(output_file): os.unlink(output_file) class TestCLIGenerateCommand: """Integration tests for the generate command.""" def test_generate_command_help(self): """Test generate command help output.""" runner = CliRunner() result = runner.invoke(main, ["generate", "--help"]) assert result.exit_code == 0 assert "INPUT_FILE" in result.output def test_generate_from_schema(self, sample_json_schema): """Test generating TypeScript from schema.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: json.dump(sample_json_schema, f) input_file = f.name try: runner = CliRunner() result = runner.invoke(main, ["generate", input_file, "--interface-name", "Config"]) assert result.exit_code == 0 assert "interface Config" in result.output finally: os.unlink(input_file) def test_generate_from_data(self, sample_json_config): """Test generating TypeScript from config data.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: json.dump(sample_json_config, f) input_file = f.name try: runner = CliRunner() result = runner.invoke(main, ["generate", input_file, "--from-data"]) assert result.exit_code == 0 assert "interface" in result.output finally: os.unlink(input_file) class TestCLISchemaCommand: """Integration tests for the schema command.""" def test_schema_command_help(self): """Test schema command help output.""" runner = CliRunner() result = runner.invoke(main, ["schema", "--help"]) assert result.exit_code == 0 assert "--output" in result.output def test_schema_from_config(self, sample_json_config): """Test generating schema from config file.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: json.dump(sample_json_config, f) config_file = f.name with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: output_file = f.name try: runner = CliRunner() result = runner.invoke(main, ["schema", "--from-config", config_file, "-o", output_file]) assert result.exit_code == 0 assert os.path.exists(output_file) with open(output_file) as f: schema = json.load(f) assert "properties" in schema finally: os.unlink(config_file) if os.path.exists(output_file): os.unlink(output_file) class TestCLIMain: """Integration tests for main CLI entry point.""" def test_main_help(self): """Test main help output.""" runner = CliRunner() result = runner.invoke(main, ["--help"]) assert result.exit_code == 0 assert "validate" in result.output assert "convert" in result.output assert "generate" in result.output assert "schema" in result.output def test_main_version(self): """Test version output.""" runner = CliRunner() result = runner.invoke(main, ["--version"]) assert result.exit_code == 0 assert "ConfigForge" in result.output def test_main_invalid_command(self): """Test invalid command handling.""" runner = CliRunner() result = runner.invoke(main, ["invalid-command"]) assert result.exit_code != 0