Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Delaigue2016-05-25 15:03:57 +0000
committerLaurent Delaigue2016-05-31 08:38:15 +0000
commit40bdc32e1427af7253a501fca0d9ce7c2bf137cb (patch)
treec7fca543903add51b0edd9a45ef60a5dfab018c6 /plugins
parentba05fbe16ff981d81606211525810ed4c8b32648 (diff)
downloadorg.eclipse.emf.compare-40bdc32e1427af7253a501fca0d9ce7c2bf137cb.tar.gz
org.eclipse.emf.compare-40bdc32e1427af7253a501fca0d9ce7c2bf137cb.tar.xz
org.eclipse.emf.compare-40bdc32e1427af7253a501fca0d9ce7c2bf137cb.zip
[493650] Fix order of merged children
Improved after discussion with Laurent Goubet. A test is added to check that when merging every diff and resolving conflicts by: - first reject all target side conflicting diffs - then accepting all other diffs yields models to be identical on both sides, no matter in what order the diffs are accepted/rejected. The test uses Collections2.permutations, which appeared in guava 12, so an update of the TP was necessary. Bug: 493650 Change-Id: Ib790b992184f6038806bf890f7af96ae2c447ca7 Signed-off-by: Laurent Delaigue <laurent.delaigue@obeo.fr>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF6
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/ComplexMergeTest.java274
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/FeatureMaps3wayMergeTest.java16
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java474
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AtLeastLunaVersionTests.java6
-rw-r--r--plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/DiffUtil.java7
6 files changed, 488 insertions, 295 deletions
diff --git a/plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF
index aca9bd2f7..2c092f71b 100644
--- a/plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.tests/META-INF/MANIFEST.MF
@@ -54,7 +54,7 @@ Export-Package: org.eclipse.emf.compare.tests,
org.eclipse.emf.compare.tests.scope,
org.eclipse.emf.compare.tests.suite,
org.eclipse.emf.compare.tests.unit
-Import-Package: com.google.common.base;version="[11.0.0,16.0.0)",
- com.google.common.cache;version="[11.0.0,16.0.0)",
- com.google.common.collect;version="[11.0.0,16.0.0)"
+Import-Package: com.google.common.base;version="[12.0.0,16.0.0)",
+ com.google.common.cache;version="[12.0.0,16.0.0)",
+ com.google.common.collect;version="[12.0.0,16.0.0)"
Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/ComplexMergeTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/ComplexMergeTest.java
new file mode 100644
index 000000000..c7b600962
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/ComplexMergeTest.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Obeo and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.tests.merge;
+
+import static com.google.common.base.Predicates.and;
+import static com.google.common.collect.Collections2.permutations;
+import static com.google.common.collect.Iterables.find;
+import static org.eclipse.emf.compare.DifferenceSource.LEFT;
+import static org.eclipse.emf.compare.DifferenceSource.RIGHT;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.added;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.moved;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.removed;
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.common.util.BasicMonitor;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.DifferenceSource;
+import org.eclipse.emf.compare.EMFCompare;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.merge.IMerger;
+import org.eclipse.emf.compare.scope.DefaultComparisonScope;
+import org.eclipse.emf.compare.scope.IComparisonScope;
+import org.eclipse.emf.compare.tests.conflict.data.ConflictInputData;
+import org.eclipse.emf.compare.tests.nodes.NodesPackage;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * This use case features 12 distinct differences of all types, with 4 real conflicts and 1 pseudo conflict.
+ * The test makes sure that whatever the order in which the operations are performed, as long the user starts
+ * by rejecting all 'remote' diffs before accepting all other diffs, the 2 sides of the comparison are equal.
+ * The combinatorial number (34560 combinations) has been limited by dealing with pseudo-conflicting diff and
+ * non-conflicting diffs after dealing with all conflicts and not only after rejecting the conflicting diffs
+ * on the remote side.
+ * <ol>
+ * <li>Left : Node8 added</li>
+ * <li>Left : Node9 added</li>
+ * <li>Left : Node1 moved</li>
+ * <li>Left : Node0 added</li>
+ * <li>Left : Node5 removed</li>
+ * <li>Left : Node6 removed</li>
+ * <li>Left : Node7 removed</li>
+ * <li>Right : Node6 moved</li>
+ * <li>Right : Node9 added</li>
+ * <li>Right : Node0 added</li>
+ * <li>Right : Node1 moved</li>
+ * <li>Right : Node5 removed</li>
+ * </ol>
+ * <ul>
+ * <li>Real conflict : Node0 (Adding the same value at different indices)</li>
+ * <li>Real conflict : Node1 (Moving the same value to different indices on both sides)</li>
+ * <li>Real conflict : Node6 (Moving and deleting the same value)</li>
+ * <li>Real conflict : Node9 (Adding the same value at different indices)</li>
+ * <li>Pseudo conflict : Node5 (Removing the same value on both sides)</li>
+ * </ul>
+ * For reference,
+ * <ul>
+ * <li>"original" is : {Node1, Node2, Node3, Node4, Node5, Node6, Node7}</li>
+ * <li>"left" is : {Node8, Node9, Node2, Node3, Node4, Node1, Node0}</li>
+ * <li>"right" is : {Node6, Node2, Node9, Node3, Node0, Node1, Node4, Node7}</li>
+ * </ul>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ * @author <a href="mailto:laurent.delaigue@obeo.fr">Laurent Delaigue</a>
+ */
+@RunWith(Parameterized.class)
+public class ComplexMergeTest {
+
+ private ConflictInputData conflictInput = new ConflictInputData();
+
+ private IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
+
+ private List<Predicate<? super Diff>> rightConflictPermutation;
+
+ private List<Predicate<? super Diff>> leftConflictPermutation;
+
+ private List<Predicate<? super Diff>> otherPermutation;
+
+ @SuppressWarnings("unchecked")
+ @Parameters
+ public static Iterable<Object[]> data() {
+ Collection<List<Predicate<? super Diff>>> rightConflictPermutations = permutations(Arrays
+ .<Predicate<? super Diff>> asList(added("Root.Node0"), //$NON-NLS-1$
+ moved("Root.Node1", "containmentRef1"), moved("Root.Node6", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "containmentRef1"), added("Root.Node9"))); //$NON-NLS-1$ //$NON-NLS-2$
+ Collection<List<Predicate<? super Diff>>> leftConflictPermutations = permutations(Arrays
+ .<Predicate<? super Diff>> asList(added("Root.Node0"), //$NON-NLS-1$
+ moved("Root.Node1", "containmentRef1"), removed("Root.Node5"), removed("Root.Node6"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ added("Root.Node9"))); //$NON-NLS-1$
+ Collection<List<Predicate<? super Diff>>> otherPermutations = permutations(Arrays
+ .<Predicate<? super Diff>> asList(
+ and(fromSide(LEFT), removed("Root.Node5")), and(fromSide(LEFT), removed("Root.Node7")), and( //$NON-NLS-1$ //$NON-NLS-2$
+ fromSide(LEFT), added("Root.Node8")))); //$NON-NLS-1$
+
+ List<Object[]> data = new ArrayList<Object[]>();
+ for (List<Predicate<? super Diff>> otherPermutation : otherPermutations) {
+ for (List<Predicate<? super Diff>> rightConflictPermutation : rightConflictPermutations) {
+ for (List<Predicate<? super Diff>> leftConflictPermutation : leftConflictPermutations) {
+ data.add(new Object[] {leftConflictPermutation, rightConflictPermutation,
+ otherPermutation });
+ }
+ }
+ }
+ return data;
+ }
+
+ public ComplexMergeTest(List<Predicate<? super Diff>> leftConflictpermutation,
+ List<Predicate<? super Diff>> rightConflictPermutation,
+ List<Predicate<? super Diff>> otherPermutation) {
+ this.rightConflictPermutation = rightConflictPermutation;
+ this.leftConflictPermutation = leftConflictpermutation;
+ this.otherPermutation = otherPermutation;
+ }
+
+ /**
+ * make sure that on a complex case, it's possible to merge left to right all conflicting right diffs
+ * (i.e. reject them all) and then merge left to right all the other differences and always get 2
+ * identical models.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testLeftToRight() throws IOException {
+ final Resource left = conflictInput.getComplexLeft();
+ final Resource origin = conflictInput.getComplexOrigin();
+ final Resource right = conflictInput.getComplexRight();
+
+ final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
+ EMFCompare emfc = EMFCompare.builder().build();
+
+ Comparison comp = emfc.compare(scope);
+ for (Predicate<? super Diff> conflictingNode : rightConflictPermutation) {
+ Diff diff = getDiff(comp, RIGHT, conflictingNode);
+ copyLeftToRight(diff);
+ }
+ for (Predicate<? super Diff> conflictingNode : leftConflictPermutation) {
+ Diff diff = getDiff(comp, LEFT, conflictingNode);
+ copyLeftToRight(diff);
+ }
+ for (Predicate<? super Diff> otherNode : otherPermutation) {
+ Diff diff = getDiff(comp, otherNode);
+ copyLeftToRight(diff);
+ }
+
+ // Left and Right should now be equal
+ assertEqualContents(comp, getNodes(left), getNodes(right));
+ }
+
+ /**
+ * make sure that on a complex case, it's possible to merge left to right all conflicting right diffs
+ * (i.e. reject them all) and then merge left to right all the other differences and always get 2
+ * identical models.
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testRightToLeft() throws IOException {
+ final Resource left = conflictInput.getComplexLeft();
+ final Resource origin = conflictInput.getComplexOrigin();
+ final Resource right = conflictInput.getComplexRight();
+
+ final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
+ EMFCompare emfc = EMFCompare.builder().build();
+
+ Comparison comp = emfc.compare(scope);
+ for (Predicate<? super Diff> conflictingNode : leftConflictPermutation) {
+ Diff diff = getDiff(comp, LEFT, conflictingNode);
+ copyRightToLeft(diff);
+ }
+ for (Predicate<? super Diff> conflictingNode : rightConflictPermutation) {
+ Diff diff = getDiff(comp, RIGHT, conflictingNode);
+ copyRightToLeft(diff);
+ }
+ for (Predicate<? super Diff> otherNode : otherPermutation) {
+ Diff diff = getDiff(comp, otherNode);
+ copyRightToLeft(diff);
+ }
+ // Left and Right should now be equal
+ assertEqualContents(comp, getNodes(left), getNodes(right));
+ }
+
+ private List<EObject> getNodes(Resource r) {
+ EObject container = r.getContents().get(0);
+ return getAsList(container, NodesPackage.eINSTANCE.getNode_ContainmentRef1());
+ }
+
+ private Diff getDiff(Comparison comp, DifferenceSource side, Predicate<? super Diff> predicate) {
+ return find(comp.getDifferences(), and(fromSide(side), predicate));
+ }
+
+ private Diff getDiff(Comparison comp, Predicate<? super Diff> predicate) {
+ return find(comp.getDifferences(), predicate);
+ }
+
+ private void copyRightToLeft(Diff diff) {
+ mergerRegistry.getHighestRankingMerger(diff).copyRightToLeft(diff, new BasicMonitor());
+ }
+
+ private void copyLeftToRight(Diff diff) {
+ mergerRegistry.getHighestRankingMerger(diff).copyLeftToRight(diff, new BasicMonitor());
+
+ }
+
+ /**
+ * Ensure that the two given lists contain the same elements in the same order. The kind of list does not
+ * matter.
+ *
+ * @param list1
+ * First of the two lists to compare.
+ * @param list2
+ * Second of the two lists to compare.
+ */
+ private static <T extends EObject> void assertEqualContents(Comparison comparison, List<T> list1,
+ List<T> list2) {
+ final int size = list1.size();
+ assertEquals(size, list2.size());
+
+ for (int i = 0; i < size; i++) {
+ final EObject eObject1 = list1.get(i);
+ final EObject eObject2 = list2.get(i);
+ final Match match = comparison.getMatch(eObject1);
+ if (match.getLeft() == eObject1) {
+ assertEquals(match.getRight(), eObject2);
+ } else {
+ assertEquals(match.getRight(), eObject1);
+ assertEquals(match.getLeft(), eObject2);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static List<EObject> getAsList(EObject object, EReference feature) {
+ if (object != null) {
+ Object value = object.eGet(feature, false);
+ final List<EObject> asList;
+ if (value instanceof List) {
+ asList = (List<EObject>)value;
+ } else if (value instanceof Iterable) {
+ asList = ImmutableList.copyOf((Iterable<EObject>)value);
+ } else if (value != null) {
+ asList = ImmutableList.of((EObject)value);
+ } else {
+ asList = Collections.emptyList();
+ }
+ return asList;
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/FeatureMaps3wayMergeTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/FeatureMaps3wayMergeTest.java
index 35157da38..4a96f7cf8 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/FeatureMaps3wayMergeTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/FeatureMaps3wayMergeTest.java
@@ -514,7 +514,7 @@ public class FeatureMaps3wayMergeTest {
assertTrue(((BasicFeatureMap)map).contains(eSFFirstKey, rightNode1));
comparison = EMFCompare.builder().build().compare(scope);
- assertEquals(4, comparison.getDifferences().size());
+ assertEquals(2, comparison.getDifferences().size());
}
@Test
@@ -602,7 +602,7 @@ public class FeatureMaps3wayMergeTest {
assertTrue(((BasicFeatureMap)map).contains(eSFFirstKey, rightNode1));
comparison = EMFCompare.builder().build().compare(scope);
- assertEquals(4, comparison.getDifferences().size());
+ assertEquals(2, comparison.getDifferences().size());
}
@Test
@@ -2204,7 +2204,7 @@ public class FeatureMaps3wayMergeTest {
final Object rightFirstKey = rightMapNode1.eGet(eSFFirstKey);
assertTrue(rightFirstKey instanceof List);
assertEquals(2, ((List)rightFirstKey).size());
- assertEquals(rightNode1, ((List)rightFirstKey).get(1));
+ assertEquals(rightNode1, ((List)rightFirstKey).get(0));
// mapNode1 references node1 through the map in right
final EStructuralFeature eSFmap = rightMapNode1.eClass().getEStructuralFeature("mapNC");
assertNotNull(eSFmap);
@@ -2214,10 +2214,10 @@ public class FeatureMaps3wayMergeTest {
final Object rightMap = rightMapNode1.eGet(eSFmap);
assertTrue(rightMap instanceof BasicFeatureMap);
assertEquals(2, ((BasicFeatureMap)rightMap).size());
- assertEquals(rightNode1, ((BasicFeatureMap)rightMap).get(eSFFirstKey, 1, true));
+ assertEquals(rightNode1, ((BasicFeatureMap)rightMap).get(eSFFirstKey, 0, true));
comparison = EMFCompare.builder().build().compare(scope);
- assertEquals(4, comparison.getDifferences().size());
+ assertEquals(2, comparison.getDifferences().size());
}
@Test
@@ -2312,7 +2312,7 @@ public class FeatureMaps3wayMergeTest {
final Object rightFirstKey = rightMapNode1.eGet(eSFFirstKey);
assertTrue(rightFirstKey instanceof List);
assertEquals(2, ((List)rightFirstKey).size());
- assertEquals(rightNode1, ((List)rightFirstKey).get(1));
+ assertEquals(rightNode1, ((List)rightFirstKey).get(0));
// mapNode1 references node1 through the map in right
final EStructuralFeature eSFmap = rightMapNode1.eClass().getEStructuralFeature("mapNC");
assertNotNull(eSFmap);
@@ -2322,10 +2322,10 @@ public class FeatureMaps3wayMergeTest {
final Object rightMap = rightMapNode1.eGet(eSFmap);
assertTrue(rightMap instanceof BasicFeatureMap);
assertEquals(2, ((BasicFeatureMap)rightMap).size());
- assertEquals(rightNode1, ((BasicFeatureMap)rightMap).get(eSFFirstKey, 1, true));
+ assertEquals(rightNode1, ((BasicFeatureMap)rightMap).get(eSFFirstKey, 0, true));
comparison = EMFCompare.builder().build().compare(scope);
- assertEquals(4, comparison.getDifferences().size());
+ assertEquals(2, comparison.getDifferences().size());
}
@Test
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java
index ef9e1aced..b4292a6ee 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/merge/MultipleMergeTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2015 Obeo and others.
+ * Copyright (c) 2012, 2016 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -70,6 +70,12 @@ public class MultipleMergeTest {
private IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
+ /**
+ * @see ComplexMergeTest for a parametric test of all combinations of merge order. This test is here to
+ * detail step by step how the merge is supposed to take place and facilitate debugging in case of a
+ * problem.
+ * @throws IOException
+ */
@Test
public void testComplexUseCaseLtoR1() throws IOException {
final Resource left = conflictInput.getComplexLeft();
@@ -81,8 +87,8 @@ public class MultipleMergeTest {
final List<Diff> differences = comparison.getDifferences();
/*
- * This use case features 12 distinct differences of all types, adding up to 3 real conflict and 2
- * pseudo conflicts.
+ * This use case features 12 distinct differences of all types, adding up to 4 real conflicts and 1
+ * pseudo conflict.
*/
// 1 - Left : Node8 added
// 2 - Left : Node9 added
@@ -112,119 +118,110 @@ public class MultipleMergeTest {
// Merge all, left to right, in order. Resolve conflicts by taking left side.
- // merge 1 (add Node8)
- final ReferenceChange diff1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), added("Root.Node8")));
- // LCS is currently {2, 3, 4}. Insertion index is right before 2.
- mergerRegistry.getHighestRankingMerger(diff1).copyLeftToRight(diff1, new BasicMonitor());
- assertValueIndexIs(diff1, false, 1);
-
- // merge 2 (add Node9). Since there is a conflict, merge 9 right beforehand
- final ReferenceChange diff2 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), added("Root.Node9")));
- final ReferenceChange diff9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ // First, reject all conflicts on the right
+ // left: 8923410, right: 62930147
+ final ReferenceChange rightAdOfNode9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node9")));
- // Revert addition of Node9 in right
- mergerRegistry.getHighestRankingMerger(diff9).copyLeftToRight(diff9, new BasicMonitor());
- // LCS is now {8, 2, 3, 4}. Insertion should be right after 8
- mergerRegistry.getHighestRankingMerger(diff2).copyLeftToRight(diff2, new BasicMonitor());
- assertValueIndexIs(diff2, false, 2);
+ mergerRegistry.getHighestRankingMerger(rightAdOfNode9).copyLeftToRight(rightAdOfNode9,
+ new BasicMonitor());
- // merge 3 (move Node1). Since there is a conflict, merge 11 beforehand
- final ReferenceChange diff3 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), moved("Root.Node1", "containmentRef1")));
- final ReferenceChange diff11 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ // left: 8923410, right: 6230147
+
+ final ReferenceChange rightMoveOfNode1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node1", "containmentRef1")));
// revert move of Node 1 in right. It should be re-positioned right before 2
- mergerRegistry.getHighestRankingMerger(diff11).copyLeftToRight(diff11, new BasicMonitor());
- assertValueIndexIs(diff11, false, 3);
- // LCS is {8, 9, 2, 3, 4}. 1 should be moved right after 4.
- mergerRegistry.getHighestRankingMerger(diff3).copyLeftToRight(diff3, new BasicMonitor());
- assertValueIndexIs(diff3, false, 7);
+ mergerRegistry.getHighestRankingMerger(rightMoveOfNode1).copyLeftToRight(rightMoveOfNode1,
+ new BasicMonitor());
+ assertValueIndexIs(rightMoveOfNode1, false, 1);
- // merge 4 (add Node0). There is a conflict. Merge 10 beforehand.
- final ReferenceChange diff4 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), added("Root.Node0")));
- final ReferenceChange diff10 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ // left: 8923410, right: 6123047
+
+ final ReferenceChange rightAddOfNode0 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), added("Root.Node0")));
// revert addition of 0 in right
- mergerRegistry.getHighestRankingMerger(diff10).copyLeftToRight(diff10, new BasicMonitor());
- // LCS is now {8, 9, 2, 3, 4, 1}. 0 should be added right after 1
- mergerRegistry.getHighestRankingMerger(diff4).copyLeftToRight(diff4, new BasicMonitor());
- assertValueIndexIs(diff4, false, 7);
-
- // merge 5 (remove Node5). There is a conflict, but it is a pseudo-conflict.
- // These diffs won't even be presented to the user, but let's merge them nonetheless.
- final ReferenceChange diff5 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node5")));
- final ReferenceChange diff12 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
- mergerRegistry.getHighestRankingMerger(diff12).copyLeftToRight(diff12, new BasicMonitor());
- assertValueIndexIs(diff12, false, -1);
- mergerRegistry.getHighestRankingMerger(diff5).copyLeftToRight(diff5, new BasicMonitor());
- assertValueIndexIs(diff5, false, -1);
+ mergerRegistry.getHighestRankingMerger(rightAddOfNode0).copyLeftToRight(rightAddOfNode0,
+ new BasicMonitor());
+
+ // left: 8923410, right: 612347
- // merge 6 (remove Node6). There is a conflict. Merge 8 beforehand.
- final ReferenceChange diff6 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node6")));
- final ReferenceChange diff8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ final ReferenceChange rightMoveOfNode6 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.RIGHT), moved("Root.Node6", "containmentRef1")));
// Revert move of 6 in right.
- mergerRegistry.getHighestRankingMerger(diff8).copyLeftToRight(diff8, new BasicMonitor());
- assertValueIndexIs(diff8, false, 5);
- mergerRegistry.getHighestRankingMerger(diff6).copyLeftToRight(diff6, new BasicMonitor());
- assertValueIndexIs(diff6, false, -1);
+ mergerRegistry.getHighestRankingMerger(rightMoveOfNode6).copyLeftToRight(rightMoveOfNode6,
+ new BasicMonitor());
+ assertValueIndexIs(rightMoveOfNode6, false, 4);
- // merge 7 (remove Node7)
- final ReferenceChange diff7 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node7")));
- mergerRegistry.getHighestRankingMerger(diff7).copyLeftToRight(diff7, new BasicMonitor());
- assertValueIndexIs(diff7, false, -1);
+ // left: 8923410, right: 123467
- // Left and Right should now be equal
- final EObject leftContainer = diff7.getMatch().getLeft();
- final EObject rightContainer = diff7.getMatch().getRight();
- final List<EObject> leftContents = getAsList(leftContainer, diff7.getReference());
- final List<EObject> rightContents = getAsList(rightContainer, diff7.getReference());
- assertEqualContents(comparison, leftContents, rightContents);
- }
+ final ReferenceChange rightDeleteOfNode5 = (ReferenceChange)Iterators.find(differences.iterator(),
+ and(fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
+ // delete of Node 5 (pseudo-conflict) => no change
+ mergerRegistry.getHighestRankingMerger(rightDeleteOfNode5).copyLeftToRight(rightDeleteOfNode5,
+ new BasicMonitor());
+ assertValueIndexIs(rightDeleteOfNode5, false, -1);
- @Test
- public void testComplexUseCaseLtoR2() throws IOException {
- final Resource left = conflictInput.getComplexLeft();
- final Resource origin = conflictInput.getComplexOrigin();
- final Resource right = conflictInput.getComplexRight();
+ // left: 8923410, right: 123467
- final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
- final Comparison comparison = EMFCompare.builder().build().compare(scope);
+ // And now, accept all other changes
- final List<Diff> differences = comparison.getDifferences();
+ // add Node8
+ final ReferenceChange leftAddOfNode8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ fromSide(DifferenceSource.LEFT), added("Root.Node8")));
+ // LCS is currently {2, 3, 4}. Insertion index is right before 2.
+ mergerRegistry.getHighestRankingMerger(leftAddOfNode8).copyLeftToRight(leftAddOfNode8,
+ new BasicMonitor());
+ assertValueIndexIs(leftAddOfNode8, false, 1);
- // See description of the changes in #testComplexUseCaseLtoR1
- // Merge all, left to right, in arbitrary order. Resolve conflicts by taking left side.
+ // left: 8923410, right: 1823467
- // merge 3 (move Node1). Since there is a conflict, merge 11 beforehand
- final ReferenceChange diff3 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ // add Node9
+ final ReferenceChange leftAddOfNode9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ fromSide(DifferenceSource.LEFT), added("Root.Node9")));
+ // LCS is now {8, 2, 3, 4}. Insertion should be right after 8
+ mergerRegistry.getHighestRankingMerger(leftAddOfNode9).copyLeftToRight(leftAddOfNode9,
+ new BasicMonitor());
+ assertValueIndexIs(leftAddOfNode9, false, 2);
+
+ // left: 8923410, right: 18923467
+
+ // move Node1
+ final ReferenceChange leftMoveOfNode1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), moved("Root.Node1", "containmentRef1")));
- final ReferenceChange diff11 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), moved("Root.Node1", "containmentRef1")));
- // revert move of Node 1 in right. It should be re-positioned right before 2
- mergerRegistry.getHighestRankingMerger(diff11).copyLeftToRight(diff11, new BasicMonitor());
- assertValueIndexIs(diff11, false, 1);
- // Merge move of 1. Should be moved right after 4.
- mergerRegistry.getHighestRankingMerger(diff3).copyLeftToRight(diff3, new BasicMonitor());
- assertValueIndexIs(diff3, false, 6);
+ // LCS is {8, 9, 2, 3, 4}. 1 should be moved right after 4.
+ mergerRegistry.getHighestRankingMerger(leftMoveOfNode1).copyLeftToRight(leftMoveOfNode1,
+ new BasicMonitor());
+ assertValueIndexIs(leftMoveOfNode1, false, 5);
- // merge 6 (add Node6). There is a conflict. Merge 8 beforehand.
- final ReferenceChange diff6 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node6")));
- final ReferenceChange diff8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), moved("Root.Node6", "containmentRef1")));
- // Revert move of 6 in right.
- mergerRegistry.getHighestRankingMerger(diff8).copyLeftToRight(diff8, new BasicMonitor());
- assertValueIndexIs(diff8, false, 5);
- mergerRegistry.getHighestRankingMerger(diff6).copyLeftToRight(diff6, new BasicMonitor());
- assertValueIndexIs(diff6, false, -1);
+ // left: 8923410, right: 89234167
+
+ // add Node0
+ final ReferenceChange leftAddOfNode0 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ fromSide(DifferenceSource.LEFT), added("Root.Node0")));
+ // LCS is now {8, 9, 2, 3, 4, 1}. 0 should be added right after 1
+ mergerRegistry.getHighestRankingMerger(leftAddOfNode0).copyLeftToRight(leftAddOfNode0,
+ new BasicMonitor());
+ assertValueIndexIs(leftAddOfNode0, false, 6);
+
+ // left: 8923410, right: 892341067
+
+ // remove Node5 (again since pseudo-conflict) should have no effect
+ // These diff won't even be presented to the user, but let's merge it anyway.
+ final ReferenceChange leftDeleteOfNode5 = (ReferenceChange)Iterators.find(differences.iterator(),
+ and(fromSide(DifferenceSource.LEFT), removed("Root.Node5")));
+ mergerRegistry.getHighestRankingMerger(leftDeleteOfNode5).copyLeftToRight(leftDeleteOfNode5,
+ new BasicMonitor());
+ assertValueIndexIs(leftDeleteOfNode5, false, -1);
+
+ // left: 8923410, right: 892341067
+
+ // remove Node6
+ final ReferenceChange leftDeleteOfNode6 = (ReferenceChange)Iterators.find(differences.iterator(),
+ and(fromSide(DifferenceSource.LEFT), removed("Root.Node6")));
+ mergerRegistry.getHighestRankingMerger(leftDeleteOfNode6).copyLeftToRight(leftDeleteOfNode6,
+ new BasicMonitor());
+ assertValueIndexIs(leftDeleteOfNode6, false, -1);
+
+ // left: 8923410, right: 89234107
// merge 7 (remove Node7)
final ReferenceChange diff7 = (ReferenceChange)Iterators.find(differences.iterator(), and(
@@ -232,45 +229,7 @@ public class MultipleMergeTest {
mergerRegistry.getHighestRankingMerger(diff7).copyLeftToRight(diff7, new BasicMonitor());
assertValueIndexIs(diff7, false, -1);
- // merge 4 (add Node0). There is a conflict. Merge 10 beforehand.
- final ReferenceChange diff4 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), added("Root.Node0")));
- final ReferenceChange diff10 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), added("Root.Node0")));
- // revert addition of 0 in right
- mergerRegistry.getHighestRankingMerger(diff10).copyLeftToRight(diff10, new BasicMonitor());
- assertValueIndexIs(diff10, false, -1);
- mergerRegistry.getHighestRankingMerger(diff4).copyLeftToRight(diff4, new BasicMonitor());
- assertValueIndexIs(diff4, false, 5);
-
- // merge 1 (add Node8)
- final ReferenceChange diff1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), added("Root.Node8")));
- mergerRegistry.getHighestRankingMerger(diff1).copyLeftToRight(diff1, new BasicMonitor());
- assertValueIndexIs(diff1, false, 0);
-
- // merge 2 (add Node9). Since there is a conflict, merge 9 right beforehand
- final ReferenceChange diff2 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), added("Root.Node9")));
- final ReferenceChange diff9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), added("Root.Node9")));
- // Revert addition of Node9 in right
- mergerRegistry.getHighestRankingMerger(diff9).copyLeftToRight(diff9, new BasicMonitor());
- assertValueIndexIs(diff9, false, -1);
- mergerRegistry.getHighestRankingMerger(diff2).copyLeftToRight(diff2, new BasicMonitor());
- assertValueIndexIs(diff2, false, 1);
-
- // merge 5 (remove Node5). There is a conflict, but it is a pseudo-conflict.
- final ReferenceChange diff5 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node5")));
- final ReferenceChange diff12 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
- // revert remove
- mergerRegistry.getHighestRankingMerger(diff12).copyLeftToRight(diff12, new BasicMonitor());
- assertValueIndexIs(diff12, false, -1);
- // apply remove
- mergerRegistry.getHighestRankingMerger(diff5).copyLeftToRight(diff5, new BasicMonitor());
- assertValueIndexIs(diff5, false, -1);
+ // left: 8923410, right: 8923410
// Left and Right should now be equal
final EObject leftContainer = diff7.getMatch().getLeft();
@@ -280,6 +239,11 @@ public class MultipleMergeTest {
assertEqualContents(comparison, leftContents, rightContents);
}
+ /**
+ * Same as previous but right to left.
+ *
+ * @throws IOException
+ */
@Test
public void testComplexUseCaseRtoL1() throws IOException {
final Resource left = conflictInput.getComplexLeft();
@@ -294,173 +258,123 @@ public class MultipleMergeTest {
// See description of the changes in #testComplexUseCaseLtoR1
// Merge all, right to left, in order. Resolve conflicts by taking right side.
- // merge 8 (move Node6). There is a conflict. Merge 6 beforehand.
- final ReferenceChange diff6 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node6")));
- final ReferenceChange diff8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), moved("Root.Node6", "containmentRef1")));
- // Revert remove of 6 in left.
- mergerRegistry.getHighestRankingMerger(diff6).copyRightToLeft(diff6, new BasicMonitor());
- assertValueIndexIs(diff6, true, 5);
- // apply the move in left
- mergerRegistry.getHighestRankingMerger(diff8).copyRightToLeft(diff8, new BasicMonitor());
- assertValueIndexIs(diff8, true, 2);
+ // left: 8923410, right: 62930147
+
+ // Revert delete of 6 on the left side
+ final ReferenceChange leftDeleteOfNode6 = (ReferenceChange)Iterators.find(differences.iterator(),
+ and(fromSide(DifferenceSource.LEFT), removed("Root.Node6")));
+ mergerRegistry.getHighestRankingMerger(leftDeleteOfNode6).copyRightToLeft(leftDeleteOfNode6,
+ new BasicMonitor());
+ assertValueIndexIs(leftDeleteOfNode6, true, 5);
+
+ // left: 89234610, right: 62930147
- // merge 9 (add Node9). Since there is a conflict, merge 2 right beforehand
- final ReferenceChange diff2 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ // Revert add of 9 on the left side
+ final ReferenceChange leftAddOfNode9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), added("Root.Node9")));
- final ReferenceChange diff9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), added("Root.Node9")));
- // Revert addition in left
- mergerRegistry.getHighestRankingMerger(diff2).copyRightToLeft(diff2, new BasicMonitor());
- assertValueIndexIs(diff2, true, -1);
- mergerRegistry.getHighestRankingMerger(diff9).copyRightToLeft(diff9, new BasicMonitor());
- assertValueIndexIs(diff9, true, 3);
+ mergerRegistry.getHighestRankingMerger(leftAddOfNode9).copyRightToLeft(leftAddOfNode9,
+ new BasicMonitor());
+ assertValueIndexIs(leftAddOfNode9, true, -1);
+
+ // left: 8234610, right: 62930147
+
+ // Revert delete of node 5, pseudo conflict -> does nothing
+ final ReferenceChange leftDeleteOfNode5 = (ReferenceChange)Iterators.find(differences.iterator(),
+ and(fromSide(DifferenceSource.LEFT), removed("Root.Node5")));
+ mergerRegistry.getHighestRankingMerger(leftDeleteOfNode5).copyRightToLeft(leftDeleteOfNode5,
+ new BasicMonitor());
+ assertValueIndexIs(leftDeleteOfNode5, true, -1);
+
+ // left: 8234610, right: 62930147
- // merge 10 (add Node0). There is a conflict. Merge 4 beforehand.
- final ReferenceChange diff4 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ // Revert add of 0 on the left side
+ final ReferenceChange leftAddOfNode0 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), added("Root.Node0")));
- final ReferenceChange diff10 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), added("Root.Node0")));
- // Revert addition in left
- mergerRegistry.getHighestRankingMerger(diff4).copyRightToLeft(diff4, new BasicMonitor());
- assertValueIndexIs(diff4, true, -1);
- mergerRegistry.getHighestRankingMerger(diff10).copyRightToLeft(diff10, new BasicMonitor());
- assertValueIndexIs(diff10, true, 5);
+ mergerRegistry.getHighestRankingMerger(leftAddOfNode0).copyRightToLeft(leftAddOfNode0,
+ new BasicMonitor());
+ assertValueIndexIs(leftAddOfNode0, true, -1);
+
+ // left: 823461, right: 62930147
- // merge 11 (move Node1). Since there is a conflict, merge 3 beforehand
- final ReferenceChange diff3 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), moved("Root.Node1", "containmentRef1")));
- final ReferenceChange diff11 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), moved("Root.Node1", "containmentRef1")));
// Revert move of 1 in left
- mergerRegistry.getHighestRankingMerger(diff3).copyRightToLeft(diff3, new BasicMonitor());
- assertValueIndexIs(diff3, true, 2);
- mergerRegistry.getHighestRankingMerger(diff11).copyRightToLeft(diff11, new BasicMonitor());
- assertValueIndexIs(diff11, true, 6);
-
- // merge 12 (remove Node5). Merge 5 beforehand.
- final ReferenceChange diff5 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node5")));
- final ReferenceChange diff12 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
- // revert remove in left
- mergerRegistry.getHighestRankingMerger(diff5).copyRightToLeft(diff5, new BasicMonitor());
- assertValueIndexIs(diff5, true, -1);
- mergerRegistry.getHighestRankingMerger(diff12).copyRightToLeft(diff12, new BasicMonitor());
- assertValueIndexIs(diff12, true, -1);
+ final ReferenceChange leftMoveOfNode1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ fromSide(DifferenceSource.LEFT), moved("Root.Node1", "containmentRef1")));
+ mergerRegistry.getHighestRankingMerger(leftMoveOfNode1).copyRightToLeft(leftMoveOfNode1,
+ new BasicMonitor());
+ assertValueIndexIs(leftMoveOfNode1, true, 1);
- // merge 1 (add Node8). This will remove Node8
- final ReferenceChange diff1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), added("Root.Node8")));
- mergerRegistry.getHighestRankingMerger(diff1).copyRightToLeft(diff1, new BasicMonitor());
- assertValueIndexIs(diff1, false, -1);
+ // left: 812346, right: 62930147
- // merge 7 (remove Node7). This will re-add Node7
- final ReferenceChange diff7 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node7")));
- mergerRegistry.getHighestRankingMerger(diff7).copyRightToLeft(diff7, new BasicMonitor());
- assertValueIndexIs(diff7, false, 7);
+ // And now, let's merge all the others right to left
- // Left and Right should now be equal
- final EObject leftContainer = diff7.getMatch().getLeft();
- final EObject rightContainer = diff7.getMatch().getRight();
- final List<EObject> leftContents = getAsList(leftContainer, diff7.getReference());
- final List<EObject> rightContents = getAsList(rightContainer, diff7.getReference());
- assertEqualContents(comparison, leftContents, rightContents);
- }
+ // move 6
+ final ReferenceChange rightMoveOfNode6 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ fromSide(DifferenceSource.RIGHT), moved("Root.Node6", "containmentRef1")));
+ mergerRegistry.getHighestRankingMerger(rightMoveOfNode6).copyRightToLeft(rightMoveOfNode6,
+ new BasicMonitor());
+ assertValueIndexIs(rightMoveOfNode6, true, 2);
- @Test
- public void testComplexUseCaseRtoL2() throws IOException {
- final Resource left = conflictInput.getComplexLeft();
- final Resource origin = conflictInput.getComplexOrigin();
- final Resource right = conflictInput.getComplexRight();
+ // left: 816234, right: 62930147
- final IComparisonScope scope = new DefaultComparisonScope(left, right, origin);
- final Comparison comparison = EMFCompare.builder().build().compare(scope);
+ // add 9
+ final ReferenceChange rightAddOfNode9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ fromSide(DifferenceSource.RIGHT), added("Root.Node9")));
+ mergerRegistry.getHighestRankingMerger(rightAddOfNode9).copyRightToLeft(rightAddOfNode9,
+ new BasicMonitor());
+ assertValueIndexIs(rightAddOfNode9, true, 4);
- final List<Diff> differences = comparison.getDifferences();
+ // left: 8162934, right: 62930147
- // "original" is : {Node1, Node2, Node3, Node4, Node5, Node6, Node7}
- // "left" is : {Node8, Node9, Node2, Node3, Node4, Node1, Node0}
- // "right" is : {Node6, Node2, Node9, Node3, Node0, Node1, Node4, Node7}
+ // add 0
+ final ReferenceChange rightAddOfNode0 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ fromSide(DifferenceSource.RIGHT), added("Root.Node0")));
+ mergerRegistry.getHighestRankingMerger(rightAddOfNode0).copyRightToLeft(rightAddOfNode0,
+ new BasicMonitor());
+ assertValueIndexIs(rightAddOfNode0, true, 6);
- // See description of the changes in #testComplexUseCaseLtoR1
- // Merge all, right to left, in arbitrary order. Resolve conflicts by taking right side.
-
- // merge 12 (remove Node5). Merge 5 beforehand.
- final ReferenceChange diff5 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node5")));
- final ReferenceChange diff12 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
- // revert remove in left
- mergerRegistry.getHighestRankingMerger(diff5).copyRightToLeft(diff5, new BasicMonitor());
- assertValueIndexIs(diff5, true, -1);
- mergerRegistry.getHighestRankingMerger(diff12).copyRightToLeft(diff12, new BasicMonitor());
- assertValueIndexIs(diff12, true, -1);
+ // left: 81629304, right: 62930147
- // merge 10 (add Node0). There is a conflict. Merge 4 beforehand.
- final ReferenceChange diff4 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), added("Root.Node0")));
- final ReferenceChange diff10 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), added("Root.Node0")));
- // Revert addition in left
- mergerRegistry.getHighestRankingMerger(diff4).copyRightToLeft(diff4, new BasicMonitor());
- assertValueIndexIs(diff4, true, -1);
- mergerRegistry.getHighestRankingMerger(diff10).copyRightToLeft(diff10, new BasicMonitor());
- assertValueIndexIs(diff10, true, 4);
+ // move 1
+ final ReferenceChange rightMoveOfNode1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ fromSide(DifferenceSource.RIGHT), moved("Root.Node1", "containmentRef1")));
+ mergerRegistry.getHighestRankingMerger(rightMoveOfNode1).copyRightToLeft(rightMoveOfNode1,
+ new BasicMonitor());
+ assertValueIndexIs(rightMoveOfNode1, true, 6);
- // merge 7 (remove Node7). This will re-add Node7
- final ReferenceChange diff7 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node7")));
- mergerRegistry.getHighestRankingMerger(diff7).copyRightToLeft(diff7, new BasicMonitor());
- assertValueIndexIs(diff7, false, 7);
+ // left: 86293014, right: 62930147
- // merge 9 (add Node9). Since there is a conflict, merge 2 right beforehand
- final ReferenceChange diff2 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), added("Root.Node9")));
- final ReferenceChange diff9 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), added("Root.Node9")));
- // Revert addition in left
- mergerRegistry.getHighestRankingMerger(diff2).copyRightToLeft(diff2, new BasicMonitor());
- assertValueIndexIs(diff2, true, -1);
- mergerRegistry.getHighestRankingMerger(diff9).copyRightToLeft(diff9, new BasicMonitor());
- assertValueIndexIs(diff9, true, 2);
+ // remove 5 (again, pseudo-conflict) -> no effect
+ final ReferenceChange rightDeleteOfNode5 = (ReferenceChange)Iterators.find(differences.iterator(),
+ and(fromSide(DifferenceSource.RIGHT), removed("Root.Node5")));
+ mergerRegistry.getHighestRankingMerger(rightDeleteOfNode5).copyRightToLeft(rightDeleteOfNode5,
+ new BasicMonitor());
+ assertValueIndexIs(rightDeleteOfNode5, true, -1);
+
+ // left: 86293014, right: 62930147
- // merge 1 (add Node8). This will remove Node8
- final ReferenceChange diff1 = (ReferenceChange)Iterators.find(differences.iterator(), and(
+ // revert add 8
+ final ReferenceChange leftAddOfNode8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
fromSide(DifferenceSource.LEFT), added("Root.Node8")));
- mergerRegistry.getHighestRankingMerger(diff1).copyRightToLeft(diff1, new BasicMonitor());
- assertValueIndexIs(diff1, false, -1);
+ mergerRegistry.getHighestRankingMerger(leftAddOfNode8).copyRightToLeft(leftAddOfNode8,
+ new BasicMonitor());
+ assertValueIndexIs(leftAddOfNode8, false, -1);
- // merge 8 (move Node6). There is a conflict. Merge 6 beforehand.
- final ReferenceChange diff6 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), removed("Root.Node6")));
- final ReferenceChange diff8 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), moved("Root.Node6", "containmentRef1")));
- // Revert remove of 6 in left.
- mergerRegistry.getHighestRankingMerger(diff6).copyRightToLeft(diff6, new BasicMonitor());
- assertValueIndexIs(diff6, true, 5);
- // apply the move in left
- mergerRegistry.getHighestRankingMerger(diff8).copyRightToLeft(diff8, new BasicMonitor());
- assertValueIndexIs(diff8, true, 0);
+ // left: 6293014, right: 62930147
- // merge 11 (move Node1). Since there is a conflict, merge 3 beforehand
- final ReferenceChange diff3 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.LEFT), moved("Root.Node1", "containmentRef1")));
- final ReferenceChange diff11 = (ReferenceChange)Iterators.find(differences.iterator(), and(
- fromSide(DifferenceSource.RIGHT), moved("Root.Node1", "containmentRef1")));
- // Revert move of 1 in left
- mergerRegistry.getHighestRankingMerger(diff3).copyRightToLeft(diff3, new BasicMonitor());
- assertValueIndexIs(diff3, true, 1);
- mergerRegistry.getHighestRankingMerger(diff11).copyRightToLeft(diff11, new BasicMonitor());
- assertValueIndexIs(diff11, true, 5);
+ // revert delete 7
+ final ReferenceChange leftDeleteOfNode7 = (ReferenceChange)Iterators.find(differences.iterator(),
+ and(fromSide(DifferenceSource.LEFT), removed("Root.Node7")));
+ mergerRegistry.getHighestRankingMerger(leftDeleteOfNode7).copyRightToLeft(leftDeleteOfNode7,
+ new BasicMonitor());
+ assertValueIndexIs(leftDeleteOfNode7, false, 7);
+
+ // left: 62930147, right: 62930147
// Left and Right should now be equal
- final EObject leftContainer = diff7.getMatch().getLeft();
- final EObject rightContainer = diff7.getMatch().getRight();
- final List<EObject> leftContents = getAsList(leftContainer, diff7.getReference());
- final List<EObject> rightContents = getAsList(rightContainer, diff7.getReference());
+ final EObject leftContainer = leftDeleteOfNode7.getMatch().getLeft();
+ final EObject rightContainer = leftDeleteOfNode7.getMatch().getRight();
+ final List<EObject> leftContents = getAsList(leftContainer, leftDeleteOfNode7.getReference());
+ final List<EObject> rightContents = getAsList(rightContainer, leftDeleteOfNode7.getReference());
assertEqualContents(comparison, leftContents, rightContents);
}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AtLeastLunaVersionTests.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AtLeastLunaVersionTests.java
index f427722d4..125bd3abc 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AtLeastLunaVersionTests.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AtLeastLunaVersionTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2015 Obeo and others.
+ * Copyright (c) 2012, 2016 Obeo and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -16,6 +16,7 @@ import junit.textui.TestRunner;
import org.eclipse.emf.compare.ComparePackage;
import org.eclipse.emf.compare.tests.conflict.PseudoConflictDetectionTest;
+import org.eclipse.emf.compare.tests.merge.ComplexMergeTest;
import org.eclipse.emf.compare.tests.merge.ConflictImplicationsTest_Bug484579;
import org.eclipse.emf.compare.tests.nodes.NodesPackage;
import org.eclipse.emf.compare.tests.nodes.util.NodesResourceFactoryImpl;
@@ -33,7 +34,8 @@ import org.junit.runners.Suite.SuiteClasses;
* @author <a href="mailto:mathieu.cartaud@obeo.fr">Mathieu Cartaud</a>
*/
@RunWith(Suite.class)
-@SuiteClasses({ConflictImplicationsTest_Bug484579.class, PseudoConflictDetectionTest.class })
+@SuiteClasses({ConflictImplicationsTest_Bug484579.class, PseudoConflictDetectionTest.class,
+ ComplexMergeTest.class, })
public class AtLeastLunaVersionTests {
/**
* Standalone launcher for all of compare's tests.
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/DiffUtil.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/DiffUtil.java
index 46db2c549..aadb32045 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/DiffUtil.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/internal/utils/DiffUtil.java
@@ -952,7 +952,8 @@ public final class DiffUtil {
expectedContainer = ComparisonUtil.getExpectedSide(targetMatch, diff.getSource(), rightToLeft);
} else {
- if (diff.getKind() == DifferenceKind.DELETE && match.getOrigin() != null) {
+ if (diff.getKind() == DifferenceKind.DELETE && match.getOrigin() != null
+ && rightToLeft == (diff.getSource() == DifferenceSource.LEFT)) {
expectedContainer = match.getOrigin();
} else if (rightToLeft) {
expectedContainer = match.getRight();
@@ -1203,7 +1204,9 @@ public final class DiffUtil {
* @see com.google.common.base.Predicate#apply(java.lang.Object)
*/
public boolean apply(Diff input) {
- return isUnresolved(input) && matchesTarget(input) && matchesValue(input);
+ return isUnresolved(input) && matchesTarget(input) && matchesValue(input)
+ // Probably ADDs in conflict with an ADD at a different index should also be ignored
+ && input.getKind() == DifferenceKind.MOVE;
}
/**

Back to the top