Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCedric Brun2011-01-05 14:13:01 +0000
committerCedric Brun2011-01-05 14:13:01 +0000
commit8a1c5eb415078284a94d29c00280485ee60843cf (patch)
tree30ee7be4f84904ae13c89e0a873d759adf061bac /plugins/org.eclipse.emf.compare.mpatch.test/src
parentf0991e9aff822115764d9c392404a906e735a602 (diff)
downloadorg.eclipse.emf.compare-8a1c5eb415078284a94d29c00280485ee60843cf.tar.gz
org.eclipse.emf.compare-8a1c5eb415078284a94d29c00280485ee60843cf.tar.xz
org.eclipse.emf.compare-8a1c5eb415078284a94d29c00280485ee60843cf.zip
repository relayout : https://bugs.eclipse.org/bugs/show_bug.cgi?id=333059
Diffstat (limited to 'plugins/org.eclipse.emf.compare.mpatch.test/src')
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/AppliedTest.java196
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ApplyTest.java83
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/Emfdiff2MPatchTest.java101
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/GeneralizationTest.java54
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/GroupingTest.java70
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/IndividualTest.java116
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/InternalRefTest.java158
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/LibraryExampleTest.java98
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/MergeChangesTest.java238
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/OclExpressionTest.java68
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/PerformanceTest.java276
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ResolveTest.java51
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ReverseTest.java158
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/UmlTest.java73
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/CommonTestOperations.java504
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/CompareTestHelper.java200
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/PerformanceTimes.java147
-rw-r--r--plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/TestConstants.java171
18 files changed, 2762 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/AppliedTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/AppliedTest.java
new file mode 100644
index 000000000..5113bafce
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/AppliedTest.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.compare.mpatch.IndepAddAttributeChange;
+import org.eclipse.emf.compare.mpatch.IndepAddElementChange;
+import org.eclipse.emf.compare.mpatch.IndepAddReferenceChange;
+import org.eclipse.emf.compare.mpatch.IndepChange;
+import org.eclipse.emf.compare.mpatch.IndepMoveElementChange;
+import org.eclipse.emf.compare.mpatch.IndepRemoveAttributeChange;
+import org.eclipse.emf.compare.mpatch.IndepRemoveElementChange;
+import org.eclipse.emf.compare.mpatch.IndepRemoveReferenceChange;
+import org.eclipse.emf.compare.mpatch.IndepUpdateAttributeChange;
+import org.eclipse.emf.compare.mpatch.IndepUpdateReferenceChange;
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.extension.ResolvedSymbolicReferences;
+import org.eclipse.emf.compare.mpatch.extension.ResolvedSymbolicReferences.ValidationResult;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.junit.Test;
+
+/**
+ * This test first calculates the differences between two models and the resolves them to the target (!) model. This
+ * must yield all changes already being applied.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ */
+public class AppliedTest {
+
+ /**
+ * Testing resolution of changes to applied version of dependency cycle test model.
+ */
+ @Test
+ public void testDependencyCycle() {
+ testApplied(TestConstants.DEP_CYCLE_URI1, TestConstants.DEP_CYCLE_URI2);
+ }
+
+ /**
+ * Testing resolution of changes to applied version of simpel test model.
+ */
+ @Test
+ public void testApplyDifferencesSimple() {
+ testApplied(TestConstants.SIMPLE_URI1, TestConstants.SIMPLE_URI2);
+ }
+
+ /**
+ * Testing resolution of changes to applied version of dependency test model.
+ */
+ @Test
+ public void testApplyDifferencesDependency() {
+ testApplied(TestConstants.DEPENDENCY_URI1, TestConstants.DEPENDENCY_URI2);
+ }
+
+ /**
+ * Testing resolution of changes to applied version of eachonce test model.
+ */
+ @Test
+ public void testApplyDifferencesEachonce() {
+ testApplied(TestConstants.EACHONCE_URI1, TestConstants.EACHONCE_URI2);
+ }
+
+ /**
+ * Testing resolution of changes to applied version of uml test model.
+ */
+ @Test
+ public void testApplyDifferencesUML() {
+ testApplied(TestConstants.UML_URI1, TestConstants.UML_URI2);
+ }
+
+ /**
+ * Test resolution of applied {@link IndepAddElementChange}.
+ */
+ @Test
+ public void testAppliedAddElement() {
+ testApplied(TestConstants.INDIVIDUAL_ADD_REM_ELEMENT_URI1, TestConstants.INDIVIDUAL_ADD_REM_ELEMENT_URI2);
+ }
+
+ /**
+ * Test resolution of applied {@link IndepRemoveElementChange}.
+ */
+ @Test
+ public void testAppliedRemoveElement() {
+ testApplied(TestConstants.INDIVIDUAL_ADD_REM_ELEMENT_URI2, TestConstants.INDIVIDUAL_ADD_REM_ELEMENT_URI1);
+ }
+
+ /**
+ * Test resolution of applied {@link IndepMoveElementChange}.
+ */
+ @Test
+ public void testAppliedMoveElement() {
+ testApplied(TestConstants.INDIVIDUAL_MOVE_ELEMENT_URI1, TestConstants.INDIVIDUAL_MOVE_ELEMENT_URI2);
+ }
+
+ /**
+ * Test resolution of applied {@link IndepAddAttributeChange}.
+ */
+ @Test
+ public void testAppliedAddAttribute() {
+ testApplied(TestConstants.INDIVIDUAL_ADD_REM_ATTRIBUTE_URI1, TestConstants.INDIVIDUAL_ADD_REM_ATTRIBUTE_URI2);
+ }
+
+ /**
+ * Test resolution of applied {@link IndepRemoveAttributeChange}.
+ */
+ @Test
+ public void testAppliedRemoveAttribute() {
+ testApplied(TestConstants.INDIVIDUAL_ADD_REM_ATTRIBUTE_URI2, TestConstants.INDIVIDUAL_ADD_REM_ATTRIBUTE_URI1);
+ }
+
+ /**
+ * Test resolution of applied {@link IndepUpdateAttributeChange}.
+ */
+ @Test
+ public void testAppliedUpdateAttribute() {
+ testApplied(TestConstants.INDIVIDUAL_UPDATE_ATTRIBUTE_URI1, TestConstants.INDIVIDUAL_UPDATE_ATTRIBUTE_URI2);
+ }
+
+ /**
+ * Test resolution of applied {@link IndepAddReferenceChange}.
+ */
+ @Test
+ public void testAppliedAddReference() {
+ testApplied(TestConstants.INDIVIDUAL_ADD_REM_REFERENCE_URI1, TestConstants.INDIVIDUAL_ADD_REM_REFERENCE_URI2);
+ }
+
+ /**
+ * Test resolution of applied {@link IndepRemoveReferenceChange}.
+ */
+ @Test
+ public void testAppliedRemoveReference() {
+ testApplied(TestConstants.INDIVIDUAL_ADD_REM_REFERENCE_URI2, TestConstants.INDIVIDUAL_ADD_REM_REFERENCE_URI1);
+ }
+
+ /**
+ * Test resolution of applied {@link IndepUpdateReferenceChange}.
+ */
+ @Test
+ public void testAppliedUpdateReference() {
+ testApplied(TestConstants.INDIVIDUAL_UPDATE_REFERENCE_URI1, TestConstants.INDIVIDUAL_UPDATE_REFERENCE_URI2);
+ }
+
+ /**
+ * Here we are only using id-based symrefs for testing whether applied changed can be recognized. The reason is that
+ * condition-based references depend on the context or on attribute values which might have been changed.
+ */
+ private void testApplied(String unchangedUri, String changedUri) {
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS) {
+ if (!"ID-based".equals(symrefCreator.getLabel()))
+ continue;
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+
+ final String info = "symrefCreator: " + symrefCreator.getLabel() + ", descriptorCreator: "
+ + descriptorCreator.getLabel();
+
+ // create MPatch
+ final MPatchModel mpatch = CommonTestOperations.createMPatch(unchangedUri, changedUri, symrefCreator,
+ descriptorCreator, info);
+ CommonTestOperations.doTransformations(mpatch, null, info);
+
+ // apply it to the changed version of the model ;-)
+ final ResourceSet resourceSet = new ResourceSetImpl(); // new resource to avoid conflicts
+ final EObject changedModel = CompareTestHelper.loadModel(changedUri, resourceSet).get(0);
+ final ResolvedSymbolicReferences resolved = CommonTestOperations.resolveAndValidate(mpatch,
+ changedModel, null, info);
+
+ // now the test: all validations must be STATE_AFTER :-)
+ final List<IndepChange> notAfter = new ArrayList<IndepChange>();
+ for (IndepChange change : resolved.getValidation().keySet()) {
+ if (!ValidationResult.STATE_AFTER.equals(resolved.getValidation().get(change)))
+ notAfter.add(change);
+ }
+ assertTrue("Should be applied but are not: " + notAfter, notAfter.isEmpty());
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ApplyTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ApplyTest.java
new file mode 100644
index 000000000..62ba17e5d
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ApplyTest.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.junit.Test;
+
+
+/**
+ * Test the entire difference creation and application scenario for several different models and test cases. The testing
+ * process is described here: {@link CommonTestOperations#applyDiffAndValidate(String, String)}. Please see the details
+ * of each test case in the javadoc of the test methods.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ */
+public class ApplyTest {
+
+ /**
+ * Testing dependency the creation and application of changes with dependency cycles.
+ */
+ @Test
+ public void testDependencyCycle() {
+ testApply(TestConstants.DEP_CYCLE_URI1, TestConstants.DEP_CYCLE_URI2);
+ }
+
+ /**
+ * The most simple test case of just one changed attribute.
+ */
+ @Test
+ public void testApplyDifferencesSimple() {
+ testApply(TestConstants.SIMPLE_URI1, TestConstants.SIMPLE_URI2);
+ }
+
+ /**
+ * Testing the creation and application of different depending changes.
+ */
+ @Test
+ public void testApplyDifferencesDependency() {
+ testApply(TestConstants.DEPENDENCY_URI1, TestConstants.DEPENDENCY_URI2);
+ }
+
+ /**
+ * Testing each type of change at least once.
+ *
+ * FIXME: A known bug is that for the eachonce metamodel the deletion of attributes is not recognized. See
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=280449 for details.
+ */
+ @Test
+ public void testApplyDifferencesEachonce() {
+ testApply(TestConstants.EACHONCE_URI1, TestConstants.EACHONCE_URI2);
+ }
+
+ /**
+ * Testing the creation and application of mpatches on ecore models.
+ *
+ * FIXME: Still issues with datatypes and references to model elements from other resources.
+ */
+ @Test
+ public void testApplyDifferencesEcore() {
+ testApply(TestConstants.ECORE_URI1, TestConstants.ECORE_URI2);
+ }
+
+ /** Same as {@link IndividualTest#testApply}. */
+ private void testApply(String unchangedUri, String changedUri) {
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS) {
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+ CommonTestOperations.applyMPatchAndValidate(unchangedUri, changedUri, symrefCreator, descriptorCreator);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/Emfdiff2MPatchTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/Emfdiff2MPatchTest.java
new file mode 100644
index 000000000..53bd095ea
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/Emfdiff2MPatchTest.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.eclipse.emf.compare.diff.metamodel.ComparisonSnapshot;
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.emfdiff2mpatch.util.TransformationLauncher;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.junit.Test;
+
+
+/**
+ * Low-level tests for the transformation from emfdiffs to mpatches for several test models.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class Emfdiff2MPatchTest {
+
+ @Test
+ public void testTransformSimple() {
+ /*
+ * Just one single difference - makes it easy to test ;-)
+ */
+ testTransformation(TestConstants.SIMPLE_URI1, TestConstants.SIMPLE_URI2, 1);
+ }
+
+ @Test
+ public void testTransformDependency() {
+ /*
+ * 4 differences build a group for additions, 5 differences for removals.
+ */
+ testTransformation(TestConstants.DEPENDENCY_URI1, TestConstants.DEPENDENCY_URI2, 9);
+ }
+
+ @Test
+ public void testTransformEachonce() {
+ /*
+ * FIXME: EMF Compare still doesn't recognize added (or removed?!) attributes! So I also added one attribute 'd'
+ * to RemoveAttribute.multiAttribute to compensate the missing change.
+ *
+ * At least it's not my fault ;-) But unfortunately we cannot test attribute additions here!
+ */
+ testTransformation(TestConstants.EACHONCE_URI1, TestConstants.EACHONCE_URI2, 14);
+ }
+
+ @Test
+ public void testTransformConflict() {
+ final List<EObject> inModels = CompareTestHelper.loadModel(TestConstants.CONFLICT_EMFDIFF_URI,
+ new ResourceSetImpl());
+ final ComparisonSnapshot emfdiff = (ComparisonSnapshot) inModels.get(0);
+ try {
+ // here it doesn't matter which symrefCreator and descriptorCreator we take!
+ TransformationLauncher.transform(emfdiff, null,
+ TestConstants.SYM_REF_CREATORS.iterator().next(), TestConstants.MODEL_DESCRIPTOR_CREATORS
+ .iterator().next());
+
+ /*
+ * The test should not reach this point!
+ */
+ fail("Transformation expected to throw an exception!");
+ } catch (final Exception e) {
+ // successful test run
+ }
+ }
+
+ private void testTransformation(String unchangedUri, String changedUri, int numberOfChanges) {
+ final ComparisonSnapshot emfdiff = CompareTestHelper.getEmfdiffFromEmfCompare(changedUri, unchangedUri);
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS) {
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+ try {
+ final MPatchModel mpatch = TransformationLauncher.transform(emfdiff, null, symrefCreator,
+ descriptorCreator);
+
+ CommonTestOperations.checkForDifferences(mpatch, numberOfChanges);
+ } catch (final Exception e) {
+ fail("Transformation unexpectedly threw an exception with symrefDescriptor: " + symrefCreator
+ + " and descriptorCreator: " + descriptorCreator + ": " + e.getMessage());
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/GeneralizationTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/GeneralizationTest.java
new file mode 100644
index 000000000..138ea67fa
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/GeneralizationTest.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.junit.Test;
+
+
+/**
+ * The test model is structured as follows:
+ *
+ * Entity Container
+ * + Entity A
+ * + Entity B
+ * + Entity C
+ *
+ * The differences (multiref.mpatch) describe the adding of a new Entity x which contains reference to all three sub-entities.
+ * These references' targets are again all three entities.
+ * That is, three Entities should be added including references to each of the entity.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ */
+public class GeneralizationTest {
+
+ /**
+ * See test description here: {@link GeneralizationTest}.
+ */
+ @Test
+ public void testMultiRef() {
+ // load models
+ final EObject model = CompareTestHelper.loadModel(TestConstants.MULTI_REF_URI1, new ResourceSetImpl()).get(0);
+ final EObject expectedModel = CompareTestHelper.loadModel(TestConstants.MULTI_REF_URI2, new ResourceSetImpl()).get(0);
+
+ // load diff
+ final MPatchModel mpatch = (MPatchModel)CompareTestHelper.loadModel(TestConstants.MULTI_REF_DIFF_URI, new ResourceSetImpl()).get(0);
+
+ // apply dependencies and check against expected model
+ CommonTestOperations.createAndApplyMPatch(mpatch, model, expectedModel, null, "multiref");
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/GroupingTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/GroupingTest.java
new file mode 100644
index 000000000..d2f0b58ea
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/GroupingTest.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.junit.Test;
+
+
+/**
+ * Check the creation of groups for several test models.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class GroupingTest {
+
+ @Test
+ public void testGroupsSimple() {
+ /*
+ * just one change leads to one group
+ */
+ testGroups(TestConstants.SIMPLE_URI1, TestConstants.SIMPLE_URI2, 1);
+ }
+
+ @Test
+ public void testGroupsDependencies() {
+ /*
+ * an added element with some changes and a removed element with some changes leads to two groups
+ */
+ testGroups(TestConstants.DEPENDENCY_URI1, TestConstants.DEPENDENCY_URI2, 2);
+ }
+
+ @Test
+ public void testGroupsEachonce() {
+ /*
+ * Uhm... difficult to foresee. I think 9. Each type one except for the 'add reference changes' because they add
+ * a reference to a newly added element and thus are in their group; and the three update references, because
+ * they all operate on the same element.
+ */
+ testGroups(TestConstants.EACHONCE_URI1, TestConstants.EACHONCE_URI2, 9);
+ }
+
+ private void testGroups(String unchangedUri, String changedUri, int expectedNumberOfGroups) {
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS) {
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+ final MPatchModel mpatch = CompareTestHelper.getMPatchFromUris(
+ changedUri, unchangedUri, symrefCreator, descriptorCreator);
+ assertNotNull("Preceeding transformation emfdiff2mpatch failed with symrefCreator: "
+ + symrefCreator.getLabel() + " and descriptorCreator: " + descriptorCreator.getLabel(), mpatch);
+
+ CommonTestOperations.groupingAndCheckForGroups(mpatch, expectedNumberOfGroups);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/IndividualTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/IndividualTest.java
new file mode 100644
index 000000000..6656e7644
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/IndividualTest.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import org.eclipse.emf.compare.mpatch.IndepAddAttributeChange;
+import org.eclipse.emf.compare.mpatch.IndepAddElementChange;
+import org.eclipse.emf.compare.mpatch.IndepAddReferenceChange;
+import org.eclipse.emf.compare.mpatch.IndepMoveElementChange;
+import org.eclipse.emf.compare.mpatch.IndepRemoveAttributeChange;
+import org.eclipse.emf.compare.mpatch.IndepRemoveElementChange;
+import org.eclipse.emf.compare.mpatch.IndepRemoveReferenceChange;
+import org.eclipse.emf.compare.mpatch.IndepUpdateAttributeChange;
+import org.eclipse.emf.compare.mpatch.IndepUpdateReferenceChange;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.junit.Test;
+
+/**
+ * This test checks each change type in an individual test case.
+ * It calculates the differences, applies them to the unchanged version, and compares it with the changed version.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ */
+public class IndividualTest {
+
+ /**
+ * Test applicability of {@link IndepAddElementChange}.
+ */
+ @Test
+ public void testApplyAddElement() {
+ testApply(TestConstants.INDIVIDUAL_ADD_REM_ELEMENT_URI1, TestConstants.INDIVIDUAL_ADD_REM_ELEMENT_URI2);
+ }
+
+ /**
+ * Test applicability of {@link IndepRemoveElementChange}.
+ */
+ @Test
+ public void testApplyRemoveElement() {
+ testApply(TestConstants.INDIVIDUAL_ADD_REM_ELEMENT_URI2, TestConstants.INDIVIDUAL_ADD_REM_ELEMENT_URI1);
+ }
+
+ /**
+ * Test applicability of {@link IndepMoveElementChange}.
+ */
+ @Test
+ public void testApplyMoveElement() {
+ testApply(TestConstants.INDIVIDUAL_MOVE_ELEMENT_URI1, TestConstants.INDIVIDUAL_MOVE_ELEMENT_URI2);
+ }
+
+ /**
+ * Test applicability of {@link IndepAddAttributeChange}.
+ */
+ @Test
+ public void testApplyAddAttribute() {
+ testApply(TestConstants.INDIVIDUAL_ADD_REM_ATTRIBUTE_URI1, TestConstants.INDIVIDUAL_ADD_REM_ATTRIBUTE_URI2);
+ }
+
+ /**
+ * Test applicability of {@link IndepRemoveAttributeChange}.
+ */
+ @Test
+ public void testApplyRemoveAttribute() {
+ testApply(TestConstants.INDIVIDUAL_ADD_REM_ATTRIBUTE_URI2, TestConstants.INDIVIDUAL_ADD_REM_ATTRIBUTE_URI1);
+ }
+
+ /**
+ * Test applicability of {@link IndepUpdateAttributeChange}.
+ */
+ @Test
+ public void testApplyUpdateAttribute() {
+ testApply(TestConstants.INDIVIDUAL_UPDATE_ATTRIBUTE_URI1, TestConstants.INDIVIDUAL_UPDATE_ATTRIBUTE_URI2);
+ }
+
+ /**
+ * Test applicability of {@link IndepAddReferenceChange}.
+ */
+ @Test
+ public void testApplyAddReference() {
+ testApply(TestConstants.INDIVIDUAL_ADD_REM_REFERENCE_URI1, TestConstants.INDIVIDUAL_ADD_REM_REFERENCE_URI2);
+ }
+
+ /**
+ * Test applicability of {@link IndepRemoveReferenceChange}.
+ */
+ @Test
+ public void testApplyRemoveReference() {
+ testApply(TestConstants.INDIVIDUAL_ADD_REM_REFERENCE_URI2, TestConstants.INDIVIDUAL_ADD_REM_REFERENCE_URI1);
+ }
+
+ /**
+ * Test applicability of {@link IndepUpdateReferenceChange}.
+ */
+ @Test
+ public void testApplyUpdateReference() {
+ testApply(TestConstants.INDIVIDUAL_UPDATE_REFERENCE_URI1, TestConstants.INDIVIDUAL_UPDATE_REFERENCE_URI2);
+ }
+
+ /** Same as {@link IndividualTest#testApply}. */
+ private void testApply(String unchangedUri, String changedUri) {
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS) {
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+ CommonTestOperations.applyMPatchAndValidate(unchangedUri, changedUri, symrefCreator, descriptorCreator);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/InternalRefTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/InternalRefTest.java
new file mode 100644
index 000000000..2154237b8
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/InternalRefTest.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.compare.mpatch.IndepAddRemElementChange;
+import org.eclipse.emf.compare.mpatch.IndepChange;
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.apply.generic.util.InternalReferencesTransformation;
+import org.eclipse.emf.compare.mpatch.apply.generic.util.MPatchDependencyTransformation;
+import org.eclipse.emf.compare.mpatch.common.util.ExtensionManager;
+import org.eclipse.emf.compare.mpatch.common.util.MPatchConstants;
+import org.eclipse.emf.compare.mpatch.descriptor.EMFModelDescriptor;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.extension.MPatchApplicationResult;
+import org.eclipse.emf.compare.mpatch.extension.ResolvedSymbolicReferences;
+import org.eclipse.emf.compare.mpatch.symrefs.ElementSetReference;
+import org.eclipse.emf.compare.mpatch.symrefs.OclCondition;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.eclipse.emf.compare.mpatch.transform.util.GeneralizeTransformation;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.junit.Test;
+
+/**
+ * The test first creates mpatches and then calls the following transformations:
+ * <ol>
+ * <li>dependency graph
+ * <li>string weakening
+ * <li>cardinality weakening
+ * <li>internal reference replacement
+ * </ol>
+ *
+ * Then the mpatch is modified such that internal references are required to resolve correctly.
+ *
+ * The modified changes are applied to a prepared model and the application result and the changed model are checked.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ */
+public class InternalRefTest {
+
+ /**
+ * See test description here: {@link InternalRefTest}.
+ */
+ @Test
+ public void testInternalRef() {
+ // get creators
+ final ISymbolicReferenceCreator symrefCreator = ExtensionManager.getAllSymbolicReferenceCreators().get(
+ "Condition-based");
+ final IModelDescriptorCreator descriptorCreator = ExtensionManager.getAllModelDescriptorCreators().get(
+ "Default");
+ final String info = "symrefCreator: " + symrefCreator.getLabel() + ", descriptorCreator: "
+ + descriptorCreator.getLabel();
+
+ // create mpatch
+ final MPatchModel mpatch = CompareTestHelper.getMPatchFromUris(TestConstants.INTERNAL_REF_URI2,
+ TestConstants.INTERNAL_REF_URI1, symrefCreator, descriptorCreator);
+
+ doTransformations(mpatch);
+ modifyDiff(mpatch);
+
+ // resolve references to other model
+ final EPackage applyModel = (EPackage) CompareTestHelper.loadModel(TestConstants.INTERNAL_REF_URI3,
+ new ResourceSetImpl()).get(0);
+ final ResolvedSymbolicReferences resolvedReferences = CompareTestHelper.resolveReferences(mpatch, applyModel, info);
+
+ // apply differences
+ final MPatchApplicationResult result = TestConstants.DIFF_APPLIER.applyMPatch(resolvedReferences, true);
+
+ // check application status
+ assertTrue("Some changes failed to apply: " + result.failed, result.failed.isEmpty());
+ assertTrue("Cross reference restoring failed for: " + result.crossReferences, result.crossReferences.isEmpty());
+ assertEquals("Application result was not successful!", MPatchApplicationResult.ApplicationStatus.SUCCESSFUL,
+ result.status);
+
+ // check model!
+ assertEquals("Different number of elements in root package than expected: " + applyModel.getEClassifiers(), 3,
+ applyModel.getEClassifiers().size());
+ assertEquals("Different number of elements in sub package than expected: "
+ + applyModel.getESubpackages().get(0).getEClassifiers(), 1, applyModel.getESubpackages().get(0)
+ .getEClassifiers().size());
+ for (EClassifier classifier : applyModel.getEClassifiers()) {
+ if (!classifier.getName().equals("C")) {
+ final EClass aClass = (EClass) classifier;
+ assertEquals("Cross references (eSuperType) does not refer to the two new classes 'C', but: "
+ + aClass.getESuperTypes(), 2, aClass.getESuperTypes().size());
+ }
+ }
+ }
+
+ private void modifyDiff(MPatchModel mpatch) {
+ assertEquals("Number of changes doesn't match!", 3, mpatch.getChanges().size());
+
+ // get model descriptor of add class 'B' change
+ final EMFModelDescriptor subModel = getAddChangeModelDescriptor(mpatch.getChanges(), "B");
+ final EList<Object> attribute = subModel.getAttributes().get(EcorePackage.Literals.ENAMED_ELEMENT__NAME);
+ final Object name = attribute.get(0);
+ assertEquals("Attribute name differs!", "B", name);
+
+ // change to 'C' and verify
+ attribute.set(0, "C");
+ final Object newName = subModel.getAttributes().get(EcorePackage.Literals.ENAMED_ELEMENT__NAME).get(0);
+ assertEquals("Attribute name should have changed to 'C'!", "C", newName);
+
+ // get model descriptor of add class 'A2' change
+ final IndepChange addChange = (IndepChange) getAddChangeModelDescriptor(mpatch.getChanges(), "A2").eContainer();
+ final ElementSetReference corrReference = (ElementSetReference) addChange.getCorrespondingElement();
+ final OclCondition condition = (OclCondition) corrReference.getConditions().get(0);
+ condition.setExpression("name = 'root'"); // no weakening here!
+ }
+
+ private EMFModelDescriptor getAddChangeModelDescriptor(EList<IndepChange> changes, String name) {
+ for (IndepChange indepChange : changes) {
+ if (indepChange instanceof IndepAddRemElementChange) {
+ final EMFModelDescriptor subModel = (EMFModelDescriptor) ((IndepAddRemElementChange) indepChange)
+ .getSubModel();
+ final EList<Object> attr = subModel.getAttributes().get(EcorePackage.Literals.ENAMED_ELEMENT__NAME);
+ if (attr != null && attr.size() == 1 && name.equals(attr.get(0)))
+ return subModel;
+ }
+ }
+ fail("EClass named '" + name + "' not found in: " + changes);
+ return null;
+ }
+
+ private void doTransformations(MPatchModel mpatch) {
+ final int deps = MPatchDependencyTransformation.calculateDependencies(mpatch);
+ assertNull(MPatchConstants.MPATCH_SHORT_NAME + " is not valid!", CompareTestHelper.validateMPatch(mpatch));
+ assertEquals("Dependencies were not calculated correctly!", 2, deps);
+ final int refs = InternalReferencesTransformation.createInternalReferences(mpatch);
+ assertNull(MPatchConstants.MPATCH_SHORT_NAME + " is not valid!", CompareTestHelper.validateMPatch(mpatch));
+ assertEquals("Internal references were not created correctly!", 2, refs);
+ final int card = GeneralizeTransformation.unboundSymbolicReferences(mpatch);
+ assertNull(MPatchConstants.MPATCH_SHORT_NAME + " is not valid!", CompareTestHelper.validateMPatch(mpatch));
+ assertEquals("Cardinality weakening was not performed correctly!", 8, card);
+ final int str = GeneralizeTransformation.expandScope(mpatch);
+ assertNull(MPatchConstants.MPATCH_SHORT_NAME + " is not valid!", CompareTestHelper.validateMPatch(mpatch));
+ assertTrue("String weakening was not performed correctly!", str >= 3);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/LibraryExampleTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/LibraryExampleTest.java
new file mode 100644
index 000000000..4b60f3f84
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/LibraryExampleTest.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.apply.generic.util.InternalReferencesTransformation;
+import org.eclipse.emf.compare.mpatch.apply.generic.util.MPatchDependencyTransformation;
+import org.eclipse.emf.compare.mpatch.common.util.ExtensionManager;
+import org.eclipse.emf.compare.mpatch.common.util.MPatchConstants;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.extension.MPatchApplicationResult;
+import org.eclipse.emf.compare.mpatch.extension.ResolvedSymbolicReferences;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.eclipse.emf.compare.mpatch.transform.util.GeneralizeTransformation;
+import org.eclipse.emf.compare.mpatch.transform.util.GroupingTransformation;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.junit.Test;
+
+/**
+ * Testing the library example:
+ * <ol>
+ * <li> Compare library.ecore and library_karl.ecore with EMF Compare
+ * <li> Create MPatch (condition-based only)
+ * <li> Perform all available transformations
+ * <li> Apply all changes to library_eve.ecore
+ * </ol>
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ */
+public class LibraryExampleTest {
+
+ /**
+ * Test description: {@link LibraryExampleTest}
+ */
+ @Test
+ public void testLibraryExample() {
+ // get creators
+ final ISymbolicReferenceCreator symrefCreator = ExtensionManager.getAllSymbolicReferenceCreators().get(
+ "Condition-based");
+ final IModelDescriptorCreator descriptorCreator = ExtensionManager.getAllModelDescriptorCreators().get(
+ "Default");
+ final String info = "symrefCreator: " + symrefCreator.getLabel() + ", descriptorCreator: "
+ + descriptorCreator.getLabel();
+
+ // create mpatch
+ final MPatchModel mpatch = CompareTestHelper.getMPatchFromUris(TestConstants.LIBRARY_URI2,
+ TestConstants.LIBRARY_URI1, symrefCreator, descriptorCreator);
+
+ doTransformations(mpatch);
+
+ // resolve references to other model
+ final EPackage applyModel = (EPackage) CompareTestHelper.loadModel(TestConstants.LIBRARY_URI3,
+ new ResourceSetImpl()).get(0);
+ final ResolvedSymbolicReferences resolvedReferences = CompareTestHelper.resolveReferences(mpatch, applyModel, info);
+
+ // apply differences
+ final MPatchApplicationResult result = TestConstants.DIFF_APPLIER.applyMPatch(resolvedReferences, true);
+
+ // check application status
+ assertTrue("Some changes failed to apply: " + result.failed, result.failed.isEmpty());
+ assertTrue("Cross reference restoring failed for: " + result.crossReferences, result.crossReferences.isEmpty());
+ assertEquals("Application result was not successful!", MPatchApplicationResult.ApplicationStatus.SUCCESSFUL,
+ result.status);
+ }
+
+ private void doTransformations(MPatchModel mpatch) {
+ final int groups = GroupingTransformation.group(mpatch);
+ assertNull(MPatchConstants.MPATCH_SHORT_NAME + " is not valid!", CompareTestHelper.validateMPatch(mpatch));
+ assertEquals("Groups were not created correctly!", 2, groups);
+ final int deps = MPatchDependencyTransformation.calculateDependencies(mpatch);
+ assertNull(MPatchConstants.MPATCH_SHORT_NAME + " is not valid!", CompareTestHelper.validateMPatch(mpatch));
+ assertEquals("Dependencies were not calculated correctly!", 4, deps);
+ final int refs = InternalReferencesTransformation.createInternalReferences(mpatch);
+ assertNull(MPatchConstants.MPATCH_SHORT_NAME + " is not valid!", CompareTestHelper.validateMPatch(mpatch));
+ assertEquals("Internal references were not created correctly!", 6, refs);
+ final int card = GeneralizeTransformation.unboundSymbolicReferences(mpatch);
+ assertNull(MPatchConstants.MPATCH_SHORT_NAME + " is not valid!", CompareTestHelper.validateMPatch(mpatch));
+ assertEquals("Cardinality weakening was not performed correctly!", 16, card);
+ final int str = GeneralizeTransformation.expandScope(mpatch);
+ assertNull(MPatchConstants.MPATCH_SHORT_NAME + " is not valid!", CompareTestHelper.validateMPatch(mpatch));
+ assertTrue("String weakening was not performed correctly!", str >= 12);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/MergeChangesTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/MergeChangesTest.java
new file mode 100644
index 000000000..efb32f7bf
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/MergeChangesTest.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.compare.mpatch.IndepChange;
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.MPatchPackage;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.extension.ResolvedSymbolicReferences;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.eclipse.emf.compare.mpatch.transform.util.GeneralizeTransformation;
+import org.eclipse.emf.compare.mpatch.util.ExtEcoreUtils;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test the merging of changes. Each change type can be merged, thus, 9 test methods. After applying the merged changes
+ * to the original unchanged model again, the result must again be the changed model!
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ */
+public class MergeChangesTest {
+
+ private static final String CONDITION_BASED_SYMREF_CREATOR = "Condition-based";
+
+ /** The merged MPatch for EMF models. */
+ private static Map<String, MPatchModel> mergedMPatchesEMF = new HashMap<String, MPatchModel>();
+
+ /** The merged MPatch for eachonce models. */
+ private static Map<String, MPatchModel> mergedMPatchesEachonce = new HashMap<String, MPatchModel>();
+
+ /**
+ * Build the MPatch and merge changes before the actual tests are performed.
+ */
+ @BeforeClass
+ public static void prepare() {
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS) {
+ if (!symrefCreator.getLabel().equals(CONDITION_BASED_SYMREF_CREATOR))
+ continue;
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+ final String info = "Symref-creator: " + symrefCreator + "; descriptor-creator: " + descriptorCreator;
+
+ // prepare MPatches
+ final MPatchModel emfMPatch = prepareMPatch(symrefCreator, descriptorCreator,
+ TestConstants.MERGE_EMF_URI1, TestConstants.MERGE_EMF_URI2, info);
+ final MPatchModel eachonceMPatch = prepareMPatch(symrefCreator, descriptorCreator,
+ TestConstants.MERGE_EACHONCE_URI1, TestConstants.MERGE_EACHONCE_URI2, info);
+
+ // storing them
+ mergedMPatchesEMF.put(info, emfMPatch);
+ mergedMPatchesEachonce.put(info, eachonceMPatch);
+ }
+ }
+ }
+
+ /**
+ * Create an MPatch for the two given uris and perform the merge transformation.
+ *
+ * @param symrefCreator
+ * The symref creator to use.
+ * @param descriptorCreator
+ * The model descriptor creator to use.
+ * @param uri1
+ * The UNCHANGED version of a model.
+ * @param uri2
+ * The CHANGED version of a model.
+ * @param info
+ * Additional information for the assert messages.
+ * @return The MPatch that was already merged.
+ */
+ private static MPatchModel prepareMPatch(ISymbolicReferenceCreator symrefCreator,
+ IModelDescriptorCreator descriptorCreator, String uri1, String uri2, String info) {
+
+ // creating mpatches
+ final MPatchModel mPatch = CompareTestHelper.getMPatchFromUris(uri2, uri1, symrefCreator, descriptorCreator);
+
+ // checking them
+ assertNotNull("Could not create MPatch (" + info + ") for " + uri1 + " and " + uri2, mPatch);
+
+ // performing common transformations
+ CommonTestOperations.doTransformations(mPatch, null, info);
+
+ // merging!!!
+ GeneralizeTransformation.mergeChanges(mPatch);
+ return mPatch;
+ }
+
+ /**
+ * Test whether added elements can be merged.
+ */
+ @Test
+ public void testMergedMPatchApplication() {
+ checkMPatchApplication(mergedMPatchesEMF, TestConstants.MERGE_EMF_URI1, TestConstants.MERGE_EMF_URI2, "EMF-model");
+ checkMPatchApplication(mergedMPatchesEachonce, TestConstants.MERGE_EACHONCE_URI1, TestConstants.MERGE_EACHONCE_URI2, "Eachonce-model");
+ }
+
+ private void checkMPatchApplication(Map<String, MPatchModel> mPatches, String uri1, String uri2, String moreInfo) {
+ for (String info : mPatches.keySet()) {
+ final MPatchModel mPatch = mPatches.get(info);
+ info += "; " + moreInfo;
+
+ // load models
+ final EObject model = CompareTestHelper.loadModel(uri1, new ResourceSetImpl()).get(0);
+ final EObject expectedModel = CompareTestHelper.loadModel(uri2, new ResourceSetImpl()).get(0);
+
+ final ResolvedSymbolicReferences resolved = CommonTestOperations.resolveAndValidate(mPatch, model, null, info);
+ final EObject newModel = CommonTestOperations.applyMPatchToModel(mPatch, model, resolved, null, info);
+ CommonTestOperations.compareChangedAndUnchangedModels(model, newModel, null, info);
+ CommonTestOperations.checkAppliedModel(model, expectedModel, info);
+ CommonTestOperations.checkBinding(resolved.getMPatchModelBinding(), info);
+ }
+ }
+
+ /**
+ * Test whether added element changes were successfully merged.
+ */
+ @Test
+ public void testAddedElementMerge() {
+ checkNumberOfChanges(mergedMPatchesEMF, MPatchPackage.Literals.INDEP_ADD_ELEMENT_CHANGE, 1);
+ }
+
+ /**
+ * Test whether removed element changes were successfully merged.
+ */
+ @Test
+ public void testRemovedElementMerge() {
+ checkNumberOfChanges(mergedMPatchesEMF, MPatchPackage.Literals.INDEP_REMOVE_ELEMENT_CHANGE, 1);
+ }
+
+ /**
+ * Test whether moved element changes were successfully merged.
+ */
+ @Test
+ public void testMovedElementMerge() {
+ // we got 2 merges here in the test model!
+ checkNumberOfChanges(mergedMPatchesEMF, MPatchPackage.Literals.INDEP_MOVE_ELEMENT_CHANGE, 2);
+ }
+
+ /**
+ * Test whether add attribute changes were successfully merged.
+ */
+ @Test
+ public void testAddAttributeMerge() {
+ checkNumberOfChanges(mergedMPatchesEachonce, MPatchPackage.Literals.INDEP_ADD_ATTRIBUTE_CHANGE, 1);
+ }
+
+ /**
+ * Test whether remove attribute changes were successfully merged.
+ */
+ @Test
+ public void testRemoveAttributeMerge() {
+ checkNumberOfChanges(mergedMPatchesEachonce, MPatchPackage.Literals.INDEP_REMOVE_ATTRIBUTE_CHANGE, 1);
+ }
+
+ /**
+ * Test whether update attribute changes were successfully merged.
+ */
+ @Test
+ public void testUpdateAttributeMerge() {
+ checkNumberOfChanges(mergedMPatchesEachonce, MPatchPackage.Literals.INDEP_UPDATE_ATTRIBUTE_CHANGE, 1);
+ }
+
+ /**
+ * Test whether add reference changes were successfully merged.
+ */
+ @Test
+ public void testAddReferenceMerge() {
+ checkNumberOfChanges(mergedMPatchesEachonce, MPatchPackage.Literals.INDEP_ADD_REFERENCE_CHANGE, 1);
+ }
+
+ /**
+ * Test whether remove reference changes were successfully merged.
+ */
+ @Test
+ public void testRemoveReferenceMerge() {
+ checkNumberOfChanges(mergedMPatchesEachonce, MPatchPackage.Literals.INDEP_REMOVE_REFERENCE_CHANGE, 1);
+ }
+
+ /**
+ * Test whether update reference changes were successfully merged.
+ */
+ @Test
+ public void testUpdateReferenceMerge() {
+ // we got 3 merges here in the test model!
+ checkNumberOfChanges(mergedMPatchesEachonce, MPatchPackage.Literals.INDEP_UPDATE_REFERENCE_CHANGE, 3);
+ }
+
+ /**
+ * Check the number of changes in all given mPatches.
+ *
+ * @param mPatches
+ * The MPatches to check.
+ * @param changeType
+ * The type that should be checked.
+ * @param count
+ * The expected number of changes of the specified type.
+ */
+ private void checkNumberOfChanges(Map<String, MPatchModel> mPatches, EClass changeType, int count) {
+ for (String info : mPatches.keySet()) {
+ final MPatchModel mPatch = mPatches.get(info);
+ final List<EObject> addElementChanges = ExtEcoreUtils.collectTypedElements(mPatch.getChanges(), Collections
+ .singleton(changeType), true);
+
+ // remove those whose upper bound of corresponding reference is still 1.
+ for (int i = addElementChanges.size() - 1; i >= 0; i--) {
+ final IndepChange change = (IndepChange) addElementChanges.get(i);
+ if (change.getCorrespondingElement().getUpperBound() == 1)
+ addElementChanges.remove(i);
+ }
+
+ // we just require one merged change here!
+ assertEquals("Wrong number of merged changes: " + changeType.getName() + "! (" + info + ")", count,
+ addElementChanges.size());
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/OclExpressionTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/OclExpressionTest.java
new file mode 100644
index 000000000..54d28e5b3
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/OclExpressionTest.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.junit.Test;
+
+
+/**
+ * Check whether all symbolic references contain valid (parseable) OCL expressions.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class OclExpressionTest {
+
+ @Test
+ public void testOCLSimple() {
+ testOCL(TestConstants.SIMPLE_URI1, TestConstants.SIMPLE_URI2);
+ }
+
+ @Test
+ public void testOCLDependency() {
+ testOCL(TestConstants.DEPENDENCY_URI1, TestConstants.DEPENDENCY_URI2);
+ }
+
+ @Test
+ public void testOCLEachonce() {
+ testOCL(TestConstants.EACHONCE_URI1, TestConstants.EACHONCE_URI2);
+ }
+
+ @Test
+ public void testOCLEcore() {
+ testOCL(TestConstants.ECORE_URI1, TestConstants.ECORE_URI2);
+ }
+
+ @Test
+ public void testOCLUml() {
+ testOCL(TestConstants.UML_URI1, TestConstants.UML_URI2);
+ }
+
+ private void testOCL(String unchangedUri, String changedUri) {
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS) {
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+ MPatchModel mpatch = CompareTestHelper.getMPatchFromUris(changedUri, unchangedUri, symrefCreator,
+ descriptorCreator);
+ assertNotNull("Preceeding transformation emfdiff2mpatch failed with symrefCreator: "
+ + symrefCreator.getLabel() + " and descriptorCreator: " + descriptorCreator.getLabel(), mpatch);
+ CommonTestOperations.checkOclExpressions(mpatch);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/PerformanceTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/PerformanceTest.java
new file mode 100644
index 000000000..94e7e51b5
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/PerformanceTest.java
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.text.Format;
+
+import org.eclipse.emf.compare.diff.metamodel.ComparisonSnapshot;
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.emfdiff2mpatch.util.TransformationLauncher;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.PerformanceTimes;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EOperation;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EParameter;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.junit.Test;
+
+
+/**
+ * This test case is about performance: by setting some parameters, the number of differences and the size of the model
+ * can be varied.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class PerformanceTest {
+
+ /** The smallest test case including this many classes (and 6 times as many changes), e.g. 50. */
+ private static final int lowerBound = 2;
+
+ /** The biggest test case including this many classes (and 6 times as many changes), e.g. 100. */
+ private static final int upperBound = 100;
+
+ /** The step with which the test size is incremented in each iteration, e.g. 10. */
+ private static final int step = 49;
+
+ /** Just some legend for the test results printed to <code>System.out</code>. */
+ private static final String header = "============================================================================================================\n"
+ + "Legend of the performance test results:\n"
+ + " Diff's - The number of differences in this test run\n"
+ + " Build - Time for building test models\n"
+ + " Emfdiff - Time for comparing these model with EMF Compare\n"
+ + " MPatch - Time for QVTO transformation to create mpatch\n"
+ + " Groups - Time for creating groups in mpatch\n"
+ + " Deps - Time for creating dependency graph in mpatch\n"
+ + " Refs - Time for creating inernal symbolic references\n"
+ + " Resolve - Time for resolving symbolic references for target model\n"
+ + " Copy - Time for copying the target model\n"
+ + " Apply - Time for applying mpatch to target model\n"
+ + " Changes - Time for comparing unchanged with changed model with EMF Compare\n"
+ + " Check - Time for checking whether all diffs have been applied successfully\n"
+ + " Total - Total time for this test run\n"
+ + " Transformation - Parameters for the transformation, i.e. symref descriptor creators\n"
+ + "All times are given in ms (miliseconds).\n\n"
+ + " Diff's | Built | Emfdiff | MPatch | Groups | Deps | Refs | Resolve | Copy | Apply | Changes | Check | Total | Transformation\n"
+ + "--------+-------+---------+--------+--------+------+------+---------+------+--------+---------+-------+--------+----------------";
+
+ /**
+ * Run the performance test with the parameters given in <code>lowerBound</code>, <code>upperBound</code>, and
+ * <code>step</code>.
+ */
+ @Test
+ public void testPerformance() {
+ System.out.println(header);
+
+ /*
+ * test for the performance documentation in the paper:
+ */
+ // System.out.println(prettyPrint(100, testPerformance(100, ExtensionManager.getAllSymbolicReferenceCreators()
+ // .get("ID-based"), TestConstants.modelDescriptorCreators.iterator().next()), "id performance test"));
+ // if("".isEmpty())return;
+
+ // iterate from 50 to 500 classes in the model to find out the limit
+ for (int i = lowerBound; i <= upperBound; i += step)
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS)
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS)
+ System.out.println(prettyPrint(i * 6, testPerformance(i, symrefCreator, descriptorCreator),
+ "descriptor: " + descriptorCreator.getLabel() + ", symref: " + symrefCreator.getLabel()));
+
+ }
+
+ private static String prettyPrint(int differences, PerformanceTimes times, String transformation) {
+ return intToFixedWidthString(differences, 7) + " |" // Differences
+ + intToFixedWidthString(times.getBuilt(), 6) + " |" // Built
+ + intToFixedWidthString(times.getEmfdiff(), 8) + " |" // Emfdiff
+ + intToFixedWidthString(times.getMPatch(), 7) + " |" // MPatch
+ + intToFixedWidthString(times.getGroups(), 7) + " |" // Groups
+ + intToFixedWidthString(times.getDeps(), 5) + " |" // Deps
+ + intToFixedWidthString(times.getRefs(), 5) + " |" // Refs
+ + intToFixedWidthString(times.getResolve(), 8) + " |" // Resolve
+ + intToFixedWidthString(times.getCopy(), 5) + " |" // Copy
+ + intToFixedWidthString(times.getApply(), 7) + " |" // Apply
+ + intToFixedWidthString(times.getChanges(), 8) + " |" // Changes
+ + intToFixedWidthString(times.getCheck(), 6) + " |" // Check
+ + intToFixedWidthString(times.getTotal(), 7) + " | " // Total
+ + transformation; // details about the transformation
+ }
+
+ private static String intToFixedWidthString(long i, int strlen) {
+ StringBuffer result = new StringBuffer();
+ String str = String.valueOf(i);
+ for (int j = 0; j < strlen - str.length(); j++)
+ result.append(" ");
+ result.append(str);
+ return result.toString();
+ }
+
+ private static PerformanceTimes testPerformance(int size, ISymbolicReferenceCreator symrefCreator,
+ IModelDescriptorCreator descriptorCreator) {
+
+ final PerformanceTimes times = new PerformanceTimes(); // start timing
+ final String info = "symrefCreator: " + symrefCreator.getLabel() + " and descriptorCreator: "
+ + descriptorCreator.getLabel();
+
+ // build performance model!
+ ResourceSet resourceSet = new ResourceSetImpl();
+ EObject rightModel = buildUnchangedModel(TestConstants.PERFORMANCE_URI1, resourceSet, size);
+ EObject leftModel = buildChangedModel(TestConstants.PERFORMANCE_URI2, resourceSet, size);
+ times.setBuilt(); // models are built
+
+// try { // store models without doing anything, e.g. to see test models
+// rightModel.eResource().save(null);
+// leftModel.eResource().save(null);
+// return times;
+// } catch (Exception e) {
+// fail("Could not save models: " + e.getMessage());
+// }
+
+ // prepare models
+ final ComparisonSnapshot emfdiff = CompareTestHelper.getEmfdiffFromEmfCompare(leftModel, rightModel);
+ times.setEmfdiff(); // emfdiff is built
+ final MPatchModel mpatch;
+ try {
+ mpatch = TransformationLauncher.transform(emfdiff, null, symrefCreator, descriptorCreator);
+ } catch (Exception e) {
+ fail("transformation failed (" + info + "): " + e.getMessage());
+ return null;
+ }
+ times.setMPatch(); // mpatch is built
+ assertNotNull("Preceeding transformation failed! " + info, mpatch);
+
+ // get new resource to not conflict with original models!
+ resourceSet = new ResourceSetImpl();
+ resourceSet.getResources().add(rightModel.eResource());
+ resourceSet.getResources().add(leftModel.eResource());
+
+ // apply differences and validate the result against the leftModel!
+ CommonTestOperations.createAndApplyMPatch(mpatch, rightModel, leftModel, times, info);
+
+ return times;
+ }
+
+ /*
+ * BELOW: METHODS FOR BUILDING THE PERFORMANCE TEST MODEL
+ */
+
+ private static Format fourFormat = new java.text.DecimalFormat("000");
+
+ private static EObject buildChangedModel(String uriString, ResourceSet resourceSet, int size) {
+ // get package of interest
+ final EPackage pack = (EPackage) CompareTestHelper.loadModel(uriString, resourceSet).get(0);
+ EPackage newPlace = null;
+ for (EPackage p : pack.getESubpackages())
+ if ("newPlace".equals(p.getName()))
+ newPlace = p;
+ assertNotNull("Cannot find package 'newPlace'", newPlace);
+
+ // get some classifiers we need later
+ EClass superType = (EClass) pack.getEClassifier("SuperType");
+ EClassifier oldReferenceTarget = pack.getEClassifier("OldReferenceTarget");
+ EClassifier newReferenceTarget = pack.getEClassifier("NewReferenceTarget");
+ assertNotNull("Cannot find classifier 'SuperType'", superType);
+ assertNotNull("Cannot find classifier 'OldReferenceTarget'", oldReferenceTarget);
+ assertNotNull("Cannot find classifier 'NewReferenceTarget'", newReferenceTarget);
+
+ // now lets create the test data
+ for (int i = 0; i < size; i++) {
+
+ // create a class
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("Class" + fourFormat.format(i));
+ c.getESuperTypes().add(superType);
+
+ // create an attribute
+ EAttribute a = EcoreFactory.eINSTANCE.createEAttribute();
+ a.setName("attribute");
+ a.setEType(EcorePackage.Literals.ESTRING);
+
+ // create a reference to newReferenceTarget
+ EReference r = EcoreFactory.eINSTANCE.createEReference();
+ r.setName("reference");
+ r.setEType(newReferenceTarget);
+ r.setUpperBound(-1);
+
+ // add everthing properly
+ c.getEStructuralFeatures().add(a);
+ c.getEStructuralFeatures().add(r);
+ newPlace.getEClassifiers().add(c);
+ }
+ return pack;
+ }
+
+ private static EObject buildUnchangedModel(String uriString, ResourceSet resourceSet, int size) {
+ // get package of interest
+ final EPackage pack = (EPackage) CompareTestHelper.loadModel(uriString, resourceSet).get(0);
+ EPackage oldPlace = null;
+ for (EPackage p : pack.getESubpackages())
+ if ("oldPlace".equals(p.getName()))
+ oldPlace = p;
+ assertNotNull("Cannot find package 'oldPlace'", oldPlace);
+
+ // get some classifiers we need later
+ EClassifier superType = pack.getEClassifier("SuperType");
+ EClassifier oldReferenceTarget = pack.getEClassifier("OldReferenceTarget");
+ EClassifier newReferenceTarget = pack.getEClassifier("NewReferenceTarget");
+ assertNotNull("Cannot find classifier 'SuperType'", superType);
+ assertNotNull("Cannot find classifier 'OldReferenceTarget'", oldReferenceTarget);
+ assertNotNull("Cannot find classifier 'NewReferenceTarget'", newReferenceTarget);
+
+ // now lets create the test data
+ for (int i = 0; i < size; i++) {
+
+ // create a class
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("Class" + fourFormat.format(i));
+
+ // create an operation with two parameters for the class
+ EOperation o = EcoreFactory.eINSTANCE.createEOperation();
+ o.setName("operation");
+ o.setEType(newReferenceTarget);
+ EParameter p1 = EcoreFactory.eINSTANCE.createEParameter();
+ p1.setName("parameter1");
+ p1.setEType(superType);
+ EParameter p2 = EcoreFactory.eINSTANCE.createEParameter();
+ p2.setName("parameter2");
+ p2.setEType(superType);
+
+ // create a reference to oldReferenceTarget
+ EReference r = EcoreFactory.eINSTANCE.createEReference();
+ r.setName("reference");
+ r.setEType(oldReferenceTarget);
+
+ // add everthing properly
+ o.getEParameters().add(p1);
+ o.getEParameters().add(p2);
+ c.getEOperations().add(o);
+ c.getEStructuralFeatures().add(r);
+ oldPlace.getEClassifiers().add(c);
+ }
+ return pack;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ResolveTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ResolveTest.java
new file mode 100644
index 000000000..7b43f4a3d
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ResolveTest.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.junit.Test;
+
+
+/**
+ * Low-level test for checking whether the symbolic references resolve correctly for different test models.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class ResolveTest {
+
+ @Test
+ public void testResolveSymbolicReferencesSimple() {
+ testResolveSymbolicReferences(TestConstants.SIMPLE_URI1, TestConstants.SIMPLE_URI2);
+ }
+
+ @Test
+ public void testResolveSymbolicReferencesDependency() {
+ testResolveSymbolicReferences(TestConstants.DEPENDENCY_URI1, TestConstants.DEPENDENCY_URI2);
+ }
+
+ @Test
+ public void testResolveSymbolicReferencesEachonce() {
+ testResolveSymbolicReferences(TestConstants.EACHONCE_URI1, TestConstants.EACHONCE_URI2);
+ }
+
+ private void testResolveSymbolicReferences(String unchangedUri, String changedUri) {
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS) {
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+ CommonTestOperations.checkSymbolicReferenceResolution(unchangedUri, changedUri, symrefCreator,
+ descriptorCreator);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ReverseTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ReverseTest.java
new file mode 100644
index 000000000..23f905ea3
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/ReverseTest.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+
+import org.eclipse.emf.compare.diff.metamodel.ComparisonResourceSnapshot;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.common.util.CommonUtils;
+import org.eclipse.emf.compare.mpatch.common.util.ExtensionManager;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.CompareTestHelper;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.eclipse.emf.compare.mpatch.transform.util.ReverseTransformation;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.junit.Test;
+
+/**
+ * This test checks whether reversed MPatches are correct.
+ *
+ * It first checks that an MPatch P equals reversed(reversed(P)).
+ *
+ * Second, an MPatch P created from M1 (unchanged) and M2 (changed) is checked as follows: M1 equals reversed(P) applied
+ * to M2.
+ *
+ * We cannot test any model whose attributes are used as unique identifiers! This is why some test models are not used
+ * here. The reason is that attribute changes will change the symbolic reference if that attribute is used in symbolic
+ * references.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ */
+public class ReverseTest {
+
+ private final static String ID_BASED_SYMREFS = "ID-based";
+ private final static String CONDITION_BASED_SYMREFS = "Condition-based";
+
+ /**
+ * Reversed test with dependency cycle model.
+ */
+ @Test
+ public void testReverseDependencyCycle() {
+ testReversed(TestConstants.DEP_CYCLE_URI1, TestConstants.DEP_CYCLE_URI2, ID_BASED_SYMREFS);
+ testReversed(TestConstants.DEP_CYCLE_URI1, TestConstants.DEP_CYCLE_URI2, CONDITION_BASED_SYMREFS);
+ }
+
+ /**
+ * Reversed test with dependency model.
+ */
+ @Test
+ public void testReverseDifferencesDependency() {
+ testReversed(TestConstants.DEPENDENCY_URI1, TestConstants.DEPENDENCY_URI2, ID_BASED_SYMREFS);
+ testReversed(TestConstants.DEPENDENCY_URI1, TestConstants.DEPENDENCY_URI2, CONDITION_BASED_SYMREFS);
+ }
+
+ /**
+ * Reversed test with eachonce model.
+ */
+ @Test
+ public void testReverseDifferencesEachonce() {
+ testReversed(TestConstants.EACHONCE_URI1, TestConstants.EACHONCE_URI2, ID_BASED_SYMREFS);
+ testReversed(TestConstants.EACHONCE_URI1, TestConstants.EACHONCE_URI2, CONDITION_BASED_SYMREFS);
+ }
+
+ /**
+ * Reversed test with ecore model.
+ */
+ @Test
+ public void testReverseDifferencesEcore() {
+ testReversed(TestConstants.ECORE_URI1, TestConstants.ECORE_URI2, ID_BASED_SYMREFS);
+ testReversed(TestConstants.ECORE_URI1, TestConstants.ECORE_URI2, CONDITION_BASED_SYMREFS);
+ }
+
+ /**
+ * Reversed test with UML model.
+ */
+ @Test
+ public void testReverseDifferencesUML() {
+ testReversed(TestConstants.UML_URI1, TestConstants.UML_URI2, ID_BASED_SYMREFS);
+ // condition-based does not work here, unfortunately, because one of the changes (cardinality from 0 to 1)
+ // resolves ambiguously in the reverted changes.
+ }
+
+ /**
+ * Reverse test with simple model.
+ */
+ @Test
+ public void testReverseSimple() {
+ testReversed(TestConstants.SIMPLE_URI1, TestConstants.SIMPLE_URI2, ID_BASED_SYMREFS);
+ testReversed(TestConstants.SIMPLE_URI1, TestConstants.SIMPLE_URI2, CONDITION_BASED_SYMREFS);
+ }
+
+ /**
+ * Reverse test with simple model.
+ */
+ @Test
+ public void testReverseLibrary() {
+ testReversed(TestConstants.LIBRARY_URI1, TestConstants.LIBRARY_URI2, ID_BASED_SYMREFS);
+ testReversed(TestConstants.LIBRARY_URI1, TestConstants.LIBRARY_URI2, CONDITION_BASED_SYMREFS);
+ }
+
+ private void testReversed(String unchangedUri, String changedUri, String symrefs) {
+ final ISymbolicReferenceCreator symrefCreator = ExtensionManager.getAllSymbolicReferenceCreators().get(symrefs);
+ assertNotNull("Please make sure this symref creator is installed correctly: " + symrefs, symrefCreator);
+
+ // but we can test all model descriptors!
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+
+ final String info = "symrefCreator: " + symrefCreator.getLabel() + ", descriptorCreator: "
+ + descriptorCreator.getLabel();
+
+ // prepare models
+ final MPatchModel mpatch = CompareTestHelper.getMPatchFromUris(changedUri, unchangedUri, symrefCreator,
+ descriptorCreator);
+ assertNotNull("Preceeding transformation failed! Make sure mpatch can be produced for: " + unchangedUri
+ + " and " + changedUri + " and " + info, mpatch);
+
+ // now reverse it!
+ reverseAndTest(mpatch, info + ", model: " + unchangedUri);
+
+ ResourceSet resourceSet = new ResourceSetImpl(); // get new resource set to avoid conflicts
+ final EObject rightModel = CompareTestHelper.loadModel(unchangedUri, resourceSet).get(0);
+ final EObject leftModel = CompareTestHelper.loadModel(changedUri, resourceSet).get(0);
+
+ // apply the differences and validate the result against the rightModel (!)
+ CommonTestOperations.createAndApplyMPatch(mpatch, leftModel, rightModel, null, info + ", model: "
+ + unchangedUri);
+ }
+ }
+
+ private void reverseAndTest(MPatchModel reversed, String info) {
+ final MPatchModel original = EcoreUtil.copy(reversed);
+ ReverseTransformation.reverse(reversed);
+ final MPatchModel doubleReversed = EcoreUtil.copy(reversed);
+ ReverseTransformation.reverse(doubleReversed);
+ final ComparisonResourceSnapshot mpatchDiff = CommonUtils.createEmfdiff(original, doubleReversed);
+ final Collection<DiffElement> differences = CommonUtils.analyzeDiff(mpatchDiff, CommonUtils.DIFF_ORDERINGS);
+ assertTrue("Double reversed mpatch does not equal original mpatch (" + info + "): " + differences,
+ differences.isEmpty());
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/UmlTest.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/UmlTest.java
new file mode 100644
index 000000000..30f7018e3
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/junit/UmlTest.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.junit;
+
+import org.eclipse.emf.compare.mpatch.common.util.ExtensionManager;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.test.util.CommonTestOperations;
+import org.eclipse.emf.compare.mpatch.test.util.TestConstants;
+import org.junit.Test;
+
+
+/**
+ * Test of difference creation and application for UML models.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class UmlTest {
+
+ /**
+ * Testing the creation and application of mpatches on uml models.
+ */
+ @Test
+ public void testApplyDifferencesUml() {
+ testApply(TestConstants.UML_URI1, TestConstants.UML_URI2);
+ }
+
+ /**
+ * Test of adding a UML association explicitly with ID-based symrefs.
+ *
+ * FIXME: The problem is that the an element which was created by a model descriptor gets a newly created id and
+ * thus cannot be resolved by any existing symbolic reference. The solution is to keep track of all created elements
+ * for each model-descriptor and its symbolic reference, respectively, and use this information to resolve symrefs
+ * which point to such newly created elements.
+ *
+ * Distinguish between cross-references within one model descriptor only (1) and those which point to another change (2).
+ * (1) is located in EMFModelDescriptorImpl, (2) in the implementation of DiffApplier.
+ */
+ @Test
+ public void testTestUmlAssocID() {
+ CommonTestOperations.applyMPatchAndValidate(TestConstants.UML_ASSOC_URI1, TestConstants.UML_ASSOC_URI2,
+ ExtensionManager.getAllSymbolicReferenceCreators().get("ID-based"),
+ TestConstants.MODEL_DESCRIPTOR_CREATORS.iterator().next());
+ }
+
+ /**
+ * Test of adding a UML association explicitly with condition-based symrefs.
+ */
+ @Test
+ public void testTestUmlAssocCondition() {
+ CommonTestOperations.applyMPatchAndValidate(TestConstants.UML_ASSOC_URI1, TestConstants.UML_ASSOC_URI2,
+ ExtensionManager.getAllSymbolicReferenceCreators().get("Condition-based"),
+ TestConstants.MODEL_DESCRIPTOR_CREATORS.iterator().next());
+ }
+
+ private void testApply(String unchangedUri, String changedUri) {
+ for (ISymbolicReferenceCreator symrefCreator : TestConstants.SYM_REF_CREATORS) {
+ for (IModelDescriptorCreator descriptorCreator : TestConstants.MODEL_DESCRIPTOR_CREATORS) {
+ CommonTestOperations.applyMPatchAndValidate(unchangedUri, changedUri, symrefCreator, descriptorCreator);
+ }
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/CommonTestOperations.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/CommonTestOperations.java
new file mode 100644
index 000000000..4e1b8d2bf
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/CommonTestOperations.java
@@ -0,0 +1,504 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.compare.diff.metamodel.ComparisonResourceSnapshot;
+import org.eclipse.emf.compare.diff.metamodel.ComparisonSnapshot;
+import org.eclipse.emf.compare.diff.metamodel.DiffElement;
+import org.eclipse.emf.compare.mpatch.ChangeGroup;
+import org.eclipse.emf.compare.mpatch.IndepChange;
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.UnknownChange;
+import org.eclipse.emf.compare.mpatch.apply.generic.util.InternalReferencesTransformation;
+import org.eclipse.emf.compare.mpatch.apply.generic.util.MPatchDependencyTransformation;
+import org.eclipse.emf.compare.mpatch.apply.util.MPatchResolver;
+import org.eclipse.emf.compare.mpatch.apply.util.MPatchValidator;
+import org.eclipse.emf.compare.mpatch.common.util.CommonUtils;
+import org.eclipse.emf.compare.mpatch.emfdiff2mpatch.util.TransformationLauncher;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.extension.MPatchApplicationResult;
+import org.eclipse.emf.compare.mpatch.extension.ResolvedSymbolicReferences;
+import org.eclipse.emf.compare.mpatch.extension.MPatchApplicationResult.ApplicationStatus;
+import org.eclipse.emf.compare.mpatch.extension.ResolvedSymbolicReferences.ValidationResult;
+import org.eclipse.emf.compare.mpatch.symrefs.OclCondition;
+import org.eclipse.emf.compare.mpatch.symrefs.SymrefsPackage;
+import org.eclipse.emf.compare.mpatch.symrefs.util.OCLConditionHelper;
+import org.eclipse.emf.compare.mpatch.transform.util.GroupingTransformation;
+import org.eclipse.emf.compare.mpatch.util.ExtEcoreUtils;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.Diagnostician;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.query.conditions.eobjects.EObjectCondition;
+
+/**
+ * Common test operations (test logic) for multiple test cases.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class CommonTestOperations {
+
+ /**
+ * This performs the following test cycle for a given model:
+ * <ol>
+ * <li>Compare the changed with the unchanged version using emf compare
+ * <li>Transform the emfdiff to mpatch
+ * <li>Compute dependency graph for the mpatch
+ * <li>Resolve mpatch to unchanged version of the model
+ * <li>Apply mpatch to unchanged version of the model
+ * <li>Use emf compare to calculate differences between changed version of the model from the parameters and the
+ * model version to which the differences have been applied
+ * <li>The latter comparison must not differ! If it does, the test fails and the differences are given in the assert
+ * log.
+ * </ol>
+ *
+ * @param unchanged
+ * The URI of the unchanged version of a model.
+ * @param changed
+ * The URI of the changed version of a model.
+ * @param symrefCreator
+ * The symbolic reference creator used for this transformation.
+ * @param descriptorCreator
+ * The model descriptor creator used for this transformation.
+ */
+ public static void applyMPatchAndValidate(String unchanged, String changed,
+ ISymbolicReferenceCreator symrefCreator, IModelDescriptorCreator descriptorCreator) {
+ final String info = "symrefCreator: " + symrefCreator.getLabel() + ", descriptorCreator: "
+ + descriptorCreator.getLabel();
+
+ // prepare models
+ final MPatchModel mpatch = createMPatch(unchanged, changed, symrefCreator, descriptorCreator, info);
+
+ ResourceSet resourceSet = new ResourceSetImpl(); // get new resource to not conflict with original models!
+ final EObject rightModel = CompareTestHelper.loadModel(unchanged, resourceSet).get(0);
+ final EObject leftModel = CompareTestHelper.loadModel(changed, resourceSet).get(0);
+
+ // apply the differences and validate the result against the leftModel
+ createAndApplyMPatch(mpatch, rightModel, leftModel, null, info);
+ }
+
+ /**
+ * Create MPatch from URIs and check that it is not <code>null</code>. No other checks are performed.
+ *
+ * @param unchanged
+ * The URI of the unchanged version of a model.
+ * @param changed
+ * The URI of the changed version of a model.
+ * @param symrefCreator
+ * The symbolic reference creator used for this transformation.
+ * @param descriptorCreator
+ * The model descriptor creator used for this transformation.
+ * @param info
+ * Additional information to print in assert messages.
+ * @return The calculated MPatch.
+ */
+ public static MPatchModel createMPatch(String unchanged, String changed, ISymbolicReferenceCreator symrefCreator,
+ IModelDescriptorCreator descriptorCreator, String info) {
+
+ // prepare models
+ final MPatchModel mpatch = CompareTestHelper.getMPatchFromUris(changed, unchanged, symrefCreator,
+ descriptorCreator);
+ assertNotNull("Preceeding transformation failed! Make sure mpatch can be produced for: " + unchanged + " and "
+ + changed + " and " + info, mpatch);
+ return mpatch;
+ }
+
+ /**
+ * Check the application of differences by comparing the result with a given model, usually the changed version from
+ * which the mpatch was created from. There should be no differences between these two - if there are, then the test
+ * fails and the differences are given in the assert log message.
+ *
+ * (So this is the self-checking part of the test case, to make Fowler happy :o) [Refactoring, Fowler])
+ *
+ * @param appliedModel
+ * A model to which differences have been applied.
+ * @param originalChangedModel
+ * The changed version of the model from which the differences have been created.
+ */
+ public static void checkAppliedModel(EObject appliedModel, EObject originalChangedModel, String info) {
+
+ // compare with target model and check whether they differ
+ final ComparisonSnapshot differences = CommonUtils.createEmfdiff(appliedModel, originalChangedModel, false);
+ final Collection<DiffElement> violations = CommonUtils.analyzeDiff(differences, CommonUtils.DIFF_ORDERINGS);
+ assertTrue("difference application was not successful! " + info + " - Violations: " + violations,
+ violations.isEmpty());
+ }
+
+ /**
+ * The following steps are performed here:
+ * <ol>
+ * <li>Group the given mpatch
+ * <li>Add dependency graph to the given mpatch
+ * <li>Perform initial symbolic reference resolution of the given mpatch to the model given in the parameters
+ * <li>Copy the given model and apply all differences on the given model.
+ * <li>Compare the changed model with the copy using EMF Compare
+ * <li>Return that {@link ComparisonSnapshot} created by EMF Compare which contains a review of all applied
+ * differences
+ * </ol>
+ *
+ * Optionally, each step can be measured in time - if you don't want to measure the time, set the parameter to
+ * <code>null</code>. The current system time is put into a field in the array:
+ * <ol start="0">
+ * <li>Starting time
+ * <li>Time after grouping
+ * <li>Time after difference calculation
+ * <li>Time after symbolic reference resolution
+ * <li>Time after creating a copy of the given model
+ * <li>Time after difference application
+ * <li>Time after comparing the model copy with the changed model
+ * </ol>
+ * So make sure the given array has at least length 7!
+ *
+ * @param mpatch
+ * Ungrouped (!) mpatch.
+ * @param model
+ * A model to which the mpatch should be applied.
+ * @param expectedModel
+ * The expected result of the difference application.
+ * @param times
+ * An array in which the times are stored. May be <code>null</code>.
+ * @param info
+ * Show additional information about the test case in the assert message, e.g. the use of particular
+ * creators for the transformation.
+ * @return A review of all applied changes.
+ */
+ public static ComparisonSnapshot createAndApplyMPatch(MPatchModel mpatch, EObject model, EObject expectedModel,
+ PerformanceTimes times, String info) {
+
+ if (times != null)
+ times.tick(); // start timing
+
+ doTransformations(mpatch, times, info);
+ final ResolvedSymbolicReferences resolved = resolveAndValidate(mpatch, model, times, info);
+ final EObject newModel = applyMPatchToModel(mpatch, model, resolved, times, info);
+ final ComparisonResourceSnapshot emfdiff = compareChangedAndUnchangedModels(model, newModel, times, info);
+ checkAppliedModel(model, expectedModel, info);
+ checkBinding(resolved.getMPatchModelBinding(), info);
+
+ if (times != null)
+ times.setCheck(); // final check
+
+ return emfdiff;
+ }
+
+ /**
+ * Validate an eObject using the EMF Validation Framework ({@link Diagnostician}).
+ *
+ * @param eObject
+ * An eobject to validate.
+ * @param info
+ * Some addition information for the assert messages.
+ */
+ public static void checkBinding(EObject eObject, String info) {
+ // validate the given element using the emf validation framework!
+ final Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject);
+ assertNull("Validation was not successful! (" + info + "): " + eObject, diagnostic.getException());
+ assertEquals("Validation was not successful! (" + info + "): " + eObject + "\n" + getMessage(diagnostic),
+ Diagnostic.OK, diagnostic.getSeverity());
+ }
+
+ /**
+ * Compare the two given models and return their differences as an emfdiff.
+ *
+ * @param changedModel
+ * The changed version of a model.
+ * @param unchangedModel
+ * The unchanged version of the model.
+ * @param times
+ * For performance check (optional, can be <code>null</code>).
+ * @param info
+ * Additional information for assert Strings.
+ * @return An emfdiff containing all differences between these two model versions.
+ */
+ public static ComparisonResourceSnapshot compareChangedAndUnchangedModels(EObject changedModel,
+ EObject unchangedModel, PerformanceTimes times, String info) {
+ // run emf compare again to return review all applied differences
+ final ComparisonResourceSnapshot emfdiff = CommonUtils.createEmfdiff(changedModel, unchangedModel, false);
+ if (times != null)
+ times.setChanges(); // final comparison
+
+ // check the modified source model
+ final EObject appliedModel = CommonUtils.getModelFromEmfdiff(emfdiff, true); // get left model
+ assertNotNull("Model with applied diff must not be null! (" + info + ")", appliedModel);
+ assertEquals("The model to which we applied the diff must be our original model! (" + info + ")", changedModel,
+ appliedModel);
+ return emfdiff;
+ }
+
+ /**
+ * Create a copy of the given model and apply the MPatch to it. Then, check whether the application was successful
+ * by check the {@link MPatchApplicationResult}.
+ *
+ * @param mpatch
+ * The MPatch to apply.
+ * @param model
+ * The model to which the MPatch should be applied.
+ * @param resolved
+ * The resolution of symbolic references.
+ * @param times
+ * For performance check (optional, can be <code>null</code>).
+ * @param info
+ * Additional information for assert Strings.
+ * @return A copy of original <code>model</code>. Note that the MPatch was applied to the parameter
+ * <code>model</code>!
+ */
+ public static EObject applyMPatchToModel(MPatchModel mpatch, EObject model, ResolvedSymbolicReferences resolved,
+ PerformanceTimes times, String info) {
+ // create a new target model - a copy as the 'right' model, whereas the original is the 'left' model
+ final EObject newModel = EcoreUtil.copy(model);
+ final ResourceImpl newModelResource = new ResourceImpl();
+ newModelResource.getContents().add(newModel);
+ newModelResource.setURI(model.eResource().getURI());
+ if (times != null)
+ times.setCopy(); // model copy time
+
+ // apply differences *with* calculating the binding!
+ final MPatchApplicationResult result = TestConstants.DIFF_APPLIER.applyMPatch(resolved, true);
+ if (times != null)
+ times.setApply(); // diff application time
+
+ // since we apply the diff to the unchanged model, we require all changes to be applied successfully!
+ assertTrue("There are changes which failed (" + info + "): " + result.failed, result.failed.isEmpty());
+ assertTrue("There are changes with unsufficient cross-reference restore (" + info + "): "
+ + result.crossReferences, result.crossReferences.isEmpty());
+ assertEquals("Diff application result is not successful (" + info + ")!", ApplicationStatus.SUCCESSFUL,
+ result.status);
+ return newModel;
+ }
+
+ /**
+ * Resolve the given MPatch to the given model and validate the resolution using the {@link MPatchValidator}.
+ *
+ * @param mpatch
+ * The MPatch to resolve.
+ * @param model
+ * The model to which the MPatch should be resolved.
+ * @param times
+ * For performance check (optional, can be <code>null</code>).
+ * @param info
+ * Additional information for assert Strings.
+ * @return The resolution.
+ */
+ public static ResolvedSymbolicReferences resolveAndValidate(MPatchModel mpatch, EObject model,
+ PerformanceTimes times, String info) {
+ // resolve symbolic references
+ final ResolvedSymbolicReferences resolved = MPatchResolver.resolveSymbolicReferences(mpatch, model,
+ ResolvedSymbolicReferences.RESOLVE_UNCHANGED);
+ if (times != null)
+ times.setResolve(); // resolution time
+
+ // validate all resolved references
+ final List<IndepChange> invalidResolution = MPatchValidator.validateResolutions(resolved);
+ assertTrue("The following changes did not resolve correctly (" + info + "): " + invalidResolution,
+ invalidResolution.isEmpty());
+ if (times != null)
+ times.setValidate(); // validation time
+ return resolved;
+ }
+
+ /**
+ * Perform the following transformations:
+ * <ul>
+ * <li>Grouping (and check that there is at least one group)
+ * <li>Dependency calculation
+ * <li>Internal Reference Creation
+ * </ul>
+ *
+ * @param mpatch
+ * The MPatch to transform.
+ * @param times
+ * For performance check (optional, can be <code>null</code>).
+ * @param info
+ * Additional information for assert Strings.
+ */
+ public static void doTransformations(MPatchModel mpatch, PerformanceTimes times, String info) {
+ // restructure differences, add dependencies, and replace internal references
+ try {
+ final int groups = GroupingTransformation.group(mpatch);
+ if (times != null)
+ times.setGroups(); // grouping time
+ assertTrue("We need at least one group after restructuring!", groups > 0);
+
+ MPatchDependencyTransformation.calculateDependencies(mpatch);
+ if (times != null)
+ times.setDeps(); // dependency calculation time
+
+ InternalReferencesTransformation.createInternalReferences(mpatch);
+ if (times != null)
+ times.setRefs(); // internal reference creation time
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Grouping or dependency calculation failed (" + info + "): " + e.getMessage());
+ }
+ }
+
+ private static String getMessage(Diagnostic diagnostic) {
+ String msg = diagnostic.getMessage();
+ for (Diagnostic d : diagnostic.getChildren()) {
+ msg += "\n" + d.getMessage();
+ }
+ return msg;
+ }
+
+ /**
+ * Check whether <code>outModel</code> contains an mpatch and that is has <code>count</code> (ungrouped) changes in
+ * total.
+ *
+ * @param mpatch
+ * It is supposed to be the result of {@link TransformationLauncher#transform(List, StringBuffer)}.
+ * @param count
+ * The expected number of changed which is contained in the result.
+ */
+ public static void checkForDifferences(MPatchModel mpatch, int count) {
+ // ignore unknown changes and groups here!
+ int counter = 0;
+ for (IndepChange change : mpatch.getChanges()) {
+ if (!(change instanceof UnknownChange || change instanceof ChangeGroup)) {
+ counter++;
+ }
+ }
+ assertEquals("MPatch does not contain " + count + " elements as expected!", count, counter);
+ }
+
+ /**
+ * This first performs an initial resolution of symbolic references in the given <code>diff</code>. Then, the
+ * MPatchValidator is used to check whether all symbolic references resolved correctly and whether the state before
+ * the changes can be found in the given model.
+ *
+ * @param mpatch
+ * MPatch.
+ * @param model
+ * A model for which the reference resolution should be performed.
+ */
+ public static void validateSymbolicReferenceResolution(MPatchModel mpatch, EObject model) {
+ try {
+ // resolve symbolic references
+ ResolvedSymbolicReferences mapping = MPatchResolver.resolveSymbolicReferences(mpatch, model,
+ ResolvedSymbolicReferences.RESOLVE_UNCHANGED);
+ assertNotNull("Result of symbolic reference resolution must not be null!", mapping);
+
+ // validate resolution
+ final List<IndepChange> invalid = MPatchValidator.validateResolutions(mapping);
+ final List<IndepChange> refs = CommonUtils.filterByValue(mapping.getValidation(),
+ ValidationResult.REFERENCE);
+ final List<IndepChange> applied = CommonUtils.filterByValue(mapping.getValidation(),
+ ValidationResult.STATE_AFTER);
+ final List<IndepChange> state = CommonUtils.filterByValue(mapping.getValidation(),
+ ValidationResult.STATE_INVALID);
+ if (!invalid.isEmpty()) {
+ final String msg = "Resolution fail!%\nAlready applied: %s%\nInvalid state: %s%\nNot resolved: %s%\nOther reasons: %s";
+ invalid.removeAll(refs);
+ invalid.removeAll(applied);
+ invalid.removeAll(state);
+ fail(String.format(msg, applied.toString(), state.toString(), refs.toString(), invalid.toString()));
+ }
+
+ } catch (Exception e) {
+ fail("Symbolic reference resolution failed: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Perform grouping on the given mpatch and compare the resulting number of groups with the given parameter.
+ *
+ * @param mpatch
+ * Ungrouped (!) mpatch.
+ * @param count
+ * The expected number of groups created.
+ */
+ public static void groupingAndCheckForGroups(MPatchModel mpatch, int count) {
+ try {
+ final int groups = GroupingTransformation.group(mpatch);
+ assertTrue("Number of groups does not match!", count == groups || count + 1 == groups);
+
+ String diagnostic = CompareTestHelper.validateMPatch(mpatch);
+ assertNull(diagnostic, diagnostic);
+ } catch (final Exception e) {
+ fail("Restructuring failed. Cause: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Check the validity of all ocl expressions by parsing them.
+ *
+ * @param mpatch
+ * MPatch.
+ */
+ public static void checkOclExpressions(MPatchModel mpatch) {
+
+ // get all ocl conditions from the mpatch
+ final List<EObject> oclConditions = ExtEcoreUtils.collectTypedElements(mpatch.getChanges(),
+ Collections.singleton(SymrefsPackage.Literals.OCL_CONDITION), true);
+
+ // iterate over them
+ for (EObject eObject : oclConditions) {
+ if (eObject instanceof OclCondition) {
+ OclCondition oclCondition = (OclCondition) eObject;
+
+ // check whether we can create a condition for them (i.e. the condition is parseable)
+ final EObjectCondition condition = OCLConditionHelper.getWhereCondition(oclCondition);
+ if (condition == null)
+ OCLConditionHelper.getWhereCondition(oclCondition);
+ assertNotNull("The OCL expression could not be processed: " + oclCondition.getExpression(), condition);
+
+ } else
+ fail("If you see this message, ExtEcoreUtils.collectTypedElements does not work correctly!");
+ }
+ }
+
+ /**
+ * Test the resolutino of symbolic references by first creating the emfdiff and then mpatch of the two given models,
+ * and then trying to resolve all symbolic references on the unchanged version of the given models. Hence, this must
+ * be unique!
+ *
+ * @param unchangedUri
+ * The unchanged version of the test model.
+ * @param changedUri
+ * The changed version of the test model.
+ * @param symrefCreator
+ * The symbolic reference creator for the transformation.
+ * @param descriptorCreator
+ * The symbolic reference creator for the transformation.
+ */
+ public static void checkSymbolicReferenceResolution(String unchangedUri, String changedUri,
+ ISymbolicReferenceCreator symrefCreator, IModelDescriptorCreator descriptorCreator) {
+ // prepare models
+ final MPatchModel mpatch = CompareTestHelper.getMPatchFromUris(changedUri, unchangedUri, symrefCreator,
+ descriptorCreator);
+ assertNotNull("Preceeding transformation emfdiff2mpatch failed with symrefCreator: " + symrefCreator.getLabel()
+ + " and descriptorCreator: " + descriptorCreator.getLabel(), mpatch);
+
+ // we need to introduce internal references here!
+ InternalReferencesTransformation.createInternalReferences(mpatch);
+
+ ResourceSet resourceSet = new ResourceSetImpl(); // get new resource to not conflict with original models!
+ final EObject rightModel = CompareTestHelper.loadModel(unchangedUri, resourceSet).get(0);
+
+ // the real check whether everything was correctly resolved
+ validateSymbolicReferenceResolution(mpatch, rightModel);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/CompareTestHelper.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/CompareTestHelper.java
new file mode 100644
index 000000000..24275a50c
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/CompareTestHelper.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.util;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.diff.metamodel.ComparisonResourceSnapshot;
+import org.eclipse.emf.compare.diff.metamodel.ComparisonSnapshot;
+import org.eclipse.emf.compare.mpatch.IndepChange;
+import org.eclipse.emf.compare.mpatch.MPatchModel;
+import org.eclipse.emf.compare.mpatch.apply.util.MPatchResolver;
+import org.eclipse.emf.compare.mpatch.apply.util.MPatchValidator;
+import org.eclipse.emf.compare.mpatch.common.util.CommonUtils;
+import org.eclipse.emf.compare.mpatch.emfdiff2mpatch.util.TransformationLauncher;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+import org.eclipse.emf.compare.mpatch.extension.ResolvedSymbolicReferences;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.Diagnostician;
+
+/**
+ * A helper class for loading models and creating {@link MPatchModel}s.
+ *
+ * No test logic in here!
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class CompareTestHelper {
+
+ /**
+ * Loads the file from the uri first from the test plugin in the workspace, and if that fails from the test plugin.
+ * Use the given resource set to load the models; this gives the caller the freedom to define the resourceset of the
+ * models.
+ */
+ public static List<EObject> loadModel(String uriString, ResourceSet resourceSet) {
+ // is uri already valid?
+ URI uri = URI.createURI(uriString);
+ if (!URIConverter.INSTANCE.exists(uri, null)) {
+
+ // try workspace
+ uri = URI.createURI(TestConstants.PREFIX_WORKSPACE + uriString);
+ if (!URIConverter.INSTANCE.exists(uri, null)) {
+
+ // try plugins
+ uri = URI.createURI(TestConstants.PREFIX_PLUGIN + uriString);
+ assertTrue("Cannot find file: " + uriString, URIConverter.INSTANCE.exists(uri, null));
+ }
+ }
+ final Resource resource = resourceSet.getResource(uri, true);
+ return resource.getContents();
+ }
+
+ /**
+ * Compare two versions of a model with EMF Compare.
+ *
+ * @param leftUri
+ * The URI of the changed version.
+ * @param rightUri
+ * The URI of the unchanged version.
+ * @return The calculated emfdiff.
+ */
+ public static ComparisonSnapshot getEmfdiffFromEmfCompare(String leftUri, String rightUri) {
+ // Loading models
+ ResourceSet resourceSet = new ResourceSetImpl();
+ final EObject leftModel = loadModel(leftUri, resourceSet).get(0);
+ final EObject rightModel = loadModel(rightUri, resourceSet).get(0);
+
+ // delegate call
+ return getEmfdiffFromEmfCompare(leftModel, rightModel);
+ }
+
+ /**
+ * Compare two versions of a model with EMF Compare.
+ *
+ * @param leftModel
+ * The changed version.
+ * @param rightModel
+ * The unchanged version.
+ * @return The calculated emfdiff.
+ */
+ public static ComparisonSnapshot getEmfdiffFromEmfCompare(EObject leftModel, EObject rightModel) {
+ ComparisonResourceSnapshot emfdiff = CommonUtils.createEmfdiff(leftModel, rightModel, true);
+ checkToString(emfdiff);
+ return emfdiff;
+ }
+
+ /**
+ * An emfdiff2mpatch transformation throws an exception if toString() of an object fails. (That is/was the case for
+ * UpdateReference and UpdateAttribute sometimes!) So lets explicitely check that here!
+ */
+ private static void checkToString(EObject eObject) {
+ TreeIterator<EObject> iterator = eObject.eAllContents();
+ while (iterator.hasNext()) {
+ EObject next = iterator.next();
+ try {
+ next.toString();
+ } catch (Exception e) {
+ fail("toString() failed on: " + next);
+ }
+ }
+ }
+
+ /**
+ * Create an {@link MPatchModel}.
+ *
+ * @param leftUri
+ * Changed version of the test model.
+ * @param rightUri
+ * Unchanged version of the test model.
+ * @param symrefCreator
+ * The symbolic reference creator.
+ * @param descriptorCreator
+ * The model descriptor creator.
+ * @return An {@link MPatchModel} created with the given creators.
+ */
+ public static MPatchModel getMPatchFromUris(String leftUri, String rightUri,
+ ISymbolicReferenceCreator symrefCreator, IModelDescriptorCreator descriptorCreator) {
+ try {
+ final ComparisonSnapshot emfdiff = getEmfdiffFromEmfCompare(leftUri, rightUri);
+ final MPatchModel mpatch = TransformationLauncher
+ .transform(emfdiff, null, symrefCreator, descriptorCreator);
+
+ final String diagnostic = validateMPatch(mpatch);
+ assertNull("Transformation with symrefCreator: " + symrefCreator.getLabel() + " and descriptorCreator: "
+ + descriptorCreator.getLabel() + " failed: " + diagnostic, diagnostic);
+
+ return mpatch;
+ } catch (final Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Use EMF validator to check whether the diff is correct in terms of the constraints in its meta model.
+ *
+ * @param maptch
+ * MPatch.
+ * @return A string containing all wrong elements or <code>null</code>, if the diff is valid.
+ */
+ public static String validateMPatch(MPatchModel maptch) {
+ // we assume that we got exactly _one_ output model here
+ final Diagnostic emfDiagnostic = Diagnostician.INSTANCE.validate(maptch);
+
+ // perform emf validation
+ if (emfDiagnostic.getSeverity() == Diagnostic.ERROR || emfDiagnostic.getSeverity() == Diagnostic.WARNING) {
+ String message = emfDiagnostic.getMessage() + "\n";
+
+ for (Diagnostic childDiagnostic : emfDiagnostic.getChildren()) {
+ switch (childDiagnostic.getSeverity()) {
+ case Diagnostic.ERROR:
+ case Diagnostic.WARNING:
+ message += "\t" + childDiagnostic.getMessage() + "\n";
+ }
+ }
+ return "Transformation result does not validate successfully:\n" + message;
+ }
+ return null;
+ }
+
+ /**
+ * Resolve the MPatch to the model.
+ *
+ * @param mpatch
+ * An MPatch.
+ * @param applyModel
+ * A model for which the MPatch should be resolved.
+ * @param info
+ * Some info String for assert messages.
+ * @return The resolution of symbolic references.
+ */
+ public static ResolvedSymbolicReferences resolveReferences(MPatchModel mpatch, EObject applyModel, String info) {
+ final ResolvedSymbolicReferences resolved = MPatchResolver.resolveSymbolicReferences(mpatch, applyModel,
+ ResolvedSymbolicReferences.RESOLVE_UNCHANGED);
+ final List<IndepChange> invalidResolution = MPatchValidator.validateResolutions(resolved);
+ assertTrue("The following changes did not resolve correctly (" + info + "): " + invalidResolution,
+ invalidResolution.isEmpty());
+ return resolved;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/PerformanceTimes.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/PerformanceTimes.java
new file mode 100644
index 000000000..e153bae92
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/PerformanceTimes.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.util;
+
+/**
+ * Data class for collecting runtime of individual tasks in the framework.
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class PerformanceTimes {
+
+ private long built;
+ private long emfdiff;
+ private long mpatch;
+ private long groups;
+ private long deps;
+ private long resolve;
+ private long validate;
+ private long copy;
+ private long apply;
+ private long changes;
+ private long check;
+ private long refs;
+
+ private long lastTime = System.currentTimeMillis();
+
+ public final void tick() {
+ lastTime = System.currentTimeMillis();
+ }
+
+ public final long getBuilt() {
+ return built;
+ }
+
+ public final long getEmfdiff() {
+ return emfdiff;
+ }
+
+ public final long getMPatch() {
+ return mpatch;
+ }
+
+ public final long getGroups() {
+ return groups;
+ }
+
+ public final long getDeps() {
+ return deps;
+ }
+
+ public final long getRefs() {
+ return refs;
+ }
+
+ public final long getResolve() {
+ return resolve;
+ }
+
+ public final long getValidate() {
+ return validate;
+ }
+
+ public final long getCopy() {
+ return copy;
+ }
+
+ public final long getApply() {
+ return apply;
+ }
+
+ public final long getChanges() {
+ return changes;
+ }
+
+ public final long getCheck() {
+ return check;
+ }
+
+ public final long getTotal() {
+ return built + emfdiff + mpatch + groups + deps + resolve + validate + copy + apply + changes + check;
+ }
+
+ private final long getTime() {
+ final long currentTime = System.currentTimeMillis();
+ final long time = currentTime - lastTime;
+ lastTime = currentTime;
+ return time;
+ }
+
+ public final void setBuilt() {
+ this.built = getTime();
+ }
+
+ public final void setEmfdiff() {
+ this.emfdiff = getTime();
+ }
+
+ public final void setMPatch() {
+ this.mpatch = getTime();
+ }
+
+ public final void setGroups() {
+ this.groups = getTime();
+ }
+
+ public final void setDeps() {
+ this.deps = getTime();
+ }
+
+ public final void setResolve() {
+ this.resolve = getTime();
+ }
+
+ public final void setValidate() {
+ this.validate = getTime();
+ }
+
+ public final void setCopy() {
+ this.copy = getTime();
+ }
+
+ public final void setApply() {
+ this.apply = getTime();
+ }
+
+ public final void setChanges() {
+ this.changes = getTime();
+ }
+
+ public final void setCheck() {
+ this.check = getTime();
+ }
+
+ public void setRefs() {
+ this.refs = getTime();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/TestConstants.java b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/TestConstants.java
new file mode 100644
index 000000000..75fea64b7
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.mpatch.test/src/org/eclipse/emf/compare/mpatch/test/util/TestConstants.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Technical University of Denmark.
+ * 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:
+ * Patrick Koenemann, DTU Informatics - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.mpatch.test.util;
+
+import java.util.Collection;
+
+import org.eclipse.emf.compare.mpatch.common.util.ExtensionManager;
+import org.eclipse.emf.compare.mpatch.extension.IMPatchApplication;
+import org.eclipse.emf.compare.mpatch.extension.IModelDescriptorCreator;
+import org.eclipse.emf.compare.mpatch.extension.ISymbolicReferenceCreator;
+
+
+/**
+ * Test constants:
+ * <ul>
+ * <li>Location of (all) test case files
+ * <li>URIs for all test case files
+ * <li>Singleton instance of {@link IMPatchApplication}
+ * <li>List of {@link ISymbolicReferenceCreator}s for testing
+ * <li>List of {@link IModelDescriptorCreator}s for testing
+ * </ul>
+ *
+ * @author Patrick Koenemann (pk@imm.dtu.dk)
+ *
+ */
+public class TestConstants {
+
+ /** Prefix for workspace test files. */
+ public static final String PREFIX_WORKSPACE = "platform:/resource/org.eclipse.emf.compare.mpatch.test/tests/";
+
+ /** Prefix for plugin test files. */
+ public static final String PREFIX_PLUGIN = "platform:/plugin/org.eclipse.emf.compare.mpatch.test/tests/";
+
+ /** Unchanged version of a simple test model containing just one changed attribute. */
+ public static final String SIMPLE_URI1 = "simple/unchanged.eachonce";
+
+ /** Changed version of a simple test model containing just one changed attribute. */
+ public static final String SIMPLE_URI2 = "simple/changed.eachonce";
+
+ /** Unchanged version of a more complex test model covering all kinds of changes. */
+ public static final String EACHONCE_URI1 = "eachonce/unchanged.eachonce";
+
+ /** Changed version of a more complex test model covering all kinds of changes. */
+ public static final String EACHONCE_URI2 = "eachonce/changed.eachonce";
+
+ /** Unchanged version of a test model covering different dependecies between changes. */
+ public static final String DEPENDENCY_URI1 = "dependencies/unchanged.eachonce";
+
+ /** Changed version of a test model covering different dependecies between changes. */
+ public static final String DEPENDENCY_URI2 = "dependencies/changed.eachonce";
+
+ /** Unchanged version of a model containing a dependency cycle. */
+ public static final String DEP_CYCLE_URI1 = "dep_cycle/unchanged.ecore";
+
+ /** Changed version of a model containing a dependency cycle. */
+ public static final String DEP_CYCLE_URI2 = "dep_cycle/changed.ecore";
+
+ /** A simple emfdiff file containing a conflicting diff element. */
+ public static final String CONFLICT_EMFDIFF_URI = "conflicts/conflict.emfdiff";
+
+ /** Unchanged version of a simple ecore model which is the basis for a performance test. */
+ public static final String PERFORMANCE_URI1 = "performance/unchanged.ecore";
+
+ /** Changed version of a simple ecore model which is the basis for a performance test. */
+ public static final String PERFORMANCE_URI2 = "performance/changed.ecore";
+
+ /**
+ * Unchanged version of an ecore model with focus on datatypes and references to datatypes outside the current
+ * resource.
+ */
+ public static final String ECORE_URI1 = "ecore/unchanged.ecore";
+
+ /**
+ * Unchanged version of an ecore model with focus on datatypes and references to datatypes outside the current
+ * resource.
+ */
+ public static final String ECORE_URI2 = "ecore/changed.ecore";
+
+ /** Unchanged version of a uml model covering all but attribute add/del changes. */
+ public static final String UML_URI1 = "uml/unchanged.uml";
+
+ /** Changed version of a uml model covering all but attribute add/del changes. */
+ public static final String UML_URI2 = "uml/changed.uml";
+
+ /** Unchanged version of a uml model without an association. */
+ public static final String UML_ASSOC_URI1 = "uml/ref_unchanged.uml";
+
+ /** Changed version of a uml model having an added association. */
+ public static final String UML_ASSOC_URI2 = "uml/ref_changed.uml";
+
+ /** Unchanged version of model for applying a change multiple times. */
+ public static final String MULTI_REF_URI1 = "multiref/multi_unchanged.eachonce";
+
+ /** Changed version of model for applying a change multiple times. */
+ public static final String MULTI_REF_URI2 = "multiref/multi_changed.eachonce";
+
+ /** The differences describing the generalized adding of a references. */
+ public static final String MULTI_REF_DIFF_URI = "multiref/multiref.mpatch";
+
+ /** Unchanged version of model for internal reference test. */
+ public static final String INTERNAL_REF_URI1 = "internal_refs/unchanged.ecore";
+
+ /** Changed version of model for internal reference test. */
+ public static final String INTERNAL_REF_URI2 = "internal_refs/changed.ecore";
+
+ /** Model to which the internal referenced diffs are applied. */
+ public static final String INTERNAL_REF_URI3 = "internal_refs/apply.ecore";
+
+ /** Unchanged version of model for library example test. */
+ public static final String LIBRARY_URI1 = "platform:/plugin/org.eclipse.emf.compare.mpatch.example/library/library.ecore";
+
+ /** Changed version of model for library example test. */
+ public static final String LIBRARY_URI2 = "platform:/plugin/org.eclipse.emf.compare.mpatch.example/library/library_karl.ecore";
+
+ /** Model version for application of mpatch for library example test. */
+ public static final String LIBRARY_URI3 = "platform:/plugin/org.eclipse.emf.compare.mpatch.example/library/library_eve.ecore";
+
+ /** Unchanged version of EMF model for merging changes. */
+ public static final String MERGE_EMF_URI1 = "merge/unchanged.ecore";
+
+ /** Changed version of EMF model for merging changes. */
+ public static final String MERGE_EMF_URI2 = "merge/changed.ecore";
+
+ /** Unchanged version of eachonce model for merging changes. */
+ public static final String MERGE_EACHONCE_URI1 = "merge/unchanged.eachonce";
+
+ /** Changed version of eachonce model for merging changes. */
+ public static final String MERGE_EACHONCE_URI2 = "merge/changed.eachonce";
+
+ /** Unchanged version of eachonce model for individual add element change. */
+ public static final String INDIVIDUAL_ADD_REM_ELEMENT_URI1 = "individual/add_rem_element1.eachonce";
+ /** Changed version of eachonce model for individual add element change. */
+ public static final String INDIVIDUAL_ADD_REM_ELEMENT_URI2 = "individual/add_rem_element2.eachonce";
+ /** Unchanged version of eachonce model for individual move element change. */
+ public static final String INDIVIDUAL_MOVE_ELEMENT_URI1 = "individual/move_element1.eachonce";
+ /** Changed version of eachonce model for individual move element change. */
+ public static final String INDIVIDUAL_MOVE_ELEMENT_URI2 = "individual/move_element2.eachonce";
+ /** Unchanged version of eachonce model for individual add attribute change. */
+ public static final String INDIVIDUAL_ADD_REM_ATTRIBUTE_URI1 = "individual/add_rem_attribute1.eachonce";
+ /** Changed version of eachonce model for individual add attribute change. */
+ public static final String INDIVIDUAL_ADD_REM_ATTRIBUTE_URI2 = "individual/add_rem_attribute2.eachonce";
+ /** Unchanged version of eachonce model for individual update attribute change. */
+ public static final String INDIVIDUAL_UPDATE_ATTRIBUTE_URI1 = "individual/update_attribute1.eachonce";
+ /** Changed version of eachonce model for individual update attribute change. */
+ public static final String INDIVIDUAL_UPDATE_ATTRIBUTE_URI2 = "individual/update_attribute2.eachonce";
+ /** Unchanged version of eachonce model for individual add reference change. */
+ public static final String INDIVIDUAL_ADD_REM_REFERENCE_URI1 = "individual/add_rem_reference1.eachonce";
+ /** Changed version of eachonce model for individual add reference change. */
+ public static final String INDIVIDUAL_ADD_REM_REFERENCE_URI2 = "individual/add_rem_reference2.eachonce";
+ /** Unchanged version of eachonce model for individual update reference change. */
+ public static final String INDIVIDUAL_UPDATE_REFERENCE_URI1 = "individual/update_reference1.eachonce";
+ /** Changed version of eachonce model for individual update reference change. */
+ public static final String INDIVIDUAL_UPDATE_REFERENCE_URI2 = "individual/update_reference2.eachonce";
+
+ /** The diff applier used in the tests. */
+ public static IMPatchApplication DIFF_APPLIER = ExtensionManager.getSelectedApplication();
+
+ /** Symbolic reference creators. */
+ public static Collection<ISymbolicReferenceCreator> SYM_REF_CREATORS = ExtensionManager.getAllSymbolicReferenceCreators().values();
+
+ /** Model descriptor creators. */
+ public static Collection<IModelDescriptorCreator> MODEL_DESCRIPTOR_CREATORS = ExtensionManager.getAllModelDescriptorCreators().values();
+}

Back to the top