Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2018-05-28 21:20:18 +0000
committerNicolas FAUVERGUE2018-07-06 13:07:17 +0000
commit9b246674d8dd9c872601384f0324ef48f65369c5 (patch)
tree1f4c2db90ceaa5e3169c02fd553c148477ffe609
parent76d3f999219aa04592ebfcaf3e70ca149840ac63 (diff)
downloadorg.eclipse.papyrus-9b246674d8dd9c872601384f0324ef48f65369c5.tar.gz
org.eclipse.papyrus-9b246674d8dd9c872601384f0324ef48f65369c5.tar.xz
org.eclipse.papyrus-9b246674d8dd9c872601384f0324ef48f65369c5.zip
Bug 533675: [Sequence Diagram] CombinedFragment can be created in any
case in the diagram Test creation of combined fragments - covering nothing at all (in blank space) - partially covering a message - within another combined fragment Also, update the tests for bug 535097 to use the editor fixture to create interaction operands by automation of the creation tool, to better simulate user interaction. This requires explicitly disabling snap to grid (which is on by default in Photon) so that the mouse pointer can be placed as precisely as is required by the tests. Change-Id: Ic68e6c49746d63dc3e7c93ad92bd89ab68937614 Signed-off-by: Christian W. Damus <give.a.damus@gmail.com> Signed-off-by: Nicolas FAUVERGUE <nicolas.fauvergue@cea.fr>
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/helpers/advice/DefaultInteractionOperandAdvice.java9
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomInteractionOperandCreationEditPolicy.java11
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionOperandEditHelperAdvice.java39
-rw-r--r--tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/CommandUtils.java208
-rw-r--r--tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java45
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.di2
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.notation111
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.uml27
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug535097-OperandsSemantic.notation1
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/AbstractOperandsTest.java58
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java102
-rw-r--r--tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/TestCFOperandsSemanticCoverage.java22
12 files changed, 553 insertions, 82 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/helpers/advice/DefaultInteractionOperandAdvice.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/helpers/advice/DefaultInteractionOperandAdvice.java
index 9dec13b09e2..c3829d2902d 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/helpers/advice/DefaultInteractionOperandAdvice.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/edit/helpers/advice/DefaultInteractionOperandAdvice.java
@@ -30,6 +30,7 @@ import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
import org.eclipse.papyrus.infra.ui.util.EditorHelper;
import org.eclipse.papyrus.uml.diagram.sequence.UmlSequenceDiagramForMultiEditor;
import org.eclipse.papyrus.uml.diagram.sequence.command.AsynchronousCommand;
+import org.eclipse.papyrus.uml.diagram.sequence.validation.AsyncValidateCommand;
import org.eclipse.ui.IEditorPart;
import org.eclipse.uml2.uml.CombinedFragment;
import org.eclipse.uml2.uml.InteractionOperand;
@@ -114,7 +115,13 @@ public class DefaultInteractionOperandAdvice extends AbstractEditHelperAdvice {
request.setSnapToEnabled(false);
request.setEditParts(operand);
org.eclipse.gef.commands.Command command = operand.getCommand(request);
- return (command == null) ? null : new CommandProxy(command);
+
+ ICommand result = (command == null) ? null : new CommandProxy(command);
+ if (result != null) {
+ // Trigger validation of the operand
+ result = result.compose(new AsyncValidateCommand(operand.resolveSemanticElement()));
+ }
+ return result;
}
}
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomInteractionOperandCreationEditPolicy.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomInteractionOperandCreationEditPolicy.java
index 952dfaa9d54..297cd871a1e 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomInteractionOperandCreationEditPolicy.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/referencialgrilling/CustomInteractionOperandCreationEditPolicy.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2017 CEA LIST and others.
+ * Copyright (c) 2017, 2018 CEA LIST, Christian W. Damus, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,6 +8,7 @@
*
* Contributors:
* Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
+ * Christian W. Damus - bug 533675
*
*****************************************************************************/
@@ -42,6 +43,7 @@ import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.papyrus.infra.gmfdiag.common.editpolicies.DefaultCreationEditPolicy;
import org.eclipse.papyrus.uml.diagram.sequence.util.SequenceUtil;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.uml2.uml.UMLPackage;
/**
* This allows to define the creation edit policy for the interaction operand.
@@ -82,7 +84,12 @@ public class CustomInteractionOperandCreationEditPolicy extends DefaultCreationE
IElementType elementType = iter.next();
Request createRequest = request.getRequestForType(elementType);
if (createRequest != null) {
- EditPart target = SequenceUtil.getParentCombinedFragmentPart(getHost().getTargetEditPart(createRequest));
+ EditPart target = getHost().getTargetEditPart(createRequest);
+ // Don't re-target creation of an interaction fragment to a thing that
+ // cannot contain it
+ if (!UMLPackage.Literals.INTERACTION_FRAGMENT.isSuperTypeOf(elementType.getEClass())) {
+ target = SequenceUtil.getParentCombinedFragmentPart(target);
+ }
if (target == null) {
continue;
}
diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionOperandEditHelperAdvice.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionOperandEditHelperAdvice.java
index ab22fb2eb93..581eab0c80c 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionOperandEditHelperAdvice.java
+++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/InteractionOperandEditHelperAdvice.java
@@ -25,11 +25,16 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
+import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes;
+import org.eclipse.papyrus.uml.service.types.utils.ElementUtil;
import org.eclipse.uml2.uml.CombinedFragment;
+import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.InteractionOperand;
/**
@@ -47,15 +52,45 @@ public class InteractionOperandEditHelperAdvice extends InteractionFragmentConta
}
@Override
+ public void configureRequest(IEditCommandRequest request) {
+ super.configureRequest(request);
+
+ if (request instanceof CreateElementRequest) {
+ configureCreate((CreateElementRequest) request);
+ }
+ }
+
+ private void configureCreate(CreateElementRequest request) {
+ if (ElementUtil.isTypeOf(request.getElementType(), UMLElementTypes.INTERACTION_OPERAND)
+ && (request.getContainer() instanceof InteractionOperand)) {
+
+ // Don't create interaction operands in other operands but in the containing
+ // combined fragment
+ InteractionOperand operand = (InteractionOperand) request.getContainer();
+ Element operandOwner = operand.getOwner();
+ if (operandOwner instanceof CombinedFragment) {
+ request.setContainer(operandOwner);
+ }
+ }
+ }
+
+ @Override
protected ICommand getAfterDestroyDependentsCommand(DestroyDependentsRequest request) {
ICommand result = super.getAfterDestroyDependentsCommand(request);
if (request.getElementToDestroy() instanceof InteractionOperand) {
InteractionOperand operand = (InteractionOperand) request.getElementToDestroy();
- CombinedFragment cfrag = (CombinedFragment) operand.getOwner();
+
+ // In case an operand was illegally created directly inside of another
+ // operand as a fragment instead of in a combined fragment as an operand
+ CombinedFragment cfrag = Optional.ofNullable(operand.getOwner())
+ .filter(CombinedFragment.class::isInstance).map(CombinedFragment.class::cast)
+ .orElse(null);
// Are we deleting all of the operands of this combined fragment?
- Optional<InteractionContainerDeletionContext> context = InteractionContainerDeletionContext.get(request);
+ Optional<InteractionContainerDeletionContext> context = (cfrag == null)
+ ? Optional.empty()
+ : InteractionContainerDeletionContext.get(request);
// We won't know until the time comes, because in the diagrams, every edit-part
// selected is deleted in its own separate context
diff --git a/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/CommandUtils.java b/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/CommandUtils.java
new file mode 100644
index 00000000000..0538434b44b
--- /dev/null
+++ b/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/CommandUtils.java
@@ -0,0 +1,208 @@
+/*****************************************************************************
+ * Copyright (c) 2018 Christian W. Damus 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:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.junit.utils;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.ICompositeOperation;
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.common.core.command.ICompositeCommand;
+import org.eclipse.gmf.runtime.diagram.ui.commands.CommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
+import org.eclipse.papyrus.infra.emf.gmf.command.ICommandWrapper;
+
+import com.google.common.base.Strings;
+
+/**
+ * Utilities for testing and debugging commands.
+ */
+public class CommandUtils {
+
+ /**
+ * Not instantiable by clients.
+ */
+ private CommandUtils() {
+ super();
+ }
+
+ /**
+ * Dump a {@code command} structure to standard error.
+ *
+ * @param command
+ * a command to dump
+ */
+ public static void dump(Object command) {
+ dump(command, System.err, 0);
+ }
+
+ /**
+ * Dump a {@code command} structure.
+ *
+ * @param command
+ * a command to dump
+ * @param sink
+ * where to dump it
+ */
+ public static void dump(Object command, Appendable sink) {
+ dump(command, sink, 0);
+ }
+
+ static Object unwrap(Object command) {
+ if (command instanceof ICommandProxy) {
+ return ((ICommandProxy) command).getICommand();
+ } else if (command instanceof CommandProxy) {
+ return ((CommandProxy) command).getCommand();
+ } else if (command instanceof ICommandWrapper<?>) {
+ return ((ICommandWrapper<?>) command).getWrappedCommand();
+ } else {
+ return command;
+ }
+ }
+
+ static void append(CharSequence text, Appendable sink) {
+ try {
+ sink.append(text);
+ } catch (IOException e) {
+ // best effort
+ }
+ }
+
+ static void appendln(CharSequence text, Appendable sink) {
+ try {
+ sink.append(text).append(System.lineSeparator());
+ } catch (IOException e) {
+ // best effort
+ }
+ }
+
+ static void appendln(Appendable sink) {
+ try {
+ sink.append(System.lineSeparator());
+ } catch (IOException e) {
+ // best effort
+ }
+ }
+
+ static void dumpKind(Object command, Appendable sink, int depth) {
+ String kind;
+ if (command instanceof Command) {
+ kind = command instanceof CompoundCommand ? "EMF*" : "EMF";
+ } else if (command instanceof org.eclipse.gef.commands.Command) {
+ kind = command instanceof org.eclipse.gef.commands.CompoundCommand ? "GEF*" : "GEF";
+ } else if (command instanceof ICommand) {
+ kind = command instanceof ICompositeCommand ? "GMF*" : "GMF";
+ } else if (command instanceof IUndoableOperation) {
+ kind = command instanceof ICompositeOperation ? "UOP*" : "UOP";
+ } else {
+ kind = "UNK";
+ }
+
+ StringBuilder buf = new StringBuilder(45);
+ buf.append(Strings.padEnd(kind, 5, ' '));
+ buf.append(Strings.repeat(" ", depth));
+
+ String className = command.getClass().getName();
+ buf.append(className.substring(className.lastIndexOf('.') + 1));
+ buf.append(": ");
+
+ append(buf, sink);
+ }
+
+ static void dump(Object command, Appendable sink, int depth) {
+ Object unwrapped = unwrap(command);
+ if (unwrapped != command) {
+ dump(unwrapped, sink, depth);
+ return;
+ }
+
+ dumpKind(command, sink, depth);
+
+ if (command instanceof Command) {
+ dump0((Command) command, sink, depth);
+ } else if (command instanceof org.eclipse.gef.commands.Command) {
+ dump0((org.eclipse.gef.commands.Command) command, sink, depth);
+ } else if (command instanceof ICommand) {
+ dump0((ICommand) command, sink, depth);
+ } else if (command instanceof IUndoableOperation) {
+ dump0((IUndoableOperation) command, sink, depth);
+ } else {
+ appendln("<unknown>", sink);
+ }
+ }
+
+ static void dump0(org.eclipse.gef.commands.Command command, Appendable sink, int depth) {
+ appendln(command.getLabel(), sink);
+
+ if (command instanceof org.eclipse.gef.commands.CompoundCommand) {
+ int nextDepth = depth + 1;
+ org.eclipse.gef.commands.CompoundCommand compound = (org.eclipse.gef.commands.CompoundCommand) command;
+ ((List<?>) compound.getCommands()).stream().forEach(c -> dump(c, sink, nextDepth));
+ }
+ }
+
+ static void dump0(Command command, Appendable sink, int depth) {
+ appendln(command.getLabel(), sink);
+
+ if (command instanceof CompoundCommand) {
+ int nextDepth = depth + 1;
+ CompoundCommand compound = (CompoundCommand) command;
+ compound.getCommandList().stream().forEach(c -> dump(c, sink, nextDepth));
+ }
+ }
+
+ static void dump0(ICommand command, Appendable sink, int depth) {
+ appendln(command.getLabel(), sink);
+
+ if (command instanceof ICompositeCommand) {
+ int nextDepth = depth + 1;
+ ICompositeCommand compound = (ICompositeCommand) command;
+ ((Iterator<?>) compound.iterator()).forEachRemaining(c -> dump(c, sink, nextDepth));
+ }
+ }
+
+ static void dump0(IUndoableOperation command, Appendable sink, int depth) {
+ appendln(command.getLabel(), sink);
+
+ if (command instanceof ICompositeOperation) {
+ int nextDepth = depth + 1;
+ Collection<?> children = Collections.emptyList();
+
+ try {
+ Field childrenField = command.getClass().getDeclaredField("children"); //$NON-NLS-1$
+ Object childrenValue = childrenField.get(command);
+ if (childrenValue != null) {
+ children = (childrenValue instanceof Collection<?>)
+ ? (Collection<?>) childrenValue
+ : (childrenValue.getClass().isArray())
+ ? Arrays.asList((Object[]) childrenValue)
+ : Collections.singleton(childrenValue);
+ }
+ } catch (Exception e) {
+ // best effort
+ }
+
+ children.forEach(c -> dump(c, sink, nextDepth));
+ }
+ }
+
+}
diff --git a/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java b/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java
index 55abac19b7b..2d43a7db213 100644
--- a/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java
+++ b/tests/junit/framework/org.eclipse.papyrus.junit.utils/src/org/eclipse/papyrus/junit/utils/rules/PapyrusEditorFixture.java
@@ -108,6 +108,7 @@ import org.eclipse.papyrus.infra.tools.util.PlatformHelper;
import org.eclipse.papyrus.infra.tools.util.TypeUtils;
import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor;
import org.eclipse.papyrus.junit.matchers.CommandMatchers;
+import org.eclipse.papyrus.junit.utils.CommandUtils;
import org.eclipse.papyrus.junit.utils.EditorUtils;
import org.eclipse.papyrus.junit.utils.JUnitUtils;
import org.eclipse.papyrus.junit.utils.tests.AbstractEditorTest;
@@ -152,6 +153,7 @@ import com.google.common.collect.Lists;
* completion of the test.
*/
public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEditingDomain> {
+ private static boolean DUMP_COMMANDS = Boolean.getBoolean("dump.commands"); //$NON-NLS-1$
private final Collection<IEditorPart> editorsToClose = Lists.newArrayList();
@@ -279,6 +281,11 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
operationHistoryIntegrityListener = new IOperationHistoryListener() {
@Override
public void historyNotification(OperationHistoryEvent event) {
+ if (DUMP_COMMANDS && (event.getEventType() == OperationHistoryEvent.ABOUT_TO_EXECUTE)) {
+ System.err.println(">> Executing command"); //$NON-NLS-1$
+ CommandUtils.dump(event.getOperation());
+ System.err.println();
+ }
if ((event.getEventType() == OperationHistoryEvent.DONE) && (activeDiagramEditor != null)) {
IUndoContext diagramContext = activeDiagramEditor.getDiagramEditDomain().getDiagramCommandStack().getUndoContext();
if (diagramContext != null) {
@@ -1513,7 +1520,7 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
*
* @since 2.2
*/
- public EditPart createShape(EditPart parent, IElementType type, Point location, Dimension size) {
+ public IGraphicalEditPart createShape(EditPart parent, IElementType type, Point location, Dimension size) {
CreateViewRequest request = CreateViewRequestFactory.getCreateShapeRequest(type, ((IGraphicalEditPart) parent).getDiagramPreferencesHint());
request.setLocation(location);
@@ -1527,12 +1534,12 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
return getNewEditPart(parent, request.getViewDescriptors());
}
- private EditPart getNewEditPart(EditPart context, Collection<? extends ViewDescriptor> viewDescriptors) {
+ private IGraphicalEditPart getNewEditPart(EditPart context, Collection<? extends ViewDescriptor> viewDescriptors) {
return viewDescriptors.stream()
.map(desc -> desc.getAdapter(View.class)).map(View.class::cast)
.filter(Objects::nonNull)
.map(view -> DiagramEditPartsUtil.getEditPartFromView(view, context))
- .filter(Objects::nonNull)
+ .filter(IGraphicalEditPart.class::isInstance).map(IGraphicalEditPart.class::cast)
.findAny().orElseGet(failOnAbsence("Could not find newly created edit-part"));
}
@@ -1551,7 +1558,7 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
*
* @since 2.2
*/
- public EditPart createShape(IElementType type, Point location, Dimension size) {
+ public IGraphicalEditPart createShape(IElementType type, Point location, Dimension size) {
class MyTool extends AspectUnspecifiedTypeCreationTool {
private Collection<? extends ViewDescriptor> results = Collections.emptyList();
@@ -1640,6 +1647,36 @@ public class PapyrusEditorFixture extends AbstractModelFixture<TransactionalEdit
}
/**
+ * Convert a point that is relative to the given part to a point relative to the
+ * current viewport (taking zoom and scroll into account). This can be used to get
+ * a "Mouse Location" to configure requests. Useful as a static import for test
+ * readability
+ *
+ * @param x
+ * the relative x coördinate
+ * @param y
+ * the relative y coördinate
+ * @param relativeTo
+ * the edit-part in which coördinate space the {@code x} and {@code y}
+ * are specified
+ * @return the point in absolute mouse-pointer coördinates
+ *
+ * @since 2.2
+ */
+ public static Point at(int x, int y, IGraphicalEditPart relativeTo) {
+ Point at = new Point(x, y);
+
+ IFigure figure = relativeTo.getContentPane();
+ Point layoutOrigin = figure.getClientArea().getLocation();
+
+ at.performTranslate(layoutOrigin.x, layoutOrigin.y);
+ figure.translateToParent(at);
+ figure.translateToAbsolute(at);
+
+ return at;
+ }
+
+ /**
* Create a size dimension (useful as a static import for test readability).
*
* @param width
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.di b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.di
new file mode 100644
index 00000000000..8c549eecdc6
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.di
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<architecture:ArchitectureDescription xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:architecture="http://www.eclipse.org/papyrus/infra/core/architecture" contextId="org.eclipse.papyrus.infra.services.edit.TypeContext"/>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.notation b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.notation
new file mode 100644
index 00000000000..887d222153b
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.notation
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmlns:style="http://www.eclipse.org/papyrus/infra/gmfdiag/style" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_QKU0YEMwEeiEZ5Jtfh6-KA" type="PapyrusUMLSequenceDiagram" name="sequence" measurementUnit="Pixel">
+ <children xmi:type="notation:Shape" xmi:id="_QKU0YUMwEeiEZ5Jtfh6-KA" type="Interaction_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_QKU0YkMwEeiEZ5Jtfh6-KA" type="Interaction_NameLabel">
+ <element xmi:type="uml:Interaction" href="bug533675.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_QKU0Y0MwEeiEZ5Jtfh6-KA" type="Interaction_SubfragmentCompartment">
+ <children xmi:type="notation:Shape" xmi:id="_RZ4XwEMwEeiEZ5Jtfh6-KA" type="Lifeline_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_RZ4-0EMwEeiEZ5Jtfh6-KA" type="Lifeline_NameLabel">
+ <element xmi:type="uml:Lifeline" href="bug533675.uml#_RZwb8EMwEeiEZ5Jtfh6-KA"/>
+ </children>
+ <element xmi:type="uml:Lifeline" href="bug533675.uml#_RZwb8EMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_RZ4XwUMwEeiEZ5Jtfh6-KA" x="58" y="10"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_R0X7YEMwEeiEZ5Jtfh6-KA" type="Lifeline_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_R0X7YkMwEeiEZ5Jtfh6-KA" type="Lifeline_NameLabel">
+ <element xmi:type="uml:Lifeline" href="bug533675.uml#_R0URAEMwEeiEZ5Jtfh6-KA"/>
+ </children>
+ <children xmi:type="notation:BasicCompartment" xmi:id="_R0cM0EMwEeiEZ5Jtfh6-KA" type="compartment_shape_display">
+ <styles xmi:type="notation:TitleStyle" xmi:id="_R0cM0UMwEeiEZ5Jtfh6-KA"/>
+ <element xmi:type="uml:Lifeline" href="bug533675.uml#_R0URAEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_R0cM0kMwEeiEZ5Jtfh6-KA"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_XgABcEMwEeiEZ5Jtfh6-KA" type="BehaviorExecutionSpecification_Shape">
+ <children xmi:type="notation:DecorationNode" xmi:id="_XgABckMwEeiEZ5Jtfh6-KA" type="BehaviorExecutionSpecification_Behavior">
+ <element xmi:type="uml:BehaviorExecutionSpecification" href="bug533675.uml#_Xf7wAEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_XgAogEMwEeiEZ5Jtfh6-KA" x="18" y="18"/>
+ </children>
+ <element xmi:type="uml:BehaviorExecutionSpecification" href="bug533675.uml#_Xf7wAEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_XgABcUMwEeiEZ5Jtfh6-KA" x="40" y="67" width="20" height="100"/>
+ </children>
+ <children xmi:type="notation:Shape" xmi:id="_NTi0AElQEeiMtthmmu-tjQ" type="DestructionOccurrenceSpecification_Shape">
+ <element xmi:type="uml:DestructionOccurrenceSpecification" href="bug533675.uml#_NSlxwElQEeiMtthmmu-tjQ"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NTi0AUlQEeiMtthmmu-tjQ" x="60" y="187"/>
+ </children>
+ <element xmi:type="uml:Lifeline" href="bug533675.uml#_R0URAEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_R0X7YUMwEeiEZ5Jtfh6-KA" x="234" y="53" width="100" height="227"/>
+ </children>
+ <element xmi:type="uml:Interaction" href="bug533675.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_QKU0ZEMwEeiEZ5Jtfh6-KA"/>
+ </children>
+ <element xmi:type="uml:Interaction" href="bug533675.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Bounds" xmi:id="_QKU0ZUMwEeiEZ5Jtfh6-KA"/>
+ </children>
+ <styles xmi:type="notation:StringValueStyle" xmi:id="_QKU0ZkMwEeiEZ5Jtfh6-KA" name="diagram_compatibility_version" stringValue="1.4.0"/>
+ <styles xmi:type="notation:DiagramStyle" xmi:id="_QKU0Z0MwEeiEZ5Jtfh6-KA"/>
+ <styles xmi:type="style:PapyrusDiagramStyle" xmi:id="_QKU0aEMwEeiEZ5Jtfh6-KA" diagramKindId="org.eclipse.papyrus.uml.diagram.sequence">
+ <owner xmi:type="uml:Class" href="bug533675.uml#_Jqu6wEMwEeiEZ5Jtfh6-KA"/>
+ </styles>
+ <element xmi:type="uml:Interaction" href="bug533675.uml#_POkWwEMwEeiEZ5Jtfh6-KA"/>
+ <edges xmi:type="notation:Connector" xmi:id="_Xfg5QEMwEeiEZ5Jtfh6-KA" type="Message_SynchEdge" source="_RZ4XwEMwEeiEZ5Jtfh6-KA" target="_R0X7YEMwEeiEZ5Jtfh6-KA">
+ <children xmi:type="notation:DecorationNode" xmi:id="_Xfg5Q0MwEeiEZ5Jtfh6-KA" type="Message_SynchNameLabel">
+ <element xmi:type="uml:Message" href="bug533675.uml#_XfUsAEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Xfg5REMwEeiEZ5Jtfh6-KA" x="1" y="-13"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_XfhgUEMwEeiEZ5Jtfh6-KA" type="Message_SynchStereotypeLabel">
+ <element xmi:type="uml:Message" href="bug533675.uml#_XfUsAEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_XfhgUUMwEeiEZ5Jtfh6-KA" x="1" y="-33"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_Xfg5QUMwEeiEZ5Jtfh6-KA"/>
+ <styles xmi:type="notation:LineStyle" xmi:id="_XfhgUkMwEeiEZ5Jtfh6-KA"/>
+ <element xmi:type="uml:Message" href="bug533675.uml#_XfUsAEMwEeiEZ5Jtfh6-KA"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Xfg5QkMwEeiEZ5Jtfh6-KA" points="[0, 0, -179, 0]$[179, 0, 0, 0]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XftGgEMwEeiEZ5Jtfh6-KA" id="(0.5,0.15714285714285714)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XfttkEMwEeiEZ5Jtfh6-KA" id="(0.5,0.29515418502202645)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_XgIkUEMwEeiEZ5Jtfh6-KA" type="Message_ReplyEdge" source="_R0X7YEMwEeiEZ5Jtfh6-KA" target="_RZ4XwEMwEeiEZ5Jtfh6-KA">
+ <children xmi:type="notation:DecorationNode" xmi:id="_XgIkU0MwEeiEZ5Jtfh6-KA" type="Message_ReplyNameLabel">
+ <element xmi:type="uml:Message" href="bug533675.uml#_XgGvIEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_XgIkVEMwEeiEZ5Jtfh6-KA" x="1" y="-13"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_XgIkVUMwEeiEZ5Jtfh6-KA" type="Message_ReplyStereotypeLabel">
+ <element xmi:type="uml:Message" href="bug533675.uml#_XgGvIEMwEeiEZ5Jtfh6-KA"/>
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_XgIkVkMwEeiEZ5Jtfh6-KA" x="1" y="-33"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_XgIkUUMwEeiEZ5Jtfh6-KA"/>
+ <styles xmi:type="notation:LineStyle" xmi:id="_XgIkV0MwEeiEZ5Jtfh6-KA"/>
+ <element xmi:type="uml:Message" href="bug533675.uml#_XgGvIEMwEeiEZ5Jtfh6-KA"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_XgIkUkMwEeiEZ5Jtfh6-KA" points="[0, 0, 179, 0]$[-179, 0, 0, 0]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XgJycEMwEeiEZ5Jtfh6-KA" id="(0.5,0.73568281938326)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_XgJycUMwEeiEZ5Jtfh6-KA" id="(0.5,0.3)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_Fj3ykElQEeiMtthmmu-tjQ" type="Message_CreateEdge" source="_RZ4XwEMwEeiEZ5Jtfh6-KA" target="_R0X7YEMwEeiEZ5Jtfh6-KA">
+ <children xmi:type="notation:DecorationNode" xmi:id="_Fj5AsElQEeiMtthmmu-tjQ" type="Message_CreateNameLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Fj5AsUlQEeiMtthmmu-tjQ" x="1" y="-13"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_Fj5AsklQEeiMtthmmu-tjQ" type="Message_CreateStereotypeLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_Fj5As0lQEeiMtthmmu-tjQ" x="1" y="-33"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_Fj3ykUlQEeiMtthmmu-tjQ"/>
+ <styles xmi:type="notation:LineStyle" xmi:id="_Fj5AtElQEeiMtthmmu-tjQ"/>
+ <element xmi:type="uml:Message" href="bug533675.uml#_FjafkElQEeiMtthmmu-tjQ"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_Fj3ykklQEeiMtthmmu-tjQ" points="[0, 0, -179, 0]$[179, 0, 0, 0]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_FkRbMElQEeiMtthmmu-tjQ" id="(0.5,0.07142857142857142)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_FkRbMUlQEeiMtthmmu-tjQ" id="(0.5,0.030837004405286344)"/>
+ </edges>
+ <edges xmi:type="notation:Connector" xmi:id="_NSsfcElQEeiMtthmmu-tjQ" type="Message_DeleteEdge" source="_RZ4XwEMwEeiEZ5Jtfh6-KA" target="_R0X7YEMwEeiEZ5Jtfh6-KA">
+ <children xmi:type="notation:DecorationNode" xmi:id="_NStGgElQEeiMtthmmu-tjQ" type="Message_DeleteNameLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_NStGgUlQEeiMtthmmu-tjQ" x="1" y="-13"/>
+ </children>
+ <children xmi:type="notation:DecorationNode" xmi:id="_NStGgklQEeiMtthmmu-tjQ" type="Message_DeleteStereotypeLabel">
+ <layoutConstraint xmi:type="notation:Location" xmi:id="_NStGg0lQEeiMtthmmu-tjQ" x="1" y="-33"/>
+ </children>
+ <styles xmi:type="notation:FontStyle" xmi:id="_NSsfcUlQEeiMtthmmu-tjQ"/>
+ <styles xmi:type="notation:LineStyle" xmi:id="_NStGhElQEeiMtthmmu-tjQ"/>
+ <element xmi:type="uml:Message" href="bug533675.uml#_NSkjoElQEeiMtthmmu-tjQ"/>
+ <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NSsfcklQEeiMtthmmu-tjQ" points="[0, 0, -176, 0]$[176, 0, 0, 0]"/>
+ <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NS-MQElQEeiMtthmmu-tjQ" id="(0.5,0.38571428571428573)"/>
+ <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NS-MQUlQEeiMtthmmu-tjQ" id="(0.5,1.0000000000000002)"/>
+ </edges>
+</notation:Diagram>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.uml b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.uml
new file mode 100644
index 00000000000..ad52e009a72
--- /dev/null
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug533675.uml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<uml:Model xmi:version="20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001" xmlns:uml="http://www.eclipse.org/uml2/5.0.0/UML" xmi:id="_HWN6cEMwEeiEZ5Jtfh6-KA" name="bug533675">
+ <packageImport xmi:type="uml:PackageImport" xmi:id="_HeHSMEMwEeiEZ5Jtfh6-KA">
+ <importedPackage xmi:type="uml:Model" href="pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#_0"/>
+ </packageImport>
+ <packagedElement xmi:type="uml:Class" xmi:id="_Jqu6wEMwEeiEZ5Jtfh6-KA" name="Foo" classifierBehavior="_POkWwEMwEeiEZ5Jtfh6-KA">
+ <ownedAttribute xmi:type="uml:Property" xmi:id="_LwEPkEMwEeiEZ5Jtfh6-KA" name="a"/>
+ <ownedAttribute xmi:type="uml:Property" xmi:id="_M6OVkEMwEeiEZ5Jtfh6-KA" name="b"/>
+ <ownedBehavior xmi:type="uml:Interaction" xmi:id="_POkWwEMwEeiEZ5Jtfh6-KA" name="DoIt">
+ <lifeline xmi:type="uml:Lifeline" xmi:id="_RZwb8EMwEeiEZ5Jtfh6-KA" name="a" represents="_LwEPkEMwEeiEZ5Jtfh6-KA" coveredBy="_FjjCcElQEeiMtthmmu-tjQ _XfZkgEMwEeiEZ5Jtfh6-KA _XgH9QEMwEeiEZ5Jtfh6-KA _NSlKsElQEeiMtthmmu-tjQ"/>
+ <lifeline xmi:type="uml:Lifeline" xmi:id="_R0URAEMwEeiEZ5Jtfh6-KA" name="b" represents="_M6OVkEMwEeiEZ5Jtfh6-KA" coveredBy="_FjjpgElQEeiMtthmmu-tjQ _XfaLkEMwEeiEZ5Jtfh6-KA _XgHWMEMwEeiEZ5Jtfh6-KA _NSlxwElQEeiMtthmmu-tjQ _Xf7wAEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_FjjCcElQEeiMtthmmu-tjQ" name="create-send" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_FjafkElQEeiMtthmmu-tjQ"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_FjjpgElQEeiMtthmmu-tjQ" name="created" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_FjafkElQEeiMtthmmu-tjQ"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XfZkgEMwEeiEZ5Jtfh6-KA" name="request-send" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_XfUsAEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XfaLkEMwEeiEZ5Jtfh6-KA" name="request-recv" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_XfUsAEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:BehaviorExecutionSpecification" xmi:id="_Xf7wAEMwEeiEZ5Jtfh6-KA" name="exec" covered="_R0URAEMwEeiEZ5Jtfh6-KA" finish="_XgHWMEMwEeiEZ5Jtfh6-KA" start="_XfaLkEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XgHWMEMwEeiEZ5Jtfh6-KA" name="reply-send" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_XgGvIEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_XgH9QEMwEeiEZ5Jtfh6-KA" name="reply-recv" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_XgGvIEMwEeiEZ5Jtfh6-KA"/>
+ <fragment xmi:type="uml:MessageOccurrenceSpecification" xmi:id="_NSlKsElQEeiMtthmmu-tjQ" name="delete-send" covered="_RZwb8EMwEeiEZ5Jtfh6-KA" message="_NSkjoElQEeiMtthmmu-tjQ"/>
+ <fragment xmi:type="uml:DestructionOccurrenceSpecification" xmi:id="_NSlxwElQEeiMtthmmu-tjQ" name="deleted" covered="_R0URAEMwEeiEZ5Jtfh6-KA" message="_NSkjoElQEeiMtthmmu-tjQ"/>
+ <message xmi:type="uml:Message" xmi:id="_FjafkElQEeiMtthmmu-tjQ" name="create" messageSort="createMessage" receiveEvent="_FjjpgElQEeiMtthmmu-tjQ" sendEvent="_FjjCcElQEeiMtthmmu-tjQ"/>
+ <message xmi:type="uml:Message" xmi:id="_XfUsAEMwEeiEZ5Jtfh6-KA" name="request" receiveEvent="_XfaLkEMwEeiEZ5Jtfh6-KA" sendEvent="_XfZkgEMwEeiEZ5Jtfh6-KA"/>
+ <message xmi:type="uml:Message" xmi:id="_XgGvIEMwEeiEZ5Jtfh6-KA" messageSort="reply" receiveEvent="_XgH9QEMwEeiEZ5Jtfh6-KA" sendEvent="_XgHWMEMwEeiEZ5Jtfh6-KA"/>
+ <message xmi:type="uml:Message" xmi:id="_NSkjoElQEeiMtthmmu-tjQ" name="delete" messageSort="deleteMessage" receiveEvent="_NSlxwElQEeiMtthmmu-tjQ" sendEvent="_NSlKsElQEeiMtthmmu-tjQ"/>
+ </ownedBehavior>
+ </packagedElement>
+</uml:Model>
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug535097-OperandsSemantic.notation b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug535097-OperandsSemantic.notation
index 0d9d5c5c8b2..b7fa34edff7 100644
--- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug535097-OperandsSemantic.notation
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/resource/bugs/bug535097-OperandsSemantic.notation
@@ -60,6 +60,7 @@
<owner xmi:type="uml:Model" href="bug535097-OperandsSemantic.uml#_3U8U0F_vEei3wLtnYCLwnw"/>
</styles>
<styles xmi:type="notation:EObjectListValueStyle" xmi:id="_kLDn8F_xEei3wLtnYCLwnw" name="css_stylesheets" eObjectListValue="_kK-IYF_xEei3wLtnYCLwnw"/>
+ <styles xmi:type="notation:BooleanValueStyle" xmi:id="_qplB8G9EEeiGVqCxr7fmEg" name="rulergrid.snaptogrid" booleanValue="false"/>
<element xmi:type="uml:Interaction" href="bug535097-OperandsSemantic.uml#_3XhHsF_vEei3wLtnYCLwnw"/>
<edges xmi:type="notation:Connector" xmi:id="_xGHW4F_2EeiussJ5A9xGlQ" type="Message_AsynchEdge" source="_5ndxEF_vEei3wLtnYCLwnw" target="_5vV6sF_vEei3wLtnYCLwnw">
<children xmi:type="notation:DecorationNode" xmi:id="_xGHW41_2EeiussJ5A9xGlQ" type="Message_AsynchNameLabel">
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/AbstractOperandsTest.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/AbstractOperandsTest.java
index f7cee236512..a116165684e 100644
--- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/AbstractOperandsTest.java
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/AbstractOperandsTest.java
@@ -13,24 +13,9 @@
package org.eclipse.papyrus.uml.diagram.sequence.tests.bug;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Objects;
-
-import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.requests.CreateUnspecifiedTypeRequest;
-import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
import org.eclipse.papyrus.junit.framework.classification.tests.AbstractPapyrusTest;
import org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture;
import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes;
@@ -120,46 +105,7 @@ public abstract class AbstractOperandsTest extends AbstractPapyrusTest {
Assert.assertEquals(expectedCoverage, operand.getFragments().contains(fragment));
}
- // Don't use editor.createShape(), because we need a special type of request to create operands.
- // The "InsertAt" behavior will only be computed if we use a CreateUnspecifiedTypeRequest (From the palette)
- // and target an Operand. The Operand will then be responsible for setting the InsertAt parameter
- // and delegate to the CombinedFragment compartment for the actual creation
- protected GraphicalEditPart createOperand(IGraphicalEditPart targetVisualPart, Point location) {
- CreateUnspecifiedTypeRequest request = new CreateUnspecifiedTypeRequest(Collections.singletonList(UMLElementTypes.InteractionOperand_Shape), targetVisualPart.getDiagramPreferencesHint());
-
- request.setLocation(location);
-
- EditPart target = targetVisualPart.getTargetEditPart(request);
- assertThat("No target edit part", target, notNullValue());
- org.eclipse.gef.commands.Command command = target.getCommand(request);
- editor.execute(command);
-
- // Find the new edit-part
- Object result = request.getNewObject();
- Assert.assertThat(result, instanceOf(Collection.class));
- Collection<?> results = (Collection<?>) result;
- return results.stream()
- .filter(ViewDescriptor.class::isInstance).map(ViewDescriptor.class::cast)
- .map(desc -> desc.getAdapter(View.class)).map(View.class::cast)
- .filter(Objects::nonNull)
- .map(view -> DiagramEditPartsUtil.getEditPartFromView(view, targetVisualPart))
- .filter(GraphicalEditPart.class::isInstance).map(GraphicalEditPart.class::cast)
- .filter(Objects::nonNull)
- .findAny().orElseThrow(() -> new IllegalStateException("Could not find new shape edit-part"));
- }
-
- // Convert a point that is relative to the given part to a point relative to the current Viewport (Taking zoom & translate into account).
- // This can be used to get a "Mouse Location" to configure Requests
- protected static Point at(int x, int y, IGraphicalEditPart relativeTo) {
- Point at = new Point(x, y);
-
- IFigure figure = relativeTo.getContentPane();
- Point layoutOrigin = figure.getClientArea().getLocation();
-
- at.performTranslate(layoutOrigin.x, layoutOrigin.y);
- figure.translateToParent(at);
- figure.translateToAbsolute(at);
-
- return at;
+ protected IGraphicalEditPart createOperand(Point location) {
+ return editor.createShape(UMLElementTypes.InteractionOperand_Shape, location, null);
}
}
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java
index ec9a97b5626..a03d57392eb 100644
--- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/CombinedFragmentRegressionTest.java
@@ -92,6 +92,8 @@ import org.eclipse.uml2.uml.UMLPackage;
import org.hamcrest.CoreMatchers;
import org.hamcrest.CustomTypeSafeMatcher;
import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
@@ -131,6 +133,22 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest {
}
/**
+ * Before test initialization with preference initialization.
+ */
+ @Before
+ public void init() {
+ UMLDiagramEditorPlugin.getInstance().getPreferenceStore().setValue(CustomDiagramGeneralPreferencePage.PREF_TRIGGER_ASYNC_VALIDATION, true);
+ }
+
+ /**
+ * After test with preference modification.
+ */
+ @After
+ public void cleanUp() {
+ UMLDiagramEditorPlugin.getInstance().getPreferenceStore().setValue(CustomDiagramGeneralPreferencePage.PREF_TRIGGER_ASYNC_VALIDATION, false);
+ }
+
+ /**
* Verify the creation and extent of a default interaction operand in a newly
* created combined fragment.
*/
@@ -394,7 +412,7 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest {
GraphicalEditPart lifelineEP = (GraphicalEditPart) editor.findEditPart("a", Lifeline.class);
// Null size to just drop the tool
- GraphicalEditPart combinedFragmentEP = (GraphicalEditPart) editor.createShape(lifelineEP, UMLElementTypes.CombinedFragment_Shape, at(80, 80), null);
+ GraphicalEditPart combinedFragmentEP = editor.createShape(lifelineEP, UMLElementTypes.CombinedFragment_Shape, at(80, 80), null);
Consumer<GraphicalEditPart> verifyCFrag = cfragEP -> {
assertThat(cfragEP, DiagramMatchers.semanticThat(instanceOf(CombinedFragment.class)));
@@ -429,7 +447,7 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest {
GraphicalEditPart bEP = (GraphicalEditPart) editor.findEditPart("b", Lifeline.class);
GraphicalEditPart interactionCompartment = (GraphicalEditPart) aEP.getParent();
- GraphicalEditPart combinedFragmentEP = (GraphicalEditPart) editor.createShape(
+ GraphicalEditPart combinedFragmentEP = editor.createShape(
interactionCompartment, UMLElementTypes.CombinedFragment_Shape,
at(25, 80), sized(360, 200));
@@ -470,7 +488,7 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest {
EditPart combinedFragmentEP = editor.findEditPart("cfrag", CombinedFragment.class);
assumeThat("Combined fragment not found", combinedFragmentEP, notNullValue());
- GraphicalEditPart interactionOperandEP = (GraphicalEditPart) editor.createShape(
+ GraphicalEditPart interactionOperandEP = editor.createShape(
lifelineEP, UMLElementTypes.InteractionOperand_Shape,
at(80, 80), null); // Null rectangle for the default size
@@ -513,7 +531,7 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest {
EditPart combinedFragmentEP = editor.findEditPart("cfrag", CombinedFragment.class);
assumeThat("Combined fragment not found", combinedFragmentEP, notNullValue());
- GraphicalEditPart interactionOperandEP = (GraphicalEditPart) editor.createShape(
+ GraphicalEditPart interactionOperandEP = editor.createShape(
aEP, UMLElementTypes.InteractionOperand_Shape,
at(80, 80), sized(220, 120)); // Extend to a point within lifeline b
@@ -874,6 +892,76 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest {
assertThat(operandEP, not(hasWarningDecorationThat(startsWith("Lifeline"))));
}
+ /**
+ * Verify the creation of a combined fragment that covers nothing at all.
+ */
+ @Test
+ @PluginResource("resource/bugs/bug533675.di")
+ public void createCFragInFreeSpace_533675() {
+ EditPart interactionEP = editor.findEditPart("DoIt", Interaction.class);
+ EditPart interactionCompartment = editor.getShapeCompartment(interactionEP);
+
+ GraphicalEditPart cfragEP = editor.createShape(interactionCompartment,
+ UMLElementTypes.CombinedFragment_Shape,
+ at(400, 80), sized(80, 80));
+ GraphicalEditPart lifelineEP = (GraphicalEditPart) editor.findEditPart("b", Lifeline.class);
+
+ Rectangle cfragBounds = cfragEP.getFigure().getBounds();
+ Rectangle lifelineBounds = lifelineEP.getFigure().getBounds();
+ Rectangle intersection = cfragBounds.getIntersection(lifelineBounds);
+
+ assertThat("Combined fragment is in the wrong place", intersection,
+ is(new Rectangle(0, 0, 0, 0)));
+ }
+
+ /**
+ * Verify the creation of a combined fragment that only partially
+ * covers a message.
+ */
+ @Test
+ @PluginResource("resource/bugs/bug533675.di")
+ public void createCFragOverHalfMessage_533675() {
+ EditPart interactionEP = editor.findEditPart("DoIt", Interaction.class);
+ EditPart interactionCompartment = editor.getShapeCompartment(interactionEP);
+
+ GraphicalEditPart cfragEP = editor.createShape(interactionCompartment,
+ UMLElementTypes.CombinedFragment_Shape,
+ at(15, 60), sized(140, 140));
+
+ // TODO: Assert that the message crosses an interaction operand boundary
+ // when the diagram is able to update the combined fragment ownership in
+ // an undo-safe way using proper commands, not reacting post execution
+ GraphicalEditPart messageEP = (GraphicalEditPart) editor.findEditPart("create", Message.class);
+ // assertThat(messageEP, hasErrorDecorationThat(startsWith("Message crosses")));
+
+ Rectangle cfragBounds = cfragEP.getFigure().getBounds();
+ Rectangle messageBounds = messageEP.getFigure().getBounds();
+ Rectangle intersection = cfragBounds.getIntersection(messageBounds);
+ assertThat("Combined fragment does not overlap message", intersection,
+ not(new Rectangle(0, 0, 0, 0)));
+ }
+
+ /**
+ * Verify the creation of a combined fragment within a combined fragment.
+ */
+ @Test
+ @PluginResource("resource/bugs/bug533683.di")
+ public void createCFragInCFrag_533675() {
+ EditPart topOperandEP = editor.findEditPart("alt1", InteractionOperand.class);
+ GraphicalEditPart lifelineEP = (GraphicalEditPart) editor.findEditPart("a", Lifeline.class);
+
+ GraphicalEditPart cfragEP = editor.createShape(topOperandEP,
+ UMLElementTypes.CombinedFragment_Shape,
+ at(40, 100), sized(140, 160));
+
+ Rectangle cfragBounds = cfragEP.getFigure().getBounds();
+ Rectangle lifelineBounds = lifelineEP.getFigure().getBounds();
+ Rectangle intersection = cfragBounds.getIntersection(lifelineBounds);
+
+ assertThat("Combined fragment does not span lifeline", intersection.width(),
+ is(lifelineBounds.width()));
+ }
+
//
// Test framework
//
@@ -889,7 +977,7 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest {
/**
* Work around the absence of an {@code equals} method in the {@link PointList} class.
- *
+ *
* @param geometry
* a geometry to test for equality with an actual observed geometry
* @return the geometry matcher
@@ -909,10 +997,10 @@ public class CombinedFragmentRegressionTest extends AbstractPapyrusTest {
/**
* Query the geometry of an interaction element in the diagram.
- *
+ *
* @param interactionElement
* an interaction element (interaction fragment or message)
- *
+ *
* @return its geometry, either a {@link Rectangle}, {@link PointList}, or {@code null}
* for elements that have no geometry of their own but would be implied by others (such
* as execution occurrences)
diff --git a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/TestCFOperandsSemanticCoverage.java b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/TestCFOperandsSemanticCoverage.java
index 96da06a737c..704d7a3ea26 100644
--- a/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/TestCFOperandsSemanticCoverage.java
+++ b/tests/junit/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence.tests/src/org/eclipse/papyrus/uml/diagram/sequence/tests/bug/TestCFOperandsSemanticCoverage.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2018 EclipseSource and others.
+ * Copyright (c) 2018 EclipseSource, Christian W. Damus, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,10 +8,13 @@
*
* Contributors:
* EclipseSource - Initial API and implementation
+ * Christian W. Damus - bug 533675
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.sequence.tests.bug;
+import static org.eclipse.papyrus.junit.utils.rules.PapyrusEditorFixture.at;
+
import java.util.Collections;
import org.eclipse.draw2d.PositionConstants;
@@ -151,7 +154,7 @@ public class TestCFOperandsSemanticCoverage extends AbstractOperandsTest {
@Test
public void testCreateOperand() {
- IGraphicalEditPart operand2Part = createOperand(operandPart, at(200, 100, cfPart)); // Between Message10 and Message11
+ IGraphicalEditPart operand2Part = createOperand(at(200, 100, cfPart)); // Between Message10 and Message11
// Covered by the first operand
assertCovered(message10, operandPart);
@@ -203,7 +206,7 @@ public class TestCFOperandsSemanticCoverage extends AbstractOperandsTest {
public void testDeleteOperand() {
// Create a new operand, delete the first one, and check that the new
// one covers everything that was initially covered by the first
- IGraphicalEditPart operand2Part = createOperand(operandPart, at(200, 100, cfPart)); // Between Message10 and Message11
+ IGraphicalEditPart operand2Part = createOperand(at(200, 100, cfPart)); // Between Message10 and Message11
editor.delete(operandPart);
assertCovered(message10, operand2Part);
@@ -221,9 +224,9 @@ public class TestCFOperandsSemanticCoverage extends AbstractOperandsTest {
editor.execute(cfPart.getCommand(request));
// Create some operands every 100px
- IGraphicalEditPart operand3Part = createOperand(operand2Part, at(200, 100, cfPart)); // Between Message10 and Message11
- IGraphicalEditPart operand4Part = createOperand(operand3Part, at(150, 200, cfPart)); // Between Exec1 and Exec2
- IGraphicalEditPart operand5Part = createOperand(operand4Part, at(75, 300, cfPart)); // Middle of exec 2, below Message12
+ IGraphicalEditPart operand3Part = createOperand(at(200, 100, cfPart)); // Between Message10 and Message11
+ IGraphicalEditPart operand4Part = createOperand(at(150, 200, cfPart)); // Between Exec1 and Exec2
+ IGraphicalEditPart operand5Part = createOperand(at(75, 300, cfPart)); // Middle of exec 2, below Message12
// Before deleting, make sure everything is what we expect...
assertCovered(message10, operand2Part);
@@ -280,9 +283,9 @@ public class TestCFOperandsSemanticCoverage extends AbstractOperandsTest {
editor.execute(cfPart.getCommand(request));
// ...and create some operands...
- IGraphicalEditPart operand2Part = createOperand(operandPart, at(200, 100, cfPart)); // Between Message10 and Message11
- IGraphicalEditPart operand3Part = createOperand(operand2Part, at(150, 200, cfPart)); // Between Exec1 and Exec2
- IGraphicalEditPart operand4Part = createOperand(operand3Part, at(75, 300, cfPart)); // Middle of exec 2, below Message12
+ IGraphicalEditPart operand2Part = createOperand(at(200, 100, cfPart)); // Between Message10 and Message11
+ IGraphicalEditPart operand3Part = createOperand(at(150, 200, cfPart)); // Between Exec1 and Exec2
+ IGraphicalEditPart operand4Part = createOperand(at(75, 300, cfPart)); // Middle of exec 2, below Message12
// ...Check the initial state...
assertCovered(message10, operandPart);
@@ -338,5 +341,4 @@ public class TestCFOperandsSemanticCoverage extends AbstractOperandsTest {
assertCoverage(getSend(message12), getOperand(operand4Part), true);
assertCoverage(getFinish(exec2), getOperand(operand4Part), true);
}
-
}

Back to the top