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