1 /* 2 * Copyright 2022 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 package androidx.build.lint 18 19 import org.junit.Test 20 import org.junit.runner.RunWith 21 import org.junit.runners.JUnit4 22 23 @RunWith(JUnit4::class) 24 class MissingJvmDefaultWithCompatibilityDetectorTest : 25 AbstractLintDetectorTest( 26 useDetector = MissingJvmDefaultWithCompatibilityDetector(), 27 useIssues = listOf(MissingJvmDefaultWithCompatibilityDetector.ISSUE), 28 ) { 29 @Test Test lint for interface with stable default methodnull30 fun `Test lint for interface with stable default method`() { 31 val input = 32 arrayOf( 33 kotlin( 34 """ 35 package java.androidx 36 37 interface InterfaceWithDefaultMethod { 38 fun methodWithoutDefaultImplementation(foo: Int): String 39 fun methodWithDefaultImplementation(): Int = 3 40 } 41 """ 42 ) 43 ) 44 45 val expected = 46 """ 47 src/java/androidx/InterfaceWithDefaultMethod.kt:4: Error: This interface must be annotated with @JvmDefaultWithCompatibility because it has a stable method with a default implementation [MissingJvmDefaultWithCompatibility] 48 interface InterfaceWithDefaultMethod { 49 ^ 50 1 errors, 0 warnings 51 """ 52 53 val expectedFixDiffs = 54 """ 55 Autofix for src/java/androidx/InterfaceWithDefaultMethod.kt line 4: Annotate with @JvmDefaultWithCompatibility: 56 @@ -4 +4 57 + @JvmDefaultWithCompatibility 58 """ 59 60 check(*input).expect(expected).expectFixDiffs(expectedFixDiffs) 61 } 62 63 @Test Test lint for interface with stable method with default parameternull64 fun `Test lint for interface with stable method with default parameter`() { 65 val input = 66 arrayOf( 67 kotlin( 68 """ 69 package java.androidx 70 71 interface InterfaceWithMethodWithDefaultParameterValue { 72 fun methodWithDefaultParameterValue(foo: Int = 3): Int 73 } 74 """ 75 ) 76 ) 77 78 val expected = 79 """ 80 src/java/androidx/InterfaceWithMethodWithDefaultParameterValue.kt:4: Error: This interface must be annotated with @JvmDefaultWithCompatibility because it has a stable method with a parameter with a default value [MissingJvmDefaultWithCompatibility] 81 interface InterfaceWithMethodWithDefaultParameterValue { 82 ^ 83 1 errors, 0 warnings 84 """ 85 86 val expectedFixDiffs = 87 """ 88 Autofix for src/java/androidx/InterfaceWithMethodWithDefaultParameterValue.kt line 4: Annotate with @JvmDefaultWithCompatibility: 89 @@ -4 +4 90 + @JvmDefaultWithCompatibility 91 """ 92 93 check(*input).expect(expected).expectFixDiffs(expectedFixDiffs) 94 } 95 96 @Test Test lint for interface implementing @JvmDefaultWithCompatibility interfacenull97 fun `Test lint for interface implementing @JvmDefaultWithCompatibility interface`() { 98 val input = 99 arrayOf( 100 kotlin( 101 """ 102 package java.androidx 103 104 import kotlin.jvm.JvmDefaultWithCompatibility 105 106 @JvmDefaultWithCompatibility 107 interface InterfaceWithAnnotation { 108 fun foo(bar: Int = 3): Int 109 } 110 """ 111 ), 112 kotlin( 113 """ 114 package java.androidx 115 116 interface InterfaceWithoutAnnotation: InterfaceWithAnnotation { 117 fun baz(): Int 118 } 119 """ 120 ), 121 Stubs.JvmDefaultWithCompatibility 122 ) 123 124 val expected = 125 """ 126 src/java/androidx/InterfaceWithoutAnnotation.kt:4: Error: This interface must be annotated with @JvmDefaultWithCompatibility because it implements an interface which uses this annotation [MissingJvmDefaultWithCompatibility] 127 interface InterfaceWithoutAnnotation: InterfaceWithAnnotation { 128 ^ 129 1 errors, 0 warnings 130 """ 131 132 val expectedFixDiffs = 133 """ 134 Autofix for src/java/androidx/InterfaceWithoutAnnotation.kt line 4: Annotate with @JvmDefaultWithCompatibility: 135 @@ -4 +4 136 + @JvmDefaultWithCompatibility 137 """ 138 .trimIndent() 139 140 check(*input).expect(expected).expectFixDiffs(expectedFixDiffs) 141 } 142 143 @Test Test lint does not apply to interface implementing @JvmDefaultWithCompatibilitynull144 fun `Test lint does not apply to interface implementing @JvmDefaultWithCompatibility`() { 145 val input = 146 arrayOf( 147 kotlin( 148 """ 149 package java.androidx 150 151 import kotlin.jvm.JvmDefaultWithCompatibility 152 153 @JvmDefaultWithCompatibility 154 interface InterfaceWithAnnotation { 155 fun foo(bar: Int = 3): Int = 4 156 } 157 """ 158 ), 159 Stubs.JvmDefaultWithCompatibility 160 ) 161 162 check(*input).expectClean() 163 } 164 165 @Test Test lint does not apply to unstable interfacenull166 fun `Test lint does not apply to unstable interface`() { 167 val input = 168 arrayOf( 169 kotlin( 170 """ 171 package java.androidx 172 173 @RequiresOptIn 174 interface UnstableInterface { 175 fun foo(bar: Int = 3): Int = 4 176 } 177 """ 178 ), 179 Stubs.OptIn 180 ) 181 182 check(*input).expectClean() 183 } 184 185 @Test Test lint does not apply to interface with no stable methodsnull186 fun `Test lint does not apply to interface with no stable methods`() { 187 val input = 188 arrayOf( 189 kotlin( 190 """ 191 package java.androidx 192 193 interface InterfaceWithoutStableMethods { 194 @RequiresOptIn 195 fun unstableMethod(foo: Int = 3): Int = 4 196 } 197 """ 198 ), 199 Stubs.OptIn 200 ) 201 202 check(*input).expectClean() 203 } 204 205 @Test Test lint does apply to interface with one unstable method and one stable methodnull206 fun `Test lint does apply to interface with one unstable method and one stable method`() { 207 val input = 208 arrayOf( 209 kotlin( 210 """ 211 package java.androidx 212 213 interface InterfaceWithStableAndUnstableMethods { 214 @RequiresOptIn 215 fun unstableMethod(foo: Int = 3): Int = 4 216 fun stableMethod(foo: Int = 3): Int = 4 217 } 218 """ 219 ), 220 Stubs.OptIn 221 ) 222 223 val expected = 224 """ 225 src/java/androidx/InterfaceWithStableAndUnstableMethods.kt:4: Error: This interface must be annotated with @JvmDefaultWithCompatibility because it has a stable method with a default implementation [MissingJvmDefaultWithCompatibility] 226 interface InterfaceWithStableAndUnstableMethods { 227 ^ 228 1 errors, 0 warnings 229 """ 230 231 val expectedFixDiffs = 232 """ 233 Autofix for src/java/androidx/InterfaceWithStableAndUnstableMethods.kt line 4: Annotate with @JvmDefaultWithCompatibility: 234 @@ -4 +4 235 + @JvmDefaultWithCompatibility 236 """ 237 .trimIndent() 238 239 check(*input).expect(expected).expectFixDiffs(expectedFixDiffs) 240 } 241 242 @Test Test lint does not apply to interface with no default methodsnull243 fun `Test lint does not apply to interface with no default methods`() { 244 val input = 245 arrayOf( 246 kotlin( 247 """ 248 package java.androidx 249 250 interface InterfaceWithoutDefaults { 251 fun methodWithoutDefaults(foo: Int): Int 252 } 253 """ 254 ) 255 ) 256 257 check(*input).expectClean() 258 } 259 260 @Test Test lint does not apply to Java filenull261 fun `Test lint does not apply to Java file`() { 262 val input = 263 arrayOf( 264 java( 265 """ 266 package java.androidx; 267 268 interface JavaInterface { 269 static int staticMethodInInterface() { 270 return 3; 271 } 272 } 273 """ 274 ) 275 ) 276 277 check(*input).expectClean() 278 } 279 } 280