diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..37ff412 --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,251 @@ +"""Tests for CLI commands.""" + +import pytest +import tempfile +import os +from click.testing import CliRunner +from pathlib import Path + + +class TestCLIConvert: + """Tests for convert command.""" + + def test_convert_json_to_yaml(self): + from src.cli import cli + + runner = CliRunner() + + with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: + f.write('{"name": "test", "value": 123}') + temp_input = f.name + + with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f: + temp_output = f.name + + try: + result = runner.invoke(cli, ['convert', temp_input, '--to', 'yaml', '-o', temp_output]) + assert result.exit_code == 0 + assert Path(temp_output).read_text().strip() != "" + finally: + os.unlink(temp_input) + if os.path.exists(temp_output): + os.unlink(temp_output) + + def test_convert_yaml_to_json(self): + from src.cli import cli + + runner = CliRunner() + + with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f: + f.write('name: test\nvalue: 123') + temp_input = f.name + + with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: + temp_output = f.name + + try: + result = runner.invoke(cli, ['convert', temp_input, '--to', 'json', '-o', temp_output]) + assert result.exit_code == 0 + assert Path(temp_output).read_text().strip() != "" + finally: + os.unlink(temp_input) + if os.path.exists(temp_output): + os.unlink(temp_output) + + def test_convert_with_indent(self): + from src.cli import cli + + runner = CliRunner() + + with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: + f.write('{"name": "test"}') + temp_input = f.name + + with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f: + temp_output = f.name + + try: + result = runner.invoke(cli, ['convert', temp_input, '--to', 'yaml', '-o', temp_output, '--indent', '4']) + assert result.exit_code == 0 + finally: + os.unlink(temp_input) + if os.path.exists(temp_output): + os.unlink(temp_output) + + def test_convert_invalid_format(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['convert', '--to', 'invalid']) + assert result.exit_code != 0 + + def test_convert_stdin_to_stdout(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['convert', '-f', 'json', '--to', 'yaml'], input='{"test": 123}') + assert result.exit_code == 0 + + +class TestCLIValidate: + """Tests for validate command.""" + + def test_validate_valid_json(self): + from src.cli import cli + + runner = CliRunner() + + with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: + f.write('{"name": "test"}') + temp_file = f.name + + try: + result = runner.invoke(cli, ['validate', temp_file]) + assert result.exit_code == 0 + finally: + os.unlink(temp_file) + + def test_validate_invalid_json(self): + from src.cli import cli + + runner = CliRunner() + + with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: + f.write('{invalid json}') + temp_file = f.name + + try: + result = runner.invoke(cli, ['validate', temp_file]) + assert result.exit_code != 0 + finally: + os.unlink(temp_file) + + def test_validate_yaml_file(self): + from src.cli import cli + + runner = CliRunner() + + with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f: + f.write('name: test') + temp_file = f.name + + try: + result = runner.invoke(cli, ['validate', temp_file]) + assert result.exit_code == 0 + finally: + os.unlink(temp_file) + + def test_validate_with_format_option(self): + from src.cli import cli + + runner = CliRunner() + + with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f: + f.write('{"name": "test"}') + temp_file = f.name + + try: + result = runner.invoke(cli, ['validate', temp_file, '--format', 'json']) + assert result.exit_code == 0 + finally: + os.unlink(temp_file) + + def test_validate_stdin(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['validate', '--stdin', '--format', 'json'], input='{"test": 1}') + assert result.exit_code == 0 + + +class TestCLIInfo: + """Tests for info command.""" + + def test_info_command(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['info']) + assert result.exit_code == 0 + assert "Supported Formats" in result.output + + +class TestCLIHelp: + """Tests for CLI help.""" + + def test_main_help(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['--help']) + assert result.exit_code == 0 + assert "Data Format Converter" in result.output + + def test_convert_help(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['convert', '--help']) + assert result.exit_code == 0 + assert "Convert data from one format to another" in result.output + + def test_validate_help(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['validate', '--help']) + assert result.exit_code == 0 + assert "Validate syntax" in result.output + + def test_tui_help(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['tui', '--help']) + assert result.exit_code == 0 + assert "interactive TUI mode" in result.output + + def test_watch_help(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['watch', '--help']) + assert result.exit_code == 0 + assert "Watch files for changes" in result.output + + +class TestCLIEdgeCases: + """Tests for edge cases and error handling.""" + + def test_convert_missing_file(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['convert', 'nonexistent.json', '--to', 'yaml']) + assert result.exit_code != 0 + + def test_convert_invalid_source_format(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['convert', '--from', 'invalid', '--to', 'yaml']) + assert result.exit_code != 0 + + def test_validate_missing_file(self): + from src.cli import cli + + runner = CliRunner() + + result = runner.invoke(cli, ['validate', 'nonexistent.json']) + assert result.exit_code != 0