don't apply patch optimization when it's incorrect
This commit is contained in:
19
jsonpatch.py
19
jsonpatch.py
@@ -171,6 +171,14 @@ def make_patch(src, dst):
|
|||||||
>>> new == dst
|
>>> new == dst
|
||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# TODO: fix patch optimiztion and remove the following check
|
||||||
|
# fix when patch with optimization is incorrect
|
||||||
|
patch = JsonPatch.from_diff(src, dst)
|
||||||
|
new = patch.apply(src)
|
||||||
|
if new != dst:
|
||||||
|
return JsonPatch.from_diff(src, dst, False)
|
||||||
|
|
||||||
return JsonPatch.from_diff(src, dst)
|
return JsonPatch.from_diff(src, dst)
|
||||||
|
|
||||||
|
|
||||||
@@ -268,7 +276,7 @@ class JsonPatch(object):
|
|||||||
return cls(patch)
|
return cls(patch)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_diff(cls, src, dst):
|
def from_diff(cls, src, dst, optimization=True):
|
||||||
"""Creates JsonPatch instance based on comparing of two document
|
"""Creates JsonPatch instance based on comparing of two document
|
||||||
objects. Json patch would be created for `src` argument against `dst`
|
objects. Json patch would be created for `src` argument against `dst`
|
||||||
one.
|
one.
|
||||||
@@ -320,7 +328,7 @@ class JsonPatch(object):
|
|||||||
'value': dst[key]}
|
'value': dst[key]}
|
||||||
|
|
||||||
def compare_lists(path, src, dst):
|
def compare_lists(path, src, dst):
|
||||||
return _compare_lists(path, src, dst)
|
return _compare_lists(path, src, dst, optimization=optimization)
|
||||||
|
|
||||||
return cls(list(compare_values([], src, dst)))
|
return cls(list(compare_values([], src, dst)))
|
||||||
|
|
||||||
@@ -561,9 +569,12 @@ class CopyOperation(PatchOperation):
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def _compare_lists(path, src, dst):
|
def _compare_lists(path, src, dst, optimization=True):
|
||||||
"""Compares two lists objects and return JSON patch about."""
|
"""Compares two lists objects and return JSON patch about."""
|
||||||
return _optimize(_compare(path, src, dst, *_split_by_common_seq(src, dst)))
|
patch = list(_compare(path, src, dst, *_split_by_common_seq(src, dst)))
|
||||||
|
if optimization:
|
||||||
|
return list(_optimize(patch))
|
||||||
|
return patch
|
||||||
|
|
||||||
|
|
||||||
def _longest_common_subseq(src, dst):
|
def _longest_common_subseq(src, dst):
|
||||||
|
|||||||
13
tests.py
13
tests.py
@@ -267,7 +267,6 @@ class EqualityTestCase(unittest.TestCase):
|
|||||||
self.assertEqual(json.dumps(patch_obj), patch.to_string())
|
self.assertEqual(json.dumps(patch_obj), patch.to_string())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MakePatchTestCase(unittest.TestCase):
|
class MakePatchTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_apply_patch_to_copy(self):
|
def test_apply_patch_to_copy(self):
|
||||||
@@ -336,7 +335,6 @@ class MakePatchTestCase(unittest.TestCase):
|
|||||||
res = jsonpatch.apply_patch(src, patch)
|
res = jsonpatch.apply_patch(src, patch)
|
||||||
self.assertEqual(res, dst)
|
self.assertEqual(res, dst)
|
||||||
|
|
||||||
|
|
||||||
def test_escape(self):
|
def test_escape(self):
|
||||||
src = {"x/y": 1}
|
src = {"x/y": 1}
|
||||||
dst = {"x/y": 2}
|
dst = {"x/y": 2}
|
||||||
@@ -368,6 +366,17 @@ class MakePatchTestCase(unittest.TestCase):
|
|||||||
dest = [7, 2, 1, 0, 9, 4, 3, 6, 5, 8]
|
dest = [7, 2, 1, 0, 9, 4, 3, 6, 5, 8]
|
||||||
patch = jsonpatch.make_patch(src, dest)
|
patch = jsonpatch.make_patch(src, dest)
|
||||||
|
|
||||||
|
def test_json_patch(self):
|
||||||
|
old = {
|
||||||
|
'queue': {'teams_out': [{'id': 3, 'reason': 'If tied'}, {'id': 5, 'reason': 'If tied'}]},
|
||||||
|
}
|
||||||
|
new = {
|
||||||
|
'queue': {'teams_out': [{'id': 5, 'reason': 'If lose'}]}
|
||||||
|
}
|
||||||
|
patch = jsonpatch.make_patch(old, new)
|
||||||
|
new_from_patch = jsonpatch.apply_patch(old, patch)
|
||||||
|
self.assertEqual(new, new_from_patch)
|
||||||
|
|
||||||
|
|
||||||
class OptimizationTests(unittest.TestCase):
|
class OptimizationTests(unittest.TestCase):
|
||||||
def test_use_replace_instead_of_remove_add(self):
|
def test_use_replace_instead_of_remove_add(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user