package test;
import java.awt.GraphicsEnvironment;
import java.lang.reflect.Field;
import java.util.stream.IntStream;
import javafx.application.Platform;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.SnapshotParameters;
import javafx.scene.image.Image;
import javafx.scene.image.PixelReader;
import javafx.scene.image.WritableImage;
import org.testfx.util.WaitForAsyncUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public interface HelperTest {
default Field getField(final Class<?> clazz, final String name) throws SecurityException, NoSuchFieldException {
final Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return field;
}
default boolean isX11Set() {
return !GraphicsEnvironment.getLocalGraphicsEnvironment().isHeadlessInstance();
}
default void assertEqualsDouble(double v1, double v2) {
assertEquals(v1, v2, 0.0000001);
}
default <T extends Node> void assertNotEqualsSnapshot(T node, Runnable toExecBetweenSnap) {
Bounds bounds = node.getBoundsInLocal();
final SnapshotParameters params = new SnapshotParameters();
final WritableImage oracle = new WritableImage((int) bounds.getWidth(), (int) bounds.getHeight());
Platform.runLater(() -> node.snapshot(params, oracle));
WaitForAsyncUtils.waitForFxEvents();
if(toExecBetweenSnap != null) {
toExecBetweenSnap.run();
}
bounds = node.getBoundsInLocal();
final WritableImage observ = new WritableImage((int) bounds.getWidth(), (int) bounds.getHeight());
Platform.runLater(() -> node.snapshot(params, observ));
WaitForAsyncUtils.waitForFxEvents();
assertNotEquals("The two snapshots do not differ.", 100d, computeSnapshotSimilarity(oracle, observ), 0.001);
}
/**
* Compute the similarity of two JavaFX images.
* @param image1 The first image to test.
* @param image2 The second image to test.
* @return A double value in [0;100] corresponding to the similarity between the two images (pixel comparison).
* @throws NullPointerException If image1 or image2 is null.
*/
default double computeSnapshotSimilarity(final Image image1, final Image image2) {
final int width = (int) image1.getWidth();
final int height = (int) image1.getHeight();
final PixelReader reader1 = image1.getPixelReader();
final PixelReader reader2 = image2.getPixelReader();
final double nbNonSimilarPixels = IntStream.range(0, width).parallel().mapToLong(i ->
IntStream.range(0, height).parallel().filter(j -> reader1.getArgb(i, j) != reader2.getArgb(i, j)).count()).sum();
return 100d - nbNonSimilarPixels / (width * height) * 100d;
}
}