Skip to content

Commit

Permalink
unify: unified_patches order fix
Browse files Browse the repository at this point in the history
* Fixes the way patches are chosen to be part of the final result.

* Adds regression tests for the added fix.

* Removes conflict.handled field.

Signed-off-by: Mihai Bivol <miha.bivol@cern.ch>
  • Loading branch information
mihaibivol committed May 18, 2016
1 parent 5258111 commit 0d7e6c1
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 9 deletions.
1 change: 0 additions & 1 deletion dictdiffer/conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ def __init__(self, patch1, patch2):
self.first_patch = patch1
self.second_patch = patch2
self.take = None
self.handled = False

def take_patch(self):
"""Return the patch determined by the *take* attribute."""
Expand Down
15 changes: 8 additions & 7 deletions dictdiffer/unify.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,20 @@ def unify(self, first_patches, second_patches, conflicts):
:param conflicts: list of Conflict objects
"""
self.unified_patches = []
sorted_patches = sorted(first_patches + second_patches, key=get_path)

self._build_index(conflicts)

sorted_patches = sorted(first_patches + second_patches, key=get_path)

for patch in sorted_patches:
conflict = self._index.get(nested_hash(patch))

# Apply only the patches that were taken as part of conflict
# resolution.
if conflict:
if not conflict.handled:
conflict.handled = True
self.unified_patches.append(conflict.take_patch())
else:
self.unified_patches.append(patch)
if conflict.take_patch() != patch:
continue

self.unified_patches.append(patch)

return self.unified_patches

Expand Down
1 change: 0 additions & 1 deletion tests/test_conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ def test_init(self):
self.assertEqual(c.first_patch, p1)
self.assertEqual(c.second_patch, p2)
self.assertEqual(c.take, None)
self.assertFalse(c.handled)

def test_take_patch(self):
p1 = ('add', '', [(1, 1)])
Expand Down
21 changes: 21 additions & 0 deletions tests/test_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import unittest

from dictdiffer import patch
from dictdiffer.merge import Merger, UnresolvedConflictsException


Expand Down Expand Up @@ -43,6 +44,26 @@ def take_first(conflict, _, __, ___):
self.assertEqual(m.unified_patches,
[('change', 'changeme', ('Jo', 'Joe'))])

def test_continue_run_multiple_conflicts_per_patch(self):
lca = {'foo': [{'x': 1}, {'y': 2}]}
first = {'foo': [{'x': 1}, {'y': 2}, {'z': 4}]}
second = {'bar': 'baz'}

expected = {
'f': {'foo': [{'x': 1}, {'y': 2}, {'z': 4}],
'bar': 'baz'},
's': {'bar': 'baz'}}

for resolution, expected_value in expected.items():
m = Merger(lca, first, second, {})
try:
m.run()
except UnresolvedConflictsException as e:
m.continue_run([resolution for _ in e.content])

self.assertEqual(patch(m.unified_patches, lca),
expected_value)


if __name__ == '__main__':
unittest.main()

0 comments on commit 0d7e6c1

Please sign in to comment.