@@ -11,6 +11,7 @@ import com.tschuchort.compiletesting.KotlinCompilation.ExitCode.OK
1111import com.tschuchort.compiletesting.KotlinCompilation.Result
1212import dagger.Lazy
1313import dagger.internal.Factory
14+ import org.junit.Ignore
1415import org.junit.Test
1516import org.junit.runner.RunWith
1617import org.junit.runners.Parameterized
@@ -288,6 +289,183 @@ public final class InjectClass_Factory implements Factory<InjectClass> {
288289 }
289290 }
290291
292+ @Test
293+ fun `a factory class is generated for an inject constructor with a lazy argument wrapped in a provider` () {
294+ /*
295+ package com.squareup.test;
296+
297+ import dagger.Lazy;
298+ import dagger.internal.DaggerGenerated;
299+ import dagger.internal.Factory;
300+ import dagger.internal.ProviderOfLazy;
301+ import javax.annotation.processing.Generated;
302+ import javax.inject.Provider;
303+
304+ @DaggerGenerated
305+ @Generated(
306+ value = "dagger.internal.codegen.ComponentProcessor",
307+ comments = "https://dagger.dev"
308+ )
309+ @SuppressWarnings({
310+ "unchecked",
311+ "rawtypes"
312+ })
313+ public final class InjectClass_Factory implements Factory<InjectClass> {
314+ private final Provider<String> stringProvider;
315+
316+ public InjectClass_Factory(Provider<String> stringProvider) {
317+ this.stringProvider = stringProvider;
318+ }
319+
320+ @Override
321+ public InjectClass get() {
322+ return newInstance(ProviderOfLazy.create(stringProvider));
323+ }
324+
325+ public static InjectClass_Factory create(Provider<String> stringProvider) {
326+ return new InjectClass_Factory(stringProvider);
327+ }
328+
329+ public static InjectClass newInstance(Provider<Lazy<String>> string) {
330+ return new InjectClass(string);
331+ }
332+ }
333+ */
334+
335+ compile(
336+ """
337+ package com.squareup.test
338+
339+ import dagger.Lazy
340+ import javax.inject.Inject
341+ import javax.inject.Provider
342+
343+ class InjectClass @Inject constructor(
344+ val string: Provider<Lazy<String>>
345+ ) {
346+ override fun equals(other: Any?): Boolean {
347+ return toString() == other.toString()
348+ }
349+ override fun toString(): String {
350+ return string.get().get()
351+ }
352+ }
353+ """
354+ ) {
355+ val factoryClass = injectClass.factoryClass()
356+
357+ val constructor = factoryClass.declaredConstructors.single()
358+ assertThat(constructor .parameterTypes.toList())
359+ .containsExactly(Provider ::class .java)
360+
361+ val staticMethods = factoryClass.declaredMethods.filter { it.isStatic }
362+
363+ val factoryInstance = staticMethods.single { it.name == " create" }
364+ .invoke(null , Provider { " a" })
365+ assertThat(factoryInstance::class .java).isEqualTo(factoryClass)
366+
367+ val newInstance = staticMethods.single { it.name == " newInstance" }
368+ .invoke(null , Provider { dagger.Lazy { " a" } })
369+ val getInstance = (factoryInstance as Factory <* >).get()
370+
371+ assertThat(newInstance).isNotNull()
372+ assertThat(getInstance).isNotNull()
373+
374+ assertThat(newInstance).isEqualTo(getInstance)
375+ assertThat(newInstance).isNotSameInstanceAs(getInstance)
376+ }
377+ }
378+
379+ @Test
380+ @Ignore(" This test is broken with Dagger as well." )
381+ // Notice in the get() function Dagger creates a Lazy of a Provider of Provider instead of a
382+ // Lazy of a Provider.
383+ fun `a factory class is generated for an inject constructor with a provider argument wrapped in a lazy` () {
384+ /*
385+ package com.squareup.test;
386+
387+ import dagger.Lazy;
388+ import dagger.internal.DaggerGenerated;
389+ import dagger.internal.DoubleCheck;
390+ import dagger.internal.Factory;
391+ import javax.annotation.processing.Generated;
392+ import javax.inject.Provider;
393+
394+ @DaggerGenerated
395+ @Generated(
396+ value = "dagger.internal.codegen.ComponentProcessor",
397+ comments = "https://dagger.dev"
398+ )
399+ @SuppressWarnings({
400+ "unchecked",
401+ "rawtypes"
402+ })
403+ public final class InjectClass_Factory implements Factory<InjectClass> {
404+ private final Provider<Provider<String>> stringProvider;
405+
406+ public InjectClass_Factory(Provider<Provider<String>> stringProvider) {
407+ this.stringProvider = stringProvider;
408+ }
409+
410+ @Override
411+ public InjectClass get() {
412+ return newInstance(DoubleCheck.lazy(stringProvider));
413+ }
414+
415+ public static InjectClass_Factory create(Provider<Provider<String>> stringProvider) {
416+ return new InjectClass_Factory(stringProvider);
417+ }
418+
419+ public static InjectClass newInstance(Lazy<Provider<String>> string) {
420+ return new InjectClass(string);
421+ }
422+ }
423+ */
424+
425+ compile(
426+ """
427+ package com.squareup.test
428+
429+ import dagger.Lazy
430+ import javax.inject.Inject
431+ import javax.inject.Provider
432+
433+ class InjectClass @Inject constructor(
434+ val string: Lazy<Provider<String>>
435+ ) {
436+ override fun equals(other: Any?): Boolean {
437+ return toString() == other.toString()
438+ }
439+ override fun toString(): String {
440+ return string.get().get()
441+ }
442+ }
443+ """
444+ ) {
445+ val factoryClass = injectClass.factoryClass()
446+
447+ val constructor = factoryClass.declaredConstructors.single()
448+ assertThat(constructor .parameterTypes.toList())
449+ .containsExactly(Provider ::class .java)
450+
451+ val staticMethods = factoryClass.declaredMethods.filter { it.isStatic }
452+
453+ val factoryInstance = staticMethods.single { it.name == " create" }
454+ .invoke(null , Provider { " a" })
455+ assertThat(factoryInstance::class .java).isEqualTo(factoryClass)
456+
457+ val newInstance = staticMethods.single { it.name == " newInstance" }
458+ .invoke(null , dagger.Lazy { Provider { " a" } })
459+ val getInstance = (factoryInstance as Factory <* >).get()
460+
461+ assertThat(newInstance).isNotNull()
462+ assertThat(getInstance).isNotNull()
463+
464+ assertThat(newInstance).isEqualTo(getInstance)
465+ assertThat(newInstance).isNotSameInstanceAs(getInstance)
466+ }
467+ }
468+
291469 @Test fun `a factory class is generated for an inject constructor with star imports` () {
292470 /*
293471package com.squareup.test;
0 commit comments