From 7838d94ec08fa3fabaebfdf8d14fc8cab690cd3d Mon Sep 17 00:00:00 2001 From: LeStegii Date: Tue, 27 Feb 2024 13:07:31 +0100 Subject: [PATCH] test(ludo): Create app test --- .../main/java/org/fulib/fx/FulibFxApp.java | 3 - ludo/src/main/java/de/uniks/ludo/App.java | 16 +- .../ludo/controller/IngameController.java | 2 + .../ludo/controller/sub/DiceSubComponent.java | 6 +- .../de/uniks/ludo/service/GameService.java | 12 + ludo/src/test/java/de/uniks/ludo/AppTest.java | 233 +++++++++++++++++- .../java/de/uniks/ludo/TestComponent.java | 17 ++ .../test/java/de/uniks/ludo/TestModule.java | 17 ++ 8 files changed, 297 insertions(+), 9 deletions(-) create mode 100644 ludo/src/test/java/de/uniks/ludo/TestComponent.java create mode 100644 ludo/src/test/java/de/uniks/ludo/TestModule.java diff --git a/framework/src/main/java/org/fulib/fx/FulibFxApp.java b/framework/src/main/java/org/fulib/fx/FulibFxApp.java index f2043cec..26f83d68 100644 --- a/framework/src/main/java/org/fulib/fx/FulibFxApp.java +++ b/framework/src/main/java/org/fulib/fx/FulibFxApp.java @@ -243,9 +243,6 @@ protected void display(@NotNull Parent parent) { // Internal helper method protected void cleanup() { - System.out.println("cleanup"); - System.out.println(this); - System.out.println(frameworkComponent); this.frameworkComponent.controllerManager().cleanup(); } diff --git a/ludo/src/main/java/de/uniks/ludo/App.java b/ludo/src/main/java/de/uniks/ludo/App.java index 884910f0..5a3c8e16 100644 --- a/ludo/src/main/java/de/uniks/ludo/App.java +++ b/ludo/src/main/java/de/uniks/ludo/App.java @@ -6,15 +6,17 @@ import javafx.stage.Stage; import org.fulib.fx.FulibFxApp; +import javax.inject.Singleton; import java.nio.file.Path; import java.util.logging.Level; import static javafx.scene.input.KeyEvent.KEY_PRESSED; +@Singleton public class App extends FulibFxApp { - private final MainComponent component; + private MainComponent component; public App() { super(); @@ -78,4 +80,16 @@ public void stop() { public MainComponent component() { return component; } + + /** + * Overrides the dagger component of the application. + * + * @param component The new dagger component + * @return The application itself + */ + public App setComponent(MainComponent component) { + this.component = component; + return this; + } + } diff --git a/ludo/src/main/java/de/uniks/ludo/controller/IngameController.java b/ludo/src/main/java/de/uniks/ludo/controller/IngameController.java index a9bca38b..9e1e6fac 100644 --- a/ludo/src/main/java/de/uniks/ludo/controller/IngameController.java +++ b/ludo/src/main/java/de/uniks/ludo/controller/IngameController.java @@ -200,6 +200,7 @@ private void setupListenerForPiece(Circle circle, Piece piece, String color) { // Creates a circle for a piece and sets the position to the piece's current field private Circle createPieceCircle(Piece piece) { Circle circle = new Circle(16); + circle.setId("piece-" + piece.getOwner().getId() + "-" + piece.getOwner().getPieces().indexOf(piece)); Player player = piece.getOwner(); AnchorPane.setTopAnchor(circle, (double) piece.getOn().getY() * 50 + 4); AnchorPane.setLeftAnchor(circle, (double) piece.getOn().getX() * 50 + 4); @@ -210,6 +211,7 @@ private Circle createPieceCircle(Piece piece) { // Creates a circle for a field and sets the position to the field's coordinates private Circle createFieldCircle(Field field) { Circle circle = new Circle(20); + circle.setId("field-" + field.getX() + "-" + field.getY()); AnchorPane.setTopAnchor(circle, (double) field.getY() * 50); AnchorPane.setLeftAnchor(circle, (double) field.getX() * 50); String color = field instanceof HomeField ? "gray" : "white"; diff --git a/ludo/src/main/java/de/uniks/ludo/controller/sub/DiceSubComponent.java b/ludo/src/main/java/de/uniks/ludo/controller/sub/DiceSubComponent.java index 0f895fdd..0a5d5e6d 100644 --- a/ludo/src/main/java/de/uniks/ludo/controller/sub/DiceSubComponent.java +++ b/ludo/src/main/java/de/uniks/ludo/controller/sub/DiceSubComponent.java @@ -1,5 +1,6 @@ package de.uniks.ludo.controller.sub; +import de.uniks.ludo.service.GameService; import io.reactivex.rxjava3.core.Observable; import javafx.animation.Timeline; import javafx.beans.property.BooleanProperty; @@ -20,6 +21,9 @@ public class DiceSubComponent extends VBox { @FXML public Label eyesLabel; + @Inject + GameService gameService; + private final BooleanProperty enabled = new SimpleBooleanProperty(true); private CompletableFuture rollFuture; @@ -36,7 +40,7 @@ public void onRender() { this.rollAnimation = new Timeline(); this.rollAnimation.setCycleCount(10); rollAnimation.getKeyFrames().add(new javafx.animation.KeyFrame(javafx.util.Duration.millis(100), event -> { - int random = (int) (Math.random() * 6 + 1); + int random = gameService.rollRandom(); eyesLabel.setText(String.valueOf(random)); })); this.rollAnimation.setOnFinished(event -> this.rollFuture.complete(Integer.parseInt(eyesLabel.getText()))); diff --git a/ludo/src/main/java/de/uniks/ludo/service/GameService.java b/ludo/src/main/java/de/uniks/ludo/service/GameService.java index 31ccafaa..af98971c 100644 --- a/ludo/src/main/java/de/uniks/ludo/service/GameService.java +++ b/ludo/src/main/java/de/uniks/ludo/service/GameService.java @@ -7,12 +7,20 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.util.Optional; +import java.util.Random; @Singleton public class GameService { + private final Random random; + @Inject public GameService() { + this.random = new Random(); + } + + public GameService(Random random) { + this.random = random; } /** @@ -165,4 +173,8 @@ public boolean movePiece(Piece piece, Field targetField) { piece.setOn(targetField); return isDone(piece.getOwner()); } + + public int rollRandom() { + return random.nextInt(6) + 1; + } } diff --git a/ludo/src/test/java/de/uniks/ludo/AppTest.java b/ludo/src/test/java/de/uniks/ludo/AppTest.java index 8f0031ed..4b9875af 100644 --- a/ludo/src/test/java/de/uniks/ludo/AppTest.java +++ b/ludo/src/test/java/de/uniks/ludo/AppTest.java @@ -1,14 +1,16 @@ package de.uniks.ludo; - +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.input.MouseButton; import javafx.stage.Stage; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Spy; -import org.mockito.junit.jupiter.MockitoExtension; +import org.testfx.api.FxAssert; import org.testfx.framework.junit5.ApplicationTest; -@ExtendWith(MockitoExtension.class) +import static org.testfx.util.WaitForAsyncUtils.waitForFxEvents; + public class AppTest extends ApplicationTest { @Spy @@ -17,13 +19,236 @@ public class AppTest extends ApplicationTest { @Override public void start(Stage stage) throws Exception { super.start(stage); + app.setComponent(DaggerTestComponent.builder().mainApp(app).build()); app.start(stage); stage.requestFocus(); } @Test public void test() { + moveTo("2");; + moveBy(0, -20); + press(MouseButton.PRIMARY); + release(MouseButton.PRIMARY); + clickOn("#startButton"); + + waitForFxEvents(); + + FxAssert.verifyThat("#playerLabel", (Label label) -> label.getText().contains("1")); + + roll(); + clickOn("#piece-1-3"); + roll(); + clickOn("#piece-1-3"); + roll(); + clickOn("#piece-1-3"); + + FxAssert.verifyThat("#playerLabel", (Label label) -> label.getText().contains("2")); + + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-3"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + clickOn("#piece-1-2"); + roll(); + roll(); + roll(); + roll(); + roll(); + roll(); + roll(); + roll(); + roll(); + roll(); + clickOn("#piece-1-1"); + roll(); + clickOn("#piece-1-1"); + roll(); + clickOn("#piece-1-1"); + roll(); + roll(); + clickOn("#piece-1-1"); + roll(); + roll(); + clickOn("#piece-1-1"); + roll(); + roll(); + clickOn("#piece-1-1"); + roll(); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-1-1"); + roll(); + roll(); + clickOn("#piece-1-1"); + roll(); + roll(); + clickOn("#piece-1-0"); + roll(); + roll(); + clickOn("#piece-1-1"); + roll(); + clickOn("#piece-1-1"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-1-1"); + roll(); + clickOn("#piece-2-0"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-1-1"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-2-0"); + roll(); + clickOn("#piece-1-1"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-1-1"); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-2-0"); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-1-1"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-2-2"); + roll(); + clickOn("#piece-2-0"); + roll(); + clickOn("#piece-2-0"); + roll(); + clickOn("#piece-2-0"); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-2-0"); + roll(); + clickOn("#piece-1-0"); + roll(); + clickOn("#piece-2-0"); + roll(); + roll(); + clickOn("#piece-2-0"); + roll(); + roll(); + clickOn("#piece-2-0"); + roll(); + roll(); + clickOn("#piece-2-0"); + roll(); + roll(); + clickOn("#piece-2-0"); + roll(); + clickOn("#piece-1-0"); + + waitForFxEvents(); + + FxAssert.verifyThat("#playerWonLabel", Node::isVisible); + + } + private void roll() { + clickOn("#eyesLabel");; + sleep(1100); } } diff --git a/ludo/src/test/java/de/uniks/ludo/TestComponent.java b/ludo/src/test/java/de/uniks/ludo/TestComponent.java new file mode 100644 index 00000000..cd926c5a --- /dev/null +++ b/ludo/src/test/java/de/uniks/ludo/TestComponent.java @@ -0,0 +1,17 @@ +package de.uniks.ludo; + +import dagger.Component; +import de.uniks.ludo.dagger.MainComponent; +import de.uniks.ludo.dagger.MainModule; + +import javax.inject.Singleton; + +@Component(modules = {MainModule.class, TestModule.class}) +@Singleton +public interface TestComponent extends MainComponent { + + @Component.Builder + interface Builder extends MainComponent.Builder { + TestComponent build(); + } +} \ No newline at end of file diff --git a/ludo/src/test/java/de/uniks/ludo/TestModule.java b/ludo/src/test/java/de/uniks/ludo/TestModule.java new file mode 100644 index 00000000..78db42b8 --- /dev/null +++ b/ludo/src/test/java/de/uniks/ludo/TestModule.java @@ -0,0 +1,17 @@ +package de.uniks.ludo; + +import dagger.Module; +import dagger.Provides; +import de.uniks.ludo.service.GameService; + +import java.util.Random; + +@Module +public class TestModule { + + @Provides + GameService gameService() { + return new GameService(new Random(42)); + } + +}