1 /*
   2  * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.css;
  27 
  28 import java.io.File;
  29 import java.lang.reflect.InvocationTargetException;
  30 import java.lang.reflect.Method;
  31 import java.lang.reflect.Modifier;
  32 import java.net.URL;
  33 import java.util.ArrayList;
  34 import java.util.Arrays;
  35 import java.util.Collections;
  36 import java.util.List;
  37 import java.util.Set;
  38 
  39 import com.sun.javafx.css.CascadingStyle;
  40 import com.sun.javafx.css.ParsedValueImpl;
  41 import com.sun.javafx.css.PseudoClassState;
  42 import com.sun.javafx.css.StyleManager;
  43 import test.com.sun.javafx.css.TestNode;
  44 import test.com.sun.javafx.css.TestNodeBase;
  45 import com.sun.javafx.sg.prism.NGNode;
  46 import javafx.beans.value.WritableValue;
  47 import javafx.scene.Group;
  48 import javafx.scene.Node;
  49 import javafx.scene.Scene;
  50 import javafx.scene.paint.Color;
  51 import javafx.scene.shape.Rectangle;
  52 import javafx.scene.text.Font;
  53 import javafx.scene.text.Text;
  54 import javafx.stage.Stage;
  55 import javafx.css.converter.BooleanConverter;
  56 import com.sun.javafx.geom.BaseBounds;
  57 import com.sun.javafx.geom.transform.BaseTransform;
  58 import com.sun.javafx.jmx.MXNodeAlgorithm;
  59 import com.sun.javafx.jmx.MXNodeAlgorithmContext;
  60 import com.sun.javafx.scene.NodeHelper;
  61 import javafx.css.CompoundSelector;
  62 import javafx.css.CssMetaData;
  63 import javafx.css.CssParser;
  64 import javafx.css.Declaration;
  65 import javafx.css.DeclarationShim;
  66 import javafx.css.FontCssMetaData;
  67 import javafx.css.ParsedValue;
  68 import javafx.css.PseudoClass;
  69 import javafx.css.Rule;
  70 import javafx.css.RuleShim;
  71 import javafx.css.Selector;
  72 import javafx.css.SelectorShim;
  73 import javafx.css.SimpleSelector;
  74 import javafx.css.SimpleSelectorShim;
  75 import javafx.css.Style;
  76 import javafx.css.StyleConverter;
  77 import javafx.css.StyleOrigin;
  78 import javafx.css.Styleable;
  79 import javafx.css.StyleableProperty;
  80 import javafx.css.Stylesheet;
  81 import javafx.css.StylesheetShim;
  82 import org.junit.Test;
  83 
  84 import static org.junit.Assert.*;
  85 
  86 
  87 public class CssMetaDataTest {
  88 
  89     public CssMetaDataTest() {
  90     }
  91 
  92     private static CssMetaData get(List<CssMetaData<? extends Styleable, ?>> list, String prop) {
  93         for (CssMetaData styleable : list) {
  94             if (prop.equals(styleable.getProperty())) return styleable;
  95         }
  96         return null;
  97     }
  98 
  99     /**
 100      * Test of getCssMetaData method of class Styleable.
 101      */
 102     @Test
 103     public void testGetCssMetaData_Styleable() {
 104         Styleable styleable = new TestNode();
 105         List<CssMetaData<? extends Styleable, ?>> expResult = TestNode.getClassCssMetaData();
 106         List result = styleable.getCssMetaData();
 107         assertEquals(expResult, result);
 108     }
 109 
 110     @Test
 111     public void testGetJavafxBeansProperty() {
 112         TestNode testNode = new TestNode();
 113         WritableValue prop = TestNodeBase.StyleableProperties.TEST.getStyleableProperty(testNode);
 114         assert(prop != null);
 115         CssMetaData result = ((StyleableProperty)prop).getCssMetaData();
 116         assert(result == TestNodeBase.StyleableProperties.TEST);
 117     }
 118 
 119     /**
 120      * Test of getProperty method, of class CssMetaData.
 121      */
 122     @Test
 123     public void testGetProperty() {
 124 
 125         String expResult = "-fx-test";
 126         String result = TestNodeBase.StyleableProperties.TEST.getProperty();
 127         assertEquals(expResult, result);
 128     }
 129 
 130     /**
 131      * Test of getConverter method, of class CssMetaData.
 132      */
 133     @Test
 134     public void testGetConverter() {
 135 
 136         StyleConverter expResult = BooleanConverter.getInstance();
 137         StyleConverter result = TestNodeBase.StyleableProperties.TEST.getConverter();
 138         assertEquals(expResult, result);
 139     }
 140 
 141     /**
 142      * Test of getInitialValue method, of class CssMetaData.
 143      */
 144     @Test
 145     public void testGetInitialValue() {
 146 
 147         TestNode testNode = new TestNode();
 148         Double expResult = testNode.getXyzzy();
 149         Double result = (Double)TestNode.StyleableProperties.XYZZY.getInitialValue(testNode);
 150         assertEquals(expResult, result);
 151 
 152     }
 153 
 154     /**
 155      * Test of getSubProperties method, of class CssMetaData.
 156      */
 157     @Test
 158     public void testGetSubProperties() {
 159 
 160         CssMetaData<TestNode,Font> fontProp =
 161                 new FontCssMetaData<TestNode>("-fx-font", Font.getDefault()) {
 162 
 163                     @Override
 164                     public boolean isSettable(TestNode n) {
 165                         return true;
 166                     }
 167 
 168                     @Override
 169                     public StyleableProperty<Font> getStyleableProperty(TestNode n) {
 170                         return null;
 171                     }
 172                 };
 173 
 174         List<CssMetaData<? extends Styleable, ?>> list = fontProp.getSubProperties();
 175         assertNotNull(list);
 176 
 177     }
 178 
 179     /**
 180      * Test of isInherits method, of class CssMetaData.
 181      */
 182     @Test
 183     public void testIsInherits() {
 184 
 185         boolean expResult = false;
 186         boolean result = TestNode.StyleableProperties.XYZZY.isInherits();
 187         assertEquals(expResult, result);
 188 
 189     }
 190 
 191     /**
 192      * Test of toString method, of class CssMetaData.
 193      */
 194     @Test
 195     public void testToString() {
 196 
 197         CssMetaData<TestNode,Font> fontProp =
 198                 new FontCssMetaData<TestNode>("-fx-font", Font.getDefault()) {
 199 
 200                     @Override
 201                     public boolean isSettable(TestNode n) {
 202                         return true;
 203                     }
 204 
 205                     @Override
 206                     public StyleableProperty<Font> getStyleableProperty(TestNode n) {
 207                         return null;
 208                     }
 209                 };
 210 
 211         String string = fontProp.toString();
 212         assertNotNull(string);
 213 
 214     }
 215 
 216     /**
 217      * Test of equals method, of class CssMetaData.
 218      */
 219     @Test
 220     public void testEquals() {
 221         TestNode testNode = new TestNode();
 222         Node node = new Node() {
 223         };
 224 
 225         CssMetaData testNodeOpacity = get(TestNode.getClassCssMetaData(), "-fx-opacity");
 226         CssMetaData nodeOpacity = get(Node.getClassCssMetaData(), "-fx-opacity");
 227 
 228         assertTrue(testNodeOpacity.equals(nodeOpacity));
 229     }
 230 
 231     static int ord = 0;
 232     static CascadingStyle createCascadingStyle(Selector selector, Declaration declaration) {
 233 
 234         Set<PseudoClass> pseudoClasses = null;
 235         if (selector instanceof SimpleSelector) {
 236 
 237             pseudoClasses =
 238                     SimpleSelectorShim.getPseudoClassStates((SimpleSelector)selector);
 239         } else {
 240 
 241             pseudoClasses = new PseudoClassState();
 242             for (SimpleSelector sel : ((CompoundSelector)selector).getSelectors()) {
 243 
 244                 Set<PseudoClass> selectorPseudoClasses = SimpleSelectorShim.getPseudoClassStates(sel);
 245                 pseudoClasses.addAll(selectorPseudoClasses);
 246             }
 247         }
 248 
 249         return new CascadingStyle(
 250                 new Style(selector, declaration),
 251                 pseudoClasses,
 252                 0,
 253                 ord++
 254         );
 255     }
 256 
 257     @Test @org.junit.Ignore
 258     public void testGetMatchingStyles() {
 259 
 260 
 261         final Stylesheet stylesheet = StylesheetShim.getStylesheet();
 262         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 263         StyleManager.getInstance().getInstance().setDefaultUserAgentStylesheet(stylesheet);
 264 
 265         final List<Rule> rules = stylesheet.getRules();
 266 
 267         //
 268         // .root { -fx-base: red; -fx-color: -fx-base; }
 269         //
 270         List<String> rootStyleClass = new ArrayList<String>();
 271         rootStyleClass.add("root");
 272 
 273         Selector root = SimpleSelectorShim.getSimpleSelector("*", rootStyleClass, null, null);
 274 
 275         ParsedValue fxBaseValue = new CssParser().parseExpr("-fx-base", "red");
 276         Declaration fxBase = DeclarationShim.getDeclaration("-fx-base", fxBaseValue, false);
 277 
 278         ParsedValueImpl<String,String> fxColorValue = new ParsedValueImpl<String,String>(fxBase.getProperty(), null, true);
 279         Declaration fxColor = DeclarationShim.getDeclaration("-fx-color", fxColorValue, false);
 280 
 281         List<Selector> selectors = new ArrayList<Selector>();
 282         Collections.addAll(selectors, root);
 283 
 284         List<Declaration> declarations = new ArrayList<Declaration>();
 285         Collections.addAll(declarations, fxBase, fxColor);
 286 
 287         Rule baseRule = RuleShim.getRule(selectors, declarations);
 288         rules.add(baseRule);
 289 
 290         //
 291         // .rect { -fx-fill: -fx-color; }
 292         //
 293         List<String> rectStyleClass = new ArrayList<String>();
 294         rectStyleClass.add("rect");
 295 
 296         Selector rect = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, null, null);
 297 
 298         ParsedValue fxFillValue = new CssParser().parseExpr("-fx-fill", "-fx-color");
 299         Declaration fxFill = DeclarationShim.getDeclaration("-fx-fill", fxFillValue, false);
 300 
 301         selectors = new ArrayList<Selector>();
 302         Collections.addAll(selectors, rect);
 303 
 304         declarations = new ArrayList<Declaration>();
 305         Collections.addAll(declarations, fxFill);
 306 
 307         Rule rectRule = RuleShim.getRule(selectors, declarations);
 308         rules.add(rectRule);
 309 
 310         // .rect:hover { -fx-fill: yellow; }
 311         List<String> pseudoclasses = new ArrayList<String>();
 312         pseudoclasses.add("hover");
 313 
 314         Selector rectHover = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, pseudoclasses, null);
 315 
 316         ParsedValueImpl<Color,Color> fxFillHoverValue = new ParsedValueImpl<Color,Color>(Color.YELLOW, null);
 317         Declaration fxFillHover = DeclarationShim.getDeclaration("-fx-fill", fxFillHoverValue, false);
 318 
 319         selectors = new ArrayList<Selector>();
 320         Collections.addAll(selectors, rectHover);
 321 
 322         declarations = new ArrayList<Declaration>();
 323         Collections.addAll(declarations, fxFillHover);
 324 
 325         Rule rectHoverRule = RuleShim.getRule(selectors, declarations);
 326         rules.add(rectHoverRule);
 327 
 328         List<Style> expecteds = new ArrayList<Style>();
 329         Collections.addAll(expecteds,
 330                            new Style(root, fxBase),
 331                            new Style(root, fxColor),
 332                            new Style(rect, fxFill),
 333                            new Style(rectHover, fxFillHover)
 334         );
 335 
 336         final Rectangle rectangle = new Rectangle();
 337         rectangle.getStyleClass().add("rect");
 338 
 339         final Group group = new Group();
 340         group.getChildren().add(rectangle);
 341 
 342         Scene scene = new Scene(group);
 343         Stage stage = new Stage();
 344         stage.setScene(scene);
 345         stage.show();
 346 
 347         final CssMetaData FILL = get(rectangle.getCssMetaData(), "-fx-fill");
 348         final List<Style> actuals = NodeHelper.getMatchingStyles(FILL, rectangle);
 349 
 350         //        System.err.println("matchingStyles: " + matchingStyles);
 351         //        System.err.println("expecteds: " + expecteds);
 352         //        System.err.println("actuals: " + actuals);
 353 
 354         assertEquals(expecteds.size(), actuals.size(), 0);
 355 
 356         for (Style style : expecteds) {
 357             if (!actuals.remove(style)) fail();
 358         }
 359         assertTrue(actuals.isEmpty());
 360     }
 361 
 362     @Test @org.junit.Ignore
 363     public void testGetMatchingStylesWithInlineStyleOnParent() {
 364 
 365 
 366         final Stylesheet stylesheet = StylesheetShim.getStylesheet();
 367         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 368         StyleManager.getInstance().getInstance().setDefaultUserAgentStylesheet(stylesheet);
 369 
 370         final List<Rule> rules = stylesheet.getRules();
 371 
 372         //
 373         // .root { -fx-base: red; -fx-color: -fx-base; }
 374         //
 375         List<String> rootStyleClass = new ArrayList<String>();
 376         rootStyleClass.add("root");
 377 
 378         Selector root = SimpleSelectorShim.getSimpleSelector("*", rootStyleClass, null, null);
 379 
 380         ParsedValue fxBaseValue = new CssParser().parseExpr("-fx-base", "red");
 381         Declaration fxBase = DeclarationShim.getDeclaration("-fx-base", fxBaseValue, false);
 382 
 383         ParsedValueImpl<String,String> fxColorValue = new ParsedValueImpl<String,String>(fxBase.getProperty(), null, true);
 384         Declaration fxColor = DeclarationShim.getDeclaration("-fx-color", fxColorValue, false);
 385 
 386         List<Selector> selectors = new ArrayList<Selector>();
 387         Collections.addAll(selectors, root);
 388 
 389         List<Declaration> declarations = new ArrayList<Declaration>();
 390         Collections.addAll(declarations, fxBase, fxColor);
 391 
 392         Rule baseRule = RuleShim.getRule(selectors, declarations);
 393         rules.add(baseRule);
 394 
 395         //
 396         // .rect { -fx-fill: -fx-color; }
 397         //
 398         List<String> rectStyleClass = new ArrayList<String>();
 399         rectStyleClass.add("rect");
 400 
 401         Selector rect = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, null, null);
 402 
 403         ParsedValue fxFillValue = new CssParser().parseExpr("-fx-fill", "-fx-color");
 404         Declaration fxFill = DeclarationShim.getDeclaration("-fx-fill", fxFillValue, false);
 405 
 406         selectors = new ArrayList<Selector>();
 407         Collections.addAll(selectors, rect);
 408 
 409         declarations = new ArrayList<Declaration>();
 410         Collections.addAll(declarations, fxFill);
 411 
 412         Rule rectRule = RuleShim.getRule(selectors, declarations);
 413         rules.add(rectRule);
 414 
 415         // .rect:hover { -fx-fill: yellow; }
 416         List<String> pseudoclasses = new ArrayList<String>();
 417         pseudoclasses.add("hover");
 418 
 419         Selector rectHover = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, pseudoclasses, null);
 420 
 421         ParsedValueImpl<Color,Color> fxFillHoverValue = new ParsedValueImpl<Color,Color>(Color.YELLOW, null);
 422         Declaration fxFillHover = DeclarationShim.getDeclaration("-fx-fill", fxFillHoverValue, false);
 423 
 424         selectors = new ArrayList<Selector>();
 425         Collections.addAll(selectors, rectHover);
 426 
 427         declarations = new ArrayList<Declaration>();
 428         Collections.addAll(declarations, fxFillHover);
 429 
 430         Rule rectHoverRule = RuleShim.getRule(selectors, declarations);
 431         rules.add(rectHoverRule);
 432 
 433         // Declaration now checks origin, so we need to make this expected
 434         // value look like it came from an inline
 435         final Declaration decl = DeclarationShim.getDeclaration("-fx-base", new ParsedValueImpl<Color,Color>(Color.GREEN, null), false);
 436 
 437         Stylesheet ss = new StylesheetShim(null) {
 438             {
 439                 setOrigin(StyleOrigin.INLINE);
 440                 getRules().add(
 441                         RuleShim.getRule(Arrays.asList(SelectorShim.getUniversalSelector()), Arrays.asList(decl))
 442                 );
 443             }
 444         };
 445 
 446         List<Style> expecteds = new ArrayList<Style>();
 447         Collections.addAll(expecteds,
 448                            new Style(SelectorShim.getUniversalSelector(), decl),
 449                            new Style(root, fxBase),
 450                            new Style(root, fxColor),
 451                            new Style(rect, fxFill),
 452                            new Style(rectHover, fxFillHover)
 453         );
 454 
 455         final Rectangle rectangle = new Rectangle();
 456         rectangle.getStyleClass().add("rect");
 457 
 458         final Group group = new Group();
 459         group.setStyle("-fx-base: green;");
 460         group.getChildren().add(rectangle);
 461 
 462         Scene scene = new Scene(group);
 463         Stage stage = new Stage();
 464         stage.setScene(scene);
 465         stage.show();
 466 
 467         final CssMetaData FILL = get(rectangle.getCssMetaData(), "-fx-fill");
 468         final List<Style> actuals = NodeHelper.getMatchingStyles(FILL, rectangle);
 469 
 470         //        System.err.println("matchingStyles: " + matchingStyles);
 471         //        System.err.println("expecteds: " + expecteds);
 472         //        System.err.println("actuals: " + actuals);
 473 
 474         assertEquals(expecteds.size(), actuals.size(), 0);
 475 
 476         // inline style should be first
 477         assertEquals(expecteds.get(0), actuals.get(0));
 478 
 479         for (Style style : expecteds) {
 480             if (!actuals.remove(style)) fail();
 481         }
 482         assertTrue(actuals.isEmpty());
 483     }
 484 
 485     @Test @org.junit.Ignore
 486     public void testGetMatchingStylesWithInlineStyleOnLeaf() {
 487 
 488 
 489         final Stylesheet stylesheet = StylesheetShim.getStylesheet();
 490         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 491         StyleManager.getInstance().getInstance().setDefaultUserAgentStylesheet(stylesheet);
 492 
 493         final List<Rule> rules = stylesheet.getRules();
 494 
 495         //
 496         // .root { -fx-base: red; -fx-color: -fx-base; }
 497         //
 498         List<String> rootStyleClass = new ArrayList<String>();
 499         rootStyleClass.add("root");
 500 
 501         Selector root = SimpleSelectorShim.getSimpleSelector("*", rootStyleClass, null, null);
 502 
 503         ParsedValue fxBaseValue = new CssParser().parseExpr("-fx-base", "red");
 504         Declaration fxBase = DeclarationShim.getDeclaration("-fx-base", fxBaseValue, false);
 505 
 506         ParsedValueImpl<String,String> fxColorValue = new ParsedValueImpl<String,String>(fxBase.getProperty(), null, true);
 507         Declaration fxColor = DeclarationShim.getDeclaration("-fx-color", fxColorValue, false);
 508 
 509         List<Selector> selectors = new ArrayList<Selector>();
 510         Collections.addAll(selectors, root);
 511 
 512         List<Declaration> declarations = new ArrayList<Declaration>();
 513         Collections.addAll(declarations, fxBase, fxColor);
 514 
 515         Rule baseRule = RuleShim.getRule(selectors, declarations);
 516         rules.add(baseRule);
 517 
 518         //
 519         // .rect { -fx-fill: -fx-color; }
 520         //
 521         List<String> rectStyleClass = new ArrayList<String>();
 522         rectStyleClass.add("rect");
 523 
 524         Selector rect = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, null, null);
 525 
 526         ParsedValue fxFillValue = new CssParser().parseExpr("-fx-fill", "-fx-color");
 527         Declaration fxFill = DeclarationShim.getDeclaration("-fx-fill", fxFillValue, false);
 528 
 529         selectors = new ArrayList<Selector>();
 530         Collections.addAll(selectors, rect);
 531 
 532         declarations = new ArrayList<Declaration>();
 533         Collections.addAll(declarations, fxFill);
 534 
 535         Rule rectRule = RuleShim.getRule(selectors, declarations);
 536         rules.add(rectRule);
 537 
 538         // .rect:hover { -fx-fill: yellow; }
 539         List<String> pseudoclasses = new ArrayList<String>();
 540         pseudoclasses.add("hover");
 541 
 542         Selector rectHover = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, pseudoclasses, null);
 543 
 544         ParsedValueImpl<Color,Color> fxFillHoverValue = new ParsedValueImpl<Color,Color>(Color.YELLOW, null);
 545         Declaration fxFillHover = DeclarationShim.getDeclaration("-fx-fill", fxFillHoverValue, false);
 546 
 547         selectors = new ArrayList<Selector>();
 548         Collections.addAll(selectors, rectHover);
 549 
 550         declarations = new ArrayList<Declaration>();
 551         Collections.addAll(declarations, fxFillHover);
 552 
 553         Rule rectHoverRule = RuleShim.getRule(selectors, declarations);
 554         rules.add(rectHoverRule);
 555 
 556         // Declaration now checks origin, so we need to make this expected
 557         // value look like it came from an inline
 558         final Declaration decl = DeclarationShim.getDeclaration("-fx-base", new ParsedValueImpl<Color,Color>(Color.GREEN, null), false);
 559 
 560         Stylesheet ss = new StylesheetShim(null) {
 561             {
 562                 setOrigin(StyleOrigin.INLINE);
 563                 getRules().add(
 564                         RuleShim.getRule(Arrays.asList(SelectorShim.getUniversalSelector()), Arrays.asList(decl))
 565                 );
 566             }
 567         };
 568 
 569         List<Style> expecteds = new ArrayList<Style>();
 570         Collections.addAll(expecteds,
 571                            new Style(SelectorShim.getUniversalSelector(), decl),
 572                            new Style(root, fxBase),
 573                            new Style(root, fxColor),
 574                            new Style(rect, fxFill),
 575                            new Style(rectHover, fxFillHover)
 576         );
 577 
 578         final Rectangle rectangle = new Rectangle();
 579         rectangle.getStyleClass().add("rect");
 580         rectangle.setStyle("-fx-base: green;");
 581 
 582         final Group group = new Group();
 583         group.getChildren().add(rectangle);
 584 
 585         Scene scene = new Scene(group);
 586         Stage stage = new Stage();
 587         stage.setScene(scene);
 588         stage.show();
 589 
 590         final CssMetaData FILL = get(rectangle.getCssMetaData(), "-fx-fill");
 591         final List<Style> actuals = NodeHelper.getMatchingStyles(FILL, rectangle);
 592 
 593         //        System.err.println("matchingStyles: " + matchingStyles);
 594         //        System.err.println("expecteds: " + expecteds);
 595         //        System.err.println("actuals: " + actuals);
 596 
 597         assertEquals(expecteds.size(), actuals.size(), 0);
 598 
 599         // inline style should be first
 600         assertEquals(expecteds.get(0), actuals.get(0));
 601 
 602         for (Style style : expecteds) {
 603             if (!actuals.remove(style)) fail();
 604         }
 605         assertTrue(actuals.isEmpty());
 606     }
 607 
 608     @Test @org.junit.Ignore
 609     public void testGetMatchingStylesWithInlineStyleOnRootAndLeaf() {
 610 
 611 
 612         final Stylesheet stylesheet = StylesheetShim.getStylesheet();
 613         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 614         StyleManager.getInstance().getInstance().setDefaultUserAgentStylesheet(stylesheet);
 615 
 616         final List<Rule> rules = stylesheet.getRules();
 617 
 618         //
 619         // .root { -fx-base: red; -fx-color: -fx-base; }
 620         //
 621         List<String> rootStyleClass = new ArrayList<String>();
 622         rootStyleClass.add("root");
 623 
 624         Selector root = SimpleSelectorShim.getSimpleSelector("*", rootStyleClass, null, null);
 625 
 626         ParsedValue fxBaseValue = new CssParser().parseExpr("-fx-base", "red");
 627         Declaration fxBase = DeclarationShim.getDeclaration("-fx-base", fxBaseValue, false);
 628 
 629         ParsedValueImpl<String,String> fxColorValue = new ParsedValueImpl<String,String>(fxBase.getProperty(), null, true);
 630         Declaration fxColor = DeclarationShim.getDeclaration("-fx-color", fxColorValue, false);
 631 
 632         List<Selector> selectors = new ArrayList<Selector>();
 633         Collections.addAll(selectors, root);
 634 
 635         List<Declaration> declarations = new ArrayList<Declaration>();
 636         Collections.addAll(declarations, fxBase, fxColor);
 637 
 638         Rule baseRule = RuleShim.getRule(selectors, declarations);
 639         rules.add(baseRule);
 640 
 641         //
 642         // .rect { -fx-fill: -fx-color; }
 643         //
 644         List<String> rectStyleClass = new ArrayList<String>();
 645         rectStyleClass.add("rect");
 646 
 647         Selector rect = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, null, null);
 648 
 649         ParsedValue fxFillValue = new CssParser().parseExpr("-fx-fill", "-fx-color");
 650         Declaration fxFill = DeclarationShim.getDeclaration("-fx-fill", fxFillValue, false);
 651 
 652         selectors = new ArrayList<Selector>();
 653         Collections.addAll(selectors, rect);
 654 
 655         declarations = new ArrayList<Declaration>();
 656         Collections.addAll(declarations, fxFill);
 657 
 658         Rule rectRule = RuleShim.getRule(selectors, declarations);
 659         rules.add(rectRule);
 660 
 661         // .rect:hover { -fx-fill: yellow; }
 662         List<String> pseudoclasses = new ArrayList<String>();
 663         pseudoclasses.add("hover");
 664 
 665         Selector rectHover = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, pseudoclasses, null);
 666 
 667         ParsedValueImpl<Color,Color> fxFillHoverValue = new ParsedValueImpl<Color,Color>(Color.YELLOW, null);
 668         Declaration fxFillHover = DeclarationShim.getDeclaration("-fx-fill", fxFillHoverValue, false);
 669 
 670         selectors = new ArrayList<Selector>();
 671         Collections.addAll(selectors, rectHover);
 672 
 673         declarations = new ArrayList<Declaration>();
 674         Collections.addAll(declarations, fxFillHover);
 675 
 676         Rule rectHoverRule = RuleShim.getRule(selectors, declarations);
 677         rules.add(rectHoverRule);
 678 
 679         // Declaration now checks origin, so we need to make this expected
 680         // value look like it came from an inline
 681         final Declaration gdecl = DeclarationShim.getDeclaration("-fx-base", new ParsedValueImpl<Color,Color>(Color.GREEN, null), false);
 682         final Declaration ydecl = DeclarationShim.getDeclaration("-fx-color", new ParsedValueImpl<Color,Color>(Color.YELLOW, null), false);
 683 
 684         Stylesheet ss = new StylesheetShim(null) {
 685             {
 686                 setOrigin(StyleOrigin.INLINE);
 687                 Collections.addAll(getRules(),
 688                                    RuleShim.getRule(Arrays.asList(SelectorShim.getUniversalSelector()), Arrays.asList(gdecl)),
 689                                    RuleShim.getRule(Arrays.asList(SelectorShim.getUniversalSelector()), Arrays.asList(ydecl))
 690                 );
 691             }
 692         };
 693 
 694         List<Style> expecteds = new ArrayList<Style>();
 695         Collections.addAll(expecteds,
 696                            new Style(SelectorShim.getUniversalSelector(), ydecl),
 697                            new Style(SelectorShim.getUniversalSelector(), gdecl),
 698                            new Style(root, fxBase),
 699                            new Style(root, fxColor),
 700                            new Style(rect, fxFill),
 701                            new Style(rectHover, fxFillHover)
 702         );
 703 
 704         final Rectangle rectangle = new Rectangle();
 705         rectangle.getStyleClass().add("rect");
 706         rectangle.setStyle("-fx-base: green;");
 707 
 708         final Group group = new Group();
 709         group.setStyle("-fx-color: yellow;");
 710         group.getChildren().add(rectangle);
 711 
 712         Scene scene = new Scene(group);
 713         Stage stage = new Stage();
 714         stage.setScene(scene);
 715         stage.show();
 716 
 717         final CssMetaData FILL = get(rectangle.getCssMetaData(), "-fx-fill");
 718         final List<Style> actuals = NodeHelper.getMatchingStyles(FILL, rectangle);
 719 
 720         //        System.err.println("matchingStyles: " + matchingStyles);
 721         //        System.err.println("expecteds: " + expecteds);
 722         //        System.err.println("actuals: " + actuals);
 723 
 724         assertEquals(expecteds.size(), actuals.size(), 0);
 725 
 726         // inline style should be first
 727         assertEquals(expecteds.get(0), actuals.get(0));
 728 
 729         for (Style style : expecteds) {
 730             if (!actuals.remove(style)) fail(style.toString());
 731         }
 732         assertTrue(actuals.isEmpty());
 733     }
 734 
 735     @Test @org.junit.Ignore
 736     public void testGetMatchingStylesShouldNotReturnAncestorPropertyIfNotInherited() {
 737 
 738 
 739         final Stylesheet stylesheet = StylesheetShim.getStylesheet();
 740         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 741         StyleManager.getInstance().getInstance().setDefaultUserAgentStylesheet(stylesheet);
 742 
 743         final List<Rule> rules = stylesheet.getRules();
 744 
 745         //
 746         // .root { -fx-base: red; -fx-color: -fx-base; }
 747         //
 748         List<String> rootStyleClass = new ArrayList<String>();
 749         rootStyleClass.add("root");
 750 
 751         Selector root = SimpleSelectorShim.getSimpleSelector("*", rootStyleClass, null, null);
 752 
 753         ParsedValue fxBaseValue = new CssParser().parseExpr("-fx-base", "red");
 754         Declaration fxBase = DeclarationShim.getDeclaration("-fx-base", fxBaseValue, false);
 755 
 756         ParsedValueImpl<String,String> fxColorValue = new ParsedValueImpl<String,String>(fxBase.getProperty(), null, true);
 757         Declaration fxColor = DeclarationShim.getDeclaration("-fx-color", fxColorValue, false);
 758 
 759         ParsedValueImpl<Color,Color> fxFillShouldNotMatchValue = new ParsedValueImpl<Color,Color>(Color.RED, null);
 760         Declaration fxFillShouldNotMatch = DeclarationShim.getDeclaration("-fx-fill", fxFillShouldNotMatchValue, false);
 761 
 762         List<Selector> selectors = new ArrayList<Selector>();
 763         Collections.addAll(selectors, root);
 764 
 765         List<Declaration> declarations = new ArrayList<Declaration>();
 766         Collections.addAll(declarations, fxBase, fxColor, fxFillShouldNotMatch);
 767 
 768         Rule baseRule = RuleShim.getRule(selectors, declarations);
 769         rules.add(baseRule);
 770 
 771         //
 772         // .rect { -fx-fill: -fx-color; }
 773         //
 774         List<String> rectStyleClass = new ArrayList<String>();
 775         rectStyleClass.add("rect");
 776 
 777         Selector rect = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, null, null);
 778 
 779         ParsedValue fxFillValue = new CssParser().parseExpr("-fx-fill", "-fx-color");
 780         Declaration fxFill = DeclarationShim.getDeclaration("-fx-fill", fxFillValue, false);
 781 
 782         selectors = new ArrayList<Selector>();
 783         Collections.addAll(selectors, rect);
 784 
 785         declarations = new ArrayList<Declaration>();
 786         Collections.addAll(declarations, fxFill);
 787 
 788         Rule rectRule = RuleShim.getRule(selectors, declarations);
 789         rules.add(rectRule);
 790 
 791         // .rect:hover { -fx-fill: yellow; }
 792         List<String> pseudoclasses = new ArrayList<String>();
 793         pseudoclasses.add("hover");
 794 
 795         Selector rectHover = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, pseudoclasses, null);
 796 
 797         ParsedValueImpl<Color,Color> fxFillHoverValue = new ParsedValueImpl<Color,Color>(Color.YELLOW, null);
 798         Declaration fxFillHover = DeclarationShim.getDeclaration("-fx-fill", fxFillHoverValue, false);
 799 
 800         selectors = new ArrayList<Selector>();
 801         Collections.addAll(selectors, rectHover);
 802 
 803         declarations = new ArrayList<Declaration>();
 804         Collections.addAll(declarations, fxFillHover);
 805 
 806         Rule rectHoverRule = RuleShim.getRule(selectors, declarations);
 807         rules.add(rectHoverRule);
 808 
 809         List<Style> expecteds = new ArrayList<Style>();
 810         Collections.addAll(expecteds,
 811                            new Style(root, fxBase),
 812                            new Style(root, fxColor),
 813                            new Style(rect, fxFill),
 814                            new Style(rectHover, fxFillHover)
 815         );
 816 
 817         final Rectangle rectangle = new Rectangle();
 818         rectangle.getStyleClass().add("rect");
 819 
 820         final Group group = new Group();
 821         group.getChildren().add(rectangle);
 822 
 823         Scene scene = new Scene(group);
 824         Stage stage = new Stage();
 825         stage.setScene(scene);
 826         stage.show();
 827 
 828         final CssMetaData FILL = get(rectangle.getCssMetaData(), "-fx-fill");
 829         final List<Style> actuals = NodeHelper.getMatchingStyles(FILL, rectangle);
 830 
 831         //        System.err.println("matchingStyles: " + matchingStyles);
 832         //        System.err.println("expecteds: " + expecteds);
 833         //        System.err.println("actuals: " + actuals);
 834 
 835         assertEquals(expecteds.size(), actuals.size(), 0);
 836 
 837         for (Style style : expecteds) {
 838             if (!actuals.remove(style)) fail();
 839         }
 840         assertTrue(actuals.isEmpty());
 841     }
 842 
 843 
 844     @Test @org.junit.Ignore
 845     public void testGetMatchingStylesShouldNotReturnInlineAncestorPropertyIfNotInherited() {
 846 
 847         final Stylesheet stylesheet = StylesheetShim.getStylesheet();
 848         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 849         StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet);
 850 
 851         final List<Rule> rules = stylesheet.getRules();
 852 
 853         List<String> rootStyleClass = new ArrayList<String>();
 854         rootStyleClass.add("root");
 855 
 856         List<String> rectStyleClass = new ArrayList<String>();
 857         rectStyleClass.add("rect");
 858 
 859         //
 860         // .root { -fx-base: red; -fx-color: -fx-base; }
 861         //
 862         Selector root = SimpleSelectorShim.getSimpleSelector("*", rootStyleClass, null, null);
 863 
 864         ParsedValue fxBaseValue = new CssParser().parseExpr("-fx-base", "red");
 865         Declaration fxBase = DeclarationShim.getDeclaration("-fx-base", fxBaseValue, false);
 866 
 867         ParsedValueImpl<String,String> fxColorValue = new ParsedValueImpl<String,String>(fxBase.getProperty(), null, true);
 868         Declaration fxColor = DeclarationShim.getDeclaration("-fx-color", fxColorValue, false);
 869 
 870         ParsedValueImpl<Color,Color> fxFillShouldNotMatchValue = new ParsedValueImpl<Color,Color>(Color.RED, null);
 871         Declaration fxFillShouldNotMatch = DeclarationShim.getDeclaration("-fx-fill", fxFillShouldNotMatchValue, false);
 872 
 873         List<Selector> selectors = new ArrayList<Selector>();
 874         Collections.addAll(selectors, root);
 875 
 876         List<Declaration> declarations = new ArrayList<Declaration>();
 877         Collections.addAll(declarations, fxBase, fxColor, fxFillShouldNotMatch);
 878 
 879         Rule baseRule = RuleShim.getRule(selectors, declarations);
 880         rules.add(baseRule);
 881 
 882         //
 883         // .rect { -fx-fill: -fx-color; }
 884         //
 885         Selector rect = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, null, null);
 886 
 887         ParsedValue fxFillValue = new CssParser().parseExpr("-fx-fill", "-fx-color");
 888         Declaration fxFill = DeclarationShim.getDeclaration("-fx-fill", fxFillValue, false);
 889 
 890         selectors = new ArrayList<Selector>();
 891         Collections.addAll(selectors, rect);
 892 
 893         declarations = new ArrayList<Declaration>();
 894         Collections.addAll(declarations, fxFill);
 895 
 896         Rule rectRule = RuleShim.getRule(selectors, declarations);
 897         rules.add(rectRule);
 898 
 899         // .rect:hover { -fx-fill: yellow; }
 900         List<String> pseudoclasses = new ArrayList<String>();
 901         pseudoclasses.add("hover");
 902 
 903         Selector rectHover = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, pseudoclasses, null);
 904 
 905         ParsedValueImpl<Color,Color> fxFillHoverValue = new ParsedValueImpl<Color,Color>(Color.YELLOW, null);
 906         Declaration fxFillHover = DeclarationShim.getDeclaration("-fx-fill", fxFillHoverValue, false);
 907 
 908         selectors = new ArrayList<Selector>();
 909         Collections.addAll(selectors, rectHover);
 910 
 911         declarations = new ArrayList<Declaration>();
 912         Collections.addAll(declarations, fxFillHover);
 913 
 914         Rule rectHoverRule = RuleShim.getRule(selectors, declarations);
 915         rules.add(rectHoverRule);
 916 
 917         List<Style> expecteds = new ArrayList<Style>();
 918         Collections.addAll(expecteds,
 919                            new Style(root, fxBase),
 920                            new Style(root, fxColor),
 921                            new Style(rect, fxFill),
 922                            new Style(rectHover, fxFillHover)
 923         );
 924 
 925         final Rectangle rectangle = new Rectangle();
 926         rectangle.getStyleClass().add("rect");
 927 
 928         final Group group = new Group();
 929         group.getChildren().add(rectangle);
 930 
 931         Scene scene = new Scene(group);
 932         Stage stage = new Stage();
 933         stage.setScene(scene);
 934         stage.show();
 935 
 936         final CssMetaData FILL = get(rectangle.getCssMetaData(), "-fx-fill");
 937         final List<Style> actuals = NodeHelper.getMatchingStyles(FILL, rectangle);
 938 
 939         //        System.err.println("matchingStyles: " + matchingStyles);
 940         //        System.err.println("expecteds: " + expecteds);
 941         //        System.err.println("actuals: " + actuals);
 942 
 943         for (Style style : expecteds) {
 944             actuals.remove(style);
 945         }
 946         assertTrue(actuals.toString(), actuals.isEmpty());
 947     }
 948 
 949     @Test @org.junit.Ignore
 950     public void testGetMatchingStylesReturnsInheritedProperty() {
 951 
 952 
 953         final Stylesheet stylesheet = StylesheetShim.getStylesheet();
 954         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 955         StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet);
 956 
 957         final List<Rule> rules = stylesheet.getRules();
 958 
 959         //
 960         // .root { -fx-base: red; -fx-color: -fx-base; }
 961         //
 962         List<String> rootStyleClass = new ArrayList<String>();
 963         rootStyleClass.add("root");
 964 
 965         Selector root = SimpleSelectorShim.getSimpleSelector("*", rootStyleClass, null, null);
 966 
 967         ParsedValue<Color,Color> fxFontShouldInheritValue = new CssParser().parseExpr("-fx-font", "12px system");
 968         Declaration fxFontShouldInherit = DeclarationShim.getDeclaration("-fx-font", fxFontShouldInheritValue, false);
 969 
 970         List<Selector> selectors = new ArrayList<Selector>();
 971         Collections.addAll(selectors, root);
 972 
 973         List<Declaration> declarations = new ArrayList<Declaration>();
 974         Collections.addAll(declarations, fxFontShouldInherit);
 975 
 976         Rule baseRule = RuleShim.getRule(selectors, declarations);
 977         rules.add(baseRule);
 978 
 979         //
 980         // .text { -fx-fill: -fx-color; }
 981         //
 982         List<String> textStyleClass = new ArrayList<String>();
 983         textStyleClass.add("text");
 984 
 985         Selector textSelector = SimpleSelectorShim.getSimpleSelector("*", textStyleClass, null, null);
 986 
 987         ParsedValue fxFillValue = new CssParser().parseExpr("-fx-fill", "red");
 988         Declaration fxFill = DeclarationShim.getDeclaration("-fx-fill", fxFillValue, false);
 989 
 990         selectors = new ArrayList<Selector>();
 991         Collections.addAll(selectors, textSelector);
 992 
 993         declarations = new ArrayList<Declaration>();
 994         Collections.addAll(declarations, fxFill);
 995 
 996         Rule rectRule = RuleShim.getRule(selectors, declarations);
 997         rules.add(rectRule);
 998 
 999         List<Style> expecteds = new ArrayList<Style>();
1000         Collections.addAll(expecteds,
1001                            new Style(root, fxFontShouldInherit)
1002         );
1003 
1004         final Text text = new Text("text");
1005         text.getStyleClass().add("text");
1006 
1007         final Group group = new Group();
1008         group.getChildren().add(text);
1009 
1010         Scene scene = new Scene(group);
1011         Stage stage = new Stage();
1012         stage.setScene(scene);
1013         stage.show();
1014 
1015         final CssMetaData FONT = get(text.getCssMetaData(), "-fx-font");
1016         final List<Style> actuals = NodeHelper.getMatchingStyles(FONT, text);
1017 
1018         //        System.err.println("matchingStyles: " + matchingStyles);
1019         //        System.err.println("expecteds: " + expecteds);
1020         //        System.err.println("actuals: " + actuals);
1021 
1022         assertEquals(expecteds.size(), actuals.size(), 0);
1023 
1024         for (Style style : expecteds) {
1025             if (!actuals.remove(style)) fail();
1026         }
1027         assertTrue(actuals.isEmpty());
1028     }
1029 
1030     @Test @org.junit.Ignore
1031     public void testGetMatchingStylesReturnsSubProperty() {
1032 
1033         final Stylesheet stylesheet = StylesheetShim.getStylesheet();
1034         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
1035         StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet);
1036 
1037         final List<Rule> rules = stylesheet.getRules();
1038 
1039         //
1040         // .root { -fx-base: red; -fx-color: -fx-base; }
1041         //
1042         List<String> rootStyleClass = new ArrayList<String>();
1043         rootStyleClass.add("root");
1044 
1045         Selector root = SimpleSelectorShim.getSimpleSelector("*", rootStyleClass, null, null);
1046 
1047         ParsedValue<Color,Color> fxFontShouldInheritValue = new CssParser().parseExpr("-fx-font", "12px system");
1048         Declaration fxFontShouldInherit = DeclarationShim.getDeclaration("-fx-font", fxFontShouldInheritValue, false);
1049 
1050         List<Selector> selectors = new ArrayList<Selector>();
1051         Collections.addAll(selectors, root);
1052 
1053         List<Declaration> declarations = new ArrayList<Declaration>();
1054         Collections.addAll(declarations, fxFontShouldInherit);
1055 
1056         Rule baseRule = RuleShim.getRule(selectors, declarations);
1057         rules.add(baseRule);
1058 
1059         //
1060         // .text { -fx-fill: -fx-color; }
1061         //
1062         List<String> rectStyleClass = new ArrayList<String>();
1063         rectStyleClass.add("text");
1064 
1065         Selector textSelector = SimpleSelectorShim.getSimpleSelector("*", rectStyleClass, null, null);
1066 
1067         ParsedValue fxFillValue = new CssParser().parseExpr("-fx-fill", "red");
1068         Declaration fxFill = DeclarationShim.getDeclaration("-fx-fill", fxFillValue, false);
1069 
1070         ParsedValue fxFontFamilyValue = new CssParser().parseExpr("-fx-font-family", "arial");
1071         Declaration fxFontFamily = DeclarationShim.getDeclaration("-fx-font-family", fxFontFamilyValue, false);
1072 
1073         selectors = new ArrayList<Selector>();
1074         Collections.addAll(selectors, textSelector);
1075 
1076         declarations = new ArrayList<Declaration>();
1077         Collections.addAll(declarations, fxFill, fxFontFamily);
1078 
1079         Rule rectRule = RuleShim.getRule(selectors, declarations);
1080         rules.add(rectRule);
1081 
1082         List<Style> expecteds = new ArrayList<Style>();
1083         Collections.addAll(expecteds,
1084                            new Style(textSelector, fxFontFamily),
1085                            new Style(root, fxFontShouldInherit)
1086         );
1087 
1088         final Text text  = new Text();
1089         text.getStyleClass().add("text");
1090 
1091         final Group group = new Group();
1092         group.getChildren().add(text);
1093 
1094         Scene scene = new Scene(group);
1095         Stage stage = new Stage();
1096         stage.setScene(scene);
1097         stage.show();
1098 
1099         final CssMetaData FONT = get(text.getCssMetaData(), "-fx-font");
1100         final List<Style> actuals = NodeHelper.getMatchingStyles(FONT, text);
1101 
1102         //        System.err.println("matchingStyles: " + matchingStyles);
1103         //        System.err.println("expecteds: " + expecteds);
1104         //        System.err.println("actuals: " + actuals);
1105 
1106         assertEquals(expecteds.size(), actuals.size(), 0);
1107 
1108         for (Style style : expecteds) {
1109             if (!actuals.remove(style)) fail();
1110         }
1111         assertTrue(actuals.isEmpty());
1112     }
1113 
1114     @Test
1115     public void testRT18097() {
1116         try {
1117             File f = System.getProperties().containsKey("CSS_META_DATA_TEST_DIR") ?
1118                     new File(System.getProperties().get("CSS_META_DATA_TEST_DIR").toString()) :
1119                     null;
1120             if (f == null) {
1121                 ClassLoader cl = Thread.currentThread().getContextClassLoader();
1122                 URL base = cl.getResource("javafx/../javafx");
1123                 f = new File(base.toURI());
1124             }
1125             //System.err.println(f.getPath());
1126             recursiveCheck(f, f.getPath().length() - 7);
1127         } catch (Exception ex) {
1128             ex.printStackTrace(System.err);
1129             fail(ex.getMessage());
1130         }
1131     }
1132 
1133     private static void checkClass(Class someClass) {
1134 
1135         if (javafx.scene.Node.class.isAssignableFrom(someClass) &&
1136                 Modifier.isAbstract(someClass.getModifiers()) == false) {
1137 
1138             String what = someClass.getName();
1139             try {
1140                 // should get NoSuchMethodException if ctor is not public
1141                 //                Constructor ctor = someClass.getConstructor((Class[])null);
1142                 Method m = someClass.getMethod("getClassCssMetaData", (Class[]) null);
1143                 //                Node node = (Node)ctor.newInstance((Object[])null);
1144                 Node node = (Node)someClass.newInstance();
1145                 List<CssMetaData<? extends Styleable, ?>> list = (List<CssMetaData<? extends Styleable, ?>>)m.invoke(null);
1146                 if(list == null || list.isEmpty()) return;
1147 
1148                 for (CssMetaData styleable : list) {
1149 
1150                     what = someClass.getName() + " " + styleable.getProperty();
1151                     WritableValue writable = styleable.getStyleableProperty(node);
1152                     assertNotNull(what, writable);
1153 
1154                     Object defaultValue = writable.getValue();
1155                     Object initialValue = styleable.getInitialValue((Node) someClass.newInstance());
1156 
1157                     if (defaultValue instanceof Number) {
1158                         // 5 and 5.0 are not the same according to equals,
1159                         // but they should be...
1160                         assert(initialValue instanceof Number);
1161                         double d1 = ((Number)defaultValue).doubleValue();
1162                         double d2 = ((Number)initialValue).doubleValue();
1163                         assertEquals(what, d1, d2, .001);
1164 
1165                     } else if (defaultValue != null && defaultValue.getClass().isArray()) {
1166                         assertTrue(what, Arrays.equals((Object[])defaultValue, (Object[])initialValue));
1167                     } else {
1168                         assertEquals(what, defaultValue, initialValue);
1169                     }
1170 
1171                 }
1172 
1173             } catch (NoSuchMethodException ex) {
1174                 System.err.println("NoSuchMethodException: " + what);
1175             } catch (IllegalAccessException ex) {
1176                 System.err.println("IllegalAccessException: " + what);
1177             } catch (IllegalArgumentException ex) {
1178                 System.err.println("IllegalArgumentException: " + what);
1179             } catch (InvocationTargetException ex) {
1180                 System.err.println("InvocationTargetException: " + what);
1181             } catch (InstantiationException ex) {
1182                 System.err.println("InstantiationException: " + what);
1183             }
1184         }
1185     }
1186 
1187     private static void checkDirectory(File directory, final int pathLength) {
1188         if (directory.isDirectory()) {
1189 
1190             for (File file : directory.listFiles()) {
1191                 if (file.isFile() && file.getName().endsWith(".class")) {
1192                     final int len = file.getPath().length() - ".class".length();
1193                     final String clName =
1194                             file.getPath().substring(pathLength+1, len).replace(File.separatorChar,'.');
1195                     try {
1196                         final Class cl = Class.forName(clName);
1197                         if (cl != null) checkClass(cl);
1198                     } catch(ClassNotFoundException ex) {
1199                         System.err.println(ex.toString() + " " + clName);
1200                     }
1201                 }
1202             }
1203         }
1204     }
1205 
1206     private static void recursiveCheck(File directory, int pathLength) {
1207         if (directory.isDirectory()) {
1208             //            System.err.println(directory.getPath());
1209             checkDirectory(directory, pathLength);
1210 
1211             for (File subFile : directory.listFiles()) {
1212                 recursiveCheck(subFile, pathLength);
1213             }
1214         }
1215     }
1216 
1217     @Test @org.junit.Ignore("tested CssMetaData#set method, which is deprecated")
1218     public void testRT_21185() {
1219 
1220         Color c1 = new Color(.1,.2,.3,1.0);
1221         Color c2 = new Color(.1,.2,.3,1.0);
1222 
1223         Rectangle rect = new Rectangle();
1224         rect.setFill(c1);
1225 
1226         StyleableProperty fill = (StyleableProperty)rect.fillProperty();
1227         StyleOrigin origin = ((StyleableProperty)rect.fillProperty()).getStyleOrigin();
1228 
1229         // set should not change the value if the values are equal and origin is same
1230         assertEquals(c1, c2);
1231         fill.applyStyle(origin, c2);
1232 
1233         assertSame(c1,rect.getFill()); // instance should not change.
1234 
1235         // set should change the value if the values are not equal.
1236         c2 = new Color(.3,.2,.1,1.0);
1237         fill.applyStyle(origin, c2);
1238         assertSame(c2,rect.getFill());
1239 
1240         // set should change the value if the origin is not the same
1241         fill.applyStyle(StyleOrigin.INLINE, c2);
1242         origin = ((StyleableProperty)rect.fillProperty()).getStyleOrigin();
1243         assertSame(StyleOrigin.INLINE, origin);
1244 
1245         // set should change the value if one is null and the other is not.
1246         rect.setFill(null);
1247         fill.applyStyle(origin, c2);
1248         assertSame(c2, rect.getFill());
1249 
1250         // set should change the value if one is null and the other is not
1251         fill.applyStyle(origin, null);
1252         assertNull(rect.getFill());
1253 
1254     }
1255 
1256 
1257     @Test  @org.junit.Ignore
1258     public void testRT_24606() {
1259 
1260         final Stylesheet stylesheet = new CssParser().parse(
1261                 ".root { -fx-base: red; }" +
1262                         ".group { -fx-color: -fx-base; }" +
1263                         ".text { -fx-fill: -fx-color; }"
1264         );
1265         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
1266         StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet);
1267 
1268         final Text text = new Text("HelloWorld");
1269         text.getStyleClass().add("text");
1270         text.setFill(Color.BLUE);
1271 
1272         final Group group = new Group();
1273         group.getStyleClass().add("group");
1274         group.getChildren().add(text);
1275 
1276         final Group root = new Group();
1277         root.getChildren().add(group);
1278 
1279         Scene scene = new Scene(root);
1280         Stage stage = new Stage();
1281         stage.setScene(scene);
1282         stage.show();
1283 
1284         CssMetaData prop = ((StyleableProperty)text.fillProperty()).getCssMetaData();
1285         List list = NodeHelper.getMatchingStyles(prop, text);
1286 
1287         assertEquals(3, list.size(), 0);
1288 
1289     }
1290 
1291 }