From a33021bf5a87350abc225a15c2a12880d88ed383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20K=C3=B6gl?= Date: Sat, 13 Feb 2016 15:40:03 +0100 Subject: [PATCH] Optimize "deep" ``replace`` operation, fixes #36 --- jsonpatch.py | 13 ++++++++++--- tests.py | 18 ++++++++++++++++++ 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):