blob: 6df8cc15a83a1e5a2041574e71945e2f79bb4a71 [file] [log] [blame]
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.build.lint
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class DeprecationMismatchDetectorTest :
AbstractLintDetectorTest(
useDetector = DeprecationMismatchDetector(),
useIssues = listOf(DeprecationMismatchDetector.ISSUE),
) {
@Test
fun `Test correctly matched @deprecated and @Deprecated`() {
val input =
arrayOf(
java(
"""
package java.androidx;
/**
* @deprecated Foo is deprecated
*/
@Deprecated
public class Foo {
/**
* @deprecated foo is deprecated
*/
@Deprecated
public void foo() {}
/**
* @deprecated FOO is deprecated
*/
@Deprecated
public static int FOO = 0;
/**
* @deprecated InnerFoo is deprecated
*/
@Deprecated
public interface InnerFoo {}
}
"""
.trimIndent()
)
)
check(*input).expectClean()
}
@Test
fun `Test @deprecated missing @Deprecated`() {
val input =
arrayOf(
java(
"""
package java.androidx;
/**
* @deprecated Foo is deprecated
*/
public class Foo {
/**
* @deprecated foo is deprecated
*/
public void foo() {}
/**
* @deprecated FOO is deprecated
*/
public static int FOO = 0;
/**
* @deprecated InnerFoo is deprecated
*/
public interface InnerFoo {}
}
"""
.trimIndent()
)
)
val expected =
"""
src/java/androidx/Foo.java:6: Error: Items with a @deprecated doc tag must be annotated with @Deprecated [DeprecationMismatch]
public class Foo {
~~~
src/java/androidx/Foo.java:10: Error: Items with a @deprecated doc tag must be annotated with @Deprecated [DeprecationMismatch]
public void foo() {}
~~~
src/java/androidx/Foo.java:15: Error: Items with a @deprecated doc tag must be annotated with @Deprecated [DeprecationMismatch]
public static int FOO = 0;
~~~
src/java/androidx/Foo.java:20: Error: Items with a @deprecated doc tag must be annotated with @Deprecated [DeprecationMismatch]
public interface InnerFoo {}
~~~~~~~~
4 errors, 0 warnings
"""
.trimIndent()
val expectedFixDiffs =
"""
Autofix for src/java/androidx/Foo.java line 6: Annotate with @Deprecated:
@@ -6 +6
+ @Deprecated
Autofix for src/java/androidx/Foo.java line 10: Annotate with @Deprecated:
@@ -10 +10
+ @Deprecated
Autofix for src/java/androidx/Foo.java line 15: Annotate with @Deprecated:
@@ -15 +15
+ @Deprecated
Autofix for src/java/androidx/Foo.java line 20: Annotate with @Deprecated:
@@ -20 +20
+ @Deprecated
"""
.trimIndent()
check(*input).expect(expected).expectFixDiffs(expectedFixDiffs)
}
@Test
fun `Test @Deprecated missing @deprecated`() {
val input =
arrayOf(
java(
"""
package java.androidx;
@Deprecated
public class Foo {
@Deprecated
public void foo() {}
@Deprecated
public static int FOO = 0;
@Deprecated
public interface InnerFoo {}
}
"""
.trimIndent()
)
)
val expected =
"""
src/java/androidx/Foo.java:4: Error: Items annotated with @Deprecated must have a @deprecated doc tag [DeprecationMismatch]
public class Foo {
~~~
src/java/androidx/Foo.java:6: Error: Items annotated with @Deprecated must have a @deprecated doc tag [DeprecationMismatch]
public void foo() {}
~~~
src/java/androidx/Foo.java:9: Error: Items annotated with @Deprecated must have a @deprecated doc tag [DeprecationMismatch]
public static int FOO = 0;
~~~
src/java/androidx/Foo.java:12: Error: Items annotated with @Deprecated must have a @deprecated doc tag [DeprecationMismatch]
public interface InnerFoo {}
~~~~~~~~
4 errors, 0 warnings
"""
.trimIndent()
check(*input).expect(expected)
}
@Test
fun `Test @deprecated not required for private APIs`() {
val input =
arrayOf(
java(
"""
package java.androidx;
@Deprecated
private class Foo {
@Deprecated
private void foo() {}
@Deprecated
private static int FOO = 0;
@Deprecated
private interface InnerFoo {}
}
"""
.trimIndent()
)
)
check(*input).expectClean()
}
@Test
fun `Test @deprecated not required for proto-generated APIs`() {
val input =
arrayOf(
java(
"""
// Generated by the protocol buffer compiler. DO NOT EDIT!
package java.androidx.proto;
@Deprecated
public class Foo {
@Deprecated
public void foo() {}
@Deprecated
public static int FOO = 0;
@Deprecated
public interface InnerFoo {}
}
"""
.trimIndent()
)
)
check(*input).expectClean()
}
@Test
fun `Test anonymous classes don't need @deprecated`() {
val input =
arrayOf(
java(
"""
package java.androidx;
/**
* @deprecated Foo is deprecated
*/
@Deprecated
public abstract class Foo<T> {
/**
* @deprecated foo is deprecated
*/
@Deprecated
public void foo();
}
"""
.trimIndent()
),
java(
"""
package java.androidx;
public class Bar {
public static void bar() {
new Foo<String>() {
@Override
public void foo() {}
}.foo();
}
}
"""
.trimIndent()
)
)
check(*input).expectClean()
}
@Test
fun `Test @RestrictTo APIs don't need @deprecated`() {
val input =
arrayOf(
java(
"""
package java.androidx;
import androidx.annotation.RestrictTo;
@RestrictTo(RestrictTo.Scope.LIBRARY)
@Deprecated
public class Foo {
@Deprecated
private void foo() {}
@Deprecated
private static int FOO = 0;
@Deprecated
private interface InnerFoo {}
}
"""
.trimIndent()
),
Stubs.RestrictTo
)
check(*input).expectClean()
}
@Test
fun `Test overriding methods don't need @deprecated`() {
val input =
arrayOf(
java(
"""
package java.androidX;
public interface MyInterface {
/** @deprecated Use XYZ instead. */
@Deprecated
void inheritedNoComment();
/** @deprecated Use XYZ instead. */
@Deprecated
void inheritedWithComment();
/** @deprecated Use XYZ instead. */
@Deprecated
void inheritedWithInheritDoc();
}
""",
),
java(
"""
package test.pkg;
public class MyClass implements MyInterface {
@Deprecated
@Override
public void inheritedNoComment() {}
/** @deprecated Use XYZ instead. */
@Deprecated
@Override
public void inheritedWithComment() {}
/** {@inheritDoc} */
@Deprecated
@Override
public void inheritedWithInheritDoc() {}
}
"""
)
)
check(*input).expectClean()
}
}