diff --git a/jsonpatch.py b/jsonpatch.py index 7c8fa8f..5dac4a1 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -169,7 +169,8 @@ class JsonPatch(object): 'add': AddOperation, 'replace': ReplaceOperation, 'move': MoveOperation, - 'test': TestOperation + 'test': TestOperation, + 'copy': CopyOperation, } def __str__(self): @@ -414,3 +415,12 @@ class TestOperation(PatchOperation): value = self.operation['value'] subobj, part = self.locate(obj, self.location) assert subobj[part] == value + + +class CopyOperation(PatchOperation): + """ Copies an object property or an array element to a new location """ + + def apply(self, obj): + subobj, part = self.locate(obj, self.location) + value = subobj[part] + AddOperation(self.operation['to'], {'value': value}).apply(obj) diff --git a/tests.py b/tests.py index b922e77..4cf0ff2 100755 --- a/tests.py +++ b/tests.py @@ -72,6 +72,20 @@ class ApplyPatchTestCase(unittest.TestCase): res = jsonpatch.apply_patch(obj, [{'move': '/foo/1', 'to': '/foo/3'}]) self.assertEqual(res, {'foo': ['all', 'cows', 'eat', 'grass']}) + def test_copy_object_key(self): + obj = {'foo': {'bar': 'baz', 'waldo': 'fred'}, + 'qux': {'corge': 'grault'}} + res = jsonpatch.apply_patch(obj, [{'copy': '/foo/waldo', + 'to': '/qux/thud'}]) + self.assertEqual(res, {'qux': {'thud': 'fred', 'corge': 'grault'}, + 'foo': {'bar': 'baz', 'waldo': 'fred'}}) + + def test_copy_array_item(self): + obj = {'foo': ['all', 'grass', 'cows', 'eat']} + res = jsonpatch.apply_patch(obj, [{'copy': '/foo/1', 'to': '/foo/3'}]) + self.assertEqual(res, {'foo': ['all', 'grass', 'cows', 'grass', 'eat']}) + + def test_test_success(self): obj = {'baz': 'qux', 'foo': ['a', 2, 'c']} jsonpatch.apply_patch(obj, [{'test': '/baz', 'value': 'qux'},