Skip to content

Commit

Permalink
More tests, cleanup & refactoring of code. Removed some unused and no…
Browse files Browse the repository at this point in the history
…t working code that is covered in other parts of the code now.
  • Loading branch information
Grokzen committed Aug 22, 2014
1 parent 08d3d5b commit 25bf22b
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 48 deletions.
38 changes: 4 additions & 34 deletions pykwalify/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ def __init__(self, source_file=None, schema_files=[], source_data=None, schema_d
elif source_file.endswith(".yaml"):
try:
self.source = yaml.load(stream)
# if len(self.source) == 0:
# raise Exception(".")
except Exception as e:
raise CoreError("Unable to load any data from source yaml file")
else:
Expand Down Expand Up @@ -201,8 +199,6 @@ def _validate_sequence(self, value, rule, path, errors=[], done=None):
Log.debug(" * Seq: {}".format(rule._sequence))
Log.debug(" * Map: {}".format(rule._mapping))

if not isinstance(rule._sequence, list):
raise CoreError("sequence data not of list type : {}".format(path))
if not len(rule._sequence) == 1:
raise CoreError("only 1 item allowed in sequence rule : {}".format(path))

Expand Down Expand Up @@ -280,17 +276,6 @@ def _validate_mapping(self, value, rule, path, errors=[], done=None):
Log.debug(" + No rule to apply, prolly because of allowempty: True")
return

if not isinstance(rule._mapping, dict):
raise CoreError("mapping is not a valid dict object")

if value is None:
Log.debug(" + Value is None, returning...")
return

if not isinstance(value, dict):
errors.append("mapping.value.notdict : {} : {}".format(value, path))
return

m = rule._mapping
Log.debug(" + RuleMapping: {}".format(m))

Expand Down Expand Up @@ -345,11 +330,6 @@ def _validate_scalar(self, value, rule, path, errors=[], done=None):
Log.debug(" # {}".format(rule._type))
Log.debug(" # {}".format(path))

if rule._sequence is not None:
raise CoreError("found sequence when validating for scalar")
if rule._mapping is not None:
raise CoreError("found mapping when validating for scalar")

if rule._enum is not None:
if value not in rule._enum:
errors.append("enum.notexists : {} : {}".format(value, path))
Expand Down Expand Up @@ -390,35 +370,25 @@ def _validate_scalar(self, value, rule, path, errors=[], done=None):
"scalar")

def _validate_range(self, max_, min_, max_ex, min_ex, errors, value, path, prefix):
##########
# Test max
"""
Validate that value is within range values.
"""

Log.debug("Validate range : {} : {} : {} : {} : {} : {}".format(max_, min_, max_ex, min_ex, value, path))

if max_ is not None:
if not isinstance(max_, int):
raise Exception("INTERNAL ERROR: variable 'max' not of 'int' type")

if max_ < value:
errors.append("{}.range.toolarge : {} < {} : {}".format(prefix, max_, value, path))

if min_ is not None:
if not isinstance(min_, int):
raise Exception("INTERNAL ERROR: variable 'min_' not of 'int' type")

if min_ > value:
errors.append("{}.range.toosmall : {} > {} : {}".format(prefix, min_, value, path))

if max_ex is not None:
if not isinstance(max_ex, int):
raise Exception("INTERNAL ERROR: variable 'max_ex' not of 'int' type")

if max_ex <= value:
errors.append("{}.range.tolarge-ex : {} <= {} : {}".format(prefix, max_ex, value, path))

if min_ex is not None:
if not isinstance(min_ex, int):
raise Exception("INTERNAL ERROR: variable 'min_ex' not of 'int' type")

if min_ex >= value:
errors.append("{}.range.toosmall-ex : {} >= {} : {}".format(prefix, min_ex, value, path))

Expand Down
10 changes: 5 additions & 5 deletions pykwalify/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
Log = logging.getLogger(__name__)

# pyKwalify imports
from pykwalify.types import DEFAULT_TYPE, typeClass, isBuiltinType, isCollectionType, isInt
from pykwalify.types import DEFAULT_TYPE, typeClass, isBuiltinType, isCollectionType, isInt, isBool
from pykwalify.errors import SchemaConflict, RuleError


Expand Down Expand Up @@ -230,16 +230,16 @@ def initRangeValue(self, v, rule, path):
max_ex = self._range.get("max-ex", None)
min_ex = self._range.get("min-ex", None)

if max is not None and not isInt(max):
if max is not None and not isInt(max) or isBool(max):
raise RuleError("range.max.notint : {} : {}".format(max, path))

if min is not None and not isInt(min):
if min is not None and not isInt(min) or isBool(min):
raise RuleError("range.min.notint : {} : {}".format(min, path))

if max_ex is not None and not isInt(max_ex):
if max_ex is not None and not isInt(max_ex) or isBool(max_ex):
raise RuleError("range.max_ex.notint : {} : {}".format(max_ex, path))

if min_ex is not None and not isInt(min_ex):
if min_ex is not None and not isInt(min_ex) or isBool(min_ex):
raise RuleError("range.min_ex.notint : {} : {}".format(min_ex, path))

if max is not None:
Expand Down
4 changes: 2 additions & 2 deletions tests/files/14b.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ sequence:
age:
type: int
range:
max: 30
min: 18
max-ex: 30
min-ex: 18
blood:
type: str
enum:
Expand Down
7 changes: 6 additions & 1 deletion tests/files/15a.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@
email: bar@mail.net
age: 15
blood: AB
birth: "1980/01/01"
birth: "1980/01/01"
- email: bar@mail.net
age: 20
blood: AB
birth: "1980/01/01"
name: bar
34 changes: 34 additions & 0 deletions tests/files/15b.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
type: seq
sequence:
- type: map
mapping:
name:
type: str
required: True
email:
type: str
required: True
pattern: .+@.+
password:
type: str
range:
max: 16
min: 8
age:
type: int
range:
max-ex: 19
min-ex: 18
blood:
type: str
enum:
- A
- B
- O
- AB
birth:
type: str # Should be date
memo:
type: any
deleted:
type: bool
2 changes: 1 addition & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ def test_run_cli(self):

cli_args = cli.parse_cli()
c = cli.run(cli_args)
assert c.validation_errors == []
assert c.validation_errors == []
2 changes: 1 addition & 1 deletion tests/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def test_types(self):

assert types.isFloat(1.0)
assert not types.isFloat("foo")

assert types.isNumber(1)
assert types.isNumber(1.0)
assert not types.isNumber("foo")
Expand Down
19 changes: 15 additions & 4 deletions tests/testcore.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@ def test_validation_error_but_not_raise_exception(self):
# TODO: Fix this issue...
# assert ('pykwalify.core', 'ERROR', 'Errors found but will not raise exception...') in l.actual()

def test_invalid_mapping_data_type(self):
"""
Test that validating range object raises correct error messages when wrong
values is sent into the function.
"""
# c = Core(source_data={"foo": None}, schema_data={"type": "map", "mapping": {"foo": {"type": "str"}}})
# c.validate()
pass

def testCoreDataMode(self):
Core(source_data=3.14159, schema_data={"type": "number"}).validate()
Core(source_data=3.14159, schema_data={"type": "float"}).validate()
Expand Down Expand Up @@ -263,7 +272,7 @@ def testCore(self):
# Test mapping with sequence with mapping and valid data
("12a.yaml", "12b.yaml", {'mapping': {'company': {'required': True, 'type': 'str'}, 'email': {'type': 'str'}, 'employees': {'sequence': [{'mapping': {'code': {'required': True, 'type': 'int'}, 'email': {'type': 'str'}, 'name': {'required': True, 'type': 'str'}}, 'type': 'map'}], 'type': 'seq'}}, 'type': 'map'}),
# Test most of the implemented functions
("14a.yaml", "14b.yaml", {'sequence': [{'mapping': {'age': {'range': {'max': 30, 'min': 18}, 'type': 'int'}, 'birth': {'type': 'str'}, 'blood': {'enum': ['A', 'B', 'O', 'AB'], 'type': 'str'}, 'deleted': {'type': 'bool'}, 'email': {'pattern': '.+@.+', 'required': True, 'type': 'str'}, 'memo': {'type': 'any'}, 'name': {'required': True, 'type': 'str'}, 'password': {'range': {'max': 16, 'min': 8}, 'type': 'str'}}, 'type': 'map'}], 'type': 'seq'}),
("14a.yaml", "14b.yaml", {'sequence': [{'mapping': {'age': {'range': {'max-ex': 30, 'min-ex': 18}, 'type': 'int'}, 'birth': {'type': 'str'}, 'blood': {'enum': ['A', 'B', 'O', 'AB'], 'type': 'str'}, 'deleted': {'type': 'bool'}, 'email': {'pattern': '.+@.+', 'required': True, 'type': 'str'}, 'memo': {'type': 'any'}, 'name': {'required': True, 'type': 'str'}, 'password': {'range': {'max': 16, 'min': 8}, 'type': 'str'}}, 'type': 'map'}], 'type': 'seq'}),
# This will test the unique constraint
("16a.yaml", "16b.yaml", {'sequence': [{'mapping': {'email': {'type': 'str'}, 'groups': {'sequence': [{'type': 'str', 'unique': True}], 'type': 'seq'}, 'name': {'required': True, 'type': 'str', 'unique': True}}, 'required': True, 'type': 'map'}], 'type': 'seq'}),
#
Expand Down Expand Up @@ -316,15 +325,17 @@ def testCore(self):
("13a.yaml", "12b.yaml", SchemaError, ["Value: A101 is not of type 'int' : /employees/0/code",
'key.undefined : mail : /employees/1']),
# TODO: write
("15a.yaml", "14b.yaml", SchemaError, ["Value: twenty is not of type 'int' : /0/age",
("15a.yaml", "15b.yaml", SchemaError, ["Value: twenty is not of type 'int' : /0/age",
'pattern.unmatch : .+@.+ --> foo(at)mail.com : /0/email',
'enum.notexists : a : /0/blood',
'required.nokey : name : /1',
'key.undefined : given-name : /1',
'key.undefined : family-name : /1',
'scalar.range.toosmall-ex : 18 >= 15 : /1/age',
'scalar.range.toosmall-ex : 18 >= 6 : /0/age',
'scalar.range.toosmall : 8 > 6 : /0/password',
'scalar.range.toosmall : 18 > 15 : /1/age',
'scalar.range.toosmall : 18 > 6 : /0/age']),
'scalar.range.tolarge-ex : 19 <= 20 : /2/age',
]),
# TODO: The reverse unique do not currently work proper # This will test the unique constraint but should fail
("17a.yaml", "16b.yaml", SchemaError, ['value.notunique :: value: foo : /0/groups/3 : /0/groups/0']),
# This tests number validation rule with wrong data
Expand Down

0 comments on commit 25bf22b

Please sign in to comment.