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 com.sun.javafx.css;
  27 
  28 import com.sun.javafx.css.parser.CSSParser;
  29 import javafx.scene.Group;
  30 import javafx.scene.Parent;
  31 import javafx.scene.Scene;
  32 import javafx.scene.SubScene;
  33 import javafx.scene.layout.Pane;
  34 import javafx.scene.paint.Color;
  35 import javafx.scene.shape.Rectangle;
  36 import javafx.stage.PopupWindow;
  37 import javafx.stage.Window;
  38 import org.junit.Before;
  39 import org.junit.Test;
  40 
  41 import java.net.URL;
  42 import java.util.List;
  43 import java.util.Map;
  44 
  45 import static org.junit.Assert.*;
  46 
  47 /**
  48  *
  49  * @author dgrieve
  50  */
  51 public class StyleManagerTest {
  52     
  53     public StyleManagerTest() {
  54     }
  55 
  56     @Before
  57     public void setUp() {
  58         StyleManager sm = StyleManager.getInstance();
  59         sm.userAgentStylesheetContainers.clear();
  60         sm.platformUserAgentStylesheetContainers.clear();
  61         sm.stylesheetContainerMap.clear();
  62         sm.cacheContainerMap.clear();
  63         sm.hasDefaultUserAgentStylesheet = false;
  64     }
  65     
  66     @Test
  67     public void testMethod_getInstance() {
  68         Scene scene = new Scene(new Group());
  69         StyleManager sm = StyleManager.getInstance();
  70         assertNotNull(sm);
  71     }
  72 
  73     private static int indexOf(final List<StyleManager.StylesheetContainer> list, final String fname) {
  74 
  75         for (int n=0, nMax=list.size(); n<nMax; n++) {
  76             StyleManager.StylesheetContainer container = list.get(n);
  77             if (fname.equals(container.fname)) {
  78                 return n;
  79             }
  80         }
  81 
  82         return -1;
  83     }
  84 
  85     @Test
  86     public void testAddUserAgentStyleshseet_String() {
  87         StyleManager sm = StyleManager.getInstance();
  88         sm.addUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
  89         int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css");
  90         assertEquals(0,index);
  91 
  92     }
  93 
  94     @Test
  95     public void testAddUserAgentStyleshseet_String_Multiple() {
  96         StyleManager sm = StyleManager.getInstance();
  97         sm.addUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
  98         sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
  99 
 100         int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css");
 101         assertEquals(0,index);
 102 
 103         index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css");
 104         assertEquals(1, index);
 105     }
 106 
 107     @Test
 108     public void testAddUserAgentStyleshseet_String_Duplicate() {
 109         StyleManager sm = StyleManager.getInstance();
 110         sm.addUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 111         sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 112         sm.addUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 113 
 114         assertTrue(sm.platformUserAgentStylesheetContainers.size() == 2);
 115 
 116         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 117         assertEquals(0,index);
 118 
 119         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 120         assertEquals(1, index);
 121 
 122     }
 123 
 124     @Test
 125     public void testSetDefaultUserAgentStyleshseet_String() {
 126         StyleManager sm = StyleManager.getInstance();
 127         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 128 
 129         int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css");
 130         assertEquals(0, index);
 131     }
 132 
 133     @Test
 134     public void testSetUserAgentStyleshseet_String_Multiple() {
 135         StyleManager sm = StyleManager.getInstance();
 136         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 137         sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 138 
 139         assertTrue(sm.platformUserAgentStylesheetContainers.size() == 2);
 140 
 141         int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css");
 142         assertEquals(0,index);
 143 
 144         index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css");
 145         assertEquals(1, index);
 146     }
 147 
 148     @Test
 149     public void testSetUserAgentStyleshseet_String_Multiple2() {
 150         StyleManager sm = StyleManager.getInstance();
 151         // same as before but set default after adding another.
 152         sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 153         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 154 
 155         assertEquals(2, sm.platformUserAgentStylesheetContainers.size());
 156 
 157         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 158         assertEquals(0,index);
 159 
 160         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 161         assertEquals(1, index);
 162     }
 163 
 164     @Test
 165     public void testSetUserAgentStyleshseet_String_Duplicate() {
 166         StyleManager sm = StyleManager.getInstance();
 167         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 168         sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 169         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 170 
 171         assertEquals(2, sm.platformUserAgentStylesheetContainers.size());
 172 
 173         int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css");
 174         assertEquals(0,index);
 175 
 176         index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css");
 177         assertEquals(1, index);
 178     }
 179 
 180     @Test
 181     public void testAddUserAgentStyleshseet_Stylesheet() {
 182 
 183         try {
 184             StyleManager sm = StyleManager.getInstance();
 185             URL ua0_url = StyleManagerTest.class.getResource("ua0.css");
 186             Stylesheet stylesheet = CSSParser.getInstance().parse(ua0_url);
 187             sm.addUserAgentStylesheet(null,stylesheet);
 188 
 189             assertEquals(1, sm.platformUserAgentStylesheetContainers.size());
 190 
 191             int index = indexOf(sm.platformUserAgentStylesheetContainers,ua0_url.toExternalForm());
 192             assertEquals(0, index);
 193 
 194         } catch (Exception ioe) {
 195             fail(ioe.getMessage());
 196         }
 197 
 198     }
 199 
 200     @Test
 201     public void testSetDefaultUserAgentStyleshseet_Stylesheet() {
 202 
 203         try {
 204             StyleManager sm = StyleManager.getInstance();
 205 
 206             URL ua1_url = StyleManagerTest.class.getResource("ua1.css");
 207             Stylesheet stylesheet = CSSParser.getInstance().parse(ua1_url);
 208             sm.addUserAgentStylesheet(null,stylesheet);
 209 
 210             URL ua0_url = StyleManagerTest.class.getResource("ua0.css");
 211             stylesheet = CSSParser.getInstance().parse(ua0_url);
 212             sm.setDefaultUserAgentStylesheet(stylesheet);
 213 
 214             assertEquals(2, sm.platformUserAgentStylesheetContainers.size());
 215 
 216             int index = indexOf(sm.platformUserAgentStylesheetContainers,ua0_url.toExternalForm());
 217             assertEquals(0, index);
 218 
 219             index = indexOf(sm.platformUserAgentStylesheetContainers,ua1_url.toExternalForm());
 220             assertEquals(1, index);
 221 
 222         } catch (Exception ioe) {
 223             fail(ioe.getMessage());
 224         }
 225 
 226     }
 227 
 228     @Test
 229     public void testSceneUAStylesheetAdded() {
 230         Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 231         scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 232 
 233         StyleManager sm = StyleManager.getInstance();
 234         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 235 
 236         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 237         assertEquals(0,index);
 238 
 239         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 240         assertEquals(-1, index);
 241 
 242         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 243         assertEquals(0,index);
 244 
 245         // the Scene user-agent stylesheet is not a platform user-agent stylesheet
 246         index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css");
 247         assertEquals(-1, index);
 248 
 249     }
 250 
 251     @Test
 252     public void testSubSceneUAStylesheetAdded() {
 253         Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 254         scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 255 
 256         StyleManager sm = StyleManager.getInstance();
 257         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 258 
 259         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 260         assertEquals(0,index);
 261 
 262         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 263         assertEquals(-1, index);
 264 
 265         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 266         assertEquals(0,index);
 267 
 268         // the Scene user-agent stylesheet is not a platform user-agent stylesheet
 269         index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css");
 270         assertEquals(-1, index);
 271 
 272     }
 273 
 274     @Test
 275     public void testForgetParent() {
 276 
 277         Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 278 
 279         StyleManager sm = StyleManager.getInstance();
 280         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 281 
 282         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 283         assertEquals(0,index);
 284 
 285         sm.forget(scene.getRoot());
 286 
 287         // forgetting the scene should not affect the platform user-agent stylesheets
 288         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 289         assertEquals(0,index);
 290 
 291     }
 292 
 293     @Test
 294     public void testForgetParent_withStylesheets() {
 295 
 296         Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 297 
 298         StyleManager sm = StyleManager.getInstance();
 299         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 300 
 301         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 302         assertEquals(0,index);
 303 
 304         sm.forget(scene.getRoot());
 305 
 306         // forgetting the scene should not affect the platform user-agent stylesheets
 307         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 308         assertEquals(0,index);
 309 
 310     }
 311 
 312     @Test
 313     public void testForgetParent_withSceneUAStylesheet() {
 314 
 315         Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 316         scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 317 
 318         StyleManager sm = StyleManager.getInstance();
 319         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 320 
 321 //        sm.findMatchingStyles(scene.getRoot(), null, null);
 322 
 323         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 324         assertEquals(0,index);
 325 
 326         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 327         assertEquals(-1, index);
 328 
 329         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 330         assertEquals(0,index);
 331 
 332         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 333         assertEquals(-1, index);
 334 
 335         sm.forget(scene.getRoot());
 336 
 337         // forgetting the parent should not affect the platform user-agent stylesheets
 338         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 339         assertEquals(0,index);
 340 
 341         // only forgetting the scene should affect the platform user-agent stylesheets
 342         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 343         assertEquals(0, index);
 344 
 345     }
 346 
 347     @Test
 348     public void testForgetParent_withTwoScenes() {
 349         Scene scene0 = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 350         scene0.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 351 
 352         Scene scene1 = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 353         scene1.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 354 
 355         StyleManager sm = StyleManager.getInstance();
 356         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 357 
 358         // even though there are two scenes using this stylesheet, there should only be one container.
 359         assertEquals(1, sm.userAgentStylesheetContainers.size());
 360 
 361         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 362         assertEquals(0,index);
 363 
 364         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 365         assertEquals(-1, index);
 366 
 367         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 368         assertEquals(0, index);
 369 
 370         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 371         assertEquals(-1, index);
 372 
 373         sm.forget(scene0.getRoot());
 374 
 375         // forgetting the scene should not affect the platform user-agent stylesheets
 376         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 377         assertEquals(0,index);
 378 
 379         // we should still have ua1.css since scene1 is still using it
 380         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 381         assertEquals(0,index);
 382 
 383         sm.forget(scene1.getRoot());
 384 
 385         // only forgetting the scene should affect the platform user-agent stylesheets
 386         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 387         assertEquals(0, index);
 388     }
 389 
 390     @Test
 391     public void testForgetParent_withParentStylesheet() {
 392 
 393         Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 394         scene.getRoot().getStylesheets().add("/com/sun/javafx/css/ua1.css");
 395 
 396         StyleManager sm = StyleManager.getInstance();
 397         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 398 
 399         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 400         assertEquals(0, index);
 401 
 402         assertTrue(sm.userAgentStylesheetContainers.isEmpty());
 403         assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css"));
 404 
 405         sm.forget(scene.getRoot());
 406 
 407         // forgetting the scene should not affect the platform user-agent stylesheets
 408         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 409         assertEquals(0, index);
 410 
 411         assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css"));
 412 
 413     }
 414 
 415     @Test
 416     public void testForgetParent_withMultipleParentStylesheets() {
 417 
 418         final Parent parent0 = new Pane(new Rectangle(){{ getStyleClass().add("rect"); }});
 419         parent0.getStylesheets().add("/com/sun/javafx/css/ua1.css");
 420 
 421         final Parent parent1 = new Pane(new Rectangle(){{ getStyleClass().add("rect"); }});
 422         parent1.getStylesheets().add("/com/sun/javafx/css/ua1.css");
 423 
 424         Scene scene = new Scene(new Group(parent0, parent1));
 425 
 426         StyleManager sm = StyleManager.getInstance();
 427         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 428 
 429         assertTrue(sm.userAgentStylesheetContainers.isEmpty());
 430 
 431         StyleManager.StylesheetContainer container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua1.css");
 432         assertNotNull(container);
 433         assertTrue(container.parentUsers.contains(parent0));
 434         assertTrue(container.parentUsers.contains(parent1));
 435 
 436         sm.forget(parent0);
 437 
 438         assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css"));
 439         assertFalse(container.parentUsers.contains(parent0));
 440         assertTrue(container.parentUsers.contains(parent1));
 441 
 442         sm.forget(parent1);
 443 
 444         assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css"));
 445         assertFalse(container.parentUsers.contains(parent0));
 446         assertFalse(container.parentUsers.contains(parent1));
 447     }
 448 
 449     @Test
 450     public void testForgetScene() {
 451 
 452         Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 453 
 454         StyleManager sm = StyleManager.getInstance();
 455         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 456 
 457         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 458         assertEquals(0,index);
 459 
 460         sm.forget(scene);
 461 
 462         // forgetting the scene should not affect the platform user-agent stylesheets
 463         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 464         assertEquals(0,index);
 465     }
 466 
 467     @Test
 468     public void testForgetScene_withUAStylesheet() {
 469 
 470         Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 471         scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 472 
 473         StyleManager sm = StyleManager.getInstance();
 474         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 475 
 476         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 477         assertEquals(0, index);
 478 
 479         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 480         assertEquals(-1, index);
 481 
 482         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 483         assertEquals(0,index);
 484 
 485         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 486         assertEquals(-1, index);
 487 
 488         sm.forget(scene);
 489 
 490         // forgetting the scene should not affect the platform user-agent stylesheets
 491         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 492         assertEquals(0,index);
 493 
 494         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 495         assertEquals(-1, index);
 496 
 497     }
 498 
 499     @Test
 500     public void testForgetScene_withTwoScenes() {
 501         Scene scene0 = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 502         scene0.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 503 
 504         Scene scene1 = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 505         scene1.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 506 
 507         StyleManager sm = StyleManager.getInstance();
 508         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 509 
 510         // even though there are two scenes using this stylesheet, there should only be one container.
 511         assertEquals(1, sm.userAgentStylesheetContainers.size());
 512 
 513         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 514         assertEquals(0,index);
 515 
 516         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 517         assertEquals(-1, index);
 518 
 519         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 520         assertEquals(0,index);
 521 
 522         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 523         assertEquals(-1, index);
 524 
 525         sm.forget(scene0);
 526 
 527         // forgetting the scene should not affect the platform user-agent stylesheets
 528         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 529         assertEquals(0,index);
 530 
 531         // we should still have ua1.css since scene1 is still using it
 532         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 533         assertEquals(0,index);
 534 
 535         sm.forget(scene1);
 536 
 537         // having forgotten scene1, userAgentStylesheetContainers should be empty.
 538         assertTrue(sm.userAgentStylesheetContainers.isEmpty());
 539     }
 540 
 541     @Test
 542     public void testForgetSubScene() {
 543 
 544         Pane subSceneRoot = new Pane(new Rectangle(){{ getStyleClass().add("rect"); }});
 545         SubScene subScene = new SubScene(subSceneRoot, 100, 100);
 546         Scene scene = new Scene(new Group(subScene));
 547 
 548         StyleManager sm = StyleManager.getInstance();
 549         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 550 
 551         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 552         assertEquals(0,index);
 553 
 554         sm.forget(subScene);
 555 
 556         // forgetting the scene should not affect the platform user-agent stylesheets
 557         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 558         assertEquals(0,index);
 559     }
 560 
 561     @Test
 562     public void testForgetSubScene_withUAStylesheet() {
 563 
 564         Pane subSceneRoot = new Pane(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 565         SubScene subScene = new SubScene(subSceneRoot, 100, 100);
 566         subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 567         Scene scene = new Scene(new Group(subScene));
 568 
 569         StyleManager sm = StyleManager.getInstance();
 570         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 571 
 572         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 573         assertEquals(0, index);
 574 
 575         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 576         assertEquals(-1, index);
 577 
 578         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 579         assertEquals(0,index);
 580 
 581         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 582         assertEquals(-1, index);
 583 
 584         sm.forget(subScene);
 585 
 586         // forgetting the scene should not affect the platform user-agent stylesheets
 587         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 588         assertEquals(0,index);
 589 
 590         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 591         assertEquals(-1, index);
 592 
 593     }
 594 
 595     @Test
 596     public void testForgetSubScene_with_UAStylesheet_and_ParentStylesheet() {
 597 
 598         // make sure forget(SubScene) get's children with stylesheets
 599         Group group = new Group(new Rectangle(){{ getStyleClass().add("rect"); }});
 600         group.getStylesheets().add("/com/sun/javafx/css/ua2.css");
 601         Pane subSceneRoot = new Pane(group);
 602         SubScene subScene = new SubScene(subSceneRoot, 100, 100);
 603         subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 604         Scene scene = new Scene(new Group(subScene));
 605 
 606         StyleManager sm = StyleManager.getInstance();
 607         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 608 
 609         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 610         assertEquals(0,index);
 611 
 612         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 613         assertEquals(-1, index);
 614 
 615         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 616         assertEquals(0,index);
 617 
 618         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 619         assertEquals(-1, index);
 620 
 621         sm.forget(subScene);
 622 
 623         // forgetting the scene should not affect the platform user-agent stylesheets
 624         index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 625         assertEquals(0,index);
 626 
 627         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 628         assertEquals(-1, index);
 629 
 630     }
 631 
 632     @Test
 633     public void testChangeSubSceneStylesheet() {
 634 
 635         Pane subSceneRoot = new Pane(new Group(new Rectangle(){{ getStyleClass().add("rect"); }}));
 636         SubScene subScene = new SubScene(subSceneRoot, 100, 100);
 637         Scene scene = new Scene(new Group(subScene));
 638 
 639         StyleManager sm = StyleManager.getInstance();
 640         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 641 
 642         int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 643         assertEquals(0,index);
 644 
 645         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css");
 646         assertEquals(-1, index);
 647 
 648         subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 649 
 650         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 651         assertEquals(0,index);
 652 
 653         sm.forget(subScene);
 654 
 655         subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua2.css");
 656 
 657         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua2.css");
 658         assertEquals(0, index);
 659 
 660         index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css");
 661         assertEquals(-1,index);
 662 
 663     }
 664 
 665     @Test
 666     public void testFindMatchingStyles_defaultStyleSheet() {
 667 
 668         StyleManager sm = StyleManager.getInstance();
 669         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 670 
 671         Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }};
 672         Scene scene = new Scene(new Group(rect));
 673 
 674         StyleMap matchingStyles = sm.findMatchingStyles(rect, null, null);
 675         Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles();
 676 
 677         assertTrue(styleMap.containsKey("-fx-fill"));
 678 
 679         List<CascadingStyle> styles = styleMap.get("-fx-fill");
 680         assertEquals(1, styles.size());
 681 
 682         Object obj = styles.get(0).getParsedValueImpl().convert(null);
 683         assertEquals(Color.RED, obj);
 684     }
 685 
 686     @Test
 687     public void testFindMatchingStyles_defaultStyleSheet_sceneUserAgentStylesheet() {
 688 
 689         StyleManager sm = StyleManager.getInstance();
 690         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 691 
 692         Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }};
 693         Scene scene = new Scene(new Group(rect));
 694         scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 695 
 696         StyleMap matchingStyles = sm.findMatchingStyles(rect, null, null);
 697         Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles();
 698 
 699         // scene stylesheet should totally replace default
 700         assertFalse(styleMap.containsKey("-fx-fill"));
 701         assertTrue(styleMap.containsKey("-fx-stroke"));
 702 
 703         List<CascadingStyle> styles = styleMap.get("-fx-stroke");
 704         assertEquals(1, styles.size());
 705 
 706         Object obj = styles.get(0).getParsedValueImpl().convert(null);
 707         assertEquals(Color.YELLOW, obj);
 708     }
 709 
 710     @Test
 711     public void testFindMatchingStyles_defaultStyleSheet_sceneUserAgentStylesheet_sceneAuthorStylesheet() {
 712 
 713         StyleManager sm = StyleManager.getInstance();
 714         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 715 
 716         Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }};
 717         Scene scene = new Scene(new Group(rect));
 718         scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 719         scene.getStylesheets().add("/com/sun/javafx/css/ua2.css");
 720 
 721         StyleMap matchingStyles = sm.findMatchingStyles(rect, null, null);
 722         Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles();
 723 
 724         // ua2.css has fill
 725         assertTrue(styleMap.containsKey("-fx-fill"));
 726         assertTrue(styleMap.containsKey("-fx-stroke"));
 727 
 728         // ua1.css and ua2.css have stroke
 729         List<CascadingStyle> styles = styleMap.get("-fx-stroke");
 730         assertEquals(2, styles.size());
 731 
 732         Object obj = styles.get(0).getParsedValueImpl().convert(null);
 733         assertEquals(Color.GREEN, obj);
 734 
 735         // ua0.css and ua2.css have fill, but we shouldn't get anything from ua0
 736         // since we have a scene user-agent stylesheet
 737         styles = styleMap.get("-fx-fill");
 738         assertEquals(1, styles.size());
 739 
 740         obj = styles.get(0).getParsedValueImpl().convert(null);
 741         assertEquals(Color.BLUE, obj);
 742     }
 743 
 744     @Test
 745     public void testFindMatchingStyles_defaultStyleSheet_subSceneUserAgentStylesheet() {
 746 
 747         StyleManager sm = StyleManager.getInstance();
 748         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 749 
 750         Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }};
 751         Pane subSceneRoot = new Pane(rect);
 752         SubScene subScene = new SubScene(subSceneRoot, 100, 100);
 753         subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 754         Scene scene = new Scene(new Group(subScene));
 755 
 756         StyleMap matchingStyles = sm.findMatchingStyles(rect, subScene, null);
 757         Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles();
 758 
 759         // SubScene stylesheet should totally replace default
 760         assertFalse(styleMap.containsKey("-fx-fill"));
 761         assertTrue(styleMap.containsKey("-fx-stroke"));
 762 
 763         List<CascadingStyle> styles = styleMap.get("-fx-stroke");
 764         assertEquals(1, styles.size());
 765 
 766         Object obj = styles.get(0).getParsedValueImpl().convert(null);
 767         assertEquals(Color.YELLOW, obj);
 768     }
 769 
 770     @Test
 771     public void testFindMatchingStyles_defaultStyleSheet_subSceneUserAgentStylesheet_parentStylesheet() {
 772 
 773         StyleManager sm = StyleManager.getInstance();
 774         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 775 
 776         Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }};
 777         Group group = new Group(rect);
 778         group.getStylesheets().add("/com/sun/javafx/css/ua2.css");
 779         Pane subSceneRoot = new Pane(group);
 780         SubScene subScene = new SubScene(subSceneRoot, 100, 100);
 781         subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 782         Scene scene = new Scene(new Group(subScene));
 783 
 784         StyleMap matchingStyles = sm.findMatchingStyles(rect, subScene, null);
 785         Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles();
 786 
 787         // ua2.css has fill
 788         assertTrue(styleMap.containsKey("-fx-fill"));
 789         assertTrue(styleMap.containsKey("-fx-stroke"));
 790 
 791         // ua1.css and ua2.css have stroke
 792         List<CascadingStyle> styles = styleMap.get("-fx-stroke");
 793         assertEquals(2, styles.size());
 794 
 795         Object obj = styles.get(0).getParsedValueImpl().convert(null);
 796         assertEquals(Color.GREEN, obj);
 797 
 798         // ua0.css and ua2.css have fill, but we shouldn't get anything from ua0
 799         // since we have a scene user-agent stylesheet
 800         styles = styleMap.get("-fx-fill");
 801         assertEquals(1, styles.size());
 802 
 803         obj = styles.get(0).getParsedValueImpl().convert(null);
 804         assertEquals(Color.BLUE, obj);
 805     }
 806 
 807     @Test
 808     public void testSwitchDefaultUserAgentStylesheets() {
 809 
 810         Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }};
 811         Group group = new Group(rect);
 812         Pane subSceneRoot = new Pane(group);
 813         SubScene subScene = new SubScene(subSceneRoot, 100, 100);
 814         Scene scene = new Scene(new Group(subScene));
 815 
 816         StyleManager sm = StyleManager.getInstance();
 817         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css");
 818 
 819         StyleMap matchingStyles = sm.findMatchingStyles(rect, subScene, null);
 820         Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles();
 821 
 822         // ua0.css has fill
 823         assertTrue(styleMap.containsKey("-fx-fill"));
 824         assertFalse(styleMap.containsKey("-fx-stroke"));
 825 
 826         List<CascadingStyle> styles = styleMap.get("-fx-fill");
 827         assertEquals(1, styles.size());
 828 
 829         Object obj = styles.get(0).getParsedValueImpl().convert(null);
 830         assertEquals(Color.RED, obj);
 831 
 832         sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua1.css");
 833 
 834         matchingStyles = sm.findMatchingStyles(rect, subScene, null);
 835         styleMap = matchingStyles.getCascadingStyles();
 836 
 837         // ua1.css has  stroke
 838         assertTrue(styleMap.containsKey("-fx-stroke"));
 839         assertFalse(styleMap.containsKey("-fx-fill"));
 840 
 841         styles = styleMap.get("-fx-stroke");
 842         assertEquals(1, styles.size());
 843 
 844         obj = styles.get(0).getParsedValueImpl().convert(null);
 845         assertEquals(Color.YELLOW, obj);
 846     }
 847 
 848     @Test
 849     public void testGetCacheContainer() {
 850 
 851         Rectangle rectangle = new Rectangle();
 852         SubScene subScene = new SubScene(null, 0, 0);
 853 
 854         StyleManager sm = StyleManager.getInstance();
 855 
 856         // no scene, should return null
 857         StyleManager.CacheContainer container = sm.getCacheContainer(rectangle, subScene);
 858 
 859         assertNull(container);
 860 
 861         // has scene, should return non-null
 862         subScene.setRoot(new Group());
 863         Scene scene = new Scene(new Group(rectangle,subScene));
 864         container = sm.getCacheContainer(rectangle, subScene);
 865 
 866         assertNotNull(container);
 867 
 868     }
 869 
 870     @Test
 871     public void testGetCacheContainer_styleable() {
 872         Rectangle rectangle = new Rectangle();
 873 
 874         StyleManager sm = StyleManager.getInstance();
 875 
 876         // no scene, should return null
 877         StyleManager.CacheContainer container = sm.getCacheContainer(rectangle, null);
 878 
 879         assertNull(container);
 880 
 881         // has scene, should return non-null
 882         Scene scene = new Scene(new Group(rectangle));
 883         container = sm.getCacheContainer(rectangle, null);
 884 
 885         assertNotNull(container);
 886 
 887     }
 888 
 889     @Test
 890     public void testGetCacheContainer_subScene() {
 891 
 892         SubScene subScene = new SubScene(null, 0, 0);
 893 
 894         StyleManager sm = StyleManager.getInstance();
 895 
 896         // no scene, should return null
 897         StyleManager.CacheContainer container = sm.getCacheContainer(null, subScene);
 898 
 899         assertNull(container);
 900 
 901         // has scene, should return non-null
 902         subScene.setRoot(new Group());
 903         Scene scene = new Scene(new Group(subScene));
 904         container = sm.getCacheContainer(null, subScene);
 905 
 906         assertNotNull(container);
 907 
 908     }
 909 
 910     @Test
 911     public void testRT_37025() {
 912 
 913         //
 914         // The issue in RT-37025 was that the stylesheet container wasn't getting removed even
 915         // though the parent had been forgotten. The StyleManager#forget(Parent) method didn't
 916         // look to see if _any_ stylesheet container had the parent as a reference.
 917         //
 918         final StyleManager sm = StyleManager.getInstance();
 919 
 920         // This test needs a bit more complexity to the scene-graph
 921         Group group = null;
 922         Pane pane = new Pane(
 923                 new Group(
 924                         new Pane(
 925                                 // I want these to be a Parent, not a Node
 926                                 new Group(new Pane(){{ getStyleClass().add("rect"); }}),
 927                                 group = new Group(new Pane(){{ getStyleClass().add("rect"); }})
 928                         )
 929                 )
 930         );
 931         pane.getStylesheets().add("/com/sun/javafx/css/ua0.css");
 932         group.getStylesheets().add("/com/sun/javafx/css/ua1.css");
 933 
 934         Group root = new Group(pane);
 935         Scene scene = new Scene(root);
 936 
 937         root.applyCss();
 938 
 939         assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua0.css"));
 940         StyleManager.StylesheetContainer container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua0.css");
 941         assertEquals(7, container.parentUsers.list.size());
 942 
 943         assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css"));
 944         container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua1.css");
 945         assertEquals(2, container.parentUsers.list.size());
 946 
 947         ((Pane)group.getParent()).getChildren().remove(group);
 948 
 949         assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css"));
 950         assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua0.css"));
 951         container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua0.css");
 952         assertEquals(5, container.parentUsers.list.size());
 953 
 954         scene.setRoot(new Group());
 955         assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua0.css"));
 956         assertFalse(StyleManager.cacheContainerMap.containsKey(root));
 957         assertTrue(StyleManager.cacheContainerMap.containsKey(scene.getRoot()));
 958 
 959     }
 960 
 961 }