Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(744)

Unified Diff: editor/tools/plugins/com.google.dart.tools.ui_test/src-framework/com/google/dart/ui/test/util/UiContext.java

Issue 18548007: UI tests for 'Rename' and 'Extract Local Variable' refactorings. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes for review comments Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: editor/tools/plugins/com.google.dart.tools.ui_test/src-framework/com/google/dart/ui/test/util/UiContext.java
diff --git a/editor/tools/plugins/com.google.dart.tools.ui_test/src-framework/com/google/dart/ui/test/util/UiContext.java b/editor/tools/plugins/com.google.dart.tools.ui_test/src-framework/com/google/dart/ui/test/util/UiContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f4da8ed439d53f8d9a4ff372da2889617d69b1b
--- /dev/null
+++ b/editor/tools/plugins/com.google.dart.tools.ui_test/src-framework/com/google/dart/ui/test/util/UiContext.java
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2013, the Dart project authors.
+ *
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.dart.ui.test.util;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+import com.google.dart.tools.internal.corext.refactoring.util.ReflectionUtils;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+import org.junit.Assert;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Helper for testing SWT UI.
+ */
+public class UiContext {
+ /**
+ * Visitor for all {@link Widget}'s.
+ */
+ public static class IWidgetsVisitor {
+ /**
+ * Invoked after visiting all children of this {@link Control}.
+ */
+ public void endVisit(Widget widget) {
+ }
+
+ /**
+ * @return <code>true</code> if the children of this {@link Widget} should be visited, and
+ * <code>false</code> if the children of this {@link Widget} should be skipped.
+ */
+ public boolean visit(Widget widget) {
+ return true;
+ }
+ }
+
+ /**
+ * @return the first {@link Widget} with compatible {@link Class}.
+ */
+ public static <T extends Widget> T findFirstWidget(Widget start, Class<T> classToFind) {
+ List<T> widgets = findWidgets(start, classToFind);
+ if (!widgets.isEmpty()) {
+ return widgets.get(0);
+ }
+ return null;
+ }
+
+ /**
+ * @return the {@link List} of {@link Widget}'s with compatible {@link Class}.
+ */
+ public static <T extends Widget> List<T> findWidgets(Widget start, final Class<T> classToFind) {
+ final List<T> widgets = Lists.newArrayList();
+ visit(start, new IWidgetsVisitor() {
+ @Override
+ @SuppressWarnings("unchecked")
+ public void endVisit(Widget widget) {
+ if (classToFind.isAssignableFrom(widget.getClass())) {
+ widgets.add((T) widget);
+ }
+ }
+ });
+ //
+ return widgets;
+ }
+
+ /**
+ * Runs the events loop for the given number of milliseconds.
+ */
+ public static void runEventLoop(int ms) {
+ long start = System.currentTimeMillis();
+ do {
+ while (Display.getDefault().readAndDispatch()) {
+ // do nothing
+ }
+ Thread.yield();
+ } while (System.currentTimeMillis() - start < ms);
+ }
+
+ /**
+ * Runs the events loop one time. Usually just to update UI, such as repaint.
+ */
+ public static void runEventLoopOnce() {
+ while (Display.getDefault().readAndDispatch()) {
+ // do nothing
+ }
+ }
+
+ public static void setChecked(TreeItem treeItem, boolean checked) {
+ treeItem.setChecked(checked);
+ // notify about check
+ Event event = new Event();
+ event.detail = SWT.CHECK;
+ event.item = treeItem;
+ treeItem.getParent().notifyListeners(SWT.Selection, event);
+ }
+
+ /**
+ * Sets given {@link TreeItem} (and only it) expanded in its {@link Tree}.
+ */
+ public static void setExpanded(TreeItem treeItem, boolean expanded) {
+ treeItem.setExpanded(expanded);
+ Event event = new Event();
+ event.widget = treeItem.getParent();
+ event.item = treeItem;
+ treeItem.getParent().notifyListeners(SWT.Expand, event);
+ }
+
+ /**
+ * Selects items in {@link org.eclipse.swt.widgets.List}.
+ */
+ public static void setSelection(org.eclipse.swt.widgets.List list, String item) {
+ list.setSelection(new String[] {item});
+ list.notifyListeners(SWT.Selection, null);
+ }
+
+ /**
+ * Sets given {@link TreeItem} (and only it) selected in its {@link Tree}.
+ */
+ public static void setSelection(TreeItem treeItem) {
+ Tree tree = treeItem.getParent();
+ tree.setSelection(treeItem);
+ treeItem.getParent().notifyListeners(SWT.Selection, null);
+ }
+
+ /**
+ * Visits all {@link Widgets}'s starting from given one.
+ */
+ public static void visit(Widget widget, IWidgetsVisitor visitor) {
+ // ignore invisible Control's
+ if (widget instanceof Control) {
+ Control control = (Control) widget;
+ if (control.getParent() != null && control.getParent().getLayout() instanceof StackLayout
+ && !control.isVisible()) {
+ return;
+ }
+ }
+ // visit
+ if (visitor.visit(widget)) {
+ // Composite
+ if (widget instanceof Composite) {
+ Composite composite = (Composite) widget;
+ Control[] children = composite.getChildren();
+ for (int i = 0; i < children.length; i++) {
+ Control child = children[i];
+ visit(child, visitor);
+ }
+ }
+ // ToolBar
+ if (widget instanceof ToolBar) {
+ ToolBar toolBar = (ToolBar) widget;
+ for (ToolItem toolItem : toolBar.getItems()) {
+ visit(toolItem, visitor);
+ }
+ }
+ // TabFolder
+ if (widget instanceof TabFolder) {
+ TabFolder tabFolder = (TabFolder) widget;
+ for (TabItem tabItem : tabFolder.getItems()) {
+ visit(tabItem, visitor);
+ }
+ }
+ // TabItem
+ if (widget instanceof TabItem) {
+ TabItem tabItem = (TabItem) widget;
+ Control control = tabItem.getControl();
+ if (control != null) {
+ visit(control, visitor);
+ }
+ }
+ // Tree
+ if (widget instanceof Tree) {
+ Tree tree = (Tree) widget;
+ for (TreeItem treeItem : tree.getItems()) {
+ visit(treeItem, visitor);
+ }
+ }
+ if (widget instanceof TreeItem) {
+ TreeItem parent = (TreeItem) widget;
+ for (TreeItem treeItem : parent.getItems()) {
+ visit(treeItem, visitor);
+ }
+ }
+ // Menu
+ if (widget instanceof Menu) {
+ Menu menu = (Menu) widget;
+ for (MenuItem menuItem : menu.getItems()) {
+ visit(menuItem, visitor);
+ }
+ }
+ if (widget instanceof MenuItem) {
+ MenuItem menuItem = (MenuItem) widget;
+ visit(menuItem.getMenu(), visitor);
+ }
+ // end
+ visitor.endVisit(widget);
+ }
+ }
+
+ /**
+ * @return <code>true</code> if given {@link String}s have same content. Special characters are
+ * ignored.
+ */
+ private static boolean isSameText(String s1, String s2) {
+ if (s1 == null || s2 == null) {
+ return false;
+ }
+ s1 = normalizeTextForComparing(s1);
+ s2 = normalizeTextForComparing(s2);
+ return s1.equals(s2);
+ }
+
+ /**
+ * Normalizes given {@link String} by removing special characters.
+ */
+ private static String normalizeTextForComparing(String s) {
+ s = s.trim();
+ s = StringUtils.remove(s, '&');
+ s = StringUtils.substringBefore(s, "\t");
+ return s;
+ }
+
+ private final Display display;
+
+ private Shell shell;
+
+ private final LinkedList<Shell> shells = Lists.newLinkedList();
+
+ public UiContext() {
+ this.display = Display.getCurrent();
+ }
+
+ public UiContext(Display display) {
+ this.display = display;
+ }
+
+ /**
+ * Sends {@link SWT#Selection} event to given {@link ToolItem} with detail.
+ */
+ public void click(ToolItem toolItem, int detail) {
+ Event event = new Event();
+ event.detail = detail;
+ toolItem.notifyListeners(SWT.Selection, event);
+ }
+
+ /**
+ * Sends {@link SWT#Selection} event to given {@link Widget}.
+ */
+ public void click(Widget widget) {
+ widget.notifyListeners(SWT.Selection, new Event());
+ }
+
+ /**
+ * Sends {@link SWT#Selection} event to given {@link Button}.
+ */
+ public void clickButton(Button button) {
+ click(button);
+ }
+
+ /**
+ * Sends {@link SWT#Selection} event to the {@link Button} with given text.
+ */
+ public void clickButton(String text) {
+ Button button = getButtonByText(text);
+ Assert.assertNotNull("Can not find button with text |" + text + "|", button);
+ clickButton(button);
+ }
+
+ /**
+ * @return the first {@link Widget} with compatible {@link Class}.
+ */
+ public <T extends Widget> T findFirstWidget(Class<T> classToFind) {
+ return findFirstWidget(getShell(), classToFind);
+ }
+
+ /**
+ * @return the {@link Shell} with the given text, may be {@code null}.
+ */
+ public Shell findShell(String text) {
+ for (Shell shell : display.getShells()) {
+ if (text.equals(shell.getText())) {
+ return shell;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return the {@link List} of {@link Widget}'s with compatible {@link Class}.
+ */
+ public <T extends Widget> List<T> findWidgets(final Class<T> classToFind) {
+ Shell shell = getShell();
+ return findWidgets(shell, classToFind);
+ }
+
+ /**
+ * @return the {@link Menu} widget that active for current {@link Shell}.
+ */
+ public Menu getActiveMenu() {
+ return (Menu) ReflectionUtils.getFieldObject(getShell(), "activeMenu");
+ }
+
+ /**
+ * @return the {@link Button} with given text.
+ */
+ public Button getButton(Widget start, final Predicate<String> predicate) {
+ final Button[] result = new Button[1];
+ visit(start, new IWidgetsVisitor() {
+ @Override
+ public void endVisit(Widget widget) {
+ if (widget instanceof Button) {
+ Button button = (Button) widget;
+ if (predicate.apply(button.getText()) || predicate.apply(button.getToolTipText())) {
+ result[0] = button;
+ }
+ }
+ }
+ });
+ return result[0];
+ }
+
+ /**
+ * @return the {@link Button} with given text.
+ */
+ public Button getButtonByText(String text) {
+ return getButtonByText(getShell(), text);
+ }
+
+ /**
+ * @return the {@link Button} with given text.
+ */
+ public Button getButtonByText(Widget start, final String text) {
+ return getButton(start, new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return isSameText(input, text);
+ }
+ });
+ }
+
+ /**
+ * @return the {@link Button} with given text.
+ */
+ public Button getButtonByTextPrefix(final String prefix) {
+ return getButton(getShell(), new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return input != null && input.startsWith(prefix);
+ }
+ });
+ }
+
+ /**
+ * @return the {@link Control} located in children on its {@link Composite} after given one.
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T getControlAfter(Control reference) {
+ Control[] children = reference.getParent().getChildren();
+ // get next Control
+ int index = ArrayUtils.indexOf(children, reference);
+ if (index < children.length - 1) {
+ return (T) children[index + 1];
+ }
+ // not found
+ return null;
+ }
+
+ /**
+ * @return the {@link Control} located in children on its {@link Composite} after {@link Label}
+ * with given text.
+ */
+ public Control getControlAfterLabel(String text) {
+ List<Label> labels = findWidgets(Label.class);
+ for (Label label : labels) {
+ String labelText = label.getText().trim();
+ if (isSameText(labelText, text)) {
+ Control[] children = label.getParent().getChildren();
+ // get next Control
+ int index = ArrayUtils.indexOf(children, label);
+ if (index < children.length - 1) {
+ return children[index + 1];
+ }
+ // stop it any case
+ break;
+ }
+ }
+ // not found
+ return null;
+ }
+
+ /**
+ * @return the {@link Menu} widget that active for current {@link Display}.
+ */
+ public Menu getLastPopup() {
+ Menu menu = null;
+ Menu[] popups = (Menu[]) ReflectionUtils.getFieldObject(display, "popups");
+ for (int i = 0; i < popups.length; i++) {
+ if (popups[i] != null) {
+ menu = popups[i];
+ }
+ }
+ return menu;
+ }
+
+ /**
+ * @return the {@link MenuItem} with given text.
+ */
+ public MenuItem getMenuItem(Menu menu, final String text) {
+ final MenuItem[] result = new MenuItem[1];
+ visit(menu, new IWidgetsVisitor() {
+ @Override
+ public void endVisit(Widget widget) {
+ if (widget instanceof MenuItem) {
+ MenuItem item = (MenuItem) widget;
+ if (isSameText(item.getText(), text)) {
+ result[0] = item;
+ }
+ }
+ }
+ });
+ return result[0];
+ }
+
+ /**
+ * @return the {@link Shell} to use as start to searching {@link Widget}'s.
+ */
+ public Shell getShell() {
+ if (this.shell != null) {
+ if (this.shell.isDisposed()) {
+ this.shell = null;
+ } else {
+ return this.shell;
+ }
+ }
+ return display.getShells()[0];
+ }
+
+ /**
+ * @return {@link Shell} with given text, may be <code>null</code>.
+ */
+ public Shell getShell(String text) {
+ for (Shell shell : display.getShells()) {
+ if (text.equals(shell.getText())) {
+ return shell;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return the {@link TabItem} with given text.
+ */
+ public TabItem getTabItem(final String text) {
+ final TabItem[] result = new TabItem[1];
+ visit(getShell(), new IWidgetsVisitor() {
+ @Override
+ public void endVisit(Widget widget) {
+ if (widget instanceof TabItem) {
+ TabItem item = (TabItem) widget;
+ if (text.equals(item.getText())) {
+ result[0] = item;
+ }
+ }
+ }
+ });
+ return result[0];
+ }
+
+ /**
+ * @return the {@link Text} widget that has {@link Label} with given text.
+ */
+ public Text getTextByLabel(final String labelText) {
+ final Text[] result = new Text[1];
+ visit(getShell(), new IWidgetsVisitor() {
+ private boolean labelFound;
+
+ @Override
+ public void endVisit(Widget widget) {
+ if (widget instanceof Label) {
+ Label label = (Label) widget;
+ labelFound = isSameText(label.getText(), labelText);
+ }
+ if (widget instanceof Text && labelFound) {
+ result[0] = (Text) widget;
+ }
+ }
+ });
+ return result[0];
+ }
+
+ /**
+ * @return the {@link Text} widget that has given text.
+ */
+ public Text getTextByText(final String textText) {
+ final Text[] result = new Text[1];
+ visit(getShell(), new IWidgetsVisitor() {
+ @Override
+ public void endVisit(Widget widget) {
+ if (widget instanceof Text) {
+ Text text = (Text) widget;
+ if (text.getText().equals(textText)) {
+ result[0] = (Text) widget;
+ }
+ }
+ }
+ });
+ return result[0];
+ }
+
+ /**
+ * @return the {@link ToolItem} with given text.
+ */
+ public ToolItem getToolItem(final String text) {
+ final ToolItem[] result = new ToolItem[1];
+ visit(getShell(), new IWidgetsVisitor() {
+ @Override
+ public void endVisit(Widget widget) {
+ if (widget instanceof ToolItem) {
+ ToolItem item = (ToolItem) widget;
+ if (text.equals(item.getText()) || text.equals(item.getToolTipText())) {
+ result[0] = item;
+ }
+ }
+ }
+ });
+ return result[0];
+ }
+
+ /**
+ * @return the {@link TreeItem} with given text.
+ */
+ public TreeItem getTreeItem(final String text) {
+ final TreeItem[] result = new TreeItem[1];
+ visit(getShell(), new IWidgetsVisitor() {
+ @Override
+ public void endVisit(Widget widget) {
+ if (widget instanceof TreeItem) {
+ TreeItem item = (TreeItem) widget;
+ if (text.equals(item.getText())) {
+ result[0] = item;
+ }
+ }
+ }
+ });
+ return result[0];
+ }
+
+ /**
+ * Specifies that it is expected that current {@link Shell} was closed, so we return to previous.
+ */
+ public void popShell() {
+ shell = shells.removeFirst();
+ }
+
+ /**
+ * Sends {@link SWT#Selection} event to given {@link Button}.
+ */
+ public void selectButton(Button button) {
+ // if Button in RADIO, deselect all other RADIO Button's
+ if ((button.getStyle() & SWT.RADIO) != 0) {
+ Control[] children = button.getParent().getChildren();
+ for (int i = 0; i < children.length; i++) {
+ Control child = children[i];
+ if (child instanceof Button && (child.getStyle() & SWT.RADIO) != 0) {
+ Button childButton = (Button) child;
+ if (childButton != button) {
+ selectButton(childButton, false);
+ }
+ }
+ }
+ }
+ // select needed Button
+ button.setFocus();
+ selectButton(button, true);
+ }
+
+ /**
+ * Selects {@link Button} with given text.
+ */
+ public void selectButton(String text) {
+ Button button = getButtonByText(text);
+ Assert.assertNotNull("Can not find button with text |" + text + "|", button);
+ selectButton(button);
+ }
+
+ /**
+ * Sends {@link SWT#Selection} event to given {@link Button}.
+ */
+ public void selectButton(String text, boolean selection) {
+ Button button = getButtonByText(text);
+ Assert.assertNotNull("Can not find button with text |" + text + "|", button);
+ button.setSelection(selection);
+ clickButton(button);
+ }
+
+ public void selectMenuItem(MenuItem menuItem) {
+ selectMenuItem(menuItem, true);
+ }
+
+ /**
+ * Sends {@link SWT#Selection} event to given {@link MenuItem} as radio item.
+ */
+ public void selectMenuItem(MenuItem menuItem, boolean selection) {
+ menuItem.setSelection(selection);
+ click(menuItem);
+ }
+
+ /**
+ * Activates the specified {@link Shell}.
+ */
+ public void useShell(Shell shell) {
+ this.shell = shell;
+ }
+
+ /**
+ * Specifies that {@link Shell} with given text should be used to search {@link Widget}'s.
+ */
+ public Shell useShell(String text) {
+ // remember current Shell
+ shells.addFirst(getShell());
+ // set new Shell
+ for (Shell sh : display.getShells()) {
+ if (text.equals(sh.getText())) {
+ shell = sh;
+ return shell;
+ }
+ }
+ throw new IllegalArgumentException("Unable to find Shell: " + text);
+ }
+
+ /**
+ * Sends {@link SWT#Selection} event to given {@link Button}.
+ */
+ private void selectButton(Button button, boolean selection) {
+ button.setSelection(selection);
+ clickButton(button);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698