1 /* 2 * Copyright (c) 2010, 2015, 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 javafx.scene.image; 27 28 import com.sun.javafx.pgstub.*; 29 import com.sun.javafx.test.PropertyInvalidationCounter; 30 import com.sun.javafx.tk.Toolkit; 31 import javafx.beans.InvalidationListener; 32 import javafx.beans.Observable; 33 import org.junit.Before; 34 import org.junit.Test; 35 36 import java.io.ByteArrayInputStream; 37 import java.io.InputStream; 38 import java.util.LinkedList; 39 import java.util.Queue; 40 41 import static org.junit.Assert.*; 42 43 public final class ImageTest { 44 private final StubToolkit toolkit; 45 private final StubImageLoaderFactory imageLoaderFactory; 46 47 public ImageTest() { 48 toolkit = (StubToolkit) Toolkit.getToolkit(); 49 imageLoaderFactory = toolkit.getImageLoaderFactory(); 50 } 51 52 @Before 53 public void setUp() { 54 imageLoaderFactory.reset(); 55 } 56 57 @Test 58 public void loadImageFromUrlBasicTest() { 59 final String url = "file:test.png"; 60 registerImage(url, 100, 200); 61 62 final Image image = new Image(url); 63 64 assertEquals(url, image.impl_getUrl()); 65 verifyLoadedImage(image, 0, 0, false, false, 100, 200); 66 } 67 68 @Test 69 public void loadImageFromUrlScaledTest() { 70 final String url = "file:test.png"; 71 registerImage(url, 300, 100); 72 73 final Image image = new Image(url, 200, 400, true, true); 74 75 assertEquals(url, image.impl_getUrl()); 76 verifyLoadedImage(image, 200, 400, true, true, 300, 100); 77 } 78 79 @Test 80 public void loadImageFromMissingUrlTest() { 81 final Image image = new Image("file:missing.png"); 82 83 assertTrue(image.isError()); 84 } 85 86 @Test 87 public void loadImageFromStreamBasicTest() { 88 final InputStream is = new ByteArrayInputStream(new byte[0]); 89 registerImage(is, 100, 200); 90 91 final Image image = new Image(is); 92 93 assertEquals(is, image.getImpl_source()); 94 verifyLoadedImage(image, 0, 0, false, false, 100, 200); 95 } 96 97 @Test 98 public void loadImageFromStreamScaledTest() { 99 final InputStream is = new ByteArrayInputStream(new byte[0]); 100 registerImage(is, 300, 100); 101 102 final Image image = new Image(is, 200, 400, true, true); 103 104 assertEquals(is, image.getImpl_source()); 105 verifyLoadedImage(image, 200, 400, true, true, 300, 100); 106 } 107 108 @Test 109 public void fromPlatformImageTest() { 110 final Object fakePlatformImage = new Object(); 111 registerImage(fakePlatformImage, 200, 500); 112 113 final Image image = Image.impl_fromPlatformImage(fakePlatformImage); 114 verifyLoadedImage(image, 0, 0, false, false, 200, 500); 115 } 116 117 @Test 118 public void loadImageAsyncProgressTest() { 119 final String url = "file:test.png"; 120 registerImage(url, 200, 100); 121 122 final Image image = new Image(url, true); 123 124 final StubAsyncImageLoader lastAsyncImageLoader = 125 getLastAsyncImageLoader(); 126 127 lastAsyncImageLoader.setProgress(0, 100); 128 final float p1 = (float) image.getProgress(); 129 130 lastAsyncImageLoader.setProgress(33, 100); 131 final float p2 = (float) image.getProgress(); 132 133 lastAsyncImageLoader.setProgress(66, 100); 134 final float p3 = (float) image.getProgress(); 135 136 lastAsyncImageLoader.setProgress(200, 100); 137 final float p4 = (float) image.getProgress(); 138 139 assertTrue(p1 < p2); 140 assertTrue(p2 < p3); 141 assertTrue(p3 == p4); 142 } 143 144 /* 145 @Test 146 public void loadImageAsyncPlaceholderTest() { 147 final Object fakePlatformImage1 = new Object(); 148 registerImage(fakePlatformImage1, 200, 500); 149 final Object fakePlatformImage2 = new Object(); 150 registerImage(fakePlatformImage2, 200, 500); 151 152 final String url = "file:test.png"; 153 registerImage(url, 200, 100); 154 155 final Image placeholderImage1 = 156 Image.impl_fromPlatformImage(fakePlatformImage1); 157 final Image placeholderImage2 = 158 Image.impl_fromPlatformImage(fakePlatformImage2); 159 final Image image = new Image(url, 500, 200, true, false, 160 true); 161 162 final StubAsyncImageLoader lastAsyncImageLoader = 163 getLastAsyncImageLoader(); 164 165 final Object platformImage1 = getPlatformImage(image); 166 final Object platformImage2 = getPlatformImage(image); 167 lastAsyncImageLoader.finish(); 168 final Object platformImage3 = getPlatformImage(image); 169 final Object platformImage4 = getPlatformImage(image); 170 171 assertNotSame(platformImage1, platformImage2); 172 assertNotSame(platformImage2, platformImage3); 173 assertNotSame(platformImage1, platformImage3); 174 assertSame(platformImage3, platformImage4); 175 176 verifyLoadedImage(image, 500, 200, true, false, 200, 100); 177 } 178 179 @Test 180 public void loadImageAsyncWithAsyncPlaceholderTest() { 181 final String placeholderUrl = "file:placeholder.png"; 182 registerImage(placeholderUrl, 200, 100); 183 final String finalUrl = "file:final.png"; 184 registerImage(finalUrl, 100, 200); 185 186 final Image placeholderImage = 187 new Image(placeholderUrl, true); 188 final StubAsyncImageLoader placeholderLoader = 189 getLastAsyncImageLoader(); 190 191 final Image finalImage = 192 new Image(finalUrl, true); 193 final StubAsyncImageLoader finalLoader = 194 getLastAsyncImageLoader(); 195 196 assertNull(finalImage.impl_getPlatformImage()); 197 assertEquals(0, finalImage.getWidth(), 0); 198 assertEquals(0, finalImage.getHeight(), 0); 199 200 placeholderLoader.finish(); 201 assertEquals(placeholderUrl, getPlatformImage(finalImage).getSource()); 202 assertEquals(200, finalImage.getWidth(), 0); 203 assertEquals(100, finalImage.getHeight(), 0); 204 205 finalLoader.finish(); 206 assertEquals(finalUrl, getPlatformImage(finalImage).getSource()); 207 assertEquals(100, finalImage.getWidth(), 0); 208 assertEquals(200, finalImage.getHeight(), 0); 209 } 210 */ 211 212 @Test 213 public void loadImageAsyncCancelTest() { 214 final String url = "file:test.png"; 215 registerImage(url, 200, 100); 216 217 final Image image1 = new Image(url, true); 218 final StubAsyncImageLoader lastAsyncImageLoader = 219 getLastAsyncImageLoader(); 220 221 image1.cancel(); 222 assertTrue(lastAsyncImageLoader.isCancelled()); 223 assertTrue(image1.isError()); 224 225 final Image image2 = new Image(url); 226 image2.cancel(); 227 verifyLoadedImage(image2, 0, 0, false, false, 200, 100); 228 } 229 230 @Test 231 public void loadImageAsyncErrorTest() { 232 final String url = "file:test.png"; 233 registerImage(url, 200, 100); 234 235 final Image image = new Image(url, true); 236 237 final StubAsyncImageLoader lastAsyncImageLoader = 238 getLastAsyncImageLoader(); 239 240 final Exception testException = new Exception("Test exception"); 241 242 lastAsyncImageLoader.finish(testException); 243 assertTrue(image.isError()); 244 assertEquals(testException, image.getException()); 245 } 246 247 @Test 248 public void loadMultipleImagesAsyncTest() { 249 final int multiImageCount = 100; 250 final Queue<StubAsyncImageLoader> asyncLoaders = 251 new LinkedList<StubAsyncImageLoader>(); 252 final Image[] images = new Image[multiImageCount]; 253 254 StubAsyncImageLoader lastAsyncLoader = null; 255 for (int i = 0; i < multiImageCount; ++i) { 256 final String url = "file:multi" + i + ".png"; 257 registerImage(url, 100, 100); 258 259 images[i] = new Image(url, true); 260 261 StubAsyncImageLoader asyncLoader = 262 imageLoaderFactory.getLastAsyncImageLoader(); 263 assertNotNull(asyncLoader); 264 if (lastAsyncLoader == asyncLoader) { 265 asyncLoaders.poll().finish(); 266 asyncLoader = imageLoaderFactory.getLastAsyncImageLoader(); 267 assertNotSame(lastAsyncLoader, asyncLoader); 268 } 269 270 asyncLoaders.add(asyncLoader); 271 lastAsyncLoader = asyncLoader; 272 } 273 274 for (final StubAsyncImageLoader asyncLoader: asyncLoaders) { 275 asyncLoader.finish(); 276 } 277 278 for (final Image image: images) { 279 verifyLoadedImage(image, 0, 0, false, false, 100, 100); 280 } 281 } 282 283 @Test 284 public void loadMultipleImagesAsyncCancelTest() { 285 final int multiImageCount = 100; 286 final Image[] images = new Image[multiImageCount]; 287 288 for (int i = 0; i < multiImageCount; ++i) { 289 final String url = "file:multi_cancel_" + i + ".png"; 290 registerImage(url, 100, 100); 291 292 images[i] = new Image(url, true); 293 } 294 295 // traverse backwards to first cancel images which were queued because 296 // of the thread limit 297 for (int i = images.length - 1; i >= 0; --i) { 298 final Image image = images[i]; 299 image.cancel(); 300 assertTrue(image.isError()); 301 } 302 } 303 304 @Test 305 public void animatedImageTest() { 306 // reset time 307 toolkit.setAnimationTime(0); 308 final Image animatedImage = 309 TestImages.createAnimatedTestImage( 310 300, 400, // width, height 311 0, // loop count 312 2000, 1000, 3000 // frame delays 313 ); 314 315 verifyLoadedImage(animatedImage, 0, 0, false, false, 300, 400); 316 317 toolkit.setAnimationTime(1000); 318 assertEquals(0, getPlatformImage(animatedImage).getFrame()); 319 320 toolkit.setAnimationTime(2500); 321 assertEquals(1, getPlatformImage(animatedImage).getFrame()); 322 323 toolkit.setAnimationTime(4500); 324 assertEquals(2, getPlatformImage(animatedImage).getFrame()); 325 326 toolkit.setAnimationTime(7000); 327 assertEquals(0, getPlatformImage(animatedImage).getFrame()); 328 329 TestImages.disposeAnimatedImage(animatedImage); 330 } 331 332 @Test 333 public void animatedImageTestLoopOnce() { 334 // reset time 335 toolkit.setAnimationTime(0); 336 final Image animatedImage = 337 TestImages.createAnimatedTestImage( 338 300, 400, // width, height 339 1, // loop count 340 2000, 1000, 3000 // frame delays 341 ); 342 343 verifyLoadedImage(animatedImage, 0, 0, false, false, 300, 400); 344 345 toolkit.setAnimationTime(1000); 346 assertEquals(0, getPlatformImage(animatedImage).getFrame()); 347 348 toolkit.setAnimationTime(2500); 349 assertEquals(1, getPlatformImage(animatedImage).getFrame()); 350 351 toolkit.setAnimationTime(4500); 352 assertEquals(2, getPlatformImage(animatedImage).getFrame()); 353 354 toolkit.setAnimationTime(7000); 355 assertEquals(2, getPlatformImage(animatedImage).getFrame()); 356 357 TestImages.disposeAnimatedImage(animatedImage); 358 } 359 360 @Test 361 public void imagePropertyListenersCalledOnceTest() { 362 final String url = "file:test.png"; 363 registerImage(url, 200, 100); 364 365 final Image image = new Image(url, true); 366 367 final StubAsyncImageLoader lastAsyncImageLoader = 368 getLastAsyncImageLoader(); 369 370 final PropertyInvalidationCounter<Number> widthInvalidationCounter = 371 new PropertyInvalidationCounter<Number>(); 372 final PropertyInvalidationCounter<Number> heightInvalidationCounter = 373 new PropertyInvalidationCounter<Number>(); 374 final PropertyInvalidationCounter<Object> plImageInvalidationCounter = 375 new PropertyInvalidationCounter<Object>(); 376 377 image.widthProperty().addListener(widthInvalidationCounter); 378 image.heightProperty().addListener(heightInvalidationCounter); 379 Toolkit.getImageAccessor().getImageProperty(image).addListener(plImageInvalidationCounter); 380 381 assertEquals(0, image.getWidth(), 0); 382 assertEquals(0, image.getHeight(), 0); 383 assertEquals(null, image.impl_getPlatformImage()); 384 385 lastAsyncImageLoader.finish(); 386 387 assertEquals(1, widthInvalidationCounter.getCounter()); 388 assertEquals(1, heightInvalidationCounter.getCounter()); 389 assertEquals(1, plImageInvalidationCounter.getCounter()); 390 } 391 392 @Test 393 public void imagePropertiesChangedAtomicallyTest() { 394 final String url = "file:test.png"; 395 registerImage(url, 200, 100); 396 397 final Image image = new Image(url, true); 398 final StubAsyncImageLoader lastAsyncImageLoader = 399 getLastAsyncImageLoader(); 400 401 final InvalidationListener imageChecker = 402 observable -> { 403 assertEquals(200, image.getWidth(), 0); 404 assertEquals(100, image.getHeight(), 0); 405 assertNotNull(image.impl_getPlatformImage()); 406 }; 407 408 image.widthProperty().addListener(imageChecker); 409 image.heightProperty().addListener(imageChecker); 410 Toolkit.getImageAccessor().getImageProperty(image).addListener(imageChecker); 411 412 assertEquals(0, image.getWidth(), 0); 413 assertEquals(0, image.getHeight(), 0); 414 assertEquals(null, image.impl_getPlatformImage()); 415 416 lastAsyncImageLoader.finish(); 417 } 418 419 private static void verifyLoadedImage(final Image image, 420 final int loadWidth, 421 final int loadHeight, 422 final boolean preserveRatio, 423 final boolean smooth, 424 final int imageWidth, 425 final int imageHeight) { 426 assertFalse(image.isError()); 427 assertEquals(1, (int) image.getProgress()); 428 429 final StubPlatformImage platformImage = 430 getPlatformImage(image); 431 assertEquals(0, platformImage.getFrame()); 432 433 final StubImageLoader imageLoader = 434 platformImage.getImageLoader(); 435 assertEquals(loadWidth, imageLoader.getLoadWidth()); 436 assertEquals(loadHeight, imageLoader.getLoadHeight()); 437 assertEquals(preserveRatio, imageLoader.getPreserveRatio()); 438 assertEquals(smooth, imageLoader.getSmooth()); 439 440 assertEquals(imageWidth, (int) image.getWidth()); 441 assertEquals(imageHeight, (int) image.getHeight()); 442 } 443 444 private static StubPlatformImage getPlatformImage(final Image srcImage) { 445 final Object unknownPlatformImage = srcImage.impl_getPlatformImage(); 446 assertTrue(unknownPlatformImage instanceof StubPlatformImage); 447 return (StubPlatformImage) unknownPlatformImage; 448 } 449 450 private void registerImage(final Object source, 451 final int width, 452 final int height) { 453 imageLoaderFactory.registerImage( 454 source, new StubPlatformImageInfo(width, height)); 455 } 456 457 private StubAsyncImageLoader getLastAsyncImageLoader() { 458 final StubAsyncImageLoader lastAsyncImageLoader = 459 imageLoaderFactory.getLastAsyncImageLoader(); 460 assertNotNull(lastAsyncImageLoader); 461 assertTrue(lastAsyncImageLoader.isStarted()); 462 463 return lastAsyncImageLoader; 464 } 465 466 @Test 467 public void createImageFromClasspathTest() { 468 final String url = "javafx/scene/image/test.png"; 469 final String resolvedUrl = Thread.currentThread().getContextClassLoader().getResource(url).toString(); 470 registerImage(resolvedUrl, 100, 200); 471 472 final Image image = new Image(url); 473 474 assertEquals(resolvedUrl, image.impl_getUrl()); 475 verifyLoadedImage(image, 0, 0, false, false, 100, 200); 476 } 477 478 @Test 479 public void createImageFromClasspathTest_withLeadingSlash() { 480 final String url = "/javafx/scene/image/test.png"; 481 final String resolvedUrl = Thread.currentThread().getContextClassLoader().getResource(url.substring(1)).toString(); 482 registerImage(resolvedUrl, 100, 200); 483 484 final Image image = new Image(url); 485 486 assertEquals(resolvedUrl, image.impl_getUrl()); 487 verifyLoadedImage(image, 0, 0, false, false, 100, 200); 488 } 489 490 @Test(expected=NullPointerException.class) 491 public void createImageFromNullUrlTest() { 492 new Image((String) null); 493 } 494 495 @Test(expected=NullPointerException.class) 496 public void createImageAsyncFromNullUrlTest() { 497 new Image(null, true); 498 } 499 500 @Test(expected=NullPointerException.class) 501 public void createImageFromNullInputStreamTest() { 502 new Image((InputStream) null); 503 } 504 505 @Test(expected=IllegalArgumentException.class) 506 public void createImageFromEmptyUrlTest() { 507 new Image(""); 508 } 509 510 @Test(expected=IllegalArgumentException.class) 511 public void createImageAsyncFromEmptyUrlTest() { 512 new Image("", true); 513 } 514 515 @Test(expected=IllegalArgumentException.class) 516 public void createImageFromInvalidUrlTest() { 517 new Image(":"); 518 } 519 520 @Test(expected=IllegalArgumentException.class) 521 public void createImageAsyncFromInvalidUrlTest() { 522 new Image(":", true); 523 } 524 525 @Test(expected=IllegalArgumentException.class) 526 public void createImageFromUnsupportedUrlTest() { 527 new Image("unsupported:image.png"); 528 } 529 530 @Test(expected=IllegalArgumentException.class) 531 public void createImageAsyncFromUnsupportedUrlTest() { 532 new Image("unsupported:image.png", true); 533 } 534 }