summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Kögl <stefan@skoegl.net>2016-02-13 15:40:03 +0100
committerStefan Kögl <stefan@skoegl.net>2016-02-13 15:40:03 +0100
commita33021bf5a87350abc225a15c2a12880d88ed383 (patch)
treead78c654333e07f201447d45fa3c97f0c3a6e6d2
parent32dcbb03d8c6b9aedefff026fda75e5d8b63b8d2 (diff)
downloadpython-json-patch-a33021bf5a87350abc225a15c2a12880d88ed383.tar.gz
Optimize "deep" ``replace`` operation, fixes #36
-rw-r--r--jsonpatch.py13
-rwxr-xr-xtests.py18
2 files changed, 28 insertions, 3 deletions
diff --git a/jsonpatch.py b/jsonpatch.py
index fb2b90d..838d66c 100644
--- a/jsonpatch.py
+++ b/jsonpatch.py
@@ -756,11 +756,18 @@ def _optimize(operations):
def _optimize_using_replace(prev, cur):
- """Optimises JSON patch by using ``replace`` operation instead of
- ``remove`` and ``add`` against the same path."""
+ """Optimises by replacing ``add``/``remove`` with ``replace`` on same path
+
+ For nested strucures, tries to recurse replacement, see #36 """
prev['op'] = 'replace'
if cur['op'] == 'add':
- prev['value'] = cur['value']
+ # make recursive patch
+ patch = make_patch(prev['value'], cur['value'])
+ if len(patch.patch) == 1:
+ prev['path'] = prev['path'] + patch.patch[0]['path']
+ prev['value'] = patch.patch[0]['value']
+ else:
+ prev['value'] = cur['value']
def _optimize_using_move(prev_item, item):
diff --git a/tests.py b/tests.py
index 2572dc0..b73b38e 100755
--- a/tests.py
+++ b/tests.py
@@ -366,6 +366,24 @@ class MakePatchTestCase(unittest.TestCase):
dest = [7, 2, 1, 0, 9, 4, 3, 6, 5, 8]
patch = jsonpatch.make_patch(src, dest)
+ def test_minimal_patch(self):
+ """ Test whether a minimal patch is created, see #36 """
+ src = [{"foo": 1, "bar": 2}]
+ dst = [{"foo": 2, "bar": 2}]
+ import pudb
+ #pudb.set_trace()
+ patch = jsonpatch.make_patch(src, dst)
+
+ exp = [
+ {
+ "path": "/0/foo",
+ "value": 2,
+ "op": "replace"
+ }
+ ]
+
+ self.assertEqual(patch.patch, exp)
+
class InvalidInputTests(unittest.TestCase):