1 /* 2 * Copyright 2021 The Android Open Source Project 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 @file:Suppress("UnstableApiUsage") 18 19 package androidx.build.lint 20 21 import com.android.tools.lint.checks.infrastructure.LintDetectorTest 22 import com.android.tools.lint.checks.infrastructure.TestFile 23 import com.android.tools.lint.checks.infrastructure.TestLintTask 24 import com.android.tools.lint.detector.api.Detector 25 import com.android.tools.lint.detector.api.Issue 26 import org.junit.Test 27 28 class TargetApiAnnotationUsageDetectorTest : LintDetectorTest() { getDetectornull29 override fun getDetector(): Detector = TargetApiAnnotationUsageDetector() 30 31 override fun getIssues(): List<Issue> = listOf(TargetApiAnnotationUsageDetector.ISSUE) 32 33 private fun checkTask(testFile: TestFile): TestLintTask { 34 return lint().files(java(annotationSource), testFile) 35 } 36 37 private val annotationSource = 38 """ 39 package android.annotation; 40 41 import static java.lang.annotation.ElementType.CONSTRUCTOR; 42 import static java.lang.annotation.ElementType.METHOD; 43 import static java.lang.annotation.ElementType.TYPE; 44 45 import java.lang.annotation.Retention; 46 import java.lang.annotation.RetentionPolicy; 47 import java.lang.annotation.Target; 48 49 @Target({TYPE, METHOD, CONSTRUCTOR}) 50 @Retention(RetentionPolicy.CLASS) 51 public @interface TargetApi { 52 int value(); 53 } 54 """ 55 .trimIndent() 56 57 @Test testAnnotationUsageJavanull58 fun testAnnotationUsageJava() { 59 val input = 60 java( 61 """ 62 package androidx.sample; 63 64 import android.annotation.TargetApi; 65 66 @TargetApi(24) 67 public class SampleClass { 68 @TargetApi(15) 69 public void method() { 70 // Stub 71 } 72 } 73 """ 74 .trimIndent() 75 ) 76 77 val expected = 78 """ 79 src/androidx/sample/SampleClass.java:5: Error: Use @RequiresApi instead of @TargetApi [BanTargetApiAnnotation] 80 @TargetApi(24) 81 ~~~~~~~~~~~~~~ 82 src/androidx/sample/SampleClass.java:7: Error: Use @RequiresApi instead of @TargetApi [BanTargetApiAnnotation] 83 @TargetApi(15) 84 ~~~~~~~~~~~~~~ 85 2 errors, 0 warnings 86 """ 87 .trimIndent() 88 89 val expectFixDiffs = 90 """ 91 Fix for src/androidx/sample/SampleClass.java line 5: Replace with `@RequiresApi`: 92 @@ -5 +5 93 - @TargetApi(24) 94 + @androidx.annotation.RequiresApi(24) 95 Fix for src/androidx/sample/SampleClass.java line 7: Replace with `@RequiresApi`: 96 @@ -7 +7 97 - @TargetApi(15) 98 + @androidx.annotation.RequiresApi(15) 99 """ 100 .trimIndent() 101 102 checkTask(input).run().expect(expected).expectFixDiffs(expectFixDiffs) 103 } 104 105 @Test testAnnotationUsageKtnull106 fun testAnnotationUsageKt() { 107 val input = 108 kotlin( 109 """ 110 package androidx.sample 111 112 import android.annotation.TargetApi 113 114 @TargetApi(24) 115 class SampleClass { 116 @TargetApi(15) 117 fun method() { 118 // Stub 119 } 120 } 121 """ 122 .trimIndent() 123 ) 124 125 val expected = 126 """ 127 src/androidx/sample/SampleClass.kt:5: Error: Use @RequiresApi instead of @TargetApi [BanTargetApiAnnotation] 128 @TargetApi(24) 129 ~~~~~~~~~~~~~~ 130 src/androidx/sample/SampleClass.kt:7: Error: Use @RequiresApi instead of @TargetApi [BanTargetApiAnnotation] 131 @TargetApi(15) 132 ~~~~~~~~~~~~~~ 133 2 errors, 0 warnings 134 """ 135 .trimIndent() 136 137 val expectFixDiffs = 138 """ 139 Fix for src/androidx/sample/SampleClass.kt line 5: Replace with `@RequiresApi`: 140 @@ -5 +5 141 - @TargetApi(24) 142 + @androidx.annotation.RequiresApi(24) 143 Fix for src/androidx/sample/SampleClass.kt line 7: Replace with `@RequiresApi`: 144 @@ -7 +7 145 - @TargetApi(15) 146 + @androidx.annotation.RequiresApi(15) 147 """ 148 .trimIndent() 149 150 checkTask(input).run().expect(expected).expectFixDiffs(expectFixDiffs) 151 } 152 } 153