1 /*
2  * Copyright (C) 2019 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.class2nonsdklist;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.testng.Assert.expectThrows;
22 import static org.testng.Assert.assertThrows;
23 
24 import com.android.annotationvisitor.AnnotationHandlerTestBase;
25 
26 import org.junit.Test;
27 
28 import java.util.Arrays;
29 import java.util.Collections;
30 import java.util.HashSet;
31 import java.util.Set;
32 
33 public class ApiResolverTest extends AnnotationHandlerTestBase {
34     @Test
testFindPublicAlternativeExactly()35     public void testFindPublicAlternativeExactly() throws Exception {
36         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>(
37                 Arrays.asList("La/b/C;->foo(I)V", "La/b/C;->bar(I)V")));
38         ApiResolver resolver = new ApiResolver(publicApis);
39         resolver.resolvePublicAlternatives("{@link a.b.C#foo(int)}", "Lb/c/D;->bar()V", 1);
40     }
41 
42     @Test
testFindPublicAlternativeDeducedPackageName()43     public void testFindPublicAlternativeDeducedPackageName() throws Exception {
44         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>(
45                 Arrays.asList("La/b/C;->foo(I)V", "La/b/C;->bar(I)V")));
46         ApiResolver resolver = new ApiResolver(publicApis);
47         resolver.resolvePublicAlternatives("{@link C#foo(int)}", "La/b/D;->bar()V", 1);
48     }
49 
50     @Test
testFindPublicAlternativeDeducedPackageAndClassName()51     public void testFindPublicAlternativeDeducedPackageAndClassName() throws Exception {
52         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>(
53                 Arrays.asList("La/b/C;->foo(I)V", "La/b/C;->bar(I)V")));
54         ApiResolver resolver = new ApiResolver(publicApis);
55         resolver.resolvePublicAlternatives("{@link #foo(int)}", "La/b/C;->bar()V", 1);
56     }
57 
58     @Test
testFindPublicAlternativeDeducedParameterTypes()59     public void testFindPublicAlternativeDeducedParameterTypes() throws Exception {
60         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>(
61                 Arrays.asList("La/b/C;->foo(I)V", "La/b/C;->bar(I)V")));
62         ApiResolver resolver = new ApiResolver(publicApis);
63         resolver.resolvePublicAlternatives("{@link #foo}", "La/b/C;->bar()V", 1);
64     }
65 
66     @Test
testFindPublicAlternativeWarnsOnMultipleParameterTypes()67     public void testFindPublicAlternativeWarnsOnMultipleParameterTypes()
68             throws SignatureSyntaxError {
69         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>(
70                 Arrays.asList("La/b/C;->foo(I)V", "La/b/C;->bar(I)I", "La/b/C;->foo(II)V")));
71         ApiResolver resolver = new ApiResolver(publicApis);
72         MultipleAlternativesFoundWarning e = expectThrows(MultipleAlternativesFoundWarning.class,
73                 () -> resolver.resolvePublicAlternatives("{@link #foo}", "La/b/C;->bar()V", 1));
74         assertThat(e.almostMatches).containsExactly(
75                 ApiComponents.fromDexSignature("La/b/C;->foo(I)V"),
76                 ApiComponents.fromDexSignature("La/b/C;->foo(II)V")
77         );
78     }
79 
80     @Test
testFindPublicAlternativeFailNoAlternative()81     public void testFindPublicAlternativeFailNoAlternative() {
82         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>(
83                 Arrays.asList("La/b/C;->bar(I)V")));
84         ApiResolver resolver = new ApiResolver(publicApis);
85         assertThrows(MemberAlternativeNotFoundError.class, ()
86                 -> resolver.resolvePublicAlternatives("{@link #foo(int)}", "La/b/C;->bar()V", 1));
87     }
88 
89     @Test
testFindPublicAlternativeFailNoAlternativeNoParameterTypes()90     public void testFindPublicAlternativeFailNoAlternativeNoParameterTypes() {
91 
92         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>(
93                 Arrays.asList("La/b/C;->bar(I)V")));
94         ApiResolver resolver = new ApiResolver(publicApis);
95         assertThrows(MemberAlternativeNotFoundError.class,
96                 () -> resolver.resolvePublicAlternatives("{@link #foo}", "La/b/C;->bar()V", 1));
97     }
98 
99     @Test
testNoPublicClassAlternatives()100     public void testNoPublicClassAlternatives() {
101         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>());
102         ApiResolver resolver = new ApiResolver(publicApis);
103         expectThrows(NoAlternativesSpecifiedError.class,
104                 () -> resolver.resolvePublicAlternatives("Foo", "La/b/C;->bar()V", 1));
105     }
106 
107     @Test
testPublicAlternativesJustPackageAndClassName()108     public void testPublicAlternativesJustPackageAndClassName() throws Exception {
109         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>(
110                 Arrays.asList("La/b/C;->bar(I)V")));
111         ApiResolver resolver = new ApiResolver(publicApis);
112         resolver.resolvePublicAlternatives("Foo {@link a.b.C}", "Lb/c/D;->bar()V", 1);
113     }
114 
115     @Test
testPublicAlternativesJustClassName()116     public void testPublicAlternativesJustClassName() throws Exception {
117         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>(
118                 Arrays.asList("La/b/C;->bar(I)V")));
119         ApiResolver resolver = new ApiResolver(publicApis);
120         resolver.resolvePublicAlternatives("Foo {@link C}", "La/b/D;->bar()V", 1);
121     }
122 
123     @Test
testNoPublicAlternativesButHasExplanation()124     public void testNoPublicAlternativesButHasExplanation() throws Exception {
125         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>());
126         ApiResolver resolver = new ApiResolver(publicApis);
127         resolver.resolvePublicAlternatives("Foo {@code bar}", "La/b/C;->bar()V", 1);
128     }
129 
130     @Test
testNoPublicAlternativesSpecifiedWithMaxSdk()131     public void testNoPublicAlternativesSpecifiedWithMaxSdk() {
132         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>());
133         ApiResolver resolver = new ApiResolver(publicApis);
134         assertThrows(RequiredAlternativeNotSpecifiedError.class,
135                 () -> resolver.resolvePublicAlternatives(null, "La/b/C;->bar()V", 29));
136     }
137 
138     @Test
testNoPublicAlternativesSpecifiedWithMaxLessThanQ()139     public void testNoPublicAlternativesSpecifiedWithMaxLessThanQ() throws Exception {
140         Set<String> publicApis = Collections.unmodifiableSet(new HashSet<>());
141         ApiResolver resolver = new ApiResolver(publicApis);
142         resolver.resolvePublicAlternatives(null, "La/b/C;->bar()V", 28);
143     }
144 
145 }