1 package leakcanary
2 
3 import kotlin.annotation.AnnotationRetention.RUNTIME
4 import kotlin.annotation.AnnotationTarget.CLASS
5 import kotlin.annotation.AnnotationTarget.FUNCTION
6 import leakcanary.SkipLeakDetection.Companion.shouldSkipTest
7 import org.junit.runner.Description
8 import shark.SharkLog
9 
10 /**
11  * Annotation for skipping leak detection in a UI test that calls
12  * [LeakAssertions.assertNoLeaks]. This annotation is useful to skip a leak detection in
13  * a test until the leaks are fixed.
14  *
15  * The check is performed by [shouldSkipTest] which is called by [AndroidDetectLeaksAssert],
16  * which requires that the [TestDescriptionHolder] rule be applied and
17  * evaluating when [LeakAssertions.assertNoLeaks] is called.
18  *
19  * [message] should contain an explanation of why leak detection is skipped, e.g. a reference to a
20  * filed issue.
21  *
22  * The optional [assertionTags] allows finer grained filtering based on the tag value passed to
23  * [LeakAssertions.assertNoLeaks]. If [assertionTags] is empty, then the test will
24  * skip leak detection entirely. If [assertionTags] is not empty, then the test will skip leak
25  * detection for any call to [LeakAssertions.assertNoLeaks] with a tag value contained in
26  * [assertionTags].
27  */
28 @Retention(RUNTIME)
29 @Target(CLASS, FUNCTION)
30 annotation class SkipLeakDetection(val message: String, vararg val assertionTags: String) {
31   companion object {
shouldSkipTestnull32     fun shouldSkipTest(testDescription: Description, assertionTag: String): Boolean {
33       val skipAnnotation =
34         testDescription.getAnnotation(SkipLeakDetection::class.java)
35       return shouldSkipTest(testDescription.displayName, skipAnnotation, assertionTag)
36     }
37 
shouldSkipTestnull38     fun shouldSkipTest(
39       testName: String,
40       skipAnnotation: SkipLeakDetection?,
41       assertionTag: String
42     ): Boolean {
43       if (skipAnnotation != null) {
44         val assertionTags = skipAnnotation.assertionTags
45         if (assertionTags.isEmpty()) {
46           SharkLog.d { "Skipping leak detection for $testName, message: ${skipAnnotation.message}" }
47           return true
48         } else if (assertionTag in assertionTags) {
49           SharkLog.d {
50             "Skipping [$assertionTag] leak detection for $testName, " +
51               "message: ${skipAnnotation.message}"
52           }
53           return true
54         }
55       }
56       return false
57     }
58   }
59 }
60 
61