swtbot: Add SWTBotTimeGraph and update SWTBotSash
authorPatrick Tasse <patrick.tasse@gmail.com>
Wed, 16 Nov 2016 22:48:48 +0000 (17:48 -0500)
committerPatrick Tasse <patrick.tasse@gmail.com>
Thu, 17 Nov 2016 20:21:52 +0000 (15:21 -0500)
The new classes SWTBotTimeGraph and SWTBotTimeGraphEntry are added to
better support UI testing of the time graph widget.

The class SWTBotSash is updated to simulate drag using SWT events.

SWTBot tests are updated accordingly.

Change-Id: Ic0800e73b85c624864825ab3f63e1bfadbacf945
Signed-off-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/85178
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/ControlFlowViewTest.java
lttng/org.eclipse.tracecompass.lttng2.kernel.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/kernel/ui/swtbot/tests/CriticalPathTest.java
lttng/org.eclipse.tracecompass.lttng2.ust.ui.swtbot.tests/src/org/eclipse/tracecompass/lttng2/ust/ui/swtbot/tests/CallStackViewTest.java
tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/ConditionHelpers.java
tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotSash.java
tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotTimeGraph.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotTimeGraphEntry.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/src/org/eclipse/tracecompass/tmf/ui/swtbot/tests/viewers/events/TmfAlignTimeAxisTest.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java

index f17395aba0932ab92f1b343a9abfece7590f6f6c..8a75cac9e0f51759999797c265ab30973c8655eb 100644 (file)
@@ -27,8 +27,6 @@ import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
 import org.eclipse.swtbot.swt.finder.keyboard.Keyboard;
 import org.eclipse.swtbot.swt.finder.keyboard.KeyboardFactory;
 import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes;
-import org.eclipse.swtbot.swt.finder.matchers.WidgetOfType;
-import org.eclipse.swtbot.swt.finder.results.VoidResult;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotToolbarButton;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
@@ -41,9 +39,9 @@ import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
-import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraph;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraphEntry;
 import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView;
-import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
 import org.eclipse.ui.IWorkbenchPart;
 import org.junit.Before;
 import org.junit.Test;
@@ -70,7 +68,6 @@ public class ControlFlowViewTest extends KernelTimeGraphViewTestBase {
     private static final String FOLLOW_CPU_FORWARD = "Follow CPU Forward";
     private static final String SELECT_PREVIOUS_STATE_CHANGE = "Select Previous State Change";
     private static final String SELECT_NEXT_STATE_CHANGE = "Select Next State Change";
-    private static final String SELECT_NEXT_PROCESS = "Select Next Process";
     private static final Keyboard KEYBOARD = KeyboardFactory.getSWTKeyboard();
     private static final @NonNull ITmfTimestamp START_TIME = TmfTimestamp.fromNanos(1368000272650993664L);
     private static final @NonNull ITmfTimestamp TID1_TIME1 = TmfTimestamp.fromNanos(1368000272651208412L);
@@ -153,18 +150,13 @@ public class ControlFlowViewTest extends KernelTimeGraphViewTestBase {
         TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, START_TIME));
         timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));
 
-        /* select first item */
-        SWTBotUtils.pressShortcutGoToTreeTop(KEYBOARD);
-        fViewBot.toolbarButton(SELECT_NEXT_PROCESS).click();
-
         /* set focus on time graph */
-        final TimeGraphControl timegraph = fViewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class));
-        UIThreadRunnable.syncExec(new VoidResult() {
-            @Override
-            public void run() {
-                timegraph.setFocus();
-            }
-        });
+        SWTBotTimeGraph timeGraph = new SWTBotTimeGraph(fViewBot.bot());
+        timeGraph.setFocus();
+
+        /* select first item */
+        KEYBOARD.pressShortcut(Keystrokes.HOME);
+        KEYBOARD.pressShortcut(Keystrokes.DOWN);
 
         /* click "Select Next State Change" 3 times */
         selectNext.run();
@@ -311,10 +303,10 @@ public class ControlFlowViewTest extends KernelTimeGraphViewTestBase {
         checked = UIThreadRunnable.syncExec(treeCheckCounter);
         assertEquals("Filtered", 26, checked.intValue());
         bot.button("OK").click();
-        treeBot = fViewBot.bot().tree();
-        treeItem = treeBot.getTreeItem(LttngTraceGenerator.getName());
-        for (int i = 0; i < 25; i++) {
-            assertEquals("Filtered Control flow view", "Half-life 3", treeItem.cell(i, 0));
+        SWTBotTimeGraph timeGraph = new SWTBotTimeGraph(fViewBot.bot());
+        SWTBotTimeGraphEntry traceEntry = timeGraph.getEntry(LttngTraceGenerator.getName());
+        for (SWTBotTimeGraphEntry entry : traceEntry.getEntries()) {
+            assertEquals("Filtered Control flow view", "Half-life 3", entry.getText());
         }
     }
 
@@ -330,21 +322,17 @@ public class ControlFlowViewTest extends KernelTimeGraphViewTestBase {
 
         /* set selection to trace start time */
         TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, START_TIME));
-        fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(START_TIME, START_TIME)));
+        timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));
 
-        /* select first item */
         final SWTBotTree tree = fViewBot.bot().tree();
-        SWTBotUtils.pressShortcutGoToTreeTop(KEYBOARD);
-        fViewBot.toolbarButton(SELECT_NEXT_PROCESS).click();
 
         /* set focus on time graph */
-        final TimeGraphControl timegraph = fViewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class));
-        UIThreadRunnable.syncExec(new VoidResult() {
-            @Override
-            public void run() {
-                timegraph.setFocus();
-            }
-        });
+        SWTBotTimeGraph timeGraph = new SWTBotTimeGraph(fViewBot.bot());
+        timeGraph.setFocus();
+
+        /* select first item */
+        KEYBOARD.pressShortcut(Keystrokes.HOME);
+        KEYBOARD.pressShortcut(Keystrokes.DOWN);
 
         /* click "Follow CPU Forward" 3 times */
         timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));
index d4db81932dc313a061ffda42a8f4c0d9ff6761a7..0d2848a44518dd895432dc1b8610a5df09f98c55 100644 (file)
@@ -20,7 +20,6 @@ import java.nio.file.Paths;
 import org.eclipse.core.runtime.FileLocator;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
-import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
 import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotMenu;
 import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
@@ -29,6 +28,8 @@ import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow.
 import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraph;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraphEntry;
 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
 import org.junit.Before;
 import org.junit.Test;
@@ -77,6 +78,7 @@ public class CriticalPathTest extends KernelTestBase {
     public void testFull() {
         SWTBotTree treeCfv = fViewBotCfv.bot().tree();
         SWTBotTree treeCp = fViewBotCp.bot().tree();
+        SWTBotTimeGraph timeGraphCp = new SWTBotTimeGraph(fViewBotCp.bot());
         assertNotNull(treeCfv.widget);
         assertNotNull(treeCp.widget);
         SWTBotTreeItem[] allItems = treeCp.getAllItems();
@@ -86,19 +88,11 @@ public class CriticalPathTest extends KernelTestBase {
 
         ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
         assertNotNull(trace);
-        SWTBotTreeItem item = treeCfv.getTreeItem(trace.getName());
-        assertNotNull(item);
-        item = item.getNode("systemd");
-        assertNotNull(item);
-        item = item.getNode("we");
-        assertNotNull(item);
-        item = item.getNode(PROCESS);
-        assertNotNull(item);
-        final SWTBotTreeItem treeItem = item;
-        UIThreadRunnable.syncExec(() -> treeCfv.widget.setTopItem(treeItem.widget));
-        item.click();
+        SWTBotTreeItem entry = treeCfv.expandNode(trace.getName(), "systemd", "we", PROCESS);
+        assertNotNull(entry);
+        entry.select();
 
-        SWTBotMenu menu = item.contextMenu("Follow " + PROCESS + "/" + TID);
+        SWTBotMenu menu = entry.contextMenu("Follow " + PROCESS + "/" + TID);
         assertEquals("Follow " + PROCESS + "/" + TID, menu.getText());
         menu.click();
         fBot.waitUntil(new DefaultCondition() {
@@ -107,8 +101,8 @@ public class CriticalPathTest extends KernelTestBase {
 
             @Override
             public boolean test() throws Exception {
-                SWTBotTreeItem[] items = treeCp.getAllItems();
-                return EXPECTED_TREE_TEXT.equals(items[0].getNode(0).getText());
+                SWTBotTimeGraphEntry[] entries = timeGraphCp.getEntries();
+                return EXPECTED_TREE_TEXT.equals(entries[0].getEntries()[0].getText());
             }
 
             @Override
index de4ce52a3f7d1aaba00b00d4b05cb9885be5b6b3..5b9129d70d0c361745122ccede888f6aa04b8bb5 100644 (file)
@@ -23,7 +23,6 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.stream.Collectors;
 
 import org.apache.log4j.ConsoleAppender;
 import org.apache.log4j.Logger;
@@ -48,6 +47,8 @@ import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils;
 import org.eclipse.tracecompass.tmf.ui.dialog.TmfFileDialogFactory;
 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.ConditionHelpers;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraph;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraphEntry;
 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
 import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
 import org.eclipse.tracecompass.tmf.ui.views.callstack.CallStackView;
@@ -68,6 +69,9 @@ public class CallStackViewTest {
     private static final String UST_ID = "org.eclipse.linuxtools.lttng2.ust.tracetype";
 
     private static final String PROJECT_NAME = "TestForCallstack";
+    private static final String TRACE = "glxgears-cyg-profile";
+    private static final String PROCESS = "UNKNOWN";
+    private static final @NonNull String THREAD = "glxgears-16073";
 
     /** The Log4j logger instance. */
     private static final Logger fLogger = Logger.getRootLogger();
@@ -94,17 +98,17 @@ public class CallStackViewTest {
      * Stack frames of consecutive events in the trace
      */
     private static final String[] STACK_FRAMES[] = new String[][] {
-            { "0x40472b", "0x4045c8", "0x404412", "", "" },
-            { "0x40472b", "0x4045c8", "0x404412", "0x40392b", "" },
-            { "0x40472b", "0x4045c8", "0x404412", "", "" },
-            { "0x40472b", "0x4045c8", "", "", "" },
-            { "0x40472b", "0x4045c8", "0x404412", "", "" },
-            { "0x40472b", "0x4045c8", "0x404412", "0x40392b", "" },
-            { "0x40472b", "0x4045c8", "0x404412", "", "" },
-            { "0x40472b", "0x4045c8", "", "", "" },
-            { "0x40472b", "0x4045c8", "0x404412", "", "" },
-            { "0x40472b", "0x4045c8", "0x404412", "0x40392b", "" },
-            { "0x40472b", "0x4045c8", "0x404412", "", "" },
+            { "0x40472b", "0x4045c8", "0x404412" },
+            { "0x40472b", "0x4045c8", "0x404412", "0x40392b" },
+            { "0x40472b", "0x4045c8", "0x404412" },
+            { "0x40472b", "0x4045c8" },
+            { "0x40472b", "0x4045c8", "0x404412" },
+            { "0x40472b", "0x4045c8", "0x404412", "0x40392b" },
+            { "0x40472b", "0x4045c8", "0x404412" },
+            { "0x40472b", "0x4045c8" },
+            { "0x40472b", "0x4045c8", "0x404412" },
+            { "0x40472b", "0x4045c8", "0x404412", "0x40392b" },
+            { "0x40472b", "0x4045c8", "0x404412" },
     };
 
     /** Tooltips of the toolbar buttons */
@@ -163,6 +167,7 @@ public class CallStackViewTest {
         SWTBotUtils.closeView("welcome", fBot);
 
         SWTBotUtils.switchToTracingPerspective();
+        SWTBotUtils.closeView("Statistics", fBot);
         /* finish waiting for eclipse to load */
         WaitUtils.waitForJobs();
     }
@@ -196,19 +201,9 @@ public class CallStackViewTest {
      */
     @Test
     public void testOpenCallstack() {
-        String node = "glxgears-cyg-profile";
-        String processName = "UNKNOWN";
-        String childName = "glxgears-16073";
-        List<String> expected = ImmutableList.of("0x40472b", "", "", "", "");
-
         SWTBotView viewBot = fBot.viewById(CallStackView.ID);
         viewBot.setFocus();
-        final SWTBotView viewBot1 = viewBot;
-        SWTBotTree tree = viewBot1.bot().tree();
-        SWTBotTreeItem treeItem = tree.getTreeItem(node).getNode(processName);
-        assertEquals(childName, treeItem.getNodes().get(0));
-        List<String> names = treeItem.getNode(childName).getNodes();
-        assertEquals(expected, names);
+        assertEquals(Arrays.asList("0x40472b"), getVisibleStackFrames(viewBot));
     }
 
     /**
@@ -284,15 +279,14 @@ public class CallStackViewTest {
 
     private static List<String> getVisibleStackFrames(final SWTBotView viewBot) {
         SWTBotTree tree = viewBot.bot().tree();
-        return Arrays.stream(tree.getAllItems())
-                // Process entries
-                .flatMap(item -> Arrays.stream(item.getItems()))
-                // Thread entries
-                .flatMap(item -> Arrays.stream(item.getItems()))
-                // Callstack entries
-                .flatMap(item -> Arrays.stream(item.getItems()))
-                .map(item -> item.cell(0))
-                .collect(Collectors.toList());
+        List<String> stackFrames = new ArrayList<>();
+        for (SWTBotTreeItem treeItem : tree.expandNode(TRACE, PROCESS, THREAD).getItems()) {
+            String name = treeItem.cell(0);
+            if (!name.isEmpty()) {
+                stackFrames.add(name);
+            }
+        }
+        return stackFrames;
     }
 
     private static void goToTime(long timestamp) {
@@ -313,7 +307,6 @@ public class CallStackViewTest {
         goToTime(TIMESTAMPS[0]);
         final SWTBotView viewBot = fBot.viewById(CallStackView.ID);
         viewBot.setFocus();
-        SWTBotTree tree = viewBot.bot().tree();
         Object mapObj = CtfTmfTestTraceUtils.class.getResource("cyg-profile-mapping.txt");
         assertTrue(mapObj instanceof URL);
         URL mapUrl = (URL) mapObj;
@@ -329,21 +322,17 @@ public class CallStackViewTest {
         shellBot.button("Browse...", 1).click();
         shellBot.button("OK").click();
         shellBot.waitUntil(Conditions.shellCloses(activeShell));
-        // FIXME: remove when updates are propagated
+        /*
+         * FIXME: Seek to time needed to update the call stack entry names.
+         * Remove when applying symbol configuration correctly updates entries.
+         */
         goToTime(TIMESTAMPS[0]);
         WaitUtils.waitForJobs();
-        List<String> names = new ArrayList<>();
-
-        for (SWTBotTreeItem swtBotTreeItem : tree.getAllItems()) {
-            for (SWTBotTreeItem items : swtBotTreeItem.getItems()) {
-                for (SWTBotTreeItem item : items.getItems()) {
-                    names.add(item.cell(0));
-                }
-            }
-        }
-        List<String> functions = getVisibleStackFrames(viewBot);
-        assertEquals(ImmutableList.of("glxgears-16073"), names);
-        assertEquals(ImmutableList.of("main", "event_loop", "handle_event", "", ""), functions);
+        SWTBotTimeGraph timeGraph = new SWTBotTimeGraph(viewBot.bot());
+        SWTBotTimeGraphEntry[] threads = timeGraph.getEntry(TRACE, PROCESS).getEntries();
+        assertEquals(1, threads.length);
+        assertEquals(THREAD, threads[0].getText());
+        assertEquals(Arrays.asList("main", "event_loop", "handle_event"), getVisibleStackFrames(viewBot));
     }
 
     /**
index aa58f69fbfea8e74ffaabb75239412808083ac3c..9d8abf3420762cadc9b4ab94a40ca0f8fd815769 100644 (file)
@@ -471,6 +471,39 @@ public final class ConditionHelpers {
         };
     }
 
+    /**
+     * Condition to check if the selection contains the specified text at the
+     * specified column. The text is checked in any item of the tree selection.
+     *
+     * @param tree
+     *            the SWTBot tree
+     * @param column
+     *            the column index
+     * @param text
+     *            the expected text
+     * @return ICondition for verification
+     */
+    public static ICondition timeGraphSelectionContains(final SWTBotTimeGraph timeGraph, final int column, final String text) {
+        return new SWTBotTestCondition() {
+            @Override
+            public boolean test() throws Exception {
+                TableCollection selection = timeGraph.selection();
+                for (int row = 0; row < selection.rowCount(); row++) {
+                    if (selection.get(row, column).equals(text)) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            @Override
+            public String getFailureMessage() {
+                return NLS.bind("Time graph selection [0,{0}]: {1} expected: {2}",
+                        new Object[] { column, timeGraph.selection().get(0, column), text});
+            }
+        };
+    }
+
     private static class EventsTableSelectionCondition extends DefaultCondition {
         private long fSelectionTime;
         private SWTWorkbenchBot fBot;
index 7d69fecc2b7d31cece859d5fee586baa18f79573..f4428a2c8422b0adc5cb825254e12e1f5bee7b74 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2015 Ericsson
+ * Copyright (c) 2015, 2016 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
 
 package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
 
-import java.awt.AWTException;
-import java.awt.Robot;
-import java.awt.event.InputEvent;
-
+import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Sash;
 import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
-import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
 import org.eclipse.swtbot.swt.finder.results.Result;
-import org.eclipse.swtbot.swt.finder.results.VoidResult;
 import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBotControl;
-import org.hamcrest.SelfDescribing;
 
 /**
- * SWT Bot sash control
+ * SWTBot class representing a Sash
  */
 public class SWTBotSash extends AbstractSWTBotControl<Sash> {
 
@@ -35,99 +31,63 @@ public class SWTBotSash extends AbstractSWTBotControl<Sash> {
      *
      * @param w
      *            the sash
-     * @param description
-     *            the description
      * @throws WidgetNotFoundException
      *             if there is no widget
      */
-    public SWTBotSash(Sash w, SelfDescribing description) throws WidgetNotFoundException {
-        super(w, description);
+    public SWTBotSash(Sash w) throws WidgetNotFoundException {
+        super(w);
     }
 
     /**
-     * Get the central point of the sash
+     * Get the bounds of the sash
      *
-     * @return the center point, good for dragging
+     * @return the bounds relative to the parent
      */
-    public Point getPoint() {
-        return UIThreadRunnable.syncExec(new Result<Point>() {
-
+    public Rectangle getBounds() {
+        return syncExec(new Result<Rectangle>() {
             @Override
-            public Point run() {
-                return widget.toDisplay(0, widget.getSize().y / 2);
+            public Rectangle run() {
+                return widget.getBounds();
             }
-
         });
     }
 
     /**
-     * Simulate a drag
+     * Drag the sash from its middle point to the destination point
      *
      * @param dst
-     *            to this destination
+     *            the destination point relative to the parent
      */
     public void drag(final Point dst) {
-        final Point src = getPoint();
-        /*
-         * example of a move
-         *
-         * dn : MouseEvent{Sash {} time=262463957 data=null button=1
-         * stateMask=0x0 x=5 y=59 count=1}
-         *
-         * move : MouseEvent{Sash {} time=262464038 data=null button=0
-         * stateMask=0x80000 x=131 y=103 count=0}
-         *
-         * move : MouseEvent{Sash {} time=262464171 data=null button=0
-         * stateMask=0x80000 x=90 y=116 count=0}
-         *
-         * up : MouseEvent{Sash {} time=262464796 data=null button=1
-         * stateMask=0x80000 x=5 y=116 count=1}
-         */
-        try {
-            final Robot awtRobot = new Robot();
-
-            // move a maximum of 10 points / event
-            final int magDist = (src.x - dst.x) * (src.x - dst.x) + (src.y - dst.y) * (src.y - dst.y);
-
-            final int steps = Math.max(1, (int) Math.sqrt(magDist / 100.0));
-
-            final int stepX = (dst.x - src.x) / steps;
-            final int stepY = (dst.y - src.y) / steps;
-            syncExec(new VoidResult() {
-                @Override
-                public void run() {
-                    awtRobot.mouseMove(src.x, src.y);
-                    SWTBotUtils.delay(15);
-                    awtRobot.mousePress(InputEvent.BUTTON1_MASK);
+        Rectangle bounds = getBounds();
+        int x = bounds.width / 2;
+        int y = bounds.height / 2;
+        notify(SWT.MouseEnter);
+        notify(SWT.Activate);
+        notify(SWT.Selection, createSelectionEvent(bounds.x + x, bounds.y + y, SWT.NONE));
+        notify(SWT.MouseDown, createMouseEvent(x, y, 1, SWT.NONE, 1));
+        notify(SWT.DragDetect, createMouseEvent(x, y, 0, SWT.NONE, 0));
+        notify(SWT.Move);
+        notify(SWT.Selection, createSelectionEvent(dst.x, dst.y, SWT.NONE));
+        notify(SWT.MouseMove, createMouseEvent(x, y, 0, SWT.BUTTON1, 0));
+        notify(SWT.Selection, createSelectionEvent(dst.x, dst.y, SWT.BUTTON1));
+        notify(SWT.MouseUp, createMouseEvent(x, y, 1, SWT.NONE, 1));
+        notify(SWT.MouseExit);
+    }
 
-                }
-            });
-            for (int i = 0; i < steps; i++) {
-                final int index = i;
-                asyncExec(new VoidResult() {
-                    @Override
-                    public void run() {
-                        int x = src.x + index * stepX;
-                        int y = src.y + index * stepY;
-                        awtRobot.mouseMove(x, y);
-                    }
-                });
-                // drag delay
-                SWTBotUtils.delay(10);
+    private Event createSelectionEvent(int x, int y, int stateMask) {
+        return syncExec(new Result<Event>() {
+            @Override
+            public Event run() {
+                boolean vertical = (widget.getStyle() | SWT.VERTICAL) != 0;
+                Point size = widget.getSize();
+                Event event = createSelectionEvent(stateMask);
+                event.x = vertical ? x : 0;
+                event.y = vertical ? 0 : y;
+                event.width = size.x;
+                event.height = size.y;
+                return event;
             }
-            // drop delay
-            SWTBotUtils.delay(100);
-            syncExec(new VoidResult() {
-                @Override
-                public void run() {
-                    awtRobot.mouseRelease(InputEvent.BUTTON1_MASK);
-                }
-            });
-
-        } catch (final AWTException e) {
-            // log.error(e.getMessage(), e);
-            throw new RuntimeException(e);
-        }
+        });
     }
-
 }
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotTimeGraph.java b/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotTimeGraph.java
new file mode 100644 (file)
index 0000000..83e9ea7
--- /dev/null
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetOfType;
+import org.eclipse.swtbot.swt.finder.results.ArrayResult;
+import org.eclipse.swtbot.swt.finder.results.IntResult;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.utils.TableCollection;
+import org.eclipse.swtbot.swt.finder.utils.TableRow;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBotControl;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
+
+/**
+ * SWTBot class representing a time graph
+ */
+public class SWTBotTimeGraph extends AbstractSWTBotControl<TimeGraphControl> {
+
+    /**
+     * Constructor
+     *
+     * @param w the widget
+     * @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
+     */
+    public SWTBotTimeGraph(TimeGraphControl w) throws WidgetNotFoundException {
+        super(w);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param bot
+     *            a SWTBot instance with which to find a time graph
+     * @throws WidgetNotFoundException
+     *             if the widget is <code>null</code> or widget has been
+     *             disposed.
+     */
+    public SWTBotTimeGraph(SWTBot bot) throws WidgetNotFoundException {
+        super(bot.widget(WidgetOfType.widgetOfType(TimeGraphControl.class)));
+    }
+
+    /**
+     * Get the root entries of this time graph
+     *
+     * @return the array of root entries
+     */
+    public SWTBotTimeGraphEntry[] getEntries() {
+        return syncExec(new ArrayResult<SWTBotTimeGraphEntry>() {
+            @Override
+            public SWTBotTimeGraphEntry[] run() {
+                List<SWTBotTimeGraphEntry> entries = new ArrayList<>();
+                for (ITimeGraphEntry entry : widget.getExpandedElements()) {
+                    if (entry.getParent() == null) {
+                        entries.add(new SWTBotTimeGraphEntry(widget, entry));
+                    }
+                }
+                return entries.toArray(new SWTBotTimeGraphEntry[0]);
+            }
+        });
+    }
+
+    /**
+     * Get the time graph entry at the specified path relative to the root.
+     *
+     * @param names
+     *            the path of names
+     * @return the time graph entry
+     * @throws WidgetNotFoundException
+     *             if the entry was not found.
+     */
+    public SWTBotTimeGraphEntry getEntry(String... names) throws WidgetNotFoundException {
+        List<ITimeGraphEntry> entries = Arrays.asList(widget.getExpandedElements());
+        ITimeGraphEntry parent = null;
+        for (String name : names) {
+            boolean found = false;
+            for (ITimeGraphEntry entry : entries) {
+                String label = entry.getName();
+                if (Objects.equals(entry.getParent(), parent) && name.equals(label)) {
+                    parent = entry;
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                throw new WidgetNotFoundException("Timed out waiting for time graph entry " + name); //$NON-NLS-1$
+            }
+        }
+        return new SWTBotTimeGraphEntry(widget, parent);
+    }
+
+    /**
+     * Gets the table collection representing the selection.
+     *
+     * @return the selection in the time graph
+     */
+    public TableCollection selection() {
+        return syncExec(new Result<TableCollection>() {
+            @Override
+            public TableCollection run() {
+                final TableCollection collection = new TableCollection();
+                ISelection selection = widget.getSelection();
+                if (!selection.isEmpty()) {
+                    Object element = ((StructuredSelection) selection).getFirstElement();
+                    if (element instanceof ITimeGraphEntry) {
+                        TableRow tableRow = new TableRow();
+                        SWTBotTimeGraphEntry entry = new SWTBotTimeGraphEntry(widget, (ITimeGraphEntry) element);
+                        tableRow.add(entry.getText());
+                        collection.add(tableRow);
+                    }
+                }
+                return collection;
+            }
+        });
+    }
+
+    /**
+     * Get the name space width
+     *
+     * @return the name space width
+     */
+    public int getNameSpace() {
+        return syncExec(new IntResult() {
+            @Override
+            public Integer run() {
+                return widget.getTimeDataProvider().getNameSpace();
+            }
+        });
+    }
+
+    /**
+     * Set the name space width
+     *
+     * @param nameSpace the name space width
+     */
+    public void setNameSpace(int nameSpace) {
+        int x = widget.getTimeDataProvider().getNameSpace();
+        Rectangle bounds = syncExec(new Result<Rectangle>() {
+            @Override
+            public Rectangle run() {
+                return widget.getBounds();
+            }
+        });
+        int y = bounds.y + bounds.height / 2;
+        notify(SWT.MouseEnter);
+        notify(SWT.MouseMove, createMouseEvent(x, y, 0, SWT.NONE, 0));
+        notify(SWT.Activate);
+        notify(SWT.FocusIn);
+        notify(SWT.MouseDown, createMouseEvent(x, y, 1, SWT.NONE, 1));
+        notify(SWT.DragDetect, createMouseEvent(nameSpace, y, 0, SWT.NONE, 0));
+        notify(SWT.MouseMove, createMouseEvent(nameSpace, y, 1, SWT.BUTTON1, 1));
+        notify(SWT.MouseUp, createMouseEvent(nameSpace, y, 1, SWT.BUTTON1, 1));
+        notify(SWT.MouseMove, createMouseEvent(0, y, 0, SWT.NONE, 0));
+    }
+}
diff --git a/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotTimeGraphEntry.java b/tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotTimeGraphEntry.java
new file mode 100644 (file)
index 0000000..c49a03d
--- /dev/null
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swtbot.swt.finder.SWTBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
+import org.eclipse.swtbot.swt.finder.results.ArrayResult;
+import org.eclipse.swtbot.swt.finder.results.Result;
+import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.waits.Conditions;
+import org.eclipse.swtbot.swt.finder.waits.WaitForObjectCondition;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBotControl;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotRootMenu;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
+
+/**
+ * SWTBot class representing a time graph entry
+ */
+public class SWTBotTimeGraphEntry extends AbstractSWTBotControl<TimeGraphControl> {
+
+    private final ITimeGraphEntry fEntry;
+
+    /**
+     * Constructor
+     *
+     * @param w the widget
+     * @param entry the time graph entry
+     *
+     * @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
+     */
+    public SWTBotTimeGraphEntry(TimeGraphControl w, ITimeGraphEntry entry) throws WidgetNotFoundException {
+        super(w);
+        fEntry = entry;
+    }
+
+
+    @Override
+    protected SWTBotRootMenu contextMenu(final Control control) throws WidgetNotFoundException {
+        UIThreadRunnable.syncExec(new VoidResult() {
+            @Override
+            public void run() {
+                Rectangle bounds = widget.getItemBounds(fEntry);
+                if (bounds == null) {
+                    return;
+                }
+                final Event event = new Event();
+                event.time = (int) System.currentTimeMillis();
+                event.display = control.getDisplay();
+                event.widget = control;
+                event.x = bounds.x + widget.getTimeDataProvider().getNameSpace() / 2;
+                event.y = bounds.y + bounds.height / 2;
+                control.notifyListeners(SWT.MenuDetect, event);
+            }
+        });
+
+        WaitForObjectCondition<Menu> waitForMenu = Conditions.waitForPopupMenu(control);
+        new SWTBot().waitUntilWidgetAppears(waitForMenu);
+        return new SWTBotRootMenu(waitForMenu.get(0));
+    }
+
+    /**
+     * Get the child entries of this entry
+     *
+     * @return the array of child entries
+     */
+    public SWTBotTimeGraphEntry[] getEntries() {
+        return syncExec(new ArrayResult<SWTBotTimeGraphEntry>() {
+            @Override
+            public SWTBotTimeGraphEntry[] run() {
+                List<SWTBotTimeGraphEntry> entries = new ArrayList<>();
+                for (ITimeGraphEntry entry : widget.getExpandedElements()) {
+                    if (fEntry.equals(entry.getParent())) {
+                        entries.add(new SWTBotTimeGraphEntry(widget, entry));
+                    }
+                }
+                return entries.toArray(new SWTBotTimeGraphEntry[0]);
+            }
+        });
+    }
+
+    /**
+     * Get the child entry of this entry with the given name
+     *
+     * @param name
+     *            the name of the entry
+     *
+     * @return the child entry
+     */
+    public SWTBotTimeGraphEntry getEntry(String name) {
+        return syncExec(new Result<SWTBotTimeGraphEntry>() {
+            @Override
+            public SWTBotTimeGraphEntry run() {
+                for (ITimeGraphEntry entry : widget.getExpandedElements()) {
+                    if (fEntry.equals(entry.getParent())) {
+                        String label = entry.getName();
+                        if (name.equals(label)) {
+                            return new SWTBotTimeGraphEntry(widget, entry);
+                        }
+                    }
+                }
+                throw new WidgetNotFoundException("Timed out waiting for time graph entry " + name); //$NON-NLS-1$
+            }
+        });
+    }
+
+    /**
+     * Get the text of this entry
+     *
+     * @return the text
+     */
+    @Override
+    public String getText() {
+        return fEntry.getName();
+    }
+
+    /**
+     * Select this time graph entry
+     *
+     * @return itself
+     */
+    public SWTBotTimeGraphEntry select() {
+        syncExec(new VoidResult() {
+            @Override
+            public void run() {
+                widget.setFocus();
+                widget.selectItem(fEntry, true);
+            }
+        });
+        return this;
+    }
+}
index d6213f2e73a0c77ffd89b128aa2c3b5110acd3d8..1a562271c6414d30c7921813818443dfa3fd686d 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2015 Ericsson
+ * Copyright (c) 2015, 2016 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
 package org.eclipse.tracecompass.tmf.ui.swtbot.tests.viewers.events;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import org.apache.log4j.ConsoleAppender;
 import org.apache.log4j.Logger;
 import org.apache.log4j.SimpleLayout;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.Sash;
 import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
 import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
-import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable;
 import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
-import org.eclipse.swtbot.swt.finder.results.VoidResult;
+import org.eclipse.swtbot.swt.finder.matchers.WidgetOfType;
 import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
+import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBot;
 import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile;
 import org.eclipse.tracecompass.tmf.ui.project.wizards.NewTmfProjectWizard;
 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotSash;
+import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotTimeGraph;
 import org.eclipse.tracecompass.tmf.ui.swtbot.tests.shared.SWTBotUtils;
 import org.eclipse.tracecompass.tmf.ui.tests.shared.WaitUtils;
 import org.eclipse.tracecompass.tmf.ui.views.callstack.CallStackView;
 import org.eclipse.tracecompass.tmf.ui.views.histogram.HistogramView;
 import org.eclipse.tracecompass.tmf.ui.views.timechart.TimeChartView;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
 import org.eclipse.ui.IFolderLayout;
 import org.eclipse.ui.IPageLayout;
 import org.eclipse.ui.IPerspectiveFactory;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -87,7 +87,6 @@ public class TmfAlignTimeAxisTest {
     }
 
     private static File fLocation;
-    private static final BaseMatcher<Sash> SASH_MATCHER = new SashMatcher();
 
     /**
      * Initialization, creates a temp trace
@@ -153,186 +152,172 @@ public class TmfAlignTimeAxisTest {
     }
 
     /**
-     * Test 3 views, none overlap, the histogram, the callstack and the
-     * timechart are aligned, the histogram is moved, callstack and timechart
-     * follow
+     * Test 3 views, none overlap, the histogram, callstack and timechart are
+     * aligned. The histogram is moved, we check that the callstack and
+     * timechart follow.
      */
     @Test
-    public void testMoveHistogramCallstackFollows() {
+    public void testMoveHistogramOthersFollow() {
         fBot = new SWTWorkbenchBot();
-        SWTBotUtils.switchToPerspective(AlignPerspectiveFactory1.ID);
-        testOverlap(HistogramView.ID, CallStackView.ID);
+        switchToPerspective(AlignPerspectiveFactory1.ID);
+        testAligned(HistogramView.ID, CallStackView.ID, TimeChartView.ID);
     }
 
     /**
-     * Test 3 views, none overlap, the histogram, the callstack and the
-     * timechart are aligned, the callstack is moved, histogram and timechart
-     * follow
+     * Test 3 views, none overlap, the histogram, callstack and timechart are
+     * aligned. The callstack is moved, we check that the histogram and
+     * timechart follow.
      */
     @Test
-    public void testMoveCallstackHistogramFollows() {
+    public void testMoveCallstackOthersFollow() {
         fBot = new SWTWorkbenchBot();
-        SWTBotUtils.switchToPerspective(AlignPerspectiveFactory1.ID);
-        testOverlap(CallStackView.ID, HistogramView.ID);
+        switchToPerspective(AlignPerspectiveFactory1.ID);
+        testAligned(CallStackView.ID, HistogramView.ID, TimeChartView.ID);
     }
 
     /**
-     * Test 3 views, overlap on the resizing view. The timechart and callstack
-     * are overlapping. Test that when the histogram moves, the timechart
-     * follows. Hidden views are not tested as their state does not matter until
-     * they are displayed
+     * Test 3 views, overlap on the resizing view. The histogram and timechart
+     * are overlapping, and the callstack is aligned. The histogram is moved, we
+     * check that the callstack follows. The hidden timechart is not checked.
      */
     @Test
     public void testOverlappingHistogramMove() {
         fBot = new SWTWorkbenchBot();
-        SWTBotUtils.switchToPerspective(AlignPerspectiveFactory2.ID);
-        testOverlap(HistogramView.ID, CallStackView.ID);
+        switchToPerspective(AlignPerspectiveFactory2.ID);
+        testAligned(HistogramView.ID, CallStackView.ID);
     }
 
     /**
-     * Test 3 views, overlap on the resizing view. The timechart and callstack
-     * are overlapping. Test that when the timechart moves, the histogram
-     * follows. Hidden views are not tested as their state does not matter until
-     * they are displayed
+     * Test 3 views, overlap on the resizing view. The histogram and timechart
+     * are overlapping, and the callstack is aligned. The callstack is moved, we
+     * check that the histogram follows. The hidden timechart is not checked.
      */
     @Test
-    public void testOverlappingTimechartMove() {
+    public void testOverlappingCallstackMove() {
         fBot = new SWTWorkbenchBot();
-        SWTBotUtils.switchToPerspective(AlignPerspectiveFactory2.ID);
-        testOverlap(CallStackView.ID, HistogramView.ID);
+        switchToPerspective(AlignPerspectiveFactory2.ID);
+        testAligned(CallStackView.ID, HistogramView.ID);
     }
 
     /**
-     * Test 3 views. No overlap. The callstack is not aligned with the
-     * histogram, the histogram is moved, we check that the callstack does NOT
-     * follow
+     * Test 3 views. No overlap. The histogram and timechart are aligned, but
+     * the callstack is not aligned. The histogram is moved, we check that the
+     * timechart follows and that the callstack does NOT follow.
      */
     @Test
     public void testNotOverlappingHistogramMove() {
         fBot = new SWTWorkbenchBot();
-        testNonOverlap(HistogramView.ID, CallStackView.ID);
+        switchToPerspective(AlignPerspectiveFactory3.ID);
+        testAligned(HistogramView.ID, TimeChartView.ID);
+        testNotAligned(HistogramView.ID, CallStackView.ID);
     }
 
     /**
-     * Test 3 views. No overlap. The callstack is not aligned with the
-     * histogram, the callstack is moved, we check that the histogram does NOT
-     * follow
+     * Test 3 views. No overlap. The histogram and timechart are aligned, but
+     * the callstack is not aligned. The callstack is moved, we check that the
+     * histogram and timechart do NOT follow.
      */
     @Test
     public void testNotOverlappingCallstackMove() {
         fBot = new SWTWorkbenchBot();
-        testNonOverlap(CallStackView.ID, HistogramView.ID);
+        switchToPerspective(AlignPerspectiveFactory3.ID);
+        testNotAligned(CallStackView.ID, HistogramView.ID, TimeChartView.ID);
     }
 
-    private static void testNonOverlap(String vId1, String vId2) {
-        final int offset = 100;
+    private static void switchToPerspective(String id) {
         // switch to the proper perspective and wait for views to align
-        SWTBotUtils.switchToPerspective(AlignPerspectiveFactory3.ID);
+        SWTBotUtils.switchToPerspective(id);
         WaitUtils.waitForJobs();
         SWTBotUtils.delay(SYNC_DELAY);
-        // get views
-        SWTBotView masterView = fBot.viewById(vId1);
-        SWTBotView slaveView = fBot.viewById(vId2);
-        final Sash slaveSash = slaveView.bot().widget(SASH_MATCHER, 0);
-        SWTBotSash slaveSashBot = new SWTBotSash(slaveSash, null);
-        Point before = slaveSashBot.getPoint();
-        // move master and wait for slaves to follow
-        drag(masterView, offset);
-        WaitUtils.waitForJobs();
-        SWTBotUtils.delay(SYNC_DELAY);
-        // verify that the slave did not follow
-        assertEquals(before, slaveSashBot.getPoint());
-        // put everything back the way it was
-        drag(masterView, -offset);
-        SWTBotUtils.delay(SYNC_DELAY);
     }
 
-    private static final class SashMatcher extends BaseMatcher<Sash> {
-        @Override
-        public boolean matches(Object item) {
-            return (item instanceof Sash);
+    private static AbstractSWTBot<?> getAlignmentControl(String viewId) {
+        SWTBotView viewBot = fBot.viewById(viewId);
+        switch (viewId) {
+        case HistogramView.ID:
+        case CallStackView.ID:
+            return new SWTBotSash(viewBot.bot().widget(WidgetOfType.widgetOfType(Sash.class)));
+        case TimeChartView.ID:
+            return new SWTBotTimeGraph(viewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class)));
+        default:
+            return null;
         }
+    }
 
-        @Override
-        public void describeTo(Description description) {
+    private static void testAligned(String masterView, String... slaveViews) {
+        final int offset = 50;
+
+        // select alignment controls and get their original alignment positions
+        AbstractSWTBot<?> master = getAlignmentControl(masterView);
+        int masterOrigin = getAlignmentPosition(master);
+        Map<AbstractSWTBot<?>, Integer> slaveMap = new HashMap<>();
+        for (String slaveView : slaveViews) {
+            AbstractSWTBot<?> slave = getAlignmentControl(slaveView);
+            int slaveOrigin = getAlignmentPosition(slave);
+            slaveMap.put(slave, slaveOrigin);
         }
+
+        // change master position
+        setAlignmentPosition(master, masterOrigin + offset);
+
+        // check resulting alignment positions, slaves follow
+        assertEquals(masterOrigin + offset, getAlignmentPosition(master), 2);
+        for (Entry<AbstractSWTBot<?>, Integer> slave : slaveMap.entrySet()) {
+            assertEquals(slave.getValue() + offset, getAlignmentPosition(slave.getKey()), 2);
+        }
+
+        // reset original alignment position
+        setAlignmentPosition(master, masterOrigin);
     }
 
-    private static final class SashFormMatcher extends BaseMatcher<SashForm> {
-        @Override
-        public boolean matches(Object item) {
-            return (item instanceof SashForm);
+    private static void testNotAligned(String masterView, String... nonSlaveViews) {
+        final int offset = 50;
+
+        // select alignment controls and get their original alignment positions
+        AbstractSWTBot<?> master = getAlignmentControl(masterView);
+        int masterOrigin = getAlignmentPosition(master);
+        Map<AbstractSWTBot<?>, Integer> nonSlaveMap = new HashMap<>();
+        for (String nonSlaveView : nonSlaveViews) {
+            AbstractSWTBot<?> nonSlave = getAlignmentControl(nonSlaveView);
+            int nonSlaveOrigin = getAlignmentPosition(nonSlave);
+            nonSlaveMap.put(nonSlave, nonSlaveOrigin);
         }
 
-        @Override
-        public void describeTo(Description description) {
+        // change master position
+        setAlignmentPosition(master, masterOrigin + offset);
+
+        // check resulting alignment positions, non-slaves do not follow
+        assertEquals(masterOrigin + offset, getAlignmentPosition(master), 2);
+        for (Entry<AbstractSWTBot<?>, Integer> nonSlave : nonSlaveMap.entrySet()) {
+            assertEquals((int) nonSlave.getValue(), getAlignmentPosition(nonSlave.getKey()));
         }
+
+        // reset original alignment position
+        setAlignmentPosition(master, masterOrigin);
     }
 
-    /**
-     * Simulate a drag operation using "setWeights"
-     */
-    private static void drag(final SWTBotView view, final int offset) {
-        // this is the final sash form
-        final SashForm sashForm = view.bot().widget(new SashFormMatcher(), 0);
-        assertNotNull(sashForm);
-        // resize widgets using sashform
-        UIThreadRunnable.syncExec(new VoidResult() {
-            @Override
-            public void run() {
-                int[] originalWeights = sashForm.getWeights();
-                int[] newWeights = Arrays.copyOf(originalWeights, originalWeights.length);
-                newWeights[0] += offset;
-                newWeights[1] -= offset;
-                sashForm.setWeights(newWeights);
-                sashForm.getParent().layout();
-            }
-        });
-        // send update signals
-        UIThreadRunnable.syncExec(new VoidResult() {
-            @Override
-            public void run() {
-                sashForm.getChildren()[0].notifyListeners(SWT.Resize, null);
-                sashForm.getChildren()[1].notifyListeners(SWT.Resize, null);
-                /*
-                 * This one is the most important, the previous two are added to
-                 * be a good citizen, this event (selection) is the one that
-                 * triggers an alignment
-                 */
-                sashForm.getChildren()[2].notifyListeners(SWT.Selection, null);
-            }
-        });
+    private static int getAlignmentPosition(AbstractSWTBot<?> control) {
+        if (control instanceof SWTBotSash) {
+            Rectangle bounds = ((SWTBotSash) control).getBounds();
+            return bounds.x + bounds.width / 2;
+        } else if (control instanceof SWTBotTimeGraph) {
+            return ((SWTBotTimeGraph) control).getNameSpace();
+        }
+        return 0;
     }
 
-    private static void testOverlap(String masterView, String slaveView) {
-        final int offset = 100;
-        final int delta = offset / 2;
-        // wait for the perspective switch to propagate alignments
-        WaitUtils.waitForJobs();
-        SWTBotUtils.delay(SYNC_DELAY);
-        // select master and slave parts to observe
-        SWTBotView masterViewBot = fBot.viewById(masterView);
-        final Sash masterSash = masterViewBot.bot().widget(SASH_MATCHER, 0);
-        SWTBotSash masterSashBot = new SWTBotSash(masterSash, null);
-
-        SWTBotView slaveViewBot = fBot.viewById(slaveView);
-        final Sash slaveSash = slaveViewBot.bot().widget(SASH_MATCHER, 0);
-        SWTBotSash slaveSashBot = new SWTBotSash(slaveSash, null);
-
-        double masterOriginalSashX = masterSashBot.getPoint().x;
-        // check that the views are already aligned
-        assertEquals("Approx align", masterOriginalSashX, slaveSashBot.getPoint().x, delta);
-        // move sash and wait for alignment
-        drag(masterViewBot, offset);
+    private static void setAlignmentPosition(AbstractSWTBot<?> control, int position) {
+        if (control instanceof SWTBotSash) {
+            SWTBotSash sash = (SWTBotSash) control;
+            Rectangle bounds = sash.getBounds();
+            Point dst = new Point(position, bounds.y + bounds.height / 2);
+            sash.drag(dst);
+        } else if (control instanceof SWTBotTimeGraph) {
+            ((SWTBotTimeGraph) control).setNameSpace(position);
+        }
+        // wait for alignment
         WaitUtils.waitForJobs();
         SWTBotUtils.delay(SYNC_DELAY);
-        // check results
-        double masterNewSashX = masterSashBot.getPoint().x;
-        assertEquals("Approx align", masterNewSashX, slaveSashBot.getPoint().x, delta);
-        assertEquals(masterOriginalSashX, masterNewSashX - offset, delta);
-        // put things back the way they were
-        drag(masterViewBot, -offset);
-        SWTBotUtils.delay(SYNC_DELAY);
     }
 
     /**
@@ -356,7 +341,7 @@ public class TmfAlignTimeAxisTest {
             layout.setEditorAreaVisible(true);
 
             // Create the top left folder
-            IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
+            IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.4f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
             topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
 
             // Create the top right folder
@@ -399,7 +384,7 @@ public class TmfAlignTimeAxisTest {
             layout.setEditorAreaVisible(true);
 
             // Create the top left folder
-            IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
+            IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.4f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
             topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
 
             // Create the middle right folder
@@ -439,7 +424,7 @@ public class TmfAlignTimeAxisTest {
             layout.setEditorAreaVisible(true);
 
             // Create the top left folder
-            IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.15f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
+            IFolderLayout topLeftFolder = layout.createFolder("topLeftFolder", IPageLayout.LEFT, 0.4f, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$
             topLeftFolder.addView(IPageLayout.ID_PROJECT_EXPLORER);
 
             IFolderLayout bottomLeftFolder = layout.createFolder("bottomLeftFolder", IPageLayout.BOTTOM, 0.5f, "topLeftFolder"); //$NON-NLS-1$
index 8e062d5a58852c951c226f772d411cf1c2f97bbd..ea8a64c5edff6e5b59f4a37eea7dc3056247fe13 100644 (file)
@@ -1606,6 +1606,21 @@ public class TimeGraphControl extends TimeGraphBaseControl
         return fItemData.fExpandedItems[index].fEntry;
     }
 
+    /**
+     * Get the bounds of the specified entry
+     *
+     * @param entry the time graph entry
+     * @return the bounds of the entry, or null if the entry is not visible
+     * @since 2.2
+     */
+    public Rectangle getItemBounds(ITimeGraphEntry entry) {
+        int idx = fItemData.findItemIndex(entry);
+        if (idx >= 0) {
+            return getItemRect(getBounds(), idx);
+        }
+        return null;
+    }
+
     Rectangle getNameRect(Rectangle bounds, int idx, int nameWidth) {
         Rectangle rect = getItemRect(bounds, idx);
         rect.width = nameWidth;
This page took 0.042365 seconds and 5 git commands to generate.