• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 package com.android.dependencymapper;
17 
18 import static com.android.dependencymapper.Utils.listClassesInJar;
19 
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 
23 import org.junit.BeforeClass;
24 import org.junit.Test;
25 
26 import java.net.URISyntaxException;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Set;
32 
33 public class ClassDependencyAnalyzerTest {
34 
35     private static List<ClassDependencyData> mClassDependencyDataList;
36 
37     private static final String CLASSES_JAR_PATH =
38             "tests/res/testfiles/dependency-mapper-test-data.jar";
39 
40     @BeforeClass
beforeClass()41     public static void beforeClass() throws URISyntaxException {
42         Path path = Paths.get(CLASSES_JAR_PATH);
43         Set<String> classesInJar = listClassesInJar(path);
44         // Perform dependency analysis.
45         mClassDependencyDataList = ClassDependencyAnalyzer.analyze(path,
46                 new ClassRelevancyFilter(classesInJar));
47     }
48 
49     @Test
testAnnotationDeps()50     public void testAnnotationDeps(){
51         String annoClass = "res.testdata.annotation.AnnotationUsage";
52         String sourceAnno = "res.testdata.annotation.SourceAnnotation";
53         String runTimeAnno = "res.testdata.annotation.RuntimeAnnotation";
54 
55         dependencyVerifier(annoClass,
56                 new HashSet<>(List.of(runTimeAnno)), new HashSet<>(List.of(sourceAnno)));
57 
58         for (ClassDependencyData dep : mClassDependencyDataList) {
59             if (dep.getQualifiedName().equals(sourceAnno)) {
60                 assertTrue(sourceAnno + " is not dependencyToAll ", dep.isDependencyToAll());
61             }
62             if (dep.getQualifiedName().equals(runTimeAnno)) {
63                 assertFalse(runTimeAnno + " is dependencyToAll ", dep.isDependencyToAll());
64             }
65         }
66     }
67 
68     @Test
testConstantsDeps()69     public void testConstantsDeps(){
70         String constDefined = "test_constant";
71         String constDefClass = "res.testdata.constants.ConstantDefinition";
72         String constUsageClass = "res.testdata.constants.ConstantUsage";
73 
74         boolean constUsageClassFound = false;
75         boolean constDefClassFound = false;
76         for (ClassDependencyData dep : mClassDependencyDataList) {
77             if (dep.getQualifiedName().equals(constUsageClass)) {
78                 constUsageClassFound = true;
79                 assertTrue("InlinedUsage of : " + constDefined + " not found",
80                         dep.inlinedUsages().contains(constDefined));
81             }
82             if (dep.getQualifiedName().equals(constDefClass)) {
83                 constDefClassFound = true;
84                 assertTrue("Constant " + constDefined + " not defined",
85                         dep.getConstantsDefined().contains(constDefined));
86             }
87         }
88         assertTrue("Class " + constUsageClass + " not found", constUsageClassFound);
89         assertTrue("Class " + constDefClass + " not found", constDefClassFound);
90     }
91 
92     @Test
testInheritanceDeps()93     public void testInheritanceDeps(){
94         String sourceClass = "res.testdata.inheritance.InheritanceUsage";
95         String baseClass = "res.testdata.inheritance.BaseClass";
96         String baseImpl = "res.testdata.inheritance.BaseImpl";
97 
98         dependencyVerifier(sourceClass,
99                 new HashSet<>(List.of(baseClass, baseImpl)), new HashSet<>());
100     }
101 
102 
103     @Test
testMethodDeps()104     public void testMethodDeps(){
105         String fieldUsage = "res.testdata.methods.FieldUsage";
106         String methodUsage = "res.testdata.methods.MethodUsage";
107         String ref1 = "res.testdata.methods.ReferenceClass1";
108         String ref2 = "res.testdata.methods.ReferenceClass2";
109 
110         dependencyVerifier(fieldUsage,
111                 new HashSet<>(List.of(ref1)), new HashSet<>(List.of(ref2)));
112         dependencyVerifier(methodUsage,
113                 new HashSet<>(List.of(ref1, ref2)), new HashSet<>());
114     }
115 
dependencyVerifier(String qualifiedName, Set<String> deps, Set<String> nonDeps)116     private void dependencyVerifier(String qualifiedName, Set<String> deps, Set<String> nonDeps) {
117         boolean depFound = false;
118         for (ClassDependencyData classDependencyData : mClassDependencyDataList) {
119             if (classDependencyData.getQualifiedName().equals(qualifiedName)) {
120                 depFound = true;
121                 for (String dep : deps) {
122                     assertTrue(qualifiedName + " does not depends on " + dep,
123                             classDependencyData.getClassDependencies().contains(dep));
124                 }
125                 for (String nonDep : nonDeps) {
126                     assertFalse(qualifiedName + " depends on " + nonDep,
127                             classDependencyData.getClassDependencies().contains(nonDep));
128                 }
129             }
130         }
131         assertTrue("Class " + qualifiedName + " not found", depFound);
132     }
133 }
134