1 /*
   2  * Copyright (c) 2011, 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.bounds;
  27 
  28 import com.sun.javafx.scene.NodeHelper;
  29 import static test.com.sun.javafx.test.TestHelper.assertBoundsEqual;
  30 import static test.com.sun.javafx.test.TestHelper.assertGroupBounds;
  31 import static test.com.sun.javafx.test.TestHelper.box;
  32 import static test.com.sun.javafx.test.TestHelper.formatBounds;
  33 import static junit.framework.Assert.assertEquals;
  34 
  35 import java.util.LinkedList;
  36 
  37 import javafx.geometry.Bounds;
  38 import javafx.scene.Group;
  39 import javafx.scene.shape.Rectangle;
  40 
  41 import org.junit.Test;
  42 
  43 public class GroupBoundsTest {
  44 
  45     /***************************************************************************
  46      * * Group Tests * * These are tests related to transforming the basic node
  47      * types including * * /
  48      **************************************************************************/
  49 
  50     // test that an empty group has empty bounds
  51     public @Test
  52     void testGroupBounds_Empty() {
  53         assertGroupBounds(new Group());
  54     }
  55 
  56     // test that adding a node to a group updates the Groups bounds
  57     public @Test
  58     void testGroupBounds_AddRect() {
  59         Group g = new Group();
  60         assertGroupBounds(g);
  61 
  62         g.getChildren().add(new Rectangle(20, 20, 50, 50));
  63         assertGroupBounds(g);
  64 
  65         g.getChildren().add(new Rectangle(90, 20, 50, 50));
  66         assertGroupBounds(g);
  67     }
  68 
  69     // test that changing a node in a group updates the groups bounds
  70     public @Test
  71     void testGroupBounds_ChangeRect() {
  72         Rectangle r1 = new Rectangle(20, 20, 50, 50);
  73         Rectangle r2 = new Rectangle(90, 20, 50, 50);
  74         Group g = new Group(r1, r2);
  75 
  76         assertGroupBounds(g);
  77 
  78         r1.setWidth(200);
  79         assertGroupBounds(g);
  80         r2.setWidth(20);
  81         assertGroupBounds(g);
  82     }
  83 
  84     // test that removing a node from the group updates the Groups bounds
  85     public @Test
  86     void testGroupBounds_RemoveRect() {
  87         Rectangle r1 = new Rectangle(20, 20, 50, 50);
  88         Rectangle r2 = new Rectangle(90, 20, 50, 50);
  89         Group g = new Group(r1, r2);
  90 
  91         assertGroupBounds(g);
  92 
  93         g.getChildren().remove(r2);
  94         assertGroupBounds(g);
  95         g.getChildren().remove(r1);
  96         assertGroupBounds(g);
  97     }
  98 
  99     public @Test
 100     void testGroupBounds_RemoveAllChildNodesAndAddOneBack() {
 101         Rectangle r1 = new Rectangle(20, 20, 50, 50);
 102         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 103         Group g = new Group(r1, r2);
 104 
 105         assertGroupBounds(g);
 106         g.getChildren().clear();
 107         assertGroupBounds(g);
 108         g.getChildren().add(r1);
 109         assertGroupBounds(g);
 110     }
 111 
 112     // test that adding the first node to a Group, which node is an invisible
 113     // node, gets the right answer for the Group's bounds.
 114     public @Test
 115     void testGroupBounds_InitialNodeInvisible() {
 116         Rectangle r1 = new Rectangle(20, 20, 50, 50);
 117         r1.setVisible(false);
 118         Group g = new Group(r1);
 119 
 120         assertGroupBounds(g);
 121     }
 122 
 123     // test that adding invisible nodes to a group doesn't update the bounds
 124     public @Test
 125     void testGroupBounds_InvisibleNodes() {
 126         Rectangle r1 = new Rectangle(20, 20, 50, 50);
 127         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 128         Group g = new Group(r1, r2);
 129         assertGroupBounds(g);
 130 
 131         Rectangle invisible = new Rectangle(-100, -100, 1, 1);
 132         invisible.setVisible(true);
 133         g.getChildren().add(invisible);
 134         assertGroupBounds(g);
 135     }
 136 
 137     // test that adding zero sized nodes does update a Groups bounds
 138     public @Test
 139     void testGroupBounds_ZeroSizedNodes() {
 140         Rectangle r1 = new Rectangle(20, 20, 50, 50);
 141         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 142         Group g = new Group(r1, r2);
 143         assertGroupBounds(g);
 144 
 145         Rectangle small = new Rectangle(-100, -100, 0, 0);
 146         g.getChildren().add(small);
 147         assertGroupBounds(g);
 148     }
 149 
 150     // test that making a node invisible updates the groups bounds
 151     public @Test
 152     void testGroupBounds_NodeMadeInvisible() {
 153         Rectangle r1 = new Rectangle(20, 20, 50, 50);
 154         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 155         Group g = new Group(r1, r2);
 156         assertGroupBounds(g);
 157 
 158         r1.setVisible(false);
 159         assertGroupBounds(g);
 160     }
 161 
 162     public @Test
 163     void testGroupBounds_NodeWithNoWidthMadeInvisible() {
 164         Rectangle r1 = new Rectangle(20, 20, 50, 50);
 165         Rectangle r2 = new Rectangle(90, 20, 0, 50);
 166         Group g = new Group(r1, r2);
 167         assertGroupBounds(g);
 168 
 169         r2.setVisible(false);
 170         assertGroupBounds(g);
 171     }
 172 
 173     public @Test
 174     void testGroupBounds_FirstNodeHasNoWidthSecondNodeDoes() {
 175         Rectangle r1 = new Rectangle(20, 20, 0, 50);
 176         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 177         Group g = new Group(r1, r2);
 178         assertGroupBounds(g);
 179     }
 180 
 181     public @Test
 182     void testGroupBounds_FirstNodeHasNoWidthSecondNodeDoes_Added() {
 183         Rectangle r1 = new Rectangle(20, 20, 0, 50);
 184         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 185         Group g = new Group();
 186         assertGroupBounds(g);
 187         g.getChildren().add(r1);
 188         assertGroupBounds(g);
 189         g.getChildren().add(r2);
 190         assertGroupBounds(g);
 191     }
 192 
 193     public @Test
 194     void testGroupBounds_FirstNodeHasNoWidthSecondNodeDoes_ClearedThenAdded() {
 195         Rectangle r1 = new Rectangle(20, 20, 0, 50);
 196         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 197         Rectangle r3 = new Rectangle(10, 15, 75, 20);
 198         Group g = new Group(r1, r2);
 199         assertGroupBounds(g);
 200         g.getChildren().remove(r2);
 201         assertGroupBounds(g);
 202         g.getChildren().add(r3);
 203         assertGroupBounds(g);
 204     }
 205 
 206     // this test uncovered a bug when using the GroupBoundsHelper. It needs
 207     // two invisible nodes to tickle it You also have to ask assert the bounds
 208     // after each change or it may not fail
 209     public @Test
 210     void testGroupBounds_TwoNodesMadeInvisible_ThenNodeAdded() {
 211         Rectangle r1 = new Rectangle(20, 20, 50, 50);
 212         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 213         Rectangle r3 = new Rectangle(10, 15, 75, 20);
 214         Group g = new Group();
 215 
 216         assertGroupBounds(g);
 217         g.getChildren().add(r1);
 218         assertGroupBounds(g);
 219         r1.setVisible(false);
 220         assertGroupBounds(g);
 221         g.getChildren().add(r2);
 222         assertGroupBounds(g);
 223         r2.setVisible(false);
 224         assertGroupBounds(g);
 225         g.getChildren().add(r3);
 226         assertGroupBounds(g);
 227     }
 228 
 229     public @Test
 230     void testGroupBounds_TogglingVisiblityToFalseAndTrueWhileExpandingBounds() {
 231         Rectangle r1 = new Rectangle(20, 20, 50, 50);
 232         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 233         Rectangle r3 = new Rectangle(10, 15, 75, 20);
 234         Group g = new Group();
 235         assertGroupBounds(g);
 236         g.getChildren().add(r1);
 237         assertGroupBounds(g);
 238         g.getChildren().add(r2);
 239         assertGroupBounds(g);
 240         r2.setVisible(false);
 241         assertGroupBounds(g);
 242         g.getChildren().add(r3);
 243         assertGroupBounds(g);
 244         r2.setVisible(true);
 245         assertGroupBounds(g);
 246     }
 247 
 248     private Group createGroupWithRects() {
 249         Group group = new Group();
 250         group.setId("group");
 251         for (int i = 1; i <= 3; i++) {
 252             for (int j = 1; j <= 3; j++) {
 253                 Rectangle r = new Rectangle(j * 100, i * 100, 50, 50);
 254                 r.setId("rect[" + i + "," + j + "]");
 255                 group.getChildren().add(r);
 256             }
 257         }
 258 
 259         // sanity test check that the size of the group is correct
 260         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 261 
 262         return group;
 263     }
 264 
 265     // Started out as a simple test and now pretty well covers all the use
 266     // cases. Oops. Bad Richard.
 267     public @Test
 268     void testMovingNodesTowardCenterOfGroupAndOther() {
 269         Group group = createGroupWithRects();
 270 
 271         // move the 1, 3, 5, 7 nodes in towards the center. Doing so should not
 272         // change the group's bounds
 273         ((Rectangle) group.getChildren().get(1)).setX(200);
 274         ((Rectangle) group.getChildren().get(1)).setY(200);
 275         ((Rectangle) group.getChildren().get(3)).setX(200);
 276         ((Rectangle) group.getChildren().get(3)).setY(200);
 277         ((Rectangle) group.getChildren().get(5)).setX(200);
 278         ((Rectangle) group.getChildren().get(5)).setY(200);
 279         ((Rectangle) group.getChildren().get(7)).setX(200);
 280         ((Rectangle) group.getChildren().get(7)).setY(200);
 281         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 282 
 283         // move the 2 and 6 nodes in towards the center. Doing so should not
 284         // change the group's bounds
 285         ((Rectangle) group.getChildren().get(2)).setX(200);
 286         ((Rectangle) group.getChildren().get(2)).setY(200);
 287         ((Rectangle) group.getChildren().get(6)).setX(200);
 288         ((Rectangle) group.getChildren().get(6)).setY(200);
 289         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 290 
 291         // move the 0 node into the center. Doing so SHOULD change the bounds
 292         // such that all nodes are in the center (200, 200) except for the
 293         // number 8 node which is at (300, 300)
 294         ((Rectangle) group.getChildren().get(0)).setX(200);
 295         ((Rectangle) group.getChildren().get(0)).setY(200);
 296         assertEquals(box(200, 200, 150, 150), group.getBoundsInLocal());
 297 
 298         // move the 8 node a little towards the center (but not all the way)
 299         // just to test that moving the bottom-right will adjust things
 300         ((Rectangle) group.getChildren().get(8)).setX(250);
 301         ((Rectangle) group.getChildren().get(8)).setY(250);
 302         assertEquals(box(200, 200, 100, 100), group.getBoundsInLocal());
 303 
 304         // move the rest of the nodes down past #8
 305         for (int i = 0; i <= 7; i++) {
 306             ((Rectangle) group.getChildren().get(i)).setX(300);
 307             ((Rectangle) group.getChildren().get(i)).setY(300);
 308         }
 309         assertEquals(box(250, 250, 100, 100), group.getBoundsInLocal());
 310 
 311         // now move #8 onto the rest
 312         ((Rectangle) group.getChildren().get(8)).setX(300);
 313         ((Rectangle) group.getChildren().get(8)).setY(300);
 314         assertEquals(box(300, 300, 50, 50), group.getBoundsInLocal());
 315     }
 316 
 317     public @Test
 318     void testMovingNodesAwayFromCenterOfGroup() {
 319         Group group = createGroupWithRects();
 320 
 321         ((Rectangle) group.getChildren().get(4)).setX(600);
 322         ((Rectangle) group.getChildren().get(4)).setY(600);
 323         assertEquals(box(100, 100, 550, 550), group.getBoundsInLocal());
 324     }
 325 
 326     public @Test
 327     void testMovingNodesWithinInteriorOfGroup() {
 328         Group group = createGroupWithRects();
 329 
 330         ((Rectangle) group.getChildren().get(4)).setX(250);
 331         ((Rectangle) group.getChildren().get(4)).setY(250);
 332         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 333     }
 334 
 335     public @Test
 336     void testMovingExteriorNodesOnExterior() {
 337         Group group = createGroupWithRects();
 338 
 339         ((Rectangle) group.getChildren().get(0)).setY(150);
 340         ((Rectangle) group.getChildren().get(1)).setX(100);
 341         ((Rectangle) group.getChildren().get(2)).setX(150);
 342         ((Rectangle) group.getChildren().get(3)).setY(120);
 343         ((Rectangle) group.getChildren().get(5)).setY(100);
 344         ((Rectangle) group.getChildren().get(6)).setX(250);
 345         ((Rectangle) group.getChildren().get(7)).setX(120);
 346         ((Rectangle) group.getChildren().get(8)).setY(200);
 347 
 348         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 349     }
 350 
 351     public @Test
 352     void testRemovingInteriorNodes() {
 353         Group group = createGroupWithRects();
 354 
 355         group.getChildren().remove(4);
 356         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 357     }
 358 
 359     public @Test
 360     void testRemovingExteriorNodes() {
 361         Group group = createGroupWithRects();
 362 
 363         group.getChildren().remove(7);
 364         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 365         group.getChildren().remove(6);
 366         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 367         group.getChildren().remove(5);
 368         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 369         group.getChildren().remove(3);
 370         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 371         group.getChildren().remove(2);
 372         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 373         group.getChildren().remove(1);
 374         assertEquals(box(100, 100, 250, 250), group.getBoundsInLocal());
 375 
 376         // and now the bounds should be changing
 377         group.getChildren().remove(0);
 378         assertEquals(box(200, 200, 150, 150), group.getBoundsInLocal());
 379         group.getChildren().remove(1);
 380         assertEquals(box(200, 200, 50, 50), group.getBoundsInLocal());
 381     }
 382 
 383     // run a set of tests that add 1000's of random sized and random positioned
 384     // rectangles to the Group, and check the groups bounds at each stage.
 385     // Also randomly make some invisible, some visible, remove some, toggle
 386     // visibility, and so forth.
 387     public @Test
 388     void testGroupBounds_Stress() {
 389         boolean fullTest = Boolean.getBoolean("test.everything");
 390         if (fullTest) {
 391             Group g = new Group();
 392             assertGroupBounds(g);
 393             for (int j = 0; j < 500; j++) {
 394                 LinkedList<String> whatHappenedStack = new java.util.LinkedList<String>();
 395                 for (int i = 0; i <= 50; i++) {
 396                     Bounds layoutBounds = g.getLayoutBounds();
 397                     int numChildren = g.getChildren().size();
 398                     String whatHappened = "";
 399                     double rnd = Math.random();
 400                     int index = (int) (Math.random() * numChildren);
 401                     if (rnd > .3 && rnd < .5 && numChildren > 0) {
 402                         // translate some rect
 403                         int direction = (Math.random() > .5) ? -1 : 1;
 404                         Bounds oldBoundsInParent = g.getChildren().get(index)
 405                                 .getBoundsInParent();
 406                         g.getChildren()
 407                                 .get(index)
 408                                 .setTranslateX(
 409                                         (int) (Math.random() * 500 * direction));
 410                         g.getChildren()
 411                                 .get(index)
 412                                 .setTranslateY(
 413                                         (int) (Math.random() * 500 * direction));
 414                         whatHappened = "On iteration " + j + "-"+ i + "I translated a "
 415                                 + g.getChildren().get(index) + " with boundsInParent "
 416                                 + formatBounds(oldBoundsInParent) + " which was the "
 417                                 + index+1 + "th item. Its new bounds are "
 418                                 + formatBounds(g.getChildren().get(index).getBoundsInParent()) + ". "
 419                                 + "The layoutBounds of the Group was "
 420                                 + formatBounds(layoutBounds) + " and is now " + formatBounds(g.getLayoutBounds()) + " and had "
 421                                 + numChildren + " number of child nodes";
 422                         whatHappenedStack.add(whatHappened);
 423                     } else if (rnd > .5 && rnd < .6 && numChildren > 0) {
 424                         // deletesome rect
 425                         whatHappened = "On iteration " + j + "-" + i+ " I deleted a "
 426                                 + "" + g.getChildren().get(index) + " with boundsInParent "
 427                                 + "" + formatBounds(g.getChildren().get(index).getBoundsInParent())+ " which was the "
 428                                 + "" + index+1+ "th item. The layoutBounds of the Group was "
 429                                 + "" + formatBounds(layoutBounds)+ " and is now " + formatBounds(g.getLayoutBounds())+ " and had "
 430                                 + "" + numChildren+ " number of child nodes";
 431                         g.getChildren().remove(index);
 432                         whatHappenedStack.add(whatHappened);
 433                     } else if (rnd > .6 && rnd < .65 && numChildren > 0) {
 434                         // toggle visibility on some rect
 435                         g.getChildren().get(index)
 436                                 .setVisible(!g.getChildren().get(index).isVisible());
 437                         whatHappened = "On iteration " + j+ "-" + i+ " I toggled the "
 438                                 + "visibility of " + g.getChildren().get(index) + " with boundsInParent "
 439                                 + "" + formatBounds(g.getChildren().get(index).getBoundsInParent())+ " to "
 440                                 + "" + g.getChildren().get(index).isVisible() + ". The layoutBounds of the "
 441                                 + "Group was " + formatBounds(layoutBounds)+ " and is now " + formatBounds(g.getLayoutBounds())+ " and "
 442                                 + "had " + numChildren+ " number of child nodes";
 443                         whatHappenedStack.add(whatHappened);
 444                     } else {
 445                         Rectangle rect = new Rectangle(
 446                                 ((int) (Math.random() * 1000)),
 447                                 ((int) (Math.random() * 1000)),
 448                                 ((int) (Math.random() * 100)),
 449                                 ((int) (Math.random() * 100)));
 450                         g.getChildren().add(rect);
 451                         whatHappened = "On iteration " + j+ "-" + i+ " I added a " + rect+ " with "
 452                                 + "boundsInParent " + formatBounds(rect.getBoundsInParent())+ " to the group. The "
 453                                 + "layoutBounds of the Group was " + formatBounds(layoutBounds)+ " and is now "
 454                                 + "" + formatBounds(g.getLayoutBounds())+ " and had " + numChildren+ " number of "
 455                                 + "child nodes";
 456                         whatHappenedStack.add(whatHappened);
 457                     }
 458                     try {
 459                         assertGroupBounds(g);
 460                     } catch (Exception any) {
 461                         System.out.println("Something went wrong. Here's what happened:");
 462                         for (String item : whatHappenedStack) {
 463                             System.out.println("{item}");
 464                         }
 465                         throw new RuntimeException(any);
 466                     }
 467                 }
 468             }
 469         }
 470     }
 471 
 472     // here is a special test for getPivotX and getPivotY
 473     @Test
 474     public void testPivotXAndPivotY() {
 475         Rectangle rect = new Rectangle(100, 100);
 476         assertEquals(50.0f, (float) NodeHelper.getPivotX(rect));
 477         assertEquals(50.0f, (float) NodeHelper.getPivotY(rect));
 478         rect.setWidth(70.0f);
 479         assertEquals(35.0f, (float) NodeHelper.getPivotX(rect));
 480         assertEquals(50.0f, (float) NodeHelper.getPivotY(rect));
 481     }
 482 
 483     /***************************************************************************
 484      * Group Bounds Sanity Tests * * These tests are for Group
 485      * to make sure that their * bounds are reported correctly
 486      * before effects or clips or transforms * are taken into account. * * The
 487      * group tests here are just basic tests, a full set of Group bounds * tests
 488      * are included in their own section later in this file. There are * many
 489      * edge cases to group bounds. The primary purpose of these next * few tests
 490      * are just to make sure that group's bounds are correct in the * simple
 491      * case. * *
 492      **************************************************************************/
 493 
 494     public @Test
 495     void testBoundsForGroup() {
 496         Rectangle r1 = new Rectangle(20, 20, 50, 50);
 497         Rectangle r2 = new Rectangle(90, 20, 50, 50);
 498         Group group = new Group(r1, r2);
 499 
 500         assertEquals(box(20, 20, 120, 50), group.getBoundsInLocal());
 501         assertEquals(group.getBoundsInLocal(), group.getBoundsInParent());
 502         assertEquals(group.getBoundsInLocal(), group.getLayoutBounds());
 503     }
 504 
 505     /**
 506      * Just a basic test to make sure basic group node bounds calculation works
 507      */
 508     public @Test
 509     void testBoundsForGroup_childGeomChanging() {
 510         Rectangle rect = new Rectangle();
 511         rect.setId("rect");
 512         Rectangle square = new Rectangle();
 513         square.setId("square");
 514         Group group = new Group(rect, square);
 515         group.setId("group");
 516 
 517         assertBoundsEqual(box(0, 0, 0, 0), rect.getBoundsInLocal());
 518         assertBoundsEqual(box(0, 0, 0, 0), square.getBoundsInLocal());
 519         assertBoundsEqual(box(0, 0, 0, 0), group.getBoundsInLocal());
 520 
 521         rect.setX(50);
 522         rect.setY(50);
 523         rect.setWidth(100);
 524         rect.setHeight(30);
 525 
 526         assertBoundsEqual(box(50, 50, 100, 30), rect.getBoundsInLocal());
 527         assertBoundsEqual(box(0, 0, 0, 0), square.getBoundsInLocal());
 528         assertBoundsEqual(box(0, 0, 150, 80), group.getBoundsInLocal());
 529 
 530         square.setX(25);
 531         square.setY(25);
 532         square.setWidth(50);
 533         square.setHeight(50);
 534 
 535         assertBoundsEqual(box(50, 50, 100, 30), rect.getBoundsInLocal());
 536         assertBoundsEqual(box(25, 25, 50, 50), square.getBoundsInLocal());
 537         assertBoundsEqual(box(25, 25, 125, 55), group.getBoundsInLocal());
 538     }
 539 
 540     public @Test
 541     void testBoundsInParentOfGroup() {
 542         Rectangle rect = new Rectangle(50, 50, 100, 30);
 543         rect.setId("rect");
 544         Group group = new Group(rect);
 545         group.setId("group");
 546         group.setTranslateX(100);
 547         group.setTranslateY(100);
 548 
 549         assertBoundsEqual(box(150, 150, 100, 30), group.getBoundsInParent());
 550     }
 551 
 552     /**
 553      * Tests that if I have a group with nobody listening to the bounds, and the
 554      * bounds change, and then I ask for the new bounds, that the bounds are
 555      * valid.
 556      */
 557     public @Test
 558     void testRequestingBoundsOnGroupWithNoListenersWorks() {
 559         Group group = new Group(new Rectangle(50, 50, 100, 30));
 560 
 561         assertBoundsEqual(box(50, 50, 100, 30), group.getBoundsInLocal());
 562     }
 563 
 564 }