diff options
author | Cedric Brun | 2011-01-05 14:13:01 +0000 |
---|---|---|
committer | Cedric Brun | 2011-01-05 14:13:01 +0000 |
commit | 8a1c5eb415078284a94d29c00280485ee60843cf (patch) | |
tree | 30ee7be4f84904ae13c89e0a873d759adf061bac /plugins/org.eclipse.emf.compare.mpatch.test/src | |
parent | f0991e9aff822115764d9c392404a906e735a602 (diff) | |
download | org.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')
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(); +} |