Merge pull request #9 from HideyoshiNakazone/better-tests
Implements Better Tests
This commit was merged in pull request #9.
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
from .schema_converter import SchemaConverter
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
SchemaConverter # Exports the schema converter class for external use
|
||||||
|
]
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class StringTypeParser(GenericTypeParser):
|
|||||||
if not isinstance(default_value, str):
|
if not isinstance(default_value, str):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Default value for {name} must be a string, "
|
f"Default value for {name} must be a string, "
|
||||||
f"but got {type(properties['default'])}."
|
f"but got <{type(properties['default']).__name__}>."
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(default_value) > properties.get("maxLength", float("inf")):
|
if len(default_value) > properties.get("maxLength", float("inf")):
|
||||||
|
|||||||
@@ -22,22 +22,22 @@ def numeric_properties_builder(properties):
|
|||||||
f"Default value must be a number, got {type(default_value).__name__}"
|
f"Default value must be a number, got {type(default_value).__name__}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if default_value >= properties.get("maximum", float("inf")):
|
if default_value > properties.get("maximum", float("inf")):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Default value exceeds maximum limit of {properties.get('maximum')}"
|
f"Default value exceeds maximum limit of {properties.get('maximum')}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if default_value <= properties.get("minimum", float("-inf")):
|
if default_value < properties.get("minimum", float("-inf")):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Default value is below minimum limit of {properties.get('minimum')}"
|
f"Default value is below minimum limit of {properties.get('minimum')}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if default_value > properties.get("exclusiveMaximum", float("inf")):
|
if default_value >= properties.get("exclusiveMaximum", float("inf")):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Default value exceeds exclusive maximum limit of {properties.get('exclusiveMaximum')}"
|
f"Default value exceeds exclusive maximum limit of {properties.get('exclusiveMaximum')}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if default_value < properties.get("exclusiveMinimum", float("-inf")):
|
if default_value <= properties.get("exclusiveMinimum", float("-inf")):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Default value is below exclusive minimum limit of {properties.get('exclusiveMinimum')}"
|
f"Default value is below exclusive minimum limit of {properties.get('exclusiveMinimum')}"
|
||||||
)
|
)
|
||||||
|
|||||||
0
tests/parser/__init__.py
Normal file
0
tests/parser/__init__.py
Normal file
115
tests/parser/test_array_type_parser.py
Normal file
115
tests/parser/test_array_type_parser.py
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
from typing import get_args
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from jambo.parser import ArrayTypeParser
|
||||||
|
|
||||||
|
|
||||||
|
class TestArrayTypeParser(TestCase):
|
||||||
|
def test_array_parser_no_options(self):
|
||||||
|
parser = ArrayTypeParser()
|
||||||
|
|
||||||
|
properties = {"items": {"type": "string"}}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
element_type = get_args(type_parsing)[0]
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing.__origin__, list)
|
||||||
|
self.assertEqual(element_type, str)
|
||||||
|
|
||||||
|
def test_array_parser_with_options_unique(self):
|
||||||
|
parser = ArrayTypeParser()
|
||||||
|
|
||||||
|
properties = {"items": {"type": "string"}, "uniqueItems": True}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing.__origin__, set)
|
||||||
|
|
||||||
|
def test_array_parser_with_options_max_min(self):
|
||||||
|
parser = ArrayTypeParser()
|
||||||
|
|
||||||
|
properties = {"items": {"type": "string"}, "maxItems": 10, "minItems": 1}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing.__origin__, list)
|
||||||
|
self.assertEqual(type_validator["max_length"], 10)
|
||||||
|
self.assertEqual(type_validator["min_length"], 1)
|
||||||
|
|
||||||
|
def test_array_parser_with_options_default_list(self):
|
||||||
|
parser = ArrayTypeParser()
|
||||||
|
|
||||||
|
properties = {"items": {"type": "string"}, "default": ["a", "b", "c"]}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing.__origin__, list)
|
||||||
|
self.assertEqual(type_validator["default_factory"](), ["a", "b", "c"])
|
||||||
|
|
||||||
|
def test_array_parse_with_options_default_set(self):
|
||||||
|
parser = ArrayTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"items": {"type": "string"},
|
||||||
|
"uniqueItems": True,
|
||||||
|
"default": ["a", "b", "c"],
|
||||||
|
}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing.__origin__, set)
|
||||||
|
self.assertEqual(type_validator["default_factory"](), {"a", "b", "c"})
|
||||||
|
|
||||||
|
def test_array_parser_with_invalid_default_elem_type(self):
|
||||||
|
parser = ArrayTypeParser()
|
||||||
|
|
||||||
|
properties = {"items": {"type": "string"}, "default": ["a", 1, "c"]}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"All items in the default list must be of type str",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_array_parser_with_invalid_default_type(self):
|
||||||
|
parser = ArrayTypeParser()
|
||||||
|
|
||||||
|
properties = {"items": {"type": "string"}, "default": "not_a_list"}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception), "Default value must be a list, got str"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_array_parser_with_invalid_default_min(self):
|
||||||
|
parser = ArrayTypeParser()
|
||||||
|
|
||||||
|
properties = {"items": {"type": "string"}, "default": ["a"], "minItems": 2}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception), "Default list is below minItems limit of 2"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_array_parser_with_invalid_default_max(self):
|
||||||
|
parser = ArrayTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"items": {"type": "string"},
|
||||||
|
"default": ["a", "b", "c", "d"],
|
||||||
|
"maxItems": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception), "Default list exceeds maxItems limit of 3"
|
||||||
|
)
|
||||||
28
tests/parser/test_bool_type_parser.py
Normal file
28
tests/parser/test_bool_type_parser.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from jambo.parser import BooleanTypeParser
|
||||||
|
|
||||||
|
|
||||||
|
class TestBoolTypeParser(TestCase):
|
||||||
|
def test_bool_parser_no_options(self):
|
||||||
|
parser = BooleanTypeParser()
|
||||||
|
|
||||||
|
properties = {"type": "boolean"}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, bool)
|
||||||
|
self.assertEqual(type_validator, {})
|
||||||
|
|
||||||
|
def test_bool_parser_with_default(self):
|
||||||
|
parser = BooleanTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, bool)
|
||||||
|
self.assertEqual(type_validator["default"], True)
|
||||||
165
tests/parser/test_float_type_parser.py
Normal file
165
tests/parser/test_float_type_parser.py
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from jambo.parser import FloatTypeParser
|
||||||
|
|
||||||
|
|
||||||
|
class TestFloatTypeParser(TestCase):
|
||||||
|
def test_float_parser_no_options(self):
|
||||||
|
parser = FloatTypeParser()
|
||||||
|
|
||||||
|
properties = {"type": "number"}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, float)
|
||||||
|
self.assertEqual(type_validator, {})
|
||||||
|
|
||||||
|
def test_float_parser_with_options(self):
|
||||||
|
parser = FloatTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "number",
|
||||||
|
"maximum": 10.5,
|
||||||
|
"minimum": 1.0,
|
||||||
|
"multipleOf": 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, float)
|
||||||
|
self.assertEqual(type_validator["le"], 10.5)
|
||||||
|
self.assertEqual(type_validator["ge"], 1.0)
|
||||||
|
self.assertEqual(type_validator["multiple_of"], 0.5)
|
||||||
|
|
||||||
|
def test_float_parser_with_default(self):
|
||||||
|
parser = FloatTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "number",
|
||||||
|
"default": 5.0,
|
||||||
|
"maximum": 10.5,
|
||||||
|
"minimum": 1.0,
|
||||||
|
"multipleOf": 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, float)
|
||||||
|
self.assertEqual(type_validator["default"], 5.0)
|
||||||
|
self.assertEqual(type_validator["le"], 10.5)
|
||||||
|
self.assertEqual(type_validator["ge"], 1.0)
|
||||||
|
self.assertEqual(type_validator["multiple_of"], 0.5)
|
||||||
|
|
||||||
|
def test_float_parser_with_default_invalid_type(self):
|
||||||
|
parser = FloatTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "number",
|
||||||
|
"default": "invalid", # Invalid default value
|
||||||
|
"maximum": 10.5,
|
||||||
|
"minimum": 1.0,
|
||||||
|
"multipleOf": 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value must be a number, got str",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_float_parser_with_default_invalid_maximum(self):
|
||||||
|
parser = FloatTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "number",
|
||||||
|
"default": 15.0,
|
||||||
|
"maximum": 10.5,
|
||||||
|
"minimum": 1.0,
|
||||||
|
"multipleOf": 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value exceeds maximum limit of 10.5",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_float_parser_with_default_invalid_minimum(self):
|
||||||
|
parser = FloatTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "number",
|
||||||
|
"default": -5.0,
|
||||||
|
"maximum": 10.5,
|
||||||
|
"minimum": 1.0,
|
||||||
|
"multipleOf": 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value is below minimum limit of 1.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_float_parser_with_default_invalid_exclusive_maximum(self):
|
||||||
|
parser = FloatTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "number",
|
||||||
|
"default": 10.5,
|
||||||
|
"exclusiveMaximum": 10.5,
|
||||||
|
"minimum": 1.0,
|
||||||
|
"multipleOf": 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value exceeds exclusive maximum limit of 10.5",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_float_parser_with_default_invalid_exclusive_minimum(self):
|
||||||
|
parser = FloatTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "number",
|
||||||
|
"default": 1.0,
|
||||||
|
"maximum": 10.5,
|
||||||
|
"exclusiveMinimum": 1.0,
|
||||||
|
"multipleOf": 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value is below exclusive minimum limit of 1.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_float_parser_with_default_invalid_multiple(self):
|
||||||
|
parser = FloatTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "number",
|
||||||
|
"default": 5.0,
|
||||||
|
"maximum": 10.5,
|
||||||
|
"minimum": 1.0,
|
||||||
|
"multipleOf": 2.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value 5.0 is not a multiple of 2.0",
|
||||||
|
)
|
||||||
165
tests/parser/test_int_type_parser.py
Normal file
165
tests/parser/test_int_type_parser.py
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from jambo.parser import IntTypeParser
|
||||||
|
|
||||||
|
|
||||||
|
class TestIntTypeParser(TestCase):
|
||||||
|
def test_int_parser_no_options(self):
|
||||||
|
parser = IntTypeParser()
|
||||||
|
|
||||||
|
properties = {"type": "integer"}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, int)
|
||||||
|
self.assertEqual(type_validator, {})
|
||||||
|
|
||||||
|
def test_int_parser_with_options(self):
|
||||||
|
parser = IntTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 10,
|
||||||
|
"minimum": 1,
|
||||||
|
"multipleOf": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, int)
|
||||||
|
self.assertEqual(type_validator["le"], 10)
|
||||||
|
self.assertEqual(type_validator["ge"], 1)
|
||||||
|
self.assertEqual(type_validator["multiple_of"], 2)
|
||||||
|
|
||||||
|
def test_int_parser_with_default(self):
|
||||||
|
parser = IntTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 6,
|
||||||
|
"maximum": 10,
|
||||||
|
"minimum": 1,
|
||||||
|
"multipleOf": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, int)
|
||||||
|
self.assertEqual(type_validator["default"], 6)
|
||||||
|
self.assertEqual(type_validator["le"], 10)
|
||||||
|
self.assertEqual(type_validator["ge"], 1)
|
||||||
|
self.assertEqual(type_validator["multiple_of"], 2)
|
||||||
|
|
||||||
|
def test_int_parser_with_default_invalid_type(self):
|
||||||
|
parser = IntTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "integer",
|
||||||
|
"default": "invalid", # Invalid default value
|
||||||
|
"maximum": 10,
|
||||||
|
"minimum": 1,
|
||||||
|
"multipleOf": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value must be a number, got str",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_int_parser_with_default_invalid_maximum(self):
|
||||||
|
parser = IntTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 15,
|
||||||
|
"maximum": 10,
|
||||||
|
"minimum": 1,
|
||||||
|
"multipleOf": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value exceeds maximum limit of 10",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_int_parser_with_default_invalid_minimum(self):
|
||||||
|
parser = IntTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "integer",
|
||||||
|
"default": -5,
|
||||||
|
"maximum": 10,
|
||||||
|
"minimum": 1,
|
||||||
|
"multipleOf": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value is below minimum limit of 1",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_int_parser_with_default_invalid_exclusive_maximum(self):
|
||||||
|
parser = IntTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 10,
|
||||||
|
"exclusiveMaximum": 10,
|
||||||
|
"minimum": 1,
|
||||||
|
"multipleOf": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value exceeds exclusive maximum limit of 10",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_int_parser_with_default_invalid_exclusive_minimum(self):
|
||||||
|
parser = IntTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 1,
|
||||||
|
"exclusiveMinimum": 1,
|
||||||
|
"maximum": 10,
|
||||||
|
"multipleOf": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value is below exclusive minimum limit of 1",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_int_parser_with_default_invalid_multipleOf(self):
|
||||||
|
parser = IntTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 5,
|
||||||
|
"maximum": 10,
|
||||||
|
"minimum": 1,
|
||||||
|
"multipleOf": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value 5 is not a multiple of 2",
|
||||||
|
)
|
||||||
23
tests/parser/test_object_type_parser.py
Normal file
23
tests/parser/test_object_type_parser.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from jambo.parser import ObjectTypeParser
|
||||||
|
|
||||||
|
|
||||||
|
class TestObjectTypeParser(TestCase):
|
||||||
|
def test_object_type_parser(self):
|
||||||
|
parser = ObjectTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"age": {"type": "integer"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Model, _args = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
obj = Model(name="name", age=10)
|
||||||
|
|
||||||
|
self.assertEqual(obj.name, "name")
|
||||||
|
self.assertEqual(obj.age, 10)
|
||||||
102
tests/parser/test_string_type_parser.py
Normal file
102
tests/parser/test_string_type_parser.py
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from jambo.parser import StringTypeParser
|
||||||
|
|
||||||
|
|
||||||
|
class TestStringTypeParser(TestCase):
|
||||||
|
def test_string_parser_no_options(self):
|
||||||
|
parser = StringTypeParser()
|
||||||
|
|
||||||
|
properties = {"type": "string"}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, str)
|
||||||
|
|
||||||
|
def test_string_parser_with_options(self):
|
||||||
|
parser = StringTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 10,
|
||||||
|
"minLength": 1,
|
||||||
|
"pattern": "^[a-zA-Z]+$",
|
||||||
|
}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, str)
|
||||||
|
self.assertEqual(type_validator["max_length"], 10)
|
||||||
|
self.assertEqual(type_validator["min_length"], 1)
|
||||||
|
self.assertEqual(type_validator["pattern"], "^[a-zA-Z]+$")
|
||||||
|
|
||||||
|
def test_string_parser_with_default_value(self):
|
||||||
|
parser = StringTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "string",
|
||||||
|
"default": "default_value",
|
||||||
|
"maxLength": 20,
|
||||||
|
"minLength": 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(type_parsing, str)
|
||||||
|
self.assertEqual(type_validator["default"], "default_value")
|
||||||
|
self.assertEqual(type_validator["max_length"], 20)
|
||||||
|
self.assertEqual(type_validator["min_length"], 5)
|
||||||
|
|
||||||
|
def test_string_parser_with_invalid_default_value_type(self):
|
||||||
|
parser = StringTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "string",
|
||||||
|
"default": 12345, # Invalid default value
|
||||||
|
"maxLength": 20,
|
||||||
|
"minLength": 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value for placeholder must be a string, but got <int>.",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_string_parser_with_default_invalid_maxlength(self):
|
||||||
|
parser = StringTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "string",
|
||||||
|
"default": "default_value",
|
||||||
|
"maxLength": 2,
|
||||||
|
"minLength": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value for placeholder exceeds maxLength limit of 2",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_string_parser_with_default_invalid_minlength(self):
|
||||||
|
parser = StringTypeParser()
|
||||||
|
|
||||||
|
properties = {
|
||||||
|
"type": "string",
|
||||||
|
"default": "a",
|
||||||
|
"maxLength": 20,
|
||||||
|
"minLength": 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
str(context.exception),
|
||||||
|
"Default value for placeholder is below minLength limit of 2",
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
from jambo.schema_converter import SchemaConverter
|
from jambo import SchemaConverter
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
from jambo.parser import (
|
|
||||||
ArrayTypeParser,
|
|
||||||
FloatTypeParser,
|
|
||||||
GenericTypeParser,
|
|
||||||
IntTypeParser,
|
|
||||||
ObjectTypeParser,
|
|
||||||
StringTypeParser,
|
|
||||||
)
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
from typing import get_args
|
|
||||||
|
|
||||||
|
|
||||||
class TestTypeParser(unittest.TestCase):
|
|
||||||
def test_get_impl(self):
|
|
||||||
self.assertEqual(GenericTypeParser.get_impl("integer"), IntTypeParser)
|
|
||||||
self.assertEqual(GenericTypeParser.get_impl("string"), StringTypeParser)
|
|
||||||
self.assertEqual(GenericTypeParser.get_impl("number"), FloatTypeParser)
|
|
||||||
self.assertEqual(GenericTypeParser.get_impl("object"), ObjectTypeParser)
|
|
||||||
self.assertEqual(GenericTypeParser.get_impl("array"), ArrayTypeParser)
|
|
||||||
|
|
||||||
def test_int_parser(self):
|
|
||||||
parser = IntTypeParser()
|
|
||||||
|
|
||||||
type_parsing, type_validator = parser.from_properties(
|
|
||||||
"placeholder",
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"exclusiveMinimum": 1,
|
|
||||||
"maximum": 10,
|
|
||||||
"exclusiveMaximum": 11,
|
|
||||||
"multipleOf": 2,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(type_parsing, int)
|
|
||||||
self.assertEqual(type_validator["ge"], 0)
|
|
||||||
self.assertEqual(type_validator["gt"], 1)
|
|
||||||
self.assertEqual(type_validator["le"], 10)
|
|
||||||
self.assertEqual(type_validator["lt"], 11)
|
|
||||||
self.assertEqual(type_validator["multiple_of"], 2)
|
|
||||||
|
|
||||||
def test_float_parser(self):
|
|
||||||
parser = FloatTypeParser()
|
|
||||||
|
|
||||||
type_parsing, type_validator = parser.from_properties(
|
|
||||||
"placeholder",
|
|
||||||
{
|
|
||||||
"type": "number",
|
|
||||||
"minimum": 0,
|
|
||||||
"exclusiveMinimum": 1,
|
|
||||||
"maximum": 10,
|
|
||||||
"exclusiveMaximum": 11,
|
|
||||||
"multipleOf": 2,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(type_parsing, float)
|
|
||||||
self.assertEqual(type_validator["ge"], 0)
|
|
||||||
self.assertEqual(type_validator["gt"], 1)
|
|
||||||
self.assertEqual(type_validator["le"], 10)
|
|
||||||
self.assertEqual(type_validator["lt"], 11)
|
|
||||||
self.assertEqual(type_validator["multiple_of"], 2)
|
|
||||||
|
|
||||||
def test_string_parser(self):
|
|
||||||
parser = StringTypeParser()
|
|
||||||
|
|
||||||
type_parsing, type_validator = parser.from_properties(
|
|
||||||
"placeholder",
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 10,
|
|
||||||
"minLength": 1,
|
|
||||||
"pattern": "[a-zA-Z0-9]",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(type_parsing, str)
|
|
||||||
self.assertEqual(type_validator["max_length"], 10)
|
|
||||||
self.assertEqual(type_validator["min_length"], 1)
|
|
||||||
self.assertEqual(type_validator["pattern"], "[a-zA-Z0-9]")
|
|
||||||
|
|
||||||
def test_object_parser(self):
|
|
||||||
parser = ObjectTypeParser()
|
|
||||||
|
|
||||||
properties = {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {"type": "string"},
|
|
||||||
"age": {"type": "integer"},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
Model, _args = parser.from_properties("placeholder", properties)
|
|
||||||
|
|
||||||
obj = Model(name="name", age=10)
|
|
||||||
|
|
||||||
self.assertEqual(obj.name, "name")
|
|
||||||
self.assertEqual(obj.age, 10)
|
|
||||||
|
|
||||||
def test_array_of_string_parser(self):
|
|
||||||
parser = ArrayTypeParser()
|
|
||||||
expected_definition = (list[str], {})
|
|
||||||
|
|
||||||
properties = {"items": {"type": "string"}}
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
parser.from_properties("placeholder", properties), expected_definition
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_array_of_object_parser(self):
|
|
||||||
parser = ArrayTypeParser()
|
|
||||||
|
|
||||||
properties = {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {"type": "string"},
|
|
||||||
"age": {"type": "integer"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"maxItems": 10,
|
|
||||||
"minItems": 1,
|
|
||||||
"uniqueItems": True,
|
|
||||||
}
|
|
||||||
|
|
||||||
type_parsing, type_validator = parser.from_properties("placeholder", properties)
|
|
||||||
|
|
||||||
self.assertEqual(type_parsing.__origin__, set)
|
|
||||||
self.assertEqual(type_validator["max_length"], 10)
|
|
||||||
self.assertEqual(type_validator["min_length"], 1)
|
|
||||||
|
|
||||||
Model = get_args(type_parsing)[0]
|
|
||||||
obj = Model(name="name", age=10)
|
|
||||||
|
|
||||||
self.assertEqual(obj.name, "name")
|
|
||||||
self.assertEqual(obj.age, 10)
|
|
||||||
Reference in New Issue
Block a user