"""Integration tests for CLI commands.""" import json import os import tempfile from pathlib import Path import pytest from click.testing import CliRunner from envschema.cli import cli @pytest.fixture def temp_schema_file(): """Create a temporary schema file.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f: json.dump({ "version": "1.0", "envVars": [ {"name": "DATABASE_URL", "type": "str", "required": True}, {"name": "DEBUG_MODE", "type": "bool", "required": False, "default": "false"}, {"name": "PORT", "type": "int", "required": False, "default": "8080"}, ] }, f) temp_path = f.name yield temp_path os.unlink(temp_path) @pytest.fixture def temp_env_file(): """Create a temporary .env file.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".env", delete=False) as f: f.write("DATABASE_URL=postgres://localhost/mydb\n") f.write("DEBUG_MODE=true\n") temp_path = f.name yield temp_path os.unlink(temp_path) class TestValidateCommand: """Tests for the validate command.""" def test_validate_missing_schema(self): runner = CliRunner() result = runner.invoke(cli, ["validate", "/nonexistent/schema.json"]) assert result.exit_code == 2 assert "Error" in result.output def test_validate_valid_env(self, temp_schema_file, temp_env_file): runner = CliRunner() result = runner.invoke(cli, ["validate", temp_schema_file, "--file", temp_env_file, "--no-env"]) assert result.exit_code == 0 def test_validate_missing_required(self, temp_schema_file): runner = CliRunner() result = runner.invoke(cli, ["validate", temp_schema_file, "--no-env"]) assert result.exit_code == 1 assert "DATABASE_URL" in result.output def test_validate_with_json_output(self, temp_schema_file, temp_env_file): runner = CliRunner() result = runner.invoke(cli, ["validate", temp_schema_file, "--file", temp_env_file, "--no-env", "--format", "json"]) assert result.exit_code == 0 data = json.loads(result.output) assert data["is_valid"] is True def test_validate_ci_mode(self, temp_schema_file, temp_env_file): runner = CliRunner() result = runner.invoke(cli, ["validate", temp_schema_file, "--file", temp_env_file, "--no-env", "--ci"]) assert result.exit_code == 0 assert "✓" not in result.output class TestGenerateCommand: """Tests for the generate command.""" def test_generate_basic(self, temp_schema_file): runner = CliRunner() with runner.isolated_filesystem(): result = runner.invoke(cli, ["generate", temp_schema_file]) assert result.exit_code == 0 assert ".env.example" in result.output def test_generate_to_custom_path(self, temp_schema_file, tmp_path): runner = CliRunner() output_path = tmp_path / "custom.env.example" result = runner.invoke(cli, ["generate", temp_schema_file, "--output", str(output_path)]) assert result.exit_code == 0 assert output_path.read_text() def test_generate_no_comments(self, temp_schema_file, tmp_path): runner = CliRunner() output_path = tmp_path / "no_comments.env" result = runner.invoke(cli, ["generate", temp_schema_file, "--output", str(output_path), "--no-comments"]) assert result.exit_code == 0 content = output_path.read_text() assert "description" not in content.lower() or "#" not in content class TestCheckCommand: """Tests for the check command.""" def test_check_valid_schema(self, temp_schema_file): runner = CliRunner() result = runner.invoke(cli, ["check", temp_schema_file]) assert result.exit_code == 0 assert "valid" in result.output.lower() def test_check_invalid_schema(self): runner = CliRunner() with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f: f.write('{"version": "1.0", "envVars": [{"name": "VAR", "type": "invalid_type"}]}') temp_path = f.name try: result = runner.invoke(cli, ["check", temp_path]) assert result.exit_code == 2 finally: os.unlink(temp_path)