1 /* 2 * Copyright (C) 2024 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.functional.jakarta; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import com.google.common.base.Optional; 22 import dagger.Binds; 23 import dagger.BindsOptionalOf; 24 import dagger.Component; 25 import dagger.Lazy; 26 import dagger.Module; 27 import dagger.Provides; 28 import dagger.multibindings.IntoMap; 29 import dagger.multibindings.StringKey; 30 import jakarta.inject.Inject; 31 import jakarta.inject.Provider; 32 import jakarta.inject.Qualifier; 33 import jakarta.inject.Scope; 34 import java.util.HashMap; 35 import java.util.Map; 36 import org.junit.Test; 37 import org.junit.runner.RunWith; 38 import org.junit.runners.JUnit4; 39 40 @RunWith(JUnit4.class) 41 public final class JakartaProviderTest { 42 43 @Scope 44 public @interface TestScope {} 45 46 @Qualifier 47 public @interface TestQualifier {} 48 49 @TestScope 50 @Component(modules = TestModule.class) 51 interface TestComponent { getJakartaFoo()52 Provider<Foo> getJakartaFoo(); 53 getJavaxFoo()54 javax.inject.Provider<Foo> getJavaxFoo(); 55 getJakartaBar()56 Provider<Bar> getJakartaBar(); 57 getJavaxBar()58 javax.inject.Provider<Bar> getJavaxBar(); 59 60 @TestQualifier getJakartaQualifiedFoo()61 Provider<Foo> getJakartaQualifiedFoo(); 62 63 @TestQualifier getJavaxQualifiedFoo()64 javax.inject.Provider<Foo> getJavaxQualifiedFoo(); 65 66 @TestQualifier getJakartaQualifiedBar()67 Provider<Bar> getJakartaQualifiedBar(); 68 69 @TestQualifier getJavaxQualifiedBar()70 javax.inject.Provider<Bar> getJavaxQualifiedBar(); 71 injectUsages()72 InjectUsages injectUsages(); 73 getJakartaProviderMap()74 Map<String, Provider<Bar>> getJakartaProviderMap(); 75 getJavaxProviderMap()76 Map<String, javax.inject.Provider<Bar>> getJavaxProviderMap(); 77 getJakartaProviderLazyMap()78 Map<String, Provider<Lazy<Bar>>> getJakartaProviderLazyMap(); 79 getJavaxProviderLazyMap()80 Map<String, javax.inject.Provider<Lazy<Bar>>> getJavaxProviderLazyMap(); 81 getManuallyProvidedJakartaMap()82 Map<Long, Provider<Long>> getManuallyProvidedJakartaMap(); 83 getManuallyProvidedJavaxMap()84 Map<Long, javax.inject.Provider<Long>> getManuallyProvidedJavaxMap(); 85 getPresentOptionalJakartaProvider()86 Optional<Provider<String>> getPresentOptionalJakartaProvider(); 87 getPresentOptionalJavaxProvider()88 Optional<javax.inject.Provider<String>> getPresentOptionalJavaxProvider(); 89 getEmptyOptionalJakartaProvider()90 Optional<Provider<Long>> getEmptyOptionalJakartaProvider(); 91 getEmptyOptionalJavaxProvider()92 Optional<javax.inject.Provider<Long>> getEmptyOptionalJavaxProvider(); 93 } 94 95 public static final class Foo { 96 @Inject Foo()97 Foo() {} 98 } 99 100 @TestScope 101 public static final class Bar { 102 @Inject Bar()103 Bar() {} 104 } 105 106 public static final class InjectUsages { 107 Provider<Bar> jakartaBar; 108 Provider<Bar> jakartaQualifiedBar; 109 javax.inject.Provider<Bar> javaxQualifiedBar; 110 111 @Inject InjectUsages(Provider<Bar> jakartaBar)112 InjectUsages(Provider<Bar> jakartaBar) { 113 this.jakartaBar = jakartaBar; 114 } 115 116 @Inject javax.inject.Provider<Bar> javaxBar; 117 118 @Inject injectBar( Provider<Bar> jakartaQualifiedBar, javax.inject.Provider<Bar> javaxQualifiedBar)119 void injectBar( 120 Provider<Bar> jakartaQualifiedBar, javax.inject.Provider<Bar> javaxQualifiedBar) { 121 this.jakartaQualifiedBar = jakartaQualifiedBar; 122 this.javaxQualifiedBar = javaxQualifiedBar; 123 } 124 } 125 126 @Module 127 abstract static class TestModule { 128 @Provides 129 @TestQualifier provideFoo( Provider<Foo> fooProvider, javax.inject.Provider<Foo> unusedOtherFooProvider)130 static Foo provideFoo( 131 Provider<Foo> fooProvider, javax.inject.Provider<Foo> unusedOtherFooProvider) { 132 return fooProvider.get(); 133 } 134 135 @Provides 136 @TestQualifier 137 @TestScope provideBar( Provider<Bar> unusedBarProvider, javax.inject.Provider<Bar> otherBarProvider)138 static Bar provideBar( 139 Provider<Bar> unusedBarProvider, javax.inject.Provider<Bar> otherBarProvider) { 140 // Use the other one in this case just to vary it from Foo 141 return otherBarProvider.get(); 142 } 143 144 @Binds 145 @IntoMap 146 @StringKey("bar") bindBarIntoMap(Bar bar)147 abstract Bar bindBarIntoMap(Bar bar); 148 149 // TODO(b/65118638): Use @Binds @IntoMap Lazy<T> once that works properly. 150 @Provides 151 @IntoMap 152 @StringKey("bar") provideLazyIntoMap(Lazy<Bar> bar)153 static Lazy<Bar> provideLazyIntoMap(Lazy<Bar> bar) { 154 return bar; 155 } 156 157 // Manually provide two Provider maps to make sure they don't conflict. 158 @Provides manuallyProvidedJakartaMap()159 static Map<Long, Provider<Long>> manuallyProvidedJakartaMap() { 160 Map<Long, Provider<Long>> map = new HashMap<>(); 161 map.put(9L, null); 162 return map; 163 } 164 165 @Provides manuallyProvidedJavaxMap()166 static Map<Long, javax.inject.Provider<Long>> manuallyProvidedJavaxMap() { 167 Map<Long, javax.inject.Provider<Long>> map = new HashMap<>(); 168 map.put(0L, null); 169 return map; 170 } 171 172 @BindsOptionalOf bindOptionalString()173 abstract String bindOptionalString(); 174 175 @Provides provideString()176 static String provideString() { 177 return "present"; 178 } 179 180 @BindsOptionalOf bindOptionalLong()181 abstract Long bindOptionalLong(); 182 } 183 184 @Test testJakartaProviders()185 public void testJakartaProviders() { 186 TestComponent testComponent = DaggerJakartaProviderTest_TestComponent.create(); 187 188 assertThat(testComponent.getJakartaFoo().get()).isNotNull(); 189 assertThat(testComponent.getJavaxFoo().get()).isNotNull(); 190 191 assertThat(testComponent.getJakartaBar().get()) 192 .isSameInstanceAs(testComponent.getJavaxBar().get()); 193 194 assertThat(testComponent.getJakartaQualifiedFoo().get()).isNotNull(); 195 assertThat(testComponent.getJavaxQualifiedFoo().get()).isNotNull(); 196 197 assertThat(testComponent.getJakartaQualifiedBar().get()) 198 .isSameInstanceAs(testComponent.getJavaxQualifiedBar().get()); 199 assertThat(testComponent.getJakartaBar().get()) 200 .isSameInstanceAs(testComponent.getJakartaQualifiedBar().get()); 201 202 InjectUsages injectUsages = testComponent.injectUsages(); 203 204 assertThat(injectUsages.jakartaBar.get()).isSameInstanceAs(injectUsages.javaxBar.get()); 205 assertThat(injectUsages.jakartaQualifiedBar.get()) 206 .isSameInstanceAs(injectUsages.javaxQualifiedBar.get()); 207 assertThat(injectUsages.jakartaBar.get()) 208 .isSameInstanceAs(injectUsages.jakartaQualifiedBar.get()); 209 210 assertThat(testComponent.getJakartaProviderMap().get("bar").get()).isSameInstanceAs( 211 testComponent.getJavaxProviderMap().get("bar").get()); 212 213 assertThat(testComponent.getJakartaProviderLazyMap().get("bar").get().get()).isSameInstanceAs( 214 testComponent.getJavaxProviderLazyMap().get("bar").get().get()); 215 216 Map<Long, Provider<Long>> manualJakartaMap = testComponent.getManuallyProvidedJakartaMap(); 217 assertThat(manualJakartaMap.keySet()).containsExactly(9L); 218 219 Map<Long, javax.inject.Provider<Long>> manualJavaxMap = 220 testComponent.getManuallyProvidedJavaxMap(); 221 assertThat(manualJavaxMap.keySet()).containsExactly(0L); 222 223 assertThat(testComponent.getPresentOptionalJakartaProvider().get().get()).isEqualTo("present"); 224 assertThat(testComponent.getPresentOptionalJavaxProvider().get().get()).isEqualTo("present"); 225 assertThat(testComponent.getEmptyOptionalJakartaProvider().isPresent()).isFalse(); 226 assertThat(testComponent.getEmptyOptionalJavaxProvider().isPresent()).isFalse(); 227 } 228 } 229