blob: 3a8261ff85c59c8b1b532efd0c703abb4b7bf8b7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2017 EclipseSource Services GmbH and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Martin Fleck - initial API and implementation
* Christian W. Damus - bug 528272
*******************************************************************************/
package org.eclipse.papyrus.compare.uml2.tests.profiles.migration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import java.util.List;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.AttributeChange;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Conflict;
import org.eclipse.emf.compare.ConflictKind;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceKind;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.ReferenceChange;
import org.eclipse.emf.compare.ResourceAttachmentChange;
import org.eclipse.emf.compare.diff.DefaultDiffEngine;
import org.eclipse.emf.compare.ide.ui.tests.framework.RuntimeTestRunner;
import org.eclipse.emf.compare.ide.ui.tests.framework.annotations.Compare;
import org.eclipse.emf.compare.ide.ui.tests.framework.annotations.DiffEngines;
import org.eclipse.emf.compare.ide.ui.tests.framework.internal.CompareTestSupport;
import org.eclipse.emf.compare.uml2.internal.ProfileApplicationChange;
import org.eclipse.emf.compare.uml2.internal.StereotypeApplicationChange;
import org.eclipse.emf.compare.uml2.internal.StereotypeAttributeChange;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.FeatureMap.Entry;
import org.eclipse.emf.ecore.xml.type.AnyType;
import org.eclipse.papyrus.compare.uml2.internal.hook.ProfileMigrationHook;
import org.eclipse.papyrus.compare.uml2.internal.hook.migration.ProfileMigrationDiagnostic;
import org.eclipse.papyrus.compare.uml2.internal.hook.migration.ProfileNamespaceURIPatternAPI;
import org.eclipse.papyrus.compare.uml2.tests.blocks.Block;
import org.eclipse.papyrus.compare.uml2.tests.elements.Viewpoint;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.util.UMLUtil;
import org.junit.ClassRule;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
/**
* <p>
* Tests whether the {@link ProfileMigrationHook profile migration} correctly migrates the models if their
* profile applications can not be found.
* </p>
* <p>
* The basic migrated, example structure is a MyML model with two stereotype applications on the same UML
* class element: One Block application from the package Blocks with the feature
* {@link Block#isEncapsulated()} set to true and one Viewpoint application from the package ModelElements
* with the feature {@link Viewpoint#getPurpose()} set to 'This is just for testing.'.
* </p>
* <ul>
* <li>Block definition: http://www.eclipse.org/papyrus/compare/test/profile/MyML/Blocks</li>
* <li>Viewpoint definition: http://www.eclipse.org/papyrus/compare/test/profile/MyML/ModelElements</li>
* </ul>
* <p>
* Artificial older profile versions of the model can not be found and therefore trigger the migration to an
* existing (newer) profile version, i.e., the versions as specified above. Since the migration is built on
* top of the Papyrus model repair mechanism, we need to ensure that packages are recognized correctly. This
* mainly implies that there needs to be a version number at the end of the URI. The older versions are
* therefore:
* </p>
* <ul>
* <li>Block package definition: http://www.eclipse.org/papyrus/compare/test/profile/MyML/Blocks<b>/1</b></li>
* <li>Viewpoint package definition:
* http://www.eclipse.org/papyrus/compare/test/profile/MyML/ModelElements<b>/1</b></li>
* </ul>
* <p>
* If the number at the end would not be given, both packages would be assumed to be the same and some
* stereotypes would be deleted.
* </p>
*
* @author Martin Fleck <mfleck@eclipsesource.com>
*/
@SuppressWarnings({"nls", "restriction" })
@RunWith(RuntimeTestRunner.class)
@DiffEngines({DefaultDiffEngine.class })
public class ProfileMigrationTest {
/** Qualified name of the {@code Block} stereotype. */
public static final String BLOCK = "MyML::Blocks::Block";
/** Qualified name of the {@code Viewpoint} stereotype. */
public static final String VIEWPOINT = "MyML::ModelElements::Viewpoint";
/**
* Default value for the purpose feature of the Viewpoint stereotype.
*/
protected static final String VIEWPOINT_PURPOSE = "This is just for testing.";
/**
* Changed value for the purpose feature of the Viewpoint stereotype.
*/
protected static final String VIEWPOINT_PURPOSE_CHANGE = "This is just for enhanced testing.";
/**
* Changed value for the purpose feature of the Viewpoint stereotype, different from
* {@link #VIEWPOINT_PURPOSE_CHANGE}.
*/
protected static final String VIEWPOINT_PURPOSE_OTHER_CHANGE = "This is just for very enhanced testing.";
/**
* Default value for the isEncapsulated feature of the Block stereotype.
*/
protected static final boolean BLOCK_ISENCAPSULATED = true;
@ClassRule
public static final TestRule READ_ONLY_RULE = new TestResourceReadOnlyHandler.Rule();
/*
* ============================ Helper Methods ============================
*/
/**
* A predicate that matches if the given {@link EObject} is an {@link AnyType} and has the given class
* name.
*
* @param className
* class name of the anytype object
* @return true if object is anytype and its class has the given name
*/
protected Predicate<EObject> anyType(final String className) {
return Predicates.and(Predicates.instanceOf(AnyType.class), new Predicate<EObject>() {
public boolean apply(final EObject object) {
return ((AnyType)object).eClass().getName().equals(className);
}
});
}
/**
* Returns the provided object if it is not null and throws an error otherwise.
*
* @param object
* object to test
* @return object
*/
protected <T> T checkNotNull(final T object) {
return checkNotNull("Unexpected null value.", object);
}
/**
* Returns the provided object if it is not null and throws an error with the given message otherwise.
*
* @param errorMessage
* message to be used in the error
* @param object
* object to test
* @return object
*/
protected <T> T checkNotNull(final String errorMessage, final T object) {
assertNotNull(errorMessage, object);
return object;
}
/**
* Returns all profile migration warnings of the given resource.
*
* @param resource
* @return profile migration warnings
*/
protected Iterable<ProfileMigrationDiagnostic> getMigrationWarnings(final Resource resource) {
return Iterables.filter(resource.getWarnings(), ProfileMigrationDiagnostic.class);
}
/**
* Returns all profile migration errors of the given resource.
*
* @param resource
* @return profile migration errors
*/
protected Iterable<ProfileMigrationDiagnostic> getMigrationErrors(final Resource resource) {
return Iterables.filter(resource.getErrors(), ProfileMigrationDiagnostic.class);
}
/**
* Returns the root of this resource if it is not null. Throws an error otherwise.
*
* @param resource
* @return root of the resource
*/
protected EObject getRoot(final Resource resource) {
// let it fail if resource is null
return checkNotNull("Root null.", resource.getContents().get(0));
}
/**
* Asserts that the migrated resources contains the specified number of successful and failed package
* migrations.
*
* @param resource
* @param successfulPackageMigrations
* @param failedPackageMigrations
*/
protected void assertPartialMigration(final Resource resource, final int successfulPackageMigrations,
final int failedPackageMigrations) {
assertMigrationSuccess(resource, successfulPackageMigrations);
assertMigrationFails(resource, failedPackageMigrations);
}
/**
* Asserts that the migrated resource contains the specified number of successful package migrations.
*
* @param resource
* @param successfulPackageMigrations
*/
protected void assertMigrationSuccess(final Resource resource, final int successfulPackageMigrations) {
// migration warnings: successful migrations
assertEquals(successfulPackageMigrations, Iterables.size(getMigrationWarnings(resource)));
}
/**
* Asserts that the migrated resource contains the specified number of failed package migrations.
*
* @param resource
* @param successfulPackageMigrations
*/
protected void assertMigrationFails(final Resource resource, final int failedPackageMigrations) {
// migration errors: failed migrations
assertEquals(failedPackageMigrations, Iterables.size(getMigrationErrors(resource)));
}
/**
* Asserts that the resource has not been migrated, i.e., it has no migration warnings and errors.
*
* @param resource
* @param successfulPackageMigrations
*/
protected void assertNoMigration(final Resource resource) {
assertPartialMigration(resource, 0, 0);
}
/**
* Asserts that the migrated resources has been completely migrated, i.e., it has two migration warnings
* and no errors
*
* @param resource
*/
protected void assertMigration(final Resource resource) {
assertPartialMigration(resource, 2, 0);
}
/**
* Returns the only UML class in the given resource. If no class is found or multiple classes are found,
* an error is thrown.
*
* @param resource
* @return the single UML class
*/
protected Class getSingleUMLClass(final Resource resource) {
final EObject root = getRoot(resource);
final Iterable<Class> umlClasses = Iterables.filter(root.eContents(), Class.class);
final Class umlClass = Iterables.getOnlyElement(umlClasses);
return umlClass;
}
/**
* Asserts that there is the correct number of differences expected from the change of an attribute in the
* {@link Viewpoint} stereotype.
*
* @param comparison
* comparison containing the differences
* @param resource
* @param changeOnBothSides
* true if changes are expected on two sides
*/
protected void assertViewPointAttributeChange(final Comparison comparison, final Resource resource,
final boolean changeOnBothSides) {
final int expectedDifferences = changeOnBothSides ? 2 : 1;
final Class singleUMLClass = getSingleUMLClass(resource);
final Viewpoint viewPoint = UMLUtil.getStereotypeApplication(singleUMLClass, Viewpoint.class);
final Match classMatch = comparison.getMatch(singleUMLClass);
final EList<Diff> classDifferences = classMatch.getDifferences();
final Match viewPointMatch = comparison.getMatch(viewPoint);
final EList<Diff> viewPointDifferences = viewPointMatch.getDifferences();
assertEquals(expectedDifferences, viewPointDifferences.size());
assertTrue(Iterables.all(viewPointDifferences, Predicates.instanceOf(AttributeChange.class)));
assertTrue(
Iterables.all(viewPointDifferences, PapyrusComparePredicates.ofKind(DifferenceKind.CHANGE)));
assertEquals(expectedDifferences, classDifferences.size());
assertTrue(Iterables.all(classDifferences, Predicates.instanceOf(StereotypeAttributeChange.class)));
assertTrue(Iterables.all(classDifferences, PapyrusComparePredicates.ofKind(DifferenceKind.CHANGE)));
}
/**
* Asserts that there is the correct number of differences expected from the addition of a stereotype.
*
* @param comparison
* comparison containing the differences
* @param resource
* migrated resource
* @param missingStereotypeClass
* added stereotype Application
* @param changeOnBothSides
* true if changes are expected on two sides
*/
protected void assertStereotypeAddition(final Comparison comparison, final Resource resource,
final java.lang.Class<? extends EObject> missingStereotypeClass,
final boolean changeOnBothSides) {
final int expectedDifferences = changeOnBothSides ? 2 : 1;
final Class singleUMLClass = getSingleUMLClass(resource);
final Match classMatch = comparison.getMatch(singleUMLClass);
final EList<Diff> classDifferences = classMatch.getDifferences();
final EObject stereotypeApplication = UMLUtil.getStereotypeApplication(singleUMLClass,
missingStereotypeClass);
final Match stereotypeMatch = comparison.getMatch(stereotypeApplication);
final EList<Diff> stereotypeDifferences = stereotypeMatch.getDifferences();
assertEquals(expectedDifferences * 2, stereotypeDifferences.size());
final Iterable<Diff> resourceAttachmentChanges = Iterables.filter(stereotypeDifferences,
Predicates.instanceOf(ResourceAttachmentChange.class));
assertEquals(expectedDifferences, Iterables.size(resourceAttachmentChanges));
assertTrue(Iterables.all(resourceAttachmentChanges,
PapyrusComparePredicates.ofKind(DifferenceKind.ADD)));
final Iterable<Diff> referenceChanges = Iterables.filter(stereotypeDifferences,
Predicates.instanceOf(ReferenceChange.class));
assertEquals(expectedDifferences, Iterables.size(referenceChanges));
assertTrue(Iterables.all(referenceChanges, PapyrusComparePredicates.ofKind(DifferenceKind.CHANGE)));
assertEquals(expectedDifferences, classDifferences.size());
assertTrue(Iterables.all(classDifferences, Predicates.instanceOf(StereotypeApplicationChange.class)));
assertTrue(Iterables.all(classDifferences, PapyrusComparePredicates.ofKind(DifferenceKind.ADD)));
}
/**
* Asserts that there is the correct number of differences expected from the deletion of a profile
* application.
*
* @param comparison
* comparison containing the differences
* @param resource
* migrated resource
* @param changeOnBothSides
* true if changes are expected on two sides
*/
protected void assertProfileApplicationDeletion(final Comparison comparison, final Resource resource,
final boolean changeOnBothSides) {
final int expectedDifferences = changeOnBothSides ? 2 : 1;
final EObject root = getRoot(resource);
final Match rootMatch = comparison.getMatch(root);
final EList<Diff> rootDifferences = rootMatch.getDifferences();
final Iterable<Diff> profileApplicationChanges = Iterables.filter(rootDifferences,
Predicates.instanceOf(ProfileApplicationChange.class));
assertEquals(expectedDifferences, Iterables.size(profileApplicationChanges));
assertTrue(Iterables.all(profileApplicationChanges,
PapyrusComparePredicates.ofKind(DifferenceKind.DELETE)));
}
/*
* ========================= Partial Migration Assertions =========================
*/
/**
* Asserts that the single UML class of this resource has the specified number of migrated stereotype
* applications.
*
* @param resource
* migrated resource
* @param migratedStereotypeApplications
* number of migrated stereotype applications
* @return the single UML class
* @see #getSingleUMLClass(Resource)
*/
protected Class assertPartiallyMigratedUmlClass(final Resource resource,
final int migratedStereotypeApplications) {
final Class umlClass = getSingleUMLClass(resource);
assertEquals("Expected " + migratedStereotypeApplications + " stereotype applications.",
migratedStereotypeApplications, umlClass.getStereotypeApplications().size());
return umlClass;
}
/**
* Asserts that part of the resource has been migrated.
*
* @param resource
* migrated resource
* @param migratedBlock
* whether the {@link Block} stereotype was migrated or not
* @param blockIsEncapsulated
* expected value of the {@link Block#isEncapsulated()} feature
* @param migratedViewpoint
* whether the {@link Viewpoint} stereotype was migrated or not
* @param viewPointPurpose
* expected value of the {@link Viewpoint#getPurpose()} feature
*/
protected void assertPartiallyMigratedStructure(final Resource resource, final boolean migratedBlock,
final boolean blockIsEncapsulated, final boolean migratedViewpoint,
final String viewPointPurpose) {
int migratedStereotypeApplications = 0;
if (migratedBlock) {
migratedStereotypeApplications++;
}
if (migratedViewpoint) {
migratedStereotypeApplications++;
}
Class umlClass = assertPartiallyMigratedUmlClass(resource, migratedStereotypeApplications);
if (migratedBlock) {
assertMigratedBlock(umlClass, blockIsEncapsulated);
} else {
assertUnmigratedBlock(resource, blockIsEncapsulated);
}
if (migratedViewpoint) {
assertMigratedViewPoint(umlClass, viewPointPurpose);
} else {
assertUnmigratedViewpoint(resource, viewPointPurpose);
}
}
/*
* ========================= Migration Assertions =========================
*/
/**
* Asserts that the given UML class has a migrated {@link Block} stereotype applied that has the given
* encapsulated value.
*
* @param umlClass
* UML class to check
* @param isEncapsulated
* expected value of the {@link Block#isEncapsulated()} feature
* @return Block stereotype applied on the UML class
*/
@SuppressWarnings("boxing")
protected Block assertMigratedBlock(final Class umlClass, final boolean isEncapsulated) {
final Block block = UMLUtil.getStereotypeApplication(umlClass, Block.class);
assertNotNull("Block got deleted.", block);
assertEquals("Wrong value in Block.", isEncapsulated, block.isEncapsulated());
return block;
}
/**
* Asserts that the given UML class has a migrated {@link Viewpoint} stereotype applied that has the given
* encapsulated value.
*
* @param umlClass
* UML class to check
* @param purpose
* expected value of the {@link Viewpoint#getPurpose()} feature
* @return Viewpoint stereotype applied on the UML class
*/
protected Viewpoint assertMigratedViewPoint(final Class umlClass, final String purpose) {
final Viewpoint viewPoint = UMLUtil.getStereotypeApplication(umlClass, Viewpoint.class);
assertNotNull("Viewpoint got deleted.", viewPoint);
assertEquals("Wrong value in Viewpoint.", purpose, viewPoint.getPurpose());
return viewPoint;
}
/**
* Asserts the completely migrated structure with two migrated packages (Block and Viewpoint) and the
* resulting two stereotype applications. Furthermore, asserts that the stereotypes have the provided
* values.
*
* @param resource
* @param blockIsEncapsulated
* expected value of the {@link Block#isEncapsulated()} feature
* @param viewPointPurpose
* expected value of the {@link Viewpoint#getPurpose()} feature
*/
protected void assertMigratedStructure(final Resource resource, final boolean blockIsEncapsulated,
final String viewPointPurpose) {
assertPartiallyMigratedStructure(resource, true, blockIsEncapsulated, true, viewPointPurpose);
}
/*
* ======================= No Migration Assertions ========================
*/
/**
* Asserts that the {@link Viewpoint} stereotype has not been migrated by checking that it is available as
* an {@link AnyType}.
*
* @param resource
* @param purpose
* expected value of the {@link Viewpoint#getPurpose()} feature
* @return the {@link AnyType} representing the {@link Viewpoint} stereotype application
*/
protected AnyType assertUnmigratedViewpoint(final Resource resource, final String purpose) {
final Iterable<EObject> viewPoints = Iterables.filter(resource.getContents(), anyType("Viewpoint"));
final AnyType viewPoint = (AnyType)Iterables.getOnlyElement(viewPoints);
boolean correctPropertyValue = false;
for (final Entry entry : viewPoint.getAnyAttribute()) {
if (entry.getEStructuralFeature().getName().equals("purpose")
&& entry.getValue().toString().equals(purpose)) {
correctPropertyValue = true;
break;
}
}
assertTrue("Wrong value in Viewpoint.", correctPropertyValue);
return viewPoint;
}
/**
* Asserts that the {@link Block} stereotype has not been migrated by checking that it is available as an
* {@link AnyType}.
*
* @param resource
* @param isEncapsulated
* expected value of the {@link Block#isEncapsulated()} feature
* @return the {@link AnyType} representing the {@link Block} stereotype application
*/
protected AnyType assertUnmigratedBlock(final Resource resource, final boolean isEncapsulated) {
final Iterable<EObject> viewPoints = Iterables.filter(resource.getContents(), anyType("Block"));
final AnyType block = (AnyType)Iterables.getOnlyElement(viewPoints);
boolean correctPropertyValue = false;
for (final Entry entry : block.getAnyAttribute()) {
if (entry.getEStructuralFeature().getName().equals("isEncapsulated")
&& Boolean.parseBoolean(entry.getValue().toString()) == isEncapsulated) {
correctPropertyValue = true;
break;
}
}
assertTrue("Wrong value in Block.", correctPropertyValue);
return block;
}
/**
* Asserts that the resource has not been migrated and contains {@link AnyType} for the missing stereotype
* applications.
*
* @param resource
* @param blockIsEncapsulated
* expected value of the {@link Block#isEncapsulated()} feature
* @param viewPointPurpose
* expected value of the {@link Viewpoint#getPurpose()} feature
*/
protected void assertUnmigratedStructure(final Resource resource, final boolean blockIsEncapsulated,
final String viewPointPurpose) {
assertPartiallyMigratedStructure(resource, false, blockIsEncapsulated, false, viewPointPurpose);
}
/*
* ============================== Test Cases ==============================
*/
/**
* All models follow the same, migrated structure. Therefore, no migration is executed.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/nodiff/left.uml", right = "data/myml/nodiff/right.uml", ancestor = "data/myml/nodiff/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testNoDifference(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertNoMigration(originResource);
assertNoMigration(leftResource);
assertNoMigration(rightResource);
// test structure of models (all models have same structure)
assertMigratedStructure(originResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// there are no conflicts and no differences since only the version changed
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
assertTrue("Unexpected differences: " + differences, differences.isEmpty());
}
/**
* Tests whether the profile migration correctly migrates the origin model even if the left and the right
* model are identical. There are no changes in the features.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/version/abb/left.uml", right = "data/myml/version/abb/right.uml", ancestor = "data/myml/version/abb/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testVersionChangeABB(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertMigration(originResource); // success: Block and Viewpoint package, no fails
assertNoMigration(leftResource);
assertNoMigration(rightResource);
// test structure of models
assertMigratedStructure(originResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// there are no conflicts and no differences since only the version changed
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
assertTrue("Unexpected differences: " + differences, differences.isEmpty());
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests whether the profile migration correctly migrates the right and the origin model. There are no
* changes in the features.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/version/aba/left.uml", right = "data/myml/version/aba/right.uml", ancestor = "data/myml/version/aba/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testVersionChangeABA(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertMigration(originResource); // success: Block and Viewpoint package, no fails
assertNoMigration(leftResource);
assertMigration(rightResource); // success: Block and Viewpoint package, no fails
// test structure of models
assertMigratedStructure(originResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// there are no conflicts and no differences since only the version changed
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
assertTrue("Unexpected differences: " + differences, differences.isEmpty());
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests whether the profile migration correctly migrates the right and the origin model and feature
* changes are detected. In the left resource, the feature {@link Viewpoint#getPurpose()} has changed and
* the difference should be detected, but no conflict should be produced. This test is equivalent to
* {@link #testAttributeChangeAAB(Comparison, CompareTestSupport)} with reversed left and right sides.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/attribute/change/aba/left.uml", right = "data/myml/attribute/change/aba/right.uml", ancestor = "data/myml/attribute/change/aba/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testAttributeChangeABA(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertMigration(originResource); // success: Block and Viewpoint package, no fails
assertNoMigration(leftResource);
assertMigration(rightResource); // success: Block and Viewpoint package, no fails
// test structure of models
assertMigratedStructure(originResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE_CHANGE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// there are no conflicts
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
// 2 differences related to viewPointChange: Attribute change refining a StereotypeAttributeChange
assertEquals(2, differences.size());
assertViewPointAttributeChange(comparison, originResource, false);
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests whether the profile migration correctly migrates the left and the origin model and feature
* changes are detected. In the right resource the feature {@link Viewpoint#getPurpose()} has changed and
* the difference should be detected, but no conflict should be produced. This test is equivalent to
* {@link #testAttributeChangeABA(Comparison, CompareTestSupport)} with reversed left and right sides.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/attribute/change/aab/left.uml", right = "data/myml/attribute/change/aab/right.uml", ancestor = "data/myml/attribute/change/aab/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testAttributeChangeAAB(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertMigration(originResource); // success: Block and Viewpoint package, no fails
assertMigration(leftResource); // success: Block and Viewpoint package, no fails
assertNoMigration(rightResource);
// test structure of models
assertMigratedStructure(originResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE_CHANGE);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// there are no conflicts
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
// 2 differences related to viewPointChange: Attribute change refining a StereotypeAttributeChange
assertEquals(2, differences.size());
assertViewPointAttributeChange(comparison, originResource, false);
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests whether the profile migration correctly migrates the origin model and feature changes are
* detected. The {@link Viewpoint#getPurpose()} feature has changed in the left and right resource to the
* same value. So, differences should be detected, but no REAL conflict should be produced.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/attribute/change/abb/left.uml", right = "data/myml/attribute/change/abb/right.uml", ancestor = "data/myml/attribute/change/abb/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testAttributeChangeABB(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertMigration(originResource); // success: Block and Viewpoint package, no fails
assertNoMigration(leftResource); // success: Block and Viewpoint package, no fails
assertNoMigration(rightResource);
// test structure of models
assertMigratedStructure(originResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE_CHANGE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE_CHANGE);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// 1 PSEUDO conflict: Viewpoint::purpose changed on both sides to equal value
assertEquals((conflicts.size() - 1) + " unexpected conflicts", 1, conflicts.size());
assertTrue(Iterables.all(conflicts,
PapyrusComparePredicates.containsConflictOfTypes(ConflictKind.PSEUDO)));
// 2 differences on both sides related to viewPointChange: Attribute change refining a
// StereotypeAttributeChange
assertEquals(4, differences.size());
assertViewPointAttributeChange(comparison, originResource, true);
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests whether the profile migration correctly migrates the origin model and feature changes are
* detected. The {@link Viewpoint#getPurpose()} feature has changed in the left and right resource to
* different values. So, differences should be detected and a REAL conflict should be produced.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/attribute/change/abc/left.uml", right = "data/myml/attribute/change/abc/right.uml", ancestor = "data/myml/attribute/change/abc/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testAttributeChangeABC(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertMigration(originResource); // success: Block and Viewpoint package, no fails
assertNoMigration(leftResource); // success: Block and Viewpoint package, no fails
assertNoMigration(rightResource);
// test structure of models
assertMigratedStructure(originResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE_CHANGE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE_OTHER_CHANGE);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// 1 REAL conflict: Viewpoint::purpose changed on both sides to equal value
assertEquals((conflicts.size() - 1) + " unexpected conflicts", 1, conflicts.size());
assertTrue(Iterables.all(conflicts,
PapyrusComparePredicates.containsConflictOfTypes(ConflictKind.REAL)));
// 2 differences on both sides related to viewPointChange: Attribute change refining a
// StereotypeAttributeChange
assertEquals(4, differences.size());
assertViewPointAttributeChange(comparison, originResource, true);
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests whether the profile migration correctly migrates the origin and right model and unknown features
* are removed as expected. The origin and the right model have a String attribute "oldAttribute" with the
* same value. This feature does not exist in the migrated version of the profile and should therefore be
* deleted. Since the profile migration happens before the comparison, this deletion is not part of the
* result. Therefore, all models are considered the same and no differences are detected.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/attribute/unmigrated/aba/left.uml", right = "data/myml/attribute/unmigrated/aba/right.uml", ancestor = "data/myml/attribute/unmigrated/aba/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testUnmigratedAttributeABA(final Comparison comparison, final CompareTestSupport support) {
// origin and right have oldAttribute="This is not available in the new version." in Viewpoint
// stereotype application, but this attribute is not in new version and gets lost
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertMigration(originResource); // success: Block and Viewpoint package, no fails
assertNoMigration(leftResource);
assertMigration(rightResource); // success: Block and Viewpoint package, no fails
// test structure of models
assertMigratedStructure(originResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// there are no conflicts and differences
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
assertTrue("Unexpected differences: " + differences, differences.isEmpty());
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests whether the profile migration correctly migrates the origin and right model and unknown features
* are created with their default value as expected. In this setup, the origin and the right model have no
* value for the {@link Viewpoint#getPurpose()} feature. Therefore the comparison should take the default
* value of this feature detect the change from the default value to the value in the left model.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/attribute/defaultval/aba/left.uml", right = "data/myml/attribute/defaultval/aba/right.uml", ancestor = "data/myml/attribute/defaultval/aba/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testAttributeDefaultValueABA(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
final Class singleUMLClass = getSingleUMLClass(originResource);
final Viewpoint viewPoint = UMLUtil.getStereotypeApplication(singleUMLClass, Viewpoint.class);
assertNotNull("Viewpoint expected.", viewPoint);
final String purposeDefaultValue = viewPoint.eClass().getEStructuralFeature("purpose")
.getDefaultValueLiteral();
// test migration
assertMigration(originResource); // success: Block and Viewpoint package, no fails
assertNoMigration(leftResource);
assertMigration(rightResource); // success: Block and Viewpoint package, no fails
// test structure of models
assertMigratedStructure(originResource, BLOCK_ISENCAPSULATED, purposeDefaultValue);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, purposeDefaultValue);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// there are no conflicts
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
// 2 differences related to viewPointChange: Attribute change refining a StereotypeAttributeChange
assertEquals(2, differences.size());
assertViewPointAttributeChange(comparison, originResource, false);
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests the behavior if the a wrong profile definition is selected which does not contain the missing
* stereotype. As a result, the unmigratable stereotypes are deleted by the Papyrus model repair
* mechanism. For this example we use the following definitions for the origin model:
* <ul>
* <li>Block definition: http://www.eclipse.org/uml2/5.0.0/UML/WrongProfile/Standard/1</li>
* </ul>
* This definition is close enough to the UML Standard Profile with package URI
* http://www.eclipse.org/uml2/5.0.0/UML/Profile/Standard to automatically migrate the missing Block
* stereotype. As the UML Standard Profile does not contain a definition for Block, the stereotype is
* deleted since the correct Block class can not be determined. We therefore expect the comparison to
* yield an error since the profile definition changed and we can not handle it accordingly.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/uri/wrongmigrated/abb/left.uml", right = "data/myml/uri/wrongmigrated/abb/right.uml", ancestor = "data/myml/uri/wrongmigrated/abb/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testWrongMigratedPackageURIABB(final Comparison comparison,
final CompareTestSupport support) {
if (ProfileNamespaceURIPatternAPI.isAvailable()) {
// With the ProfileNamespaceURIPatternAPI, we don't perform string matching and therefore do not
// return a wrong profile. Instead, no profile is returned, leaving the Block stereotype intact.
return;
}
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertMigration(originResource); // success: Viewpoint package, wrong success: Block package
assertNoMigration(leftResource);
assertNoMigration(rightResource);
// test structure of models
final Class umlClass = assertPartiallyMigratedUmlClass(originResource, 1);
assertMigratedViewPoint(umlClass, VIEWPOINT_PURPOSE);
// Block was migrated to a wrong package, because the URI was not helpful enough
final Block blockApplication = UMLUtil.getStereotypeApplication(umlClass, Block.class);
assertNull("Block should have been deleted.", blockApplication);
// wrong migration -> deletion, so also no AnyType present
assertFalse(Iterables.tryFind(originResource.getContents(), Predicates.instanceOf(AnyType.class))
.isPresent());
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// there are no conflicts and no differences since the comparison was not completed
assertEquals(Diagnostic.ERROR, comparison.getDiagnostic().getSeverity());
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
assertTrue("Unexpected differences: " + differences, differences.isEmpty());
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests the behavior if the profile definitions can not be migrated, but a wrong profile definition is
* selected instead. As a result, the unmigratable stereotypes are deleted by the Papyrus model repair
* mechanism. For this example we use the following definitions for the origin model:
* <ul>
* <li>Block definition: http://www.eclipse.org/fake/0/Lang/Fakes/1</li>
* </ul>
* Since we cannot find a proper profile containing such a package, the unresolved {@link AnyType}s remain
* in the resources. We expect the comparison to yield an error since the profile definition changed and
* we can not handle it accordingly.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/uri/notmigrated/abb/left.uml", right = "data/myml/uri/notmigrated/abb/right.uml", ancestor = "data/myml/uri/notmigrated/abb/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testNotMigratedPackageURIABB(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertPartialMigration(originResource, 1, 1); // could not migrate block
assertNoMigration(leftResource);
assertNoMigration(rightResource);
// test structure of models
assertPartiallyMigratedStructure(originResource, false, BLOCK_ISENCAPSULATED, true,
VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// there are no conflicts and no differences since the comparison was not completed
assertEquals(Diagnostic.ERROR, comparison.getDiagnostic().getSeverity());
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
assertTrue("Unexpected differences: " + differences, differences.isEmpty());
}
/**
* Tests the behavior if the profile definitions can not be migrated, but a wrong profile definition is
* selected instead. As a result, the unmigratable stereotypes are deleted by the Papyrus model repair
* mechanism. For this example we use the following definitions for the left and origin model:
* <ul>
* <li>Block definition: http://www.eclipse.org/fake/0/Lang/Fakes/1</li>
* </ul>
* Since we cannot find a proper profile containing such a package, the unresolved {@link AnyType}s remain
* in the resources. We expect the comparison to yield an error since the profile definition changed and
* we can not handle it accordingly.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/uri/notmigrated/aab/left.uml", right = "data/myml/uri/notmigrated/aab/right.uml", ancestor = "data/myml/uri/notmigrated/aab/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testNotMigratedPackageURIAAB(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertPartialMigration(originResource, 1, 1);
assertPartialMigration(leftResource, 1, 1);
assertNoMigration(rightResource);
// test structure of models
assertPartiallyMigratedStructure(originResource, false, BLOCK_ISENCAPSULATED, true,
VIEWPOINT_PURPOSE);
assertPartiallyMigratedStructure(leftResource, false, BLOCK_ISENCAPSULATED, true, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// there are no conflicts and no differences since the comparison was not completed
assertEquals(Diagnostic.ERROR, comparison.getDiagnostic().getSeverity());
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
assertTrue("Unexpected differences: " + differences, differences.isEmpty());
}
/**
* Tests the behavior if the profile definitions follow not the expected URI scheme. As a result,
* stereotype applications are grouped incorrectly and deleted by the Papyrus model repair mechanism. For
* this example we use the following definitions for the origin model:
* <ul>
* <li>Block definition: http://www.eclipse.org/papyrus/compare/test/beta/profile/MyML/Blocks</li>
* <li>Viewpoint definition:
* http://www.eclipse.org/papyrus/compare/test/beta/profile/MyML/ModelElements</li>
* </ul>
* As a result, both definitions are assumed to be the same and the we only migrate stereotypes of the
* first found package. The remaining stereotypes can not be migrated with this package (as the definition
* would be in another package) and are deleted automatically together with their profile application. We
* therefore expect one stereotype to be added to the left and right model and therefore get differences
* and PSEUDO conflicts in the comparison.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/uri/wrongformat/abb/left.uml", right = "data/myml/uri/wrongformat/abb/right.uml", ancestor = "data/myml/uri/wrongformat/abb/origin.uml", resourceSetHooks = ProfileMigrationHook.class)
public void testWrongFormatPackageURIsABB(final Comparison comparison, final CompareTestSupport support) {
if (ProfileNamespaceURIPatternAPI.isAvailable()) {
// With the ProfileNamespaceURIPatternAPI, we don't perform string matching and therefore do not
// return a profile for URIs we cannot match. Instead, no profile is returned, resulting in an
// unsuccessful migration and not a wrong correct one.
return;
}
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertMigration(originResource); // success: Viewpoint package, wrong success: Block package
assertNoMigration(leftResource);
assertNoMigration(rightResource);
// test structure of models
final Class umlClass = assertPartiallyMigratedUmlClass(originResource, 1);
// deletion is non-deterministic, sometimes Block is migrated, sometimes Viewpoint
final Viewpoint viewPointApplication = UMLUtil.getStereotypeApplication(umlClass, Viewpoint.class);
final Block blockApplication = UMLUtil.getStereotypeApplication(umlClass, Block.class);
java.lang.Class<? extends EObject> missingStereotypeClass = null;
if (viewPointApplication == null) {
// Block got migrated
missingStereotypeClass = Viewpoint.class;
assertNull("Viewpoint should have been deleted.", viewPointApplication);
assertMigratedBlock(umlClass, BLOCK_ISENCAPSULATED);
} else {
// Viewpoint got migrated
missingStereotypeClass = Block.class;
assertNull("Block should have been deleted.", blockApplication);
assertMigratedViewPoint(umlClass, VIEWPOINT_PURPOSE);
}
// no anytypes left as the stereotype got deleted and not only "not migrated"
assertFalse(Iterables.tryFind(originResource.getContents(), Predicates.instanceOf(AnyType.class))
.isPresent());
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// test differences and conflicts
if (!PapyrusMigrationUtil.isLuna()) {
// 4 PSEUDO conflict: stereotype application (2)
assertEquals((conflicts.size() - 2) + " unexpected conflicts", 2, conflicts.size());
assertTrue(Iterables.all(conflicts,
PapyrusComparePredicates.containsConflictOfTypes(ConflictKind.PSEUDO)));
// 2 differences on both sides related to stereotype removal: ResourceAttachmentChange and
// ReferenceChange refining a StereotypeApplicationChange
assertEquals(6, differences.size());
assertStereotypeAddition(comparison, rightResource, missingStereotypeClass, true); // both sides
} else {
// In the model repair mechanism of Luna, IDs were not preserved so we detect a lot of differences
// and PSEUDO conflicts through additions and removals as the elements are not matched as expected
}
}
/**
* Tests the behavior without the profile migration capabilities, i.e., without the
* {@link ProfileMigrationHook}. We expect the comparison to yield an error since the profile definition
* changed and we can not handle it accordingly.
*
* @param comparison
* comparison object between the models
* @param support
* exposed by the testing framework
*/
@Compare(left = "data/myml/version/aba/left.uml", right = "data/myml/version/aba/right.uml", ancestor = "data/myml/version/aba/origin.uml")
public void testErrorWithoutMigration(final Comparison comparison, final CompareTestSupport support) {
final List<Diff> differences = comparison.getDifferences();
final EList<Conflict> conflicts = comparison.getConflicts();
// does not use ProfileMigrationHook
final Resource originResource = support.getAncestorResource();
final Resource leftResource = support.getLeftResource();
final Resource rightResource = support.getRightResource();
// test migration
assertNoMigration(originResource);
assertNoMigration(leftResource);
assertNoMigration(rightResource);
// test structure of models
assertUnmigratedStructure(originResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertMigratedStructure(leftResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
assertUnmigratedStructure(rightResource, BLOCK_ISENCAPSULATED, VIEWPOINT_PURPOSE);
// there are no conflicts and no differences since the comparison was not completed
assertEquals(Diagnostic.ERROR, comparison.getDiagnostic().getSeverity());
assertTrue("Unexpected conflicts: " + conflicts, conflicts.isEmpty());
assertTrue("Unexpected differences: " + differences, differences.isEmpty());
}
}