the updated spec [1] didn't change anything that would make a new version of python-json-patch necessary. This commit only updates the reference to the current version, and adds a new example [1] http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-03
155 lines
5.6 KiB
Python
Executable File
155 lines
5.6 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import doctest
|
|
import unittest
|
|
import jsonpatch
|
|
|
|
|
|
class ApplyPatchTestCase(unittest.TestCase):
|
|
|
|
def test_apply_patch_from_string(self):
|
|
obj = {'foo': 'bar'}
|
|
patch = '[{"add": "/baz", "value": "qux"}]'
|
|
res = jsonpatch.apply_patch(obj, patch)
|
|
self.assertTrue(obj is not res)
|
|
self.assertTrue('baz' in res)
|
|
self.assertEqual(res['baz'], 'qux')
|
|
|
|
def test_apply_patch_to_copy(self):
|
|
obj = {'foo': 'bar'}
|
|
res = jsonpatch.apply_patch(obj, [{'add': '/baz', 'value': 'qux'}])
|
|
self.assertTrue(obj is not res)
|
|
|
|
def test_apply_patch_to_same_instance(self):
|
|
obj = {'foo': 'bar'}
|
|
res = jsonpatch.apply_patch(obj, [{'add': '/baz', 'value': 'qux'}],
|
|
in_place=True)
|
|
self.assertTrue(obj is res)
|
|
|
|
def test_add_object_key(self):
|
|
obj = {'foo': 'bar'}
|
|
res = jsonpatch.apply_patch(obj, [{'add': '/baz', 'value': 'qux'}])
|
|
self.assertTrue('baz' in res)
|
|
self.assertEqual(res['baz'], 'qux')
|
|
|
|
def test_add_array_item(self):
|
|
obj = {'foo': ['bar', 'baz']}
|
|
res = jsonpatch.apply_patch(obj, [{'add': '/foo/1', 'value': 'qux'}])
|
|
self.assertEqual(res['foo'], ['bar', 'qux', 'baz'])
|
|
|
|
def test_remove_object_key(self):
|
|
obj = {'foo': 'bar', 'baz': 'qux'}
|
|
res = jsonpatch.apply_patch(obj, [{'remove': '/baz'}])
|
|
self.assertTrue('baz' not in res)
|
|
|
|
def test_remove_array_item(self):
|
|
obj = {'foo': ['bar', 'qux', 'baz']}
|
|
res = jsonpatch.apply_patch(obj, [{'remove': '/foo/1'}])
|
|
self.assertEqual(res['foo'], ['bar', 'baz'])
|
|
|
|
def test_replace_object_key(self):
|
|
obj = {'foo': 'bar', 'baz': 'qux'}
|
|
res = jsonpatch.apply_patch(obj, [{'replace': '/baz', 'value': 'boo'}])
|
|
self.assertTrue(res['baz'], 'boo')
|
|
|
|
def test_replace_array_item(self):
|
|
obj = {'foo': ['bar', 'qux', 'baz']}
|
|
res = jsonpatch.apply_patch(obj, [{'replace': '/foo/1',
|
|
'value': 'boo'}])
|
|
self.assertEqual(res['foo'], ['bar', 'boo', 'baz'])
|
|
|
|
def test_move_object_key(self):
|
|
obj = {'foo': {'bar': 'baz', 'waldo': 'fred'},
|
|
'qux': {'corge': 'grault'}}
|
|
res = jsonpatch.apply_patch(obj, [{'move': '/foo/waldo',
|
|
'to': '/qux/thud'}])
|
|
self.assertEqual(res, {'qux': {'thud': 'fred', 'corge': 'grault'},
|
|
'foo': {'bar': 'baz'}})
|
|
|
|
def test_move_array_item(self):
|
|
obj = {'foo': ['all', 'grass', 'cows', 'eat']}
|
|
res = jsonpatch.apply_patch(obj, [{'move': '/foo/1', 'to': '/foo/3'}])
|
|
self.assertEqual(res, {'foo': ['all', 'cows', 'eat', 'grass']})
|
|
|
|
def test_test_success(self):
|
|
obj = {'baz': 'qux', 'foo': ['a', 2, 'c']}
|
|
jsonpatch.apply_patch(obj, [{'test': '/baz', 'value': 'qux'},
|
|
{'test': '/foo/1', 'value': 2}])
|
|
|
|
def test_test_error(self):
|
|
obj = {'bar': 'qux'}
|
|
self.assertRaises(AssertionError,
|
|
jsonpatch.apply_patch,
|
|
obj, [{'test': '/bar', 'value': 'bar'}])
|
|
|
|
|
|
class MakePatchTestCase(unittest.TestCase):
|
|
|
|
def test_apply_patch_to_copy(self):
|
|
src = {'foo': 'bar', 'boo': 'qux'}
|
|
dst = {'baz': 'qux', 'foo': 'boo'}
|
|
patch = jsonpatch.make_patch(src, dst)
|
|
res = patch.apply(src)
|
|
self.assertTrue(src is not res)
|
|
|
|
def test_apply_patch_to_same_instance(self):
|
|
src = {'foo': 'bar', 'boo': 'qux'}
|
|
dst = {'baz': 'qux', 'foo': 'boo'}
|
|
patch = jsonpatch.make_patch(src, dst)
|
|
res = patch.apply(src, in_place=True)
|
|
self.assertTrue(src is res)
|
|
|
|
def test_objects(self):
|
|
src = {'foo': 'bar', 'boo': 'qux'}
|
|
dst = {'baz': 'qux', 'foo': 'boo'}
|
|
patch = jsonpatch.make_patch(src, dst)
|
|
res = patch.apply(src)
|
|
self.assertEqual(res, dst)
|
|
|
|
def test_arrays(self):
|
|
src = {'numbers': [1, 2, 3], 'other': [1, 3, 4, 5]}
|
|
dst = {'numbers': [1, 3, 4, 5], 'other': [1, 3, 4]}
|
|
patch = jsonpatch.make_patch(src, dst)
|
|
res = patch.apply(src)
|
|
self.assertEqual(res, dst)
|
|
|
|
def test_complex_object(self):
|
|
src = {'data': [
|
|
{'foo': 1}, {'bar': [1, 2, 3]}, {'baz': {'1': 1, '2': 2}}
|
|
]}
|
|
dst = {'data': [
|
|
{'foo': [42]}, {'bar': []}, {'baz': {'boo': 'oom!'}}
|
|
]}
|
|
patch = jsonpatch.make_patch(src, dst)
|
|
res = patch.apply(src)
|
|
self.assertEqual(res, dst)
|
|
|
|
def test_array_add_remove(self):
|
|
# see https://github.com/stefankoegl/python-json-patch/issues/4
|
|
src = {'numbers': [], 'other': [1, 5, 3, 4]}
|
|
dst = {'numbers': [1, 3, 4, 5], 'other': []}
|
|
patch = jsonpatch.make_patch(src, dst)
|
|
res = patch.apply(src)
|
|
self.assertEqual(res, dst)
|
|
|
|
def test_add_nested(self):
|
|
# see http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-03#appendix-A.10
|
|
src = {"foo": "bar"}
|
|
patch_obj = [ { "add": "/child", "value": { "grandchild": { } } } ]
|
|
res = jsonpatch.apply_patch(src, patch_obj)
|
|
expected = { "foo": "bar",
|
|
"child": { "grandchild": { } }
|
|
}
|
|
self.assertEqual(expected, res)
|
|
|
|
def suite():
|
|
suite = unittest.TestSuite()
|
|
suite.addTest(doctest.DocTestSuite(jsonpatch))
|
|
suite.addTest(unittest.makeSuite(ApplyPatchTestCase))
|
|
suite.addTest(unittest.makeSuite(MakePatchTestCase))
|
|
return suite
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main(defaultTest='suite')
|