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;
  27 
  28 import javafx.collections.ObservableList;
  29 import javafx.geometry.BoundingBox;
  30 import javafx.geometry.Bounds;
  31 import javafx.scene.shape.Rectangle;
  32 import java.util.HashSet;
  33 import java.util.Set;
  34 import javafx.scene.Group;
  35 import javafx.scene.Node;
  36 import javafx.scene.ParentShim;
  37 import org.junit.Test;
  38 import static org.junit.Assert.assertEquals;
  39 import static org.junit.Assert.assertFalse;
  40 import static org.junit.Assert.assertNull;
  41 import static org.junit.Assert.assertSame;
  42 import static org.junit.Assert.assertTrue;
  43 import static org.junit.Assert.fail;
  44 
  45 /**
  46  * Tests various aspects of Group.
  47  *
  48  */
  49 public class GroupTest {
  50     // TODO add test methods here.
  51     // The methods must be annotated with annotation @Test. For example:
  52     //
  53     // @Test
  54     // public void hello() {}
  55     // TODO need to remove tests from here that are redundant with StructureTest
  56 
  57     // Things to test:
  58         // Test that when a Group of nodes is added to a Scene, then the scene
  59         // variable is set on all the nodes
  60             // TODO one way to perhaps do this efficiently is by lazily binding
  61             // the scene to the parent's scene, but this won't work because
  62             // then the scene cannot be set on the rootmost parent!
  63 
  64         // Test that when a Group of nodes is removed from a Scene, then the
  65         // scene variable is set back to null
  66 
  67         // Test lookup works from a group
  68 
  69         // Test that changing visibility affects child nodes
  70         // TODO do we actually change the visible state of a child node? I don't
  71         // think we should.
  72 
  73         // Test that layoutBounds is something reasonable (need to talk with Amy
  74         // to remember what reasonable is. I think it is the union of all the
  75         // layoutBounds of the children, as opposed to the current implementation
  76         // for Group)
  77 
  78         // Basic tests for boundsInGroup, boundsInLocal
  79 
  80         // Tests for contains() and intersects()
  81         // especially when there are transforms on the Group
  82 
  83         // Test that a brand new Group is marked as needing layout
  84 
  85         // Test that when nodes are added to the group, if any of the nodes
  86         // added need layout then the group is marked as needing layout
  87 
  88         // Test that scene variable is set for children if the Group is already
  89         // part of a Scene
  90 
  91         // Test that scene variable is set when Group is added to a scene
  92 
  93         // Add a test to make sure that if a subclass of Group performs layout,
  94         // that doing so will cause the bounds of the group to be updated.
  95         // Really this just means, if a group's needLayout flag is true, and
  96         // then layout() is called, bounds should be updated appropriately.
  97 
  98     // TODO this exception handling infrastructure should be reconciled
  99     // with the infrastructure in StructureTest.fx. Perhaps all the
 100     // exception-throwing tests should be moved into the same file.
 101 
 102     /***************************************************************************
 103      *                                                                         *
 104      *                          Testing Group Content                          *
 105      *                                                                         *
 106      **************************************************************************/
 107 
 108     // Utility function to check the internal consistency of a group node
 109     // and its SG counterpart.
 110     void checkSGConsistency(Group g) {
 111     // TODO disable this because it depends on TestGroup
 112 //        var sgGroup: TestGroup = g.impl_getPGNode() as TestGroup;
 113 //        var sgChildren: java.util.List = sgParentShim.getChildren(group);
 114 //        assertNotNull(sgChildren);
 115 //        assertEquals(sizeof(ParentShim.getChildren(g)), sgChildren.size());
 116 //        for (index in [0..sizeof(ParentShim.getChildren(g))-1]) {
 117 //            assertNotNull(ParentShim.getChildren(g)[index]);
 118 //            assertSame(ParentShim.getChildren(g)[index].impl_getPGNode(), sgChildren.get(index));
 119 //        }
 120     }
 121 
 122 
 123     @Test
 124     public void testVarArgConstructor() {
 125         Rectangle r1 = new Rectangle();
 126         Rectangle r2 = new Rectangle();
 127 
 128         Group g = new Group(r1, r2);
 129         assertTrue(ParentShim.getChildren(g).contains(r1));
 130         assertTrue(ParentShim.getChildren(g).contains(r2));
 131     }
 132 
 133     @Test
 134     public void testCollectionConstructor() {
 135         Rectangle r1 = new Rectangle();
 136         Rectangle r2 = new Rectangle();
 137         Set s = new HashSet();
 138         s.add(r1);
 139         s.add(r2);
 140 
 141         Group g = new Group(s);
 142         assertTrue(ParentShim.getChildren(g).contains(r1));
 143         assertTrue(ParentShim.getChildren(g).contains(r2));
 144     }
 145 
 146     // Test the creation of a cyclic graph
 147     @Test
 148     public void testCyclicGraph() {
 149         Group group1 = new Group();
 150         Group group2 = new Group();
 151         assertNull(group1.getParent());
 152         assertNull(group2.getParent());
 153         assertEquals(0, ParentShim.getChildren(group1).size());
 154         assertEquals(0, ParentShim.getChildren(group2).size());
 155         checkSGConsistency(group1);
 156         checkSGConsistency(group2);
 157 
 158         ParentShim.getChildren(group1).add(group2);
 159         assertNull(group1.getParent());
 160         assertEquals(group1, group2.getParent());
 161         assertEquals(1, ParentShim.getChildren(group1).size());
 162         assertEquals(0, ParentShim.getChildren(group2).size());
 163         checkSGConsistency(group1);
 164         checkSGConsistency(group2);
 165 
 166         ObservableList<Node> content = ParentShim.getChildren(group2);
 167         try {
 168             content.add(group1);
 169             fail("IllegalArgument should have been thrown.");
 170         } catch (IllegalArgumentException iae) {
 171             // expected
 172         }
 173 
 174         assertNull(group1.getParent());
 175         assertEquals(group1, group2.getParent());
 176         assertEquals(1, ParentShim.getChildren(group1).size());
 177         assertEquals(0, ParentShim.getChildren(group2).size());
 178         checkSGConsistency(group1);
 179         checkSGConsistency(group2);
 180     }
 181 
 182     // Add and remove content of a group
 183     @Test
 184     public void testAddRemove() {
 185         Group group = new Group();
 186         Rectangle node = new Rectangle();
 187         assertEquals(0, ParentShim.getChildren(group).size());
 188         assertNull(node.getParent());
 189         assertNull(group.getParent());
 190         checkSGConsistency(group);
 191 
 192         ParentShim.getChildren(group).add(node);
 193         assertEquals(1, ParentShim.getChildren(group).size());
 194         assertEquals(node, ParentShim.getChildren(group).get(0));
 195         assertEquals(group, node.getParent());
 196         assertNull(group.getParent());
 197         checkSGConsistency(group);
 198 
 199         ParentShim.getChildren(group).remove(node);
 200         assertEquals(0, ParentShim.getChildren(group).size());
 201         assertNull(node.getParent());
 202         assertNull(group.getParent());
 203         checkSGConsistency(group);
 204     }
 205 
 206     // Add/remove test with multiple children
 207     @Test
 208     public void testAddRemove2() {
 209         Group group = new Group();
 210         Rectangle node1 = new Rectangle();
 211         node1.setX(1);
 212         Rectangle node2 = new Rectangle();
 213         node2.setX(2);
 214 
 215         assertEquals(0, ParentShim.getChildren(group).size());
 216         assertNull(node1.getParent());
 217         assertNull(node2.getParent());
 218         assertNull(group.getParent());
 219         checkSGConsistency(group);
 220 
 221         ParentShim.getChildren(group).add(node1);
 222         assertEquals(1, ParentShim.getChildren(group).size());
 223         assertEquals(node1, ParentShim.getChildren(group).get(0));
 224         assertNull(node2.getParent());
 225         assertEquals(group, node1.getParent());
 226         assertNull(group.getParent());
 227         checkSGConsistency(group);
 228 
 229         ParentShim.getChildren(group).add(node2);
 230         assertEquals(2, ParentShim.getChildren(group).size());
 231         assertEquals(node1, ParentShim.getChildren(group).get(0));
 232         assertEquals(node2, ParentShim.getChildren(group).get(1));
 233         assertEquals(group, node1.getParent());
 234         assertEquals(group, node2.getParent());
 235         assertNull(group.getParent());
 236         checkSGConsistency(group);
 237 
 238         ParentShim.getChildren(group).remove(node1);
 239         assertEquals(1, ParentShim.getChildren(group).size());
 240         assertNull(node1.getParent());
 241         assertEquals(group, node2.getParent());
 242         assertEquals(node2, ParentShim.getChildren(group).get(0));
 243         assertNull(group.getParent());
 244         checkSGConsistency(group);
 245 
 246         ParentShim.getChildren(group).add(node1);
 247         assertEquals(2, ParentShim.getChildren(group).size());
 248         assertEquals(node1, ParentShim.getChildren(group).get(1));
 249         assertEquals(node2, ParentShim.getChildren(group).get(0));
 250         assertEquals(group, node1.getParent());
 251         assertEquals(group, node2.getParent());
 252         assertNull(group.getParent());
 253         checkSGConsistency(group);
 254 
 255         Rectangle node3 = new Rectangle();
 256         node3.setX(3);
 257         Rectangle node4 = new Rectangle();
 258         node4.setX(4);
 259         assertNull(node3.getParent());
 260         assertNull(node4.getParent());
 261         assertNull(group.getParent());
 262         checkSGConsistency(group);
 263 
 264         ParentShim.getChildren(group).add(0, node3);
 265         ParentShim.getChildren(group).add(node4);
 266         assertEquals(4, ParentShim.getChildren(group).size());
 267         assertEquals(node1, ParentShim.getChildren(group).get(2));
 268         assertEquals(node2, ParentShim.getChildren(group).get(1));
 269         assertEquals(node3, ParentShim.getChildren(group).get(0));
 270         assertEquals(node4, ParentShim.getChildren(group).get(3));
 271         assertEquals(group, node1.getParent());
 272         assertEquals(group, node2.getParent());
 273         assertEquals(group, node3.getParent());
 274         assertEquals(group, node4.getParent());
 275         assertNull(group.getParent());
 276         checkSGConsistency(group);
 277 
 278         ParentShim.getChildren(group).clear();
 279         assertEquals(0, ParentShim.getChildren(group).size());
 280         assertNull(node1.getParent());
 281         assertNull(node2.getParent());
 282         assertNull(node3.getParent());
 283         assertNull(node4.getParent());
 284         assertNull(group.getParent());
 285         checkSGConsistency(group);
 286     }
 287 
 288     // Initialize two different group's content with the same child
 289     @Test
 290     public void testMultiInit() {
 291         Rectangle node = new Rectangle();
 292         assertNull(node.getParent());
 293 
 294         Group group1 = new Group();
 295         ParentShim.getChildren(group1).add(node);
 296         assertEquals(1, ParentShim.getChildren(group1).size());
 297         assertEquals(node, ParentShim.getChildren(group1).get(0));
 298         assertEquals(group1, node.getParent());
 299         assertNull(group1.getParent());
 300         checkSGConsistency(group1);
 301 
 302         Group group2 = new Group();
 303         try {
 304             ParentShim.getChildren(group2).add(node);
 305         } catch (Throwable t) {
 306             assertNull("unexpected exception", t);
 307         }
 308 
 309         assertEquals(0, ParentShim.getChildren(group1).size());
 310         assertEquals(1, ParentShim.getChildren(group2).size());
 311         assertEquals(node, ParentShim.getChildren(group2).get(0));
 312         assertSame(group2, node.getParent());
 313         assertNull(group1.getParent());
 314         assertNull(group2.getParent());
 315         checkSGConsistency(group1);
 316         checkSGConsistency(group2);
 317     }
 318 
 319     // Initialize the same group with two references to the same child instance
 320     // Then initialize a second group with the same instance
 321     @Test
 322     public void testMultiInit2() {
 323         Rectangle node = new Rectangle();
 324         assertNull(node.getParent());
 325 
 326         Group group1 = new Group();
 327         ObservableList<Node> content = ParentShim.getChildren(group1);
 328         try {
 329             content.addAll(node, node);
 330             fail("IllegalArgument should have been thrown.");
 331         } catch (IllegalArgumentException iae) {
 332             // expected
 333         }
 334 
 335         assertEquals(0, ParentShim.getChildren(group1).size());
 336         assertNull(node.getParent());
 337         assertNull(group1.getParent());
 338         checkSGConsistency(group1);
 339 
 340         Group group2 = new Group();
 341         ParentShim.getChildren(group2).add(node);
 342         assertEquals(1, ParentShim.getChildren(group2).size());
 343         assertSame(node, ParentShim.getChildren(group2).get(0));
 344         assertSame(group2, node.getParent());
 345         assertEquals(0, ParentShim.getChildren(group1).size());
 346         assertNull(group1.getParent());
 347         assertNull(group2.getParent());
 348         checkSGConsistency(group1);
 349         checkSGConsistency(group2);
 350     }
 351 
 352     // Insert the same child into two different group's content observableArrayList
 353     @Test
 354     public void testMultiAdd() {
 355         Rectangle node = new Rectangle();
 356         Group group1 = new Group();
 357         Group group2 = new Group();
 358         assertNull(node.getParent());
 359         assertEquals(0, ParentShim.getChildren(group1).size());
 360         assertEquals(0, ParentShim.getChildren(group2).size());
 361         assertNull(group1.getParent());
 362         assertNull(group2.getParent());
 363         checkSGConsistency(group1);
 364         checkSGConsistency(group2);
 365 
 366         ParentShim.getChildren(group1).add(node);
 367         assertEquals(1, ParentShim.getChildren(group1).size());
 368         assertSame(node, ParentShim.getChildren(group1).get(0));
 369         assertSame(group1, node.getParent());
 370         assertNull(group1.getParent());
 371         checkSGConsistency(group1);
 372 
 373         try {
 374             ParentShim.getChildren(group2).add(node);
 375         } catch(Throwable t) {
 376             assertNull("unexpected exception", t);
 377         }
 378 
 379         assertEquals(0, ParentShim.getChildren(group1).size());
 380         assertEquals(1, ParentShim.getChildren(group2).size());
 381         assertSame(node, ParentShim.getChildren(group2).get(0));
 382         assertSame(group2, node.getParent());
 383         assertNull(group1.getParent());
 384         assertNull(group2.getParent());
 385         checkSGConsistency(group1);
 386         checkSGConsistency(group2);
 387     }
 388 
 389     // Insert the same child twice into a group's content observableArrayList
 390     // Then insert it into a second group
 391     @Test
 392     public void testMultiAdd2() {
 393         Rectangle node = new Rectangle();
 394         Group group1 = new Group();
 395         Group group2 = new Group();
 396         assertNull(node.getParent());
 397         assertEquals(0, ParentShim.getChildren(group1).size());
 398         assertEquals(0, ParentShim.getChildren(group2).size());
 399         assertNull(group1.getParent());
 400         assertNull(group2.getParent());
 401         checkSGConsistency(group1);
 402         checkSGConsistency(group2);
 403 
 404         ParentShim.getChildren(group1).add(node);
 405         assertEquals(1, ParentShim.getChildren(group1).size());
 406         assertSame(node, ParentShim.getChildren(group1).get(0));
 407         assertSame(group1, node.getParent());
 408         assertNull(group1.getParent());
 409         checkSGConsistency(group1);
 410 
 411         ObservableList<Node> content = ParentShim.getChildren(group1);
 412         try {
 413             content.add(node);
 414             fail("IllegalArgument should have been thrown.");
 415         } catch (IllegalArgumentException iae) {
 416             // expected
 417         }
 418 
 419         assertEquals(1, ParentShim.getChildren(group1).size());
 420         assertSame(node, ParentShim.getChildren(group1).get(0));
 421         assertSame(group1, node.getParent());
 422         assertNull(group1.getParent());
 423         checkSGConsistency(group1);
 424 
 425         try {
 426             ParentShim.getChildren(group2).add(node);
 427         } catch (Throwable t) {
 428             assertNull("unexpected exception", t);
 429         }
 430 
 431         assertEquals(0, ParentShim.getChildren(group1).size());
 432         assertEquals(1, ParentShim.getChildren(group2).size());
 433         assertSame(node, ParentShim.getChildren(group2).get(0));
 434         assertSame(group2, node.getParent());
 435         assertNull(group1.getParent());
 436         assertNull(group2.getParent());
 437         checkSGConsistency(group1);
 438         checkSGConsistency(group2);
 439     }
 440 
 441     // More complex test of inserting children into a group when they are already
 442     // a child of another group (or the same group more than once)
 443     @Test
 444     public void testMultiAdd3() {
 445         Rectangle node = new Rectangle();
 446         Group group1 = new Group();
 447         Group group2 = new Group();
 448         assertNull(node.getParent());
 449         assertEquals(0, ParentShim.getChildren(group1).size());
 450         assertEquals(0, ParentShim.getChildren(group2).size());
 451         assertNull(group1.getParent());
 452         assertNull(group2.getParent());
 453         checkSGConsistency(group1);
 454         checkSGConsistency(group2);
 455 
 456         // TODO
 457         // ...
 458     }
 459 
 460     /**
 461      * If the layout bounds has a NaN, it shouldn't leak out through node.prefWidth
 462      */
 463     @Test public void Node_prefWidth_BasedOnLayoutBounds_CleansUpAfterBadBounds() {
 464         Group node = new Group() {
 465             @Override protected Bounds impl_computeLayoutBounds() {
 466                 return new BoundingBox(0, 0, Double.NaN, 50);
 467             }
 468         };
 469         assertEquals(0, node.prefWidth(-1), 0);
 470         assertEquals(0, node.prefWidth(5), 0);
 471     }
 472 
 473     /**
 474      * If the layout bounds has a negative value, it shouldn't leak out through node.prefWidth
 475      */
 476     @Test public void Node_prefWidth_BasedOnLayoutBounds_CleansUpAfterBadBounds2() {
 477         Group node = new Group() {
 478             @Override protected Bounds impl_computeLayoutBounds() {
 479                 return new BoundingBox(0, 0, -10, 50);
 480             }
 481         };
 482         assertEquals(0, node.prefWidth(-1), 0);
 483         assertEquals(0, node.prefWidth(5), 0);
 484     }
 485 
 486     /**
 487      * If the layout bounds has a NaN, it shouldn't leak out through node.prefHeight
 488      */
 489     @Test public void Node_prefHeight_BasedOnLayoutBounds_CleansUpAfterBadBounds() {
 490         Group node = new Group() {
 491             @Override protected Bounds impl_computeLayoutBounds() {
 492                 return new BoundingBox(0, 0, 50, Double.NaN);
 493             }
 494         };
 495         assertEquals(0, node.prefHeight(-1), 0);
 496         assertEquals(0, node.prefHeight(5), 0);
 497     }
 498 
 499     /**
 500      * If the layout bounds has a negative value, it shouldn't leak out through node.prefHeight
 501      */
 502     @Test public void Node_prefHeight_BasedOnLayoutBounds_CleansUpAfterBadBounds2() {
 503         Group node = new Group() {
 504             @Override protected Bounds impl_computeLayoutBounds() {
 505                 return new BoundingBox(0, 0, 50, -10);
 506             }
 507         };
 508         assertEquals(0, node.prefHeight(-1), 0);
 509         assertEquals(0, node.prefHeight(5), 0);
 510     }
 511 
 512     @Test
 513     public void testPrefWidthDoesNotIncludeInvisibleChild() {
 514         Group group = new Group();
 515 
 516         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 517         region.setVisible(false);
 518         test.javafx.scene.layout.MockRegion region2 = new test.javafx.scene.layout.MockRegion(50,75);
 519         ParentShim.getChildren(group).addAll(region,region2);
 520 
 521         assertEquals(50, group.prefWidth(-1), 0);
 522     }
 523 
 524     @Test
 525     public void testPrefHeightDoesNotIncludeInvisibleChild() {
 526         Group group = new Group();
 527 
 528         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 529         region.setVisible(false);
 530         test.javafx.scene.layout.MockRegion region2 = new test.javafx.scene.layout.MockRegion(50,75);
 531         ParentShim.getChildren(group).addAll(region,region2);
 532 
 533         assertEquals(75, group.prefHeight(-1), 0);
 534     }
 535 
 536     @Test
 537     public void testPrefWidthWithResizableChild() {
 538         Group group = new Group();
 539 
 540         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 541         ParentShim.getChildren(group).add(region);
 542 
 543         assertEquals(100, group.prefWidth(-1), 0);
 544     }
 545 
 546     @Test
 547     public void testPrefHeightWithResizableChild() {
 548         Group group = new Group();
 549 
 550         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 551         ParentShim.getChildren(group).add(region);
 552 
 553         assertEquals(150, group.prefHeight(-1), 0);
 554     }
 555 
 556     @Test
 557     public void testPrefWidthIncludesResizableChildScaleX() {
 558         Group group = new Group();
 559 
 560         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 561         region.setScaleX(2.0);
 562         ParentShim.getChildren(group).add(region);
 563 
 564         assertEquals(200, group.prefWidth(-1), 0);
 565     }
 566 
 567     @Test
 568     public void testPrefHeightIncludesResizableChildScaleY() {
 569         Group group = new Group();
 570 
 571         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 572         region.setScaleY(2.0);
 573         ParentShim.getChildren(group).add(region);
 574 
 575         assertEquals(300, group.prefHeight(-1), 0);
 576     }
 577 
 578     @Test
 579     public void testPrefWidthIncludesResizableChildsClip() {
 580         Group group = new Group();
 581 
 582         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 583         region.setClip(new Rectangle(50,75));
 584         ParentShim.getChildren(group).add(region);
 585 
 586         assertEquals(50, group.prefWidth(-1), 0);
 587     }
 588 
 589     @Test
 590     public void testPrefHeightIncludesResizableChildsClip() {
 591         Group group = new Group();
 592 
 593         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 594         region.setClip(new Rectangle(50,75));
 595         ParentShim.getChildren(group).add(region);
 596 
 597         assertEquals(75, group.prefHeight(-1), 0);
 598     }
 599 
 600     @Test
 601     public void testPrefWidthIncludesResizableChildsRotation() {
 602         Group group = new Group();
 603 
 604         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 605         region.setRotate(90);
 606         ParentShim.getChildren(group).add(region);
 607 
 608         assertEquals(150, group.prefWidth(-1), 0);
 609     }
 610 
 611     @Test
 612     public void testPrefHeightIncludesResizableChildsRotation() {
 613         Group group = new Group();
 614 
 615         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 616         region.setRotate(90);
 617         ParentShim.getChildren(group).add(region);
 618 
 619         assertEquals(100, group.prefHeight(-1), 0);
 620     }
 621 
 622     @Test
 623     public void testPrefWidthIncludesResizableChildsTranslateX() {
 624         Group group = new Group();
 625 
 626         test.javafx.scene.layout.MockRegion region1 = new test.javafx.scene.layout.MockRegion(100,150);
 627         test.javafx.scene.layout.MockRegion region2 = new test.javafx.scene.layout.MockRegion(100,150);
 628         region2.setTranslateX(50);
 629         ParentShim.getChildren(group).addAll(region1,region2);
 630 
 631         assertEquals(150, group.prefWidth(-1), 0);
 632     }
 633 
 634     @Test
 635     public void testPrefHeightIncludesResizableChildsTranslateY() {
 636         Group group = new Group();
 637 
 638         test.javafx.scene.layout.MockRegion region1 = new test.javafx.scene.layout.MockRegion(100,150);
 639         test.javafx.scene.layout.MockRegion region2 = new test.javafx.scene.layout.MockRegion(100,150);
 640         region2.setTranslateY(50);
 641         ParentShim.getChildren(group).addAll(region1,region2);
 642 
 643         assertEquals(200, group.prefHeight(-1), 0);
 644     }
 645 
 646     @Test
 647     public void testPrefWidthDoesNotIncludeScaleX() {
 648         Group group = new Group();
 649         group.setScaleX(2.0);
 650 
 651         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 652         ParentShim.getChildren(group).add(region);
 653 
 654         assertEquals(100, group.prefWidth(-1), 0);
 655     }
 656 
 657     @Test
 658     public void testPrefHeightDoesNotIncludeScaleY() {
 659         Group group = new Group();
 660         group.setScaleY(2.0);
 661 
 662         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 663         ParentShim.getChildren(group).add(region);
 664 
 665         assertEquals(150, group.prefHeight(-1), 0);
 666     }
 667 
 668     @Test
 669     public void testPrefWidthDoesNotIncludeClip() {
 670         Group group = new Group();
 671         group.setClip(new Rectangle(50,75));
 672 
 673         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 674         ParentShim.getChildren(group).add(region);
 675 
 676         assertEquals(100, group.prefWidth(-1), 0);
 677     }
 678 
 679     @Test
 680     public void testPrefHeightDoesNotIncludeClip() {
 681         Group group = new Group();
 682         group.setClip(new Rectangle(50,75));
 683 
 684         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 685         ParentShim.getChildren(group).add(region);
 686 
 687         assertEquals(150, group.prefHeight(-1), 0);
 688     }
 689 
 690     @Test
 691     public void testPrefWidthDoesNotIncludeRotation() {
 692         Group group = new Group();
 693         group.setRotate(45);
 694 
 695         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 696         ParentShim.getChildren(group).add(region);
 697 
 698         assertEquals(100, group.prefWidth(-1), 0);
 699     }
 700 
 701     @Test
 702     public void testPrefHeightDoesNotIncludeRotation() {
 703         Group group = new Group();
 704         group.setRotate(45);
 705 
 706         test.javafx.scene.layout.MockRegion region = new test.javafx.scene.layout.MockRegion(100,150);
 707         ParentShim.getChildren(group).add(region);
 708 
 709         assertEquals(150, group.prefHeight(-1), 0);
 710     }
 711 
 712     @Test
 713     public void testPrefWidthDoesNotIncludeTranslateX() {
 714         Group group = new Group();
 715         group.setTranslateX(50);
 716 
 717         test.javafx.scene.layout.MockRegion region1 = new test.javafx.scene.layout.MockRegion(100,150);
 718         test.javafx.scene.layout.MockRegion region2 = new test.javafx.scene.layout.MockRegion(100,150);
 719         ParentShim.getChildren(group).addAll(region1,region2);
 720 
 721         assertEquals(100, group.prefWidth(-1), 0);
 722     }
 723 
 724     @Test
 725     public void testPrefHeightDoesNotIncludeTranslateY() {
 726         Group group = new Group();
 727         group.setTranslateY(50);
 728 
 729         test.javafx.scene.layout.MockRegion region1 = new test.javafx.scene.layout.MockRegion(100,150);
 730         test.javafx.scene.layout.MockRegion region2 = new test.javafx.scene.layout.MockRegion(100,150);
 731         ParentShim.getChildren(group).addAll(region1,region2);
 732 
 733         assertEquals(150, group.prefHeight(-1), 0);
 734     }
 735 
 736     @Test
 737     public void testNonResizableChildDoesNotTriggerLayout() {
 738         Group group = new Group();
 739         Rectangle rect = new Rectangle(50,50);
 740         ParentShim.getChildren(group).add(rect);
 741 
 742         group.layout(); // clear dirty flag
 743 
 744         rect.setWidth(100);
 745         assertFalse(group.isNeedsLayout());
 746     }
 747 
 748     @Test
 749     public void testMinMaxSizesCorrespondToPreferred() {
 750         Group group = new Group();
 751         Rectangle rect = new Rectangle(50,50);
 752         ParentShim.getChildren(group).add(rect);
 753 
 754         assertEquals(50, group.minWidth(-1), 1e-100);
 755         assertEquals(50, group.minHeight(-1), 1e-100);
 756         assertEquals(50, group.maxWidth(-1), 1e-100);
 757         assertEquals(50, group.maxHeight(-1), 1e-100);
 758 
 759         rect.setWidth(100);
 760 
 761         assertEquals(100, group.minWidth(-1), 1e-100);
 762         assertEquals(50, group.minHeight(-1), 1e-100);
 763         assertEquals(100, group.maxWidth(-1), 1e-100);
 764         assertEquals(50, group.maxHeight(-1), 1e-100);
 765 
 766         rect.setHeight(200);
 767 
 768         assertEquals(100, group.minWidth(-1), 1e-100);
 769         assertEquals(200, group.minHeight(-1), 1e-100);
 770         assertEquals(100, group.maxWidth(-1), 1e-100);
 771         assertEquals(200, group.maxHeight(-1), 1e-100);
 772     }
 773 }