001 package sysModel.env; 002 003 import junit.framework.TestCase; 004 import model.ILambda; 005 import model.fish.GenericFish; 006 import sysModel.ICmdFactory; 007 import sysModel.ISecurityAdapter; 008 import sysModel.NoOpLambda; 009 import sysModel.fish.IFishFactory; 010 import sysModel.fish.AFish; 011 import sysModel.parser.DefaultTokenVisitor; 012 import sysModel.parser.Lexer; 013 import sysModel.parser.ParserException; 014 015 import javax.swing.*; 016 import java.awt.*; 017 import java.awt.event.MouseEvent; 018 import java.util.LinkedList; 019 020 /** 021 * Implementation of a square wrapping environment. 022 * 023 * @author Mathias G. Ricken 024 */ 025 public class WrappingEnv extends BoundedEnv { 026 027 /** 028 * Factory method for overridden Location. 029 * 030 * @param x x coordinate 031 * @param y y coordinate 032 * @return new WrappingEnv.Location at (x, y) 033 */ 034 public ASquareEnv.Location makeLocation(double x, double y) { 035 return new Location(x, y); 036 } 037 038 /** 039 * Overridden location class that does wrapping. 040 * 041 * @author Mathias G. Ricken 042 */ 043 public class Location extends ASquareEnv.Location { 044 /** 045 * Ctor for location. 046 * 047 * @param x x position 048 * @param y y position 049 */ 050 public Location(double x, double y) { 051 super(x, y); 052 } 053 054 /** 055 * Return the location of a neighbor in the given direction. 056 * 057 * @param dir the direction of the neighbor to be returned 058 * @return neighbor in that direction 059 */ 060 public ASquareEnv.Location getNeighbor(Direction dir) { 061 double newX = getX() + dir.getDeltaX(); 062 double newY = getY() + dir.getDeltaY(); 063 if (0 > newX) { 064 newX = _width + newX; 065 } 066 else if (newX >= _width) { 067 newX = newX - _width; 068 } 069 if (0 > newY) { 070 newY = _height + newY; 071 } 072 else if (newY >= _height) { 073 newY = newY - _height; 074 } 075 return makeLocation(newX, newY); 076 } 077 } 078 079 /** 080 * Construct a new square wrapping environment. Does not set this object up for actual use. Note: This constructor 081 * needs to exist and be public for the "environment selection" dialog to work. 082 * 083 * @param cmdFactory command factory to use 084 * @param sm security manager to control fish action 085 */ 086 public WrappingEnv(ICmdFactory cmdFactory, ISecurityAdapter sm) { 087 super(cmdFactory, sm); 088 } 089 090 /** 091 * Construct a new square wrapping environment. 092 * 093 * @param cmdFactory command factory to use 094 * @param sm security manager to control fish actions 095 * @param width width of environment 096 * @param height height of environment 097 */ 098 public WrappingEnv(ICmdFactory cmdFactory, ISecurityAdapter sm, int width, int height) { 099 super(cmdFactory, sm, width, height); 100 } 101 102 /** 103 * Get the environment settings class. 104 * 105 * @return environment settings class 106 */ 107 public AEnvFactory makeEnvFactory() { 108 return new AEnvFactory() { 109 private JTextField _rowField; 110 private JTextField _colField; 111 112 { 113 setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 114 add(new JLabel("rows: ")); 115 add(_rowField = new JTextField("10")); 116 add(new JLabel(" cols: ")); 117 add(_colField = new JTextField("10")); 118 } 119 120 public AGlobalEnv create() { 121 return new WrappingEnv(_cmdFactory, 122 _securityAdapter, 123 Integer.parseInt(_colField.getText()), 124 Integer.parseInt(_rowField.getText())); 125 } 126 127 public String toString() { 128 return WrappingEnv.class.getName(); 129 } 130 }; 131 } 132 133 /** 134 * Factory method for parsing a stream of tokens and creating a global environment from it. 135 * 136 * @param l lexer 137 * @return new global environment 138 */ 139 protected AGlobalEnv parseEnvironment(final Lexer l) { 140 // have to read size of environment 141 return (AGlobalEnv) l.nextToken().execute(new DefaultTokenVisitor() { 142 public Object defaultCase() { 143 throw new ParserException("Invalid token"); 144 } 145 146 public Object numCase(final double width) { 147 // width was read 148 return (AGlobalEnv) l.nextToken().execute(new DefaultTokenVisitor() { 149 public Object defaultCase() { 150 throw new ParserException("Invalid token"); 151 } 152 153 public Object numCase(double height) { 154 // height was read 155 BoundedEnv env = new WrappingEnv(_cmdFactory, _securityAdapter, (int) width, (int) height); 156 157 // parse fish 158 env.parseFish(l); 159 160 return env; 161 } 162 }); 163 } 164 }); 165 } 166 167 /***************************************************************************************************************** 168 * Tests follow 169 *****************************************************************************************************************/ 170 171 /** 172 * Test cases for WrappingEnv. 173 * 174 * @author Mathias Ricken 175 */ 176 public static class Test_WrappingEnv extends TestCase { 177 private ICmdFactory _cmdFactory; 178 private ISecurityAdapter _sm; 179 private WrappingEnv _env; 180 private IFishFactory _fishFactory; 181 182 private static final ILambda _notify = new ILambda() { 183 public Object apply(Object param) { 184 return "notifyCmd"; 185 } 186 }; 187 private static final ILambda _delete = new ILambda() { 188 public Object apply(Object param) { 189 return "deleteCmd"; 190 } 191 }; 192 private static final ILambda _add = new ILambda() { 193 public Object apply(Object param) { 194 return "addCmd"; 195 } 196 }; 197 198 public void setUp() throws Exception { 199 super.setUp(); 200 _cmdFactory = new ICmdFactory() { 201 public ILambda makeNotifyCmd(ILambda lambda) { 202 return _notify; 203 } 204 205 public ILambda makeDeleteCmd(ALocalEnv env) { 206 return _delete; 207 } 208 209 public ILambda makeAddCmd(AFish fish) { 210 return _add; 211 } 212 }; 213 _sm = new ISecurityAdapter() { 214 public void setProtected(boolean _protected) { 215 } 216 public ThreadGroup getFishThreadGroup() { 217 return null; 218 } 219 public ClassLoader getClassLoader() { 220 return null; 221 } 222 public void handleException(Throwable t) { 223 } 224 }; 225 226 _env = new WrappingEnv(_cmdFactory, _sm, 10, 10); 227 228 _fishFactory = new IFishFactory() { 229 /** 230 * Create a new fish. 231 * 232 * @return new fish 233 */ 234 public AFish createFish() { 235 return new GenericFish(Color.RED); 236 } 237 }; 238 } 239 240 int countNonEmpty() { 241 int count = 0; 242 WrappingEnv.IField[][] map = _env._fieldMap; 243 IFieldVisitor countVisitor = new IFieldVisitor() { 244 public Object emptyCase(EmptyField host, Object param) { 245 return new Integer(0); 246 } 247 248 public Object nonEmptyCase(NonEmptyField host, Object param) { 249 return new Integer(1); 250 } 251 }; 252 for (int i = 0; i < map.length; i++) { 253 WrappingEnv.IField[] iFields = map[i]; 254 for (int j = 0; j < iFields.length; j++) { 255 WrappingEnv.IField iField = iFields[j]; 256 count += ((Integer) iField.execute(countVisitor, null)).intValue(); 257 } 258 } 259 return count; 260 } 261 262 /** 263 * Test addFishToInternalData. 264 */ 265 public void testAddFish() { 266 assertEquals(0, countNonEmpty()); 267 268 ALocalEnv lTop = _env.makeLocalEnv(new Point.Double(1.0, 1.0)); 269 GenericFish fTop = new GenericFish(Color.RED); 270 fTop.setLocalEnvironment(lTop); 271 _env.addFishToInternalData(lTop, fTop); 272 273 assertEquals(1, countNonEmpty()); 274 275 ALocalEnv lBottom = _env.makeLocalEnv(new Point.Double(1.0, 2.0)); 276 GenericFish fBottom = new GenericFish(Color.RED); 277 fBottom.setLocalEnvironment(lBottom); 278 _env.addFishToInternalData(lBottom, fBottom); 279 280 assertEquals(2, countNonEmpty()); 281 } 282 283 /** 284 * Test editFish. 285 */ 286 public void testEditFish() { 287 assertEquals(0, countNonEmpty()); 288 289 ASquareLocalEnvironment l = (ASquareLocalEnvironment) _env.makeLocalEnv(new Point.Double(1.0, 1.0)); 290 GenericFish f = new GenericFish(Color.RED); 291 f.setLocalEnvironment(l); 292 _env.addFishToInternalData(l, f); 293 WrappingEnv.Direction d = l.direction(); 294 295 assertEquals(1, countNonEmpty()); 296 assertEquals(0.0, d.getAngle(), 0.01); 297 298 ILambda lambda = _env.editFish(l, _fishFactory, MouseEvent.BUTTON1); 299 assertEquals(1, countNonEmpty()); 300 assertEquals(Math.PI / 2.0, d.getAngle(), 0.01); 301 assertEquals(NoOpLambda.instance(), lambda); 302 303 lambda = _env.editFish(l, _fishFactory, MouseEvent.BUTTON1); 304 assertEquals(1, countNonEmpty()); 305 assertEquals(Math.PI, d.getAngle(), 0.01); 306 assertEquals(NoOpLambda.instance(), lambda); 307 308 lambda = _env.editFish(l, _fishFactory, MouseEvent.BUTTON1); 309 assertEquals(1, countNonEmpty()); 310 assertEquals(3 * Math.PI / 2.0, d.getAngle(), 0.01); 311 assertEquals(NoOpLambda.instance(), lambda); 312 313 lambda = _env.editFish(l, _fishFactory, MouseEvent.BUTTON1); 314 assertEquals(0, countNonEmpty()); 315 assertEquals(0, d.getAngle(), 0.01); 316 assertEquals(_delete, lambda); 317 } 318 319 /** 320 * Test getViewPosition. 321 */ 322 public void testGetViewPosition() { 323 assertTrue(_env.getViewPosition(new Point.Double(0, 0)).equals(new Point.Double(0, 0))); 324 assertTrue(_env.getViewPosition(new Point.Double(1.0, 0)).equals(new Point.Double(1.0, 0))); 325 assertTrue(_env.getViewPosition(new Point.Double(1.2, 0)).equals(new Point.Double(1.2, 0))); 326 assertTrue(_env.getViewPosition(new Point.Double(0, 1.0)).equals(new Point.Double(0, 1.0))); 327 assertTrue(_env.getViewPosition(new Point.Double(0, 1.3)).equals(new Point.Double(0, 1.3))); 328 assertTrue(_env.getViewPosition(new Point.Double(-2.5, 0)).equals(new Point.Double(-2.5, 0))); 329 assertTrue(_env.getViewPosition(new Point.Double(-3.0, 0)).equals(new Point.Double(-3.0, 0))); 330 assertTrue(_env.getViewPosition(new Point.Double(0, -2.5)).equals(new Point.Double(0, -2.5))); 331 assertTrue(_env.getViewPosition(new Point.Double(0, -3.0)).equals(new Point.Double(0, -3.0))); 332 assertTrue(_env.getViewPosition(new Point.Double(2.0, 1.0)).equals(new Point.Double(2.0, 1.0))); 333 assertTrue(_env.getViewPosition(new Point.Double(-4.0, -2.3)).equals(new Point.Double(-4.0, -2.3))); 334 } 335 336 /** 337 * Test getPanDelta. 338 */ 339 public void testGetPanDelta() { 340 assertTrue(_env.getPanDelta(new Point.Double(0, 0)).equals(new Point.Double(0, 0))); 341 assertTrue(_env.getPanDelta(new Point.Double(1.0, 0)).equals(new Point.Double(0, 0))); 342 assertTrue(_env.getPanDelta(new Point.Double(1.2, 0)).equals(new Point.Double(0, 0))); 343 assertTrue(_env.getPanDelta(new Point.Double(0, 1.0)).equals(new Point.Double(0, 0))); 344 assertTrue(_env.getPanDelta(new Point.Double(0, 1.3)).equals(new Point.Double(0, 0))); 345 assertTrue(_env.getPanDelta(new Point.Double(-2.5, 0)).equals(new Point.Double(0, 0))); 346 assertTrue(_env.getPanDelta(new Point.Double(-3.0, 0)).equals(new Point.Double(0, 0))); 347 assertTrue(_env.getPanDelta(new Point.Double(0, -2.5)).equals(new Point.Double(0, 0))); 348 assertTrue(_env.getPanDelta(new Point.Double(0, -3.0)).equals(new Point.Double(0, 0))); 349 assertTrue(_env.getPanDelta(new Point.Double(2.0, 1.0)).equals(new Point.Double(0, 0))); 350 assertTrue(_env.getPanDelta(new Point.Double(-4.0, -2.3)).equals(new Point.Double(0, 0))); 351 } 352 } 353 354 /** 355 * Test cases for WrappingEnv.LocalEnv. 356 * 357 * @author Mathias Ricken 358 */ 359 public static class Test_WrappingEnv_LocalEnv extends TestCase { 360 private ICmdFactory _cmdFactory; 361 private ISecurityAdapter _sm; 362 private WrappingEnv _env; 363 364 private static class SuccessException extends RuntimeException { 365 public SuccessException() { 366 super(); 367 } 368 } 369 370 private static final ILambda _notify = new ILambda() { 371 public Object apply(Object param) { 372 return "notifyCmd"; 373 } 374 }; 375 private static final ILambda _delete = new ILambda() { 376 public Object apply(Object param) { 377 return "deleteCmd"; 378 } 379 }; 380 private static final ILambda _add = new ILambda() { 381 public Object apply(Object param) { 382 return "addCmd"; 383 } 384 }; 385 386 public void setUp() throws Exception { 387 super.setUp(); 388 _cmdFactory = new ICmdFactory() { 389 public ILambda makeNotifyCmd(ILambda lambda) { 390 return _notify; 391 } 392 393 public ILambda makeDeleteCmd(ALocalEnv env) { 394 return _delete; 395 } 396 397 public ILambda makeAddCmd(AFish fish) { 398 return _add; 399 } 400 }; 401 _sm = new ISecurityAdapter() { 402 public void setProtected(boolean _protected) { 403 } 404 public ThreadGroup getFishThreadGroup() { 405 return null; 406 } 407 public ClassLoader getClassLoader() { 408 return null; 409 } 410 public void handleException(Throwable t) { 411 } 412 }; 413 414 _env = new WrappingEnv(_cmdFactory, _sm, 10, 10); 415 } 416 417 /** 418 * Test local environment's execute. 419 */ 420 public void testExecute() { 421 ALocalEnv l = _env.makeLocalEnv(new Point.Double(1, 1)); 422 423 try { 424 l.execute(new AGlobalEnv.ILocalEnvVisitor() { 425 public Object emptyCase(ALocalEnv host, Object param) { 426 // ok 427 throw new SuccessException(); 428 } 429 430 public Object nonEmptyCase(ALocalEnv host, Object param) { 431 throw new RuntimeException("Should be empty"); 432 } 433 }, null); 434 fail("emptyCase should have been called --"); 435 } 436 catch (SuccessException e) { 437 } 438 439 440 GenericFish f = new GenericFish(Color.RED); 441 f.setLocalEnvironment(l); 442 _env.addFish(l, f); 443 l.setState(NonEmptyLocalEnvState.Singleton); 444 try { 445 l.execute(new AGlobalEnv.ILocalEnvVisitor() { 446 public Object emptyCase(ALocalEnv host, Object param) { 447 throw new RuntimeException("Should be non-empty"); 448 } 449 450 public Object nonEmptyCase(ALocalEnv host, Object param) { 451 // ok 452 throw new SuccessException(); 453 } 454 }, null); 455 fail("nonEmptyCase should have been called --"); 456 } 457 catch (SuccessException e) { 458 } 459 460 ALocalEnv l2 = _env.makeLocalEnv(new Point.Double(1, 1)); 461 try { 462 l2.execute(new AGlobalEnv.ILocalEnvVisitor() { 463 public Object emptyCase(ALocalEnv host, Object param) { 464 throw new RuntimeException("Should be non-empty"); 465 } 466 467 public Object nonEmptyCase(ALocalEnv host, Object param) { 468 // ok 469 throw new SuccessException(); 470 } 471 }, null); 472 fail("nonEmptyCase should have been called --"); 473 } 474 catch (SuccessException e) { 475 } 476 477 ALocalEnv l3 = _env.makeLocalEnv(new Point.Double(1.4, 1.6)); 478 try { 479 l3.execute(new AGlobalEnv.ILocalEnvVisitor() { 480 public Object emptyCase(ALocalEnv host, Object param) { 481 throw new RuntimeException("Should be non-empty"); 482 } 483 484 public Object nonEmptyCase(ALocalEnv host, Object param) { 485 // ok 486 throw new SuccessException(); 487 } 488 }, null); 489 fail("nonEmptyCase should have been called --"); 490 } 491 catch (SuccessException e) { 492 } 493 494 ALocalEnv l4 = _env.makeLocalEnv(new Point.Double(1.0, 2.0)); 495 try { 496 l4.execute(new AGlobalEnv.ILocalEnvVisitor() { 497 public Object emptyCase(ALocalEnv host, Object param) { 498 // ok 499 throw new SuccessException(); 500 } 501 502 public Object nonEmptyCase(ALocalEnv host, Object param) { 503 throw new RuntimeException("Should be empty"); 504 } 505 }, null); 506 fail("emptyCase should have been called --"); 507 } 508 catch (SuccessException e) { 509 } 510 511 GenericFish f4 = new GenericFish(Color.RED); 512 f4.setLocalEnvironment(l4); 513 _env.addFish(l4, f4); 514 l4.setState(NonEmptyLocalEnvState.Singleton); 515 try { 516 l4.execute(new AGlobalEnv.ILocalEnvVisitor() { 517 public Object emptyCase(ALocalEnv host, Object param) { 518 throw new RuntimeException("Should be non-empty"); 519 } 520 521 public Object nonEmptyCase(ALocalEnv host, Object param) { 522 // ok 523 throw new SuccessException(); 524 } 525 }, null); 526 fail("nonEmptyCase should have been called --"); 527 } 528 catch (SuccessException e) { 529 } 530 } 531 532 /** 533 * Test local environment's tryMoveFwd. 534 */ 535 public void testTryMoveFwd() { 536 ALocalEnv lTop = _env.makeLocalEnv(new Point.Double(1.0, 1.0)); 537 GenericFish fTop = new GenericFish(Color.RED); 538 fTop.setLocalEnvironment(lTop); 539 _env.addFish(lTop, fTop); 540 lTop.setState(NonEmptyLocalEnvState.Singleton); 541 542 ALocalEnv lBottom = _env.makeLocalEnv(new Point.Double(1.0, 2.0)); 543 GenericFish fBottom = new GenericFish(Color.RED); 544 fBottom.setLocalEnvironment(lBottom); 545 _env.addFish(lBottom, fBottom); 546 lBottom.setState(NonEmptyLocalEnvState.Singleton); 547 548 // move lBottom into lTop --> blocked 549 Integer i = (Integer) lBottom.tryMoveFwd(fBottom, new IBlockedCommand() { 550 public Object apply(Object param) { 551 // ok 552 return new Integer(456); 553 } 554 }, new IOpenCommand() { 555 public Object apply(Object param) { 556 throw new RuntimeException("Should be blocked"); 557 } 558 }); 559 assertEquals("Error in delegation, blockedCmd not called, or incorrect return value --", 560 new Integer(456), 561 i); 562 563 // move lTop --> open, don't move 564 i = (Integer) lTop.tryMoveFwd(fTop, new IBlockedCommand() { 565 public Object apply(Object param) { 566 throw new RuntimeException("Should be open"); 567 } 568 }, new IOpenCommand() { 569 public Object apply(Object param) { 570 assertNotNull("Error, deactivatable move lambda needs to be passed to openCmd --", param); 571 assertEquals("Error, deactivatable move lambda needs to be passed to openCmd --", 572 DeactivatableLambda.class, 573 param.getClass()); 574 // ok 575 return new Integer(123); 576 } 577 }); 578 assertEquals("Error in delegation, openCmd not called, or incorrect return value --", new Integer(123), i); 579 580 // move lBottom into lTop --> blocked 581 i = (Integer) lBottom.tryMoveFwd(fBottom, new IBlockedCommand() { 582 public Object apply(Object param) { 583 // ok 584 return new Integer(789); 585 } 586 }, new IOpenCommand() { 587 public Object apply(Object param) { 588 throw new RuntimeException("Should be blocked"); 589 } 590 }); 591 assertEquals("Error in delegation, blockedCmd not called, or incorrect return value --", 592 new Integer(789), 593 i); 594 595 // move lTop --> open, move 596 i = (Integer) lTop.tryMoveFwd(fTop, new IBlockedCommand() { 597 public Object apply(Object param) { 598 throw new RuntimeException("Should be open"); 599 } 600 }, new IOpenCommand() { 601 public Object apply(Object param) { 602 assertNotNull("Error, deactivatable move lambda needs to be passed to openCmd --", param); 603 assertEquals("Error, deactivatable move lambda needs to be passed to openCmd --", 604 DeactivatableLambda.class, 605 param.getClass()); 606 // ok, make move 607 ((ILambda) param).apply(null); 608 return new Integer(111); 609 } 610 }); 611 assertEquals("Error in delegation, openCmd not called, or incorrect return value --", new Integer(111), i); 612 613 // move lBottom --> open 614 i = (Integer) lBottom.tryMoveFwd(fBottom, new IBlockedCommand() { 615 public Object apply(Object param) { 616 throw new RuntimeException("Should be open"); 617 } 618 }, new IOpenCommand() { 619 public Object apply(Object param) { 620 assertNotNull("Error, deactivatable move lambda needs to be passed to openCmd --", param); 621 assertEquals("Error, deactivatable move lambda needs to be passed to openCmd --", 622 DeactivatableLambda.class, 623 param.getClass()); 624 // ok 625 return new Integer(222); 626 } 627 }); 628 assertEquals("Error in delegation, openCmd not called, or incorrect return value --", new Integer(222), i); 629 630 // move lTop into edge, wrap --> open 631 i = (Integer) lTop.tryMoveFwd(fTop, new IBlockedCommand() { 632 public Object apply(Object param) { 633 throw new RuntimeException("Should be open"); 634 } 635 }, new IOpenCommand() { 636 public Object apply(Object param) { 637 assertNotNull("Error, deactivatable move lambda needs to be passed to openCmd --", param); 638 assertEquals("Error, deactivatable move lambda needs to be passed to openCmd --", 639 DeactivatableLambda.class, 640 param.getClass()); 641 // ok 642 return new Integer(333); 643 } 644 }); 645 assertEquals("Error in delegation, openCmd not called, or incorrect return value --", new Integer(333), i); 646 647 // turn and move lTop --> open 648 lTop.turnRight(fTop, Math.PI / 2.0); 649 i = (Integer) lTop.tryMoveFwd(fTop, new IBlockedCommand() { 650 public Object apply(Object param) { 651 throw new RuntimeException("Should be open"); 652 } 653 }, new IOpenCommand() { 654 public Object apply(Object param) { 655 assertNotNull("Error, deactivatable move lambda needs to be passed to openCmd --", param); 656 assertEquals("Error, deactivatable move lambda needs to be passed to openCmd --", 657 DeactivatableLambda.class, 658 param.getClass()); 659 // ok 660 return new Integer(444); 661 } 662 }); 663 assertEquals("Error in delegation, openCmd not called, or incorrect return value --", new Integer(444), i); 664 } 665 666 int countNonEmpty() { 667 int count = 0; 668 WrappingEnv.IField[][] map = _env._fieldMap; 669 IFieldVisitor countVisitor = new IFieldVisitor() { 670 public Object emptyCase(EmptyField host, Object param) { 671 return new Integer(0); 672 } 673 674 public Object nonEmptyCase(NonEmptyField host, Object param) { 675 return new Integer(1); 676 } 677 }; 678 for (int i = 0; i < map.length; i++) { 679 WrappingEnv.IField[] iFields = map[i]; 680 for (int j = 0; j < iFields.length; j++) { 681 WrappingEnv.IField iField = iFields[j]; 682 count += ((Integer) iField.execute(countVisitor, null)).intValue(); 683 } 684 } 685 return count; 686 } 687 688 /** 689 * Test local environment's tryBreedFwd. 690 */ 691 public void testTryBreedFwd() { 692 assertEquals(0, countNonEmpty()); 693 694 ALocalEnv lTop = _env.makeLocalEnv(new Point.Double(1.0, 1.0)); 695 GenericFish fTop = new GenericFish(Color.RED); 696 fTop.setLocalEnvironment(lTop); 697 _env.addFish(lTop, fTop); 698 lTop.setState(NonEmptyLocalEnvState.Singleton); 699 700 assertEquals(1, countNonEmpty()); 701 702 ALocalEnv lBottom = _env.makeLocalEnv(new Point.Double(1.0, 2.0)); 703 GenericFish fBottom = new GenericFish(Color.RED); 704 fBottom.setLocalEnvironment(lBottom); 705 _env.addFish(lBottom, fBottom); 706 lBottom.setState(NonEmptyLocalEnvState.Singleton); 707 708 assertEquals(2, countNonEmpty()); 709 710 // breed lBottom into lTop --> blocked 711 Integer i = (Integer) lBottom.tryBreedFwd(fBottom, new IBlockedCommand() { 712 public Object apply(Object param) { 713 // ok 714 return new Integer(456); 715 } 716 }, new IOpenCommand() { 717 public Object apply(Object param) { 718 throw new RuntimeException("Should be blocked"); 719 } 720 }); 721 assertEquals("Error in delegation, blockedCmd not called, or incorrect return value --", 722 new Integer(456), 723 i); 724 725 // breed lTop --> open, don't breed 726 i = (Integer) lTop.tryBreedFwd(fTop, new IBlockedCommand() { 727 public Object apply(Object param) { 728 throw new RuntimeException("Should be open"); 729 } 730 }, new IOpenCommand() { 731 public Object apply(Object param) { 732 assertNotNull("Error, deactivatable breed lambda needs to be passed to openCmd --", param); 733 assertEquals("Error, deactivatable breed lambda needs to be passed to openCmd --", 734 DeactivatableLambda.class, 735 param.getClass()); 736 // ok 737 return new Integer(123); 738 } 739 }); 740 assertEquals("Error in delegation, openCmd not called, or incorrect return value --", new Integer(123), i); 741 742 assertEquals(2, countNonEmpty()); 743 744 // breed lBottom into lTop --> blocked 745 i = (Integer) lBottom.tryBreedFwd(fBottom, new IBlockedCommand() { 746 public Object apply(Object param) { 747 // ok 748 return new Integer(456); 749 } 750 }, new IOpenCommand() { 751 public Object apply(Object param) { 752 throw new RuntimeException("Should be blocked"); 753 } 754 }); 755 assertEquals("Error in delegation, blockedCmd not called, or incorrect return value --", 756 new Integer(456), 757 i); 758 759 // breed lTop --> open, breed 760 i = (Integer) lTop.tryBreedFwd(fTop, new IBlockedCommand() { 761 public Object apply(Object param) { 762 throw new RuntimeException("Should be open"); 763 } 764 }, new IOpenCommand() { 765 public Object apply(Object param) { 766 assertNotNull("Error, deactivatable breed lambda needs to be passed to openCmd --", param); 767 assertEquals("Error, deactivatable breed lambda needs to be passed to openCmd --", 768 DeactivatableLambda.class, 769 param.getClass()); 770 // ok, breed 771 ((ILambda) param).apply(null); 772 return new Integer(123); 773 } 774 }); 775 assertEquals("Error in delegation, openCmd not called, or incorrect return value --", new Integer(123), i); 776 777 assertEquals(3, countNonEmpty()); 778 779 // breed lBottom into lTop --> blocked 780 i = (Integer) lBottom.tryBreedFwd(fBottom, new IBlockedCommand() { 781 public Object apply(Object param) { 782 // ok 783 return new Integer(456); 784 } 785 }, new IOpenCommand() { 786 public Object apply(Object param) { 787 throw new RuntimeException("Should be blocked"); 788 } 789 }); 790 assertEquals("Error in delegation, blockedCmd not called, or incorrect return value --", 791 new Integer(456), 792 i); 793 794 // breed lTop --> blocked 795 i = (Integer) lTop.tryBreedFwd(fTop, new IBlockedCommand() { 796 public Object apply(Object param) { 797 // ok 798 return new Integer(456); 799 } 800 }, new IOpenCommand() { 801 public Object apply(Object param) { 802 throw new RuntimeException("Should be blocked"); 803 } 804 }); 805 assertEquals("Error in delegation, blockedCmd not called, or incorrect return value --", 806 new Integer(456), 807 i); 808 809 // turn and breed lTop --> open, don't breed 810 lTop.turnRight(fTop, Math.PI / 2.0); 811 i = (Integer) lTop.tryBreedFwd(fTop, new IBlockedCommand() { 812 public Object apply(Object param) { 813 throw new RuntimeException("Should be open"); 814 } 815 }, new IOpenCommand() { 816 public Object apply(Object param) { 817 assertNotNull("Error, deactivatable breed lambda needs to be passed to openCmd --", param); 818 assertEquals("Error, deactivatable breed lambda needs to be passed to openCmd --", 819 DeactivatableLambda.class, 820 param.getClass()); 821 // ok 822 return new Integer(789); 823 } 824 }); 825 assertEquals("Error in delegation, openCmd not called, or incorrect return value --", new Integer(789), i); 826 827 assertEquals(3, countNonEmpty()); 828 829 // turn and breed lTop --> open, breed 830 i = (Integer) lTop.tryBreedFwd(fTop, new IBlockedCommand() { 831 public Object apply(Object param) { 832 throw new RuntimeException("Should be open"); 833 } 834 }, new IOpenCommand() { 835 public Object apply(Object param) { 836 assertNotNull("Error, deactivatable breed lambda needs to be passed to openCmd --", param); 837 assertEquals("Error, deactivatable breed lambda needs to be passed to openCmd --", 838 DeactivatableLambda.class, 839 param.getClass()); 840 // ok, breed 841 ((ILambda) param).apply(null); 842 return new Integer(789); 843 } 844 }); 845 assertEquals("Error in delegation, openCmd not called, or incorrect return value --", new Integer(789), i); 846 847 assertEquals(4, countNonEmpty()); 848 849 // turn and breed lTop --> blocked 850 i = (Integer) lTop.tryBreedFwd(fTop, new IBlockedCommand() { 851 public Object apply(Object param) { 852 // ok 853 return new Integer(789); 854 } 855 }, new IOpenCommand() { 856 public Object apply(Object param) { 857 throw new RuntimeException("Should be blocked"); 858 } 859 }); 860 assertEquals("Error in delegation, blockedCmd not called, or incorrect return value --", 861 new Integer(789), 862 i); 863 864 assertEquals(4, countNonEmpty()); 865 } 866 867 /** 868 * Test local environment's turnRight. 869 */ 870 public void testTurnRight() { 871 ASquareLocalEnvironment l = (ASquareLocalEnvironment) _env.makeLocalEnv(new Point.Double(1.0, 1.0)); 872 GenericFish f = new GenericFish(Color.RED); 873 f.setLocalEnvironment(l); 874 _env.addFish(l, f); 875 l.setState(NonEmptyLocalEnvState.Singleton); 876 WrappingEnv.Direction d = l.direction(); 877 878 assertEquals(0.0, d.getAngle(), 0.01); 879 l.turnRight(f, Math.PI / 2); 880 assertEquals(Math.PI / 2.0, d.getAngle(), 0.01); 881 l.turnRight(f, Math.PI / 2); 882 assertEquals(Math.PI, d.getAngle(), 0.01); 883 l.turnRight(f, Math.PI / 2); 884 assertEquals(3 * Math.PI / 2.0, d.getAngle(), 0.01); 885 l.turnRight(f, Math.PI / 2); 886 assertEquals(0, d.getAngle(), 0.01); 887 } 888 889 /** 890 * Test local environment's removeFish. 891 */ 892 public void testRemoveFish() { 893 assertEquals(0, countNonEmpty()); 894 895 ALocalEnv lTop = _env.makeLocalEnv(new Point.Double(1.0, 1.0)); 896 GenericFish fTop = new GenericFish(Color.RED); 897 fTop.setLocalEnvironment(lTop); 898 _env.addFish(lTop, fTop); 899 lTop.setState(NonEmptyLocalEnvState.Singleton); 900 901 assertEquals(1, countNonEmpty()); 902 903 ALocalEnv lBottom = _env.makeLocalEnv(new Point.Double(1.0, 2.0)); 904 GenericFish fBottom = new GenericFish(Color.RED); 905 fBottom.setLocalEnvironment(lBottom); 906 _env.addFish(lBottom, fBottom); 907 lBottom.setState(NonEmptyLocalEnvState.Singleton); 908 909 assertEquals(2, countNonEmpty()); 910 911 lTop.removeFish(fTop); 912 913 assertEquals(1, countNonEmpty()); 914 915 lBottom.removeFish(fBottom); 916 917 assertEquals(0, countNonEmpty()); 918 } 919 920 /** 921 * Test to make sure only one move lambda can be executed. 922 */ 923 public void testOnlyOneMove() { 924 ASquareLocalEnvironment l = (ASquareLocalEnvironment) _env.makeLocalEnv(new Point.Double(5.0, 5.0)); 925 GenericFish f = new GenericFish(Color.RED); 926 f.setLocalEnvironment(l); 927 _env.addFish(l, f); 928 l.setState(NonEmptyLocalEnvState.Singleton); 929 930 final LinkedList<ILambda> lambdas = new LinkedList<ILambda>(); 931 l.tryMoveFwd(f, new IBlockedCommand() { 932 public Object apply(Object param) { 933 throw new RuntimeException("Should be open"); 934 } 935 }, new IOpenCommand() { 936 public Object apply(Object param) { 937 lambdas.add((ILambda)param); 938 return null; 939 } 940 }); 941 f.turnRight(); 942 l.tryMoveFwd(f, new IBlockedCommand() { 943 public Object apply(Object param) { 944 throw new RuntimeException("Should be open"); 945 } 946 }, new IOpenCommand() { 947 public Object apply(Object param) { 948 lambdas.add((ILambda)param); 949 return null; 950 } 951 }); 952 953 assertEquals(2, lambdas.size()); 954 955 lambdas.get(0).apply(null); 956 Location loc = (Location) l.location(); 957 assertTrue(loc.same(_env.makeLocation(5.0, 4.0))); 958 959 lambdas.get(1).apply(null); 960 loc = (Location) l.location(); 961 assertTrue(loc.same(_env.makeLocation(5.0, 4.0))); 962 963 lambdas.clear(); 964 l.tryMoveFwd(f, new IBlockedCommand() { 965 public Object apply(Object param) { 966 throw new RuntimeException("Should be open"); 967 } 968 }, new IOpenCommand() { 969 public Object apply(Object param) { 970 lambdas.add((ILambda)param); 971 return null; 972 } 973 }); 974 f.turnRight(); 975 l.tryMoveFwd(f, new IBlockedCommand() { 976 public Object apply(Object param) { 977 throw new RuntimeException("Should be open"); 978 } 979 }, new IOpenCommand() { 980 public Object apply(Object param) { 981 lambdas.add((ILambda)param); 982 return null; 983 } 984 }); 985 986 assertEquals(2, lambdas.size()); 987 988 lambdas.get(1).apply(null); 989 loc = (Location) l.location(); 990 assertTrue(loc.same(_env.makeLocation(6.0, 4.0))); 991 992 lambdas.get(0).apply(null); 993 loc = (Location) l.location(); 994 assertTrue(loc.same(_env.makeLocation(6.0, 4.0))); 995 } 996 997 } 998 999 /** 1000 * Test cases for WrappingEnv.Location. 1001 * 1002 * @author Mathias Ricken 1003 */ 1004 public static class Test_WrappingEnv_Location extends TestCase { 1005 private ICmdFactory _cmdFactory; 1006 private ISecurityAdapter _sm; 1007 private WrappingEnv _env; 1008 1009 private static final ILambda _notify = new ILambda() { 1010 public Object apply(Object param) { 1011 return "notifyCmd"; 1012 } 1013 }; 1014 private static final ILambda _delete = new ILambda() { 1015 public Object apply(Object param) { 1016 return "deleteCmd"; 1017 } 1018 }; 1019 private static final ILambda _add = new ILambda() { 1020 public Object apply(Object param) { 1021 return "addCmd"; 1022 } 1023 }; 1024 1025 public void setUp() throws Exception { 1026 super.setUp(); 1027 _cmdFactory = new ICmdFactory() { 1028 public ILambda makeNotifyCmd(ILambda lambda) { 1029 return _notify; 1030 } 1031 1032 public ILambda makeDeleteCmd(ALocalEnv env) { 1033 return _delete; 1034 } 1035 1036 public ILambda makeAddCmd(AFish fish) { 1037 return _add; 1038 } 1039 }; 1040 _sm = new ISecurityAdapter() { 1041 public void setProtected(boolean _protected) { 1042 } 1043 public ThreadGroup getFishThreadGroup() { 1044 return null; 1045 } 1046 public ClassLoader getClassLoader() { 1047 return null; 1048 } 1049 public void handleException(Throwable t) { 1050 } 1051 }; 1052 1053 _env = new WrappingEnv(_cmdFactory, _sm, 50, 50); 1054 } 1055 1056 /** 1057 * Test getters, setters, and ctor. 1058 */ 1059 public void testGetSet() { 1060 ASquareEnv.Location l = _env.makeLocation(5, 7); 1061 assertEquals(5.0, l.getX(), 0.01); 1062 assertEquals(7.0, l.getY(), 0.01); 1063 1064 l.setX(11); 1065 assertEquals(11.0, l.getX(), 0.01); 1066 assertEquals(7.0, l.getY(), 0.01); 1067 1068 l.setY(13); 1069 assertEquals(11.0, l.getX(), 0.01); 1070 assertEquals(13.0, l.getY(), 0.01); 1071 } 1072 1073 /** 1074 * Test same. 1075 */ 1076 public void testSame() { 1077 ASquareEnv.Location l = _env.makeLocation(17, 23); 1078 ASquareEnv.Location l1 = _env.makeLocation(17, 23); 1079 ASquareEnv.Location l2 = _env.makeLocation(31, 37); 1080 assertEquals(true, l.same(l1)); 1081 assertEquals(false, l.same(l2)); 1082 assertEquals(true, l1.same(l)); 1083 assertEquals(false, l2.same(l)); 1084 assertEquals(false, l2.same(l1)); 1085 assertEquals(false, l1.same(l2)); 1086 } 1087 1088 /** 1089 * Test inField. 1090 */ 1091 public void testInField() { 1092 ASquareEnv.Location l = _env.makeLocation(17, 23); 1093 ASquareEnv.Location l1 = _env.makeLocation(17, 23); 1094 ASquareEnv.Location l2 = _env.makeLocation(17.13, 23.53); 1095 ASquareEnv.Location l3 = _env.makeLocation(17.49, 23.77); 1096 ASquareEnv.Location l4 = _env.makeLocation(31, 37); 1097 ASquareEnv.Location l5 = _env.makeLocation(31.81, 37.51); 1098 assertEquals(true, l.inField(l1)); 1099 assertEquals(true, l1.inField(l)); 1100 assertEquals(true, l.inField(l2)); 1101 assertEquals(true, l2.inField(l)); 1102 assertEquals(true, l.inField(l3)); 1103 assertEquals(true, l3.inField(l)); 1104 assertEquals(false, l.inField(l4)); 1105 assertEquals(false, l4.inField(l)); 1106 assertEquals(false, l.inField(l5)); 1107 assertEquals(false, l5.inField(l)); 1108 } 1109 1110 /** 1111 * Test getNeighbor. 1112 */ 1113 public void testNeighbor() { 1114 ASquareEnv.Location l = _env.makeLocation(17, 23); 1115 ASquareEnv.Location l1 = _env.makeLocation(17, 22); 1116 ASquareEnv.Location l2 = _env.makeLocation(18, 22); 1117 ASquareEnv.Location l3 = _env.makeLocation(18, 23); 1118 ASquareEnv.Location l4 = _env.makeLocation(17, 23); 1119 l = l.getNeighbor(_env.makeDirection(0, -1)); 1120 assertEquals(true, l.same(l1)); 1121 l = l.getNeighbor(_env.makeDirection(1, 0)); 1122 assertEquals(true, l.same(l2)); 1123 l = l.getNeighbor(_env.makeDirection(0, 1)); 1124 assertEquals(true, l.same(l3)); 1125 l = l.getNeighbor(_env.makeDirection(-1, 0)); 1126 assertEquals(true, l.same(l4)); 1127 1128 // test wrapping 1129 ASquareEnv.Location w = _env.makeLocation(0, 0); 1130 ASquareEnv.Location w1 = _env.makeLocation(0, 49); 1131 ASquareEnv.Location w2 = _env.makeLocation(49, 49); 1132 ASquareEnv.Location w3 = _env.makeLocation(49, 0); 1133 ASquareEnv.Location w4 = _env.makeLocation(0, 0); 1134 w = w.getNeighbor(_env.makeDirection(0, -1)); 1135 assertEquals(true, w.same(w1)); 1136 w = w.getNeighbor(_env.makeDirection(-1, 0)); 1137 assertEquals(true, w.same(w2)); 1138 w = w.getNeighbor(_env.makeDirection(0, 1)); 1139 assertEquals(true, w.same(w3)); 1140 w = w.getNeighbor(_env.makeDirection(1, 0)); 1141 assertEquals(true, w.same(w4)); 1142 } 1143 } 1144 }