1 /** 2 * Copyright (C) 2006 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.inject; 18 19 20 import junit.framework.TestCase; 21 22 import java.util.concurrent.CountDownLatch; 23 import java.util.concurrent.atomic.AtomicReference; 24 25 /** 26 * @author jessewilson (at) google.com (Jesse Wilson) 27 */ 28 29 public class BindingOrderTest extends TestCase { 30 31 public void testBindingOutOfOrder() { 32 Guice.createInjector(new AbstractModule() { 33 protected void configure() { 34 bind(BoundFirst.class); 35 bind(BoundSecond.class).to(BoundSecondImpl.class); 36 } 37 }); 38 } 39 40 public static class BoundFirst { 41 @Inject public BoundFirst(BoundSecond boundSecond) { } 42 } 43 44 interface BoundSecond { } 45 static class BoundSecondImpl implements BoundSecond { } 46 47 public void testBindingOrderAndScopes() { 48 Injector injector = Guice.createInjector(new AbstractModule() { 49 protected void configure() { 50 bind(A.class); 51 bind(B.class).asEagerSingleton(); 52 } 53 }); 54 55 assertSame(injector.getInstance(A.class).b, injector.getInstance(A.class).b); 56 } 57 58 public void testBindingWithExtraThreads() throws InterruptedException { 59 final CountDownLatch ready = new CountDownLatch(1); 60 final CountDownLatch done = new CountDownLatch(1); 61 final AtomicReference<B> ref = new AtomicReference<B>(); 62 63 final Object createsAThread = new Object() { 64 @Inject void createAnotherThread(final Injector injector) { 65 new Thread() { 66 public void run() { 67 ready.countDown(); 68 A a = injector.getInstance(A.class); 69 ref.set(a.b); 70 done.countDown(); 71 } 72 }.start(); 73 74 // to encourage collisions, we make sure the other thread is running before returning 75 try { 76 ready.await(); 77 } catch (InterruptedException e) { 78 throw new RuntimeException(e); 79 } 80 } 81 }; 82 83 Guice.createInjector(new AbstractModule() { 84 protected void configure() { 85 requestInjection(createsAThread); 86 bind(A.class).toInstance(new A()); 87 } 88 }); 89 90 done.await(); 91 assertNotNull(ref.get()); 92 } 93 94 static class A { 95 @Inject B b; 96 } 97 98 static class B { } 99 } 100