1 /* 2 * Copyright (C) 2017 The Dagger Authors. 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 17 package dagger.android; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.fail; 21 22 import android.app.Activity; 23 import android.os.Build; 24 import androidx.test.ext.junit.runners.AndroidJUnit4; 25 import com.google.common.collect.ImmutableMap; 26 import dagger.android.AndroidInjector.Factory; 27 import dagger.android.DispatchingAndroidInjector.InvalidInjectorBindingException; 28 import java.util.Map; 29 import javax.inject.Provider; 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.robolectric.Robolectric; 33 import org.robolectric.annotation.Config; 34 35 @RunWith(AndroidJUnit4.class) 36 // Robolectric requires Java9 to run API 29 and above, so use API 28 instead 37 @Config(sdk = Build.VERSION_CODES.P) 38 public final class DispatchingAndroidInjectorTest { 39 @Test withClassKeys()40 public void withClassKeys() { 41 DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 42 newDispatchingAndroidInjector( 43 ImmutableMap.of(FooActivity.class, FooInjector.Factory::new), ImmutableMap.of()); 44 45 FooActivity activity = Robolectric.setupActivity(FooActivity.class); 46 assertThat(dispatchingAndroidInjector.maybeInject(activity)).isTrue(); 47 } 48 49 @Test withStringKeys()50 public void withStringKeys() { 51 DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 52 newDispatchingAndroidInjector( 53 ImmutableMap.of(), 54 ImmutableMap.of(FooActivity.class.getName(), FooInjector.Factory::new)); 55 56 FooActivity activity = Robolectric.setupActivity(FooActivity.class); 57 assertThat(dispatchingAndroidInjector.maybeInject(activity)).isTrue(); 58 } 59 60 @Test withMixedKeys()61 public void withMixedKeys() { 62 DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 63 newDispatchingAndroidInjector( 64 ImmutableMap.of(FooActivity.class, FooInjector.Factory::new), 65 ImmutableMap.of(BarActivity.class.getName(), BarInjector.Factory::new)); 66 67 FooActivity fooActivity = Robolectric.setupActivity(FooActivity.class); 68 assertThat(dispatchingAndroidInjector.maybeInject(fooActivity)).isTrue(); 69 BarActivity barActivity = Robolectric.setupActivity(BarActivity.class); 70 assertThat(dispatchingAndroidInjector.maybeInject(barActivity)).isTrue(); 71 } 72 73 @Test maybeInject_returnsFalse_ifNoMatchingInjectorExists()74 public void maybeInject_returnsFalse_ifNoMatchingInjectorExists() { 75 DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 76 newDispatchingAndroidInjector(ImmutableMap.of(), ImmutableMap.of()); 77 78 BarActivity activity = Robolectric.setupActivity(BarActivity.class); 79 assertThat(dispatchingAndroidInjector.maybeInject(activity)).isFalse(); 80 } 81 82 @Test throwsIfFactoryCreateReturnsNull()83 public void throwsIfFactoryCreateReturnsNull() { 84 DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 85 newDispatchingAndroidInjector( 86 ImmutableMap.of(FooActivity.class, () -> null), ImmutableMap.of()); 87 FooActivity activity = Robolectric.setupActivity(FooActivity.class); 88 89 try { 90 dispatchingAndroidInjector.maybeInject(activity); 91 fail("Expected NullPointerException"); 92 } catch (NullPointerException expected) { 93 } 94 } 95 96 @Test throwsIfClassMismatched()97 public void throwsIfClassMismatched() { 98 DispatchingAndroidInjector<Activity> dispatchingAndroidInjector = 99 newDispatchingAndroidInjector( 100 ImmutableMap.of(FooActivity.class, BarInjector.Factory::new), ImmutableMap.of()); 101 FooActivity activity = Robolectric.setupActivity(FooActivity.class); 102 103 try { 104 dispatchingAndroidInjector.maybeInject(activity); 105 fail("Expected InvalidInjectorBindingException"); 106 } catch (InvalidInjectorBindingException expected) { 107 } 108 } 109 newDispatchingAndroidInjector( Map<Class<?>, Provider<Factory<?>>> injectorFactoriesWithClassKeys, Map<String, Provider<AndroidInjector.Factory<?>>> injectorFactoriesWithStringKeys)110 private static <T> DispatchingAndroidInjector<T> newDispatchingAndroidInjector( 111 Map<Class<?>, Provider<Factory<?>>> injectorFactoriesWithClassKeys, 112 Map<String, Provider<AndroidInjector.Factory<?>>> 113 injectorFactoriesWithStringKeys) { 114 return new DispatchingAndroidInjector<>( 115 injectorFactoriesWithClassKeys, injectorFactoriesWithStringKeys); 116 } 117 118 static class FooActivity extends Activity {} 119 120 static class BarActivity extends Activity {} 121 122 static class FooInjector implements AndroidInjector<FooActivity> { 123 @Override inject(FooActivity instance)124 public void inject(FooActivity instance) {} 125 126 static class Factory implements AndroidInjector.Factory<FooActivity> { 127 @Override create(FooActivity activity)128 public AndroidInjector<FooActivity> create(FooActivity activity) { 129 return new FooInjector(); 130 } 131 } 132 } 133 134 static class BarInjector implements AndroidInjector<BarActivity> { 135 @Override inject(BarActivity instance)136 public void inject(BarActivity instance) {} 137 138 static class Factory implements AndroidInjector.Factory<BarActivity> { 139 @Override create(BarActivity activity)140 public AndroidInjector<BarActivity> create(BarActivity activity) { 141 return new BarInjector(); 142 } 143 } 144 } 145 } 146