Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Delaigue2016-10-14 10:45:12 -0400
committerLaurent Delaigue2016-10-17 02:12:05 -0400
commitfcdec72a8076a82bb99a3e24a295ac7446864b7a (patch)
treeeb5c5e2d2024a545f1c8e10c8595fdeaed96d485
parent85571f4a0b0ce4ea1edea21d0c817f44a694816a (diff)
downloadorg.eclipse.emf.compare-fcdec72a8076a82bb99a3e24a295ac7446864b7a.tar.gz
org.eclipse.emf.compare-fcdec72a8076a82bb99a3e24a295ac7446864b7a.tar.xz
org.eclipse.emf.compare-fcdec72a8076a82bb99a3e24a295ac7446864b7a.zip
[505994] Fix cascading filter on refined diffs
Refined diffs that are not in direct conflict but have at least on refining diff in REAL conflict should not be filtered out by the cascading filter. bug: 505994 Change-Id: Ife2ccc3d6319e381c16d5d2a5a68295e7a73ac6a Signed-off-by: Laurent Delaigue <laurent.delaigue@obeo.fr>
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/CascadingDiffFilterTest.java206
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/ancestor.ecore3
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/left.ecore7
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/right.ecore3
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/groups/provider/AbstractTestTreeNodeItemProviderAdapter.java2
-rw-r--r--plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java7
6 files changed, 225 insertions, 3 deletions
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/CascadingDiffFilterTest.java b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/CascadingDiffFilterTest.java
new file mode 100644
index 000000000..cc5a92e01
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/CascadingDiffFilterTest.java
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Obeo.
+ * 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.rcp.ui.tests.structuremergeviewer.filters;
+
+import static org.eclipse.emf.compare.ConflictKind.PSEUDO;
+import static org.eclipse.emf.compare.ConflictKind.REAL;
+import static org.eclipse.emf.compare.rcp.ui.tests.structuremergeviewer.groups.provider.AbstractTestTreeNodeItemProviderAdapter.getComparison;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.eclipse.emf.compare.CompareFactory;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Conflict;
+import org.eclipse.emf.compare.ConflictKind;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl.CascadingDifferencesFilter;
+import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.BasicDifferenceGroupImpl;
+import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.DiffNode;
+import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchNode;
+import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchResourceNode;
+import org.eclipse.emf.compare.tests.edit.data.ResourceScopeProvider;
+import org.eclipse.emf.compare.tests.framework.AbstractInputData;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.emf.edit.tree.TreePackage;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Predicates;
+
+@SuppressWarnings("restriction")
+public class CascadingDiffFilterTest {
+
+ private Comparison comp;
+
+ private CascadingDifferencesFilter filter;
+
+ private TestECrossReferenceAdapter crossReferenceAdapter;
+
+ /**
+ * Basic test to make sure the 1st addition is not filtered and its children are.
+ */
+ @Test
+ public void testWithoutRefiningDiffs() {
+ BasicDifferenceGroupImpl group = new BasicDifferenceGroupImpl(comp, Predicates.alwaysTrue(),
+ crossReferenceAdapter);
+ group.buildSubTree();
+ assertEquals(2, group.getChildren().size());
+ MatchNode rootNode = (MatchNode)group.getChildren().get(0);
+ assertTrue(group.getChildren().get(1) instanceof MatchResourceNode);
+
+ assertEquals(1, rootNode.getChildren().size());
+ MatchNode cNode = (MatchNode)rootNode.getChildren().get(0);
+ assertEquals(2, cNode.getChildren().size());
+
+ DiffNode addClassNode = (DiffNode)cNode.getChildren().get(0);
+ assertFalse(filter.getPredicateWhenSelected().apply(addClassNode));
+ assertFalse(filter.getPredicateWhenUnselected().apply(addClassNode));
+
+ MatchNode attNode = (MatchNode)cNode.getChildren().get(1);
+ assertEquals(1, attNode.getChildren().size());
+
+ DiffNode addAttNode = (DiffNode)attNode.getChildren().get(0);
+ assertTrue(filter.getPredicateWhenSelected().apply(addAttNode));
+ assertFalse(filter.getPredicateWhenUnselected().apply(addAttNode));
+ }
+
+ /**
+ * A non-conflicting cascading refined diff is not filtered if it has a real conflict diff among its
+ * refining diffs.
+ */
+ @Test
+ public void testWithRealConflictRefiningDiffs() {
+ Match rootMatch = comp.getMatches().get(0);
+ Match cMatch = rootMatch.getSubmatches().get(0);
+ Match attMatch = cMatch.getSubmatches().get(0);
+ Diff attAddition = cMatch.getDifferences().get(0);
+
+ // Create a refinedDiff refined by the att addition
+ createRefinedDiff(attMatch, attAddition);
+
+ // Create a real conflict on the refining diff
+ createConflict(attAddition, REAL);
+
+ BasicDifferenceGroupImpl group = new BasicDifferenceGroupImpl(comp, Predicates.alwaysTrue(),
+ crossReferenceAdapter);
+ group.buildSubTree();
+ assertEquals(2, group.getChildren().size());
+ MatchNode rootNode = (MatchNode)group.getChildren().get(0);
+ assertTrue(group.getChildren().get(1) instanceof MatchResourceNode);
+
+ assertEquals(1, rootNode.getChildren().size());
+ MatchNode cNode = (MatchNode)rootNode.getChildren().get(0);
+ assertEquals(2, cNode.getChildren().size());
+
+ DiffNode addClassNode = (DiffNode)cNode.getChildren().get(0);
+ assertFalse(filter.getPredicateWhenSelected().apply(addClassNode));
+ assertFalse(filter.getPredicateWhenUnselected().apply(addClassNode));
+
+ MatchNode attNode = (MatchNode)cNode.getChildren().get(1);
+ assertEquals(1, attNode.getChildren().size());
+
+ DiffNode refinedDiffNode = (DiffNode)attNode.getChildren().get(0);
+ assertFalse(filter.getPredicateWhenSelected().apply(refinedDiffNode));
+ assertFalse(filter.getPredicateWhenUnselected().apply(refinedDiffNode));
+ assertEquals(1, refinedDiffNode.getChildren().size());
+
+ // It's useless to test on the refining diff since filters are not applied on refining diffs
+ }
+
+ /**
+ * A non-conflicting cascading refined diff is filtered if it has some pseudo but no real conflict diff
+ * among its refining diffs.
+ */
+ @Test
+ public void testWithPseudoConflictRefiningDiffs() {
+ Match rootMatch = comp.getMatches().get(0);
+ Match cMatch = rootMatch.getSubmatches().get(0);
+ Match attMatch = cMatch.getSubmatches().get(0);
+ Diff attAddition = cMatch.getDifferences().get(0);
+
+ createRefinedDiff(attMatch, attAddition);
+
+ createConflict(attAddition, PSEUDO);
+
+ BasicDifferenceGroupImpl group = new BasicDifferenceGroupImpl(comp, Predicates.alwaysTrue(),
+ crossReferenceAdapter);
+ group.buildSubTree();
+ assertEquals(2, group.getChildren().size());
+ MatchNode rootNode = (MatchNode)group.getChildren().get(0);
+ assertTrue(group.getChildren().get(1) instanceof MatchResourceNode);
+
+ assertEquals(1, rootNode.getChildren().size());
+ MatchNode cNode = (MatchNode)rootNode.getChildren().get(0);
+ assertEquals(2, cNode.getChildren().size());
+
+ DiffNode addClassNode = (DiffNode)cNode.getChildren().get(0);
+ assertFalse(filter.getPredicateWhenSelected().apply(addClassNode));
+ assertFalse(filter.getPredicateWhenUnselected().apply(addClassNode));
+
+ MatchNode attNode = (MatchNode)cNode.getChildren().get(1);
+ assertEquals(1, attNode.getChildren().size());
+
+ DiffNode refinedDiffNode = (DiffNode)attNode.getChildren().get(0);
+ assertTrue(filter.getPredicateWhenSelected().apply(refinedDiffNode));
+ assertFalse(filter.getPredicateWhenUnselected().apply(refinedDiffNode));
+ assertEquals(1, refinedDiffNode.getChildren().size());
+
+ // It's useless to test on the refining diff since filters are not applied on refining diffs
+ }
+
+ protected void createConflict(Diff attAddition, ConflictKind kind) {
+ Conflict conflict = CompareFactory.eINSTANCE.createConflict();
+ conflict.setKind(kind);
+ conflict.getDifferences().add(attAddition);
+ comp.getConflicts().add(conflict);
+ }
+
+ protected void createRefinedDiff(Match attMatch, Diff attAddition) {
+ Diff refinedDiff = CompareFactory.eINSTANCE.createDiff();
+ refinedDiff.getRefinedBy().add(attAddition);
+ attMatch.getDifferences().add(refinedDiff);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ comp = getComparison(new CascadingScope());
+ crossReferenceAdapter = new TestECrossReferenceAdapter();
+ filter = new CascadingDifferencesFilter();
+ }
+
+ private class TestECrossReferenceAdapter extends ECrossReferenceAdapter {
+ @Override
+ protected boolean isIncluded(EReference eReference) {
+ return eReference == TreePackage.Literals.TREE_NODE__DATA;
+ }
+ }
+
+ public class CascadingScope extends AbstractInputData implements ResourceScopeProvider {
+
+ public Resource getOrigin() throws IOException {
+ return loadFromClassLoader("data/cascading/ancestor.ecore");//$NON-NLS-1$
+ }
+
+ public Resource getLeft() throws IOException {
+ return loadFromClassLoader("data/cascading/left.ecore");//$NON-NLS-1$
+ }
+
+ public Resource getRight() throws IOException {
+ return loadFromClassLoader("data/cascading/right.ecore");//$NON-NLS-1$
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/ancestor.ecore b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/ancestor.ecore
new file mode 100644
index 000000000..8dbb83c21
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/ancestor.ecore
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ name="root" xmi:id="_root"/>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/left.ecore b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/left.ecore
new file mode 100644
index 000000000..70ad02ab5
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/left.ecore
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="root" xmi:id="_root">
+ <eClassifiers xsi:type="ecore:EClass" name="c" xmi:id="_c">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="att" xmi:id="_att"/>
+ </eClassifiers>
+</ecore:EPackage>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/right.ecore b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/right.ecore
new file mode 100644
index 000000000..8dbb83c21
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/filters/data/cascading/right.ecore
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+ name="root" xmi:id="_root"/>
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/groups/provider/AbstractTestTreeNodeItemProviderAdapter.java b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/groups/provider/AbstractTestTreeNodeItemProviderAdapter.java
index 4db1cb666..b204c8e0e 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/groups/provider/AbstractTestTreeNodeItemProviderAdapter.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui.tests/src/org/eclipse/emf/compare/rcp/ui/tests/structuremergeviewer/groups/provider/AbstractTestTreeNodeItemProviderAdapter.java
@@ -61,7 +61,7 @@ public class AbstractTestTreeNodeItemProviderAdapter {
* @return the comparison
* @throws IOException
*/
- protected static Comparison getComparison(ResourceScopeProvider scopeProvider) throws IOException {
+ public static Comparison getComparison(ResourceScopeProvider scopeProvider) throws IOException {
final IComparisonScope scope = new DefaultComparisonScope(scopeProvider.getLeft(),
scopeProvider.getRight(), scopeProvider.getOrigin());
final Builder builder = EMFCompare.builder();
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java
index c40ea814b..aa2fb2562 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/filters/impl/CascadingDifferencesFilter.java
@@ -12,6 +12,7 @@ package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.imp
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.or;
+import static org.eclipse.emf.compare.ConflictKind.REAL;
import static org.eclipse.emf.compare.DifferenceKind.ADD;
import static org.eclipse.emf.compare.DifferenceKind.DELETE;
import static org.eclipse.emf.compare.DifferenceKind.MOVE;
@@ -19,6 +20,7 @@ import static org.eclipse.emf.compare.DifferenceSource.LEFT;
import static org.eclipse.emf.compare.DifferenceSource.RIGHT;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.CONTAINMENT_REFERENCE_CHANGE;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide;
+import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasNoDirectOrIndirectConflict;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind;
import com.google.common.base.Predicate;
@@ -41,7 +43,7 @@ import org.eclipse.emf.edit.tree.TreeNode;
* Differences hidden are all those that match the following criteria:
* <ul>
* <li>this.kind != MOVE</li>
- * <li>this.conflict == null</li>
+ * <li>this.conflict == null && this.'indirect real conflicts' is empty</li>
* <li>this.refines is empty</li>
* <li>this is located inside a TreeNode that represents a Match that is either ADDed or DELETEd, and for
* which the diff that represents this addition or deletion is not refined by this.</li>
@@ -63,7 +65,8 @@ public class CascadingDifferencesFilter extends AbstractDifferenceFilter {
EObject data = treeNode.getData();
if (data instanceof Diff && !(data instanceof ResourceAttachmentChange)) {
Diff diff = (Diff)data;
- if (diff.getKind() != MOVE && diff.getConflict() == null && diff.getRefines().isEmpty()) {
+ if (diff.getKind() != MOVE && hasNoDirectOrIndirectConflict(REAL).apply(diff)
+ && diff.getRefines().isEmpty()) {
TreeNode parent = treeNode.getParent();
if (parent != null && parent.getData() instanceof Match) {
Match parentMatch = (Match)parent.getData();

Back to the top