1*f585d8a3SJacky Wang /* 2*f585d8a3SJacky Wang * Copyright (C) 2017 The Dagger Authors. 3*f585d8a3SJacky Wang * 4*f585d8a3SJacky Wang * Licensed under the Apache License, Version 2.0 (the "License"); 5*f585d8a3SJacky Wang * you may not use this file except in compliance with the License. 6*f585d8a3SJacky Wang * You may obtain a copy of the License at 7*f585d8a3SJacky Wang * 8*f585d8a3SJacky Wang * http://www.apache.org/licenses/LICENSE-2.0 9*f585d8a3SJacky Wang * 10*f585d8a3SJacky Wang * Unless required by applicable law or agreed to in writing, software 11*f585d8a3SJacky Wang * distributed under the License is distributed on an "AS IS" BASIS, 12*f585d8a3SJacky Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*f585d8a3SJacky Wang * See the License for the specific language governing permissions and 14*f585d8a3SJacky Wang * limitations under the License. 15*f585d8a3SJacky Wang */ 16*f585d8a3SJacky Wang 17*f585d8a3SJacky Wang package dagger.android; 18*f585d8a3SJacky Wang 19*f585d8a3SJacky Wang import static com.google.common.truth.Truth.assertThat; 20*f585d8a3SJacky Wang import static org.junit.Assert.fail; 21*f585d8a3SJacky Wang 22*f585d8a3SJacky Wang import android.app.Activity; 23*f585d8a3SJacky Wang import android.os.Build; 24*f585d8a3SJacky Wang import androidx.test.ext.junit.runners.AndroidJUnit4; 25*f585d8a3SJacky Wang import com.google.common.collect.ImmutableMap; 26*f585d8a3SJacky Wang import dagger.android.AndroidInjector.Factory; 27*f585d8a3SJacky Wang import dagger.android.DispatchingAndroidInjector.InvalidInjectorBindingException; 28*f585d8a3SJacky Wang import java.util.Map; 29*f585d8a3SJacky Wang import javax.inject.Provider; 30*f585d8a3SJacky Wang import org.junit.Test; 31*f585d8a3SJacky Wang import org.junit.runner.RunWith; 32*f585d8a3SJacky Wang import org.robolectric.Robolectric; 33*f585d8a3SJacky Wang import org.robolectric.annotation.Config; 34*f585d8a3SJacky Wang 35*f585d8a3SJacky Wang @RunWith(AndroidJUnit4.class) 36*f585d8a3SJacky Wang // Robolectric requires Java9 to run API 29 and above, so use API 28 instead 37*f585d8a3SJacky Wang @Config(sdk = Build.VERSION_CODES.P) 38*f585d8a3SJacky Wang public final class DispatchingAndroidInjectorTest { 39*f585d8a3SJacky Wang @Test withClassKeys()40*f585d8a3SJacky Wang public void withClassKeys() { 41*f585d8a3SJacky Wang DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 42*f585d8a3SJacky Wang newDispatchingAndroidInjector( 43*f585d8a3SJacky Wang ImmutableMap.of(FooActivity.class, FooInjector.Factory::new), ImmutableMap.of()); 44*f585d8a3SJacky Wang 45*f585d8a3SJacky Wang FooActivity activity = Robolectric.setupActivity(FooActivity.class); 46*f585d8a3SJacky Wang assertThat(dispatchingAndroidInjector.maybeInject(activity)).isTrue(); 47*f585d8a3SJacky Wang } 48*f585d8a3SJacky Wang 49*f585d8a3SJacky Wang @Test withStringKeys()50*f585d8a3SJacky Wang public void withStringKeys() { 51*f585d8a3SJacky Wang DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 52*f585d8a3SJacky Wang newDispatchingAndroidInjector( 53*f585d8a3SJacky Wang ImmutableMap.of(), 54*f585d8a3SJacky Wang ImmutableMap.of(FooActivity.class.getName(), FooInjector.Factory::new)); 55*f585d8a3SJacky Wang 56*f585d8a3SJacky Wang FooActivity activity = Robolectric.setupActivity(FooActivity.class); 57*f585d8a3SJacky Wang assertThat(dispatchingAndroidInjector.maybeInject(activity)).isTrue(); 58*f585d8a3SJacky Wang } 59*f585d8a3SJacky Wang 60*f585d8a3SJacky Wang @Test withMixedKeys()61*f585d8a3SJacky Wang public void withMixedKeys() { 62*f585d8a3SJacky Wang DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 63*f585d8a3SJacky Wang newDispatchingAndroidInjector( 64*f585d8a3SJacky Wang ImmutableMap.of(FooActivity.class, FooInjector.Factory::new), 65*f585d8a3SJacky Wang ImmutableMap.of(BarActivity.class.getName(), BarInjector.Factory::new)); 66*f585d8a3SJacky Wang 67*f585d8a3SJacky Wang FooActivity fooActivity = Robolectric.setupActivity(FooActivity.class); 68*f585d8a3SJacky Wang assertThat(dispatchingAndroidInjector.maybeInject(fooActivity)).isTrue(); 69*f585d8a3SJacky Wang BarActivity barActivity = Robolectric.setupActivity(BarActivity.class); 70*f585d8a3SJacky Wang assertThat(dispatchingAndroidInjector.maybeInject(barActivity)).isTrue(); 71*f585d8a3SJacky Wang } 72*f585d8a3SJacky Wang 73*f585d8a3SJacky Wang @Test maybeInject_returnsFalse_ifNoMatchingInjectorExists()74*f585d8a3SJacky Wang public void maybeInject_returnsFalse_ifNoMatchingInjectorExists() { 75*f585d8a3SJacky Wang DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 76*f585d8a3SJacky Wang newDispatchingAndroidInjector(ImmutableMap.of(), ImmutableMap.of()); 77*f585d8a3SJacky Wang 78*f585d8a3SJacky Wang BarActivity activity = Robolectric.setupActivity(BarActivity.class); 79*f585d8a3SJacky Wang assertThat(dispatchingAndroidInjector.maybeInject(activity)).isFalse(); 80*f585d8a3SJacky Wang } 81*f585d8a3SJacky Wang 82*f585d8a3SJacky Wang @Test throwsIfFactoryCreateReturnsNull()83*f585d8a3SJacky Wang public void throwsIfFactoryCreateReturnsNull() { 84*f585d8a3SJacky Wang DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 85*f585d8a3SJacky Wang newDispatchingAndroidInjector( 86*f585d8a3SJacky Wang ImmutableMap.of(FooActivity.class, () -> null), ImmutableMap.of()); 87*f585d8a3SJacky Wang FooActivity activity = Robolectric.setupActivity(FooActivity.class); 88*f585d8a3SJacky Wang 89*f585d8a3SJacky Wang try { 90*f585d8a3SJacky Wang dispatchingAndroidInjector.maybeInject(activity); 91*f585d8a3SJacky Wang fail("Expected NullPointerException"); 92*f585d8a3SJacky Wang } catch (NullPointerException expected) { 93*f585d8a3SJacky Wang } 94*f585d8a3SJacky Wang } 95*f585d8a3SJacky Wang 96*f585d8a3SJacky Wang @Test throwsIfClassMismatched()97*f585d8a3SJacky Wang public void throwsIfClassMismatched() { 98*f585d8a3SJacky Wang DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 99*f585d8a3SJacky Wang newDispatchingAndroidInjector( 100*f585d8a3SJacky Wang ImmutableMap.of(FooActivity.class, BarInjector.Factory::new), ImmutableMap.of()); 101*f585d8a3SJacky Wang FooActivity activity = Robolectric.setupActivity(FooActivity.class); 102*f585d8a3SJacky Wang 103*f585d8a3SJacky Wang try { 104*f585d8a3SJacky Wang dispatchingAndroidInjector.maybeInject(activity); 105*f585d8a3SJacky Wang fail("Expected InvalidInjectorBindingException"); 106*f585d8a3SJacky Wang } catch (InvalidInjectorBindingException expected) { 107*f585d8a3SJacky Wang } 108*f585d8a3SJacky Wang } 109*f585d8a3SJacky Wang newDispatchingAndroidInjector( Map<Class<?>, Provider<Factory<?>>> injectorFactoriesWithClassKeys, Map<String, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithStringKeys)110*f585d8a3SJacky Wang private static <T> DispatchingAndroidInjector<T> newDispatchingAndroidInjector( 111*f585d8a3SJacky Wang Map<Class<?>, Provider<Factory<?>>> injectorFactoriesWithClassKeys, 112*f585d8a3SJacky Wang Map<String, Provider<AndroidInjector.Factory<?>>> 113*f585d8a3SJacky Wang injectorFactoriesWithStringKeys) { 114*f585d8a3SJacky Wang return new DispatchingAndroidInjector<>( 115*f585d8a3SJacky Wang injectorFactoriesWithClassKeys, injectorFactoriesWithStringKeys); 116*f585d8a3SJacky Wang } 117*f585d8a3SJacky Wang 118*f585d8a3SJacky Wang static class FooActivity extends Activity {} 119*f585d8a3SJacky Wang 120*f585d8a3SJacky Wang static class BarActivity extends Activity {} 121*f585d8a3SJacky Wang 122*f585d8a3SJacky Wang static class FooInjector implements AndroidInjector<FooActivity> { 123*f585d8a3SJacky Wang @Override inject(FooActivity instance)124*f585d8a3SJacky Wang public void inject(FooActivity instance) {} 125*f585d8a3SJacky Wang 126*f585d8a3SJacky Wang static class Factory implements AndroidInjector.Factory<FooActivity> { 127*f585d8a3SJacky Wang @Override create(FooActivity activity)128*f585d8a3SJacky Wang public AndroidInjector<FooActivity> create(FooActivity activity) { 129*f585d8a3SJacky Wang return new FooInjector(); 130*f585d8a3SJacky Wang } 131*f585d8a3SJacky Wang } 132*f585d8a3SJacky Wang } 133*f585d8a3SJacky Wang 134*f585d8a3SJacky Wang static class BarInjector implements AndroidInjector<BarActivity> { 135*f585d8a3SJacky Wang @Override inject(BarActivity instance)136*f585d8a3SJacky Wang public void inject(BarActivity instance) {} 137*f585d8a3SJacky Wang 138*f585d8a3SJacky Wang static class Factory implements AndroidInjector.Factory<BarActivity> { 139*f585d8a3SJacky Wang @Override create(BarActivity activity)140*f585d8a3SJacky Wang public AndroidInjector<BarActivity> create(BarActivity activity) { 141*f585d8a3SJacky Wang return new BarInjector(); 142*f585d8a3SJacky Wang } 143*f585d8a3SJacky Wang } 144*f585d8a3SJacky Wang } 145*f585d8a3SJacky Wang } 146