From 1337680ef7f17cd0543a6fbe6aa15a91c1d3e902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Tue, 14 Oct 2025 12:14:56 +0200 Subject: [PATCH] Add a SWTTest Junit extension to allow tests executed in the UI thread Currently we require SWT-UI based tests to be executed by special runners known as the 'UIHarness' to be run in the UI thread, what has several problems: 1) is requires usually to fire up a whole workbench (and a workspace) 2) the whole testsuite has to run in the UI thread 3) no way to customize this further 4) actually this is nothing that belongs into the test framework This now adds a new SWTTest JUnit extension that allows to mark a test class with an extension and get your methods executed in the UI thread. --- binaries/.classpath_cocoa | 1 + binaries/.classpath_gtk | 1 + binaries/.classpath_win32 | 1 + .../build.properties | 2 + .../common/org/eclipse/swt/test/SWTTest.java | 64 +++++++++++++++++++ bundles/org.eclipse.swt/META-INF/MANIFEST.MF | 2 +- 6 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/test/SWTTest.java diff --git a/binaries/.classpath_cocoa b/binaries/.classpath_cocoa index 1793b5a0a6b..629db11a1df 100644 --- a/binaries/.classpath_cocoa +++ b/binaries/.classpath_cocoa @@ -30,4 +30,5 @@ + diff --git a/binaries/.classpath_gtk b/binaries/.classpath_gtk index e51d302489d..64e5ba848f4 100644 --- a/binaries/.classpath_gtk +++ b/binaries/.classpath_gtk @@ -32,4 +32,5 @@ + diff --git a/binaries/.classpath_win32 b/binaries/.classpath_win32 index d57ed0d923c..fd7b50d6127 100644 --- a/binaries/.classpath_win32 +++ b/binaries/.classpath_win32 @@ -32,4 +32,5 @@ + diff --git a/binaries/org.eclipse.swt.gtk.linux.x86_64/build.properties b/binaries/org.eclipse.swt.gtk.linux.x86_64/build.properties index f37c11a4023..fb81ffc11a2 100644 --- a/binaries/org.eclipse.swt.gtk.linux.x86_64/build.properties +++ b/binaries/org.eclipse.swt.gtk.linux.x86_64/build.properties @@ -43,6 +43,8 @@ source.. = \ ../../bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk output.. = bin/ +jars.extra.classpath = platform:/plugin/junit-jupiter-api + pom.model.property.os=linux pom.model.property.ws=gtk pom.model.property.arch=x86_64 diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/test/SWTTest.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/test/SWTTest.java new file mode 100644 index 00000000000..1b5e4b553d3 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/test/SWTTest.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2025 Christoph Läubrich and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.test; + +import java.lang.reflect.*; + +import org.eclipse.pde.api.tools.annotations.*; +import org.eclipse.swt.widgets.*; +import org.junit.jupiter.api.extension.*; + +/** + * The {@link SWTTest} is an extension that can be using in JUnit Platform + * Runners as an extension to execute the test code in the default display + * thread. + *

+ * Usage: You would never use this in any client code but when writing a + * test for the JUnit Platform like in this example: + *

+ *

+ *

+ * @ExtendWith(SWTTest.class)
+ * public class MyTestThaRequireUI {
+ *
+ * }
+ * 
+ *

+ */ +@NoInstantiate +public final class SWTTest implements InvocationInterceptor { + + @Override + public void interceptTestMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, + ExtensionContext extensionContext) throws Throwable { + + if (Display.getCurrent() == null) { + invocation.proceed(); + } else { + Throwable[] throwable = new Throwable[1]; + Display.getDefault().syncExec(() -> { + try { + invocation.proceed(); + } catch (Throwable t) { + throwable[0] = t; + } + + }); + Throwable t = throwable[0]; + if (t != null) { + throw t; + } + } + } +} diff --git a/bundles/org.eclipse.swt/META-INF/MANIFEST.MF b/bundles/org.eclipse.swt/META-INF/MANIFEST.MF index e00e43a3b4f..bd15934bc21 100644 --- a/bundles/org.eclipse.swt/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.swt/META-INF/MANIFEST.MF @@ -5,7 +5,7 @@ Bundle-SymbolicName: org.eclipse.swt; singleton:=true Bundle-Version: 3.132.0.qualifier Bundle-ManifestVersion: 2 Bundle-Localization: plugin -DynamicImport-Package: org.eclipse.swt.accessibility2 +DynamicImport-Package: org.eclipse.swt.accessibility2,org.junit.jupiter.api.extension.* Export-Package: org.eclipse.swt, org.eclipse.swt.accessibility,