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