Skip to content

Commit

Permalink
Change validate_* methods after testing.
Browse files Browse the repository at this point in the history
Fixed:

- Fix no_null default in validate_metadata_presence
- Fix external_codelists default in validate_schema_codelists_match
  • Loading branch information
jpmckinney committed Mar 16, 2020
1 parent b7f60f3 commit 61fb55a
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 15 deletions.
17 changes: 10 additions & 7 deletions jscc/testing/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from jscc.testing.schema import is_json_schema
from jscc.testing.util import http_get
schemas = [(path, name, data) for path, name, _, data in walk_json_data(patch) if is_json_schema(data)]
schemas = [(path, name, data) for path, name, _, data in walk_json_data() if is_json_schema(data)]
metaschema = http_get('http://json-schema.org/draft-04/schema').json()
@pytest.mark.parametrize('path,name,data', schemas)
Expand Down Expand Up @@ -269,7 +269,7 @@ def block(path, data, pointer):
return _traverse(block)(*args)


def validate_null_type(path, data, pointer='', no_null=True, should_be_nullable=True, allow_object_null=(),
def validate_null_type(path, data, pointer='', no_null=False, should_be_nullable=True, allow_object_null=(),
allow_no_null=(), allow_null=()):
"""
Warns and returns the number of errors relating to non-nullable optional fields and nullable required fields.
Expand Down Expand Up @@ -507,7 +507,7 @@ def block(path, data, pointer):
if original == pointer:
warn('{} object array should require "id" field at {}'.format(path, pointer), ObjectIdWarning)
else:
warn('{} object array should require "id" field at {} (from {})'.format( path, original, pointer),
warn('{} object array should require "id" field at {} (from {})'.format(path, original, pointer),
ObjectIdWarning)

return errors
Expand Down Expand Up @@ -566,7 +566,7 @@ def validate_ref(path, data):
return 0


def validate_schema_codelists_match(path, data, top, is_extension=False, is_profile=False, external_codelists=()):
def validate_schema_codelists_match(path, data, top, is_extension=False, is_profile=False, external_codelists=None):
"""
Warns and returns the number of errors relating to mismatches between codelist files and codelist references from
JSON Schema.
Expand All @@ -577,6 +577,9 @@ def validate_schema_codelists_match(path, data, top, is_extension=False, is_prof
:param external_codelists: names of codelists defined by the standard
:type external_codelists: list, tuple or set
"""
if not external_codelists:
external_codelists = set()

def collect_codelist_values(path, data, pointer=''):
"""
Collects ``codelist`` values from JSON Schema.
Expand Down Expand Up @@ -605,7 +608,7 @@ def collect_codelist_values(path, data, pointer=''):
if csvname.startswith(('+', '-')):
if csvname[1:] not in external_codelists:
errors += 1
warn('{} {} modifies non-existent codelist'.format(path, csvname), SchemaCodelistsMatchWarning)
warn('{} modifies non-existent codelist'.format(csvname), SchemaCodelistsMatchWarning)
else:
codelist_files.add(csvname)

Expand All @@ -620,11 +623,11 @@ def collect_codelist_values(path, data, pointer=''):

if unused_codelists:
errors += 1
warn('repository has unused codelists: {}'.format(', '.join(sorted(unused_codelists))),
warn('unused codelists: {}'.format(', '.join(sorted(unused_codelists))),
SchemaCodelistsMatchWarning)
if missing_codelists:
errors += 1
warn('repository is missing codelists: {}'.format(', '.join(sorted(missing_codelists))),
warn('missing codelists: {}'.format(', '.join(sorted(missing_codelists))),
SchemaCodelistsMatchWarning)

return errors
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/empty/invalid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{
1 change: 1 addition & 0 deletions tests/fixtures/indent/invalid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{
9 changes: 9 additions & 0 deletions tests/fixtures/schema/codelist_enum.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@
]
}
},
"passNoType": {
"codelist": "test.csv",
"openCodelist": false,
"items": {
"enum": [
"code"
]
}
},
"failOpenString": {
"codelist": "failOpenString.csv",
"openCodelist": true,
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/schema/codelists/+nonexistent.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Code
4 changes: 2 additions & 2 deletions tests/fixtures/schema/null_type.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
"failOptional": {
"type": "string"
},
"object": {
"failObject": {
"type": [
"object",
"null"
]
}
},
"required": [
"required",
"passRequired",
"failRequired"
]
}
48 changes: 42 additions & 6 deletions tests/test_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import jscc.testing.checks
from jscc.exceptions import DuplicateKeyError
from jscc.testing.checks import (get_empty_files, get_invalid_json_files, get_misindented_files,
validate_codelist_enum, validate_object_id, validate_schema_codelists_match)
validate_codelist_enum, validate_object_id, validate_ref,
validate_schema_codelists_match)
from tests import parse, path


Expand Down Expand Up @@ -168,7 +169,19 @@ def test_validate_null_type():

assert errors == len(records) == 3
assert sorted(str(record.message) for record in records) == [
"tests/fixtures/schema/null_type.json nullable object ['object', 'null'] at /properties/object",
"tests/fixtures/schema/null_type.json non-nullable optional string at /properties/failOptional",
"tests/fixtures/schema/null_type.json nullable object ['object', 'null'] at /properties/failObject",
"tests/fixtures/schema/null_type.json nullable required ['string', 'null'] at /properties/failRequired",
]


def test_validate_null_type_no_null():
with pytest.warns(UserWarning) as records:
errors = validate('null_type', no_null=True)

assert errors == len(records) == 3
assert sorted(str(record.message) for record in records) == [
"tests/fixtures/schema/null_type.json nullable object ['object', 'null'] at /properties/failObject",
"tests/fixtures/schema/null_type.json nullable required ['string', 'null'] at /properties/failRequired",
"tests/fixtures/schema/null_type.json nullable required ['string', 'null'] at /properties/passOptional",
]
Expand All @@ -192,7 +205,15 @@ def allow_missing(pointer):
]


def test_validate_ref():
def test_validate_ref_pass():
filepath = 'schema/schema.json'
with pytest.warns(None) as records:
errors = validate_ref(path(filepath), parse(filepath))

assert errors == len(records) == 0


def test_validate_ref_fail():
with pytest.warns(UserWarning) as records:
errors = validate('ref')

Expand Down Expand Up @@ -220,8 +241,23 @@ def test_validate_schema_codelists_match():
with pytest.warns(UserWarning) as records:
errors = validate_schema_codelists_match(path(filepath), parse(filepath), path('schema'))

assert errors == len(records) == 2
assert errors == len(records) == 3
assert sorted(str(record.message) for record in records) == [
'+nonexistent.csv modifies non-existent codelist',
'missing codelists: failOpenArray.csv, failOpenString.csv, missing.csv',
'unused codelists: extra.csv',
]


def test_validate_schema_codelists_match_codelist():
filepath = 'schema/codelist_enum.json'
with pytest.warns(UserWarning) as records:
errors = validate_schema_codelists_match(path(filepath), parse(filepath), path('schema'), is_extension=True,
external_codelists={'failOpenArray.csv', 'failOpenString.csv'})

assert errors == len(records) == 3
assert sorted(str(record.message) for record in records) == [
'repository has unused codelists: extra.csv',
'repository is missing codelists: failOpenArray.csv, failOpenString.csv, missing.csv',
'+nonexistent.csv modifies non-existent codelist',
'missing codelists: missing.csv',
'unused codelists: extra.csv',
]

0 comments on commit 61fb55a

Please sign in to comment.