1 7 package tests.jfun.yan; 8 9 import junit.framework.TestCase; 10 import junit.framework.TestSuite; 11 12 import java.beans.IntrospectionException ; 13 import java.io.Serializable ; 14 import java.util.ArrayList ; 15 import java.util.HashMap ; 16 import java.util.LinkedList ; 17 import java.util.List ; 18 import java.util.Collection ; 19 20 import tests.jfun.models.BankAccount; 21 import tests.jfun.models.BankAccountDao; 22 import tests.jfun.models.DumbBankAccountDao; 23 import tests.jfun.models.DumbMyBeanDao; 24 import tests.jfun.models.InjectingDecorator; 25 import tests.jfun.models.Injector; 26 import tests.jfun.models.MyBean; 27 import tests.jfun.models.MyBeanDao; 28 import tests.jfun.models.Named; 29 import tests.jfun.models.Struct; 30 import tests.jfun.yan.tck.BaseContainerTestCase; 31 import tests.jfun.yan.testmodel.*; 32 import jfun.yan.*; 33 import jfun.yan.containers.DefaultContainer; 34 import jfun.yan.containers.ProxyContainer; 35 import jfun.yan.etc.InjectorHelper; 36 import jfun.yan.factory.GlobalScope; 37 import jfun.yan.factory.ThreadLocalScope; 38 import jfun.yan.lifecycle.DefaultLifecycleManager; 39 import jfun.yan.lifecycle.Lifecycle; 40 46 public class DefaultContainerTestCase 47 extends BaseNonSingletonContainerTestCase { 48 public static void main(String [] args){ 50 try{ 51 Utils.runTest(suite()); 52 } 53 catch(YanException e){ 54 e.printResolutionTrace(System.err); 55 throw e; 56 } 57 } 58 private static TestSuite suite(){ 59 return new TestSuite(DefaultContainerTestCase.class); 60 } 61 public void testBasicInstantiationAndContainment() 62 { 63 Container pico = 64 createPicoContainerWithTouchableAndDependsOnTouchable(); 65 66 assertTrue("Component should be instance of Touchable", 67 Touchable.class.isAssignableFrom( 68 pico.getComponentOfType(Touchable.class) 69 .getType())); 70 } 71 83 94 100 101 public void TodotestUnambiguouSelfDependency() { 102 Container pico = new DefaultContainer(); 103 pico.registerConstructor(SimpleTouchable.class); 104 pico.registerConstructor(DecoratedTouchable.class); 105 Touchable t = (Touchable) pico.getInstance(DecoratedTouchable.class); 106 assertNotNull(t); 107 } 108 109 public static class Thingie { 110 public Thingie(List c) { 111 assertNotNull(c); 112 } 113 } 114 115 public void testThangCanBeInstantiatedWithArrayList() { 116 Container pico = new DefaultContainer(); 117 pico.registerConstructor(Thingie.class); 118 pico.registerConstructor(ArrayList .class, new Class [0]); 119 assertNotNull(pico.getInstance(Thingie.class)); 120 } 121 122 public void getComponentsOfTypeReturnsModifiableList() { 123 Container pico = new DefaultContainer(); 124 pico.registerConstructor(Thingie.class); 125 pico.getComponentsOfType(Thingie.class).add((Component)Components.value(null)); 126 } 127 128 129 public static class Service { 130 } 131 132 public static class TransientComponent { 133 private Service service; 134 135 public TransientComponent(Service service) { 136 this.service = service; 137 } 138 } 139 140 public void testDefaultPicoContainerReturnsNewInstanceForEachCallWhenUsingTransientComponentAdapter() { 141 DefaultContainer picoContainer = new DefaultContainer(); 142 picoContainer.registerConstructor(Service.class); 143 picoContainer.registerComponent(TransientComponent.class, 144 Components.ctor(TransientComponent.class)); 145 TransientComponent c1 = (TransientComponent) picoContainer.getInstance(TransientComponent.class); 146 TransientComponent c2 = (TransientComponent) picoContainer.getInstance(TransientComponent.class); 147 assertNotSame(c1, c2); 148 assertSame(c1.service, c2.service); 149 } 150 151 public static class DependsOnCollection { 152 public DependsOnCollection(Collection c) { 153 } 154 } 155 156 public void testShouldProvideInfoAboutDependingWhenAmbiguityHappens() { 157 Container pico = new DefaultContainer(); 158 pico.registerValue(new ArrayList ()); 159 pico.registerValue(new LinkedList ()); 160 pico.registerConstructor(DependsOnCollection.class); 161 try { 162 pico.getInstanceOfType(DependsOnCollection.class); 163 fail(); 164 } catch (AmbiguousComponentResolutionException expected) { 165 } 166 } 167 protected Container getContainerImpl(){ 168 return new DefaultContainer(); 169 } 170 205 public void testEachPersonGetsNewId() 206 throws Exception { 207 final Container yan = getContainerWithPerson(); 208 final Person p1 = (Person)yan.getInstance(Person.class); 209 final Person p2 = (Person)yan.getInstance(Person.class); 210 assertEquals(1, p1.getId()); 211 assertEquals(2, p2.getId()); 212 213 } 214 215 public static class Account{ 216 private PersonBean owner; 217 private PersonBean ceo; 218 private PersonBean cto; 219 220 public Account(PersonBean owner, PersonBean ceo, PersonBean cto) { 221 super(); 222 this.owner = owner; 223 this.ceo = ceo; 224 this.cto = cto; 225 } 226 227 public PersonBean getCeo() { 228 return ceo; 229 } 230 public void setCeo(PersonBean ceo) { 231 this.ceo = ceo; 232 } 233 public PersonBean getCto() { 234 return cto; 235 } 236 public void setCto(PersonBean cto) { 237 this.cto = cto; 238 } 239 public PersonBean getOwner() { 240 return owner; 241 } 242 public void setOwner(PersonBean owner) { 243 this.owner = owner; 244 } 245 } 246 public void testUseTypeAndSingleton(){ 247 final Container yan = createYanContainer(); 248 yan.registerComponent("singletonPerson", 249 Components.useType(PersonBean.class).singleton()); 250 yan.registerComponent(Components.ctor(PersonBean.class, 251 new Class []{String .class})); 252 yan.registerValue("Ben"); 253 yan.registerComponent(Components.ctor(Account.class) 254 .withArgument(0, Components.useKey("singletonPerson")) 255 .withArgument(1, Components.useKey("singletonPerson"))); 256 final Account acc1 = (Account)yan.getInstanceOfType(Account.class); 257 assertSame(acc1.getOwner(), acc1.getCeo()); 258 assertNotSame(acc1.getCeo(), acc1.getCto()); 259 assertEquals("Ben", acc1.getOwner().getName()); 260 } 261 public void testVerify1() 262 throws Throwable { 263 final Container yan = this.createYanContainer(); 264 final DefaultLifecycleManager man = new DefaultLifecycleManager(); 265 266 Component mybean = Components.bean(MyBean.class, new String []{"1","short"}); 267 mybean = man.newLifecycle() 268 .verifier("verify") 269 .manage(mybean); 270 yan.registerValue(new Short ((short)1)); 271 yan.registerValue(Boolean.valueOf(true)); 272 yan.registerComponent("target", mybean); 273 MyBean bean = (MyBean)yan.getInstance("target"); 274 assertTrue(bean.is1()); 275 try{ 276 man.verify(); 277 } 278 catch(IllegalStateException e){ 279 return; 280 } 281 fail("should have failed with illegal state"); 282 } 283 public void testVerify2() 284 throws Throwable { 285 final Container yan = this.createYanContainer(); 286 Component mybean = Components.bean(MyBean.class, new String []{"1","short"}) 287 .followedBy(new Binder(){ 288 public Creator bind(Object obj){ 289 return Components.method(obj, "verify"); 290 } 291 }); 292 yan.registerValue(new Short ((short)1)); 293 yan.registerValue(Boolean.valueOf(true)); 294 yan.registerComponent("target", mybean); 295 try{ 296 MyBean bean = (MyBean)yan.getInstance("target"); 297 } 298 catch(ComponentInstantiationException e){ 299 return; 300 } 301 fail("should have failed in verification"); 302 303 304 } 305 public void testField()throws Throwable { 306 final Component c1 = Components.static_field(Struct.class, "default_instance"); 307 final Component c2 = c1.field("name"); 308 assertResult(c2, "default"); 309 assertResult(c2.withArgument(0, Components.value("x")), "default"); 310 assertResult(c2.singleton(), "default"); 311 final Component c3 = Components.ctor(Struct.class) 312 .withArguments(new Component[]{Components.value(1), Components.value("hello"), Components.value(10)}); 313 assertResult(c3.field("name"), "hello"); 314 assertResult(c3.field("id"), new Integer (1)); 315 assertResult(c3.field("age"), new Integer (10)); 316 class Tmp{ 317 Component customize(Component c){ 318 return c.withArgument(1, Components.value("a")); 319 } 320 } 321 Tmp tmp = new Tmp(); 322 assertResult(tmp.customize(c3.field("name")), "hello"); 323 324 assertError(c3.cast(null).field("age1"), IllegalArgumentException .class, Struct.class.getName()+".age1 not found."); 325 final Component getname = Components.fun( 326 Functions.instance_field(Struct.class, "name")) 327 .withArgument(0, Components.static_field(Struct.class, "default_instance")); 328 assertResult(getname, "default"); 329 } 330 public void testVerifyBind(){ 331 final Component str = Components.value("abc"); 332 final Container yan = createYanContainer(); 333 assertEquals(int.class, yan.verifyComponent(str.method("length"))); 334 assertEquals(Object .class, yan.verifyComponent(str.bind(new Binder(){ 335 public Creator bind(Object obj){ 336 return Components.value(obj.toString().length()); 337 } 338 }))); 339 } 340 341 public static Component getBeanInjector(Object obj) 342 throws IntrospectionException { 343 return Components.value(obj).bean().optionalProperties(); 344 } 345 public void testInstantiatorAndFactory(){ 346 Container yan = createYanContainer(); 347 final Component injector = Components.method(this, "getBeanInjector"); 348 349 yan.registerComponent("target", 350 injector.bind(Monad.instantiator()) 351 .factory(Injector.class) 352 ); 353 yan.registerValue("apple"); 354 MyBean mbean = new MyBean(); 355 Injector inj = (Injector)yan.getInstance("target"); 356 inj.inject(mbean); 357 assertEquals("apple", mbean.getName()); 358 } 359 public void testInjectorHelper(){ 360 Container yan = createYanContainer(); 361 final Binder injection = new Binder(){ 362 public Creator bind(Object obj) 363 throws IntrospectionException { 364 return getBeanInjector(obj); 365 } 366 }; 367 368 369 yan.registerComponent("target", 370 new InjectorHelper() 371 .getInjectorComponent(Injector.class, injection) 372 ); 373 yan.registerValue("apple"); 374 MyBean mbean = new MyBean(); 375 Injector inj = (Injector)yan.getInstance("target"); 376 inj.inject(mbean); 377 assertEquals("apple", mbean.getName()); 378 } 379 380 public void testInjectingDaoDecorator(){ 381 Container yan = createYanContainer(); 382 yan.registerValue("apple"); 383 final Binder injection = new Binder(){ 384 public Creator bind(Object obj) 385 throws IntrospectionException { 386 return getBeanInjector(obj); 387 } 388 }; 389 Component injector = new InjectorHelper() 390 .getInjectorComponent(Injector.class, injection); 391 Component dumb_dao = Components.ctor(DumbMyBeanDao.class); 392 Component dao = Components.static_method(InjectingDecorator.class, 393 "getInjectingDecorator", new Class []{Object .class, Class .class, Injector.class}) 394 .withArguments(new Component[]{dumb_dao, Components.value(MyBean.class), injector}); 395 396 yan.registerComponent("dao", dao); 397 MyBeanDao mdao = (MyBeanDao)yan.getInstance("dao"); 398 assertEquals(mdao, mdao); 399 Named mbean = mdao.getBeanById(1); 400 assertEquals("apple", mbean.getName()); 401 } 402 public void testReturningInjectedProxy(){ 403 Container yan = createYanContainer(); 404 yan.registerValue("apple"); 405 final Binder injection = new Binder(){ 406 public Creator bind(Object obj) 407 throws IntrospectionException { 408 return getBeanInjector(obj); 409 } 410 }; 411 Component dumb_dao = Components.ctor(DumbMyBeanDao.class); 412 final Component dao = new InjectorHelper().getProxyComponentReturningInjected(MyBeanDao.class, 413 dumb_dao, MyBean.class, injection); 414 yan.registerComponent("dao", dao); 415 MyBeanDao mdao = (MyBeanDao)yan.getInstance("dao"); 416 assertEquals(mdao, mdao); 417 Named mbean = mdao.getBeanById(1); 418 assertEquals("apple", mbean.getName()); 419 } 420 public void testNestedInjectionProxy(){ 421 Container yan = createYanContainer(); 422 yan.registerValue("apple"); 423 yan.registerConstructor("BankAccount", BankAccount.class, null); 424 final Binder bean_injection = new Binder(){ 425 public Creator bind(Object obj) 426 throws IntrospectionException { 427 return getBeanInjector(obj); 428 } 429 }; 430 final Binder account_injection = new Binder(){ 431 public Creator bind(Object obj) 432 throws IntrospectionException { 433 return Components.value(obj).bean() 434 ; 436 } 437 }; 438 Component dumb_dao = Components.ctor(DumbBankAccountDao.class); 439 InjectorHelper helper = new InjectorHelper(); 440 Component dao = helper.getProxyComponentReturningInjected(BankAccountDao.class, 441 dumb_dao, MyBean.class, bean_injection); 442 dao = helper.getProxyComponentReturningInjected(BankAccountDao.class, dao, 443 BankAccount.class, account_injection); 444 yan.registerComponent("dao", dao); 445 yan.registerValue(new Integer (10)); 446 yan.registerValue(new char[]{'a','b'}); 447 BankAccountDao mdao = (BankAccountDao)yan.getInstance("dao"); 448 assertEquals(mdao, mdao); 449 MyBean mbean = mdao.getMyBean(1); 450 assertEquals("apple", mbean.getName()); 451 BankAccount account = mdao.getAccount("a"); 452 assertEquals('a', account.getChar(0)); 453 assertEquals('b', account.getChar(1)); 454 assertEquals("apple", account.getId()); 455 assertEquals(10, account.getBalance()); 456 } 457 public static class A{ 458 private B b; 459 private String name; 460 public B getB() { 461 return b; 462 } 463 public void setB(B b) { 464 this.b = b; 465 } 466 public String getName() { 467 return name; 468 } 469 public void setName(String name) { 470 this.name = name; 471 } 472 } 473 public static class B{ 474 private A a; 475 private int id; 476 public A getA() { 477 return a; 478 } 479 public void setA(A a) { 480 this.a = a; 481 } 482 public int getId() { 483 return id; 484 } 485 public void setId(int id) { 486 this.id = id; 487 } 488 } 489 public void testMutualRecursionOnSingletonBean() 490 throws IntrospectionException { 491 Component a = Components.bean(A.class).singleton(); 492 Component b = Components.bean(B.class).singleton(); 493 verifyABMutualRecursionForSingleton(a, b); 494 } 495 public void testMutualRecursionOnSingletonThenBean() 496 throws IntrospectionException { 497 Component a = Components.ctor(A.class).singleton().bean(); 498 Component b = Components.ctor(B.class).singleton().bean(); 499 try{ 500 verifyABMutualRecursionForSingleton(a, b); 501 fail("should have failed with cyclic dependency"); 502 } 503 catch(CyclicDependencyException e){} 504 } 505 public void testManualMutualRecursionOnSingletonBean() 506 throws IntrospectionException { 507 Component a = Components.bean(A.class) 508 .withProperty("b", Components.useKey("b")).singleton(); 509 Component b = Components.bean(B.class) 510 .withProperty("a", Components.useKey("a")).singleton(); 511 verifyABMutualRecursionForSingleton(a, b); 512 } 513 public void testManualMutualRecursionOnSemiSingletonBean() 514 throws IntrospectionException { 515 Component a = Components.bean(A.class) 516 .singleton().withProperty("b", Components.useKey("b")); 517 Component b = Components.bean(B.class) 518 .singleton().withProperty("a", Components.useKey("a")); 519 verifyABMutualRecursionForSingleton(a, b); 520 } 521 public void testMutualRecursionOnThreadLocalSingletonBean() 522 throws IntrospectionException { 523 Component a = Components.bean(A.class).singleton(new ThreadLocalScope()); 524 Component b = Components.bean(B.class).singleton(new ThreadLocalScope()); 525 verifyABMutualRecursionForSingleton(a, b); 526 } 527 public void testMutualRecursionOnScopedSingletonBean() 528 throws IntrospectionException { 529 Component a = Components.bean(A.class).singleton(new GlobalScope()); 530 Component b = Components.bean(B.class).singleton(new ThreadLocalScope()); 531 verifyABMutualRecursionForSingleton(a, b); 532 } 533 public void testManualMutualRecursionOnScopedSingletonBean() 534 throws IntrospectionException { 535 Component a = Components.bean(A.class) 536 .withProperty("b", Components.useKey("b")).singleton(new GlobalScope()); 537 Component b = Components.bean(B.class) 538 .withProperty("a", Components.useKey("a")).singleton(new ThreadLocalScope()); 539 verifyABMutualRecursionForSingleton(a, b); 540 } 541 public void testManualMutualRecursionOnScopedSemiSingletonBean() 542 throws IntrospectionException { 543 Component a = Components.bean(A.class) 544 .singleton(new GlobalScope()).withProperty("b", Components.useKey("b")); 545 Component b = Components.bean(B.class) 546 .singleton(new ThreadLocalScope()).withProperty("a", Components.useKey("a")); 547 verifyABMutualRecursionForSingleton(a, b); 548 } 549 public void testMutualRecursionOnScopedSingletonSingletonBean() 550 throws IntrospectionException { 551 Component a = Components.bean(A.class).singleton(new GlobalScope()).singleton(); 552 Component b = Components.bean(B.class).singleton(new ThreadLocalScope()).singleton(); 553 verifyABMutualRecursionForSingleton(a, b); 554 } 555 public void testMutualRecursionOnSingletonScopedSingletonBean() 556 throws IntrospectionException { 557 Component a = Components.bean(A.class).singleton().singleton(new GlobalScope()); 558 Component b = Components.bean(B.class).singleton().singleton(new ThreadLocalScope()).singleton(); 559 verifyABMutualRecursionForSingleton(a, b); 560 } 561 private void verifyABMutualRecursionForSingleton(Component ac, Component bc){ 562 final Container yan = createYanContainer(); 563 yan.registerValue("Tom"); 564 yan.registerValue(new Integer (10)); 565 yan.registerComponent("a", ac); 566 yan.registerComponent("b", bc); 567 A a = (A)yan.getInstance("a"); 568 B b = (B)yan.getInstance("b"); 569 assertEquals("Tom", a.getName()); 570 assertEquals(10, b.getId()); 571 assertSame(a.getB(), b); 572 assertSame(a, b.getA()); 573 assertSame(a, yan.getInstance("a")); 574 assertSame(b, yan.getInstance("b")); 575 } 576 } 577 | Popular Tags |