package tc.oc.commons.core.inject;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import javax.inject.Named;
import com.google.common.collect.Lists;
import com.google.inject.CreationException;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
import com.google.inject.util.Modules;
import org.junit.Test;
import tc.oc.test.InjectedTestCase;
import static org.junit.Assert.*;
import static tc.oc.test.Assert.*;
public class InjectableMethodTest extends InjectedTestCase {
@Test
public void constant() throws Exception {
class Woot {
String foo() {
return "hi";
}
}
InjectableMethod<?> method = InjectableMethod.forDeclaredMethod(new Woot(), "foo");
String hi = Guice.createInjector(method.bindingModule()).getInstance(String.class);
assertEquals("hi", hi);
}
@Test
public void voidReturnType() throws Exception {
class Woot {
void foo() {}
}
InjectableMethod<?> method = InjectableMethod.forDeclaredMethod(new Woot(), "foo");
assertThrows(CreationException.class, () ->
Guice.createInjector(method.bindingModule())
);
}
@Test
public void dependencies() throws Exception {
class Woot {
String foo(int i, short s) {
return i + " " + s;
}
}
InjectableMethod<?> method = InjectableMethod.forDeclaredMethod(new Woot(), "foo", int.class, short.class);
String hi = Guice.createInjector(
method.bindingModule(),
binder -> {
binder.bind(int.class).toInstance(123);
binder.bind(short.class).toInstance((short) 456);
}
).getInstance(String.class);
assertEquals("123 456", hi);
}
@Test
public void qualifiedReturnType() throws Exception {
class Woot {
@Named("q") String foo() {
return "hi";
}
}
InjectableMethod<?> method = InjectableMethod.forDeclaredMethod(new Woot(), "foo");
String hi = Guice.createInjector(method.bindingModule()).getInstance(Key.get(String.class, Names.named("q")));
assertEquals("hi", hi);
}
@Test
public void qualifiedDependency() throws Exception {
class Woot {
String foo(@Named("q") int i) {
return String.valueOf(i);
}
}
InjectableMethod<?> method = InjectableMethod.forDeclaredMethod(new Woot(), "foo", int.class);
String hi = Guice.createInjector(
method.bindingModule(),
binder -> binder.bind(int.class)
.annotatedWith(Names.named("q"))
.toInstance(123)
).getInstance(String.class);
assertEquals("123", hi);
}
@Retention(RetentionPolicy.RUNTIME)
@interface Yay {}
@Test
public void scanForMethods() throws Exception {
class Woot {
@Yay String foo() {
return "foo";
}
String bar() {
return "bar";
}
}
List<InjectableMethod<?>> methods = InjectableMethod.forAnnotatedMethods(TypeLiteral.get(Woot.class), new Woot(), Yay.class);
Injector injector = Guice.createInjector(Lists.transform(methods, InjectableMethod::bindingModule));
assertEquals("foo", injector.getInstance(String.class));
}
}