def test_bad_yaml(tmpdir): bad_yaml = tmpdir.join('bad.json') bad_yaml.write('{[!very #bad yaml') data = {'$ref': f'{str(bad_yaml)}'} with raises(DecodeError): resolve(data)
def test_bad_json(tmpdir): bad_json = tmpdir.join('bad.json') bad_json.write('!very #bad ^stuff') data = {'$ref': f'{str(bad_json)}'} with raises(DecodeError): resolve(data)
def test_web(): data = { 'real': 'stuff', 'bad_ref': { '$ref': 'http://example.com#/well/this/does/not/matter' } } with raises(ResolutionError): resolve(data)
def test_bad_file_ref(): data = { 'real': 'stuff', 'bad_ref': { '$ref': '/not/existing/file#/well/this/does/not/matter' } } with raises(FileResolutionError): resolve(data)
def test_nested(tmpdir): root_dir = tmpdir.mkdir('root_dir') root_doc = root_dir.join('root.json') root_data = { 'some': 'stuff', 'some_ref': { '$ref': 'child_dir/child.json#/some_key/child_key' } } root_doc.write(json.dumps(root_data)) child_doc = root_dir.mkdir('child_dir').join('child.json') child_data = { 'some': 'useless thing', 'now': 'useful data', 'some_key': { 'another': 'useless thing', 'child_key': { '$ref': '#/now' } } } child_doc.write(json.dumps(child_data)) data = {'file_ref': {'$ref': f'{str(root_doc)}#/some_ref'}} resolved = resolve(data) assert resolved == {'file_ref': 'useful data'}
def test_nested_yaml(tmpdir): root_dir = tmpdir.mkdir('root_dir') root_doc = root_dir.join('root.yaml') root_data = { 'some': 'stuff', 'some_ref': { '$ref': 'child_dir/child.yaml#/some_key/child_key' } } root_doc.write(yaml.dump(root_data, default_flow_style=False)) child_doc = root_dir.mkdir('child_dir').join('child.yaml') child_data = { 'some': 'useless thing', 'now': 'useful data', 'some_key': { 'another': 'useless thing', 'child_key': { '$ref': '#/now' } } } child_doc.write(yaml.dump(child_data, default_flow_style=False)) data = {'file_ref': {'$ref': f'{str(root_doc)}#/some_ref'}} resolved = resolve(data) assert resolved == {'file_ref': 'useful data'}
def test_external_only(tmpdir): root_dir = tmpdir.mkdir('root_dir') root_doc = root_dir.join('root.json') file_data = {'some': 'in_file_data'} root_doc.write(json.dumps(file_data)) data = { 'inline': 'data', 'internal_ref': { '$ref': '#/inline' }, 'file_ref': { '$ref': f"{str(root_doc)}#/some" } } resolved = resolve(data, external_only=True) assert resolved == { 'inline': 'data', 'file_ref': 'in_file_data', 'internal_ref': { '$ref': '#/inline' } }
def test_inplace(): data = {'some': 'data', 'other': 'stuff', 'some_ref': {'$ref': '#/other'}} resolved = resolve(data) assert resolved is data assert data['some_ref'] == 'stuff'
def test_complicated(tmpdir): root_dir = tmpdir.mkdir('root_dir') root_doc = root_dir.join('root_doc.json') root_data = { 'this': ['is', 'useless'], 'some_key': { 'actual': 'stuff', 'things': [1, { '$ref': 'child1_dir/child1_doc.json#/for_root' }, 3] } } root_doc.write(json.dumps(root_data)) child1_doc = root_dir.mkdir('child1_dir').join('child1_doc.json') child1_data = { 'again': 'useless', 'for_root': { 'childish': 'things', 'weird': { '$ref': '../child2_dir/child2_doc.json#/for_child1' } } } child1_doc.write(json.dumps(child1_data)) child2_doc = root_dir.mkdir('child2_dir').join('child2_doc.json') child2_data = { 'still': 'useless', 'for_child1': { 'grand': 'child?', } } child2_doc.write(json.dumps(child2_data)) data = {'some': 'data', 'file': {'$ref': f'{str(root_doc)}#/some_key'}} resolved = resolve(data) assert resolved == { 'some': 'data', 'file': { 'actual': 'stuff', 'things': [1, { 'childish': 'things', 'weird': { 'grand': 'child?' } }, 3] } }
def test_not_dict(tmpdir): root_dir = tmpdir.mkdir('root_dir') root_doc = root_dir.join('root.json') file_data = 'some stuff here' root_doc.write(json.dumps(file_data)) data = {'inline': 'data', 'file_ref': {'$ref': f"{str(root_doc)}"}} resolved = resolve(data) assert resolved == {'inline': 'data', 'file_ref': 'some stuff here'}
def test_basic(tmpdir): root_dir = tmpdir.mkdir('root_dir') root_doc = root_dir.join('root.json') file_data = {'some': 'in_file_data'} root_doc.write(json.dumps(file_data)) data = {'inline': 'data', 'file_ref': {'$ref': f"{str(root_doc)}#/some"}} resolved = resolve(data) assert resolved == {'inline': 'data', 'file_ref': 'in_file_data'}
def test_cwd(tmpdir): root_dir = tmpdir.mkdir('root_dir') root_doc = root_dir.join('root.json') file_data = {'some': 'stuff'} root_doc.write(json.dumps(file_data)) data = {'inline': 'data', 'file_ref': {'$ref': 'root.json#/some'}} resolved = resolve(data, cwd=str(root_dir)) assert resolved == {'inline': 'data', 'file_ref': 'stuff'}
def test_complicated(): data = { 'key_1': 1234, 'key_2': 'abcd', 'key_3': True, 'key_4': [1, True, 'three', { '$ref': '#/key_1' }], 'key_5': { 'key_5_1': 1234, 'key_5_2': { 'key_5_2_1': 'one two three' }, 'key_5_3': [123, { '$ref': '#/key_5/key_5_1' }] }, 'key_6': { 'key_6_1': 4567, 'key_6_2': { 'key_6_2_1': 'four five six' }, 'key_6_3': [456, { '$ref': '#/key_5/key_5_3' }] } } resolved = resolve(data) assert resolved == { 'key_1': 1234, 'key_2': 'abcd', 'key_3': True, 'key_4': [1, True, 'three', 1234], 'key_5': { 'key_5_1': 1234, 'key_5_2': { 'key_5_2_1': 'one two three' }, 'key_5_3': [123, 1234] }, 'key_6': { 'key_6_1': 4567, 'key_6_2': { 'key_6_2_1': 'four five six' }, 'key_6_3': [456, [123, 1234]] } }
def test_nested(): data = { 'some': { '$ref': '#/other' }, 'other': 'stuff', 'some_ref': { '$ref': '#/some' } } resolved = resolve(data) assert resolved == {**data, 'some': 'stuff', 'some_ref': 'stuff'}
def test_object(): data = { 'some': { 'nested': 'data' }, 'other': 'stuff', 'some_ref': { '$ref': '#/some' } } resolved = resolve(data) assert resolved == {**data, 'some_ref': {'nested': 'data'}}
def test_yaml(tmpdir): root_dir = tmpdir.mkdir('root_dir') root_doc = root_dir.join('root.yaml') root_doc.write('''--- hello: yaml thing: '$ref': '#/hello' ''') data = {'inline': 'data', 'file_ref': {'$ref': f"{str(root_doc)}#/thing"}} resolved = resolve(data) assert resolved == {'inline': 'data', 'file_ref': 'yaml'}
def test_bad_internal_ref(): data = {'real': 'stuff', 'bad_ref': {'$ref': '#/does/not/exist'}} with raises(InternalResolutionError): resolve(data)
def test_non_dict(): assert resolve(1234) == 1234
def test_empty(): assert {} == resolve({})
def main(custom_args: list = None): """ The main entry point of the `dref` command line tool. Accepts two positional arguments: input_uri - the input document to be resolved. output_file - the output file for resolved data. If the `output_file` extension is `yaml` or `yml`, the output format will be YAML, otherwise JSON. The program may be used from inside other python programs by calling this function, and passing the arguments as the `custom_args` function argument as a `list`. By default, the `sys.argv` is used. """ args = parse_args(sys.argv[1:] if custom_args is None else custom_args) log_level = VERBOSITY.get(args.verbosity, logging.INFO) out_handler = logging.StreamHandler(sys.stdout) out_handler.setFormatter(DrefLogFormatter(use_color=sys.stdout.isatty())) out_handler.addFilter( DrefLogFilter(logging.WARN, logging.INFO, logging.DEBUG)) err_handler = logging.StreamHandler(sys.stderr) err_handler.setFormatter(DrefLogFormatter(use_color=sys.stderr.isatty())) err_handler.addFilter(DrefLogFilter(logging.ERROR)) log = logging.getLogger('dollar-ref') log.addHandler(out_handler) log.addHandler(err_handler) log.setLevel(log_level) try: data = read_file(args.input_uri) cwd = os.path.dirname(args.input_uri) except FileNotFoundError: log.error(f"Input file '{args.input_uri}' was not found.") sys.exit(1) try: resolved = resolve(data, cwd=cwd, external_only=True) with open(args.output_file, 'w') as out: if args.output_file.endswith(('yml', 'yaml')): raw_out = yaml.dump(resolved, explicit_start=True, default_flow_style=False) else: raw_out = json.dumps(resolved) out.write(raw_out) except FileNotFoundError: log.error(f"Could not write to output file '{args.output_file}'.") sys.exit(1) except ResolutionError as exc: log.error(str(exc)) sys.exit(1) log.info(f"Successfully resolved '{args.input_uri}' " f"into '{args.output_file}'.")
def test_list(): data = {'some': 'data', 'refs': ['item', {'$ref': '#/some'}]} resolved = resolve(data) assert resolved == {'some': 'data', 'refs': ['item', 'data']}
def test_basic(): data = {'some': 'data', 'other': 'stuff', 'some_ref': {'$ref': '#/other'}} resolved = resolve(data) assert resolved == {**data, 'some_ref': 'stuff'}
def bad_ref(): data = {'real': 'stuff', 'bad_ref': {'$ref': '%real$wierd&things'}} with raises(FileResolutionError): resolve(data)