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.TestMode 22 import org.junit.Test 23 import org.junit.runner.RunWith 24 import org.junit.runners.JUnit4 25 26 @RunWith(JUnit4::class) 27 class BanConcurrentHashMapTest : 28 AbstractLintDetectorTest( 29 useDetector = BanConcurrentHashMap(), 30 useIssues = listOf(BanConcurrentHashMap.ISSUE), 31 ) { 32 33 @Test Detection of ConcurrentHashMap import in Java sourcesnull34 fun `Detection of ConcurrentHashMap import in Java sources`() { 35 val input = 36 java( 37 "src/androidx/ConcurrentHashMapImportJava.java", 38 """ 39 import androidx.annotation.NonNull; 40 import java.util.Map; 41 import java.util.concurrent.ConcurrentHashMap; 42 43 public class ConcurrentHashMapUsageJava { 44 private final Map<?, ?> mMap = new ConcurrentHashMap<>(); 45 46 public <V, K> Map<V, K> createMap() { 47 return new ConcurrentHashMap<>(); 48 } 49 } 50 """ 51 .trimIndent() 52 ) 53 54 val expected = 55 """ 56 src/androidx/ConcurrentHashMapImportJava.java:3: Error: Detected ConcurrentHashMap usage. [BanConcurrentHashMap] 57 import java.util.concurrent.ConcurrentHashMap; 58 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 59 1 errors, 0 warnings 60 """ 61 .trimIndent() 62 63 // Skip FULLY_QUALIFIED mode -- this test specifically deals with importing the class, and 64 // FULLY_QUALIFIED removes the import. Usages of the fully qualified type are tested below. 65 lint().files(input).skipTestModes(TestMode.FULLY_QUALIFIED).run().expect(expected) 66 } 67 68 @Test Detection of ConcurrentHashMap fully-qualified usage in Java sourcesnull69 fun `Detection of ConcurrentHashMap fully-qualified usage in Java sources`() { 70 val input = 71 java( 72 "src/androidx/ConcurrentHashMapUsageJava.java", 73 """ 74 import androidx.annotation.NonNull; 75 import java.util.Map; 76 77 public class ConcurrentHashMapUsageJava { 78 private final Map<?, ?> mMap = new java.util.concurrent.ConcurrentHashMap<>(); 79 80 public <V, K> Map<V, K> createMap() { 81 return new java.util.concurrent.ConcurrentHashMap<>(); 82 } 83 } 84 """ 85 .trimIndent() 86 ) 87 88 val expected = 89 """ 90 src/androidx/ConcurrentHashMapUsageJava.java:5: Error: Detected ConcurrentHashMap usage. [BanConcurrentHashMap] 91 private final Map<?, ?> mMap = new java.util.concurrent.ConcurrentHashMap<>(); 92 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 src/androidx/ConcurrentHashMapUsageJava.java:8: Error: Detected ConcurrentHashMap usage. [BanConcurrentHashMap] 94 return new java.util.concurrent.ConcurrentHashMap<>(); 95 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 96 2 errors, 0 warnings 97 """ 98 .trimIndent() 99 100 check(input).expect(expected) 101 } 102 103 @Test Detection of ConcurrentHashMap import in Kotlin sourcesnull104 fun `Detection of ConcurrentHashMap import in Kotlin sources`() { 105 val input = 106 kotlin( 107 "src/androidx/ConcurrentHashMapImportKotlin.kt", 108 """ 109 package androidx 110 111 import java.util.concurrent.ConcurrentHashMap 112 113 class ConcurrentHashMapUsageKotlin { 114 private val mMap: ConcurrentHashMap<*, *> = ConcurrentHashMap<Any, Any>() 115 116 fun <V, K> createMap(): Map<V, K> { 117 return ConcurrentHashMap() 118 } 119 } 120 """ 121 .trimIndent() 122 ) 123 124 val expected = 125 """ 126 src/androidx/ConcurrentHashMapImportKotlin.kt:3: Error: Detected ConcurrentHashMap usage. [BanConcurrentHashMap] 127 import java.util.concurrent.ConcurrentHashMap 128 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 129 1 errors, 0 warnings 130 """ 131 .trimIndent() 132 133 lint() 134 .files(*stubs, input) 135 // This fails in IMPORT_ALIAS mode because changing the import line changes the error. 136 // It fails in FULLY_QUALIFIED mode because more errors occur when the fully-qualified 137 // class is used. These cases are tested separately. 138 .skipTestModes(TestMode.IMPORT_ALIAS, TestMode.FULLY_QUALIFIED) 139 .run() 140 .expect(expected) 141 } 142 143 @Test Detection of ConcurrentHashMap fully-qualified usage in Kotlin sourcesnull144 fun `Detection of ConcurrentHashMap fully-qualified usage in Kotlin sources`() { 145 val input = 146 kotlin( 147 "src/androidx/ConcurrentHashMapUsageKotlin.kt", 148 """ 149 package androidx 150 151 class ConcurrentHashMapUsageKotlin { 152 private val mMap: Map<*, *> = java.util.concurrent.ConcurrentHashMap<Any, Any>() 153 154 fun <V, K> createMap(): Map<V, K> { 155 return java.util.concurrent.ConcurrentHashMap() 156 } 157 } 158 """ 159 .trimIndent() 160 ) 161 162 val expected = 163 """ 164 src/androidx/ConcurrentHashMapUsageKotlin.kt:4: Error: Detected ConcurrentHashMap usage. [BanConcurrentHashMap] 165 private val mMap: Map<*, *> = java.util.concurrent.ConcurrentHashMap<Any, Any>() 166 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 src/androidx/ConcurrentHashMapUsageKotlin.kt:7: Error: Detected ConcurrentHashMap usage. [BanConcurrentHashMap] 168 return java.util.concurrent.ConcurrentHashMap() 169 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 170 2 errors, 0 warnings 171 """ 172 .trimIndent() 173 174 lint().files(*stubs, input).run().expect(expected) 175 } 176 177 @Test Detection of ConcurrentHashMap import alias in Kotlin sourcesnull178 fun `Detection of ConcurrentHashMap import alias in Kotlin sources`() { 179 val input = 180 kotlin( 181 "src/androidx/ConcurrentHashMapUsageAliasKotlin.kt", 182 """ 183 package androidx 184 185 import java.util.concurrent.ConcurrentHashMap as NewClassName 186 187 class ConcurrentHashMapUsageAliasKotlin { 188 private val mMap: Map<*, *> = NewClassName<Any, Any>() 189 190 fun <V, K> createMap(): Map<V, K> { 191 return NewClassName() 192 } 193 } 194 """ 195 .trimIndent() 196 ) 197 198 val expected = 199 """ 200 src/androidx/ConcurrentHashMapUsageAliasKotlin.kt:3: Error: Detected ConcurrentHashMap usage. [BanConcurrentHashMap] 201 import java.util.concurrent.ConcurrentHashMap as NewClassName 202 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 203 1 errors, 0 warnings 204 """ 205 .trimIndent() 206 207 lint() 208 .files(*stubs, input) 209 // In FULLY_QUALIFIED test mode, more errors occur when the fully-qualified class is 210 // used. This case is tested separately. 211 .skipTestModes(TestMode.FULLY_QUALIFIED) 212 .run() 213 .expect(expected) 214 } 215 } 216