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
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
;
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
;
57 * Set up the model comparison with the following use case:
59 * The 3 models loaded are:
61 * <li>Origin which contains 3 nodes structured like this:
64 * Root - DeletedNode - ReferencedNode
65 * \ - HoldingReferenceNode
69 * <li>Left that has an extra eopposite reference between "HoldingReference" and "ReferencedNode"</li>
70 * <li>Right in which "DeletedNode" has been deleted"</li>
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:
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>
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".
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.
147 public void testAcceptConflictDiffWithConflictingDiffWithRequiredByProg() {
148 mergerRegistry
.getHighestRankingMerger(refChangeDiff
).copyLeftToRight(refChangeDiff
,
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());