| /******************************************************************************* |
| * Copyright (c) 2020, 2021 Obeo. |
| * All rights reserved. |
| * |
| * Contributors: |
| * Obeo - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.sirius.tests.unit.diagram.layout; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ListIterator; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Optional; |
| |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.draw2d.Connection; |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.Label; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.PointList; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.gef.ConnectionEditPart; |
| import org.eclipse.gef.EditPart; |
| import org.eclipse.gef.RequestConstants; |
| import org.eclipse.gef.requests.ChangeBoundsRequest; |
| import org.eclipse.gef.rulers.RulerProvider; |
| import org.eclipse.gef.tools.ToolUtilities; |
| import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.figures.ResizableCompartmentFigure; |
| import org.eclipse.gmf.runtime.diagram.ui.internal.properties.WorkspaceViewerProperties; |
| import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor; |
| import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer; |
| import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart; |
| import org.eclipse.gmf.runtime.diagram.ui.render.util.DiagramImageUtils; |
| import org.eclipse.gmf.runtime.diagram.ui.requests.ArrangeRequest; |
| import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx; |
| import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel; |
| import org.eclipse.gmf.runtime.draw2d.ui.geometry.LineSeg; |
| import org.eclipse.gmf.runtime.draw2d.ui.geometry.PointListUtilities; |
| import org.eclipse.gmf.runtime.draw2d.ui.internal.figures.AnimatableScrollPane; |
| import org.eclipse.gmf.runtime.notation.Bounds; |
| import org.eclipse.gmf.runtime.notation.Diagram; |
| import org.eclipse.gmf.runtime.notation.LayoutConstraint; |
| import org.eclipse.gmf.runtime.notation.Location; |
| import org.eclipse.gmf.runtime.notation.Node; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.sirius.common.tools.internal.resource.ResourceSyncClientNotifier; |
| import org.eclipse.sirius.diagram.DDiagram; |
| import org.eclipse.sirius.diagram.DDiagramElement; |
| import org.eclipse.sirius.diagram.DNode; |
| import org.eclipse.sirius.diagram.DNodeContainer; |
| import org.eclipse.sirius.diagram.DNodeList; |
| import org.eclipse.sirius.diagram.DNodeListElement; |
| import org.eclipse.sirius.diagram.tools.api.preferences.SiriusDiagramPreferencesKeys; |
| import org.eclipse.sirius.diagram.tools.internal.commands.PinElementsCommand; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramBorderNodeEditPart; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramContainerEditPart; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramListEditPart; |
| import org.eclipse.sirius.diagram.ui.edit.api.part.IDiagramContainerEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeContainerCompartmentEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.edit.parts.DEdgeEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeListElementEditPart; |
| import org.eclipse.sirius.diagram.ui.internal.operation.ResetOriginChangeModelOperation; |
| import org.eclipse.sirius.diagram.ui.tools.api.editor.DDiagramEditor; |
| import org.eclipse.sirius.diagram.ui.tools.api.graphical.edit.styles.IBorderItemOffsets; |
| import org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutUtils; |
| import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.IContainerLabelOffsets; |
| import org.eclipse.sirius.ext.gmf.runtime.gef.ui.figures.SiriusWrapLabel; |
| import org.eclipse.sirius.tests.SiriusTestsPlugin; |
| import org.eclipse.sirius.tests.support.api.EclipseTestsSupportHelper; |
| import org.eclipse.sirius.tests.support.api.SiriusDiagramTestCase; |
| import org.eclipse.sirius.tests.support.api.TestsUtil; |
| import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager; |
| import org.eclipse.sirius.ui.business.api.session.SessionUIManager; |
| import org.eclipse.sirius.viewpoint.DRepresentation; |
| import org.eclipse.ui.IEditorPart; |
| |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Lists; |
| |
| /** |
| * Tests to realize some verification of arrange result with basic ELK layouts. |
| * |
| * @author lredor |
| */ |
| @SuppressWarnings("restriction") |
| public class SimpleELKLayoutTest extends SiriusDiagramTestCase { |
| private static final String PATH = "/data/unit/layout/withELK/"; |
| |
| private static final String PATH_REPLACE = "/data/unit/layout/withELK/replace/"; |
| |
| private static final String VSM_RESOURCE_NAME = "My.odesign"; |
| |
| private static final String SEMANTIC_RESOURCE_NAME = "My.ecore"; |
| |
| private static final String REPRESENTATIONS_RESOURCE_NAME = "representations.aird"; |
| |
| private DDiagram diagram; |
| |
| private IDiagramWorkbenchPart editorPart; |
| |
| private boolean initialSnapToGridValue; |
| |
| private double initialGridSpacingValue; |
| |
| private int initialRulerUnitValue; |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| |
| EclipseTestsSupportHelper.INSTANCE.copyFile(SiriusTestsPlugin.PLUGIN_ID + PATH + VSM_RESOURCE_NAME, "/" + TEMPORARY_PROJECT_NAME + "/" + VSM_RESOURCE_NAME); |
| EclipseTestsSupportHelper.INSTANCE.copyFile(SiriusTestsPlugin.PLUGIN_ID + PATH + SEMANTIC_RESOURCE_NAME, "/" + TEMPORARY_PROJECT_NAME + "/" + SEMANTIC_RESOURCE_NAME); |
| EclipseTestsSupportHelper.INSTANCE.copyFile(SiriusTestsPlugin.PLUGIN_ID + PATH + REPRESENTATIONS_RESOURCE_NAME, "/" + TEMPORARY_PROJECT_NAME + "/" + REPRESENTATIONS_RESOURCE_NAME); |
| |
| genericSetUp("/" + TEMPORARY_PROJECT_NAME + "/" + SEMANTIC_RESOURCE_NAME, "/" + TEMPORARY_PROJECT_NAME + "/" + VSM_RESOURCE_NAME, |
| "/" + TEMPORARY_PROJECT_NAME + "/" + REPRESENTATIONS_RESOURCE_NAME); |
| |
| SessionUIManager.INSTANCE.createUISession(session); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| if (editorPart != null) { |
| SessionUIManager.INSTANCE.getUISession(session).closeEditors(false, Collections.singleton((DDiagramEditor) editorPart)); |
| } |
| TestsUtil.emptyEventsFromUIThread(); |
| super.tearDown(); |
| } |
| |
| /** |
| * Makes sure that activating the Snap to grid has no effect on the ELK layout. |
| */ |
| public void testArrangeWithSnapToWithELK() { |
| // We create a new diagram |
| EObject root = session.getSemanticResources().stream().findFirst().get().getContents().get(0); |
| DRepresentation representation = createRepresentation("SimpleDiagram", root); |
| // We open the editor and set the preferences for the test. |
| IEditorPart newEditorPart = DialectUIManager.INSTANCE.openEditor(session, representation, new NullProgressMonitor()); |
| IPreferenceStore workspaceViewerPreferenceStore = ((DiagramGraphicalViewer) ((DiagramEditor) newEditorPart).getDiagramGraphicalViewer()).getWorkspaceViewerPreferenceStore(); |
| changeSnapToPreferences(workspaceViewerPreferenceStore); |
| try { |
| arrangeAll((DiagramEditor) newEditorPart); |
| TestsUtil.synchronizationWithUIThread(); |
| // We keep the figures bounds after the arrange all without the Snap to grid. |
| Map<DNode, Rectangle> DNodes2Bounds = computeNodesBounds(representation); |
| // We activate the Snap to Grid. |
| workspaceViewerPreferenceStore.setValue(WorkspaceViewerProperties.SNAPTOGRID, true); |
| // We perform the arrange all again. |
| arrangeAll((DiagramEditor) newEditorPart); |
| TestsUtil.synchronizationWithUIThread(); |
| // We check that the layout did not change |
| Map<DNode, Rectangle> afterDNodes2Bounds = computeNodesBounds(representation); |
| afterDNodes2Bounds.forEach((dNode, rect) -> { |
| assertEquals("The layout should not change after having activated the snap to grid with ELK algorithm.", DNodes2Bounds.get(dNode), rect); |
| }); |
| } finally { |
| restoreInitilaPreferences(workspaceViewerPreferenceStore); |
| } |
| } |
| |
| /** |
| * Makes sure that activating the Snap to grid has effect on diagram without ELK algorithm |
| */ |
| public void testArrangeWithSnapToWithoutELK() { |
| // We create a new diagram |
| EObject root = session.getSemanticResources().stream().findFirst().get().getContents().get(0); |
| DRepresentation representation = createRepresentation("SimpleDiagramNoELK", root); |
| // We open the editor and set the preferences for the test. |
| IEditorPart newEditorPart = DialectUIManager.INSTANCE.openEditor(session, representation, new NullProgressMonitor()); |
| IPreferenceStore workspaceViewerPreferenceStore = ((DiagramGraphicalViewer) ((DiagramEditor) newEditorPart).getDiagramGraphicalViewer()).getWorkspaceViewerPreferenceStore(); |
| changeSnapToPreferences(workspaceViewerPreferenceStore); |
| try { |
| arrangeAll((DiagramEditor) newEditorPart); |
| TestsUtil.synchronizationWithUIThread(); |
| // We keep the figures bounds after the arrange all without the Snap to grid. |
| Map<DNode, Rectangle> dNodes2Bounds = computeNodesBounds(representation); |
| // We activate the Snap to Grid. |
| workspaceViewerPreferenceStore.setValue(WorkspaceViewerProperties.SNAPTOGRID, true); |
| // We perform the arrange all again. |
| arrangeAll((DiagramEditor) newEditorPart); |
| TestsUtil.synchronizationWithUIThread(); |
| // We check that the layout has changed |
| Map<DNode, Rectangle> afterDNodes2Bounds = computeNodesBounds(representation); |
| boolean atLeastOneElementHasChanged = false; |
| for (Iterator<Entry<DNode, Rectangle>> iterator = afterDNodes2Bounds.entrySet().iterator(); iterator.hasNext();) { |
| Entry<DNode, Rectangle> dNodeToRect = iterator.next(); |
| if (!dNodeToRect.getValue().equals(dNodes2Bounds.get(dNodeToRect.getKey()))) { |
| atLeastOneElementHasChanged = true; |
| break; |
| } |
| } |
| assertTrue("The activation of the Snap to grid should have changed the layout", atLeastOneElementHasChanged); |
| } finally { |
| restoreInitilaPreferences(workspaceViewerPreferenceStore); |
| } |
| } |
| |
| /** |
| * Check that the size of a Node under the root (under the diagram), is sufficiently large to read the label. |
| */ |
| public void testSizeOfRootNode() { |
| openDiagram("simpleDiagram"); |
| |
| Optional<DDiagramElement> c1Dde = diagram.getDiagramElements().stream().filter(dde -> dde.getName().equals("MyClass1")).findFirst(); |
| assertTrue("The diagram should have a node named \"MyClass1\".", c1Dde.isPresent()); |
| IGraphicalEditPart c1EditPart = getEditPart(c1Dde.get()); |
| assertTrue("The node for \"MyClass1\" should be a DNodeEditPart.", c1EditPart instanceof DNodeEditPart); |
| Dimension minimumTextSize = ((DNodeEditPart) c1EditPart).getNodeLabel().getPreferredSize(); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Check that the new Size is bigger than the minimum size to display the text |
| Dimension c1Dimension = c1EditPart.getFigure().getSize(); |
| assertTrue("The size of \"MyClass1\" should be sufficiently large to read the label (minimul label size is " + minimumTextSize + " and node size is " + c1Dimension + ".", |
| c1Dimension.contains(minimumTextSize)); |
| } |
| |
| /** |
| * Check that the Note is moved with an arrange using ELK, when the preference "Move unlinked notes during layout" |
| * is enabled. |
| * |
| * @throws Exception |
| * in case of problem |
| */ |
| public void testNoteLayoutWithPrefTrue() throws Exception { |
| testNoteLayoutAccordingToPref(true); |
| } |
| |
| /** |
| * Check that the Note is not moved with an arrange using ELK, when the preference "Move unlinked notes during |
| * layout" is disabled. |
| * |
| * @throws Exception |
| * in case of problem |
| */ |
| public void testNoteLayoutWithPrefFalse() throws Exception { |
| testNoteLayoutAccordingToPref(false); |
| } |
| |
| /** |
| * Check that the size of a Note is the same before and after an arrange. |
| */ |
| @SuppressWarnings("rawtypes") |
| public void testNoteHaveFixedSizeAfterLayout() { |
| openDiagram("simpleDiagramWithNote"); |
| |
| // Get the GMF node corresponding to the Note |
| Node noteNode = getNote(editorPart.getDiagram()); |
| assertTrue("One note should exist on the diagram", noteNode != null); |
| |
| // Get the corresponding edit part |
| Map editPartRegistry = editorPart.getDiagramEditPart().getRoot().getViewer().getEditPartRegistry(); |
| final IGraphicalEditPart noteEditPart = (IGraphicalEditPart) editPartRegistry.get(noteNode); |
| |
| // Get the initial note bounds (to be compare to the new bounds after the layout) |
| final Rectangle initialNoteBounds = noteEditPart.getFigure().getBounds().getCopy(); |
| |
| changeDiagramPreference(SiriusDiagramPreferencesKeys.PREF_MOVE_NOTES_DURING_LATOUT.name(), true); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Check that the Note has been moved during the arrange |
| Rectangle currentNoteBounds = noteEditPart.getFigure().getBounds().getCopy(); |
| assertFalse("The Note should be moved during the arrange.", initialNoteBounds.getLocation().equals(currentNoteBounds.getLocation())); |
| |
| // Check that the size of the Note is the same after the arrange |
| assertEquals("The Note should have the same size before and after the arrange.", initialNoteBounds.getSize(), (currentNoteBounds.getSize())); |
| } |
| |
| /** |
| * Check that the size of a Text is the same before and after an arrange. |
| */ |
| @SuppressWarnings("rawtypes") |
| public void testTextHaveFixedSizeAfterLayout() { |
| openDiagram("simpleDiagramWithText"); |
| |
| // Get the GMF node corresponding to the Note |
| Node textNode = getText(editorPart.getDiagram()); |
| assertTrue("One test should exist on the diagram", textNode != null); |
| |
| // Get the corresponding edit part |
| Map editPartRegistry = editorPart.getDiagramEditPart().getRoot().getViewer().getEditPartRegistry(); |
| final IGraphicalEditPart textEditPart = (IGraphicalEditPart) editPartRegistry.get(textNode); |
| |
| // Get the initial text bounds (to be compare to the new bounds after the layout) |
| final Rectangle initialTextBounds = textEditPart.getFigure().getBounds().getCopy(); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Check that the Text has been moved during the arrange |
| Rectangle currentTextBounds = textEditPart.getFigure().getBounds().getCopy(); |
| assertFalse("The Text should be moved during the arrange.", initialTextBounds.getLocation().equals(currentTextBounds.getLocation())); |
| |
| // Check that the size of the Note is the same after the arrange |
| assertEquals("The Text should have the same size before and after the arrange.", initialTextBounds.getSize(), currentTextBounds.getSize()); |
| } |
| |
| /** |
| * Check that the location of the label is centered under the bottom side of its border node. |
| */ |
| public void testLocationOfLabelOnBorderOnBorderNode() { |
| openDiagram("diagramWithBorderNodesWithLabelOnBorder"); |
| |
| Optional<DDiagramElement> dde = diagram.getDiagramElements().stream().filter(ode -> ode.getName().equals("att1")).findFirst(); |
| assertTrue("The diagram should have a node named \"att1\".", dde.isPresent()); |
| IGraphicalEditPart portEditPart = getEditPart(dde.get()); |
| assertTrue("The node for \"att1\" should be a AbstractDiagramBorderNodeEditPart but was a " + portEditPart.getClass().getSimpleName(), |
| portEditPart instanceof AbstractDiagramBorderNodeEditPart); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| Rectangle borderNodeBounds = portEditPart.getFigure().getBounds().getCopy(); |
| |
| // Check the label location |
| boolean labelFound = false; |
| for (Object portChildObj : portEditPart.getChildren()) { |
| if (portChildObj instanceof IGraphicalEditPart) { |
| IFigure labelFigure = ((IGraphicalEditPart) portChildObj).getFigure(); |
| String text = null; |
| if (labelFigure instanceof WrappingLabel) { |
| text = ((WrappingLabel) labelFigure).getText(); |
| } else if (labelFigure instanceof Label) { |
| text = ((Label) labelFigure).getText(); |
| } else if (labelFigure instanceof SiriusWrapLabel) { |
| SiriusWrapLabel label = (SiriusWrapLabel) labelFigure; |
| text = label.getText(); |
| } |
| |
| if (text != null) { |
| labelFound = true; |
| Rectangle labelBounds = labelFigure.getBounds(); |
| assertEquals("The label of the border node is visually not horizontally centered on its border node (draw2d x coordinate).", labelBounds.getCenter().x(), |
| borderNodeBounds.getCenter().x()); |
| assertEquals("The label of the border node is visually not under the bottom side of its border node (draw2d y coordinate).", labelBounds.getTop().y(), |
| borderNodeBounds.getBottom().y() + 1); |
| assertTrue(((IGraphicalEditPart) portChildObj).getModel() instanceof Node); |
| Node labelNode = (Node) ((IGraphicalEditPart) portChildObj).getModel(); |
| Location gmfLabelLocation = (Location) labelNode.getLayoutConstraint(); |
| assertEquals("The x GMF coordinate of the label of the border node does not correspond to a centered location.", -(labelBounds.width() - borderNodeBounds.width()) / 2, |
| gmfLabelLocation.getX(), 1); |
| assertEquals("The y GMF coordinate of the label of the border node does not correspond to a location under its border node.", borderNodeBounds.height() + 1, |
| gmfLabelLocation.getY()); |
| } |
| } |
| if (!labelFound) { |
| fail("The label of the border node has not been found."); |
| } |
| } |
| |
| } |
| |
| /** |
| * Check that the height of a ListContainer is sufficient to display the list items (when list items are only icons |
| * without text). |
| */ |
| public void testListContainerWithIconListItemsLayout() { |
| openDiagram("diagramWithListWithIconListItems"); |
| |
| // Check for a list in the diagram |
| checkForListContainerWithIconListItems("L_MyClass1"); |
| // Check for a list in a container |
| checkForListContainerWithIconListItems("MyClass1"); |
| } |
| |
| private void checkForListContainerWithIconListItems(String listName) { |
| Optional<DDiagramElement> dde = diagram.getDiagramElements().stream().filter(ode -> ode.getName().equals(listName)).findFirst(); |
| assertTrue("The diagram should have a node named \"" + listName + "\".", dde.isPresent()); |
| IGraphicalEditPart editPart = getEditPart(dde.get()); |
| assertTrue("The node for \"" + listName + "\" should be a AbstractDiagramListEditPart but was a " + editPart.getClass().getSimpleName(), editPart instanceof AbstractDiagramListEditPart); |
| |
| assertEquals("Wrong number of list items, the list should contain 3 list items.", 3, ((DNodeList) dde.get()).getOwnedElements().stream().count()); |
| |
| Dimension listItemSize = getEditPart(((DNodeList) dde.get()).getOwnedElements().get(0)).getFigure().getSize(); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| Dimension listSize = editPart.getFigure().getSize(); |
| |
| assertTrue("The height of the list should be at least bigger that thrice the size of a list item + 20 pixels for the title. Expected more than " + (20 + (3 * listItemSize.height())) |
| + " but was " + listSize.height(), listSize.height() > (20 + (3 * listItemSize.height()))); |
| } |
| |
| /** |
| * Check that the size of a ListContainer is OK: |
| * <UL> |
| * <LI>Size is long enough to avoid wrap label of list items</LI> |
| * <LI>Incoming edges have no bendpoint</LI> |
| * <LI>Size if not too big</LI> |
| * </UL> |
| */ |
| public void testListContainerLayout() { |
| openDiagram("diagramWithList"); |
| |
| Optional<DDiagramElement> c2Dde = diagram.getDiagramElements().stream().filter(dde -> dde.getName().equals("MyClass2")).findFirst(); |
| assertTrue("The diagram should have a node named \"MyClass2\".", c2Dde.isPresent()); |
| IGraphicalEditPart c2EditPart = getEditPart(c2Dde.get()); |
| assertTrue("The node for \"MyClass2\" should be a DNodeListEditPart.", c2EditPart instanceof DNodeListEditPart); |
| |
| Optional<DNodeListElement> listItem = ((DNodeList) c2Dde.get()).getOwnedElements().stream().filter(dde -> dde.getName().equals("listItemWithALongName")).findFirst(); |
| assertTrue("The container \"MyClass2\" should have a list item named \"listItemWithALongName\".", listItem.isPresent()); |
| IGraphicalEditPart listItemEditPart = getEditPart(listItem.get()); |
| assertTrue("The node for \"listItemWithALongName\" should be a DNodeListElementEditPart.", listItemEditPart instanceof DNodeListElementEditPart); |
| int expectedOneLineHeight = ((DNodeListElementEditPart) listItemEditPart).getFigure().getSize().height(); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Check that the new size of list item is sufficiently large to display the label without wrapping. |
| assertEquals("The list item should be on one line (with one line height)", expectedOneLineHeight, ((DNodeListElementEditPart) listItemEditPart).getFigure().getSize().height()); |
| |
| // Check that the new size of the list if not too big (around 2x the size of one line height : a delta of 20 |
| // pixels for all margins). |
| assertEquals("The list should not be too high (arround 2x the size of one line height)", 2 * expectedOneLineHeight, c2EditPart.getFigure().getSize().height(), 20); |
| |
| // Check that incoming edge has only 2 points (ie without intermediate bendpoints) |
| assertEquals("The container \"MyClass2\" should have one incoming edge", 1, c2EditPart.getTargetConnections().size()); |
| assertTrue("The container \"MyClass2\" should have one incoming edge of kind DEdgeEditPart", c2EditPart.getTargetConnections().get(0) instanceof DEdgeEditPart); |
| DEdgeEditPart edgeEditPart = (DEdgeEditPart) c2EditPart.getTargetConnections().get(0); |
| assertTrue("The edge figure should be a PolylineConnectionEx", edgeEditPart.getFigure() instanceof PolylineConnectionEx); |
| assertEquals("The edge should have only 2 points (ie without intermediate bendpoints)", 2, ((PolylineConnectionEx) edgeEditPart.getFigure()).getPoints().size()); |
| } |
| |
| /** |
| * Check that the size of an empty ListContainer without title is OK (ie same size as default Sirius Size : 40x40). |
| */ |
| public void testEmptyListContainerMinimalSizeLayout() { |
| openDiagram("diagramWithEmptyListWithoutTitle"); |
| |
| Optional<DDiagramElement> dde = diagram.getDiagramElements().stream().findFirst(); |
| assertTrue("The diagram should have at least one node.", dde.isPresent()); |
| IGraphicalEditPart editPart = getEditPart(dde.get()); |
| assertTrue("The first node should be a DNodeListEditPart.", editPart instanceof DNodeListEditPart); |
| |
| assertEquals("Wrong number of list items, the list should be empty.", 0, ((DNodeList) dde.get()).getOwnedElements().stream().count()); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Check that the new size is the default one |
| // (org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramElementContainerEditPart.getDefaultDimension(DDiagramElement) |
| // ie LayoutUtils.NEW_DEFAULT_CONTAINER_DIMENSION. |
| assertEquals("The width of the list should be the default Sirius one (to have a minimal size for empty list)", LayoutUtils.NEW_DEFAULT_CONTAINER_DIMENSION.width, |
| ((DNodeListEditPart) editPart).getFigure().getSize().width()); |
| assertEquals("The height of the list should be the default Sirius one (to have a minimal size for empty list)", LayoutUtils.NEW_DEFAULT_CONTAINER_DIMENSION.height, |
| ((DNodeListEditPart) editPart).getFigure().getSize().height()); |
| } |
| |
| /** |
| * Check the layout of a container with VStack layout. |
| */ |
| public void testVStackContainerLayout() { |
| openDiagram("diagramWithRegions"); |
| |
| Optional<DDiagramElement> vStackContainer = diagram.getDiagramElements().stream().filter(dde -> dde.getName().equals("root_V")).findFirst(); |
| assertTrue("The diagram should have a node named \"root_V\".", vStackContainer.isPresent()); |
| IGraphicalEditPart vStackContainerEditPart = getEditPart(vStackContainer.get()); |
| assertTrue("The node for \"root_V\" should be an AbstractDiagramContainerEditPart.", vStackContainerEditPart instanceof AbstractDiagramContainerEditPart); |
| |
| Optional<DDiagramElement> c2Dde = ((DNodeContainer) vStackContainer.get()).getOwnedDiagramElements().stream().filter(dde -> dde.getName().equals("MyClass2")).findFirst(); |
| assertTrue("The container \"root_V\" should have a region named \"MyClass2\".", c2Dde.isPresent()); |
| IGraphicalEditPart c2EditPart = getEditPart(c2Dde.get()); |
| assertTrue("The node for \"MyClass2\" should be a AbstractDiagramContainerEditPart.", c2EditPart instanceof AbstractDiagramContainerEditPart); |
| int expectedOneLineHeight = ((AbstractDiagramContainerEditPart) c2EditPart).getNodeLabel().getSize().height(); |
| int expectedOneLineWidth = ((AbstractDiagramContainerEditPart) c2EditPart).getNodeLabel().getSize().width(); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Check that the new size of list item is sufficiently large to display the label without wrapping : one line |
| // label height + label offset + 1 pixel for the separator between 2 regions. |
| int expectedRegionHeight = Math.max(expectedOneLineHeight + IContainerLabelOffsets.LABEL_OFFSET + 1, LayoutUtils.NEW_DEFAULT_CONTAINER_DIMENSION.height); |
| int currentLineHeight = ((AbstractDiagramContainerEditPart) c2EditPart).getFigure().getSize().height(); |
| assertTrue("The empty region should be on one line (with at least one line height; more than " + expectedRegionHeight + " but was " + currentLineHeight + ")", |
| currentLineHeight >= expectedRegionHeight); |
| |
| // The GMF size of VStack container should be "auto-size" ie {-1,-1} |
| assertTrue(vStackContainerEditPart.getNotationView() instanceof Node); |
| Node vStackNode = (Node) vStackContainerEditPart.getNotationView(); |
| LayoutConstraint layoutConstraint = vStackNode.getLayoutConstraint(); |
| assertTrue(layoutConstraint instanceof Bounds); |
| Bounds bounds = (Bounds) layoutConstraint; |
| assertEquals("The width of the VStack container should be \"auto-sized\" after an arrange all.", -1, bounds.getWidth()); |
| assertEquals("The height of the VStack container should be \"auto-sized\" after an arrange all.", -1, bounds.getHeight()); |
| |
| // Check that the new size of the VStack compartment if not too big (around 5x the size of one region height : a |
| // delta of 20 pixels for all margins). |
| assertEquals("The VStack container should not be too high (arround 5x the size of one line height)", 5 * expectedRegionHeight, vStackContainerEditPart.getFigure().getSize().height(), 20); |
| |
| // Check width |
| assertEquals("The region size should fit the label size", expectedOneLineWidth, c2EditPart.getFigure().getSize().width(), 10); |
| |
| // Check width, height, x and y location of each region (GMF bounds): Same width for each region, same height |
| // for each region, x==0 for each region, y==0 for first region and other regions below |
| assertEquals(2, ((AbstractDiagramContainerEditPart) vStackContainerEditPart).getChildren().size()); |
| Object compartmentEditPart = ((AbstractDiagramContainerEditPart) vStackContainerEditPart).getChildren().get(1); |
| assertTrue(compartmentEditPart instanceof AbstractDNodeContainerCompartmentEditPart); |
| int previousRegionWidth = 0; |
| int previousRegionHeight = 0; |
| int previousY = 0; |
| for (Object child : ((AbstractDNodeContainerCompartmentEditPart) compartmentEditPart).getChildren()) { |
| if (child instanceof AbstractDiagramContainerEditPart) { |
| AbstractDiagramContainerEditPart regionEditPart = (AbstractDiagramContainerEditPart) child; |
| assertTrue(regionEditPart.getNotationView() instanceof Node); |
| Node regionNode = (Node) regionEditPart.getNotationView(); |
| LayoutConstraint regionLayoutConstraint = regionNode.getLayoutConstraint(); |
| assertTrue(regionLayoutConstraint instanceof Bounds); |
| Bounds regionBounds = (Bounds) regionLayoutConstraint; |
| assertEquals("x coordinate of each region should be 0", 0, regionBounds.getX()); |
| assertEquals("Each region should be below the previous, wrong location for " + ((DNodeContainer) regionEditPart.resolveSemanticElement()).getName(), previousY + previousRegionHeight, |
| regionBounds.getY()); |
| previousY = regionBounds.getY(); |
| if (previousRegionWidth == 0) { |
| previousRegionWidth = regionBounds.getWidth(); |
| } else { |
| assertEquals("Each region should have the same width, width of \"" + ((DNodeContainer) regionEditPart.resolveSemanticElement()).getName() |
| + "\" is not the same than the previous region", previousRegionWidth, regionBounds.getWidth()); |
| } |
| if (previousRegionHeight == 0) { |
| previousRegionHeight = regionBounds.getHeight(); |
| } else { |
| assertEquals("Each region should have the same height, height of \"" + ((DNodeContainer) regionEditPart.resolveSemanticElement()).getName() |
| + "\" is not the same than the previous region", previousRegionHeight, regionBounds.getHeight()); |
| previousRegionHeight = regionBounds.getHeight(); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Check that the "authorized side" constraint of a border node is considered in ELK layout. |
| */ |
| public void testBorderNodeLayoutWithOneAuthorizedSide() { |
| openDiagram("diagramWithBorderNodesWithOneAuthorizedSide"); |
| |
| // Initialization checks |
| Optional<DDiagramElement> p1Dde = diagram.getOwnedDiagramElements().stream().filter(dde -> dde.getName().equals("p1")).findFirst(); |
| assertTrue("The diagram should have an element named \"p1\".", p1Dde.isPresent()); |
| assertTrue("The diagram should have a node named \"p1\".", p1Dde.get() instanceof DNode); |
| |
| Optional<DDiagramElement> p2Dde = diagram.getOwnedDiagramElements().stream().filter(dde -> dde.getName().equals("p2")).findFirst(); |
| assertTrue("The diagram should have an element named \"p2\".", p2Dde.isPresent()); |
| assertTrue("The diagram should have a node named \"p2\".", p2Dde.get() instanceof DNode); |
| |
| List<DNode> borderNodesOfP1 = ((DNode) p1Dde.get()).getOwnedBorderedNodes(); |
| assertEquals("\"p1\" should have one border node.", 1, borderNodesOfP1.size()); |
| |
| List<DNode> borderNodesOfP2 = ((DNode) p2Dde.get()).getOwnedBorderedNodes(); |
| assertEquals("\"p2\" should have one border node.", 1, borderNodesOfP2.size()); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Check that the figure of border node of p1 is above them from 2 pixels. |
| IGraphicalEditPart p1EditPart = getEditPart(p1Dde.get()); |
| IGraphicalEditPart borderNodeOfp1EditPart = getEditPart(borderNodesOfP1.get(0)); |
| Rectangle borderNodeOfp1Bounds = borderNodeOfp1EditPart.getFigure().getBounds(); |
| int p1Delta = borderNodeOfp1Bounds.height() - IBorderItemOffsets.DEFAULT_OFFSET.height(); |
| assertEquals("The y location of p1 should be 2 pixels lower that its border node as border node is constaint on North side.", p1EditPart.getFigure().getBounds().y() - p1Delta, |
| borderNodeOfp1Bounds.y()); |
| // Check that GMF coordinates also reflect that |
| assertTrue(borderNodeOfp1EditPart.getModel() instanceof Node); |
| Node borderNodeOfp1Node = (Node) borderNodeOfp1EditPart.getModel(); |
| Location gmfLocation1 = (Location) borderNodeOfp1Node.getLayoutConstraint(); |
| assertEquals("The y GMF coordinate of the the border node of p1 is wrong.", -p1Delta, gmfLocation1.getY()); |
| // Check that the figure of border node of p2 is below them from 2 pixels. |
| IGraphicalEditPart p2EditPart = getEditPart(p2Dde.get()); |
| IGraphicalEditPart borderNodeOfp2EditPart = getEditPart(borderNodesOfP2.get(0)); |
| Rectangle p2Bounds = p2EditPart.getFigure().getBounds(); |
| Rectangle borderNodeOfp2Bounds = borderNodeOfp2EditPart.getFigure().getBounds(); |
| int p2Delta = borderNodeOfp2Bounds.height() - IBorderItemOffsets.DEFAULT_OFFSET.height(); |
| assertEquals("The bottom location of p2 should be 2 pixels upper that its border node as border node is constaint on South side.", p2Bounds.getBottom().y() + p2Delta, |
| borderNodeOfp2Bounds.getBottom().y()); |
| // Check that GMF coordinates also reflect that |
| assertTrue(borderNodeOfp2EditPart.getModel() instanceof Node); |
| Node borderNodeOfp2Node = (Node) borderNodeOfp2EditPart.getModel(); |
| Location gmfLocation2 = (Location) borderNodeOfp2Node.getLayoutConstraint(); |
| assertEquals("The y GMF coordinate of the the border node of p2 is wrong.", p2Bounds.height() - IBorderItemOffsets.DEFAULT_OFFSET.height(), gmfLocation2.getY()); |
| } |
| |
| /** |
| * Check that when all sides are "authorized", a classical ELK layout (from left to right) is done. |
| */ |
| public void testBorderNodeLayoutWithAllAuthorizedSides() { |
| openDiagram("diagramWithBorderNodesWithAllAuthorizedSides"); |
| |
| // Initialization checks |
| Optional<DDiagramElement> p1Dde = diagram.getOwnedDiagramElements().stream().filter(dde -> dde.getName().equals("p1")).findFirst(); |
| assertTrue("The diagram should have an element named \"p1\".", p1Dde.isPresent()); |
| assertTrue("The diagram should have a node named \"p1\".", p1Dde.get() instanceof DNode); |
| |
| Optional<DDiagramElement> p2Dde = diagram.getOwnedDiagramElements().stream().filter(dde -> dde.getName().equals("p2")).findFirst(); |
| assertTrue("The diagram should have an element named \"p2\".", p2Dde.isPresent()); |
| assertTrue("The diagram should have a node named \"p2\".", p2Dde.get() instanceof DNode); |
| |
| List<DNode> borderNodesOfP1 = ((DNode) p1Dde.get()).getOwnedBorderedNodes(); |
| assertEquals("\"p1\" should have one border node.", 1, borderNodesOfP1.size()); |
| |
| List<DNode> borderNodesOfP2 = ((DNode) p2Dde.get()).getOwnedBorderedNodes(); |
| assertEquals("\"p2\" should have one border node.", 1, borderNodesOfP2.size()); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Check that the figure of border node of p1 is above them from 2 pixels. |
| IGraphicalEditPart p1EditPart = getEditPart(p1Dde.get()); |
| IGraphicalEditPart borderNodeOfp1EditPart = getEditPart(borderNodesOfP1.get(0)); |
| Rectangle p1Bounds = p1EditPart.getFigure().getBounds(); |
| Rectangle borderNodeOfp1Bounds = borderNodeOfp1EditPart.getFigure().getBounds(); |
| int p1Delta = borderNodeOfp1Bounds.width() - IBorderItemOffsets.DEFAULT_OFFSET.height(); |
| assertEquals("The right location of p1 should be 2 pixels lefter that its border node as border node has no constraint (East side is used).", p1Bounds.getRight().x() + p1Delta, |
| borderNodeOfp1Bounds.getRight().x()); |
| // Check that GMF coordinates also reflect that |
| assertTrue(borderNodeOfp1EditPart.getModel() instanceof Node); |
| Node borderNodeOfp1Node = (Node) borderNodeOfp1EditPart.getModel(); |
| Location gmfLocation1 = (Location) borderNodeOfp1Node.getLayoutConstraint(); |
| assertEquals("The x GMF coordinate of the the border node of p1 is wrong.", p1Bounds.width() - IBorderItemOffsets.DEFAULT_OFFSET.height(), gmfLocation1.getX()); |
| // Check that the figure of border node of p2 is below them from 2 pixels. |
| IGraphicalEditPart p2EditPart = getEditPart(p2Dde.get()); |
| IGraphicalEditPart borderNodeOfp2EditPart = getEditPart(borderNodesOfP2.get(0)); |
| Rectangle p2Bounds = p2EditPart.getFigure().getBounds(); |
| Rectangle borderNodeOfp2Bounds = borderNodeOfp2EditPart.getFigure().getBounds(); |
| int p2Delta = borderNodeOfp2Bounds.height() - IBorderItemOffsets.DEFAULT_OFFSET.height(); |
| assertEquals("The x location of p2 should be 2 pixels righter that its border node as border node has no constraint (West side is used).", p2Bounds.x() - p2Delta, borderNodeOfp2Bounds.x()); |
| // Check that GMF coordinates also reflect that |
| assertTrue(borderNodeOfp2EditPart.getModel() instanceof Node); |
| Node borderNodeOfp2Node = (Node) borderNodeOfp2EditPart.getModel(); |
| Location gmfLocation2 = (Location) borderNodeOfp2Node.getLayoutConstraint(); |
| assertEquals("The x GMF coordinate of the the border node of p2 is wrong.", -p2Delta, gmfLocation2.getX()); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange all respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>There is no scrollbar on all containers</LI> |
| * <LI>All the containers's contents correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeAllResult() { |
| testArrangeAllResult_ForPackageArrangeSelection("diagramWithContainer"); |
| } |
| |
| /** |
| * Makes sure that the label on border of a node is moved when only its location is changed (nothing else is |
| * changed). |
| */ |
| public void testArrangeAllResultWhenOnlyABorderLabelShouldBeMoved() { |
| openDiagram("diagramWithJustALabelOnBorderMove"); |
| |
| // Get locations of MyClass1 and of attribute1 (they should not be moved in this test, already correctly |
| // located)) |
| Optional<DDiagramElement> ddeClass = diagram.getDiagramElements().stream().filter(ode -> ode.getName().equals("MyClass1")).findFirst(); |
| assertTrue("The diagram should have a node named \"MyClass1\".", ddeClass.isPresent()); |
| IGraphicalEditPart nodeEditPart = getEditPart(ddeClass.get()); |
| assertTrue("The node for \"MyClass1\" should be a AbstractDiagramContainerEditPart but was a " + nodeEditPart.getClass().getSimpleName(), |
| nodeEditPart instanceof AbstractDiagramContainerEditPart); |
| Rectangle nodeBounds = nodeEditPart.getFigure().getBounds().getCopy(); |
| |
| Optional<DDiagramElement> dde = diagram.getDiagramElements().stream().filter(ode -> ode.getName().equals("attribute1")).findFirst(); |
| assertTrue("The diagram should have a node named \"attribute1\".", dde.isPresent()); |
| IGraphicalEditPart portEditPart = getEditPart(dde.get()); |
| assertTrue("The node for \"attribute1\" should be a AbstractDiagramBorderNodeEditPart but was a " + portEditPart.getClass().getSimpleName(), |
| portEditPart instanceof AbstractDiagramBorderNodeEditPart); |
| Rectangle borderNodeBounds = portEditPart.getFigure().getBounds().getCopy(); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| assertEquals("The node for \"MyClass1\" should not move during this test (data corrupted or behavior unexpected).", nodeBounds, nodeEditPart.getFigure().getBounds().getCopy()); |
| assertEquals("The border node for \"attribute1\" should not move during this test (data corrupted or behavior unexpected).", borderNodeBounds, portEditPart.getFigure().getBounds().getCopy()); |
| |
| // Check the label location |
| boolean labelFound = false; |
| for (Object portChildObj : portEditPart.getChildren()) { |
| if (portChildObj instanceof IGraphicalEditPart) { |
| IFigure labelFigure = ((IGraphicalEditPart) portChildObj).getFigure(); |
| String text = null; |
| if (labelFigure instanceof WrappingLabel) { |
| text = ((WrappingLabel) labelFigure).getText(); |
| } else if (labelFigure instanceof Label) { |
| text = ((Label) labelFigure).getText(); |
| } else if (labelFigure instanceof SiriusWrapLabel) { |
| SiriusWrapLabel label = (SiriusWrapLabel) labelFigure; |
| text = label.getText(); |
| } |
| |
| if (text != null) { |
| labelFound = true; |
| Rectangle labelBounds = labelFigure.getBounds(); |
| assertTrue(((IGraphicalEditPart) portChildObj).getModel() instanceof Node); |
| Node labelNode = (Node) ((IGraphicalEditPart) portChildObj).getModel(); |
| Location gmfLabelLocation = (Location) labelNode.getLayoutConstraint(); |
| assertEquals("The x GMF coordinate of the label of the border node does not correspond to a centered location.", -(labelBounds.width() - borderNodeBounds.width()) / 2, |
| gmfLabelLocation.getX(), 1); |
| assertEquals("The y GMF coordinate of the label of the border node does not correspond to a location under its border node.", borderNodeBounds.height() + 1, |
| gmfLabelLocation.getY()); |
| assertEquals("Even if GMF coordinates are OK, the label of the border node is visually not horizontally centered on its border node (draw2d x coordinate).", |
| labelBounds.getCenter().x(), borderNodeBounds.getCenter().x()); |
| assertEquals("Even if GMF coordinates are OK, the label of the border node is visually not under the bottom side of its border node (draw2d y coordinate).", |
| labelBounds.getTop().y(), borderNodeBounds.getBottom().y() + 1); |
| } |
| } |
| if (!labelFound) { |
| fail("The label of the border node has not been found."); |
| } |
| } |
| } |
| |
| /** |
| * Makes sure that the result of an arrange all respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>There is no scrollbar on all containers</LI> |
| * <LI>All the containers's contents correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeAllResultOfDiagramWithOneChild() { |
| openDiagram("diagramWithContainerWithOnlyOneChild"); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Assert that the bounding box coordinates of all elements are {20, 20} |
| // Compute primary edit parts (first level edit parts of the container) |
| List<?> primaryEditParts = getPrimaryEditParts(editorPart.getDiagramEditPart()); |
| List<IGraphicalEditPart> primaryGraphicalEditParts = Lists.newArrayList(Iterables.filter(primaryEditParts, IGraphicalEditPart.class)); |
| Rectangle boundingbox = DiagramImageUtils.calculateImageRectangle(primaryGraphicalEditParts, 0, new Dimension(0, 0)); |
| assertEquals("Wrong x coordinate for the bounding box of all diagram elements.", ResetOriginChangeModelOperation.MARGIN, boundingbox.x()); |
| assertEquals("Wrong y coordinate for the bounding box of all diagram elements.", ResetOriginChangeModelOperation.MARGIN, boundingbox.y()); |
| |
| // Assert that there is no scroll bar on all containers |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p1")); |
| |
| // Assert that content of all containers is "correctly layouted" |
| assertAlignCentered(50, "Class1_1", "Class1_2"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on one container respect the following rules: |
| * <UL> |
| * <LI>No scroll bar in the container (container resized)</LI> |
| * <LI>Container is not moved</LI> |
| * <LI>Container's content is correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultOnOneContainerInDiagram() { |
| testArrangeSelectionResultOnOneContainerInDiagram("diagramWithContainer"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on one container respect the following rules: |
| * <UL> |
| * <LI>No scroll bar in the container (container resized)</LI> |
| * <LI>Container is not moved</LI> |
| * <LI>Container's content is correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultOnOneContainerInAnotherContainer() { |
| testArrangeSelectionResultOnOneContainerInAnotherContainer("diagramWithContainer"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on one container respect the following rules: |
| * <UL> |
| * <LI>No scroll bar in the container (container resized)</LI> |
| * <LI>Container is not moved</LI> |
| * <LI>Container's content is correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultOnOneContainerWithBorderNode() { |
| testArrangeSelectionResultOnOneContainerWithBorderNode("diagramWithContainer"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on two containers respect the following rules: |
| * <UL> |
| * <LI>The top-left corner of bounding box of selected elements remains the same</LI> |
| * <LI>Selected elements are layouted according to each others (but by ignoring other not selected elements, |
| * potential overlap with these elements)</LI> |
| * <LI>The content of the selected container is correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultOnTwoContainers() { |
| testArrangeSelectionResultOnTwoContainers("diagramWithContainer"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of a container and some of its children respect the following |
| * rules: |
| * <UL> |
| * <LI>Same rules of arrange selection on only the container</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultOnOneContainerAndSomeOfItsChildren() { |
| testArrangeSelectionResultOnOneContainerAndSomeOfItsChildren("diagramWithContainer"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of some children of a container respect the following rules: |
| * <UL> |
| * <LI>The top-left corner of bounding box of selected elements remains the same</LI> |
| * <LI>Selected elements are layouted according to each others (but by ignoring other not selected elements, |
| * potential overlap with these elements)</LI> |
| * <LI>The container size and location are not changed.</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultOnSomeContainerChildren() { |
| testArrangeSelectionResultOnSomeContainerChildren("diagramWithContainer"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of some children of a container (contained in another |
| * container) respect the following rules: |
| * <UL> |
| * <LI>The top-left corner of bounding box of selected elements remains the same</LI> |
| * <LI>Selected elements are layouted according to each others (but by ignoring other not selected elements, |
| * potential overlap with these elements)</LI> |
| * <LI>The container size and location are not changed.</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultOnSomeContainerChildren_ContainedInAContainer() { |
| testArrangeSelectionResultOnSomeContainerChildren_ContainedInAContainer("diagramWithContainer"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of a container and some children of other container respect |
| * the following rules: |
| * <UL> |
| * <LI>No rules: No layout is perform as this kind of arrange selection is forbidden (see comment in method |
| * org.eclipse.gmf.runtime.diagram.ui.actions.internal.ArrangeAction.getTargetEditPartForArrangeSelection(List)).</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultOnAContainerAndSomeChildrenOfOtherConainer() { |
| testArrangeSelectionResultOnAContainerAndSomeChildrenOfOtherConainer("diagramWithContainer"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange all respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>There is no scrollbar on all containers</LI> |
| * <LI>All the containers's contents correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeAllResultWithScroll() { |
| testArrangeAllResult_ForPackageArrangeSelection("diagramWithContainerAndScroll"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on one container respect the following rules: |
| * <UL> |
| * <LI>No scroll bar in the container (container resized)</LI> |
| * <LI>Container is not moved</LI> |
| * <LI>Container's content is correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultWithScrollOnOneContainerInDiagram() { |
| testArrangeSelectionResultOnOneContainerInDiagram("diagramWithContainerAndScroll"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on one container respect the following rules: |
| * <UL> |
| * <LI>No scroll bar in the container (container resized)</LI> |
| * <LI>Container is not moved</LI> |
| * <LI>Container's content is correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultWithScrollOnOneContainerInAnotherContainer() { |
| testArrangeSelectionResultOnOneContainerInAnotherContainer("diagramWithContainerAndScroll"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on one container respect the following rules: |
| * <UL> |
| * <LI>No scroll bar in the container (container resized)</LI> |
| * <LI>Container is not moved</LI> |
| * <LI>Container's content is correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultWithScrollOnOneContainerWithBorderNode() { |
| testArrangeSelectionResultOnOneContainerWithBorderNode("diagramWithContainerAndScroll"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on two containers respect the following rules: |
| * <UL> |
| * <LI>The top-left corner of bounding box of selected elements remains the same</LI> |
| * <LI>Selected elements are layouted according to each others (but by ignoring other not selected elements, |
| * potential overlap with these elements)</LI> |
| * <LI>The content of the selected container is correctly layouted</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultWithScrollOnTwoContainers() { |
| testArrangeSelectionResultOnTwoContainers("diagramWithContainerAndScroll"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of a container and some of its children respect the following |
| * rules: |
| * <UL> |
| * <LI>Same rules of arrange selection on only the container</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultWithScrollOnOneContainerAndSomeOfItsChildren() { |
| testArrangeSelectionResultOnOneContainerAndSomeOfItsChildren("diagramWithContainerAndScroll"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of some children of a container respect the following rules: |
| * <UL> |
| * <LI>The top-left corner of bounding box of selected elements remains the same</LI> |
| * <LI>Selected elements are layouted according to each others (but by ignoring other not selected elements, |
| * potential overlap with these elements)</LI> |
| * <LI>The container size and location are not changed.</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultWithScrollOnSomeContainerChildren() { |
| testArrangeSelectionResultOnSomeContainerChildren("diagramWithContainerAndScroll"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of some children of a container respect the following rules: |
| * <UL> |
| * <LI>The top-left corner of bounding box of selected elements remains the same</LI> |
| * <LI>Selected elements are layouted according to each others (but by ignoring other not selected elements, |
| * potential overlap with these elements)</LI> |
| * <LI>The container size and location are not changed.</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultWithScrollOnSomeContainerChildrenn_ContainedInAContainer() { |
| testArrangeSelectionResultOnSomeContainerChildren_ContainedInAContainer("diagramWithContainerAndScroll"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of a container and some children of other container respect |
| * the following rules: |
| * <UL> |
| * <LI>No rules: No layout is perform as this kind of arrange selection is forbidden (see comment in method |
| * org.eclipse.gmf.runtime.diagram.ui.actions.internal.ArrangeAction.getTargetEditPartForArrangeSelection(List)).</LI> |
| * <UL> |
| */ |
| public void testArrangeSelectionResultWithScrollOnAContainerAndSomeChildrenOfOtherConainer() { |
| testArrangeSelectionResultOnAContainerAndSomeChildrenOfOtherConainer("diagramWithContainerAndScroll"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on one container respect the following rules: |
| * <UL> |
| * <LI>No scroll bar in the container (container resized)</LI> |
| * <LI>Container is not moved</LI> |
| * <LI>Container's content is correctly layouted</LI> |
| * <UL> |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeSelectionResultOnOneContainerInDiagram(String diagramName) { |
| openDiagram(diagramName); |
| |
| IGraphicalEditPart editPart = getEditPart("p1"); |
| Point locationOfP1BeforeLayout = editPart.getFigure().getBounds().getTopLeft(); |
| |
| // Launch an arrange selection |
| arrangeSelection(editPart); |
| |
| // Assert that there is no scroll bar on p1 |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) editPart); |
| |
| // Assert that the location of the container is the same before and after the layout |
| assertEquals("The location of the container should be the same before and after the layout.", locationOfP1BeforeLayout, editPart.getFigure().getBounds().getTopLeft()); |
| |
| // Assert content is layouted |
| assertAlignCentered(50, "Class1_1", "Class1_2"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on one container respect the following rules: |
| * <UL> |
| * <LI>No scroll bar in the container (container resized)</LI> |
| * <LI>Container is not moved</LI> |
| * <LI>Container's content is correctly layouted</LI> |
| * <UL> |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeSelectionResultOnOneContainerInAnotherContainer(String diagramName) { |
| openDiagram(diagramName); |
| |
| IGraphicalEditPart editPart = getEditPart("p2_2"); |
| Point locationOfP22BeforeLayout = editPart.getFigure().getBounds().getTopLeft(); |
| |
| // Launch an arrange selection |
| arrangeSelection(editPart); |
| |
| // Assert that there is no scroll bar on p2_2 |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) editPart); |
| |
| // Assert that the location of the container is the same before and after the layout |
| assertEquals("The location of the container should be the same before and after the layout.", locationOfP22BeforeLayout, editPart.getFigure().getBounds().getTopLeft()); |
| |
| // Assert content is layouted |
| assertAlignCentered(50, "Class2_2_1", "Class2_2_2"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on one container respect the following rules: |
| * <UL> |
| * <LI>No scroll bar in the container (container resized)</LI> |
| * <LI>Container is not moved</LI> |
| * <LI>Container's content is correctly layouted</LI> |
| * <UL> |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeSelectionResultOnOneContainerWithBorderNode(String diagramName) { |
| openDiagram(diagramName); |
| |
| IGraphicalEditPart editPart = getEditPart("p4"); |
| Point locationOfP4BeforeLayout = editPart.getFigure().getBounds().getTopLeft(); |
| |
| // Launch an arrange selection |
| arrangeSelection(editPart); |
| |
| // Assert that there is no scroll bar on p1 |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) editPart); |
| |
| // Assert that the location of the container is the same before and after the layout |
| assertEquals("The location of the container should be the same before and after the layout.", locationOfP4BeforeLayout, editPart.getFigure().getBounds().getTopLeft()); |
| |
| // Assert content is layouted |
| assertAlignCentered(50, "Class4_1", "Class4_2"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection on two containers respect the following rules: |
| * <UL> |
| * <LI>The top-left corner of bounding box of selected elements remains the same</LI> |
| * <LI>Selected elements are layouted according to each others (but by ignoring other not selected elements, |
| * potential overlap with these elements)</LI> |
| * <LI>The content of the selected container is correctly layouted</LI> |
| * <UL> |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeSelectionResultOnTwoContainers(String diagramName) { |
| openDiagram(diagramName); |
| |
| IGraphicalEditPart p1EditPart = getEditPart("p1"); |
| IGraphicalEditPart p3EditPart = getEditPart("p3"); |
| Point topLeftCornerBeforeLayout = getTopLeftCorner(p1EditPart, p3EditPart); |
| |
| // Launch an arrange selection |
| arrangeSelection(p1EditPart, p3EditPart); |
| |
| // Assert that the top-left corner of bounding box remains the same |
| assertEquals("The top-left corner of the bounding box of layouted elements should remain the same.", topLeftCornerBeforeLayout, getTopLeftCorner(p1EditPart, p3EditPart)); |
| |
| // Assert that p1 and p3 is layouted according to each other |
| assertAlignCentered(50, "p1", "p3"); |
| |
| // Assert that content of all containers is "correctly layouted" |
| assertAlignCentered(50, "Class1_1", "Class1_2"); |
| assertAlignCentered(50, "Class3_1", "Class3_2", "Class3_3", "Class3_4"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of a container and some of its children respect the following |
| * rules: |
| * <UL> |
| * <LI>Same rules of arrange selection on only the container</LI> |
| * <UL> |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeSelectionResultOnOneContainerAndSomeOfItsChildren(String diagramName) { |
| openDiagram(diagramName); |
| |
| IGraphicalEditPart p2EditPart = getEditPart("p2"); |
| Point locationOfP2BeforeLayout = p2EditPart.getFigure().getBounds().getTopLeft(); |
| IGraphicalEditPart class21EditPart = getEditPart("Class2_1"); |
| IGraphicalEditPart class23EditPart = getEditPart("Class2_3"); |
| |
| // Launch an arrange selection |
| arrangeSelection(p2EditPart, class21EditPart, class23EditPart); |
| |
| // Assert that there is no scroll bar on p2 |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) p2EditPart); |
| |
| // Assert that the location of the container is the same before and after the layout |
| assertEquals("The location of the container should be the same before and after the layout.", locationOfP2BeforeLayout, p2EditPart.getFigure().getBounds().getTopLeft()); |
| |
| // Assert content is layouted |
| assertAlignCentered(50, "p2_2", "Class2_1", "Class2_2", "Class2_3"); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of some children of a container respect the following rules: |
| * <UL> |
| * <LI>The top-left corner of bounding box of selected elements remains the same</LI> |
| * <LI>Selected elements are layouted according to each others (but by ignoring other not selected elements, |
| * potential overlap with these elements)</LI> |
| * <LI>The container size and location are not changed.</LI> |
| * <UL> |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeSelectionResultOnSomeContainerChildren_ContainedInAContainer(String diagramName) { |
| openDiagram(diagramName); |
| |
| IGraphicalEditPart p22EditPart = getEditPart("p2_2"); |
| Rectangle boundsOfP22BeforeLayout = p22EditPart.getFigure().getBounds().getCopy(); |
| IGraphicalEditPart class222EditPart = getEditPart("Class2_2_2"); |
| IGraphicalEditPart class221EditPart = getEditPart("Class2_2_1"); |
| Point topLeftCornerBeforeLayout = getTopLeftCorner(class221EditPart, class222EditPart); |
| |
| // Launch an arrange selection |
| arrangeSelection(class222EditPart, class221EditPart); |
| |
| // Assert that the top-left corner of bounding box remains the same |
| assertEquals("The top-left corner of the bounding box of layouted elements should remain the same.", topLeftCornerBeforeLayout, getTopLeftCorner(class221EditPart, class222EditPart)); |
| |
| // Assert content is layouted |
| assertAlignCentered(50, "Class2_2_1", "Class2_2_2"); |
| |
| // Assert that the location and the size of the container is the same before and after the layout |
| assertEquals("The location and the size of the container should be the same before and after the layout.", boundsOfP22BeforeLayout, p22EditPart.getFigure().getBounds()); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of some children of a container respect the following rules: |
| * <UL> |
| * <LI>The top-left corner of bounding box of selected elements remains the same</LI> |
| * <LI>Selected elements are layouted according to each others (but by ignoring other not selected elements, |
| * potential overlap with these elements)</LI> |
| * <LI>The container size and location are not changed.</LI> |
| * <UL> |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeSelectionResultOnSomeContainerChildren(String diagramName) { |
| openDiagram(diagramName); |
| |
| IGraphicalEditPart p2EditPart = getEditPart("p2"); |
| Rectangle boundsOfP2BeforeLayout = p2EditPart.getFigure().getBounds().getCopy(); |
| IGraphicalEditPart class22EditPart = getEditPart("Class2_2"); |
| IGraphicalEditPart class21EditPart = getEditPart("Class2_1"); |
| Point topLeftCornerBeforeLayout = getTopLeftCorner(class21EditPart, class22EditPart); |
| |
| // Launch an arrange selection |
| arrangeSelection(class22EditPart, class21EditPart); |
| |
| // Assert that the top-left corner of bounding box remains the same |
| assertEquals("The top-left corner of the bounding box of layouted elements should remain the same.", topLeftCornerBeforeLayout, getTopLeftCorner(class21EditPart, class22EditPart)); |
| |
| // Assert content is layouted |
| assertAlignCentered(50, "Class2_1", "Class2_2"); |
| |
| // Assert that the location and the size of the container is the same before and after the layout |
| assertEquals("The location and the size of the container should be the same before and after the layout.", boundsOfP2BeforeLayout, p2EditPart.getFigure().getBounds()); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange selection of a container and some children of other container respect |
| * the following rules: |
| * <UL> |
| * <LI>No rules: No layout is perform as this kind of arrange selection is forbidden (see comment in method |
| * org.eclipse.gmf.runtime.diagram.ui.actions.internal.ArrangeAction.getTargetEditPartForArrangeSelection(List)).</LI> |
| * <UL> |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeSelectionResultOnAContainerAndSomeChildrenOfOtherConainer(String diagramName) { |
| openDiagram(diagramName); |
| |
| IGraphicalEditPart p1EditPart = getEditPart("p1"); |
| IGraphicalEditPart class22EditPart = getEditPart("Class2_2"); |
| IGraphicalEditPart class21EditPart = getEditPart("Class2_1"); |
| |
| // Keep the figures bounds after the arrange all without pinned elements. |
| Map<DNode, Rectangle> DNodes2Bounds = computeNodesBounds(diagram); |
| |
| // Launch an arrange selection |
| arrangeSelection(p1EditPart, class22EditPart, class21EditPart); |
| |
| // Check that the layout is the same (because arrange selection on element not in the same parent has no |
| // result). |
| Map<DNode, Rectangle> afterDNodes2Bounds = computeNodesBounds(diagram); |
| afterDNodes2Bounds.forEach((dNode, rect) -> { |
| assertEquals("The layout result should not change after an arrange selection of elements without parent link.", DNodes2Bounds.get(dNode), rect); |
| }); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange all respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>There is no scrollbar on all containers</LI> |
| * <LI>All the containers's contents correctly layouted</LI> |
| * <UL> |
| * This method should be used for diagram on the package packageForArrangeSelectionTest. |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| protected void testArrangeAllResult_ForPackageArrangeSelection(String diagramName) { |
| openDiagram(diagramName); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Assert that the bounding box coordinates of all elements are {20, 20} |
| // Compute primary edit parts (first level edit parts of the container) |
| List<?> primaryEditParts = getPrimaryEditParts(editorPart.getDiagramEditPart()); |
| List<IGraphicalEditPart> primaryGraphicalEditParts = Lists.newArrayList(Iterables.filter(primaryEditParts, IGraphicalEditPart.class)); |
| Rectangle boundingbox = DiagramImageUtils.calculateImageRectangle(primaryGraphicalEditParts, 0, new Dimension(0, 0)); |
| assertEquals("Wrong x coordinate for the bounding box of all diagram elements.", ResetOriginChangeModelOperation.MARGIN, boundingbox.x()); |
| assertEquals("Wrong y coordinate for the bounding box of all diagram elements.", ResetOriginChangeModelOperation.MARGIN, boundingbox.y()); |
| |
| // Assert that there is no scroll bar on all containers |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p1")); |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p2")); |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p3")); |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p4")); |
| |
| // Assert that content of all containers is "correctly layouted" |
| assertAlignCentered(50, "Class1", "Class2", "Class3", "Class4", "p1", "p2", "p3", "p4"); |
| assertAlignCentered(50, "Class1_1", "Class1_2"); |
| assertAlignCentered(50, "p2_2", "Class2_1", "Class2_2", "Class2_3"); |
| assertAlignCentered(50, "Class3_1", "Class3_2", "Class3_3", "Class3_4"); |
| assertAlignCentered(50, "Class4_1", "Class4_2"); |
| } |
| |
| /** |
| * Makes sure that pinned elements do no affect result of layout when using ELK. |
| */ |
| public void testArrangeWithPinnedElements() { |
| // Create a new diagram |
| EObject root = session.getSemanticResources().stream().findFirst().get().getContents().get(0); |
| DRepresentation representation = createRepresentation("SimpleDiagram", root); |
| // Open the editor |
| IEditorPart newEditorPart = DialectUIManager.INSTANCE.openEditor(session, representation, new NullProgressMonitor()); |
| // Move 3 nodes |
| Optional<DDiagramElement> c2Dde = ((DDiagram) representation).getDiagramElements().stream().filter(dde -> dde.getName().equals("MyClass2")).findFirst(); |
| assertTrue("The diagram should have an element named \"MyClass2\".", c2Dde.isPresent()); |
| Optional<DDiagramElement> c3Dde = ((DDiagram) representation).getDiagramElements().stream().filter(dde -> dde.getName().equals("MyClass3")).findFirst(); |
| assertTrue("The diagram should have an element named \"MyClass3\".", c3Dde.isPresent()); |
| Optional<DDiagramElement> c4Dde = ((DDiagram) representation).getDiagramElements().stream().filter(dde -> dde.getName().equals("MyClass4")).findFirst(); |
| assertTrue("The diagram should have an element named \"MyClass4\".", c4Dde.isPresent()); |
| moveEditPart(c2Dde.get(), new Point(100, 50)); |
| moveEditPart(c3Dde.get(), new Point(100, 50)); |
| moveEditPart(c4Dde.get(), new Point(100, 50)); |
| // Arrange the diagram without any pinned elements |
| arrangeAll((DiagramEditor) newEditorPart); |
| TestsUtil.synchronizationWithUIThread(); |
| // Keep the figures bounds after the arrange all without pinned elements. |
| Map<DNode, Rectangle> DNodes2Bounds = computeNodesBounds(representation); |
| // Move the same elements and pin 2 of them. |
| moveEditPart(c2Dde.get(), new Point(100, 50)); |
| moveEditPart(c3Dde.get(), new Point(100, 50)); |
| moveEditPart(c4Dde.get(), new Point(100, 50));; |
| List<DDiagramElement> elementsToPin = new ArrayList<DDiagramElement>(); |
| elementsToPin.add(c2Dde.get()); |
| elementsToPin.add(c4Dde.get()); |
| executeCommand(new PinElementsCommand(elementsToPin)); |
| // Perform the arrange all again. |
| arrangeAll((DiagramEditor) newEditorPart); |
| TestsUtil.synchronizationWithUIThread(); |
| // Check that the layout is the same as without pinned elements |
| Map<DNode, Rectangle> afterDNodes2Bounds = computeNodesBounds(representation); |
| afterDNodes2Bounds.forEach((dNode, rect) -> { |
| assertEquals("The layout result should not change after having pinned some elements.", DNodes2Bounds.get(dNode), rect); |
| }); |
| } |
| |
| /** |
| * Make sure that arrange all launched at diagram creation is OK when using ELK. |
| */ |
| public void testArrangeAtCreation1() { |
| EObject root = session.getSemanticResources().stream().findFirst().get().getContents().get(0); |
| assertTrue(root instanceof EPackage); |
| EPackage subPackage = ((EPackage) root).getESubpackages().get(1); |
| assertEquals("Wrong name for the second subpackage.", "packageForArrangeSelectionTest", subPackage.getName()); |
| |
| testArrangeAtCreation(subPackage, "DiagramWithContainer"); |
| } |
| |
| /** |
| * Make sure that arrange all launched at diagram creation is OK when using ELK. |
| */ |
| public void testArrangeAtCreation2() { |
| testArrangeAtCreation("SimpleDiagram"); |
| } |
| |
| /** |
| * Make sure that arrange all launched at diagram creation is OK when using ELK. |
| */ |
| public void testArrangeAtCreation3() { |
| testArrangeAtCreation("DiagramWithBorderNodesWithOneAuthorizedSide"); |
| } |
| |
| /** |
| * Make sure that arrange all launched at diagram creation is OK when using ELK. |
| */ |
| public void testArrangeAtCreation4() { |
| EObject root = session.getSemanticResources().stream().findFirst().get().getContents().get(0); |
| assertTrue(root instanceof EPackage); |
| EPackage subPackage = ((EPackage) root).getESubpackages().get(1); |
| assertEquals("Wrong name for the second subpackage.", "packageForArrangeSelectionTest", subPackage.getName()); |
| |
| testArrangeAtCreation("DiagramWithContainerAndEdges"); |
| } |
| |
| /** |
| * Make sure that arrange launched at diagram opening, with new elements created because of the refresh is OK when |
| * using ELK. |
| */ |
| public void testArrangeAtOpening1() { |
| // Open the diagram, launch an arrange all and close the diagram |
| testArrangeAllResult_ForPackageArrangeSelection("diagramWithContainer"); |
| |
| Rectangle boundsOfP1BeforeLayoutAtOpening = getEditPart("p1").getFigure().getBounds().getCopy(); |
| Rectangle boundsOfP22BeforeLayoutAtOpening = getEditPart("p2_2").getFigure().getBounds().getCopy(); |
| Rectangle boundsOfP3BeforeLayoutAtOpening = getEditPart("p3").getFigure().getBounds().getCopy(); |
| |
| SessionUIManager.INSTANCE.getUISession(session).closeEditors(false, Collections.singleton((DDiagramEditor) editorPart)); |
| TestsUtil.emptyEventsFromUIThread(); |
| |
| // Modify externally session file (Copy another ecore file with additional semantic elements) |
| EclipseTestsSupportHelper.INSTANCE.copyFile(SiriusTestsPlugin.PLUGIN_ID + PATH_REPLACE + SEMANTIC_RESOURCE_NAME, "/" + TEMPORARY_PROJECT_NAME + "/" + SEMANTIC_RESOURCE_NAME); |
| try { |
| Job.getJobManager().join(ResourceSyncClientNotifier.FAMILY, new NullProgressMonitor()); |
| } catch (OperationCanceledException | InterruptedException e) { |
| fail(e.getMessage()); |
| } |
| |
| openDiagram("diagramWithContainer"); |
| |
| // Assert new elements are layouted |
| assertAlignCentered(50, "Class5", "Class6"); |
| assertAlignCentered(50, "Class1_3", "Class1_4", "Class1_5"); |
| assertAlignCentered(50, "Class3_5", "Class3_6"); |
| |
| // Assert that top left corner of new layouted elements is OK |
| assertEquals(new Point(ResetOriginChangeModelOperation.MARGIN, ResetOriginChangeModelOperation.MARGIN), getTopLeftCorner(getEditPart("Class5"), getEditPart("Class6"))); |
| // TODO : This top left container corresponds to the insets (it could be computed). But by default, it should be |
| // the same location is during an arrange all (further improvement) |
| Point expectedContainerTopLeftCorner = new Point(7, 6); |
| assertEquals(expectedContainerTopLeftCorner, getTopLeftCorner(getEditPart("Class1_3"), getEditPart("Class1_4"), getEditPart("Class1_5"))); |
| assertEquals(expectedContainerTopLeftCorner, getTopLeftCorner(getEditPart("Class3_5"), getEditPart("Class3_6"))); |
| // TODO : The top left corner should be the same for container in other container (it is currently not the case) |
| // (further improvement) |
| expectedContainerTopLeftCorner = new Point(5, 6); |
| assertEquals(expectedContainerTopLeftCorner, getTopLeftCorner(getEditPart("Class2_2_3"))); |
| |
| // Assert that there is no scroll bar on container (for p1 and p3 the new elements layout is larger than |
| // previous) |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p1")); |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p2_2")); |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p3")); |
| |
| // Assert that the location of the container with new elements are the same before and after the layout |
| assertEquals("The location of the container p1 should be the same before and after the layout.", boundsOfP1BeforeLayoutAtOpening.getLocation(), |
| getEditPart("p1").getFigure().getBounds().getLocation()); |
| assertEquals("The location of the container p2_2 should be the same before and after the layout.", boundsOfP22BeforeLayoutAtOpening.getLocation(), |
| getEditPart("p2_2").getFigure().getBounds().getLocation()); |
| assertEquals("The location of the container p3 should be the same before and after the layout.", boundsOfP3BeforeLayoutAtOpening.getLocation(), |
| getEditPart("p3").getFigure().getBounds().getLocation()); |
| } |
| |
| /** |
| * Make sure that arrange launched at diagram opening, with new elements created because of the refresh is OK when |
| * using ELK. |
| */ |
| public void testArrangeAtOpening2() { |
| // Open the diagram, launch an arrange all and close the diagram |
| testArrangeAllResult_ForPackageArrangeSelection("diagramWithContainerAndEdges"); |
| |
| Rectangle boundsOfP1BeforeLayoutAtOpening = getEditPart("p1").getFigure().getBounds().getCopy(); |
| Rectangle boundsOfP22BeforeLayoutAtOpening = getEditPart("p2_2").getFigure().getBounds().getCopy(); |
| Rectangle boundsOfP3BeforeLayoutAtOpening = getEditPart("p3").getFigure().getBounds().getCopy(); |
| |
| SessionUIManager.INSTANCE.getUISession(session).closeEditors(false, Collections.singleton((DDiagramEditor) editorPart)); |
| TestsUtil.emptyEventsFromUIThread(); |
| |
| // Modify externally session file (Copy another ecore file with additional semantic elements) |
| EclipseTestsSupportHelper.INSTANCE.copyFile(SiriusTestsPlugin.PLUGIN_ID + PATH_REPLACE + SEMANTIC_RESOURCE_NAME, "/" + TEMPORARY_PROJECT_NAME + "/" + SEMANTIC_RESOURCE_NAME); |
| try { |
| Job.getJobManager().join(ResourceSyncClientNotifier.FAMILY, new NullProgressMonitor()); |
| } catch (OperationCanceledException | InterruptedException e) { |
| fail(e.getMessage()); |
| } |
| |
| openDiagram("diagramWithContainerAndEdges"); |
| |
| // Assert new elements are layouted |
| assertAlignCentered(50, "Class5", "Class6"); |
| assertAlignCentered(50, "Class1_3", "Class1_4"); |
| assertAlignCentered(50, "Class3_5", "Class3_6"); |
| |
| // Assert that top left corner of new layouted elements is OK |
| assertEquals(new Point(ResetOriginChangeModelOperation.MARGIN, ResetOriginChangeModelOperation.MARGIN), getTopLeftCorner(getEditPart("Class5"), getEditPart("Class6"))); |
| // TODO : This top left container corresponds to the insets (it could be computed). But by default, it should be |
| // the same location is during an arrange all (further improvement) |
| Point expectedContainerTopLeftCorner = new Point(7, 6); |
| assertEquals(expectedContainerTopLeftCorner, getTopLeftCorner(getEditPart("Class1_3"), getEditPart("Class1_4"), getEditPart("Class1_5"))); |
| assertEquals(expectedContainerTopLeftCorner, getTopLeftCorner(getEditPart("Class3_5"), getEditPart("Class3_6"))); |
| // TODO : The top left corner should be the same for container in other container (it is currently not the case) |
| // (further improvement) |
| expectedContainerTopLeftCorner = new Point(5, 6); |
| assertEquals(expectedContainerTopLeftCorner, getTopLeftCorner(getEditPart("Class2_2_3"))); |
| |
| // Assert that there is no scroll bar on container (for p1 and p3 the new elements layout is larger than |
| // previous) |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p1")); |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p2_2")); |
| assertNoVisibleScrollBar((IDiagramContainerEditPart) getEditPart("p3")); |
| |
| // Assert that the location and the size of the container with new elements are the same before and after the |
| // layout |
| assertEquals("The location of the container p1 should be the same before and after the layout.", boundsOfP1BeforeLayoutAtOpening.getLocation(), |
| getEditPart("p1").getFigure().getBounds().getLocation()); |
| assertEquals("The location of the container p2_2 should be the same before and after the layout.", boundsOfP22BeforeLayoutAtOpening.getLocation(), |
| getEditPart("p2_2").getFigure().getBounds().getLocation()); |
| assertEquals("The location of the container p3 should be the same before and after the layout.", boundsOfP3BeforeLayoutAtOpening.getLocation(), |
| getEditPart("p3").getFigure().getBounds().getLocation()); |
| } |
| |
| /** |
| * Make sure that arrange all launched at diagram creation is OK when using ELK. |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeAtCreation(String diagramName) { |
| testArrangeAtCreation(session.getSemanticResources().stream().findFirst().get().getContents().get(0), diagramName); |
| } |
| |
| /** |
| * Make sure that arrange all launched at diagram creation is OK when using ELK. |
| * |
| * @param semanticRootElement |
| * The semantic root element used to create the diagram |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| |
| public void testArrangeAtCreation(EObject semanticRootElement, String diagramName) { |
| // Create a new diagram |
| DRepresentation representation = createRepresentation(diagramName, semanticRootElement); |
| // Open the editor |
| IEditorPart newEditorPart = DialectUIManager.INSTANCE.openEditor(session, representation, new NullProgressMonitor()); |
| |
| // Keep the figures bounds after the arrange all launches automatically at opening. |
| Map<DNode, Rectangle> DNodes2Bounds = computeNodesBounds(representation); |
| |
| // Launch an arrange all explicitly |
| arrangeAll((DiagramEditor) newEditorPart); |
| |
| // Check that the layout is the same as after opening |
| Map<DNode, Rectangle> afterDNodes2Bounds = computeNodesBounds(representation); |
| afterDNodes2Bounds.forEach((dNode, rect) -> { |
| assertEquals("The layout result should not change.", DNodes2Bounds.get(dNode), rect); |
| }); |
| } |
| |
| /** |
| * Makes sure that the border node is not in the margin area of {20x20}. |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeAllResultWithBorderNode() { |
| testArrangeAllResult_ForPackageResetOrigin("resetOrigin1"); |
| } |
| |
| /** |
| * Makes sure that the label of border node is not in the margin area of {20x20}. |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeAllResultWithBorderNodeWithLabel() { |
| testArrangeAllResult_ForPackageResetOrigin("resetOrigin2"); |
| } |
| |
| /** |
| * Makes sure that the edge is not in the margin area of {20x20}. |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| public void testArrangeAllResultWithEdgeOutsideOfBoundingBox() { |
| testArrangeAllResult_ForPackageResetOrigin("resetOrigin3", true, false); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The edge on edge has 2 sections, and its end point is the only point on the main edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_Simple_EdgeAsTarget() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_subClasses for simpleEdgeOnEdge"); |
| DEdgeEditPart targetEdgeEditPart = checkEdge("C1", "C2", true); |
| Connection targetConnection = targetEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsTarget("op1", targetConnection, 3); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The edge on edge, from op1 to other edge, has 2 sections, and its start point is the only point on the main |
| * edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_Simple_EdgeAsSource() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_subClassesReverse for simpleEdgeOnEdge"); |
| DEdgeEditPart sourceEdgeEditPart = checkEdge("C1", "C2", true); |
| Connection sourceConnection = sourceEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsSource("op1", sourceConnection, 3); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The main edge from C3 to C4 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The edge on edge, from op1 to edge C1-C2, has 2 sections, and its end point is the only point on the main |
| * edge</LI> |
| * <LI>The edge on edge, from op3 to edge C1-C2, has 2 sections, and its end point is the only point on the main |
| * edge</LI> |
| * <LI>The edge on edge, from op2 to edge C3-C4, has 2 sections, and its end point is the only point on the main |
| * edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_Complexe_EdgeAsTarget() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_subClasses for complexeEdgeOnEdge"); |
| DEdgeEditPart targetEdgeEditPart = checkEdge("C1", "C2", true); |
| Connection targetConnection = targetEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsTarget("op1", targetConnection, 3); |
| checkEdgeWithEdgeAsTarget("op3", targetConnection, 3); |
| targetEdgeEditPart = checkEdge("C3", "C4", true); |
| targetConnection = targetEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsTarget("op2", targetConnection, 3); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The main edge from C3 to C4 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The edge on edge, from edge C1-C2 to op1, has 2 sections, and its start point is the only point on the main |
| * edge</LI> |
| * <LI>The edge on edge, from edge C1-C2 to op3, has 2 sections, and its start point is the only point on the main |
| * edge</LI> |
| * <LI>The edge on edge, from edge C3-C4 to op2, has 2 sections, and its start point is the only point on the main |
| * edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_Complexe_EdgeAsSource() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_subClassesReverse for complexeEdgeOnEdge"); |
| DEdgeEditPart sourceEdgeEditPart = checkEdge("C1", "C2", true); |
| Connection sourceConnection = sourceEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsSource("op1", sourceConnection, 3); |
| checkEdgeWithEdgeAsSource("op3", sourceConnection, 3); |
| sourceEdgeEditPart = checkEdge("C3", "C4", true); |
| sourceConnection = sourceEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsSource("op2", sourceConnection, 3); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge and with edges with different containing |
| * levels respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The other edges, pointing to it, are "rectilinear" with expected number of bendpoints, and their end points |
| * are the only points on the main edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_DifferentLevel1_EdgeAsTarget() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_withPackage for levels1EdgeOnEdge", true, false); |
| DEdgeEditPart targetEdgeEditPart = checkEdge("C1", "C2", true); |
| Connection targetConnection = targetEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsTarget("op1", targetConnection, 3); |
| checkEdgeWithEdgeAsTarget("op2", targetConnection, 5); |
| checkEdgeWithEdgeAsTarget("op3", targetConnection, 5); |
| checkEdgeWithEdgeAsTarget("op4", targetConnection, 5); |
| checkEdgeWithEdgeAsTarget("op5", targetConnection, 5); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge and with edges with different containing |
| * levels respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The other edges, pointing to it, are "rectilinear" with expected number of bendpoints, and their end points |
| * are the only points on the main edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_DifferentLevel2_EdgeAsTarget() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_withPackageWithOpAtRoot for levels1EdgeOnEdge"); |
| DEdgeEditPart targetEdgeEditPart = checkEdge("C1", "C2", true); |
| Connection targetConnection = targetEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsTarget("op1", targetConnection, 3); |
| checkEdgeWithEdgeAsTarget("op2", targetConnection, 3); |
| checkEdgeWithEdgeAsTarget("op3", targetConnection, 3); |
| checkEdgeWithEdgeAsTarget("op4", targetConnection, 3); |
| checkEdgeWithEdgeAsTarget("op5", targetConnection, 3); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge and with edges with different containing |
| * levels respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The other edges, pointing to it, are "rectilinear" with expected number of bendpoints, and their end points |
| * are the only points on the main edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_DifferentLevel3_EdgeAsTarget() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_withPackageWithOpAtRoot for levels2EdgeOnEdge"); |
| DEdgeEditPart targetEdgeEditPart = checkEdge("C2", "C1", true); |
| Connection targetConnection = targetEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsTarget("op1", targetConnection, 5); |
| checkEdgeWithEdgeAsTarget("op2", targetConnection, 5); |
| checkEdgeWithEdgeAsTarget("op3", targetConnection, 5); |
| checkEdgeWithEdgeAsTarget("op4", targetConnection, 3); |
| checkEdgeWithEdgeAsTarget("op5", targetConnection, 5); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge and with edges with different containing |
| * levels respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The other edges, starting from it, are "rectilinear" with expected number of bendpoints, and their start |
| * points are the only points on the main edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_DifferentLevel1_EdgeAsSource() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_withPackageReverse for levels1EdgeOnEdge"); |
| DEdgeEditPart targetEdgeEditPart = checkEdge("C1", "C2", true); |
| Connection targetConnection = targetEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsSource("op1", targetConnection, 3); |
| checkEdgeWithEdgeAsSource("op2", targetConnection, 3); |
| checkEdgeWithEdgeAsSource("op3", targetConnection, 3); |
| checkEdgeWithEdgeAsSource("op4", targetConnection, 3); |
| checkEdgeWithEdgeAsSource("op5", targetConnection, 3); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge and with edges with different containing |
| * levels respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The other edges, starting from it, are "rectilinear" with expected number of bendpoints, and their start |
| * points are the only points on the main edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_DifferentLevel2_EdgeAsSource() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_withPackageWithOpAtRootReverse for levels1EdgeOnEdge"); |
| DEdgeEditPart targetEdgeEditPart = checkEdge("C1", "C2", true); |
| Connection targetConnection = targetEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsSource("op1", targetConnection, 3); |
| checkEdgeWithEdgeAsSource("op2", targetConnection, 3); |
| checkEdgeWithEdgeAsSource("op3", targetConnection, 3); |
| checkEdgeWithEdgeAsSource("op4", targetConnection, 3); |
| checkEdgeWithEdgeAsSource("op5", targetConnection, 3); |
| } |
| |
| /** |
| * Makes sure that the result of an arrange containing an edge on edge and with edges with different containing |
| * levels respect the following rules: |
| * <UL> |
| * <LI>The top left corner of the bounding box is {20, 20}</LI> |
| * <LI>The main edge from C1 to C2 is a straight line (2 points on the same y axis)</LI> |
| * <LI>The other edges, starting from it, are "rectilinear" with expected number of bendpoints, and their start |
| * points are the only points on the main edge</LI> |
| * <UL> |
| */ |
| public void testArrangeAll_edgeOnEdge_DifferentLevel3_EdgeAsSource() { |
| testArrangeAllResult_ForPackageResetOrigin("diagramEdgeOnEdge_withPackageWithOpAtRootReverse for levels2EdgeOnEdge"); |
| DEdgeEditPart targetEdgeEditPart = checkEdge("C2", "C1", true); |
| Connection targetConnection = targetEdgeEditPart.getConnectionFigure(); |
| checkEdgeWithEdgeAsSource("op1", targetConnection, 3); |
| checkEdgeWithEdgeAsSource("op2", targetConnection, 5); |
| checkEdgeWithEdgeAsSource("op3", targetConnection, 5); |
| checkEdgeWithEdgeAsSource("op4", targetConnection, 5); |
| checkEdgeWithEdgeAsSource("op5", targetConnection, 5); |
| } |
| /** |
| * Makes sure that no diagram element are not in the margin area of {20x20}.<BR/> |
| * This method should be used for diagram on the package "resetOriginCases". |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| */ |
| protected void testArrangeAllResult_ForPackageResetOrigin(String diagramName) { |
| testArrangeAllResult_ForPackageResetOrigin(diagramName, false, false); |
| } |
| |
| /** |
| * Makes sure that no diagram element are not in the margin area of {20x20}.<BR/> |
| * This method should be used for diagram on the package "resetOriginCases". |
| * |
| * @param diagramName |
| * The name of the diagram to use |
| * @param withHorizontalEdgeCase |
| * true if the diagram contains at least one edge outside of the bounding box of nodes on the horizontal |
| * axis, false otherwise. |
| * @param withVerticalEdgeCase |
| * true if the diagram contains at least one edge outside of the bounding box of nodes on the vertical |
| * axis, false otherwise. |
| */ |
| protected void testArrangeAllResult_ForPackageResetOrigin(String diagramName, boolean withHorizontalEdgeCase, boolean withVerticalEdgeCase) { |
| openDiagram(diagramName); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Assert that the bounding box coordinates of all elements are {20, 20} |
| // Compute primary edit parts (first level edit parts of the container) |
| List<?> primaryEditParts = getPrimaryEditParts(editorPart.getDiagramEditPart()); |
| List<IGraphicalEditPart> primaryGraphicalEditParts = Lists.newArrayList(Iterables.filter(primaryEditParts, IGraphicalEditPart.class)); |
| Rectangle boundingbox = DiagramImageUtils.calculateImageRectangle(primaryGraphicalEditParts, 0, new Dimension(0, 0)); |
| // Fix the bounding box according to : |
| // * calculatedTolerance, ie 4 pixels used in |
| // org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx#getBounds()) |
| // * jumpLinkSize, ie 10 pixels , used in |
| // org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx#getBounds()) |
| // * expand, ie 1 pixel, used in org.eclipse.draw2d.Polyline.getBounds() |
| if (withVerticalEdgeCase) { |
| boundingbox.shrink(15, 0); |
| } |
| if (withHorizontalEdgeCase) { |
| boundingbox.shrink(0, 15); |
| } |
| assertEquals("Wrong x coordinate for the bounding box of all diagram elements.", ResetOriginChangeModelOperation.MARGIN, boundingbox.x()); |
| assertEquals("Wrong y coordinate for the bounding box of all diagram elements.", ResetOriginChangeModelOperation.MARGIN, boundingbox.y()); |
| } |
| |
| protected void openDiagram(String diagramName) { |
| diagram = (DDiagram) getRepresentationsByName(diagramName).toArray()[0]; |
| editorPart = (IDiagramWorkbenchPart) DialectUIManager.INSTANCE.openEditor(session, diagram, new NullProgressMonitor()); |
| TestsUtil.synchronizationWithUIThread(); |
| } |
| |
| /** |
| * Check that the Note is moved or not moved with an arrange using ELK, according to the value of the preference |
| * "Move unlinked notes during layout". |
| * |
| * @throws Exception |
| * in case of problem |
| */ |
| @SuppressWarnings("rawtypes") |
| protected void testNoteLayoutAccordingToPref(boolean moveNoteDuringLayout) throws Exception { |
| openDiagram("simpleDiagramWithNote"); |
| |
| // Get the GMF node corresponding to the Note |
| Node noteNode = getNote(editorPart.getDiagram()); |
| assertTrue("One note should exist on the diagram", noteNode != null); |
| |
| // Get the corresponding edit part |
| Map editPartRegistry = editorPart.getDiagramEditPart().getRoot().getViewer().getEditPartRegistry(); |
| final IGraphicalEditPart noteEditPart = (IGraphicalEditPart) editPartRegistry.get(noteNode); |
| |
| // Get the initial note bounds (to be compare to the new bounds after the layout) |
| final Rectangle initialNoteBounds = noteEditPart.getFigure().getBounds().getCopy(); |
| |
| changeDiagramPreference(SiriusDiagramPreferencesKeys.PREF_MOVE_NOTES_DURING_LATOUT.name(), moveNoteDuringLayout); |
| |
| // Launch an arrange all |
| arrangeAll((DiagramEditor) editorPart); |
| |
| // Compare the new location with the expected result |
| Rectangle currentNoteBounds = noteEditPart.getFigure().getBounds().getCopy(); |
| if (moveNoteDuringLayout) { |
| assertFalse("The Note should be moved during the arrange.", initialNoteBounds.getLocation().equals(currentNoteBounds.getLocation())); |
| } else { |
| assertTrue("The Note should not be moved during the arrange.", initialNoteBounds.getLocation().equals(currentNoteBounds.getLocation())); |
| Optional<DDiagramElement> c4Dde = diagram.getDiagramElements().stream().filter(dde -> dde.getName().equals("MyClass4")).findFirst(); |
| if (c4Dde.isPresent()) { |
| IGraphicalEditPart c4EditPart = getEditPart(c4Dde.get()); |
| Rectangle c4Bounds = c4EditPart.getFigure().getBounds().getCopy(); |
| assertTrue("As the Note is not moved, it is expected to overlap \"MyClass4\" node.", currentNoteBounds.intersects(c4Bounds)); |
| } else { |
| fail("The diagram should have a node named \"MyClass4\"."); |
| } |
| } |
| } |
| |
| private Node getNote(Diagram gmfDiagram) { |
| return getSpecificGmfNode(gmfDiagram, "Note"); |
| } |
| |
| private Node getText(Diagram gmfDiagram) { |
| return getSpecificGmfNode(gmfDiagram, "Text"); |
| } |
| |
| private Node getSpecificGmfNode(Diagram gmfDiagram, String id) { |
| Node specificNode = null; |
| for (Iterator<Object> iterator = gmfDiagram.getChildren().iterator(); iterator.hasNext() && specificNode == null;) { |
| Object node = iterator.next(); |
| if (node instanceof Node) { |
| if (((Node) node).getType().equals(id)) { |
| specificNode = (Node) node; |
| } |
| } |
| } |
| return specificNode; |
| } |
| |
| private void restoreInitilaPreferences(IPreferenceStore workspaceViewerPreferenceStore) { |
| workspaceViewerPreferenceStore.setValue(WorkspaceViewerProperties.SNAPTOGRID, initialSnapToGridValue); |
| workspaceViewerPreferenceStore.setValue(WorkspaceViewerProperties.GRIDSPACING, initialGridSpacingValue); |
| workspaceViewerPreferenceStore.setValue(WorkspaceViewerProperties.RULERUNIT, initialRulerUnitValue); |
| } |
| |
| private void changeSnapToPreferences(IPreferenceStore workspaceViewerPreferenceStore) { |
| initialSnapToGridValue = workspaceViewerPreferenceStore.getBoolean(WorkspaceViewerProperties.SNAPTOGRID); |
| initialGridSpacingValue = workspaceViewerPreferenceStore.getDouble(WorkspaceViewerProperties.GRIDSPACING); |
| initialRulerUnitValue = workspaceViewerPreferenceStore.getInt(WorkspaceViewerProperties.RULERUNIT); |
| workspaceViewerPreferenceStore.setValue(WorkspaceViewerProperties.SNAPTOGRID, false); |
| workspaceViewerPreferenceStore.setValue(WorkspaceViewerProperties.GRIDSPACING, 100.0); |
| workspaceViewerPreferenceStore.setValue(WorkspaceViewerProperties.RULERUNIT, RulerProvider.UNIT_PIXELS); |
| } |
| |
| private Map<DNode, Rectangle> computeNodesBounds(DRepresentation representation) { |
| Map<DNode, Rectangle> dNodes2Bounds = new HashMap<>(); |
| ((DDiagram) representation).getNodes().stream().forEach(dNode -> { |
| IGraphicalEditPart editPart = getEditPart(dNode); |
| dNodes2Bounds.put(dNode, editPart.getFigure().getBounds().getCopy()); |
| }); |
| return dNodes2Bounds; |
| } |
| |
| private void arrangeAll(final DiagramEditor editorPart) { |
| ArrangeRequest arrangeRequest = new ArrangeRequest(ActionIds.ACTION_ARRANGE_ALL); |
| arrangeRequest.setPartsToArrange(Collections.singletonList(editorPart)); |
| editorPart.getDiagramEditPart().performRequest(arrangeRequest); |
| TestsUtil.synchronizationWithUIThread(); |
| } |
| |
| private void arrangeSelection(final IGraphicalEditPart... editPartsToSelect) { |
| arrangeSelection(Arrays.asList(editPartsToSelect)); |
| } |
| |
| private void arrangeSelection(List<IGraphicalEditPart> editPartsToSelect) { |
| ArrangeRequest arrangeRequest = new ArrangeRequest(ActionIds.ACTION_ARRANGE_SELECTION); |
| // Filter the list as it is done in |
| // org.eclipse.gmf.runtime.diagram.ui.actions.internal.ArrangeAction.createOperationSet() |
| List<IGraphicalEditPart> realEditPartsToSelect = ToolUtilities.getSelectionWithoutDependants(editPartsToSelect); |
| arrangeRequest.setPartsToArrange(realEditPartsToSelect); |
| // Validate that there is a common parent (as in |
| // org.eclipse.gmf.runtime.diagram.ui.actions.internal.ArrangeAction.getTargetEditPartForArrangeSelection(List)). |
| boolean validated = true; |
| EditPart parentEP = getSelectionParent(realEditPartsToSelect); |
| for (int i = 1; i < realEditPartsToSelect.size(); i++) { |
| EditPart part = (EditPart) realEditPartsToSelect.get(i); |
| if (part instanceof ConnectionEditPart) { |
| continue; |
| } |
| // if there is no common parent, then Arrange Selected isn't |
| // supported. |
| if (part.getParent() != parentEP) { |
| validated = false; |
| } |
| } |
| if (validated) { |
| editorPart.getDiagramEditPart().performRequest(arrangeRequest); |
| TestsUtil.synchronizationWithUIThread(); |
| } |
| } |
| |
| /** |
| * Copy of org.eclipse.gmf.runtime.diagram.ui.actions.internal.ArrangeAction.getSelectionParent(List).<BR/> |
| * getSelectionParent Utility to return the logical parent of the selection list |
| * |
| * @param editparts |
| * List to parse for a common parent. |
| * @return EditPart that is the parent or null if a common parent doesn't exist. |
| */ |
| @SuppressWarnings("rawtypes") |
| private EditPart getSelectionParent(List editparts) { |
| ListIterator li = editparts.listIterator(); |
| while (li.hasNext()) { |
| Object obj = li.next(); |
| if (!(obj instanceof ConnectionEditPart) && obj instanceof EditPart) { |
| return ((EditPart) obj).getParent(); |
| } |
| } |
| return null; |
| } |
| |
| private IGraphicalEditPart getEditPart(String editorPartName) { |
| Optional<DDiagramElement> dde = diagram.getDiagramElements().stream().filter(ode -> ode.getName().equals(editorPartName)).findFirst(); |
| assertTrue("The diagram should have a node named \"" + editorPartName + "\".", dde.isPresent()); |
| return getEditPart(dde.get()); |
| } |
| |
| /** |
| * Gets the primary editparts on this container, that is, the top-level shapes and connectors. |
| * |
| * @param containerEditPart |
| * the concerned container |
| * |
| * @return List of primary edit parts. If there are none then it returns a Collections.EMPTY_LIST, which is |
| * immutable |
| */ |
| private List<?> getPrimaryEditParts(IGraphicalEditPart containerEditPart) { |
| List<?> result = null; |
| if (containerEditPart instanceof DiagramEditPart) { |
| result = ((DiagramEditPart) containerEditPart).getPrimaryEditParts(); |
| } else { |
| for (Object child : containerEditPart.getChildren()) { |
| if (child instanceof AbstractDNodeContainerCompartmentEditPart) { |
| result = ((AbstractDNodeContainerCompartmentEditPart) child).getChildren(); |
| } |
| } |
| } |
| if (result == null) { |
| result = Collections.EMPTY_LIST; |
| } |
| return result; |
| } |
| |
| private void assertNoVisibleScrollBar(IDiagramContainerEditPart part) { |
| IFigure hScrollBar = null; |
| IFigure vScrollBar = null; |
| Object child = part.getChildren().get(1); |
| if (child instanceof AbstractDNodeContainerCompartmentEditPart) { |
| ResizableCompartmentFigure compartmentFigure = (ResizableCompartmentFigure) ((IGraphicalEditPart) child).getFigure(); |
| hScrollBar = ((AnimatableScrollPane) compartmentFigure.getScrollPane()).basicGetHorizontalScrollBar(); |
| vScrollBar = ((AnimatableScrollPane) compartmentFigure.getScrollPane()).basicGetVerticalScrollBar(); |
| } |
| boolean hScrollBarVisible = hScrollBar != null && hScrollBar.isVisible(); |
| boolean vScrollBarVisible = vScrollBar != null && vScrollBar.isVisible(); |
| assertFalse("No scrollbar should be visible for this container (hScrollBar:" + hScrollBarVisible + ", vScrollBar:" + vScrollBarVisible + ").", hScrollBarVisible || vScrollBarVisible); |
| } |
| |
| private void assertAlignCentered(int verticalSpace, String... names) { |
| String previousName = ""; |
| int previousCenter = 0; |
| int previousRight = 0; |
| for (String name : names) { |
| IGraphicalEditPart editPart = getEditPart(name); |
| Rectangle bounds = editPart.getFigure().getBounds(); |
| if (!previousName.isEmpty()) { |
| Point leftPoint = bounds.getLeft(); |
| int currentCenter = leftPoint.y(); |
| assertEquals("\"" + previousName + "\" is not centered aligned with \"" + name + "\".", previousCenter, currentCenter); |
| previousCenter = currentCenter; |
| assertEquals("\"" + name + "\" should be " + verticalSpace + " after \"" + previousName + "\".", previousRight + verticalSpace, leftPoint.x()); |
| previousRight = bounds.getRight().x(); |
| } |
| } |
| } |
| |
| private Point getTopLeftCorner(IGraphicalEditPart... editParts) { |
| Point topLeftCorner = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); |
| for (IGraphicalEditPart editPart : editParts) { |
| Point location = editPart.getFigure().getBounds().getTopLeft(); |
| topLeftCorner = new Point(Math.min(location.x(), topLeftCorner.x()), Math.min(location.y(), topLeftCorner.y())); |
| } |
| return topLeftCorner; |
| } |
| |
| /** |
| * Move the edit part. |
| * |
| * @param dde |
| * the DDiagramElement of the edit part to move. |
| * @param point |
| * delta to move. |
| * |
| */ |
| private void moveEditPart(DDiagramElement dde, Point point) { |
| IGraphicalEditPart editPart = getEditPart(dde); |
| ChangeBoundsRequest request = new ChangeBoundsRequest(); |
| request.setMoveDelta(point); |
| request.setLocation(point); |
| request.setType(RequestConstants.REQ_MOVE); |
| editPart.performRequest(request); |
| TestsUtil.synchronizationWithUIThread(); |
| } |
| |
| private void checkEdgeWithEdgeAsTarget(String sourceNodeName, Connection targetConnection, int expectedNumberOfPoints) { |
| DEdgeEditPart edgePointingToAnotherEdge = getEdgeWithNodeAsSource(sourceNodeName); |
| Connection connectionFigure = edgePointingToAnotherEdge.getConnectionFigure(); |
| PointList points = connectionFigure.getPoints(); |
| assertEquals("Wrong number of points for the edge between \"" + sourceNodeName + "\" and another edge.", expectedNumberOfPoints, points.size()); |
| List<Object> targetLineSegments = PointListUtilities.getLineSegments(targetConnection.getPoints()); |
| assertTrue("The last point of the egde between \"" + sourceNodeName + "\" and another edge should be on the target edge.", containsPoint(targetLineSegments, points.getLastPoint())); |
| for (int i = 0; i < points.size() - 1; i++) { |
| Point pointToTest = points.getPoint(i); |
| assertFalse("Only the last point of the egde between \"" + sourceNodeName + "\" and another edge should be on the target edge. The point " + pointToTest + " is also on the target edge.", |
| containsPoint(targetLineSegments, pointToTest)); |
| } |
| if (expectedNumberOfPoints == 2) { |
| assertTrue("The edge between \"" + sourceNodeName + "\" and another edge is not horizontal.", |
| new LineSeg(connectionFigure.getPoints().getFirstPoint(), connectionFigure.getPoints().getLastPoint()).isHorizontal()); |
| } else if (expectedNumberOfPoints == 3 || expectedNumberOfPoints == 5) { |
| for (int i = 0; i < points.size() - 2; i++) { |
| LineSeg aSegment = new LineSeg(points.getPoint(i), points.getPoint(i + 1)); |
| LineSeg aFollowingSegment = new LineSeg(points.getPoint(i + 1), points.getPoint(i + 2)); |
| assertTrue("A segment of the egde between \"" + sourceNodeName + "\" and another edge should make a right angle with its following segment.", |
| (aSegment.isHorizontal() && aFollowingSegment.isVertical()) || (aSegment.isVertical() && aFollowingSegment.isHorizontal())); |
| } |
| } else { |
| fail(expectedNumberOfPoints + " is not an handled value for the expectedNumberOfPoints parameters."); |
| } |
| } |
| |
| private void checkEdgeWithEdgeAsSource(String targetNodeName, Connection sourceConnection, int expectedNumberOfPoints) { |
| DEdgeEditPart edgeStartingFormAnotherEdge = getEdgeWithNodeAsTarget(targetNodeName); |
| Connection connectionFigure = edgeStartingFormAnotherEdge.getConnectionFigure(); |
| PointList points = connectionFigure.getPoints(); |
| assertEquals("Wrong number of points for the edge between another edge and \"" + targetNodeName + "\".", expectedNumberOfPoints, points.size()); |
| List<Object> sourceLineSegments = PointListUtilities.getLineSegments(sourceConnection.getPoints()); |
| assertTrue("The first point of the egde between another edge and \"" + targetNodeName + "\" should be on the source edge.", containsPoint(sourceLineSegments, points.getFirstPoint())); |
| for (int i = 1; i < points.size(); i++) { |
| Point pointToTest = points.getPoint(i); |
| assertFalse("Only the first point of the egde between another edge and \"" + targetNodeName + "\" should be on the source edge. The point " + pointToTest + " is also on the source edge.", |
| containsPoint(sourceLineSegments, pointToTest)); |
| } |
| if (expectedNumberOfPoints == 2) { |
| assertTrue("The edge between another edge and \"" + targetNodeName + "\" is not horizontal.", |
| new LineSeg(connectionFigure.getPoints().getFirstPoint(), connectionFigure.getPoints().getLastPoint()).isHorizontal()); |
| } else if (expectedNumberOfPoints == 3 || expectedNumberOfPoints == 4 || expectedNumberOfPoints == 5) { |
| for (int i = 0; i < points.size() - 2; i++) { |
| LineSeg aSegment = new LineSeg(points.getPoint(i), points.getPoint(i + 1)); |
| LineSeg aFollowingSegment = new LineSeg(points.getPoint(i + 1), points.getPoint(i + 2)); |
| assertTrue("The first segment of the egde between another edge and \"" + targetNodeName + "\" should make a right angle with the second segment.", |
| (aSegment.isHorizontal() && aFollowingSegment.isVertical()) || (aSegment.isVertical() && aFollowingSegment.isHorizontal())); |
| } |
| } else { |
| fail(expectedNumberOfPoints + " is not an handled value for the expectedNumberOfPoints parameters."); |
| } |
| } |
| |
| private boolean containsPoint(List<Object> targetLineSegments, Point pointTotest) { |
| LineSeg lineSeg = PointListUtilities.getNearestSegment(targetLineSegments, pointTotest.x, pointTotest.y); |
| return lineSeg.containsPoint(pointTotest, 0); |
| } |
| |
| /** |
| * Check that the edge between <code>sourceNodeName</code> and <code>targetNodeName</code> exists and optionally |
| * check if it is an horizontal straight line (only two points with same y axis). |
| * |
| * @param sourceNodeName |
| * The name of the source node of the edge |
| * @param targetNodeName |
| * The name of the target node of the edge |
| * @param mustBeHorizontal |
| * true if we must check that the edge is an horizontal edge, false if we want to check that the edge has |
| * 3 segments with right angle between each of them. |
| */ |
| private DEdgeEditPart checkEdge(String sourceNodeName, String targetNodeName, boolean mustBeHorizontal) { |
| IGraphicalEditPart sourceNodeEditPart = getDDiagramElement(sourceNodeName); |
| IGraphicalEditPart targetNodeEditPart = getDDiagramElement(targetNodeName); |
| |
| Optional<DEdgeEditPart> edgeEditPart = sourceNodeEditPart.getSourceConnections().stream().filter(DEdgeEditPart.class::isInstance).map(DEdgeEditPart.class::cast) |
| .filter(deep -> targetNodeEditPart.equals(((DEdgeEditPart) deep).getTarget())).findFirst(); |
| assertTrue("The diagram should have an edge between \"" + sourceNodeName + "\" and \"" + targetNodeName + "\".", edgeEditPart.isPresent()); |
| Connection connectionFigure = edgeEditPart.get().getConnectionFigure(); |
| if (mustBeHorizontal) { |
| assertEquals("Wrong number of points for the edge between \"" + sourceNodeName + "\" and \"" + targetNodeName + "\".", 2, connectionFigure.getPoints().size()); |
| assertTrue("The edge between \"" + sourceNodeName + "\" and \"" + targetNodeName + "\" is not horizontal.", |
| new LineSeg(connectionFigure.getPoints().getFirstPoint(), connectionFigure.getPoints().getLastPoint()).isHorizontal()); |
| } else { |
| assertEquals("Wrong number of points for the edge between \"" + sourceNodeName + "\" and \"" + targetNodeName + "\".", 4, connectionFigure.getPoints().size()); |
| PointList points = connectionFigure.getPoints(); |
| LineSeg firstSegment = new LineSeg(points.getPoint(0), points.getPoint(1)); |
| LineSeg secondSegment = new LineSeg(points.getPoint(1), points.getPoint(2)); |
| LineSeg thirdSegment = new LineSeg(points.getPoint(2), points.getPoint(3)); |
| assertTrue("The first segment of the egde between \"" + sourceNodeName + "\" and \"" + targetNodeName + "\" should make a right angle with the second segment.", |
| (firstSegment.isHorizontal() && secondSegment.isVertical()) || (firstSegment.isVertical() && secondSegment.isHorizontal())); |
| assertTrue("The second segment of the egde between \"" + sourceNodeName + "\" and \"" + targetNodeName + "\" should make a right angle with the third segment.", |
| (secondSegment.isHorizontal() && thirdSegment.isVertical()) || (secondSegment.isVertical() && thirdSegment.isHorizontal())); |
| } |
| return edgeEditPart.get(); |
| } |
| |
| /** |
| * Get the diagramElement with the current name. |
| * |
| * @param nodeName |
| * The node of the diagram element |
| * @return the corresponding diagramElement. |
| */ |
| protected IGraphicalEditPart getDDiagramElement(String nodeName) { |
| Optional<DDiagramElement> ddeSource = diagram.getDiagramElements().stream().filter(dde -> dde.getName().equals(nodeName)).findFirst(); |
| assertTrue("The diagram should have a node named \"" + nodeName + "\".", ddeSource.isPresent()); |
| IGraphicalEditPart sourceNodeEditPart = getEditPart(ddeSource.get()); |
| assertTrue("The node for \"" + nodeName + "\" should be a AbstractDiagramContainerEditPart but was a " + sourceNodeEditPart.getClass().getSimpleName(), |
| sourceNodeEditPart instanceof AbstractDiagramContainerEditPart); |
| return sourceNodeEditPart; |
| } |
| |
| /** |
| * Get the first edge having <code>sourceNodeName</code> as source node. |
| * |
| * @param sourceNodeName |
| * The name of the source node of the edge |
| * @return the first edge having <code>sourceNodeName</code> as source node. |
| */ |
| private DEdgeEditPart getEdgeWithNodeAsSource(String sourceNodeName) { |
| IGraphicalEditPart sourceNodeEditPart = getDDiagramElement(sourceNodeName); |
| |
| Optional<DEdgeEditPart> edgeEditPart = sourceNodeEditPart.getSourceConnections().stream().filter(DEdgeEditPart.class::isInstance).map(DEdgeEditPart.class::cast).findFirst(); |
| assertTrue("The diagram should have an edge starting from \"" + sourceNodeName + "\".", edgeEditPart.isPresent()); |
| return edgeEditPart.get(); |
| } |
| |
| /** |
| * Get the first edge having <code>targetNodeName</code> as target node. |
| * |
| * @param targetNodeName |
| * The name of the target node of the edge |
| * @return the first edge having <code>targetNodeName</code> as target node. |
| */ |
| private DEdgeEditPart getEdgeWithNodeAsTarget(String targetNodeName) { |
| IGraphicalEditPart targetNodeEditPart = getDDiagramElement(targetNodeName); |
| |
| Optional<DEdgeEditPart> edgeEditPart = targetNodeEditPart.getTargetConnections().stream().filter(DEdgeEditPart.class::isInstance).map(DEdgeEditPart.class::cast).findFirst(); |
| assertTrue("The diagram should have an edge ending to \"" + targetNodeName + "\".", edgeEditPart.isPresent()); |
| return edgeEditPart.get(); |
| } |
| } |