package com.mountainminds.eclemma.internal.core.analysis; import java.io.File; import java.io.FileWriter; import java.io.StringReader; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import junit.framework.TestCase; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.InvalidRegistryObjectException; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import com.mountainminds.eclemma.core.CoverageTools; import com.mountainminds.eclemma.core.ICoverageSession; import com.mountainminds.eclemma.core.IInstrumentation; import com.mountainminds.eclemma.core.JavaProjectKit; import com.mountainminds.eclemma.core.analysis.IJavaCoverageListener; import com.mountainminds.eclemma.core.launching.JavaApplicationLauncher; import com.vladium.emma.data.ClassDescriptor; import com.vladium.emma.data.DataFactory; import com.vladium.emma.data.ICoverageData; import com.vladium.emma.data.IMergeable; import com.vladium.emma.data.IMetaData; import com.vladium.emma.data.MethodDescriptor; import com.vladium.emma.data.ICoverageData.DataHolder; public class MethodMatcherTest extends TestCase { private JavaProjectKit javaProject; protected void setUp() throws Exception { super.setUp(); CoverageTools.getSessionManager().removeAllSessions(); } private TestData setupProject(String xiClassName, String xiLongName) throws Exception { // Setup and build the project javaProject = new JavaProjectKit(xiClassName); javaProject.enableJava5(); final IPackageFragmentRoot root = javaProject.createSourceFolder("src"); javaProject.createCompilationUnit(root, "testdata/src", xiLongName + ".java"); JavaProjectKit.waitForBuild(); javaProject.assertNoErrors(); // Move the launch file into place File launchFileTarget = new File("../../junit-workspace/" + xiClassName + "/" + xiClassName + ".launch"); // Copy the launch file into place String launchString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + "<launchConfiguration type=\"org.eclipse.jdt.launching.localJavaApplication\">" + "<listAttribute key=\"org.eclipse.debug.core.MAPPED_RESOURCE_PATHS\">" + "<listEntry value=\"/testdata/src/" + xiLongName + ".java\"/>" + "</listAttribute>" + "<listAttribute key=\"org.eclipse.debug.core.MAPPED_RESOURCE_TYPES\">" + "<listEntry value=\"1\"/>" + "</listAttribute>" + "<stringAttribute key=\"org.eclipse.jdt.launching.MAIN_TYPE\" value=\"" + xiLongName.replace('/', '.') + "\"/>" + "<stringAttribute key=\"org.eclipse.jdt.launching.PROJECT_ATTR\" value=\"" + xiClassName + "\"/>" + "</launchConfiguration>"; StringReader in = new StringReader(launchString); FileWriter out = new FileWriter(launchFileTarget); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); assertTrue(launchFileTarget.getCanonicalPath(), launchFileTarget.exists()); // Refresh the project to pickup the launch file javaProject.project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); // Attach coverage listener CoverageListener listener = new CoverageListener(); CoverageTools.addJavaCoverageListener(listener); // Launch the program in coverage mode ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); IPath path = new Path(xiClassName + ".launch"); IFile file = javaProject.project.getFile(path); ILaunchConfiguration launchConfig = launchManager .getLaunchConfiguration(file); JavaApplicationLauncher javaLauncher = new JavaApplicationLauncher(); javaLauncher.setInitializationData(new Config(), null, null); ILaunch launch = javaLauncher.getLaunch(launchConfig, ""); javaLauncher.launch(launchConfig, "", launch, new NullProgressMonitor()); // Get the coverage session listener.waitForCoverageChanged(); ICoverageSession[] sessions = CoverageTools.getSessionManager() .getSessions(); assertEquals(1, sessions.length); ICoverageSession session = sessions[0]; // Get the instrumentation data assertEquals(1, session.getCoverageDataFiles().length); IInstrumentation[] instrumentations = session.getInstrumentations(); assertEquals(1, instrumentations.length); IInstrumentation instrumentation = instrumentations[0]; // Get the coverage data File f = session.getCoverageDataFiles()[0].toFile(); assertTrue(f.exists()); IMergeable data = DataFactory.load(f)[DataFactory.TYPE_COVERAGEDATA]; final ICoverageData coveragedata = (ICoverageData) data; assertNotNull(coveragedata); // Get the metadata IPath metadatafile = instrumentation.getMetaDataFile(); File metadataf = metadatafile.toFile(); assertTrue(metadataf.exists()); IMetaData metadata = (IMetaData) DataFactory.load(metadataf)[DataFactory.TYPE_METADATA]; assertNotNull(metadata); // Extract the type descriptors from the metadata final Map descriptors = new HashMap(); for (Iterator i = metadata.iterator(); i.hasNext();) { ClassDescriptor cd = (ClassDescriptor) i.next(); descriptors.put(cd.getClassVMName(), cd); } return new TestData(descriptors, instrumentation, coveragedata); } private static class TestData { public TestData(Map descriptors, IInstrumentation instrumentation, ICoverageData coveragedata) { this.descriptors = descriptors; this.instrumentation = instrumentation; this.coveragedata = coveragedata; } public final Map descriptors; public final IInstrumentation instrumentation; public final ICoverageData coveragedata; } public void testImplicitConstructor() throws Exception { final String fullName = "methodmatcher/ImplicitConstructor"; final TestData testData = setupProject("ImplicitConstructor", fullName); // Visit the types IPackageFragmentRoot[] roots = testData.instrumentation.getClassFiles() .getPackageFragmentRoots(); TypeTraverser jep = new TypeTraverser(roots); jep.process(new ITypeVisitor() { public void visit(IType type, String binaryname) { try { // Test the name of the type assertEquals(fullName, binaryname); // Test the number of child IJavaElements assertEquals(1, type.getChildren().length); // Get the Type Descriptor ClassDescriptor classDesc = (ClassDescriptor) testData.descriptors .remove(binaryname); assertNotNull(classDesc); // Get the coveragedata DataHolder data = testData.coveragedata.getCoverage(classDesc); assertNotNull(data); boolean[][] covered = data.m_coverage; // Extract the method descriptors MethodDescriptor[] methods = classDesc.getMethods(); assertEquals(2, methods.length); // Construct a matcher MethodMatcher matcher = new MethodMatcher(type, covered, methods); assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("main", element.getElementName()); assertEquals("main", mdescriptor.getName()); } assertFalse(matcher.methodMatched()); } catch (JavaModelException e) { throw new RuntimeException(e); } } public void done() { // Do Nothing } }, new NullProgressMonitor()); } public void testExplicitConstructor() throws Exception { final String fullName = "methodmatcher/ExplicitConstructor"; final TestData testData = setupProject("ExplicitConstructor", fullName); // Visit the types IPackageFragmentRoot[] roots = testData.instrumentation.getClassFiles() .getPackageFragmentRoots(); TypeTraverser jep = new TypeTraverser(roots); jep.process(new ITypeVisitor() { public void visit(IType type, String binaryname) { try { // Test the name of the type assertEquals(fullName, binaryname); // Test the number of child IJavaElements assertEquals(2, type.getChildren().length); // Get the Type Descriptor ClassDescriptor classDesc = (ClassDescriptor) testData.descriptors .remove(binaryname); assertNotNull(classDesc); // Get the coveragedata DataHolder data = testData.coveragedata.getCoverage(classDesc); assertNotNull(data); boolean[][] covered = data.m_coverage; // Extract the method descriptors MethodDescriptor[] methods = classDesc.getMethods(); assertEquals(2, methods.length); // Construct a matcher MethodMatcher matcher = new MethodMatcher(type, covered, methods); assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("ExplicitConstructor", element.getElementName()); assertEquals("<init>", mdescriptor.getName()); } assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("main", element.getElementName()); assertEquals("main", mdescriptor.getName()); } assertFalse(matcher.methodMatched()); } catch (JavaModelException e) { throw new RuntimeException(e); } } public void done() { // Do Nothing } }, new NullProgressMonitor()); } public void testStaticInit() throws Exception { final String fullName = "methodmatcher/StaticInit"; final TestData testData = setupProject("StaticInit", fullName); // Visit the types IPackageFragmentRoot[] roots = testData.instrumentation.getClassFiles() .getPackageFragmentRoots(); TypeTraverser jep = new TypeTraverser(roots); jep.process(new ITypeVisitor() { public void visit(IType type, String binaryname) { try { // Test the name of the type assertEquals(fullName, binaryname); // Test the number of child IJavaElements assertEquals(2, type.getChildren().length); // Get the Type Descriptor ClassDescriptor classDesc = (ClassDescriptor) testData.descriptors .remove(binaryname); assertNotNull(classDesc); // Get the coveragedata DataHolder data = testData.coveragedata.getCoverage(classDesc); assertNotNull(data); boolean[][] covered = data.m_coverage; // Extract the method descriptors MethodDescriptor[] methods = classDesc.getMethods(); assertEquals(3, methods.length); // Construct a matcher MethodMatcher matcher = new MethodMatcher(type, covered, methods); assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("", element.getElementName()); assertTrue(element.toString(), element.toString().startsWith( "<static initializer #1>")); assertEquals("<clinit>", mdescriptor.getName()); } assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("main", element.getElementName()); assertEquals("main", mdescriptor.getName()); } assertFalse(matcher.methodMatched()); } catch (JavaModelException e) { throw new RuntimeException(e); } } public void done() { // Do Nothing } }, new NullProgressMonitor()); } public void testComplexTest() throws Exception { final String fullName = "methodmatcher/ComplexTest"; final TestData testData = setupProject("ComplexTest", fullName); // Visit the types IPackageFragmentRoot[] roots = testData.instrumentation.getClassFiles() .getPackageFragmentRoots(); TypeTraverser jep = new TypeTraverser(roots); jep.process(new ITypeVisitor() { public void visit(IType type, String binaryname) { try { // Test the name of the type assertEquals(fullName, binaryname); // Test the number of child IJavaElements assertEquals(7, type.getChildren().length); // Get the Type Descriptor ClassDescriptor classDesc = (ClassDescriptor) testData.descriptors .remove(binaryname); assertNotNull(classDesc); // Get the coveragedata DataHolder data = testData.coveragedata.getCoverage(classDesc); assertNotNull(data); boolean[][] covered = data.m_coverage; // Extract the method descriptors MethodDescriptor[] methods = classDesc.getMethods(); assertEquals(4, methods.length); // Construct a matcher MethodMatcher matcher = new MethodMatcher(type, covered, methods); assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("", element.getElementName()); assertTrue(element.toString(), element.toString().startsWith( "<static initializer #1>")); assertEquals("<clinit>", mdescriptor.getName()); } assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("ComplexTest", element.getElementName()); assertEquals("<init>", mdescriptor.getName()); } assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("instanceMethod", element.getElementName()); assertEquals("instanceMethod", mdescriptor.getName()); } assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("main", element.getElementName()); assertEquals("main", mdescriptor.getName()); } assertFalse(matcher.methodMatched()); } catch (JavaModelException e) { throw new RuntimeException(e); } } public void done() { // Do Nothing } }, new NullProgressMonitor()); } public void testMultipleStaticInit() throws Exception { final String fullName = "methodmatcher/MultipleStaticInit"; final TestData testData = setupProject("MultipleStaticInit", fullName); // Visit the types IPackageFragmentRoot[] roots = testData.instrumentation.getClassFiles() .getPackageFragmentRoots(); TypeTraverser jep = new TypeTraverser(roots); jep.process(new ITypeVisitor() { public void visit(IType type, String binaryname) { try { // Test the name of the type assertEquals(fullName, binaryname); // Test the number of child IJavaElements assertEquals(4, type.getChildren().length); // Get the Type Descriptor ClassDescriptor classDesc = (ClassDescriptor) testData.descriptors .remove(binaryname); assertNotNull(classDesc); // Get the coveragedata DataHolder data = testData.coveragedata.getCoverage(classDesc); assertNotNull(data); boolean[][] covered = data.m_coverage; // Extract the method descriptors MethodDescriptor[] methods = classDesc.getMethods(); assertEquals(3, methods.length); // Construct a matcher MethodMatcher matcher = new MethodMatcher(type, covered, methods); assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("", element.getElementName()); assertTrue(element.toString(), element.toString().startsWith( "<static initializer #1>")); assertEquals("<clinit>", mdescriptor.getName()); } assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("main", element.getElementName()); assertEquals("main", mdescriptor.getName()); } assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("", element.getElementName()); assertTrue(element.toString(), element.toString().startsWith( "<static initializer #2>")); assertEquals("<clinit>", mdescriptor.getName()); } assertFalse(matcher.methodMatched()); } catch (JavaModelException e) { throw new RuntimeException(e); } } public void done() { // Do Nothing } }, new NullProgressMonitor()); } public void testStaticVarInit() throws Exception { final String fullName = "methodmatcher/StaticVarInit"; final TestData testData = setupProject("StaticVarInit", fullName); // Visit the types IPackageFragmentRoot[] roots = testData.instrumentation.getClassFiles() .getPackageFragmentRoots(); TypeTraverser jep = new TypeTraverser(roots); jep.process(new ITypeVisitor() { public void visit(IType type, String binaryname) { try { // Test the name of the type assertEquals(fullName, binaryname); // Test the number of child IJavaElements assertEquals(2, type.getChildren().length); // Get the Type Descriptor ClassDescriptor classDesc = (ClassDescriptor) testData.descriptors .remove(binaryname); assertNotNull(classDesc); // Get the coveragedata DataHolder data = testData.coveragedata.getCoverage(classDesc); assertNotNull(data); boolean[][] covered = data.m_coverage; // Extract the method descriptors MethodDescriptor[] methods = classDesc.getMethods(); assertEquals(3, methods.length); // Construct a matcher MethodMatcher matcher = new MethodMatcher(type, covered, methods); assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("main", element.getElementName()); assertEquals("main", mdescriptor.getName()); } assertFalse(matcher.methodMatched()); } catch (JavaModelException e) { throw new RuntimeException(e); } } public void done() { // Do Nothing } }, new NullProgressMonitor()); } public void testInstanceInit() throws Exception { final String fullName = "methodmatcher/InstanceInit"; final TestData testData = setupProject("InstanceInit", fullName); // Visit the types IPackageFragmentRoot[] roots = testData.instrumentation.getClassFiles() .getPackageFragmentRoots(); TypeTraverser jep = new TypeTraverser(roots); jep.process(new ITypeVisitor() { public void visit(IType type, String binaryname) { try { // Test the name of the type assertEquals(fullName, binaryname); // Test the number of child IJavaElements assertEquals(3, type.getChildren().length); // Get the Type Descriptor ClassDescriptor classDesc = (ClassDescriptor) testData.descriptors .remove(binaryname); assertNotNull(classDesc); // Get the coveragedata DataHolder data = testData.coveragedata.getCoverage(classDesc); assertNotNull(data); boolean[][] covered = data.m_coverage; // Extract the method descriptors MethodDescriptor[] methods = classDesc.getMethods(); assertEquals(2, methods.length); // Construct a matcher MethodMatcher matcher = new MethodMatcher(type, covered, methods); assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("InstanceInit", element.getElementName()); assertEquals("<init>", mdescriptor.getName()); } assertTrue(matcher.methodMatched()); { // Get selected objects IJavaElement element = matcher.getMatchedElement(); MethodDescriptor mdescriptor = matcher.getMatchedDescriptor(); assertEquals("main", element.getElementName()); assertEquals("main", mdescriptor.getName()); } assertFalse(matcher.methodMatched()); } catch (JavaModelException e) { throw new RuntimeException(e); } } public void done() { // Do Nothing } }, new NullProgressMonitor()); } protected void tearDown() throws Exception { if (javaProject != null) { javaProject.destroy(); } super.tearDown(); } private class CoverageListener implements IJavaCoverageListener { private boolean coverageChanged = false; public synchronized void coverageChanged() { coverageChanged = true; this.notifyAll(); } public synchronized void waitForCoverageChanged() throws InterruptedException { while (!coverageChanged) { this.wait(); } } } private class Config implements IConfigurationElement { public Object createExecutableExtension(String propertyName) throws CoreException { // Do nothing return null; } public String getAttribute(String name) throws InvalidRegistryObjectException { return "org.eclipse.jdt.launching.localJavaApplication"; } public String getAttributeAsIs(String name) throws InvalidRegistryObjectException { // Do nothing return null; } public String[] getAttributeNames() throws InvalidRegistryObjectException { // Do nothing return null; } public IConfigurationElement[] getChildren() throws InvalidRegistryObjectException { // Do nothing return null; } public IConfigurationElement[] getChildren(String name) throws InvalidRegistryObjectException { // Do nothing return null; } public IExtension getDeclaringExtension() throws InvalidRegistryObjectException { // Do nothing return null; } public String getName() throws InvalidRegistryObjectException { // Do nothing return null; } public String getNamespace() throws InvalidRegistryObjectException { // Do nothing return null; } public String getNamespaceIdentifier() throws InvalidRegistryObjectException { // Do nothing return null; } public Object getParent() throws InvalidRegistryObjectException { // Do nothing return null; } public String getValue() throws InvalidRegistryObjectException { // Do nothing return null; } public String getValueAsIs() throws InvalidRegistryObjectException { // Do nothing return null; } public boolean isValid() { // Do nothing return false; } } }