Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hilt: allow custom injection support for tests. #4173

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion java/dagger/hilt/EntryPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package dagger.hilt;

import static java.lang.annotation.RetentionPolicy.CLASS;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down Expand Up @@ -44,7 +45,7 @@
*
* @see <a href="https://dagger.dev/hilt/entry-points">Entry points</a>
*/
@Retention(CLASS)
@Retention(RUNTIME)
@Target(ElementType.TYPE)
@GeneratesRootInput
public @interface EntryPoint {}
1 change: 1 addition & 0 deletions java/dagger/hilt/android/internal/managers/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ android_library(
"SavedStateHandleModule.java",
"ServiceComponentManager.java",
"ViewComponentManager.java",
"TestInjectInterceptor.java",
],
exports = [":saved_state_handle_holder"],
deps = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package dagger.hilt.android.internal.managers;

/**
* This class does nothing in production or in tests when running under Hilt testing framework. However, the calls
* to TestInjectInterceptor.injectForTesting() are done in a few strategic places just before Hilt does the injection
* into Android Components.
*
* As a result this class enables non-Hilt based frameworks to take over the injection process.
*/
public class TestInjectInterceptor {
/**
* This method always returns false by default. However, if this method is intercepted during testing
* by frameworks like Robolectric, the intercepting code can take over the injection process and
* instruct Hilt to skip doing anything extra for this instance.
*
* Return false if no custom injection was done and Hilt should continue as normal. Return true
* if the testing framework has takes over the injection process and Hilt should skip any extra
* work.
*/
public static boolean injectForTesting(Object injectTo) {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,9 @@ && ancestorExtendsGeneratedHiltClass(metadata)) {
methodSpecBuilder
.beginControlFlow("if (!injected)")
.addStatement("injected = true")
.beginControlFlow("if ($T.injectForTesting(this))", ClassNames.TEST_INJECT_INTERCEPTOR)
.addStatement("return")
.endControlFlow()
.addStatement(
"(($T) $L).$L($L)",
metadata.injectorClassName(),
Expand All @@ -395,6 +398,10 @@ && ancestorExtendsGeneratedHiltClass(metadata)) {
.beginControlFlow("if (!injected)")
.beginControlFlow("synchronized (injectedLock)")
.beginControlFlow("if (!injected)")
.beginControlFlow("if ($T.injectForTesting(this))", ClassNames.TEST_INJECT_INTERCEPTOR)
.addStatement("injected = true")
.addStatement("return")
.endControlFlow()
.addStatement(
"(($T) $T.generatedComponent(context)).$L($L)",
metadata.injectorClassName(),
Expand Down
3 changes: 2 additions & 1 deletion java/dagger/hilt/android/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Keep for the reflective cast done in EntryPoints.
# See b/183070411#comment4 for more info.
-keep,allowobfuscation,allowshrinking @dagger.hilt.android.EarlyEntryPoint class *
-keep,allowobfuscation,allowshrinking @dagger.hilt.android.EarlyEntryPoint class *
-assumenosideeffects class dagger.hilt.android.internal.managers.TestInjectInterceptor { *; }
2 changes: 1 addition & 1 deletion java/dagger/hilt/android/qualifiers/ActivityContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@

/** Annotation for a {@code Context} that corresponds to the activity. */
@Qualifier
@Retention(RetentionPolicy.CLASS)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
public @interface ActivityContext {}
3 changes: 3 additions & 0 deletions java/dagger/hilt/android/qualifiers/ApplicationContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
package dagger.hilt.android.qualifiers;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

/** Annotation for an Application Context dependency. */
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
public @interface ApplicationContext {}
2 changes: 2 additions & 0 deletions java/dagger/hilt/processor/internal/ClassNames.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ public final class ClassNames {
get("dagger.hilt.android.internal.testing", "InternalTestRoot");
public static final ClassName TEST_INJECTOR =
get("dagger.hilt.android.internal.testing", "TestInjector");

public static final ClassName TEST_INJECT_INTERCEPTOR = get("dagger.hilt.android.internal.managers", "TestInjectInterceptor");
public static final ClassName TEST_APPLICATION_COMPONENT_MANAGER =
get("dagger.hilt.android.internal.testing", "TestApplicationComponentManager");
public static final ClassName TEST_APPLICATION_COMPONENT_MANAGER_HOLDER =
Expand Down