blob: f5cc65a2988b40bc4bde7bb687f765d1fb60fc7c [file] [log] [blame]
/*******************************************************************************
* 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
* Tanja Mayerhofer - bug 501864
*******************************************************************************/
package org.eclipse.emf.compare.rcp.ui.tests.structuremergeviewer.groups;
import static com.google.common.base.Predicates.and;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.fromSide;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
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.DifferenceSource;
import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.StructureMergeViewerFilter;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl.TechnicalitiesFilter;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.BasicDifferenceGroupImpl;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.ThreeWayComparisonGroupProvider;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.ThreeWayComparisonGroupProvider.CompositeConflict;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.ThreeWayComparisonGroupProvider.ConflictsGroupImpl;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.ConflictNode;
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.tests.structuremergeviewer.groups.provider.AbstractTestTreeNodeItemProviderAdapter;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.edit.tree.TreeNode;
import org.eclipse.emf.edit.tree.TreePackage;
import org.junit.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus;
@SuppressWarnings("restriction")
public class ConflictsGroupTest extends AbstractTestTreeNodeItemProviderAdapter {
private static final CompareFactory FACTORY = CompareFactory.eINSTANCE;
private ECrossReferenceAdapter crossReferenceAdapter;
@Override
public void before() throws IOException {
super.before();
crossReferenceAdapter = new TestECrossReferenceAdapter();
}
/**
* Tests that multiple conflicts containing overlapping diffs are merged in the SMV. Overlapping diffs can
* happen due to the replacement of refining diffs with their refined diffs in the SMV. This test is
* related to <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=501864"</a>
*/
@Test
public void testMergingMultipleConflictsWithOverlappingDiffs() {
// Create diffs
final Diff diff1 = FACTORY.createDiff();
final Diff diff1a = FACTORY.createDiff();
final Diff diff1b = FACTORY.createDiff();
diff1.getRefinedBy().add(diff1a);
diff1.getRefinedBy().add(diff1b);
final Diff diff2 = FACTORY.createDiff();
final Diff diff3 = FACTORY.createDiff();
final Diff diff3a = FACTORY.createDiff();
final Diff diff3b = FACTORY.createDiff();
diff3.getRefinedBy().add(diff3a);
diff3.getRefinedBy().add(diff3b);
final Diff diff4 = FACTORY.createDiff();
// Create overlapping conflicts
Conflict conflict1 = FACTORY.createConflict();
conflict1.getDifferences().add(diff1a);
conflict1.getDifferences().add(diff2);
Conflict conflict2 = FACTORY.createConflict();
conflict2.getDifferences().add(diff3a);
conflict2.getDifferences().add(diff4);
Conflict conflict3 = FACTORY.createConflict();
conflict3.getDifferences().add(diff1b);
conflict3.getDifferences().add(diff3b);
// Create comparison
final Comparison comparison = FACTORY.createComparison();
comparison.getConflicts().add(conflict1);
comparison.getConflicts().add(conflict2);
comparison.getConflicts().add(conflict3);
// Build conflict nodes
final ConflictsGroupImpl conflictsGroup = buildConflictGroup(comparison);
// One conflict node was created
List<? extends TreeNode> conflictNodes = conflictsGroup.getChildren();
assertEquals(1, conflictNodes.size());
// The conflict node groups the three created conflicts
ConflictNode conflictNode = (ConflictNode)conflictNodes.get(0);
CompositeConflict compositeConflict = (CompositeConflict)conflictNode.basicGetData();
assertEquals(3, compositeConflict.getConflicts().size());
// The composite conflict contains all refined diffs
EList<Diff> differences = compositeConflict.getDifferences();
assertEquals(4, differences.size());
assertTrue(differences.contains(diff1));
assertTrue(differences.contains(diff2));
assertTrue(differences.contains(diff3));
assertTrue(differences.contains(diff4));
}
/**
* Tests that a composite conflict has the conflict kind {@link ConflictKind#REAL} if it contains at least
* one conflict of conflict kind {@link ConflictKind#REAL}. This test is related to <a
* href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=501864"</a>
*/
@Test
public void testDerivationOfConflictGroupKindReal() {
final Conflict realConflict = FACTORY.createConflict();
realConflict.setKind(ConflictKind.REAL);
final Conflict pseudoConflict = FACTORY.createConflict();
pseudoConflict.setKind(ConflictKind.PSEUDO);
final CompositeConflict realCompositeConflict = new CompositeConflict(realConflict);
assertEquals(ConflictKind.REAL, realCompositeConflict.getKind());
final CompositeConflict pseudoCompositeConflict = new CompositeConflict(pseudoConflict);
assertEquals(ConflictKind.PSEUDO, pseudoCompositeConflict.getKind());
// The union of one real conflict and one pseudo conflict results in a composite conflict with
// conflict kind real
pseudoCompositeConflict.join(realCompositeConflict);
final CompositeConflict mergedConflictGroup = pseudoCompositeConflict;
assertEquals(2, mergedConflictGroup.getConflicts().size());
assertTrue(mergedConflictGroup.getConflicts().contains(realConflict));
assertTrue(mergedConflictGroup.getConflicts().contains(pseudoConflict));
assertEquals(ConflictKind.REAL, mergedConflictGroup.getKind());
}
/**
* Tests that a composite conflict has the conflict kind {@link ConflictKind#PSEUDO} if it contains only
* conflicts of conflict kind {@link ConflictKind#PSEUDO}. This test is related to <a
* href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=501864"</a>
*/
@Test
public void testDerivationOfConflictGroupKindPseudo() {
final Conflict pseudoConflict1 = FACTORY.createConflict();
pseudoConflict1.setKind(ConflictKind.PSEUDO);
final Conflict pseudoConflict2 = FACTORY.createConflict();
pseudoConflict2.setKind(ConflictKind.PSEUDO);
final CompositeConflict pseudoCompositeConflict1 = new CompositeConflict(pseudoConflict1);
assertEquals(ConflictKind.PSEUDO, pseudoCompositeConflict1.getKind());
final CompositeConflict pseudoCompositeConflict2 = new CompositeConflict(pseudoConflict2);
assertEquals(ConflictKind.PSEUDO, pseudoCompositeConflict2.getKind());
// The union of pseudo conflicts results in a composite conflict with conflict kind pseudo
pseudoCompositeConflict2.join(pseudoCompositeConflict1);
final CompositeConflict mergedConflictGroup = pseudoCompositeConflict2;
assertEquals(2, mergedConflictGroup.getConflicts().size());
assertTrue(mergedConflictGroup.getConflicts().contains(pseudoConflict1));
assertTrue(mergedConflictGroup.getConflicts().contains(pseudoConflict2));
assertEquals(ConflictKind.PSEUDO, mergedConflictGroup.getKind());
}
/**
* Tests that a refined diff whose refinding diffs are involved in a real conflict
* {@link ConflictKind#REAL} is only shown in the conflicts group but not in the left or right diff group.
* This test is related to <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=501864"</a>
*/
@Test
public void testRefinedDiffsWithRealConflictsAreOnlyInConflictGroup() {
ConflictsGroupWithRefinedDiffTestScenario scenario = new ConflictsGroupWithRefinedDiffTestScenario();
// Create real conflict between refining diffs
final Conflict conflict = scenario.addConflict(scenario.diff1b, scenario.diff2b, ConflictKind.REAL);
// Build conflict nodes
final ConflictsGroupImpl conflictsGroup = buildConflictGroup(scenario.comparison);
// One conflict node was created
final List<? extends TreeNode> conflictNodes = conflictsGroup.getChildren();
assertEquals(1, conflictNodes.size());
// The conflict node is associated with the created conflict
final ConflictNode conflictNode = (ConflictNode)conflictNodes.get(0);
final CompositeConflict conflictNodeConflict = (CompositeConflict)conflictNode.basicGetData();
assertEquals(1, conflictNodeConflict.getConflicts().size());
assertTrue(conflictNodeConflict.getConflicts().contains(conflict));
// The conflict node contains diff nodes for the refined diffs
assertEquals(1, conflictNode.getChildren().size());
final MatchNode matchNode = (MatchNode)conflictNode.getChildren().get(0);
assertTrue(matchNodeContainsDiffNodesForDiffs(matchNode, scenario.diff1, scenario.diff2));
// The technicalities filter does not filter this conflict, because there is a real conflict between
// the refining diffs
final List<? extends TreeNode> conflictDiffNodesFiltered = applyTechnicalitiesFilter(
matchNode.getChildren());
assertEquals(2, conflictDiffNodesFiltered.size());
// Build left side
final BasicDifferenceGroupImpl leftSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.LEFT);
// There are no diffs in the left side
assertEquals(0, leftSide.getChildren().size());
// Build right side
final BasicDifferenceGroupImpl rightSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.RIGHT);
// There are no diffs in the right side
assertEquals(0, rightSide.getChildren().size());
}
/**
* Tests that a refined diff whose refining diffs are involved in a real conflict
* {@link ConflictKind#REAL} and in a pseudo conflict {@link ConflictKind#REAL} is only shown in the
* conflicts group but not in the left or right diff group. This test is related to <a
* href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=501864"</a>
*/
@Test
public void testRefinedDiffsWithRealAndPseudoConflictsAreOnlyInConflictGroup() {
ConflictsGroupWithRefinedDiffTestScenario scenario = new ConflictsGroupWithRefinedDiffTestScenario();
// Create real conflict between refining diffs
final Conflict conflictReal = scenario.addConflict(scenario.diff1b, scenario.diff2b,
ConflictKind.REAL);
// Create pseudo conflict between refining diffs
final Conflict conflictPseudo = scenario.addConflict(scenario.diff1a, scenario.diff2a,
ConflictKind.PSEUDO);
// Build conflict nodes
final ConflictsGroupImpl conflictsGroup = buildConflictGroup(scenario.comparison);
// One conflict node was created
final List<? extends TreeNode> conflictNodes = conflictsGroup.getChildren();
assertEquals(1, conflictNodes.size());
// The conflict node is associated with the created conflicts
final ConflictNode conflictNode = (ConflictNode)conflictNodes.get(0);
final CompositeConflict conflictNodeConflict = (CompositeConflict)conflictNode.basicGetData();
assertEquals(2, conflictNodeConflict.getConflicts().size());
assertTrue(conflictNodeConflict.getConflicts().contains(conflictReal));
assertTrue(conflictNodeConflict.getConflicts().contains(conflictPseudo));
// The conflict node contains diff nodes for the refined diffs
assertEquals(1, conflictNode.getChildren().size());
final MatchNode matchNode = (MatchNode)conflictNode.getChildren().get(0);
assertTrue(matchNodeContainsDiffNodesForDiffs(matchNode, scenario.diff1, scenario.diff2));
// The technicalities filter does not filter this conflict, because there is a real conflict between
// the refining diffs
final List<? extends TreeNode> conflictDiffNodesFiltered = applyTechnicalitiesFilter(
matchNode.getChildren());
assertEquals(2, conflictDiffNodesFiltered.size());
// Build left side
final BasicDifferenceGroupImpl leftSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.LEFT);
// There are no diffs in the left side
assertEquals(0, leftSide.getChildren().size());
// Build right side
final BasicDifferenceGroupImpl rightSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.RIGHT);
// There are no diffs in the right side
assertEquals(0, rightSide.getChildren().size());
}
/**
* Tests that a refined diff that is refined by diffs who are all involved in pseudo conflicts
* {@link ConflictKind#REAL} is only shown in the conflicts group but not in the left or right diff group.
* This test is related to <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=501864"</a>
*/
@Test
public void testRefinedDiffsWithOnlyPseudoConflictsAreOnlyInConflictGroup() {
ConflictsGroupWithRefinedDiffTestScenario scenario = new ConflictsGroupWithRefinedDiffTestScenario();
// Create pseudo conflicts between refining diffs
final Conflict conflictPseudo1 = scenario.addConflict(scenario.diff1b, scenario.diff2b,
ConflictKind.PSEUDO);
final Conflict conflictPseudo2 = scenario.addConflict(scenario.diff1a, scenario.diff2a,
ConflictKind.PSEUDO);
// Build conflict nodes
final ConflictsGroupImpl conflictsGroup = buildConflictGroup(scenario.comparison);
// One conflict node was created
final List<? extends TreeNode> conflictNodes = conflictsGroup.getChildren();
assertEquals(1, conflictNodes.size());
// The conflict node is associated with the created conflicts
final ConflictNode conflictNode = (ConflictNode)conflictNodes.get(0);
final CompositeConflict conflictNodeConflict = (CompositeConflict)conflictNode.basicGetData();
assertEquals(2, conflictNodeConflict.getConflicts().size());
assertTrue(conflictNodeConflict.getConflicts().contains(conflictPseudo1));
assertTrue(conflictNodeConflict.getConflicts().contains(conflictPseudo2));
// The conflict node contains diff nodes for the refined diffs
assertEquals(1, conflictNode.getChildren().size());
final MatchNode matchNode = (MatchNode)conflictNode.getChildren().get(0);
assertTrue(matchNodeContainsDiffNodesForDiffs(matchNode, scenario.diff1, scenario.diff2));
// The technicalities filter filters this conflict, since the involved refined diffs are refined by
// diffs that are all involved in pseudo conflicts
final List<? extends TreeNode> conflictDiffNodesFiltered = applyTechnicalitiesFilter(
matchNode.getChildren());
assertEquals(0, conflictDiffNodesFiltered.size());
// Build left side
final BasicDifferenceGroupImpl leftSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.LEFT);
// There are no diffs in the left side
assertEquals(0, leftSide.getChildren().size());
// Build right side
final BasicDifferenceGroupImpl rightSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.RIGHT);
// There are no diffs in the right side
assertEquals(0, rightSide.getChildren().size());
}
/**
* Tests that a refined diff that is refined by one diff involved in a pseudo conflict
* {@link ConflictKind#PSEUDO} and one diff involved in no conflict is shown only in the side group. This
* test is related to <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=501864"</a>
*/
@Test
public void testRefinedDiffsWithOnlyOnePseudoConflictAreInDiffGroupOnly() {
ConflictsGroupWithRefinedDiffTestScenario scenario = new ConflictsGroupWithRefinedDiffTestScenario();
// Create pseudo conflict
final Conflict conflictPseudo = scenario.addConflict(scenario.diff1b, scenario.diff2b,
ConflictKind.PSEUDO);
// Build conflict nodes
final ConflictsGroupImpl conflictsGroup = buildConflictGroup(scenario.comparison);
// One conflict node was created
List<? extends TreeNode> conflictNodes = conflictsGroup.getChildren();
assertEquals(1, conflictNodes.size());
// The conflict node is associated with the created conflict
ConflictNode conflictNode = (ConflictNode)conflictNodes.get(0);
CompositeConflict conflictNodeConflict = (CompositeConflict)conflictNode.basicGetData();
assertEquals(1, conflictNodeConflict.getConflicts().size());
assertTrue(conflictNodeConflict.getConflicts().contains(conflictPseudo));
// The conflict node contains diff nodes for the refined diffs
assertEquals(1, conflictNode.getChildren().size());
MatchNode matchNode = (MatchNode)conflictNode.getChildren().get(0);
assertTrue(matchNodeContainsDiffNodesForDiffs(matchNode, scenario.diff1, scenario.diff2));
// The technicalities filter does not filter this conflict, because it involved a refined diff that is
// refined by a diff that is not involved in a conflict
final List<? extends TreeNode> conflictDiffNodesFiltered = applyTechnicalitiesFilter(
matchNode.getChildren());
assertEquals(2, conflictDiffNodesFiltered.size());
// Build left side
final BasicDifferenceGroupImpl leftSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.LEFT);
// There is one refined diff in the left side, which is refined by one diff that is not in a conflict
// and one diff that is in a PSEUDO conflict
assertEquals(1, leftSide.getChildren().size());
MatchNode matchNodeLeft = (MatchNode)leftSide.getChildren().get(0);
assertTrue(matchNodeContainsDiffNodesForDiffs(matchNodeLeft, scenario.diff1));
// The technicalities filter does not filter the changes on the left side, because the refined diff is
// refined by a diff that is not involved in a conflict
final List<? extends TreeNode> diffNodesLeftFiltered = applyTechnicalitiesFilter(
matchNodeLeft.getChildren());
assertEquals(1, diffNodesLeftFiltered.size());
final List<? extends TreeNode> subDiffNodesLeftFiltered = applyTechnicalitiesFilter(
diffNodesLeftFiltered.get(0).getChildren());
assertEquals(1, subDiffNodesLeftFiltered.size());
// Build right side
final BasicDifferenceGroupImpl rightSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.RIGHT);
// There is one refined diff in the right side, which is refined by one diff that is not in a conflict
// and one diff that is in a PSEUDO conflict
assertEquals(1, rightSide.getChildren().size());
MatchNode matchNodeRight = (MatchNode)rightSide.getChildren().get(0);
assertTrue(matchNodeContainsDiffNodesForDiffs(matchNodeRight, scenario.diff2));
// The technicalities filter does not filter the changes on the right side, because the refined diff
// is refined by a diff that is not involved in a conflict
final List<? extends TreeNode> diffNodesRightFiltered = applyTechnicalitiesFilter(
matchNodeRight.getChildren());
assertEquals(1, diffNodesRightFiltered.size());
final List<? extends TreeNode> subDiffNodesRightFiltered = applyTechnicalitiesFilter(
diffNodesRightFiltered.get(0).getChildren());
assertEquals(1, subDiffNodesRightFiltered.size());
}
/**
* Tests that a refined diff that is directly involved in a pseudo conflict {@link ConflictKind#PSEUDO}
* and that is refined by one diff involved in a real conflict {@link ConflictKind#REAL} is shown in the
* conflicts group. This test is related to <a
* href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=501864"</a>
*/
@Test
public void testRefinedDiffsInPseudoConflictAndWithRefiningDiffsInRealConflictAreInConflictGroup() {
ConflictsGroupWithRefinedDiffTestScenario scenario = new ConflictsGroupWithRefinedDiffTestScenario();
// Create pseudo conflict
final Conflict conflictPseudo = scenario.addConflict(scenario.diff1, scenario.diff2,
ConflictKind.PSEUDO);
// Create real conflict
final Conflict conflictReal = scenario.addConflict(scenario.diff1b, scenario.diff2b,
ConflictKind.REAL);
// Build conflict nodes
final ConflictsGroupImpl conflictsGroup = buildConflictGroup(scenario.comparison);
// One conflict node was created
List<? extends TreeNode> conflictNodes = conflictsGroup.getChildren();
assertEquals(1, conflictNodes.size());
// The conflict node is associated with both created conflicts
ConflictNode conflictNode = (ConflictNode)conflictNodes.get(0);
CompositeConflict conflictNodeConflict = (CompositeConflict)conflictNode.basicGetData();
assertEquals(2, conflictNodeConflict.getConflicts().size());
assertTrue(conflictNodeConflict.getConflicts().contains(conflictPseudo));
assertTrue(conflictNodeConflict.getConflicts().contains(conflictReal));
// The conflict node contains diff nodes for the refined diffs
assertEquals(1, conflictNode.getChildren().size());
MatchNode matchNode = (MatchNode)conflictNode.getChildren().get(0);
assertTrue(matchNodeContainsDiffNodesForDiffs(matchNode, scenario.diff1, scenario.diff2));
// The technicalities filter does not filter this conflict, because there is a real conflict between
// the refining diffs
final List<? extends TreeNode> conflictDiffNodesFiltered = applyTechnicalitiesFilter(
matchNode.getChildren());
assertEquals(2, conflictDiffNodesFiltered.size());
// Build left side
final BasicDifferenceGroupImpl leftSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.LEFT);
// There are no diffs in the left side
assertEquals(0, leftSide.getChildren().size());
// Build right side
final BasicDifferenceGroupImpl rightSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.RIGHT);
// There are no diffs in the right side
assertEquals(0, rightSide.getChildren().size());
}
/**
* Tests that a refined diff that is neither directly nor indirect involved in any conflict is shown in
* the left or right diff group. This test is related to <a
* href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=501864"</a>
*/
@Test
public void testRefinedDiffsWithoutConfictsAreInDiffGroup() {
ConflictsGroupWithRefinedDiffTestScenario scenario = new ConflictsGroupWithRefinedDiffTestScenario();
// Build conflict nodes
final ConflictsGroupImpl conflictsGroup = buildConflictGroup(scenario.comparison);
// No conflict node was created
assertEquals(0, conflictsGroup.getChildren().size());
// Build left side
final BasicDifferenceGroupImpl leftSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.LEFT);
// There is one refined diff in the left side, which is neither directly nor indirectly involved in a
// conflict
assertEquals(1, leftSide.getChildren().size());
MatchNode matchNodeLeft = (MatchNode)leftSide.getChildren().get(0);
assertTrue(matchNodeContainsDiffNodesForDiffs(matchNodeLeft, scenario.diff1));
// The technicalities filter does not filter the changes on the left side, because they are not
// involved in conflicts
final List<? extends TreeNode> diffNodesLeftFiltered = applyTechnicalitiesFilter(
matchNodeLeft.getChildren());
assertEquals(1, diffNodesLeftFiltered.size());
final List<? extends TreeNode> subDiffNodesLeftFiltered = applyTechnicalitiesFilter(
diffNodesLeftFiltered.get(0).getChildren());
assertEquals(2, subDiffNodesLeftFiltered.size());
// Build right side
final BasicDifferenceGroupImpl rightSide = buildDifferenceGroup(scenario.comparison,
DifferenceSource.RIGHT);
// There is one refined diff in the right side, which is neither directly nor indirectly involved in a
// conflict
assertEquals(1, rightSide.getChildren().size());
MatchNode matchNodeRight = (MatchNode)rightSide.getChildren().get(0);
assertTrue(matchNodeContainsDiffNodesForDiffs(matchNodeRight, scenario.diff2));
// The technicalities filter does not filter the changes on the right side, because they are not
// involved in conflicts
final List<? extends TreeNode> diffNodesRightFiltered = applyTechnicalitiesFilter(
matchNodeRight.getChildren());
assertEquals(1, diffNodesRightFiltered.size());
final List<? extends TreeNode> subDiffNodesRightFiltered = applyTechnicalitiesFilter(
diffNodesRightFiltered.get(0).getChildren());
assertEquals(2, subDiffNodesRightFiltered.size());
}
private class TestECrossReferenceAdapter extends ECrossReferenceAdapter {
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.ecore.util.ECrossReferenceAdapter#isIncluded(org.eclipse.emf.ecore.EReference)
*/
@Override
protected boolean isIncluded(EReference eReference) {
return eReference == TreePackage.Literals.TREE_NODE__DATA;
}
}
private ConflictsGroupImpl buildConflictGroup(Comparison comparison) {
final ConflictsGroupImpl conflictsGroup = new ConflictsGroupImpl(comparison,
EMFCompareRCPUIMessages.getString("ThreeWayComparisonGroupProvider.conflicts.label"), //$NON-NLS-1$
crossReferenceAdapter);
conflictsGroup.buildSubTree();
return conflictsGroup;
}
private BasicDifferenceGroupImpl buildDifferenceGroup(Comparison comparison, DifferenceSource source) {
final BasicDifferenceGroupImpl differenceGroup = new BasicDifferenceGroupImpl(comparison,
and(fromSide(source), ThreeWayComparisonGroupProvider.DEFAULT_DIFF_GROUP_FILTER_PREDICATE),
"", crossReferenceAdapter);
differenceGroup.buildSubTree();
return differenceGroup;
}
private boolean matchNodeContainsDiffNodesForDiffs(MatchNode matchNode, Diff... diffs) {
final boolean matchNodeContainsRightAmountOfChildren = matchNode.getChildren().size() == diffs.length;
boolean matchNodeContainsDiffNodesForDiffs = true;
for (Diff diff : diffs) {
DiffNode diffNode = getDiffNode(matchNode.getChildren(), diff);
if (!isDiffNodeForDiff(diffNode, diff)) {
matchNodeContainsDiffNodesForDiffs = false;
}
}
return matchNodeContainsRightAmountOfChildren && matchNodeContainsDiffNodesForDiffs;
}
private DiffNode getDiffNode(EList<TreeNode> nodes, Diff diff) {
for (TreeNode node : nodes) {
if (node instanceof DiffNode) {
DiffNode diffNode = (DiffNode)node;
if (diffNode.basicGetData() == diff) {
return diffNode;
}
}
}
return null;
}
private boolean isDiffNodeForDiff(DiffNode diffNode, Diff diff) {
if (diffNode == null || diff == null) {
return false;
}
final boolean diffNodeAssociatedWithDiff = diffNode.basicGetData() == diff;
final boolean diffNodeContainsRightAmountOfChildren = diffNode.getChildren().size() == diff
.getRefinedBy().size();
boolean diffNodeContainsNodesForRefiningDiffs = true;
for (Diff refiningDiff : diff.getRefinedBy()) {
final DiffNode diffNodeForRefiningDiff = getDiffNode(diffNode.getChildren(), refiningDiff);
if (diffNodeForRefiningDiff == null) {
diffNodeContainsNodesForRefiningDiffs = false;
}
}
return diffNodeAssociatedWithDiff && diffNodeContainsRightAmountOfChildren
&& diffNodeContainsNodesForRefiningDiffs;
}
private List<? extends TreeNode> applyTechnicalitiesFilter(List<? extends TreeNode> actualTrees) {
final StructureMergeViewerFilter filter = new StructureMergeViewerFilter(new EventBus());
final TechnicalitiesFilter technicalitiesFilter = new TechnicalitiesFilter();
filter.addFilter(technicalitiesFilter);
Predicate<EObject> viewerFilterPredicate = new Predicate<EObject>() {
public boolean apply(EObject input) {
AdapterImpl adapter = new AdapterImpl();
adapter.setTarget(input);
return filter.select(null, null, adapter);
}
};
List<? extends TreeNode> filteredTrees = Lists
.newArrayList(Collections2.filter(actualTrees, viewerFilterPredicate));
return filteredTrees;
}
}