121 lines
4.3 KiB
Python
121 lines
4.3 KiB
Python
"""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)
|