Skip to content

Commit

Permalink
Agrego parámetro validator_class
Browse files Browse the repository at this point in the history
Permite extender la funcionalidad de validación de catálogos. La clase
deberá implementar los métodos is_valid, que devuelve True o False según
el catálogo sea válido, e iter_errors, un generator de errores. La forma
más sencilla de cumplir los requerimientos es que el validador sea una
instancia de jsonschema.Draft4Validator, o de una clase que herede de
ésta.
  • Loading branch information
lucaslavandeira committed May 24, 2019
1 parent fcdbe9f commit 9d606a0
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 22 deletions.
5 changes: 3 additions & 2 deletions pydatajson/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ class DataJson(dict):
CATALOG_FIELDS_PATH = os.path.join(ABSOLUTE_PROJECT_DIR, "fields")

def __init__(self, catalog=None, schema_filename=None, schema_dir=None,
default_values=None, catalog_format=None):
default_values=None, catalog_format=None,
validator_class=None):
"""Lee un catálogo y crea un objeto con funciones para manipularlo.
Salvo que se indique lo contrario, se utiliza como default el schema
Expand Down Expand Up @@ -97,7 +98,7 @@ def __init__(self, catalog=None, schema_filename=None, schema_dir=None,
self.has_catalog = False

self.validator = validation.create_validator(
schema_filename, schema_dir)
schema_filename, schema_dir, validator_class)

# asigno docstrings de los métodos modularizados
fn_doc = indicators.generate_catalogs_indicators.__doc__
Expand Down
7 changes: 5 additions & 2 deletions pydatajson/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
logger = logging.getLogger('pydatajson')


def create_validator(schema_filename=None, schema_dir=None):
def create_validator(schema_filename=None,
schema_dir=None,
validator_class=None):
"""Crea el validador necesario para inicializar un objeto DataJson.
Para poder resolver referencias inter-esquemas, un Validador requiere
Expand All @@ -64,6 +66,7 @@ def create_validator(schema_filename=None, schema_dir=None):
schema_dir = schema_dir or ABSOLUTE_SCHEMA_DIR
schema_path = os.path.join(schema_dir, schema_filename)
schema = readers.read_json(schema_path)
validator_class = validator_class or jsonschema.Draft4Validator

# Según https://github.com/Julian/jsonschema/issues/98
# Permite resolver referencias locales a otros esquemas.
Expand All @@ -75,7 +78,7 @@ def create_validator(schema_filename=None, schema_dir=None):

format_checker = jsonschema.FormatChecker()

validator = jsonschema.Draft4Validator(
validator = validator_class(
schema=schema, resolver=resolver, format_checker=format_checker)

return validator
Expand Down
53 changes: 35 additions & 18 deletions tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import re

import vcr
from nose.tools import assert_true, assert_false, assert_dict_equal,\
from jsonschema import Draft4Validator
from nose.tools import assert_true, assert_false, assert_dict_equal, \
assert_regexp_matches
from six import iteritems, text_type

Expand Down Expand Up @@ -100,7 +101,7 @@ def test_invalid_dataset_theme_type(self):
case_filename = "invalid_dataset_theme_type"
expected_valid = False
path = ['error', 'dataset', 0, 'errors', 0, 'message']
regex = "%s is not valid under any of the given schemas"\
regex = "%s is not valid under any of the given schemas" \
% jsonschema_str('contrataciones')
self.validate_message_with_file(
case_filename, expected_valid, path, regex)
Expand All @@ -117,7 +118,7 @@ def test_invalid_keywords(self):
case_filename = "invalid_keywords"
expected_valid = False
path = ['error', 'dataset', 1, 'errors', 0, 'message']
regex = "\[%s, %s, %s\] is not valid under any of the given schemas"\
regex = "\[%s, %s, %s\] is not valid under any of the given schemas" \
% (jsonschema_str(';;bienes;;'), jsonschema_str('::compras::'),
jsonschema_str('//contrataciones//'))
self.validate_message_with_file(
Expand Down Expand Up @@ -192,7 +193,7 @@ def test_several_assorted_errors(self):
),
]
for path, regex in expected_errors:
yield self.validate_contains_message_with_file,\
yield self.validate_contains_message_with_file, \
case_filename, path, regex

def validate_message_with_file(
Expand Down Expand Up @@ -250,17 +251,17 @@ def test_validate_invalid_remote_datajson_has_errors(self):
""" Testea `validate_catalog` contra un data.json remoto invalido."""

errors = [(
['error', 'catalog', 'errors', ],
"%s is too short" % jsonschema_str('')
),
(
['error', 'catalog', 'errors', ],
"%s is not a %s" % (jsonschema_str(''),
jsonschema_str('email'))
)]
['error', 'catalog', 'errors', ],
"%s is too short" % jsonschema_str('')
),
(
['error', 'catalog', 'errors', ],
"%s is not a %s" % (jsonschema_str(''),
jsonschema_str('email'))
)]
for path, regex in errors:
with my_vcr.use_cassette('test_validate_bad_remote_datajson'):
yield self.validate_contains_message, BAD_DATAJSON_URL,\
yield self.validate_contains_message, BAD_DATAJSON_URL, \
path, regex

# Tests contra una URL REMOTA
Expand All @@ -275,13 +276,18 @@ def test_validate_invalid_remote_datajson_has_errors2(self):
""" Testea `validate_catalog` contra un data.json remoto invalido."""
errors = [
([
'error', 'catalog', 'errors', ], "%s is not a %s" %
(jsonschema_str(''), jsonschema_str('email'))), ([
'error', 'catalog', 'errors', ], "%s is too short" %
jsonschema_str('')), ]
'error', 'catalog', 'errors', ], "%s is not a %s" %
(jsonschema_str(''), jsonschema_str('email'))),
([
'error',
'catalog',
'errors', ],
"%s is too short" %
jsonschema_str(
'')), ]
for path, regex in errors:
with my_vcr.use_cassette('test_validate_bad_remote_datajson2'):
yield self.validate_contains_message, BAD_DATAJSON_URL2,\
yield self.validate_contains_message, BAD_DATAJSON_URL2, \
path, regex

def test_correctness_of_accrualPeriodicity_regex(self):
Expand Down Expand Up @@ -337,3 +343,14 @@ def test_invalid_catalog_list_format(self):
error['message'] in [
reported['dataset_error_message'] for reported
in report_list['dataset']])

def test_specify_validator_class(self):
class MyValidator(Draft4Validator):
def my_method(self):
return "MyValidator!"

dj = pydatajson.DataJson(self.get_sample('full_data.json'),
validator_class=MyValidator)
dj.is_valid_catalog()
dj.validate_catalog()
assert_true(dj.validator.my_method() == "MyValidator!")

0 comments on commit 9d606a0

Please sign in to comment.