package moe.tristan.easyfxml.util;

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import moe.tristan.easyfxml.spring.SpringContext;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.testfx.framework.junit.ApplicationTest;

import javafx.application.Platform;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

import java.util.concurrent.ExecutionException;

import static org.assertj.core.api.Assertions.assertThat;

@ContextConfiguration(classes = SpringContext.class)
@RunWith(SpringRunner.class)
public class StagesTest extends ApplicationTest {

    private static String STAGE_TITLE;
    private static String STAGE_TITLE_2;
    private static Pane STAGE_PANE;
    private static Stage TEST_STAGE;

    @Override
    public void start(final Stage stage) {
        Platform.setImplicitExit(false);
        STAGE_TITLE = "STAGE_TITLE";
        STAGE_TITLE_2 = "STAGE_TITLE_2";
        STAGE_PANE = new Pane();
        TEST_STAGE = stage;
        stage.show();
        stage.hide();
    }

    @Test
    public void stageOf() throws ExecutionException, InterruptedException {
        Stages.stageOf(STAGE_TITLE, STAGE_PANE)
              .thenAccept(stage -> {
                  assertThat(stage.getScene().getRoot()).isEqualTo(STAGE_PANE);
                  assertThat(stage.getTitle()).isEqualTo(STAGE_TITLE);
              })
              .toCompletableFuture().get();
    }

    @Test
    public void scheduleDisplaying() throws ExecutionException, InterruptedException {
        Stages.scheduleDisplaying(TEST_STAGE)
              .thenAccept(stage -> assertThat(TEST_STAGE.isShowing()).isTrue())
              .toCompletableFuture().get();
    }

    @Test
    public void scheduleHiding() throws ExecutionException, InterruptedException {
        Stages.scheduleHiding(TEST_STAGE)
              .thenAccept(stage -> assertThat(TEST_STAGE.isShowing()).isFalse())
              .toCompletableFuture().get();
    }

    @Test
    public void asyncStageOperation() throws ExecutionException, InterruptedException {
        FxAsync.doOnFxThread(TEST_STAGE, stage -> stage.setTitle(STAGE_TITLE_2))
               .thenAccept(stage -> assertThat(stage.getTitle()).isEqualTo(STAGE_TITLE_2))
               .toCompletableFuture().get();
    }
}

@@ -40,194 +40,46 @@
 ort 
-org.springframework.test.context.ContextConfiguration;%0Aimport org.springframework.test.context.junit4.SpringRunner;%0Aimport moe.tristan.easyfxml.spring.SpringContext;%0Aimport org.junit.Tes
+moe.tristan.easyfxml.api.FxmlStyleshee
 t;%0Ai
@@ -98,22 +98,12 @@
 nit.
-runner.RunWith
+Test
 ;%0Aim
@@ -188,16 +188,85 @@
 atform;%0A
+import javafx.collections.ObservableList;%0Aimport javafx.scene.Scene;%0A
 import j
@@ -318,16 +318,61 @@
 Stage;%0A%0A
+import java.util.concurrent.CompletionStage;%0A
 import j
@@ -410,16 +410,52 @@
 ception;
+%0Aimport java.util.function.Function;
 %0A%0Aimport
@@ -511,139 +511,440 @@
 t;%0A%0A
-@ContextConfiguration(classes = SpringContext.class)%0A@RunWith(SpringRunner.class)%0Apublic class StagesTest extends ApplicationTest %7B
+public class StagesTest extends ApplicationTest %7B%0A%0A    private static final FxmlStylesheet TEST_STYLE = new FxmlStylesheet() %7B%0A        @Override%0A        public String getExternalForm() %7B%0A            return Resources.getResourceURL(%22fxml/test_style.css%22)%0A                            .getOrElseThrow((Function%3C? super Throwable, RuntimeException%3E) RuntimeException::new)%0A                            .toExternalForm();%0A        %7D%0A    %7D;
 %0A%0A  
@@ -957,147 +957,114 @@
 ate 
-static String STAGE_TITLE;%0A    private static String STAGE_TITLE_2;%0A    private static Pane STAGE_PANE;%0A    private static Stage TEST_STAGE
+Stage testStage;%0A    private String stageTitle;%0A    private String stageTitle2;%0A    private Pane stagePane
 ;%0A%0A 
@@ -1172,74 +1172,68 @@
     
-STAGE_TITLE = %22STAGE_TITLE%22;%0A        STAGE_TITLE_2 = %22STAGE_TITLE_
+stageTitle = %22stageTitle%22;%0A        stageTitle2 = %22stageTitle
 2%22;%0A
@@ -1240,26 +1240,25 @@
         
-STAGE_PANE
+stagePane
  = new P
@@ -1276,26 +1276,75 @@
     
-TEST_STAGE = stage
+testStage = stage;%0A        testStage.setScene(new Scene(stagePane))
 ;%0A  
@@ -1490,46 +1490,83 @@
     
-Stages.stageOf(STAGE_TITLE, STAGE_PANE
+final Pane newPane = new Pane();%0A        Stages.stageOf(stageTitle, newPane
 )%0A  
@@ -1671,18 +1671,15 @@
 lTo(
-STAGE_PANE
+newPane
 );%0A 
@@ -1734,27 +1734,26 @@
 EqualTo(
-STAGE_TITLE
+stageTitle
 );%0A     
@@ -1942,34 +1942,33 @@
 eDisplaying(
-TEST_STAGE
+testStage
 )%0A          
@@ -1999,34 +1999,33 @@
  assertThat(
-TEST_STAGE
+testStage
 .isShowing()
@@ -2210,26 +2210,25 @@
 eHiding(
-TEST_STAGE
+testStage
 )%0A      
@@ -2267,26 +2267,25 @@
 ertThat(
-TEST_STAGE
+testStage
 .isShowi
@@ -2483,18 +2483,17 @@
 ead(
-TEST_STAGE
+testStage
 , st
@@ -2514,28 +2514,26 @@
 etTitle(
-STAGE_TITLE_
+stageTitle
 2))%0A    
@@ -2607,66 +2607,545 @@
 lTo(
-STAGE_TITLE_2))%0A               .toCompletableFuture().get(
+stageTitle2))%0A               .toCompletableFuture().get();%0A    %7D%0A%0A    @Test%0A    public void setStylesheet() throws ExecutionException, InterruptedException %7B%0A        final CompletionStage%3CStage%3E setStyleAsyncOp = Stages.setStylesheet(testStage, TEST_STYLE);%0A        final Stage stage = setStyleAsyncOp.toCompletableFuture().get();%0A        final ObservableList%3CString%3E stylesheets = stage.getScene().getStylesheets();%0A        assertThat(stylesheets).hasSize(1);%0A        assertThat(stylesheets).containsExactly(TEST_STYLE.getExternalForm()
 );%0A 

Add some light testing to Stages#setStylesheet