aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc R. Hoffmann <hoffmann@mountainminds.com>2014-01-22 22:34:49 -0800
committerMarc R. Hoffmann <hoffmann@mountainminds.com>2014-01-22 22:34:49 -0800
commit38a27cd6745f678d29203119c7023543acacbd24 (patch)
tree336b9c483da5ce41b5d8abdd13c76f22e30f45a2
parenta7617e95423a1929577a59f03e08d67478b589bf (diff)
parent68dc5ebfa0cc8e718e514a25cd4276a6ca86dd96 (diff)
downloadjacoco-38a27cd6745f678d29203119c7023543acacbd24.tar.gz
Merge pull request #185 from jacoco/issue-185
Print warning if class ids differ
-rw-r--r--jacoco-maven-plugin.test/it/it-report-nomatch/nomatch.execbin0 -> 24 bytes
-rw-r--r--jacoco-maven-plugin.test/it/it-report-nomatch/pom.xml44
-rw-r--r--jacoco-maven-plugin.test/it/it-report-nomatch/src/main/java/Example.java14
-rw-r--r--jacoco-maven-plugin.test/it/it-report-nomatch/verify.bsh24
-rw-r--r--jacoco-maven-plugin/src/org/jacoco/maven/AbstractReportMojo.java2
-rw-r--r--jacoco-maven-plugin/src/org/jacoco/maven/BundleCreator.java36
-rw-r--r--jacoco-maven-plugin/src/org/jacoco/maven/CheckMojo.java15
-rw-r--r--org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.xml36
-rw-r--r--org.jacoco.ant.test/src/org/jacoco/ant/data/nomatch.execbin0 -> 42 bytes
-rw-r--r--org.jacoco.ant/src/org/jacoco/ant/ReportTask.java27
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java82
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageBuilderTest.java49
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataStoreTest.java3
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/BundleCoverageImplTest.java4
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java2
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassCoverageImplTest.java31
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/PackageCoverageTest.java8
-rw-r--r--org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java23
-rw-r--r--org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java17
-rw-r--r--org.jacoco.core/src/org/jacoco/core/analysis/IClassCoverage.java10
-rw-r--r--org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java19
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java11
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java13
-rw-r--r--org.jacoco.doc/docroot/doc/changes.html11
-rw-r--r--org.jacoco.report.test/src/org/jacoco/report/ReportStructureTestDriver.java4
-rw-r--r--org.jacoco.report.test/src/org/jacoco/report/check/BundleCheckerTest.java4
-rw-r--r--org.jacoco.report.test/src/org/jacoco/report/csv/ClassRowWriterTest.java2
-rw-r--r--org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ClassPageTest.java8
-rw-r--r--org.jacoco.report.test/src/org/jacoco/report/internal/html/page/PackagePageTest.java16
29 files changed, 400 insertions, 115 deletions
diff --git a/jacoco-maven-plugin.test/it/it-report-nomatch/nomatch.exec b/jacoco-maven-plugin.test/it/it-report-nomatch/nomatch.exec
new file mode 100644
index 00000000..31cad96f
--- /dev/null
+++ b/jacoco-maven-plugin.test/it/it-report-nomatch/nomatch.exec
Binary files differ
diff --git a/jacoco-maven-plugin.test/it/it-report-nomatch/pom.xml b/jacoco-maven-plugin.test/it/it-report-nomatch/pom.xml
new file mode 100644
index 00000000..73b6a096
--- /dev/null
+++ b/jacoco-maven-plugin.test/it/it-report-nomatch/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2009, 2014 Mountainminds GmbH & Co. KG and Contributors
+ 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:
+ Evgeny Mandrikov - initial API and implementation
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>jacoco</groupId>
+ <artifactId>setup-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>it-report-nomatch</artifactId>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>@project.groupId@</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>report</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ <configuration>
+ <dataFile>nomatch.exec</dataFile>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/jacoco-maven-plugin.test/it/it-report-nomatch/src/main/java/Example.java b/jacoco-maven-plugin.test/it/it-report-nomatch/src/main/java/Example.java
new file mode 100644
index 00000000..5d2c1392
--- /dev/null
+++ b/jacoco-maven-plugin.test/it/it-report-nomatch/src/main/java/Example.java
@@ -0,0 +1,14 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2014 Mountainminds GmbH & Co. KG and Contributors
+ * 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:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+public class Example {
+
+}
diff --git a/jacoco-maven-plugin.test/it/it-report-nomatch/verify.bsh b/jacoco-maven-plugin.test/it/it-report-nomatch/verify.bsh
new file mode 100644
index 00000000..e45c9ad7
--- /dev/null
+++ b/jacoco-maven-plugin.test/it/it-report-nomatch/verify.bsh
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2014 Mountainminds GmbH & Co. KG and Contributors
+ * 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:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+String buildLog = FileUtils.fileRead( new File( basedir, "build.log" ) );
+if ( buildLog.indexOf( "Classes in bundle 'it-report-nomatch' do no match with execution data." ) < 0 ) {
+ throw new RuntimeException( "Warning 1 was not printed" );
+}
+if ( buildLog.indexOf( "For report generation the same class files must be used as at runtime." ) < 0 ) {
+ throw new RuntimeException( "Warning 2 was not printed" );
+}
+if ( buildLog.indexOf( "Execution data for class Example does not match." ) < 0 ) {
+ throw new RuntimeException( "Warning 3 was not printed" );
+}
diff --git a/jacoco-maven-plugin/src/org/jacoco/maven/AbstractReportMojo.java b/jacoco-maven-plugin/src/org/jacoco/maven/AbstractReportMojo.java
index ac735c17..4c694aa8 100644
--- a/jacoco-maven-plugin/src/org/jacoco/maven/AbstractReportMojo.java
+++ b/jacoco-maven-plugin/src/org/jacoco/maven/AbstractReportMojo.java
@@ -215,7 +215,7 @@ public abstract class AbstractReportMojo extends AbstractMavenReport {
final FileFilter fileFilter = new FileFilter(this.getIncludes(),
this.getExcludes());
final BundleCreator creator = new BundleCreator(this.getProject(),
- fileFilter);
+ fileFilter, getLog());
final IBundleCoverage bundle = creator.createBundle(executionDataStore);
final SourceFileCollection locator = new SourceFileCollection(
getCompileSourceRoots(), sourceEncoding);
diff --git a/jacoco-maven-plugin/src/org/jacoco/maven/BundleCreator.java b/jacoco-maven-plugin/src/org/jacoco/maven/BundleCreator.java
index 3088399f..e20c4aef 100644
--- a/jacoco-maven-plugin/src/org/jacoco/maven/BundleCreator.java
+++ b/jacoco-maven-plugin/src/org/jacoco/maven/BundleCreator.java
@@ -12,15 +12,20 @@
*******************************************************************************/
package org.jacoco.maven;
+import static java.lang.String.format;
+
import java.io.File;
import java.io.IOException;
+import java.util.Collection;
import java.util.List;
+import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.FileUtils;
import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.CoverageBuilder;
import org.jacoco.core.analysis.IBundleCoverage;
+import org.jacoco.core.analysis.IClassCoverage;
import org.jacoco.core.data.ExecutionDataStore;
/**
@@ -30,6 +35,7 @@ public final class BundleCreator {
private final MavenProject project;
private final FileFilter fileFilter;
+ private final Log log;
/**
* Construct a new BundleCreator given the MavenProject and FileFilter.
@@ -38,10 +44,14 @@ public final class BundleCreator {
* the MavenProject
* @param fileFilter
* the FileFilter
+ * @param log
+ * for log output
*/
- public BundleCreator(final MavenProject project, final FileFilter fileFilter) {
+ public BundleCreator(final MavenProject project,
+ final FileFilter fileFilter, final Log log) {
this.project = project;
this.fileFilter = fileFilter;
+ this.log = log;
}
/**
@@ -68,6 +78,28 @@ public final class BundleCreator {
analyzer.analyzeAll(file);
}
- return builder.getBundle(this.project.getName());
+ final IBundleCoverage bundle = builder
+ .getBundle(this.project.getName());
+ logBundleInfo(bundle, builder.getNoMatchClasses());
+
+ return bundle;
+ }
+
+ private void logBundleInfo(final IBundleCoverage bundle,
+ final Collection<IClassCoverage> nomatch) {
+ log.info(format("Analyzed bundle '%s' with %s classes",
+ bundle.getName(),
+ Integer.valueOf(bundle.getClassCounter().getTotalCount())));
+ if (!nomatch.isEmpty()) {
+ log.warn(format(
+ "Classes in bundle '%s' do no match with execution data. "
+ + "For report generation the same class files must be used as at runtime.",
+ bundle.getName()));
+ for (final IClassCoverage c : nomatch) {
+ log.warn(format("Execution data for class %s does not match.",
+ c.getName()));
+ }
+ }
}
+
}
diff --git a/jacoco-maven-plugin/src/org/jacoco/maven/CheckMojo.java b/jacoco-maven-plugin/src/org/jacoco/maven/CheckMojo.java
index 94779c6a..f5f9a55a 100644
--- a/jacoco-maven-plugin/src/org/jacoco/maven/CheckMojo.java
+++ b/jacoco-maven-plugin/src/org/jacoco/maven/CheckMojo.java
@@ -54,10 +54,10 @@ public class CheckMojo extends AbstractJacocoMojo implements IViolationsOutput {
* If a limit refers to a ratio the range is from 0.0 to 1.0 where the
* number of decimal places will also determine the precision in error
* messages.
- *
+ *
* Note that you <b>must</b> use <tt>implementation</tt> hints for
- * <tt>rule</tt> and <tt>limit</tt> when using Maven 2, with Maven 3 you
- * do not need to specify the attributes.
+ * <tt>rule</tt> and <tt>limit</tt> when using Maven 2, with Maven 3 you do
+ * not need to specify the attributes.
* </p>
*
* <p>
@@ -137,11 +137,12 @@ public class CheckMojo extends AbstractJacocoMojo implements IViolationsOutput {
getLog().info(MSG_SKIPPING + dataFile);
return false;
}
- final File classesDirectory = new File(getProject().getBuild().getOutputDirectory());
+ final File classesDirectory = new File(getProject().getBuild()
+ .getOutputDirectory());
if (!classesDirectory.exists()) {
getLog().info(
- "Skipping JaCoCo execution due to missing classes directory:" +
- classesDirectory);
+ "Skipping JaCoCo execution due to missing classes directory:"
+ + classesDirectory);
return false;
}
return true;
@@ -189,7 +190,7 @@ public class CheckMojo extends AbstractJacocoMojo implements IViolationsOutput {
final FileFilter fileFilter = new FileFilter(this.getIncludes(),
this.getExcludes());
final BundleCreator creator = new BundleCreator(getProject(),
- fileFilter);
+ fileFilter, getLog());
try {
final ExecutionDataStore executionData = loadExecutionData();
return creator.createBundle(executionData);
diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.xml
index bed8b2f0..04ab9802 100644
--- a/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.xml
+++ b/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.xml
@@ -117,6 +117,24 @@
</jacoco:report>
<au:assertLogDoesntContain level="warn" text="source code annotation"/>
</target>
+
+ <target name="testReportWithNoMatch">
+ <property name="nomatch.file" location="${basedir}/data/nomatch.exec"/>
+ <jacoco:report>
+ <executiondata>
+ <file file="${nomatch.file}"/>
+ </executiondata>
+ <structure name="root">
+ <classfiles>
+ <path location="${org.jacoco.ant.reportTaskTest.classes.dir}"/>
+ </classfiles>
+ </structure>
+ </jacoco:report>
+ <au:assertLogContains level="warn" text="Classes in bundle 'root' do no match with execution data."/>
+ <au:assertLogContains level="warn" text="For report generation the same class files must be used as at runtime."/>
+ <au:assertLogContains level="warn" text="Execution data for class org/jacoco/ant/TestTarget does not match."/>
+ </target>
+
<!-- HTML Output -->
@@ -220,7 +238,7 @@
<sourcefiles encoding="UTF-8">
<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
</sourcefiles>
- </structure>
+ </structure>
<html destdir="${temp.dir}"/>
</jacoco:report>
@@ -239,7 +257,7 @@
<sourcefiles encoding="UTF-8" tabwidth="13">
<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
</sourcefiles>
- </structure>
+ </structure>
<html destdir="${temp.dir}"/>
</jacoco:report>
@@ -287,7 +305,7 @@
<sourcefiles encoding="UTF-8">
<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
</sourcefiles>
- </structure>
+ </structure>
<html destdir="${temp.dir}"/>
</jacoco:report>
@@ -304,7 +322,7 @@
<sourcefiles encoding="UTF-8">
<dirset dir="${org.jacoco.ant.reportTaskTest.sources.dir}/.." includes="src" />
</sourcefiles>
- </structure>
+ </structure>
<html destdir="${temp.dir}"/>
</jacoco:report>
@@ -323,7 +341,7 @@
<sourcefiles encoding="UTF-16">
<fileset dir="${temp.dir}" />
</sourcefiles>
- </structure>
+ </structure>
<html destdir="${temp.dir}"/>
</jacoco:report>
@@ -342,7 +360,7 @@
<sourcefiles encoding="UTF-8">
<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
</sourcefiles>
- </structure>
+ </structure>
<html destdir="${temp.dir}" locale="gr"/>
</jacoco:report>
@@ -423,7 +441,7 @@
<sourcefiles encoding="UTF-8">
<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
</sourcefiles>
- </structure>
+ </structure>
<check>
<rule element="CLASS">
<limit counter="METHOD" value="MISSEDCOUNT" maximum="100"/>
@@ -442,7 +460,7 @@
<sourcefiles encoding="UTF-8">
<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
</sourcefiles>
- </structure>
+ </structure>
<check>
<rule element="BUNDLE">
<limit counter="INSTRUCTION" value="COVEREDRATIO" minimum="0.90"/>
@@ -462,7 +480,7 @@
<sourcefiles encoding="UTF-8">
<fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
</sourcefiles>
- </structure>
+ </structure>
<check failonviolation="false" violationsproperty="violation">
<rule element="BUNDLE">
<limit counter="METHOD" value="COVEREDRATIO" minimum="0.50"/>
diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/data/nomatch.exec b/org.jacoco.ant.test/src/org/jacoco/ant/data/nomatch.exec
new file mode 100644
index 00000000..ef7d62ae
--- /dev/null
+++ b/org.jacoco.ant.test/src/org/jacoco/ant/data/nomatch.exec
Binary files differ
diff --git a/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java b/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java
index ba58894a..90bad95d 100644
--- a/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java
+++ b/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java
@@ -18,6 +18,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -32,6 +33,7 @@ import org.apache.tools.ant.util.FileUtils;
import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.CoverageBuilder;
import org.jacoco.core.analysis.IBundleCoverage;
+import org.jacoco.core.analysis.IClassCoverage;
import org.jacoco.core.analysis.ICoverageNode;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.data.SessionInfoStore;
@@ -543,9 +545,6 @@ public class ReportTask extends Task {
}
} else {
final IBundleCoverage bundle = createBundle(group);
- log(format("Writing group \"%s\" with %s classes",
- bundle.getName(),
- Integer.valueOf(bundle.getClassCounter().getTotalCount())));
final SourceFilesElement sourcefiles = group.sourcefiles;
final AntResourcesLocator locator = new AntResourcesLocator(
sourcefiles.encoding, sourcefiles.tabWidth);
@@ -571,14 +570,32 @@ public class ReportTask extends Task {
in.close();
}
}
- return builder.getBundle(group.name);
+ final IBundleCoverage bundle = builder.getBundle(group.name);
+ logBundleInfo(bundle, builder.getNoMatchClasses());
+ return bundle;
+ }
+
+ private void logBundleInfo(final IBundleCoverage bundle,
+ final Collection<IClassCoverage> nomatch) {
+ log(format("Writing bundle '%s' with %s classes", bundle.getName(),
+ Integer.valueOf(bundle.getClassCounter().getTotalCount())));
+ if (!nomatch.isEmpty()) {
+ log(format(
+ "Classes in bundle '%s' do no match with execution data. "
+ + "For report generation the same class files must be used as at runtime.",
+ bundle.getName()), Project.MSG_WARN);
+ for (final IClassCoverage c : nomatch) {
+ log(format("Execution data for class %s does not match.",
+ c.getName()), Project.MSG_WARN);
+ }
+ }
}
private void checkForMissingDebugInformation(final ICoverageNode node) {
if (node.getClassCounter().getTotalCount() > 0
&& node.getLineCounter().getTotalCount() == 0) {
log(format(
- "To enable source code annotation class files for bundle '%s' have to be compiled with debug information",
+ "To enable source code annotation class files for bundle '%s' have to be compiled with debug information.",
node.getName()), Project.MSG_WARN);
}
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java
index 7e5298aa..f287526b 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java
@@ -12,6 +12,8 @@
package org.jacoco.core.analysis;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -23,8 +25,9 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
-import java.util.Set;
+import java.util.Map;
import java.util.jar.JarInputStream;
import java.util.jar.Pack200;
import java.util.zip.GZIPOutputStream;
@@ -32,6 +35,7 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.jacoco.core.data.ExecutionDataStore;
+import org.jacoco.core.internal.data.CRC64;
import org.jacoco.core.test.TargetLoader;
import org.junit.Before;
import org.junit.Rule;
@@ -48,38 +52,61 @@ public class AnalyzerTest {
private Analyzer analyzer;
- private final Set<String> classes = new HashSet<String>();
+ private Map<String, IClassCoverage> classes;
+
+ private ExecutionDataStore executionData;
private class EmptyStructureVisitor implements ICoverageVisitor {
public void visitCoverage(IClassCoverage coverage) {
final String name = coverage.getName();
- assertTrue("Class already processed: " + name, classes.add(name));
+ assertNull("Class already processed: " + name,
+ classes.put(name, coverage));
}
}
@Before
public void setup() {
- analyzer = new Analyzer(new ExecutionDataStore(),
- new EmptyStructureVisitor());
+ classes = new HashMap<String, IClassCoverage>();
+ executionData = new ExecutionDataStore();
+ analyzer = new Analyzer(executionData, new EmptyStructureVisitor());
}
@Test
- public void testAnalyzeClass1() throws IOException {
+ public void testAnalyzeClassFromStream() throws IOException {
analyzer.analyzeClass(TargetLoader.getClassData(AnalyzerTest.class),
"Test");
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
+ assertClasses("org/jacoco/core/analysis/AnalyzerTest");
+ }
+
+ @Test
+ public void testAnalyzeClassFromByteArray() throws IOException {
+ analyzer.analyzeClass(
+ TargetLoader.getClassDataAsBytes(AnalyzerTest.class), "Test");
+ assertClasses("org/jacoco/core/analysis/AnalyzerTest");
+ assertFalse(classes.get("org/jacoco/core/analysis/AnalyzerTest")
+ .isNoMatch());
}
@Test
- public void testAnalyzeClass2() throws IOException {
+ public void testAnalyzeClassIdMatch() throws IOException {
+ final byte[] bytes = TargetLoader
+ .getClassDataAsBytes(AnalyzerTest.class);
+ executionData.get(Long.valueOf(CRC64.checksum(bytes)),
+ "org/jacoco/core/analysis/AnalyzerTest", 100);
+ analyzer.analyzeClass(bytes, "Test");
+ assertFalse(classes.get("org/jacoco/core/analysis/AnalyzerTest")
+ .isNoMatch());
+ }
+
+ @Test
+ public void testAnalyzeClassNoIdMatch() throws IOException {
+ executionData.get(Long.valueOf(0),
+ "org/jacoco/core/analysis/AnalyzerTest", 100);
analyzer.analyzeClass(
TargetLoader.getClassDataAsBytes(AnalyzerTest.class), "Test");
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
+ assertTrue(classes.get("org/jacoco/core/analysis/AnalyzerTest")
+ .isNoMatch());
}
@Test
@@ -100,9 +127,7 @@ public class AnalyzerTest {
final int count = analyzer.analyzeAll(
TargetLoader.getClassData(AnalyzerTest.class), "Test");
assertEquals(1, count);
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
+ assertClasses("org/jacoco/core/analysis/AnalyzerTest");
}
@Test
@@ -116,9 +141,7 @@ public class AnalyzerTest {
final int count = analyzer.analyzeAll(
new ByteArrayInputStream(buffer.toByteArray()), "Test");
assertEquals(1, count);
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
+ assertClasses("org/jacoco/core/analysis/AnalyzerTest");
}
@Test
@@ -151,9 +174,7 @@ public class AnalyzerTest {
final int count = analyzer.analyzeAll(new ByteArrayInputStream(
pack200buffer.toByteArray()), "Test");
assertEquals(1, count);
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
+ assertClasses("org/jacoco/core/analysis/AnalyzerTest");
}
@Test
@@ -161,7 +182,7 @@ public class AnalyzerTest {
final int count = analyzer.analyzeAll(new ByteArrayInputStream(
new byte[0]), "Test");
assertEquals(0, count);
- assertEquals(Collections.emptySet(), classes);
+ assertEquals(Collections.emptyMap(), classes);
}
@Test
@@ -169,9 +190,7 @@ public class AnalyzerTest {
createClassfile("bin1", AnalyzerTest.class);
final int count = analyzer.analyzeAll(folder.getRoot());
assertEquals(1, count);
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
+ assertClasses("org/jacoco/core/analysis/AnalyzerTest");
}
@Test
@@ -181,10 +200,8 @@ public class AnalyzerTest {
String path = "bin1" + File.pathSeparator + "bin2";
final int count = analyzer.analyzeAll(path, folder.getRoot());
assertEquals(2, count);
- assertEquals(
- new HashSet<String>(Arrays.asList(
- "org/jacoco/core/analysis/Analyzer",
- "org/jacoco/core/analysis/AnalyzerTest")), classes);
+ assertClasses("org/jacoco/core/analysis/Analyzer",
+ "org/jacoco/core/analysis/AnalyzerTest");
}
@Test(expected = IOException.class)
@@ -231,4 +248,9 @@ public class AnalyzerTest {
out.close();
}
+ private void assertClasses(String... classNames) {
+ assertEquals(new HashSet<String>(Arrays.asList(classNames)),
+ classes.keySet());
+ }
+
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageBuilderTest.java b/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageBuilderTest.java
index c2d5a4d3..4a54c702 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageBuilderTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageBuilderTest.java
@@ -49,7 +49,7 @@ public class CoverageBuilderTest {
method.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 7);
method.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 8);
method.incrementMethodCounter();
- addClass(123L, "Sample", null, method);
+ addClass(123L, false, "Sample", null, method);
final Collection<IClassCoverage> classes = coverageBuilder.getClasses();
assertEquals(1, classes.size());
@@ -81,7 +81,7 @@ public class CoverageBuilderTest {
method.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, 7);
method.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, 8);
method.incrementMethodCounter();
- addClass(123L, "Sample", null, method);
+ addClass(123L, false, "Sample", null, method);
final Collection<IClassCoverage> classes = coverageBuilder.getClasses();
assertEquals(1, classes.size());
@@ -109,7 +109,7 @@ public class CoverageBuilderTest {
public void testIgnoreClassesWithoutCode() {
final MethodCoverageImpl method = new MethodCoverageImpl("doit", "()V",
null);
- addClass(123L, "Sample", null, method);
+ addClass(123L, false, "Sample", null, method);
final Collection<IClassCoverage> classes = coverageBuilder.getClasses();
assertTrue(classes.isEmpty());
@@ -119,24 +119,24 @@ public class CoverageBuilderTest {
public void testDuplicateClassNameDifferent() {
MethodCoverageImpl method = new MethodCoverageImpl("doit", "()V", null);
method.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 3);
- addClass(123L, "Sample", null, method);
+ addClass(123L, false, "Sample", null, method);
// Add class with different id must fail:
method = new MethodCoverageImpl("doit", "()V", null);
method.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 3);
- addClass(345L, "Sample", null, method);
+ addClass(345L, false, "Sample", null, method);
}
@Test
public void testDuplicateClassNameIdentical() {
MethodCoverageImpl method = new MethodCoverageImpl("doit", "()V", null);
method.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 3);
- addClass(123L, "Sample", null, method);
+ addClass(123L, false, "Sample", null, method);
// Add class with same id:
method = new MethodCoverageImpl("doit", "()V", null);
method.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 3);
- addClass(123L, "Sample", null, method);
+ addClass(123L, false, "Sample", null, method);
// Second add must be ignored:
final Collection<IClassCoverage> classes = coverageBuilder.getClasses();
@@ -148,12 +148,12 @@ public class CoverageBuilderTest {
final MethodCoverageImpl method1 = new MethodCoverageImpl("doit",
"()V", null);
method1.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 3);
- addClass(123L, "Sample", "Sample.java", method1);
+ addClass(123L, false, "Sample", "Sample.java", method1);
final MethodCoverageImpl method2 = new MethodCoverageImpl("doit",
"()V", null);
method2.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 6);
- addClass(234L, "Second", "Sample.java", method2);
+ addClass(234L, false, "Second", "Sample.java", method2);
final Collection<ISourceFileCoverage> sourcefiles = coverageBuilder
.getSourceFiles();
@@ -169,17 +169,17 @@ public class CoverageBuilderTest {
final MethodCoverageImpl method1 = new MethodCoverageImpl("doit",
"()V", null);
method1.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 3);
- addClass(1, "org/jacoco/examples/Sample1", null, method1);
+ addClass(1, false, "org/jacoco/examples/Sample1", null, method1);
final MethodCoverageImpl method2 = new MethodCoverageImpl("doit",
"()V", null);
method2.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 6);
- addClass(2, "org/jacoco/examples/Sample2", null, method2);
+ addClass(2, false, "org/jacoco/examples/Sample2", null, method2);
final MethodCoverageImpl method3 = new MethodCoverageImpl("doit",
"()V", null);
method3.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 1);
- addClass(3, "Sample3", null, method3);
+ addClass(3, false, "Sample3", null, method3);
IBundleCoverage bundle = coverageBuilder.getBundle("testbundle");
assertEquals("testbundle", bundle.getName());
@@ -205,6 +205,27 @@ public class CoverageBuilderTest {
getNames(p2.getClasses()));
}
+ @Test
+ public void testGetNoMatchClasses() {
+ MethodCoverageImpl m = new MethodCoverageImpl("doit", "()V", null);
+ m.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 1);
+ addClass(1, true, "Sample1", null, m);
+
+ m = new MethodCoverageImpl("doit", "()V", null);
+ m.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 2);
+ addClass(2, true, "Sample2", null, m);
+
+ m = new MethodCoverageImpl("doit", "()V", null);
+ m.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 3);
+ addClass(3, false, "Sample3", null, m);
+
+ final Set<String> actual = getNames(coverageBuilder.getNoMatchClasses());
+ final Set<String> expected = new HashSet<String>(Arrays.asList(
+ "Sample1", "Sample2"));
+
+ assertEquals(expected, actual);
+ }
+
private Set<String> getNames(Collection<? extends ICoverageNode> nodes) {
Set<String> result = new HashSet<String>();
for (ICoverageNode n : nodes) {
@@ -213,10 +234,10 @@ public class CoverageBuilderTest {
return result;
}
- private void addClass(long id, String name, String source,
+ private void addClass(long id, boolean nomatch, String name, String source,
MethodCoverageImpl... methods) {
final ClassCoverageImpl coverage = new ClassCoverageImpl(name, id,
- null, "java/lang/Object", new String[0]);
+ nomatch, null, "java/lang/Object", new String[0]);
coverage.setSourceFileName(source);
for (MethodCoverageImpl m : methods) {
coverage.addMethod(m);
diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataStoreTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataStoreTest.java
index 83bc8de5..dcf494b9 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataStoreTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataStoreTest.java
@@ -46,6 +46,7 @@ public class ExecutionDataStoreTest implements IExecutionDataVisitor {
@Test
public void testEmpty() {
assertNull(store.get(123));
+ assertFalse(store.contains("org/jacoco/example/Foo"));
store.accept(this);
assertEquals(Collections.emptyMap(), dataOutput);
}
@@ -56,6 +57,7 @@ public class ExecutionDataStoreTest implements IExecutionDataVisitor {
store.put(new ExecutionData(1000, "Sample", probes));
final ExecutionData data = store.get(1000);
assertSame(probes, data.getProbes());
+ assertTrue(store.contains("Sample"));
store.accept(this);
assertEquals(Collections.singletonMap(Long.valueOf(1000), data),
dataOutput);
@@ -96,6 +98,7 @@ public class ExecutionDataStoreTest implements IExecutionDataVisitor {
assertFalse(data.getProbes()[1]);
assertFalse(data.getProbes()[2]);
assertSame(data, store.get(id, "Sample", 3));
+ assertTrue(store.contains("Sample"));
}
@Test(expected = IllegalStateException.class)
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/BundleCoverageImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/BundleCoverageImplTest.java
index 00703d9f..63111f11 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/BundleCoverageImplTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/BundleCoverageImplTest.java
@@ -80,10 +80,10 @@ public class BundleCoverageImplTest {
@Test
public void testGroupByPackage() {
- ClassCoverageImpl ca = new ClassCoverageImpl("p1/A", 1, null,
+ ClassCoverageImpl ca = new ClassCoverageImpl("p1/A", 1, false, null,
"java/lang/Object", new String[0]);
ca.setSourceFileName("A.java");
- ClassCoverageImpl cb = new ClassCoverageImpl("p2/B", 2, null,
+ ClassCoverageImpl cb = new ClassCoverageImpl("p2/B", 2, false, null,
"java/lang/Object", new String[0]);
cb.setSourceFileName("B.java");
ISourceFileCoverage sb = new SourceFileCoverageImpl("B.java", "p2");
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java
index 7f4f9b25..a1484ef9 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java
@@ -25,7 +25,7 @@ public class ClassAnalyzerTest {
@Before
public void setup() {
- analyzer = new ClassAnalyzer(0x0000, null, new StringPool());
+ analyzer = new ClassAnalyzer(0x0000, false, null, new StringPool());
analyzer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Foo", null,
"java/lang/Object", null);
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassCoverageImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassCoverageImplTest.java
index 1f9cc9bd..39fe29ad 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassCoverageImplTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassCoverageImplTest.java
@@ -12,6 +12,10 @@
package org.jacoco.core.internal.analysis;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
import org.jacoco.core.analysis.ICoverageNode;
import org.jacoco.core.analysis.ISourceNode;
@@ -24,36 +28,45 @@ public class ClassCoverageImplTest {
@Test
public void testProperties() {
- ClassCoverageImpl data = new ClassCoverageImpl("Sample", 12345,
+ ClassCoverageImpl data = new ClassCoverageImpl("Sample", 12345, false,
"LSample;", "java/lang/Object", new String[0]);
data.setSourceFileName("Sample.java");
assertEquals(ICoverageNode.ElementType.CLASS, data.getElementType());
assertEquals("Sample", data.getName());
assertEquals(12345, data.getId());
+ assertFalse(data.isNoMatch());
assertEquals("LSample;", data.getSignature());
assertEquals("java/lang/Object", data.getSuperName());
assertEquals(0, data.getInterfaceNames().length);
assertEquals("Sample.java", data.getSourceFileName());
+ assertEquals(Collections.emptyList(), data.getMethods());
+ }
+
+ @Test
+ public void testNoMatch() {
+ ClassCoverageImpl data = new ClassCoverageImpl("Sample", 12345, true,
+ "LSample;", "java/lang/Object", new String[0]);
+ assertTrue(data.isNoMatch());
}
@Test
public void testGetPackageName1() {
ClassCoverageImpl data = new ClassCoverageImpl("ClassInDefaultPackage",
- 0, null, "java/lang/Object", new String[0]);
+ 0, false, null, "java/lang/Object", new String[0]);
assertEquals("", data.getPackageName());
}
@Test
public void testGetPackageName2() {
ClassCoverageImpl data = new ClassCoverageImpl(
- "org/jacoco/examples/Sample", 0, null, "java/lang/Object",
- new String[0]);
+ "org/jacoco/examples/Sample", 0, false, null,
+ "java/lang/Object", new String[0]);
assertEquals("org/jacoco/examples", data.getPackageName());
}
@Test
public void testEmptyClass() {
- ICoverageNode data = new ClassCoverageImpl("Sample", 0, null,
+ ICoverageNode data = new ClassCoverageImpl("Sample", 0, false, null,
"java/lang/Object", new String[0]);
assertEquals(CounterImpl.COUNTER_0_0, data.getInstructionCounter());
assertEquals(CounterImpl.COUNTER_0_0, data.getBranchCounter());
@@ -63,8 +76,8 @@ public class ClassCoverageImplTest {
@Test
public void testAddMethodMissed() {
- ClassCoverageImpl data = new ClassCoverageImpl("Sample", 0, null,
- "java/lang/Object", new String[0]);
+ ClassCoverageImpl data = new ClassCoverageImpl("Sample", 0, false,
+ null, "java/lang/Object", new String[0]);
data.addMethod(createMethod(false));
assertEquals(CounterImpl.COUNTER_1_0, data.getInstructionCounter());
assertEquals(CounterImpl.COUNTER_1_0, data.getMethodCounter());
@@ -73,8 +86,8 @@ public class ClassCoverageImplTest {
@Test
public void testAddMethodCovered() {
- ClassCoverageImpl data = new ClassCoverageImpl("Sample", 0, null,
- "java/lang/Object", new String[0]);
+ ClassCoverageImpl data = new ClassCoverageImpl("Sample", 0, false,
+ null, "java/lang/Object", new String[0]);
data.addMethod(createMethod(true));
assertEquals(CounterImpl.COUNTER_0_1, data.getInstructionCounter());
assertEquals(CounterImpl.COUNTER_0_1, data.getMethodCounter());
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/PackageCoverageTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/PackageCoverageTest.java
index e578a80b..2df29176 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/PackageCoverageTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/PackageCoverageTest.java
@@ -30,8 +30,8 @@ public class PackageCoverageTest {
public void testProperties() {
Collection<IClassCoverage> classes = Collections
.singleton((IClassCoverage) new ClassCoverageImpl(
- "org/jacoco/test/Sample", 0, null, "java/lang/Object",
- new String[0]));
+ "org/jacoco/test/Sample", 0, false, null,
+ "java/lang/Object", new String[0]));
Collection<ISourceFileCoverage> sourceFiles = Collections
.singleton((ISourceFileCoverage) new SourceFileCoverageImpl(
"Sample.java", "org/jacoco/test/Sample"));
@@ -47,7 +47,7 @@ public class PackageCoverageTest {
public void testCountersWithSources() {
// Classes with source reference will not considered for counters:
final ClassCoverageImpl classnode = new ClassCoverageImpl(
- "org/jacoco/test/Sample", 0, null, "java/lang/Object",
+ "org/jacoco/test/Sample", 0, false, null, "java/lang/Object",
new String[0]) {
{
classCounter = CounterImpl.getInstance(9, 0);
@@ -81,7 +81,7 @@ public class PackageCoverageTest {
public void testCountersWithoutSources() {
// Classes without source reference will be considered for counters:
final ClassCoverageImpl classnode = new ClassCoverageImpl(
- "org/jacoco/test/Sample", 0, null, "java/lang/Object",
+ "org/jacoco/test/Sample", 0, false, null, "java/lang/Object",
new String[0]) {
{
classCounter = CounterImpl.getInstance(1, 0);
diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
index f81026d0..de6397dc 100644
--- a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
@@ -68,13 +68,24 @@ public class Analyzer {
*
* @param classid
* id of the class calculated with {@link CRC64}
+ * @param className
+ * VM name of the class
* @return ASM visitor to write class definition to
*/
- private ClassVisitor createAnalyzingVisitor(final long classid) {
+ private ClassVisitor createAnalyzingVisitor(final long classid,
+ final String className) {
final ExecutionData data = executionData.get(classid);
- final boolean[] probes = data == null ? null : data.getProbes();
- final ClassAnalyzer analyzer = new ClassAnalyzer(classid, probes,
- stringPool) {
+ final boolean[] probes;
+ final boolean noMatch;
+ if (data == null) {
+ probes = null;
+ noMatch = executionData.contains(className);
+ } else {
+ probes = data.getProbes();
+ noMatch = false;
+ }
+ final ClassAnalyzer analyzer = new ClassAnalyzer(classid, noMatch,
+ probes, stringPool) {
@Override
public void visitEnd() {
super.visitEnd();
@@ -91,8 +102,8 @@ public class Analyzer {
* reader with class definitions
*/
public void analyzeClass(final ClassReader reader) {
- final ClassVisitor visitor = createAnalyzingVisitor(CRC64
- .checksum(reader.b));
+ final ClassVisitor visitor = createAnalyzingVisitor(
+ CRC64.checksum(reader.b), reader.getClassName());
reader.accept(visitor, 0);
}
diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java b/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java
index 93db3805..5dad8ea1 100644
--- a/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java
+++ b/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java
@@ -11,6 +11,7 @@
*******************************************************************************/
package org.jacoco.core.analysis;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -78,6 +79,22 @@ public class CoverageBuilder implements ICoverageVisitor {
sourcefiles.values());
}
+ /**
+ * Returns all classes for which execution data does not match.
+ *
+ * @see IClassCoverage#isNoMatch()
+ * @return collection of classes with non-matching execution data
+ */
+ public Collection<IClassCoverage> getNoMatchClasses() {
+ final Collection<IClassCoverage> result = new ArrayList<IClassCoverage>();
+ for (final IClassCoverage c : classes.values()) {
+ if (c.isNoMatch()) {
+ result.add(c);
+ }
+ }
+ return result;
+ }
+
// === IStructureVisitor ===
public void visitCoverage(final IClassCoverage coverage) {
diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/IClassCoverage.java b/org.jacoco.core/src/org/jacoco/core/analysis/IClassCoverage.java
index 4054f632..f05f0daa 100644
--- a/org.jacoco.core/src/org/jacoco/core/analysis/IClassCoverage.java
+++ b/org.jacoco.core/src/org/jacoco/core/analysis/IClassCoverage.java
@@ -30,6 +30,16 @@ public interface IClassCoverage extends ISourceNode {
public long getId();
/**
+ * Returns if the the analyzed class does match the execution data provided.
+ * More precisely if execution data is available for a class with the same
+ * qualified name but with a different class id.
+ *
+ * @return <code>true</code> if this class does not match to the provided
+ * execution data.
+ */
+ public boolean isNoMatch();
+
+ /**
* Returns the VM signature of the class.
*
* @return VM signature of the class (may be <code>null</code>)
diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java
index d73ce6d2..705f453c 100644
--- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java
+++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java
@@ -13,7 +13,9 @@ package org.jacoco.core.data;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
/**
* In-memory data store for execution data. The data can be added through its
@@ -27,6 +29,8 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
private final Map<Long, ExecutionData> entries = new HashMap<Long, ExecutionData>();
+ private final Set<String> names = new HashSet<String>();
+
/**
* Adds the given {@link ExecutionData} object into the store. If there is
* already execution data with this same class id, this structure is merged
@@ -44,6 +48,7 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
final ExecutionData entry = entries.get(id);
if (entry == null) {
entries.put(id, data);
+ names.add(data.getName());
} else {
entry.merge(data);
}
@@ -96,6 +101,19 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
}
/**
+ * Checks whether execution data for classes with the given name are
+ * contained in the store.
+ *
+ * @param name
+ * VM name
+ * @return <code>true</code> if at least one class with the name is
+ * contained.
+ */
+ public boolean contains(final String name) {
+ return names.contains(name);
+ }
+
+ /**
* Returns the coverage data for the class with the given identifier. If
* there is no data available under the given id a new entry is created.
*
@@ -113,6 +131,7 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
if (entry == null) {
entry = new ExecutionData(id.longValue(), name, probecount);
entries.put(id, entry);
+ names.add(name);
} else {
entry.assertCompatibility(id.longValue(), name, probecount);
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java
index 74d5da5c..8508ab18 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java
@@ -24,6 +24,7 @@ import org.objectweb.asm.Opcodes;
public class ClassAnalyzer extends ClassProbesVisitor {
private final long classid;
+ private final boolean noMatch;
private final boolean probes[];
private final StringPool stringPool;
@@ -34,14 +35,18 @@ public class ClassAnalyzer extends ClassProbesVisitor {
*
* @param classid
* id of the class
+ * @param noMatch
+ * <code>true</code> if class id does not match with execution
+ * data
* @param probes
* execution data for this class or <code>null</code>
* @param stringPool
* shared pool to minimize the number of {@link String} instances
*/
- public ClassAnalyzer(final long classid, final boolean[] probes,
- final StringPool stringPool) {
+ public ClassAnalyzer(final long classid, final boolean noMatch,
+ final boolean[] probes, final StringPool stringPool) {
this.classid = classid;
+ this.noMatch = noMatch;
this.probes = probes;
this.stringPool = stringPool;
}
@@ -61,7 +66,7 @@ public class ClassAnalyzer extends ClassProbesVisitor {
final String signature, final String superName,
final String[] interfaces) {
this.coverage = new ClassCoverageImpl(stringPool.get(name), classid,
- stringPool.get(signature), stringPool.get(superName),
+ noMatch, stringPool.get(signature), stringPool.get(superName),
stringPool.get(interfaces));
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java
index 3ee8667c..1a29f24e 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassCoverageImpl.java
@@ -23,6 +23,7 @@ import org.jacoco.core.analysis.IMethodCoverage;
public class ClassCoverageImpl extends SourceNodeImpl implements IClassCoverage {
private final long id;
+ private final boolean noMatch;
private final String signature;
private final String superName;
private final String[] interfaces;
@@ -36,6 +37,9 @@ public class ClassCoverageImpl extends SourceNodeImpl implements IClassCoverage
* vm name of the class
* @param id
* class identifier
+ * @param noMatch
+ * <code>true</code>, if class id does not match with execution
+ * data
* @param signature
* vm signature of the class
* @param superName
@@ -44,10 +48,11 @@ public class ClassCoverageImpl extends SourceNodeImpl implements IClassCoverage
* vm names of interfaces of this class
*/
public ClassCoverageImpl(final String name, final long id,
- final String signature, final String superName,
- final String[] interfaces) {
+ final boolean noMatch, final String signature,
+ final String superName, final String[] interfaces) {
super(ElementType.CLASS, name);
this.id = id;
+ this.noMatch = noMatch;
this.signature = signature;
this.superName = superName;
this.interfaces = interfaces;
@@ -87,6 +92,10 @@ public class ClassCoverageImpl extends SourceNodeImpl implements IClassCoverage
return id;
}
+ public boolean isNoMatch() {
+ return noMatch;
+ }
+
public String getSignature() {
return signature;
}
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index 14787b70..417f11e3 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -21,13 +21,18 @@
<h2>Snapshot Build @qualified.bundle.version@ (@build.date@)</h2>
<h3>New Features</h3>
+<ul>
+ <li>Warnings are logged during report generation if different versions of
+ classes are used than at runtime (GitHub <a href="https://github.com/jacoco/jacoco/issues/185">#185</a>).</li>
+</ul>
<h3>Fixed Bugs</h3>
<ul>
<li>Skip jacoco instrumentation for mvn modules with package type ear (GitHub <a href="https://github.com/jacoco/jacoco/issues/169">#169</a>).</li>
- <li>Align skip conditions and messages for Maven goals and give reasons (GitHub <a href="https://github.com/jacoco/jacoco/issues/171">#171</a>).
- This includes removal of the specific skip condition for packages e.g. POMs and instead checks existence of <tt>target/classes</tt> in appropriate
- goals.</li>
+ <li>Align skip conditions and messages for Maven goals and give reasons. This
+ includes removal of the specific skip condition for packages e.g. POMs and
+ instead checks existence of <tt>target/classes</tt> in appropriate goals
+ (GitHub <a href="https://github.com/jacoco/jacoco/issues/171">#171</a>).</li>
</ul>
<h3>API Changes</h3>
diff --git a/org.jacoco.report.test/src/org/jacoco/report/ReportStructureTestDriver.java b/org.jacoco.report.test/src/org/jacoco/report/ReportStructureTestDriver.java
index c338312c..3631ea18 100644
--- a/org.jacoco.report.test/src/org/jacoco/report/ReportStructureTestDriver.java
+++ b/org.jacoco.report.test/src/org/jacoco/report/ReportStructureTestDriver.java
@@ -74,8 +74,8 @@ public class ReportStructureTestDriver {
methodCoverage = m;
final ClassCoverageImpl classCoverageImpl = new ClassCoverageImpl(
- "org/jacoco/example/FooClass", 1001, null, "java/lang/Object",
- new String[0]);
+ "org/jacoco/example/FooClass", 1001, false, null,
+ "java/lang/Object", new String[0]);
classCoverageImpl.setSourceFileName("FooClass.java");
classCoverageImpl.addMethod(methodCoverage);
classCoverage = classCoverageImpl;
diff --git a/org.jacoco.report.test/src/org/jacoco/report/check/BundleCheckerTest.java b/org.jacoco.report.test/src/org/jacoco/report/check/BundleCheckerTest.java
index 743e784d..db40045e 100644
--- a/org.jacoco.report.test/src/org/jacoco/report/check/BundleCheckerTest.java
+++ b/org.jacoco.report.test/src/org/jacoco/report/check/BundleCheckerTest.java
@@ -134,8 +134,8 @@ public class BundleCheckerTest implements IViolationsOutput {
m.incrementMethodCounter();
final ClassCoverageImpl c = new ClassCoverageImpl(
- "org/jacoco/example/FooClass", 1001, null, "java/lang/Object",
- new String[0]);
+ "org/jacoco/example/FooClass", 1001, false, null,
+ "java/lang/Object", new String[0]);
c.setSourceFileName("FooClass.java");
c.addMethod(m);
diff --git a/org.jacoco.report.test/src/org/jacoco/report/csv/ClassRowWriterTest.java b/org.jacoco.report.test/src/org/jacoco/report/csv/ClassRowWriterTest.java
index ca80fd36..50d6e281 100644
--- a/org.jacoco.report.test/src/org/jacoco/report/csv/ClassRowWriterTest.java
+++ b/org.jacoco.report.test/src/org/jacoco/report/csv/ClassRowWriterTest.java
@@ -74,7 +74,7 @@ public class ClassRowWriterTest {
@Test
public void TestRow() throws Exception {
IClassCoverage node = new ClassCoverageImpl("test/package/Foo", 123,
- null, "java/lang/Object", null) {
+ false, null, "java/lang/Object", null) {
{
instructionCounter = CounterImpl.getInstance(1, 11);
branchCounter = CounterImpl.getInstance(2, 22);
diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ClassPageTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ClassPageTest.java
index 7e2ccc73..c1ed05cf 100644
--- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ClassPageTest.java
+++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ClassPageTest.java
@@ -35,8 +35,8 @@ public class ClassPageTest extends PageTestBase {
@Override
public void setup() throws Exception {
super.setup();
- node = new ClassCoverageImpl("org/jacoco/example/Foo", 123, null,
- "java/lang/Object", null);
+ node = new ClassCoverageImpl("org/jacoco/example/Foo", 123, false,
+ null, "java/lang/Object", null);
node.addMethod(new MethodCoverageImpl("a", "()V", null));
node.addMethod(new MethodCoverageImpl("b", "()V", null));
node.addMethod(new MethodCoverageImpl("c", "()V", null));
@@ -66,8 +66,8 @@ public class ClassPageTest extends PageTestBase {
@Test
public void testGetFileNameDefault() throws IOException {
- IClassCoverage defaultNode = new ClassCoverageImpl("Foo", 123, null,
- "java/lang/Object", null);
+ IClassCoverage defaultNode = new ClassCoverageImpl("Foo", 123, false,
+ null, "java/lang/Object", null);
page = new ClassPage(defaultNode, null, null, rootFolder, context);
assertEquals("Foo.html", page.getFileName());
}
diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/PackagePageTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/PackagePageTest.java
index af74ae4b..dd3258f1 100644
--- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/PackagePageTest.java
+++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/PackagePageTest.java
@@ -59,11 +59,11 @@ public class PackagePageTest extends PageTestBase {
@Test
public void testContentsWithSource() throws Exception {
IClassCoverage class1 = new ClassCoverageImpl(
- "org/jacoco/example/Foo1", 0x1000, null, "java/lang/Object",
- null);
+ "org/jacoco/example/Foo1", 0x1000, false, null,
+ "java/lang/Object", null);
IClassCoverage class2 = new ClassCoverageImpl(
- "org/jacoco/example/Foo2", 0x2000, null, "java/lang/Object",
- null);
+ "org/jacoco/example/Foo2", 0x2000, false, null,
+ "java/lang/Object", null);
ISourceFileCoverage src1 = new SourceFileCoverageImpl("Src1.java",
"org/jacoco/example");
node = new PackageCoverageImpl("org/jacoco/example", Arrays.asList(
@@ -96,11 +96,11 @@ public class PackagePageTest extends PageTestBase {
@Test
public void testContentsNoSource() throws Exception {
IClassCoverage class1 = new ClassCoverageImpl(
- "org/jacoco/example/Foo1", 0x1000, null, "java/lang/Object",
- null);
+ "org/jacoco/example/Foo1", 0x1000, false, null,
+ "java/lang/Object", null);
IClassCoverage class2 = new ClassCoverageImpl(
- "org/jacoco/example/Foo2", 0x2000, null, "java/lang/Object",
- null);
+ "org/jacoco/example/Foo2", 0x2000, false, null,
+ "java/lang/Object", null);
node = new PackageCoverageImpl("org/jacoco/example", Arrays.asList(
class1, class2), Collections.<ISourceFileCoverage> emptyList());