/*************************************************************************** * Copyright 2009-2012 by Christian Ihle * * kontakt@usikkert.net * * * * This file is part of KouInject. * * * * KouInject is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of * * the License, or (at your option) any later version. * * * * KouInject is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with KouInject. * * If not, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ package net.usikkert.kouinject; import static org.junit.Assert.*; import net.usikkert.kouinject.testbeans.notscanned.TheInterfaceUser; import net.usikkert.kouinject.testbeans.scanned.CarBean; import net.usikkert.kouinject.testbeans.scanned.LastBean; import net.usikkert.kouinject.testbeans.scanned.any.AnyBean; import net.usikkert.kouinject.testbeans.scanned.coffee.JavaBean; import net.usikkert.kouinject.testbeans.scanned.hierarchy.interfacebean.InterfaceBeanImpl; import net.usikkert.kouinject.testbeans.scanned.hierarchy.overriding.subpackage.OverridingSubpackageBean; import net.usikkert.kouinject.testbeans.scanned.scope.SingletonBean; import org.junit.Before; import org.junit.Test; import java.lang.reflect.Modifier; import java.net.URL; import java.net.URLClassLoader; import java.util.Set; /** * Test of {@link ClassPathScanner}. * * @author Christian Ihle */ public class ClassPathScannerTest { private static final String ALL = "net.usikkert.kouinject"; private static final String SCANNED = "net.usikkert.kouinject.testbeans.scanned"; private static final String SCANNED_ANY = "net.usikkert.kouinject.testbeans.scanned.any"; private static final String SCANNED_SCOPE = "net.usikkert.kouinject.testbeans.scanned.scope"; private static final String SCANNED_HIERARCHY = "net.usikkert.kouinject.testbeans.scanned.hierarchy"; private ClassPathScanner scanner; @Before public void createScanner() { scanner = new ClassPathScanner(); } @Test public void findClassesShouldDetectClassesInScannedPackage() { final Set<Class<?>> classes = scanner.findClasses(SCANNED); assertTrue(classes.contains(LastBean.class)); assertFalse(classes.contains(TheInterfaceUser.class)); } @Test public void findClassesShouldDetectClassesInSubPackages() { final Set<Class<?>> classes = scanner.findClasses(SCANNED); assertTrue(classes.contains(InterfaceBeanImpl.class)); assertTrue(classes.contains(JavaBean.class)); assertTrue(classes.contains(OverridingSubpackageBean.class)); } @Test public void findClassesShouldDetectClassesInDifferentBasePackages() { final Set<Class<?>> classes = scanner.findClasses(SCANNED_ANY, SCANNED_SCOPE, SCANNED_HIERARCHY); assertTrue(classes.contains(AnyBean.class)); assertTrue(classes.contains(SingletonBean.class)); assertTrue(classes.contains(OverridingSubpackageBean.class)); assertFalse(classes.contains(JavaBean.class)); assertFalse(classes.contains(CarBean.class)); } @Test public void findClassesShouldHandleArrays() { final Set<Class<?>> classes = scanner.findClasses(new String[] {SCANNED_ANY, SCANNED_SCOPE, SCANNED_HIERARCHY}); assertTrue(classes.contains(AnyBean.class)); assertTrue(classes.contains(SingletonBean.class)); assertTrue(classes.contains(OverridingSubpackageBean.class)); assertFalse(classes.contains(JavaBean.class)); assertFalse(classes.contains(CarBean.class)); } @Test(expected = IllegalArgumentException.class) public void findClassesShouldRequireAtLeastOneBasePackage() { scanner.findClasses(); } @Test(expected = IllegalArgumentException.class) public void findClassesShouldRequireAtLeastOneBasePackageWithArray() { scanner.findClasses(new String[] {}); } @Test(expected = IllegalArgumentException.class) public void findClassesShouldValidateBasePackagesNotNull() { scanner.findClasses(null); } @Test(expected = IllegalArgumentException.class) public void findClassesShouldValidateBasePackagesNotNullInArray() { scanner.findClasses(new String[] {null}); } @Test(expected = IllegalArgumentException.class) public void findClassesShouldValidateBasePackagesNotEmpty() { scanner.findClasses(" "); } @Test(expected = IllegalArgumentException.class) public void findClassesShouldValidateBasePackagesNotEmptyInArray() { scanner.findClasses(new String[] {" "}); } @Test public void findClassesShouldNotIncludeInterfaces() { final Set<Class<?>> classes = scanner.findClasses(ALL); for (final Class<?> class1 : classes) { assertFalse(class1.isInterface()); } } @Test public void findClassesShouldNotIncludeAnnotations() { final Set<Class<?>> classes = scanner.findClasses(ALL); for (final Class<?> class1 : classes) { assertFalse(class1.isAnnotation()); } } @Test public void findClassesShouldNotIncludeEnums() { final Set<Class<?>> classes = scanner.findClasses(ALL); for (final Class<?> class1 : classes) { assertFalse(class1.isEnum()); } } @Test public void findClassesShouldNotIncludeSyntheticClasses() { final Set<Class<?>> classes = scanner.findClasses(ALL); for (final Class<?> class1 : classes) { assertFalse(class1.isSynthetic()); } } @Test public void findClassesShouldNotIncludeAnonymousClasses() { final Set<Class<?>> classes = scanner.findClasses(ALL); for (final Class<?> class1 : classes) { assertFalse(class1.isAnonymousClass()); } } @Test public void findClassesShouldNotIncludeInnerClasses() { final Set<Class<?>> classes = scanner.findClasses(ALL); for (final Class<?> class1 : classes) { assertFalse(class1.isMemberClass()); } } @Test public void findClassesShouldNotIncludeAbstractClasses() { final Set<Class<?>> classes = scanner.findClasses(ALL); for (final Class<?> class1 : classes) { assertFalse(Modifier.isAbstract(class1.getModifiers())); } } @Test public void findClassesShouldUseClassLoaderFromClassIfContextClassLoaderIsNull() { final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); // Setting the default ClassLoader to null Thread.currentThread().setContextClassLoader(null); final ClassPathScanner classPathScanner = new ClassPathScanner(); final Set<Class<?>> classes = classPathScanner.findClasses(SCANNED); assertTrue(classes.contains(LastBean.class)); assertFalse(classes.contains(TheInterfaceUser.class)); // Cleanup Thread.currentThread().setContextClassLoader(contextClassLoader); } @Test public void findClassesShouldFindClassesInJarFiles() { final URL jarFileUrl = getClass().getClassLoader().getResource("test-beans.jar"); assertNotNull(jarFileUrl); final URLClassLoader jarClassLoader = new URLClassLoader(new URL[] { jarFileUrl }); final ClassPathScanner classPathScanner = new ClassPathScanner(jarClassLoader); final Set<Class<?>> classes = classPathScanner.findClasses("net.usikkert.kouinject.testbeans.jar"); assertNotNull(classes); assertEquals(8, classes.size()); assertTrue(containsClass(classes, "net.usikkert.kouinject.testbeans.jar.FirstLevel1JarBean")); assertTrue(containsClass(classes, "net.usikkert.kouinject.testbeans.jar.SecondLevel1JarBean")); assertTrue(containsClass(classes, "net.usikkert.kouinject.testbeans.jar.level2.FirstLevel2JarBean")); assertTrue(containsClass(classes, "net.usikkert.kouinject.testbeans.jar.level2.SecondLevel2JarBean")); assertTrue(containsClass(classes, "net.usikkert.kouinject.testbeans.jar.level2point2.ThirdLevel2JarBean")); assertTrue(containsClass(classes, "net.usikkert.kouinject.testbeans.jar.level2point2.FourthLevel2JarBean")); assertTrue(containsClass(classes, "net.usikkert.kouinject.testbeans.jar.level2point2.level3.FirstLevel3JarBean")); assertTrue(containsClass(classes, "net.usikkert.kouinject.testbeans.jar.level2point2.level3.SecondLevel3JarBean")); // Just to be sure containsClass() doesn't always return true assertFalse(containsClass(classes, "net.usikkert.kouinject.testbeans.jar.ThirdLevel1JarBean")); } @Test public void findClassesShouldFindClassesInJarFilesThatCanBeInstantiated() throws IllegalAccessException, InstantiationException { final URL jarFileUrl = getClass().getClassLoader().getResource("test-beans.jar"); assertNotNull(jarFileUrl); final URLClassLoader jarClassLoader = new URLClassLoader(new URL[] { jarFileUrl }); final ClassPathScanner classPathScanner = new ClassPathScanner(jarClassLoader); final Set<Class<?>> classes = classPathScanner.findClasses("net.usikkert.kouinject.testbeans.jar"); assertNotNull(classes); assertEquals(8, classes.size()); for (final Class<?> aClass : classes) { final Object instance = aClass.newInstance(); assertNotNull(instance); } } private boolean containsClass(final Set<Class<?>> classes, final String className) { for (final Class<?> aClass : classes) { if (aClass.getName().equals(className)) { return true; } } return false; } }