1 /* 2 * Copyright (C) 2024 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.lint 18 19 import com.android.tools.lint.checks.infrastructure.TestFile 20 import com.android.tools.metalava.DriverTest 21 import com.android.tools.metalava.testing.java 22 import org.junit.Test 23 import org.junit.runners.Parameterized 24 25 /** Tests for the filtering of issues done by [ApiLint]. */ 26 class ApiLintFilteringTest(private val previouslyReleasedApiUse: PreviouslyReleasedApiUse) : 27 DriverTest() { 28 29 enum class PreviouslyReleasedApiUse { 30 WITH, 31 WITHOUT, 32 } 33 34 companion object { 35 /** Run each test with and without the previously released API. */ 36 @JvmStatic 37 @Parameterized.Parameters(name = "{0}") testParametersnull38 fun testParameters() = PreviouslyReleasedApiUse.values() 39 } 40 41 private fun checkFiltering( 42 sourceFiles: Array<TestFile>, 43 expectedIssuesWithoutPreviouslyReleasedApi: String, 44 previouslyReleasedApi: String, 45 expectedIssuesWithPreviouslyReleasedApi: String, 46 ) { 47 val (apiLint, expectedIssues) = 48 if (previouslyReleasedApiUse == PreviouslyReleasedApiUse.WITH) 49 Pair(previouslyReleasedApi, expectedIssuesWithPreviouslyReleasedApi) 50 else Pair("", expectedIssuesWithoutPreviouslyReleasedApi) 51 val expectedFail = if (expectedIssues == "") "" else DefaultLintErrorMessage 52 check( 53 apiLint = apiLint, 54 sourceFiles = sourceFiles, 55 expectedFail = expectedFail, 56 expectedIssues = expectedIssues, 57 ) 58 } 59 60 @Test test errors are ignored on previously released APIsnull61 fun `test errors are ignored on previously released APIs`() { 62 checkFiltering( 63 sourceFiles = 64 arrayOf( 65 java( 66 """ 67 package test.pkg; 68 public class Foo { 69 public void method(String s) {} 70 public int hashCode() {return 0;} 71 public String field; 72 } 73 """ 74 ), 75 ), 76 expectedIssuesWithoutPreviouslyReleasedApi = 77 """ 78 src/test/pkg/Foo.java:4: error: Must override both equals and hashCode; missing one in test.pkg.Foo [EqualsAndHashCode] 79 src/test/pkg/Foo.java:3: error: Missing nullability on parameter `s` in method `method` [MissingNullability] 80 src/test/pkg/Foo.java:5: error: Bare field field must be marked final, or moved behind accessors if mutable [MutableBareField] 81 src/test/pkg/Foo.java:5: error: Missing nullability on field `field` in class `class test.pkg.Foo` [MissingNullability] 82 """, 83 previouslyReleasedApi = 84 """ 85 // Signature format: 2.0 86 package test.pkg { 87 public class Foo { 88 method public void method(String); 89 method public int hashCode(); 90 field public String field; 91 } 92 } 93 """, 94 expectedIssuesWithPreviouslyReleasedApi = "", 95 ) 96 } 97 98 @Test test checkClass produced errors are treated as warnings on new members of previously released classesnull99 fun `test checkClass produced errors are treated as warnings on new members of previously released classes`() { 100 // The `EqualsAndHashCode` check is performed by `checkEquals()` which is called by 101 // `checkClass()` and so was previously only called for new classes. This test checks that 102 // behavior is maintained. 103 checkFiltering( 104 sourceFiles = 105 arrayOf( 106 java( 107 """ 108 package test.pkg; 109 public class Foo { 110 public void method(String s) {} 111 public String field; 112 public int hashCode() {return 0;} 113 } 114 """ 115 ), 116 ), 117 expectedIssuesWithoutPreviouslyReleasedApi = 118 """ 119 src/test/pkg/Foo.java:5: error: Must override both equals and hashCode; missing one in test.pkg.Foo [EqualsAndHashCode] 120 src/test/pkg/Foo.java:3: error: Missing nullability on parameter `s` in method `method` [MissingNullability] 121 src/test/pkg/Foo.java:4: error: Bare field field must be marked final, or moved behind accessors if mutable [MutableBareField] 122 src/test/pkg/Foo.java:4: error: Missing nullability on field `field` in class `class test.pkg.Foo` [MissingNullability] 123 """, 124 previouslyReleasedApi = 125 """ 126 // Signature format: 2.0 127 package test.pkg { 128 public class Foo { 129 } 130 } 131 """, 132 expectedIssuesWithPreviouslyReleasedApi = 133 // Notice that the `EqualsAndHashCode` issue is reported as a warning, not an error. 134 """ 135 src/test/pkg/Foo.java:5: warning: Must override both equals and hashCode; missing one in test.pkg.Foo (ErrorWhenNew) [EqualsAndHashCode] 136 src/test/pkg/Foo.java:3: error: Missing nullability on parameter `s` in method `method` [MissingNullability] 137 src/test/pkg/Foo.java:4: error: Bare field field must be marked final, or moved behind accessors if mutable [MutableBareField] 138 src/test/pkg/Foo.java:4: error: Missing nullability on field `field` in class `class test.pkg.Foo` [MissingNullability] 139 """, 140 ) 141 } 142 } 143