/* * The Apache Software License, Version 1.1 * * Copyright (C) 2000-2002 The Apache Software Foundation. All rights * reserved. * Copyright (C) 2010 John Lewis * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "Ant" and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package net.sourceforge.cobertura.test; import groovy.util.AntBuilder; import groovy.util.Node; import net.sourceforge.cobertura.ant.ReportTask; import net.sourceforge.cobertura.test.util.TestUtils; import org.apache.commons.io.FileUtils; import org.apache.tools.ant.taskdefs.Java; import org.junit.Test; import java.io.File; import java.util.HashMap; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class FunctionalTest extends AbstractCoberturaTestCase { AntBuilder ant = TestUtils.getCoberturaAntBuilder(TestUtils .getCoberturaClassDir()); Node dom; IgnoreUtil ignoreUtil; @Test public void interfaceFunctionalTest() throws Exception { /* * Interfaces are not instrumented (yet). So, instrument an interface and make * sure line/conditional information is not in the report. */ /* * Use a temporary directory and create a few sources files. */ File tempDir = TestUtils.getTempDir(); File srcDir = new File(tempDir, "src"); File instrumentDir = new File(tempDir, "instrument"); File mainSourceFile = new File(srcDir, "mypackage/Main.java"); File datafile = new File(srcDir, "cobertura.ser"); mainSourceFile.getParentFile().mkdirs(); File interfaceSourceFile = new File(srcDir, "mypackage/MyInterface.java"); FileUtils .write( interfaceSourceFile, "\n package mypackage;" + "\n " + "\n public interface MyInterface {" + "\n public static final Object MY_CONSTANT = new Object(); /* the test expects this to be line 5 */" + "\n }"); FileUtils.write(mainSourceFile, "\n package mypackage;" + "\n " + "\n public class Main implements MyInterface {" + "\n " + "\n public static void main(String[] args) {" + "\n System.out.println(new Main());" + "\n System.out.println(MY_CONSTANT);" + "\n }" + "\n }"); TestUtils.compileSource(ant, srcDir); TestUtils.instrumentClasses(ant, srcDir, datafile, instrumentDir); /* * Kick off the Main (instrumented) class. */ Java java = new Java(); java.setProject(TestUtils.project); java.setClassname("mypackage.Main"); java.setDir(srcDir); java.setFork(true); java.setFailonerror(true); java.setClasspath(TestUtils.getCoberturaDefaultClasspath()); java.execute(); /* * Now create a cobertura xml file and make sure the correct counts are in it. */ ReportTask reportTask = new ReportTask(); reportTask.setProject(TestUtils.project); reportTask.setDataFile(datafile.getAbsolutePath()); reportTask.setFormat("xml"); reportTask.setDestDir(srcDir); reportTask.execute(); dom = TestUtils.getXMLReportDOM(srcDir.getAbsolutePath() + "/coverage.xml"); List<Node> lines = TestUtils.getLineCounts(dom, "mypackage.MyInterface", "<clinit>", null); // When/if interfaces are instrumented, the next line can go away and the // lines in this method that have been commented out, can be uncommented. assertEquals("Interfaces are being instrumented", lines.size(), 0); } @Test public void conditionalInFinallyFunctionalTest() throws Exception { /* * Use a temporary directory and create a few sources files. */ File tempDir = TestUtils.getTempDir(); File srcDir = new File(tempDir, "src"); File instrumentDir = new File(tempDir, "instrument"); File mainSourceFile = new File(srcDir, "mypackage/Main.java"); File datafile = new File(srcDir, "cobertura.ser"); mainSourceFile.getParentFile().mkdirs(); FileUtils.write(mainSourceFile, "\n package mypackage;" + "\n " + "\n " + "\n " + "\n public class Main {" + "\n " + "\n private boolean isDisabled() {" + "\n return true;" + "\n }" + "\n " + "\n private void doSomething() {" + "\n }" + "\n " + "\n public void aMethod() {" + "\n boolean disabled = false;" + "\n try {" + "\n disabled = isDisabled();" + "\n } finally {" + "\n if (disabled)" + "\n doSomething();" + "\n }" + "\n }" + "\n " + "\n " + "\n }"); TestUtils.compileSource(ant, srcDir); TestUtils.instrumentClasses(ant, srcDir, datafile, instrumentDir); /* * Now create a cobertura xml file and make sure the correct counts are in it. */ ReportTask reportTask = new ReportTask(); reportTask.setProject(TestUtils.project); reportTask.setDataFile(datafile.getAbsolutePath()); reportTask.setFormat("xml"); reportTask.setDestDir(srcDir); reportTask.execute(); dom = TestUtils.getXMLReportDOM(srcDir.getAbsolutePath() + "/coverage.xml"); List<Node> lines = TestUtils.getLineCounts(dom, "mypackage.Main", "aMethod", null); Node conditionalLine = null; for (Node line : lines) { if ("20".equals(line.attribute("number"))) { conditionalLine = line; } } assertNotNull(conditionalLine); assertEquals("0% (0/2)", conditionalLine .attribute("condition-coverage")); } @Test public void callJunit() throws Exception { /* * Use a temporary directory and create a few sources files. */ File tempDir = TestUtils.getTempDir(); final File srcDir = new File(tempDir, "src"); final File reportDir = new File(tempDir, "report"); reportDir.mkdirs(); final File instrumentDir = new File(tempDir, "instrument"); instrumentDir.mkdirs(); File buildDir = new File(tempDir, "build"); buildDir.mkdirs(); File testSourceFile = new File(srcDir, "mypackage/MyTest.groovy"); testSourceFile.getParentFile().mkdirs(); FileUtils .write( testSourceFile, "\n package mypackage" + "\n " + "\n import junit.framework.TestSuite" + "\n import junit.framework.Test" + "\n " + "\n " + "\n public class MyTest extends TestSuite {" + "\n public MyTest(String arg0) {" + "\n super(arg0);" + "\n }" + "\n " + "\n public static Test suite() {" + "\n " + "\n // do something that will cause Sub's static initializer to run" + "\n Sub.class" + "\n " + "\n return new TestSuite(\"Empty Suite\")" + "\n }" + "\n }"); File superSourceFile = new File(srcDir, "mypackage/Super.java"); File subSourceFile = new File(srcDir, "mypackage/Sub.java"); File datafile = new File(srcDir, "cobertura.ser"); FileUtils.write(superSourceFile, "\n package mypackage;" + "\n " + "\n public class Super {" + "\n static {" + "\n Sub.aStaticMethod();" + "\n };" + "\n }"); FileUtils.write(subSourceFile, "\n package mypackage;" + "\n " + "\n public class Sub extends Super {" + "\n " + "\n public static void aStaticMethod() {" + "\n System.out.println(\"aStaticMethod called\");" + "\n }" + "\n " + "\n }"); // compile to the srcDir TestUtils.compileGroovy(ant, srcDir); // instrument all but the test class (in place) TestUtils.instrumentClasses(ant, srcDir, datafile, instrumentDir, new HashMap() { { put("excludeClassesRegexList", "mypackage.MyTest"); } }); // run the MyTest TestUtils.junit(new HashMap() { { put("testClass", "mypackage.MyTest"); put("ant", ant); put("buildDir", srcDir); put("instrumentDir", instrumentDir); put("reportDir", reportDir); } }); /* * Now create a cobertura xml file and make sure the correct counts are in it. */ ReportTask reportTask = new ReportTask(); reportTask.setProject(TestUtils.project); reportTask.setDataFile(datafile.getAbsolutePath()); reportTask.setFormat("xml"); reportTask.setDestDir(srcDir); reportTask.execute(); dom = TestUtils.getXMLReportDOM(srcDir.getAbsolutePath() + "/coverage.xml"); List<Node> lines = TestUtils.getLineCounts(dom, "mypackage.Sub", "aStaticMethod"); Node aStaticMethodLine = null; for (Node line : lines) { if ("7".equals(line.attribute("number"))) { aStaticMethodLine = line; break; } } assertNotNull(aStaticMethodLine); assertEquals(1, Integer.valueOf( aStaticMethodLine.attribute("hits").toString()).intValue()); } @Test public void simpleFunctionalTest() throws Exception { /* * Use a temporary directory and create a few sources files. */ File tempDir = TestUtils.getTempDir(); File srcDir = new File(tempDir, "src"); File instrumentDir = new File(tempDir, "instrument"); File mainSourceFile = new File(srcDir, "mypackage/Main.java"); File simpleSourceFile = new File(srcDir, "mypackage/Simple.java"); File datafile = new File(srcDir, "cobertura.ser"); mainSourceFile.getParentFile().mkdirs(); FileUtils.write(simpleSourceFile, "\n package mypackage;" + "\n " + "\n public class Simple {" + "\n }"); FileUtils.write(mainSourceFile, "\n package mypackage;" + "\n " + "\n " + "\n " + "\n public class Main {" + "\n " + "\n " + "\n public boolean isSimple() {" + "\n return false;" + "\n }" + "\n " + "\n " + "\n private Object create() {" + "\n if (isSimple()) {" + "\n Object result = new Simple();" + "\n } else {" + "\n Object result = new Main();" + "\n }" + "\n return null;" + "\n " + "\n }" + "\n }"); TestUtils.compileSource(ant, srcDir); TestUtils.instrumentClasses(ant, srcDir, datafile, instrumentDir); } }