/* * Copyright 2016 Kejun Xia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.shipdream.lib.poke; import com.shipdream.lib.poke.exception.PokeException; import com.shipdream.lib.poke.exception.ProvideException; import com.shipdream.lib.poke.exception.ProviderConflictException; import org.junit.Assert; import org.junit.Test; import java.lang.annotation.Retention; import javax.inject.Named; import javax.inject.Qualifier; import javax.inject.Singleton; import static java.lang.annotation.RetentionPolicy.RUNTIME; public class TestComponentInjection extends BaseTestCases { private interface Food { } private static class Apple implements Food { } private static class Milk implements Food { } @Test(expected = ProviderConflictException.class) public void shouldDetectConflictProvides() throws PokeException { Object module = new Object() { @Provides public Food providesFood1() { return new Apple(); } @Provides public Food providesFood2() { return new Milk(); } }; Graph graph = new Graph(); graph.setRootComponent(new Component().register(module)); } @Qualifier @Retention(RUNTIME) @interface Fruit { } @Qualifier @Retention(RUNTIME) @interface Drink { } @Test public void componentMethodInjectionShouldWork() throws PokeException { class Bread implements Food{ } Object module = new Object() { @Fruit @Provides public Food providesFood1() { return new Apple(); } @Drink @Provides public Food providesFood2() { return new Milk(); } @Provides public Food providesFood3() { return new Bread(); } }; class Fridge { @Fruit @MyInject private Food fruit; @MyInject private Food bread; @Drink @MyInject private Food drink; } Graph graph = new Graph(); graph.setRootComponent(new Component().register(module)); Fridge fridge = new Fridge(); graph.inject(fridge, MyInject.class); Assert.assertEquals(fridge.fruit.getClass(), Apple.class); Assert.assertEquals(fridge.drink.getClass(), Milk.class); Assert.assertEquals(fridge.bread.getClass(), Bread.class); } @Test public void componentMethodInjectionShouldWork1() throws PokeException { Object module = new Object() { @Named("Fruit") @Provides public Food providesFood1() { return new Apple(); } @Named("Drink") @Provides public Food providesFood2() { return new Milk(); } @Named("Untagged") @Provides public Food providesFood3() { return new Milk(); } }; class Fridge { @Named("Fruit") @MyInject private Food fruit; @Named("Untagged") @MyInject private Food drink2; @Named("Drink") @MyInject private Food drink; } Graph graph = new Graph(); graph.setRootComponent(new Component().register(module)); Fridge fridge = new Fridge(); graph.inject(fridge, MyInject.class); Assert.assertEquals(fridge.fruit.getClass(), Apple.class); Assert.assertEquals(fridge.drink.getClass(), Milk.class); Assert.assertEquals(fridge.drink2.getClass(), Milk.class); } static class SingletonModule { @Singleton @Provides public Food providesFood() { return new Apple(); } } @Test public void singletonComponentShouldProvideSameInstance() throws PokeException { Object module = new SingletonModule(); Component component = new Component("AppSingleton"); Graph graph = new Graph(); graph.setRootComponent(component.register(module)); Graph graph2 = new Graph(); graph2.setRootComponent(component); class Fridge { @MyInject private Food fruit; } Fridge fridge = new Fridge(); graph.inject(fridge, MyInject.class); Fridge fridge1 = new Fridge(); graph2.inject(fridge1, MyInject.class); Assert.assertNotNull(fridge.fruit); Assert.assertTrue(fridge.fruit == fridge1.fruit); } static class BadModule { @Provides public Food providesFood() { return null; } } @Test (expected = ProvideException.class) public void should_detect_ProvideException_with_providers_return_void () throws PokeException { Graph graph = new Graph(); graph.setRootComponent(new Component().register(new BadModule())); class Fridge { @MyInject private Food myFood; } Fridge fridge = new Fridge(); graph.inject(fridge, MyInject.class); } }