[434828] Test Merge Conflict Diff With Conflicting Diff With RequiredBy
[EMFCompare2.git] / plugins / org.eclipse.emf.compare.ide.ui.tests / src / org / eclipse / emf / compare / ide / ui / tests / structuremergeviewer / actions / TestBug434828.java
blob3f1367fbcabef09cb4271077df5808689b0d58ed
1 /*******************************************************************************
2 * Copyright (c) 2014 Obeo.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Obeo - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.emf.compare.ide.ui.tests.structuremergeviewer.actions;
13 import java.io.IOException;
14 import java.util.Collections;
16 import org.eclipse.emf.common.util.BasicMonitor;
17 import org.eclipse.emf.common.util.EList;
18 import org.eclipse.emf.compare.Comparison;
19 import org.eclipse.emf.compare.Conflict;
20 import org.eclipse.emf.compare.Diff;
21 import org.eclipse.emf.compare.DifferenceState;
22 import org.eclipse.emf.compare.EMFCompare;
23 import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.actions.MergeRunnableImpl;
24 import org.eclipse.emf.compare.internal.merge.IMergeData;
25 import org.eclipse.emf.compare.internal.merge.MergeMode;
26 import org.eclipse.emf.compare.merge.IMerger;
27 import org.eclipse.emf.compare.rcp.EMFCompareRCPPlugin;
28 import org.eclipse.emf.compare.scope.DefaultComparisonScope;
29 import org.eclipse.emf.compare.tests.framework.AbstractInputData;
30 import org.eclipse.emf.compare.tests.nodes.Node;
31 import org.eclipse.emf.ecore.EObject;
32 import org.eclipse.emf.ecore.resource.Resource;
33 import org.eclipse.emf.ecore.util.EcoreUtil;
34 import org.junit.Assert;
35 import org.junit.Before;
36 import org.junit.Test;
38 /**
39 * This test is related to the bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=434827">434827</a>
41 * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
43 @SuppressWarnings("restriction")
44 public class TestBug434828 {
46 private IMerger.Registry mergerRegistry;
48 private DefaultComparisonScope scope;
50 private Diff deletedNodeDeletionDiff;
52 private Diff holdingRefDeletionDiff;
54 private Diff refChangeDiff;
56 /**
57 * Set up the model comparison with the following use case:
58 * <p>
59 * The 3 models loaded are:
60 * <ul>
61 * <li>Origin which contains 3 nodes structured like this:
63 * <pre>
64 * Root - DeletedNode - ReferencedNode
65 * \ - HoldingReferenceNode
66 * </pre>
68 * </li>
69 * <li>Left that has an extra eopposite reference between "HoldingReference" and "ReferencedNode"</li>
70 * <li>Right in which "DeletedNode" has been deleted"</li>
71 * </ul>
72 * </p>
74 * @throws IOException
76 @Before
77 public void setUp() throws IOException {
78 Bug434828InputData inputData = new Bug434828InputData();
79 final Resource left = inputData.getResource("left.nodes"); //$NON-NLS-1$
80 final Resource right = inputData.getResource("right.nodes"); //$NON-NLS-1$
81 final Resource origin = inputData.getResource("origin.nodes"); //$NON-NLS-1$
82 scope = new DefaultComparisonScope(left, right, origin);
83 final Comparison comparison = EMFCompare.builder().build().compare(scope);
84 mergerRegistry = EMFCompareRCPPlugin.getDefault().getMergerRegistry();
86 // Keeps tracks of the differences to test.
87 EList<Conflict> conflicts = comparison.getConflicts();
88 Assert.assertEquals(1, conflicts.size());
89 Conflict conflict = conflicts.get(0);
91 // Get the right diff of the conflict: change of eopposite reference
92 EList<Diff> leftConflicts = conflict.getLeftDifferences();
93 Assert.assertEquals(2, leftConflicts.size());
94 refChangeDiff = leftConflicts.get(0);// Both difference are equivalent.
96 // Get the left diff of the conflict; deletion of "ReferencedNode"
97 EList<Diff> rightConflicts = conflict.getRightDifferences();
98 Assert.assertEquals(1, rightConflicts.size());
99 holdingRefDeletionDiff = rightConflicts.get(0);
100 // Get the required by diff of the right conflict
101 EList<Diff> rightRequiredBy = holdingRefDeletionDiff.getRequiredBy();
102 Assert.assertEquals(1, rightRequiredBy.size());
103 deletedNodeDeletionDiff = rightRequiredBy.get(0);
108 * In the resulting comparison model we have:
109 * <ul>
110 * <li>Two equivalent differences which are the reference changes between "HoldingReference" and
111 * "ReferencedNode"</li>
112 * <li>One deletion difference (deletion of "HoldingDeletedNode") that requires a another deletion
113 * difference (deletion of "RefencedNode")</li>
114 * <ul>
115 * This test aims to check that accepting one of the two equivalent differences should reject the deletion
116 * of "ReferencedNode", and doesn't modify the state of "HoldingDeletedNode".
118 @Test
119 public void testAcceptConflictDiffWithConflictingDiffWithRequiredBy() {
120 MergeRunnableImpl mergeRunnable = new MergeRunnableImpl(true, false, MergeMode.ACCEPT);
121 mergeRunnable.merge(Collections.singletonList(refChangeDiff), false, mergerRegistry);
123 Assert.assertEquals(DifferenceState.MERGED, refChangeDiff.getState());
124 Assert.assertEquals(MergeMode.ACCEPT, getMergeData(refChangeDiff).getMergeMode());
125 Assert.assertEquals(DifferenceState.MERGED, holdingRefDeletionDiff.getState());
126 Assert.assertEquals(MergeMode.REJECT, getMergeData(holdingRefDeletionDiff).getMergeMode());
127 Assert.assertEquals(DifferenceState.UNRESOLVED, deletedNodeDeletionDiff.getState());
129 // Checks that the content of the left resource is correct.
130 Resource leftResource = (Resource)scope.getLeft();
132 EList<EObject> content = leftResource.getContents();
133 Assert.assertEquals(1, content.size());
134 Node root = (Node)content.get(0);
135 EList<Node> children = root.getContainmentRef1();
136 // Checks that "HoldingDeletedNode" is in the model.
137 Assert.assertEquals(2, children.size());
138 Node firstChildren = children.get(0);
139 // Checks that "ReferencedNode" is in the model.
140 Assert.assertEquals(1, firstChildren.getContainmentRef1().size());
144 * Same test described above but this time the merge is done programmatically.
146 @Test
147 public void testAcceptConflictDiffWithConflictingDiffWithRequiredByProg() {
148 mergerRegistry.getHighestRankingMerger(refChangeDiff).copyLeftToRight(refChangeDiff,
149 new BasicMonitor());
151 Assert.assertEquals(DifferenceState.MERGED, refChangeDiff.getState());
152 Assert.assertEquals(DifferenceState.MERGED, holdingRefDeletionDiff.getState());
153 Assert.assertEquals(DifferenceState.MERGED, deletedNodeDeletionDiff.getState());
155 // Checks that the content of the right resource is correct.
156 Resource rightResource = (Resource)scope.getRight();
158 EList<EObject> content = rightResource.getContents();
159 Assert.assertEquals(1, content.size());
160 Node root = (Node)content.get(0);
161 EList<Node> children = root.getContainmentRef1();
162 // Checks that "DeletedNode" is in the model.
163 Assert.assertEquals(2, children.size());
164 Node firstChildren = children.get(0);
165 // Checks that "ReferencedNode" is in the model.
166 Assert.assertEquals(1, firstChildren.getContainmentRef1().size());
169 private IMergeData getMergeData(Diff diff) {
170 return (IMergeData)EcoreUtil.getExistingAdapter(diff, IMergeData.class);
174 * Input data for this bug.
176 * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
178 public class Bug434828InputData extends AbstractInputData {
180 private static final String PATH_PREFIX = "data/_434828/"; //$NON-NLS-1$
182 public Resource getResource(String resourceName) throws IOException {
183 StringBuilder resourceURL = new StringBuilder(PATH_PREFIX);
184 resourceURL.append(resourceName);
185 return loadFromClassLoader(resourceURL.toString());