From ab775d187539c85cb7214905ad295358b240af14 Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Fri, 13 Nov 2020 00:21:07 +0300 Subject: feat: add custom json pointer support --- jsonpatch.py | 76 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/jsonpatch.py b/jsonpatch.py index 7d5489a..c893bea 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -106,7 +106,7 @@ def multidict(ordered_pairs): _jsonloads = functools.partial(json.loads, object_pairs_hook=multidict) -def apply_patch(doc, patch, in_place=False): +def apply_patch(doc, patch, in_place=False, pointer_cls=JsonPointer): """Apply list of patches to specified json document. :param doc: Document object. @@ -137,13 +137,13 @@ def apply_patch(doc, patch, in_place=False): """ if isinstance(patch, basestring): - patch = JsonPatch.from_string(patch) + patch = JsonPatch.from_string(patch, pointer_cls=pointer_cls) else: - patch = JsonPatch(patch) + patch = JsonPatch(patch, pointer_cls=pointer_cls) return patch.apply(doc, in_place) -def make_patch(src, dst): +def make_patch(src, dst, pointer_cls=JsonPointer): """Generates patch by comparing two document objects. Actually is a proxy to :meth:`JsonPatch.from_diff` method. @@ -153,6 +153,9 @@ def make_patch(src, dst): :param dst: Data source document object. :type dst: dict + :param pointer_cls: JSON pointer (sub)class. + :type pointer_cls: Type[JsonPointer] + >>> src = {'foo': 'bar', 'numbers': [1, 3, 4, 8]} >>> dst = {'baz': 'qux', 'numbers': [1, 4, 7]} >>> patch = make_patch(src, dst) @@ -161,7 +164,7 @@ def make_patch(src, dst): True """ - return JsonPatch.from_diff(src, dst) + return JsonPatch.from_diff(src, dst, pointer_cls=pointer_cls) class JsonPatch(object): @@ -210,8 +213,9 @@ class JsonPatch(object): ... patch.apply(old) #doctest: +ELLIPSIS {...} """ - def __init__(self, patch): + def __init__(self, patch, pointer_cls=JsonPointer): self.patch = patch + self.pointer_cls = pointer_cls self.operations = { 'remove': RemoveOperation, @@ -246,19 +250,22 @@ class JsonPatch(object): return not(self == other) @classmethod - def from_string(cls, patch_str): + def from_string(cls, patch_str, pointer_cls=JsonPointer): """Creates JsonPatch instance from string source. :param patch_str: JSON patch as raw string. - :type patch_str: str + :type pointer_cls: str + + :param pointer_cls: JSON pointer (sub)class. + :type pointer_cls: Type[JsonPointer] :return: :class:`JsonPatch` instance. """ patch = _jsonloads(patch_str) - return cls(patch) + return cls(patch, pointer_cls=pointer_cls) @classmethod - def from_diff(cls, src, dst, optimization=True): + def from_diff(cls, src, dst, optimization=True, pointer_cls=JsonPointer): """Creates JsonPatch instance based on comparison of two document objects. Json patch would be created for `src` argument against `dst` one. @@ -269,6 +276,9 @@ class JsonPatch(object): :param dst: Data source document object. :type dst: dict + :param pointer_cls: JSON pointer (sub)class. + :type pointer_cls: Type[JsonPointer] + :return: :class:`JsonPatch` instance. >>> src = {'foo': 'bar', 'numbers': [1, 3, 4, 8]} @@ -279,10 +289,10 @@ class JsonPatch(object): True """ - builder = DiffBuilder() + builder = DiffBuilder(pointer_cls=pointer_cls) builder._compare_values('', None, src, dst) ops = list(builder.execute()) - return cls(ops) + return cls(ops, pointer_cls=pointer_cls) def to_string(self): """Returns patch set as JSON string.""" @@ -326,24 +336,25 @@ class JsonPatch(object): raise InvalidJsonPatch("Unknown operation {0!r}".format(op)) cls = self.operations[op] - return cls(operation) + return cls(operation, pointer_cls=self.pointer_cls) class PatchOperation(object): """A single operation inside a JSON Patch.""" - def __init__(self, operation): + def __init__(self, operation, pointer_cls=JsonPointer): + self.pointer_cls = pointer_cls if not operation.__contains__('path'): raise InvalidJsonPatch("Operation must have a 'path' member") - if isinstance(operation['path'], JsonPointer): + if isinstance(operation['path'], self.pointer_cls): self.location = operation['path'].path self.pointer = operation['path'] else: self.location = operation['path'] try: - self.pointer = JsonPointer(self.location) + self.pointer = self.pointer_cls(self.location) except TypeError as ex: raise InvalidJsonPatch("Invalid 'path'") @@ -511,10 +522,10 @@ class MoveOperation(PatchOperation): def apply(self, obj): try: - if isinstance(self.operation['from'], JsonPointer): + if isinstance(self.operation['from'], self.pointer_cls): from_ptr = self.operation['from'] else: - from_ptr = JsonPointer(self.operation['from']) + from_ptr = self.pointer_cls(self.operation['from']) except KeyError as ex: raise InvalidJsonPatch( "The operation does not contain a 'from' member") @@ -536,24 +547,24 @@ class MoveOperation(PatchOperation): obj = RemoveOperation({ 'op': 'remove', 'path': self.operation['from'] - }).apply(obj) + }, pointer_cls=self.pointer_cls).apply(obj) obj = AddOperation({ 'op': 'add', 'path': self.location, 'value': value - }).apply(obj) + }, pointer_cls=self.pointer_cls).apply(obj) return obj @property def from_path(self): - from_ptr = JsonPointer(self.operation['from']) + from_ptr = self.pointer_cls(self.operation['from']) return '/'.join(from_ptr.parts[:-1]) @property def from_key(self): - from_ptr = JsonPointer(self.operation['from']) + from_ptr = self.pointer_cls(self.operation['from']) try: return int(from_ptr.parts[-1]) except TypeError: @@ -561,7 +572,7 @@ class MoveOperation(PatchOperation): @from_key.setter def from_key(self, value): - from_ptr = JsonPointer(self.operation['from']) + from_ptr = self.pointer_cls(self.operation['from']) from_ptr.parts[-1] = str(value) self.operation['from'] = from_ptr.path @@ -624,7 +635,7 @@ class CopyOperation(PatchOperation): def apply(self, obj): try: - from_ptr = JsonPointer(self.operation['from']) + from_ptr = self.pointer_cls(self.operation['from']) except KeyError as ex: raise InvalidJsonPatch( "The operation does not contain a 'from' member") @@ -639,14 +650,15 @@ class CopyOperation(PatchOperation): 'op': 'add', 'path': self.location, 'value': value - }).apply(obj) + }, pointer_cls=self.pointer_cls).apply(obj) return obj class DiffBuilder(object): - def __init__(self): + def __init__(self, pointer_cls=JsonPointer): + self.pointer_cls = pointer_cls self.index_storage = [{}, {}] self.index_storage2 = [[], []] self.__root = root = [] @@ -715,7 +727,7 @@ class DiffBuilder(object): 'op': 'replace', 'path': op_second.location, 'value': op_second.operation['value'], - }).operation + }, pointer_cls=self.pointer_cls).operation curr = curr[1][1] continue @@ -736,14 +748,14 @@ class DiffBuilder(object): 'op': 'move', 'from': op.location, 'path': _path_join(path, key), - }) + }, pointer_cls=self.pointer_cls) self.insert(new_op) else: new_op = AddOperation({ 'op': 'add', 'path': _path_join(path, key), 'value': item, - }) + }, pointer_cls=self.pointer_cls) new_index = self.insert(new_op) self.store_index(item, new_index, _ST_ADD) @@ -751,7 +763,7 @@ class DiffBuilder(object): new_op = RemoveOperation({ 'op': 'remove', 'path': _path_join(path, key), - }) + }, pointer_cls=self.pointer_cls) index = self.take_index(item, _ST_ADD) new_index = self.insert(new_op) if index is not None: @@ -766,7 +778,7 @@ class DiffBuilder(object): 'op': 'move', 'from': new_op.location, 'path': op.location, - }) + }, pointer_cls=self.pointer_cls) new_index[2] = new_op else: @@ -780,7 +792,7 @@ class DiffBuilder(object): 'op': 'replace', 'path': _path_join(path, key), 'value': item, - })) + }, pointer_cls=self.pointer_cls)) def _compare_dicts(self, path, src, dst): src_keys = set(src.keys()) -- cgit v1.2.1 From bb4ea7ba669b26d29f31ec75015d92fb6633f07b Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Fri, 13 Nov 2020 00:21:16 +0300 Subject: test: custo json pointer --- tests.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests.py b/tests.py index 0abf4d2..0402a03 100755 --- a/tests.py +++ b/tests.py @@ -671,6 +671,59 @@ class JsonPointerTests(unittest.TestCase): self.assertEqual(result, expected) +class CustomJsonPointerTests(unittest.TestCase): + + class CustomJsonPointer(jsonpointer.JsonPointer): + pass + + def test_apply_patch_from_string(self): + obj = {'foo': 'bar'} + patch = '[{"op": "add", "path": "/baz", "value": "qux"}]' + res = jsonpatch.apply_patch( + obj, patch, + pointer_cls=self.CustomJsonPointer, + ) + self.assertTrue(obj is not res) + self.assertTrue('baz' in res) + self.assertEqual(res['baz'], 'qux') + + def test_apply_patch_from_object(self): + obj = {'foo': 'bar'} + res = jsonpatch.apply_patch( + obj, [{'op': 'add', 'path': '/baz', 'value': 'qux'}], + pointer_cls=self.CustomJsonPointer, + ) + self.assertTrue(obj is not res) + + def test_make_patch(self): + src = {'foo': 'bar', 'boo': 'qux'} + dst = {'baz': 'qux', 'foo': 'boo'} + patch = jsonpatch.make_patch( + src, dst, pointer_cls=self.CustomJsonPointer, + ) + res = patch.apply(src) + self.assertTrue(src is not res) + self.assertEqual(patch.pointer_cls, self.CustomJsonPointer) + self.assertTrue(patch._ops) + for op in patch._ops: + self.assertEqual(op.pointer_cls, self.CustomJsonPointer) + + def test_operations(self): + patch = jsonpatch.JsonPatch([ + {'op': 'add', 'path': '/foo', 'value': [1, 2, 3]}, + {'op': 'move', 'path': '/baz', 'from': '/foo'}, + {'op': 'add', 'path': '/baz', 'value': [1, 2, 3]}, + {'op': 'remove', 'path': '/baz/1'}, + {'op': 'test', 'path': '/baz', 'value': [1, 3]}, + {'op': 'replace', 'path': '/baz/0', 'value': 42}, + {'op': 'remove', 'path': '/baz/1'}, + ], pointer_cls=self.CustomJsonPointer) + self.assertEqual(patch.apply({}), {'baz': [42]}) + self.assertEqual(patch.pointer_cls, self.CustomJsonPointer) + self.assertTrue(patch._ops) + for op in patch._ops: + self.assertEqual(op.pointer_cls, self.CustomJsonPointer) + if __name__ == '__main__': modules = ['jsonpatch'] @@ -687,6 +740,7 @@ if __name__ == '__main__': suite.addTest(unittest.makeSuite(ConflictTests)) suite.addTest(unittest.makeSuite(OptimizationTests)) suite.addTest(unittest.makeSuite(JsonPointerTests)) + suite.addTest(unittest.makeSuite(CustomJsonPointerTests)) return suite -- cgit v1.2.1 From 124eb76c09136aef56618e7347230f981edd51c3 Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Fri, 13 Nov 2020 00:27:30 +0300 Subject: doc: fix docstrings --- jsonpatch.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/jsonpatch.py b/jsonpatch.py index c893bea..92857ef 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -119,6 +119,9 @@ def apply_patch(doc, patch, in_place=False, pointer_cls=JsonPointer): By default patch will be applied to document copy. :type in_place: bool + :param pointer_cls: JSON pointer class to use. + :type pointer_cls: Type[JsonPointer] + :return: Patched document object. :rtype: dict @@ -153,7 +156,7 @@ def make_patch(src, dst, pointer_cls=JsonPointer): :param dst: Data source document object. :type dst: dict - :param pointer_cls: JSON pointer (sub)class. + :param pointer_cls: JSON pointer class to use. :type pointer_cls: Type[JsonPointer] >>> src = {'foo': 'bar', 'numbers': [1, 3, 4, 8]} @@ -256,7 +259,7 @@ class JsonPatch(object): :param patch_str: JSON patch as raw string. :type pointer_cls: str - :param pointer_cls: JSON pointer (sub)class. + :param pointer_cls: JSON pointer class to use. :type pointer_cls: Type[JsonPointer] :return: :class:`JsonPatch` instance. @@ -276,7 +279,7 @@ class JsonPatch(object): :param dst: Data source document object. :type dst: dict - :param pointer_cls: JSON pointer (sub)class. + :param pointer_cls: JSON pointer class to use. :type pointer_cls: Type[JsonPointer] :return: :class:`JsonPatch` instance. -- cgit v1.2.1 From fb04fcc4df0e060586f6401b61af703d60bb6b65 Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Sun, 15 Nov 2020 17:27:33 +0300 Subject: test: add more tests --- tests.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests.py b/tests.py index 0402a03..ec4758d 100755 --- a/tests.py +++ b/tests.py @@ -676,6 +676,28 @@ class CustomJsonPointerTests(unittest.TestCase): class CustomJsonPointer(jsonpointer.JsonPointer): pass + def test_json_patch_from_string(self): + patch = '[{"op": "add", "path": "/baz", "value": "qux"}]' + res = jsonpatch.JsonPatch.from_string( + patch, pointer_cls=self.CustomJsonPointer, + ) + self.assertEqual(res.pointer_cls, self.CustomJsonPointer) + + def test_json_patch_from_object(self): + patch = [{'op': 'add', 'path': '/baz', 'value': 'qux'}], + res = jsonpatch.JsonPatch( + patch, pointer_cls=self.CustomJsonPointer, + ) + self.assertEqual(res.pointer_cls, self.CustomJsonPointer) + + def test_json_patch_from_diff(self): + old = {'foo': 'bar'} + new = {'foo': 'baz'} + res = jsonpatch.JsonPatch.from_diff( + old, new, pointer_cls=self.CustomJsonPointer, + ) + self.assertEqual(res.pointer_cls, self.CustomJsonPointer) + def test_apply_patch_from_string(self): obj = {'foo': 'bar'} patch = '[{"op": "add", "path": "/baz", "value": "qux"}]' -- cgit v1.2.1 From 0b680ea87afc6e747fc584aaef513815de0c52c3 Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Mon, 16 Nov 2020 10:53:52 +0300 Subject: chore: bump version --- jsonpatch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonpatch.py b/jsonpatch.py index 92857ef..201e9d1 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -56,7 +56,7 @@ except ImportError: # Will be parsed by setup.py to determine package metadata __author__ = 'Stefan Kögl ' -__version__ = '1.24' +__version__ = '1.27' __website__ = 'https://github.com/stefankoegl/python-json-patch' __license__ = 'Modified BSD License' -- cgit v1.2.1 From c37b40ffec5674bf76bbb2197917e528e74b4552 Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Mon, 16 Nov 2020 16:05:00 +0300 Subject: test: update --- tests.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests.py b/tests.py index ec4758d..941c685 100755 --- a/tests.py +++ b/tests.py @@ -728,6 +728,7 @@ class CustomJsonPointerTests(unittest.TestCase): self.assertEqual(patch.pointer_cls, self.CustomJsonPointer) self.assertTrue(patch._ops) for op in patch._ops: + self.assertIsInstance(op.pointer, self.CustomJsonPointer) self.assertEqual(op.pointer_cls, self.CustomJsonPointer) def test_operations(self): @@ -744,6 +745,7 @@ class CustomJsonPointerTests(unittest.TestCase): self.assertEqual(patch.pointer_cls, self.CustomJsonPointer) self.assertTrue(patch._ops) for op in patch._ops: + self.assertIsInstance(op.pointer, self.CustomJsonPointer) self.assertEqual(op.pointer_cls, self.CustomJsonPointer) -- cgit v1.2.1 From 0994bfe2ce199d6edccb4ab97fc10e3c26683348 Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Tue, 17 Nov 2020 11:02:15 +0300 Subject: test: add toy jsonpointer example --- tests.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests.py b/tests.py index 941c685..25c9e4f 100755 --- a/tests.py +++ b/tests.py @@ -748,6 +748,17 @@ class CustomJsonPointerTests(unittest.TestCase): self.assertIsInstance(op.pointer, self.CustomJsonPointer) self.assertEqual(op.pointer_cls, self.CustomJsonPointer) + class PrefixJsonPointer(jsonpointer.JsonPointer): + def __init__(self, pointer): + super().__init__('/foo/bar' + pointer) + + def test_json_patch_wtih_prefix_pointer(self): + res = jsonpatch.apply_patch( + {'foo': {'bar': {}}}, [{'op': 'add', 'path': '/baz', 'value': 'qux'}], + pointer_cls=self.PrefixJsonPointer, + ) + self.assertEqual(res, {'foo': {'bar': {'baz': 'qux'}}}) + if __name__ == '__main__': modules = ['jsonpatch'] -- cgit v1.2.1 From d24fa96a7ad1f01cb793c0efe835a76ddd3b2fc7 Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Tue, 17 Nov 2020 11:28:45 +0300 Subject: test: fix for py27 --- tests.py | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/tests.py b/tests.py index 25c9e4f..2dfc18c 100755 --- a/tests.py +++ b/tests.py @@ -671,39 +671,45 @@ class JsonPointerTests(unittest.TestCase): self.assertEqual(result, expected) -class CustomJsonPointerTests(unittest.TestCase): +class CustomJsonPointer(jsonpointer.JsonPointer): + pass + + +class PrefixJsonPointer(jsonpointer.JsonPointer): + def __init__(self, pointer): + super(PrefixJsonPointer, self).__init__('/foo/bar' + pointer) - class CustomJsonPointer(jsonpointer.JsonPointer): - pass + +class CustomJsonPointerTests(unittest.TestCase): def test_json_patch_from_string(self): patch = '[{"op": "add", "path": "/baz", "value": "qux"}]' res = jsonpatch.JsonPatch.from_string( - patch, pointer_cls=self.CustomJsonPointer, + patch, pointer_cls=CustomJsonPointer, ) - self.assertEqual(res.pointer_cls, self.CustomJsonPointer) + self.assertEqual(res.pointer_cls, CustomJsonPointer) def test_json_patch_from_object(self): patch = [{'op': 'add', 'path': '/baz', 'value': 'qux'}], res = jsonpatch.JsonPatch( - patch, pointer_cls=self.CustomJsonPointer, + patch, pointer_cls=CustomJsonPointer, ) - self.assertEqual(res.pointer_cls, self.CustomJsonPointer) + self.assertEqual(res.pointer_cls, CustomJsonPointer) def test_json_patch_from_diff(self): old = {'foo': 'bar'} new = {'foo': 'baz'} res = jsonpatch.JsonPatch.from_diff( - old, new, pointer_cls=self.CustomJsonPointer, + old, new, pointer_cls=CustomJsonPointer, ) - self.assertEqual(res.pointer_cls, self.CustomJsonPointer) + self.assertEqual(res.pointer_cls, CustomJsonPointer) def test_apply_patch_from_string(self): obj = {'foo': 'bar'} patch = '[{"op": "add", "path": "/baz", "value": "qux"}]' res = jsonpatch.apply_patch( obj, patch, - pointer_cls=self.CustomJsonPointer, + pointer_cls=CustomJsonPointer, ) self.assertTrue(obj is not res) self.assertTrue('baz' in res) @@ -713,7 +719,7 @@ class CustomJsonPointerTests(unittest.TestCase): obj = {'foo': 'bar'} res = jsonpatch.apply_patch( obj, [{'op': 'add', 'path': '/baz', 'value': 'qux'}], - pointer_cls=self.CustomJsonPointer, + pointer_cls=CustomJsonPointer, ) self.assertTrue(obj is not res) @@ -721,15 +727,15 @@ class CustomJsonPointerTests(unittest.TestCase): src = {'foo': 'bar', 'boo': 'qux'} dst = {'baz': 'qux', 'foo': 'boo'} patch = jsonpatch.make_patch( - src, dst, pointer_cls=self.CustomJsonPointer, + src, dst, pointer_cls=CustomJsonPointer, ) res = patch.apply(src) self.assertTrue(src is not res) - self.assertEqual(patch.pointer_cls, self.CustomJsonPointer) + self.assertEqual(patch.pointer_cls, CustomJsonPointer) self.assertTrue(patch._ops) for op in patch._ops: - self.assertIsInstance(op.pointer, self.CustomJsonPointer) - self.assertEqual(op.pointer_cls, self.CustomJsonPointer) + self.assertIsInstance(op.pointer, CustomJsonPointer) + self.assertEqual(op.pointer_cls, CustomJsonPointer) def test_operations(self): patch = jsonpatch.JsonPatch([ @@ -740,22 +746,18 @@ class CustomJsonPointerTests(unittest.TestCase): {'op': 'test', 'path': '/baz', 'value': [1, 3]}, {'op': 'replace', 'path': '/baz/0', 'value': 42}, {'op': 'remove', 'path': '/baz/1'}, - ], pointer_cls=self.CustomJsonPointer) + ], pointer_cls=CustomJsonPointer) self.assertEqual(patch.apply({}), {'baz': [42]}) - self.assertEqual(patch.pointer_cls, self.CustomJsonPointer) + self.assertEqual(patch.pointer_cls, CustomJsonPointer) self.assertTrue(patch._ops) for op in patch._ops: - self.assertIsInstance(op.pointer, self.CustomJsonPointer) - self.assertEqual(op.pointer_cls, self.CustomJsonPointer) - - class PrefixJsonPointer(jsonpointer.JsonPointer): - def __init__(self, pointer): - super().__init__('/foo/bar' + pointer) + self.assertIsInstance(op.pointer, CustomJsonPointer) + self.assertEqual(op.pointer_cls, CustomJsonPointer) def test_json_patch_wtih_prefix_pointer(self): res = jsonpatch.apply_patch( {'foo': {'bar': {}}}, [{'op': 'add', 'path': '/baz', 'value': 'qux'}], - pointer_cls=self.PrefixJsonPointer, + pointer_cls=PrefixJsonPointer, ) self.assertEqual(res, {'foo': {'bar': {'baz': 'qux'}}}) -- cgit v1.2.1 From 4d073929b732af3403ae9fac92433e0066f0061a Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Tue, 17 Nov 2020 11:29:23 +0300 Subject: style: fix typo --- tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests.py b/tests.py index 2dfc18c..c676121 100755 --- a/tests.py +++ b/tests.py @@ -754,7 +754,7 @@ class CustomJsonPointerTests(unittest.TestCase): self.assertIsInstance(op.pointer, CustomJsonPointer) self.assertEqual(op.pointer_cls, CustomJsonPointer) - def test_json_patch_wtih_prefix_pointer(self): + def test_json_patch_with_prefix_pointer(self): res = jsonpatch.apply_patch( {'foo': {'bar': {}}}, [{'op': 'add', 'path': '/baz', 'value': 'qux'}], pointer_cls=PrefixJsonPointer, -- cgit v1.2.1 From c9613e303531ce4a016b3a696992743e62e12258 Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Tue, 17 Nov 2020 11:52:33 +0300 Subject: chore: revert version bump --- jsonpatch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonpatch.py b/jsonpatch.py index 201e9d1..92857ef 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -56,7 +56,7 @@ except ImportError: # Will be parsed by setup.py to determine package metadata __author__ = 'Stefan Kögl ' -__version__ = '1.27' +__version__ = '1.24' __website__ = 'https://github.com/stefankoegl/python-json-patch' __license__ = 'Modified BSD License' -- cgit v1.2.1 From 50fb942e3500d84950ec9309f886f1952bd2fa25 Mon Sep 17 00:00:00 2001 From: Artyom Nikitin Date: Tue, 17 Nov 2020 20:54:36 +0300 Subject: tests: moar --- tests.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests.py b/tests.py index c676121..7df2c2b 100755 --- a/tests.py +++ b/tests.py @@ -738,6 +738,44 @@ class CustomJsonPointerTests(unittest.TestCase): self.assertEqual(op.pointer_cls, CustomJsonPointer) def test_operations(self): + operations =[ + ( + jsonpatch.AddOperation, { + 'op': 'add', 'path': '/foo', 'value': [1, 2, 3] + } + ), + ( + jsonpatch.MoveOperation, { + 'op': 'move', 'path': '/baz', 'from': '/foo' + }, + ), + ( + jsonpatch.RemoveOperation, { + 'op': 'remove', 'path': '/baz/1' + }, + ), + ( + jsonpatch.TestOperation, { + 'op': 'test', 'path': '/baz', 'value': [1, 3] + }, + ), + ( + jsonpatch.ReplaceOperation, { + 'op': 'replace', 'path': '/baz/0', 'value': 42 + }, + ), + ( + jsonpatch.RemoveOperation, { + 'op': 'remove', 'path': '/baz/1' + }, + ) + ] + for cls, patch in operations: + operation = cls(patch, pointer_cls=CustomJsonPointer) + self.assertEqual(operation.pointer_cls, CustomJsonPointer) + self.assertIsInstance(operation.pointer, CustomJsonPointer) + + def test_operations_from_patch(self): patch = jsonpatch.JsonPatch([ {'op': 'add', 'path': '/foo', 'value': [1, 2, 3]}, {'op': 'move', 'path': '/baz', 'from': '/foo'}, -- cgit v1.2.1