import json from pathlib import Path import pytest from urllib.request import urlopen from fastjsonschema import RefResolver, JsonSchemaValueException, compile, _get_code_generator_class REMOTES = { 'http://localhost:1234/integer.json': {'type': 'integer'}, 'http://localhost:1234/name.json': { 'type': 'string', 'definitions': { 'orNull': {'anyOf': [{'type': 'null'}, {'$ref': '#'}]}, }, }, 'http://localhost:1234/subSchemas.json': { 'integer': {'type': 'integer'}, 'refToInteger': {'$ref': '#/integer'}, }, 'http://localhost:1234/folder/folderInteger.json': {'type': 'integer'} } def remotes_handler(uri): if uri in REMOTES: return REMOTES[uri] req = urlopen(uri) encoding = req.info().get_content_charset() or 'utf-8' return json.loads(req.read().decode(encoding),) def resolve_param_values_and_ids(schema_version, suite_dir, ignored_suite_files=[], ignore_tests=[]): suite_dir_path = Path(suite_dir).resolve() test_file_paths = sorted(set(suite_dir_path.glob("**/*.json"))) param_values = [] param_ids = [] for test_file_path in test_file_paths: with test_file_path.open(encoding='UTF-8') as test_file: test_cases = json.load(test_file) for test_case in test_cases: for test_data in test_case['tests']: param_values.append(pytest.param( schema_version, test_case['schema'], test_data['data'], test_data['valid'], marks=pytest.mark.xfail if test_file_path.name in ignored_suite_files or test_case['description'] in ignore_tests else pytest.mark.none, )) param_ids.append('{} / {} / {}'.format( test_file_path.name, test_case['description'], test_data['description'], )) return param_values, param_ids def template_test(schema_version, schema, data, is_valid): """ Test function to be used (imported) in final test file to run the tests which are generated by `pytest_generate_tests` hook. """ # For debug purposes. When test fails, it will print stdout. resolver = RefResolver.from_schema(schema, handlers={'http': remotes_handler}) debug_generator = _get_code_generator_class(schema_version)(schema, resolver=resolver) print(debug_generator.global_state_code) print(debug_generator.func_code) # JSON schema test suits do not contain schema version. # Our library needs to know that or it would use always the latest implementation. if isinstance(schema, dict): schema.setdefault('$schema', schema_version) validate = compile(schema, handlers={'http': remotes_handler}) try: result = validate(data) print('Validate result:', result) except JsonSchemaValueException: if is_valid: raise else: if not is_valid: pytest.fail('Test should not pass')