| /******************************************************************************* |
| * Copyright (C) 2015, 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 |
| * Philip Langer - bug 501864 |
| *******************************************************************************/ |
| package org.eclipse.papyrus.compare.diagram.tests.resourceattachmentchange.move; |
| |
| import static com.google.common.base.Predicates.and; |
| import static com.google.common.base.Predicates.instanceOf; |
| import static com.google.common.collect.Iterables.filter; |
| import static com.google.common.collect.Iterables.size; |
| import static org.eclipse.emf.compare.utils.EMFComparePredicates.ofKind; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| |
| import java.io.File; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.compare.Comparison; |
| import org.eclipse.emf.compare.Conflict; |
| import org.eclipse.emf.compare.Diff; |
| import org.eclipse.emf.compare.DifferenceKind; |
| import org.eclipse.emf.compare.ResourceAttachmentChange; |
| import org.eclipse.emf.compare.ide.ui.tests.workspace.TestProject; |
| import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; |
| import org.eclipse.jgit.api.ResetCommand.ResetType; |
| import org.eclipse.papyrus.compare.diagram.tests.AbstractGitTestCase; |
| import org.junit.Test; |
| |
| /** |
| * Tests for ResourceAttachmentChange with MOVE kind. |
| * |
| * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a> |
| */ |
| @SuppressWarnings({"nls", "unused" }) |
| public class ResourceAttachmentChangeMoveConflictTests extends AbstractGitTestCase { |
| |
| /** |
| * Path to the test data. |
| */ |
| private static String TEST_DATA_PATH = "src/org/eclipse/papyrus/compare/diagram/tests/resourceattachmentchange/move/data/"; |
| |
| private ResourceSetImpl resourceSet; |
| |
| private IProject iProject; |
| |
| private TestProject testProject1; |
| |
| private IFile modelDi; |
| |
| private IFile modelNotation; |
| |
| private IFile modelUml; |
| |
| private IFile fragmentDi; |
| |
| private IFile fragmentNotation; |
| |
| private IFile fragmentUml; |
| |
| /** |
| * BRANCH_3 checkouted (the deletion). Comparison with BRANCH_2 (the move). Comparison: Conflicts, with 1 |
| * concerning a {@link ResourceAttachmentChange} DELETE with 1 {@link ResourceAttachmentChange} MOVE. |
| */ |
| @Test |
| public void testComparisonMoveRemoteDeleteLocal() throws Exception { |
| setUpRepositoryCase002(); |
| |
| // Check comparison model : conflicts and 1 RAC Move |
| repository.checkoutBranch(BRANCH_3); |
| Comparison comparison = compare(BRANCH_3, BRANCH_2, modelNotation); |
| assertEquals(2, comparison.getConflicts().size()); |
| assertEquals(1, size(filter(comparison.getDifferences(), |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.MOVE))))); |
| // There is a conflict between the move in 2nd commit & the deletion in 3rd commit |
| Conflict conflict = comparison.getConflicts().get(1); |
| EList<Diff> differences = conflict.getDifferences(); |
| assertEquals(2, differences.size()); |
| assertEquals(1, size(filter(differences, |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.DELETE))))); |
| assertEquals(1, size(filter(differences, |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.MOVE))))); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_2 checkouted (the move). Comparison with BRANCH_3 (the deletion). Comparison: Conflicts, with 1 |
| * concerning a {@link ResourceAttachmentChange} DELETE with 1 {@link ResourceAttachmentChange} MOVE. |
| */ |
| @Test |
| public void testComparisonMoveLocalDeleteRemote() throws Exception { |
| setUpRepositoryCase002(); |
| |
| // Check comparison model : conflicts and 1 RAC Move |
| repository.checkoutBranch(BRANCH_2); |
| Comparison comparison = compare(BRANCH_2, BRANCH_3, modelNotation); |
| assertEquals(2, comparison.getConflicts().size()); |
| assertEquals(1, size(filter(comparison.getDifferences(), |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.MOVE))))); |
| // There is a conflict between the move in 2nd commit & the deletion in 3rd commit |
| Conflict conflict = comparison.getConflicts().get(1); |
| EList<Diff> differences = conflict.getDifferences(); |
| assertEquals(2, differences.size()); |
| assertEquals(1, size(filter(differences, |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.DELETE))))); |
| assertEquals(1, size(filter(differences, |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.MOVE))))); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_3 checkouted (the deletion). Comparison with BRANCH_2 (the move). Merge: Conflicts. |
| */ |
| @Test |
| public void testMergeMoveRemoteDeleteLocal() throws Exception { |
| setUpRepositoryCase002(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_3, ResetType.HARD); |
| repository.mergeLogicalWithNewCommit(BRANCH_2); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_2 checkouted (the move). Comparison with BRANCH_3 (the deletion). Merge: Conflicts. |
| */ |
| @Test |
| public void testMergeMoveLocalDeleteRemote() throws Exception { |
| setUpRepositoryCase002(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_2, ResetType.HARD); |
| repository.mergeLogicalWithNewCommit(BRANCH_3); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_3 checkouted (the deletion). Comparison with BRANCH_2 (the move). Rebase: Conflicts. |
| */ |
| @Test |
| public void testRebaseMoveRemoteDeleteLocal() throws Exception { |
| setUpRepositoryCase002(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_3, ResetType.HARD); |
| repository.rebaseLogical(BRANCH_2); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_2 checkouted (the move). Comparison with BRANCH_3 (the deletion). Rebase: Conflicts. |
| */ |
| @Test |
| public void testRebaseMoveLocalDeleteRemote() throws Exception { |
| setUpRepositoryCase002(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_2, ResetType.HARD); |
| repository.rebaseLogical(BRANCH_3); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_3 checkouted (the deletion). Comparison with BRANCH_2 (the move). Merge: Conflicts. |
| */ |
| @Test |
| public void testCherryPickMoveRemoteDeleteLocal() throws Exception { |
| setUpRepositoryCase002(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_3, ResetType.HARD); |
| repository.cherryPickLogical(BRANCH_2); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_2 checkouted (the move). Comparison with BRANCH_3 (the deletion). Merge: Conflicts. |
| */ |
| @Test |
| public void testCherryPickMoveLocalDeleteRemote() throws Exception { |
| setUpRepositoryCase002(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_2, ResetType.HARD); |
| repository.cherryPickLogical(BRANCH_3); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_3 checkouted (the second move). Comparison with BRANCH_2 (the first move). Comparison: |
| * Conflicts, with 2 {@link ResourceAttachmentChange} MOVE. |
| */ |
| @Test |
| public void testComparisonMoveRemoteMoveLocal() throws Exception { |
| setUpRepositoryCase003(); |
| |
| // Check comparison model : conflicts and 2 RAC Move |
| repository.checkoutBranch(BRANCH_3); |
| Comparison comparison = compare(BRANCH_3, BRANCH_2, modelNotation); |
| assertEquals(2, comparison.getConflicts().size()); |
| assertEquals(2, size(filter(comparison.getDifferences(), |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.MOVE))))); |
| // There is a conflict between the move in 2nd commit & the move in 3rd commit |
| Conflict conflict = comparison.getConflicts().get(1); |
| EList<Diff> differences = conflict.getDifferences(); |
| assertEquals(2, differences.size()); |
| assertEquals(2, size(filter(differences, |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.MOVE))))); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_2 checkouted (the first move). Comparison with BRANCH_3 (the second move). Comparison: |
| * Conflicts, with 2 {@link ResourceAttachmentChange} MOVE. |
| */ |
| @Test |
| public void testComparisonMoveLocalMoveRemote() throws Exception { |
| setUpRepositoryCase003(); |
| |
| // Check comparison model : conflicts and 2 RAC Move |
| repository.checkoutBranch(BRANCH_2); |
| Comparison comparison = compare(BRANCH_2, BRANCH_3, modelNotation); |
| assertEquals(2, comparison.getConflicts().size()); |
| assertEquals(2, size(filter(comparison.getDifferences(), |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.MOVE))))); |
| // There is a conflict between the move in 2nd commit & the move in 3rd commit |
| Conflict conflict = comparison.getConflicts().get(1); |
| EList<Diff> differences = conflict.getDifferences(); |
| assertEquals(2, differences.size()); |
| assertEquals(2, size(filter(differences, |
| and(instanceOf(ResourceAttachmentChange.class), ofKind(DifferenceKind.MOVE))))); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_3 checkouted (the second move). Comparison with BRANCH_2 (the first move). Merge: Conflicts. |
| */ |
| @Test |
| public void testMergeMoveRemoteMoveLocal() throws Exception { |
| setUpRepositoryCase003(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_3, ResetType.HARD); |
| repository.mergeLogicalWithNewCommit(BRANCH_2); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_2 checkouted (the first move). Comparison with BRANCH_3 (the second move). Merge: Conflicts. |
| */ |
| @Test |
| public void testMergeMoveLocalMoveRemote() throws Exception { |
| setUpRepositoryCase003(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_2, ResetType.HARD); |
| repository.mergeLogicalWithNewCommit(BRANCH_3); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_3 checkouted (the second move). Comparison with BRANCH_2 (the first move). Rebase: Conflicts. |
| */ |
| @Test |
| public void testRebaseMoveRemoteMoveLocal() throws Exception { |
| setUpRepositoryCase003(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_3, ResetType.HARD); |
| repository.rebaseLogical(BRANCH_2); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_2 checkouted (the first move). Comparison with BRANCH_3 (the second move). Rebase: Conflicts. |
| */ |
| @Test |
| public void testRebaseMoveLocalMoveRemote() throws Exception { |
| setUpRepositoryCase003(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_2, ResetType.HARD); |
| repository.rebaseLogical(BRANCH_3); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_3 checkouted (the second move). Comparison with BRANCH_2 (the first move). CherryPick: |
| * Conflicts. |
| */ |
| @Test |
| public void testCherryPickMoveRemoteMoveLocal() throws Exception { |
| setUpRepositoryCase003(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_3, ResetType.HARD); |
| repository.cherryPickLogical(BRANCH_2); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * BRANCH_2 checkouted (the first move). Comparison with BRANCH_3 (the second move). CherryPick: |
| * Conflicts. |
| */ |
| @Test |
| public void testCherryPickMoveLocalMoveRemote() throws Exception { |
| setUpRepositoryCase003(); |
| |
| repository.checkoutBranch(MASTER); |
| repository.reset(BRANCH_2, ResetType.HARD); |
| repository.cherryPickLogical(BRANCH_3); |
| |
| // Conflicts |
| assertFalse(repository.status().getConflicting().isEmpty()); |
| |
| testProject1.dispose(); |
| } |
| |
| /** |
| * Case 002. 3 commits. 1st commit: a model with 2 packages. 1 class diagram associated to the model, and |
| * 1 class diagram associated to the 2nd package. 2nd commit: the 2nd package is fragmented. The class |
| * diagram associated is moved in a new resource (notation model). 3rd commit: reset to the 1st commit. |
| * Remove the 2nd package. Also remove it from the diagram. |
| */ |
| private void setUpRepositoryCase002() throws Exception { |
| resourceSet = new ResourceSetImpl(); |
| File workingDirectory = repository.getRepository().getWorkTree(); |
| testProject1 = new TestProject("Project1", workingDirectory.getAbsolutePath()); |
| iProject = testProject1.getProject(); |
| repository.connect(iProject); |
| |
| // 1st commit: a model with 2 packages. |
| // 1 class diagram associated to the model, and 1 class diagram associated to the 2nd package. |
| modelDi = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit1/model.di", ""); |
| modelNotation = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit1/model.notation", |
| ""); |
| modelUml = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit1/model.uml", ""); |
| |
| repository.addAllAndCommit("1st-commit"); |
| repository.createBranch(MASTER, BRANCH_1); |
| |
| // 2nd commit: the 2nd package is fragmented. |
| // The class diagram associated is moved in a new resource (notation model). |
| modelDi = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit2/model.di", ""); |
| modelNotation = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit2/model.notation", |
| ""); |
| modelUml = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit2/model.uml", ""); |
| fragmentDi = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit2/fragment.di", ""); |
| fragmentNotation = addToProject(TEST_DATA_PATH, testProject1, iProject, |
| "case002/commit2/fragment.notation", ""); |
| fragmentUml = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit2/fragment.uml", |
| ""); |
| repository.addAllAndCommit("2nd-commit"); |
| repository.createBranch(MASTER, BRANCH_2); |
| |
| // Back to 1st commit |
| repository.reset(BRANCH_1, ResetType.HARD); |
| |
| // 3rd commit: reset to the 1st commit. |
| // Remove the 2nd package. Also remove it from the diagram. |
| modelDi = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit3/model.di", ""); |
| modelNotation = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit3/model.notation", |
| ""); |
| modelUml = addToProject(TEST_DATA_PATH, testProject1, iProject, "case002/commit3/model.uml", ""); |
| repository.addAllAndCommit("3rd-commit"); |
| repository.createBranch(MASTER, BRANCH_3); |
| |
| repository.checkoutBranch(MASTER); |
| } |
| |
| /** |
| * Case 003. 3 commits. 1st commit: a model with 2 packages. 1 class diagram associated to the model, and |
| * 1 class diagram associated to the 2nd package. 2nd commit: the 2nd package is fragmented. The class |
| * diagram associated is moved in a new resource X (notation model). 3rd commit: reset to the 1st commit. |
| * The 2nd package is fragmented. The class diagram associated is moved in a new resource Y (notation |
| * model). |
| */ |
| private void setUpRepositoryCase003() throws Exception { |
| resourceSet = new ResourceSetImpl(); |
| File workingDirectory = repository.getRepository().getWorkTree(); |
| testProject1 = new TestProject("Project1", workingDirectory.getAbsolutePath()); |
| iProject = testProject1.getProject(); |
| repository.connect(iProject); |
| |
| // 1st commit: a model with 2 packages. |
| // 1 class diagram associated to the model, and 1 class diagram associated to the 2nd package. |
| modelDi = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit1/model.di", ""); |
| modelNotation = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit1/model.notation", |
| ""); |
| modelUml = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit1/model.uml", ""); |
| |
| repository.addAllAndCommit("1st-commit"); |
| repository.createBranch(MASTER, BRANCH_1); |
| |
| // 2nd commit: the 2nd package is fragmented. |
| // The class diagram associated is moved in a new resource X (notation model). |
| modelDi = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit2/model.di", ""); |
| modelNotation = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit2/model.notation", |
| ""); |
| modelUml = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit2/model.uml", ""); |
| fragmentDi = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit2/fragment.di", ""); |
| fragmentNotation = addToProject(TEST_DATA_PATH, testProject1, iProject, |
| "case003/commit2/fragment.notation", ""); |
| fragmentUml = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit2/fragment.uml", |
| ""); |
| repository.addAllAndCommit("2nd-commit"); |
| repository.createBranch(MASTER, BRANCH_2); |
| |
| // Back to 1st commit |
| repository.reset(BRANCH_1, ResetType.HARD); |
| |
| // 3rd commit: the 2nd package is fragmented. |
| // The class diagram associated is moved in a new resource Y (notation model). |
| modelDi = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit3/model.di", ""); |
| modelNotation = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit3/model.notation", |
| ""); |
| modelUml = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit3/model.uml", ""); |
| IFile controlDi = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit3/control.di", |
| ""); |
| IFile controlNotation = addToProject(TEST_DATA_PATH, testProject1, iProject, |
| "case003/commit3/control.notation", ""); |
| IFile controlUml = addToProject(TEST_DATA_PATH, testProject1, iProject, "case003/commit3/control.uml", |
| ""); |
| repository.addAllAndCommit("3rd-commit"); |
| repository.createBranch(MASTER, BRANCH_3); |
| |
| repository.checkoutBranch(MASTER); |
| } |
| |
| } |