def test_merge_by_id_simple_ref(self): schema = { "mergeStrategy": "arrayMergeById", "mergeOptions": {"idRef": "key"} } a = [ {"key": "A", "field": 1}, ] b = [ {"key": "A", "field": 2}, ] expected = [ {"key": "A", "field": 2}, ] merger = jsonmerge.Merger(schema) base = None base = merger.merge(base, a) base = merger.merge(base, b) self.assertEqual(base, expected)
def test_version_meta(self): schema = {'type': 'object', 'mergeStrategy': 'version'} meta = { 'properties': { 'date': {}, 'version': {} } } merger = jsonmerge.Merger(schema) schema2 = merger.get_schema(meta) self.assertEqual(schema2, { 'type': 'array', 'items': { 'properties': { 'value': {'type': 'object'}, 'date': {}, 'version': {} } } })
def test_dont_resolve_refs(self): schema = { 'id': 'http://example.com/schema_1.json', 'mergeStrategy': 'overwrite', 'properties': { 'foo': { '$ref': '#/definitions/bar' } }, 'definitions': { 'bar': { 'properties': { 'baz': {} } } } } mschema_correct = dict(schema) del mschema_correct['mergeStrategy'] merger = jsonmerge.Merger(schema) mschema = merger.get_schema() self.assertEqual(mschema_correct, mschema)
def __init__(self, db_path, max_size, schemafile): self.db_path = db_path self.logger = logging.getLogger('root') self._sem = gevent.lock.BoundedSemaphore() self.lmdb = lmdb.open( db_path, map_size=max_size, subdir=False, max_dbs=5, writemap=True, # metasync=False, # sync=False, map_async=True, max_readers=16, max_spare_txns=10) self.index_name = 'index'.encode('utf-8') self.deltas_name = 'deltas'.encode('utf-8') self.mtimes_name = 'mtimes'.encode('utf-8') with self._sem: with self.lmdb.begin(write=True) as txn: self.lmdb.open_db(key=self.index_name, txn=txn, dupsort=True) self.lmdb.open_db(key=self.mtimes_name, txn=txn) self.lmdb.open_db(key=self.deltas_name, txn=txn) self.delta_idx = self.get_delta_idx() self.merger = jsonmerge.Merger(json.load(schemafile))
def test_version(self): schema = {'mergeStrategy': 'version'} merger = jsonmerge.Merger(schema) schema2 = merger.get_schema() self.assertEqual(schema2, {'items': {'properties': {'value': {}}}})
def test_append(self): schema = {'type': 'array', 'mergeStrategy': 'append'} merger = jsonmerge.Merger(schema) schema2 = merger.get_schema() self.assertEqual(schema2, {'type': 'array'})
def test_array_in_schema(self): schema_1 = { 'id': 'http://example.com/schema_1.json', '$ref': 'schema_2.json#/definitions/foo' } schema_2 = { 'id': 'http://example.com/schema_2.json', 'definitions': { 'foo': { 'mergeStrategy': 'overwrite', 'enum': [ "foo", "bar", ] }, } } merger = jsonmerge.Merger(schema_1) merger.cache_schema(schema_2) mschema = merger.get_schema() d = { 'enum': [ "foo", "bar", ] } self.assertEqual(d, mschema)
def test_merge_by_id_compex_ref(self): schema = { "mergeStrategy": "arrayMergeById", "mergeOptions": {"idRef": "/foo/bar"}, } a = [ {'foo': {'bar': 1}, 'baz': 1} ] b = [ {'foo': {'bar': 2}} ] c = [ {'foo': {'bar': 1}, 'baz': 2} ] # by default, it should fall back to "replace" strategy for integers. expected = [ {'foo': {'bar': 1}, 'baz': 2}, {'foo': {'bar': 2}} ] merger = jsonmerge.Merger(schema) base = None base = merger.merge(base, a) base = merger.merge(base, b) base = merger.merge(base, c) self.assertEqual(base, expected)
def patch(self, path, data=None, headers=None, **kwargs): """ Sends a PATCH request to host/path. :param path: String, resource path on server :param data: Data as a dictionary, bytes, or file-like object to send in the body of the request. :param headers: Dictionary of HTTP headers to be sent with the request, overwrites default headers if there is overlap :param kwargs: Other arguments used in the requests.request call valid parameters in kwargs are the optional parameters of Requests.Request http://docs.python-requests.org/en/master/api/ :return: requests.Response :raises: RequestException """ if headers is not None: merger = jsonmerge.Merger(schema) kwargs["headers"] = merger.merge(self.defaultHeaders, headers) else: kwargs["headers"] = self.defaultHeaders url = combine_urls(self.host, path) if self.cert is not None: kwargs["cert"] = self.cert self.logger.debug("Trying to send HTTP PATCH to {}".format(url)) try: resp = requests.patch(url, data=data, **kwargs) self._log_response(resp) except RequestException as es: self._log_exception(es) raise return resp
def test_resolve_refs(self): schema_1 = { 'id': 'http://example.com/schema_1.json', '$ref': 'schema_2.json#/definitions/foo' } schema_2 = { 'id': 'http://example.com/schema_2.json', 'definitions': { 'foo': { 'mergeStrategy': 'overwrite', 'properties': { 'bar': { '$ref': '#/definitions/baz' }, 'b': {} }, }, 'baz': { 'mergeStrategy': 'append' } } } merger = jsonmerge.Merger(schema_1) merger.cache_schema(schema_2) mschema = merger.get_schema() d = {'bar': []} jsonschema.validate(d, mschema)
def test_default_object_merge(self): schema = { 'properties': { 'foo': { 'mergeStrategy': 'version', } } } merger = jsonmerge.Merger(schema) schema2 = merger.get_schema() self.assertEqual(schema2, { 'properties': { 'foo': { 'type': 'array', 'items': { 'properties': { 'value': {}, } } } } })
def test_overwrite(self): schema = {'mergeStrategy': 'overwrite'} merger = jsonmerge.Merger(schema) schema2 = merger.get_schema() self.assertEqual(schema2, {})
def test_default_overwrite(self): schema = {'description': 'test'} merger = jsonmerge.Merger(schema) schema2 = merger.get_schema() self.assertEqual(schema2, {'description': 'test'})
def test_default_object_merge_trivial(self): schema = {'type': 'object'} merger = jsonmerge.Merger(schema) schema2 = merger.get_schema() self.assertEqual(schema2, {'type': 'object'})
def test_merge_def(self): strat = mrg.TopicArray() schema = {'mergeStrategy': 'topicArray'} merger = jsonmerge.Merger(schema, {'topicArray': strat}, 'OrderedDict') base = [ { "@id": "goob", "tag": "physics" }, { "@id": "gurn", "scheme": "hsr", "tag": "physics" }, { "scheme": "hsr", "tag": "biology" } ] head = [ { "@id": "goob", "tag": "Physics" }, { "scheme": "hsr", "tag": "physics", "lab": "MML" }, { "scheme": "hsr", "tag": "biology" } ] mrgd = merger.merge(base, head) self.assertIsInstance(mrgd, list) self.assertEqual(mrgd, [ { "@id": "goob", "tag": "Physics" }, { "@id": "gurn", "scheme": "hsr", "tag": "physics", "lab": "MML" }, { "scheme": "hsr", "tag": "biology" } ])
def delete(self, path, headers=None, **kwargs): """ Sends a DELETE request to host/path. :param path: String, resource path on server :param headers: Dictionary of HTTP headers to be sent with the request, overwrites default headers if there is overlap :param kwargs: Other arguments used in the requests.request call valid parameters in kwargs are the optional parameters of Requests.Request http://docs.python-requests.org/en/master/api/ :return: requests.Response :raises: RequestException """ if headers is not None: merger = jsonmerge.Merger(SCHEMA) kwargs["headers"] = merger.merge(self.defaultHeaders, headers) else: kwargs["headers"] = self.defaultHeaders url = combine_urls(self.host, path) if self.cert is not None: kwargs["cert"] = self.cert self.logger.debug("Trying to send HTTP DELETE to {}".format(url)) try: resp = requests.delete(url, **kwargs) self._log_response(resp) except requests.RequestException as es: self._log_exception(es) raise return resp
def test_refs(self): schema = { 'properties': { 'a': { '$ref': "#/definitions/a" }, }, 'definitions': { "a": { "properties": { "b": { 'mergeStrategy': 'version' }, } }, } } merger = jsonmerge.Merger(schema) base = None base = merger.merge(base, {"a": {"b": "c"}}) base = merger.merge(base, {"a": {"b": "d"}}) self.assertEqual(base, {"a": {"b": [{"value": "c"}, {"value": "d"}]}})
def test_object_merge_simple(self): schema = {'mergeStrategy': 'objectMerge'} merger = jsonmerge.Merger(schema) schema2 = merger.get_schema() self.assertEqual(schema2, {})
def test_merge_by_id_no_items(self): schema = { "mergeStrategy": "arrayMergeById", "mergeOptions": {"idRef": "id"}, } a = [ {"id": "A", "field": 1}, ] b = [ {"id": "A", "field": 2}, ] # by default, it should fall back to "replace" strategy for integers. expected = [ {"id": "A", "field": 2}, ] merger = jsonmerge.Merger(schema) base = None base = merger.merge(base, a) base = merger.merge(base, b) self.assertEqual(base, expected)
def get_versioned_validation_schema(versioned_release): merger = jsonmerge.Merger(versioned_release) versioned_validation_schema = merger.get_schema() versioned_validation_schema["id"] = "http://ocds.open-contracting.org/standard/r/1__0__RC/versioned-release-validation-schema.json" # nopep8 versioned_validation_schema["$schema"] = "http://json-schema.org/draft-04/schema#" # nopep8 versioned_validation_schema["title"] = "Schema for a compiled, versioned Open Contracting Release." # nopep8 return versioned_validation_schema
def test_merge_by_id_with_depth(self): schema = { "properties": { "test": { "mergeStrategy": "arrayMergeById", "type": "array", "items": { "$ref": "#/definitions/refitem" } } }, "definitions": { "refitem": { "type": "object", "properties": { "field1": { "type": "string", "mergeStrategy": "version" } } } } } expected = { "properties": { "test": { "type": "array", "items": { "$ref": "#/definitions/refitem" } } }, "definitions": { "refitem": { "type": "object", "properties": { "field1": { "type": "array", "items": { "properties": { "value": { "type": "string" } } } } } } } } merger = jsonmerge.Merger(schema) schema2 = merger.get_schema() self.assertEqual(schema2, expected)
def test_merge_by_id_bad_base_type(self): schema = { 'mergeStrategy': 'arrayMergeById' } head = [] base = {'foo': 'bar'} merger = jsonmerge.Merger(schema) self.assertRaises(BaseInstanceError, merger.merge, base, head)
def from_schema(cls, data, schema, src_ref=None): """populate instance from schema defaults (or None)""" if schema: defaults = schema.schema_defaults(schema) # Note that here we take advantage of jsonmerge's schema annotations to drive the merge behavior. merger = jsonmerge.Merger(schema) defaults = merger.merge(defaults, dict(data)) else: defaults = data return cls(defaults, schema, src_ref)
def test_version_ignoredups_true(self): schema = {'mergeStrategy': 'version'} merger = jsonmerge.Merger(schema) base = None base = merger.merge(base, "a") base = merger.merge(base, "a") self.assertEqual(base, [{'value': "a"}])
def test_merge_by_id_with_complex_array(self): schema = { "properties": { "awards": { "type": "array", "mergeStrategy": "arrayMergeById", "items": { "properties": { "id": {"type": "string"}, "field": { "type": "array", "items": { "properties": { "xx": { "type": "string" } } } } } } } } } a = { "awards": [ {"id": "A", "field": [{"xx": "testA1"}, {"xx": "testA2"}]}, {"id": "B", "field": [{"xx": "testA3"}, {"xx": "testA4"}]} ] } b = { "awards": [ {"id": "B", "field": [{"xx": "testA3"}, {"xx": "testA6"}]}, {"id": "C", "field": [{"xx": "testA7"}, {"xx": "testA8"}]} ] } expected = { "awards": [ {"id": "A", "field": [{"xx": "testA1"}, {"xx": "testA2"}]}, {"id": "B", "field": [{"xx": "testA3"}, {"xx": "testA6"}]}, {"id": "C", "field": [{"xx": "testA7"}, {"xx": "testA8"}]} ] } merger = jsonmerge.Merger(schema) base = None base = merger.merge(base, a) base = merger.merge(base, b) self.assertEqual(base, expected)
def test_merge_by_id_no_base_id(self): schema = { 'mergeStrategy': 'arrayMergeById' } head = [ {'id': 'a'} ] base = [ {} ] merger = jsonmerge.Merger(schema) r = merger.merge(base, head) self.assertEqual(r, [ {}, {'id': 'a'} ])
def test_merge(self): strat = mrg.UniqueArray() schema = {'mergeStrategy': 'uniqueArray'} merger = jsonmerge.Merger(schema, {'uniqueArray': strat}, 'OrderedDict') base = [ "a", "e", "i" ] head = [ "b", "i", "z", "a" ] mrgd = merger.merge(base, head) self.assertIsInstance(mrgd, list) self.assertEqual(mrgd, [ "a", "e", "i", "b", "z" ])
def get_versioned_validation_schema(versioned_release): merger = jsonmerge.Merger(versioned_release) versioned_validation_schema = merger.get_schema() versioned_validation_schema[ "id"] = "https://raw.githubusercontent.com/open-contracting/standard/master/standard/schema/versioned-release-validation-schema.json" # nopep8 versioned_validation_schema[ "$schema"] = "http://json-schema.org/draft-04/schema#" # nopep8 versioned_validation_schema[ "title"] = "Schema for a compiled, versioned Open Contracting Release." # nopep8 return versioned_validation_schema
def test_version_unique_false(self): schema = {'mergeStrategy': 'version', 'mergeOptions': {'unique': False}} merger = jsonmerge.Merger(schema) base = None base = merger.merge(base, "a") base = merger.merge(base, "a") self.assertEqual(base, [{'value': "a"}, {'value': "a"}])
def test_oneof(self): schema = { 'mergeStrategy': 'objectMerge', 'oneOf': [ {'properties': {'a': {}}}, {'properties': {'b': {}}} ] } merger = jsonmerge.Merger(schema) self.assertRaises(SchemaError, merger.get_schema)