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