All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.testfx.framework.junit5.JavaFXInterceptorUtils Maven / Gradle / Ivy

There is a newer version: 4.0.18
Show newest version
/*
 * Copyright 2013-2014 SmartBear Software
 * Copyright 2014-2023 The TestFX Contributors
 *
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the
 * European Commission - subsequent versions of the EUPL (the "Licence"); You may
 * not use this work except in compliance with the Licence.
 *
 * You may obtain a copy of the Licence at:
 * http://ec.europa.eu/idabc/eupl.html
 *
 * Unless required by applicable law or agreed to in writing, software distributed
 * under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the Licence for the
 * specific language governing permissions and limitations under the Licence.
 */
package org.testfx.framework.junit5;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.InvocationInterceptor;
import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
import org.testfx.framework.junit5.utils.FXUtils;

/**
 * Simple JUnit 5 extension to ensure that {@code @Test} statements are executed
 * in the JavaFX UI thread. This is (strictly) necessary when testing setter
 * and/or getter methods of JavaFX classes (ie. Node derived, properties etc).
 * 

* Use the *

    *
  • {@code @ExtendWith(avaFxInterceptor.class) } if all @Test, or *
  • {@code @ExtendWith(SelectiveJavaFxInterceptor.class) } if only @Test * + @TestFx annotated tests *
* should be executed within the JavaFX UI thread. */ public class JavaFXInterceptorUtils { /** * Simple JUnit 5 extension to ensure that {@code @Test} statements are executed * in the JavaFX UI thread. This is (strictly) necessary when testing setter * and/or getter methods of JavaFX classes (ie. Node derived, properties etc). *

* Example usage: * *

     * 
     * @ExtendWith(ApplicationExtension.class)
     * @ExtendWith(JavaFxInterceptor.class)
     * public class SquareButtonTest {
     *     @Start
     *     public void start(Stage stage) {
     *         // usual FX initialisation
     *         // ...
     *     }
     *
     *    @TestFx
     *    // note: this is equivalent to {@code @Test} when using {@code @ExtendWith(JavaFxInterceptor.class)}
     *    public void testJavaFxThreadSafety() {
     *        // verifies that this test is indeed executed in the JavaFX thread
     *        assertTrue(Platform.isFxApplicationThread());
     *
     *        // perform the regular JavaFX thread safe assertion tests
     *        // ...
     *    }
     *
     *    @Test // also executed in JavaFX thread,
     *    // for different behaviour use:  {@code @ExtendWith(SelectiveJavaFxInterceptor.class)}
     *    public void testNonJavaFx() {
     *        // verifies that this test is also executed in the JavaFX thread
     *        assertTrue(Platform.isFxApplicationThread());
     *
     *        // perform regular assertion tests within the JavaFX thread
     *        // ...
     *    }
     * }
     *
     * 
     * 
*/ public static class JavaFxInterceptor implements InvocationInterceptor { @Override public void interceptTestMethod(final Invocation invocation, final ReflectiveInvocationContext invocationContext, final ExtensionContext extensionContext) throws Throwable { final AtomicReference throwable = new AtomicReference<>(); // N.B. explicit run and wait since the test should only continue // if the previous JavaFX access as been finished. FXUtils.runAndWait(() -> { try { // executes function after @Test invocation.proceed(); } catch (final Throwable t) { throwable.set(t); } }); final Throwable t = throwable.get(); if (t != null) { throw t; } } } /** * Simple JUnit 5 extension to ensure that {@code @Test} statements are executed * in the JavaFX UI thread. This is (strictly) necessary when testing setter * and/or getter methods of JavaFX classes (ie. Node derived, properties etc). *

* Example usage: * *

     * 
     * @ExtendWith(ApplicationExtension.class)
     * @ExtendWith(SelectiveJavaFxInterceptor.class)
     * public class SquareButtonTest {
     *     @Start
     *     public void start(Stage stage) {
     *         // usual FX initialisation
     *         // ...
     *     }
     *
     *    @TestFx // forces execution in JavaFX thread
     *    public void testJavaFxThreadSafety() {
     *        // verifies that this test is indeed executed in the JavaFX thread
     *        assertTrue(Platform.isFxApplicationThread());
     *
     *        // perform the regular JavaFX thread safe assertion tests
     *        // ...
     *    }
     *
     *    @Test // explicitly not executed in JavaFX thread;
     *    // for different behaviour use:  {@code @ExtendWith(JavaFxInterceptor.class)}
     *    public void testNonJavaFx() {
     *        // verifies that this test is not executed within the JavaFX thread
     *        assertFalse(Platform.isFxApplicationThread());
     *
     *        // perform the regular non-JavaFX thread-related assertion tests
     *        // ...
     *    }
     * }
     *
     * 
     * 
*/ public static class SelectiveJavaFxInterceptor implements InvocationInterceptor { @Override public void interceptTestMethod(final Invocation invocation, final ReflectiveInvocationContext invocationContext, final ExtensionContext extensionContext) throws Throwable { final AtomicReference throwable = new AtomicReference<>(); boolean isFxAnnotation = false; final Optional element = extensionContext.getElement(); if (element.isPresent()) { for (final Annotation annotation : element.get().getAnnotations()) { if (annotation.annotationType().equals(TestFx.class)) { isFxAnnotation = true; } } } final Runnable testToBeExecuted = () -> { try { // executes function after @Test invocation.proceed(); } catch (final Throwable t) { throwable.set(t); } }; // N.B. explicit run and wait since the test should only continue // if the previous JavaFX access as been finished. if (isFxAnnotation) { FXUtils.runAndWait(testToBeExecuted); } else { testToBeExecuted.run(); } final Throwable t = throwable.get(); if (t != null) { throw t; } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy