package ru.vyarus.guice.ext.generator; import com.google.inject.*; import com.google.inject.matcher.Matchers; import com.google.inject.name.Names; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.junit.Assert; import org.junit.Test; import ru.vyarus.guice.ext.core.generator.anchor.GeneratorAnchorModule; import ru.vyarus.guice.ext.generator.support.anchor.*; import ru.vyarus.guice.ext.generator.support.aop.CustomAop; import javax.inject.Inject; import javax.inject.Provider; /** * @author Vyacheslav Rusakov * @since 21.09.2016 */ public class GeneratorAnchorsTest { @Test(expected = AbstractMethodError.class) public void checkChildInjectorFailure() throws Exception { // aop registered in child injector Injector injector = Guice.createInjector().createChildInjector(new ChildAopModule()); // bean will be generated at root injector and so no aop will apply on it injector.getInstance(TestIface.class).hello(); } @Test public void testAnchorModule() throws Exception { // aop registered in child injector with anchor module Injector injector = Guice.createInjector().createChildInjector(new ChildAopModule(), new GeneratorAnchorModule()); injector.getInstance(TestIface.class).hello(); injector.getInstance(PureAbstractClass.class).hello(); // important: RootService not registered and so will be created by JIT in root injector injector.getInstance(CtorAbstractClass.class).hello(); injector.getInstance(GenericsCtorAbstractClass.class).hello(); } @Test public void dynamicInjectionTest() throws Exception { Injector injector = Guice.createInjector() .createChildInjector(new ChildAopModule(), new GeneratorAnchorModule()); // service resolved with jit still injects correct dependency injector.getInstance(DynamicService.class).hello(); } @Test public void testPrivateModules() throws Exception { Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { install(new MyPrivateModule("test")); install(new MyPrivateModule("other")); } }); Assert.assertEquals(injector.getInstance(Key.get(TestIface.class, Names.named("test"))).hello(), "test"); Assert.assertEquals(injector.getInstance(Key.get(TestIface.class, Names.named("other"))).hello(), "other"); } static class ChildAopModule extends AbstractModule { String res; public ChildAopModule() { this(""); } public ChildAopModule(String res) { this.res = res; } @Override protected void configure() { bindInterceptor(Matchers.any(), Matchers.annotatedWith(CustomAop.class), new MethodInterceptor() { @Override public Object invoke(MethodInvocation invocation) throws Throwable { return res; } }); } } private static class MyPrivateModule extends PrivateModule { private String res; public MyPrivateModule(String res) { this.res = res; } @Override protected void configure() { install(new ChildAopModule(res)); install(new GeneratorAnchorModule()); // duplicate binding required for exposing (otherwise only provider method could be used) bind(TestIface.class).annotatedWith(Names.named(res)).toProvider(ExposedApi.class); expose(TestIface.class).annotatedWith(Names.named(res)); } // @Provides // @Exposed // @Named("test") // TestIface provide(TestIface serv) { // return serv; // } } private static class ExposedApi implements Provider<TestIface> { @Inject TestIface iface; @Override public TestIface get() { return iface; } } }