Re-upload: CI infrastructure issue resolved, all tests verified passing

This commit is contained in:
Developer
2026-03-22 16:48:09 +00:00
parent 71bae33ea9
commit 24b94c12bc
165 changed files with 23945 additions and 436 deletions

View File

View File

@@ -0,0 +1,73 @@
import pytest
@pytest.fixture
def sample_har_data():
return {
"log": {
"version": "1.2",
"creator": {"name": "Test", "version": "1.0"},
"entries": [
{
"startedDateTime": "2024-01-01T00:00:00.000Z",
"time": 100,
"request": {
"method": "GET",
"url": "https://api.example.com/users/123",
"headers": [
{"name": "Content-Type", "value": "application/json"},
{"name": "Authorization", "value": "Bearer test_token"},
],
"queryString": [{"name": "include", "value": "profile"}],
"postData": None,
},
"response": {
"status": 200,
"statusText": "OK",
"headers": [
{"name": "Content-Type", "value": "application/json"},
],
"content": {
"mimeType": "application/json",
"text": '{"id": 123, "name": "John Doe", "email": "john@example.com"}',
},
},
},
{
"startedDateTime": "2024-01-01T00:00:01.000Z",
"time": 200,
"request": {
"method": "POST",
"url": "https://api.example.com/users",
"headers": [
{"name": "Content-Type", "value": "application/json"},
],
"queryString": [],
"postData": {
"mimeType": "application/json",
"text": '{"name": "Jane Doe", "email": "jane@example.com"}',
},
},
"response": {
"status": 201,
"statusText": "Created",
"headers": [
{"name": "Content-Type", "value": "application/json"},
],
"content": {
"mimeType": "application/json",
"text": '{"id": 456, "name": "Jane Doe", "email": "jane@example.com", "created_at": "2024-01-01T00:00:01Z"}',
},
},
},
],
}
}
@pytest.fixture
def sample_har_file(tmp_path, sample_har_data):
import json
har_file = tmp_path / "test.har"
har_file.write_text(json.dumps(sample_har_data))
return str(har_file)

View File

@@ -0,0 +1,120 @@
"""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)

View File

@@ -0,0 +1,183 @@
"""End-to-end integration tests for the full validation flow."""
import json
import os
import tempfile
import pytest
from click.testing import CliRunner
from envschema.cli import cli
from envschema.core import validate_environment
from envschema.generator import generate_env_example
class TestFullValidationFlow:
"""Integration tests for complete validation workflows."""
def test_json_schema_with_valid_env(self):
"""Test validating a valid .env against a JSON schema."""
with tempfile.TemporaryDirectory() as tmpdir:
schema_path = os.path.join(tmpdir, "schema.json")
env_path = os.path.join(tmpdir, ".env")
schema_data = {
"version": "1.0",
"envVars": [
{"name": "DATABASE_URL", "type": "str", "required": True},
{"name": "DEBUG", "type": "bool", "required": False, "default": "false"},
{"name": "PORT", "type": "int", "required": False, "default": "8080"},
{"name": "ALLOWED_HOSTS", "type": "list", "required": False},
]
}
with open(schema_path, "w") as f:
json.dump(schema_data, f)
with open(env_path, "w") as f:
f.write("DATABASE_URL=postgres://localhost/mydb\n")
f.write("DEBUG=true\n")
f.write("PORT=3000\n")
f.write("ALLOWED_HOSTS=localhost,127.0.0.1\n")
runner = CliRunner()
result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env"])
assert result.exit_code == 0
def test_json_schema_with_invalid_types(self):
"""Test that type mismatches are caught."""
with tempfile.TemporaryDirectory() as tmpdir:
schema_path = os.path.join(tmpdir, "schema.json")
env_path = os.path.join(tmpdir, ".env")
schema_data = {
"version": "1.0",
"envVars": [
{"name": "PORT", "type": "int", "required": True},
]
}
with open(schema_path, "w") as f:
json.dump(schema_data, f)
with open(env_path, "w") as f:
f.write("PORT=not_a_number\n")
runner = CliRunner()
result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env"])
assert result.exit_code == 1
assert "PORT" in result.output
def test_missing_required_variables(self):
"""Test that missing required variables are reported."""
with tempfile.TemporaryDirectory() as tmpdir:
schema_path = os.path.join(tmpdir, "schema.json")
env_path = os.path.join(tmpdir, ".env")
schema_data = {
"version": "1.0",
"envVars": [
{"name": "REQUIRED_VAR1", "type": "str", "required": True},
{"name": "REQUIRED_VAR2", "type": "str", "required": True},
{"name": "OPTIONAL_VAR", "type": "str", "required": False},
]
}
with open(schema_path, "w") as f:
json.dump(schema_data, f)
with open(env_path, "w") as f:
f.write("REQUIRED_VAR1=value1\n")
runner = CliRunner()
result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env"])
assert result.exit_code == 1
assert "REQUIRED_VAR2" in result.output
def test_generate_and_validate_flow(self):
"""Test generating .env.example and then validating it."""
with tempfile.TemporaryDirectory() as tmpdir:
schema_path = os.path.join(tmpdir, "schema.json")
example_path = os.path.join(tmpdir, ".env.example")
schema_data = {
"version": "1.0",
"envVars": [
{"name": "DATABASE_URL", "type": "str", "required": True, "description": "Database connection string"},
{"name": "DEBUG", "type": "bool", "required": False, "default": "false", "description": "Enable debug mode"},
{"name": "PORT", "type": "int", "required": False, "default": "8080", "description": "Server port"},
]
}
with open(schema_path, "w") as f:
json.dump(schema_data, f)
runner = CliRunner()
result = runner.invoke(cli, ["generate", schema_path, "--output", example_path])
assert result.exit_code == 0
with open(example_path, "r") as f:
content = f.read()
assert "DATABASE_URL=" in content
assert "DEBUG=false" in content
assert "PORT=8080" in content
assert "Database connection string" in content
class TestCIMode:
"""Tests for CI mode functionality."""
def test_ci_mode_clean_output(self):
"""Test that CI mode produces cleaner output."""
with tempfile.TemporaryDirectory() as tmpdir:
schema_path = os.path.join(tmpdir, "schema.json")
env_path = os.path.join(tmpdir, ".env")
schema_data = {
"version": "1.0",
"envVars": [
{"name": "DATABASE_URL", "type": "str", "required": True},
]
}
with open(schema_path, "w") as f:
json.dump(schema_data, f)
with open(env_path, "w") as f:
f.write("DATABASE_URL=postgres://localhost/mydb\n")
runner = CliRunner()
result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env", "--ci"])
assert result.exit_code == 0
assert "" not in result.output
assert "" not in result.output
def test_ci_mode_json_output(self):
"""Test CI mode with JSON output."""
with tempfile.TemporaryDirectory() as tmpdir:
schema_path = os.path.join(tmpdir, "schema.json")
env_path = os.path.join(tmpdir, ".env")
schema_data = {
"version": "1.0",
"envVars": [
{"name": "DATABASE_URL", "type": "str", "required": True},
]
}
with open(schema_path, "w") as f:
json.dump(schema_data, f)
with open(env_path, "w") as f:
f.write("DATABASE_URL=postgres://localhost/mydb\n")
runner = CliRunner()
result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env", "--ci", "--format", "json"])
assert result.exit_code == 0
data = json.loads(result.output)
assert data["is_valid"] is True

View File

View File

@@ -0,0 +1,188 @@
"""Unit tests for the validation engine."""
import pytest
from envschema.schema import Schema, EnvVar, EnvVarType
from envschema.core import ValidationEngine, ValidationResult
class TestValidationResult:
"""Tests for ValidationResult."""
def test_valid_result(self):
result = ValidationResult(is_valid=True)
assert result.is_valid is True
assert result.missing_required == []
assert result.type_errors == []
assert result.pattern_errors == []
assert result.warnings == []
def test_result_to_dict(self):
result = ValidationResult(is_valid=True)
d = result.to_dict()
assert d["is_valid"] is True
assert d["missing_required"] == []
class TestValidationEngine:
"""Tests for ValidationEngine."""
def test_validate_empty_env(self):
schema = Schema(envvars=[])
engine = ValidationEngine(schema)
result = engine.validate({})
assert result.is_valid is True
def test_validate_missing_required(self):
schema = Schema(
envvars=[
EnvVar(name="REQUIRED_VAR", required=True),
]
)
engine = ValidationEngine(schema)
result = engine.validate({})
assert result.is_valid is False
assert "REQUIRED_VAR" in result.missing_required
def test_validate_present_required(self):
schema = Schema(
envvars=[
EnvVar(name="REQUIRED_VAR", required=True),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"REQUIRED_VAR": "value"})
assert result.is_valid is True
def test_validate_optional_missing(self):
schema = Schema(
envvars=[
EnvVar(name="OPTIONAL_VAR", required=False),
]
)
engine = ValidationEngine(schema)
result = engine.validate({})
assert result.is_valid is True
def test_validate_with_default(self):
schema = Schema(
envvars=[
EnvVar(name="VAR_WITH_DEFAULT", required=False, default="default_value"),
]
)
engine = ValidationEngine(schema)
result = engine.validate({})
assert result.is_valid is True
def test_validate_string_type(self):
schema = Schema(
envvars=[
EnvVar(name="STRING_VAR", type=EnvVarType.STRING),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"STRING_VAR": "any value"})
assert result.is_valid is True
def test_validate_integer_type_valid(self):
schema = Schema(
envvars=[
EnvVar(name="INT_VAR", type=EnvVarType.INTEGER),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"INT_VAR": "42"})
assert result.is_valid is True
def test_validate_integer_type_invalid(self):
schema = Schema(
envvars=[
EnvVar(name="INT_VAR", type=EnvVarType.INTEGER),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"INT_VAR": "not_a_number"})
assert result.is_valid is False
assert len(result.type_errors) == 1
assert result.type_errors[0].var_name == "INT_VAR"
def test_validate_boolean_type_valid(self):
schema = Schema(
envvars=[
EnvVar(name="BOOL_VAR", type=EnvVarType.BOOLEAN),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"BOOL_VAR": "true"})
assert result.is_valid is True
def test_validate_boolean_type_invalid(self):
schema = Schema(
envvars=[
EnvVar(name="BOOL_VAR", type=EnvVarType.BOOLEAN),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"BOOL_VAR": "maybe"})
assert result.is_valid is False
def test_validate_list_type_valid(self):
schema = Schema(
envvars=[
EnvVar(name="LIST_VAR", type=EnvVarType.LIST),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"LIST_VAR": "a,b,c"})
assert result.is_valid is True
def test_validate_list_type_invalid(self):
schema = Schema(
envvars=[
EnvVar(name="LIST_VAR", type=EnvVarType.LIST),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"LIST_VAR": "single_value"})
assert result.is_valid is False
def test_validate_pattern_match(self):
schema = Schema(
envvars=[
EnvVar(name="PATTERN_VAR", type=EnvVarType.STRING, pattern=r"^[A-Z]+$"),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"PATTERN_VAR": "VALID"})
assert result.is_valid is True
def test_validate_pattern_no_match(self):
schema = Schema(
envvars=[
EnvVar(name="PATTERN_VAR", type=EnvVarType.STRING, pattern=r"^[A-Z]+$"),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"PATTERN_VAR": "invalid"})
assert result.is_valid is False
def test_validate_extra_var_warning(self):
schema = Schema(
envvars=[
EnvVar(name="KNOWN_VAR", type=EnvVarType.STRING),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"KNOWN_VAR": "value", "UNKNOWN_VAR": "other"})
assert result.is_valid is True
assert "Unknown environment variable: UNKNOWN_VAR" in result.warnings
def test_validate_case_insensitive(self):
schema = Schema(
envvars=[
EnvVar(name="TEST_VAR", required=True),
]
)
engine = ValidationEngine(schema)
result = engine.validate({"test_var": "value"})
assert result.is_valid is True

View File

@@ -0,0 +1,105 @@
"""Unit tests for the .env.example generator."""
import pytest
from envschema.schema import Schema, EnvVar, EnvVarType
from envschema.generator import generate_env_example, generate_env_example_to_file
class TestGenerateEnvExample:
"""Tests for generate_env_example function."""
def test_empty_schema(self):
schema = Schema()
result = generate_env_example(schema)
assert "# Environment Variables Schema" in result
def test_basic_variable(self):
schema = Schema(
envvars=[
EnvVar(name="TEST_VAR", type=EnvVarType.STRING),
]
)
result = generate_env_example(schema)
assert "TEST_VAR=" in result
def test_required_variable(self):
schema = Schema(
envvars=[
EnvVar(name="REQUIRED_VAR", required=True),
]
)
result = generate_env_example(schema)
assert "# REQUIRED" in result
assert "REQUIRED_VAR=" in result
def test_variable_with_default(self):
schema = Schema(
envvars=[
EnvVar(name="VAR_WITH_DEFAULT", default="default_value"),
]
)
result = generate_env_example(schema)
assert "VAR_WITH_DEFAULT=default_value" in result
def test_variable_with_description(self):
schema = Schema(
envvars=[
EnvVar(
name="DESCRIBED_VAR",
description="This is a description",
),
]
)
result = generate_env_example(schema)
assert "# This is a description" in result
def test_variable_with_type(self):
schema = Schema(
envvars=[
EnvVar(name="INT_VAR", type=EnvVarType.INTEGER),
]
)
result = generate_env_example(schema)
assert "INT_VAR=" in result
def test_no_descriptions(self):
schema = Schema(
envvars=[
EnvVar(
name="VAR",
description="Some description",
),
]
)
result = generate_env_example(schema, include_descriptions=False)
assert "Some description" not in result
def test_multiple_variables(self):
schema = Schema(
envvars=[
EnvVar(name="VAR1", required=True, description="First var"),
EnvVar(name="VAR2", default="value"),
EnvVar(name="VAR3", type=EnvVarType.INTEGER),
]
)
result = generate_env_example(schema)
assert "VAR1=" in result
assert "VAR2=value" in result
assert "VAR3=" in result
class TestGenerateEnvExampleToFile:
"""Tests for generate_env_example_to_file function."""
def test_write_to_file(self, tmp_path):
schema = Schema(
envvars=[
EnvVar(name="TEST_VAR"),
]
)
output_path = tmp_path / ".env.example"
generate_env_example_to_file(schema, str(output_path))
content = output_path.read_text()
assert "TEST_VAR=" in content

View File

@@ -0,0 +1,174 @@
"""Unit tests for schema parsing."""
import json
import tempfile
from pathlib import Path
import pytest
from envschema.schema import (
Schema,
EnvVar,
EnvVarType,
load_schema_from_file,
load_json_schema,
load_yaml_schema,
)
class TestEnvVar:
"""Tests for EnvVar model."""
def test_env_var_creation(self):
var = EnvVar(name="TEST_VAR", type=EnvVarType.STRING)
assert var.name == "TEST_VAR"
assert var.type == EnvVarType.STRING
assert var.required is False
assert var.default is None
def test_env_var_with_all_fields(self):
var = EnvVar(
name="DATABASE_URL",
type=EnvVarType.STRING,
required=True,
default="postgres://localhost",
description="Database connection string",
pattern=r"^postgres://.*",
)
assert var.required is True
assert var.default == "postgres://localhost"
assert var.description == "Database connection string"
assert var.pattern == r"^postgres://.*"
def test_env_var_name_uppercase(self):
var = EnvVar(name="test_var")
assert var.name == "TEST_VAR"
def test_env_var_invalid_name(self):
with pytest.raises(ValueError):
EnvVar(name="invalid name with spaces")
class TestSchema:
"""Tests for Schema model."""
def test_schema_creation(self):
schema = Schema()
assert schema.version == "1.0"
assert schema.envvars == []
def test_schema_with_vars(self):
schema = Schema(
envvars=[
EnvVar(name="VAR1", type=EnvVarType.STRING),
EnvVar(name="VAR2", type=EnvVarType.INTEGER, required=True),
]
)
assert len(schema.envvars) == 2
def test_get_var(self):
schema = Schema(
envvars=[
EnvVar(name="DATABASE_URL", type=EnvVarType.STRING),
]
)
var = schema.get_var("DATABASE_URL")
assert var is not None
assert var.name == "DATABASE_URL"
def test_get_var_case_insensitive(self):
schema = Schema(
envvars=[
EnvVar(name="DATABASE_URL", type=EnvVarType.STRING),
]
)
var = schema.get_var("database_url")
assert var is not None
def test_get_var_not_found(self):
schema = Schema()
var = schema.get_var("NONEXISTENT")
assert var is None
def test_get_required_vars(self):
schema = Schema(
envvars=[
EnvVar(name="VAR1", required=True),
EnvVar(name="VAR2", required=False),
EnvVar(name="VAR3", required=True),
]
)
required = schema.get_required_vars()
assert len(required) == 2
assert {v.name for v in required} == {"VAR1", "VAR3"}
class TestLoadJsonSchema:
"""Tests for JSON schema loading."""
def test_load_valid_json_schema(self):
json_content = json.dumps({
"version": "1.0",
"envVars": [
{"name": "TEST_VAR", "type": "str"}
]
})
schema = load_json_schema(json_content)
assert schema.version == "1.0"
assert len(schema.envvars) == 1
def test_load_invalid_json(self):
with pytest.raises(ValueError, match="Invalid JSON"):
load_json_schema("not valid json")
def test_load_invalid_schema_structure(self):
with pytest.raises((ValueError, Exception), match="Invalid schema"):
load_json_schema('{"version": "1.0", "envVars": [{"name": "VAR", "type": "invalid_type"}]}')
class TestLoadYamlSchema:
"""Tests for YAML schema loading."""
def test_load_valid_yaml_schema(self):
yaml_content = """
version: "1.0"
envVars:
- name: TEST_VAR
type: str
"""
schema = load_yaml_schema(yaml_content)
assert schema.version == "1.0"
assert len(schema.envvars) == 1
def test_load_invalid_yaml(self):
with pytest.raises(ValueError, match="Invalid YAML"):
load_yaml_schema("invalid: yaml: content:")
class TestLoadSchemaFromFile:
"""Tests for file-based schema loading."""
def test_load_json_file(self, tmp_path):
schema_file = tmp_path / "schema.json"
schema_file.write_text(json.dumps({
"version": "1.0",
"envVars": [{"name": "TEST", "type": "str"}]
}))
schema = load_schema_from_file(str(schema_file))
assert schema.version == "1.0"
def test_load_yaml_file(self, tmp_path):
schema_file = tmp_path / "schema.yaml"
schema_file.write_text('version: "1.0"\nenvVars: []')
schema = load_schema_from_file(str(schema_file))
assert schema.version == "1.0"
def test_file_not_found(self):
with pytest.raises(FileNotFoundError):
load_schema_from_file("/nonexistent/path/schema.json")
def test_unsupported_format(self, tmp_path):
schema_file = tmp_path / "schema.txt"
schema_file.write_text("some content")
with pytest.raises(ValueError, match="Unsupported schema format"):
load_schema_from_file(str(schema_file))

View File

@@ -0,0 +1,176 @@
"""Unit tests for type validators."""
import pytest
from envschema.schema import EnvVarType
from envschema.validators import (
StringValidator,
IntegerValidator,
BooleanValidator,
ListValidator,
PatternValidator,
validate_value,
)
class TestStringValidator:
"""Tests for StringValidator."""
def test_valid_string(self):
is_valid, error = StringValidator.validate("any value")
assert is_valid is True
assert error is None
def test_empty_string(self):
is_valid, error = StringValidator.validate("")
assert is_valid is True
assert error is None
def test_none_value(self):
is_valid, error = StringValidator.validate(None)
assert is_valid is True
assert error is None
class TestIntegerValidator:
"""Tests for IntegerValidator."""
def test_valid_integer(self):
is_valid, error = IntegerValidator.validate("42")
assert is_valid is True
assert error is None
def test_valid_negative_integer(self):
is_valid, error = IntegerValidator.validate("-10")
assert is_valid is True
assert error is None
def test_valid_zero(self):
is_valid, error = IntegerValidator.validate("0")
assert is_valid is True
assert error is None
def test_invalid_float(self):
is_valid, error = IntegerValidator.validate("3.14")
assert is_valid is False
assert error is not None
def test_invalid_string(self):
is_valid, error = IntegerValidator.validate("abc")
assert is_valid is False
assert error is not None
def test_none_value(self):
is_valid, error = IntegerValidator.validate(None)
assert is_valid is True
assert error is None
class TestBooleanValidator:
"""Tests for BooleanValidator."""
@pytest.mark.parametrize("value", ["true", "True", "TRUE", "1", "yes", "Yes", "YES", "on", "ON"])
def test_valid_true_values(self, value):
is_valid, error = BooleanValidator.validate(value)
assert is_valid is True
assert error is None
@pytest.mark.parametrize("value", ["false", "False", "FALSE", "0", "no", "No", "NO", "off", "OFF"])
def test_valid_false_values(self, value):
is_valid, error = BooleanValidator.validate(value)
assert is_valid is True
assert error is None
@pytest.mark.parametrize("value", ["maybe", "2", "truee", "yess"])
def test_invalid_boolean_values(self, value):
is_valid, error = BooleanValidator.validate(value)
assert is_valid is False
assert error is not None
def test_none_value(self):
is_valid, error = BooleanValidator.validate(None)
assert is_valid is True
assert error is None
class TestListValidator:
"""Tests for ListValidator."""
def test_valid_list(self):
is_valid, error = ListValidator.validate("item1,item2,item3")
assert is_valid is True
assert error is None
def test_single_item_list(self):
is_valid, error = ListValidator.validate("single")
assert is_valid is False
assert error is not None
def test_empty_string(self):
is_valid, error = ListValidator.validate("")
assert is_valid is False
def test_none_value(self):
is_valid, error = ListValidator.validate(None)
assert is_valid is True
assert error is None
def test_parse_list(self):
result = ListValidator.parse("item1, item2 , item3")
assert result == ["item1", "item2", "item3"]
def test_parse_list_with_empty_items(self):
result = ListValidator.parse("item1,,item2")
assert result == ["item1", "item2"]
class TestPatternValidator:
"""Tests for PatternValidator."""
def test_valid_pattern_match(self):
is_valid, error = PatternValidator.validate("ABC123", r"^[A-Z]+[0-9]+$")
assert is_valid is True
assert error is None
def test_invalid_pattern_match(self):
is_valid, error = PatternValidator.validate("abc123", r"^[A-Z]+[0-9]+$")
assert is_valid is False
assert error is not None
def test_invalid_regex_pattern(self):
is_valid, error = PatternValidator.validate("test", r"[invalid")
assert is_valid is False
assert error is not None
def test_none_value(self):
is_valid, error = PatternValidator.validate(None, r"^[A-Z]+$")
assert is_valid is True
assert error is None
class TestValidateValue:
"""Tests for the main validate_value function."""
def test_validate_string(self):
is_valid, error = validate_value("test", EnvVarType.STRING)
assert is_valid is True
def test_validate_integer(self):
is_valid, error = validate_value("42", EnvVarType.INTEGER)
assert is_valid is True
def test_validate_boolean(self):
is_valid, error = validate_value("true", EnvVarType.BOOLEAN)
assert is_valid is True
def test_validate_list(self):
is_valid, error = validate_value("a,b,c", EnvVarType.LIST)
assert is_valid is True
def test_validate_with_pattern(self):
is_valid, error = validate_value("ABC123", EnvVarType.STRING, r"^[A-Z]+[0-9]+$")
assert is_valid is True
def test_validate_with_invalid_pattern(self):
is_valid, error = validate_value("abc123", EnvVarType.STRING, r"^[A-Z]+[0-9]+$")
assert is_valid is False