Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/DiffRelationshipComputerTest.java')
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/DiffRelationshipComputerTest.java420
1 files changed, 420 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/DiffRelationshipComputerTest.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/DiffRelationshipComputerTest.java
new file mode 100644
index 000000000..252f30c3a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/diff/DiffRelationshipComputerTest.java
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright (c) 2017 EclipseSource Services GmbH 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:
+ * Martin Fleck - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.tests.diff;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+import org.eclipse.emf.compare.CompareFactory;
+import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.internal.spec.DiffSpec;
+import org.eclipse.emf.compare.merge.CachingDiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.ComputeDiffsToMerge;
+import org.eclipse.emf.compare.merge.IDiffRelationshipComputer;
+import org.eclipse.emf.compare.merge.IMerger;
+import org.eclipse.emf.compare.merge.IMerger.Registry2;
+import org.eclipse.emf.compare.merge.IMerger2;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This class holds test cases that are related to the {@link IDiffRelationshipComputer} and specifically, the
+ * {@link CachingDiffRelationshipComputer}.
+ *
+ * @author Martin Fleck <mfleck@eclipsesource.com>
+ */
+@SuppressWarnings({"boxing" })
+public class DiffRelationshipComputerTest {
+
+ /** Merge direction. */
+ protected static boolean MERGE_RIGHT_TO_LEFT = true;
+
+ /** Merger registry with the mock merger. */
+ protected Registry2 mergerRegistry;
+
+ /** Mock merger with a high ranking applying to the testing diff. */
+ protected IMerger2 merger;
+
+ /** Comparison. */
+ protected Comparison comparison;
+
+ /** Match. */
+ protected Match match;
+
+ /** Testing diff. */
+ protected Diff diff;
+
+ /** Dependency of the testing diff. */
+ protected Diff mergeDependency;
+
+ /** Resulting diff of the testing diff. */
+ protected Diff resultingMerge;
+
+ /** Resulting rejection of the testing diff. */
+ protected Diff resultingRejection;
+
+ /**
+ * Creates a new merger registry, merger and relevant diffs.
+ */
+ @Before
+ public void setupClass() {
+ mergerRegistry = createMergerRegistry();
+ comparison = createComparison();
+ comparison.getMatches().add(match = createMatch());
+ comparison.getDifferences().add(diff = createDiff(match));
+ comparison.getDifferences().add(mergeDependency = createDiff(match));
+ comparison.getDifferences().add(resultingMerge = createDiff(match));
+ comparison.getDifferences().add(resultingRejection = createDiff(match));
+ merger = mockMerger(diff, mergeDependency, resultingMerge, resultingRejection, 1000, mergerRegistry);
+ mergerRegistry.add(merger);
+ }
+
+ protected CachingDiffRelationshipComputer getDiffRelationshipComputer() {
+ return new CachingDiffRelationshipComputer(mergerRegistry);
+ }
+
+ /**
+ * Tests that the computer is working correctly for direct merge dependencies.
+ */
+ @Test
+ public void testDirectMergeDependencies() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call calculation method a few times
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called exactly once
+ verifyDirectMergeDependenciesCalledExactly(1);
+ }
+
+ /**
+ * Tests that the computer is working correctly for direct resulting merges.
+ */
+ @Test
+ public void testDirectResultingMerges() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call calculation method a few times
+ assertDirectResultingMerges(computer.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingMerges(computer.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingMerges(computer.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingMerges(computer.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called exactly once
+ verifyDirectResultingMergesCalledExactly(1);
+ }
+
+ /**
+ * Tests that the computer is working correctly for direct resulting rejections.
+ */
+ @Test
+ public void testDirectResultingRejections() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call calculation method a few times
+ assertDirectResultingRejections(computer.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingRejections(computer.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingRejections(computer.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectResultingRejections(computer.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called exactly once
+ verifyDirectResultingRejectionsCalledExactly(1);
+ }
+
+ /**
+ * Tests that the computer is working correctly for all resulting merges.
+ */
+ @Test
+ public void testAllResultingMerges() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call calculation method a few times
+ assertAllResultingMerges(computer.getAllResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingMerges(computer.getAllResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingMerges(computer.getAllResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingMerges(computer.getAllResultingMerges(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods of the diffs are called at most once
+ verifyMergerCalculationsCalledAtMostOnce();
+ }
+
+ /**
+ * Tests that the computer is working correctly for all resulting rejections.
+ */
+ @Test
+ public void testAllResultingRejections() {
+ IDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // call resulting rejections a few more times
+ assertAllResultingRejections(computer.getAllResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingRejections(computer.getAllResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingRejections(computer.getAllResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+ assertAllResultingRejections(computer.getAllResultingRejections(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods of the diffs are called at most once
+ verifyMergerCalculationsCalledAtMostOnce();
+ }
+
+ /**
+ * Tests that a diff state change invalidates the cached relationships and leads to a re-calculation of
+ * the relationships.
+ */
+ @Test
+ public void testInvalidateCache() {
+ CachingDiffRelationshipComputer computer = getDiffRelationshipComputer();
+
+ // trigger first time caching
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation method was called exactly once
+ verifyDirectMergeDependenciesCalledExactly(1);
+
+ // invalidate cache
+ computer.invalidate();
+
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called twice now, because we needed to recalculate the relationships
+ verifyDirectMergeDependenciesCalledExactly(2);
+
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called twice now, same as before
+ verifyDirectMergeDependenciesCalledExactly(2);
+
+ // invalidate cache
+ computer.invalidate();
+
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+ assertDirectMergeDependencies(computer.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT));
+
+ // the calculation methods was called three times now, because of recalculation
+ verifyDirectMergeDependenciesCalledExactly(3);
+ }
+
+ /**
+ * Tests that the is correctly used in {@link ComputeDiffsToMerge}.
+ */
+ @Test
+ public void testComputeDiffsToMergeIntegration() {
+ ComputeDiffsToMerge computer = new ComputeDiffsToMerge(MERGE_RIGHT_TO_LEFT,
+ new CachingDiffRelationshipComputer(mergerRegistry));
+
+ // call resulting merges a few more times
+ assertAllResultingMerges(computer.getAllDiffsToMerge(diff));
+ assertAllResultingMerges(computer.getAllDiffsToMerge(diff));
+ assertAllResultingMerges(computer.getAllDiffsToMerge(diff));
+ assertAllResultingMerges(computer.getAllDiffsToMerge(diff));
+
+ // the calculation methods of the diffs are called at most once
+ verifyMergerCalculationsCalledAtMostOnce();
+ }
+
+ /**
+ * Verifies that any of the relationship calculating methods of the merger were called at most once.
+ */
+ protected void verifyMergerCalculationsCalledAtMostOnce() {
+ verify(merger, atMost(1)).getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT);
+ verify(merger, atMost(1)).getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT);
+ verify(merger, atMost(1)).getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT);
+ }
+
+ /**
+ * Verifies that the calculation method for the direct merge dependencies was called exactly the given
+ * number of times.
+ *
+ * @param times
+ * number of times the method should have been called.
+ */
+ protected void verifyDirectMergeDependenciesCalledExactly(int times) {
+ verify(merger, times(times)).getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT);
+ }
+
+ /**
+ * Verifies that the calculation method for the direct resulting merges was called exactly the given
+ * number of times.
+ *
+ * @param times
+ * number of times the method should have been called.
+ */
+ protected void verifyDirectResultingMergesCalledExactly(int times) {
+ verify(merger, times(times)).getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT);
+ }
+
+ /**
+ * Verifies that the calculation method for the direct resulting rejections was called exactly the given
+ * number of times.
+ *
+ * @param times
+ * number of times the method should have been called.
+ */
+ protected void verifyDirectResultingRejectionsCalledExactly(int times) {
+ verify(merger, times(times)).getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT);
+ }
+
+ /**
+ * Asserts that the known resulting merges (dependency, diff itself, direct resulting merge) are the only
+ * diffs available in the given set.
+ *
+ * @param resultingMerges
+ * calculated resulting merges
+ */
+ protected void assertDirectMergeDependencies(Set<Diff> mergeDependencies) {
+ assertEquals(1, mergeDependencies.size());
+ assertTrue(mergeDependencies.contains(mergeDependency));
+ }
+
+ /**
+ * Asserts that the known resulting merges (dependency, diff itself, direct resulting merge) are the only
+ * diffs available in the given set.
+ *
+ * @param resultingMerges
+ * calculated resulting merges
+ */
+ protected void assertDirectResultingRejections(Set<Diff> resultingRejections) {
+ assertEquals(1, resultingRejections.size());
+ assertTrue(resultingRejections.contains(resultingRejection));
+ }
+
+ /**
+ * Asserts that the known resulting merges (dependency, diff itself, direct resulting merge) are the only
+ * diffs available in the given set.
+ *
+ * @param resultingMerges
+ * calculated resulting merges
+ */
+ protected void assertDirectResultingMerges(Set<Diff> resultingMerges) {
+ assertEquals(1, resultingMerges.size());
+ assertTrue(resultingMerges.contains(resultingMerge));
+ }
+
+ /**
+ * Asserts that the known resulting merges (dependency, diff itself, direct resulting merge) are the only
+ * diffs available in the given set.
+ *
+ * @param resultingMerges
+ * calculated resulting merges
+ */
+ protected void assertAllResultingMerges(Set<Diff> resultingMerges) {
+ assertEquals(3, resultingMerges.size());
+ assertTrue(resultingMerges.contains(mergeDependency));
+ assertTrue(resultingMerges.contains(diff));
+ assertTrue(resultingMerges.contains(resultingMerge));
+ }
+
+ /**
+ * Asserts that the known resulting rejection is the only diff available in the given set.
+ *
+ * @param resultingRejections
+ * calculated resulting rejections
+ */
+ protected void assertAllResultingRejections(Set<Diff> resultingRejections) {
+ assertEquals(1, resultingRejections.size());
+ assertTrue(resultingRejections.contains(resultingRejection));
+ }
+
+ /**
+ * Creates a new comparison.
+ *
+ * @return new comparison instance
+ */
+ private static Comparison createComparison() {
+ return CompareFactory.eINSTANCE.createComparison();
+ }
+
+ /**
+ * Creates a new match.
+ *
+ * @return new match instance
+ */
+ private static Match createMatch() {
+ return CompareFactory.eINSTANCE.createMatch();
+ }
+
+ /**
+ * Creates a new diff instance.
+ *
+ * @param match
+ * @return new diff instance
+ */
+ private static Diff createDiff(Match match) {
+ Diff diff = new DiffSpec();
+ diff.setMatch(match);
+ return diff;
+ }
+
+ /**
+ * Creates a new standalone instance of a merger registry.
+ *
+ * @return new merger registry instance
+ */
+ private static IMerger.Registry2 createMergerRegistry() {
+ return (Registry2)IMerger.RegistryImpl.createStandaloneInstance();
+ }
+
+ /**
+ * Creates a mock merger that returns the given diffs as relationships for the testing diff.
+ *
+ * @param diff
+ * testing diff
+ * @param mergeDependency
+ * dependency of the testing diff
+ * @param resultingMerge
+ * resulting diff for the testing diff
+ * @param resultingRejection
+ * resulting rejection for the testing diff
+ * @param ranking
+ * ranking of the mock merger
+ * @param registry
+ * registry of the mock merger
+ * @return a mock merger
+ */
+ private static IMerger2 mockMerger(Diff diff, Diff mergeDependency, Diff resultingMerge,
+ Diff resultingRejection, int ranking, IMerger.Registry registry) {
+ IMerger2 mockMerger = mock(IMerger2.class);
+ when(mockMerger.getDirectMergeDependencies(diff, MERGE_RIGHT_TO_LEFT))
+ .thenReturn(Sets.newHashSet(mergeDependency));
+ when(mockMerger.getDirectResultingMerges(diff, MERGE_RIGHT_TO_LEFT))
+ .thenReturn(Sets.newHashSet(resultingMerge));
+ when(mockMerger.getDirectResultingRejections(diff, MERGE_RIGHT_TO_LEFT))
+ .thenReturn(Sets.newHashSet(resultingRejection));
+ when(mockMerger.isMergerFor(any(Diff.class))).thenReturn(Boolean.TRUE);
+ when(mockMerger.getRanking()).thenReturn(ranking);
+ when(mockMerger.getRegistry()).thenReturn(registry);
+ return mockMerger;
+ }
+}

Back to the top