/******************************************************************************* * Copyright (c) 2009-2015 CWI * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * * Davy Landman - Davy.Landman@cwi.nl - CWI *******************************************************************************/ package org.rascalmpl.test.infrastructure; import java.io.File; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.junit.Test; import org.junit.runners.Suite; import org.junit.runners.model.InitializationError; public class RecursiveTestSuite extends Suite { public RecursiveTestSuite(Class<?> setupClass) throws InitializationError { super(setupClass, getClasses(setupClass)); } private static Class<?>[] getClasses(Class<?> setupClass) { List<Class<?>> result = new ArrayList<Class<?>>(); if (setupClass.isAnnotationPresent(RecursiveTest.class)) { String[] directories = setupClass.getAnnotation(RecursiveTest.class).value(); addClassesFromDirectories(setupClass, result, directories, true); } if (setupClass.isAnnotationPresent(RecursiveJavaOnlyTest.class)) { String[] directories = setupClass.getAnnotation(RecursiveJavaOnlyTest.class).value(); addClassesFromDirectories(setupClass, result, directories, false); } return result.toArray(new Class<?>[0]); } private static void addClassesFromDirectories(Class<?> setupClass, List<Class<?>> result, String[] directories, boolean includeRascalTests) { String packageName = setupClass.getPackage().getName(); String path = setupClass.getProtectionDomain().getCodeSource().getLocation().getFile(); path = path + packageName.replace('.', File.separatorChar); for (String dir: directories) { findTestClasses(setupClass.getPackage(), new File(path + File.separatorChar + dir), includeRascalTests, result); } } private static void findTestClasses(Package root, File path, boolean includeRascalTests, List<Class<?>> result) { for (File f : path.listFiles()) { if (f.isDirectory()) { findTestClasses(root, f, includeRascalTests, result); } else if (f.getName().endsWith(".class")) { // check if the Class has @Test methods String className = f.getName().substring(0, f.getName().length() - 6); className = path.getPath().replace(File.separatorChar, '.') + '.' + className; className = className.substring(className.indexOf(root.getName())); // remove the part of the path which is just the subdir of the project. try { Class<?> currentClass = Class.forName(className); if (currentClass.isAnnotationPresent(RascalJUnitTestPrefix.class) || currentClass.isAnnotationPresent(RecursiveRascalParallelTest.class)) { if (includeRascalTests) { result.add(currentClass); } } else { for (Method m: currentClass.getMethods()) { if (m.isAnnotationPresent(Test.class)) { result.add(currentClass); break; } } } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } }