1 /*
2  * Copyright 2023 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 org.junit.Test
22 import org.junit.runner.RunWith
23 import org.junit.runners.JUnit4
24 
25 @RunWith(JUnit4::class)
26 class ObsoleteCompatDetectorTest :
27     AbstractLintDetectorTest(
28         useDetector = ObsoleteCompatDetector(),
29         useIssues = listOf(ObsoleteCompatDetector.ISSUE),
30         stubs =
31             arrayOf(
32                 java(
33                     """
34         package androidx.annotation;
35 
36         import static java.lang.annotation.ElementType.CONSTRUCTOR;
37         import static java.lang.annotation.ElementType.FIELD;
38         import static java.lang.annotation.ElementType.METHOD;
39 
40         import java.lang.annotation.Target;
41 
42         @Target({METHOD, FIELD, CONSTRUCTOR})
43         public @interface ReplaceWith {
44             String expression();
45         }
46     """
47                 )
48             )
49     ) {
50 
51     @Test
Obsolete compat methodnull52     fun `Obsolete compat method`() {
53         val input =
54             arrayOf(
55                 javaSample("androidx.ObsoleteCompatMethod"),
56             )
57 
58         val expected =
59             """
60 src/androidx/ObsoleteCompatMethod.java:33: Error: Obsolete compat method should provide replacement [ObsoleteCompatMethod]
61     public static long hashCode(Object obj) {
62                        ~~~~~~~~
63 src/androidx/ObsoleteCompatMethod.java:38: Error: Obsolete compat method should provide replacement [ObsoleteCompatMethod]
64     public static long hashCodeNoDoc(Object obj) {
65                        ~~~~~~~~~~~~~
66 2 errors, 0 warnings
67         """
68                 .trimIndent()
69 
70         val expectedAutoFix =
71             """
72 Fix for src/androidx/ObsoleteCompatMethod.java line 33: Replace obsolete compat method:
73 @@ -20 +20
74 + import androidx.annotation.ReplaceWith;
75 @@ -32 +33
76 +      * @deprecated Call {@link Object#hashCode()} directly.
77 @@ -33 +35
78 +     @Deprecated
79 +     @ReplaceWith(expression = "obj.hashCode()")
80 Fix for src/androidx/ObsoleteCompatMethod.java line 38: Replace obsolete compat method:
81 @@ -20 +20
82 + import androidx.annotation.ReplaceWith;
83 @@ -38 +39
84 +     @Deprecated
85 +     @ReplaceWith(expression = "obj.hashCode()")
86 +     /** @deprecated Call {@link Object#hashCode()} directly. */
87         """
88                 .trimIndent()
89 
90         check(*input).expect(expected).expectFixDiffs(expectedAutoFix)
91     }
92 
93     @Test
Obsolete compat method missing @ReplaceWithnull94     fun `Obsolete compat method missing @ReplaceWith`() {
95         val input =
96             arrayOf(
97                 javaSample("androidx.ObsoleteCompatMethodMissingReplaceWith"),
98             )
99 
100         val expected =
101             """
102 src/androidx/ObsoleteCompatMethodMissingReplaceWith.java:32: Error: Obsolete compat method should provide replacement [ObsoleteCompatMethod]
103     public static long hashCode(Object obj) {
104                        ~~~~~~~~
105 1 errors, 0 warnings
106         """
107                 .trimIndent()
108 
109         val expectedAutoFix =
110             """
111 Autofix for src/androidx/ObsoleteCompatMethodMissingReplaceWith.java line 32: Replace obsolete compat method:
112 @@ -18 +18
113 + import androidx.annotation.ReplaceWith;
114 @@ -31 +32
115 +     @ReplaceWith(expression = "obj.hashCode()")
116         """
117                 .trimIndent()
118 
119         check(*input).expect(expected).expectFixDiffs(expectedAutoFix)
120     }
121 
122     @Test
Obsolete compat method missing multi-line @ReplaceWithnull123     fun `Obsolete compat method missing multi-line @ReplaceWith`() {
124         val input =
125             arrayOf(
126                 javaSample("androidx.ObsoleteCompatMethodMissingMultiLineReplaceWith"),
127             )
128 
129         val expected =
130             """
131 src/androidx/ObsoleteCompatMethodMissingMultiLineReplaceWith.java:32: Error: Obsolete compat method should provide replacement [ObsoleteCompatMethod]
132     public static long hashCode(Object obj) {
133                        ~~~~~~~~
134 1 errors, 0 warnings
135         """
136                 .trimIndent()
137 
138         val expectedAutoFix =
139             """
140 Autofix for src/androidx/ObsoleteCompatMethodMissingMultiLineReplaceWith.java line 32: Replace obsolete compat method:
141 @@ -18 +18
142 + import androidx.annotation.ReplaceWith;
143 @@ -31 +32
144 +     @ReplaceWith(expression = "obj.hashCode()")
145         """
146                 .trimIndent()
147 
148         check(*input).expect(expected).expectFixDiffs(expectedAutoFix)
149     }
150 
151     @Test
Obsolete compat methods missing @Deprecatednull152     fun `Obsolete compat methods missing @Deprecated`() {
153         val input =
154             arrayOf(
155                 javaSample("androidx.ObsoleteCompatMethodMissingDeprecated"),
156             )
157 
158         val expected =
159             """
160 src/androidx/ObsoleteCompatMethodMissingDeprecated.java:37: Error: Obsolete compat method should provide replacement [ObsoleteCompatMethod]
161     public static long hashCode(Object obj) {
162                        ~~~~~~~~
163 1 errors, 0 warnings
164         """
165                 .trimIndent()
166 
167         val expectedAutoFix =
168             """
169 Autofix for src/androidx/ObsoleteCompatMethodMissingDeprecated.java line 37: Replace obsolete compat method:
170 @@ -36 +36
171 +     @Deprecated
172         """
173                 .trimIndent()
174 
175         check(*input).expect(expected).expectFixDiffs(expectedAutoFix)
176     }
177 
178     @Test
Obsolete compat methods missing javadocnull179     fun `Obsolete compat methods missing javadoc`() {
180         val input =
181             arrayOf(
182                 javaSample("androidx.ObsoleteCompatMethodMissingJavadoc"),
183             )
184 
185         val expected =
186             """
187 src/androidx/ObsoleteCompatMethodMissingJavadoc.java:37: Error: Obsolete compat method should provide replacement [ObsoleteCompatMethod]
188     public static long hashCode(Object obj) {
189                        ~~~~~~~~
190 src/androidx/ObsoleteCompatMethodMissingJavadoc.java:44: Error: Obsolete compat method should provide replacement [ObsoleteCompatMethod]
191     public static long hashCodeNoDoc(Object obj) {
192                        ~~~~~~~~~~~~~
193 2 errors, 0 warnings
194         """
195                 .trimIndent()
196 
197         val expectedAutoFix =
198             """
199 Autofix for src/androidx/ObsoleteCompatMethodMissingJavadoc.java line 37: Replace obsolete compat method:
200 @@ -34 +34
201 +      * @deprecated Call {@link Object#hashCode()} directly.
202 Autofix for src/androidx/ObsoleteCompatMethodMissingJavadoc.java line 44: Replace obsolete compat method:
203 @@ -42 +42
204 +     /** @deprecated Call {@link Object#hashCode()} directly. */
205         """
206                 .trimIndent()
207 
208         check(*input).expect(expected).expectFixDiffs(expectedAutoFix)
209     }
210 
211     @Test
Obsolete compat methods missing Deprecated and javadocnull212     fun `Obsolete compat methods missing Deprecated and javadoc`() {
213         val input =
214             arrayOf(
215                 javaSample("androidx.ObsoleteCompatMethodMissingDeprecatedAndJavadoc"),
216             )
217 
218         val expected =
219             """
220 src/androidx/ObsoleteCompatMethodMissingDeprecatedAndJavadoc.java:36: Error: Obsolete compat method should provide replacement [ObsoleteCompatMethod]
221     public static long hashCode(Object obj) {
222                        ~~~~~~~~
223 src/androidx/ObsoleteCompatMethodMissingDeprecatedAndJavadoc.java:42: Error: Obsolete compat method should provide replacement [ObsoleteCompatMethod]
224     public static long hashCodeNoDoc(Object obj) {
225                        ~~~~~~~~~~~~~
226 2 errors, 0 warnings
227         """
228                 .trimIndent()
229 
230         val expectedAutoFix =
231             """
232 Fix for src/androidx/ObsoleteCompatMethodMissingDeprecatedAndJavadoc.java line 36: Replace obsolete compat method:
233 @@ -34 +34
234 +      * @deprecated Call {@link Object#hashCode()} directly.
235 @@ -35 +36
236 +     @Deprecated
237 Fix for src/androidx/ObsoleteCompatMethodMissingDeprecatedAndJavadoc.java line 42: Replace obsolete compat method:
238 @@ -41 +41
239 +     @Deprecated
240 +     /** @deprecated Call {@link Object#hashCode()} directly. */
241         """
242                 .trimIndent()
243 
244         check(*input).expect(expected).expectFixDiffs(expectedAutoFix)
245     }
246 }
247