1 10 package tests.jfun.yan.tck; 11 12 import junit.framework.Assert; 13 import junit.framework.AssertionFailedError; 14 import junit.framework.TestCase; 15 import junit.framework.TestSuite; 16 import jfun.yan.*; 17 import jfun.yan.containers.DefaultContainer; 18 import jfun.yan.factory.GlobalScope; 19 import jfun.yan.factory.ThreadLocalScope; 20 import jfun.yan.util.AmbiguityException; 21 import jfun.yan.util.ReflectionUtil; 22 23 import java.io.ByteArrayInputStream ; 24 import java.io.ByteArrayOutputStream ; 25 import java.io.IOException ; 26 import java.io.ObjectInputStream ; 27 import java.io.ObjectOutputStream ; 28 import java.lang.reflect.Constructor ; 29 import java.math.BigDecimal ; 30 import java.util.ArrayList ; 31 import java.util.Collection ; 32 import java.util.HashMap ; 33 import java.util.HashSet ; 34 import java.util.Iterator ; 35 import java.util.LinkedList ; 36 import java.util.List ; 37 import java.util.Set ; 38 39 40 45 public abstract class BaseComponentTestCase 46 extends TestCase { 47 public static void main(String [] args){ 48 tests.jfun.yan.Utils.runTest(suite()); 49 } 50 private static TestSuite suite(){ 51 return new TestSuite(BaseComponentTestCase.class); 52 } 53 public static int SERIALIZABLE = 1; 54 public static int VERIFYING = 2; 55 public static int INSTANTIATING = 4; 56 public static int RESOLVING = 8; 57 58 59 protected int getComponentAdapterNature() { 60 return SERIALIZABLE | VERIFYING | INSTANTIATING | RESOLVING; 61 } 62 67 71 77 protected abstract Component prepDEF_verifyWithoutDependencyWorks(Container picoContainer); 78 79 final public void testDEF_verifyWithoutDependencyWorks() { 80 final Container yan = new DefaultContainer(); 81 final Component component = prepDEF_verifyWithoutDependencyWorks(yan); 82 verify(component, yan); 85 } 86 87 93 protected abstract Component prepDEF_verifyDoesNotInstantiate(Container yan); 94 95 final public void testDEF_verifyDoesNotInstantiate() { 96 final Container yan = new DefaultContainer(); 97 final Component component = prepDEF_verifyDoesNotInstantiate(yan); 98 final Component notInstantiatablecomponentAdapter = 100 new NotInstantiatableComponentAdapter(component); 101 final Container wrappedPicoContainer = wrapComponentInstances( 102 NotInstantiatableComponentAdapter.class, yan, null); 103 verify(notInstantiatablecomponentAdapter, wrappedPicoContainer); 104 107 } 108 109 110 111 115 121 protected Component prepSER_isSerializable(Container yan) { 122 throw new AssertionFailedError("You have to overwrite this method for a useful test"); 123 } 124 public static final class TestTransient implements java.io.Serializable { 125 private transient final String s = new String ("abc"); 126 127 public String getS() { 128 return s; 129 } 130 } 131 public static void testTransient() 132 throws Exception { 133 final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream (); 134 final ObjectOutputStream outputStream = new ObjectOutputStream (byteArrayOutputStream); 135 final TestTransient tt = new TestTransient(); 136 assertEquals("abc", tt.getS()); 137 outputStream.writeObject(tt); 138 final ObjectInputStream inputStream = new ObjectInputStream (new ByteArrayInputStream (byteArrayOutputStream.toByteArray())); 139 final TestTransient tt2 = (TestTransient)inputStream.readObject(); 140 assertNull(tt2.getS()); 141 } 142 private void testSerializable(Component component, Container yan) 143 throws IOException , ClassNotFoundException { 144 145 final Object instance = create(component, yan); 147 assertNotNull(instance); 148 final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream (); 149 final ObjectOutputStream outputStream = new ObjectOutputStream (byteArrayOutputStream); 150 outputStream.writeObject(component); 151 outputStream.close(); 152 final ObjectInputStream inputStream = new ObjectInputStream (new ByteArrayInputStream (byteArrayOutputStream.toByteArray())); 153 final Component serializedComponentAdapter = (Component) inputStream.readObject(); 154 inputStream.close(); 155 assertEquals(component.getType(), serializedComponentAdapter.getType()); 157 final Object instanceAfterSerialization = create(serializedComponentAdapter, yan); 158 assertNotNull(instanceAfterSerialization); 159 assertSame(instance.getClass(), instanceAfterSerialization.getClass()); 161 } 164 final public void testSER_isSerializable() 165 throws IOException , ClassNotFoundException { 166 185 final Container yan = new DefaultContainer(); 186 testSerializable(prepSER_isSerializable(yan), yan); 187 testSerializable(Components.value("hello"), yan); 188 testSerializable(Components.ctor(ArrayList .class, null), yan); 189 testSerializable(Components.ctor(ArrayList .class, null), yan); 190 testSerializable(Components.method(this, "greet").withArgument(0, Components.value("Tom")).singleton().proxy(), yan); 191 testSerializable(Components.method(this, "greet").withArgument(0, Components.value("Tom")).singleton(new GlobalScope()).proxy(), yan); 192 testSerializable(Components.method(this, "greet").withArgument(0, Components.value("Tom")).singleton(new ThreadLocalScope()).proxy(), yan); 193 } 194 public static String greet(String name){ 195 return "hello " +name; 196 } 197 203 protected Component prepSER_isXStreamSerializable(Container yan) { 204 throw new AssertionFailedError("You have to overwrite this method for a useful test"); 205 } 206 207 208 212 219 protected Component prepVER_verificationFails(Container yan) { 220 throw new AssertionFailedError("You have to overwrite this method for a useful test"); 221 } 222 223 final public void testVER_verificationFails() { 224 if ((getComponentAdapterNature() & VERIFYING) > 0) { 225 final Container yan = new DefaultContainer(); 226 final Component component = prepVER_verificationFails(yan); 227 try { 229 yan.verifyComponent(component); 230 fail("YanException expected"); 231 } catch (YanException e) { 232 } catch (Exception e) { 233 fail("YanException expected"); 234 } 235 try { 236 create(component, yan); fail("PicoInitializationException or YanException expected"); 238 } catch (ComponentInstantiationException e) { 239 } catch (YanException e) { 240 } catch (Exception e) { 241 fail("PicoInitializationException or YanException expected"); 242 } 243 } 244 } 245 246 250 256 protected Component prepINS_createsNewInstances(Container yan) { 257 throw new AssertionFailedError("You have to overwrite this method for a useful test"); 258 } 259 private static Object create(Component cc, ComponentMap c){ 260 return cc.create(c.getDependencyOfType(cc.getType(),c)); 261 } 262 private static Class verify(Component cc, ComponentMap c){ 263 return cc.verify(c.getDependencyOfType(cc.getType(),c)); 264 } 265 final public void testINS_createsNewInstances() { 266 if ((getComponentAdapterNature() & INSTANTIATING) > 0) { 267 final Container yan = new DefaultContainer(); 268 final Component component = prepINS_createsNewInstances(yan); 269 final Object instance = create(component, yan); 271 assertNotNull(instance); 272 assertNotSame(instance, create(component, yan)); 273 assertSame(instance.getClass(), create(component, yan).getClass()); 274 } 275 } 276 277 283 protected abstract Component prepINS_errorIsRethrown(Container yan); 284 285 final public void testINS_errorIsRethrown() { 286 if ((getComponentAdapterNature() & INSTANTIATING) > 0) { 287 final Container yan = new DefaultContainer(); 288 289 291 final Component component = prepINS_errorIsRethrown(yan); 292 293 try{ 294 create(component, yan); 295 fail("Thrown Error excpected"); 296 } 297 catch(Error e){ 298 assertEquals("test", e.getMessage()); 299 } 300 301 } 302 } 303 304 311 protected Component prepINS_runtimeExceptionIsRethrown(Container yan) { 312 throw new AssertionFailedError("You have to overwrite this method for a useful test"); 313 } 314 315 final public void testINS_runtimeExceptionIsRethrown() { 316 if ((getComponentAdapterNature() & INSTANTIATING) > 0) { 317 final Container yan = new DefaultContainer(); 318 final Component component = prepINS_runtimeExceptionIsRethrown(yan); 319 try { 321 create(component, yan); 322 fail("Thrown RuntimeException excpected"); 323 } catch (final ComponentInstantiationException e) { 324 assertEquals("test", e.getCause().getMessage()); 325 } 326 } 327 } 328 329 336 protected Component prepINS_normalExceptionIsRethrownInsidePicoInvocationTargetInitializationException( 337 Container yan) { 338 throw new AssertionFailedError("You have to overwrite this method for a useful test"); 339 } 340 341 final public void testINS_normalExceptionIsRethrownInsidePicoInvocationTargetInitializationException() { 342 if ((getComponentAdapterNature() & INSTANTIATING) > 0) { 343 final Container yan = new DefaultContainer(); 344 final Component component = prepINS_normalExceptionIsRethrownInsidePicoInvocationTargetInitializationException(yan); 345 try { 347 create(component, yan); 348 fail("Thrown PicoInvocationTargetInitializationException excpected"); 349 } catch (final ComponentInstantiationException e) { 350 assertTrue(e.getMessage().endsWith("test")); 351 assertTrue(e.getCause() instanceof Exception ); 352 } 353 } 354 } 355 356 360 367 protected abstract Component prepRES_dependenciesAreResolved(Container yan); 368 369 final public void testRES_dependenciesAreResolved() { 370 if ((getComponentAdapterNature() & RESOLVING) > 0) { 371 final List dependencies = new LinkedList (); 372 final Object [] wrapperDependencies = new Object []{dependencies}; 373 final Container yan = new DefaultContainer(); 374 final Component component = prepRES_dependenciesAreResolved(yan); 375 assertFalse(yan.getComponents().contains(component)); 377 final Container wrappedPicoContainer = wrapComponentInstances( 378 CollectingComponentAdapter.class, yan, wrapperDependencies); 379 final Object instance = create(component,wrappedPicoContainer); 380 assertNotNull(instance); 381 assertTrue(dependencies.size() > 0); 382 } 383 } 384 385 392 protected Component prepRES_failingVerificationWithCyclicDependencyException(Container yan) { 393 throw new AssertionFailedError("You have to overwrite this method for a useful test"); 394 } 395 416 417 424 450 451 477 static public class NotInstantiatableComponentAdapter 478 extends DelegatingComponent { 479 public NotInstantiatableComponentAdapter(final Component delegate) { 480 super(delegate); 481 } 482 483 public Object create(final Dependency pp) { 484 Assert.fail("Not instantiatable"); 485 return null; 486 } 487 } 488 static public class CollectingComponentAdapter 489 extends DelegatingComponent { 490 final List list; 491 492 public CollectingComponentAdapter(final Component delegate, final List list) { 493 super(delegate); 494 this.list = list; 495 } 496 497 public Object create(final Dependency pp) { 498 final Object result = 499 BaseComponentTestCase.create(getDelegateTarget(), pp.getComponentMap()); 500 list.add(result); 501 return result; 502 } 503 } 504 526 final protected Container wrapComponentInstances( 527 final Class decoratingComponentAdapterClass, final Container yan, final Object [] wrapperDependencies) { 528 assertTrue(DelegatingComponent.class.isAssignableFrom(decoratingComponentAdapterClass)); 529 final Container mutablePicoContainer = new DefaultContainer(); 530 final int size = (wrapperDependencies != null ? wrapperDependencies.length : 0) + 1; 531 final Collection allComponentAdapters = yan.getComponents(); 532 for (final Iterator iter = allComponentAdapters.iterator(); iter.hasNext();) { 533 final Creator[] params = new Creator[size]; 535 params[0] = Components.value(iter.next()).guard().singleton(); 536 for (int i = 1; i < params.length; i++) { 537 Component tmp = Components.value(wrapperDependencies[i - 1]); 538 switch(i%3){ case 0: 540 tmp = tmp.singleton(new GlobalScope()); 541 break; 542 case 1: 543 tmp = tmp.singleton(new ThreadLocalScope()); 544 case 2: 545 tmp = tmp.singleton(); 546 } 547 params[i] = tmp.guard(); 548 } 549 Component cc = Components.ctor(decoratingComponentAdapterClass) 550 .withArguments(params); 551 final Container instantiatingPicoContainer = new DefaultContainer(); 552 instantiatingPicoContainer.registerComponent("decorator", 553 cc); 554 mutablePicoContainer.registerComponent( 555 (Component) instantiatingPicoContainer.getInstance("decorator")); 556 } 557 return mutablePicoContainer; 558 } 559 static class Dummy{ 560 public void mtd1(int i){} 561 public void mtd2(){} 562 public void mtd2(int i){} 563 static void static1(){} 564 public static void static1(int i){} 565 public static void static2(){} 566 public static void static2(int i){} 567 } 568 public static class PublicDummy{ 569 PublicDummy(int i){} 570 void mtd1(){} 571 public void mtd1(int i){} 572 public void mtd2(){} 573 public void mtd2(int i){} 574 static void static1(){} 575 public static void static1(int i){} 576 public static void static2(){} 577 public static void static2(int i){} 578 public void mtd0(){} 579 public static void mtd0(int i){} 580 } 581 public static class AmbiguousDummy{ 582 public AmbiguousDummy(){} 583 public AmbiguousDummy(int i){} 584 } 585 public void testInvalidComponents(){ 586 try{ 587 Components.ctor(Dummy.class); 588 fail("should prevent non-public type"); 589 } 590 catch(IllegalArgumentException e){ 591 assertTrue(e.getMessage().startsWith("constructor not found")); 592 } 593 try{ 594 Components.ctor(PublicDummy.class); 595 fail("should prevent non-public constructor"); 596 } 597 catch(IllegalArgumentException e){ 598 assertTrue(e.getMessage().startsWith("constructor not found")); 599 } 600 try{ 601 Components.ctor(AmbiguousDummy.class); 602 fail("should prevent ambiguous constructors"); 603 } 604 catch(IllegalArgumentException e){ 605 assertTrue(e.getMessage().endsWith("more than one qualified constructors")); 606 } 607 try{ 608 Components.method(new PublicDummy(3), "mtd2"); 609 } 610 catch(AmbiguityException e){ 611 assertTrue(e.getMessage().endsWith("has more than one qualified methods named mtd2")); 612 } 614 try{ 615 Components.method(new PublicDummy(3), "mtdx"); 616 } 617 catch(IllegalArgumentException e){ 618 assertTrue(e.getMessage().startsWith("method")); 619 assertTrue(e.getMessage().endsWith("not found")); 620 } 622 assertNotNull(Components.static_method(PublicDummy.class, "mtd0")); 623 try{ 624 Components.method(new PublicDummy(3), "mtd0"); 625 fail("should prevent constructor resolution error"); 626 } 627 catch(AmbiguityException e){ 628 assertTrue(e.getMessage().endsWith("has more than one qualified methods named mtd0")); 629 } 630 try{ 631 Components.ctor(AmbiguousDummy.class, new Class []{String .class}); 632 fail("should prevent constructor resolution error"); 633 } 634 catch(IllegalArgumentException e){ 635 assertTrue(e.getMessage().startsWith("constructor not found")); 636 } 637 Components.static_method(PublicDummy.class, "static1"); 638 Components.method(new PublicDummy(1), "static1"); 639 Components.method(new PublicDummy(2), "mtd1"); 640 try{ 641 Components.static_method(Dummy.class, "static1", null); 642 fail("should prevent no-such-method"); 643 } 644 catch(IllegalArgumentException e){ 645 assertTrue(e.getMessage().endsWith("Dummy.static1() not found.")); 646 } 647 try{ 648 Components.static_method(PublicDummy.class, "mtd2", null); 649 fail("should prevent non-static error"); 650 } 651 catch(IllegalArgumentException e){ 652 assertTrue(e.getMessage().endsWith("is not static")); 654 } 655 try{ 656 Components.static_method(Dummy.class, "mtd1"); 657 fail("should prevent non-static error"); 658 } 659 catch(IllegalArgumentException e){ 660 assertTrue(e.getMessage().startsWith("static method named mtd1 ")); 662 assertTrue(e.getMessage().indexOf("cannot be found")>0); 663 } 664 } 665 public void testComponentAsObject(){ 666 final Component c = Components.static_method(java.text.DateFormat .class, 667 "getDateInstance", null); 668 assertEquals(c, c); 669 final HashMap map = new HashMap (); 670 map.put(c, c); 671 assertSame(c, map.get(c)); 672 assertTrue(c.toString().endsWith("getDateInstance()")); 673 } 674 public void testSubsumptionAndCasting(){ 675 Integer seed = new Integer (1); 676 final Component c0 = 677 Components.value(seed) 678 .subsume(Integer .class) 679 .subsume(int.class); 680 681 final Component c1 = 682 Components.value(null) 683 .subsume(Integer .class) 684 .subsume(int.class); 685 try{ 686 c1.subsume(Number .class) 687 .subsume(int.class); 688 fail("should have failed subsumption"); 689 } 690 catch(IllegalArgumentException e){ 691 assertEquals("java.lang.Number is not a subtype of int", e.getMessage()); 692 } 693 final Component c2 = 694 Components.cast(Components.cast(c1.cast(Number .class), Number .class), 695 Integer .class); 696 final Component c20 = 697 Components.cast(Components.cast(c0.subsume(Number .class), Number .class), 698 Integer .class); 699 assertSame(seed, c20.create(null)); 700 final Component c3 = Components.cast(c2, int.class); 701 try{ 702 c3.create(null); 703 fail("should have failed with ClassCastException"); 704 } 705 catch(TypeMismatchException e){ 706 assertEquals("int expected, while java.lang.Object encountered.", e.getMessage()); 707 assertEquals(int.class, e.getExpectedType()); 708 assertSame(null, e.getActualType()); 709 } 710 } 711 public static class Account implements Comparable { 712 private String num; 713 private BigDecimal balance; 714 private java.util.List activities; 715 716 public java.util.List getActivities() { 717 return activities; 718 } 719 public void setActivities(java.util.List activities) { 720 this.activities = activities; 721 } 722 public BigDecimal getBalance() { 723 return balance; 724 } 725 public void setBalance(BigDecimal balance) { 726 this.balance = balance; 727 } 728 public String getNum() { 729 return num; 730 } 731 public void setNum(String num) { 732 this.num = num; 733 } 734 735 public int compareTo(Object o) { 736 return balance.compareTo((BigDecimal )o); 737 } 738 } 739 public void testProxy()throws Exception { 740 final Component cc = 741 Components.bean(Account.class, new String []{"num", "balance"}) 742 .proxy(); 743 final Component cc2 = cc.proxy(new Class []{Comparable .class}); 744 final Component cc3 = cc.proxy(new Class []{}); 745 Component cc4 = cc2.proxy(new Class []{Comparable .class}); 746 try{ 747 cc4.proxy(new Class []{Runnable .class}); 748 fail("should have failed with IllegalArgumentException"); 749 } 750 catch(IllegalArgumentException e){ 751 assertEquals("type java.lang.Runnable is not a super type of any of [interface java.lang.Comparable]", 752 e.getMessage()); 753 } 754 755 } 756 public static CharSequence getCharSequence(){ 757 return "1"; 758 } 759 public void testArray(){ 760 final Component c1 = Components.ctor(String .class, null); 761 final Component c2 = Components.ctor(StringBuffer .class, null); 762 final Component c3 = Components.method(this, "getCharSequence"); 763 final Component c4 = Components.useKey("xxx"); 764 final Component a1 = Components.array(new Component[]{}); 765 assertEquals(Object [].class, a1.getType()); 766 final Component a2 = Components.array(new Component[]{c1}); 767 assertEquals(String [].class, a2.getType()); 768 final Component a3 = Components.array(new Component[]{c1, c3}); 769 assertEquals(CharSequence [].class, a3.getType()); 770 final Component a4 = Components.array(new Component[]{c1, c3, c2}); 771 assertEquals(CharSequence [].class, a4.getType()); 772 final Component a5 = Components.array(new Component[]{c1, c2}); 773 assertEquals(Object [].class, a5.getType()); 774 final Component a6 = Components.array(new Component[]{c1, c2, c3, c4}); 775 assertEquals(Object [].class, a6.getType()); 776 } 777 } | Popular Tags |