1 /* 2 * Copyright (C) 2017 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 com.android.tools.metalava 18 19 import com.android.tools.metalava.model.text.FileFormat 20 import com.android.tools.metalava.testing.java 21 import org.junit.Test 22 23 class NullabilityAnnotationsValidatorTest : DriverTest() { 24 25 @Test Empty report when all expected annotations presentnull26 fun `Empty report when all expected annotations present`() { 27 check( 28 sourceFiles = 29 arrayOf( 30 java( 31 """ 32 package test.pkg; 33 34 public interface Appendable { 35 Appendable append(CharSequence csq) throws IOException; 36 } 37 38 public interface List<T> { 39 T get(int index); 40 } 41 42 // This is not annotated at all, shouldn't complain about this. 43 public interface NotAnnotated { 44 NotAnnotated combine(NotAnnotated other); 45 } 46 """ 47 ), 48 libcoreNonNullSource, 49 libcoreNullableSource, 50 libcoreNullFromTypeParamSource 51 ), 52 format = FileFormat.V2, 53 mergeJavaStubAnnotations = 54 """ 55 package test.pkg; 56 57 import libcore.util.NonNull; 58 import libcore.util.Nullable; 59 import libcore.util.NullFromTypeParam; 60 61 public interface Appendable { 62 @NonNull Appendable append(@Nullable java.lang.CharSequence csq); 63 } 64 65 public interface List<T> { 66 @NullFromTypeParam T get(int index); 67 } 68 """, 69 extraArguments = arrayOf(ARG_VALIDATE_NULLABILITY_FROM_MERGED_STUBS), 70 validateNullability = setOf() 71 ) 72 } 73 74 @Test Missing parameter annotationnull75 fun `Missing parameter annotation`() { 76 check( 77 sourceFiles = 78 arrayOf( 79 java( 80 """ 81 package test.pkg; 82 83 public interface Appendable { 84 Appendable append(CharSequence csq) throws IOException; 85 } 86 87 public interface List<T> { 88 T get(int index); 89 } 90 """ 91 ), 92 libcoreNonNullSource, 93 libcoreNullFromTypeParamSource 94 ), 95 format = FileFormat.V2, 96 mergeJavaStubAnnotations = 97 """ 98 package test.pkg; 99 100 import libcore.util.NonNull; 101 import libcore.util.NullFromTypeParam; 102 103 public interface Appendable { 104 @NonNull Appendable append(java.lang.CharSequence csq); 105 } 106 107 public interface List<T> { 108 @NullFromTypeParam T get(int index); 109 } 110 """, 111 extraArguments = arrayOf(ARG_VALIDATE_NULLABILITY_FROM_MERGED_STUBS), 112 validateNullability = 113 setOf( 114 "WARNING: method test.pkg.Appendable.append(CharSequence), parameter csq, MISSING" 115 ) 116 ) 117 } 118 119 @Test Missing return type annotationsnull120 fun `Missing return type annotations`() { 121 check( 122 sourceFiles = 123 arrayOf( 124 java( 125 """ 126 package test.pkg; 127 128 public interface Appendable { 129 Appendable append(CharSequence csq) throws IOException; 130 } 131 132 public interface List<T> { 133 T get(int index); 134 } 135 """ 136 ), 137 libcoreNullableSource 138 ), 139 format = FileFormat.V2, 140 mergeJavaStubAnnotations = 141 """ 142 package test.pkg; 143 144 import libcore.util.Nullable; 145 146 public interface Appendable { 147 Appendable append(@Nullable java.lang.CharSequence csq); 148 } 149 150 public interface List<T> { 151 } 152 """, 153 extraArguments = arrayOf(ARG_VALIDATE_NULLABILITY_FROM_MERGED_STUBS), 154 validateNullability = 155 setOf( 156 "WARNING: method test.pkg.Appendable.append(CharSequence), return value, MISSING", 157 "WARNING: method test.pkg.List.get(int), return value, MISSING" 158 ) 159 ) 160 } 161 162 @Test Error from annotation on primitivenull163 fun `Error from annotation on primitive`() { 164 check( 165 sourceFiles = 166 arrayOf( 167 java( 168 """ 169 package test.pkg; 170 171 public interface Appendable { 172 Appendable append(CharSequence csq) throws IOException; 173 } 174 175 public interface List<T> { 176 T get(int index); 177 } 178 """ 179 ), 180 libcoreNonNullSource, 181 libcoreNullableSource, 182 libcoreNullFromTypeParamSource 183 ), 184 format = FileFormat.V2, 185 mergeJavaStubAnnotations = 186 """ 187 package test.pkg; 188 189 import libcore.util.NonNull; 190 import libcore.util.Nullable; 191 import libcore.util.NullFromTypeParam; 192 193 public interface Appendable { 194 @NonNull Appendable append(@Nullable java.lang.CharSequence csq); 195 } 196 197 public interface List<T> { 198 @NullFromTypeParam T get(@NonNull int index); 199 } 200 """, 201 extraArguments = arrayOf(ARG_VALIDATE_NULLABILITY_FROM_MERGED_STUBS), 202 validateNullability = 203 setOf("ERROR: method test.pkg.List.get(int), parameter index, ON_PRIMITIVE") 204 ) 205 } 206 207 @Test Error from NullFromTypeParam not on type paramnull208 fun `Error from NullFromTypeParam not on type param`() { 209 check( 210 sourceFiles = 211 arrayOf( 212 java( 213 """ 214 package test.pkg; 215 216 public interface Appendable { 217 Appendable append(CharSequence csq) throws IOException; 218 } 219 220 public interface List<T> { 221 T get(int index); 222 } 223 """ 224 ), 225 libcoreNullableSource, 226 libcoreNullFromTypeParamSource 227 ), 228 format = FileFormat.V2, 229 mergeJavaStubAnnotations = 230 """ 231 package test.pkg; 232 233 import libcore.util.Nullable; 234 import libcore.util.NullFromTypeParam; 235 236 public interface Appendable { 237 @NullFromTypeParam Appendable append(@Nullable java.lang.CharSequence csq); 238 } 239 240 public interface List<T> { 241 @NullFromTypeParam T get(int index); 242 } 243 """, 244 extraArguments = arrayOf(ARG_VALIDATE_NULLABILITY_FROM_MERGED_STUBS), 245 validateNullability = 246 setOf( 247 "ERROR: method test.pkg.Appendable.append(CharSequence), return value, BAD_TYPE_PARAM" 248 ) 249 ) 250 } 251 252 @Test Using class listnull253 fun `Using class list`() { 254 check( 255 sourceFiles = 256 arrayOf( 257 java( 258 """ 259 package test.pkg; 260 261 import libcore.util.Nullable; 262 263 // This will be validated. It is missing an annotation on its return type. 264 public interface Appendable { 265 Appendable append(@Nullable CharSequence csq) throws IOException; 266 } 267 268 // This is missing an annotation on its return type, but will not be validated. 269 public interface List<T> { 270 T get(int index); 271 } 272 """ 273 ), 274 libcoreNullableSource 275 ), 276 format = FileFormat.V2, 277 extraArguments = arrayOf(ARG_VALIDATE_NULLABILITY_FROM_MERGED_STUBS), 278 validateNullabilityFromList = 279 """ 280 # a comment, then a blank line, then the class to validate 281 282 test.pkg.Appendable 283 """, 284 validateNullability = 285 setOf( 286 "WARNING: method test.pkg.Appendable.append(CharSequence), return value, MISSING" 287 ) 288 ) 289 } 290 } 291