1 /*
   2  * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.scene.control;
  27 
  28 import javafx.css.CssMetaData;
  29 import java.io.File;
  30 import java.lang.reflect.InvocationTargetException;
  31 import java.lang.reflect.Method;
  32 import java.lang.reflect.Modifier;
  33 import java.net.URL;
  34 import java.util.Arrays;
  35 import java.util.List;
  36 import javafx.beans.property.DoubleProperty;
  37 import javafx.beans.property.ObjectProperty;
  38 import javafx.beans.property.SimpleDoubleProperty;
  39 import javafx.beans.property.SimpleObjectProperty;
  40 import javafx.beans.value.ChangeListener;
  41 import javafx.beans.value.ObservableValue;
  42 import javafx.beans.value.WritableValue;
  43 import javafx.scene.Group;
  44 import javafx.scene.Node;
  45 import javafx.scene.shape.Rectangle;
  46 import com.sun.javafx.scene.control.Logging;
  47 import javafx.css.Styleable;
  48 import javafx.css.StyleableProperty;
  49 import javafx.scene.control.ContextMenu;
  50 import javafx.scene.control.Control;
  51 import javafx.scene.control.ControlShim;
  52 import javafx.scene.control.Skin;
  53 import javafx.scene.control.Tooltip;
  54 import org.junit.Before;
  55 import org.junit.Ignore;
  56 import org.junit.Test;
  57 import sun.util.logging.PlatformLogger;
  58 import sun.util.logging.PlatformLogger.Level;
  59 
  60 import static org.junit.Assert.*;
  61 
  62 /**
  63  * Things every Control needs to test:
  64  *  - Properties
  65  *     - Set the value, see that it changes
  66  *     - Set an illegal value, see that it is rejected
  67  *     - Bind to some other value, see that when the binding fires, the property is updated (vague)
  68  *  - CSS
  69  *     - Change state, watch the pseudo class state change
  70  *     - Default style-class has what you expect
  71  *     - (2nd order) impl_cssSettable returns true for thing in their default state
  72  *     - (2nd order) impl_cssSettable returns false for things manually specified
  73  *     - (3rd order) impl_cssKeys includes all the public properties
  74  *  - Methods
  75  *     - For all methods, calling the method mutates the state appropriately
  76  */
  77 public class ControlTest {
  78     private static final double MIN_WIDTH = 35;
  79     private static final double MIN_HEIGHT = 45;
  80     private static final double MAX_WIDTH = 2000;
  81     private static final double MAX_HEIGHT = 2011;
  82     private static final double PREF_WIDTH = 100;
  83     private static final double PREF_HEIGHT = 130;
  84     private static final double BASELINE_OFFSET = 10;
  85 
  86     private ControlStub c;
  87     private SkinStub<ControlStub> s;
  88     private ResizableRectangle skinNode;
  89 
  90     private Level originalLogLevel = null;
  91 
  92     @Before public void setUp() {
  93         c = new ControlStub();
  94         s = new SkinStub<ControlStub>(c);
  95         skinNode = new ResizableRectangle();
  96         skinNode.resize(20, 20);
  97         skinNode.minWidth = MIN_WIDTH;
  98         skinNode.minHeight = MIN_HEIGHT;
  99         skinNode.maxWidth = MAX_WIDTH;
 100         skinNode.maxHeight = MAX_HEIGHT;
 101         skinNode.prefWidth = PREF_WIDTH;
 102         skinNode.prefHeight = PREF_HEIGHT;
 103         skinNode.baselineOffset = BASELINE_OFFSET;
 104         s.setNode(skinNode);
 105     }
 106 
 107     private void disableLogging() {
 108         final PlatformLogger logger = Logging.getControlsLogger();
 109         originalLogLevel = logger.level();
 110         logger.setLevel(Level.OFF);
 111     }
 112 
 113     private void enableLogging() {
 114         final PlatformLogger logger = Logging.getControlsLogger();
 115 //        logger.setLevel(originalLogLevel);
 116         logger.setLevel(Level.FINE);
 117     }
 118 
 119     @Test public void focusTraversableIsTrueByDefault() {
 120         assertTrue(c.isFocusTraversable());
 121     }
 122 
 123     @Test public void resizableIsTrueByDefault() {
 124         assertTrue(c.isResizable());
 125     }
 126 
 127     @Test public void modifyingTheControlWidthUpdatesTheLayoutBounds() {
 128         c.resize(173, c.getHeight());
 129         assertEquals(173, c.getLayoutBounds().getWidth(), 0);
 130     }
 131 
 132     @Test public void modifyingTheControlWidthLeadsToRequestLayout() {
 133         // Make sure the Control has it's needsLayout flag cleared
 134         c.layout();
 135         assertTrue(!c.isNeedsLayout());
 136         // Run the test
 137         c.resize(173, c.getHeight());
 138         assertTrue(c.isNeedsLayout());
 139     }
 140 
 141     @Test public void modifyingTheControlHeightUpdatesTheLayoutBounds() {
 142         c.resize(c.getWidth(), 173);
 143         assertEquals(173, c.getLayoutBounds().getHeight(), 0);
 144     }
 145 
 146     @Test public void modifyingTheControlHeightLeadsToRequestLayout() {
 147         // Make sure the Control has it's needsLayout flag cleared
 148         c.layout();
 149         assertTrue(!c.isNeedsLayout());
 150         // Run the test
 151         c.resize(c.getWidth(), 173);
 152         assertTrue(c.isNeedsLayout());
 153     }
 154 
 155     @Test public void multipleModificationsToWidthAndHeightAreReflectedInLayoutBounds() {
 156         c.resize(723, 234);
 157         c.resize(992, 238);
 158         assertEquals(992, c.getLayoutBounds().getWidth(), 0);
 159         assertEquals(238, c.getLayoutBounds().getHeight(), 0);
 160     }
 161 
 162     @Test public void containsDelegatesToTheSkinWhenSet() {
 163         c.setSkin(s);
 164         skinNode.resize(100, 100);
 165         assertTrue(c.getSkin().getNode() != null);
 166         assertTrue(c.contains(50, 50));
 167     }
 168 
 169     @Test public void intersectsReturnsTrueWhenThereIsNoSkin() {
 170         c.relocate(0, 0);
 171         c.resize(100, 100);
 172         assertTrue(c.intersects(50, 50, 100, 100));
 173     }
 174 
 175     @Test public void intersectsDelegatesToTheSkinWhenSet() {
 176         c.setSkin(s);
 177         skinNode.resize(100, 100);
 178         assertTrue(c.intersects(50, 50, 100, 100));
 179     }
 180 
 181     @Test public void skinIsResizedToExactSizeOfControlOnLayout() {
 182         c.setSkin(s);
 183         c.resize(67, 998);
 184         c.layout();
 185         assertEquals(0, s.getNode().getLayoutBounds().getMinX(), 0);
 186         assertEquals(0, s.getNode().getLayoutBounds().getMinY(), 0);
 187         assertEquals(67, s.getNode().getLayoutBounds().getWidth(), 0);
 188         assertEquals(998, s.getNode().getLayoutBounds().getHeight(), 0);
 189     }
 190 
 191     @Test public void skinWithNodeLargerThanControlDoesntAffectLayoutBounds() {
 192         s.setNode(new Rectangle(0, 0, 1000, 1001));
 193         c.setSkin(s);
 194         c.resize(50, 40);
 195         c.layout();
 196         // Sanity check: the layout bounds of the skin node itself is large
 197         assertEquals(1000, c.getSkin().getNode().getLayoutBounds().getWidth(), 0);
 198         assertEquals(1001, c.getSkin().getNode().getLayoutBounds().getHeight(), 0);
 199         // Test: the layout bounds of the control is still 50, 40
 200         assertEquals(50, c.getLayoutBounds().getWidth(), 0);
 201         assertEquals(40, c.getLayoutBounds().getHeight(), 0);
 202     }
 203 
 204     /****************************************************************************
 205      * minWidth Tests                                                           *
 206      ***************************************************************************/
 207 
 208     @Test public void callsToSetMinWidthResultInRequestLayoutBeingCalledOnParentNotOnControl() {
 209         // Setup and sanity check
 210         Group parent = new Group();
 211         parent.getChildren().add(c);
 212         parent.layout();
 213         assertTrue(!parent.isNeedsLayout());
 214         assertTrue(!c.isNeedsLayout());
 215         // Test
 216         c.setMinWidth(123.45);
 217         assertTrue(parent.isNeedsLayout());
 218         assertTrue(!c.isNeedsLayout());
 219     }
 220 
 221     @Test public void getMinWidthReturnsTheMinWidthOfTheSkinNode() {
 222         c.setSkin(s);
 223         assertEquals(MIN_WIDTH, c.minWidth(-1), 0.0);
 224     }
 225 
 226     @Test public void getMinWidthReturnsTheCustomSetMinWidthWhenSpecified() {
 227         c.setSkin(s);
 228         c.setMinWidth(123.45);
 229         assertEquals(123.45, c.minWidth(-1), 0.0);
 230     }
 231 
 232     @Test public void getMinWidthReturnsTheCustomSetMinWidthWhenSpecifiedEvenWhenThereIsNoSkin() {
 233         c.setMinWidth(123.45);
 234         assertEquals(123.45, c.minWidth(-1), 0.0);
 235     }
 236 
 237     @Test public void minWidthWhenNoSkinIsSetIsZeroByDefault() {
 238         assertEquals(0, c.minWidth(-1), 0.0);
 239     }
 240 
 241     @Test public void resettingMinWidthTo_USE_PREF_SIZE_ReturnsThePrefWidthOfTheSkinNodeWhenThereIsASkin() {
 242         c.setSkin(s);
 243         c.setMinWidth(123.45);
 244         c.setMinWidth(Control.USE_PREF_SIZE);
 245         assertEquals(PREF_WIDTH, c.minWidth(-1), 0.0);
 246     }
 247 
 248     @Test public void resettingMinWidthTo_USE_PREF_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefWidthIsNotSet() {
 249         c.setMinWidth(123.45);
 250         c.setMinWidth(Control.USE_PREF_SIZE);
 251         assertEquals(0, c.minWidth(-1), 0.0);
 252     }
 253 
 254     @Test public void resettingMinWidthTo_USE_PREF_SIZE_ReturnsPrefWidthWhenThereIsNoSkinAndPrefWidthIsSet() {
 255         c.setMinWidth(123.45);
 256         c.setPrefWidth(98.6);
 257         c.setMinWidth(Control.USE_PREF_SIZE);
 258         assertEquals(98.6, c.minWidth(-1), 0.0);
 259     }
 260 
 261     @Test public void resettingMinWidthTo_USE_COMPUTED_SIZE_ReturnsTheMinWidthOfTheSkinNodeWhenThereIsASkin() {
 262         c.setSkin(s);
 263         c.setMinWidth(123.45);
 264         c.setMinWidth(Control.USE_COMPUTED_SIZE);
 265         assertEquals(MIN_WIDTH, c.minWidth(-1), 0.0);
 266     }
 267 
 268     @Test public void resettingMinWidthTo_USE_COMPUTED_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefWidthIsNotSet() {
 269         c.setMinWidth(123.45);
 270         c.setMinWidth(Control.USE_COMPUTED_SIZE);
 271         assertEquals(0, c.minWidth(-1), 0.0);
 272     }
 273 
 274     @Test public void minWidthIs_USE_COMPUTED_SIZE_ByDefault() {
 275         assertEquals(Control.USE_COMPUTED_SIZE, c.getMinWidth(), 0);
 276         assertEquals(Control.USE_COMPUTED_SIZE, c.minWidthProperty().get(), 0);
 277     }
 278 
 279     @Test public void minWidthCanBeSet() {
 280         c.setMinWidth(234);
 281         assertEquals(234, c.getMinWidth(), 0);
 282         assertEquals(234, c.minWidthProperty().get(), 0);
 283     }
 284 
 285     @Test public void minWidthCanBeBound() {
 286         DoubleProperty other = new SimpleDoubleProperty(939);
 287         c.minWidthProperty().bind(other);
 288         assertEquals(939, c.getMinWidth(), 0);
 289         other.set(332);
 290         assertEquals(332, c.getMinWidth(), 0);
 291     }
 292 
 293     @Test public void minWidthPropertyHasBeanReference() {
 294         assertSame(c, c.minWidthProperty().getBean());
 295     }
 296 
 297     @Test public void minWidthPropertyHasName() {
 298         assertEquals("minWidth", c.minWidthProperty().getName());
 299     }
 300 
 301     /****************************************************************************
 302      * minHeight Tests                                                          *
 303      ***************************************************************************/
 304 
 305     @Test public void callsToSetMinHeightResultInRequestLayoutBeingCalledOnParentNotOnControl() {
 306         // Setup and sanity check
 307         Group parent = new Group();
 308         parent.getChildren().add(c);
 309         parent.layout();
 310         assertTrue(!parent.isNeedsLayout());
 311         assertTrue(!c.isNeedsLayout());
 312         // Test
 313         c.setMinHeight(98.76);
 314         assertTrue(parent.isNeedsLayout());
 315         assertTrue(!c.isNeedsLayout());
 316     }
 317 
 318     @Test public void getMinHeightReturnsTheMinHeightOfTheSkinNode() {
 319         c.setSkin(s);
 320         assertEquals(MIN_HEIGHT, c.minHeight(-1), 0.0);
 321     }
 322 
 323     @Test public void getMinHeightReturnsTheCustomSetMinHeightWhenSpecified() {
 324         c.setSkin(s);
 325         c.setMinHeight(98.76);
 326         assertEquals(98.76, c.minHeight(-1), 0.0);
 327     }
 328 
 329     @Test public void getMinHeightReturnsTheCustomSetMinHeightWhenSpecifiedEvenWhenThereIsNoSkin() {
 330         c.setMinHeight(98.76);
 331         assertEquals(98.76, c.minHeight(-1), 0.0);
 332     }
 333 
 334     @Test public void minHeightWhenNoSkinIsSetIsZeroByDefault() {
 335         assertEquals(0, c.minHeight(-1), 0.0);
 336     }
 337 
 338     @Test public void resettingMinHeightTo_USE_PREF_SIZE_ReturnsThePrefHeightOfTheSkinNodeWhenThereIsASkin() {
 339         c.setSkin(s);
 340         c.setMinHeight(98.76);
 341         c.setMinHeight(Control.USE_PREF_SIZE);
 342         assertEquals(PREF_HEIGHT, c.minHeight(-1), 0.0);
 343     }
 344 
 345     @Test public void resettingMinHeightTo_USE_PREF_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefHeightIsNotSet() {
 346         c.setMinHeight(98.76);
 347         c.setMinHeight(Control.USE_PREF_SIZE);
 348         assertEquals(0, c.minHeight(-1), 0.0);
 349     }
 350 
 351     @Test public void resettingMinHeightTo_USE_PREF_SIZE_ReturnsPrefHeightWhenThereIsNoSkinAndPrefHeightIsSet() {
 352         c.setMinHeight(98.76);
 353         c.setPrefHeight(105.2);
 354         c.setMinHeight(Control.USE_PREF_SIZE);
 355         assertEquals(105.2, c.minHeight(-1), 0.0);
 356     }
 357 
 358     @Test public void resettingMinHeightTo_USE_COMPUTED_SIZE_ReturnsTheMinHeightOfTheSkinNodeWhenThereIsASkin() {
 359         c.setSkin(s);
 360         c.setMinHeight(98.76);
 361         c.setMinHeight(Control.USE_COMPUTED_SIZE);
 362         assertEquals(MIN_HEIGHT, c.minHeight(-1), 0.0);
 363     }
 364 
 365     @Test public void resettingMinHeightTo_USE_COMPUTED_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefHeightIsNotSet() {
 366         c.setMinHeight(98.76);
 367         c.setMinHeight(Control.USE_COMPUTED_SIZE);
 368         assertEquals(0, c.minHeight(-1), 0.0);
 369     }
 370 
 371     @Test public void minHeightIs_USE_COMPUTED_SIZE_ByDefault() {
 372         assertEquals(Control.USE_COMPUTED_SIZE, c.getMinHeight(), 0);
 373         assertEquals(Control.USE_COMPUTED_SIZE, c.minHeightProperty().get(), 0);
 374     }
 375 
 376     @Test public void minHeightCanBeSet() {
 377         c.setMinHeight(98.76);
 378         assertEquals(98.76, c.getMinHeight(), 0);
 379         assertEquals(98.76, c.minHeightProperty().get(), 0);
 380     }
 381 
 382     @Test public void minHeightCanBeBound() {
 383         DoubleProperty other = new SimpleDoubleProperty(939);
 384         c.minHeightProperty().bind(other);
 385         assertEquals(939, c.getMinHeight(), 0);
 386         other.set(332);
 387         assertEquals(332, c.getMinHeight(), 0);
 388     }
 389 
 390     @Test public void minHeightPropertyHasBeanReference() {
 391         assertSame(c, c.minHeightProperty().getBean());
 392     }
 393 
 394     @Test public void minHeightPropertyHasName() {
 395         assertEquals("minHeight", c.minHeightProperty().getName());
 396     }
 397 
 398     /****************************************************************************
 399      * maxWidth Tests                                                           *
 400      ***************************************************************************/
 401 
 402     @Test public void callsToSetMaxWidthResultInRequestLayoutBeingCalledOnParentNotOnControl() {
 403         // Setup and sanity check
 404         Group parent = new Group();
 405         parent.getChildren().add(c);
 406         parent.layout();
 407         assertTrue(!parent.isNeedsLayout());
 408         assertTrue(!c.isNeedsLayout());
 409         // Test
 410         c.setMaxWidth(500);
 411         assertTrue(parent.isNeedsLayout());
 412         assertTrue(!c.isNeedsLayout());
 413     }
 414 
 415     @Test public void getMaxWidthReturnsTheMaxWidthOfTheSkinNode() {
 416         c.setSkin(s);
 417         assertEquals(MAX_WIDTH, c.maxWidth(-1), 0.0);
 418     }
 419 
 420     @Test public void getMaxWidthReturnsTheCustomSetMaxWidthWhenSpecified() {
 421         c.setSkin(s);
 422         c.setMaxWidth(500);
 423         assertEquals(500, c.maxWidth(-1), 0.0);
 424     }
 425 
 426     @Test public void getMaxWidthReturnsTheCustomSetMaxWidthWhenSpecifiedEvenWhenThereIsNoSkin() {
 427         c.setMaxWidth(500);
 428         assertEquals(500, c.maxWidth(-1), 0.0);
 429     }
 430 
 431     @Test public void maxWidthWhenNoSkinIsSetIsZeroByDefault() {
 432         assertEquals(0, c.maxWidth(-1), 0.0);
 433     }
 434 
 435     @Test public void resettingMaxWidthTo_USE_PREF_SIZE_ReturnsThePrefWidthOfTheSkinNodeWhenThereIsASkin() {
 436         c.setSkin(s);
 437         c.setMaxWidth(500);
 438         c.setMaxWidth(Control.USE_PREF_SIZE);
 439         assertEquals(PREF_WIDTH, c.maxWidth(-1), 0.0);
 440     }
 441 
 442     @Test public void resettingMaxWidthTo_USE_PREF_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefWidthIsNotSet() {
 443         c.setMaxWidth(500);
 444         c.setMaxWidth(Control.USE_PREF_SIZE);
 445         assertEquals(0, c.maxWidth(-1), 0.0);
 446     }
 447 
 448     @Test public void resettingMaxWidthTo_USE_PREF_SIZE_ReturnsPrefWidthWhenThereIsNoSkinAndPrefWidthIsSet() {
 449         c.setMaxWidth(500);
 450         c.setPrefWidth(98.6);
 451         c.setMaxWidth(Control.USE_PREF_SIZE);
 452         assertEquals(98.6, c.maxWidth(-1), 0.0);
 453     }
 454 
 455     @Test public void resettingMaxWidthTo_USE_COMPUTED_SIZE_ReturnsTheMaxWidthOfTheSkinNodeWhenThereIsASkin() {
 456         c.setSkin(s);
 457         c.setMaxWidth(500);
 458         c.setMaxWidth(Control.USE_COMPUTED_SIZE);
 459         assertEquals(MAX_WIDTH, c.maxWidth(-1), 0.0);
 460     }
 461 
 462     @Test public void resettingMaxWidthTo_USE_COMPUTED_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefWidthIsNotSet() {
 463         c.setMaxWidth(500);
 464         c.setMaxWidth(Control.USE_COMPUTED_SIZE);
 465         assertEquals(0, c.maxWidth(-1), 0.0);
 466     }
 467 
 468     @Test public void maxWidthIs_USE_COMPUTED_SIZE_ByDefault() {
 469         assertEquals(Control.USE_COMPUTED_SIZE, c.getMaxWidth(), 0);
 470         assertEquals(Control.USE_COMPUTED_SIZE, c.maxWidthProperty().get(), 0);
 471     }
 472 
 473     @Test public void maxWidthCanBeSet() {
 474         c.setMaxWidth(500);
 475         assertEquals(500, c.getMaxWidth(), 0);
 476         assertEquals(500, c.maxWidthProperty().get(), 0);
 477     }
 478 
 479     @Test public void maxWidthCanBeBound() {
 480         DoubleProperty other = new SimpleDoubleProperty(939);
 481         c.maxWidthProperty().bind(other);
 482         assertEquals(939, c.getMaxWidth(), 0);
 483         other.set(332);
 484         assertEquals(332, c.getMaxWidth(), 0);
 485     }
 486 
 487     @Test public void maxWidthPropertyHasBeanReference() {
 488         assertSame(c, c.maxWidthProperty().getBean());
 489     }
 490 
 491     @Test public void maxWidthPropertyHasName() {
 492         assertEquals("maxWidth", c.maxWidthProperty().getName());
 493     }
 494 
 495     /****************************************************************************
 496      * maxHeight Tests                                                          *
 497      ***************************************************************************/
 498 
 499     @Test public void callsToSetMaxHeightResultInRequestLayoutBeingCalledOnParentNotOnControl() {
 500         // Setup and sanity check
 501         Group parent = new Group();
 502         parent.getChildren().add(c);
 503         parent.layout();
 504         assertTrue(!parent.isNeedsLayout());
 505         assertTrue(!c.isNeedsLayout());
 506         // Test
 507         c.setMaxHeight(450);
 508         assertTrue(parent.isNeedsLayout());
 509         assertTrue(!c.isNeedsLayout());
 510     }
 511 
 512     @Test public void getMaxHeightReturnsTheMaxHeightOfTheSkinNode() {
 513         c.setSkin(s);
 514         assertEquals(MAX_HEIGHT, c.maxHeight(-1), 0.0);
 515     }
 516 
 517     @Test public void getMaxHeightReturnsTheCustomSetMaxHeightWhenSpecified() {
 518         c.setSkin(s);
 519         c.setMaxHeight(450);
 520         assertEquals(450, c.maxHeight(-1), 0.0);
 521     }
 522 
 523     @Test public void getMaxHeightReturnsTheCustomSetMaxHeightWhenSpecifiedEvenWhenThereIsNoSkin() {
 524         c.setMaxHeight(500);
 525         assertEquals(500, c.maxHeight(-1), 0.0);
 526     }
 527 
 528     @Test public void maxHeightWhenNoSkinIsSetIsZeroByDefault() {
 529         assertEquals(0, c.maxHeight(-1), 0.0);
 530     }
 531 
 532     @Test public void resettingMaxHeightTo_USE_PREF_SIZE_ReturnsThePrefHeightOfTheSkinNodeWhenThereIsASkin() {
 533         c.setSkin(s);
 534         c.setMaxHeight(500);
 535         c.setMaxHeight(Control.USE_PREF_SIZE);
 536         assertEquals(PREF_HEIGHT, c.maxHeight(-1), 0.0);
 537     }
 538 
 539     @Test public void resettingMaxHeightTo_USE_PREF_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefHeightIsNotSet() {
 540         c.setMaxHeight(500);
 541         c.setMaxHeight(Control.USE_PREF_SIZE);
 542         assertEquals(0, c.maxHeight(-1), 0.0);
 543     }
 544 
 545     @Test public void resettingMaxHeightTo_USE_PREF_SIZE_ReturnsPrefHeightWhenThereIsNoSkinAndPrefHeightIsSet() {
 546         c.setMaxHeight(500);
 547         c.setPrefHeight(105.2);
 548         c.setMaxHeight(Control.USE_PREF_SIZE);
 549         assertEquals(105.2, c.maxHeight(-1), 0.0);
 550     }
 551 
 552     @Test public void resettingMaxHeightTo_USE_COMPUTED_SIZE_ReturnsTheMaxHeightOfTheSkinNodeWhenThereIsASkin() {
 553         c.setSkin(s);
 554         c.setMaxHeight(500);
 555         c.setMaxHeight(Control.USE_COMPUTED_SIZE);
 556         assertEquals(MAX_HEIGHT, c.maxHeight(-1), 0.0);
 557     }
 558 
 559     @Test public void resettingMaxHeightTo_USE_COMPUTED_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefHeightIsNotSet() {
 560         c.setMaxHeight(500);
 561         c.setMaxHeight(Control.USE_COMPUTED_SIZE);
 562         assertEquals(0, c.maxHeight(-1), 0.0);
 563     }
 564 
 565     @Test public void maxHeightIs_USE_COMPUTED_SIZE_ByDefault() {
 566         assertEquals(Control.USE_COMPUTED_SIZE, c.getMaxHeight(), 0);
 567         assertEquals(Control.USE_COMPUTED_SIZE, c.maxHeightProperty().get(), 0);
 568     }
 569 
 570     @Test public void maxHeightCanBeSet() {
 571         c.setMaxHeight(500);
 572         assertEquals(500, c.getMaxHeight(), 0);
 573         assertEquals(500, c.maxHeightProperty().get(), 0);
 574     }
 575 
 576     @Test public void maxHeightCanBeBound() {
 577         DoubleProperty other = new SimpleDoubleProperty(939);
 578         c.maxHeightProperty().bind(other);
 579         assertEquals(939, c.getMaxHeight(), 0);
 580         other.set(332);
 581         assertEquals(332, c.getMaxHeight(), 0);
 582     }
 583 
 584     @Test public void maxHeightPropertyHasBeanReference() {
 585         assertSame(c, c.maxHeightProperty().getBean());
 586     }
 587 
 588     @Test public void maxHeightPropertyHasName() {
 589         assertEquals("maxHeight", c.maxHeightProperty().getName());
 590     }
 591 
 592     /****************************************************************************
 593      * prefWidth Tests                                                          *
 594      ***************************************************************************/
 595 
 596     @Test public void callsToSetPrefWidthResultInRequestLayoutBeingCalledOnParentNotOnControl() {
 597         // Setup and sanity check
 598         Group parent = new Group();
 599         parent.getChildren().add(c);
 600         parent.layout();
 601         assertTrue(!parent.isNeedsLayout());
 602         assertTrue(!c.isNeedsLayout());
 603         // Test
 604         c.setPrefWidth(80);
 605         assertTrue(parent.isNeedsLayout());
 606         assertTrue(!c.isNeedsLayout());
 607     }
 608 
 609     @Test public void getPrefWidthReturnsThePrefWidthOfTheSkinNode() {
 610         c.setSkin(s);
 611         assertEquals(PREF_WIDTH, c.prefWidth(-1), 0.0);
 612     }
 613 
 614     @Test public void getPrefWidthReturnsTheCustomSetPrefWidthWhenSpecified() {
 615         c.setSkin(s);
 616         c.setPrefWidth(80);
 617         assertEquals(80, c.prefWidth(-1), 0.0);
 618     }
 619 
 620     @Test public void getPrefWidthReturnsTheCustomSetPrefWidthWhenSpecifiedEvenWhenThereIsNoSkin() {
 621         c.setPrefWidth(80);
 622         assertEquals(80, c.prefWidth(-1), 0.0);
 623     }
 624 
 625     @Test public void prefWidthWhenNoSkinIsSetIsZeroByDefault() {
 626         assertEquals(0, c.prefWidth(-1), 0.0);
 627     }
 628 
 629     @Ignore ("What should happen when the pref width is set to USE_PREF_SIZE? Seems it should be an exception")
 630     @Test public void resettingPrefWidthTo_USE_PREF_SIZE_ThrowsExceptionWhenThereIsASkin() {
 631         c.setSkin(s);
 632         c.setPrefWidth(80);
 633         c.setPrefWidth(Control.USE_PREF_SIZE);
 634         assertEquals(PREF_WIDTH, c.prefWidth(-1), 0.0);
 635     }
 636 
 637     @Test public void resettingPrefWidthTo_USE_COMPUTED_SIZE_ReturnsThePrefWidthOfTheSkinNodeWhenThereIsASkin() {
 638         c.setSkin(s);
 639         c.setPrefWidth(80);
 640         c.setPrefWidth(Control.USE_COMPUTED_SIZE);
 641         assertEquals(PREF_WIDTH, c.prefWidth(-1), 0.0);
 642     }
 643 
 644     @Test public void resettingPrefWidthTo_USE_COMPUTED_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefWidthIsNotSet() {
 645         c.setPrefWidth(80);
 646         c.setPrefWidth(Control.USE_COMPUTED_SIZE);
 647         assertEquals(0, c.prefWidth(-1), 0.0);
 648     }
 649 
 650     @Test public void prefWidthIs_USE_COMPUTED_SIZE_ByDefault() {
 651         assertEquals(Control.USE_COMPUTED_SIZE, c.getPrefWidth(), 0);
 652         assertEquals(Control.USE_COMPUTED_SIZE, c.prefWidthProperty().get(), 0);
 653     }
 654 
 655     @Test public void prefWidthCanBeSet() {
 656         c.setPrefWidth(80);
 657         assertEquals(80, c.getPrefWidth(), 0);
 658         assertEquals(80, c.prefWidthProperty().get(), 0);
 659     }
 660 
 661     @Test public void prefWidthCanBeBound() {
 662         DoubleProperty other = new SimpleDoubleProperty(939);
 663         c.prefWidthProperty().bind(other);
 664         assertEquals(939, c.getPrefWidth(), 0);
 665         other.set(332);
 666         assertEquals(332, c.getPrefWidth(), 0);
 667     }
 668 
 669     @Test public void prefWidthPropertyHasBeanReference() {
 670         assertSame(c, c.prefWidthProperty().getBean());
 671     }
 672 
 673     @Test public void prefWidthPropertyHasName() {
 674         assertEquals("prefWidth", c.prefWidthProperty().getName());
 675     }
 676 
 677     /****************************************************************************
 678      * prefHeight Tests                                                         *
 679      ***************************************************************************/
 680 
 681     @Test public void callsToSetPrefHeightResultInRequestLayoutBeingCalledOnParentNotOnControl() {
 682         // Setup and sanity check
 683         Group parent = new Group();
 684         parent.getChildren().add(c);
 685         parent.layout();
 686         assertTrue(!parent.isNeedsLayout());
 687         assertTrue(!c.isNeedsLayout());
 688         // Test
 689         c.setPrefHeight(92);
 690         assertTrue(parent.isNeedsLayout());
 691         assertTrue(!c.isNeedsLayout());
 692     }
 693 
 694     @Test public void getPrefHeightReturnsThePrefHeightOfTheSkinNode() {
 695         c.setSkin(s);
 696         assertEquals(PREF_HEIGHT, c.prefHeight(-1), 0.0);
 697     }
 698 
 699     @Test public void getPrefHeightReturnsTheCustomSetPrefHeightWhenSpecified() {
 700         c.setSkin(s);
 701         c.setPrefHeight(92);
 702         assertEquals(92, c.prefHeight(-1), 0.0);
 703     }
 704 
 705     @Test public void getPrefHeightReturnsTheCustomSetPrefHeightWhenSpecifiedEvenWhenThereIsNoSkin() {
 706         c.setPrefHeight(92);
 707         assertEquals(92, c.prefHeight(-1), 0.0);
 708     }
 709 
 710     @Test public void prefHeightWhenNoSkinIsSetIsZeroByDefault() {
 711         assertEquals(0, c.prefHeight(-1), 0.0);
 712     }
 713 
 714     @Ignore ("What should happen when the pref width is set to USE_PREF_SIZE? Seems it should be an exception")
 715     @Test public void resettingPrefHeightTo_USE_PREF_SIZE_ThrowsExceptionWhenThereIsASkin() {
 716         c.setSkin(s);
 717         c.setPrefHeight(92);
 718         c.setPrefHeight(Control.USE_PREF_SIZE);
 719         assertEquals(PREF_HEIGHT, c.prefHeight(-1), 0.0);
 720     }
 721 
 722     @Test public void resettingPrefHeightTo_USE_COMPUTED_SIZE_ReturnsThePrefHeightOfTheSkinNodeWhenThereIsASkin() {
 723         c.setSkin(s);
 724         c.setPrefHeight(92);
 725         c.setPrefHeight(Control.USE_COMPUTED_SIZE);
 726         assertEquals(PREF_HEIGHT, c.prefHeight(-1), 0.0);
 727     }
 728 
 729     @Test public void resettingPrefHeightTo_USE_COMPUTED_SIZE_ReturnsZeroWhenThereIsNoSkinAndPrefHeightIsNotSet() {
 730         c.setPrefHeight(92);
 731         c.setPrefHeight(Control.USE_COMPUTED_SIZE);
 732         assertEquals(0, c.prefHeight(-1), 0.0);
 733     }
 734 
 735     @Test public void prefHeightIs_USE_COMPUTED_SIZE_ByDefault() {
 736         assertEquals(Control.USE_COMPUTED_SIZE, c.getPrefHeight(), 0);
 737         assertEquals(Control.USE_COMPUTED_SIZE, c.prefHeightProperty().get(), 0);
 738     }
 739 
 740     @Test public void prefHeightCanBeSet() {
 741         c.setPrefHeight(98.76);
 742         assertEquals(98.76, c.getPrefHeight(), 0);
 743         assertEquals(98.76, c.prefHeightProperty().get(), 0);
 744     }
 745 
 746     @Test public void prefHeightCanBeBound() {
 747         DoubleProperty other = new SimpleDoubleProperty(939);
 748         c.prefHeightProperty().bind(other);
 749         assertEquals(939, c.getPrefHeight(), 0);
 750         other.set(332);
 751         assertEquals(332, c.getPrefHeight(), 0);
 752     }
 753 
 754     @Test public void prefHeightPropertyHasBeanReference() {
 755         assertSame(c, c.prefHeightProperty().getBean());
 756     }
 757 
 758     @Test public void prefHeightPropertyHasName() {
 759         assertEquals("prefHeight", c.prefHeightProperty().getName());
 760     }
 761 
 762     /*********************************************************************
 763      * Tests for the skin property                                       *
 764      ********************************************************************/
 765 
 766     @Test public void skinIsNullByDefault() {
 767         assertNull(c.getSkin());
 768         assertNull(c.contextMenuProperty().get());
 769     }
 770 
 771     @Test public void skinCanBeSet() {
 772         c.setSkin(s);
 773         assertSame(s, c.getSkin());
 774         assertSame(s, c.skinProperty().get());
 775     }
 776 
 777     @Test public void skinCanBeCleared() {
 778         c.setSkin(s);
 779         c.setSkin(null);
 780         assertNull(c.getSkin());
 781         assertNull(c.skinProperty().get());
 782     }
 783 
 784     @Test public void skinCanBeBound() {
 785         ObjectProperty other = new SimpleObjectProperty(s);
 786         c.skinProperty().bind(other);
 787         assertSame(s, c.getSkin());
 788         other.set(null);
 789         assertNull(c.getSkin());
 790     }
 791 
 792     @Test public void skinPropertyHasBeanReference() {
 793         assertSame(c, c.skinProperty().getBean());
 794     }
 795 
 796     @Test public void skinPropertyHasName() {
 797         assertEquals("skin", c.skinProperty().getName());
 798     }
 799 
 800     @Test public void canSpecifySkinViaCSS() {
 801         disableLogging();
 802         try {
 803             ((StyleableProperty)ControlShim.skinClassNameProperty(c)).applyStyle(null, "test.javafx.scene.control.SkinStub");
 804             assertNotNull(c.getSkin());
 805             assertTrue(c.getSkin() instanceof SkinStub);
 806             assertSame(c, c.getSkin().getSkinnable());
 807         } finally {
 808             enableLogging();
 809         }
 810     }
 811 
 812     @Test public void specifyingSameSkinTwiceViaCSSDoesntSetTwice() {
 813         disableLogging();
 814         try {
 815             SkinChangeListener listener = new SkinChangeListener();
 816             c.skinProperty().addListener(listener);
 817             ((StyleableProperty)ControlShim.skinClassNameProperty(c)).applyStyle(null, "test.javafx.scene.control.SkinStub");
 818             assertTrue(listener.changed);
 819             listener.changed = false;
 820             ((StyleableProperty)ControlShim.skinClassNameProperty(c)).applyStyle(null, "test.javafx.scene.control.SkinStub");
 821             assertFalse(listener.changed);
 822         } finally {
 823             enableLogging();
 824         }
 825     }
 826 
 827     @Test public void specifyingNullSkinNameHasNoEffect() {
 828         disableLogging();
 829         try {
 830             SkinChangeListener listener = new SkinChangeListener();
 831             c.skinProperty().addListener(listener);
 832             ((StyleableProperty)ControlShim.skinClassNameProperty(c)).applyStyle(null, null);
 833             assertFalse(listener.changed);
 834             assertNull(c.getSkin());
 835         } finally {
 836             enableLogging();
 837         }
 838     }
 839 
 840     @Test public void specifyingEmptyStringSkinNameHasNoEffect() {
 841         disableLogging();
 842         try {
 843             SkinChangeListener listener = new SkinChangeListener();
 844             c.skinProperty().addListener(listener);
 845             ((StyleableProperty)ControlShim.skinClassNameProperty(c)).applyStyle(null, "");
 846             assertFalse(listener.changed);
 847             assertNull(c.getSkin());
 848         } finally {
 849             enableLogging();
 850         }
 851     }
 852 
 853     @Test public void loadingSkinWithNoAppropriateConstructorResultsInNoSkin() {
 854         disableLogging();
 855         try {
 856             SkinChangeListener listener = new SkinChangeListener();
 857             c.skinProperty().addListener(listener);
 858             ((StyleableProperty)ControlShim.skinClassNameProperty(c)).applyStyle(null, "test.javafx.scene.control.ControlTest$BadSkin");
 859             assertFalse(listener.changed);
 860             assertNull(c.getSkin());
 861         } finally {
 862             enableLogging();
 863         }
 864     }
 865 
 866     @Test public void exceptionThrownDuringSkinConstructionResultsInNoSkin() {
 867         disableLogging();
 868         try {
 869             SkinChangeListener listener = new SkinChangeListener();
 870             c.skinProperty().addListener(listener);
 871             ((StyleableProperty)ControlShim.skinClassNameProperty(c)).applyStyle(null, "test.javafx.scene.control.ControlTest$ExceptionalSkin");
 872             assertFalse(listener.changed);
 873             assertNull(c.getSkin());
 874         } finally {
 875             enableLogging();
 876         }
 877     }
 878 
 879     /*********************************************************************
 880      * Tests for the tooltip property                                    *
 881      ********************************************************************/
 882 
 883     @Test public void tooltipIsNullByDefault() {
 884         assertNull(c.getTooltip());
 885         assertNull(c.tooltipProperty().get());
 886     }
 887 
 888     @Test public void tooltipCanBeSet() {
 889         Tooltip tip = new Tooltip("Hello");
 890         c.setTooltip(tip);
 891         assertSame(tip, c.getTooltip());
 892         assertSame(tip, c.tooltipProperty().get());
 893     }
 894 
 895     @Test public void tooltipCanBeCleared() {
 896         Tooltip tip = new Tooltip("Hello");
 897         c.setTooltip(tip);
 898         c.setTooltip(null);
 899         assertNull(c.getTooltip());
 900         assertNull(c.tooltipProperty().get());
 901     }
 902 
 903     @Test public void tooltipCanBeBound() {
 904         Tooltip tip = new Tooltip("Hello");
 905         ObjectProperty<Tooltip> other = new SimpleObjectProperty<Tooltip>(tip);
 906         c.tooltipProperty().bind(other);
 907         assertSame(tip, c.getTooltip());
 908         assertSame(tip, c.tooltipProperty().get());
 909         other.set(null);
 910         assertNull(c.getTooltip());
 911         assertNull(c.tooltipProperty().get());
 912     }
 913 
 914     @Test public void tooltipPropertyHasBeanReference() {
 915         assertSame(c, c.tooltipProperty().getBean());
 916     }
 917 
 918     @Test public void tooltipPropertyHasName() {
 919         assertEquals("tooltip", c.tooltipProperty().getName());
 920     }
 921 
 922     /*********************************************************************
 923      * Tests for the contextMenu property                                    *
 924      ********************************************************************/
 925 
 926     @Test public void contextMenuIsNullByDefault() {
 927         assertNull(c.getContextMenu());
 928         assertNull(c.contextMenuProperty().get());
 929     }
 930 
 931     @Test public void contextMenuCanBeSet() {
 932         ContextMenu menu = new ContextMenu();
 933         c.setContextMenu(menu);
 934         assertSame(menu, c.getContextMenu());
 935         assertSame(menu, c.contextMenuProperty().get());
 936     }
 937 
 938     @Test public void contextMenuCanBeCleared() {
 939         ContextMenu menu = new ContextMenu();
 940         c.setContextMenu(menu);
 941         c.setContextMenu(null);
 942         assertNull(c.getContextMenu());
 943         assertNull(c.getContextMenu());
 944     }
 945 
 946     @Test public void contextMenuCanBeBound() {
 947         ContextMenu menu = new ContextMenu();
 948         ObjectProperty<ContextMenu> other = new SimpleObjectProperty<ContextMenu>(menu);
 949         c.contextMenuProperty().bind(other);
 950         assertSame(menu, c.getContextMenu());
 951         assertSame(menu, c.contextMenuProperty().get());
 952         other.set(null);
 953         assertNull(c.getContextMenu());
 954         assertNull(c.contextMenuProperty().get());
 955     }
 956 
 957     @Test public void contextMenuPropertyHasBeanReference() {
 958         assertSame(c, c.contextMenuProperty().getBean());
 959     }
 960 
 961     @Test public void contextMenuPropertyHasName() {
 962         assertEquals("contextMenu", c.contextMenuProperty().getName());
 963     }
 964 
 965     /*********************************************************************
 966      * Miscellaneous tests                                               *
 967      ********************************************************************/
 968 
 969     @Test public void setMinSizeUpdatesBothMinWidthAndMinHeight() {
 970         c.setMinSize(123.45, 98.6);
 971         assertEquals(123.45, c.getMinWidth(), 0);
 972         assertEquals(98.6, c.getMinHeight(), 0);
 973     }
 974 
 975     @Test public void setMaxSizeUpdatesBothMaxWidthAndMaxHeight() {
 976         c.setMaxSize(658.9, 373.4);
 977         assertEquals(658.9, c.getMaxWidth(), 0);
 978         assertEquals(373.4, c.getMaxHeight(), 0);
 979     }
 980 
 981     @Test public void setPrefSizeUpdatesBothPrefWidthAndPrefHeight() {
 982         c.setPrefSize(720, 540);
 983         assertEquals(720, c.getPrefWidth(), 0);
 984         assertEquals(540, c.getPrefHeight(), 0);
 985     }
 986 
 987     @Test public void baselineOffsetIsZeroWhenThereIsNoSkin() {
 988         assertEquals(0, c.getBaselineOffset(), 0f);
 989     }
 990 
 991     @Test public void baselineOffsetUpdatedWhenTheSkinChanges() {
 992         c.setSkin(s);
 993         assertEquals(BASELINE_OFFSET, c.getBaselineOffset(), 0);
 994     }
 995 
 996     @Test
 997     public void testRT18097() {
 998         try {
 999             File f = System.getProperties().containsKey("CSS_META_DATA_TEST_DIR") ?
1000                     new File(System.getProperties().get("CSS_META_DATA_TEST_DIR").toString()) :
1001                     null;
1002             if (f == null) {
1003                 ClassLoader cl = Thread.currentThread().getContextClassLoader();
1004                 URL base = cl.getResource("test/javafx/../javafx");
1005                 f = new File(base.toURI());
1006             }
1007             //System.err.println(f.getPath());
1008             assertTrue("" + f.getCanonicalPath() + " is not a directory", f.isDirectory());
1009             recursiveCheck(f, f.getPath().length() - 7);
1010         } catch (Exception ex) {
1011             ex.printStackTrace(System.err);
1012             fail(ex.getMessage());
1013         }
1014     }
1015 
1016     private static void checkClass(Class someClass) {
1017 
1018         // Ignore inner classes
1019         if (someClass.getEnclosingClass() != null) return;
1020 
1021         if (javafx.scene.control.Control.class.isAssignableFrom(someClass) &&
1022                 Modifier.isAbstract(someClass.getModifiers()) == false &&
1023                 Modifier.isPrivate(someClass.getModifiers()) == false) {
1024             String what = someClass.getName();
1025             try {
1026                 // should get NoSuchMethodException if ctor is not public
1027 //                Constructor ctor = someClass.getConstructor((Class[])null);
1028                 Method m = someClass.getMethod("getClassCssMetaData", (Class[]) null);
1029 //                Node node = (Node)ctor.newInstance((Object[])null);
1030                 Node node = (Node)someClass.newInstance();
1031                 for (CssMetaData styleable : (List<CssMetaData<? extends Styleable, ?>>) m.invoke(null)) {
1032 
1033                     what = someClass.getName() + " " + styleable.getProperty();
1034                     WritableValue writable = styleable.getStyleableProperty(node);
1035                     assertNotNull(what, writable);
1036 
1037                     Object defaultValue = writable.getValue();
1038                     Object initialValue = styleable.getInitialValue((Node) someClass.newInstance());
1039 
1040                     if (defaultValue instanceof Number) {
1041                         // 5 and 5.0 are not the same according to equals,
1042                         // but they should be...
1043                         assert(initialValue instanceof Number);
1044                         double d1 = ((Number)defaultValue).doubleValue();
1045                         double d2 = ((Number)initialValue).doubleValue();
1046                         assertEquals(what, d1, d2, .001);
1047 
1048                     } else if (defaultValue != null && defaultValue.getClass().isArray()) {
1049                         assertTrue(what, Arrays.equals((Object[])defaultValue, (Object[])initialValue));
1050                     } else {
1051                         assertEquals(what, defaultValue, initialValue);
1052                     }
1053 
1054                 }
1055 
1056             } catch (NoSuchMethodException ex) {
1057                 fail("NoSuchMethodException: RT-18097 cannot be tested on " + what);
1058             } catch (IllegalAccessException ex) {
1059                 System.err.println("IllegalAccessException:  RT-18097 cannot be tested on " + what);
1060             } catch (IllegalArgumentException ex) {
1061                 fail("IllegalArgumentException:  RT-18097 cannot be tested on " + what);
1062             } catch (InvocationTargetException ex) {
1063                 fail("InvocationTargetException:  RT-18097 cannot be tested on " + what);
1064             } catch (InstantiationException ex) {
1065                 fail("InstantiationException:  RT-18097 cannot be tested on " + what);
1066             }
1067         }
1068     }
1069 
1070     private static void checkDirectory(File directory, final int pathLength) {
1071         if (directory.isDirectory()) {
1072 
1073             for (File file : directory.listFiles()) {
1074                 if (file.isFile() && file.getName().endsWith(".class")) {
1075                     final String filePath = file.getPath();
1076                     final int len = file.getPath().length() - ".class".length();
1077                     final String clName =
1078                         file.getPath().substring(pathLength+1, len).replace(File.separatorChar,'.');
1079                     if (clName.startsWith("javafx.scene") == false) continue;
1080                     try {
1081                         final Class cl = Class.forName(clName);
1082                         if (cl != null) checkClass(cl);
1083                     } catch(ClassNotFoundException ex) {
1084                         System.err.println(ex.toString() + " " + clName);
1085                     }
1086                 }
1087             }
1088         }
1089     }
1090 
1091     private static void recursiveCheck(File directory, int pathLength) {
1092         if (directory.isDirectory()) {
1093 //            System.out.println(directory.getPath());
1094             checkDirectory(directory, pathLength);
1095 
1096             for (File subFile : directory.listFiles()) {
1097                 recursiveCheck(subFile, pathLength);
1098             }
1099         }
1100     }
1101 
1102 
1103     // TODO need to test key event dispatch
1104 
1105 //    // test that the Control.Behavior methods correctly fix the coordinate
1106 //    // space values to match based on old node & new
1107 //    function testControlBehaviorCorrectlyMapsEventCoordinates() {
1108 //        var c = ControlStub { width: 20, height: 20, skin: SkinStub {} }
1109 //        var n = Rectangle { width: 100, height: 100 }
1110 //        var g:Group;
1111 //        // setting up a fairly complicated scene to see if the coordinate
1112 //        // values on the copied event are correct. This scene has two different
1113 //        // groups, and each group has a translate transform applied.
1114 //        // The node "n" where the event originated is in a different group
1115 //        // from the "c" node.
1116 //        //
1117 //        // in scene coords, n is 100x100 at 40, 52
1118 //        //                  c is 20x20 at 5, 30
1119 //        // in local coords n is 100x100 at 0, 0
1120 //        //                 c is 20x20 at 0, 0
1121 //        Scene {
1122 //            content: g = Group {
1123 //                // n is 100x100, child group is 40x10
1124 //                translateX: 40
1125 //                translateY: 52
1126 //                content: [
1127 //                    n,
1128 //                    Group {
1129 //                        // the content is 20x20. Scale makes it 40x10
1130 //                        translateX: -35
1131 //                        translateY: -22
1132 //                        content: c // this is 20x20
1133 //                    }
1134 //                ]
1135 //            }
1136 //        }
1137 //
1138 //        // BEGIN SANITY CHECK
1139 //        // start off with a couple sanity checks to make sure I have my math
1140 //        // right such that if the real portion of this test fails, I know it
1141 //        // is not due to a faulty test
1142 //
1143 //        // test local coords of n
1144 //        assertEquals(0, n.boundsInLocal.minX);
1145 //        assertEquals(0, n.boundsInLocal.minY);
1146 //        assertEquals(100, n.boundsInLocal.width);
1147 //        assertEquals(100, n.boundsInLocal.height);
1148 //
1149 //        // test local coords of c
1150 //        assertEquals(0, c.boundsInLocal.minX);
1151 //        assertEquals(0, c.boundsInLocal.minY);
1152 //        assertEquals(20, c.boundsInLocal.width);
1153 //        assertEquals(20, c.boundsInLocal.height);
1154 //
1155 //        // test scene coords of n
1156 //        assertEquals(40, n.localToScene(n.boundsInLocal).minX);
1157 //        assertEquals(52, n.localToScene(n.boundsInLocal).minY);
1158 //        assertEquals(100, n.localToScene(n.boundsInLocal).width);
1159 //        assertEquals(100, n.localToScene(n.boundsInLocal).height);
1160 //
1161 //        // test scene coords of c
1162 //        assertEquals(5, c.localToScene(c.boundsInLocal).minX);
1163 //        assertEquals(30, c.localToScene(c.boundsInLocal).minY);
1164 //        assertEquals(20, c.localToScene(c.boundsInLocal).width);
1165 //        assertEquals(20, c.localToScene(c.boundsInLocal).height);
1166 //        // END SANITY CHECK
1167 //
1168 //        // create a simple mouse event on node. The x/y are 0,0, thus in the
1169 //        // top left corner of the fill area of the rectangle.
1170 //        c.onMousePressed = function(evt:MouseEvent):Void {
1171 //            // this mouse event should have been translated from "g" space
1172 //            // to "c" space. Relative to "g", "c" is 40x10 at -35, -22
1173 //            //  so (0,0) in c space relative to n would be at 35, 22
1174 //            assertEquals(35.0, evt.x);
1175 //            assertEquals(22.0, evt.y);
1176 //        }
1177 //        // invoke the code path that leads to calling the previously defined
1178 //        // onMousePressed function handler
1179 //        mousePress(g, 0, 0);
1180 //    }
1181 
1182     /**
1183      * Used for representing the "node" of the Skin, such that each of the fields
1184      * minWidth, minHeight, maxWidth, maxHeight, prefWidth, and prefHeight have
1185      * different values, and thus can more easily detect bugs if the various
1186      * test methods fail (if they all had the same value, it would potentially
1187      * mask bugs where maxWidth was called instead of minWidth, and so forth).
1188      */
1189     public class ResizableRectangle extends Rectangle {
1190         private double minWidth;
1191         private double maxWidth;
1192         private double minHeight;
1193         private double maxHeight;
1194         private double prefWidth;
1195         private double prefHeight;
1196         private double baselineOffset;
1197 
1198         @Override public boolean isResizable() { return true; }
1199         @Override public double minWidth(double h) { return minWidth; }
1200         @Override public double minHeight(double w) { return minHeight; }
1201         @Override public double prefWidth(double height) { return prefWidth; }
1202         @Override public double prefHeight(double width) { return prefHeight; }
1203         @Override public double maxWidth(double h) { return maxWidth; }
1204         @Override public double maxHeight(double w) { return maxHeight; }
1205         @Override public double getBaselineOffset() { return baselineOffset; }
1206 
1207         @Override public void resize(double width, double height) {
1208             setWidth(width);
1209             setHeight(height);
1210         }
1211     }
1212 
1213     /**
1214      * This is a Skin without an appropriate constructor, and will fail
1215      * to load!
1216      * @param <C>
1217      */
1218     public static final class BadSkin<C extends Control> extends SkinStub<C> {
1219         public BadSkin() {
1220             super(null);
1221         }
1222     }
1223 
1224     /**
1225      * This is a Skin without an appropriate constructor, and will fail
1226      * to load!
1227      * @param <C>
1228      */
1229     public static final class ExceptionalSkin<C extends Control> extends SkinStub<C> {
1230         public ExceptionalSkin(C control) {
1231             super(control);
1232             throw new NullPointerException("I am EXCEPTIONAL!");
1233         }
1234     }
1235 
1236     public class SkinChangeListener implements ChangeListener<Skin> {
1237         boolean changed = false;
1238         @Override public void changed(ObservableValue<? extends Skin> observable, Skin oldValue, Skin newValue) {
1239             changed = true;
1240         }
1241     }
1242 }