| /******************************************************************************* |
| * Copyright (c) 2006 IBM Corporation and others. |
| * 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: |
| * David Saff (saff@mit.edu) - initial API and implementation |
| * (bug 102632: [JUnit] Support for JUnit 4.) |
| *******************************************************************************/ |
| |
| package org.eclipse.jdt.internal.junit.launcher; |
| |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| |
| import org.eclipse.jdt.core.Flags; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IMember; |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.ISourceRange; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.ToolFactory; |
| import org.eclipse.jdt.core.compiler.IScanner; |
| import org.eclipse.jdt.core.compiler.ITerminalSymbols; |
| import org.eclipse.jdt.core.compiler.InvalidInputException; |
| |
| import org.eclipse.jdt.internal.junit.util.TestSearchEngine; |
| |
| |
| public class JUnit4TestFinder implements ITestFinder { |
| |
| private JUnit3TestFinder fJUnit3TestFinder= new JUnit3TestFinder(); |
| |
| private static class Annotation { |
| private static final JUnit4TestFinder.Annotation RUN_WITH= new JUnit4TestFinder.Annotation(new String[] { "RunWith", "org.junit.runner.RunWith" }); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| private static final JUnit4TestFinder.Annotation TEST= new JUnit4TestFinder.Annotation(new String[] { "Test", "org.junit.Test" }); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| private final String[] names; |
| |
| private Annotation(String[] names) { |
| this.names= names; |
| } |
| |
| public boolean foundIn(String source) { |
| IScanner scanner= ToolFactory.createScanner(false, true, false, false); |
| scanner.setSource(source.toCharArray()); |
| try { |
| int tok; |
| do { |
| tok= scanner.getNextToken(); |
| if (tok == ITerminalSymbols.TokenNameAT) { |
| String annotationName= ""; //$NON-NLS-1$ |
| tok= scanner.getNextToken(); |
| while (tok == ITerminalSymbols.TokenNameIdentifier || tok == ITerminalSymbols.TokenNameDOT) { |
| annotationName+= String.valueOf(scanner.getCurrentTokenSource()); |
| tok= scanner.getNextToken(); |
| } |
| for (int i= 0; i < names.length; i++) { |
| String annotation= names[i]; |
| if (annotationName.equals(annotation)) |
| return true; |
| } |
| } |
| } while (tok != ITerminalSymbols.TokenNameEOF); |
| } catch (InvalidInputException e) { |
| return false; |
| } |
| return false; |
| } |
| |
| boolean annotates(IMember member) throws JavaModelException { |
| ISourceRange sourceRange= member.getSourceRange(); |
| ISourceRange nameRange= member.getNameRange(); |
| int charsToSearch= nameRange.getOffset() - sourceRange.getOffset(); |
| String source= member.getSource().substring(0, charsToSearch); |
| return foundIn(source); |
| } |
| |
| boolean annotatesAtLeastOneMethod(IType type) throws JavaModelException { |
| IMethod[] methods= type.getMethods(); |
| for (int i= 0; i < methods.length; i++) { |
| if (annotates(methods[i])) |
| return true; |
| } |
| return false; |
| } |
| } |
| |
| public void findTestsInContainer(Object[] elements, Set result, IProgressMonitor pm) { |
| try { |
| for (int i= 0; i < elements.length; i++) { |
| Object container= TestSearchEngine.computeScope(elements[i]); |
| if (container instanceof IJavaProject) { |
| IJavaProject project= (IJavaProject) container; |
| findTestsInProject(project, result); |
| } else if (container instanceof IPackageFragmentRoot) { |
| IPackageFragmentRoot root= (IPackageFragmentRoot) container; |
| findTestsInPackageFragmentRoot(root, result); |
| } else if (container instanceof IPackageFragment) { |
| IPackageFragment fragment= (IPackageFragment) container; |
| findTestsInPackageFragment(fragment, result); |
| } else if (container instanceof ICompilationUnit) { |
| ICompilationUnit cu= (ICompilationUnit) container; |
| findTestsInCompilationUnit(cu, result); |
| } else if (container instanceof IType) { |
| IType type= (IType) container; |
| findTestsInType(type, result); |
| } |
| } |
| } catch (JavaModelException e) { |
| // do nothing |
| } |
| } |
| |
| private void findTestsInProject(IJavaProject project, Set result) throws JavaModelException { |
| IPackageFragmentRoot[] roots= project.getPackageFragmentRoots(); |
| for (int i= 0; i < roots.length; i++) { |
| IPackageFragmentRoot root= roots[i]; |
| findTestsInPackageFragmentRoot(root, result); |
| } |
| } |
| |
| private void findTestsInPackageFragmentRoot(IPackageFragmentRoot root, Set result) throws JavaModelException { |
| IJavaElement[] children= root.getChildren(); |
| for (int j= 0; j < children.length; j++) { |
| IPackageFragment fragment= (IPackageFragment) children[j]; |
| findTestsInPackageFragment(fragment, result); |
| } |
| } |
| |
| private void findTestsInPackageFragment(IPackageFragment fragment, Set result) throws JavaModelException { |
| ICompilationUnit[] compilationUnits= fragment.getCompilationUnits(); |
| for (int k= 0; k < compilationUnits.length; k++) { |
| ICompilationUnit unit= compilationUnits[k]; |
| findTestsInCompilationUnit(unit, result); |
| } |
| } |
| |
| private void findTestsInCompilationUnit(ICompilationUnit unit, Set result) throws JavaModelException { |
| IType[] types= unit.getAllTypes(); |
| for (int l= 0; l < types.length; l++) { |
| IType type= types[l]; |
| findTestsInType(type, result); |
| } |
| } |
| |
| private void findTestsInType(IType type, Set result) throws JavaModelException { |
| if (isTest(type)) |
| result.add(type); |
| } |
| |
| public boolean isTest(IType type) throws JavaModelException { |
| if (!Flags.isAbstract(type.getFlags())) { |
| if (Annotation.RUN_WITH.annotates(type) || Annotation.TEST.annotatesAtLeastOneMethod(type)) |
| return true; |
| return fJUnit3TestFinder.isTest(type); |
| } |
| return false; |
| } |
| } |