Initial upload: ConfDoc v0.1.0 - Config validation and documentation generator
This commit is contained in:
185
tests/test_validator.py
Normal file
185
tests/test_validator.py
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
import pytest
|
||||||
|
from confdoc.validator.validator import SchemaValidator
|
||||||
|
from confdoc.validator.errors import ValidationError, ErrorFormatter, ErrorSeverity
|
||||||
|
|
||||||
|
|
||||||
|
class TestSchemaValidator:
|
||||||
|
def test_valid_config_passes(self):
|
||||||
|
validator = SchemaValidator()
|
||||||
|
config = {"name": "test", "value": 123}
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"value": {"type": "integer"}
|
||||||
|
},
|
||||||
|
"required": ["name"]
|
||||||
|
}
|
||||||
|
is_valid, errors = validator.validate(config, schema)
|
||||||
|
assert is_valid is True
|
||||||
|
assert len(errors) == 0
|
||||||
|
|
||||||
|
def test_invalid_type_fails(self):
|
||||||
|
validator = SchemaValidator()
|
||||||
|
config = {"name": 123}
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"}
|
||||||
|
},
|
||||||
|
"required": ["name"]
|
||||||
|
}
|
||||||
|
is_valid, errors = validator.validate(config, schema)
|
||||||
|
assert is_valid is False
|
||||||
|
assert len(errors) > 0
|
||||||
|
|
||||||
|
def test_missing_required_property(self):
|
||||||
|
validator = SchemaValidator()
|
||||||
|
config = {"value": 123}
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"value": {"type": "integer"}
|
||||||
|
},
|
||||||
|
"required": ["name"]
|
||||||
|
}
|
||||||
|
is_valid, errors = validator.validate(config, schema)
|
||||||
|
assert is_valid is False
|
||||||
|
assert len(errors) > 0
|
||||||
|
|
||||||
|
def test_nested_object_validation(self):
|
||||||
|
validator = SchemaValidator()
|
||||||
|
config = {"app": {"name": "test", "version": "1.0"}}
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"app": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"version": {"type": "string"}
|
||||||
|
},
|
||||||
|
"required": ["name"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["app"]
|
||||||
|
}
|
||||||
|
is_valid, errors = validator.validate(config, schema)
|
||||||
|
assert is_valid is True
|
||||||
|
|
||||||
|
def test_array_validation(self):
|
||||||
|
validator = SchemaValidator()
|
||||||
|
config = {"items": [1, 2, 3]}
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "integer"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is_valid, errors = validator.validate(config, schema)
|
||||||
|
assert is_valid is True
|
||||||
|
|
||||||
|
def test_enum_validation(self):
|
||||||
|
validator = SchemaValidator()
|
||||||
|
config = {"status": "active"}
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["active", "inactive", "pending"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is_valid, errors = validator.validate(config, schema)
|
||||||
|
assert is_valid is True
|
||||||
|
|
||||||
|
def test_enum_invalid_value(self):
|
||||||
|
validator = SchemaValidator()
|
||||||
|
config = {"status": "unknown"}
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["active", "inactive", "pending"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is_valid, errors = validator.validate(config, schema)
|
||||||
|
assert is_valid is False
|
||||||
|
|
||||||
|
|
||||||
|
class TestValidationError:
|
||||||
|
def test_error_creation(self):
|
||||||
|
error = ValidationError(
|
||||||
|
message="Test error",
|
||||||
|
path="app.name",
|
||||||
|
line=10,
|
||||||
|
column=5,
|
||||||
|
severity=ErrorSeverity.ERROR,
|
||||||
|
suggestion="Add the property"
|
||||||
|
)
|
||||||
|
assert error.message == "Test error"
|
||||||
|
assert error.path == "app.name"
|
||||||
|
assert error.line == 10
|
||||||
|
assert error.severity == ErrorSeverity.ERROR
|
||||||
|
|
||||||
|
def test_error_to_dict(self):
|
||||||
|
error = ValidationError(
|
||||||
|
message="Test error",
|
||||||
|
path="app.name",
|
||||||
|
severity=ErrorSeverity.WARNING
|
||||||
|
)
|
||||||
|
result = error.to_dict()
|
||||||
|
assert result["message"] == "Test error"
|
||||||
|
assert result["path"] == "app.name"
|
||||||
|
assert result["severity"] == "warning"
|
||||||
|
|
||||||
|
def test_error_str_format(self):
|
||||||
|
error = ValidationError(
|
||||||
|
message="Missing required property",
|
||||||
|
path="app.name",
|
||||||
|
suggestion="Add the property"
|
||||||
|
)
|
||||||
|
result = str(error)
|
||||||
|
assert "Missing required property" in result
|
||||||
|
assert "app.name" in result
|
||||||
|
assert "Add the property" in result
|
||||||
|
|
||||||
|
|
||||||
|
class TestErrorFormatter:
|
||||||
|
def test_classify_severity_required(self):
|
||||||
|
error_info = {"validator": "required"}
|
||||||
|
severity = ErrorFormatter.classify_severity(error_info)
|
||||||
|
assert severity == ErrorSeverity.CRITICAL
|
||||||
|
|
||||||
|
def test_classify_severity_type(self):
|
||||||
|
error_info = {"validator": "type"}
|
||||||
|
severity = ErrorFormatter.classify_severity(error_info)
|
||||||
|
assert severity == ErrorSeverity.ERROR
|
||||||
|
|
||||||
|
def test_classify_severity_minimum(self):
|
||||||
|
error_info = {"validator": "minimum"}
|
||||||
|
severity = ErrorFormatter.classify_severity(error_info)
|
||||||
|
assert severity == ErrorSeverity.WARNING
|
||||||
|
|
||||||
|
def test_generate_suggestion_required(self):
|
||||||
|
error_info = {"validator": "required", "missing_property": "name"}
|
||||||
|
suggestion = ErrorFormatter.generate_suggestion(error_info)
|
||||||
|
assert "name" in suggestion
|
||||||
|
|
||||||
|
def test_generate_suggestion_type(self):
|
||||||
|
error_info = {"validator": "type", "expected": "string", "found": "integer"}
|
||||||
|
suggestion = ErrorFormatter.generate_suggestion(error_info)
|
||||||
|
assert "string" in suggestion
|
||||||
|
assert "integer" in suggestion
|
||||||
|
|
||||||
|
def test_generate_suggestion_enum(self):
|
||||||
|
error_info = {"validator": "enum", "validator_value": ["a", "b", "c"]}
|
||||||
|
suggestion = ErrorFormatter.generate_suggestion(error_info)
|
||||||
|
assert "a" in suggestion or "b" in suggestion
|
||||||
Reference in New Issue
Block a user