/* * Copyright (C) 2008 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 com.android.tools.layoutlib.create; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import com.android.tools.layoutlib.create.AsmAnalyzer.DependencyVisitor; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.objectweb.asm.ClassReader; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.TreeMap; /** * Unit tests for some methods of {@link AsmAnalyzer}. */ public class AsmAnalyzerTest { private MockLog mLog; private ArrayList mOsJarPath; private AsmAnalyzer mAa; @Before public void setUp() throws Exception { mLog = new MockLog(); URL url = this.getClass().getClassLoader().getResource("data/mock_android.jar"); mOsJarPath = new ArrayList(); mOsJarPath.add(url.getFile()); Set excludeClasses = new HashSet(1); excludeClasses.add("java.lang.JavaClass"); String[] includeFiles = new String[]{"mock_android/data/data*"}; mAa = new AsmAnalyzer(mLog, mOsJarPath, null /* gen */, null /* deriveFrom */, null /* includeGlobs */, excludeClasses, includeFiles); } @After public void tearDown() throws Exception { } @Test public void testParseZip() throws IOException { Map map = new TreeMap(); Map filesFound = new TreeMap(); mAa.parseZip(mOsJarPath, map, filesFound); assertArrayEquals(new String[] { "java.lang.JavaClass", "mock_android.dummy.InnerTest", "mock_android.dummy.InnerTest$DerivingClass", "mock_android.dummy.InnerTest$MyGenerics1", "mock_android.dummy.InnerTest$MyIntEnum", "mock_android.dummy.InnerTest$MyStaticInnerClass", "mock_android.dummy.InnerTest$NotStaticInner1", "mock_android.dummy.InnerTest$NotStaticInner2", "mock_android.util.EmptyArray", "mock_android.view.View", "mock_android.view.ViewGroup", "mock_android.view.ViewGroup$LayoutParams", "mock_android.view.ViewGroup$MarginLayoutParams", "mock_android.widget.LinearLayout", "mock_android.widget.LinearLayout$LayoutParams", "mock_android.widget.TableLayout", "mock_android.widget.TableLayout$LayoutParams" }, map.keySet().toArray()); assertArrayEquals(new String[] {"mock_android/data/dataFile"}, filesFound.keySet().toArray()); } @Test public void testFindClass() throws IOException, LogAbortException { Map zipClasses = new TreeMap(); Map filesFound = new TreeMap(); mAa.parseZip(mOsJarPath, zipClasses, filesFound); TreeMap found = new TreeMap(); ClassReader cr = mAa.findClass("mock_android.view.ViewGroup$LayoutParams", zipClasses, found); assertNotNull(cr); assertEquals("mock_android/view/ViewGroup$LayoutParams", cr.getClassName()); assertArrayEquals(new String[] { "mock_android.view.ViewGroup$LayoutParams" }, found.keySet().toArray()); assertArrayEquals(new ClassReader[] { cr }, found.values().toArray()); } @Test public void testFindGlobs() throws IOException, LogAbortException { Map zipClasses = new TreeMap(); Map filesFound = new TreeMap(); mAa.parseZip(mOsJarPath, zipClasses, filesFound); TreeMap found = new TreeMap(); // this matches classes, a package match returns nothing found.clear(); mAa.findGlobs("mock_android.view", zipClasses, found); assertArrayEquals(new String[] { }, found.keySet().toArray()); // a complex glob search. * is a search pattern that matches names, not dots mAa.findGlobs("mock_android.*.*Group$*Layout*", zipClasses, found); assertArrayEquals(new String[] { "mock_android.view.ViewGroup$LayoutParams", "mock_android.view.ViewGroup$MarginLayoutParams" }, found.keySet().toArray()); // a complex glob search. ** is a search pattern that matches names including dots mAa.findGlobs("mock_android.**Group*", zipClasses, found); assertArrayEquals(new String[] { "mock_android.view.ViewGroup", "mock_android.view.ViewGroup$LayoutParams", "mock_android.view.ViewGroup$MarginLayoutParams" }, found.keySet().toArray()); // matches a single class found.clear(); mAa.findGlobs("mock_android.view.View", zipClasses, found); assertArrayEquals(new String[] { "mock_android.view.View" }, found.keySet().toArray()); // matches everyting inside the given package but not sub-packages found.clear(); mAa.findGlobs("mock_android.view.*", zipClasses, found); assertArrayEquals(new String[] { "mock_android.view.View", "mock_android.view.ViewGroup", "mock_android.view.ViewGroup$LayoutParams", "mock_android.view.ViewGroup$MarginLayoutParams" }, found.keySet().toArray()); for (String key : found.keySet()) { ClassReader value = found.get(key); assertNotNull("No value for " + key, value); assertEquals(key, AsmAnalyzer.classReaderToClassName(value)); } } @Test public void testFindClassesDerivingFrom() throws LogAbortException, IOException { Map zipClasses = new TreeMap(); Map filesFound = new TreeMap(); mAa.parseZip(mOsJarPath, zipClasses, filesFound); TreeMap found = new TreeMap(); mAa.findClassesDerivingFrom("mock_android.view.View", zipClasses, found); assertArrayEquals(new String[] { "mock_android.view.View", "mock_android.view.ViewGroup", "mock_android.widget.LinearLayout", "mock_android.widget.TableLayout", }, found.keySet().toArray()); for (String key : found.keySet()) { ClassReader value = found.get(key); assertNotNull("No value for " + key, value); assertEquals(key, AsmAnalyzer.classReaderToClassName(value)); } } @Test public void testDependencyVisitor() throws IOException, LogAbortException { Map zipClasses = new TreeMap(); Map filesFound = new TreeMap(); mAa.parseZip(mOsJarPath, zipClasses, filesFound); TreeMap keep = new TreeMap(); TreeMap new_keep = new TreeMap(); TreeMap in_deps = new TreeMap(); TreeMap out_deps = new TreeMap(); ClassReader cr = mAa.findClass("mock_android.widget.LinearLayout", zipClasses, keep); DependencyVisitor visitor = mAa.getVisitor(zipClasses, keep, new_keep, in_deps, out_deps); // get first level dependencies cr.accept(visitor, 0 /* flags */); assertArrayEquals(new String[] { "mock_android.util.EmptyArray", "mock_android.view.ViewGroup", "mock_android.widget.LinearLayout$LayoutParams", }, out_deps.keySet().toArray()); in_deps.putAll(out_deps); out_deps.clear(); // get second level dependencies for (ClassReader cr2 : in_deps.values()) { cr2.accept(visitor, 0 /* flags */); } assertArrayEquals(new String[] { "mock_android.view.View", "mock_android.view.ViewGroup$LayoutParams", "mock_android.view.ViewGroup$MarginLayoutParams", }, out_deps.keySet().toArray()); in_deps.putAll(out_deps); out_deps.clear(); // get third level dependencies (there are none) for (ClassReader cr2 : in_deps.values()) { cr2.accept(visitor, 0 /* flags */); } keep.putAll(new_keep); assertArrayEquals(new String[] { }, out_deps.keySet().toArray()); assertArrayEquals(new String[] { "mock_android.widget.LinearLayout", }, keep.keySet().toArray()); } }