diff --git a/.github/workflows/gradle-dependencies.yaml b/.github/workflows/gradle-dependencies.yaml new file mode 100644 index 00000000..20936958 --- /dev/null +++ b/.github/workflows/gradle-dependencies.yaml @@ -0,0 +1,19 @@ +name: Gradle Dependency Submission + +on: + push: + paths: + - '**/*.gradle' + - '.github/workflows/dependencies.yaml' + +permissions: + contents: write + +jobs: + dependency-submission: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + - name: Generate and submit dependency graph + uses: gradle/actions/dependency-submission@v3 diff --git a/README.md b/README.md index 5fb9e272..d9693608 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# ☕ fulibFx +# ☕ fulibFx +[![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/javadoc.svg?style=for-the-badge&color=green)](https://javadoc.io/doc/org.fulib/fulibFx) ![Java 17/21](https://img.shields.io/github/actions/workflow/status/fujaba/fulibFx/java-ci-cd.yaml?style=for-the-badge&logo=github&color=green) [![GH Pages](https://img.shields.io/badge/GH_Pages-Click_here-green?style=for-the-badge&logo=github)](https://fujaba.github.io/fulibFx) fulibFx is a versatile framework for JavaFX applications that is specifically designed for MVC pattern projects. It provides a simple way to create and manage controllers, views, routes, subcomponents, modals, and more. @@ -125,7 +126,7 @@ When developing an application, it is often necessary to reload the application a way to [refresh a controller](docs/features/3-history.md) without having to reload the whole application. This can be done by calling the `refresh` method - +GIF showing the hot reload feature ### 🧷 Utilities diff --git a/annotation-processor/build.gradle b/annotation-processor/build.gradle index 4d61c278..ad32817e 100644 --- a/annotation-processor/build.gradle +++ b/annotation-processor/build.gradle @@ -20,14 +20,10 @@ repositories { // Project dependencies dependencies { - // https://mvnrepository.com/artifact/com.google.auto.service/auto-service-annotations - implementation group: 'com.google.auto.service', name: 'auto-service-annotations', version: '1.1.1' + implementation group: 'com.google.auto.service', name: 'auto-service-annotations', version: autoServiceVersion + annotationProcessor group: 'com.google.auto.service', name: 'auto-service', version: autoServiceVersion - // https://mvnrepository.com/artifact/com.google.auto.service/auto-service - annotationProcessor group: 'com.google.auto.service', name: 'auto-service', version: '1.1.1' - - // Framework - implementation project(":framework") + implementation project(':framework') } // ------------------- Build ------------------- diff --git a/build.gradle b/build.gradle index f56e1ce6..fecd8c1d 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ allprojects { 'java.awt.headless': 'true', 'testfx.robot': 'glass', 'testfx.headless': 'true', + 'headless.geometry': '1920x1080-32', 'glass.platform': 'Monocle', 'monocle.platform': 'Headless', 'prism.order': 'sw', diff --git a/docs/controller/1-controllers.md b/docs/controller/1-controllers.md index 6b78dc5d..fb5c5c74 100644 --- a/docs/controller/1-controllers.md +++ b/docs/controller/1-controllers.md @@ -1,4 +1,4 @@ -# Controller +# Controller [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/annotation/controller/Controller.html) Controllers are the backbone of your application. To set up a controller, create a class where the controller logic will be defined and annotate it with `@Controller`. @@ -11,7 +11,7 @@ public class TodoController { } ``` -### Events +### Events [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/annotation/event/package-summary.html) Within your controller class, you have the ability to define methods that are automatically triggered when the controller is initialized, rendered or destroyed. These methods should be annotated with either `@onInit`, `@onRender` diff --git a/docs/controller/10-key-events.md b/docs/controller/10-key-events.md index 5d3c5c42..c8e38087 100644 --- a/docs/controller/10-key-events.md +++ b/docs/controller/10-key-events.md @@ -1,4 +1,4 @@ -# Keyboard Listener +# Keyboard Listener [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/annotation/event/onKey.html) The framework provides an easy way of registering keybinds for a controller. By using the `@onKey` annotation, you can define methods that will be called when a key is pressed. diff --git a/docs/controller/2-components.md b/docs/controller/2-components.md index e87506e3..bfd9d2c2 100644 --- a/docs/controller/2-components.md +++ b/docs/controller/2-components.md @@ -1,4 +1,4 @@ -# Components +# Components [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/annotation/controller/Component.html) Components are a special type of controller that can be used to create reusable components. Components have to extend from a JavaFX Parent (or any class extending from Parent) and have to be annotated with `@Component`. diff --git a/docs/controller/4-parameters.md b/docs/controller/4-parameters.md index a3980f09..07abf369 100644 --- a/docs/controller/4-parameters.md +++ b/docs/controller/4-parameters.md @@ -1,4 +1,4 @@ -# Parameters +# Parameters [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/annotation/param/package-summary.html) To pass parameters to a controller, an additional argument can be provided to the show method, consisting of a map of strings and objects. The strings specify the argument's name and the objects are the value of the argument. For example, diff --git a/docs/controller/5-internationalization.md b/docs/controller/5-internationalization.md index b9d2a404..7df8aa85 100644 --- a/docs/controller/5-internationalization.md +++ b/docs/controller/5-internationalization.md @@ -1,4 +1,4 @@ -# Internationalization +# Internationalization [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/annotation/controller/Resource.html) In order to use resource bundles in your controller's FXML file, you have to provide an instance of the resource bundle to the framework. This can be done by creating a field containing your instance (e.g. with Dagger) and annotating it with `@Resource`. diff --git a/docs/controller/6-titles.md b/docs/controller/6-titles.md index a049d55b..d6d782fb 100644 --- a/docs/controller/6-titles.md +++ b/docs/controller/6-titles.md @@ -1,4 +1,4 @@ -# Titles +# Titles [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/annotation/controller/Title.html) The title of a controller or component can be set by annotating The class with `@Title`. The annotation takes an argument specifying the title of the controller or component. diff --git a/docs/controller/7-routing.md b/docs/controller/7-routing.md index 74213a6e..e90e4cb8 100644 --- a/docs/controller/7-routing.md +++ b/docs/controller/7-routing.md @@ -1,4 +1,4 @@ -# Routing +# Routing [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/annotation/Route.html) Routes are the main way to navigate between views. To set up routes to different views, you have to create a class where the routes will be defined. diff --git a/docs/controller/8-subcomponents.md b/docs/controller/8-subcomponents.md index 301fd75e..b938d0a1 100644 --- a/docs/controller/8-subcomponents.md +++ b/docs/controller/8-subcomponents.md @@ -1,4 +1,4 @@ -# Subcomponents +# Subcomponents [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/annotation/controller/SubComponent.html) Components can be used inside other controllers to reduce the complexity of a single controller by moving some features into subcomponents (also called subcomponents). diff --git a/docs/features/1-subscriber.md b/docs/features/1-subscriber.md index 7cb3fb8f..b4b64412 100644 --- a/docs/features/1-subscriber.md +++ b/docs/features/1-subscriber.md @@ -1,4 +1,4 @@ -# Subscriber +# Subscriber [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/controller/Subscriber.html) By creating a new `Subscriber` instance (or by using dependency injection to provide one) and using its utility methods, you can easily manage subscriptions without having to worry about disposing them one by one. Using `subscriber.dispose()` diff --git a/docs/features/2-for.md b/docs/features/2-for.md index 8acc4349..642ec12f 100644 --- a/docs/features/2-for.md +++ b/docs/features/2-for.md @@ -1,4 +1,4 @@ -# For-Loops +# For-Loops [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/constructs/FxFor.html) For-Loops can be used to easily display a node/subcomponent for all items in a list. Whenever an item is added to or removed from the list, the list of nodes updates accordingly. diff --git a/docs/features/4-modals.md b/docs/features/4-modals.md index 7f16dd1c..474769d8 100644 --- a/docs/features/4-modals.md +++ b/docs/features/4-modals.md @@ -1,4 +1,4 @@ -# Modals +# Modals [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/controller/Modals.html) Modals are a special type of window that can be used to display a controller on top of another controller. Modals can be used to display popup windows, dialogs, etc. diff --git a/docs/features/5-node-duplicator.md b/docs/features/5-node-duplicator.md index a63c64b6..5cf8ca3d 100644 --- a/docs/features/5-node-duplicator.md +++ b/docs/features/5-node-duplicator.md @@ -1,4 +1,4 @@ -# Node duplication +# Node duplication [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/duplicate/Duplicators.html) As JavaFX by itself doesn't support the duplication of nodes, the framework implements its own duplication logic in the form of `Duplicator`s. The framework includes duplicators for most of the diff --git a/docs/features/6-data-structures.md b/docs/features/6-data-structures.md index 2f5d20b5..c1a51ab2 100644 --- a/docs/features/6-data-structures.md +++ b/docs/features/6-data-structures.md @@ -1,20 +1,20 @@ # Other Data structures The framework provides a few data structures that can be used to simplify the creation of JavaFX applications. -### Duplicator +### Duplicator [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/duplicate/Duplicators.html) A `Duplicator` is a functional interface that takes an object and returns a duplicate of the object. It can be used to create copies of Objects such as JavaFX nodes. The framework used Duplicators for the For-Loops. For more information, see the section about [Node duplication](5-node-duplicator.md). -### Subscriber +### Subscriber [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/controller/Subscriber.html) The `Subscriber` is a utility class that can be used to manage subscriptions. It can be used to subscribe to observables without having to worry about disposing them one by one. For more information, see the section about [subscriptions](1-subscriber.md). -### RefreshableDisposable +### RefreshableDisposable [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/data/disposable/RefreshableDisposable.html) The `RefreshableDisposable` is an interface defining disposables that can be refreshed. Refreshing a disposable will make it usable again, after it has been disposed. An example for this is the `RefreshableCompositeDisposable`. -### ItemListDisposable +### ItemListDisposable [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/data/disposable/ItemListDisposable.html) The `ItemListDisposable` will run an action for all added items upon disposal. This can be used to clean up items in a list with a certain action in a single disposable. @@ -24,14 +24,14 @@ disposable.add("Hello"); disposable.dispose(); // Will print "Hello", "World" and "!" to the console (LIFO order) ``` -### TraversableQueue +### TraversableQueue [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/doc/org.fulib/fulibFx/latest/org/fulib/fx/data/TraversableQueue.html) A `TraversableQueue` is a queue that saves the latest n entries made to it. Like a normal queue, it can be used to store items in a FIFO order. When the queue is full, the oldest item will be removed. However, it also provides methods to traverse the queue, meaning you can go back and forth between items in the queue. When you go back in the queue and add a new item, all items after the current item will be removed. This can be compared to the history of a browser and is used for the history of routes. -### Either +### Either [![Javadocs](https://javadoc.io/badge2/org.fulib/fulibFx/Javadocs.svg?color=green)](https://javadoc.io/static/org.fulib/fulibFx/0.1.1/org/fulib/fx/data/Either.html) The `Either` class combines two optionals into a single object. It used to represent a value with two possible types. The framework uses it for the history, where the `Either` can be either a controller or a route. It has some methods for checking which type it is and for getting the value correct value. diff --git a/framework/build.gradle b/framework/build.gradle index b421aeb4..c9005a2e 100644 --- a/framework/build.gradle +++ b/framework/build.gradle @@ -2,8 +2,7 @@ plugins { id "java" id 'maven-publish' id 'signing' - // https://plugins.gradle.org/plugin/org.openjfx.javafxplugin - id "org.openjfx.javafxplugin" version "0.1.0" + id "org.openjfx.javafxplugin" version "$javaFxPluginVersion" } group = projectGroup @@ -22,51 +21,32 @@ repositories { // JavaFX dependencies javafx { - version = '21.0.2' + version = javaFxVersion modules = ['javafx.controls', 'javafx.graphics', 'javafx.fxml', 'javafx.media'] } // Project dependencies dependencies { - // https://mvnrepository.com/artifact/org.jetbrains/annotations - implementation group: 'org.jetbrains', name: 'annotations', version: '24.1.0' + implementation group: 'org.jetbrains', name: 'annotations', version: jetbrainsAnnotationsVersion + implementation group: 'io.reactivex.rxjava3', name: 'rxjava', version: rxJavaVersion - // https://mvnrepository.com/artifact/com.google.dagger/dagger - implementation group: 'com.google.dagger', name: 'dagger', version: '2.51' - - // https://mvnrepository.com/artifact/com.google.dagger/dagger-compiler - annotationProcessor group: 'com.google.dagger', name: 'dagger-compiler', version: '2.51' - - // https://mvnrepository.com/artifact/io.reactivex.rxjava3/rxjava - implementation group: 'io.reactivex.rxjava3', name: 'rxjava', version: '3.1.8' + implementation group: 'com.google.dagger', name: 'dagger', version: daggerVersion + annotationProcessor group: 'com.google.dagger', name: 'dagger-compiler', version: daggerVersion } // ------------------- Tests ------------------- // Test dependencies dependencies { + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: junitJupiterVersion + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitJupiterVersion - // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.1' - - // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine - testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.1' - - // https://mvnrepository.com/artifact/org.testfx/testfx-junit5 - testImplementation group: 'org.testfx', name: 'testfx-junit5', version: '4.0.17' - - // https://mvnrepository.com/artifact/org.hamcrest/hamcrest - testImplementation group: 'org.hamcrest', name: 'hamcrest', version: '2.2' - - // https://mvnrepository.com/artifact/org.testfx/openjfx-monocle - testImplementation group: 'org.testfx', name: 'openjfx-monocle', version: '17.0.10' - - // https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter - testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: '5.11.0' - - // https://mvnrepository.com/artifact/com.google.dagger/dagger-compiler - testAnnotationProcessor group: 'com.google.dagger', name: 'dagger-compiler', version: '2.51' + testImplementation group: 'org.testfx', name: 'testfx-junit5', version: testFxVersion + testImplementation group: 'org.testfx', name: 'openjfx-monocle', version: monocleVersion + testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: mockitoVersion + testImplementation group: 'org.hamcrest', name: 'hamcrest', version: hamcrestVersion + testAnnotationProcessor group: 'com.google.dagger', name: 'dagger-compiler', version: daggerVersion } test { diff --git a/framework/src/test/java/org/fulib/fx/app/FrameworkTest.java b/framework/src/test/java/org/fulib/fx/app/FrameworkTest.java index a144d39f..09b9b7a8 100644 --- a/framework/src/test/java/org/fulib/fx/app/FrameworkTest.java +++ b/framework/src/test/java/org/fulib/fx/app/FrameworkTest.java @@ -1,12 +1,15 @@ package org.fulib.fx.app; +import javafx.application.Platform; import org.fulib.fx.FulibFxApp; -import org.fulib.fx.app.controllertypes.BasicComponent; -import org.fulib.fx.app.history.AController; -import org.fulib.fx.app.history.BController; -import org.fulib.fx.app.history.CController; -import org.fulib.fx.app.modal.ModalComponent; -import org.fulib.fx.app.controllertypes.sub.ButtonSubComponent; +import org.fulib.fx.app.controller.types.BasicComponent; +import org.fulib.fx.app.controller.ParamController; +import org.fulib.fx.app.controller.TitleController; +import org.fulib.fx.app.controller.history.AController; +import org.fulib.fx.app.controller.history.BController; +import org.fulib.fx.app.controller.history.CController; +import org.fulib.fx.app.controller.ModalComponent; +import org.fulib.fx.app.controller.subcomponent.basic.ButtonSubComponent; import org.fulib.fx.controller.Modals; import org.fulib.fx.controller.exception.ControllerInvalidRouteException; import org.fulib.fx.controller.exception.IllegalControllerException; @@ -28,6 +31,11 @@ public class FrameworkTest extends ApplicationTest { + public static void runAndWait(Runnable runnable) { + Platform.runLater(runnable); + waitForFxEvents(); + } + public final FulibFxApp app = new FulibFxApp() { final TestComponent component = DaggerTestComponent.builder().mainApp(this).build(); @@ -46,32 +54,38 @@ public void start(Stage stage) throws Exception { stage.requestFocus(); } + @Test + public void title() { + runAndWait(() -> app.show(new TitleController())); + assertEquals("Title", app.stage().getTitle()); + } + /** * Tests if the framework is able to load the routes and different kinds of controllers. */ @Test public void controllerTypes() { - app.show("/controller/basic"); + runAndWait(() -> app.show("/controller/basic")); verifyThat("Basic Controller", Node::isVisible); sleep(200); - app.show("/controller/method"); + runAndWait(() -> app.show("/controller/method")); verifyThat("Method Controller", Node::isVisible); sleep(200); - app.show("/controller/view"); + runAndWait(() -> app.show("/controller/view")); verifyThat("View Controller", Node::isVisible); sleep(200); - app.show("/component/basic"); + runAndWait(() -> app.show("/component/basic")); verifyThat("Basic Component", Node::isVisible); sleep(200); - app.show("/component/root"); + runAndWait(() -> app.show("/component/root")); verifyThat("Root Component", Node::isVisible); sleep(200); - app.show("../root"); + runAndWait(() -> app.show("../root")); verifyThat("Root Component", Node::isVisible); sleep(200); @@ -86,7 +100,7 @@ public void controllerTypes() { */ @Test public void subComponent() { - app.show("/controller/withsubcomponent"); + runAndWait(() -> app.show("/controller/withsubcomponent")); sleep(200); ButtonSubComponent button = lookup("#buttonSubComponent").query(); verifyThat(button, Node::isVisible); @@ -97,7 +111,7 @@ public void subComponent() { public void routeSubComponent() { assertThrows(IllegalArgumentException.class, () -> app.initAndRender("/controller/view")); - assertEquals(BasicComponent.class, app.initAndRender("/component/basic").getClass()); + runAndWait(() -> assertEquals(BasicComponent.class, app.initAndRender("/component/basic").getClass())); } /** @@ -112,7 +126,7 @@ public void simpleForTest() { list.add("!"); }); - app.show("/controller/for", Map.of("list", list)); + runAndWait(() -> app.show("/controller/for", Map.of("list", list))); verifyThat("#container", Node::isVisible); VBox container = lookup("#container").queryAs(VBox.class); @@ -135,20 +149,20 @@ public void testSubOrder() { List renderList = new ArrayList<>(); List destroyList = new ArrayList<>(); - app.show("/ordertest/main", Map.of("initList", initList, "renderList", renderList, "destroyList", destroyList)); + runAndWait(() -> app.show("/ordertest/main", Map.of("initList", initList, "renderList", renderList, "destroyList", destroyList))); assertEquals(List.of("main", "sub", "subsub", "othersubsub"), initList); assertEquals(List.of("subsub", "othersubsub", "sub", "main"), renderList); assertEquals(List.of(), destroyList); - app.show("/controller/basic"); + runAndWait(() -> app.show("/controller/basic")); assertEquals(List.of("othersubsub", "subsub", "sub", "main"), destroyList); } @Test public void modalTest() { - app.show("/controller/basic"); + runAndWait(() -> app.show("/controller/basic")); verifyThat("Basic Controller", Node::isVisible); sleep(200); @@ -178,7 +192,7 @@ public void params() { "character", 'a', "bool", true ); - app.show(controller, params); + runAndWait(() -> app.show(controller, params)); assertEquals(1, controller.getOnInitParam()); assertEquals("string", controller.getSetterParam()); @@ -196,31 +210,31 @@ public void params() { @Test public void history() { - app.show(new AController(), Map.of("string", "a")); + runAndWait(() -> app.show(new AController(), Map.of("string", "a"))); verifyThat("A:a", Node::isVisible); - app.show(new BController(), Map.of("string", "b")); + runAndWait(() -> app.show(new BController(), Map.of("string", "b"))); verifyThat("B:b", Node::isVisible); - app.show(new CController(), Map.of("string", "c")); + runAndWait(() -> app.show(new CController(), Map.of("string", "c"))); verifyThat("C:c", Node::isVisible); - app.back(); + runAndWait(app::back); verifyThat("B:b", Node::isVisible); - app.back(); + runAndWait(app::back); verifyThat("A:a", Node::isVisible); - app.forward(); + runAndWait(app::forward); verifyThat("B:b", Node::isVisible); - app.forward(); + runAndWait(app::forward); verifyThat("C:c", Node::isVisible); - app.forward(); + runAndWait(app::forward); verifyThat("C:c", Node::isVisible); // should not change - app.back(); + runAndWait(app::back); verifyThat("B:b", Node::isVisible); FulibFxApp.FX_SCHEDULER.scheduleDirect(app::refresh); diff --git a/framework/src/test/java/org/fulib/fx/app/TestRouting.java b/framework/src/test/java/org/fulib/fx/app/TestRouting.java index 4c286e19..47063426 100644 --- a/framework/src/test/java/org/fulib/fx/app/TestRouting.java +++ b/framework/src/test/java/org/fulib/fx/app/TestRouting.java @@ -1,8 +1,11 @@ package org.fulib.fx.app; import org.fulib.fx.annotation.Route; -import org.fulib.fx.app.controllertypes.*; -import org.fulib.fx.app.subcontrollertest.MainController; +import org.fulib.fx.app.controller.*; +import org.fulib.fx.app.controller.subcomponent.basic.SubComponentController; +import org.fulib.fx.app.controller.types.*; +import org.fulib.fx.app.controller.types.invalid.NonExtendingComponent; +import org.fulib.fx.app.controller.subcomponent.order.MainController; import javax.inject.Inject; import javax.inject.Provider; @@ -23,7 +26,7 @@ public class TestRouting { @Inject @Route("controller/view") - Provider viewControllerProvider; + Provider viewControllerProvider; @Inject @Route("controller/method") diff --git a/framework/src/test/java/org/fulib/fx/app/controllertypes/ForController.java b/framework/src/test/java/org/fulib/fx/app/controller/ForController.java similarity index 91% rename from framework/src/test/java/org/fulib/fx/app/controllertypes/ForController.java rename to framework/src/test/java/org/fulib/fx/app/controller/ForController.java index 76da4c6e..ffbb7439 100644 --- a/framework/src/test/java/org/fulib/fx/app/controllertypes/ForController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/ForController.java @@ -1,11 +1,11 @@ -package org.fulib.fx.app.controllertypes; +package org.fulib.fx.app.controller; import org.fulib.fx.annotation.controller.Controller; import org.fulib.fx.annotation.controller.SubComponent; import org.fulib.fx.annotation.event.onDestroy; import org.fulib.fx.annotation.event.onRender; import org.fulib.fx.annotation.param.Param; -import org.fulib.fx.app.controllertypes.sub.ButtonSubComponent; +import org.fulib.fx.app.controller.subcomponent.basic.ButtonSubComponent; import javafx.collections.ObservableList; import javafx.scene.control.Labeled; import javafx.scene.layout.VBox; diff --git a/framework/src/test/java/org/fulib/fx/app/modal/ModalComponent.java b/framework/src/test/java/org/fulib/fx/app/controller/ModalComponent.java similarity index 89% rename from framework/src/test/java/org/fulib/fx/app/modal/ModalComponent.java rename to framework/src/test/java/org/fulib/fx/app/controller/ModalComponent.java index a3b7e1d7..7cd79997 100644 --- a/framework/src/test/java/org/fulib/fx/app/modal/ModalComponent.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/ModalComponent.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.modal; +package org.fulib.fx.app.controller; import org.fulib.fx.annotation.controller.Component; import javafx.scene.control.Label; diff --git a/framework/src/test/java/org/fulib/fx/app/ParamController.java b/framework/src/test/java/org/fulib/fx/app/controller/ParamController.java similarity index 98% rename from framework/src/test/java/org/fulib/fx/app/ParamController.java rename to framework/src/test/java/org/fulib/fx/app/controller/ParamController.java index 4915bb55..6b6143c1 100644 --- a/framework/src/test/java/org/fulib/fx/app/ParamController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/ParamController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app; +package org.fulib.fx.app.controller; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; diff --git a/framework/src/test/java/org/fulib/fx/app/controller/TitleController.java b/framework/src/test/java/org/fulib/fx/app/controller/TitleController.java new file mode 100644 index 00000000..738779cc --- /dev/null +++ b/framework/src/test/java/org/fulib/fx/app/controller/TitleController.java @@ -0,0 +1,15 @@ +package org.fulib.fx.app.controller; + +import javafx.scene.layout.VBox; +import org.fulib.fx.annotation.controller.Controller; +import org.fulib.fx.annotation.controller.Title; + +@Title("Title") +@Controller(view = "#view") +public class TitleController { + + public VBox view() { + return new VBox(); + } + +} diff --git a/framework/src/test/java/org/fulib/fx/app/history/AController.java b/framework/src/test/java/org/fulib/fx/app/controller/history/AController.java similarity index 92% rename from framework/src/test/java/org/fulib/fx/app/history/AController.java rename to framework/src/test/java/org/fulib/fx/app/controller/history/AController.java index e3b3ed1e..905ad710 100644 --- a/framework/src/test/java/org/fulib/fx/app/history/AController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/history/AController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.history; +package org.fulib.fx.app.controller.history; import javafx.scene.control.Label; import javafx.scene.layout.VBox; diff --git a/framework/src/test/java/org/fulib/fx/app/history/BController.java b/framework/src/test/java/org/fulib/fx/app/controller/history/BController.java similarity index 92% rename from framework/src/test/java/org/fulib/fx/app/history/BController.java rename to framework/src/test/java/org/fulib/fx/app/controller/history/BController.java index 93184bd9..5af4ce66 100644 --- a/framework/src/test/java/org/fulib/fx/app/history/BController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/history/BController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.history; +package org.fulib.fx.app.controller.history; import javafx.scene.control.Label; import javafx.scene.layout.VBox; diff --git a/framework/src/test/java/org/fulib/fx/app/history/CController.java b/framework/src/test/java/org/fulib/fx/app/controller/history/CController.java similarity index 92% rename from framework/src/test/java/org/fulib/fx/app/history/CController.java rename to framework/src/test/java/org/fulib/fx/app/controller/history/CController.java index df320215..b820f61b 100644 --- a/framework/src/test/java/org/fulib/fx/app/history/CController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/history/CController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.history; +package org.fulib.fx.app.controller.history; import javafx.scene.control.Label; import javafx.scene.layout.VBox; diff --git a/framework/src/test/java/org/fulib/fx/app/controllertypes/sub/ButtonSubComponent.java b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/basic/ButtonSubComponent.java similarity index 83% rename from framework/src/test/java/org/fulib/fx/app/controllertypes/sub/ButtonSubComponent.java rename to framework/src/test/java/org/fulib/fx/app/controller/subcomponent/basic/ButtonSubComponent.java index e7cc7cda..1ebc3911 100644 --- a/framework/src/test/java/org/fulib/fx/app/controllertypes/sub/ButtonSubComponent.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/basic/ButtonSubComponent.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.controllertypes.sub; +package org.fulib.fx.app.controller.subcomponent.basic; import org.fulib.fx.annotation.controller.Component; import javafx.scene.control.Button; diff --git a/framework/src/test/java/org/fulib/fx/app/controllertypes/SubComponentController.java b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/basic/SubComponentController.java similarity index 78% rename from framework/src/test/java/org/fulib/fx/app/controllertypes/SubComponentController.java rename to framework/src/test/java/org/fulib/fx/app/controller/subcomponent/basic/SubComponentController.java index 029a1372..45193ec6 100644 --- a/framework/src/test/java/org/fulib/fx/app/controllertypes/SubComponentController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/basic/SubComponentController.java @@ -1,8 +1,7 @@ -package org.fulib.fx.app.controllertypes; +package org.fulib.fx.app.controller.subcomponent.basic; import org.fulib.fx.annotation.controller.Controller; import org.fulib.fx.annotation.controller.SubComponent; -import org.fulib.fx.app.controllertypes.sub.ButtonSubComponent; import javafx.fxml.FXML; import javax.inject.Inject; diff --git a/framework/src/test/java/org/fulib/fx/app/subcontrollertest/MainController.java b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/MainController.java similarity index 94% rename from framework/src/test/java/org/fulib/fx/app/subcontrollertest/MainController.java rename to framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/MainController.java index 67562227..8897dbb3 100644 --- a/framework/src/test/java/org/fulib/fx/app/subcontrollertest/MainController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/MainController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.subcontrollertest; +package org.fulib.fx.app.controller.subcomponent.order; import org.fulib.fx.annotation.controller.Controller; import org.fulib.fx.annotation.controller.SubComponent; diff --git a/framework/src/test/java/org/fulib/fx/app/subcontrollertest/OtherSubSubController.java b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/OtherSubSubController.java similarity index 93% rename from framework/src/test/java/org/fulib/fx/app/subcontrollertest/OtherSubSubController.java rename to framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/OtherSubSubController.java index 3ab70c41..bc2f6827 100644 --- a/framework/src/test/java/org/fulib/fx/app/subcontrollertest/OtherSubSubController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/OtherSubSubController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.subcontrollertest; +package org.fulib.fx.app.controller.subcomponent.order; import org.fulib.fx.annotation.controller.Component; import org.fulib.fx.annotation.event.onDestroy; diff --git a/framework/src/test/java/org/fulib/fx/app/subcontrollertest/SubController.java b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/SubController.java similarity index 94% rename from framework/src/test/java/org/fulib/fx/app/subcontrollertest/SubController.java rename to framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/SubController.java index 951e0de1..2f57b952 100644 --- a/framework/src/test/java/org/fulib/fx/app/subcontrollertest/SubController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/SubController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.subcontrollertest; +package org.fulib.fx.app.controller.subcomponent.order; import org.fulib.fx.annotation.controller.Component; import org.fulib.fx.annotation.controller.SubComponent; diff --git a/framework/src/test/java/org/fulib/fx/app/subcontrollertest/SubSubController.java b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/SubSubController.java similarity index 93% rename from framework/src/test/java/org/fulib/fx/app/subcontrollertest/SubSubController.java rename to framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/SubSubController.java index 9f747c14..260a1d94 100644 --- a/framework/src/test/java/org/fulib/fx/app/subcontrollertest/SubSubController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/subcomponent/order/SubSubController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.subcontrollertest; +package org.fulib.fx.app.controller.subcomponent.order; import org.fulib.fx.annotation.controller.Component; import org.fulib.fx.annotation.event.onDestroy; diff --git a/framework/src/test/java/org/fulib/fx/app/controllertypes/BasicComponent.java b/framework/src/test/java/org/fulib/fx/app/controller/types/BasicComponent.java similarity index 88% rename from framework/src/test/java/org/fulib/fx/app/controllertypes/BasicComponent.java rename to framework/src/test/java/org/fulib/fx/app/controller/types/BasicComponent.java index a1583196..fee9a13e 100644 --- a/framework/src/test/java/org/fulib/fx/app/controllertypes/BasicComponent.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/types/BasicComponent.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.controllertypes; +package org.fulib.fx.app.controller.types; import org.fulib.fx.annotation.controller.Component; import javafx.scene.control.Label; diff --git a/framework/src/test/java/org/fulib/fx/app/controllertypes/BasicController.java b/framework/src/test/java/org/fulib/fx/app/controller/types/BasicController.java similarity index 88% rename from framework/src/test/java/org/fulib/fx/app/controllertypes/BasicController.java rename to framework/src/test/java/org/fulib/fx/app/controller/types/BasicController.java index 98df643b..a6dcd269 100644 --- a/framework/src/test/java/org/fulib/fx/app/controllertypes/BasicController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/types/BasicController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.controllertypes; +package org.fulib.fx.app.controller.types; import org.fulib.fx.annotation.controller.Controller; diff --git a/framework/src/test/java/org/fulib/fx/app/controllertypes/ViewController.java b/framework/src/test/java/org/fulib/fx/app/controller/types/FXMLController.java similarity index 52% rename from framework/src/test/java/org/fulib/fx/app/controllertypes/ViewController.java rename to framework/src/test/java/org/fulib/fx/app/controller/types/FXMLController.java index 346e9eb2..ba4232c8 100644 --- a/framework/src/test/java/org/fulib/fx/app/controllertypes/ViewController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/types/FXMLController.java @@ -1,14 +1,14 @@ -package org.fulib.fx.app.controllertypes; +package org.fulib.fx.app.controller.types; import org.fulib.fx.annotation.controller.Controller; import javax.inject.Inject; -@Controller(view = "../view/View.fxml") -public class ViewController { +@Controller(view = "../view/View.fxml") // Path traversal +public class FXMLController { @Inject - public ViewController() { + public FXMLController() { // The FXML file contains a label with the text "View Controller" } } diff --git a/framework/src/test/java/org/fulib/fx/app/controllertypes/MethodController.java b/framework/src/test/java/org/fulib/fx/app/controller/types/MethodController.java similarity index 90% rename from framework/src/test/java/org/fulib/fx/app/controllertypes/MethodController.java rename to framework/src/test/java/org/fulib/fx/app/controller/types/MethodController.java index c27acde3..dffbecbf 100644 --- a/framework/src/test/java/org/fulib/fx/app/controllertypes/MethodController.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/types/MethodController.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.controllertypes; +package org.fulib.fx.app.controller.types; import org.fulib.fx.annotation.controller.Controller; import javafx.scene.control.Label; diff --git a/framework/src/test/java/org/fulib/fx/app/controllertypes/RootComponent.java b/framework/src/test/java/org/fulib/fx/app/controller/types/RootComponent.java similarity index 90% rename from framework/src/test/java/org/fulib/fx/app/controllertypes/RootComponent.java rename to framework/src/test/java/org/fulib/fx/app/controller/types/RootComponent.java index b339b554..3fee1c00 100644 --- a/framework/src/test/java/org/fulib/fx/app/controllertypes/RootComponent.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/types/RootComponent.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.controllertypes; +package org.fulib.fx.app.controller.types; import org.fulib.fx.annotation.controller.Component; import javafx.fxml.FXML; diff --git a/framework/src/test/java/org/fulib/fx/app/controllertypes/NonExtendingComponent.java b/framework/src/test/java/org/fulib/fx/app/controller/types/invalid/NonExtendingComponent.java similarity index 78% rename from framework/src/test/java/org/fulib/fx/app/controllertypes/NonExtendingComponent.java rename to framework/src/test/java/org/fulib/fx/app/controller/types/invalid/NonExtendingComponent.java index de6110a6..62990767 100644 --- a/framework/src/test/java/org/fulib/fx/app/controllertypes/NonExtendingComponent.java +++ b/framework/src/test/java/org/fulib/fx/app/controller/types/invalid/NonExtendingComponent.java @@ -1,4 +1,4 @@ -package org.fulib.fx.app.controllertypes; +package org.fulib.fx.app.controller.types.invalid; import org.fulib.fx.annotation.controller.Component; diff --git a/framework/src/test/java/org/fulib/fx/data/DuplicationTest.java b/framework/src/test/java/org/fulib/fx/data/DuplicationTest.java new file mode 100644 index 00000000..aba9711c --- /dev/null +++ b/framework/src/test/java/org/fulib/fx/data/DuplicationTest.java @@ -0,0 +1,137 @@ +package org.fulib.fx.data; + +import javafx.application.Platform; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Pane; +import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import javafx.scene.text.Font; +import javafx.scene.text.Text; +import javafx.scene.text.TextAlignment; +import javafx.stage.Stage; +import org.fulib.fx.duplicate.Duplicators; +import org.junit.jupiter.api.Test; +import org.testfx.framework.junit5.ApplicationTest; + +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.testfx.util.WaitForAsyncUtils.waitForFxEvents; + +public class DuplicationTest extends ApplicationTest { + + + VBox pane = new VBox(); + + @Override + public void start(Stage stage) { + pane.setAlignment(Pos.CENTER); + stage.setScene(new Scene(pane)); + stage.show(); + } + + @Test + public void button() { + Button button = new Button(); + + // Button(Base) + button.setDefaultButton(true); + button.setCancelButton(true); + button.setOnAction(e -> System.out.println("Button clicked")); + + // Labeled + button.setText("Button"); + button.setAlignment(Pos.BOTTOM_RIGHT); + button.setTextAlignment(TextAlignment.RIGHT); + button.setTextOverrun(OverrunStyle.LEADING_ELLIPSIS); + button.setEllipsisString("Button"); + button.setWrapText(true); + button.setFont(Font.font(20)); + button.setGraphic(new Pane()); + button.setUnderline(true); + button.setLineSpacing(10); + button.setContentDisplay(ContentDisplay.TOP); + button.setGraphicTextGap(10); + button.setTextFill(Color.color(0.5, 0.5, 0.5)); + button.setMnemonicParsing(true); + + // Control + button.setContextMenu(new ContextMenu()); + button.setTooltip(new Tooltip("Button")); + + Button button1 = Duplicators.duplicate(button); + + assertEquals(button.isDefaultButton(), button1.isDefaultButton()); + assertEquals(button.isCancelButton(), button1.isCancelButton()); + assertEquals(button.getOnAction(), button1.getOnAction()); + assertEquals(button.getText(), button1.getText()); + assertEquals(button.getAlignment(), button1.getAlignment()); + assertEquals(button.getTextAlignment(), button1.getTextAlignment()); + assertEquals(button.getTextOverrun(), button1.getTextOverrun()); + assertEquals(button.getEllipsisString(), button1.getEllipsisString()); + assertEquals(button.isWrapText(), button1.isWrapText()); + assertEquals(button.getFont(), button1.getFont()); + assertEquals(button.getGraphic(), button1.getGraphic()); + assertEquals(button.isUnderline(), button1.isUnderline()); + assertEquals(button.getLineSpacing(), button1.getLineSpacing()); + assertEquals(button.getContentDisplay(), button1.getContentDisplay()); + assertEquals(button.getGraphicTextGap(), button1.getGraphicTextGap()); + assertEquals(button.getTextFill(), button1.getTextFill()); + assertEquals(button.isMnemonicParsing(), button1.isMnemonicParsing()); + assertEquals(button.getContextMenu(), button1.getContextMenu()); + assertEquals(button.getTooltip(), button1.getTooltip()); + } + + @Test + public void parents() { + VBox vBox = new VBox( + new Label("1"), + new Text("2") + ); + + VBox duplicate = Duplicators.duplicate(vBox); + + Platform.runLater(() -> { + pane.getChildren().add(vBox); + pane.getChildren().add(duplicate); + }); + waitForFxEvents(); + sleep(200); + + assertEquals(List.of("1", "2"), duplicate.getChildren().stream().map(node -> { + if (node instanceof Label) { + return ((Label) node).getText(); + } else if (node instanceof Text) { + return ((Text) node).getText(); + } + return null; // should not happen + }).toList()); + + } + + @Test + public void imageView() throws URISyntaxException, MalformedURLException { + HBox hBox = new HBox( + new ImageView( + new Image(this.getClass().getResource("128.jpg").toString()) + ) + ); + + HBox duplicate = Duplicators.duplicate(hBox); + + ImageView original = (ImageView) hBox.getChildren().get(0); + ImageView copied = (ImageView) duplicate.getChildren().get(0); + + assertEquals(original.getImage(), copied.getImage()); + } + + +} diff --git a/framework/src/test/resources/org/fulib/fx/app/controllertypes/WithSubComponent.fxml b/framework/src/test/resources/org/fulib/fx/app/controller/subcomponent/basic/WithSubComponent.fxml similarity index 63% rename from framework/src/test/resources/org/fulib/fx/app/controllertypes/WithSubComponent.fxml rename to framework/src/test/resources/org/fulib/fx/app/controller/subcomponent/basic/WithSubComponent.fxml index 04e915a6..fd265d80 100644 --- a/framework/src/test/resources/org/fulib/fx/app/controllertypes/WithSubComponent.fxml +++ b/framework/src/test/resources/org/fulib/fx/app/controller/subcomponent/basic/WithSubComponent.fxml @@ -3,8 +3,8 @@ - - + + diff --git a/framework/src/test/resources/org/fulib/fx/app/controllertypes/Basic.fxml b/framework/src/test/resources/org/fulib/fx/app/controller/types/Basic.fxml similarity index 73% rename from framework/src/test/resources/org/fulib/fx/app/controllertypes/Basic.fxml rename to framework/src/test/resources/org/fulib/fx/app/controller/types/Basic.fxml index 77a049f4..270895f3 100644 --- a/framework/src/test/resources/org/fulib/fx/app/controllertypes/Basic.fxml +++ b/framework/src/test/resources/org/fulib/fx/app/controller/types/Basic.fxml @@ -3,6 +3,6 @@ - + diff --git a/framework/src/test/resources/org/fulib/fx/app/controllertypes/Root.fxml b/framework/src/test/resources/org/fulib/fx/app/controller/types/Root.fxml similarity index 91% rename from framework/src/test/resources/org/fulib/fx/app/controllertypes/Root.fxml rename to framework/src/test/resources/org/fulib/fx/app/controller/types/Root.fxml index ab1e58fa..9c8f008e 100644 --- a/framework/src/test/resources/org/fulib/fx/app/controllertypes/Root.fxml +++ b/framework/src/test/resources/org/fulib/fx/app/controller/types/Root.fxml @@ -3,6 +3,6 @@ - + diff --git a/framework/src/test/resources/org/fulib/fx/app/view/View.fxml b/framework/src/test/resources/org/fulib/fx/app/controller/view/View.fxml similarity index 73% rename from framework/src/test/resources/org/fulib/fx/app/view/View.fxml rename to framework/src/test/resources/org/fulib/fx/app/controller/view/View.fxml index f1a63d8a..1b3a1435 100644 --- a/framework/src/test/resources/org/fulib/fx/app/view/View.fxml +++ b/framework/src/test/resources/org/fulib/fx/app/controller/view/View.fxml @@ -3,6 +3,6 @@ - + diff --git a/framework/src/test/resources/org/fulib/fx/data/128.jpg b/framework/src/test/resources/org/fulib/fx/data/128.jpg new file mode 100644 index 00000000..d2b9cf19 Binary files /dev/null and b/framework/src/test/resources/org/fulib/fx/data/128.jpg differ diff --git a/gradle.properties b/gradle.properties index 852091b5..5cadc808 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,3 +10,57 @@ javaSourceVersion = 17 javaTargetVersion = 17 generateSourcesJar = false generateJavadocJar = false + +# --------------- Gradle Plugins --------------- + +# https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow +shadowPluginVersion = 7.0.0 + +# https://plugins.gradle.org/plugin/org.openjfx.javafxplugin +javaFxPluginVersion = 0.1.0 + +# https://plugins.gradle.org/plugin/org.fulib.fulibGradle +fulibGradlePluginVersion = 0.5.0 + +# --------------- Dependencies --------------- + +# https://mvnrepository.com/artifact/org.openjfx/javafx-base +javaFxVersion = 21.0.2 + +# https://mvnrepository.com/artifact/org.jetbrains/annotations +jetbrainsAnnotationsVersion = 24.1.0 + +# https://mvnrepository.com/artifact/com.google.dagger/dagger +# https://mvnrepository.com/artifact/com.google.dagger/dagger-compiler +daggerVersion = 2.51 + +# https://mvnrepository.com/artifact/io.reactivex.rxjava3/rxjava +rxJavaVersion = 3.1.8 + +# https://mvnrepository.com/artifact/com.google.auto.service/auto-service +# https://mvnrepository.com/artifact/com.google.auto.service/auto-service-annotations +autoServiceVersion = 1.1.1 + +# https://mvnrepository.com/artifact/org.fulib/fulib +fulibVersion = 1.6.2 + +# https://mvnrepository.com/artifact/org.fulib/fulibScenarios +fulibScenariosVersion = 1.7.1 + +# --------------- Test Dependencies --------------- + +# https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api +# https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine +junitJupiterVersion = 5.10.2 + +# https://mvnrepository.com/artifact/org.testfx/testfx-junit5 +testFxVersion = 4.0.18 + +# https://mvnrepository.com/artifact/org.testfx/openjfx-monocle +monocleVersion = 17.0.10 + +# https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter +mockitoVersion = 5.11.0 + +# https://mvnrepository.com/artifact/org.hamcrest/hamcrest +hamcrestVersion = 2.2 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f..d64cd491 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e411586a..a80b22ce 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 744e882e..1aa94a42 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,99 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MSYS* | MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +119,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,88 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 107acd32..25da30db 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/ludo/build.gradle b/ludo/build.gradle index 60971e24..7756fee5 100644 --- a/ludo/build.gradle +++ b/ludo/build.gradle @@ -1,67 +1,40 @@ plugins { id "java" - id "org.openjfx.javafxplugin" version "0.0.13" - id "com.github.johnrengelman.shadow" version "7.0.0" - id 'org.fulib.fulibGradle' version '0.5.0' -} - -configurations { - internal - implementation.extendsFrom(internal) + id "org.openjfx.javafxplugin" version "$javaFxPluginVersion" + id "com.github.johnrengelman.shadow" version "$shadowPluginVersion" + id 'org.fulib.fulibGradle' version "$fulibGradlePluginVersion" } // JavaFX dependencies javafx { - version = '20' + version = javaFxVersion modules = ['javafx.controls', 'javafx.graphics', 'javafx.fxml', 'javafx.media'] } // Project dependencies dependencies { - // https://mvnrepository.com/artifact/org.jetbrains/annotations - implementation 'org.jetbrains:annotations:24.0.1' - - // https://mvnrepository.com/artifact/com.google.dagger/dagger - implementation group: 'com.google.dagger', name: 'dagger', version: '2.42' - - // https://mvnrepository.com/artifact/com.google.dagger/dagger-compiler - annotationProcessor group: 'com.google.dagger', name: 'dagger-compiler', version: '2.42' - - // https://mvnrepository.com/artifact/io.reactivex.rxjava3/rxjava - implementation group: 'io.reactivex.rxjava3', name: 'rxjava', version: '3.1.4' + implementation group: 'org.jetbrains', name: 'annotations', version: jetbrainsAnnotationsVersion + implementation group: 'io.reactivex.rxjava3', name: 'rxjava', version: rxJavaVersion - // https://mvnrepository.com/artifact/org.fulib/fulibScenarios - fulibScenarios group: 'org.fulib', name: 'fulibScenarios', version: '1.7.0' + implementation group: 'com.google.dagger', name: 'dagger', version: daggerVersion + annotationProcessor group: 'com.google.dagger', name: 'dagger-compiler', version: daggerVersion - // https://mvnrepository.com/artifact/org.fulib/fulib - fulibScenarios group: 'org.fulib', name: 'fulib', version: '1.6.2' + fulibScenarios group: 'org.fulib', name: 'fulibScenarios', version: fulibScenariosVersion + fulibScenarios group: 'org.fulib', name: 'fulib', version: fulibVersion - implementation project(":framework") + implementation project(':framework') } // ------------------- Tests ------------------- // Test dependencies dependencies { - - // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.9.2' - - // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine - testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.9.2' - - // https://mvnrepository.com/artifact/org.testfx/testfx-junit5 - testImplementation group: 'org.testfx', name: 'testfx-junit5', version: '4.0.16-alpha' - - // https://mvnrepository.com/artifact/org.testfx/openjfx-monocle - testImplementation group: 'org.testfx', name: 'openjfx-monocle', version: '17.0.10' - - // https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter - testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: '5.2.0' - - // https://mvnrepository.com/artifact/com.google.dagger/dagger-compiler - testAnnotationProcessor group: 'com.google.dagger', name: 'dagger-compiler', version: '2.42' - + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: junitJupiterVersion + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitJupiterVersion + testImplementation group: 'org.testfx', name: 'testfx-junit5', version: testFxVersion + testImplementation group: 'org.testfx', name: 'openjfx-monocle', version: monocleVersion + testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: mockitoVersion + testAnnotationProcessor group: 'com.google.dagger', name: 'dagger-compiler', version: daggerVersion } java { @@ -74,10 +47,6 @@ test { } jar { - from { - configurations.internal.collect { it.isDirectory() ? it : zipTree(it) } - } - manifest { attributes( "Manifest-Version": 1.0, @@ -106,12 +75,6 @@ repositories { group projectGroup version projectVersion -// Include local jar dependencies -dependencies { - implementation fileTree(dir: "libs/implementation", include: "*.jar") - internal fileTree(dir: "libs/internal", include: "*.jar") -} - static JavaVersion getVersionForMajor(String version) { return JavaVersion.values().find { (it.majorVersion == version) } } diff --git a/ludo/src/test/java/de/uniks/ludo/AppTest.java b/ludo/src/test/java/de/uniks/ludo/AppTest.java index 4b9875af..550baf9e 100644 --- a/ludo/src/test/java/de/uniks/ludo/AppTest.java +++ b/ludo/src/test/java/de/uniks/ludo/AppTest.java @@ -1,8 +1,9 @@ package de.uniks.ludo; +import javafx.application.Platform; import javafx.scene.Node; import javafx.scene.control.Label; -import javafx.scene.input.MouseButton; +import javafx.scene.input.KeyCode; import javafx.stage.Stage; import org.junit.jupiter.api.Test; import org.mockito.Spy; @@ -26,11 +27,15 @@ public void start(Stage stage) throws Exception { @Test public void test() { - moveTo("2");; - moveBy(0, -20); - press(MouseButton.PRIMARY); - release(MouseButton.PRIMARY); - clickOn("#startButton"); + Platform.runLater(() -> app.stage().requestFocus()); + waitForFxEvents(); + + press(KeyCode.LEFT); + release(KeyCode.LEFT); + press(KeyCode.TAB); + release(KeyCode.TAB); + press(KeyCode.SPACE); + release(KeyCode.SPACE); waitForFxEvents(); @@ -247,7 +252,7 @@ public void test() { } private void roll() { - clickOn("#eyesLabel");; + clickOn("#eyesLabel"); sleep(1100); }