1 /*
   2  * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.scene;
  27 
  28 import test.util.Util;
  29 import javafx.scene.image.WritableImage;
  30 import javafx.stage.Stage;
  31 import java.util.concurrent.CountDownLatch;
  32 import java.util.concurrent.TimeUnit;
  33 import javafx.application.Application;
  34 import javafx.application.Platform;
  35 import javafx.scene.Group;
  36 import javafx.scene.Node;
  37 import javafx.scene.Scene;
  38 import javafx.scene.SnapshotParameters;
  39 import javafx.scene.SnapshotResult;
  40 import javafx.scene.paint.Color;
  41 import javafx.stage.StageStyle;
  42 import javafx.util.Callback;
  43 import junit.framework.AssertionFailedError;
  44 
  45 import static org.junit.Assert.*;
  46 import static test.util.Util.TIMEOUT;
  47 
  48 /**
  49  * Common base class for testing snapshot.
  50  */
  51 public class SnapshotCommon {
  52 
  53     // Used to launch the application before running any test
  54     private static final CountDownLatch launchLatch = new CountDownLatch(1);
  55 
  56     // Singleton Application instance
  57     static MyApp myApp;
  58 
  59     // Application class. An instance is created and initialized before running
  60     // the first test, and it lives through the execution of all tests.
  61     public static class MyApp extends Application {
  62         Stage primaryStage;
  63 
  64         @Override public void init() {
  65             SnapshotCommon.myApp = this;
  66         }
  67 
  68         @Override public void start(Stage primaryStage) throws Exception {
  69             assertTrue(Platform.isFxApplicationThread());
  70             primaryStage.setTitle("Primary stage");
  71             Group root = new Group();
  72             Scene scene = new Scene(root);
  73             scene.setFill(Color.LIGHTYELLOW);
  74             primaryStage.setScene(scene);
  75             primaryStage.setX(0);
  76             primaryStage.setY(0);
  77             primaryStage.setWidth(210);
  78             primaryStage.setHeight(180);
  79             assertFalse(primaryStage.isShowing());
  80             primaryStage.show();
  81             assertTrue(primaryStage.isShowing());
  82 
  83             this.primaryStage = primaryStage;
  84             launchLatch.countDown();
  85         }
  86     }
  87 
  88     static class TestStage extends Stage {
  89         TestStage(Scene scene) {
  90             this(StageStyle.UNDECORATED, scene);
  91         }
  92 
  93         TestStage(StageStyle style, Scene scene) {
  94             this.setTitle("Test stage");
  95             initStyle(style);
  96 
  97             this.setScene(scene);
  98             if (scene.getWidth() <= 0) {
  99                 this.setWidth(200);
 100                 this.setHeight(150);
 101             }
 102             this.setX(225);
 103             this.setY(0);
 104         }
 105     }
 106 
 107     static void doSetupOnce() {
 108         // Start the Application
 109         new Thread(() -> Application.launch(MyApp.class, (String[])null)).start();
 110 
 111         try {
 112             if (!launchLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
 113                 throw new AssertionFailedError("Timeout waiting for Application to launch");
 114             }
 115         } catch (InterruptedException ex) {
 116             AssertionFailedError err = new AssertionFailedError("Unexpected exception");
 117             err.initCause(ex);
 118             throw err;
 119         }
 120 
 121         assertEquals(0, launchLatch.getCount());
 122     }
 123 
 124     static void doTeardownOnce() {
 125         Platform.exit();
 126     }
 127 
 128     protected void runDeferredSnapshotWait(final Node node,
 129             final Callback<SnapshotResult, Void> cb,
 130             final SnapshotParameters params,
 131             final WritableImage img,
 132             final Runnable runAfter) {
 133 
 134         final Throwable[] testError = new Throwable[1];
 135         final CountDownLatch latch = new CountDownLatch(1);
 136 
 137         Util.runAndWait(() -> {
 138             node.snapshot(result -> {
 139                 try {
 140                     cb.call(result);
 141                 } catch (Throwable th) {
 142                     testError[0] = th;
 143                 } finally {
 144                     latch.countDown();
 145                 }
 146                 return null;
 147             }, params, img);
 148             assertEquals(1, latch.getCount());
 149 
 150             if (runAfter != null) {
 151                 runAfter.run();
 152             }
 153         });
 154 
 155         try {
 156             if (!latch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
 157                 throw new AssertionFailedError("Timeout waiting for snapshot callback");
 158             }
 159         } catch (InterruptedException ex) {
 160             AssertionFailedError err = new AssertionFailedError("Unexpected exception");
 161             err.initCause(ex);
 162             throw err;
 163         }
 164 
 165         if (testError[0] != null) {
 166             if (testError[0] instanceof Error) {
 167                 throw (Error)testError[0];
 168             } else if (testError[0] instanceof RuntimeException) {
 169                 throw (RuntimeException)testError[0];
 170             } else {
 171                 AssertionFailedError err = new AssertionFailedError("Unknown execution exception");
 172                 err.initCause(testError[0].getCause());
 173                 throw err;
 174             }
 175         }
 176     }
 177 
 178     protected void runDeferredSnapshotWait(final Node node,
 179             final Callback<SnapshotResult, Void> cb,
 180             final SnapshotParameters params,
 181             final WritableImage img) {
 182 
 183         runDeferredSnapshotWait(node, cb, params, img, null);
 184     }
 185 
 186     protected void runDeferredSnapshotWait(final Scene scene,
 187             final Callback<SnapshotResult, Void> cb,
 188             final WritableImage img) {
 189 
 190         final Throwable[] testError = new Throwable[1];
 191         final CountDownLatch latch = new CountDownLatch(1);
 192 
 193         Util.runAndWait(() -> {
 194             scene.snapshot(result -> {
 195                 try {
 196                     cb.call(result);
 197                 } catch (Throwable th) {
 198                     testError[0] = th;
 199                 } finally {
 200                     latch.countDown();
 201                 }
 202                 return null;
 203             }, img);
 204             assertEquals(1, latch.getCount());
 205         });
 206 
 207         try {
 208             if (!latch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
 209                 throw new AssertionFailedError("Timeout waiting for snapshot callback");
 210             }
 211         } catch (InterruptedException ex) {
 212             AssertionFailedError err = new AssertionFailedError("Unexpected exception");
 213             err.initCause(ex);
 214             throw err;
 215         }
 216 
 217         if (testError[0] != null) {
 218             if (testError[0] instanceof Error) {
 219                 throw (Error)testError[0];
 220             } else if (testError[0] instanceof RuntimeException) {
 221                 throw (RuntimeException)testError[0];
 222             } else {
 223                 AssertionFailedError err = new AssertionFailedError("Unknown execution exception");
 224                 err.initCause(testError[0].getCause());
 225                 throw err;
 226             }
 227         }
 228     }
 229 
 230 }