1/**
2 * Copyright (C) 2009 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
17package com.google.inject.throwingproviders;
18
19import com.google.inject.AbstractModule;
20import com.google.inject.BindingAnnotation;
21import com.google.inject.Exposed;
22import com.google.inject.Guice;
23import com.google.inject.Injector;
24import com.google.inject.Key;
25import com.google.inject.PrivateModule;
26import com.google.inject.Provides;
27import com.google.inject.TypeLiteral;
28import com.google.inject.name.Named;
29import com.google.inject.name.Names;
30
31import junit.framework.TestCase;
32
33import java.lang.annotation.Retention;
34import java.lang.annotation.RetentionPolicy;
35import java.net.BindException;
36import java.rmi.RemoteException;
37
38/**
39 * Test methods for {@link CheckedProviderMethodsModule}.
40 */
41public class CheckedProviderMethodsModuleTest extends TestCase {
42
43  private final TypeLiteral<RpcProvider<String>> rpcProviderOfString
44      = new TypeLiteral<RpcProvider<String>>() { };
45  private final TypeLiteral<RpcProvider<Integer>> rpcProviderOfInteger
46      = new TypeLiteral<RpcProvider<Integer>>() { };
47  private final TypeLiteral<RpcProvider<Long>> rpcProviderOfLong
48      = new TypeLiteral<RpcProvider<Long>>() { };
49  private final TypeLiteral<RpcProvider<Float>> rpcProviderOfFloat
50      = new TypeLiteral<RpcProvider<Float>>() { };
51  private final TypeLiteral<RpcProvider<Pair<Double, String>>> rpcProviderOfPair
52      = new TypeLiteral<RpcProvider<Pair<Double, String>>>() { };
53
54  private final TestScope testScope = new TestScope();
55
56  interface RpcProvider<T> extends CheckedProvider<T> {
57    T get() throws RemoteException, BindException;
58  }
59
60  @Retention(RetentionPolicy.RUNTIME)
61  @BindingAnnotation
62  @interface TestAnnotation {
63  }
64
65  class TestModule extends AbstractModule {
66
67    private int nextIntToReturn = 100;
68
69    @Override
70    protected void configure() {
71      bindScope(TestScope.Scoped.class, testScope);
72      install(ThrowingProviderBinder.forModule(this));
73      install(new TestPrivateModule());
74    }
75
76    @CheckedProvides(RpcProvider.class)
77    String getSomeStringFromServer() {
78      return "Works";
79    }
80
81    @CheckedProvides(RpcProvider.class) @TestScope.Scoped
82    int getSomeIntegerFromServer() {
83      return nextIntToReturn;
84    }
85
86    @CheckedProvides(RpcProvider.class) @TestAnnotation
87    long getSomeLongFromServer() {
88      return 0xffL;
89    }
90
91    @Provides
92    double getSomeDouble() {
93      return 2.0d;
94    }
95
96    @CheckedProvides(RpcProvider.class)
97    Pair<Double, String> getSomePair(Double input) {
98      return new Pair<Double, String>(input * 2, "foo");
99    }
100
101    @CheckedProvides(RpcProvider.class)
102    float getFloat() throws BindException {
103      throw new BindException("foo");
104    }
105
106    void setNextIntToReturn(int next) {
107      nextIntToReturn = next;
108    }
109  }
110
111  class TestPrivateModule extends PrivateModule {
112
113    @Override
114    protected void configure() {
115      install(ThrowingProviderBinder.forModule(this));
116    }
117
118    @CheckedProvides(RpcProvider.class) @Named("fruit") @Exposed
119    String provideApples() {
120      return "apple";
121    }
122  }
123
124
125  public void testNoAnnotationNoScope() throws BindException, RemoteException {
126    Injector injector = Guice.createInjector(new TestModule());
127    RpcProvider<String> provider = injector
128        .getInstance(Key.get(rpcProviderOfString));
129    assertEquals("Works", provider.get());
130  }
131
132  public void testWithScope() throws BindException, RemoteException {
133    TestModule testModule = new TestModule();
134    Injector injector = Guice.createInjector(testModule);
135    RpcProvider<Integer> provider = injector
136        .getInstance(Key.get(rpcProviderOfInteger));
137
138    assertEquals((Integer)100, provider.get());
139    testModule.setNextIntToReturn(120);
140    assertEquals((Integer)100, provider.get());
141    testScope.beginNewScope();
142    assertEquals((Integer)120, provider.get());
143  }
144
145  public void testWithAnnotation() throws BindException, RemoteException {
146    TestModule testModule = new TestModule();
147    Injector injector = Guice.createInjector(testModule);
148    RpcProvider<Long> provider = injector
149        .getInstance(Key.get(rpcProviderOfLong, TestAnnotation.class));
150    assertEquals((Long)0xffL, provider.get());
151  }
152
153  public void testWithInjectedParameters() throws BindException, RemoteException {
154    TestModule testModule = new TestModule();
155    Injector injector = Guice.createInjector(testModule);
156    RpcProvider<Pair<Double, String>> provider = injector
157        .getInstance(Key.get(rpcProviderOfPair));
158    Pair<Double, String> pair = provider.get();
159    assertEquals(pair.first, 4.0d);
160  }
161
162  public void testWithThrownException() {
163    TestModule testModule = new TestModule();
164    Injector injector = Guice.createInjector(testModule);
165    RpcProvider<Float> provider = injector
166        .getInstance(Key.get(rpcProviderOfFloat));
167    try {
168      provider.get();
169      fail();
170    } catch (RemoteException e) {
171      fail();
172    } catch (BindException e) {
173      // good
174    }
175  }
176
177  public void testExposedMethod() throws BindException, RemoteException {
178    TestModule testModule = new TestModule();
179    Injector injector = Guice.createInjector(testModule);
180    RpcProvider<String> provider = injector
181        .getInstance(Key.get(rpcProviderOfString, Names.named("fruit")));
182    assertEquals("apple", provider.get());
183
184  }
185
186  private static class Pair<A, B> {
187    A first;
188    B second;
189
190    Pair(A a, B b) {
191      this.first= a;
192      this.second = b;
193    }
194  }
195}