Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'tests/junit/plugins/uml/profile/org.eclipse.papyrus.uml.profile.tests/src/org/eclipse/papyrus/uml/profile/tests/DialogInteractionRule.java')
-rw-r--r--tests/junit/plugins/uml/profile/org.eclipse.papyrus.uml.profile.tests/src/org/eclipse/papyrus/uml/profile/tests/DialogInteractionRule.java178
1 files changed, 178 insertions, 0 deletions
diff --git a/tests/junit/plugins/uml/profile/org.eclipse.papyrus.uml.profile.tests/src/org/eclipse/papyrus/uml/profile/tests/DialogInteractionRule.java b/tests/junit/plugins/uml/profile/org.eclipse.papyrus.uml.profile.tests/src/org/eclipse/papyrus/uml/profile/tests/DialogInteractionRule.java
new file mode 100644
index 00000000000..e2b42f79984
--- /dev/null
+++ b/tests/junit/plugins/uml/profile/org.eclipse.papyrus.uml.profile.tests/src/org/eclipse/papyrus/uml/profile/tests/DialogInteractionRule.java
@@ -0,0 +1,178 @@
+/*****************************************************************************
+ * Copyright (c) 2015 Christian W. Damus and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Christian W. Damus - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.uml.profile.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.junit.utils.JUnitUtils;
+import org.eclipse.papyrus.uml.profile.service.ui.RefreshProfileDialog;
+import org.eclipse.swt.SWT;
+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.Shell;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+/**
+ * A JUnit rule that interacts (or not) with the editor's Profile Migration Dialog.
+ */
+public class DialogInteractionRule extends TestWatcher {
+ private DialogInteractionKind interactionMode;
+ private volatile boolean active;
+
+ private final Lock lock = new ReentrantLock();
+ private final Condition dialogInteractionDone = lock.newCondition();
+ private final AtomicReference<Boolean> interactionResult = new AtomicReference<>();
+
+ public void assertInteraction() {
+ waitForInteraction();
+
+ Boolean result = interactionResult.get();
+ assertThat("No dialog interaction occurred", result, notNullValue());
+ assertThat("Expected dialog interaction did not occur: " + interactionMode, result, is(true));
+ }
+
+ @Override
+ protected void starting(Description description) {
+ interactionMode = JUnitUtils.getAnnotation(description, DialogInteractionMode.class).value();
+ active = true;
+
+ Display.getDefault().asyncExec(new InteractionRunnable());
+ }
+
+ @Override
+ protected void finished(Description description) {
+ active = false;
+ }
+
+ protected void waitForInteraction() {
+ Display current = Display.getCurrent();
+
+ if (current != null) {
+ // This is the UI thread. Flush it
+ for (;;) {
+ try {
+ if (!current.readAndDispatch()) {
+ break;
+ }
+ } catch (Exception e) {
+ // It may provide diagnostic information for the test
+ e.printStackTrace();
+ }
+ }
+ } else {
+ // Synchronize with the UI thread
+ Display.getDefault().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ // Pass
+ }
+ });
+ }
+ }
+
+ static <W extends Window> W findWindow(Class<W> windowType) {
+ W result = null;
+
+ for (Shell next : Display.getDefault().getShells()) {
+ if (windowType.isInstance(next.getData())) {
+ result = windowType.cast(next.getData());
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ static Button findButton(Composite composite, int code) {
+ Button result = null;
+
+ Integer id = code;
+ Control[] controls = composite.getChildren();
+ for (int i = 0; (i < controls.length) && (result == null); i++) {
+ final Control next = controls[i];
+
+ if (next instanceof Button) {
+ Button button = (Button) next;
+ if (id.equals(button.getData())) {
+ result = button;
+ }
+ } else if (next instanceof Composite) {
+ result = findButton((Composite) next, code);
+ }
+ }
+
+ return result;
+ }
+
+ //
+ // Nested types
+ //
+
+ /**
+ * An asynchronous UI runnable that is schedule to run after the editor has opened,
+ * and so after it has shown the profile migration dialog (if any), to interact with
+ * it if it is open.
+ */
+ private class InteractionRunnable implements Runnable {
+ @Override
+ public void run() {
+ Boolean result = false;
+
+ if (active) {
+ RefreshProfileDialog dialog = findWindow(RefreshProfileDialog.class);
+
+ switch (interactionMode) {
+ case CANCEL:
+ if (dialog != null) {
+ result = true;
+ findButton(dialog.getShell(), IDialogConstants.CANCEL_ID).notifyListeners(SWT.Selection, new Event());
+ }
+ break;
+ case OK:
+ if (dialog != null) {
+ result = true;
+ findButton(dialog.getShell(), IDialogConstants.OK_ID).notifyListeners(SWT.Selection, new Event());
+ }
+ break;
+ default: // NONE
+ result = dialog == null;
+ break;
+ }
+ }
+
+ lock.lock();
+
+ try {
+ interactionResult.set(result);
+ dialogInteractionDone.signalAll();
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+}

Back to the top