diff options
author | Evgeny Mandrikov <mandrikov@gmail.com> | 2012-08-30 22:13:04 +0600 |
---|---|---|
committer | Evgeny Mandrikov <mandrikov@gmail.com> | 2012-08-30 22:13:04 +0600 |
commit | e69ba4dbb015949c5d84ba7bbb0b53efac28bb23 (patch) | |
tree | 44cbe6d78216fcb3c37c0aca1dc7ed3fc09906fa | |
parent | a888d873ac20357a4a11029bc84c5c4b48e394a3 (diff) | |
download | platform_external_jacoco-e69ba4dbb015949c5d84ba7bbb0b53efac28bb23.tar.gz platform_external_jacoco-e69ba4dbb015949c5d84ba7bbb0b53efac28bb23.tar.bz2 platform_external_jacoco-e69ba4dbb015949c5d84ba7bbb0b53efac28bb23.zip |
Fix EOLs
244 files changed, 28293 insertions, 28293 deletions
diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/CoverageTransformerTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/CoverageTransformerTest.java index bfa1e7b6..78ece831 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/CoverageTransformerTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/CoverageTransformerTest.java @@ -1,172 +1,172 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt;
-
-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;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.instrument.IllegalClassFormatException;
-
-import org.jacoco.core.JaCoCo;
-import org.jacoco.core.runtime.AgentOptions;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link CoverageTransformer}.
- */
-public class CoverageTransformerTest {
-
- private ExceptionRecorder recorder;
-
- private AgentOptions options;
-
- private ClassLoader classLoader;
-
- private StubRuntime runtime;
-
- @Before
- public void setup() {
- recorder = new ExceptionRecorder();
- options = new AgentOptions();
- classLoader = getClass().getClassLoader();
- runtime = new StubRuntime();
- }
-
- @After
- public void teardown() {
- recorder.assertEmpty();
- }
-
- @Test
- public void testFilterAgentClass() {
- CoverageTransformer t = createTransformer();
- assertFalse(t.filter(classLoader,
- "org/jacoco/agent/rt/somepkg/SomeClass"));
- }
-
- @Test
- public void testFilterSystemClass() {
- CoverageTransformer t = createTransformer();
- assertFalse(t.filter(null, "org/example/Foo"));
- }
-
- @Test
- public void testFilterClassLoaderPositive() {
- options.setExclClassloader("org.jacoco.agent.SomeWhere$*");
- CoverageTransformer t = createTransformer();
- assertTrue(t.filter(classLoader, "org/example/Foo"));
- }
-
- @Test
- public void testFilterClassLoaderNegative() {
- options.setExclClassloader("org.jacoco.agent.rt.CoverageTransformerTest$*");
- CoverageTransformer t = createTransformer();
- ClassLoader myClassLoader = new ClassLoader(null) {
- };
- assertFalse(t.filter(myClassLoader, "org/example/Foo"));
- }
-
- @Test
- public void testFilterIncludedClassPositive() {
- options.setIncludes("org.jacoco.core.*:org.jacoco.agent.rt.*");
- CoverageTransformer t = createTransformer();
- assertTrue(t.filter(classLoader, "org/jacoco/core/Foo"));
- }
-
- @Test
- public void testFilterIncludedClassNegative() {
- options.setIncludes("org.jacoco.core.*:org.jacoco.agent.rt.*");
- CoverageTransformer t = createTransformer();
- assertFalse(t.filter(classLoader, "org/jacoco/report/Foo"));
- }
-
- @Test
- public void testFilterExcludedClassPositive() {
- options.setExcludes("*Test");
- CoverageTransformer t = createTransformer();
- assertFalse(t.filter(classLoader, "org/jacoco/core/FooTest"));
- }
-
- @Test
- public void testFilterExcludedClassPositiveInner() {
- options.setExcludes("org.jacoco.example.Foo$Inner");
- CoverageTransformer t = createTransformer();
- assertFalse(t.filter(classLoader, "org/jacoco/example/Foo$Inner"));
- }
-
- @Test
- public void testFilterExcludedClassNegative() {
- options.setExcludes("*Test");
- CoverageTransformer t = createTransformer();
- assertTrue(t.filter(classLoader, "org/jacoco/core/Foo"));
- }
-
- @Test
- public void testTransformFiltered() throws IllegalClassFormatException {
- CoverageTransformer t = createTransformer();
- assertNull(t.transform(null, "org.jacoco.Sample", null, null,
- new byte[0]));
- }
-
- @Test
- public void testTransformFailure() {
- CoverageTransformer t = createTransformer();
- try {
- t.transform(classLoader, "org.jacoco.Sample", null, null, null);
- fail("IllegalClassFormatException expected.");
- } catch (IllegalClassFormatException e) {
- assertEquals("Error while instrumenting class org.jacoco.Sample.",
- e.getMessage());
- }
- recorder.assertException(IllegalClassFormatException.class,
- "Error while instrumenting class org.jacoco.Sample.",
- NullPointerException.class);
- recorder.clear();
- }
-
- @Test
- public void testRedefinedClass() throws Exception {
- CoverageTransformer t = createTransformer();
- // Just pick any non-system class outside our namespace
- final Class<?> target = JaCoCo.class;
- t.transform(classLoader, target.getName(), target, null,
- getClassData(target));
- runtime.assertDisconnected(target);
- }
-
- private CoverageTransformer createTransformer() {
- return new CoverageTransformer(runtime, options, recorder);
- }
-
- private static byte[] getClassData(Class<?> clazz) throws IOException {
- final String resource = "/" + clazz.getName().replace('.', '/')
- + ".class";
- final InputStream in = clazz.getResourceAsStream(resource);
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
- byte[] buffer = new byte[0x100];
- int len;
- while ((len = in.read(buffer)) != -1) {
- out.write(buffer, 0, len);
- }
- in.close();
- return out.toByteArray();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt; + +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; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.instrument.IllegalClassFormatException; + +import org.jacoco.core.JaCoCo; +import org.jacoco.core.runtime.AgentOptions; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link CoverageTransformer}. + */ +public class CoverageTransformerTest { + + private ExceptionRecorder recorder; + + private AgentOptions options; + + private ClassLoader classLoader; + + private StubRuntime runtime; + + @Before + public void setup() { + recorder = new ExceptionRecorder(); + options = new AgentOptions(); + classLoader = getClass().getClassLoader(); + runtime = new StubRuntime(); + } + + @After + public void teardown() { + recorder.assertEmpty(); + } + + @Test + public void testFilterAgentClass() { + CoverageTransformer t = createTransformer(); + assertFalse(t.filter(classLoader, + "org/jacoco/agent/rt/somepkg/SomeClass")); + } + + @Test + public void testFilterSystemClass() { + CoverageTransformer t = createTransformer(); + assertFalse(t.filter(null, "org/example/Foo")); + } + + @Test + public void testFilterClassLoaderPositive() { + options.setExclClassloader("org.jacoco.agent.SomeWhere$*"); + CoverageTransformer t = createTransformer(); + assertTrue(t.filter(classLoader, "org/example/Foo")); + } + + @Test + public void testFilterClassLoaderNegative() { + options.setExclClassloader("org.jacoco.agent.rt.CoverageTransformerTest$*"); + CoverageTransformer t = createTransformer(); + ClassLoader myClassLoader = new ClassLoader(null) { + }; + assertFalse(t.filter(myClassLoader, "org/example/Foo")); + } + + @Test + public void testFilterIncludedClassPositive() { + options.setIncludes("org.jacoco.core.*:org.jacoco.agent.rt.*"); + CoverageTransformer t = createTransformer(); + assertTrue(t.filter(classLoader, "org/jacoco/core/Foo")); + } + + @Test + public void testFilterIncludedClassNegative() { + options.setIncludes("org.jacoco.core.*:org.jacoco.agent.rt.*"); + CoverageTransformer t = createTransformer(); + assertFalse(t.filter(classLoader, "org/jacoco/report/Foo")); + } + + @Test + public void testFilterExcludedClassPositive() { + options.setExcludes("*Test"); + CoverageTransformer t = createTransformer(); + assertFalse(t.filter(classLoader, "org/jacoco/core/FooTest")); + } + + @Test + public void testFilterExcludedClassPositiveInner() { + options.setExcludes("org.jacoco.example.Foo$Inner"); + CoverageTransformer t = createTransformer(); + assertFalse(t.filter(classLoader, "org/jacoco/example/Foo$Inner")); + } + + @Test + public void testFilterExcludedClassNegative() { + options.setExcludes("*Test"); + CoverageTransformer t = createTransformer(); + assertTrue(t.filter(classLoader, "org/jacoco/core/Foo")); + } + + @Test + public void testTransformFiltered() throws IllegalClassFormatException { + CoverageTransformer t = createTransformer(); + assertNull(t.transform(null, "org.jacoco.Sample", null, null, + new byte[0])); + } + + @Test + public void testTransformFailure() { + CoverageTransformer t = createTransformer(); + try { + t.transform(classLoader, "org.jacoco.Sample", null, null, null); + fail("IllegalClassFormatException expected."); + } catch (IllegalClassFormatException e) { + assertEquals("Error while instrumenting class org.jacoco.Sample.", + e.getMessage()); + } + recorder.assertException(IllegalClassFormatException.class, + "Error while instrumenting class org.jacoco.Sample.", + NullPointerException.class); + recorder.clear(); + } + + @Test + public void testRedefinedClass() throws Exception { + CoverageTransformer t = createTransformer(); + // Just pick any non-system class outside our namespace + final Class<?> target = JaCoCo.class; + t.transform(classLoader, target.getName(), target, null, + getClassData(target)); + runtime.assertDisconnected(target); + } + + private CoverageTransformer createTransformer() { + return new CoverageTransformer(runtime, options, recorder); + } + + private static byte[] getClassData(Class<?> clazz) throws IOException { + final String resource = "/" + clazz.getName().replace('.', '/') + + ".class"; + final InputStream in = clazz.getResourceAsStream(resource); + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[0x100]; + int len; + while ((len = in.read(buffer)) != -1) { + out.write(buffer, 0, len); + } + in.close(); + return out.toByteArray(); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/StubRuntime.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/StubRuntime.java index 2303480d..dac76c93 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/StubRuntime.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/StubRuntime.java @@ -1,66 +1,66 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-import java.util.Arrays;
-
-import org.jacoco.core.runtime.AbstractRuntime;
-import org.jacoco.core.runtime.IRuntime;
-import org.objectweb.asm.MethodVisitor;
-
-/**
- * Stub {@link IRuntime} implementation for unit testing only.
- */
-public class StubRuntime extends AbstractRuntime {
-
- private Class<?> disconnected;
-
- public StubRuntime() {
- setSessionId("stubid");
- store.get(Long.valueOf(0x12345678), "Foo", 2);
- }
-
- public int generateDataAccessor(long classid, String classname,
- int probecount, MethodVisitor mv) {
- return 0;
- }
-
- public void startup() {
- }
-
- public void shutdown() {
- }
-
- @Override
- public void disconnect(Class<?> type) throws Exception {
- this.disconnected = type;
- }
-
- public void fillProbes() {
- final boolean[] data = store.get(0x12345678).getData();
- Arrays.fill(data, true);
- }
-
- public void assertNoProbes() {
- final boolean[] data = store.get(0x12345678).getData();
- assertFalse(data[0]);
- assertFalse(data[1]);
- }
-
- public void assertDisconnected(Class<?> expected) {
- assertEquals(expected, disconnected);
- }
-
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.util.Arrays; + +import org.jacoco.core.runtime.AbstractRuntime; +import org.jacoco.core.runtime.IRuntime; +import org.objectweb.asm.MethodVisitor; + +/** + * Stub {@link IRuntime} implementation for unit testing only. + */ +public class StubRuntime extends AbstractRuntime { + + private Class<?> disconnected; + + public StubRuntime() { + setSessionId("stubid"); + store.get(Long.valueOf(0x12345678), "Foo", 2); + } + + public int generateDataAccessor(long classid, String classname, + int probecount, MethodVisitor mv) { + return 0; + } + + public void startup() { + } + + public void shutdown() { + } + + @Override + public void disconnect(Class<?> type) throws Exception { + this.disconnected = type; + } + + public void fillProbes() { + final boolean[] data = store.get(0x12345678).getData(); + Arrays.fill(data, true); + } + + public void assertNoProbes() { + final boolean[] data = store.get(0x12345678).getData(); + assertFalse(data[0]); + assertFalse(data[1]); + } + + public void assertDisconnected(Class<?> expected) { + assertEquals(expected, disconnected); + } + }
\ No newline at end of file diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/ExecutorTestBase.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/ExecutorTestBase.java index e3c3d022..050eca0b 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/ExecutorTestBase.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/ExecutorTestBase.java @@ -1,59 +1,59 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import static org.junit.Assert.fail;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import org.junit.After;
-import org.junit.Before;
-
-/**
- * Unit tests base for tests that need an {@link Executor} for multithreaded
- * test scenarios.
- */
-public abstract class ExecutorTestBase {
-
- protected ExecutorService executor;
-
- @Before
- public void setup() throws Exception {
- executor = Executors.newSingleThreadExecutor();
- }
-
- @After
- public void teardown() throws Exception {
- executor.shutdown();
- }
-
- /**
- * Asserts that the given future blocks.
- *
- * @param future
- * future to test
- * @throws Exception
- */
- protected void assertBlocks(final Future<?> future) throws Exception {
- try {
- future.get(10, TimeUnit.MILLISECONDS);
- fail("Operation should block");
- } catch (TimeoutException e) {
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import static org.junit.Assert.fail; + +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.junit.After; +import org.junit.Before; + +/** + * Unit tests base for tests that need an {@link Executor} for multithreaded + * test scenarios. + */ +public abstract class ExecutorTestBase { + + protected ExecutorService executor; + + @Before + public void setup() throws Exception { + executor = Executors.newSingleThreadExecutor(); + } + + @After + public void teardown() throws Exception { + executor.shutdown(); + } + + /** + * Asserts that the given future blocks. + * + * @param future + * future to test + * @throws Exception + */ + protected void assertBlocks(final Future<?> future) throws Exception { + try { + future.get(10, TimeUnit.MILLISECONDS); + fail("Operation should block"); + } catch (TimeoutException e) { + } + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/LocalControllerTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/LocalControllerTest.java index b747dee8..c82f6921 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/LocalControllerTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/LocalControllerTest.java @@ -1,61 +1,61 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.jacoco.agent.rt.StubRuntime;
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.IRuntime;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-/**
- * Unit tests for {@link LocalController}.
- */
-public class LocalControllerTest {
-
- @Rule
- public TemporaryFolder folder = new TemporaryFolder();
-
- @Test
- public void testWriteData() throws Exception {
- File destFile = folder.newFile("jacoco.exec");
- AgentOptions options = new AgentOptions();
- options.setDestfile(destFile.getAbsolutePath());
-
- IRuntime runtime = new StubRuntime();
-
- LocalController controller = new LocalController();
- controller.startup(options, runtime);
- controller.writeExecutionData();
- controller.shutdown();
-
- assertTrue("Execution data file should be created", destFile.exists());
- }
-
- @Test(expected = IOException.class)
- public void testInvalidDestFile() throws Exception {
- AgentOptions options = new AgentOptions();
- options.setDestfile(folder.newFolder("folder").getAbsolutePath());
- IRuntime runtime = new StubRuntime();
- LocalController controller = new LocalController();
-
- // Startup should fail as the file can not be created:
- controller.startup(options, runtime);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; + +import org.jacoco.agent.rt.StubRuntime; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.IRuntime; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +/** + * Unit tests for {@link LocalController}. + */ +public class LocalControllerTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void testWriteData() throws Exception { + File destFile = folder.newFile("jacoco.exec"); + AgentOptions options = new AgentOptions(); + options.setDestfile(destFile.getAbsolutePath()); + + IRuntime runtime = new StubRuntime(); + + LocalController controller = new LocalController(); + controller.startup(options, runtime); + controller.writeExecutionData(); + controller.shutdown(); + + assertTrue("Execution data file should be created", destFile.exists()); + } + + @Test(expected = IOException.class) + public void testInvalidDestFile() throws Exception { + AgentOptions options = new AgentOptions(); + options.setDestfile(folder.newFolder("folder").getAbsolutePath()); + IRuntime runtime = new StubRuntime(); + LocalController controller = new LocalController(); + + // Startup should fail as the file can not be created: + controller.startup(options, runtime); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/MockServerSocket.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/MockServerSocket.java index 696ffe8b..05407cb3 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/MockServerSocket.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/MockServerSocket.java @@ -1,188 +1,188 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.nio.channels.ServerSocketChannel;
-
-/**
- * Emulation of a {@link ServerSocket} for testing purposes without any physical
- * tcp/ip connections.
- */
-public class MockServerSocket extends ServerSocket {
-
- private final Object lock = new Object();
-
- private boolean closed;
-
- private Socket connection;
-
- private boolean inAccept;
-
- public MockServerSocket() throws IOException {
- super();
- closed = false;
- inAccept = false;
- }
-
- /**
- * Establishes a new mock connection. This method blocks until the other end
- * of the connection has been accepted.
- *
- * @return remote end of the mock connection
- */
- public Socket connect() throws Exception {
- synchronized (lock) {
- final MockSocketConnection c = new MockSocketConnection();
- connection = c.getSocketA();
- lock.notifyAll();
- while (connection != null) {
- lock.wait();
- }
- return c.getSocketB();
- }
- }
-
- /**
- * Blocks until another thread calls the {@link #accept()} method.
- */
- public void waitForAccept() throws Exception {
- synchronized (lock) {
- while (!inAccept) {
- lock.wait();
- }
- }
-
- }
-
- @Override
- public void close() throws IOException {
- synchronized (lock) {
- closed = true;
- lock.notifyAll();
- }
- }
-
- @Override
- public boolean isClosed() {
- return closed;
- }
-
- @Override
- public Socket accept() throws IOException {
- synchronized (lock) {
- inAccept = true;
- lock.notifyAll();
- try {
- while (connection == null) {
- if (closed) {
- throw new SocketException("socket closed");
- }
- lock.wait();
- }
- return connection;
- } catch (InterruptedException e) {
- throw new InterruptedIOException();
- } finally {
- connection = null;
- inAccept = false;
- lock.notifyAll();
- }
- }
- }
-
- // unsupported server socket methods:
-
- @Override
- public void bind(SocketAddress endpoint, int backlog) throws IOException {
- throw new AssertionError();
- }
-
- @Override
- public void bind(SocketAddress endpoint) throws IOException {
- throw new AssertionError();
- }
-
- @Override
- public ServerSocketChannel getChannel() {
- throw new AssertionError();
- }
-
- @Override
- public InetAddress getInetAddress() {
- throw new AssertionError();
- }
-
- @Override
- public int getLocalPort() {
- throw new AssertionError();
- }
-
- @Override
- public SocketAddress getLocalSocketAddress() {
- throw new AssertionError();
- }
-
- @Override
- public synchronized int getReceiveBufferSize() throws SocketException {
- throw new AssertionError();
- }
-
- @Override
- public boolean getReuseAddress() throws SocketException {
- throw new AssertionError();
- }
-
- @Override
- public synchronized int getSoTimeout() throws IOException {
- throw new AssertionError();
- }
-
- @Override
- public boolean isBound() {
- throw new AssertionError();
- }
-
- @Override
- public void setPerformancePreferences(int connectionTime, int latency,
- int bandwidth) {
- throw new AssertionError();
- }
-
- @Override
- public synchronized void setReceiveBufferSize(int size)
- throws SocketException {
- throw new AssertionError();
- }
-
- @Override
- public void setReuseAddress(boolean on) throws SocketException {
- throw new AssertionError();
- }
-
- @Override
- public synchronized void setSoTimeout(int timeout) throws SocketException {
- throw new AssertionError();
- }
-
- @Override
- public String toString() {
- throw new AssertionError();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.nio.channels.ServerSocketChannel; + +/** + * Emulation of a {@link ServerSocket} for testing purposes without any physical + * tcp/ip connections. + */ +public class MockServerSocket extends ServerSocket { + + private final Object lock = new Object(); + + private boolean closed; + + private Socket connection; + + private boolean inAccept; + + public MockServerSocket() throws IOException { + super(); + closed = false; + inAccept = false; + } + + /** + * Establishes a new mock connection. This method blocks until the other end + * of the connection has been accepted. + * + * @return remote end of the mock connection + */ + public Socket connect() throws Exception { + synchronized (lock) { + final MockSocketConnection c = new MockSocketConnection(); + connection = c.getSocketA(); + lock.notifyAll(); + while (connection != null) { + lock.wait(); + } + return c.getSocketB(); + } + } + + /** + * Blocks until another thread calls the {@link #accept()} method. + */ + public void waitForAccept() throws Exception { + synchronized (lock) { + while (!inAccept) { + lock.wait(); + } + } + + } + + @Override + public void close() throws IOException { + synchronized (lock) { + closed = true; + lock.notifyAll(); + } + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public Socket accept() throws IOException { + synchronized (lock) { + inAccept = true; + lock.notifyAll(); + try { + while (connection == null) { + if (closed) { + throw new SocketException("socket closed"); + } + lock.wait(); + } + return connection; + } catch (InterruptedException e) { + throw new InterruptedIOException(); + } finally { + connection = null; + inAccept = false; + lock.notifyAll(); + } + } + } + + // unsupported server socket methods: + + @Override + public void bind(SocketAddress endpoint, int backlog) throws IOException { + throw new AssertionError(); + } + + @Override + public void bind(SocketAddress endpoint) throws IOException { + throw new AssertionError(); + } + + @Override + public ServerSocketChannel getChannel() { + throw new AssertionError(); + } + + @Override + public InetAddress getInetAddress() { + throw new AssertionError(); + } + + @Override + public int getLocalPort() { + throw new AssertionError(); + } + + @Override + public SocketAddress getLocalSocketAddress() { + throw new AssertionError(); + } + + @Override + public synchronized int getReceiveBufferSize() throws SocketException { + throw new AssertionError(); + } + + @Override + public boolean getReuseAddress() throws SocketException { + throw new AssertionError(); + } + + @Override + public synchronized int getSoTimeout() throws IOException { + throw new AssertionError(); + } + + @Override + public boolean isBound() { + throw new AssertionError(); + } + + @Override + public void setPerformancePreferences(int connectionTime, int latency, + int bandwidth) { + throw new AssertionError(); + } + + @Override + public synchronized void setReceiveBufferSize(int size) + throws SocketException { + throw new AssertionError(); + } + + @Override + public void setReuseAddress(boolean on) throws SocketException { + throw new AssertionError(); + } + + @Override + public synchronized void setSoTimeout(int timeout) throws SocketException { + throw new AssertionError(); + } + + @Override + public String toString() { + throw new AssertionError(); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/MockServerSocketTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/MockServerSocketTest.java index 8b2f9fae..07e8b4e1 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/MockServerSocketTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/MockServerSocketTest.java @@ -1,150 +1,150 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link MockServerSocket}.
- */
-public class MockServerSocketTest extends ExecutorTestBase {
-
- private ServerSocket serverSocket;
-
- /**
- * To verify that the tests reflect the behavior of real TCP sockets this
- * flag can be set to <code>true</code>.
- */
- private static final boolean REAL_SOCKETS = Boolean
- .getBoolean("MockServerSocketTest.realSockets");
-
- @Before
- @Override
- public void setup() throws Exception {
- super.setup();
- if (REAL_SOCKETS) {
- System.err.println("Using Real Sockets!");
- final InetAddress addr = InetAddress.getByName("localhost");
- serverSocket = new ServerSocket(16300, 1, addr);
- } else {
- serverSocket = new MockServerSocket();
- }
- }
-
- @After
- @Override
- public void teardown() throws Exception {
- serverSocket.close();
- super.teardown();
- }
-
- private Socket connect() throws Exception {
- if (REAL_SOCKETS) {
- final InetAddress addr = InetAddress.getByName("localhost");
- return new Socket(addr, 16300);
- } else {
- return ((MockServerSocket) serverSocket).connect();
- }
-
- }
-
- @Test
- public void testClose() throws Exception {
- assertFalse(serverSocket.isClosed());
- serverSocket.close();
- assertTrue(serverSocket.isClosed());
- }
-
- @Test(expected = SocketException.class)
- public void testCloseWhileAccept() throws Throwable {
- final Future<Socket> f = executor.submit(new Callable<Socket>() {
- public Socket call() throws Exception {
- return serverSocket.accept();
- }
- });
- assertBlocks(f);
- serverSocket.close();
- try {
- f.get();
- } catch (ExecutionException e) {
- throw e.getCause();
- }
- }
-
- @Test
- public void testAccept() throws Exception {
- final Future<Socket> f = executor.submit(new Callable<Socket>() {
- public Socket call() throws Exception {
- return serverSocket.accept();
- }
- });
- assertBlocks(f);
- connect().getOutputStream().write(123);
- final Socket socket = f.get();
- assertNotNull(socket);
- assertEquals(123, socket.getInputStream().read());
- }
-
- @Test(expected = SocketException.class)
- public void testAcceptOnClosedServerSocket() throws Exception {
- serverSocket.close();
- serverSocket.accept();
- }
-
- @Test
- public void testConnect() throws Exception {
- if (!REAL_SOCKETS) {
- final Future<Socket> f = executor.submit(new Callable<Socket>() {
- public Socket call() throws Exception {
- return ((MockServerSocket) serverSocket).connect();
- }
- });
- assertBlocks(f);
- serverSocket.accept().getOutputStream().write(42);
- final Socket socket = f.get();
- assertNotNull(socket);
- assertEquals(42, socket.getInputStream().read());
- }
- }
-
- @Test
- public void testWaitForAccept() throws Exception {
- if (!REAL_SOCKETS) {
- final Future<Void> f = executor.submit(new Callable<Void>() {
- public Void call() throws Exception {
- ((MockServerSocket) serverSocket).waitForAccept();
- connect();
- return null;
- }
- });
- assertBlocks(f);
- serverSocket.accept();
- f.get();
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link MockServerSocket}. + */ +public class MockServerSocketTest extends ExecutorTestBase { + + private ServerSocket serverSocket; + + /** + * To verify that the tests reflect the behavior of real TCP sockets this + * flag can be set to <code>true</code>. + */ + private static final boolean REAL_SOCKETS = Boolean + .getBoolean("MockServerSocketTest.realSockets"); + + @Before + @Override + public void setup() throws Exception { + super.setup(); + if (REAL_SOCKETS) { + System.err.println("Using Real Sockets!"); + final InetAddress addr = InetAddress.getByName("localhost"); + serverSocket = new ServerSocket(16300, 1, addr); + } else { + serverSocket = new MockServerSocket(); + } + } + + @After + @Override + public void teardown() throws Exception { + serverSocket.close(); + super.teardown(); + } + + private Socket connect() throws Exception { + if (REAL_SOCKETS) { + final InetAddress addr = InetAddress.getByName("localhost"); + return new Socket(addr, 16300); + } else { + return ((MockServerSocket) serverSocket).connect(); + } + + } + + @Test + public void testClose() throws Exception { + assertFalse(serverSocket.isClosed()); + serverSocket.close(); + assertTrue(serverSocket.isClosed()); + } + + @Test(expected = SocketException.class) + public void testCloseWhileAccept() throws Throwable { + final Future<Socket> f = executor.submit(new Callable<Socket>() { + public Socket call() throws Exception { + return serverSocket.accept(); + } + }); + assertBlocks(f); + serverSocket.close(); + try { + f.get(); + } catch (ExecutionException e) { + throw e.getCause(); + } + } + + @Test + public void testAccept() throws Exception { + final Future<Socket> f = executor.submit(new Callable<Socket>() { + public Socket call() throws Exception { + return serverSocket.accept(); + } + }); + assertBlocks(f); + connect().getOutputStream().write(123); + final Socket socket = f.get(); + assertNotNull(socket); + assertEquals(123, socket.getInputStream().read()); + } + + @Test(expected = SocketException.class) + public void testAcceptOnClosedServerSocket() throws Exception { + serverSocket.close(); + serverSocket.accept(); + } + + @Test + public void testConnect() throws Exception { + if (!REAL_SOCKETS) { + final Future<Socket> f = executor.submit(new Callable<Socket>() { + public Socket call() throws Exception { + return ((MockServerSocket) serverSocket).connect(); + } + }); + assertBlocks(f); + serverSocket.accept().getOutputStream().write(42); + final Socket socket = f.get(); + assertNotNull(socket); + assertEquals(42, socket.getInputStream().read()); + } + } + + @Test + public void testWaitForAccept() throws Exception { + if (!REAL_SOCKETS) { + final Future<Void> f = executor.submit(new Callable<Void>() { + public Void call() throws Exception { + ((MockServerSocket) serverSocket).waitForAccept(); + connect(); + return null; + } + }); + assertBlocks(f); + serverSocket.accept(); + f.get(); + } + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpClientControllerTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpClientControllerTest.java index b34d4923..67ed2767 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpClientControllerTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpClientControllerTest.java @@ -1,113 +1,113 @@ -/*******************************************************************************
-/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- * Marc R. Hoffmann - migration to mock socket
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.util.List;
-
-import org.jacoco.agent.rt.ExceptionRecorder;
-import org.jacoco.agent.rt.StubRuntime;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.core.data.SessionInfoStore;
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.RemoteControlReader;
-import org.jacoco.core.runtime.RemoteControlWriter;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link TcpClientController}.
- */
-public class TcpClientControllerTest {
-
- private ExceptionRecorder logger;
-
- private IAgentController controller;
-
- private StubRuntime runtime;
-
- private Socket remoteSocket;
-
- private RemoteControlWriter remoteWriter;
-
- private RemoteControlReader remoteReader;
-
- @Before
- public void setup() throws Exception {
- logger = new ExceptionRecorder();
- final MockSocketConnection con = new MockSocketConnection();
- remoteSocket = con.getSocketB();
- remoteWriter = new RemoteControlWriter(remoteSocket.getOutputStream());
- controller = new TcpClientController(logger) {
- @Override
- protected Socket createSocket(AgentOptions options)
- throws IOException {
- return con.getSocketA();
- }
- };
- runtime = new StubRuntime();
- controller.startup(new AgentOptions(), runtime);
- remoteReader = new RemoteControlReader(remoteSocket.getInputStream());
- }
-
- @Test
- public void testShutdown() throws Exception {
- controller.shutdown();
- assertFalse(remoteReader.read());
- logger.assertEmpty();
- }
-
- @Test
- public void testRemoteClose() throws Exception {
- remoteSocket.close();
- controller.shutdown();
- logger.assertEmpty();
- }
-
- @Test
- public void testInvalidCommand() throws Exception {
- remoteWriter.visitSessionInfo(new SessionInfo("info", 1, 2));
- while (remoteReader.read()) {
- }
- controller.shutdown();
- logger.assertException(IOException.class, "No session info visitor.");
- }
-
- @Test
- public void testWriteExecutionData() throws Exception {
- controller.writeExecutionData();
-
- final ExecutionDataStore execStore = new ExecutionDataStore();
- remoteReader.setExecutionDataVisitor(execStore);
- final SessionInfoStore infoStore = new SessionInfoStore();
- remoteReader.setSessionInfoVisitor(infoStore);
-
- remoteReader.read();
-
- assertEquals("Foo", execStore.get(0x12345678).getName());
-
- final List<SessionInfo> infos = infoStore.getInfos();
- assertEquals(1, infos.size());
- assertEquals("stubid", infos.get(0).getId());
-
- logger.assertEmpty();
- controller.shutdown();
- }
-
-}
+/******************************************************************************* +/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * Marc R. Hoffmann - migration to mock socket + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.io.IOException; +import java.net.Socket; +import java.util.List; + +import org.jacoco.agent.rt.ExceptionRecorder; +import org.jacoco.agent.rt.StubRuntime; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.data.SessionInfoStore; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link TcpClientController}. + */ +public class TcpClientControllerTest { + + private ExceptionRecorder logger; + + private IAgentController controller; + + private StubRuntime runtime; + + private Socket remoteSocket; + + private RemoteControlWriter remoteWriter; + + private RemoteControlReader remoteReader; + + @Before + public void setup() throws Exception { + logger = new ExceptionRecorder(); + final MockSocketConnection con = new MockSocketConnection(); + remoteSocket = con.getSocketB(); + remoteWriter = new RemoteControlWriter(remoteSocket.getOutputStream()); + controller = new TcpClientController(logger) { + @Override + protected Socket createSocket(AgentOptions options) + throws IOException { + return con.getSocketA(); + } + }; + runtime = new StubRuntime(); + controller.startup(new AgentOptions(), runtime); + remoteReader = new RemoteControlReader(remoteSocket.getInputStream()); + } + + @Test + public void testShutdown() throws Exception { + controller.shutdown(); + assertFalse(remoteReader.read()); + logger.assertEmpty(); + } + + @Test + public void testRemoteClose() throws Exception { + remoteSocket.close(); + controller.shutdown(); + logger.assertEmpty(); + } + + @Test + public void testInvalidCommand() throws Exception { + remoteWriter.visitSessionInfo(new SessionInfo("info", 1, 2)); + while (remoteReader.read()) { + } + controller.shutdown(); + logger.assertException(IOException.class, "No session info visitor."); + } + + @Test + public void testWriteExecutionData() throws Exception { + controller.writeExecutionData(); + + final ExecutionDataStore execStore = new ExecutionDataStore(); + remoteReader.setExecutionDataVisitor(execStore); + final SessionInfoStore infoStore = new SessionInfoStore(); + remoteReader.setSessionInfoVisitor(infoStore); + + remoteReader.read(); + + assertEquals("Foo", execStore.get(0x12345678).getName()); + + final List<SessionInfo> infos = infoStore.getInfos(); + assertEquals(1, infos.size()); + assertEquals("stubid", infos.get(0).getId()); + + logger.assertEmpty(); + controller.shutdown(); + } + +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpConnectionTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpConnectionTest.java index 49654668..94fd025d 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpConnectionTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpConnectionTest.java @@ -1,265 +1,265 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Future;
-
-import org.jacoco.agent.rt.StubRuntime;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.data.ExecutionDataWriter;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.core.data.SessionInfoStore;
-import org.jacoco.core.runtime.RemoteControlReader;
-import org.jacoco.core.runtime.RemoteControlWriter;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link TcpConnection}.
- */
-public class TcpConnectionTest extends ExecutorTestBase {
-
- private MockSocketConnection mockConnection;
-
- private StubRuntime runtime;
-
- @Before
- @Override
- public void setup() throws Exception {
- super.setup();
- mockConnection = new MockSocketConnection();
- runtime = new StubRuntime();
- }
-
- @Test(expected = IOException.class)
- public void testInvalidHeader() throws Exception {
- final OutputStream remoteOut = mockConnection.getSocketB()
- .getOutputStream();
- remoteOut.write(0x01);
- remoteOut.write(0xC0);
- remoteOut.write(0xCA);
- final TcpConnection connection = new TcpConnection(
- mockConnection.getSocketA(), runtime);
- connection.init();
- connection.run();
- }
-
- @Test(expected = IOException.class)
- public void testInvalidContent() throws Exception {
- final OutputStream remoteOut = mockConnection.getSocketB()
- .getOutputStream();
- new ExecutionDataWriter(remoteOut);
- final TcpConnection con = new TcpConnection(
- mockConnection.getSocketA(), runtime);
- con.init();
- remoteOut.write(123);
- con.run();
- }
-
- /**
- * Remote endpoint is closed after a valid header has been send.
- */
- @Test
- public void testRemoteClose() throws Exception {
- final OutputStream remoteOut = mockConnection.getSocketB()
- .getOutputStream();
- new ExecutionDataWriter(remoteOut);
-
- final TcpConnection con = new TcpConnection(
- mockConnection.getSocketA(), runtime);
- con.init();
-
- final Future<Void> f = executor.submit(new Callable<Void>() {
- public Void call() throws Exception {
- con.run();
- return null;
- }
- });
-
- assertBlocks(f);
-
- mockConnection.getSocketB().close();
- f.get();
- }
-
- /**
- * Remote endpoint is closed before even a valid header was send.
- */
- public void testRemoteCloseWithoutHeader() throws Throwable {
- final TcpConnection con = new TcpConnection(
- mockConnection.getSocketA(), runtime);
-
- final Future<Void> f = executor.submit(new Callable<Void>() {
- public Void call() throws Exception {
- con.init();
- return null;
- }
- });
-
- assertBlocks(f);
-
- mockConnection.getSocketB().close();
- f.get();
- }
-
- /**
- * Local socket is closed while waiting for commands.
- *
- * @throws Exception
- */
- @Test
- public void testLocalClose() throws Exception {
- final OutputStream remoteOut = mockConnection.getSocketB()
- .getOutputStream();
- new ExecutionDataWriter(remoteOut);
-
- final TcpConnection con = new TcpConnection(
- mockConnection.getSocketA(), runtime);
- con.init();
-
- final Future<Void> f = executor.submit(new Callable<Void>() {
- public Void call() throws Exception {
- con.run();
- return null;
- }
- });
-
- assertBlocks(f);
-
- con.close();
- f.get();
- }
-
- @Test
- public void testRemoteDump() throws Exception {
- final RemoteControlWriter remoteWriter = new RemoteControlWriter(
- mockConnection.getSocketB().getOutputStream());
-
- final TcpConnection con = new TcpConnection(
- mockConnection.getSocketA(), runtime);
- con.init();
-
- final Future<Void> f = executor.submit(new Callable<Void>() {
- public Void call() throws Exception {
- con.run();
- return null;
- }
- });
-
- assertBlocks(f);
-
- remoteWriter.visitDumpCommand(true, false);
- readAndAssertData();
-
- con.close();
- f.get();
- }
-
- @Test
- public void testLocalDump() throws Exception {
- new RemoteControlWriter(mockConnection.getSocketB().getOutputStream());
-
- final TcpConnection con = new TcpConnection(
- mockConnection.getSocketA(), runtime);
- con.init();
-
- final Future<Void> f = executor.submit(new Callable<Void>() {
- public Void call() throws Exception {
- con.run();
- return null;
- }
- });
-
- assertBlocks(f);
-
- con.writeExecutionData();
- readAndAssertData();
-
- con.close();
- f.get();
- }
-
- @Test
- public void testLocalDumpWithoutInit() throws Exception {
- final TcpConnection con = new TcpConnection(
- mockConnection.getSocketA(), runtime);
- // Must not write any data as we're not initialized:
- con.writeExecutionData();
-
- assertEquals(0, mockConnection.getSocketB().getInputStream()
- .available());
- }
-
- private void readAndAssertData() throws IOException {
- final RemoteControlReader remoteReader = new RemoteControlReader(
- mockConnection.getSocketB().getInputStream());
-
- final ExecutionDataStore execStore = new ExecutionDataStore();
- remoteReader.setExecutionDataVisitor(execStore);
- final SessionInfoStore infoStore = new SessionInfoStore();
- remoteReader.setSessionInfoVisitor(infoStore);
-
- assertTrue(remoteReader.read());
-
- final List<SessionInfo> infos = infoStore.getInfos();
- assertEquals(1, infos.size());
- assertEquals("stubid", infos.get(0).getId());
-
- assertEquals("Foo", execStore.get(0x12345678).getName());
- }
-
- @Test
- public void testRemoteReset() throws Exception {
- runtime.fillProbes();
-
- final RemoteControlWriter remoteWriter = new RemoteControlWriter(
- mockConnection.getSocketB().getOutputStream());
-
- final TcpConnection con = new TcpConnection(
- mockConnection.getSocketA(), runtime);
- con.init();
-
- final Future<Void> f = executor.submit(new Callable<Void>() {
- public Void call() throws Exception {
- con.run();
- return null;
- }
- });
-
- assertBlocks(f);
-
- remoteWriter.visitDumpCommand(false, true);
-
- final RemoteControlReader remoteReader = new RemoteControlReader(
- mockConnection.getSocketB().getInputStream());
-
- final ExecutionDataStore execStore = new ExecutionDataStore();
- remoteReader.setExecutionDataVisitor(execStore);
- final SessionInfoStore infoStore = new SessionInfoStore();
- remoteReader.setSessionInfoVisitor(infoStore);
-
- assertTrue(remoteReader.read());
- assertTrue(infoStore.getInfos().isEmpty());
- assertTrue(execStore.getContents().isEmpty());
- runtime.assertNoProbes();
-
- con.close();
- f.get();
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; + +import org.jacoco.agent.rt.StubRuntime; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.ExecutionDataWriter; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.data.SessionInfoStore; +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link TcpConnection}. + */ +public class TcpConnectionTest extends ExecutorTestBase { + + private MockSocketConnection mockConnection; + + private StubRuntime runtime; + + @Before + @Override + public void setup() throws Exception { + super.setup(); + mockConnection = new MockSocketConnection(); + runtime = new StubRuntime(); + } + + @Test(expected = IOException.class) + public void testInvalidHeader() throws Exception { + final OutputStream remoteOut = mockConnection.getSocketB() + .getOutputStream(); + remoteOut.write(0x01); + remoteOut.write(0xC0); + remoteOut.write(0xCA); + final TcpConnection connection = new TcpConnection( + mockConnection.getSocketA(), runtime); + connection.init(); + connection.run(); + } + + @Test(expected = IOException.class) + public void testInvalidContent() throws Exception { + final OutputStream remoteOut = mockConnection.getSocketB() + .getOutputStream(); + new ExecutionDataWriter(remoteOut); + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), runtime); + con.init(); + remoteOut.write(123); + con.run(); + } + + /** + * Remote endpoint is closed after a valid header has been send. + */ + @Test + public void testRemoteClose() throws Exception { + final OutputStream remoteOut = mockConnection.getSocketB() + .getOutputStream(); + new ExecutionDataWriter(remoteOut); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), runtime); + con.init(); + + final Future<Void> f = executor.submit(new Callable<Void>() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + mockConnection.getSocketB().close(); + f.get(); + } + + /** + * Remote endpoint is closed before even a valid header was send. + */ + public void testRemoteCloseWithoutHeader() throws Throwable { + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), runtime); + + final Future<Void> f = executor.submit(new Callable<Void>() { + public Void call() throws Exception { + con.init(); + return null; + } + }); + + assertBlocks(f); + + mockConnection.getSocketB().close(); + f.get(); + } + + /** + * Local socket is closed while waiting for commands. + * + * @throws Exception + */ + @Test + public void testLocalClose() throws Exception { + final OutputStream remoteOut = mockConnection.getSocketB() + .getOutputStream(); + new ExecutionDataWriter(remoteOut); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), runtime); + con.init(); + + final Future<Void> f = executor.submit(new Callable<Void>() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + con.close(); + f.get(); + } + + @Test + public void testRemoteDump() throws Exception { + final RemoteControlWriter remoteWriter = new RemoteControlWriter( + mockConnection.getSocketB().getOutputStream()); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), runtime); + con.init(); + + final Future<Void> f = executor.submit(new Callable<Void>() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + remoteWriter.visitDumpCommand(true, false); + readAndAssertData(); + + con.close(); + f.get(); + } + + @Test + public void testLocalDump() throws Exception { + new RemoteControlWriter(mockConnection.getSocketB().getOutputStream()); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), runtime); + con.init(); + + final Future<Void> f = executor.submit(new Callable<Void>() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + con.writeExecutionData(); + readAndAssertData(); + + con.close(); + f.get(); + } + + @Test + public void testLocalDumpWithoutInit() throws Exception { + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), runtime); + // Must not write any data as we're not initialized: + con.writeExecutionData(); + + assertEquals(0, mockConnection.getSocketB().getInputStream() + .available()); + } + + private void readAndAssertData() throws IOException { + final RemoteControlReader remoteReader = new RemoteControlReader( + mockConnection.getSocketB().getInputStream()); + + final ExecutionDataStore execStore = new ExecutionDataStore(); + remoteReader.setExecutionDataVisitor(execStore); + final SessionInfoStore infoStore = new SessionInfoStore(); + remoteReader.setSessionInfoVisitor(infoStore); + + assertTrue(remoteReader.read()); + + final List<SessionInfo> infos = infoStore.getInfos(); + assertEquals(1, infos.size()); + assertEquals("stubid", infos.get(0).getId()); + + assertEquals("Foo", execStore.get(0x12345678).getName()); + } + + @Test + public void testRemoteReset() throws Exception { + runtime.fillProbes(); + + final RemoteControlWriter remoteWriter = new RemoteControlWriter( + mockConnection.getSocketB().getOutputStream()); + + final TcpConnection con = new TcpConnection( + mockConnection.getSocketA(), runtime); + con.init(); + + final Future<Void> f = executor.submit(new Callable<Void>() { + public Void call() throws Exception { + con.run(); + return null; + } + }); + + assertBlocks(f); + + remoteWriter.visitDumpCommand(false, true); + + final RemoteControlReader remoteReader = new RemoteControlReader( + mockConnection.getSocketB().getInputStream()); + + final ExecutionDataStore execStore = new ExecutionDataStore(); + remoteReader.setExecutionDataVisitor(execStore); + final SessionInfoStore infoStore = new SessionInfoStore(); + remoteReader.setSessionInfoVisitor(infoStore); + + assertTrue(remoteReader.read()); + assertTrue(infoStore.getInfos().isEmpty()); + assertTrue(execStore.getContents().isEmpty()); + runtime.assertNoProbes(); + + con.close(); + f.get(); + } +} diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpServerControllerTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpServerControllerTest.java index 26c813c6..b965b238 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpServerControllerTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/controller/TcpServerControllerTest.java @@ -1,142 +1,142 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- * Marc R. Hoffmann - migration to mock socket
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.UnknownHostException;
-import java.util.List;
-
-import org.jacoco.agent.rt.ExceptionRecorder;
-import org.jacoco.agent.rt.StubRuntime;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.data.ExecutionDataWriter;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.core.data.SessionInfoStore;
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.RemoteControlReader;
-import org.jacoco.core.runtime.RemoteControlWriter;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link TcpServerController}.
- */
-public class TcpServerControllerTest {
-
- private ExceptionRecorder logger;
-
- private AgentOptions options;
-
- private StubRuntime runtime;
-
- private MockServerSocket serverSocket;
-
- private TcpServerController controller;
-
- @Before
- public void setup() throws Exception {
- options = new AgentOptions();
- runtime = new StubRuntime();
- logger = new ExceptionRecorder();
- serverSocket = new MockServerSocket();
- controller = new TcpServerController(logger) {
- @Override
- protected ServerSocket createServerSocket(AgentOptions options)
- throws IOException {
- return serverSocket;
- }
- };
- controller.startup(options, runtime);
- }
-
- @Test
- public void testShutdownWithoutConnection() throws Exception {
- serverSocket.waitForAccept();
- controller.shutdown();
- logger.assertEmpty();
- }
-
- @Test
- public void testShutdownWithConnection() throws Exception {
- serverSocket.waitForAccept();
- new ExecutionDataWriter(serverSocket.connect().getOutputStream());
- controller.shutdown();
- logger.assertEmpty();
- }
-
- @Test
- public void testWriteExecutionData() throws Exception {
- final Socket socket = serverSocket.connect();
- final RemoteControlWriter remoteWriter = new RemoteControlWriter(
- socket.getOutputStream());
- final RemoteControlReader remoteReader = new RemoteControlReader(
- socket.getInputStream());
-
- // First process a NOP command to ensure the connection is initialized:
- remoteWriter.visitDumpCommand(false, false);
- remoteReader.read();
-
- // Now the actual test starts:
- controller.writeExecutionData();
-
- final ExecutionDataStore execStore = new ExecutionDataStore();
- remoteReader.setExecutionDataVisitor(execStore);
- final SessionInfoStore infoStore = new SessionInfoStore();
- remoteReader.setSessionInfoVisitor(infoStore);
- remoteReader.read();
-
- assertEquals("Foo", execStore.get(0x12345678).getName());
-
- final List<SessionInfo> infos = infoStore.getInfos();
- assertEquals(1, infos.size());
- assertEquals("stubid", infos.get(0).getId());
-
- logger.assertEmpty();
- controller.shutdown();
- }
-
- @Test
- public void testInvalidHeader() throws Exception {
- final Socket socket = serverSocket.connect();
- final OutputStream out = socket.getOutputStream();
- out.write(0xca);
- out.write(0xfe);
- out.write(0xba);
- out.write(0xbe);
- serverSocket.waitForAccept();
- logger.assertException(IOException.class,
- "Invalid execution data file.");
- controller.shutdown();
- }
-
- @Test
- public void testGetInetAddressLoopback() throws UnknownHostException {
- final InetAddress addr = controller.getInetAddress(null);
- assertTrue(addr.isLoopbackAddress());
- }
-
- @Test
- public void testGetInetAddressAny() throws UnknownHostException {
- final InetAddress addr = controller.getInetAddress("*");
- assertNull(addr);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * Marc R. Hoffmann - migration to mock socket + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.List; + +import org.jacoco.agent.rt.ExceptionRecorder; +import org.jacoco.agent.rt.StubRuntime; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.ExecutionDataWriter; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.data.SessionInfoStore; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link TcpServerController}. + */ +public class TcpServerControllerTest { + + private ExceptionRecorder logger; + + private AgentOptions options; + + private StubRuntime runtime; + + private MockServerSocket serverSocket; + + private TcpServerController controller; + + @Before + public void setup() throws Exception { + options = new AgentOptions(); + runtime = new StubRuntime(); + logger = new ExceptionRecorder(); + serverSocket = new MockServerSocket(); + controller = new TcpServerController(logger) { + @Override + protected ServerSocket createServerSocket(AgentOptions options) + throws IOException { + return serverSocket; + } + }; + controller.startup(options, runtime); + } + + @Test + public void testShutdownWithoutConnection() throws Exception { + serverSocket.waitForAccept(); + controller.shutdown(); + logger.assertEmpty(); + } + + @Test + public void testShutdownWithConnection() throws Exception { + serverSocket.waitForAccept(); + new ExecutionDataWriter(serverSocket.connect().getOutputStream()); + controller.shutdown(); + logger.assertEmpty(); + } + + @Test + public void testWriteExecutionData() throws Exception { + final Socket socket = serverSocket.connect(); + final RemoteControlWriter remoteWriter = new RemoteControlWriter( + socket.getOutputStream()); + final RemoteControlReader remoteReader = new RemoteControlReader( + socket.getInputStream()); + + // First process a NOP command to ensure the connection is initialized: + remoteWriter.visitDumpCommand(false, false); + remoteReader.read(); + + // Now the actual test starts: + controller.writeExecutionData(); + + final ExecutionDataStore execStore = new ExecutionDataStore(); + remoteReader.setExecutionDataVisitor(execStore); + final SessionInfoStore infoStore = new SessionInfoStore(); + remoteReader.setSessionInfoVisitor(infoStore); + remoteReader.read(); + + assertEquals("Foo", execStore.get(0x12345678).getName()); + + final List<SessionInfo> infos = infoStore.getInfos(); + assertEquals(1, infos.size()); + assertEquals("stubid", infos.get(0).getId()); + + logger.assertEmpty(); + controller.shutdown(); + } + + @Test + public void testInvalidHeader() throws Exception { + final Socket socket = serverSocket.connect(); + final OutputStream out = socket.getOutputStream(); + out.write(0xca); + out.write(0xfe); + out.write(0xba); + out.write(0xbe); + serverSocket.waitForAccept(); + logger.assertException(IOException.class, + "Invalid execution data file."); + controller.shutdown(); + } + + @Test + public void testGetInetAddressLoopback() throws UnknownHostException { + final InetAddress addr = controller.getInetAddress(null); + assertTrue(addr.isLoopbackAddress()); + } + + @Test + public void testGetInetAddressAny() throws UnknownHostException { + final InetAddress addr = controller.getInetAddress("*"); + assertNull(addr); + } + +} diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/CoverageTransformer.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/CoverageTransformer.java index 2f679154..b23d6a10 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/CoverageTransformer.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/CoverageTransformer.java @@ -1,138 +1,138 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt;
-
-import static java.lang.String.format;
-
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
-import java.security.ProtectionDomain;
-
-import org.jacoco.core.instr.Instrumenter;
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.IRuntime;
-import org.jacoco.core.runtime.WildcardMatcher;
-
-/**
- * Class file transformer to instrument classes for code coverage analysis.
- */
-public class CoverageTransformer implements ClassFileTransformer {
-
- private static final String AGENT_PREFIX;
-
- static {
- final String name = CoverageTransformer.class.getName();
- AGENT_PREFIX = toVMName(name.substring(0, name.lastIndexOf('.')));
- }
-
- private final IRuntime runtime;
-
- private final Instrumenter instrumenter;
-
- private final IExceptionLogger logger;
-
- private final WildcardMatcher includes;
-
- private final WildcardMatcher excludes;
-
- private final WildcardMatcher exclClassloader;
-
- private final ClassFileDumper classFileDumper;
-
- /**
- * New transformer with the given delegates.
- *
- * @param runtime
- * coverage runtime
- * @param options
- * configuration options for the generator
- * @param logger
- * logger for exceptions during instrumentation
- */
- public CoverageTransformer(final IRuntime runtime,
- final AgentOptions options, final IExceptionLogger logger) {
- this.runtime = runtime;
- this.instrumenter = new Instrumenter(runtime);
- this.logger = logger;
- // Class names will be reported in VM notation:
- includes = new WildcardMatcher(
- toWildcard(toVMName(options.getIncludes())));
- excludes = new WildcardMatcher(
- toWildcard(toVMName(options.getExcludes())));
- exclClassloader = new WildcardMatcher(
- toWildcard(options.getExclClassloader()));
- classFileDumper = new ClassFileDumper(options.getClassDumpDir());
- }
-
- public byte[] transform(final ClassLoader loader, final String classname,
- final Class<?> classBeingRedefined,
- final ProtectionDomain protectionDomain,
- final byte[] classfileBuffer) throws IllegalClassFormatException {
-
- if (!filter(loader, classname)) {
- return null;
- }
-
- try {
- classFileDumper.dump(classname, classfileBuffer);
- if (classBeingRedefined != null) {
- // For redefined classes we must clear the execution data
- // reference as probes might have changed.
- runtime.disconnect(classBeingRedefined);
- }
- return instrumenter.instrument(classfileBuffer);
- } catch (final Exception ex) {
- final IllegalClassFormatException wrapper = new IllegalClassFormatException(
- format("Error while instrumenting class %s.", classname));
- // Report this, as the exception is ignored by the JVM:
- logger.logExeption(wrapper);
- throw (IllegalClassFormatException) wrapper.initCause(ex);
- }
- }
-
- /**
- * Checks whether this class should be instrumented.
- *
- * @param loader
- * loader for the class
- * @param classname
- * VM name of the class to check
- * @return <code>true</code> if the class should be instrumented
- */
- protected boolean filter(final ClassLoader loader, final String classname) {
- // Don't instrument classes of the bootstrap loader:
- return loader != null &&
-
- !classname.startsWith(AGENT_PREFIX) &&
-
- !exclClassloader.matches(loader.getClass().getName()) &&
-
- includes.matches(classname) &&
-
- !excludes.matches(classname);
- }
-
- private String toWildcard(final String src) {
- if (src.indexOf('|') != -1) {
- final IllegalArgumentException ex = new IllegalArgumentException(
- "Usage of '|' as a list separator for JaCoCo agent options is deprecated and will not work in future versions - use ':' instead.");
- logger.logExeption(ex);
- return src.replace('|', ':');
- }
- return src;
- }
-
- private static String toVMName(final String srcName) {
- return srcName.replace('.', '/');
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt; + +import static java.lang.String.format; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.security.ProtectionDomain; + +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.WildcardMatcher; + +/** + * Class file transformer to instrument classes for code coverage analysis. + */ +public class CoverageTransformer implements ClassFileTransformer { + + private static final String AGENT_PREFIX; + + static { + final String name = CoverageTransformer.class.getName(); + AGENT_PREFIX = toVMName(name.substring(0, name.lastIndexOf('.'))); + } + + private final IRuntime runtime; + + private final Instrumenter instrumenter; + + private final IExceptionLogger logger; + + private final WildcardMatcher includes; + + private final WildcardMatcher excludes; + + private final WildcardMatcher exclClassloader; + + private final ClassFileDumper classFileDumper; + + /** + * New transformer with the given delegates. + * + * @param runtime + * coverage runtime + * @param options + * configuration options for the generator + * @param logger + * logger for exceptions during instrumentation + */ + public CoverageTransformer(final IRuntime runtime, + final AgentOptions options, final IExceptionLogger logger) { + this.runtime = runtime; + this.instrumenter = new Instrumenter(runtime); + this.logger = logger; + // Class names will be reported in VM notation: + includes = new WildcardMatcher( + toWildcard(toVMName(options.getIncludes()))); + excludes = new WildcardMatcher( + toWildcard(toVMName(options.getExcludes()))); + exclClassloader = new WildcardMatcher( + toWildcard(options.getExclClassloader())); + classFileDumper = new ClassFileDumper(options.getClassDumpDir()); + } + + public byte[] transform(final ClassLoader loader, final String classname, + final Class<?> classBeingRedefined, + final ProtectionDomain protectionDomain, + final byte[] classfileBuffer) throws IllegalClassFormatException { + + if (!filter(loader, classname)) { + return null; + } + + try { + classFileDumper.dump(classname, classfileBuffer); + if (classBeingRedefined != null) { + // For redefined classes we must clear the execution data + // reference as probes might have changed. + runtime.disconnect(classBeingRedefined); + } + return instrumenter.instrument(classfileBuffer); + } catch (final Exception ex) { + final IllegalClassFormatException wrapper = new IllegalClassFormatException( + format("Error while instrumenting class %s.", classname)); + // Report this, as the exception is ignored by the JVM: + logger.logExeption(wrapper); + throw (IllegalClassFormatException) wrapper.initCause(ex); + } + } + + /** + * Checks whether this class should be instrumented. + * + * @param loader + * loader for the class + * @param classname + * VM name of the class to check + * @return <code>true</code> if the class should be instrumented + */ + protected boolean filter(final ClassLoader loader, final String classname) { + // Don't instrument classes of the bootstrap loader: + return loader != null && + + !classname.startsWith(AGENT_PREFIX) && + + !exclClassloader.matches(loader.getClass().getName()) && + + includes.matches(classname) && + + !excludes.matches(classname); + } + + private String toWildcard(final String src) { + if (src.indexOf('|') != -1) { + final IllegalArgumentException ex = new IllegalArgumentException( + "Usage of '|' as a list separator for JaCoCo agent options is deprecated and will not work in future versions - use ':' instead."); + logger.logExeption(ex); + return src.replace('|', ':'); + } + return src; + } + + private static String toVMName(final String srcName) { + return srcName.replace('.', '/'); + } + +} diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java index c52fc824..a2f9b521 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/JacocoAgent.java @@ -1,175 +1,175 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt;
-
-import java.lang.instrument.Instrumentation;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-import org.jacoco.agent.rt.controller.IAgentController;
-import org.jacoco.agent.rt.controller.LocalController;
-import org.jacoco.agent.rt.controller.MBeanController;
-import org.jacoco.agent.rt.controller.TcpClientController;
-import org.jacoco.agent.rt.controller.TcpServerController;
-import org.jacoco.core.runtime.AbstractRuntime;
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.AgentOptions.OutputMode;
-import org.jacoco.core.runtime.IRuntime;
-import org.jacoco.core.runtime.ModifiedSystemClassRuntime;
-
-/**
- * The agent which is referred as the <code>Premain-Class</code>.
- */
-public class JacocoAgent {
-
- private final AgentOptions options;
-
- private final IExceptionLogger logger;
-
- private IAgentController controller;
-
- /**
- * Creates a new agent with the given agent options.
- *
- * @param options
- * agent options
- * @param logger
- * logger used by this agent
- */
- public JacocoAgent(final AgentOptions options, final IExceptionLogger logger) {
- this.options = options;
- this.logger = logger;
- }
-
- /**
- * Creates a new agent with the given agent options string.
- *
- * @param options
- * agent options as text string
- * @param logger
- * logger used by this agent
- */
- public JacocoAgent(final String options, final IExceptionLogger logger) {
- this(new AgentOptions(options), logger);
- }
-
- /**
- * Initializes this agent.
- *
- * @param inst
- * instrumentation services
- * @throws Exception
- * internal startup problem
- */
- public void init(final Instrumentation inst) throws Exception {
- final IRuntime runtime = createRuntime(inst);
- String sessionId = options.getSessionId();
- if (sessionId == null) {
- sessionId = createSessionId();
- }
- runtime.setSessionId(sessionId);
- runtime.startup();
- inst.addTransformer(new CoverageTransformer(runtime, options, logger));
- controller = createAgentController();
- controller.startup(options, runtime);
- }
-
- /**
- * Create controller implementation as given by the agent options.
- *
- * @return configured controller implementation
- */
- protected IAgentController createAgentController() {
- final OutputMode controllerType = options.getOutput();
- switch (controllerType) {
- case file:
- return new LocalController();
- case tcpserver:
- return new TcpServerController(logger);
- case tcpclient:
- return new TcpClientController(logger);
- case mbean:
- return new MBeanController();
- default:
- throw new AssertionError(controllerType);
- }
- }
-
- private String createSessionId() {
- String host;
- try {
- host = InetAddress.getLocalHost().getHostName();
- } catch (final UnknownHostException e) {
- host = "unknownhost";
- }
- return host + "-" + AbstractRuntime.createRandomId();
- }
-
- /**
- * Creates the specific coverage runtime implementation.
- *
- * @param inst
- * instrumentation services
- * @return coverage runtime instance
- * @throws Exception
- * creation problem
- */
- protected IRuntime createRuntime(final Instrumentation inst)
- throws Exception {
- return ModifiedSystemClassRuntime.createFor(inst, "java/util/UUID");
- }
-
- /**
- * Shutdown the agent again.
- */
- public void shutdown() {
- try {
- if (options.getDumpOnExit()) {
- controller.writeExecutionData();
- }
- controller.shutdown();
- } catch (final Exception e) {
- logger.logExeption(e);
- }
- }
-
- /**
- * This method is called by the JVM to initialize Java agents.
- *
- * @param options
- * agent options
- * @param inst
- * instrumentation callback provided by the JVM
- * @throws Exception
- * in case initialization fails
- */
- public static void premain(final String options, final Instrumentation inst)
- throws Exception {
-
- final JacocoAgent agent = new JacocoAgent(options,
- new IExceptionLogger() {
- public void logExeption(final Exception ex) {
- ex.printStackTrace();
- }
- });
-
- agent.init(inst);
-
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- agent.shutdown();
- }
- });
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt; + +import java.lang.instrument.Instrumentation; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.jacoco.agent.rt.controller.IAgentController; +import org.jacoco.agent.rt.controller.LocalController; +import org.jacoco.agent.rt.controller.MBeanController; +import org.jacoco.agent.rt.controller.TcpClientController; +import org.jacoco.agent.rt.controller.TcpServerController; +import org.jacoco.core.runtime.AbstractRuntime; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.AgentOptions.OutputMode; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.ModifiedSystemClassRuntime; + +/** + * The agent which is referred as the <code>Premain-Class</code>. + */ +public class JacocoAgent { + + private final AgentOptions options; + + private final IExceptionLogger logger; + + private IAgentController controller; + + /** + * Creates a new agent with the given agent options. + * + * @param options + * agent options + * @param logger + * logger used by this agent + */ + public JacocoAgent(final AgentOptions options, final IExceptionLogger logger) { + this.options = options; + this.logger = logger; + } + + /** + * Creates a new agent with the given agent options string. + * + * @param options + * agent options as text string + * @param logger + * logger used by this agent + */ + public JacocoAgent(final String options, final IExceptionLogger logger) { + this(new AgentOptions(options), logger); + } + + /** + * Initializes this agent. + * + * @param inst + * instrumentation services + * @throws Exception + * internal startup problem + */ + public void init(final Instrumentation inst) throws Exception { + final IRuntime runtime = createRuntime(inst); + String sessionId = options.getSessionId(); + if (sessionId == null) { + sessionId = createSessionId(); + } + runtime.setSessionId(sessionId); + runtime.startup(); + inst.addTransformer(new CoverageTransformer(runtime, options, logger)); + controller = createAgentController(); + controller.startup(options, runtime); + } + + /** + * Create controller implementation as given by the agent options. + * + * @return configured controller implementation + */ + protected IAgentController createAgentController() { + final OutputMode controllerType = options.getOutput(); + switch (controllerType) { + case file: + return new LocalController(); + case tcpserver: + return new TcpServerController(logger); + case tcpclient: + return new TcpClientController(logger); + case mbean: + return new MBeanController(); + default: + throw new AssertionError(controllerType); + } + } + + private String createSessionId() { + String host; + try { + host = InetAddress.getLocalHost().getHostName(); + } catch (final UnknownHostException e) { + host = "unknownhost"; + } + return host + "-" + AbstractRuntime.createRandomId(); + } + + /** + * Creates the specific coverage runtime implementation. + * + * @param inst + * instrumentation services + * @return coverage runtime instance + * @throws Exception + * creation problem + */ + protected IRuntime createRuntime(final Instrumentation inst) + throws Exception { + return ModifiedSystemClassRuntime.createFor(inst, "java/util/UUID"); + } + + /** + * Shutdown the agent again. + */ + public void shutdown() { + try { + if (options.getDumpOnExit()) { + controller.writeExecutionData(); + } + controller.shutdown(); + } catch (final Exception e) { + logger.logExeption(e); + } + } + + /** + * This method is called by the JVM to initialize Java agents. + * + * @param options + * agent options + * @param inst + * instrumentation callback provided by the JVM + * @throws Exception + * in case initialization fails + */ + public static void premain(final String options, final Instrumentation inst) + throws Exception { + + final JacocoAgent agent = new JacocoAgent(options, + new IExceptionLogger() { + public void logExeption(final Exception ex) { + ex.printStackTrace(); + } + }); + + agent.init(inst); + + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + agent.shutdown(); + } + }); + } + +} diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/IAgentController.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/IAgentController.java index 77f4df2f..c8dde9fa 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/IAgentController.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/IAgentController.java @@ -1,54 +1,54 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.IRuntime;
-
-/**
- * Common interface for different implementations that control execution data
- * dumps.
- */
-public interface IAgentController {
-
- /**
- * Configure the agent controller with the supplied options and connect it
- * to the coverage runtime
- *
- * @param options
- * Options used to configure the agent controller
- * @param runtime
- * Coverage runtime this agent controller will be connected to
- * @throws Exception
- * in case startup fails
- */
- public void startup(final AgentOptions options, final IRuntime runtime)
- throws Exception;
-
- /**
- * Shutdown the agent controller and clean up any resources it has created.
- *
- * @throws Exception
- * in case shutdown fails
- */
- public void shutdown() throws Exception;
-
- /**
- * Write all execution data in the runtime to a location determined by the
- * agent controller. This method should only be called by the Agent
- *
- * @throws Exception
- * in case writing fails
- */
- public void writeExecutionData() throws Exception;
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.IRuntime; + +/** + * Common interface for different implementations that control execution data + * dumps. + */ +public interface IAgentController { + + /** + * Configure the agent controller with the supplied options and connect it + * to the coverage runtime + * + * @param options + * Options used to configure the agent controller + * @param runtime + * Coverage runtime this agent controller will be connected to + * @throws Exception + * in case startup fails + */ + public void startup(final AgentOptions options, final IRuntime runtime) + throws Exception; + + /** + * Shutdown the agent controller and clean up any resources it has created. + * + * @throws Exception + * in case shutdown fails + */ + public void shutdown() throws Exception; + + /** + * Write all execution data in the runtime to a location determined by the + * agent controller. This method should only be called by the Agent + * + * @throws Exception + * in case writing fails + */ + public void writeExecutionData() throws Exception; + +} diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/LocalController.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/LocalController.java index 7668bf41..5f7d405d 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/LocalController.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/LocalController.java @@ -1,59 +1,59 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.jacoco.core.data.ExecutionDataWriter;
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.IRuntime;
-
-/**
- * Local only agent controller that will write coverage data to the filesystem.
- * This controller uses the following agent options:
- * <ul>
- * <li>destfile</li>
- * <li>append</li>
- * </ul>
- */
-public class LocalController implements IAgentController {
-
- private IRuntime runtime;
-
- private OutputStream output;
-
- public final void startup(final AgentOptions options, final IRuntime runtime)
- throws IOException {
- this.runtime = runtime;
- final File destFile = new File(options.getDestfile()).getAbsoluteFile();
- final File folder = destFile.getParentFile();
- if (folder != null) {
- folder.mkdirs();
- }
- output = new BufferedOutputStream(new FileOutputStream(destFile,
- options.getAppend()));
- }
-
- public void writeExecutionData() throws IOException {
- final ExecutionDataWriter writer = new ExecutionDataWriter(output);
- runtime.collect(writer, writer, false);
- }
-
- public void shutdown() throws IOException {
- output.close();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.jacoco.core.data.ExecutionDataWriter; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.IRuntime; + +/** + * Local only agent controller that will write coverage data to the filesystem. + * This controller uses the following agent options: + * <ul> + * <li>destfile</li> + * <li>append</li> + * </ul> + */ +public class LocalController implements IAgentController { + + private IRuntime runtime; + + private OutputStream output; + + public final void startup(final AgentOptions options, final IRuntime runtime) + throws IOException { + this.runtime = runtime; + final File destFile = new File(options.getDestfile()).getAbsoluteFile(); + final File folder = destFile.getParentFile(); + if (folder != null) { + folder.mkdirs(); + } + output = new BufferedOutputStream(new FileOutputStream(destFile, + options.getAppend())); + } + + public void writeExecutionData() throws IOException { + final ExecutionDataWriter writer = new ExecutionDataWriter(output); + runtime.collect(writer, writer, false); + } + + public void shutdown() throws IOException { + output.close(); + } + +} diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpClientController.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpClientController.java index 6539904f..e59c4abd 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpClientController.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpClientController.java @@ -1,88 +1,88 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import java.io.IOException;
-import java.net.Socket;
-
-import org.jacoco.agent.rt.IExceptionLogger;
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.IRuntime;
-
-/**
- * Controller that connects to a TCP port. This controller uses the following
- * agent options:
- * <ul>
- * <li>address</li>
- * <li>port</li>
- * </ul>
- */
-public class TcpClientController implements IAgentController {
-
- private final IExceptionLogger logger;
-
- private TcpConnection connection;
-
- private Thread worker;
-
- /**
- * New controller instance.
- *
- * @param logger
- * logger to use in case of exceptions is spawned threads
- */
- public TcpClientController(final IExceptionLogger logger) {
- this.logger = logger;
- }
-
- public void startup(final AgentOptions options, final IRuntime runtime)
- throws IOException {
- final Socket socket = createSocket(options);
- connection = new TcpConnection(socket, runtime);
- connection.init();
- worker = new Thread(new Runnable() {
- public void run() {
- try {
- connection.run();
- } catch (final IOException e) {
- logger.logExeption(e);
- }
- }
- });
- worker.setName(getClass().getName());
- worker.setDaemon(true);
- worker.start();
- }
-
- public void shutdown() throws Exception {
- connection.close();
- worker.join();
- }
-
- public void writeExecutionData() throws IOException {
- connection.writeExecutionData();
- }
-
- /**
- * Open a socket based on the given configuration.
- *
- * @param options
- * address and port configuration
- * @return opened socket
- * @throws IOException
- */
- protected Socket createSocket(final AgentOptions options)
- throws IOException {
- return new Socket(options.getAddress(), options.getPort());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import java.io.IOException; +import java.net.Socket; + +import org.jacoco.agent.rt.IExceptionLogger; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.IRuntime; + +/** + * Controller that connects to a TCP port. This controller uses the following + * agent options: + * <ul> + * <li>address</li> + * <li>port</li> + * </ul> + */ +public class TcpClientController implements IAgentController { + + private final IExceptionLogger logger; + + private TcpConnection connection; + + private Thread worker; + + /** + * New controller instance. + * + * @param logger + * logger to use in case of exceptions is spawned threads + */ + public TcpClientController(final IExceptionLogger logger) { + this.logger = logger; + } + + public void startup(final AgentOptions options, final IRuntime runtime) + throws IOException { + final Socket socket = createSocket(options); + connection = new TcpConnection(socket, runtime); + connection.init(); + worker = new Thread(new Runnable() { + public void run() { + try { + connection.run(); + } catch (final IOException e) { + logger.logExeption(e); + } + } + }); + worker.setName(getClass().getName()); + worker.setDaemon(true); + worker.start(); + } + + public void shutdown() throws Exception { + connection.close(); + worker.join(); + } + + public void writeExecutionData() throws IOException { + connection.writeExecutionData(); + } + + /** + * Open a socket based on the given configuration. + * + * @param options + * address and port configuration + * @return opened socket + * @throws IOException + */ + protected Socket createSocket(final AgentOptions options) + throws IOException { + return new Socket(options.getAddress(), options.getPort()); + } + +} diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpConnection.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpConnection.java index 2bff22bb..348eeec0 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpConnection.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpConnection.java @@ -1,109 +1,109 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.net.SocketException;
-
-import org.jacoco.core.runtime.IRemoteCommandVisitor;
-import org.jacoco.core.runtime.IRuntime;
-import org.jacoco.core.runtime.RemoteControlReader;
-import org.jacoco.core.runtime.RemoteControlWriter;
-
-/**
- * Handler for a single socket based remote connection.
- */
-class TcpConnection implements IRemoteCommandVisitor {
-
- private final IRuntime runtime;
-
- private final Socket socket;
-
- private RemoteControlWriter writer;
-
- private RemoteControlReader reader;
-
- private boolean initialized;
-
- public TcpConnection(final Socket socket, final IRuntime runtime) {
- this.socket = socket;
- this.runtime = runtime;
- this.initialized = false;
- }
-
- public void init() throws IOException {
- this.writer = new RemoteControlWriter(socket.getOutputStream());
- this.reader = new RemoteControlReader(socket.getInputStream());
- this.reader.setRemoteCommandVisitor(this);
- this.initialized = true;
- }
-
- /**
- * Processes all requests for this session until the socket is closed.
- *
- * @throws IOException
- * in case of problems whith the connection
- */
- public void run() throws IOException {
- try {
- while (reader.read()) {
- }
- } catch (final SocketException e) {
- // If the local socket is closed while polling for commands the
- // SocketException is expected.
- if (!socket.isClosed()) {
- throw e;
- }
- } finally {
- close();
- }
- }
-
- /**
- * Dumps the current execution data if the connection is already initialized
- * and the underlying socket is still open.
- *
- * @throws IOException
- */
- public void writeExecutionData() throws IOException {
- if (initialized && !socket.isClosed()) {
- visitDumpCommand(true, false);
- }
- }
-
- /**
- * Closes the underlying socket if not closed yet.
- *
- * @throws IOException
- */
- public void close() throws IOException {
- if (!socket.isClosed()) {
- socket.close();
- }
- }
-
- // === IRemoteCommandVisitor ===
-
- public void visitDumpCommand(final boolean dump, final boolean reset)
- throws IOException {
- if (dump) {
- runtime.collect(writer, writer, reset);
- } else {
- if (reset) {
- runtime.reset();
- }
- }
- writer.sendCmdOk();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import java.io.IOException; +import java.net.Socket; +import java.net.SocketException; + +import org.jacoco.core.runtime.IRemoteCommandVisitor; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; + +/** + * Handler for a single socket based remote connection. + */ +class TcpConnection implements IRemoteCommandVisitor { + + private final IRuntime runtime; + + private final Socket socket; + + private RemoteControlWriter writer; + + private RemoteControlReader reader; + + private boolean initialized; + + public TcpConnection(final Socket socket, final IRuntime runtime) { + this.socket = socket; + this.runtime = runtime; + this.initialized = false; + } + + public void init() throws IOException { + this.writer = new RemoteControlWriter(socket.getOutputStream()); + this.reader = new RemoteControlReader(socket.getInputStream()); + this.reader.setRemoteCommandVisitor(this); + this.initialized = true; + } + + /** + * Processes all requests for this session until the socket is closed. + * + * @throws IOException + * in case of problems whith the connection + */ + public void run() throws IOException { + try { + while (reader.read()) { + } + } catch (final SocketException e) { + // If the local socket is closed while polling for commands the + // SocketException is expected. + if (!socket.isClosed()) { + throw e; + } + } finally { + close(); + } + } + + /** + * Dumps the current execution data if the connection is already initialized + * and the underlying socket is still open. + * + * @throws IOException + */ + public void writeExecutionData() throws IOException { + if (initialized && !socket.isClosed()) { + visitDumpCommand(true, false); + } + } + + /** + * Closes the underlying socket if not closed yet. + * + * @throws IOException + */ + public void close() throws IOException { + if (!socket.isClosed()) { + socket.close(); + } + } + + // === IRemoteCommandVisitor === + + public void visitDumpCommand(final boolean dump, final boolean reset) + throws IOException { + if (dump) { + runtime.collect(writer, writer, reset); + } else { + if (reset) { + runtime.reset(); + } + } + writer.sendCmdOk(); + } + +} diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpServerController.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpServerController.java index 5408e3a2..3538b087 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpServerController.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/controller/TcpServerController.java @@ -1,126 +1,126 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent.rt.controller;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.UnknownHostException;
-
-import org.jacoco.agent.rt.IExceptionLogger;
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.IRuntime;
-
-/**
- * Controller that opens TCP server socket. This controller uses the following
- * agent options:
- * <ul>
- * <li>address</li>
- * <li>port</li>
- * </ul>
- */
-public class TcpServerController implements IAgentController {
-
- private TcpConnection connection;
-
- private final IExceptionLogger logger;
-
- private ServerSocket serverSocket;
-
- private Thread worker;
-
- /**
- * New controller instance.
- *
- * @param logger
- * logger to use in case of exceptions is spawned threads
- */
- public TcpServerController(final IExceptionLogger logger) {
- this.logger = logger;
- }
-
- public void startup(final AgentOptions options, final IRuntime runtime)
- throws IOException {
- serverSocket = createServerSocket(options);
- worker = new Thread(new Runnable() {
- public void run() {
- while (!serverSocket.isClosed()) {
- try {
- synchronized (serverSocket) {
- connection = new TcpConnection(
- serverSocket.accept(), runtime);
- }
- connection.init();
- connection.run();
- } catch (final IOException e) {
- // If the serverSocket is closed while accepting
- // connections a SocketException is expected.
- if (!serverSocket.isClosed()) {
- logger.logExeption(e);
- }
- }
- }
- }
- });
- worker.setName(getClass().getName());
- worker.setDaemon(true);
- worker.start();
- }
-
- public void shutdown() throws Exception {
- serverSocket.close();
- synchronized (serverSocket) {
- if (connection != null) {
- connection.close();
- }
- }
- worker.join();
- }
-
- public void writeExecutionData() throws IOException {
- if (connection != null) {
- connection.writeExecutionData();
- }
- }
-
- /**
- * Open a server socket based on the given configuration.
- *
- * @param options
- * address and port configuration
- * @return opened server socket
- * @throws IOException
- */
- protected ServerSocket createServerSocket(final AgentOptions options)
- throws IOException {
- final InetAddress inetAddr = getInetAddress(options.getAddress());
- return new ServerSocket(options.getPort(), 1, inetAddr);
- }
-
- /**
- * Returns the {@link InetAddress} object to open the server socket on.
- *
- * @param address
- * address specified as a string
- * @return address to open the server socket
- * @throws UnknownHostException
- */
- protected InetAddress getInetAddress(final String address)
- throws UnknownHostException {
- if ("*".equals(address)) {
- return null;
- } else {
- return InetAddress.getByName(address);
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent.rt.controller; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.UnknownHostException; + +import org.jacoco.agent.rt.IExceptionLogger; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.IRuntime; + +/** + * Controller that opens TCP server socket. This controller uses the following + * agent options: + * <ul> + * <li>address</li> + * <li>port</li> + * </ul> + */ +public class TcpServerController implements IAgentController { + + private TcpConnection connection; + + private final IExceptionLogger logger; + + private ServerSocket serverSocket; + + private Thread worker; + + /** + * New controller instance. + * + * @param logger + * logger to use in case of exceptions is spawned threads + */ + public TcpServerController(final IExceptionLogger logger) { + this.logger = logger; + } + + public void startup(final AgentOptions options, final IRuntime runtime) + throws IOException { + serverSocket = createServerSocket(options); + worker = new Thread(new Runnable() { + public void run() { + while (!serverSocket.isClosed()) { + try { + synchronized (serverSocket) { + connection = new TcpConnection( + serverSocket.accept(), runtime); + } + connection.init(); + connection.run(); + } catch (final IOException e) { + // If the serverSocket is closed while accepting + // connections a SocketException is expected. + if (!serverSocket.isClosed()) { + logger.logExeption(e); + } + } + } + } + }); + worker.setName(getClass().getName()); + worker.setDaemon(true); + worker.start(); + } + + public void shutdown() throws Exception { + serverSocket.close(); + synchronized (serverSocket) { + if (connection != null) { + connection.close(); + } + } + worker.join(); + } + + public void writeExecutionData() throws IOException { + if (connection != null) { + connection.writeExecutionData(); + } + } + + /** + * Open a server socket based on the given configuration. + * + * @param options + * address and port configuration + * @return opened server socket + * @throws IOException + */ + protected ServerSocket createServerSocket(final AgentOptions options) + throws IOException { + final InetAddress inetAddr = getInetAddress(options.getAddress()); + return new ServerSocket(options.getPort(), 1, inetAddr); + } + + /** + * Returns the {@link InetAddress} object to open the server socket on. + * + * @param address + * address specified as a string + * @return address to open the server socket + * @throws UnknownHostException + */ + protected InetAddress getInetAddress(final String address) + throws UnknownHostException { + if ("*".equals(address)) { + return null; + } else { + return InetAddress.getByName(address); + } + } + +} diff --git a/org.jacoco.agent.test/src/org/jacoco/agent/AgentJarTest.java b/org.jacoco.agent.test/src/org/jacoco/agent/AgentJarTest.java index e88ac5d6..b9c7b637 100644 --- a/org.jacoco.agent.test/src/org/jacoco/agent/AgentJarTest.java +++ b/org.jacoco.agent.test/src/org/jacoco/agent/AgentJarTest.java @@ -1,91 +1,91 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.junit.After;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link AgentJar}.
- */
-public class AgentJarTest {
-
- private File file;
-
- @After
- public void teardown() {
- if (file != null) {
- file.delete();
- }
- }
-
- @Test
- public void testGetResource() throws IOException {
- final InputStream in = AgentJar.getResource().openStream();
- assertAgentContents(in);
- }
-
- @Test
- public void testGetResourceAsStream() throws IOException {
- final InputStream in = AgentJar.getResourceAsStream();
- assertAgentContents(in);
- }
-
- @Test
- public void testExtractTo() throws IOException {
- file = File.createTempFile("agent", ".jar");
- AgentJar.extractTo(file);
- assertAgentContents(new FileInputStream(file));
- }
-
- @Test(expected = IOException.class)
- public void testExtractToNegative() throws IOException {
- file = File.createTempFile("folder", null);
- file.delete();
- file.mkdirs();
- AgentJar.extractTo(file);
- }
-
- @Test
- public void testExtractToTempLocation() throws IOException {
- file = AgentJar.extractToTempLocation();
- assertAgentContents(new FileInputStream(file));
- file.delete();
- }
-
- private void assertAgentContents(InputStream in) throws IOException {
- final ZipInputStream zip = new ZipInputStream(in);
- while (true) {
- final ZipEntry entry = zip.getNextEntry();
- assertNotNull("Manifest not found.", entry);
- if ("META-INF/MANIFEST.MF".equals(entry.getName())) {
- final Manifest manifest = new Manifest(zip);
- assertEquals("JaCoCo Java Agent", manifest.getMainAttributes()
- .getValue("Implementation-Title"));
- in.close();
- break;
- }
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.junit.After; +import org.junit.Test; + +/** + * Unit tests for {@link AgentJar}. + */ +public class AgentJarTest { + + private File file; + + @After + public void teardown() { + if (file != null) { + file.delete(); + } + } + + @Test + public void testGetResource() throws IOException { + final InputStream in = AgentJar.getResource().openStream(); + assertAgentContents(in); + } + + @Test + public void testGetResourceAsStream() throws IOException { + final InputStream in = AgentJar.getResourceAsStream(); + assertAgentContents(in); + } + + @Test + public void testExtractTo() throws IOException { + file = File.createTempFile("agent", ".jar"); + AgentJar.extractTo(file); + assertAgentContents(new FileInputStream(file)); + } + + @Test(expected = IOException.class) + public void testExtractToNegative() throws IOException { + file = File.createTempFile("folder", null); + file.delete(); + file.mkdirs(); + AgentJar.extractTo(file); + } + + @Test + public void testExtractToTempLocation() throws IOException { + file = AgentJar.extractToTempLocation(); + assertAgentContents(new FileInputStream(file)); + file.delete(); + } + + private void assertAgentContents(InputStream in) throws IOException { + final ZipInputStream zip = new ZipInputStream(in); + while (true) { + final ZipEntry entry = zip.getNextEntry(); + assertNotNull("Manifest not found.", entry); + if ("META-INF/MANIFEST.MF".equals(entry.getName())) { + final Manifest manifest = new Manifest(zip); + assertEquals("JaCoCo Java Agent", manifest.getMainAttributes() + .getValue("Implementation-Title")); + in.close(); + break; + } + } + } + +} diff --git a/org.jacoco.agent/src/org/jacoco/agent/AgentJar.java b/org.jacoco.agent/src/org/jacoco/agent/AgentJar.java index a77c1a43..ca82f9e3 100644 --- a/org.jacoco.agent/src/org/jacoco/agent/AgentJar.java +++ b/org.jacoco.agent/src/org/jacoco/agent/AgentJar.java @@ -1,129 +1,129 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.agent;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-
-/**
- * API to access the agent JAR file as a resource. While the agent is a JAR file
- * it is considered as a plain resource that must be configured for the
- * application under test (target JVM). The agent JAR does not provide any
- * public Java API.
- */
-public final class AgentJar {
-
- /**
- * Name of the agent JAR file resource within this bundle.
- */
- private static final String RESOURCE = "/jacocoagent.jar";
-
- private AgentJar() {
- }
-
- /**
- * Returns a URL pointing to the JAR file.
- *
- * @return URL of the JAR file
- */
- public static URL getResource() {
- final URL url = AgentJar.class.getResource(RESOURCE);
- if (url == null) {
- throw new AssertionError(ERRORMSG);
- }
- return url;
- }
-
- /**
- * Returns the content of the JAR file as a stream.
- *
- * @return content of the JAR file
- */
- public static InputStream getResourceAsStream() {
- final InputStream stream = AgentJar.class.getResourceAsStream(RESOURCE);
- if (stream == null) {
- throw new AssertionError(ERRORMSG);
- }
- return stream;
- }
-
- /**
- * Extract the JaCoCo agent JAR and put it into a temporary location. This
- * file should be deleted on exit, but may not if the VM is terminated
- *
- * @return Location of the Agent Jar file in the local file system. The file
- * should exist and be readable.
- * @throws IOException
- * Unable to unpack agent jar
- */
- public static File extractToTempLocation() throws IOException {
- final File agentJar = File.createTempFile("jacocoagent", ".jar");
- agentJar.deleteOnExit();
-
- extractTo(agentJar);
-
- return agentJar;
- }
-
- /**
- * Extract the JaCoCo agent JAR and put it into the specified location.
- *
- * @param destination
- * Location to write JaCoCo Agent Jar to. Must be writeable
- * @throws IOException
- * Unable to unpack agent jar
- */
- public static void extractTo(File destination) throws IOException {
- InputStream inputJarStream = getResourceAsStream();
- OutputStream outputJarStream = null;
-
- try {
-
- outputJarStream = new FileOutputStream(destination);
-
- final byte[] buffer = new byte[8192];
-
- int bytesRead;
- while ((bytesRead = inputJarStream.read(buffer)) != -1) {
- outputJarStream.write(buffer, 0, bytesRead);
- }
- } finally {
- safeClose(inputJarStream);
- safeClose(outputJarStream);
- }
- }
-
- /**
- * Close a stream ignoring any error
- *
- * @param closeable
- * stream to be closed
- */
- private static void safeClose(Closeable closeable) {
- try {
- if (closeable != null) {
- closeable.close();
- }
- } catch (IOException e) {
- }
- }
-
- private static final String ERRORMSG = String.format(
- "The resource %s has not been found. Please see "
- + "/org.jacoco.agent/README.TXT for details.", RESOURCE);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.agent; + +import java.io.Closeable; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; + +/** + * API to access the agent JAR file as a resource. While the agent is a JAR file + * it is considered as a plain resource that must be configured for the + * application under test (target JVM). The agent JAR does not provide any + * public Java API. + */ +public final class AgentJar { + + /** + * Name of the agent JAR file resource within this bundle. + */ + private static final String RESOURCE = "/jacocoagent.jar"; + + private AgentJar() { + } + + /** + * Returns a URL pointing to the JAR file. + * + * @return URL of the JAR file + */ + public static URL getResource() { + final URL url = AgentJar.class.getResource(RESOURCE); + if (url == null) { + throw new AssertionError(ERRORMSG); + } + return url; + } + + /** + * Returns the content of the JAR file as a stream. + * + * @return content of the JAR file + */ + public static InputStream getResourceAsStream() { + final InputStream stream = AgentJar.class.getResourceAsStream(RESOURCE); + if (stream == null) { + throw new AssertionError(ERRORMSG); + } + return stream; + } + + /** + * Extract the JaCoCo agent JAR and put it into a temporary location. This + * file should be deleted on exit, but may not if the VM is terminated + * + * @return Location of the Agent Jar file in the local file system. The file + * should exist and be readable. + * @throws IOException + * Unable to unpack agent jar + */ + public static File extractToTempLocation() throws IOException { + final File agentJar = File.createTempFile("jacocoagent", ".jar"); + agentJar.deleteOnExit(); + + extractTo(agentJar); + + return agentJar; + } + + /** + * Extract the JaCoCo agent JAR and put it into the specified location. + * + * @param destination + * Location to write JaCoCo Agent Jar to. Must be writeable + * @throws IOException + * Unable to unpack agent jar + */ + public static void extractTo(File destination) throws IOException { + InputStream inputJarStream = getResourceAsStream(); + OutputStream outputJarStream = null; + + try { + + outputJarStream = new FileOutputStream(destination); + + final byte[] buffer = new byte[8192]; + + int bytesRead; + while ((bytesRead = inputJarStream.read(buffer)) != -1) { + outputJarStream.write(buffer, 0, bytesRead); + } + } finally { + safeClose(inputJarStream); + safeClose(outputJarStream); + } + } + + /** + * Close a stream ignoring any error + * + * @param closeable + * stream to be closed + */ + private static void safeClose(Closeable closeable) { + try { + if (closeable != null) { + closeable.close(); + } + } catch (IOException e) { + } + } + + private static final String ERRORMSG = String.format( + "The resource %s has not been found. Please see " + + "/org.jacoco.agent/README.TXT for details.", RESOURCE); + +} diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.java b/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.java index ed14190e..4353be8e 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.java +++ b/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.java @@ -1,30 +1,30 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import java.io.File;
-
-import junit.framework.TestSuite;
-
-import org.apache.ant.antunit.junit3.AntUnitSuite;
-import org.apache.ant.antunit.junit4.AntUnitSuiteRunner;
-import org.junit.runner.RunWith;
-
-@RunWith(AntUnitSuiteRunner.class)
-public class AgentTaskTest {
-
- public static TestSuite suite() {
- final File file = new File("src/org/jacoco/ant/AgentTaskTest.xml");
- return new AntUnitSuite(file, AgentTaskTest.class);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import java.io.File; + +import junit.framework.TestSuite; + +import org.apache.ant.antunit.junit3.AntUnitSuite; +import org.apache.ant.antunit.junit4.AntUnitSuiteRunner; +import org.junit.runner.RunWith; + +@RunWith(AntUnitSuiteRunner.class) +public class AgentTaskTest { + + public static TestSuite suite() { + final File file = new File("src/org/jacoco/ant/AgentTaskTest.xml"); + return new AntUnitSuite(file, AgentTaskTest.class); + } + +} diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.xml index ecbc9d27..485dc0bb 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/AgentTaskTest.xml @@ -1,64 +1,64 @@ -<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Copyright (c) 2009, 2012 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:
- Brock Janiczak - initial API and implementation
-
- $Id: $
--->
-
-<project name="JaCoCo Agent Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant">
-
- <target name="testCoverageAgent">
- <jacoco:agent property="jacocoagent" append="false" destfile="test.exec"
- exclClassLoader="EvilClassLoader" includes="org.example.*"
- excludes="*Test" sessionid="testid" dumponexit="false"
- output="tcpclient" address="remotehost" port="1234"
- classdumpdir="target/dump"/>
- <au:assertPropertySet name="jacocoagent"/>
- <au:assertPropertyContains name="jacocoagent" value="-javaagent:"/>
- <au:assertPropertyContains name="jacocoagent" value="append=false"/>
- <property name="exec.file" location="test.exec"/>
- <au:assertPropertyContains name="jacocoagent" value="destfile=${exec.file}"/>
- <au:assertPropertyContains name="jacocoagent" value="exclclassloader=EvilClassLoader"/>
- <au:assertPropertyContains name="jacocoagent" value="includes=org.example.*"/>
- <au:assertPropertyContains name="jacocoagent" value="excludes=*Test"/>
- <au:assertPropertyContains name="jacocoagent" value="sessionid=testid"/>
- <au:assertPropertyContains name="jacocoagent" value="dumponexit=false"/>
- <au:assertPropertyContains name="jacocoagent" value="output=tcpclient"/>
- <au:assertPropertyContains name="jacocoagent" value="address=remotehost"/>
- <au:assertPropertyContains name="jacocoagent" value="port=1234"/>
- <property name="dump.dir" location="target/dump"/>
- <au:assertPropertyContains name="jacocoagent" value="classdumpdir=${dump.dir}"/>
- </target>
-
- <target name="testCoverageAgentDisabled">
- <jacoco:agent enabled="false" property="jacocoagent" append="false" destfile="${basedir}/test.exec" exclClassLoader="sun.reflect.DelegatingClassLoader"/>
- <au:assertPropertyEquals name="jacocoagent" value=""/>
- </target>
-
- <target name="testCoverageAgentWithNoProperty">
- <au:expectfailure expectedMessage="Property is mandatory">
- <jacoco:agent/>
- </au:expectfailure>
- </target>
-
- <target name="testCoverageAgentWithEmptyProperty">
- <au:expectfailure expectedMessage="Property is mandatory">
- <jacoco:agent property=""/>
- </au:expectfailure>
- </target>
-
- <target name="testCoverageAgentReuseAgentJar">
- <jacoco:agent property="agent1"/>
- <jacoco:agent property="agent2"/>
- <au:assertEquals expected="${agent1}" actual="${agent2}"/>
- </target>
-
+<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Copyright (c) 2009, 2012 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: + Brock Janiczak - initial API and implementation + + $Id: $ +--> + +<project name="JaCoCo Agent Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant"> + + <target name="testCoverageAgent"> + <jacoco:agent property="jacocoagent" append="false" destfile="test.exec" + exclClassLoader="EvilClassLoader" includes="org.example.*" + excludes="*Test" sessionid="testid" dumponexit="false" + output="tcpclient" address="remotehost" port="1234" + classdumpdir="target/dump"/> + <au:assertPropertySet name="jacocoagent"/> + <au:assertPropertyContains name="jacocoagent" value="-javaagent:"/> + <au:assertPropertyContains name="jacocoagent" value="append=false"/> + <property name="exec.file" location="test.exec"/> + <au:assertPropertyContains name="jacocoagent" value="destfile=${exec.file}"/> + <au:assertPropertyContains name="jacocoagent" value="exclclassloader=EvilClassLoader"/> + <au:assertPropertyContains name="jacocoagent" value="includes=org.example.*"/> + <au:assertPropertyContains name="jacocoagent" value="excludes=*Test"/> + <au:assertPropertyContains name="jacocoagent" value="sessionid=testid"/> + <au:assertPropertyContains name="jacocoagent" value="dumponexit=false"/> + <au:assertPropertyContains name="jacocoagent" value="output=tcpclient"/> + <au:assertPropertyContains name="jacocoagent" value="address=remotehost"/> + <au:assertPropertyContains name="jacocoagent" value="port=1234"/> + <property name="dump.dir" location="target/dump"/> + <au:assertPropertyContains name="jacocoagent" value="classdumpdir=${dump.dir}"/> + </target> + + <target name="testCoverageAgentDisabled"> + <jacoco:agent enabled="false" property="jacocoagent" append="false" destfile="${basedir}/test.exec" exclClassLoader="sun.reflect.DelegatingClassLoader"/> + <au:assertPropertyEquals name="jacocoagent" value=""/> + </target> + + <target name="testCoverageAgentWithNoProperty"> + <au:expectfailure expectedMessage="Property is mandatory"> + <jacoco:agent/> + </au:expectfailure> + </target> + + <target name="testCoverageAgentWithEmptyProperty"> + <au:expectfailure expectedMessage="Property is mandatory"> + <jacoco:agent property=""/> + </au:expectfailure> + </target> + + <target name="testCoverageAgentReuseAgentJar"> + <jacoco:agent property="agent1"/> + <jacoco:agent property="agent2"/> + <au:assertEquals expected="${agent1}" actual="${agent2}"/> + </target> + </project>
\ No newline at end of file diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.java b/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.java index 5b507733..f78bb59a 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.java +++ b/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.java @@ -1,32 +1,32 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import java.io.File;
-
-import junit.framework.TestSuite;
-
-import org.apache.ant.antunit.junit3.AntUnitSuite;
-import org.apache.ant.antunit.junit4.AntUnitSuiteRunner;
-import org.junit.runner.RunWith;
-
-@RunWith(AntUnitSuiteRunner.class)
-public class CoverageTaskTest {
-
- public static TestSuite suite() {
- System.setProperty("org.jacoco.ant.coverageTaskTest.classes.dir",
- TestTarget.getClassPath());
- final File file = new File("src/org/jacoco/ant/CoverageTaskTest.xml");
- return new AntUnitSuite(file, CoverageTaskTest.class);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import java.io.File; + +import junit.framework.TestSuite; + +import org.apache.ant.antunit.junit3.AntUnitSuite; +import org.apache.ant.antunit.junit4.AntUnitSuiteRunner; +import org.junit.runner.RunWith; + +@RunWith(AntUnitSuiteRunner.class) +public class CoverageTaskTest { + + public static TestSuite suite() { + System.setProperty("org.jacoco.ant.coverageTaskTest.classes.dir", + TestTarget.getClassPath()); + final File file = new File("src/org/jacoco/ant/CoverageTaskTest.xml"); + return new AntUnitSuite(file, CoverageTaskTest.class); + } + +} diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.xml index 1fda7406..92a26104 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/CoverageTaskTest.xml @@ -1,145 +1,145 @@ -<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Copyright (c) 2009, 2012 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:
- Brock Janiczak - initial API and implementation
-
- $Id: $
--->
-
-<project name="JaCoCo Coverage Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant">
-
- <target name="setUp">
- <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" />
- <mkdir dir="${temp.dir}"/>
- <property name="exec.file" location="${temp.dir}/exec.file" />
- </target>
-
- <target name="tearDown">
- <delete dir="${temp.dir}" quiet="false" failonerror="true"/>
- </target>
-
- <target name="testNoSubTasks">
- <au:expectfailure expectedMessage="A child task must be supplied for the coverage task">
- <jacoco:coverage/>
- </au:expectfailure>
- </target>
-
- <target name="testMultipleSubTasks">
- <au:expectfailure expectedMessage="Only one child task can be supplied to the coverge task">
- <jacoco:coverage>
- <java classname="org.jacoco.ant.TestTarget" fork="true" failonerror="true">
- <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/>
- </java>
- <java classname="org.jacoco.ant.TestTarget" fork="true" failonerror="true">
- <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/>
- </java>
- </jacoco:coverage>
- </au:expectfailure>
-
- <au:assertLogDoesntContain text="Target executed"/>
- </target>
-
- <target name="testInvalidSubTask">
- <au:expectfailure expectedMessage="jar is not a valid child of the coverage task">
- <jacoco:coverage>
- <jar destfile="test.jar"/>
- </jacoco:coverage>
- </au:expectfailure>
- </target>
-
- <target name="testCoverageOfForkedJava">
- <jacoco:coverage destfile="${exec.file}">
- <java classname="org.jacoco.ant.TestTarget" fork="true" failonerror="true">
- <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/>
- </java>
- </jacoco:coverage>
-
- <au:assertLogContains text="Enhancing java with coverage"/>
- <au:assertFileExists file="${exec.file}"/>
- <au:assertLogContains text="Target executed"/>
- </target>
-
- <target name="testCoverageOfForkedJavaWithVariable">
- <property name="trueProperty" value="true"/>
- <jacoco:coverage destfile="${exec.file}">
- <java classname="org.jacoco.ant.TestTarget" fork="${trueProperty}" failonerror="true">
- <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/>
- </java>
- </jacoco:coverage>
-
- <au:assertLogContains text="Enhancing java with coverage"/>
- <au:assertFileExists file="${exec.file}"/>
- <au:assertLogContains text="Target executed"/>
- </target>
-
- <target name="testCoverageOfForkedJavaDisabled">
- <jacoco:coverage enabled="false" destfile="${exec.file}">
- <java classname="org.jacoco.ant.TestTarget" fork="true" failonerror="true">
- <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/>
- </java>
- </jacoco:coverage>
-
- <au:assertLogDoesntContain text="Enhancing java with coverage"/>
- <au:assertFileDoesntExist file="${exec.file}"/>
- <au:assertLogContains text="Target executed"/>
- </target>
-
- <target name="testCoverageOfNonForkedJava">
- <au:expectfailure expectedMessage="Coverage can only be applied on a forked VM">
- <jacoco:coverage>
- <java classname="org.jacoco.ant.TestTarget" fork="false" failonerror="true">
- <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/>
- </java>
- </jacoco:coverage>
- </au:expectfailure>
-
- <au:assertLogDoesntContain text="Target executed"/>
- </target>
-
- <target name="testCoverageOfForkedJUnit">
- <jacoco:coverage destfile="${exec.file}">
- <junit fork="true" haltonfailure="true" showoutput="true">
- <classpath path="${java.class.path}"/>
- <test name="org.jacoco.ant.TestTarget" />
- </junit>
- </jacoco:coverage>
-
- <au:assertLogContains text="Enhancing junit with coverage"/>
- <au:assertFileExists file="${exec.file}"/>
- <au:assertLogContains text="Target executed"/>
- </target>
-
- <target name="testCoverageOfForkedJUnitDisabled">
- <jacoco:coverage enabled="false" destfile="${exec.file}">
- <junit fork="true" haltonfailure="true" showoutput="true">
- <classpath path="${java.class.path}"/>
- <test name="org.jacoco.ant.TestTarget" />
- </junit>
- </jacoco:coverage>
-
- <au:assertLogDoesntContain text="Enhancing junit with coverage"/>
- <au:assertFileDoesntExist file="${exec.file}"/>
- <au:assertLogContains text="Target executed"/>
- </target>
-
- <target name="testCoverageOfNonForkedJUnit">
- <au:expectfailure expectedMessage="Coverage can only be applied on a forked VM">
- <jacoco:coverage>
- <junit fork="false" haltonfailure="true" showoutput="true">
- <classpath path="${java.class.path}"/>
- <test name="org.jacoco.ant.TestTarget" />
- </junit>
- </jacoco:coverage>
- </au:expectfailure>
-
- <au:assertLogDoesntContain text="Target executed"/>
- </target>
-
+<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Copyright (c) 2009, 2012 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: + Brock Janiczak - initial API and implementation + + $Id: $ +--> + +<project name="JaCoCo Coverage Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant"> + + <target name="setUp"> + <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" /> + <mkdir dir="${temp.dir}"/> + <property name="exec.file" location="${temp.dir}/exec.file" /> + </target> + + <target name="tearDown"> + <delete dir="${temp.dir}" quiet="false" failonerror="true"/> + </target> + + <target name="testNoSubTasks"> + <au:expectfailure expectedMessage="A child task must be supplied for the coverage task"> + <jacoco:coverage/> + </au:expectfailure> + </target> + + <target name="testMultipleSubTasks"> + <au:expectfailure expectedMessage="Only one child task can be supplied to the coverge task"> + <jacoco:coverage> + <java classname="org.jacoco.ant.TestTarget" fork="true" failonerror="true"> + <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/> + </java> + <java classname="org.jacoco.ant.TestTarget" fork="true" failonerror="true"> + <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/> + </java> + </jacoco:coverage> + </au:expectfailure> + + <au:assertLogDoesntContain text="Target executed"/> + </target> + + <target name="testInvalidSubTask"> + <au:expectfailure expectedMessage="jar is not a valid child of the coverage task"> + <jacoco:coverage> + <jar destfile="test.jar"/> + </jacoco:coverage> + </au:expectfailure> + </target> + + <target name="testCoverageOfForkedJava"> + <jacoco:coverage destfile="${exec.file}"> + <java classname="org.jacoco.ant.TestTarget" fork="true" failonerror="true"> + <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/> + </java> + </jacoco:coverage> + + <au:assertLogContains text="Enhancing java with coverage"/> + <au:assertFileExists file="${exec.file}"/> + <au:assertLogContains text="Target executed"/> + </target> + + <target name="testCoverageOfForkedJavaWithVariable"> + <property name="trueProperty" value="true"/> + <jacoco:coverage destfile="${exec.file}"> + <java classname="org.jacoco.ant.TestTarget" fork="${trueProperty}" failonerror="true"> + <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/> + </java> + </jacoco:coverage> + + <au:assertLogContains text="Enhancing java with coverage"/> + <au:assertFileExists file="${exec.file}"/> + <au:assertLogContains text="Target executed"/> + </target> + + <target name="testCoverageOfForkedJavaDisabled"> + <jacoco:coverage enabled="false" destfile="${exec.file}"> + <java classname="org.jacoco.ant.TestTarget" fork="true" failonerror="true"> + <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/> + </java> + </jacoco:coverage> + + <au:assertLogDoesntContain text="Enhancing java with coverage"/> + <au:assertFileDoesntExist file="${exec.file}"/> + <au:assertLogContains text="Target executed"/> + </target> + + <target name="testCoverageOfNonForkedJava"> + <au:expectfailure expectedMessage="Coverage can only be applied on a forked VM"> + <jacoco:coverage> + <java classname="org.jacoco.ant.TestTarget" fork="false" failonerror="true"> + <classpath path="${org.jacoco.ant.coverageTaskTest.classes.dir}"/> + </java> + </jacoco:coverage> + </au:expectfailure> + + <au:assertLogDoesntContain text="Target executed"/> + </target> + + <target name="testCoverageOfForkedJUnit"> + <jacoco:coverage destfile="${exec.file}"> + <junit fork="true" haltonfailure="true" showoutput="true"> + <classpath path="${java.class.path}"/> + <test name="org.jacoco.ant.TestTarget" /> + </junit> + </jacoco:coverage> + + <au:assertLogContains text="Enhancing junit with coverage"/> + <au:assertFileExists file="${exec.file}"/> + <au:assertLogContains text="Target executed"/> + </target> + + <target name="testCoverageOfForkedJUnitDisabled"> + <jacoco:coverage enabled="false" destfile="${exec.file}"> + <junit fork="true" haltonfailure="true" showoutput="true"> + <classpath path="${java.class.path}"/> + <test name="org.jacoco.ant.TestTarget" /> + </junit> + </jacoco:coverage> + + <au:assertLogDoesntContain text="Enhancing junit with coverage"/> + <au:assertFileDoesntExist file="${exec.file}"/> + <au:assertLogContains text="Target executed"/> + </target> + + <target name="testCoverageOfNonForkedJUnit"> + <au:expectfailure expectedMessage="Coverage can only be applied on a forked VM"> + <jacoco:coverage> + <junit fork="false" haltonfailure="true" showoutput="true"> + <classpath path="${java.class.path}"/> + <test name="org.jacoco.ant.TestTarget" /> + </junit> + </jacoco:coverage> + </au:expectfailure> + + <au:assertLogDoesntContain text="Target executed"/> + </target> + </project>
\ No newline at end of file diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.java b/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.java index 8151ace1..22aed90f 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.java +++ b/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.java @@ -1,29 +1,29 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import java.io.File;
-
-import junit.framework.TestSuite;
-
-import org.apache.ant.antunit.junit3.AntUnitSuite;
-import org.apache.ant.antunit.junit4.AntUnitSuiteRunner;
-import org.junit.runner.RunWith;
-
-@RunWith(AntUnitSuiteRunner.class)
-public class DumpTaskTest {
-
- public static TestSuite suite() {
- final File file = new File("src/org/jacoco/ant/DumpTaskTest.xml");
- return new AntUnitSuite(file, DumpTaskTest.class);
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import java.io.File; + +import junit.framework.TestSuite; + +import org.apache.ant.antunit.junit3.AntUnitSuite; +import org.apache.ant.antunit.junit4.AntUnitSuiteRunner; +import org.junit.runner.RunWith; + +@RunWith(AntUnitSuiteRunner.class) +public class DumpTaskTest { + + public static TestSuite suite() { + final File file = new File("src/org/jacoco/ant/DumpTaskTest.xml"); + return new AntUnitSuite(file, DumpTaskTest.class); + } +} diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.xml index da2ded29..377a60ef 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskTest.xml @@ -1,57 +1,57 @@ -<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Copyright (c) 2009, 2012 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:
- Brock Janiczak - initial API and implementation
-
- $Id: $
--->
-
-<project name="JaCoCo Dump Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant">
-
- <target name="setUp">
- <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" />
- <mkdir dir="${temp.dir}"/>
- <property name="exec.file" location="${temp.dir}/exec.file" />
- </target>
-
- <target name="tearDown">
- <delete dir="${temp.dir}" quiet="false" failonerror="true"/>
- </target>
-
-
- <target name="testNoServer">
- <au:expectfailure expectedMessage="Unable to dump coverage data">
- <jacoco:dump dump="true" destfile="${exec.file}"/>
- </au:expectfailure>
- <au:assertFileDoesntExist file="${exec.file}"/>
- </target>
-
- <target name="testUnknownHost">
- <au:expectfailure expectedMessage="Unable to dump coverage data">
- <jacoco:dump dump="false" address="nosuchhost"/>
- </au:expectfailure>
- <au:assertFileDoesntExist file="${exec.file}"/>
- </target>
-
- <target name="testInvalidPort">
- <au:expectfailure expectedMessage="Invalid port value">
- <jacoco:dump dump="false" port="-1234"/>
- </au:expectfailure>
- <au:assertFileDoesntExist file="${exec.file}"/>
- </target>
-
- <target name="testNoDestFile">
- <au:expectfailure expectedMessage="Destination file is required when dumping execution data">
- <jacoco:dump dump="true"/>
- </au:expectfailure>
- <au:assertFileDoesntExist file="${exec.file}"/>
- </target>
-
+<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Copyright (c) 2009, 2012 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: + Brock Janiczak - initial API and implementation + + $Id: $ +--> + +<project name="JaCoCo Dump Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant"> + + <target name="setUp"> + <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" /> + <mkdir dir="${temp.dir}"/> + <property name="exec.file" location="${temp.dir}/exec.file" /> + </target> + + <target name="tearDown"> + <delete dir="${temp.dir}" quiet="false" failonerror="true"/> + </target> + + + <target name="testNoServer"> + <au:expectfailure expectedMessage="Unable to dump coverage data"> + <jacoco:dump dump="true" destfile="${exec.file}"/> + </au:expectfailure> + <au:assertFileDoesntExist file="${exec.file}"/> + </target> + + <target name="testUnknownHost"> + <au:expectfailure expectedMessage="Unable to dump coverage data"> + <jacoco:dump dump="false" address="nosuchhost"/> + </au:expectfailure> + <au:assertFileDoesntExist file="${exec.file}"/> + </target> + + <target name="testInvalidPort"> + <au:expectfailure expectedMessage="Invalid port value"> + <jacoco:dump dump="false" port="-1234"/> + </au:expectfailure> + <au:assertFileDoesntExist file="${exec.file}"/> + </target> + + <target name="testNoDestFile"> + <au:expectfailure expectedMessage="Destination file is required when dumping execution data"> + <jacoco:dump dump="true"/> + </au:expectfailure> + <au:assertFileDoesntExist file="${exec.file}"/> + </target> + </project>
\ No newline at end of file diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskWithServerTest.java b/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskWithServerTest.java index f0a32f48..d25dae4c 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskWithServerTest.java +++ b/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskWithServerTest.java @@ -1,32 +1,32 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import java.io.File;
-
-import junit.framework.TestSuite;
-
-import org.apache.ant.antunit.junit3.AntUnitSuite;
-import org.apache.ant.antunit.junit4.AntUnitSuiteRunner;
-import org.junit.runner.RunWith;
-
-@RunWith(AntUnitSuiteRunner.class)
-public class DumpTaskWithServerTest {
-
- public static TestSuite suite() {
- System.setProperty("org.jacoco.ant.dumpTaskWithServerTest.classes.dir",
- TestTarget.getClassPath());
- final File file = new File(
- "src/org/jacoco/ant/DumpTaskWithServerTest.xml");
- return new AntUnitSuite(file, DumpTaskWithServerTest.class);
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import java.io.File; + +import junit.framework.TestSuite; + +import org.apache.ant.antunit.junit3.AntUnitSuite; +import org.apache.ant.antunit.junit4.AntUnitSuiteRunner; +import org.junit.runner.RunWith; + +@RunWith(AntUnitSuiteRunner.class) +public class DumpTaskWithServerTest { + + public static TestSuite suite() { + System.setProperty("org.jacoco.ant.dumpTaskWithServerTest.classes.dir", + TestTarget.getClassPath()); + final File file = new File( + "src/org/jacoco/ant/DumpTaskWithServerTest.xml"); + return new AntUnitSuite(file, DumpTaskWithServerTest.class); + } +} diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskWithServerTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskWithServerTest.xml index 1c5bb30c..0fa8c1ec 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskWithServerTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/DumpTaskWithServerTest.xml @@ -1,74 +1,74 @@ -<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Copyright (c) 2009, 2012 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:
- Brock Janiczak - initial API and implementation
-
- $Id: $
--->
-
-<project name="JaCoCo Dump Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant">
-
- <target name="setUp">
- <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" />
- <mkdir dir="${temp.dir}"/>
- <property name="exec.file" location="${temp.dir}/exec.file" />
- <property name="term.file" location="${temp.dir}/term.file" />
-
- <jacoco:coverage output="tcpserver" port="6300">
- <java classname="org.jacoco.ant.TestTarget" spawn="true" fork="true" maxmemory="16m">
- <classpath path="${org.jacoco.ant.dumpTaskWithServerTest.classes.dir}"/>
- <jvmarg value="-client"/>
- <arg value="${term.file}"/>
- </java>
- </jacoco:coverage>
-
- <waitfor maxwait="1" maxwaitunit="second" checkevery="10" checkeveryunit="millisecond">
- <socket server="localhost" port="6300"/>
- </waitfor>
- </target>
-
- <target name="tearDown">
- <touch file="${term.file}"/>
- <waitfor maxwait="5" maxwaitunit="second" checkevery="10" checkeveryunit="millisecond">
- <not>
- <socket server="localhost" port="6300"/>
- </not>
- </waitfor>
- <delete dir="${temp.dir}" quiet="false" failonerror="true"/>
- </target>
-
-
- <target name="testDump">
- <jacoco:dump dump="true" destfile="${exec.file}"/>
-
- <au:assertFileExists file="${exec.file}"/>
- <au:assertLogContains text="Dumping execution data to ${exec.file}"/>
- </target>
-
- <target name="testNoDumpOrReset">
- <jacoco:dump dump="false" reset="false"/>
-
- <au:assertLogDoesntContain text="Dumping execution data to"/>
- </target>
-
- <target name="testResetOnly">
- <jacoco:dump dump="false" reset="true"/>
-
- <au:assertLogDoesntContain text="Dumping execution data to"/>
- </target>
-
- <target name="testNoDumpWithFileSet">
- <jacoco:dump dump="false" destfile="${exec.file}"/>
-
- <au:assertLogDoesntContain text="Dumping execution data to"/>
- <au:assertFileDoesntExist file="${exec.file}"/>
- </target>
-
+<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Copyright (c) 2009, 2012 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: + Brock Janiczak - initial API and implementation + + $Id: $ +--> + +<project name="JaCoCo Dump Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant"> + + <target name="setUp"> + <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" /> + <mkdir dir="${temp.dir}"/> + <property name="exec.file" location="${temp.dir}/exec.file" /> + <property name="term.file" location="${temp.dir}/term.file" /> + + <jacoco:coverage output="tcpserver" port="6300"> + <java classname="org.jacoco.ant.TestTarget" spawn="true" fork="true" maxmemory="16m"> + <classpath path="${org.jacoco.ant.dumpTaskWithServerTest.classes.dir}"/> + <jvmarg value="-client"/> + <arg value="${term.file}"/> + </java> + </jacoco:coverage> + + <waitfor maxwait="1" maxwaitunit="second" checkevery="10" checkeveryunit="millisecond"> + <socket server="localhost" port="6300"/> + </waitfor> + </target> + + <target name="tearDown"> + <touch file="${term.file}"/> + <waitfor maxwait="5" maxwaitunit="second" checkevery="10" checkeveryunit="millisecond"> + <not> + <socket server="localhost" port="6300"/> + </not> + </waitfor> + <delete dir="${temp.dir}" quiet="false" failonerror="true"/> + </target> + + + <target name="testDump"> + <jacoco:dump dump="true" destfile="${exec.file}"/> + + <au:assertFileExists file="${exec.file}"/> + <au:assertLogContains text="Dumping execution data to ${exec.file}"/> + </target> + + <target name="testNoDumpOrReset"> + <jacoco:dump dump="false" reset="false"/> + + <au:assertLogDoesntContain text="Dumping execution data to"/> + </target> + + <target name="testResetOnly"> + <jacoco:dump dump="false" reset="true"/> + + <au:assertLogDoesntContain text="Dumping execution data to"/> + </target> + + <target name="testNoDumpWithFileSet"> + <jacoco:dump dump="false" destfile="${exec.file}"/> + + <au:assertLogDoesntContain text="Dumping execution data to"/> + <au:assertFileDoesntExist file="${exec.file}"/> + </target> + </project>
\ No newline at end of file diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.java b/org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.java index 966eae10..6cb6df58 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.java +++ b/org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.java @@ -1,30 +1,30 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import java.io.File;
-
-import junit.framework.TestSuite;
-
-import org.apache.ant.antunit.junit3.AntUnitSuite;
-import org.apache.ant.antunit.junit4.AntUnitSuiteRunner;
-import org.junit.runner.RunWith;
-
-@RunWith(AntUnitSuiteRunner.class)
-public class MergeTaskTest {
-
- public static TestSuite suite() {
- final File file = new File("src/org/jacoco/ant/MergeTaskTest.xml");
- return new AntUnitSuite(file, MergeTaskTest.class);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import java.io.File; + +import junit.framework.TestSuite; + +import org.apache.ant.antunit.junit3.AntUnitSuite; +import org.apache.ant.antunit.junit4.AntUnitSuiteRunner; +import org.junit.runner.RunWith; + +@RunWith(AntUnitSuiteRunner.class) +public class MergeTaskTest { + + public static TestSuite suite() { + final File file = new File("src/org/jacoco/ant/MergeTaskTest.xml"); + return new AntUnitSuite(file, MergeTaskTest.class); + } + +} diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.xml b/org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.xml index dcaecc9b..f7f50000 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/MergeTaskTest.xml @@ -1,74 +1,74 @@ -<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Copyright (c) 2009, 2012 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:
- Brock Janiczak - initial API and implementation
-
- $Id: $
--->
-
-<project name="JaCoCo Merge Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant">
-
- <target name="setUp">
- <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" />
- <mkdir dir="${temp.dir}"/>
- <property name="exec.file" location="${temp.dir}/exec.file" />
- </target>
-
- <target name="tearDown">
- <delete dir="${temp.dir}" quiet="false" failonerror="true"/>
- </target>
-
- <target name="testMergeNoDestination">
- <au:expectfailure expectedMessage="Destination file must be supplied">
- <jacoco:merge/>
- </au:expectfailure>
- </target>
-
- <target name="testMergeToDirectory">
- <au:expectfailure expectedMessage="Unable to write merged file ${temp.dir}">
- <jacoco:merge destfile="${temp.dir}"/>
- </au:expectfailure>
- </target>
-
- <target name="testMergeEmptySet">
- <jacoco:merge destfile="${exec.file}"/>
-
- <au:assertFileExists file="${exec.file}"/>
- </target>
-
- <target name="testMergeMultipleFiles">
- <jacoco:merge destfile="${exec.file}">
- <fileset dir="${basedir}/data" includes="*.exec"/>
- </jacoco:merge>
-
- <property name="sample1.file" location="${basedir}/data/sample1.exec"/>
- <property name="sample2.file" location="${basedir}/data/sample2.exec"/>
- <au:assertLogContains text="Loading execution data file ${sample1.file}"/>
- <au:assertLogContains text="Loading execution data file ${sample2.file}"/>
- <au:assertFileExists file="${exec.file}"/>
- </target>
-
- <target name="testMergeBadFiles">
- <property name="bad.file" location="${basedir}/data/sample.bad"/>
- <au:expectfailure expectedMessage="Unable to read ${bad.file}">
- <jacoco:merge destfile="${exec.file}">
- <file file="${basedir}/data/sample.bad"/>
- </jacoco:merge>
- </au:expectfailure>
- </target>
-
- <target name="testMergeDirectory">
- <jacoco:merge destfile="${exec.file}">
- <dirset dir="${basedir}/data"/>
- </jacoco:merge>
-
- <au:assertFileExists file="${exec.file}"/>
- </target>
+<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Copyright (c) 2009, 2012 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: + Brock Janiczak - initial API and implementation + + $Id: $ +--> + +<project name="JaCoCo Merge Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant"> + + <target name="setUp"> + <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" /> + <mkdir dir="${temp.dir}"/> + <property name="exec.file" location="${temp.dir}/exec.file" /> + </target> + + <target name="tearDown"> + <delete dir="${temp.dir}" quiet="false" failonerror="true"/> + </target> + + <target name="testMergeNoDestination"> + <au:expectfailure expectedMessage="Destination file must be supplied"> + <jacoco:merge/> + </au:expectfailure> + </target> + + <target name="testMergeToDirectory"> + <au:expectfailure expectedMessage="Unable to write merged file ${temp.dir}"> + <jacoco:merge destfile="${temp.dir}"/> + </au:expectfailure> + </target> + + <target name="testMergeEmptySet"> + <jacoco:merge destfile="${exec.file}"/> + + <au:assertFileExists file="${exec.file}"/> + </target> + + <target name="testMergeMultipleFiles"> + <jacoco:merge destfile="${exec.file}"> + <fileset dir="${basedir}/data" includes="*.exec"/> + </jacoco:merge> + + <property name="sample1.file" location="${basedir}/data/sample1.exec"/> + <property name="sample2.file" location="${basedir}/data/sample2.exec"/> + <au:assertLogContains text="Loading execution data file ${sample1.file}"/> + <au:assertLogContains text="Loading execution data file ${sample2.file}"/> + <au:assertFileExists file="${exec.file}"/> + </target> + + <target name="testMergeBadFiles"> + <property name="bad.file" location="${basedir}/data/sample.bad"/> + <au:expectfailure expectedMessage="Unable to read ${bad.file}"> + <jacoco:merge destfile="${exec.file}"> + <file file="${basedir}/data/sample.bad"/> + </jacoco:merge> + </au:expectfailure> + </target> + + <target name="testMergeDirectory"> + <jacoco:merge destfile="${exec.file}"> + <dirset dir="${basedir}/data"/> + </jacoco:merge> + + <au:assertFileExists file="${exec.file}"/> + </target> </project>
\ No newline at end of file diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.java b/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.java index 3774f645..5097608a 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.java +++ b/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.java @@ -1,34 +1,34 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import java.io.File;
-
-import junit.framework.TestSuite;
-
-import org.apache.ant.antunit.junit3.AntUnitSuite;
-import org.apache.ant.antunit.junit4.AntUnitSuiteRunner;
-import org.junit.runner.RunWith;
-
-@RunWith(AntUnitSuiteRunner.class)
-public class ReportTaskTest {
-
- public static TestSuite suite() {
- System.setProperty("org.jacoco.ant.reportTaskTest.classes.dir",
- TestTarget.getClassPath());
- System.setProperty("org.jacoco.ant.reportTaskTest.sources.dir",
- new File("./src").getAbsolutePath());
- final File file = new File("src/org/jacoco/ant/ReportTaskTest.xml");
- return new AntUnitSuite(file, ReportTaskTest.class);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import java.io.File; + +import junit.framework.TestSuite; + +import org.apache.ant.antunit.junit3.AntUnitSuite; +import org.apache.ant.antunit.junit4.AntUnitSuiteRunner; +import org.junit.runner.RunWith; + +@RunWith(AntUnitSuiteRunner.class) +public class ReportTaskTest { + + public static TestSuite suite() { + System.setProperty("org.jacoco.ant.reportTaskTest.classes.dir", + TestTarget.getClassPath()); + System.setProperty("org.jacoco.ant.reportTaskTest.sources.dir", + new File("./src").getAbsolutePath()); + final File file = new File("src/org/jacoco/ant/ReportTaskTest.xml"); + return new AntUnitSuite(file, ReportTaskTest.class); + } + +} 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 fff8b1f1..5e0add05 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.xml +++ b/org.jacoco.ant.test/src/org/jacoco/ant/ReportTaskTest.xml @@ -1,416 +1,416 @@ -<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Copyright (c) 2009, 2012 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:
- Brock Janiczak - initial API and implementation
- Dominik Stadler - source folder support
-
- $Id: $
--->
-
-<project name="JaCoCo Report Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant">
-
- <target name="setUp">
- <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" />
- <mkdir dir="${temp.dir}"/>
- </target>
-
- <target name="tearDown">
- <delete dir="${temp.dir}" quiet="false" failonerror="true" />
- </target>
-
-
- <target name="testReportNoStructureElement">
- <au:expectfailure expectedMessage="Group name must be supplied">
- <jacoco:report/>
- </au:expectfailure>
- </target>
-
- <target name="testReportNoStructureName">
- <au:expectfailure expectedMessage="Group name must be supplied">
- <jacoco:report>
- <structure/>
- </jacoco:report>
- </au:expectfailure>
- </target>
-
- <target name="testReportNoGroupName">
- <au:expectfailure expectedMessage="Group name must be supplied">
- <jacoco:report>
- <structure name="root">
- <group/>
- </structure>
- </jacoco:report>
- </au:expectfailure>
- </target>
-
- <target name="testReportWithExecutiondataFiles">
- <jacoco:report>
- <executiondata>
- <fileset dir="${basedir}/data" includes="*.exec"/>
- </executiondata>
- <structure name="root"/>
- </jacoco:report>
- </target>
-
- <target name="testReportInvalidExecutionDataFile">
- <property name="doesnotexist.file" location="doesnotexist.exec"/>
- <au:expectfailure expectedMessage="Unable to read execution data file ${doesnotexist.file}">
- <jacoco:report>
- <executiondata>
+<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Copyright (c) 2009, 2012 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: + Brock Janiczak - initial API and implementation + Dominik Stadler - source folder support + + $Id: $ +--> + +<project name="JaCoCo Report Task Tests" xmlns:au="antlib:org.apache.ant.antunit" xmlns:jacoco="antlib:org.jacoco.ant"> + + <target name="setUp"> + <tempfile property="temp.dir" prefix="jacocoTest" destdir="${java.io.tmpdir}" /> + <mkdir dir="${temp.dir}"/> + </target> + + <target name="tearDown"> + <delete dir="${temp.dir}" quiet="false" failonerror="true" /> + </target> + + + <target name="testReportNoStructureElement"> + <au:expectfailure expectedMessage="Group name must be supplied"> + <jacoco:report/> + </au:expectfailure> + </target> + + <target name="testReportNoStructureName"> + <au:expectfailure expectedMessage="Group name must be supplied"> + <jacoco:report> + <structure/> + </jacoco:report> + </au:expectfailure> + </target> + + <target name="testReportNoGroupName"> + <au:expectfailure expectedMessage="Group name must be supplied"> + <jacoco:report> + <structure name="root"> + <group/> + </structure> + </jacoco:report> + </au:expectfailure> + </target> + + <target name="testReportWithExecutiondataFiles"> + <jacoco:report> + <executiondata> + <fileset dir="${basedir}/data" includes="*.exec"/> + </executiondata> + <structure name="root"/> + </jacoco:report> + </target> + + <target name="testReportInvalidExecutionDataFile"> + <property name="doesnotexist.file" location="doesnotexist.exec"/> + <au:expectfailure expectedMessage="Unable to read execution data file ${doesnotexist.file}"> + <jacoco:report> + <executiondata> <file file="doesnotexist.exec"/> - </executiondata>
- <structure name="root"/>
- </jacoco:report>
- </au:expectfailure>
- </target>
-
- <target name="testReportWithSourceButNoDebug">
- <java classname="org.jacoco.ant.RemoveDebugInfos" classpath="${java.class.path}" failonerror="true">
- <arg value="${org.jacoco.ant.reportTaskTest.classes.dir}/org/jacoco/ant/TestTarget.class" />
- <arg value="${temp.dir}/TestTarget.class" />
- </java>
- <jacoco:report>
- <structure name="root">
- <classfiles>
- <fileset dir="${temp.dir}" id="*.class" />
- </classfiles>
- <sourcefiles encoding="UTF-8">
- <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
- </sourcefiles>
- </structure>
- </jacoco:report>
- <au:assertLogContains level="warn" text="To enable source code annotation class files for bundle 'root' have to be compiled with debug information"/>
- </target>
-
- <target name="testReportWithSourceDirButNoDebug">
- <java classname="org.jacoco.ant.RemoveDebugInfos" classpath="${java.class.path}" failonerror="true">
- <arg value="${org.jacoco.ant.reportTaskTest.classes.dir}/org/jacoco/ant/TestTarget.class" />
- <arg value="${temp.dir}/TestTarget.class" />
- </java>
- <jacoco:report>
- <structure name="root">
- <classfiles>
- <fileset dir="${temp.dir}" id="*.class" />
- </classfiles>
- <sourcefiles encoding="UTF-8">
- <dirset file="${org.jacoco.ant.reportTaskTest.sources.dir}" />
- </sourcefiles>
- </structure>
- </jacoco:report>
- <au:assertLogContains level="warn" text="To enable source code annotation class files for bundle 'root' have to be compiled with debug information"/>
- </target>
-
- <target name="testReportWithSourceButNoClasses">
- <jacoco:report>
- <structure name="root">
- <sourcefiles encoding="UTF-8">
- <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
- </sourcefiles>
- </structure>
- </jacoco:report>
- <au:assertLogDoesntContain level="warn" text="source code annotation"/>
- </target>
-
- <!-- HTML Output -->
-
- <target name="testReportHtmlNoDestdirOrDestfile">
- <au:expectfailure expectedMessage="Destination directory or file must be supplied for html report">
- <jacoco:report>
- <structure name="root"/>
- <html/>
- </jacoco:report>
- </au:expectfailure>
- </target>
-
- <target name="testReportHtmlBothDestdirAndDestfile">
- <au:expectfailure expectedMessage="Either destination directory or file must be supplied, not both">
- <jacoco:report>
- <structure name="root"/>
- <html destdir="${temp.dir}" destfile="${temp.dir}/report.zip"/>
- </jacoco:report>
- </au:expectfailure>
- </target>
-
- <target name="testReportHtmlWithClassFileSet">
- <jacoco:report>
- <structure name="Test">
- <group name="Group">
- <classfiles>
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </classfiles>
- </group>
- </structure>
- <html destdir="${temp.dir}"/>
- </jacoco:report>
-
- <au:assertFileExists file="${temp.dir}/Group/org.jacoco.ant/TestTarget.html"/>
- </target>
-
- <target name="testReportHtmlWithPath">
- <jacoco:report>
- <structure name="Test">
- <group name="Group">
- <classfiles>
- <path location="${org.jacoco.ant.reportTaskTest.classes.dir}"/>
- </classfiles>
- </group>
- </structure>
- <html destdir="${temp.dir}"/>
- </jacoco:report>
-
- <au:assertFileExists file="${temp.dir}/Group/org.jacoco.ant/TestTarget.html"/>
- </target>
-
- <target name="testReportHtmlWithJAR">
- <property name="testReportHtmlWithJAR.jarfile" location="${temp.dir}/testclasses.jar"/>
- <jar destfile="${testReportHtmlWithJAR.jarfile}">
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </jar>
- <jacoco:report>
- <structure name="Test">
- <group name="Group">
- <classfiles>
- <file file="${testReportHtmlWithJAR.jarfile}"/>
- </classfiles>
- </group>
- </structure>
- <html destdir="${temp.dir}"/>
- </jacoco:report>
-
- <au:assertFileExists file="${temp.dir}/Group/org.jacoco.ant/TestTarget.html"/>
- </target>
-
- <target name="testReportHtmlFooter">
- <jacoco:report>
- <structure name="Test"/>
- <html footer="ExampleFooter" destdir="${temp.dir}"/>
- </jacoco:report>
-
- <loadfile property="testReportHtmlFooter.content" srcfile="${temp.dir}/index.html" encoding="UTF-8"/>
- <au:assertTrue message="Footer not included in ${testReportHtmlFooter.content}">
- <contains string="${testReportHtmlFooter.content}" substring="ExampleFooter"/>
- </au:assertTrue>
- </target>
-
- <target name="testReportHtmlEncoding">
- <jacoco:report>
- <structure name="Test"/>
- <html encoding="UTF-16" destdir="${temp.dir}"/>
- </jacoco:report>
-
- <loadfile property="testReportHtmlEncoding.content" srcfile="${temp.dir}/index.html" encoding="UTF-16"/>
- <au:assertTrue message="Encoding not set in ${testReportHtmlEncoding.content}">
- <contains string="${testReportHtmlEncoding.content}" substring="encoding="UTF-16""/>
- </au:assertTrue>
- </target>
-
- <target name="testReportHtmlDefaultTabWidth">
- <jacoco:report>
- <structure name="Test">
- <classfiles>
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </classfiles>
- <sourcefiles encoding="UTF-8">
- <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
- </sourcefiles>
- </structure>
- <html destdir="${temp.dir}"/>
- </jacoco:report>
-
- <loadfile property="testReportHtmlTabWidth.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/>
- <au:assertTrue message="Tab width not set in ${testReportHtmlTabWidth.content}">
- <contains string="${testReportHtmlTabWidth.content}" substring="window['PR_TAB_WIDTH']=4"/>
- </au:assertTrue>
- </target>
-
- <target name="testReportHtmlTabWidth">
- <jacoco:report>
- <structure name="Test">
- <classfiles>
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </classfiles>
- <sourcefiles encoding="UTF-8" tabwidth="13">
- <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
- </sourcefiles>
- </structure>
- <html destdir="${temp.dir}"/>
- </jacoco:report>
-
- <loadfile property="testReportHtmlTabWidth.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/>
- <au:assertTrue message="Tab width not set in ${testReportHtmlTabWidth.content}">
- <contains string="${testReportHtmlTabWidth.content}" substring="window['PR_TAB_WIDTH']=13"/>
- </au:assertTrue>
- </target>
-
- <target name="testReportHtmlInvalidTabWidth">
- <au:expectfailure expectedMessage="Tab width must be greater than 0">
- <jacoco:report>
- <structure name="Test">
- <classfiles>
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </classfiles>
- <sourcefiles encoding="UTF-8" tabwidth="0">
- <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
- </sourcefiles>
- </structure>
- <html destdir="${temp.dir}"/>
- </jacoco:report>
- </au:expectfailure>
- </target>
-
- <target name="testReportHtmlZipFile">
- <jacoco:report>
- <structure name="Test">
- <classfiles>
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </classfiles>
- </structure>
- <html destfile="${temp.dir}/report.zip"/>
- </jacoco:report>
-
- <au:assertFileExists file="${temp.dir}/report.zip"/>
- </target>
-
- <target name="testReportHtmlWithSources">
- <jacoco:report>
- <structure name="Test">
- <classfiles>
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </classfiles>
- <sourcefiles encoding="UTF-8">
- <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
- </sourcefiles>
- </structure>
- <html destdir="${temp.dir}"/>
- </jacoco:report>
-
- <au:assertFileExists file="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/>
- <au:assertFileExists file="${temp.dir}/default/TestTargetInDefault.java.html"/>
- </target>
-
- <target name="testReportHtmlWithSourcesDir">
- <jacoco:report>
- <structure name="Test">
- <classfiles>
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </classfiles>
- <sourcefiles encoding="UTF-8">
- <dirset dir="${org.jacoco.ant.reportTaskTest.sources.dir}/.." includes="src" />
- </sourcefiles>
- </structure>
- <html destdir="${temp.dir}"/>
- </jacoco:report>
-
- <au:assertFileExists file="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/>
- <au:assertFileExists file="${temp.dir}/default/TestTargetInDefault.java.html"/>
- </target>
-
- <target name="testReportHtmlWithSourceEncoding">
- <mkdir dir="${temp.dir}/org/jacoco/ant"/>
- <echo file="${temp.dir}/org/jacoco/ant/TestTarget.java" encoding="UTF-16">Source Code</echo>
- <jacoco:report>
- <structure name="Test">
- <classfiles>
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </classfiles>
- <sourcefiles encoding="UTF-16">
- <fileset dir="${temp.dir}" />
- </sourcefiles>
- </structure>
- <html destdir="${temp.dir}"/>
- </jacoco:report>
-
- <loadfile property="testReportHtmlWithSourceEncoding.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html" encoding="UTF-8"/>
- <au:assertTrue message="Report does not contain expected text.">
- <contains string="${testReportHtmlWithSourceEncoding.content}" substring="Source Code"/>
- </au:assertTrue>
- </target>
-
- <target name="testReportHtmlLocale">
- <jacoco:report>
- <structure name="Test">
- <classfiles>
- <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/>
- </classfiles>
- <sourcefiles encoding="UTF-8">
- <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" />
- </sourcefiles>
- </structure>
- <html destdir="${temp.dir}" locale="gr"/>
- </jacoco:report>
-
- <loadfile property="testReportHtmlLocale.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html" encoding="UTF-8"/>
- <au:assertTrue message="Report does not contain expected language tag.">
- <contains string="${testReportHtmlLocale.content}" substring="lang="gr""/>
- </au:assertTrue>
- </target>
-
- <!-- CSV Output -->
-
- <target name="testReportCsvNoDestfile">
- <au:expectfailure expectedMessage="Destination file must be supplied for csv report">
- <jacoco:report>
- <structure name="root"/>
- <csv/>
- </jacoco:report>
- </au:expectfailure>
- </target>
-
- <target name="testReportCsvEncoding">
- <property name="testReportCsvEncoding.destfile" location="${temp.dir}/report.csv"/>
- <jacoco:report>
- <structure name="Test"/>
- <csv encoding="UTF-16" destfile="${testReportCsvEncoding.destfile}"/>
- </jacoco:report>
-
- <au:assertFileExists file="${testReportCsvEncoding.destfile}"/>
- <loadfile property="testReportCsvEncoding.content" srcfile="${testReportCsvEncoding.destfile}" encoding="UTF-16"/>
- <au:assertTrue message="Encoding not set in ${testReportCsvEncoding.content}">
- <contains string="${testReportCsvEncoding.content}" substring="METHOD_COVERED"/>
- </au:assertTrue>
- </target>
-
-
- <!-- XML Output -->
-
- <target name="testReportXmlNoDestfile">
- <au:expectfailure expectedMessage="Destination file must be supplied for xml report">
- <jacoco:report>
- <structure name="root"/>
- <xml/>
- </jacoco:report>
- </au:expectfailure>
- </target>
-
- <target name="testReportXmlInvalidDestfile">
- <au:expectfailure expectedMessage="Error while creating report">
- <jacoco:report>
- <structure name="root"/>
- <xml destfile="${temp.dir}"/>
- </jacoco:report>
- </au:expectfailure>
- </target>
-
- <target name="testReportXmlEncoding">
- <property name="testReportXmlEncoding.destfile" location="${temp.dir}/report.xml"/>
- <jacoco:report>
- <structure name="Test"/>
- <xml encoding="UTF-16" destfile="${testReportXmlEncoding.destfile}"/>
- </jacoco:report>
-
- <au:assertFileExists file="${testReportXmlEncoding.destfile}"/>
- <loadfile property="testReportXmlEncoding.content" srcfile="${testReportXmlEncoding.destfile}" encoding="UTF-16"/>
- <au:assertTrue message="Encoding not set in ${testReportXmlEncoding.content}">
- <contains string="${testReportXmlEncoding.content}" substring="encoding="UTF-16""/>
- </au:assertTrue>
- </target>
-
-
+ </executiondata> + <structure name="root"/> + </jacoco:report> + </au:expectfailure> + </target> + + <target name="testReportWithSourceButNoDebug"> + <java classname="org.jacoco.ant.RemoveDebugInfos" classpath="${java.class.path}" failonerror="true"> + <arg value="${org.jacoco.ant.reportTaskTest.classes.dir}/org/jacoco/ant/TestTarget.class" /> + <arg value="${temp.dir}/TestTarget.class" /> + </java> + <jacoco:report> + <structure name="root"> + <classfiles> + <fileset dir="${temp.dir}" id="*.class" /> + </classfiles> + <sourcefiles encoding="UTF-8"> + <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" /> + </sourcefiles> + </structure> + </jacoco:report> + <au:assertLogContains level="warn" text="To enable source code annotation class files for bundle 'root' have to be compiled with debug information"/> + </target> + + <target name="testReportWithSourceDirButNoDebug"> + <java classname="org.jacoco.ant.RemoveDebugInfos" classpath="${java.class.path}" failonerror="true"> + <arg value="${org.jacoco.ant.reportTaskTest.classes.dir}/org/jacoco/ant/TestTarget.class" /> + <arg value="${temp.dir}/TestTarget.class" /> + </java> + <jacoco:report> + <structure name="root"> + <classfiles> + <fileset dir="${temp.dir}" id="*.class" /> + </classfiles> + <sourcefiles encoding="UTF-8"> + <dirset file="${org.jacoco.ant.reportTaskTest.sources.dir}" /> + </sourcefiles> + </structure> + </jacoco:report> + <au:assertLogContains level="warn" text="To enable source code annotation class files for bundle 'root' have to be compiled with debug information"/> + </target> + + <target name="testReportWithSourceButNoClasses"> + <jacoco:report> + <structure name="root"> + <sourcefiles encoding="UTF-8"> + <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" /> + </sourcefiles> + </structure> + </jacoco:report> + <au:assertLogDoesntContain level="warn" text="source code annotation"/> + </target> + + <!-- HTML Output --> + + <target name="testReportHtmlNoDestdirOrDestfile"> + <au:expectfailure expectedMessage="Destination directory or file must be supplied for html report"> + <jacoco:report> + <structure name="root"/> + <html/> + </jacoco:report> + </au:expectfailure> + </target> + + <target name="testReportHtmlBothDestdirAndDestfile"> + <au:expectfailure expectedMessage="Either destination directory or file must be supplied, not both"> + <jacoco:report> + <structure name="root"/> + <html destdir="${temp.dir}" destfile="${temp.dir}/report.zip"/> + </jacoco:report> + </au:expectfailure> + </target> + + <target name="testReportHtmlWithClassFileSet"> + <jacoco:report> + <structure name="Test"> + <group name="Group"> + <classfiles> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </classfiles> + </group> + </structure> + <html destdir="${temp.dir}"/> + </jacoco:report> + + <au:assertFileExists file="${temp.dir}/Group/org.jacoco.ant/TestTarget.html"/> + </target> + + <target name="testReportHtmlWithPath"> + <jacoco:report> + <structure name="Test"> + <group name="Group"> + <classfiles> + <path location="${org.jacoco.ant.reportTaskTest.classes.dir}"/> + </classfiles> + </group> + </structure> + <html destdir="${temp.dir}"/> + </jacoco:report> + + <au:assertFileExists file="${temp.dir}/Group/org.jacoco.ant/TestTarget.html"/> + </target> + + <target name="testReportHtmlWithJAR"> + <property name="testReportHtmlWithJAR.jarfile" location="${temp.dir}/testclasses.jar"/> + <jar destfile="${testReportHtmlWithJAR.jarfile}"> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </jar> + <jacoco:report> + <structure name="Test"> + <group name="Group"> + <classfiles> + <file file="${testReportHtmlWithJAR.jarfile}"/> + </classfiles> + </group> + </structure> + <html destdir="${temp.dir}"/> + </jacoco:report> + + <au:assertFileExists file="${temp.dir}/Group/org.jacoco.ant/TestTarget.html"/> + </target> + + <target name="testReportHtmlFooter"> + <jacoco:report> + <structure name="Test"/> + <html footer="ExampleFooter" destdir="${temp.dir}"/> + </jacoco:report> + + <loadfile property="testReportHtmlFooter.content" srcfile="${temp.dir}/index.html" encoding="UTF-8"/> + <au:assertTrue message="Footer not included in ${testReportHtmlFooter.content}"> + <contains string="${testReportHtmlFooter.content}" substring="ExampleFooter"/> + </au:assertTrue> + </target> + + <target name="testReportHtmlEncoding"> + <jacoco:report> + <structure name="Test"/> + <html encoding="UTF-16" destdir="${temp.dir}"/> + </jacoco:report> + + <loadfile property="testReportHtmlEncoding.content" srcfile="${temp.dir}/index.html" encoding="UTF-16"/> + <au:assertTrue message="Encoding not set in ${testReportHtmlEncoding.content}"> + <contains string="${testReportHtmlEncoding.content}" substring="encoding="UTF-16""/> + </au:assertTrue> + </target> + + <target name="testReportHtmlDefaultTabWidth"> + <jacoco:report> + <structure name="Test"> + <classfiles> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </classfiles> + <sourcefiles encoding="UTF-8"> + <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" /> + </sourcefiles> + </structure> + <html destdir="${temp.dir}"/> + </jacoco:report> + + <loadfile property="testReportHtmlTabWidth.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/> + <au:assertTrue message="Tab width not set in ${testReportHtmlTabWidth.content}"> + <contains string="${testReportHtmlTabWidth.content}" substring="window['PR_TAB_WIDTH']=4"/> + </au:assertTrue> + </target> + + <target name="testReportHtmlTabWidth"> + <jacoco:report> + <structure name="Test"> + <classfiles> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </classfiles> + <sourcefiles encoding="UTF-8" tabwidth="13"> + <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" /> + </sourcefiles> + </structure> + <html destdir="${temp.dir}"/> + </jacoco:report> + + <loadfile property="testReportHtmlTabWidth.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/> + <au:assertTrue message="Tab width not set in ${testReportHtmlTabWidth.content}"> + <contains string="${testReportHtmlTabWidth.content}" substring="window['PR_TAB_WIDTH']=13"/> + </au:assertTrue> + </target> + + <target name="testReportHtmlInvalidTabWidth"> + <au:expectfailure expectedMessage="Tab width must be greater than 0"> + <jacoco:report> + <structure name="Test"> + <classfiles> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </classfiles> + <sourcefiles encoding="UTF-8" tabwidth="0"> + <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" /> + </sourcefiles> + </structure> + <html destdir="${temp.dir}"/> + </jacoco:report> + </au:expectfailure> + </target> + + <target name="testReportHtmlZipFile"> + <jacoco:report> + <structure name="Test"> + <classfiles> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </classfiles> + </structure> + <html destfile="${temp.dir}/report.zip"/> + </jacoco:report> + + <au:assertFileExists file="${temp.dir}/report.zip"/> + </target> + + <target name="testReportHtmlWithSources"> + <jacoco:report> + <structure name="Test"> + <classfiles> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </classfiles> + <sourcefiles encoding="UTF-8"> + <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" /> + </sourcefiles> + </structure> + <html destdir="${temp.dir}"/> + </jacoco:report> + + <au:assertFileExists file="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/> + <au:assertFileExists file="${temp.dir}/default/TestTargetInDefault.java.html"/> + </target> + + <target name="testReportHtmlWithSourcesDir"> + <jacoco:report> + <structure name="Test"> + <classfiles> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </classfiles> + <sourcefiles encoding="UTF-8"> + <dirset dir="${org.jacoco.ant.reportTaskTest.sources.dir}/.." includes="src" /> + </sourcefiles> + </structure> + <html destdir="${temp.dir}"/> + </jacoco:report> + + <au:assertFileExists file="${temp.dir}/org.jacoco.ant/TestTarget.java.html"/> + <au:assertFileExists file="${temp.dir}/default/TestTargetInDefault.java.html"/> + </target> + + <target name="testReportHtmlWithSourceEncoding"> + <mkdir dir="${temp.dir}/org/jacoco/ant"/> + <echo file="${temp.dir}/org/jacoco/ant/TestTarget.java" encoding="UTF-16">Source Code</echo> + <jacoco:report> + <structure name="Test"> + <classfiles> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </classfiles> + <sourcefiles encoding="UTF-16"> + <fileset dir="${temp.dir}" /> + </sourcefiles> + </structure> + <html destdir="${temp.dir}"/> + </jacoco:report> + + <loadfile property="testReportHtmlWithSourceEncoding.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html" encoding="UTF-8"/> + <au:assertTrue message="Report does not contain expected text."> + <contains string="${testReportHtmlWithSourceEncoding.content}" substring="Source Code"/> + </au:assertTrue> + </target> + + <target name="testReportHtmlLocale"> + <jacoco:report> + <structure name="Test"> + <classfiles> + <fileset dir="${org.jacoco.ant.reportTaskTest.classes.dir}" includes="**/*.class"/> + </classfiles> + <sourcefiles encoding="UTF-8"> + <fileset dir="${org.jacoco.ant.reportTaskTest.sources.dir}" /> + </sourcefiles> + </structure> + <html destdir="${temp.dir}" locale="gr"/> + </jacoco:report> + + <loadfile property="testReportHtmlLocale.content" srcfile="${temp.dir}/org.jacoco.ant/TestTarget.java.html" encoding="UTF-8"/> + <au:assertTrue message="Report does not contain expected language tag."> + <contains string="${testReportHtmlLocale.content}" substring="lang="gr""/> + </au:assertTrue> + </target> + + <!-- CSV Output --> + + <target name="testReportCsvNoDestfile"> + <au:expectfailure expectedMessage="Destination file must be supplied for csv report"> + <jacoco:report> + <structure name="root"/> + <csv/> + </jacoco:report> + </au:expectfailure> + </target> + + <target name="testReportCsvEncoding"> + <property name="testReportCsvEncoding.destfile" location="${temp.dir}/report.csv"/> + <jacoco:report> + <structure name="Test"/> + <csv encoding="UTF-16" destfile="${testReportCsvEncoding.destfile}"/> + </jacoco:report> + + <au:assertFileExists file="${testReportCsvEncoding.destfile}"/> + <loadfile property="testReportCsvEncoding.content" srcfile="${testReportCsvEncoding.destfile}" encoding="UTF-16"/> + <au:assertTrue message="Encoding not set in ${testReportCsvEncoding.content}"> + <contains string="${testReportCsvEncoding.content}" substring="METHOD_COVERED"/> + </au:assertTrue> + </target> + + + <!-- XML Output --> + + <target name="testReportXmlNoDestfile"> + <au:expectfailure expectedMessage="Destination file must be supplied for xml report"> + <jacoco:report> + <structure name="root"/> + <xml/> + </jacoco:report> + </au:expectfailure> + </target> + + <target name="testReportXmlInvalidDestfile"> + <au:expectfailure expectedMessage="Error while creating report"> + <jacoco:report> + <structure name="root"/> + <xml destfile="${temp.dir}"/> + </jacoco:report> + </au:expectfailure> + </target> + + <target name="testReportXmlEncoding"> + <property name="testReportXmlEncoding.destfile" location="${temp.dir}/report.xml"/> + <jacoco:report> + <structure name="Test"/> + <xml encoding="UTF-16" destfile="${testReportXmlEncoding.destfile}"/> + </jacoco:report> + + <au:assertFileExists file="${testReportXmlEncoding.destfile}"/> + <loadfile property="testReportXmlEncoding.content" srcfile="${testReportXmlEncoding.destfile}" encoding="UTF-16"/> + <au:assertTrue message="Encoding not set in ${testReportXmlEncoding.content}"> + <contains string="${testReportXmlEncoding.content}" substring="encoding="UTF-16""/> + </au:assertTrue> + </target> + + </project>
\ No newline at end of file diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/TestTarget.java b/org.jacoco.ant.test/src/org/jacoco/ant/TestTarget.java index 8b2f5404..b27ae95c 100644 --- a/org.jacoco.ant.test/src/org/jacoco/ant/TestTarget.java +++ b/org.jacoco.ant.test/src/org/jacoco/ant/TestTarget.java @@ -1,61 +1,61 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-
-import org.junit.Test;
-
-/**
- * Simple test target for Java applications ant JUnit4 tests. To assert
- * execution it creates an empty file <code>target.txt</code> in the working
- * directory.
- */
-public class TestTarget {
-
- @Test
- public void testNothing() throws IOException {
- System.out.println("Target executed");
- }
-
- public static void main(String[] args) throws Exception {
- System.out.println("Target executed");
-
- // Wait for termination file to turn up
- // This option puts the target in a pseudo 'server' mode
- if (args.length == 1) {
- final File termFile = new File(args[0]);
-
- while (!termFile.exists()) {
- Thread.sleep(100);
- }
- }
- }
-
- /**
- * @return location where this class is located
- */
- public static String getClassPath() {
- final String name = TestTarget.class.getName();
- final String res = "/" + name.replace('.', '/') + ".class";
- String loc = TestTarget.class.getResource(res).getFile();
- try {
- loc = URLDecoder.decode(loc, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- }
- return loc.substring(0, loc.length() - res.length());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.ant; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + +import org.junit.Test; + +/** + * Simple test target for Java applications ant JUnit4 tests. To assert + * execution it creates an empty file <code>target.txt</code> in the working + * directory. + */ +public class TestTarget { + + @Test + public void testNothing() throws IOException { + System.out.println("Target executed"); + } + + public static void main(String[] args) throws Exception { + System.out.println("Target executed"); + + // Wait for termination file to turn up + // This option puts the target in a pseudo 'server' mode + if (args.length == 1) { + final File termFile = new File(args[0]); + + while (!termFile.exists()) { + Thread.sleep(100); + } + } + } + + /** + * @return location where this class is located + */ + public static String getClassPath() { + final String name = TestTarget.class.getName(); + final String res = "/" + name.replace('.', '/') + ".class"; + String loc = TestTarget.class.getResource(res).getFile(); + try { + loc = URLDecoder.decode(loc, "UTF-8"); + } catch (UnsupportedEncodingException e) { + } + return loc.substring(0, loc.length() - res.length()); + } + +} diff --git a/org.jacoco.ant/src/org/jacoco/ant/AbstractCoverageTask.java b/org.jacoco.ant/src/org/jacoco/ant/AbstractCoverageTask.java index 6c8d37c2..c9bd0f7d 100644 --- a/org.jacoco.ant/src/org/jacoco/ant/AbstractCoverageTask.java +++ b/org.jacoco.ant/src/org/jacoco/ant/AbstractCoverageTask.java @@ -1,215 +1,215 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.jacoco.agent.AgentJar;
-import org.jacoco.core.runtime.AgentOptions;
-
-/**
- * Base class for all coverage tasks that require agent options
- */
-public class AbstractCoverageTask extends Task {
-
- private final AgentOptions agentOptions;
-
- private boolean enabled;
-
- /**
- * Create default agent options
- */
- protected AbstractCoverageTask() {
- super();
- agentOptions = new AgentOptions();
- enabled = true;
- }
-
- /**
- * @return Whether or not the current task is enabled
- */
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * Sets whether or not the current task is enabled
- *
- * @param enabled
- * Enablement state of the task
- */
- public void setEnabled(final boolean enabled) {
- this.enabled = enabled;
- }
-
- /**
- * Gets the currently configured agent options for this task
- *
- * @return Configured agent options
- */
- public AgentOptions getAgentOptions() {
- return agentOptions;
- }
-
- /**
- * Sets the location to write coverage execution data. Default is current
- * working directory
- *
- * @param file
- * Location to write coverage execution data
- */
- public void setDestfile(final File file) {
- agentOptions.setDestfile(file.getAbsolutePath());
- }
-
- /**
- * Append execution coverage data if a coverage file is already present.
- * Default is <code>true</code>
- *
- * @param append
- * <code>true</code> to append execution data to an existing file
- */
- public void setAppend(final boolean append) {
- agentOptions.setAppend(append);
- }
-
- /**
- * List of wildcard patterns classes to include for instrumentation. Default
- * is <code>*</code>
- *
- * @param includes
- * Wildcard pattern of included classes
- */
- public void setIncludes(final String includes) {
- agentOptions.setIncludes(includes);
- }
-
- /**
- * List of wildcard patterns classes to exclude from instrumentation.
- * Default is the empty string, no classes excluded
- *
- * @param excludes
- * Wildcard pattern of excluded classes
- */
- public void setExcludes(final String excludes) {
- agentOptions.setExcludes(excludes);
- }
-
- /**
- * List of wildcard patterns for classloaders that JaCoCo will not
- * instrument classes from. Default is
- * <code>sun.reflect.DelegatingClassLoader</code>
- *
- * @param exclClassLoader
- * Wildcard pattern of class loaders to exclude
- */
- public void setExclClassLoader(final String exclClassLoader) {
- agentOptions.setExclClassloader(exclClassLoader);
- }
-
- /**
- * Sets the session identifier. Default is a auto-generated id
- *
- * @param id
- * session identifier
- */
- public void setSessionId(final String id) {
- agentOptions.setSessionId(id);
- }
-
- /**
- * Dump coverage data on VM termination. Default is <code>true</code>
- *
- * @param dumpOnExit
- * <code>true</code> to write coverage data on VM termination
- */
- public void setDumpOnExit(final boolean dumpOnExit) {
- agentOptions.setDumpOnExit(dumpOnExit);
- }
-
- /**
- * Sets the output method. Default is <code>file</code>
- *
- * @param output
- * Output method
- */
- public void setOutput(final String output) {
- agentOptions.setOutput(output);
- }
-
- /**
- * Sets the IP address or hostname to bind to when output method is tcp
- * server or connect to when the output method is tcp client. Default is
- * <code>localhost</code>
- *
- * @param address
- * Address to bind or connect to
- */
- public void setAddress(final String address) {
- agentOptions.setAddress(address);
- }
-
- /**
- * Sets the Port to bind to when the output method is tcp server or connect
- * to when the output method is tcp client. Default is <code>6300</code>
- *
- * @param port
- */
- public void setPort(final int port) {
- agentOptions.setPort(port);
- }
-
- /**
- * Sets the directory where all class files seen by the agent should be
- * dumped to.
- *
- * @param dir
- * dump output location
- */
- public void setClassdumpdir(final File dir) {
- agentOptions.setClassDumpDir(dir.getAbsolutePath());
- }
-
- /**
- * Creates JVM argument to launch with the specified JaCoCo agent jar and
- * the current options
- *
- * @return JVM Argument to pass to new VM
- */
- protected String getLaunchingArgument() {
- return getAgentOptions().getVMArgument(getAgentFile());
- }
-
- private File getAgentFile() {
- try {
- File agentFile = null;
- final String agentFileLocation = getProject().getProperty(
- "_jacoco.agentFile");
- if (agentFileLocation != null) {
- agentFile = new File(agentFileLocation);
- } else {
- agentFile = AgentJar.extractToTempLocation();
- getProject().setProperty("_jacoco.agentFile",
- agentFile.toString());
- }
-
- return agentFile;
- } catch (final IOException e) {
- throw new BuildException("Unable to extract agent jar", e,
- getLocation());
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import java.io.File; +import java.io.IOException; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.jacoco.agent.AgentJar; +import org.jacoco.core.runtime.AgentOptions; + +/** + * Base class for all coverage tasks that require agent options + */ +public class AbstractCoverageTask extends Task { + + private final AgentOptions agentOptions; + + private boolean enabled; + + /** + * Create default agent options + */ + protected AbstractCoverageTask() { + super(); + agentOptions = new AgentOptions(); + enabled = true; + } + + /** + * @return Whether or not the current task is enabled + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Sets whether or not the current task is enabled + * + * @param enabled + * Enablement state of the task + */ + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } + + /** + * Gets the currently configured agent options for this task + * + * @return Configured agent options + */ + public AgentOptions getAgentOptions() { + return agentOptions; + } + + /** + * Sets the location to write coverage execution data. Default is current + * working directory + * + * @param file + * Location to write coverage execution data + */ + public void setDestfile(final File file) { + agentOptions.setDestfile(file.getAbsolutePath()); + } + + /** + * Append execution coverage data if a coverage file is already present. + * Default is <code>true</code> + * + * @param append + * <code>true</code> to append execution data to an existing file + */ + public void setAppend(final boolean append) { + agentOptions.setAppend(append); + } + + /** + * List of wildcard patterns classes to include for instrumentation. Default + * is <code>*</code> + * + * @param includes + * Wildcard pattern of included classes + */ + public void setIncludes(final String includes) { + agentOptions.setIncludes(includes); + } + + /** + * List of wildcard patterns classes to exclude from instrumentation. + * Default is the empty string, no classes excluded + * + * @param excludes + * Wildcard pattern of excluded classes + */ + public void setExcludes(final String excludes) { + agentOptions.setExcludes(excludes); + } + + /** + * List of wildcard patterns for classloaders that JaCoCo will not + * instrument classes from. Default is + * <code>sun.reflect.DelegatingClassLoader</code> + * + * @param exclClassLoader + * Wildcard pattern of class loaders to exclude + */ + public void setExclClassLoader(final String exclClassLoader) { + agentOptions.setExclClassloader(exclClassLoader); + } + + /** + * Sets the session identifier. Default is a auto-generated id + * + * @param id + * session identifier + */ + public void setSessionId(final String id) { + agentOptions.setSessionId(id); + } + + /** + * Dump coverage data on VM termination. Default is <code>true</code> + * + * @param dumpOnExit + * <code>true</code> to write coverage data on VM termination + */ + public void setDumpOnExit(final boolean dumpOnExit) { + agentOptions.setDumpOnExit(dumpOnExit); + } + + /** + * Sets the output method. Default is <code>file</code> + * + * @param output + * Output method + */ + public void setOutput(final String output) { + agentOptions.setOutput(output); + } + + /** + * Sets the IP address or hostname to bind to when output method is tcp + * server or connect to when the output method is tcp client. Default is + * <code>localhost</code> + * + * @param address + * Address to bind or connect to + */ + public void setAddress(final String address) { + agentOptions.setAddress(address); + } + + /** + * Sets the Port to bind to when the output method is tcp server or connect + * to when the output method is tcp client. Default is <code>6300</code> + * + * @param port + */ + public void setPort(final int port) { + agentOptions.setPort(port); + } + + /** + * Sets the directory where all class files seen by the agent should be + * dumped to. + * + * @param dir + * dump output location + */ + public void setClassdumpdir(final File dir) { + agentOptions.setClassDumpDir(dir.getAbsolutePath()); + } + + /** + * Creates JVM argument to launch with the specified JaCoCo agent jar and + * the current options + * + * @return JVM Argument to pass to new VM + */ + protected String getLaunchingArgument() { + return getAgentOptions().getVMArgument(getAgentFile()); + } + + private File getAgentFile() { + try { + File agentFile = null; + final String agentFileLocation = getProject().getProperty( + "_jacoco.agentFile"); + if (agentFileLocation != null) { + agentFile = new File(agentFileLocation); + } else { + agentFile = AgentJar.extractToTempLocation(); + getProject().setProperty("_jacoco.agentFile", + agentFile.toString()); + } + + return agentFile; + } catch (final IOException e) { + throw new BuildException("Unable to extract agent jar", e, + getLocation()); + } + } + +} diff --git a/org.jacoco.ant/src/org/jacoco/ant/AgentTask.java b/org.jacoco.ant/src/org/jacoco/ant/AgentTask.java index ed846f47..43190ac2 100644 --- a/org.jacoco.ant/src/org/jacoco/ant/AgentTask.java +++ b/org.jacoco.ant/src/org/jacoco/ant/AgentTask.java @@ -1,49 +1,49 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import org.apache.tools.ant.BuildException;
-
-/**
- * Ant task that will unpack the coverage agent jar and generate the JVM options
- * required to use it
- */
-public class AgentTask extends AbstractCoverageTask {
-
- private String property;
-
- /**
- * Sets the name of the property to hold the agent JVM options
- *
- * @param property
- * Name of the property to be populated
- */
- public void setProperty(final String property) {
- this.property = property;
- }
-
- /**
- * Unpacks a private copy of the JaCoCo agent and populates
- * <code>property</code> with the JVM arguments required to use it. The
- * value set into the property is only valid for the lifetime of the current
- * JVM. The agent jar will be removed on termination of the JVM.
- */
- @Override
- public void execute() throws BuildException {
- if (property == null || property.length() == 0) {
- throw new BuildException("Property is mandatory", getLocation());
- }
- final String jvmArg = isEnabled() ? getLaunchingArgument() : "";
-
- getProject().setNewProperty(property, jvmArg);
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import org.apache.tools.ant.BuildException; + +/** + * Ant task that will unpack the coverage agent jar and generate the JVM options + * required to use it + */ +public class AgentTask extends AbstractCoverageTask { + + private String property; + + /** + * Sets the name of the property to hold the agent JVM options + * + * @param property + * Name of the property to be populated + */ + public void setProperty(final String property) { + this.property = property; + } + + /** + * Unpacks a private copy of the JaCoCo agent and populates + * <code>property</code> with the JVM arguments required to use it. The + * value set into the property is only valid for the lifetime of the current + * JVM. The agent jar will be removed on termination of the JVM. + */ + @Override + public void execute() throws BuildException { + if (property == null || property.length() == 0) { + throw new BuildException("Property is mandatory", getLocation()); + } + final String jvmArg = isEnabled() ? getLaunchingArgument() : ""; + + getProject().setNewProperty(property, jvmArg); + } +} diff --git a/org.jacoco.ant/src/org/jacoco/ant/CoverageTask.java b/org.jacoco.ant/src/org/jacoco/ant/CoverageTask.java index 58d713ee..8aeee8f7 100644 --- a/org.jacoco.ant/src/org/jacoco/ant/CoverageTask.java +++ b/org.jacoco.ant/src/org/jacoco/ant/CoverageTask.java @@ -1,197 +1,197 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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 - TestNG support
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import static java.lang.String.format;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.RuntimeConfigurable;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.TaskContainer;
-import org.apache.tools.ant.UnknownElement;
-
-/**
- * Container task to run Java/JUnit tasks with the JaCoCo agent jar. Coverage
- * will only be applied if all of the following are true:
- * <ul>
- * <li>Exactly one sub task may be present</li>
- * <li>Task must be either Java or JUnit</li>
- * <li>Task must be using a forked VM (so vm args can be passed)</li>
- * </ul>
- */
-public class CoverageTask extends AbstractCoverageTask implements TaskContainer {
-
- private final Collection<TaskEnhancer> taskEnhancers = new ArrayList<TaskEnhancer>();
- private Task childTask;
-
- /**
- * Creates a new default coverage task
- */
- public CoverageTask() {
- super();
- taskEnhancers.add(new JavaLikeTaskEnhancer("java"));
- taskEnhancers.add(new JavaLikeTaskEnhancer("junit"));
- taskEnhancers.add(new TestNGTaskEnhancer("testng"));
- }
-
- /**
- * Add child task to this container and reconfigure it to run with coverage
- * enabled
- */
- public void addTask(final Task task) {
- if (childTask != null) {
- throw new BuildException(
- "Only one child task can be supplied to the coverge task",
- getLocation());
- }
-
- this.childTask = task;
-
- final String subTaskTypeName = task.getTaskType();
-
- final TaskEnhancer enhancer = findEnhancerForTask(subTaskTypeName);
- if (enhancer == null) {
- throw new BuildException(format(
- "%s is not a valid child of the coverage task",
- subTaskTypeName), getLocation());
- }
-
- if (isEnabled()) {
- log(format("Enhancing %s with coverage", childTask.getTaskName()));
- enhancer.enhanceTask(task);
- }
-
- task.maybeConfigure();
- }
-
- private TaskEnhancer findEnhancerForTask(final String taskName) {
- for (final TaskEnhancer enhancer : taskEnhancers) {
- if (enhancer.supportsTask(taskName)) {
- return enhancer;
- }
- }
-
- return null;
- }
-
- /**
- * Executes subtask and performs any required cleanup
- */
- @Override
- public void execute() throws BuildException {
- if (childTask == null) {
- throw new BuildException(
- "A child task must be supplied for the coverage task",
- getLocation());
- }
-
- childTask.execute();
- }
-
- /**
- * Task enhancer for TestNG. TestNG task always run in a forked VM and has
- * nested jvmargs elements
- */
- private class TestNGTaskEnhancer extends JavaLikeTaskEnhancer {
-
- public TestNGTaskEnhancer(final String supportedTaskName) {
- super(supportedTaskName);
- }
-
- @Override
- public void enhanceTask(final Task task) {
- addJvmArgs(task);
- }
-
- }
-
- /**
- * Basic task enhancer that can handle all 'java like' tasks. That is, tasks
- * that have a top level fork attribute and nested jvmargs elements
- */
- private class JavaLikeTaskEnhancer implements TaskEnhancer {
-
- private final String supportedTaskName;
-
- public JavaLikeTaskEnhancer(final String supportedTaskName) {
- this.supportedTaskName = supportedTaskName;
- }
-
- public boolean supportsTask(final String taskname) {
- return taskname.equals(supportedTaskName);
- }
-
- public void enhanceTask(final Task task) {
- final RuntimeConfigurable configurableWrapper = task
- .getRuntimeConfigurableWrapper();
-
- final String forkValue = getProject().replaceProperties(
- (String) configurableWrapper.getAttributeMap().get("fork"));
-
- if (!Project.toBoolean(forkValue)) {
- throw new BuildException(
- "Coverage can only be applied on a forked VM",
- getLocation());
- }
-
- addJvmArgs(task);
- }
-
- public void addJvmArgs(final Task task) {
- final UnknownElement el = new UnknownElement("jvmarg");
- el.setTaskName("jvmarg");
- el.setQName("jvmarg");
-
- final RuntimeConfigurable runtimeConfigurableWrapper = el
- .getRuntimeConfigurableWrapper();
- runtimeConfigurableWrapper.setAttribute("value",
- getLaunchingArgument());
-
- task.getRuntimeConfigurableWrapper().addChild(
- runtimeConfigurableWrapper);
-
- ((UnknownElement) task).addChild(el);
- }
- }
-
- /**
- * The task enhancer is responsible for potentially reconfiguring a task to
- * support running with code coverage enabled
- */
- private interface TaskEnhancer {
- /**
- * @param taskname
- * Task type to enhance
- * @return <code>true</code> if this enhancer is capable of enhancing
- * the requested task type
- */
- public boolean supportsTask(String taskname);
-
- /**
- * Attempt to enhance the supplied task with coverage information. This
- * operation may fail if the task is being executed in the current VM
- *
- * @param task
- * Task instance to enhance (usually an
- * {@link UnknownElement})
- * @throws BuildException
- * Thrown if this enhancer can handle this type of task, but
- * this instance can not be enhanced for some reason.
- */
- public void enhanceTask(Task task) throws BuildException;
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 - TestNG support + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import static java.lang.String.format; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.RuntimeConfigurable; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.TaskContainer; +import org.apache.tools.ant.UnknownElement; + +/** + * Container task to run Java/JUnit tasks with the JaCoCo agent jar. Coverage + * will only be applied if all of the following are true: + * <ul> + * <li>Exactly one sub task may be present</li> + * <li>Task must be either Java or JUnit</li> + * <li>Task must be using a forked VM (so vm args can be passed)</li> + * </ul> + */ +public class CoverageTask extends AbstractCoverageTask implements TaskContainer { + + private final Collection<TaskEnhancer> taskEnhancers = new ArrayList<TaskEnhancer>(); + private Task childTask; + + /** + * Creates a new default coverage task + */ + public CoverageTask() { + super(); + taskEnhancers.add(new JavaLikeTaskEnhancer("java")); + taskEnhancers.add(new JavaLikeTaskEnhancer("junit")); + taskEnhancers.add(new TestNGTaskEnhancer("testng")); + } + + /** + * Add child task to this container and reconfigure it to run with coverage + * enabled + */ + public void addTask(final Task task) { + if (childTask != null) { + throw new BuildException( + "Only one child task can be supplied to the coverge task", + getLocation()); + } + + this.childTask = task; + + final String subTaskTypeName = task.getTaskType(); + + final TaskEnhancer enhancer = findEnhancerForTask(subTaskTypeName); + if (enhancer == null) { + throw new BuildException(format( + "%s is not a valid child of the coverage task", + subTaskTypeName), getLocation()); + } + + if (isEnabled()) { + log(format("Enhancing %s with coverage", childTask.getTaskName())); + enhancer.enhanceTask(task); + } + + task.maybeConfigure(); + } + + private TaskEnhancer findEnhancerForTask(final String taskName) { + for (final TaskEnhancer enhancer : taskEnhancers) { + if (enhancer.supportsTask(taskName)) { + return enhancer; + } + } + + return null; + } + + /** + * Executes subtask and performs any required cleanup + */ + @Override + public void execute() throws BuildException { + if (childTask == null) { + throw new BuildException( + "A child task must be supplied for the coverage task", + getLocation()); + } + + childTask.execute(); + } + + /** + * Task enhancer for TestNG. TestNG task always run in a forked VM and has + * nested jvmargs elements + */ + private class TestNGTaskEnhancer extends JavaLikeTaskEnhancer { + + public TestNGTaskEnhancer(final String supportedTaskName) { + super(supportedTaskName); + } + + @Override + public void enhanceTask(final Task task) { + addJvmArgs(task); + } + + } + + /** + * Basic task enhancer that can handle all 'java like' tasks. That is, tasks + * that have a top level fork attribute and nested jvmargs elements + */ + private class JavaLikeTaskEnhancer implements TaskEnhancer { + + private final String supportedTaskName; + + public JavaLikeTaskEnhancer(final String supportedTaskName) { + this.supportedTaskName = supportedTaskName; + } + + public boolean supportsTask(final String taskname) { + return taskname.equals(supportedTaskName); + } + + public void enhanceTask(final Task task) { + final RuntimeConfigurable configurableWrapper = task + .getRuntimeConfigurableWrapper(); + + final String forkValue = getProject().replaceProperties( + (String) configurableWrapper.getAttributeMap().get("fork")); + + if (!Project.toBoolean(forkValue)) { + throw new BuildException( + "Coverage can only be applied on a forked VM", + getLocation()); + } + + addJvmArgs(task); + } + + public void addJvmArgs(final Task task) { + final UnknownElement el = new UnknownElement("jvmarg"); + el.setTaskName("jvmarg"); + el.setQName("jvmarg"); + + final RuntimeConfigurable runtimeConfigurableWrapper = el + .getRuntimeConfigurableWrapper(); + runtimeConfigurableWrapper.setAttribute("value", + getLaunchingArgument()); + + task.getRuntimeConfigurableWrapper().addChild( + runtimeConfigurableWrapper); + + ((UnknownElement) task).addChild(el); + } + } + + /** + * The task enhancer is responsible for potentially reconfiguring a task to + * support running with code coverage enabled + */ + private interface TaskEnhancer { + /** + * @param taskname + * Task type to enhance + * @return <code>true</code> if this enhancer is capable of enhancing + * the requested task type + */ + public boolean supportsTask(String taskname); + + /** + * Attempt to enhance the supplied task with coverage information. This + * operation may fail if the task is being executed in the current VM + * + * @param task + * Task instance to enhance (usually an + * {@link UnknownElement}) + * @throws BuildException + * Thrown if this enhancer can handle this type of task, but + * this instance can not be enhanced for some reason. + */ + public void enhanceTask(Task task) throws BuildException; + } +} diff --git a/org.jacoco.ant/src/org/jacoco/ant/DumpTask.java b/org.jacoco.ant/src/org/jacoco/ant/DumpTask.java index c6beeeca..645403e7 100644 --- a/org.jacoco.ant/src/org/jacoco/ant/DumpTask.java +++ b/org.jacoco.ant/src/org/jacoco/ant/DumpTask.java @@ -1,176 +1,176 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import static java.lang.String.format;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.util.FileUtils;
-import org.jacoco.core.data.ExecutionDataWriter;
-import org.jacoco.core.runtime.AgentOptions;
-import org.jacoco.core.runtime.RemoteControlReader;
-import org.jacoco.core.runtime.RemoteControlWriter;
-
-/**
- * Ant task for remotely controlling an application that is running with the
- * tcpserver output mode
- */
-public class DumpTask extends Task {
-
- private static final OutputStream NUL = new OutputStream() {
- @Override
- public void write(final int b) throws IOException {
- // nothing to do
- }
- };
-
- private boolean dump = true;
- private boolean reset = false;
- private File destfile = null;
- private String address = AgentOptions.DEFAULT_ADDRESS;
- private int port = AgentOptions.DEFAULT_PORT;
- private boolean append = true;
-
- /**
- * Sets the location of the execution data file to write. This parameter is
- * required when dump is <code>true</code>. Default is
- * <code>jacoco.exec</code>
- *
- * @param destfile
- * Location to write execution data to
- */
- public void setDestfile(final File destfile) {
- this.destfile = destfile;
- }
-
- /**
- * IP Address or hostname to connect to. Defaults to <code>localhost</code>
- *
- * @param address
- * IP Address or hostname to connect to
- */
- public void setAddress(final String address) {
- this.address = address;
- }
-
- /**
- * Port number to connect to. Default is <code>6300</code>
- *
- * @param port
- * Port to connect to
- */
- public void setPort(final int port) {
- this.port = port;
- }
-
- /**
- * <code>true</code> if the destination file it to be appended to.
- * <code>false</code> if the file is to be overwritten
- *
- * @param append
- * <code>true</code> if the destination file should be appended
- * to
- */
- public void setAppend(final boolean append) {
- this.append = append;
- }
-
- /**
- * Sets whether execution data should be downloaded from the remote host.
- * Defaults to <code>false</code>
- *
- * @param dump
- * <code>true</code> to download execution data
- */
- public void setDump(final boolean dump) {
- this.dump = dump;
- }
-
- /**
- * Sets whether a reset command should be sent after the execution data has
- * been copied. Defaults to <code>false</code>
- *
- * @param reset
- * <code>true</code> to reset execution data
- */
- public void setReset(final boolean reset) {
- this.reset = reset;
- }
-
- @Override
- public void execute() throws BuildException {
-
- if (port <= 0) {
- throw new BuildException("Invalid port value", getLocation());
- }
- if (dump && destfile == null) {
- throw new BuildException(
- "Destination file is required when dumping execution data",
- getLocation());
- }
-
- OutputStream output = null;
-
- try {
-
- // 1. Open socket connection
- final Socket socket = new Socket(InetAddress.getByName(address),
- port);
- log(format("Connecting to %s", socket.getRemoteSocketAddress()));
- final RemoteControlWriter remoteWriter = new RemoteControlWriter(
- socket.getOutputStream());
- final RemoteControlReader remoteReader = new RemoteControlReader(
- socket.getInputStream());
-
- // 2. Open file output
- output = openOutputStream();
- final ExecutionDataWriter outputWriter = new ExecutionDataWriter(
- output);
- remoteReader.setSessionInfoVisitor(outputWriter);
- remoteReader.setExecutionDataVisitor(outputWriter);
-
- // 3. Request dump
- remoteWriter.visitDumpCommand(dump, reset);
- remoteReader.read();
-
- socket.close();
-
- } catch (final IOException e) {
- throw new BuildException("Unable to dump coverage data", e,
- getLocation());
- } finally {
- FileUtils.close(output);
- }
- }
-
- private OutputStream openOutputStream() throws IOException {
- OutputStream output;
- if (dump) {
- log(format("Dumping execution data to %s",
- destfile.getAbsolutePath()));
- FileUtils.getFileUtils().createNewFile(destfile, true);
- output = new FileOutputStream(destfile, append);
- } else {
- output = NUL;
- }
- return output;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import static java.lang.String.format; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.FileUtils; +import org.jacoco.core.data.ExecutionDataWriter; +import org.jacoco.core.runtime.AgentOptions; +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; + +/** + * Ant task for remotely controlling an application that is running with the + * tcpserver output mode + */ +public class DumpTask extends Task { + + private static final OutputStream NUL = new OutputStream() { + @Override + public void write(final int b) throws IOException { + // nothing to do + } + }; + + private boolean dump = true; + private boolean reset = false; + private File destfile = null; + private String address = AgentOptions.DEFAULT_ADDRESS; + private int port = AgentOptions.DEFAULT_PORT; + private boolean append = true; + + /** + * Sets the location of the execution data file to write. This parameter is + * required when dump is <code>true</code>. Default is + * <code>jacoco.exec</code> + * + * @param destfile + * Location to write execution data to + */ + public void setDestfile(final File destfile) { + this.destfile = destfile; + } + + /** + * IP Address or hostname to connect to. Defaults to <code>localhost</code> + * + * @param address + * IP Address or hostname to connect to + */ + public void setAddress(final String address) { + this.address = address; + } + + /** + * Port number to connect to. Default is <code>6300</code> + * + * @param port + * Port to connect to + */ + public void setPort(final int port) { + this.port = port; + } + + /** + * <code>true</code> if the destination file it to be appended to. + * <code>false</code> if the file is to be overwritten + * + * @param append + * <code>true</code> if the destination file should be appended + * to + */ + public void setAppend(final boolean append) { + this.append = append; + } + + /** + * Sets whether execution data should be downloaded from the remote host. + * Defaults to <code>false</code> + * + * @param dump + * <code>true</code> to download execution data + */ + public void setDump(final boolean dump) { + this.dump = dump; + } + + /** + * Sets whether a reset command should be sent after the execution data has + * been copied. Defaults to <code>false</code> + * + * @param reset + * <code>true</code> to reset execution data + */ + public void setReset(final boolean reset) { + this.reset = reset; + } + + @Override + public void execute() throws BuildException { + + if (port <= 0) { + throw new BuildException("Invalid port value", getLocation()); + } + if (dump && destfile == null) { + throw new BuildException( + "Destination file is required when dumping execution data", + getLocation()); + } + + OutputStream output = null; + + try { + + // 1. Open socket connection + final Socket socket = new Socket(InetAddress.getByName(address), + port); + log(format("Connecting to %s", socket.getRemoteSocketAddress())); + final RemoteControlWriter remoteWriter = new RemoteControlWriter( + socket.getOutputStream()); + final RemoteControlReader remoteReader = new RemoteControlReader( + socket.getInputStream()); + + // 2. Open file output + output = openOutputStream(); + final ExecutionDataWriter outputWriter = new ExecutionDataWriter( + output); + remoteReader.setSessionInfoVisitor(outputWriter); + remoteReader.setExecutionDataVisitor(outputWriter); + + // 3. Request dump + remoteWriter.visitDumpCommand(dump, reset); + remoteReader.read(); + + socket.close(); + + } catch (final IOException e) { + throw new BuildException("Unable to dump coverage data", e, + getLocation()); + } finally { + FileUtils.close(output); + } + } + + private OutputStream openOutputStream() throws IOException { + OutputStream output; + if (dump) { + log(format("Dumping execution data to %s", + destfile.getAbsolutePath())); + FileUtils.getFileUtils().createNewFile(destfile, true); + output = new FileOutputStream(destfile, append); + } else { + output = NUL; + } + return output; + } + +} diff --git a/org.jacoco.ant/src/org/jacoco/ant/MergeTask.java b/org.jacoco.ant/src/org/jacoco/ant/MergeTask.java index 92f9b3e9..77dea180 100644 --- a/org.jacoco.ant/src/org/jacoco/ant/MergeTask.java +++ b/org.jacoco.ant/src/org/jacoco/ant/MergeTask.java @@ -1,124 +1,124 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import static java.lang.String.format;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Iterator;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.types.resources.Union;
-import org.apache.tools.ant.util.FileUtils;
-import org.jacoco.core.data.ExecutionDataReader;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.data.ExecutionDataWriter;
-import org.jacoco.core.data.SessionInfoStore;
-
-/**
- * Task for merging a set of execution data store files into a single file
- */
-public class MergeTask extends Task {
-
- private File destfile;
-
- private final Union files = new Union();
-
- /**
- * Sets the location of the merged data store
- *
- * @param destfile
- * Destination data store location
- */
- public void setDestfile(final File destfile) {
- this.destfile = destfile;
- }
-
- /**
- * This task accepts any number of execution data resources.
- *
- * @param resources
- * Execution data resources
- */
- public void addConfigured(final ResourceCollection resources) {
- files.add(resources);
- }
-
- @Override
- public void execute() throws BuildException {
- if (destfile == null) {
- throw new BuildException("Destination file must be supplied",
- getLocation());
- }
-
- final SessionInfoStore infoStore = new SessionInfoStore();
- final ExecutionDataStore dataStore = new ExecutionDataStore();
-
- loadSourceFiles(infoStore, dataStore);
-
- OutputStream outputStream = null;
- try {
- FileUtils.getFileUtils().createNewFile(destfile, true);
-
- outputStream = new BufferedOutputStream(new FileOutputStream(
- destfile));
- final ExecutionDataWriter dataWriter = new ExecutionDataWriter(
- outputStream);
- infoStore.accept(dataWriter);
- dataStore.accept(dataWriter);
- } catch (final IOException e) {
- throw new BuildException(format("Unable to write merged file %s",
- destfile.getAbsolutePath()), e, getLocation());
- } finally {
- FileUtils.close(outputStream);
- }
-
- }
-
- private void loadSourceFiles(final SessionInfoStore infoStore,
- final ExecutionDataStore dataStore) {
- final Iterator<?> resourceIterator = files.iterator();
- while (resourceIterator.hasNext()) {
- final Resource resource = (Resource) resourceIterator.next();
-
- if (resource.isDirectory()) {
- continue;
- }
-
- log(format("Loading execution data file %s", resource));
-
- InputStream resourceStream = null;
- try {
- resourceStream = resource.getInputStream();
- final ExecutionDataReader reader = new ExecutionDataReader(
- resourceStream);
- reader.setSessionInfoVisitor(infoStore);
- reader.setExecutionDataVisitor(dataStore);
- reader.read();
- } catch (final IOException e) {
- throw new BuildException(format("Unable to read %s", resource),
- e, getLocation());
- } finally {
- FileUtils.close(resourceStream);
- }
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.ant; + +import static java.lang.String.format; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Iterator; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Resource; +import org.apache.tools.ant.types.ResourceCollection; +import org.apache.tools.ant.types.resources.Union; +import org.apache.tools.ant.util.FileUtils; +import org.jacoco.core.data.ExecutionDataReader; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.ExecutionDataWriter; +import org.jacoco.core.data.SessionInfoStore; + +/** + * Task for merging a set of execution data store files into a single file + */ +public class MergeTask extends Task { + + private File destfile; + + private final Union files = new Union(); + + /** + * Sets the location of the merged data store + * + * @param destfile + * Destination data store location + */ + public void setDestfile(final File destfile) { + this.destfile = destfile; + } + + /** + * This task accepts any number of execution data resources. + * + * @param resources + * Execution data resources + */ + public void addConfigured(final ResourceCollection resources) { + files.add(resources); + } + + @Override + public void execute() throws BuildException { + if (destfile == null) { + throw new BuildException("Destination file must be supplied", + getLocation()); + } + + final SessionInfoStore infoStore = new SessionInfoStore(); + final ExecutionDataStore dataStore = new ExecutionDataStore(); + + loadSourceFiles(infoStore, dataStore); + + OutputStream outputStream = null; + try { + FileUtils.getFileUtils().createNewFile(destfile, true); + + outputStream = new BufferedOutputStream(new FileOutputStream( + destfile)); + final ExecutionDataWriter dataWriter = new ExecutionDataWriter( + outputStream); + infoStore.accept(dataWriter); + dataStore.accept(dataWriter); + } catch (final IOException e) { + throw new BuildException(format("Unable to write merged file %s", + destfile.getAbsolutePath()), e, getLocation()); + } finally { + FileUtils.close(outputStream); + } + + } + + private void loadSourceFiles(final SessionInfoStore infoStore, + final ExecutionDataStore dataStore) { + final Iterator<?> resourceIterator = files.iterator(); + while (resourceIterator.hasNext()) { + final Resource resource = (Resource) resourceIterator.next(); + + if (resource.isDirectory()) { + continue; + } + + log(format("Loading execution data file %s", resource)); + + InputStream resourceStream = null; + try { + resourceStream = resource.getInputStream(); + final ExecutionDataReader reader = new ExecutionDataReader( + resourceStream); + reader.setSessionInfoVisitor(infoStore); + reader.setExecutionDataVisitor(dataStore); + reader.read(); + } catch (final IOException e) { + throw new BuildException(format("Unable to read %s", resource), + e, getLocation()); + } finally { + FileUtils.close(resourceStream); + } + } + } + +} diff --git a/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java b/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java index c7593a47..dd458b21 100644 --- a/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java +++ b/org.jacoco.ant/src/org/jacoco/ant/ReportTask.java @@ -1,495 +1,495 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.ant;
-
-import static java.lang.String.format;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.resources.FileResource;
-import org.apache.tools.ant.types.resources.Union;
-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.ICoverageNode;
-import org.jacoco.core.data.ExecutionDataReader;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.data.SessionInfoStore;
-import org.jacoco.report.FileMultiReportOutput;
-import org.jacoco.report.IMultiReportOutput;
-import org.jacoco.report.IReportGroupVisitor;
-import org.jacoco.report.IReportVisitor;
-import org.jacoco.report.MultiReportVisitor;
-import org.jacoco.report.ZipMultiReportOutput;
-import org.jacoco.report.csv.CSVFormatter;
-import org.jacoco.report.html.HTMLFormatter;
-import org.jacoco.report.xml.XMLFormatter;
-
-/**
- * Task for coverage report generation. Experimental implementation that needs
- * refinement.
- */
-public class ReportTask extends Task {
-
- /**
- * The source files are specified in a resource collection with additional
- * attributes.
- */
- public static class SourceFilesElement extends Union {
-
- String encoding = null;
-
- int tabWidth = 4;
-
- /**
- * Defines the optional source file encoding. If not set the platform
- * default is used.
- *
- * @param encoding
- * source file encoding
- */
- public void setEncoding(final String encoding) {
- this.encoding = encoding;
- }
-
- /**
- * Sets the tab stop width for the source pages. Default value is 4.
- *
- * @param tabWidth
- * number of characters per tab stop
- */
- public void setTabwidth(final int tabWidth) {
- if (tabWidth <= 0) {
- throw new BuildException("Tab width must be greater than 0");
- }
- this.tabWidth = tabWidth;
- }
-
- }
-
- /**
- * Container element for class file groups.
- */
- public static class GroupElement {
-
- private final List<GroupElement> children = new ArrayList<GroupElement>();
-
- private final Union classfiles = new Union();
-
- private final SourceFilesElement sourcefiles = new SourceFilesElement();
-
- private String name;
-
- /**
- * Sets the name of the group.
- *
- * @param name
- * name of the group
- */
- public void setName(final String name) {
- this.name = name;
- }
-
- /**
- * Creates a new child group.
- *
- * @return new child group
- */
- public GroupElement createGroup() {
- final GroupElement group = new GroupElement();
- children.add(group);
- return group;
- }
-
- /**
- * Returns the nested resource collection for class files.
- *
- * @return resource collection for class files
- */
- public Union createClassfiles() {
- return classfiles;
- }
-
- /**
- * Returns the nested resource collection for source files.
- *
- * @return resource collection for source files
- */
- public SourceFilesElement createSourcefiles() {
- return sourcefiles;
- }
-
- }
-
- /**
- * Interface for child elements that define formatters.
- */
- private interface IFormatterElement {
-
- IReportVisitor createVisitor() throws IOException;
-
- }
-
- /**
- * Formatter Element for HTML reports.
- */
- public class HTMLFormatterElement implements IFormatterElement {
-
- private File destdir;
-
- private File destfile;
-
- private String footer = "";
-
- private String encoding = "UTF-8";
-
- private Locale locale = Locale.getDefault();
-
- /**
- * Sets the output directory for the report.
- *
- * @param destdir
- * output directory
- */
- public void setDestdir(final File destdir) {
- this.destdir = destdir;
- }
-
- /**
- * Sets the Zip output file for the report.
- *
- * @param destfile
- * Zip output file
- */
- public void setDestfile(final File destfile) {
- this.destfile = destfile;
- }
-
- /**
- * Sets an optional footer text that will be displayed on every report
- * page.
- *
- * @param text
- * footer text
- */
- public void setFooter(final String text) {
- this.footer = text;
- }
-
- /**
- * Sets the output encoding for generated HTML files. Default is UTF-8.
- *
- * @param encoding
- * output encoding
- */
- public void setEncoding(final String encoding) {
- this.encoding = encoding;
- }
-
- /**
- * Sets the locale for generated text output. By default the platform
- * locale is used.
- *
- * @param locale
- * text locale
- */
- public void setLocale(final Locale locale) {
- this.locale = locale;
- }
-
- public IReportVisitor createVisitor() throws IOException {
- final IMultiReportOutput output;
- if (destfile != null) {
- if (destdir != null) {
- throw new BuildException(
- "Either destination directory or file must be supplied, not both",
- getLocation());
- }
- final FileOutputStream stream = new FileOutputStream(destfile);
- output = new ZipMultiReportOutput(stream);
-
- } else {
- if (destdir == null) {
- throw new BuildException(
- "Destination directory or file must be supplied for html report",
- getLocation());
- }
- output = new FileMultiReportOutput(destdir);
- }
- final HTMLFormatter formatter = new HTMLFormatter();
- formatter.setFooterText(footer);
- formatter.setOutputEncoding(encoding);
- formatter.setLocale(locale);
- return formatter.createVisitor(output);
- }
-
- }
-
- /**
- * Formatter Element for CSV reports.
- */
- public class CSVFormatterElement implements IFormatterElement {
-
- private File destfile;
-
- private String encoding = "UTF-8";
-
- /**
- * Sets the output file for the report.
- *
- * @param destfile
- * output file
- */
- public void setDestfile(final File destfile) {
- this.destfile = destfile;
- }
-
- public IReportVisitor createVisitor() throws IOException {
- if (destfile == null) {
- throw new BuildException(
- "Destination file must be supplied for csv report",
- getLocation());
- }
- final CSVFormatter formatter = new CSVFormatter();
- formatter.setOutputEncoding(encoding);
- return formatter.createVisitor(new FileOutputStream(destfile));
- }
-
- /**
- * Sets the output encoding for generated XML file. Default is UTF-8.
- *
- * @param encoding
- * output encoding
- */
- public void setEncoding(final String encoding) {
- this.encoding = encoding;
- }
-
- }
-
- /**
- * Formatter Element for XML reports.
- */
- public class XMLFormatterElement implements IFormatterElement {
-
- private File destfile;
-
- private String encoding = "UTF-8";
-
- /**
- * Sets the output file for the report.
- *
- * @param destfile
- * output file
- */
- public void setDestfile(final File destfile) {
- this.destfile = destfile;
- }
-
- /**
- * Sets the output encoding for generated XML file. Default is UTF-8.
- *
- * @param encoding
- * output encoding
- */
- public void setEncoding(final String encoding) {
- this.encoding = encoding;
- }
-
- public IReportVisitor createVisitor() throws IOException {
- if (destfile == null) {
- throw new BuildException(
- "Destination file must be supplied for xml report",
- getLocation());
- }
- final XMLFormatter formatter = new XMLFormatter();
- formatter.setOutputEncoding(encoding);
- return formatter.createVisitor(new FileOutputStream(destfile));
- }
-
- }
-
- private final Union executiondataElement = new Union();
-
- private SessionInfoStore sessionInfoStore;
-
- private ExecutionDataStore executionDataStore;
-
- private final GroupElement structure = new GroupElement();
-
- private final List<IFormatterElement> formatters = new ArrayList<IFormatterElement>();
-
- /**
- * Returns the nested resource collection for execution data files.
- *
- * @return resource collection for execution files
- */
- public Union createExecutiondata() {
- return executiondataElement;
- }
-
- /**
- * Returns the root group element that defines the report structure.
- *
- * @return root group element
- */
- public GroupElement createStructure() {
- return structure;
- }
-
- /**
- * Creates a new HTML report element.
- *
- * @return HTML report element
- */
- public HTMLFormatterElement createHtml() {
- final HTMLFormatterElement element = new HTMLFormatterElement();
- formatters.add(element);
- return element;
- }
-
- /**
- * Creates a new CSV report element.
- *
- * @return CSV report element
- */
- public CSVFormatterElement createCsv() {
- final CSVFormatterElement element = new CSVFormatterElement();
- formatters.add(element);
- return element;
- }
-
- /**
- * Creates a new XML report element.
- *
- * @return CSV report element
- */
- public XMLFormatterElement createXml() {
- final XMLFormatterElement element = new XMLFormatterElement();
- formatters.add(element);
- return element;
- }
-
- @Override
- public void execute() throws BuildException {
- loadExecutionData();
- try {
- final IReportVisitor visitor = createVisitor();
- visitor.visitInfo(sessionInfoStore.getInfos(),
- executionDataStore.getContents());
- createReport(visitor, structure);
- visitor.visitEnd();
- } catch (final IOException e) {
- throw new BuildException("Error while creating report", e,
- getLocation());
- }
- }
-
- private void loadExecutionData() {
- sessionInfoStore = new SessionInfoStore();
- executionDataStore = new ExecutionDataStore();
- for (final Iterator<?> i = executiondataElement.iterator(); i.hasNext();) {
- final Resource resource = (Resource) i.next();
- log(format("Loading execution data file %s", resource));
- InputStream in = null;
- try {
- in = new BufferedInputStream(resource.getInputStream());
- final ExecutionDataReader reader = new ExecutionDataReader(in);
- reader.setSessionInfoVisitor(sessionInfoStore);
- reader.setExecutionDataVisitor(executionDataStore);
- reader.read();
- } catch (final IOException e) {
- throw new BuildException(format(
- "Unable to read execution data file %s", resource), e,
- getLocation());
- } finally {
- FileUtils.close(in);
- }
- }
- }
-
- private IReportVisitor createVisitor() throws IOException {
- final List<IReportVisitor> visitors = new ArrayList<IReportVisitor>();
- for (final IFormatterElement f : formatters) {
- visitors.add(f.createVisitor());
- }
- return new MultiReportVisitor(visitors);
- }
-
- private void createReport(final IReportGroupVisitor visitor,
- final GroupElement group) throws IOException {
- if (group.name == null) {
- throw new BuildException("Group name must be supplied",
- getLocation());
- }
- if (group.children.size() > 0) {
- final IReportGroupVisitor groupVisitor = visitor
- .visitGroup(group.name);
- for (final GroupElement child : group.children) {
- createReport(groupVisitor, child);
- }
- } 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);
- locator.addAll(sourcefiles.iterator());
- if (!locator.isEmpty()) {
- checkForMissingDebugInformation(bundle);
- }
- visitor.visitBundle(bundle, locator);
- }
- }
-
- private IBundleCoverage createBundle(final GroupElement group)
- throws IOException {
- final CoverageBuilder builder = new CoverageBuilder();
- final Analyzer analyzer = new Analyzer(executionDataStore, builder);
- for (final Iterator<?> i = group.classfiles.iterator(); i.hasNext();) {
- final Resource resource = (Resource) i.next();
- if (resource.isDirectory() && resource instanceof FileResource) {
- analyzer.analyzeAll(((FileResource) resource).getFile());
- } else {
- final InputStream in = resource.getInputStream();
- analyzer.analyzeAll(in);
- in.close();
- }
- }
- return builder.getBundle(group.name);
- }
-
- 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",
- node.getName()), Project.MSG_WARN);
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.ant; + +import static java.lang.String.format; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Resource; +import org.apache.tools.ant.types.resources.FileResource; +import org.apache.tools.ant.types.resources.Union; +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.ICoverageNode; +import org.jacoco.core.data.ExecutionDataReader; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.SessionInfoStore; +import org.jacoco.report.FileMultiReportOutput; +import org.jacoco.report.IMultiReportOutput; +import org.jacoco.report.IReportGroupVisitor; +import org.jacoco.report.IReportVisitor; +import org.jacoco.report.MultiReportVisitor; +import org.jacoco.report.ZipMultiReportOutput; +import org.jacoco.report.csv.CSVFormatter; +import org.jacoco.report.html.HTMLFormatter; +import org.jacoco.report.xml.XMLFormatter; + +/** + * Task for coverage report generation. Experimental implementation that needs + * refinement. + */ +public class ReportTask extends Task { + + /** + * The source files are specified in a resource collection with additional + * attributes. + */ + public static class SourceFilesElement extends Union { + + String encoding = null; + + int tabWidth = 4; + + /** + * Defines the optional source file encoding. If not set the platform + * default is used. + * + * @param encoding + * source file encoding + */ + public void setEncoding(final String encoding) { + this.encoding = encoding; + } + + /** + * Sets the tab stop width for the source pages. Default value is 4. + * + * @param tabWidth + * number of characters per tab stop + */ + public void setTabwidth(final int tabWidth) { + if (tabWidth <= 0) { + throw new BuildException("Tab width must be greater than 0"); + } + this.tabWidth = tabWidth; + } + + } + + /** + * Container element for class file groups. + */ + public static class GroupElement { + + private final List<GroupElement> children = new ArrayList<GroupElement>(); + + private final Union classfiles = new Union(); + + private final SourceFilesElement sourcefiles = new SourceFilesElement(); + + private String name; + + /** + * Sets the name of the group. + * + * @param name + * name of the group + */ + public void setName(final String name) { + this.name = name; + } + + /** + * Creates a new child group. + * + * @return new child group + */ + public GroupElement createGroup() { + final GroupElement group = new GroupElement(); + children.add(group); + return group; + } + + /** + * Returns the nested resource collection for class files. + * + * @return resource collection for class files + */ + public Union createClassfiles() { + return classfiles; + } + + /** + * Returns the nested resource collection for source files. + * + * @return resource collection for source files + */ + public SourceFilesElement createSourcefiles() { + return sourcefiles; + } + + } + + /** + * Interface for child elements that define formatters. + */ + private interface IFormatterElement { + + IReportVisitor createVisitor() throws IOException; + + } + + /** + * Formatter Element for HTML reports. + */ + public class HTMLFormatterElement implements IFormatterElement { + + private File destdir; + + private File destfile; + + private String footer = ""; + + private String encoding = "UTF-8"; + + private Locale locale = Locale.getDefault(); + + /** + * Sets the output directory for the report. + * + * @param destdir + * output directory + */ + public void setDestdir(final File destdir) { + this.destdir = destdir; + } + + /** + * Sets the Zip output file for the report. + * + * @param destfile + * Zip output file + */ + public void setDestfile(final File destfile) { + this.destfile = destfile; + } + + /** + * Sets an optional footer text that will be displayed on every report + * page. + * + * @param text + * footer text + */ + public void setFooter(final String text) { + this.footer = text; + } + + /** + * Sets the output encoding for generated HTML files. Default is UTF-8. + * + * @param encoding + * output encoding + */ + public void setEncoding(final String encoding) { + this.encoding = encoding; + } + + /** + * Sets the locale for generated text output. By default the platform + * locale is used. + * + * @param locale + * text locale + */ + public void setLocale(final Locale locale) { + this.locale = locale; + } + + public IReportVisitor createVisitor() throws IOException { + final IMultiReportOutput output; + if (destfile != null) { + if (destdir != null) { + throw new BuildException( + "Either destination directory or file must be supplied, not both", + getLocation()); + } + final FileOutputStream stream = new FileOutputStream(destfile); + output = new ZipMultiReportOutput(stream); + + } else { + if (destdir == null) { + throw new BuildException( + "Destination directory or file must be supplied for html report", + getLocation()); + } + output = new FileMultiReportOutput(destdir); + } + final HTMLFormatter formatter = new HTMLFormatter(); + formatter.setFooterText(footer); + formatter.setOutputEncoding(encoding); + formatter.setLocale(locale); + return formatter.createVisitor(output); + } + + } + + /** + * Formatter Element for CSV reports. + */ + public class CSVFormatterElement implements IFormatterElement { + + private File destfile; + + private String encoding = "UTF-8"; + + /** + * Sets the output file for the report. + * + * @param destfile + * output file + */ + public void setDestfile(final File destfile) { + this.destfile = destfile; + } + + public IReportVisitor createVisitor() throws IOException { + if (destfile == null) { + throw new BuildException( + "Destination file must be supplied for csv report", + getLocation()); + } + final CSVFormatter formatter = new CSVFormatter(); + formatter.setOutputEncoding(encoding); + return formatter.createVisitor(new FileOutputStream(destfile)); + } + + /** + * Sets the output encoding for generated XML file. Default is UTF-8. + * + * @param encoding + * output encoding + */ + public void setEncoding(final String encoding) { + this.encoding = encoding; + } + + } + + /** + * Formatter Element for XML reports. + */ + public class XMLFormatterElement implements IFormatterElement { + + private File destfile; + + private String encoding = "UTF-8"; + + /** + * Sets the output file for the report. + * + * @param destfile + * output file + */ + public void setDestfile(final File destfile) { + this.destfile = destfile; + } + + /** + * Sets the output encoding for generated XML file. Default is UTF-8. + * + * @param encoding + * output encoding + */ + public void setEncoding(final String encoding) { + this.encoding = encoding; + } + + public IReportVisitor createVisitor() throws IOException { + if (destfile == null) { + throw new BuildException( + "Destination file must be supplied for xml report", + getLocation()); + } + final XMLFormatter formatter = new XMLFormatter(); + formatter.setOutputEncoding(encoding); + return formatter.createVisitor(new FileOutputStream(destfile)); + } + + } + + private final Union executiondataElement = new Union(); + + private SessionInfoStore sessionInfoStore; + + private ExecutionDataStore executionDataStore; + + private final GroupElement structure = new GroupElement(); + + private final List<IFormatterElement> formatters = new ArrayList<IFormatterElement>(); + + /** + * Returns the nested resource collection for execution data files. + * + * @return resource collection for execution files + */ + public Union createExecutiondata() { + return executiondataElement; + } + + /** + * Returns the root group element that defines the report structure. + * + * @return root group element + */ + public GroupElement createStructure() { + return structure; + } + + /** + * Creates a new HTML report element. + * + * @return HTML report element + */ + public HTMLFormatterElement createHtml() { + final HTMLFormatterElement element = new HTMLFormatterElement(); + formatters.add(element); + return element; + } + + /** + * Creates a new CSV report element. + * + * @return CSV report element + */ + public CSVFormatterElement createCsv() { + final CSVFormatterElement element = new CSVFormatterElement(); + formatters.add(element); + return element; + } + + /** + * Creates a new XML report element. + * + * @return CSV report element + */ + public XMLFormatterElement createXml() { + final XMLFormatterElement element = new XMLFormatterElement(); + formatters.add(element); + return element; + } + + @Override + public void execute() throws BuildException { + loadExecutionData(); + try { + final IReportVisitor visitor = createVisitor(); + visitor.visitInfo(sessionInfoStore.getInfos(), + executionDataStore.getContents()); + createReport(visitor, structure); + visitor.visitEnd(); + } catch (final IOException e) { + throw new BuildException("Error while creating report", e, + getLocation()); + } + } + + private void loadExecutionData() { + sessionInfoStore = new SessionInfoStore(); + executionDataStore = new ExecutionDataStore(); + for (final Iterator<?> i = executiondataElement.iterator(); i.hasNext();) { + final Resource resource = (Resource) i.next(); + log(format("Loading execution data file %s", resource)); + InputStream in = null; + try { + in = new BufferedInputStream(resource.getInputStream()); + final ExecutionDataReader reader = new ExecutionDataReader(in); + reader.setSessionInfoVisitor(sessionInfoStore); + reader.setExecutionDataVisitor(executionDataStore); + reader.read(); + } catch (final IOException e) { + throw new BuildException(format( + "Unable to read execution data file %s", resource), e, + getLocation()); + } finally { + FileUtils.close(in); + } + } + } + + private IReportVisitor createVisitor() throws IOException { + final List<IReportVisitor> visitors = new ArrayList<IReportVisitor>(); + for (final IFormatterElement f : formatters) { + visitors.add(f.createVisitor()); + } + return new MultiReportVisitor(visitors); + } + + private void createReport(final IReportGroupVisitor visitor, + final GroupElement group) throws IOException { + if (group.name == null) { + throw new BuildException("Group name must be supplied", + getLocation()); + } + if (group.children.size() > 0) { + final IReportGroupVisitor groupVisitor = visitor + .visitGroup(group.name); + for (final GroupElement child : group.children) { + createReport(groupVisitor, child); + } + } 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); + locator.addAll(sourcefiles.iterator()); + if (!locator.isEmpty()) { + checkForMissingDebugInformation(bundle); + } + visitor.visitBundle(bundle, locator); + } + } + + private IBundleCoverage createBundle(final GroupElement group) + throws IOException { + final CoverageBuilder builder = new CoverageBuilder(); + final Analyzer analyzer = new Analyzer(executionDataStore, builder); + for (final Iterator<?> i = group.classfiles.iterator(); i.hasNext();) { + final Resource resource = (Resource) i.next(); + if (resource.isDirectory() && resource instanceof FileResource) { + analyzer.analyzeAll(((FileResource) resource).getFile()); + } else { + final InputStream in = resource.getInputStream(); + analyzer.analyzeAll(in); + in.close(); + } + } + return builder.getBundle(group.name); + } + + 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", + node.getName()), Project.MSG_WARN); + } + } + +} diff --git a/org.jacoco.ant/src/org/jacoco/ant/antlib.xml b/org.jacoco.ant/src/org/jacoco/ant/antlib.xml index 0516b019..a2d7acef 100644 --- a/org.jacoco.ant/src/org/jacoco/ant/antlib.xml +++ b/org.jacoco.ant/src/org/jacoco/ant/antlib.xml @@ -1,22 +1,22 @@ -<?xml version="1.0"?>
-
-<!--
- Copyright (c) 2009, 2012 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:
- Brock Janiczak - initial API and implementation
-
- $Id: $
--->
-
-<antlib>
- <taskdef name="coverage" classname="org.jacoco.ant.CoverageTask"/>
- <taskdef name="agent" classname="org.jacoco.ant.AgentTask"/>
- <taskdef name="report" classname="org.jacoco.ant.ReportTask"/>
- <taskdef name="merge" classname="org.jacoco.ant.MergeTask"/>
- <taskdef name="dump" classname="org.jacoco.ant.DumpTask"/>
+<?xml version="1.0"?> + +<!-- + Copyright (c) 2009, 2012 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: + Brock Janiczak - initial API and implementation + + $Id: $ +--> + +<antlib> + <taskdef name="coverage" classname="org.jacoco.ant.CoverageTask"/> + <taskdef name="agent" classname="org.jacoco.ant.AgentTask"/> + <taskdef name="report" classname="org.jacoco.ant.ReportTask"/> + <taskdef name="merge" classname="org.jacoco.ant.MergeTask"/> + <taskdef name="dump" classname="org.jacoco.ant.DumpTask"/> </antlib>
\ No newline at end of file diff --git a/org.jacoco.core.test/src/org/jacoco/core/JaCoCoTest.java b/org.jacoco.core.test/src/org/jacoco/core/JaCoCoTest.java index 52f90b8d..231e3433 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/JaCoCoTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/JaCoCoTest.java @@ -1,33 +1,33 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core;
-
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link JaCoCo}.
- */
-public class JaCoCoTest {
-
- @Test
- public void testVERSION() {
- assertNotNull(JaCoCo.VERSION);
- }
-
- @Test
- public void testHOMEURL() {
- assertNotNull(JaCoCo.HOMEURL);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +/** + * Unit tests for {@link JaCoCo}. + */ +public class JaCoCoTest { + + @Test + public void testVERSION() { + assertNotNull(JaCoCo.VERSION); + } + + @Test + public void testHOMEURL() { + assertNotNull(JaCoCo.HOMEURL); + } + +} 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 f33c0793..3a1ad2d8 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 @@ -1,174 +1,174 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.test.TargetLoader;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-/**
- * Unit tests for {@link Analyzer}.
- */
-public class AnalyzerTest {
-
- @Rule
- public TemporaryFolder folder = new TemporaryFolder();
-
- private Analyzer analyzer;
-
- private final Set<String> classes = new HashSet<String>();
-
- private class EmptyStructureVisitor implements ICoverageVisitor {
-
- public void visitCoverage(IClassCoverage coverage) {
- final String name = coverage.getName();
- assertTrue("Class already processed: " + name, classes.add(name));
- }
- }
-
- @Before
- public void setup() {
- analyzer = new Analyzer(new ExecutionDataStore(),
- new EmptyStructureVisitor());
- }
-
- @Test
- public void testAnalyzeClass1() throws IOException {
- analyzer.analyzeClass(TargetLoader.getClassData(AnalyzerTest.class));
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
- }
-
- @Test
- public void testAnalyzeClass2() throws IOException {
- analyzer.analyzeClass(TargetLoader
- .getClassDataAsBytes(AnalyzerTest.class));
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
- }
-
- @Test
- public void testAnalyzeArchive() throws IOException {
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- final ZipOutputStream zip = new ZipOutputStream(buffer);
- zip.putNextEntry(new ZipEntry(
- "org/jacoco/core/analysis/AnalyzerTest.class"));
- zip.write(TargetLoader.getClassDataAsBytes(AnalyzerTest.class));
- zip.finish();
- final int count = analyzer.analyzeArchive(new ByteArrayInputStream(
- buffer.toByteArray()));
- assertEquals(1, count);
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
- }
-
- @Test
- public void testAnalyzeAll1() throws IOException {
- final int count = analyzer.analyzeAll(TargetLoader
- .getClassData(AnalyzerTest.class));
- assertEquals(1, count);
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
- }
-
- @Test
- public void testAnalyzeAll2() throws IOException {
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- final ZipOutputStream zip = new ZipOutputStream(buffer);
- zip.putNextEntry(new ZipEntry(
- "org/jacoco/core/analysis/AnalyzerTest.class"));
- zip.write(TargetLoader.getClassDataAsBytes(AnalyzerTest.class));
- zip.finish();
- final int count = analyzer.analyzeAll(new ByteArrayInputStream(buffer
- .toByteArray()));
- assertEquals(1, count);
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
- }
-
- @Test
- public void testAnalyzeAll3() throws IOException {
- final int count = analyzer.analyzeAll(new ByteArrayInputStream(
- new byte[0]));
- assertEquals(0, count);
- assertEquals(Collections.emptySet(), classes);
- }
-
- @Test
- public void testAnalyzeAll4() throws IOException {
- createClassfile("bin1", AnalyzerTest.class);
- final int count = analyzer.analyzeAll(folder.getRoot());
- assertEquals(1, count);
- assertEquals(
- Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"),
- classes);
- }
-
- @Test
- public void testAnalyzeAll5() throws IOException {
- createClassfile("bin1", Analyzer.class);
- createClassfile("bin2", AnalyzerTest.class);
- 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);
- }
-
- @Test(expected = IOException.class)
- public void testAnalyzeAll6() throws IOException {
- File file = new File(folder.getRoot(), "broken.zip");
- OutputStream out = new FileOutputStream(file);
- ZipOutputStream zip = new ZipOutputStream(out);
- zip.putNextEntry(new ZipEntry("brokenentry.txt"));
- out.write(0x23); // Unexpected data here
- zip.close();
- analyzer.analyzeAll(file);
- }
-
- private void createClassfile(final String dir, final Class<?> source)
- throws IOException {
- File file = new File(folder.getRoot(), dir);
- file.mkdirs();
- file = new File(file, "some.class");
- OutputStream out = new FileOutputStream(file);
- out.write(TargetLoader.getClassDataAsBytes(source));
- out.close();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.test.TargetLoader; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +/** + * Unit tests for {@link Analyzer}. + */ +public class AnalyzerTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + private Analyzer analyzer; + + private final Set<String> classes = new HashSet<String>(); + + private class EmptyStructureVisitor implements ICoverageVisitor { + + public void visitCoverage(IClassCoverage coverage) { + final String name = coverage.getName(); + assertTrue("Class already processed: " + name, classes.add(name)); + } + } + + @Before + public void setup() { + analyzer = new Analyzer(new ExecutionDataStore(), + new EmptyStructureVisitor()); + } + + @Test + public void testAnalyzeClass1() throws IOException { + analyzer.analyzeClass(TargetLoader.getClassData(AnalyzerTest.class)); + assertEquals( + Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"), + classes); + } + + @Test + public void testAnalyzeClass2() throws IOException { + analyzer.analyzeClass(TargetLoader + .getClassDataAsBytes(AnalyzerTest.class)); + assertEquals( + Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"), + classes); + } + + @Test + public void testAnalyzeArchive() throws IOException { + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + final ZipOutputStream zip = new ZipOutputStream(buffer); + zip.putNextEntry(new ZipEntry( + "org/jacoco/core/analysis/AnalyzerTest.class")); + zip.write(TargetLoader.getClassDataAsBytes(AnalyzerTest.class)); + zip.finish(); + final int count = analyzer.analyzeArchive(new ByteArrayInputStream( + buffer.toByteArray())); + assertEquals(1, count); + assertEquals( + Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"), + classes); + } + + @Test + public void testAnalyzeAll1() throws IOException { + final int count = analyzer.analyzeAll(TargetLoader + .getClassData(AnalyzerTest.class)); + assertEquals(1, count); + assertEquals( + Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"), + classes); + } + + @Test + public void testAnalyzeAll2() throws IOException { + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + final ZipOutputStream zip = new ZipOutputStream(buffer); + zip.putNextEntry(new ZipEntry( + "org/jacoco/core/analysis/AnalyzerTest.class")); + zip.write(TargetLoader.getClassDataAsBytes(AnalyzerTest.class)); + zip.finish(); + final int count = analyzer.analyzeAll(new ByteArrayInputStream(buffer + .toByteArray())); + assertEquals(1, count); + assertEquals( + Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"), + classes); + } + + @Test + public void testAnalyzeAll3() throws IOException { + final int count = analyzer.analyzeAll(new ByteArrayInputStream( + new byte[0])); + assertEquals(0, count); + assertEquals(Collections.emptySet(), classes); + } + + @Test + public void testAnalyzeAll4() throws IOException { + createClassfile("bin1", AnalyzerTest.class); + final int count = analyzer.analyzeAll(folder.getRoot()); + assertEquals(1, count); + assertEquals( + Collections.singleton("org/jacoco/core/analysis/AnalyzerTest"), + classes); + } + + @Test + public void testAnalyzeAll5() throws IOException { + createClassfile("bin1", Analyzer.class); + createClassfile("bin2", AnalyzerTest.class); + 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); + } + + @Test(expected = IOException.class) + public void testAnalyzeAll6() throws IOException { + File file = new File(folder.getRoot(), "broken.zip"); + OutputStream out = new FileOutputStream(file); + ZipOutputStream zip = new ZipOutputStream(out); + zip.putNextEntry(new ZipEntry("brokenentry.txt")); + out.write(0x23); // Unexpected data here + zip.close(); + analyzer.analyzeAll(file); + } + + private void createClassfile(final String dir, final Class<?> source) + throws IOException { + File file = new File(folder.getRoot(), dir); + file.mkdirs(); + file = new File(file, "some.class"); + OutputStream out = new FileOutputStream(file); + out.write(TargetLoader.getClassDataAsBytes(source)); + out.close(); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/analysis/CounterComparatorTest.java b/org.jacoco.core.test/src/org/jacoco/core/analysis/CounterComparatorTest.java index 15047ec0..ba95d2b4 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/analysis/CounterComparatorTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/analysis/CounterComparatorTest.java @@ -1,123 +1,123 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import static org.jacoco.core.analysis.ICoverageNode.ElementType.GROUP;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Comparator;
-
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link CounterComparator}.
- */
-public class CounterComparatorTest {
-
- @Test
- public void testTotalItemsComparator() {
- final Comparator<ICounter> cmp = CounterComparator.TOTALITEMS;
- assertCmpLess(cmp, 19, 5, 19, 6);
- assertCmpEquals(cmp, 20, 5, 19, 6);
- assertCmpGreater(cmp, 21, 5, 19, 6);
- }
-
- @Test
- public void testCoveredItemsComparator() {
- final Comparator<ICounter> cmp = CounterComparator.COVEREDITEMS;
- assertCmpLess(cmp, 73, 7, 42, 8);
- assertCmpEquals(cmp, 42, 8, 82, 8);
- assertCmpGreater(cmp, 21, 9, 32, 8);
- }
-
- @Test
- public void testMissedItemsComparator() {
- final Comparator<ICounter> cmp = CounterComparator.MISSEDITEMS;
- assertCmpLess(cmp, 10, 40, 11, 80);
- assertCmpEquals(cmp, 10, 40, 10, 80);
- assertCmpGreater(cmp, 11, 39, 10, 80);
- }
-
- @Test
- public void testCoveredRatioComparator() {
- final Comparator<ICounter> cmp = CounterComparator.COVEREDRATIO;
- assertCmpLess(cmp, 25, 25, 44, 46);
- assertCmpEquals(cmp, 40, 10, 64, 16);
- assertCmpGreater(cmp, 25, 25, 46, 44);
- }
-
- @Test
- public void testMissedRatioComparator() {
- final Comparator<ICounter> cmp = CounterComparator.MISSEDRATIO;
- assertCmpLess(cmp, 25, 25, 46, 44);
- assertCmpEquals(cmp, 40, 10, 64, 16);
- assertCmpGreater(cmp, 25, 25, 44, 46);
- }
-
- @Test
- public void testReverseComparator() {
- final Comparator<ICounter> cmp = CounterComparator.TOTALITEMS.reverse();
- assertCmpGreater(cmp, 19, 5, 19, 6);
- assertCmpEquals(cmp, 20, 5, 19, 6);
- assertCmpLess(cmp, 21, 5, 19, 6);
- }
-
- @Test
- public void testNodeComparator1() {
- ICoverageNode d1 = new MockNode(18);
- ICoverageNode d2 = new MockNode(15);
- final Comparator<ICoverageNode> cmp = CounterComparator.TOTALITEMS
- .on(CounterEntity.INSTRUCTION);
- assertTrue(cmp.compare(d1, d2) > 0);
- }
-
- @Test
- public void testNodeComparator2() {
- ICoverageNode d1 = new MockNode(18);
- ICoverageNode d2 = new MockNode(15);
- final Comparator<ICoverageNode> cmp = CounterComparator.TOTALITEMS
- .on(CounterEntity.LINE);
- assertEquals(0, cmp.compare(d1, d2), 0.0);
- }
-
- private void assertCmpEquals(Comparator<ICounter> cmp, int missed1,
- int covered1, int missed2, int covered2) {
- assertEquals(0,
- cmp.compare(ctr(missed1, covered1), ctr(missed2, covered2)),
- 0.0);
- }
-
- private void assertCmpLess(Comparator<ICounter> cmp, int missed1,
- int covered1, int missed2, int covered2) {
- assertTrue(cmp.compare(ctr(missed1, covered1), ctr(missed2, covered2)) < 0);
- }
-
- private void assertCmpGreater(Comparator<ICounter> cmp, int missed1,
- int covered1, int missed2, int covered2) {
- assertTrue(cmp.compare(ctr(missed1, covered1), ctr(missed2, covered2)) > 0);
- }
-
- private CounterImpl ctr(int missed, int covered) {
- return CounterImpl.getInstance(missed, covered);
- }
-
- private static final class MockNode extends CoverageNodeImpl {
- MockNode(int total) {
- super(GROUP, "mock");
- instructionCounter = CounterImpl.getInstance(total, 0);
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import static org.jacoco.core.analysis.ICoverageNode.ElementType.GROUP; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Comparator; + +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.junit.Test; + +/** + * Unit tests for {@link CounterComparator}. + */ +public class CounterComparatorTest { + + @Test + public void testTotalItemsComparator() { + final Comparator<ICounter> cmp = CounterComparator.TOTALITEMS; + assertCmpLess(cmp, 19, 5, 19, 6); + assertCmpEquals(cmp, 20, 5, 19, 6); + assertCmpGreater(cmp, 21, 5, 19, 6); + } + + @Test + public void testCoveredItemsComparator() { + final Comparator<ICounter> cmp = CounterComparator.COVEREDITEMS; + assertCmpLess(cmp, 73, 7, 42, 8); + assertCmpEquals(cmp, 42, 8, 82, 8); + assertCmpGreater(cmp, 21, 9, 32, 8); + } + + @Test + public void testMissedItemsComparator() { + final Comparator<ICounter> cmp = CounterComparator.MISSEDITEMS; + assertCmpLess(cmp, 10, 40, 11, 80); + assertCmpEquals(cmp, 10, 40, 10, 80); + assertCmpGreater(cmp, 11, 39, 10, 80); + } + + @Test + public void testCoveredRatioComparator() { + final Comparator<ICounter> cmp = CounterComparator.COVEREDRATIO; + assertCmpLess(cmp, 25, 25, 44, 46); + assertCmpEquals(cmp, 40, 10, 64, 16); + assertCmpGreater(cmp, 25, 25, 46, 44); + } + + @Test + public void testMissedRatioComparator() { + final Comparator<ICounter> cmp = CounterComparator.MISSEDRATIO; + assertCmpLess(cmp, 25, 25, 46, 44); + assertCmpEquals(cmp, 40, 10, 64, 16); + assertCmpGreater(cmp, 25, 25, 44, 46); + } + + @Test + public void testReverseComparator() { + final Comparator<ICounter> cmp = CounterComparator.TOTALITEMS.reverse(); + assertCmpGreater(cmp, 19, 5, 19, 6); + assertCmpEquals(cmp, 20, 5, 19, 6); + assertCmpLess(cmp, 21, 5, 19, 6); + } + + @Test + public void testNodeComparator1() { + ICoverageNode d1 = new MockNode(18); + ICoverageNode d2 = new MockNode(15); + final Comparator<ICoverageNode> cmp = CounterComparator.TOTALITEMS + .on(CounterEntity.INSTRUCTION); + assertTrue(cmp.compare(d1, d2) > 0); + } + + @Test + public void testNodeComparator2() { + ICoverageNode d1 = new MockNode(18); + ICoverageNode d2 = new MockNode(15); + final Comparator<ICoverageNode> cmp = CounterComparator.TOTALITEMS + .on(CounterEntity.LINE); + assertEquals(0, cmp.compare(d1, d2), 0.0); + } + + private void assertCmpEquals(Comparator<ICounter> cmp, int missed1, + int covered1, int missed2, int covered2) { + assertEquals(0, + cmp.compare(ctr(missed1, covered1), ctr(missed2, covered2)), + 0.0); + } + + private void assertCmpLess(Comparator<ICounter> cmp, int missed1, + int covered1, int missed2, int covered2) { + assertTrue(cmp.compare(ctr(missed1, covered1), ctr(missed2, covered2)) < 0); + } + + private void assertCmpGreater(Comparator<ICounter> cmp, int missed1, + int covered1, int missed2, int covered2) { + assertTrue(cmp.compare(ctr(missed1, covered1), ctr(missed2, covered2)) > 0); + } + + private CounterImpl ctr(int missed, int covered) { + return CounterImpl.getInstance(missed, covered); + } + + private static final class MockNode extends CoverageNodeImpl { + MockNode(int total) { + super(GROUP, "mock"); + instructionCounter = CounterImpl.getInstance(total, 0); + } + } + +} 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 a1f4f660..fb0c71b2 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 @@ -1,226 +1,226 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.jacoco.core.internal.analysis.ClassCoverageImpl;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.jacoco.core.internal.analysis.MethodCoverageImpl;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link CoverageBuilder}.
- */
-public class CoverageBuilderTest {
-
- private CoverageBuilder coverageBuilder;
-
- @Before
- public void setup() {
- coverageBuilder = new CoverageBuilder();
- }
-
- @Test
- public void testCreateClassMissed() {
- final MethodCoverageImpl method = new MethodCoverageImpl("doit", "()V",
- null);
- method.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 6);
- 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);
-
- final Collection<IClassCoverage> classes = coverageBuilder.getClasses();
- assertEquals(1, classes.size());
- IClassCoverage c = classes.iterator().next();
- assertEquals("Sample", c.getName());
- assertEquals(1, c.getClassCounter().getTotalCount());
- assertEquals(0, c.getClassCounter().getCoveredCount());
- assertEquals(1, c.getMethodCounter().getTotalCount());
- assertEquals(0, c.getMethodCounter().getCoveredCount());
- assertEquals(3, c.getLineCounter().getTotalCount());
- assertEquals(0, c.getLineCounter().getCoveredCount());
-
- final Collection<IMethodCoverage> methods = c.getMethods();
- assertEquals(1, methods.size());
- IMethodCoverage m = methods.iterator().next();
- assertEquals("doit", m.getName());
- assertEquals("()V", m.getDesc());
- assertEquals(1, m.getMethodCounter().getTotalCount());
- assertEquals(0, m.getMethodCounter().getCoveredCount());
- assertEquals(3, m.getLineCounter().getTotalCount());
- assertEquals(0, m.getLineCounter().getCoveredCount());
- }
-
- @Test
- public void testCreateClassCovered() {
- final MethodCoverageImpl method = new MethodCoverageImpl("doit", "()V",
- null);
- method.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, 6);
- 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);
-
- final Collection<IClassCoverage> classes = coverageBuilder.getClasses();
- assertEquals(1, classes.size());
- IClassCoverage c = classes.iterator().next();
- assertEquals("Sample", c.getName());
- assertEquals(1, c.getClassCounter().getTotalCount());
- assertEquals(1, c.getClassCounter().getCoveredCount());
- assertEquals(1, c.getMethodCounter().getTotalCount());
- assertEquals(1, c.getMethodCounter().getCoveredCount());
- assertEquals(3, c.getLineCounter().getTotalCount());
- assertEquals(3, c.getLineCounter().getCoveredCount());
-
- final Collection<IMethodCoverage> methods = c.getMethods();
- assertEquals(1, methods.size());
- IMethodCoverage m = methods.iterator().next();
- assertEquals("doit", m.getName());
- assertEquals("()V", m.getDesc());
- assertEquals(1, m.getMethodCounter().getTotalCount());
- assertEquals(1, m.getMethodCounter().getCoveredCount());
- assertEquals(3, m.getLineCounter().getTotalCount());
- assertEquals(3, m.getLineCounter().getCoveredCount());
- }
-
- @Test
- public void testIgnoreClassesWithoutCode() {
- final MethodCoverageImpl method = new MethodCoverageImpl("doit", "()V",
- null);
- addClass(123L, "Sample", null, method);
-
- final Collection<IClassCoverage> classes = coverageBuilder.getClasses();
- assertTrue(classes.isEmpty());
- }
-
- @Test(expected = IllegalStateException.class)
- 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);
-
- // 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);
- }
-
- @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);
-
- // 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);
-
- // Second add must be ignored:
- final Collection<IClassCoverage> classes = coverageBuilder.getClasses();
- assertEquals(1, classes.size());
- }
-
- @Test
- public void testCreateSourceFile() {
- 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);
-
- 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);
-
- final Collection<ISourceFileCoverage> sourcefiles = coverageBuilder
- .getSourceFiles();
- assertEquals(1, sourcefiles.size());
- ISourceFileCoverage s = sourcefiles.iterator().next();
-
- assertEquals(2, s.getClassCounter().getTotalCount());
- assertEquals(0, s.getClassCounter().getCoveredCount());
- }
-
- @Test
- public void testGetBundle() {
- 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);
-
- 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);
-
- final MethodCoverageImpl method3 = new MethodCoverageImpl("doit",
- "()V", null);
- method3.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 1);
- addClass(3, "Sample3", null, method3);
-
- IBundleCoverage bundle = coverageBuilder.getBundle("testbundle");
- assertEquals("testbundle", bundle.getName());
-
- final Collection<IPackageCoverage> packages = bundle.getPackages();
- assertEquals(2, packages.size());
- Map<String, IPackageCoverage> packagesByName = new HashMap<String, IPackageCoverage>();
- for (IPackageCoverage p : packages) {
- packagesByName.put(p.getName(), p);
- }
-
- IPackageCoverage p1 = packagesByName.get("org/jacoco/examples");
- assertNotNull(p1);
- assertEquals(
- new HashSet<String>(Arrays.asList(
- "org/jacoco/examples/Sample1",
- "org/jacoco/examples/Sample2")),
- getNames(p1.getClasses()));
-
- IPackageCoverage p2 = packagesByName.get("");
- assertNotNull(p2);
- assertEquals(Collections.singleton("Sample3"),
- getNames(p2.getClasses()));
- }
-
- private Set<String> getNames(Collection<? extends ICoverageNode> nodes) {
- Set<String> result = new HashSet<String>();
- for (ICoverageNode n : nodes) {
- result.add(n.getName());
- }
- return result;
- }
-
- private void addClass(long id, String name, String source,
- MethodCoverageImpl... methods) {
- final ClassCoverageImpl coverage = new ClassCoverageImpl(name, id,
- null, "java/lang/Object", new String[0]);
- coverage.setSourceFileName(source);
- for (MethodCoverageImpl m : methods) {
- coverage.addMethod(m);
- }
- coverageBuilder.visitCoverage(coverage);
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.jacoco.core.internal.analysis.ClassCoverageImpl; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.core.internal.analysis.MethodCoverageImpl; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link CoverageBuilder}. + */ +public class CoverageBuilderTest { + + private CoverageBuilder coverageBuilder; + + @Before + public void setup() { + coverageBuilder = new CoverageBuilder(); + } + + @Test + public void testCreateClassMissed() { + final MethodCoverageImpl method = new MethodCoverageImpl("doit", "()V", + null); + method.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 6); + 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); + + final Collection<IClassCoverage> classes = coverageBuilder.getClasses(); + assertEquals(1, classes.size()); + IClassCoverage c = classes.iterator().next(); + assertEquals("Sample", c.getName()); + assertEquals(1, c.getClassCounter().getTotalCount()); + assertEquals(0, c.getClassCounter().getCoveredCount()); + assertEquals(1, c.getMethodCounter().getTotalCount()); + assertEquals(0, c.getMethodCounter().getCoveredCount()); + assertEquals(3, c.getLineCounter().getTotalCount()); + assertEquals(0, c.getLineCounter().getCoveredCount()); + + final Collection<IMethodCoverage> methods = c.getMethods(); + assertEquals(1, methods.size()); + IMethodCoverage m = methods.iterator().next(); + assertEquals("doit", m.getName()); + assertEquals("()V", m.getDesc()); + assertEquals(1, m.getMethodCounter().getTotalCount()); + assertEquals(0, m.getMethodCounter().getCoveredCount()); + assertEquals(3, m.getLineCounter().getTotalCount()); + assertEquals(0, m.getLineCounter().getCoveredCount()); + } + + @Test + public void testCreateClassCovered() { + final MethodCoverageImpl method = new MethodCoverageImpl("doit", "()V", + null); + method.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, 6); + 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); + + final Collection<IClassCoverage> classes = coverageBuilder.getClasses(); + assertEquals(1, classes.size()); + IClassCoverage c = classes.iterator().next(); + assertEquals("Sample", c.getName()); + assertEquals(1, c.getClassCounter().getTotalCount()); + assertEquals(1, c.getClassCounter().getCoveredCount()); + assertEquals(1, c.getMethodCounter().getTotalCount()); + assertEquals(1, c.getMethodCounter().getCoveredCount()); + assertEquals(3, c.getLineCounter().getTotalCount()); + assertEquals(3, c.getLineCounter().getCoveredCount()); + + final Collection<IMethodCoverage> methods = c.getMethods(); + assertEquals(1, methods.size()); + IMethodCoverage m = methods.iterator().next(); + assertEquals("doit", m.getName()); + assertEquals("()V", m.getDesc()); + assertEquals(1, m.getMethodCounter().getTotalCount()); + assertEquals(1, m.getMethodCounter().getCoveredCount()); + assertEquals(3, m.getLineCounter().getTotalCount()); + assertEquals(3, m.getLineCounter().getCoveredCount()); + } + + @Test + public void testIgnoreClassesWithoutCode() { + final MethodCoverageImpl method = new MethodCoverageImpl("doit", "()V", + null); + addClass(123L, "Sample", null, method); + + final Collection<IClassCoverage> classes = coverageBuilder.getClasses(); + assertTrue(classes.isEmpty()); + } + + @Test(expected = IllegalStateException.class) + 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); + + // 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); + } + + @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); + + // 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); + + // Second add must be ignored: + final Collection<IClassCoverage> classes = coverageBuilder.getClasses(); + assertEquals(1, classes.size()); + } + + @Test + public void testCreateSourceFile() { + 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); + + 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); + + final Collection<ISourceFileCoverage> sourcefiles = coverageBuilder + .getSourceFiles(); + assertEquals(1, sourcefiles.size()); + ISourceFileCoverage s = sourcefiles.iterator().next(); + + assertEquals(2, s.getClassCounter().getTotalCount()); + assertEquals(0, s.getClassCounter().getCoveredCount()); + } + + @Test + public void testGetBundle() { + 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); + + 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); + + final MethodCoverageImpl method3 = new MethodCoverageImpl("doit", + "()V", null); + method3.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 1); + addClass(3, "Sample3", null, method3); + + IBundleCoverage bundle = coverageBuilder.getBundle("testbundle"); + assertEquals("testbundle", bundle.getName()); + + final Collection<IPackageCoverage> packages = bundle.getPackages(); + assertEquals(2, packages.size()); + Map<String, IPackageCoverage> packagesByName = new HashMap<String, IPackageCoverage>(); + for (IPackageCoverage p : packages) { + packagesByName.put(p.getName(), p); + } + + IPackageCoverage p1 = packagesByName.get("org/jacoco/examples"); + assertNotNull(p1); + assertEquals( + new HashSet<String>(Arrays.asList( + "org/jacoco/examples/Sample1", + "org/jacoco/examples/Sample2")), + getNames(p1.getClasses())); + + IPackageCoverage p2 = packagesByName.get(""); + assertNotNull(p2); + assertEquals(Collections.singleton("Sample3"), + getNames(p2.getClasses())); + } + + private Set<String> getNames(Collection<? extends ICoverageNode> nodes) { + Set<String> result = new HashSet<String>(); + for (ICoverageNode n : nodes) { + result.add(n.getName()); + } + return result; + } + + private void addClass(long id, String name, String source, + MethodCoverageImpl... methods) { + final ClassCoverageImpl coverage = new ClassCoverageImpl(name, id, + null, "java/lang/Object", new String[0]); + coverage.setSourceFileName(source); + for (MethodCoverageImpl m : methods) { + coverage.addMethod(m); + } + coverageBuilder.visitCoverage(coverage); + } +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageNodeImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageNodeImplTest.java index f18f6737..59f7b3d9 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageNodeImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/analysis/CoverageNodeImplTest.java @@ -1,132 +1,132 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.BRANCH;
-import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.CLASS;
-import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.COMPLEXITY;
-import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.INSTRUCTION;
-import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.LINE;
-import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.METHOD;
-import static org.junit.Assert.assertEquals;
-
-import java.util.Arrays;
-
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link CoverageNodeImpl}.
- */
-public class CoverageNodeImplTest {
-
- @Test
- public void testProperties() {
- ICoverageNode node = new CoverageNodeImpl(ElementType.GROUP, "sample");
- assertEquals(ElementType.GROUP, node.getElementType());
- assertEquals("sample", node.getName());
- }
-
- @Test
- public void testInit() {
- ICoverageNode node = new CoverageNodeImpl(ElementType.GROUP, "sample");
- assertEquals(CounterImpl.COUNTER_0_0, node.getBranchCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getInstructionCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getLineCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getComplexityCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getMethodCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getClassCounter());
- }
-
- @Test
- public void testIncrement() {
- CoverageNodeImpl parent = new CoverageNodeImpl(ElementType.GROUP,
- "sample");
- ICoverageNode child = new CoverageNodeImpl(ElementType.GROUP, "sample") {
- {
- instructionCounter = CounterImpl.getInstance(1, 41);
- branchCounter = CounterImpl.getInstance(10, 15);
- lineCounter = CounterImpl.getInstance(5, 3);
- complexityCounter = CounterImpl.getInstance(4, 2);
- methodCounter = CounterImpl.getInstance(1, 21);
- classCounter = CounterImpl.getInstance(1, 11);
- }
- };
- parent.increment(child);
- assertEquals(CounterImpl.getInstance(1, 41),
- parent.getCounter(INSTRUCTION));
- assertEquals(CounterImpl.getInstance(1, 41),
- parent.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(10, 15), parent.getCounter(BRANCH));
- assertEquals(CounterImpl.getInstance(10, 15), parent.getBranchCounter());
- assertEquals(CounterImpl.getInstance(5, 3), parent.getCounter(LINE));
- assertEquals(CounterImpl.getInstance(5, 3), parent.getLineCounter());
- assertEquals(CounterImpl.getInstance(4, 2),
- parent.getCounter(COMPLEXITY));
- assertEquals(CounterImpl.getInstance(4, 2),
- parent.getComplexityCounter());
- assertEquals(CounterImpl.getInstance(1, 21), parent.getCounter(METHOD));
- assertEquals(CounterImpl.getInstance(1, 21), parent.getMethodCounter());
- assertEquals(CounterImpl.getInstance(1, 11), parent.getCounter(CLASS));
- assertEquals(CounterImpl.getInstance(1, 11), parent.getClassCounter());
- }
-
- @Test
- public void testIncrementCollection() {
- CoverageNodeImpl parent = new CoverageNodeImpl(ElementType.GROUP,
- "sample");
- ICoverageNode child1 = new CoverageNodeImpl(ElementType.GROUP, "sample") {
- {
- branchCounter = CounterImpl.getInstance(5, 2);
- }
- };
- ICoverageNode child2 = new CoverageNodeImpl(ElementType.GROUP, "sample") {
- {
- branchCounter = CounterImpl.getInstance(3, 3);
- }
- };
- parent.increment(Arrays.asList(child1, child2));
- assertEquals(CounterImpl.getInstance(8, 5), parent.getBranchCounter());
- }
-
- @Test
- public void testGetPlainCopy() {
- ICoverageNode node = new CoverageNodeImpl(ElementType.CLASS, "Sample") {
- {
- classCounter = CounterImpl.getInstance(1, 1);
- methodCounter = CounterImpl.getInstance(2, 2);
- branchCounter = CounterImpl.getInstance(3, 3);
- instructionCounter = CounterImpl.getInstance(4, 4);
- lineCounter = CounterImpl.getInstance(5, 5);
- complexityCounter = CounterImpl.getInstance(6, 6);
- }
- };
- ICoverageNode copy = node.getPlainCopy();
- assertEquals(ElementType.CLASS, copy.getElementType());
- assertEquals("Sample", copy.getName());
- assertEquals(CounterImpl.getInstance(1, 1), copy.getClassCounter());
- assertEquals(CounterImpl.getInstance(2, 2), copy.getMethodCounter());
- assertEquals(CounterImpl.getInstance(3, 3), copy.getBranchCounter());
- assertEquals(CounterImpl.getInstance(4, 4),
- copy.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(5, 5), copy.getLineCounter());
- assertEquals(CounterImpl.getInstance(6, 6), copy.getComplexityCounter());
- }
-
- @Test
- public void testToString() {
- CoverageNodeImpl node = new CoverageNodeImpl(ElementType.CLASS, "Test");
- assertEquals("Test [CLASS]", node.toString());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.BRANCH; +import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.CLASS; +import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.COMPLEXITY; +import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.INSTRUCTION; +import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.LINE; +import static org.jacoco.core.analysis.ICoverageNode.CounterEntity.METHOD; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.junit.Test; + +/** + * Unit tests for {@link CoverageNodeImpl}. + */ +public class CoverageNodeImplTest { + + @Test + public void testProperties() { + ICoverageNode node = new CoverageNodeImpl(ElementType.GROUP, "sample"); + assertEquals(ElementType.GROUP, node.getElementType()); + assertEquals("sample", node.getName()); + } + + @Test + public void testInit() { + ICoverageNode node = new CoverageNodeImpl(ElementType.GROUP, "sample"); + assertEquals(CounterImpl.COUNTER_0_0, node.getBranchCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getLineCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getComplexityCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getMethodCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getClassCounter()); + } + + @Test + public void testIncrement() { + CoverageNodeImpl parent = new CoverageNodeImpl(ElementType.GROUP, + "sample"); + ICoverageNode child = new CoverageNodeImpl(ElementType.GROUP, "sample") { + { + instructionCounter = CounterImpl.getInstance(1, 41); + branchCounter = CounterImpl.getInstance(10, 15); + lineCounter = CounterImpl.getInstance(5, 3); + complexityCounter = CounterImpl.getInstance(4, 2); + methodCounter = CounterImpl.getInstance(1, 21); + classCounter = CounterImpl.getInstance(1, 11); + } + }; + parent.increment(child); + assertEquals(CounterImpl.getInstance(1, 41), + parent.getCounter(INSTRUCTION)); + assertEquals(CounterImpl.getInstance(1, 41), + parent.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(10, 15), parent.getCounter(BRANCH)); + assertEquals(CounterImpl.getInstance(10, 15), parent.getBranchCounter()); + assertEquals(CounterImpl.getInstance(5, 3), parent.getCounter(LINE)); + assertEquals(CounterImpl.getInstance(5, 3), parent.getLineCounter()); + assertEquals(CounterImpl.getInstance(4, 2), + parent.getCounter(COMPLEXITY)); + assertEquals(CounterImpl.getInstance(4, 2), + parent.getComplexityCounter()); + assertEquals(CounterImpl.getInstance(1, 21), parent.getCounter(METHOD)); + assertEquals(CounterImpl.getInstance(1, 21), parent.getMethodCounter()); + assertEquals(CounterImpl.getInstance(1, 11), parent.getCounter(CLASS)); + assertEquals(CounterImpl.getInstance(1, 11), parent.getClassCounter()); + } + + @Test + public void testIncrementCollection() { + CoverageNodeImpl parent = new CoverageNodeImpl(ElementType.GROUP, + "sample"); + ICoverageNode child1 = new CoverageNodeImpl(ElementType.GROUP, "sample") { + { + branchCounter = CounterImpl.getInstance(5, 2); + } + }; + ICoverageNode child2 = new CoverageNodeImpl(ElementType.GROUP, "sample") { + { + branchCounter = CounterImpl.getInstance(3, 3); + } + }; + parent.increment(Arrays.asList(child1, child2)); + assertEquals(CounterImpl.getInstance(8, 5), parent.getBranchCounter()); + } + + @Test + public void testGetPlainCopy() { + ICoverageNode node = new CoverageNodeImpl(ElementType.CLASS, "Sample") { + { + classCounter = CounterImpl.getInstance(1, 1); + methodCounter = CounterImpl.getInstance(2, 2); + branchCounter = CounterImpl.getInstance(3, 3); + instructionCounter = CounterImpl.getInstance(4, 4); + lineCounter = CounterImpl.getInstance(5, 5); + complexityCounter = CounterImpl.getInstance(6, 6); + } + }; + ICoverageNode copy = node.getPlainCopy(); + assertEquals(ElementType.CLASS, copy.getElementType()); + assertEquals("Sample", copy.getName()); + assertEquals(CounterImpl.getInstance(1, 1), copy.getClassCounter()); + assertEquals(CounterImpl.getInstance(2, 2), copy.getMethodCounter()); + assertEquals(CounterImpl.getInstance(3, 3), copy.getBranchCounter()); + assertEquals(CounterImpl.getInstance(4, 4), + copy.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(5, 5), copy.getLineCounter()); + assertEquals(CounterImpl.getInstance(6, 6), copy.getComplexityCounter()); + } + + @Test + public void testToString() { + CoverageNodeImpl node = new CoverageNodeImpl(ElementType.CLASS, "Test"); + assertEquals("Test [CLASS]", node.toString()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/analysis/NodeComparatorTest.java b/org.jacoco.core.test/src/org/jacoco/core/analysis/NodeComparatorTest.java index 8f42c4bf..fc81787e 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/analysis/NodeComparatorTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/analysis/NodeComparatorTest.java @@ -1,79 +1,79 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import static org.jacoco.core.analysis.ICoverageNode.ElementType.GROUP;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.junit.Test;
-
-/**
- * Unit test for {@link NodeComparator}.
- */
-public class NodeComparatorTest {
-
- @Test
- public void testSort() {
- ICoverageNode d1 = new MockNode(18);
- ICoverageNode d2 = new MockNode(21);
- ICoverageNode d3 = new MockNode(30);
- ICoverageNode d4 = new MockNode(60);
- ICoverageNode d5 = new MockNode(99);
- final List<ICoverageNode> result = CounterComparator.TOTALITEMS.on(
- CounterEntity.INSTRUCTION).sort(
- Arrays.asList(d3, d5, d1, d4, d2));
- assertEquals(Arrays.asList(d1, d2, d3, d4, d5), result);
- }
-
- @Test
- public void testSecond1() {
- ICoverageNode d1 = new MockLineData(5, 30);
- ICoverageNode d2 = new MockLineData(3, 80);
- final NodeComparator c1 = CounterComparator.TOTALITEMS
- .on(CounterEntity.INSTRUCTION);
- final NodeComparator c2 = CounterComparator.TOTALITEMS
- .on(CounterEntity.LINE);
- assertTrue(c1.second(c2).compare(d1, d2) > 0);
- }
-
- @Test
- public void testSecond2() {
- ICoverageNode d1 = new MockLineData(5, 30);
- ICoverageNode d2 = new MockLineData(5, 80);
- final NodeComparator c1 = CounterComparator.TOTALITEMS
- .on(CounterEntity.INSTRUCTION);
- final NodeComparator c2 = CounterComparator.TOTALITEMS
- .on(CounterEntity.LINE);
- assertTrue(c1.second(c2).compare(d1, d2) < 0);
- }
-
- private static final class MockNode extends CoverageNodeImpl {
- MockNode(int total) {
- super(GROUP, "mock");
- instructionCounter = CounterImpl.getInstance(total, 0);
- }
- }
-
- private static final class MockLineData extends CoverageNodeImpl {
- MockLineData(int totalInstruction, int totalLine) {
- super(GROUP, "mock");
- instructionCounter = CounterImpl.getInstance(totalInstruction, 0);
- lineCounter = CounterImpl.getInstance(totalLine, 0);
- }
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import static org.jacoco.core.analysis.ICoverageNode.ElementType.GROUP; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.junit.Test; + +/** + * Unit test for {@link NodeComparator}. + */ +public class NodeComparatorTest { + + @Test + public void testSort() { + ICoverageNode d1 = new MockNode(18); + ICoverageNode d2 = new MockNode(21); + ICoverageNode d3 = new MockNode(30); + ICoverageNode d4 = new MockNode(60); + ICoverageNode d5 = new MockNode(99); + final List<ICoverageNode> result = CounterComparator.TOTALITEMS.on( + CounterEntity.INSTRUCTION).sort( + Arrays.asList(d3, d5, d1, d4, d2)); + assertEquals(Arrays.asList(d1, d2, d3, d4, d5), result); + } + + @Test + public void testSecond1() { + ICoverageNode d1 = new MockLineData(5, 30); + ICoverageNode d2 = new MockLineData(3, 80); + final NodeComparator c1 = CounterComparator.TOTALITEMS + .on(CounterEntity.INSTRUCTION); + final NodeComparator c2 = CounterComparator.TOTALITEMS + .on(CounterEntity.LINE); + assertTrue(c1.second(c2).compare(d1, d2) > 0); + } + + @Test + public void testSecond2() { + ICoverageNode d1 = new MockLineData(5, 30); + ICoverageNode d2 = new MockLineData(5, 80); + final NodeComparator c1 = CounterComparator.TOTALITEMS + .on(CounterEntity.INSTRUCTION); + final NodeComparator c2 = CounterComparator.TOTALITEMS + .on(CounterEntity.LINE); + assertTrue(c1.second(c2).compare(d1, d2) < 0); + } + + private static final class MockNode extends CoverageNodeImpl { + MockNode(int total) { + super(GROUP, "mock"); + instructionCounter = CounterImpl.getInstance(total, 0); + } + } + + private static final class MockLineData extends CoverageNodeImpl { + MockLineData(int totalInstruction, int totalLine) { + super(GROUP, "mock"); + instructionCounter = CounterImpl.getInstance(totalInstruction, 0); + lineCounter = CounterImpl.getInstance(totalLine, 0); + } + } +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataReaderWriterTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataReaderWriterTest.java index 1671e5e0..1557a9c6 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataReaderWriterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataReaderWriterTest.java @@ -1,315 +1,315 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.Random;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link ExecutionDataReader} and {@link ExecutionDataWriter}.
- * The tests don't care about the written binary format, they just verify
- * symmetry.
- */
-public class ExecutionDataReaderWriterTest {
-
- protected ByteArrayOutputStream buffer;
-
- private ExecutionDataWriter writer;
-
- private ExecutionDataStore store;
-
- private SessionInfo sessionInfo;
-
- private Random random;
-
- @Before
- public void setup() throws IOException {
- buffer = new ByteArrayOutputStream();
- writer = createWriter(buffer);
- store = new ExecutionDataStore();
- random = new Random(5);
- }
-
- @Test
- public void testEmpty() throws IOException {
- final ExecutionDataReader reader = createReader();
- reader.setSessionInfoVisitor(new ISessionInfoVisitor() {
- public void visitSessionInfo(final SessionInfo info) {
- fail("No data expected.");
- }
- });
- reader.setExecutionDataVisitor(new IExecutionDataVisitor() {
- public void visitClassExecution(final ExecutionData data) {
- fail("No data expected.");
- }
- });
- assertFalse(reader.read());
- }
-
- @Test
- public void testFlush() throws IOException {
- final boolean[] flushCalled = new boolean[] { false };
- final OutputStream out = new OutputStream() {
- @Override
- public void write(int b) throws IOException {
- }
-
- @Override
- public void flush() throws IOException {
- flushCalled[0] = true;
- }
- };
- new ExecutionDataWriter(out).flush();
- assertTrue(flushCalled[0]);
- }
-
- @Test
- public void testCustomBlocks() throws IOException {
- buffer.write(-22);
- buffer.write(-33);
- final ExecutionDataReader reader = new ExecutionDataReader(
- new ByteArrayInputStream(buffer.toByteArray())) {
-
- @Override
- protected boolean readBlock(byte blocktype) throws IOException {
- switch (blocktype) {
- case -22:
- return true;
- case -33:
- return false;
- }
- return super.readBlock(blocktype);
- }
- };
- assertTrue(reader.read());
- }
-
- @Test
- public void testGetFileHeader() {
- byte[] header = ExecutionDataWriter.getFileHeader();
- assertEquals(5, header.length);
- assertEquals(0x01, 0xFF & header[0]);
- assertEquals(0xC0, 0xFF & header[1]);
- assertEquals(0xC0, 0xFF & header[2]);
- final char version = ExecutionDataWriter.FORMAT_VERSION;
- assertEquals(version >> 8, 0xFF & header[3]);
- assertEquals(version & 0xFF, 0xFF & header[4]);
- }
-
- @Test
- public void testMultipleHeaders() throws IOException {
- new ExecutionDataWriter(buffer);
- new ExecutionDataWriter(buffer);
- new ExecutionDataWriter(buffer);
- assertFalse(createReader().read());
- }
-
- @Test(expected = IOException.class)
- public void testInvalidMagicNumber() throws IOException {
- buffer = new ByteArrayOutputStream();
- buffer.write(ExecutionDataWriter.BLOCK_HEADER);
- buffer.write(0x12);
- buffer.write(0x34);
- createReader().read();
- }
-
- @Test(expected = IOException.class)
- public void testInvalidHeaderVersion() throws IOException {
- buffer = new ByteArrayOutputStream();
- buffer.write(ExecutionDataWriter.BLOCK_HEADER);
- buffer.write(0xC0);
- buffer.write(0xC0);
- final char version = ExecutionDataWriter.FORMAT_VERSION - 1;
- buffer.write(version >> 8);
- buffer.write(version & 0xFF);
- createReader().read();
- }
-
- @Test(expected = IOException.class)
- public void testMissingHeader() throws IOException {
- buffer.reset();
- writer.visitClassExecution(new ExecutionData(Long.MIN_VALUE, "Sample",
- createData(0)));
- createReaderWithVisitors().read();
- }
-
- @Test(expected = IOException.class)
- public void testUnknownBlock() throws IOException {
- buffer.write(0xff);
- createReader().read();
- }
-
- @Test
- public void testEmptyFile() throws IOException {
- buffer = new ByteArrayOutputStream();
- createReader().read();
- }
-
- // === Session Info ===
-
- @Test(expected = IOException.class)
- public void testNoSessionInfoVisitor() throws IOException {
- writer.visitSessionInfo(new SessionInfo("x", 0, 1));
- createReader().read();
- }
-
- @Test
- public void testSessionInfo() throws IOException {
- writer.visitSessionInfo(new SessionInfo("TestSession",
- 2837123124567891234L, 3444234223498879234L));
- assertFalse(createReaderWithVisitors().read());
- assertNotNull(sessionInfo);
- assertEquals("TestSession", sessionInfo.getId());
- assertEquals(2837123124567891234L, sessionInfo.getStartTimeStamp());
- assertEquals(3444234223498879234L, sessionInfo.getDumpTimeStamp());
- }
-
- @Test(expected = RuntimeException.class)
- public void testSessionInfoIOException() throws IOException {
- final boolean[] broken = new boolean[1];
- final ExecutionDataWriter writer = createWriter(new OutputStream() {
- @Override
- public void write(int b) throws IOException {
- if (broken[0]) {
- throw new IOException();
- }
- }
- });
- broken[0] = true;
- writer.visitSessionInfo(new SessionInfo("X", 0, 0));
- }
-
- // === Execution Data ===
-
- @Test(expected = IOException.class)
- public void testNoExecutionDataVisitor() throws IOException {
- writer.visitClassExecution(new ExecutionData(Long.MIN_VALUE, "Sample",
- createData(0)));
- createReader().read();
- }
-
- @Test
- public void testMinClassId() throws IOException {
- final boolean[] data = createData(0);
- writer.visitClassExecution(new ExecutionData(Long.MIN_VALUE, "Sample",
- data));
- assertFalse(createReaderWithVisitors().read());
- assertArrayEquals(data, store.get(Long.MIN_VALUE).getData());
- }
-
- @Test
- public void testMaxClassId() throws IOException {
- final boolean[] data = createData(0);
- writer.visitClassExecution(new ExecutionData(Long.MAX_VALUE, "Sample",
- data));
- assertFalse(createReaderWithVisitors().read());
- assertArrayEquals(data, store.get(Long.MAX_VALUE).getData());
- }
-
- @Test
- public void testEmptyClass() throws IOException {
- final boolean[] data = createData(0);
- writer.visitClassExecution(new ExecutionData(3, "Sample", data));
- assertFalse(createReaderWithVisitors().read());
- assertArrayEquals(data, store.get(3).getData());
- }
-
- @Test
- public void testOneClass() throws IOException {
- final boolean[] data = createData(5);
- writer.visitClassExecution(new ExecutionData(3, "Sample", data));
- assertFalse(createReaderWithVisitors().read());
- assertArrayEquals(data, store.get(3).getData());
- }
-
- @Test
- public void testTwoClasses() throws IOException {
- final boolean[] data1 = createData(5);
- final boolean[] data2 = createData(7);
- writer.visitClassExecution(new ExecutionData(333, "Sample", data1));
- writer.visitClassExecution(new ExecutionData(-45, "Sample", data2));
- assertFalse(createReaderWithVisitors().read());
- assertArrayEquals(data1, store.get(333).getData());
- assertArrayEquals(data2, store.get(-45).getData());
- }
-
- @Test
- public void testBigClass() throws IOException {
- final boolean[] data = createData(117);
- writer.visitClassExecution(new ExecutionData(123, "Sample", data));
- assertFalse(createReaderWithVisitors().read());
- assertArrayEquals(data, store.get(123).getData());
- }
-
- @Test(expected = RuntimeException.class)
- public void testExecutionDataIOException() throws IOException {
- final boolean[] broken = new boolean[1];
- final ExecutionDataWriter writer = createWriter(new OutputStream() {
- @Override
- public void write(int b) throws IOException {
- if (broken[0]) {
- throw new IOException();
- }
- }
- });
- broken[0] = true;
- writer.visitClassExecution(new ExecutionData(3, "Sample", createData(1)));
- }
-
- private ExecutionDataReader createReaderWithVisitors() throws IOException {
- final ExecutionDataReader reader = createReader();
- reader.setExecutionDataVisitor(store);
- reader.setSessionInfoVisitor(new ISessionInfoVisitor() {
- public void visitSessionInfo(SessionInfo info) {
- sessionInfo = info;
- }
- });
- return reader;
- }
-
- private boolean[] createData(final int probeCount) {
- final boolean[] data = new boolean[random.nextInt(probeCount + 1)];
- for (int j = 0; j < data.length; j++) {
- data[j] = random.nextBoolean();
- }
- return data;
- }
-
- private void assertArrayEquals(final boolean[] expected,
- final boolean[] actual) {
- assertTrue(Arrays.equals(expected, actual));
- }
-
- protected ExecutionDataWriter createWriter(OutputStream out)
- throws IOException {
- return new ExecutionDataWriter(out);
- }
-
- protected ExecutionDataReader createReader() throws IOException {
- return new ExecutionDataReader(new ByteArrayInputStream(
- buffer.toByteArray()));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.data; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Random; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link ExecutionDataReader} and {@link ExecutionDataWriter}. + * The tests don't care about the written binary format, they just verify + * symmetry. + */ +public class ExecutionDataReaderWriterTest { + + protected ByteArrayOutputStream buffer; + + private ExecutionDataWriter writer; + + private ExecutionDataStore store; + + private SessionInfo sessionInfo; + + private Random random; + + @Before + public void setup() throws IOException { + buffer = new ByteArrayOutputStream(); + writer = createWriter(buffer); + store = new ExecutionDataStore(); + random = new Random(5); + } + + @Test + public void testEmpty() throws IOException { + final ExecutionDataReader reader = createReader(); + reader.setSessionInfoVisitor(new ISessionInfoVisitor() { + public void visitSessionInfo(final SessionInfo info) { + fail("No data expected."); + } + }); + reader.setExecutionDataVisitor(new IExecutionDataVisitor() { + public void visitClassExecution(final ExecutionData data) { + fail("No data expected."); + } + }); + assertFalse(reader.read()); + } + + @Test + public void testFlush() throws IOException { + final boolean[] flushCalled = new boolean[] { false }; + final OutputStream out = new OutputStream() { + @Override + public void write(int b) throws IOException { + } + + @Override + public void flush() throws IOException { + flushCalled[0] = true; + } + }; + new ExecutionDataWriter(out).flush(); + assertTrue(flushCalled[0]); + } + + @Test + public void testCustomBlocks() throws IOException { + buffer.write(-22); + buffer.write(-33); + final ExecutionDataReader reader = new ExecutionDataReader( + new ByteArrayInputStream(buffer.toByteArray())) { + + @Override + protected boolean readBlock(byte blocktype) throws IOException { + switch (blocktype) { + case -22: + return true; + case -33: + return false; + } + return super.readBlock(blocktype); + } + }; + assertTrue(reader.read()); + } + + @Test + public void testGetFileHeader() { + byte[] header = ExecutionDataWriter.getFileHeader(); + assertEquals(5, header.length); + assertEquals(0x01, 0xFF & header[0]); + assertEquals(0xC0, 0xFF & header[1]); + assertEquals(0xC0, 0xFF & header[2]); + final char version = ExecutionDataWriter.FORMAT_VERSION; + assertEquals(version >> 8, 0xFF & header[3]); + assertEquals(version & 0xFF, 0xFF & header[4]); + } + + @Test + public void testMultipleHeaders() throws IOException { + new ExecutionDataWriter(buffer); + new ExecutionDataWriter(buffer); + new ExecutionDataWriter(buffer); + assertFalse(createReader().read()); + } + + @Test(expected = IOException.class) + public void testInvalidMagicNumber() throws IOException { + buffer = new ByteArrayOutputStream(); + buffer.write(ExecutionDataWriter.BLOCK_HEADER); + buffer.write(0x12); + buffer.write(0x34); + createReader().read(); + } + + @Test(expected = IOException.class) + public void testInvalidHeaderVersion() throws IOException { + buffer = new ByteArrayOutputStream(); + buffer.write(ExecutionDataWriter.BLOCK_HEADER); + buffer.write(0xC0); + buffer.write(0xC0); + final char version = ExecutionDataWriter.FORMAT_VERSION - 1; + buffer.write(version >> 8); + buffer.write(version & 0xFF); + createReader().read(); + } + + @Test(expected = IOException.class) + public void testMissingHeader() throws IOException { + buffer.reset(); + writer.visitClassExecution(new ExecutionData(Long.MIN_VALUE, "Sample", + createData(0))); + createReaderWithVisitors().read(); + } + + @Test(expected = IOException.class) + public void testUnknownBlock() throws IOException { + buffer.write(0xff); + createReader().read(); + } + + @Test + public void testEmptyFile() throws IOException { + buffer = new ByteArrayOutputStream(); + createReader().read(); + } + + // === Session Info === + + @Test(expected = IOException.class) + public void testNoSessionInfoVisitor() throws IOException { + writer.visitSessionInfo(new SessionInfo("x", 0, 1)); + createReader().read(); + } + + @Test + public void testSessionInfo() throws IOException { + writer.visitSessionInfo(new SessionInfo("TestSession", + 2837123124567891234L, 3444234223498879234L)); + assertFalse(createReaderWithVisitors().read()); + assertNotNull(sessionInfo); + assertEquals("TestSession", sessionInfo.getId()); + assertEquals(2837123124567891234L, sessionInfo.getStartTimeStamp()); + assertEquals(3444234223498879234L, sessionInfo.getDumpTimeStamp()); + } + + @Test(expected = RuntimeException.class) + public void testSessionInfoIOException() throws IOException { + final boolean[] broken = new boolean[1]; + final ExecutionDataWriter writer = createWriter(new OutputStream() { + @Override + public void write(int b) throws IOException { + if (broken[0]) { + throw new IOException(); + } + } + }); + broken[0] = true; + writer.visitSessionInfo(new SessionInfo("X", 0, 0)); + } + + // === Execution Data === + + @Test(expected = IOException.class) + public void testNoExecutionDataVisitor() throws IOException { + writer.visitClassExecution(new ExecutionData(Long.MIN_VALUE, "Sample", + createData(0))); + createReader().read(); + } + + @Test + public void testMinClassId() throws IOException { + final boolean[] data = createData(0); + writer.visitClassExecution(new ExecutionData(Long.MIN_VALUE, "Sample", + data)); + assertFalse(createReaderWithVisitors().read()); + assertArrayEquals(data, store.get(Long.MIN_VALUE).getData()); + } + + @Test + public void testMaxClassId() throws IOException { + final boolean[] data = createData(0); + writer.visitClassExecution(new ExecutionData(Long.MAX_VALUE, "Sample", + data)); + assertFalse(createReaderWithVisitors().read()); + assertArrayEquals(data, store.get(Long.MAX_VALUE).getData()); + } + + @Test + public void testEmptyClass() throws IOException { + final boolean[] data = createData(0); + writer.visitClassExecution(new ExecutionData(3, "Sample", data)); + assertFalse(createReaderWithVisitors().read()); + assertArrayEquals(data, store.get(3).getData()); + } + + @Test + public void testOneClass() throws IOException { + final boolean[] data = createData(5); + writer.visitClassExecution(new ExecutionData(3, "Sample", data)); + assertFalse(createReaderWithVisitors().read()); + assertArrayEquals(data, store.get(3).getData()); + } + + @Test + public void testTwoClasses() throws IOException { + final boolean[] data1 = createData(5); + final boolean[] data2 = createData(7); + writer.visitClassExecution(new ExecutionData(333, "Sample", data1)); + writer.visitClassExecution(new ExecutionData(-45, "Sample", data2)); + assertFalse(createReaderWithVisitors().read()); + assertArrayEquals(data1, store.get(333).getData()); + assertArrayEquals(data2, store.get(-45).getData()); + } + + @Test + public void testBigClass() throws IOException { + final boolean[] data = createData(117); + writer.visitClassExecution(new ExecutionData(123, "Sample", data)); + assertFalse(createReaderWithVisitors().read()); + assertArrayEquals(data, store.get(123).getData()); + } + + @Test(expected = RuntimeException.class) + public void testExecutionDataIOException() throws IOException { + final boolean[] broken = new boolean[1]; + final ExecutionDataWriter writer = createWriter(new OutputStream() { + @Override + public void write(int b) throws IOException { + if (broken[0]) { + throw new IOException(); + } + } + }); + broken[0] = true; + writer.visitClassExecution(new ExecutionData(3, "Sample", createData(1))); + } + + private ExecutionDataReader createReaderWithVisitors() throws IOException { + final ExecutionDataReader reader = createReader(); + reader.setExecutionDataVisitor(store); + reader.setSessionInfoVisitor(new ISessionInfoVisitor() { + public void visitSessionInfo(SessionInfo info) { + sessionInfo = info; + } + }); + return reader; + } + + private boolean[] createData(final int probeCount) { + final boolean[] data = new boolean[random.nextInt(probeCount + 1)]; + for (int j = 0; j < data.length; j++) { + data[j] = random.nextBoolean(); + } + return data; + } + + private void assertArrayEquals(final boolean[] expected, + final boolean[] actual) { + assertTrue(Arrays.equals(expected, actual)); + } + + protected ExecutionDataWriter createWriter(OutputStream out) + throws IOException { + return new ExecutionDataWriter(out); + } + + protected ExecutionDataReader createReader() throws IOException { + return new ExecutionDataReader(new ByteArrayInputStream( + buffer.toByteArray())); + } + +} 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 401db129..0e0f5ace 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 @@ -1,163 +1,163 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link ExecutionDataStore}.
- */
-public class ExecutionDataStoreTest implements IExecutionDataVisitor {
-
- private ExecutionDataStore store;
-
- private Map<Long, ExecutionData> dataOutput;
-
- @Before
- public void setup() {
- store = new ExecutionDataStore();
- dataOutput = new HashMap<Long, ExecutionData>();
- }
-
- @Test
- public void testEmpty() {
- assertNull(store.get(123));
- store.accept(this);
- assertEquals(Collections.emptyMap(), dataOutput);
- }
-
- @Test
- public void testPut() {
- final boolean[] probes = new boolean[] { false, false, true };
- store.put(new ExecutionData(1000, "Sample", probes));
- final ExecutionData data = store.get(1000);
- assertSame(probes, data.getData());
- store.accept(this);
- assertEquals(Collections.singletonMap(Long.valueOf(1000), data),
- dataOutput);
- }
-
- @Test
- public void testGetContents() {
- final boolean[] probes = new boolean[] {};
- final ExecutionData a = new ExecutionData(1000, "A", probes);
- store.put(a);
- final ExecutionData aa = new ExecutionData(1000, "A", probes);
- store.put(aa);
- final ExecutionData b = new ExecutionData(1001, "B", probes);
- store.put(b);
- final Set<ExecutionData> actual = new HashSet<ExecutionData>(
- store.getContents());
- final Set<ExecutionData> expected = new HashSet<ExecutionData>(
- Arrays.asList(a, b));
- assertEquals(expected, actual);
- }
-
- @Test
- public void testGetWithoutCreate() {
- final ExecutionData data = new ExecutionData(1000, "Sample",
- new boolean[] {});
- store.put(data);
- assertSame(data, store.get(1000));
- }
-
- @Test
- public void testGetWithCreate() {
- final Long id = Long.valueOf(1000);
- final ExecutionData data = store.get(id, "Sample", 3);
- assertEquals(1000, data.getId());
- assertEquals("Sample", data.getName());
- assertEquals(3, data.getData().length);
- assertFalse(data.getData()[0]);
- assertFalse(data.getData()[1]);
- assertFalse(data.getData()[2]);
- assertSame(data, store.get(id, "Sample", 3));
- }
-
- @Test(expected = IllegalStateException.class)
- public void testGetNegative1() {
- final boolean[] data = new boolean[] { false, false, true };
- store.put(new ExecutionData(1000, "Sample", data));
- store.get(Long.valueOf(1000), "Other", 3);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testGetNegative2() {
- final boolean[] data = new boolean[] { false, false, true };
- store.put(new ExecutionData(1000, "Sample", data));
- store.get(Long.valueOf(1000), "Sample", 4);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testPutNegative() {
- final boolean[] data = new boolean[0];
- store.put(new ExecutionData(1000, "Sample1", data));
- store.put(new ExecutionData(1000, "Sample2", data));
- }
-
- @Test
- public void testMerge() {
- final boolean[] data1 = new boolean[] { false, true, false, true };
- store.visitClassExecution(new ExecutionData(1000, "Sample", data1));
- final boolean[] data2 = new boolean[] { false, true, true, false };
- store.visitClassExecution(new ExecutionData(1000, "Sample", data2));
-
- final boolean[] result = store.get(1000).getData();
- assertFalse(result[0]);
- assertTrue(result[1]);
- assertTrue(result[2]);
- assertTrue(result[3]);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testMergeNegative() {
- final boolean[] data1 = new boolean[] { false, false };
- store.visitClassExecution(new ExecutionData(1000, "Sample", data1));
- final boolean[] data2 = new boolean[] { false, false, false };
- store.visitClassExecution(new ExecutionData(1000, "Sample", data2));
- }
-
- @Test
- public void testReset() throws InstantiationException,
- IllegalAccessException {
- final boolean[] data1 = new boolean[] { true, true, false };
- store.put(new ExecutionData(1000, "Sample", data1));
- store.reset();
- final boolean[] data2 = store.get(1000).getData();
- assertNotNull(data2);
- assertFalse(data2[0]);
- assertFalse(data2[1]);
- assertFalse(data2[2]);
- }
-
- // === IExecutionDataOutput ===
-
- public void visitClassExecution(final ExecutionData data) {
- dataOutput.put(Long.valueOf(data.getId()), data);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.data; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link ExecutionDataStore}. + */ +public class ExecutionDataStoreTest implements IExecutionDataVisitor { + + private ExecutionDataStore store; + + private Map<Long, ExecutionData> dataOutput; + + @Before + public void setup() { + store = new ExecutionDataStore(); + dataOutput = new HashMap<Long, ExecutionData>(); + } + + @Test + public void testEmpty() { + assertNull(store.get(123)); + store.accept(this); + assertEquals(Collections.emptyMap(), dataOutput); + } + + @Test + public void testPut() { + final boolean[] probes = new boolean[] { false, false, true }; + store.put(new ExecutionData(1000, "Sample", probes)); + final ExecutionData data = store.get(1000); + assertSame(probes, data.getData()); + store.accept(this); + assertEquals(Collections.singletonMap(Long.valueOf(1000), data), + dataOutput); + } + + @Test + public void testGetContents() { + final boolean[] probes = new boolean[] {}; + final ExecutionData a = new ExecutionData(1000, "A", probes); + store.put(a); + final ExecutionData aa = new ExecutionData(1000, "A", probes); + store.put(aa); + final ExecutionData b = new ExecutionData(1001, "B", probes); + store.put(b); + final Set<ExecutionData> actual = new HashSet<ExecutionData>( + store.getContents()); + final Set<ExecutionData> expected = new HashSet<ExecutionData>( + Arrays.asList(a, b)); + assertEquals(expected, actual); + } + + @Test + public void testGetWithoutCreate() { + final ExecutionData data = new ExecutionData(1000, "Sample", + new boolean[] {}); + store.put(data); + assertSame(data, store.get(1000)); + } + + @Test + public void testGetWithCreate() { + final Long id = Long.valueOf(1000); + final ExecutionData data = store.get(id, "Sample", 3); + assertEquals(1000, data.getId()); + assertEquals("Sample", data.getName()); + assertEquals(3, data.getData().length); + assertFalse(data.getData()[0]); + assertFalse(data.getData()[1]); + assertFalse(data.getData()[2]); + assertSame(data, store.get(id, "Sample", 3)); + } + + @Test(expected = IllegalStateException.class) + public void testGetNegative1() { + final boolean[] data = new boolean[] { false, false, true }; + store.put(new ExecutionData(1000, "Sample", data)); + store.get(Long.valueOf(1000), "Other", 3); + } + + @Test(expected = IllegalStateException.class) + public void testGetNegative2() { + final boolean[] data = new boolean[] { false, false, true }; + store.put(new ExecutionData(1000, "Sample", data)); + store.get(Long.valueOf(1000), "Sample", 4); + } + + @Test(expected = IllegalStateException.class) + public void testPutNegative() { + final boolean[] data = new boolean[0]; + store.put(new ExecutionData(1000, "Sample1", data)); + store.put(new ExecutionData(1000, "Sample2", data)); + } + + @Test + public void testMerge() { + final boolean[] data1 = new boolean[] { false, true, false, true }; + store.visitClassExecution(new ExecutionData(1000, "Sample", data1)); + final boolean[] data2 = new boolean[] { false, true, true, false }; + store.visitClassExecution(new ExecutionData(1000, "Sample", data2)); + + final boolean[] result = store.get(1000).getData(); + assertFalse(result[0]); + assertTrue(result[1]); + assertTrue(result[2]); + assertTrue(result[3]); + } + + @Test(expected = IllegalStateException.class) + public void testMergeNegative() { + final boolean[] data1 = new boolean[] { false, false }; + store.visitClassExecution(new ExecutionData(1000, "Sample", data1)); + final boolean[] data2 = new boolean[] { false, false, false }; + store.visitClassExecution(new ExecutionData(1000, "Sample", data2)); + } + + @Test + public void testReset() throws InstantiationException, + IllegalAccessException { + final boolean[] data1 = new boolean[] { true, true, false }; + store.put(new ExecutionData(1000, "Sample", data1)); + store.reset(); + final boolean[] data2 = store.get(1000).getData(); + assertNotNull(data2); + assertFalse(data2[0]); + assertFalse(data2[1]); + assertFalse(data2[2]); + } + + // === IExecutionDataOutput === + + public void visitClassExecution(final ExecutionData data) { + dataOutput.put(Long.valueOf(data.getId()), data); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataTest.java index 27337d2f..0ee8b8f5 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataTest.java @@ -1,113 +1,113 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link ExecutionData}.
- */
-public class ExecutionDataTest {
-
- @Test
- public void testCreateEmpty() {
- final ExecutionData e = new ExecutionData(5, "Example", 3);
- assertEquals(5, e.getId());
- assertEquals("Example", e.getName());
- assertEquals(3, e.getData().length);
- assertFalse(e.getData()[0]);
- assertFalse(e.getData()[1]);
- assertFalse(e.getData()[2]);
- }
-
- @Test
- public void testGetters() {
- final boolean[] data = new boolean[0];
- final ExecutionData e = new ExecutionData(5, "Example", data);
- assertEquals(5, e.getId());
- assertEquals("Example", e.getName());
- assertSame(data, e.getData());
- }
-
- @Test
- public void testReset() {
- final ExecutionData e = new ExecutionData(5, "Example", new boolean[] {
- true, false, true });
- e.reset();
- assertFalse(e.getData()[0]);
- assertFalse(e.getData()[1]);
- assertFalse(e.getData()[2]);
- }
-
- @Test
- public void testMerge() {
- final ExecutionData a = new ExecutionData(5, "Example", new boolean[] {
- false, true, false, true });
- final ExecutionData b = new ExecutionData(5, "Example", new boolean[] {
- false, false, true, true });
- a.merge(b);
-
- // b is merged into a:
- assertFalse(a.getData()[0]);
- assertTrue(a.getData()[1]);
- assertTrue(a.getData()[2]);
- assertTrue(a.getData()[3]);
-
- // b must not be modified:
- assertFalse(b.getData()[0]);
- assertFalse(b.getData()[1]);
- assertTrue(b.getData()[2]);
- assertTrue(b.getData()[3]);
- }
-
- @Test
- public void testAssertCompatibility() {
- final ExecutionData a = new ExecutionData(5, "Example",
- new boolean[] { true });
- a.assertCompatibility(5, "Example", 1);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testAssertCompatibilityNegative1() {
- final ExecutionData a = new ExecutionData(5, "Example",
- new boolean[] { true });
- a.assertCompatibility(55, "Example", 1);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testAssertCompatibilityNegative2() {
- final ExecutionData a = new ExecutionData(5, "Example",
- new boolean[] { true });
- a.assertCompatibility(5, "Exxxample", 1);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testAssertCompatibilityNegative3() {
- final ExecutionData a = new ExecutionData(5, "Example",
- new boolean[] { true });
- a.assertCompatibility(5, "Example", 3);
- }
-
- @Test
- public void testToString() {
- final ExecutionData a = new ExecutionData(Long.MAX_VALUE, "Example",
- new boolean[] { true });
- assertEquals("ExecutionData [name=Example, id=7fffffffffffffff]",
- a.toString());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.data; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Unit tests for {@link ExecutionData}. + */ +public class ExecutionDataTest { + + @Test + public void testCreateEmpty() { + final ExecutionData e = new ExecutionData(5, "Example", 3); + assertEquals(5, e.getId()); + assertEquals("Example", e.getName()); + assertEquals(3, e.getData().length); + assertFalse(e.getData()[0]); + assertFalse(e.getData()[1]); + assertFalse(e.getData()[2]); + } + + @Test + public void testGetters() { + final boolean[] data = new boolean[0]; + final ExecutionData e = new ExecutionData(5, "Example", data); + assertEquals(5, e.getId()); + assertEquals("Example", e.getName()); + assertSame(data, e.getData()); + } + + @Test + public void testReset() { + final ExecutionData e = new ExecutionData(5, "Example", new boolean[] { + true, false, true }); + e.reset(); + assertFalse(e.getData()[0]); + assertFalse(e.getData()[1]); + assertFalse(e.getData()[2]); + } + + @Test + public void testMerge() { + final ExecutionData a = new ExecutionData(5, "Example", new boolean[] { + false, true, false, true }); + final ExecutionData b = new ExecutionData(5, "Example", new boolean[] { + false, false, true, true }); + a.merge(b); + + // b is merged into a: + assertFalse(a.getData()[0]); + assertTrue(a.getData()[1]); + assertTrue(a.getData()[2]); + assertTrue(a.getData()[3]); + + // b must not be modified: + assertFalse(b.getData()[0]); + assertFalse(b.getData()[1]); + assertTrue(b.getData()[2]); + assertTrue(b.getData()[3]); + } + + @Test + public void testAssertCompatibility() { + final ExecutionData a = new ExecutionData(5, "Example", + new boolean[] { true }); + a.assertCompatibility(5, "Example", 1); + } + + @Test(expected = IllegalStateException.class) + public void testAssertCompatibilityNegative1() { + final ExecutionData a = new ExecutionData(5, "Example", + new boolean[] { true }); + a.assertCompatibility(55, "Example", 1); + } + + @Test(expected = IllegalStateException.class) + public void testAssertCompatibilityNegative2() { + final ExecutionData a = new ExecutionData(5, "Example", + new boolean[] { true }); + a.assertCompatibility(5, "Exxxample", 1); + } + + @Test(expected = IllegalStateException.class) + public void testAssertCompatibilityNegative3() { + final ExecutionData a = new ExecutionData(5, "Example", + new boolean[] { true }); + a.assertCompatibility(5, "Example", 3); + } + + @Test + public void testToString() { + final ExecutionData a = new ExecutionData(Long.MAX_VALUE, "Example", + new boolean[] { true }); + assertEquals("ExecutionData [name=Example, id=7fffffffffffffff]", + a.toString()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/MethodRecorder.java b/org.jacoco.core.test/src/org/jacoco/core/instr/MethodRecorder.java index 9b99497e..f4aad7ed 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/instr/MethodRecorder.java +++ b/org.jacoco.core.test/src/org/jacoco/core/instr/MethodRecorder.java @@ -1,46 +1,46 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.instr;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-import org.objectweb.asm.util.TraceMethodVisitor;
-
-/**
- * Recorder of method events for test verification.
- */
-public class MethodRecorder extends TraceMethodVisitor {
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof MethodRecorder)) {
- return false;
- }
- MethodRecorder that = (MethodRecorder) obj;
- return text.equals(that.text);
- }
-
- @Override
- public int hashCode() {
- return text.hashCode();
- }
-
- @Override
- public String toString() {
- StringWriter buffer = new StringWriter();
- PrintWriter printer = new PrintWriter(buffer);
- print(printer);
- printer.flush();
- return buffer.toString();
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.instr; + +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.objectweb.asm.util.TraceMethodVisitor; + +/** + * Recorder of method events for test verification. + */ +public class MethodRecorder extends TraceMethodVisitor { + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof MethodRecorder)) { + return false; + } + MethodRecorder that = (MethodRecorder) obj; + return text.equals(that.text); + } + + @Override + public int hashCode() { + return text.hashCode(); + } + + @Override + public String toString() { + StringWriter buffer = new StringWriter(); + PrintWriter printer = new PrintWriter(buffer); + print(printer); + printer.flush(); + return buffer.toString(); + } +} 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 439ae59e..efb222dc 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 @@ -1,124 +1,124 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.IPackageCoverage;
-import org.jacoco.core.analysis.ISourceFileCoverage;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link BundleCoverageImpl}.
- */
-public class BundleCoverageImplTest {
-
- @Test
- public void testProperties() {
- Collection<IClassCoverage> classes = Collections.emptySet();
- Collection<ISourceFileCoverage> sourcefiles = Collections.emptySet();
- Collection<IPackageCoverage> packages = Collections
- .singleton((IPackageCoverage) new PackageCoverageImpl("p1",
- classes, sourcefiles));
- BundleCoverageImpl bundle = new BundleCoverageImpl("testbundle",
- packages);
- assertEquals(ICoverageNode.ElementType.BUNDLE, bundle.getElementType());
- assertEquals("testbundle", bundle.getName());
- assertEquals(packages, bundle.getPackages());
- }
-
- @Test
- public void testCounters() {
- Collection<IClassCoverage> classes = Collections.emptySet();
- Collection<ISourceFileCoverage> sourcefiles = Collections.emptySet();
- final IPackageCoverage p1 = new PackageCoverageImpl("p1", classes,
- sourcefiles) {
- {
- classCounter = CounterImpl.getInstance(1, 0);
- methodCounter = CounterImpl.getInstance(2, 0);
- branchCounter = CounterImpl.getInstance(3, 0);
- instructionCounter = CounterImpl.getInstance(4, 0);
- lineCounter = CounterImpl.getInstance(5, 0);
- }
- };
- final IPackageCoverage p2 = new PackageCoverageImpl("p1", classes,
- sourcefiles) {
- {
- classCounter = CounterImpl.getInstance(1, 0);
- methodCounter = CounterImpl.getInstance(2, 0);
- branchCounter = CounterImpl.getInstance(3, 0);
- instructionCounter = CounterImpl.getInstance(4, 0);
- lineCounter = CounterImpl.getInstance(5, 0);
- }
- };
- BundleCoverageImpl bundle = new BundleCoverageImpl("testbundle",
- Arrays.asList(p1, p2));
- assertEquals(CounterImpl.getInstance(2, 0), bundle.getClassCounter());
- assertEquals(CounterImpl.getInstance(4, 0), bundle.getMethodCounter());
- assertEquals(CounterImpl.getInstance(6, 0), bundle.getBranchCounter());
- assertEquals(CounterImpl.getInstance(8, 0),
- bundle.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(10, 0), bundle.getLineCounter());
- }
-
- @Test
- public void testGroupByPackage() {
- ClassCoverageImpl ca = new ClassCoverageImpl("p1/A", 1, null,
- "java/lang/Object", new String[0]);
- ca.setSourceFileName("A.java");
- ClassCoverageImpl cb = new ClassCoverageImpl("p2/B", 2, null,
- "java/lang/Object", new String[0]);
- cb.setSourceFileName("B.java");
- ISourceFileCoverage sb = new SourceFileCoverageImpl("B.java", "p2");
- ISourceFileCoverage sc = new SourceFileCoverageImpl("C.java", "p3");
- BundleCoverageImpl bundle = new BundleCoverageImpl("bundle",
- Arrays.asList((IClassCoverage) ca, (IClassCoverage) cb),
- Arrays.asList(sb, sc));
-
- Collection<IPackageCoverage> packages = bundle.getPackages();
- assertEquals(3, packages.size(), 0.0);
-
- IPackageCoverage p1 = findPackage("p1", packages);
- assertNotNull(p1);
- assertEquals(Collections.singletonList(ca), p1.getClasses());
- assertTrue(p1.getSourceFiles().isEmpty());
-
- IPackageCoverage p2 = findPackage("p2", packages);
- assertNotNull(p2);
- assertEquals(Collections.singletonList(cb), p2.getClasses());
- assertEquals(Collections.singletonList(sb), p2.getSourceFiles());
-
- IPackageCoverage p3 = findPackage("p3", packages);
- assertNotNull(p3);
- assertTrue(p3.getClasses().isEmpty());
- assertEquals(Collections.singletonList(sc), p3.getSourceFiles());
- }
-
- private IPackageCoverage findPackage(String name,
- Collection<IPackageCoverage> packages) {
- for (IPackageCoverage p : packages) {
- if (name.equals(p.getName())) {
- return p;
- }
- }
- return null;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.IPackageCoverage; +import org.jacoco.core.analysis.ISourceFileCoverage; +import org.junit.Test; + +/** + * Unit tests for {@link BundleCoverageImpl}. + */ +public class BundleCoverageImplTest { + + @Test + public void testProperties() { + Collection<IClassCoverage> classes = Collections.emptySet(); + Collection<ISourceFileCoverage> sourcefiles = Collections.emptySet(); + Collection<IPackageCoverage> packages = Collections + .singleton((IPackageCoverage) new PackageCoverageImpl("p1", + classes, sourcefiles)); + BundleCoverageImpl bundle = new BundleCoverageImpl("testbundle", + packages); + assertEquals(ICoverageNode.ElementType.BUNDLE, bundle.getElementType()); + assertEquals("testbundle", bundle.getName()); + assertEquals(packages, bundle.getPackages()); + } + + @Test + public void testCounters() { + Collection<IClassCoverage> classes = Collections.emptySet(); + Collection<ISourceFileCoverage> sourcefiles = Collections.emptySet(); + final IPackageCoverage p1 = new PackageCoverageImpl("p1", classes, + sourcefiles) { + { + classCounter = CounterImpl.getInstance(1, 0); + methodCounter = CounterImpl.getInstance(2, 0); + branchCounter = CounterImpl.getInstance(3, 0); + instructionCounter = CounterImpl.getInstance(4, 0); + lineCounter = CounterImpl.getInstance(5, 0); + } + }; + final IPackageCoverage p2 = new PackageCoverageImpl("p1", classes, + sourcefiles) { + { + classCounter = CounterImpl.getInstance(1, 0); + methodCounter = CounterImpl.getInstance(2, 0); + branchCounter = CounterImpl.getInstance(3, 0); + instructionCounter = CounterImpl.getInstance(4, 0); + lineCounter = CounterImpl.getInstance(5, 0); + } + }; + BundleCoverageImpl bundle = new BundleCoverageImpl("testbundle", + Arrays.asList(p1, p2)); + assertEquals(CounterImpl.getInstance(2, 0), bundle.getClassCounter()); + assertEquals(CounterImpl.getInstance(4, 0), bundle.getMethodCounter()); + assertEquals(CounterImpl.getInstance(6, 0), bundle.getBranchCounter()); + assertEquals(CounterImpl.getInstance(8, 0), + bundle.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(10, 0), bundle.getLineCounter()); + } + + @Test + public void testGroupByPackage() { + ClassCoverageImpl ca = new ClassCoverageImpl("p1/A", 1, null, + "java/lang/Object", new String[0]); + ca.setSourceFileName("A.java"); + ClassCoverageImpl cb = new ClassCoverageImpl("p2/B", 2, null, + "java/lang/Object", new String[0]); + cb.setSourceFileName("B.java"); + ISourceFileCoverage sb = new SourceFileCoverageImpl("B.java", "p2"); + ISourceFileCoverage sc = new SourceFileCoverageImpl("C.java", "p3"); + BundleCoverageImpl bundle = new BundleCoverageImpl("bundle", + Arrays.asList((IClassCoverage) ca, (IClassCoverage) cb), + Arrays.asList(sb, sc)); + + Collection<IPackageCoverage> packages = bundle.getPackages(); + assertEquals(3, packages.size(), 0.0); + + IPackageCoverage p1 = findPackage("p1", packages); + assertNotNull(p1); + assertEquals(Collections.singletonList(ca), p1.getClasses()); + assertTrue(p1.getSourceFiles().isEmpty()); + + IPackageCoverage p2 = findPackage("p2", packages); + assertNotNull(p2); + assertEquals(Collections.singletonList(cb), p2.getClasses()); + assertEquals(Collections.singletonList(sb), p2.getSourceFiles()); + + IPackageCoverage p3 = findPackage("p3", packages); + assertNotNull(p3); + assertTrue(p3.getClasses().isEmpty()); + assertEquals(Collections.singletonList(sc), p3.getSourceFiles()); + } + + private IPackageCoverage findPackage(String name, + Collection<IPackageCoverage> packages) { + for (IPackageCoverage p : packages) { + if (name.equals(p.getName())) { + return p; + } + } + return 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 e8a773e0..03aa2c1e 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 @@ -1,94 +1,94 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.junit.Assert.assertEquals;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ISourceNode;
-import org.junit.Test;
-
-/**
- * Unit test for {@link ClassCoverageImpl}.
- */
-public class ClassCoverageImplTest {
-
- @Test
- public void testProperties() {
- ClassCoverageImpl data = new ClassCoverageImpl("Sample", 12345,
- "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());
- assertEquals("LSample;", data.getSignature());
- assertEquals("java/lang/Object", data.getSuperName());
- assertEquals(0, data.getInterfaceNames().length);
- assertEquals("Sample.java", data.getSourceFileName());
- }
-
- @Test
- public void testGetPackageName1() {
- ClassCoverageImpl data = new ClassCoverageImpl("ClassInDefaultPackage",
- 0, 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]);
- assertEquals("org/jacoco/examples", data.getPackageName());
- }
-
- @Test
- public void testEmptyClass() {
- ICoverageNode data = new ClassCoverageImpl("Sample", 0, null,
- "java/lang/Object", new String[0]);
- assertEquals(CounterImpl.COUNTER_0_0, data.getInstructionCounter());
- assertEquals(CounterImpl.COUNTER_0_0, data.getBranchCounter());
- assertEquals(CounterImpl.COUNTER_0_0, data.getMethodCounter());
- assertEquals(CounterImpl.COUNTER_1_0, data.getClassCounter());
- }
-
- @Test
- public void testAddMethodMissed() {
- ClassCoverageImpl data = new ClassCoverageImpl("Sample", 0, 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());
- assertEquals(CounterImpl.COUNTER_1_0, data.getClassCounter());
- }
-
- @Test
- public void testAddMethodCovered() {
- ClassCoverageImpl data = new ClassCoverageImpl("Sample", 0, 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());
- assertEquals(CounterImpl.COUNTER_0_1, data.getClassCounter());
- }
-
- private MethodCoverageImpl createMethod(boolean covered) {
- final MethodCoverageImpl m = new MethodCoverageImpl("sample", "()V",
- null);
- m.increment(
- covered ? CounterImpl.COUNTER_0_1 : CounterImpl.COUNTER_1_0,
- CounterImpl.COUNTER_0_0, ISourceNode.UNKNOWN_LINE);
- m.incrementMethodCounter();
- return m;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.junit.Assert.assertEquals; + +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ISourceNode; +import org.junit.Test; + +/** + * Unit test for {@link ClassCoverageImpl}. + */ +public class ClassCoverageImplTest { + + @Test + public void testProperties() { + ClassCoverageImpl data = new ClassCoverageImpl("Sample", 12345, + "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()); + assertEquals("LSample;", data.getSignature()); + assertEquals("java/lang/Object", data.getSuperName()); + assertEquals(0, data.getInterfaceNames().length); + assertEquals("Sample.java", data.getSourceFileName()); + } + + @Test + public void testGetPackageName1() { + ClassCoverageImpl data = new ClassCoverageImpl("ClassInDefaultPackage", + 0, 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]); + assertEquals("org/jacoco/examples", data.getPackageName()); + } + + @Test + public void testEmptyClass() { + ICoverageNode data = new ClassCoverageImpl("Sample", 0, null, + "java/lang/Object", new String[0]); + assertEquals(CounterImpl.COUNTER_0_0, data.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_0, data.getBranchCounter()); + assertEquals(CounterImpl.COUNTER_0_0, data.getMethodCounter()); + assertEquals(CounterImpl.COUNTER_1_0, data.getClassCounter()); + } + + @Test + public void testAddMethodMissed() { + ClassCoverageImpl data = new ClassCoverageImpl("Sample", 0, 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()); + assertEquals(CounterImpl.COUNTER_1_0, data.getClassCounter()); + } + + @Test + public void testAddMethodCovered() { + ClassCoverageImpl data = new ClassCoverageImpl("Sample", 0, 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()); + assertEquals(CounterImpl.COUNTER_0_1, data.getClassCounter()); + } + + private MethodCoverageImpl createMethod(boolean covered) { + final MethodCoverageImpl m = new MethodCoverageImpl("sample", "()V", + null); + m.increment( + covered ? CounterImpl.COUNTER_0_1 : CounterImpl.COUNTER_1_0, + CounterImpl.COUNTER_0_0, ISourceNode.UNKNOWN_LINE); + m.incrementMethodCounter(); + return m; + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ContentTypeDetectorTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ContentTypeDetectorTest.java index bb9f1acb..c89058c1 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ContentTypeDetectorTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ContentTypeDetectorTest.java @@ -1,161 +1,161 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-
-import org.jacoco.core.test.TargetLoader;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link ContentTypeDetector}.
- */
-public class ContentTypeDetectorTest {
-
- private byte[] data;
-
- private ContentTypeDetector detector;
-
- @Test
- public void testEmptyStream() throws IOException {
- initData();
- assertEquals(ContentTypeDetector.UNKNOWN, detector.getType());
- assertContent();
- }
-
- @Test
- public void testClassFile() throws IOException {
- initData(TargetLoader
- .getClassDataAsBytes(ContentTypeDetectorTest.class));
- assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
- assertContent();
- }
-
- @Test
- public void testClassFile11() throws IOException {
- initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x03, 0x00, 0x2D);
- assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
- assertContent();
- }
-
- @Test
- public void testClassFile12() throws IOException {
- initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x2E);
- assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
- assertContent();
- }
-
- @Test
- public void testClassFile13() throws IOException {
- initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x2F);
- assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
- assertContent();
- }
-
- @Test
- public void testClassFile14() throws IOException {
- initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x30);
- assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
- assertContent();
- }
-
- @Test
- public void testClassFile15() throws IOException {
- initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x31);
- assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
- assertContent();
- }
-
- @Test
- public void testClassFile16() throws IOException {
- initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x32);
- assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
- assertContent();
- }
-
- @Test
- public void testClassFile17() throws IOException {
- initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x33);
- assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
- assertContent();
- }
-
- @Test
- public void testMachObjectFile() throws IOException {
- initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x02);
- assertEquals(ContentTypeDetector.UNKNOWN, detector.getType());
- assertContent();
- }
-
- @Test
- public void testZipFile() throws IOException {
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- final ZipOutputStream zip = new ZipOutputStream(buffer);
- zip.putNextEntry(new ZipEntry("hello.txt"));
- zip.write("Hello Zip!".getBytes());
- zip.close();
- initData(buffer.toByteArray());
- assertEquals(ContentTypeDetector.ZIPFILE, detector.getType());
- assertContent();
- }
-
- @Test
- public void testStreamWithoutMarkSupport() throws IOException {
- initData(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07);
- detector = new ContentTypeDetector(new ByteArrayInputStream(data) {
-
- @Override
- public void mark(int readlimit) {
- }
-
- @Override
- public void reset() {
- }
-
- @Override
- public boolean markSupported() {
- return false;
- }
-
- });
- assertContent();
- }
-
- private void initData(byte[] bytes) throws IOException {
- this.data = bytes;
- this.detector = new ContentTypeDetector(new ByteArrayInputStream(data));
- }
-
- private void initData(final int... bytes) throws IOException {
- byte[] data = new byte[bytes.length];
- for (int i = 0; i < bytes.length; i++) {
- data[i] = (byte) bytes[i];
- }
- initData(data);
- }
-
- private void assertContent() throws IOException {
- final InputStream actual = detector.getInputStream();
- for (int b : data) {
- assertEquals(b, (byte) actual.read());
- }
- assertEquals(-1, actual.read());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.jacoco.core.test.TargetLoader; +import org.junit.Test; + +/** + * Unit tests for {@link ContentTypeDetector}. + */ +public class ContentTypeDetectorTest { + + private byte[] data; + + private ContentTypeDetector detector; + + @Test + public void testEmptyStream() throws IOException { + initData(); + assertEquals(ContentTypeDetector.UNKNOWN, detector.getType()); + assertContent(); + } + + @Test + public void testClassFile() throws IOException { + initData(TargetLoader + .getClassDataAsBytes(ContentTypeDetectorTest.class)); + assertEquals(ContentTypeDetector.CLASSFILE, detector.getType()); + assertContent(); + } + + @Test + public void testClassFile11() throws IOException { + initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x03, 0x00, 0x2D); + assertEquals(ContentTypeDetector.CLASSFILE, detector.getType()); + assertContent(); + } + + @Test + public void testClassFile12() throws IOException { + initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x2E); + assertEquals(ContentTypeDetector.CLASSFILE, detector.getType()); + assertContent(); + } + + @Test + public void testClassFile13() throws IOException { + initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x2F); + assertEquals(ContentTypeDetector.CLASSFILE, detector.getType()); + assertContent(); + } + + @Test + public void testClassFile14() throws IOException { + initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x30); + assertEquals(ContentTypeDetector.CLASSFILE, detector.getType()); + assertContent(); + } + + @Test + public void testClassFile15() throws IOException { + initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x31); + assertEquals(ContentTypeDetector.CLASSFILE, detector.getType()); + assertContent(); + } + + @Test + public void testClassFile16() throws IOException { + initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x32); + assertEquals(ContentTypeDetector.CLASSFILE, detector.getType()); + assertContent(); + } + + @Test + public void testClassFile17() throws IOException { + initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x33); + assertEquals(ContentTypeDetector.CLASSFILE, detector.getType()); + assertContent(); + } + + @Test + public void testMachObjectFile() throws IOException { + initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x02); + assertEquals(ContentTypeDetector.UNKNOWN, detector.getType()); + assertContent(); + } + + @Test + public void testZipFile() throws IOException { + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + final ZipOutputStream zip = new ZipOutputStream(buffer); + zip.putNextEntry(new ZipEntry("hello.txt")); + zip.write("Hello Zip!".getBytes()); + zip.close(); + initData(buffer.toByteArray()); + assertEquals(ContentTypeDetector.ZIPFILE, detector.getType()); + assertContent(); + } + + @Test + public void testStreamWithoutMarkSupport() throws IOException { + initData(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07); + detector = new ContentTypeDetector(new ByteArrayInputStream(data) { + + @Override + public void mark(int readlimit) { + } + + @Override + public void reset() { + } + + @Override + public boolean markSupported() { + return false; + } + + }); + assertContent(); + } + + private void initData(byte[] bytes) throws IOException { + this.data = bytes; + this.detector = new ContentTypeDetector(new ByteArrayInputStream(data)); + } + + private void initData(final int... bytes) throws IOException { + byte[] data = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + data[i] = (byte) bytes[i]; + } + initData(data); + } + + private void assertContent() throws IOException { + final InputStream actual = detector.getInputStream(); + for (int b : data) { + assertEquals(b, (byte) actual.read()); + } + assertEquals(-1, actual.read()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/CounterImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/CounterImplTest.java index 0599f777..6899e489 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/CounterImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/CounterImplTest.java @@ -1,197 +1,197 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import org.jacoco.core.analysis.ICounter;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link CounterImpl}.
- */
-public class CounterImplTest {
-
- @Test
- public void testGetInstance1() {
- ICounter c = CounterImpl.getInstance(0, 0);
- assertEquals(0, c.getTotalCount());
- assertEquals(0, c.getMissedCount());
- assertEquals(0, c.getCoveredCount());
- }
-
- @Test
- public void testGetInstance2() {
- ICounter c = CounterImpl.getInstance(33, 15);
- assertEquals(48, c.getTotalCount());
- assertEquals(33, c.getMissedCount());
- assertEquals(15, c.getCoveredCount());
- }
-
- @Test
- public void testGetInstance3() {
- ICounter c = CounterImpl.getInstance(15, 12);
- ICounter copy = CounterImpl.getInstance(c);
- assertEquals(27, copy.getTotalCount());
- assertEquals(15, copy.getMissedCount());
- assertEquals(12, copy.getCoveredCount());
- }
-
- @Test
- public void testFixInstance() {
- ICounter c1 = CounterImpl.getInstance(30, 30);
- ICounter c2 = CounterImpl.getInstance(30, 30);
- assertSame(c1, c2);
- }
-
- @Test
- public void testVarInstance() {
- ICounter c1 = CounterImpl.getInstance(31, 30);
- ICounter c2 = CounterImpl.getInstance(31, 30);
- assertNotSame(c1, c2);
- }
-
- @Test
- public void testIncrement1() {
- CounterImpl c = CounterImpl.getInstance(1, 1);
- c = c.increment(CounterImpl.getInstance(2, 1));
- assertEquals(3, c.getMissedCount());
- assertEquals(2, c.getCoveredCount());
- }
-
- @Test
- public void testIncrement2() {
- CounterImpl c = CounterImpl.getInstance(31, 5);
- c = c.increment(CounterImpl.getInstance(7, 3));
- assertEquals(38, c.getMissedCount());
- assertEquals(8, c.getCoveredCount());
- }
-
- @Test
- public void testGetCoveredRatio1() {
- ICounter c = CounterImpl.getInstance(30, 10);
- assertEquals(0.25, c.getCoveredRatio(), 0.0);
- }
-
- @Test
- public void testGetCoveredRatio2() {
- ICounter c = CounterImpl.getInstance(20, 0);
- assertEquals(0.0, c.getCoveredRatio(), 0.0);
- }
-
- @Test
- public void testGetCoveredRatio3() {
- ICounter c = CounterImpl.getInstance(0, 0);
- assertTrue(Double.isNaN(c.getCoveredRatio()));
- }
-
- @Test
- public void testGetMissedRatio1() {
- ICounter c = CounterImpl.getInstance(10, 30);
- assertEquals(0.25, c.getMissedRatio(), 0.0);
- }
-
- @Test
- public void testGetMissedRatio2() {
- ICounter c = CounterImpl.getInstance(0, 20);
- assertEquals(0.0, c.getMissedRatio(), 0.0);
- }
-
- @Test
- public void testGetMissedRatio3() {
- ICounter c = CounterImpl.getInstance(0, 0);
- assertTrue(Double.isNaN(c.getMissedRatio()));
- }
-
- @Test
- public void testGetMissedStatus1() {
- ICounter c = CounterImpl.getInstance(0, 0);
- assertEquals(ICounter.EMPTY, c.getStatus());
- }
-
- @Test
- public void testGetMissedStatus2() {
- ICounter c = CounterImpl.getInstance(5, 0);
- assertEquals(ICounter.NOT_COVERED, c.getStatus());
- }
-
- @Test
- public void testGetMissedStatus3() {
- ICounter c = CounterImpl.getInstance(0, 5);
- assertEquals(ICounter.FULLY_COVERED, c.getStatus());
- }
-
- @Test
- public void testGetMissedStatus4() {
- ICounter c = CounterImpl.getInstance(2, 3);
- assertEquals(ICounter.PARTLY_COVERED, c.getStatus());
- }
-
- @Test
- public void testEquals1() {
- ICounter c1 = CounterImpl.getInstance(300, 123);
- ICounter c2 = CounterImpl.getInstance(300, 123);
- assertEquals(c1, c2);
- }
-
- @Test
- public void testEquals2() {
- ICounter c1 = CounterImpl.getInstance(300, 123);
- ICounter c2 = CounterImpl.getInstance(400, 123);
- assertFalse(c1.equals(c2));
- }
-
- @Test
- public void testEquals3() {
- ICounter c1 = CounterImpl.getInstance(300, 123);
- ICounter c2 = CounterImpl.getInstance(300, 124);
- assertFalse(c1.equals(c2));
- }
-
- @Test
- public void testEquals4() {
- ICounter c = CounterImpl.getInstance(300, 123);
- assertFalse(c.equals(new Integer(123)));
- }
-
- @Test
- public void testHashCode1() {
- ICounter c1 = CounterImpl.getInstance(300, 123);
- ICounter c2 = CounterImpl.getInstance(300, 123);
- assertEquals(c1.hashCode(), c2.hashCode());
- }
-
- @Test
- public void testHashCode2() {
- ICounter c1 = CounterImpl.getInstance(300, 123);
- ICounter c2 = CounterImpl.getInstance(400, 123);
- assertFalse(c1.hashCode() == c2.hashCode());
- }
-
- @Test
- public void testHashCode3() {
- ICounter c1 = CounterImpl.getInstance(300, 123);
- ICounter c2 = CounterImpl.getInstance(300, 124);
- assertFalse(c1.hashCode() == c2.hashCode());
- }
-
- @Test
- public void testToString() {
- ICounter c = CounterImpl.getInstance(300, 123);
- assertEquals("Counter[300/123]", c.toString());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.jacoco.core.analysis.ICounter; +import org.junit.Test; + +/** + * Unit tests for {@link CounterImpl}. + */ +public class CounterImplTest { + + @Test + public void testGetInstance1() { + ICounter c = CounterImpl.getInstance(0, 0); + assertEquals(0, c.getTotalCount()); + assertEquals(0, c.getMissedCount()); + assertEquals(0, c.getCoveredCount()); + } + + @Test + public void testGetInstance2() { + ICounter c = CounterImpl.getInstance(33, 15); + assertEquals(48, c.getTotalCount()); + assertEquals(33, c.getMissedCount()); + assertEquals(15, c.getCoveredCount()); + } + + @Test + public void testGetInstance3() { + ICounter c = CounterImpl.getInstance(15, 12); + ICounter copy = CounterImpl.getInstance(c); + assertEquals(27, copy.getTotalCount()); + assertEquals(15, copy.getMissedCount()); + assertEquals(12, copy.getCoveredCount()); + } + + @Test + public void testFixInstance() { + ICounter c1 = CounterImpl.getInstance(30, 30); + ICounter c2 = CounterImpl.getInstance(30, 30); + assertSame(c1, c2); + } + + @Test + public void testVarInstance() { + ICounter c1 = CounterImpl.getInstance(31, 30); + ICounter c2 = CounterImpl.getInstance(31, 30); + assertNotSame(c1, c2); + } + + @Test + public void testIncrement1() { + CounterImpl c = CounterImpl.getInstance(1, 1); + c = c.increment(CounterImpl.getInstance(2, 1)); + assertEquals(3, c.getMissedCount()); + assertEquals(2, c.getCoveredCount()); + } + + @Test + public void testIncrement2() { + CounterImpl c = CounterImpl.getInstance(31, 5); + c = c.increment(CounterImpl.getInstance(7, 3)); + assertEquals(38, c.getMissedCount()); + assertEquals(8, c.getCoveredCount()); + } + + @Test + public void testGetCoveredRatio1() { + ICounter c = CounterImpl.getInstance(30, 10); + assertEquals(0.25, c.getCoveredRatio(), 0.0); + } + + @Test + public void testGetCoveredRatio2() { + ICounter c = CounterImpl.getInstance(20, 0); + assertEquals(0.0, c.getCoveredRatio(), 0.0); + } + + @Test + public void testGetCoveredRatio3() { + ICounter c = CounterImpl.getInstance(0, 0); + assertTrue(Double.isNaN(c.getCoveredRatio())); + } + + @Test + public void testGetMissedRatio1() { + ICounter c = CounterImpl.getInstance(10, 30); + assertEquals(0.25, c.getMissedRatio(), 0.0); + } + + @Test + public void testGetMissedRatio2() { + ICounter c = CounterImpl.getInstance(0, 20); + assertEquals(0.0, c.getMissedRatio(), 0.0); + } + + @Test + public void testGetMissedRatio3() { + ICounter c = CounterImpl.getInstance(0, 0); + assertTrue(Double.isNaN(c.getMissedRatio())); + } + + @Test + public void testGetMissedStatus1() { + ICounter c = CounterImpl.getInstance(0, 0); + assertEquals(ICounter.EMPTY, c.getStatus()); + } + + @Test + public void testGetMissedStatus2() { + ICounter c = CounterImpl.getInstance(5, 0); + assertEquals(ICounter.NOT_COVERED, c.getStatus()); + } + + @Test + public void testGetMissedStatus3() { + ICounter c = CounterImpl.getInstance(0, 5); + assertEquals(ICounter.FULLY_COVERED, c.getStatus()); + } + + @Test + public void testGetMissedStatus4() { + ICounter c = CounterImpl.getInstance(2, 3); + assertEquals(ICounter.PARTLY_COVERED, c.getStatus()); + } + + @Test + public void testEquals1() { + ICounter c1 = CounterImpl.getInstance(300, 123); + ICounter c2 = CounterImpl.getInstance(300, 123); + assertEquals(c1, c2); + } + + @Test + public void testEquals2() { + ICounter c1 = CounterImpl.getInstance(300, 123); + ICounter c2 = CounterImpl.getInstance(400, 123); + assertFalse(c1.equals(c2)); + } + + @Test + public void testEquals3() { + ICounter c1 = CounterImpl.getInstance(300, 123); + ICounter c2 = CounterImpl.getInstance(300, 124); + assertFalse(c1.equals(c2)); + } + + @Test + public void testEquals4() { + ICounter c = CounterImpl.getInstance(300, 123); + assertFalse(c.equals(new Integer(123))); + } + + @Test + public void testHashCode1() { + ICounter c1 = CounterImpl.getInstance(300, 123); + ICounter c2 = CounterImpl.getInstance(300, 123); + assertEquals(c1.hashCode(), c2.hashCode()); + } + + @Test + public void testHashCode2() { + ICounter c1 = CounterImpl.getInstance(300, 123); + ICounter c2 = CounterImpl.getInstance(400, 123); + assertFalse(c1.hashCode() == c2.hashCode()); + } + + @Test + public void testHashCode3() { + ICounter c1 = CounterImpl.getInstance(300, 123); + ICounter c2 = CounterImpl.getInstance(300, 124); + assertFalse(c1.hashCode() == c2.hashCode()); + } + + @Test + public void testToString() { + ICounter c = CounterImpl.getInstance(300, 123); + assertEquals("Counter[300/123]", c.toString()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/LineImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/LineImplTest.java index 7b0c4e01..c89c6ec5 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/LineImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/LineImplTest.java @@ -1,177 +1,177 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-import org.jacoco.core.analysis.ICounter;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link LineImplTest}.
- */
-public class LineImplTest {
-
- private LineImpl line;
-
- @Before
- public void setup() {
- line = LineImpl.EMPTY;
- }
-
- @Test
- public void testEMPTY() {
- assertEquals(CounterImpl.COUNTER_0_0, line.getInstructionCounter());
- assertEquals(CounterImpl.COUNTER_0_0, line.getBranchCounter());
- assertEquals(ICounter.EMPTY, line.getStatus());
- }
-
- @Test
- public void testIncrement1() {
- line = line.increment(CounterImpl.getInstance(1, 2),
- CounterImpl.getInstance(3, 4));
- assertEquals(CounterImpl.getInstance(1, 2),
- line.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(3, 4), line.getBranchCounter());
- }
-
- @Test
- public void testIncrement2() {
- line = line.increment(CounterImpl.getInstance(1, 2),
- CounterImpl.getInstance(3, 4000));
- assertEquals(CounterImpl.getInstance(1, 2),
- line.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(3, 4000), line.getBranchCounter());
- }
-
- @Test
- public void testIncrement3() {
- line = line.increment(CounterImpl.getInstance(1, 2),
- CounterImpl.getInstance(3000, 4000));
- assertEquals(CounterImpl.getInstance(1, 2),
- line.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(3000, 4000),
- line.getBranchCounter());
- }
-
- @Test
- public void testIncrement4() {
- line = line.increment(CounterImpl.getInstance(1, 2000),
- CounterImpl.getInstance(3000, 4000));
- assertEquals(CounterImpl.getInstance(1, 2000),
- line.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(3000, 4000),
- line.getBranchCounter());
- }
-
- @Test
- public void testIncrement5() {
- line = line.increment(CounterImpl.getInstance(1000, 2000),
- CounterImpl.getInstance(3000, 4000));
- assertEquals(CounterImpl.getInstance(1000, 2000),
- line.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(3000, 4000),
- line.getBranchCounter());
- }
-
- @Test
- public void testGetStatus1() {
- line = line.increment(CounterImpl.getInstance(1, 0),
- CounterImpl.getInstance(0, 0));
- assertEquals(ICounter.NOT_COVERED, line.getStatus());
- }
-
- @Test
- public void testGetStatus2() {
- line = line.increment(CounterImpl.getInstance(0, 0),
- CounterImpl.getInstance(1, 0));
- assertEquals(ICounter.NOT_COVERED, line.getStatus());
- }
-
- @Test
- public void testGetStatus3() {
- line = line.increment(CounterImpl.getInstance(0, 1),
- CounterImpl.getInstance(0, 0));
- assertEquals(ICounter.FULLY_COVERED, line.getStatus());
- }
-
- @Test
- public void testGetStatus4() {
- line = line.increment(CounterImpl.getInstance(0, 0),
- CounterImpl.getInstance(0, 1));
- assertEquals(ICounter.FULLY_COVERED, line.getStatus());
- }
-
- @Test
- public void testGetStatus5() {
- line = line.increment(CounterImpl.getInstance(1, 1),
- CounterImpl.getInstance(0, 0));
- assertEquals(ICounter.PARTLY_COVERED, line.getStatus());
- }
-
- @Test
- public void testGetStatus6() {
- line = line.increment(CounterImpl.getInstance(0, 1),
- CounterImpl.getInstance(1, 1));
- assertEquals(ICounter.PARTLY_COVERED, line.getStatus());
- }
-
- @Test
- public void testHashCode() {
- line = line.increment(CounterImpl.getInstance(111, 222),
- CounterImpl.getInstance(333, 444));
- LineImpl line2 = LineImpl.EMPTY;
- line2 = line2.increment(CounterImpl.getInstance(111, 222),
- CounterImpl.getInstance(333, 444));
- assertEquals(line.hashCode(), line2.hashCode());
- }
-
- @Test
- public void testEquals1() {
- line = line.increment(CounterImpl.getInstance(111, 222),
- CounterImpl.getInstance(333, 444));
- LineImpl line2 = LineImpl.EMPTY;
- line2 = line2.increment(CounterImpl.getInstance(111, 222),
- CounterImpl.getInstance(333, 444));
- assertEquals(line, line2);
- }
-
- @Test
- public void testEquals2() {
- line = line.increment(CounterImpl.getInstance(111, 222),
- CounterImpl.getInstance(333, 444));
- assertFalse(line.equals(new Object()));
- }
-
- @Test
- public void testEquals3() {
- line = line.increment(CounterImpl.getInstance(111, 222),
- CounterImpl.getInstance(333, 444));
- LineImpl line2 = LineImpl.EMPTY;
- line2 = line2.increment(CounterImpl.getInstance(111, 2220),
- CounterImpl.getInstance(333, 444));
- assertFalse(line.equals(line2));
- }
-
- @Test
- public void testEquals4() {
- line = line.increment(CounterImpl.getInstance(111, 222),
- CounterImpl.getInstance(333, 4440));
- LineImpl line2 = LineImpl.EMPTY;
- line2 = line2.increment(CounterImpl.getInstance(111, 222),
- CounterImpl.getInstance(333, 444));
- assertFalse(line.equals(line2));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.jacoco.core.analysis.ICounter; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link LineImplTest}. + */ +public class LineImplTest { + + private LineImpl line; + + @Before + public void setup() { + line = LineImpl.EMPTY; + } + + @Test + public void testEMPTY() { + assertEquals(CounterImpl.COUNTER_0_0, line.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_0, line.getBranchCounter()); + assertEquals(ICounter.EMPTY, line.getStatus()); + } + + @Test + public void testIncrement1() { + line = line.increment(CounterImpl.getInstance(1, 2), + CounterImpl.getInstance(3, 4)); + assertEquals(CounterImpl.getInstance(1, 2), + line.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(3, 4), line.getBranchCounter()); + } + + @Test + public void testIncrement2() { + line = line.increment(CounterImpl.getInstance(1, 2), + CounterImpl.getInstance(3, 4000)); + assertEquals(CounterImpl.getInstance(1, 2), + line.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(3, 4000), line.getBranchCounter()); + } + + @Test + public void testIncrement3() { + line = line.increment(CounterImpl.getInstance(1, 2), + CounterImpl.getInstance(3000, 4000)); + assertEquals(CounterImpl.getInstance(1, 2), + line.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(3000, 4000), + line.getBranchCounter()); + } + + @Test + public void testIncrement4() { + line = line.increment(CounterImpl.getInstance(1, 2000), + CounterImpl.getInstance(3000, 4000)); + assertEquals(CounterImpl.getInstance(1, 2000), + line.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(3000, 4000), + line.getBranchCounter()); + } + + @Test + public void testIncrement5() { + line = line.increment(CounterImpl.getInstance(1000, 2000), + CounterImpl.getInstance(3000, 4000)); + assertEquals(CounterImpl.getInstance(1000, 2000), + line.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(3000, 4000), + line.getBranchCounter()); + } + + @Test + public void testGetStatus1() { + line = line.increment(CounterImpl.getInstance(1, 0), + CounterImpl.getInstance(0, 0)); + assertEquals(ICounter.NOT_COVERED, line.getStatus()); + } + + @Test + public void testGetStatus2() { + line = line.increment(CounterImpl.getInstance(0, 0), + CounterImpl.getInstance(1, 0)); + assertEquals(ICounter.NOT_COVERED, line.getStatus()); + } + + @Test + public void testGetStatus3() { + line = line.increment(CounterImpl.getInstance(0, 1), + CounterImpl.getInstance(0, 0)); + assertEquals(ICounter.FULLY_COVERED, line.getStatus()); + } + + @Test + public void testGetStatus4() { + line = line.increment(CounterImpl.getInstance(0, 0), + CounterImpl.getInstance(0, 1)); + assertEquals(ICounter.FULLY_COVERED, line.getStatus()); + } + + @Test + public void testGetStatus5() { + line = line.increment(CounterImpl.getInstance(1, 1), + CounterImpl.getInstance(0, 0)); + assertEquals(ICounter.PARTLY_COVERED, line.getStatus()); + } + + @Test + public void testGetStatus6() { + line = line.increment(CounterImpl.getInstance(0, 1), + CounterImpl.getInstance(1, 1)); + assertEquals(ICounter.PARTLY_COVERED, line.getStatus()); + } + + @Test + public void testHashCode() { + line = line.increment(CounterImpl.getInstance(111, 222), + CounterImpl.getInstance(333, 444)); + LineImpl line2 = LineImpl.EMPTY; + line2 = line2.increment(CounterImpl.getInstance(111, 222), + CounterImpl.getInstance(333, 444)); + assertEquals(line.hashCode(), line2.hashCode()); + } + + @Test + public void testEquals1() { + line = line.increment(CounterImpl.getInstance(111, 222), + CounterImpl.getInstance(333, 444)); + LineImpl line2 = LineImpl.EMPTY; + line2 = line2.increment(CounterImpl.getInstance(111, 222), + CounterImpl.getInstance(333, 444)); + assertEquals(line, line2); + } + + @Test + public void testEquals2() { + line = line.increment(CounterImpl.getInstance(111, 222), + CounterImpl.getInstance(333, 444)); + assertFalse(line.equals(new Object())); + } + + @Test + public void testEquals3() { + line = line.increment(CounterImpl.getInstance(111, 222), + CounterImpl.getInstance(333, 444)); + LineImpl line2 = LineImpl.EMPTY; + line2 = line2.increment(CounterImpl.getInstance(111, 2220), + CounterImpl.getInstance(333, 444)); + assertFalse(line.equals(line2)); + } + + @Test + public void testEquals4() { + line = line.increment(CounterImpl.getInstance(111, 222), + CounterImpl.getInstance(333, 4440)); + LineImpl line2 = LineImpl.EMPTY; + line2 = line2.increment(CounterImpl.getInstance(111, 222), + CounterImpl.getInstance(333, 444)); + assertFalse(line.equals(line2)); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageImplTest.java index c3a2aeba..bf73cb15 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageImplTest.java @@ -1,131 +1,131 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.junit.Assert.assertEquals;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.junit.Test;
-
-/**
- * Unit test for {@link MethodCoverageImpl}.
- */
-public class MethodCoverageImplTest {
-
- @Test
- public void testProperties() {
- // Example: java.util.Collections.emptySet()
- MethodCoverageImpl node = new MethodCoverageImpl("emptySet",
- "()Ljava/util/Set;",
- "<T:Ljava/lang/Object;>()Ljava/util/Set<TT;>;");
- assertEquals(ICoverageNode.ElementType.METHOD, node.getElementType());
- assertEquals("emptySet", node.getName());
- assertEquals("()Ljava/util/Set;", node.getDesc());
- assertEquals("<T:Ljava/lang/Object;>()Ljava/util/Set<TT;>;",
- node.getSignature());
- }
-
- @Test
- public void testEmptyMethod() {
- ICoverageNode node = new MethodCoverageImpl("sample", "()V", null);
-
- assertEquals(CounterImpl.COUNTER_0_0, node.getInstructionCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getBranchCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getLineCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getComplexityCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getMethodCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getClassCounter());
- }
-
- @Test
- public void testIncrementMissedInstructions() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.getInstance(25, 0), CounterImpl.COUNTER_0_0,
- 3);
- node.incrementMethodCounter();
- assertEquals(CounterImpl.COUNTER_1_0, node.getMethodCounter());
- assertEquals(CounterImpl.COUNTER_1_0, node.getComplexityCounter());
- }
-
- @Test
- public void testIncrementCoveredInstructions() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.getInstance(12, 13),
- CounterImpl.COUNTER_0_0, 3);
- node.incrementMethodCounter();
- assertEquals(CounterImpl.COUNTER_0_1, node.getMethodCounter());
- assertEquals(CounterImpl.COUNTER_0_1, node.getComplexityCounter());
- }
-
- @Test
- public void testIncrementComplexity1() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.COUNTER_0_0, CounterImpl.COUNTER_0_0, 3);
- assertEquals(CounterImpl.COUNTER_0_0, node.getComplexityCounter());
- }
-
- @Test
- public void testIncrementComplexity2() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(2, 0),
- 3);
- assertEquals(CounterImpl.getInstance(1, 0), node.getComplexityCounter());
- }
-
- @Test
- public void testIncrementComplexity3() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(1, 1),
- 3);
- assertEquals(CounterImpl.getInstance(1, 0), node.getComplexityCounter());
- }
-
- @Test
- public void testIncrementComplexity4() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(0, 2),
- 3);
- assertEquals(CounterImpl.getInstance(0, 1), node.getComplexityCounter());
- }
-
- @Test
- public void testIncrementComplexity5() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(3, 0),
- 3);
- assertEquals(CounterImpl.getInstance(2, 0), node.getComplexityCounter());
- }
-
- @Test
- public void testIncrementComplexity6() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(2, 1),
- 3);
- assertEquals(CounterImpl.getInstance(2, 0), node.getComplexityCounter());
- }
-
- @Test
- public void testIncrementComplexity7() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(1, 2),
- 3);
- assertEquals(CounterImpl.getInstance(1, 1), node.getComplexityCounter());
- }
-
- @Test
- public void testIncrementComplexity8() {
- MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null);
- node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(0, 3),
- 3);
- assertEquals(CounterImpl.getInstance(0, 2), node.getComplexityCounter());
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.junit.Assert.assertEquals; + +import org.jacoco.core.analysis.ICoverageNode; +import org.junit.Test; + +/** + * Unit test for {@link MethodCoverageImpl}. + */ +public class MethodCoverageImplTest { + + @Test + public void testProperties() { + // Example: java.util.Collections.emptySet() + MethodCoverageImpl node = new MethodCoverageImpl("emptySet", + "()Ljava/util/Set;", + "<T:Ljava/lang/Object;>()Ljava/util/Set<TT;>;"); + assertEquals(ICoverageNode.ElementType.METHOD, node.getElementType()); + assertEquals("emptySet", node.getName()); + assertEquals("()Ljava/util/Set;", node.getDesc()); + assertEquals("<T:Ljava/lang/Object;>()Ljava/util/Set<TT;>;", + node.getSignature()); + } + + @Test + public void testEmptyMethod() { + ICoverageNode node = new MethodCoverageImpl("sample", "()V", null); + + assertEquals(CounterImpl.COUNTER_0_0, node.getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getBranchCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getLineCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getComplexityCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getMethodCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getClassCounter()); + } + + @Test + public void testIncrementMissedInstructions() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.getInstance(25, 0), CounterImpl.COUNTER_0_0, + 3); + node.incrementMethodCounter(); + assertEquals(CounterImpl.COUNTER_1_0, node.getMethodCounter()); + assertEquals(CounterImpl.COUNTER_1_0, node.getComplexityCounter()); + } + + @Test + public void testIncrementCoveredInstructions() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.getInstance(12, 13), + CounterImpl.COUNTER_0_0, 3); + node.incrementMethodCounter(); + assertEquals(CounterImpl.COUNTER_0_1, node.getMethodCounter()); + assertEquals(CounterImpl.COUNTER_0_1, node.getComplexityCounter()); + } + + @Test + public void testIncrementComplexity1() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_0_0, CounterImpl.COUNTER_0_0, 3); + assertEquals(CounterImpl.COUNTER_0_0, node.getComplexityCounter()); + } + + @Test + public void testIncrementComplexity2() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(2, 0), + 3); + assertEquals(CounterImpl.getInstance(1, 0), node.getComplexityCounter()); + } + + @Test + public void testIncrementComplexity3() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(1, 1), + 3); + assertEquals(CounterImpl.getInstance(1, 0), node.getComplexityCounter()); + } + + @Test + public void testIncrementComplexity4() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(0, 2), + 3); + assertEquals(CounterImpl.getInstance(0, 1), node.getComplexityCounter()); + } + + @Test + public void testIncrementComplexity5() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(3, 0), + 3); + assertEquals(CounterImpl.getInstance(2, 0), node.getComplexityCounter()); + } + + @Test + public void testIncrementComplexity6() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(2, 1), + 3); + assertEquals(CounterImpl.getInstance(2, 0), node.getComplexityCounter()); + } + + @Test + public void testIncrementComplexity7() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(1, 2), + 3); + assertEquals(CounterImpl.getInstance(1, 1), node.getComplexityCounter()); + } + + @Test + public void testIncrementComplexity8() { + MethodCoverageImpl node = new MethodCoverageImpl("sample", "()V", null); + node.increment(CounterImpl.COUNTER_0_0, CounterImpl.getInstance(0, 3), + 3); + assertEquals(CounterImpl.getInstance(0, 2), node.getComplexityCounter()); + } +} 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 e9b49654..7f3e5d2b 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 @@ -1,105 +1,105 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ISourceFileCoverage;
-import org.junit.Test;
-
-/**
- * Unit test for {@link PackageCoverageImpl}.
- */
-public class PackageCoverageTest {
-
- @Test
- public void testProperties() {
- Collection<IClassCoverage> classes = Collections
- .singleton((IClassCoverage) new ClassCoverageImpl(
- "org/jacoco/test/Sample", 0, null, "java/lang/Object",
- new String[0]));
- Collection<ISourceFileCoverage> sourceFiles = Collections
- .singleton((ISourceFileCoverage) new SourceFileCoverageImpl(
- "Sample.java", "org/jacoco/test/Sample"));
- PackageCoverageImpl data = new PackageCoverageImpl("org/jacoco/test",
- classes, sourceFiles);
- assertEquals(ICoverageNode.ElementType.PACKAGE, data.getElementType());
- assertEquals("org/jacoco/test", data.getName());
- assertEquals(classes, data.getClasses());
- assertEquals(sourceFiles, data.getSourceFiles());
- }
-
- @Test
- 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",
- new String[0]) {
- {
- classCounter = CounterImpl.getInstance(9, 0);
- methodCounter = CounterImpl.getInstance(9, 0);
- branchCounter = CounterImpl.getInstance(9, 0);
- instructionCounter = CounterImpl.getInstance(9, 0);
- }
- };
- classnode.setSourceFileName("Sample.java");
- // Only source files will be considered for counters:
- final ISourceFileCoverage sourceFile = new SourceFileCoverageImpl(
- "Sample.java", "org/jacoco/test/Sample") {
- {
- classCounter = CounterImpl.getInstance(1, 0);
- methodCounter = CounterImpl.getInstance(2, 0);
- branchCounter = CounterImpl.getInstance(3, 0);
- instructionCounter = CounterImpl.getInstance(4, 0);
- }
- };
- PackageCoverageImpl data = new PackageCoverageImpl("org/jacoco/test",
- Collections.singleton((IClassCoverage) classnode),
- Collections.singleton(sourceFile));
- assertEquals(CounterImpl.getInstance(1, 0), data.getClassCounter());
- assertEquals(CounterImpl.getInstance(2, 0), data.getMethodCounter());
- assertEquals(CounterImpl.getInstance(3, 0), data.getBranchCounter());
- assertEquals(CounterImpl.getInstance(4, 0),
- data.getInstructionCounter());
- }
-
- @Test
- 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",
- new String[0]) {
- {
- classCounter = CounterImpl.getInstance(1, 0);
- methodCounter = CounterImpl.getInstance(2, 0);
- branchCounter = CounterImpl.getInstance(3, 0);
- instructionCounter = CounterImpl.getInstance(4, 0);
- }
- };
- final Collection<ISourceFileCoverage> sourceFiles = Collections
- .emptySet();
- PackageCoverageImpl data = new PackageCoverageImpl("org/jacoco/test",
- Collections.singleton((IClassCoverage) classnode), sourceFiles);
- assertEquals(CounterImpl.getInstance(1, 0), data.getClassCounter());
- assertEquals(CounterImpl.getInstance(2, 0), data.getMethodCounter());
- assertEquals(CounterImpl.getInstance(3, 0), data.getBranchCounter());
- assertEquals(CounterImpl.getInstance(4, 0),
- data.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(0, 0), data.getLineCounter());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.junit.Assert.assertEquals; + +import java.util.Collection; +import java.util.Collections; + +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ISourceFileCoverage; +import org.junit.Test; + +/** + * Unit test for {@link PackageCoverageImpl}. + */ +public class PackageCoverageTest { + + @Test + public void testProperties() { + Collection<IClassCoverage> classes = Collections + .singleton((IClassCoverage) new ClassCoverageImpl( + "org/jacoco/test/Sample", 0, null, "java/lang/Object", + new String[0])); + Collection<ISourceFileCoverage> sourceFiles = Collections + .singleton((ISourceFileCoverage) new SourceFileCoverageImpl( + "Sample.java", "org/jacoco/test/Sample")); + PackageCoverageImpl data = new PackageCoverageImpl("org/jacoco/test", + classes, sourceFiles); + assertEquals(ICoverageNode.ElementType.PACKAGE, data.getElementType()); + assertEquals("org/jacoco/test", data.getName()); + assertEquals(classes, data.getClasses()); + assertEquals(sourceFiles, data.getSourceFiles()); + } + + @Test + 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", + new String[0]) { + { + classCounter = CounterImpl.getInstance(9, 0); + methodCounter = CounterImpl.getInstance(9, 0); + branchCounter = CounterImpl.getInstance(9, 0); + instructionCounter = CounterImpl.getInstance(9, 0); + } + }; + classnode.setSourceFileName("Sample.java"); + // Only source files will be considered for counters: + final ISourceFileCoverage sourceFile = new SourceFileCoverageImpl( + "Sample.java", "org/jacoco/test/Sample") { + { + classCounter = CounterImpl.getInstance(1, 0); + methodCounter = CounterImpl.getInstance(2, 0); + branchCounter = CounterImpl.getInstance(3, 0); + instructionCounter = CounterImpl.getInstance(4, 0); + } + }; + PackageCoverageImpl data = new PackageCoverageImpl("org/jacoco/test", + Collections.singleton((IClassCoverage) classnode), + Collections.singleton(sourceFile)); + assertEquals(CounterImpl.getInstance(1, 0), data.getClassCounter()); + assertEquals(CounterImpl.getInstance(2, 0), data.getMethodCounter()); + assertEquals(CounterImpl.getInstance(3, 0), data.getBranchCounter()); + assertEquals(CounterImpl.getInstance(4, 0), + data.getInstructionCounter()); + } + + @Test + 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", + new String[0]) { + { + classCounter = CounterImpl.getInstance(1, 0); + methodCounter = CounterImpl.getInstance(2, 0); + branchCounter = CounterImpl.getInstance(3, 0); + instructionCounter = CounterImpl.getInstance(4, 0); + } + }; + final Collection<ISourceFileCoverage> sourceFiles = Collections + .emptySet(); + PackageCoverageImpl data = new PackageCoverageImpl("org/jacoco/test", + Collections.singleton((IClassCoverage) classnode), sourceFiles); + assertEquals(CounterImpl.getInstance(1, 0), data.getClassCounter()); + assertEquals(CounterImpl.getInstance(2, 0), data.getMethodCounter()); + assertEquals(CounterImpl.getInstance(3, 0), data.getBranchCounter()); + assertEquals(CounterImpl.getInstance(4, 0), + data.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(0, 0), data.getLineCounter()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceFileCoverageImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceFileCoverageImplTest.java index f499ed4e..66d57c0f 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceFileCoverageImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceFileCoverageImplTest.java @@ -1,32 +1,32 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.jacoco.core.analysis.ICoverageNode.ElementType.SOURCEFILE;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-/**
- * Unit test for {@link SourceFileCoverageImpl}.
- */
-public class SourceFileCoverageImplTest {
-
- @Test
- public void testProperties() {
- SourceFileCoverageImpl data = new SourceFileCoverageImpl("Sample.java",
- "org/jacoco/examples");
- assertEquals(SOURCEFILE, data.getElementType());
- assertEquals("org/jacoco/examples", data.getPackageName());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.jacoco.core.analysis.ICoverageNode.ElementType.SOURCEFILE; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +/** + * Unit test for {@link SourceFileCoverageImpl}. + */ +public class SourceFileCoverageImplTest { + + @Test + public void testProperties() { + SourceFileCoverageImpl data = new SourceFileCoverageImpl("Sample.java", + "org/jacoco/examples"); + assertEquals(SOURCEFILE, data.getElementType()); + assertEquals("org/jacoco/examples", data.getPackageName()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceNodeImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceNodeImplTest.java index 12d1002a..3071eeee 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceNodeImplTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/SourceNodeImplTest.java @@ -1,216 +1,216 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.junit.Assert.assertEquals;
-
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.core.analysis.ISourceNode;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link SourceNodeImpl}.
- */
-public class SourceNodeImplTest {
-
- @Test
- public void testInit() {
- final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo");
- assertEquals(ElementType.CLASS, node.getElementType());
- assertEquals("Foo", node.getName());
- assertEquals(ISourceNode.UNKNOWN_LINE, node.getFirstLine());
- assertEquals(ISourceNode.UNKNOWN_LINE, node.getLastLine());
- assertEquals(LineImpl.EMPTY, node.getLine(123));
- }
-
- @Test
- public void testGetLine() {
- final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo");
- node.ensureCapacity(10, 20);
- assertEquals(LineImpl.EMPTY, node.getLine(5));
- assertEquals(LineImpl.EMPTY, node.getLine(15));
- assertEquals(LineImpl.EMPTY, node.getLine(25));
- }
-
- @Test
- public void testEnsureCapacityUnknown1() {
- final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo");
- node.ensureCapacity(10, ISourceNode.UNKNOWN_LINE);
- assertEquals(LineImpl.EMPTY, node.getLine(10));
- }
-
- @Test
- public void testEnsureCapacityUnknown2() {
- final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo");
- node.ensureCapacity(ISourceNode.UNKNOWN_LINE, 10);
- assertEquals(LineImpl.EMPTY, node.getLine(10));
- }
-
- @Test
- public void testIncrementLineUnknown() {
- final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo");
- node.increment(CounterImpl.getInstance(1, 2),
- CounterImpl.getInstance(3, 4), ISourceNode.UNKNOWN_LINE);
- assertEquals(CounterImpl.getInstance(1, 2),
- node.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(3, 4), node.getBranchCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getLineCounter());
- }
-
- @Test
- public void testIncrementLines() {
- final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo");
- node.increment(CounterImpl.getInstance(1, 1), CounterImpl.COUNTER_0_0,
- 10);
- node.increment(CounterImpl.getInstance(2, 2), CounterImpl.COUNTER_0_0,
- 12);
-
- assertEquals(CounterImpl.getInstance(1, 1), node.getLine(10)
- .getInstructionCounter());
- assertEquals(CounterImpl.COUNTER_0_0, node.getLine(11)
- .getInstructionCounter());
- assertEquals(CounterImpl.getInstance(2, 2), node.getLine(12)
- .getInstructionCounter());
- }
-
- @Test
- public void testIncrementLine1_1() {
- testIncrementLine(0, 0, 0, 0, 0, 0);
- }
-
- @Test
- public void testIncrementLine1_2() {
- testIncrementLine(0, 0, 5, 0, 1, 0);
- }
-
- @Test
- public void testIncrementLine1_3() {
- testIncrementLine(0, 0, 0, 5, 0, 1);
- }
-
- @Test
- public void testIncrementLine1_4() {
- testIncrementLine(0, 0, 5, 5, 0, 1);
- }
-
- @Test
- public void testIncrementLine2_1() {
- testIncrementLine(3, 0, 0, 0, 1, 0);
- }
-
- @Test
- public void testIncrementLine2_2() {
- testIncrementLine(3, 0, 5, 0, 1, 0);
- }
-
- @Test
- public void testIncrementLine2_3() {
- testIncrementLine(3, 0, 0, 5, 0, 1);
- }
-
- @Test
- public void testIncrementLine2_4() {
- testIncrementLine(3, 0, 5, 5, 0, 1);
- }
-
- @Test
- public void testIncrementLine3_1() {
- testIncrementLine(0, 3, 0, 0, 0, 1);
- }
-
- @Test
- public void testIncrementLine3_2() {
- testIncrementLine(0, 3, 5, 0, 0, 1);
- }
-
- @Test
- public void testIncrementLine3_3() {
- testIncrementLine(0, 3, 0, 5, 0, 1);
- }
-
- @Test
- public void testIncrementLine3_4() {
- testIncrementLine(0, 3, 5, 5, 0, 1);
- }
-
- @Test
- public void testIncrementLine4_1() {
- testIncrementLine(3, 3, 0, 0, 0, 1);
- }
-
- @Test
- public void testIncrementLine4_2() {
- testIncrementLine(3, 3, 5, 0, 0, 1);
- }
-
- @Test
- public void testIncrementLine4_3() {
- testIncrementLine(3, 3, 0, 5, 0, 1);
- }
-
- @Test
- public void testIncrementLine4_4() {
- testIncrementLine(3, 3, 5, 5, 0, 1);
- }
-
- private void testIncrementLine(int mi1, int ci1, int mi2, int ci2,
- int expectedMissedLines, int expectedCoveredLines) {
- final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo");
- node.increment(CounterImpl.getInstance(mi1, ci1),
- CounterImpl.COUNTER_0_0, 33);
- node.increment(CounterImpl.getInstance(mi2, ci2),
- CounterImpl.COUNTER_0_0, 33);
- assertEquals(CounterImpl.getInstance(expectedMissedLines,
- expectedCoveredLines), node.getLineCounter());
- assertEquals(CounterImpl.getInstance(mi1 + mi2, ci1 + ci2), node
- .getLine(33).getInstructionCounter());
- }
-
- @Test
- public void testIncrementChildNoLines() {
- final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo");
- final SourceNodeImpl child = new SourceNodeImpl(ElementType.CLASS,
- "Foo") {
- {
- this.instructionCounter = CounterImpl.getInstance(1, 11);
- this.branchCounter = CounterImpl.getInstance(2, 22);
- this.methodCounter = CounterImpl.getInstance(3, 33);
- this.classCounter = CounterImpl.getInstance(4, 44);
- }
- };
- node.increment(child);
- assertEquals(CounterImpl.getInstance(1, 11),
- node.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(2, 22), node.getBranchCounter());
- assertEquals(CounterImpl.getInstance(3, 33), node.getMethodCounter());
- assertEquals(CounterImpl.getInstance(4, 44), node.getClassCounter());
- }
-
- @Test
- public void testIncrementChildWithLines() {
- final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo");
-
- final SourceNodeImpl child = new SourceNodeImpl(ElementType.CLASS,
- "Foo");
- child.increment(CounterImpl.getInstance(1, 11),
- CounterImpl.getInstance(3, 33), 5);
-
- node.increment(child);
- node.increment(child);
-
- assertEquals(CounterImpl.getInstance(2, 22),
- node.getInstructionCounter());
- assertEquals(CounterImpl.getInstance(6, 66), node.getBranchCounter());
- assertEquals(CounterImpl.getInstance(0, 1), node.getLineCounter());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.junit.Assert.assertEquals; + +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.core.analysis.ISourceNode; +import org.junit.Test; + +/** + * Unit tests for {@link SourceNodeImpl}. + */ +public class SourceNodeImplTest { + + @Test + public void testInit() { + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo"); + assertEquals(ElementType.CLASS, node.getElementType()); + assertEquals("Foo", node.getName()); + assertEquals(ISourceNode.UNKNOWN_LINE, node.getFirstLine()); + assertEquals(ISourceNode.UNKNOWN_LINE, node.getLastLine()); + assertEquals(LineImpl.EMPTY, node.getLine(123)); + } + + @Test + public void testGetLine() { + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo"); + node.ensureCapacity(10, 20); + assertEquals(LineImpl.EMPTY, node.getLine(5)); + assertEquals(LineImpl.EMPTY, node.getLine(15)); + assertEquals(LineImpl.EMPTY, node.getLine(25)); + } + + @Test + public void testEnsureCapacityUnknown1() { + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo"); + node.ensureCapacity(10, ISourceNode.UNKNOWN_LINE); + assertEquals(LineImpl.EMPTY, node.getLine(10)); + } + + @Test + public void testEnsureCapacityUnknown2() { + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo"); + node.ensureCapacity(ISourceNode.UNKNOWN_LINE, 10); + assertEquals(LineImpl.EMPTY, node.getLine(10)); + } + + @Test + public void testIncrementLineUnknown() { + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo"); + node.increment(CounterImpl.getInstance(1, 2), + CounterImpl.getInstance(3, 4), ISourceNode.UNKNOWN_LINE); + assertEquals(CounterImpl.getInstance(1, 2), + node.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(3, 4), node.getBranchCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getLineCounter()); + } + + @Test + public void testIncrementLines() { + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo"); + node.increment(CounterImpl.getInstance(1, 1), CounterImpl.COUNTER_0_0, + 10); + node.increment(CounterImpl.getInstance(2, 2), CounterImpl.COUNTER_0_0, + 12); + + assertEquals(CounterImpl.getInstance(1, 1), node.getLine(10) + .getInstructionCounter()); + assertEquals(CounterImpl.COUNTER_0_0, node.getLine(11) + .getInstructionCounter()); + assertEquals(CounterImpl.getInstance(2, 2), node.getLine(12) + .getInstructionCounter()); + } + + @Test + public void testIncrementLine1_1() { + testIncrementLine(0, 0, 0, 0, 0, 0); + } + + @Test + public void testIncrementLine1_2() { + testIncrementLine(0, 0, 5, 0, 1, 0); + } + + @Test + public void testIncrementLine1_3() { + testIncrementLine(0, 0, 0, 5, 0, 1); + } + + @Test + public void testIncrementLine1_4() { + testIncrementLine(0, 0, 5, 5, 0, 1); + } + + @Test + public void testIncrementLine2_1() { + testIncrementLine(3, 0, 0, 0, 1, 0); + } + + @Test + public void testIncrementLine2_2() { + testIncrementLine(3, 0, 5, 0, 1, 0); + } + + @Test + public void testIncrementLine2_3() { + testIncrementLine(3, 0, 0, 5, 0, 1); + } + + @Test + public void testIncrementLine2_4() { + testIncrementLine(3, 0, 5, 5, 0, 1); + } + + @Test + public void testIncrementLine3_1() { + testIncrementLine(0, 3, 0, 0, 0, 1); + } + + @Test + public void testIncrementLine3_2() { + testIncrementLine(0, 3, 5, 0, 0, 1); + } + + @Test + public void testIncrementLine3_3() { + testIncrementLine(0, 3, 0, 5, 0, 1); + } + + @Test + public void testIncrementLine3_4() { + testIncrementLine(0, 3, 5, 5, 0, 1); + } + + @Test + public void testIncrementLine4_1() { + testIncrementLine(3, 3, 0, 0, 0, 1); + } + + @Test + public void testIncrementLine4_2() { + testIncrementLine(3, 3, 5, 0, 0, 1); + } + + @Test + public void testIncrementLine4_3() { + testIncrementLine(3, 3, 0, 5, 0, 1); + } + + @Test + public void testIncrementLine4_4() { + testIncrementLine(3, 3, 5, 5, 0, 1); + } + + private void testIncrementLine(int mi1, int ci1, int mi2, int ci2, + int expectedMissedLines, int expectedCoveredLines) { + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo"); + node.increment(CounterImpl.getInstance(mi1, ci1), + CounterImpl.COUNTER_0_0, 33); + node.increment(CounterImpl.getInstance(mi2, ci2), + CounterImpl.COUNTER_0_0, 33); + assertEquals(CounterImpl.getInstance(expectedMissedLines, + expectedCoveredLines), node.getLineCounter()); + assertEquals(CounterImpl.getInstance(mi1 + mi2, ci1 + ci2), node + .getLine(33).getInstructionCounter()); + } + + @Test + public void testIncrementChildNoLines() { + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo"); + final SourceNodeImpl child = new SourceNodeImpl(ElementType.CLASS, + "Foo") { + { + this.instructionCounter = CounterImpl.getInstance(1, 11); + this.branchCounter = CounterImpl.getInstance(2, 22); + this.methodCounter = CounterImpl.getInstance(3, 33); + this.classCounter = CounterImpl.getInstance(4, 44); + } + }; + node.increment(child); + assertEquals(CounterImpl.getInstance(1, 11), + node.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(2, 22), node.getBranchCounter()); + assertEquals(CounterImpl.getInstance(3, 33), node.getMethodCounter()); + assertEquals(CounterImpl.getInstance(4, 44), node.getClassCounter()); + } + + @Test + public void testIncrementChildWithLines() { + final SourceNodeImpl node = new SourceNodeImpl(ElementType.CLASS, "Foo"); + + final SourceNodeImpl child = new SourceNodeImpl(ElementType.CLASS, + "Foo"); + child.increment(CounterImpl.getInstance(1, 11), + CounterImpl.getInstance(3, 33), 5); + + node.increment(child); + node.increment(child); + + assertEquals(CounterImpl.getInstance(2, 22), + node.getInstructionCounter()); + assertEquals(CounterImpl.getInstance(6, 66), node.getBranchCounter()); + assertEquals(CounterImpl.getInstance(0, 1), node.getLineCounter()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/StringPoolTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/StringPoolTest.java index 5f9daa2b..2d28572c 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/StringPoolTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/StringPoolTest.java @@ -1,72 +1,72 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link StringPool}.
- */
-public class StringPoolTest {
-
- private StringPool pool;
-
- @Before
- public void setup() {
- pool = new StringPool();
- }
-
- @Test
- public void testGetStringNull() {
- assertNull(pool.get((String) null));
- }
-
- @Test
- public void testGetString() {
- final String a = pool.get(new String("JaCoCo"));
- final String b = pool.get(new String("JaCoCo"));
-
- assertEquals("JaCoCo", a);
- assertEquals("JaCoCo", b);
- assertSame(a, b);
- }
-
- @Test
- public void testGetArrayNull() {
- assertNull(pool.get((String[]) null));
- }
-
- @Test
- public void testGetEmptyArray() {
- final String[] arr1 = pool.get(new String[0]);
- final String[] arr2 = pool.get(new String[0]);
-
- assertEquals(0, arr1.length);
- assertSame(arr1, arr2);
- }
-
- @Test
- public void testGetArray() {
- final String[] arr1 = pool.get(new String[] { new String("JaCoCo") });
- final String[] arr2 = pool.get(new String[] { new String("JaCoCo") });
-
- assertEquals(1, arr1.length);
- assertEquals("JaCoCo", arr1[0]);
- assertSame(arr1[0], arr2[0]);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link StringPool}. + */ +public class StringPoolTest { + + private StringPool pool; + + @Before + public void setup() { + pool = new StringPool(); + } + + @Test + public void testGetStringNull() { + assertNull(pool.get((String) null)); + } + + @Test + public void testGetString() { + final String a = pool.get(new String("JaCoCo")); + final String b = pool.get(new String("JaCoCo")); + + assertEquals("JaCoCo", a); + assertEquals("JaCoCo", b); + assertSame(a, b); + } + + @Test + public void testGetArrayNull() { + assertNull(pool.get((String[]) null)); + } + + @Test + public void testGetEmptyArray() { + final String[] arr1 = pool.get(new String[0]); + final String[] arr2 = pool.get(new String[0]); + + assertEquals(0, arr1.length); + assertSame(arr1, arr2); + } + + @Test + public void testGetArray() { + final String[] arr1 = pool.get(new String[] { new String("JaCoCo") }); + final String[] arr2 = pool.get(new String[] { new String("JaCoCo") }); + + assertEquals(1, arr1.length); + assertEquals("JaCoCo", arr1[0]); + assertSame(arr1[0], arr2[0]); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/data/CRC64Test.java b/org.jacoco.core.test/src/org/jacoco/core/internal/data/CRC64Test.java index 5c38160f..9900bca9 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/data/CRC64Test.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/data/CRC64Test.java @@ -1,67 +1,67 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.data;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.UnsupportedEncodingException;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link CRC64}.
- */
-public class CRC64Test {
-
- @Test
- public void test0() {
- final long sum = CRC64.checksum(new byte[0]);
- assertEquals(0L, sum);
- }
-
- /**
- * Example taken from http://swissknife.sourceforge.net/docs/CRC64.html
- *
- * @throws UnsupportedEncodingException
- */
- @Test
- public void test1() throws UnsupportedEncodingException {
- final long sum = CRC64.checksum("IHATEMATH".getBytes("ASCII"));
- assertEquals(0xE3DCADD69B01ADD1L, sum);
- }
-
- /**
- * Example generated with http://fsumfe.sourceforge.net/
- *
- * @throws UnsupportedEncodingException
- */
- @Test
- public void test2() {
- final long sum = CRC64.checksum(new byte[] { (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
- (byte) 0xff, (byte) 0xff });
- assertEquals(0x5300000000000000L, sum);
- }
-
- /**
- * Example generated with http://fsumfe.sourceforge.net/
- *
- * @throws UnsupportedEncodingException
- */
- @Test
- public void test3() throws UnsupportedEncodingException {
- final long sum = CRC64.checksum("JACOCO_JACOCO_JACOCO_JACOCO"
- .getBytes("ASCII"));
- assertEquals(0xD8016B38AAD48308L, sum);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.data; + +import static org.junit.Assert.assertEquals; + +import java.io.UnsupportedEncodingException; + +import org.junit.Test; + +/** + * Unit tests for {@link CRC64}. + */ +public class CRC64Test { + + @Test + public void test0() { + final long sum = CRC64.checksum(new byte[0]); + assertEquals(0L, sum); + } + + /** + * Example taken from http://swissknife.sourceforge.net/docs/CRC64.html + * + * @throws UnsupportedEncodingException + */ + @Test + public void test1() throws UnsupportedEncodingException { + final long sum = CRC64.checksum("IHATEMATH".getBytes("ASCII")); + assertEquals(0xE3DCADD69B01ADD1L, sum); + } + + /** + * Example generated with http://fsumfe.sourceforge.net/ + * + * @throws UnsupportedEncodingException + */ + @Test + public void test2() { + final long sum = CRC64.checksum(new byte[] { (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff }); + assertEquals(0x5300000000000000L, sum); + } + + /** + * Example generated with http://fsumfe.sourceforge.net/ + * + * @throws UnsupportedEncodingException + */ + @Test + public void test3() throws UnsupportedEncodingException { + final long sum = CRC64.checksum("JACOCO_JACOCO_JACOCO_JACOCO" + .getBytes("ASCII")); + assertEquals(0xD8016B38AAD48308L, sum); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/data/CompactDataInputOutputTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/data/CompactDataInputOutputTest.java index 8738eead..e3f4bfee 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/data/CompactDataInputOutputTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/data/CompactDataInputOutputTest.java @@ -1,118 +1,118 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.data;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.IOException;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link CompactDataInput} and {@link CompactDataOutput}. The
- * tests don't care about the written binary format, they just verify symmetry.
- */
-public class CompactDataInputOutputTest {
-
- private CompactDataOutput out;
-
- private CompactDataInput in;
-
- @Before
- public void setup() throws IOException {
- PipedOutputStream pipe = new PipedOutputStream();
- out = new CompactDataOutput(pipe);
- in = new CompactDataInput(new PipedInputStream(pipe));
- }
-
- @Test
- public void testVarInt0x00000000() throws IOException {
- testVarInt(0x00000000);
- }
-
- @Test
- public void testVarInt0x0000007F() throws IOException {
- testVarInt(0x0000007F);
- }
-
- @Test
- public void testVarInt0x00000080() throws IOException {
- testVarInt(0x00000080);
- }
-
- @Test
- public void testVarInt0x00000100() throws IOException {
- testVarInt(0x00000100);
- }
-
- @Test
- public void testVarInt0x12345678() throws IOException {
- testVarInt(0x12345678);
- }
-
- @Test
- public void testVarIntMinus1() throws IOException {
- testVarInt(-1);
- }
-
- @Test
- public void testVarIntMinValue() throws IOException {
- testVarInt(Integer.MIN_VALUE);
- }
-
- @Test
- public void testVarIntMaxValue() throws IOException {
- testVarInt(Integer.MAX_VALUE);
- }
-
- private void testVarInt(int value) throws IOException {
- out.writeVarInt(value);
- out.close();
- assertEquals(Long.valueOf(value), Long.valueOf(in.readVarInt()));
- assertEquals(Integer.valueOf(-1), Integer.valueOf(in.read()));
- }
-
- @Test
- public void testPackedBooleanEmpty() throws IOException {
- testPackedBoolean();
- }
-
- @Test
- public void testPackedBoolean3() throws IOException {
- testPackedBoolean(false, false, true);
- }
-
- @Test
- public void testPackedBoolean8() throws IOException {
- testPackedBoolean(true, false, true, false, false, true, false, true);
- }
-
- @Test
- public void testPackedBoolean9() throws IOException {
- testPackedBoolean(true, true, false, true, false, false, true, false,
- true);
- }
-
- private void testPackedBoolean(boolean... values) throws IOException {
- out.writeBooleanArray(values);
- out.close();
- final boolean[] actual = in.readBooleanArray();
- for (int i = 0; i < values.length; i++) {
- assertEquals("Index " + i, Boolean.valueOf(values[i]),
- Boolean.valueOf(actual[i]));
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.data; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link CompactDataInput} and {@link CompactDataOutput}. The + * tests don't care about the written binary format, they just verify symmetry. + */ +public class CompactDataInputOutputTest { + + private CompactDataOutput out; + + private CompactDataInput in; + + @Before + public void setup() throws IOException { + PipedOutputStream pipe = new PipedOutputStream(); + out = new CompactDataOutput(pipe); + in = new CompactDataInput(new PipedInputStream(pipe)); + } + + @Test + public void testVarInt0x00000000() throws IOException { + testVarInt(0x00000000); + } + + @Test + public void testVarInt0x0000007F() throws IOException { + testVarInt(0x0000007F); + } + + @Test + public void testVarInt0x00000080() throws IOException { + testVarInt(0x00000080); + } + + @Test + public void testVarInt0x00000100() throws IOException { + testVarInt(0x00000100); + } + + @Test + public void testVarInt0x12345678() throws IOException { + testVarInt(0x12345678); + } + + @Test + public void testVarIntMinus1() throws IOException { + testVarInt(-1); + } + + @Test + public void testVarIntMinValue() throws IOException { + testVarInt(Integer.MIN_VALUE); + } + + @Test + public void testVarIntMaxValue() throws IOException { + testVarInt(Integer.MAX_VALUE); + } + + private void testVarInt(int value) throws IOException { + out.writeVarInt(value); + out.close(); + assertEquals(Long.valueOf(value), Long.valueOf(in.readVarInt())); + assertEquals(Integer.valueOf(-1), Integer.valueOf(in.read())); + } + + @Test + public void testPackedBooleanEmpty() throws IOException { + testPackedBoolean(); + } + + @Test + public void testPackedBoolean3() throws IOException { + testPackedBoolean(false, false, true); + } + + @Test + public void testPackedBoolean8() throws IOException { + testPackedBoolean(true, false, true, false, false, true, false, true); + } + + @Test + public void testPackedBoolean9() throws IOException { + testPackedBoolean(true, true, false, true, false, false, true, false, + true); + } + + private void testPackedBoolean(boolean... values) throws IOException { + out.writeBooleanArray(values); + out.close(); + final boolean[] actual = in.readBooleanArray(); + for (int i = 0; i < values.length; i++) { + assertEquals("Index " + i, Boolean.valueOf(values[i]), + Boolean.valueOf(actual[i])); + } + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/ClassProbesAdapterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/ClassProbesAdapterTest.java index ac4fd05e..6c070d14 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/ClassProbesAdapterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/ClassProbesAdapterTest.java @@ -1,152 +1,152 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.commons.EmptyVisitor;
-
-/**
- * Unit tests for {@link ClassProbesAdapter}.
- */
-public class ClassProbesAdapterTest {
-
- private static class MockVisitor extends EmptyVisitor implements
- IClassProbesVisitor {
-
- int count;
-
- @Override
- public IMethodProbesVisitor visitMethod(int access, String name,
- String desc, String signature, String[] exceptions) {
- return null;
- }
-
- public void visitTotalProbeCount(int count) {
- this.count = count;
- }
- }
-
- @Test
- public void testProbeCounter() {
- final MockVisitor mv = new MockVisitor();
- final ClassProbesAdapter adapter = new ClassProbesAdapter(mv);
- assertEquals(0, adapter.nextId());
- assertEquals(1, adapter.nextId());
- assertEquals(2, adapter.nextId());
- adapter.visitEnd();
- assertEquals(3, mv.count);
- }
-
- @Test
- public void testVisitClassMethods() {
- final MockVisitor mv = new MockVisitor() {
- @Override
- public IMethodProbesVisitor visitMethod(int access, String name,
- String desc, String signature, String[] exceptions) {
- class MockMethodVisitor extends EmptyVisitor implements
- IMethodProbesVisitor {
- public void visitProbe(int probeId) {
- }
-
- public void visitJumpInsnWithProbe(int opcode, Label label,
- int probeId) {
- }
-
- public void visitInsnWithProbe(int opcode, int probeId) {
- }
-
- public void visitTableSwitchInsnWithProbes(int min,
- int max, Label dflt, Label[] labels) {
- }
-
- public void visitLookupSwitchInsnWithProbes(Label dflt,
- int[] keys, Label[] labels) {
- }
- }
- return new MockMethodVisitor();
- }
- };
- final ClassProbesAdapter adapter = new ClassProbesAdapter(mv);
- adapter.visit(Opcodes.V1_5, 0, "Foo", null, "java/lang/Object", null);
- writeMethod(adapter);
- writeMethod(adapter);
- writeMethod(adapter);
-
- assertEquals(0, mv.count);
- adapter.visitEnd();
- assertEquals(3, mv.count);
- }
-
- @Test
- public void testVisitInterfaceMethod() {
- final MockVisitor mv = new MockVisitor() {
- @Override
- public IMethodProbesVisitor visitMethod(int access, String name,
- String desc, String signature, String[] exceptions) {
- class MockMethodVisitor extends EmptyVisitor implements
- IMethodProbesVisitor {
- public void visitProbe(int probeId) {
- }
-
- public void visitJumpInsnWithProbe(int opcode, Label label,
- int probeId) {
- }
-
- public void visitInsnWithProbe(int opcode, int probeId) {
- }
-
- public void visitTableSwitchInsnWithProbes(int min,
- int max, Label dflt, Label[] labels) {
- }
-
- public void visitLookupSwitchInsnWithProbes(Label dflt,
- int[] keys, Label[] labels) {
- }
- }
- return new MockMethodVisitor();
- }
- };
- final ClassProbesAdapter adapter = new ClassProbesAdapter(mv);
- adapter.visit(Opcodes.V1_5, Opcodes.ACC_INTERFACE, "Foo", null,
- "java/lang/Object", null);
- writeMethod(adapter);
-
- assertEquals(1, mv.count);
- adapter.visitEnd();
- assertEquals(1, mv.count);
- }
-
- @Test
- public void testVisitMethodNullMethodVisitor() {
- final MockVisitor mv = new MockVisitor();
- final ClassProbesAdapter adapter = new ClassProbesAdapter(mv);
- writeMethod(adapter);
- writeMethod(adapter);
- writeMethod(adapter);
- adapter.visitEnd();
- assertEquals(3, mv.count);
- }
-
- private void writeMethod(final ClassVisitor cv) {
- MethodVisitor mv = cv.visitMethod(0, "foo", "V()", null, null);
- mv.visitCode();
- mv.visitInsn(Opcodes.RETURN);
- mv.visitMaxs(0, 1);
- mv.visitEnd();
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.commons.EmptyVisitor; + +/** + * Unit tests for {@link ClassProbesAdapter}. + */ +public class ClassProbesAdapterTest { + + private static class MockVisitor extends EmptyVisitor implements + IClassProbesVisitor { + + int count; + + @Override + public IMethodProbesVisitor visitMethod(int access, String name, + String desc, String signature, String[] exceptions) { + return null; + } + + public void visitTotalProbeCount(int count) { + this.count = count; + } + } + + @Test + public void testProbeCounter() { + final MockVisitor mv = new MockVisitor(); + final ClassProbesAdapter adapter = new ClassProbesAdapter(mv); + assertEquals(0, adapter.nextId()); + assertEquals(1, adapter.nextId()); + assertEquals(2, adapter.nextId()); + adapter.visitEnd(); + assertEquals(3, mv.count); + } + + @Test + public void testVisitClassMethods() { + final MockVisitor mv = new MockVisitor() { + @Override + public IMethodProbesVisitor visitMethod(int access, String name, + String desc, String signature, String[] exceptions) { + class MockMethodVisitor extends EmptyVisitor implements + IMethodProbesVisitor { + public void visitProbe(int probeId) { + } + + public void visitJumpInsnWithProbe(int opcode, Label label, + int probeId) { + } + + public void visitInsnWithProbe(int opcode, int probeId) { + } + + public void visitTableSwitchInsnWithProbes(int min, + int max, Label dflt, Label[] labels) { + } + + public void visitLookupSwitchInsnWithProbes(Label dflt, + int[] keys, Label[] labels) { + } + } + return new MockMethodVisitor(); + } + }; + final ClassProbesAdapter adapter = new ClassProbesAdapter(mv); + adapter.visit(Opcodes.V1_5, 0, "Foo", null, "java/lang/Object", null); + writeMethod(adapter); + writeMethod(adapter); + writeMethod(adapter); + + assertEquals(0, mv.count); + adapter.visitEnd(); + assertEquals(3, mv.count); + } + + @Test + public void testVisitInterfaceMethod() { + final MockVisitor mv = new MockVisitor() { + @Override + public IMethodProbesVisitor visitMethod(int access, String name, + String desc, String signature, String[] exceptions) { + class MockMethodVisitor extends EmptyVisitor implements + IMethodProbesVisitor { + public void visitProbe(int probeId) { + } + + public void visitJumpInsnWithProbe(int opcode, Label label, + int probeId) { + } + + public void visitInsnWithProbe(int opcode, int probeId) { + } + + public void visitTableSwitchInsnWithProbes(int min, + int max, Label dflt, Label[] labels) { + } + + public void visitLookupSwitchInsnWithProbes(Label dflt, + int[] keys, Label[] labels) { + } + } + return new MockMethodVisitor(); + } + }; + final ClassProbesAdapter adapter = new ClassProbesAdapter(mv); + adapter.visit(Opcodes.V1_5, Opcodes.ACC_INTERFACE, "Foo", null, + "java/lang/Object", null); + writeMethod(adapter); + + assertEquals(1, mv.count); + adapter.visitEnd(); + assertEquals(1, mv.count); + } + + @Test + public void testVisitMethodNullMethodVisitor() { + final MockVisitor mv = new MockVisitor(); + final ClassProbesAdapter adapter = new ClassProbesAdapter(mv); + writeMethod(adapter); + writeMethod(adapter); + writeMethod(adapter); + adapter.visitEnd(); + assertEquals(3, mv.count); + } + + private void writeMethod(final ClassVisitor cv) { + MethodVisitor mv = cv.visitMethod(0, "foo", "V()", null, null); + mv.visitCode(); + mv.visitInsn(Opcodes.RETURN); + mv.visitMaxs(0, 1); + mv.visitEnd(); + } +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/InstructionTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/InstructionTest.java index 61550fdc..d707f688 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/InstructionTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/InstructionTest.java @@ -1,85 +1,85 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link Instruction}.
- */
-public class InstructionTest {
-
- private Instruction instruction;
-
- @Before
- public void setup() {
- instruction = new Instruction(123);
- }
-
- @Test
- public void testInit() {
- assertEquals(123, instruction.getLine());
- assertEquals(0, instruction.getBranches());
- assertEquals(0, instruction.getCoveredBranches());
- }
-
- @Test
- public void testAddBranch() {
- instruction.addBranch();
- assertEquals(1, instruction.getBranches());
- instruction.addBranch();
- assertEquals(2, instruction.getBranches());
- instruction.addBranch();
- assertEquals(3, instruction.getBranches());
- assertEquals(0, instruction.getCoveredBranches());
- }
-
- @Test
- public void testSetPredecessor() {
- final Instruction predecessor = new Instruction(122);
- instruction.setPredecessor(predecessor);
- assertEquals(1, predecessor.getBranches());
- }
-
- @Test
- public void testSetCovered() {
- final Instruction predecessor = new Instruction(122);
- instruction.setPredecessor(predecessor);
- instruction.setCovered();
- assertEquals(1, instruction.getCoveredBranches());
- assertEquals(1, predecessor.getCoveredBranches());
-
- instruction.setCovered();
- assertEquals(2, instruction.getCoveredBranches());
- assertEquals(1, predecessor.getCoveredBranches());
- }
-
- @Test
- public void testSetCoveredOnLongSequence() {
- final Instruction first = new Instruction(0);
- Instruction next = first;
- for (int i = 0; i < 0x10000; i++) {
- final Instruction insn = new Instruction(i);
- insn.setPredecessor(next);
- next = insn;
- }
-
- // The implementation must not cause an StackOverflowError even on very
- // long sequences:
- next.setCovered();
- assertEquals(1, first.getCoveredBranches());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link Instruction}. + */ +public class InstructionTest { + + private Instruction instruction; + + @Before + public void setup() { + instruction = new Instruction(123); + } + + @Test + public void testInit() { + assertEquals(123, instruction.getLine()); + assertEquals(0, instruction.getBranches()); + assertEquals(0, instruction.getCoveredBranches()); + } + + @Test + public void testAddBranch() { + instruction.addBranch(); + assertEquals(1, instruction.getBranches()); + instruction.addBranch(); + assertEquals(2, instruction.getBranches()); + instruction.addBranch(); + assertEquals(3, instruction.getBranches()); + assertEquals(0, instruction.getCoveredBranches()); + } + + @Test + public void testSetPredecessor() { + final Instruction predecessor = new Instruction(122); + instruction.setPredecessor(predecessor); + assertEquals(1, predecessor.getBranches()); + } + + @Test + public void testSetCovered() { + final Instruction predecessor = new Instruction(122); + instruction.setPredecessor(predecessor); + instruction.setCovered(); + assertEquals(1, instruction.getCoveredBranches()); + assertEquals(1, predecessor.getCoveredBranches()); + + instruction.setCovered(); + assertEquals(2, instruction.getCoveredBranches()); + assertEquals(1, predecessor.getCoveredBranches()); + } + + @Test + public void testSetCoveredOnLongSequence() { + final Instruction first = new Instruction(0); + Instruction next = first; + for (int i = 0; i < 0x10000; i++) { + final Instruction insn = new Instruction(i); + insn.setPredecessor(next); + next = insn; + } + + // The implementation must not cause an StackOverflowError even on very + // long sequences: + next.setCovered(); + assertEquals(1, first.getCoveredBranches()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelFlowAnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelFlowAnalyzerTest.java index 1a73eac9..fa916bb0 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelFlowAnalyzerTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelFlowAnalyzerTest.java @@ -1,374 +1,374 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.objectweb.asm.Opcodes.*;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Unit tests for {@link LabelFlowAnalyzer}.
- */
-public class LabelFlowAnalyzerTest {
-
- private LabelFlowAnalyzer analyzer;
-
- private Label label;
-
- @Before
- public void setup() {
- analyzer = new LabelFlowAnalyzer();
- label = new Label();
- }
-
- @Test
- public void testFlowScenario01() {
- assertFalse(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario02() {
- analyzer.visitJumpInsn(GOTO, label);
- assertFalse(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario03() {
- analyzer.visitInsn(RETURN);
- analyzer.visitLabel(label);
- assertFalse(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario04() {
- analyzer.visitLabel(label);
- assertFalse(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario05() {
- analyzer.visitLabel(label);
- analyzer.visitJumpInsn(GOTO, label);
- assertTrue(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario06() {
- analyzer.visitJumpInsn(IFEQ, label);
- analyzer.visitLabel(label);
- assertTrue(LabelInfo.isMultiTarget(label));
- assertTrue(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario07() {
- analyzer.visitJumpInsn(IFEQ, label);
- analyzer.visitJumpInsn(GOTO, label);
- assertTrue(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario08() {
- analyzer.visitJumpInsn(IFEQ, label);
- analyzer.visitJumpInsn(IFGT, label);
- analyzer.visitLabel(label);
- assertTrue(LabelInfo.isMultiTarget(label));
- assertTrue(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario09() {
- analyzer.visitInsn(Opcodes.NOP);
- analyzer.visitLabel(label);
- analyzer.visitLabel(label);
- assertFalse(LabelInfo.isMultiTarget(label));
- assertTrue(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario10() {
- analyzer.visitTryCatchBlock(new Label(), new Label(), label,
- "java/lang/Exception");
- analyzer.visitJumpInsn(GOTO, label);
- assertTrue(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario11() {
- // Even if the same label is referenced multiple times but from the same
- // source instruction this is only counted as one target.
- analyzer.visitLookupSwitchInsn(label, new int[] { 0, 1 }, new Label[] {
- label, label });
- assertFalse(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testFlowScenario12() {
- // Even if the same label is referenced multiple times but from the same
- // source instruction this is only counted as one target.
- analyzer.visitTableSwitchInsn(0, 1, label, new Label[] { label, label });
- assertFalse(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testInit() {
- assertFalse(analyzer.successor);
- assertTrue(analyzer.first);
- }
-
- @Test
- public void testInsn() {
- testInsn(NOP, true);
- testInsn(ACONST_NULL, true);
- testInsn(ICONST_M1, true);
- testInsn(ICONST_0, true);
- testInsn(ICONST_1, true);
- testInsn(ICONST_2, true);
- testInsn(ICONST_3, true);
- testInsn(ICONST_4, true);
- testInsn(ICONST_5, true);
- testInsn(LCONST_0, true);
- testInsn(LCONST_1, true);
- testInsn(FCONST_0, true);
- testInsn(FCONST_1, true);
- testInsn(FCONST_2, true);
- testInsn(DCONST_0, true);
- testInsn(DCONST_1, true);
- testInsn(IALOAD, true);
- testInsn(LALOAD, true);
- testInsn(FALOAD, true);
- testInsn(DALOAD, true);
- testInsn(AALOAD, true);
- testInsn(BALOAD, true);
- testInsn(CALOAD, true);
- testInsn(SALOAD, true);
- testInsn(IASTORE, true);
- testInsn(LASTORE, true);
- testInsn(FASTORE, true);
- testInsn(DASTORE, true);
- testInsn(AASTORE, true);
- testInsn(BASTORE, true);
- testInsn(CASTORE, true);
- testInsn(SASTORE, true);
- testInsn(POP, true);
- testInsn(POP2, true);
- testInsn(DUP, true);
- testInsn(DUP_X1, true);
- testInsn(DUP_X2, true);
- testInsn(DUP2, true);
- testInsn(DUP2_X1, true);
- testInsn(DUP2_X2, true);
- testInsn(SWAP, true);
- testInsn(IADD, true);
- testInsn(LADD, true);
- testInsn(FADD, true);
- testInsn(DADD, true);
- testInsn(ISUB, true);
- testInsn(LSUB, true);
- testInsn(FSUB, true);
- testInsn(DSUB, true);
- testInsn(IMUL, true);
- testInsn(LMUL, true);
- testInsn(FMUL, true);
- testInsn(DMUL, true);
- testInsn(IDIV, true);
- testInsn(LDIV, true);
- testInsn(FDIV, true);
- testInsn(DDIV, true);
- testInsn(IREM, true);
- testInsn(LREM, true);
- testInsn(FREM, true);
- testInsn(DREM, true);
- testInsn(INEG, true);
- testInsn(LNEG, true);
- testInsn(FNEG, true);
- testInsn(DNEG, true);
- testInsn(ISHL, true);
- testInsn(LSHL, true);
- testInsn(ISHR, true);
- testInsn(LSHR, true);
- testInsn(IUSHR, true);
- testInsn(LUSHR, true);
- testInsn(IAND, true);
- testInsn(LAND, true);
- testInsn(IOR, true);
- testInsn(LOR, true);
- testInsn(IXOR, true);
- testInsn(LXOR, true);
- testInsn(I2L, true);
- testInsn(I2F, true);
- testInsn(I2D, true);
- testInsn(L2I, true);
- testInsn(L2F, true);
- testInsn(L2D, true);
- testInsn(F2I, true);
- testInsn(F2L, true);
- testInsn(F2D, true);
- testInsn(D2I, true);
- testInsn(D2L, true);
- testInsn(D2F, true);
- testInsn(I2B, true);
- testInsn(I2C, true);
- testInsn(I2S, true);
- testInsn(LCMP, true);
- testInsn(FCMPL, true);
- testInsn(FCMPG, true);
- testInsn(DCMPL, true);
- testInsn(DCMPG, true);
- testInsn(IRETURN, false);
- testInsn(LRETURN, false);
- testInsn(FRETURN, false);
- testInsn(DRETURN, false);
- testInsn(ARETURN, false);
- testInsn(RETURN, false);
- testInsn(ARRAYLENGTH, true);
- testInsn(ATHROW, false);
- testInsn(MONITORENTER, true);
- testInsn(MONITOREXIT, true);
- }
-
- private void testInsn(int opcode, boolean expected) {
- // ensure the flags are actually set:
- analyzer.successor = !expected;
- analyzer.first = true;
- analyzer.visitInsn(opcode);
- assertTrue(expected == analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test(expected = AssertionError.class)
- public void testVisitInsnNegative() {
- analyzer.visitInsn(RET);
- }
-
- @Test
- public void testIntInsn() {
- analyzer.visitIntInsn(BIPUSH, 0);
- assertTrue(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test
- public void testVarInsn() {
- analyzer.visitVarInsn(ILOAD, 0);
- assertTrue(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test
- public void testTypeInsn() {
- analyzer.visitTypeInsn(NEW, "java/lang/String");
- assertTrue(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test
- public void testFieldInsn() {
- analyzer.successor = false;
- analyzer.visitFieldInsn(GETFIELD, "Foo", "name", "Ljava/lang/String;");
- assertTrue(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test
- public void testMethodInsn() {
- analyzer.visitMethodInsn(INVOKEVIRTUAL, "Foo", "doit", "()V");
- assertTrue(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test
- public void testJumpInsn() {
- testJumpInsn(IFEQ, true);
- testJumpInsn(IFNE, true);
- testJumpInsn(IFLT, true);
- testJumpInsn(IFGE, true);
- testJumpInsn(IFGT, true);
- testJumpInsn(IFLE, true);
- testJumpInsn(IF_ICMPEQ, true);
- testJumpInsn(IF_ICMPNE, true);
- testJumpInsn(IF_ICMPLT, true);
- testJumpInsn(IF_ICMPGE, true);
- testJumpInsn(IF_ICMPGT, true);
- testJumpInsn(IF_ICMPLE, true);
- testJumpInsn(IF_ACMPEQ, true);
- testJumpInsn(IF_ACMPNE, true);
- testJumpInsn(GOTO, false);
- testJumpInsn(IFNULL, true);
- testJumpInsn(IFNONNULL, true);
- }
-
- private void testJumpInsn(int opcode, boolean expected) {
- // ensure the flags are actually set:
- analyzer.successor = !expected;
- analyzer.first = true;
- analyzer.visitJumpInsn(opcode, label);
- assertTrue(expected == analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test(expected = AssertionError.class)
- public void testVisitJumpInsnNegative() {
- analyzer.visitJumpInsn(JSR, label);
- }
-
- @Test
- public void testLdcInsn() {
- analyzer.visitLdcInsn("Foo");
- assertTrue(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test
- public void testIincInsn() {
- analyzer.visitIincInsn(0, 1);
- assertTrue(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test
- public void testTableSwitchInsn() {
- analyzer.visitTableSwitchInsn(0, 0, label, new Label[] { label });
- assertFalse(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test
- public void testLookupSwitchInsn() {
- analyzer.visitLookupSwitchInsn(label, new int[] { 0 },
- new Label[] { label });
- assertFalse(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
- @Test
- public void testMultiANewArrayInsn() {
- analyzer.visitMultiANewArrayInsn("java/lang/String", 3);
- assertTrue(analyzer.successor);
- assertFalse(analyzer.first);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.objectweb.asm.Opcodes.*; + +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; + +/** + * Unit tests for {@link LabelFlowAnalyzer}. + */ +public class LabelFlowAnalyzerTest { + + private LabelFlowAnalyzer analyzer; + + private Label label; + + @Before + public void setup() { + analyzer = new LabelFlowAnalyzer(); + label = new Label(); + } + + @Test + public void testFlowScenario01() { + assertFalse(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario02() { + analyzer.visitJumpInsn(GOTO, label); + assertFalse(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario03() { + analyzer.visitInsn(RETURN); + analyzer.visitLabel(label); + assertFalse(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario04() { + analyzer.visitLabel(label); + assertFalse(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario05() { + analyzer.visitLabel(label); + analyzer.visitJumpInsn(GOTO, label); + assertTrue(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario06() { + analyzer.visitJumpInsn(IFEQ, label); + analyzer.visitLabel(label); + assertTrue(LabelInfo.isMultiTarget(label)); + assertTrue(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario07() { + analyzer.visitJumpInsn(IFEQ, label); + analyzer.visitJumpInsn(GOTO, label); + assertTrue(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario08() { + analyzer.visitJumpInsn(IFEQ, label); + analyzer.visitJumpInsn(IFGT, label); + analyzer.visitLabel(label); + assertTrue(LabelInfo.isMultiTarget(label)); + assertTrue(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario09() { + analyzer.visitInsn(Opcodes.NOP); + analyzer.visitLabel(label); + analyzer.visitLabel(label); + assertFalse(LabelInfo.isMultiTarget(label)); + assertTrue(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario10() { + analyzer.visitTryCatchBlock(new Label(), new Label(), label, + "java/lang/Exception"); + analyzer.visitJumpInsn(GOTO, label); + assertTrue(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario11() { + // Even if the same label is referenced multiple times but from the same + // source instruction this is only counted as one target. + analyzer.visitLookupSwitchInsn(label, new int[] { 0, 1 }, new Label[] { + label, label }); + assertFalse(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testFlowScenario12() { + // Even if the same label is referenced multiple times but from the same + // source instruction this is only counted as one target. + analyzer.visitTableSwitchInsn(0, 1, label, new Label[] { label, label }); + assertFalse(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testInit() { + assertFalse(analyzer.successor); + assertTrue(analyzer.first); + } + + @Test + public void testInsn() { + testInsn(NOP, true); + testInsn(ACONST_NULL, true); + testInsn(ICONST_M1, true); + testInsn(ICONST_0, true); + testInsn(ICONST_1, true); + testInsn(ICONST_2, true); + testInsn(ICONST_3, true); + testInsn(ICONST_4, true); + testInsn(ICONST_5, true); + testInsn(LCONST_0, true); + testInsn(LCONST_1, true); + testInsn(FCONST_0, true); + testInsn(FCONST_1, true); + testInsn(FCONST_2, true); + testInsn(DCONST_0, true); + testInsn(DCONST_1, true); + testInsn(IALOAD, true); + testInsn(LALOAD, true); + testInsn(FALOAD, true); + testInsn(DALOAD, true); + testInsn(AALOAD, true); + testInsn(BALOAD, true); + testInsn(CALOAD, true); + testInsn(SALOAD, true); + testInsn(IASTORE, true); + testInsn(LASTORE, true); + testInsn(FASTORE, true); + testInsn(DASTORE, true); + testInsn(AASTORE, true); + testInsn(BASTORE, true); + testInsn(CASTORE, true); + testInsn(SASTORE, true); + testInsn(POP, true); + testInsn(POP2, true); + testInsn(DUP, true); + testInsn(DUP_X1, true); + testInsn(DUP_X2, true); + testInsn(DUP2, true); + testInsn(DUP2_X1, true); + testInsn(DUP2_X2, true); + testInsn(SWAP, true); + testInsn(IADD, true); + testInsn(LADD, true); + testInsn(FADD, true); + testInsn(DADD, true); + testInsn(ISUB, true); + testInsn(LSUB, true); + testInsn(FSUB, true); + testInsn(DSUB, true); + testInsn(IMUL, true); + testInsn(LMUL, true); + testInsn(FMUL, true); + testInsn(DMUL, true); + testInsn(IDIV, true); + testInsn(LDIV, true); + testInsn(FDIV, true); + testInsn(DDIV, true); + testInsn(IREM, true); + testInsn(LREM, true); + testInsn(FREM, true); + testInsn(DREM, true); + testInsn(INEG, true); + testInsn(LNEG, true); + testInsn(FNEG, true); + testInsn(DNEG, true); + testInsn(ISHL, true); + testInsn(LSHL, true); + testInsn(ISHR, true); + testInsn(LSHR, true); + testInsn(IUSHR, true); + testInsn(LUSHR, true); + testInsn(IAND, true); + testInsn(LAND, true); + testInsn(IOR, true); + testInsn(LOR, true); + testInsn(IXOR, true); + testInsn(LXOR, true); + testInsn(I2L, true); + testInsn(I2F, true); + testInsn(I2D, true); + testInsn(L2I, true); + testInsn(L2F, true); + testInsn(L2D, true); + testInsn(F2I, true); + testInsn(F2L, true); + testInsn(F2D, true); + testInsn(D2I, true); + testInsn(D2L, true); + testInsn(D2F, true); + testInsn(I2B, true); + testInsn(I2C, true); + testInsn(I2S, true); + testInsn(LCMP, true); + testInsn(FCMPL, true); + testInsn(FCMPG, true); + testInsn(DCMPL, true); + testInsn(DCMPG, true); + testInsn(IRETURN, false); + testInsn(LRETURN, false); + testInsn(FRETURN, false); + testInsn(DRETURN, false); + testInsn(ARETURN, false); + testInsn(RETURN, false); + testInsn(ARRAYLENGTH, true); + testInsn(ATHROW, false); + testInsn(MONITORENTER, true); + testInsn(MONITOREXIT, true); + } + + private void testInsn(int opcode, boolean expected) { + // ensure the flags are actually set: + analyzer.successor = !expected; + analyzer.first = true; + analyzer.visitInsn(opcode); + assertTrue(expected == analyzer.successor); + assertFalse(analyzer.first); + } + + @Test(expected = AssertionError.class) + public void testVisitInsnNegative() { + analyzer.visitInsn(RET); + } + + @Test + public void testIntInsn() { + analyzer.visitIntInsn(BIPUSH, 0); + assertTrue(analyzer.successor); + assertFalse(analyzer.first); + } + + @Test + public void testVarInsn() { + analyzer.visitVarInsn(ILOAD, 0); + assertTrue(analyzer.successor); + assertFalse(analyzer.first); + } + + @Test + public void testTypeInsn() { + analyzer.visitTypeInsn(NEW, "java/lang/String"); + assertTrue(analyzer.successor); + assertFalse(analyzer.first); + } + + @Test + public void testFieldInsn() { + analyzer.successor = false; + analyzer.visitFieldInsn(GETFIELD, "Foo", "name", "Ljava/lang/String;"); + assertTrue(analyzer.successor); + assertFalse(analyzer.first); + } + + @Test + public void testMethodInsn() { + analyzer.visitMethodInsn(INVOKEVIRTUAL, "Foo", "doit", "()V"); + assertTrue(analyzer.successor); + assertFalse(analyzer.first); + } + + @Test + public void testJumpInsn() { + testJumpInsn(IFEQ, true); + testJumpInsn(IFNE, true); + testJumpInsn(IFLT, true); + testJumpInsn(IFGE, true); + testJumpInsn(IFGT, true); + testJumpInsn(IFLE, true); + testJumpInsn(IF_ICMPEQ, true); + testJumpInsn(IF_ICMPNE, true); + testJumpInsn(IF_ICMPLT, true); + testJumpInsn(IF_ICMPGE, true); + testJumpInsn(IF_ICMPGT, true); + testJumpInsn(IF_ICMPLE, true); + testJumpInsn(IF_ACMPEQ, true); + testJumpInsn(IF_ACMPNE, true); + testJumpInsn(GOTO, false); + testJumpInsn(IFNULL, true); + testJumpInsn(IFNONNULL, true); + } + + private void testJumpInsn(int opcode, boolean expected) { + // ensure the flags are actually set: + analyzer.successor = !expected; + analyzer.first = true; + analyzer.visitJumpInsn(opcode, label); + assertTrue(expected == analyzer.successor); + assertFalse(analyzer.first); + } + + @Test(expected = AssertionError.class) + public void testVisitJumpInsnNegative() { + analyzer.visitJumpInsn(JSR, label); + } + + @Test + public void testLdcInsn() { + analyzer.visitLdcInsn("Foo"); + assertTrue(analyzer.successor); + assertFalse(analyzer.first); + } + + @Test + public void testIincInsn() { + analyzer.visitIincInsn(0, 1); + assertTrue(analyzer.successor); + assertFalse(analyzer.first); + } + + @Test + public void testTableSwitchInsn() { + analyzer.visitTableSwitchInsn(0, 0, label, new Label[] { label }); + assertFalse(analyzer.successor); + assertFalse(analyzer.first); + } + + @Test + public void testLookupSwitchInsn() { + analyzer.visitLookupSwitchInsn(label, new int[] { 0 }, + new Label[] { label }); + assertFalse(analyzer.successor); + assertFalse(analyzer.first); + } + + @Test + public void testMultiANewArrayInsn() { + analyzer.visitMultiANewArrayInsn("java/lang/String", 3); + assertTrue(analyzer.successor); + assertFalse(analyzer.first); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelInfoTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelInfoTest.java index e6ccee85..ac3cffb5 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelInfoTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelInfoTest.java @@ -1,130 +1,130 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.Label;
-
-/**
- * Unit tests for {@link LabelInfoTest}.
- */
-public class LabelInfoTest {
-
- private Label label;
-
- @Before
- public void setup() {
- label = new Label();
- }
-
- @Test
- public void testDefaults() {
- assertFalse(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- assertFalse(LabelInfo.isDone(label));
- assertEquals(LabelInfo.NO_PROBE, LabelInfo.getProbeId(label));
- assertNull(LabelInfo.getIntermediateLabel(label));
- assertNull(LabelInfo.getInstruction(label));
- }
-
- @Test
- public void testOtherInfoObject() {
- label.info = new Object();
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testSuccessor() {
- LabelInfo.setSuccessor(label);
- assertFalse(LabelInfo.isMultiTarget(label));
- assertTrue(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testMultiTarget1() {
- LabelInfo.setTarget(label);
- assertFalse(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
-
- LabelInfo.setTarget(label);
- assertTrue(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testMultiTarget2() {
- LabelInfo.setSuccessor(label);
- assertFalse(LabelInfo.isMultiTarget(label));
- assertTrue(LabelInfo.isSuccessor(label));
-
- LabelInfo.setTarget(label);
- assertTrue(LabelInfo.isMultiTarget(label));
- assertTrue(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testMultiTarget3() {
- LabelInfo.setTarget(label);
- assertFalse(LabelInfo.isMultiTarget(label));
- assertFalse(LabelInfo.isSuccessor(label));
-
- LabelInfo.setSuccessor(label);
- assertTrue(LabelInfo.isMultiTarget(label));
- assertTrue(LabelInfo.isSuccessor(label));
- }
-
- @Test
- public void testSetResetDone1() {
- LabelInfo.setDone(label);
- assertTrue(LabelInfo.isDone(label));
-
- LabelInfo.resetDone(label);
- assertFalse(LabelInfo.isDone(label));
- }
-
- @Test
- public void testSetResetDone2() {
- LabelInfo.setDone(label);
- assertTrue(LabelInfo.isDone(label));
-
- LabelInfo.resetDone(new Label[] { label, new Label() });
- assertFalse(LabelInfo.isDone(label));
- }
-
- @Test
- public void testSetProbeId() {
- LabelInfo.setProbeId(label, 123);
- assertEquals(123, LabelInfo.getProbeId(label));
- }
-
- @Test
- public void testSetIntermediateLabel() {
- final Label i = new Label();
- LabelInfo.setIntermediateLabel(label, i);
- assertSame(i, LabelInfo.getIntermediateLabel(label));
- }
-
- @Test
- public void testSetInstruction() {
- final Instruction instruction = new Instruction(123);
- LabelInfo.setInstruction(label, instruction);
- assertSame(instruction, LabelInfo.getInstruction(label));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.Label; + +/** + * Unit tests for {@link LabelInfoTest}. + */ +public class LabelInfoTest { + + private Label label; + + @Before + public void setup() { + label = new Label(); + } + + @Test + public void testDefaults() { + assertFalse(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + assertFalse(LabelInfo.isDone(label)); + assertEquals(LabelInfo.NO_PROBE, LabelInfo.getProbeId(label)); + assertNull(LabelInfo.getIntermediateLabel(label)); + assertNull(LabelInfo.getInstruction(label)); + } + + @Test + public void testOtherInfoObject() { + label.info = new Object(); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testSuccessor() { + LabelInfo.setSuccessor(label); + assertFalse(LabelInfo.isMultiTarget(label)); + assertTrue(LabelInfo.isSuccessor(label)); + } + + @Test + public void testMultiTarget1() { + LabelInfo.setTarget(label); + assertFalse(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + + LabelInfo.setTarget(label); + assertTrue(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + } + + @Test + public void testMultiTarget2() { + LabelInfo.setSuccessor(label); + assertFalse(LabelInfo.isMultiTarget(label)); + assertTrue(LabelInfo.isSuccessor(label)); + + LabelInfo.setTarget(label); + assertTrue(LabelInfo.isMultiTarget(label)); + assertTrue(LabelInfo.isSuccessor(label)); + } + + @Test + public void testMultiTarget3() { + LabelInfo.setTarget(label); + assertFalse(LabelInfo.isMultiTarget(label)); + assertFalse(LabelInfo.isSuccessor(label)); + + LabelInfo.setSuccessor(label); + assertTrue(LabelInfo.isMultiTarget(label)); + assertTrue(LabelInfo.isSuccessor(label)); + } + + @Test + public void testSetResetDone1() { + LabelInfo.setDone(label); + assertTrue(LabelInfo.isDone(label)); + + LabelInfo.resetDone(label); + assertFalse(LabelInfo.isDone(label)); + } + + @Test + public void testSetResetDone2() { + LabelInfo.setDone(label); + assertTrue(LabelInfo.isDone(label)); + + LabelInfo.resetDone(new Label[] { label, new Label() }); + assertFalse(LabelInfo.isDone(label)); + } + + @Test + public void testSetProbeId() { + LabelInfo.setProbeId(label, 123); + assertEquals(123, LabelInfo.getProbeId(label)); + } + + @Test + public void testSetIntermediateLabel() { + final Label i = new Label(); + LabelInfo.setIntermediateLabel(label, i); + assertSame(i, LabelInfo.getIntermediateLabel(label)); + } + + @Test + public void testSetInstruction() { + final Instruction instruction = new Instruction(123); + LabelInfo.setInstruction(label, instruction); + assertSame(instruction, LabelInfo.getInstruction(label)); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ClassInstrumenterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ClassInstrumenterTest.java index 20ba1c7b..a9e8a96d 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ClassInstrumenterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ClassInstrumenterTest.java @@ -1,64 +1,64 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import static org.junit.Assert.assertNull;
-
-import org.jacoco.core.runtime.IRuntime;
-import org.jacoco.core.runtime.LoggerRuntime;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.commons.EmptyVisitor;
-
-/**
- * Unit tests for {@link ClassInstrumenter}.
- */
-public class ClassInstrumenterTest {
-
- private IRuntime runtime;
-
- private ClassInstrumenter instrumenter;
-
- @Before
- public void setup() {
- runtime = new LoggerRuntime();
- instrumenter = new ClassInstrumenter(123, runtime, new EmptyVisitor());
- }
-
- @Test(expected = IllegalStateException.class)
- public void testInstrumentInstrumentedClass1() {
- instrumenter.visitField(InstrSupport.DATAFIELD_ACC,
- InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC, null,
- null);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testInstrumentInstrumentedClass2() {
- instrumenter.visitMethod(InstrSupport.INITMETHOD_ACC,
- InstrSupport.INITMETHOD_NAME, InstrSupport.INITMETHOD_DESC,
- null, null);
- }
-
- @Test
- public void testNoMethodVisitor() {
- instrumenter = new ClassInstrumenter(123, runtime, new EmptyVisitor() {
- @Override
- public MethodVisitor visitMethod(int access, String name,
- String desc, String signature, String[] exceptions) {
- return null;
- }
- });
- assertNull(instrumenter.visitMethod(0, "foo", "()V", null, null));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.instr; + +import static org.junit.Assert.assertNull; + +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.LoggerRuntime; +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.commons.EmptyVisitor; + +/** + * Unit tests for {@link ClassInstrumenter}. + */ +public class ClassInstrumenterTest { + + private IRuntime runtime; + + private ClassInstrumenter instrumenter; + + @Before + public void setup() { + runtime = new LoggerRuntime(); + instrumenter = new ClassInstrumenter(123, runtime, new EmptyVisitor()); + } + + @Test(expected = IllegalStateException.class) + public void testInstrumentInstrumentedClass1() { + instrumenter.visitField(InstrSupport.DATAFIELD_ACC, + InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC, null, + null); + } + + @Test(expected = IllegalStateException.class) + public void testInstrumentInstrumentedClass2() { + instrumenter.visitMethod(InstrSupport.INITMETHOD_ACC, + InstrSupport.INITMETHOD_NAME, InstrSupport.INITMETHOD_DESC, + null, null); + } + + @Test + public void testNoMethodVisitor() { + instrumenter = new ClassInstrumenter(123, runtime, new EmptyVisitor() { + @Override + public MethodVisitor visitMethod(int access, String name, + String desc, String signature, String[] exceptions) { + return null; + } + }); + assertNull(instrumenter.visitMethod(0, "foo", "()V", null, null)); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java index 94a4e536..0f827c91 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java @@ -1,115 +1,115 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.util.TraceMethodVisitor;
-
-/**
- * Unit tests for {@link InstrSupport}.
- */
-public class InstrSupportTest {
-
- private TraceMethodVisitor trace;
-
- @Before
- public void setup() {
- trace = new TraceMethodVisitor();
- }
-
- @Test
- public void testPushIntM2147483648() {
- InstrSupport.push(trace, -2147483648);
- assertInstruction("LDC -2147483648");
- }
-
- @Test
- public void testPushIntM32768() {
- InstrSupport.push(trace, -32768);
- assertInstruction("SIPUSH -32768");
- }
-
- @Test
- public void testPushIntM128() {
- InstrSupport.push(trace, -128);
- assertInstruction("BIPUSH -128");
- }
-
- @Test
- public void testPushIntM1() {
- InstrSupport.push(trace, -1);
- assertInstruction("ICONST_M1");
- }
-
- @Test
- public void testPushInt0() {
- InstrSupport.push(trace, 0);
- assertInstruction("ICONST_0");
- }
-
- @Test
- public void testPushInt1() {
- InstrSupport.push(trace, 1);
- assertInstruction("ICONST_1");
- }
-
- @Test
- public void testPushInt2() {
- InstrSupport.push(trace, 2);
- assertInstruction("ICONST_2");
- }
-
- @Test
- public void testPushInt3() {
- InstrSupport.push(trace, 3);
- assertInstruction("ICONST_3");
- }
-
- @Test
- public void testPushInt4() {
- InstrSupport.push(trace, 4);
- assertInstruction("ICONST_4");
- }
-
- @Test
- public void testPushInt5() {
- InstrSupport.push(trace, 5);
- assertInstruction("ICONST_5");
- }
-
- @Test
- public void testPushInt127() {
- InstrSupport.push(trace, 127);
- assertInstruction("BIPUSH 127");
- }
-
- @Test
- public void testPushInt32767() {
- InstrSupport.push(trace, 32767);
- assertInstruction("SIPUSH 32767");
- }
-
- @Test
- public void testPushInt2147483647() {
- InstrSupport.push(trace, 2147483647);
- assertInstruction("LDC 2147483647");
- }
-
- private void assertInstruction(String expected) {
- assertEquals(1, trace.text.size());
- assertEquals(expected, trace.text.get(0).toString().trim());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.instr; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.util.TraceMethodVisitor; + +/** + * Unit tests for {@link InstrSupport}. + */ +public class InstrSupportTest { + + private TraceMethodVisitor trace; + + @Before + public void setup() { + trace = new TraceMethodVisitor(); + } + + @Test + public void testPushIntM2147483648() { + InstrSupport.push(trace, -2147483648); + assertInstruction("LDC -2147483648"); + } + + @Test + public void testPushIntM32768() { + InstrSupport.push(trace, -32768); + assertInstruction("SIPUSH -32768"); + } + + @Test + public void testPushIntM128() { + InstrSupport.push(trace, -128); + assertInstruction("BIPUSH -128"); + } + + @Test + public void testPushIntM1() { + InstrSupport.push(trace, -1); + assertInstruction("ICONST_M1"); + } + + @Test + public void testPushInt0() { + InstrSupport.push(trace, 0); + assertInstruction("ICONST_0"); + } + + @Test + public void testPushInt1() { + InstrSupport.push(trace, 1); + assertInstruction("ICONST_1"); + } + + @Test + public void testPushInt2() { + InstrSupport.push(trace, 2); + assertInstruction("ICONST_2"); + } + + @Test + public void testPushInt3() { + InstrSupport.push(trace, 3); + assertInstruction("ICONST_3"); + } + + @Test + public void testPushInt4() { + InstrSupport.push(trace, 4); + assertInstruction("ICONST_4"); + } + + @Test + public void testPushInt5() { + InstrSupport.push(trace, 5); + assertInstruction("ICONST_5"); + } + + @Test + public void testPushInt127() { + InstrSupport.push(trace, 127); + assertInstruction("BIPUSH 127"); + } + + @Test + public void testPushInt32767() { + InstrSupport.push(trace, 32767); + assertInstruction("SIPUSH 32767"); + } + + @Test + public void testPushInt2147483647() { + InstrSupport.push(trace, 2147483647); + assertInstruction("LDC 2147483647"); + } + + private void assertInstruction(String expected) { + assertEquals(1, trace.text.size()); + assertEquals(expected, trace.text.get(0).toString().trim()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/MethodInstrumenterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/MethodInstrumenterTest.java index 182e0453..e8613a0a 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/MethodInstrumenterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/MethodInstrumenterTest.java @@ -1,234 +1,234 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import static org.junit.Assert.assertEquals;
-
-import org.jacoco.core.instr.MethodRecorder;
-import org.jacoco.core.internal.flow.LabelInfo;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Unit tests for {@link MethodInstrumenter}.
- */
-public class MethodInstrumenterTest {
-
- private MethodInstrumenter instrumenter;
-
- private MethodRecorder expected;
-
- private MethodRecorder actual;
-
- @Before
- public void setup() {
- actual = new MethodRecorder();
- expected = new MethodRecorder();
- final IProbeInserter probeInserter = new IProbeInserter() {
-
- public void insertProbe(int id) {
- actual.visitLdcInsn("Probe " + id);
- }
- };
- final IFrameInserter frameInserter = new IFrameInserter() {
-
- public void insertFrame() {
- actual.visitLdcInsn("Frame");
- }
- };
- instrumenter = new MethodInstrumenter(actual, probeInserter,
- frameInserter);
- }
-
- void sampleReturn() {
- return;
- }
-
- @Test
- public void testVisitProbe() {
- instrumenter.visitProbe(33);
-
- expected.visitLdcInsn("Probe 33");
-
- assertEquals(expected, actual);
- }
-
- @Test
- public void testVisitInsnWithProbe() {
- instrumenter.visitInsnWithProbe(Opcodes.RETURN, 3);
-
- expected.visitLdcInsn("Probe 3");
- expected.visitInsn(Opcodes.RETURN);
-
- assertEquals(expected, actual);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_GOTO() {
- final Label label = new Label();
- instrumenter.visitJumpInsnWithProbe(Opcodes.GOTO, label, 3);
-
- expected.visitLdcInsn("Probe 3");
- expected.visitJumpInsn(Opcodes.GOTO, label);
-
- assertEquals(expected, actual);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IFEQ() {
- testVisitJumpInsnWithProbe(Opcodes.IFEQ, Opcodes.IFNE);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IFGE() {
- testVisitJumpInsnWithProbe(Opcodes.IFGE, Opcodes.IFLT);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IFGT() {
- testVisitJumpInsnWithProbe(Opcodes.IFGT, Opcodes.IFLE);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IFLE() {
- testVisitJumpInsnWithProbe(Opcodes.IFLE, Opcodes.IFGT);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IFLT() {
- testVisitJumpInsnWithProbe(Opcodes.IFLT, Opcodes.IFGE);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IFNE() {
- testVisitJumpInsnWithProbe(Opcodes.IFNE, Opcodes.IFEQ);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IF_ACMPEQ() {
- testVisitJumpInsnWithProbe(Opcodes.IF_ACMPEQ, Opcodes.IF_ACMPNE);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IF_ACMPNE() {
- testVisitJumpInsnWithProbe(Opcodes.IF_ACMPNE, Opcodes.IF_ACMPEQ);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IF_ICMPEQ() {
- testVisitJumpInsnWithProbe(Opcodes.IF_ICMPEQ, Opcodes.IF_ICMPNE);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IF_ICMPGE() {
- testVisitJumpInsnWithProbe(Opcodes.IF_ICMPGE, Opcodes.IF_ICMPLT);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IF_ICMPGT() {
- testVisitJumpInsnWithProbe(Opcodes.IF_ICMPGT, Opcodes.IF_ICMPLE);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IF_ICMPLE() {
- testVisitJumpInsnWithProbe(Opcodes.IF_ICMPLE, Opcodes.IF_ICMPGT);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IF_ICMPLT() {
- testVisitJumpInsnWithProbe(Opcodes.IF_ICMPLT, Opcodes.IF_ICMPGE);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IF_ICMPNE() {
- testVisitJumpInsnWithProbe(Opcodes.IF_ICMPNE, Opcodes.IF_ICMPEQ);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IFNULL() {
- testVisitJumpInsnWithProbe(Opcodes.IFNULL, Opcodes.IFNONNULL);
- }
-
- @Test
- public void testVisitJumpInsnWithProbe_IFNONNULL() {
- testVisitJumpInsnWithProbe(Opcodes.IFNONNULL, Opcodes.IFNULL);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testVisitJumpInsnWithProbe_InvalidOpcode() {
- testVisitJumpInsnWithProbe(Opcodes.NOP, Opcodes.NOP);
- }
-
- private void testVisitJumpInsnWithProbe(int opcodeOrig, int opcodeInstr) {
- final Label label = new Label();
- instrumenter.visitJumpInsnWithProbe(opcodeOrig, label, 3);
-
- final Label l2 = new Label();
- expected.visitJumpInsn(opcodeInstr, l2);
- expected.visitLdcInsn("Probe 3");
- expected.visitJumpInsn(Opcodes.GOTO, label);
- expected.visitLabel(l2);
- expected.visitLdcInsn("Frame");
-
- assertEquals(expected, actual);
- }
-
- @Test
- public void testVisitTableSwitchInsnWithProbes() {
- final Label L0 = new Label();
- final Label L1 = new Label();
- final Label L2 = new Label();
- LabelInfo.setProbeId(L0, 0);
- LabelInfo.setProbeId(L1, 1);
- instrumenter.visitTableSwitchInsnWithProbes(3, 5, L0, new Label[] { L1,
- L1, L2 });
-
- expected.visitTableSwitchInsn(3, 4, L0, new Label[] { L1, L1, L2 });
- expected.visitLabel(L0);
- expected.visitLdcInsn("Frame");
- expected.visitLdcInsn("Probe 0");
- expected.visitJumpInsn(Opcodes.GOTO, new Label());
- expected.visitLabel(L1);
- expected.visitLdcInsn("Frame");
- expected.visitLdcInsn("Probe 1");
- expected.visitJumpInsn(Opcodes.GOTO, new Label());
-
- assertEquals(expected, actual);
- }
-
- @Test
- public void testVisitLookupSwitchInsnWithProbes() {
- final Label L0 = new Label();
- final Label L1 = new Label();
- final Label L2 = new Label();
- LabelInfo.setProbeId(L0, 0);
- LabelInfo.setProbeId(L1, 1);
- instrumenter.visitLookupSwitchInsnWithProbes(L0,
- new int[] { 10, 20, 30 }, new Label[] { L1, L1, L2 });
-
- expected.visitLookupSwitchInsn(L0, new int[] { 10, 20, 30 },
- new Label[] { L1, L1, L2 });
- expected.visitLabel(L0);
- expected.visitLdcInsn("Frame");
- expected.visitLdcInsn("Probe 0");
- expected.visitJumpInsn(Opcodes.GOTO, new Label());
- expected.visitLabel(L1);
- expected.visitLdcInsn("Frame");
- expected.visitLdcInsn("Probe 1");
- expected.visitJumpInsn(Opcodes.GOTO, new Label());
-
- assertEquals(expected, actual);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.instr; + +import static org.junit.Assert.assertEquals; + +import org.jacoco.core.instr.MethodRecorder; +import org.jacoco.core.internal.flow.LabelInfo; +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; + +/** + * Unit tests for {@link MethodInstrumenter}. + */ +public class MethodInstrumenterTest { + + private MethodInstrumenter instrumenter; + + private MethodRecorder expected; + + private MethodRecorder actual; + + @Before + public void setup() { + actual = new MethodRecorder(); + expected = new MethodRecorder(); + final IProbeInserter probeInserter = new IProbeInserter() { + + public void insertProbe(int id) { + actual.visitLdcInsn("Probe " + id); + } + }; + final IFrameInserter frameInserter = new IFrameInserter() { + + public void insertFrame() { + actual.visitLdcInsn("Frame"); + } + }; + instrumenter = new MethodInstrumenter(actual, probeInserter, + frameInserter); + } + + void sampleReturn() { + return; + } + + @Test + public void testVisitProbe() { + instrumenter.visitProbe(33); + + expected.visitLdcInsn("Probe 33"); + + assertEquals(expected, actual); + } + + @Test + public void testVisitInsnWithProbe() { + instrumenter.visitInsnWithProbe(Opcodes.RETURN, 3); + + expected.visitLdcInsn("Probe 3"); + expected.visitInsn(Opcodes.RETURN); + + assertEquals(expected, actual); + } + + @Test + public void testVisitJumpInsnWithProbe_GOTO() { + final Label label = new Label(); + instrumenter.visitJumpInsnWithProbe(Opcodes.GOTO, label, 3); + + expected.visitLdcInsn("Probe 3"); + expected.visitJumpInsn(Opcodes.GOTO, label); + + assertEquals(expected, actual); + } + + @Test + public void testVisitJumpInsnWithProbe_IFEQ() { + testVisitJumpInsnWithProbe(Opcodes.IFEQ, Opcodes.IFNE); + } + + @Test + public void testVisitJumpInsnWithProbe_IFGE() { + testVisitJumpInsnWithProbe(Opcodes.IFGE, Opcodes.IFLT); + } + + @Test + public void testVisitJumpInsnWithProbe_IFGT() { + testVisitJumpInsnWithProbe(Opcodes.IFGT, Opcodes.IFLE); + } + + @Test + public void testVisitJumpInsnWithProbe_IFLE() { + testVisitJumpInsnWithProbe(Opcodes.IFLE, Opcodes.IFGT); + } + + @Test + public void testVisitJumpInsnWithProbe_IFLT() { + testVisitJumpInsnWithProbe(Opcodes.IFLT, Opcodes.IFGE); + } + + @Test + public void testVisitJumpInsnWithProbe_IFNE() { + testVisitJumpInsnWithProbe(Opcodes.IFNE, Opcodes.IFEQ); + } + + @Test + public void testVisitJumpInsnWithProbe_IF_ACMPEQ() { + testVisitJumpInsnWithProbe(Opcodes.IF_ACMPEQ, Opcodes.IF_ACMPNE); + } + + @Test + public void testVisitJumpInsnWithProbe_IF_ACMPNE() { + testVisitJumpInsnWithProbe(Opcodes.IF_ACMPNE, Opcodes.IF_ACMPEQ); + } + + @Test + public void testVisitJumpInsnWithProbe_IF_ICMPEQ() { + testVisitJumpInsnWithProbe(Opcodes.IF_ICMPEQ, Opcodes.IF_ICMPNE); + } + + @Test + public void testVisitJumpInsnWithProbe_IF_ICMPGE() { + testVisitJumpInsnWithProbe(Opcodes.IF_ICMPGE, Opcodes.IF_ICMPLT); + } + + @Test + public void testVisitJumpInsnWithProbe_IF_ICMPGT() { + testVisitJumpInsnWithProbe(Opcodes.IF_ICMPGT, Opcodes.IF_ICMPLE); + } + + @Test + public void testVisitJumpInsnWithProbe_IF_ICMPLE() { + testVisitJumpInsnWithProbe(Opcodes.IF_ICMPLE, Opcodes.IF_ICMPGT); + } + + @Test + public void testVisitJumpInsnWithProbe_IF_ICMPLT() { + testVisitJumpInsnWithProbe(Opcodes.IF_ICMPLT, Opcodes.IF_ICMPGE); + } + + @Test + public void testVisitJumpInsnWithProbe_IF_ICMPNE() { + testVisitJumpInsnWithProbe(Opcodes.IF_ICMPNE, Opcodes.IF_ICMPEQ); + } + + @Test + public void testVisitJumpInsnWithProbe_IFNULL() { + testVisitJumpInsnWithProbe(Opcodes.IFNULL, Opcodes.IFNONNULL); + } + + @Test + public void testVisitJumpInsnWithProbe_IFNONNULL() { + testVisitJumpInsnWithProbe(Opcodes.IFNONNULL, Opcodes.IFNULL); + } + + @Test(expected = IllegalArgumentException.class) + public void testVisitJumpInsnWithProbe_InvalidOpcode() { + testVisitJumpInsnWithProbe(Opcodes.NOP, Opcodes.NOP); + } + + private void testVisitJumpInsnWithProbe(int opcodeOrig, int opcodeInstr) { + final Label label = new Label(); + instrumenter.visitJumpInsnWithProbe(opcodeOrig, label, 3); + + final Label l2 = new Label(); + expected.visitJumpInsn(opcodeInstr, l2); + expected.visitLdcInsn("Probe 3"); + expected.visitJumpInsn(Opcodes.GOTO, label); + expected.visitLabel(l2); + expected.visitLdcInsn("Frame"); + + assertEquals(expected, actual); + } + + @Test + public void testVisitTableSwitchInsnWithProbes() { + final Label L0 = new Label(); + final Label L1 = new Label(); + final Label L2 = new Label(); + LabelInfo.setProbeId(L0, 0); + LabelInfo.setProbeId(L1, 1); + instrumenter.visitTableSwitchInsnWithProbes(3, 5, L0, new Label[] { L1, + L1, L2 }); + + expected.visitTableSwitchInsn(3, 4, L0, new Label[] { L1, L1, L2 }); + expected.visitLabel(L0); + expected.visitLdcInsn("Frame"); + expected.visitLdcInsn("Probe 0"); + expected.visitJumpInsn(Opcodes.GOTO, new Label()); + expected.visitLabel(L1); + expected.visitLdcInsn("Frame"); + expected.visitLdcInsn("Probe 1"); + expected.visitJumpInsn(Opcodes.GOTO, new Label()); + + assertEquals(expected, actual); + } + + @Test + public void testVisitLookupSwitchInsnWithProbes() { + final Label L0 = new Label(); + final Label L1 = new Label(); + final Label L2 = new Label(); + LabelInfo.setProbeId(L0, 0); + LabelInfo.setProbeId(L1, 1); + instrumenter.visitLookupSwitchInsnWithProbes(L0, + new int[] { 10, 20, 30 }, new Label[] { L1, L1, L2 }); + + expected.visitLookupSwitchInsn(L0, new int[] { 10, 20, 30 }, + new Label[] { L1, L1, L2 }); + expected.visitLabel(L0); + expected.visitLdcInsn("Frame"); + expected.visitLdcInsn("Probe 0"); + expected.visitJumpInsn(Opcodes.GOTO, new Label()); + expected.visitLabel(L1); + expected.visitLdcInsn("Frame"); + expected.visitLdcInsn("Probe 1"); + expected.visitJumpInsn(Opcodes.GOTO, new Label()); + + assertEquals(expected, actual); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ProbeInserterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ProbeInserterTest.java index 50fd701f..b5905480 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ProbeInserterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ProbeInserterTest.java @@ -1,372 +1,372 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import static org.junit.Assert.assertEquals;
-
-import org.jacoco.core.instr.MethodRecorder;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Unit tests for {@link ProbeInserter}.
- */
-public class ProbeInserterTest {
-
- private MethodRecorder actual, expected;
-
- private IProbeArrayStrategy arrayStrategy;
-
- @Before
- public void setup() {
- actual = new MethodRecorder();
- expected = new MethodRecorder();
- arrayStrategy = new IProbeArrayStrategy() {
-
- public int storeInstance(MethodVisitor mv, int variable) {
- mv.visitLdcInsn("init");
- return 5;
- }
-
- public void addMembers(ClassVisitor delegate) {
- }
- };
- }
-
- @After
- public void verify() {
- assertEquals(expected, actual);
- }
-
- @Test
- public void testVariableStatic() {
- ProbeInserter pi = new ProbeInserter(Opcodes.ACC_STATIC, "()V", actual,
- arrayStrategy);
- pi.insertProbe(0);
-
- expected.visitLdcInsn("init");
- expected.visitVarInsn(Opcodes.ALOAD, 0);
- expected.visitInsn(Opcodes.ICONST_0);
- expected.visitInsn(Opcodes.ICONST_1);
- expected.visitInsn(Opcodes.BASTORE);
- }
-
- @Test
- public void testVariableNonStatic() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- pi.insertProbe(0);
-
- expected.visitLdcInsn("init");
- expected.visitVarInsn(Opcodes.ALOAD, 1);
- expected.visitInsn(Opcodes.ICONST_0);
- expected.visitInsn(Opcodes.ICONST_1);
- expected.visitInsn(Opcodes.BASTORE);
- }
-
- @Test
- public void testVariableNonStatic_IZObject() {
- ProbeInserter pi = new ProbeInserter(0, "(IZLjava/lang/Object;)V",
- actual, arrayStrategy);
- pi.insertProbe(0);
-
- expected.visitLdcInsn("init");
- expected.visitVarInsn(Opcodes.ALOAD, 4);
- expected.visitInsn(Opcodes.ICONST_0);
- expected.visitInsn(Opcodes.ICONST_1);
- expected.visitInsn(Opcodes.BASTORE);
- }
-
- @Test
- public void testVariableNonStatic_JD() {
- ProbeInserter pi = new ProbeInserter(0, "(JD)V", actual, arrayStrategy);
- pi.insertProbe(0);
-
- expected.visitLdcInsn("init");
- expected.visitVarInsn(Opcodes.ALOAD, 5);
- expected.visitInsn(Opcodes.ICONST_0);
- expected.visitInsn(Opcodes.ICONST_1);
- expected.visitInsn(Opcodes.BASTORE);
- }
-
- @Test
- public void testVisitProlog() {
- ProbeInserter pi = new ProbeInserter(0, "(I)V", actual, arrayStrategy);
- Label label = new Label();
- pi.visitLabel(label);
- pi.visitLineNumber(123, label);
- pi.visitFrame(Opcodes.F_NEW, 1, new Object[] { "I" }, 0, new Object[0]);
- pi.visitInsn(Opcodes.NOP);
-
- expected.visitFrame(Opcodes.F_NEW, 1, new Object[] { "I" }, 0,
- new Object[0]);
- expected.visitLdcInsn("init");
- expected.visitLabel(label);
- expected.visitLineNumber(123, label);
- expected.visitInsn(Opcodes.NOP);
- }
-
- @Test
- public void testVisitLabel() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- Label label = new Label();
- pi.visitInsn(Opcodes.NOP);
- pi.visitLabel(label);
-
- expected.visitLdcInsn("init");
- expected.visitInsn(Opcodes.NOP);
- expected.visitLabel(label);
- }
-
- @Test
- public void testVisitLineNumber() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- Label label = new Label();
- pi.visitInsn(Opcodes.NOP);
- pi.visitLineNumber(123, label);
-
- expected.visitLdcInsn("init");
- expected.visitInsn(Opcodes.NOP);
- expected.visitLineNumber(123, label);
- }
-
- @Test
- public void testVisitVarIns() {
- ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy);
-
- pi.visitVarInsn(Opcodes.ALOAD, 0);
- pi.visitVarInsn(Opcodes.ILOAD, 1);
- pi.visitVarInsn(Opcodes.ILOAD, 2);
- pi.visitVarInsn(Opcodes.ISTORE, 3);
- pi.visitVarInsn(Opcodes.FSTORE, 4);
-
- expected.visitLdcInsn("init");
- // Argument variables stay at the same position:
- expected.visitVarInsn(Opcodes.ALOAD, 0);
- expected.visitVarInsn(Opcodes.ILOAD, 1);
- expected.visitVarInsn(Opcodes.ILOAD, 2);
-
- // Local variables are shifted by one:
- expected.visitVarInsn(Opcodes.ISTORE, 4);
- expected.visitVarInsn(Opcodes.FSTORE, 5);
- }
-
- @Test
- public void testVisitIincInsn() {
- ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy);
- pi.visitIincInsn(0, 100);
- pi.visitIincInsn(1, 101);
- pi.visitIincInsn(2, 102);
- pi.visitIincInsn(3, 103);
- pi.visitIincInsn(4, 104);
-
- expected.visitLdcInsn("init");
- // Argument variables stay at the same position:
- expected.visitIincInsn(0, 100);
- expected.visitIincInsn(1, 101);
- expected.visitIincInsn(2, 102);
-
- // Local variables are shifted by one:
- expected.visitIincInsn(4, 103);
- expected.visitIincInsn(5, 104);
- }
-
- @Test
- public void testVisitLocalVariable() {
- ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy);
-
- pi.visitLocalVariable(null, null, null, null, null, 0);
- pi.visitLocalVariable(null, null, null, null, null, 1);
- pi.visitLocalVariable(null, null, null, null, null, 2);
- pi.visitLocalVariable(null, null, null, null, null, 3);
- pi.visitLocalVariable(null, null, null, null, null, 4);
-
- expected.visitLdcInsn("init");
- // Argument variables stay at the same position:
- expected.visitLocalVariable(null, null, null, null, null, 0);
- expected.visitLocalVariable(null, null, null, null, null, 1);
- expected.visitLocalVariable(null, null, null, null, null, 2);
-
- // Local variables are shifted by one:
- expected.visitLocalVariable(null, null, null, null, null, 4);
- expected.visitLocalVariable(null, null, null, null, null, 5);
- }
-
- @Test
- public void testVisitIntInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- pi.visitIntInsn(Opcodes.BIPUSH, 15);
-
- expected.visitLdcInsn("init");
- expected.visitIntInsn(Opcodes.BIPUSH, 15);
- }
-
- @Test
- public void testVisitTypeInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- pi.visitTypeInsn(Opcodes.NEW, "Foo");
-
- expected.visitLdcInsn("init");
- expected.visitTypeInsn(Opcodes.NEW, "Foo");
- }
-
- @Test
- public void testVisitFieldInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- pi.visitFieldInsn(Opcodes.GETFIELD, "Foo", "i", "I");
-
- expected.visitLdcInsn("init");
- expected.visitFieldInsn(Opcodes.GETFIELD, "Foo", "i", "I");
- }
-
- @Test
- public void testVisitMethodInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- pi.visitMethodInsn(Opcodes.INVOKEINTERFACE, "Foo", "doit", "()V");
-
- expected.visitLdcInsn("init");
- expected.visitMethodInsn(Opcodes.INVOKEINTERFACE, "Foo", "doit", "()V");
- }
-
- @Test
- public void testVisitJumpInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- Label label = new Label();
- pi.visitJumpInsn(Opcodes.GOTO, label);
-
- expected.visitLdcInsn("init");
- expected.visitJumpInsn(Opcodes.GOTO, label);
- }
-
- @Test
- public void testVisitLdcInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- pi.visitLdcInsn("JaCoCo");
-
- expected.visitLdcInsn("init");
- expected.visitLdcInsn("JaCoCo");
- }
-
- @Test
- public void testVisitTableSwitchInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- Label dflt = new Label();
- pi.visitTableSwitchInsn(0, 1, dflt, new Label[0]);
-
- expected.visitLdcInsn("init");
- expected.visitTableSwitchInsn(0, 1, dflt, new Label[0]);
- }
-
- @Test
- public void testVisitLookupSwitchInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- Label dflt = new Label();
- pi.visitLookupSwitchInsn(dflt, new int[0], new Label[0]);
-
- expected.visitLdcInsn("init");
- expected.visitLookupSwitchInsn(dflt, new int[0], new Label[0]);
- }
-
- @Test
- public void testVisitMultiANewArrayInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- pi.visitMultiANewArrayInsn("[[[I", 3);
-
- expected.visitLdcInsn("init");
- expected.visitMultiANewArrayInsn("[[[I", 3);
- }
-
- @Test
- public void testVisitMaxs1() {
- ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy);
- pi.visitInsn(Opcodes.NOP);
- pi.visitMaxs(0, 8);
-
- expected.visitLdcInsn("init");
- expected.visitInsn(Opcodes.NOP);
- expected.visitMaxs(5, 9);
- }
-
- @Test
- public void testVisitMaxs2() {
- ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy);
- pi.visitInsn(Opcodes.NOP);
- pi.visitMaxs(10, 8);
-
- expected.visitLdcInsn("init");
- expected.visitInsn(Opcodes.NOP);
- expected.visitMaxs(13, 9);
- }
-
- @Test
- public void testVisitFrame() {
- ProbeInserter pi = new ProbeInserter(0, "(J)V", actual, arrayStrategy);
-
- pi.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo", Opcodes.LONG },
- 0, new Object[0]);
- pi.visitInsn(Opcodes.NOP);
- pi.visitFrame(Opcodes.F_NEW, 3, new Object[] { "Foo", Opcodes.LONG,
- "java/lang/String" }, 0, new Object[0]);
-
- // The first (implicit) frame must not be modified:
- expected.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo",
- Opcodes.LONG }, 0, new Object[0]);
-
- expected.visitLdcInsn("init");
- expected.visitInsn(Opcodes.NOP);
-
- // Starting from the second frame on the probe variable is inserted:
- expected.visitFrame(Opcodes.F_NEW, 4, new Object[] { "Foo",
- Opcodes.LONG, "[Z", "java/lang/String" }, 0, new Object[0]);
- }
-
- @Test
- public void testVisitFrameDeadCode() {
- ProbeInserter pi = new ProbeInserter(0, "(J)V", actual, arrayStrategy);
-
- pi.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo", Opcodes.LONG },
- 0, new Object[0]);
- pi.visitInsn(Opcodes.RETURN);
-
- // Such sequences are generated by ASM to replace dead code, see
- // http://asm.ow2.org/doc/developer-guide.html#deadcode
- pi.visitFrame(Opcodes.F_NEW, 0, new Object[] {}, 1,
- new Object[] { "java/lang/Throwable" });
- pi.visitInsn(Opcodes.NOP);
- pi.visitInsn(Opcodes.NOP);
- pi.visitInsn(Opcodes.ATHROW);
-
- // The first (implicit) frame must not be modified:
- expected.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo",
- Opcodes.LONG }, 0, new Object[0]);
- expected.visitLdcInsn("init");
- expected.visitInsn(Opcodes.RETURN);
-
- // The locals in this frame are filled with TOP up to the probe variable
- expected.visitFrame(Opcodes.F_NEW, 3, new Object[] { Opcodes.TOP,
- Opcodes.TOP, "[Z", }, 1, new Object[] { "java/lang/Throwable" });
- expected.visitInsn(Opcodes.NOP);
- expected.visitInsn(Opcodes.NOP);
- expected.visitInsn(Opcodes.ATHROW);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testVisitFrame_invalidType() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy);
- pi.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.instr; + +import static org.junit.Assert.assertEquals; + +import org.jacoco.core.instr.MethodRecorder; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Unit tests for {@link ProbeInserter}. + */ +public class ProbeInserterTest { + + private MethodRecorder actual, expected; + + private IProbeArrayStrategy arrayStrategy; + + @Before + public void setup() { + actual = new MethodRecorder(); + expected = new MethodRecorder(); + arrayStrategy = new IProbeArrayStrategy() { + + public int storeInstance(MethodVisitor mv, int variable) { + mv.visitLdcInsn("init"); + return 5; + } + + public void addMembers(ClassVisitor delegate) { + } + }; + } + + @After + public void verify() { + assertEquals(expected, actual); + } + + @Test + public void testVariableStatic() { + ProbeInserter pi = new ProbeInserter(Opcodes.ACC_STATIC, "()V", actual, + arrayStrategy); + pi.insertProbe(0); + + expected.visitLdcInsn("init"); + expected.visitVarInsn(Opcodes.ALOAD, 0); + expected.visitInsn(Opcodes.ICONST_0); + expected.visitInsn(Opcodes.ICONST_1); + expected.visitInsn(Opcodes.BASTORE); + } + + @Test + public void testVariableNonStatic() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + pi.insertProbe(0); + + expected.visitLdcInsn("init"); + expected.visitVarInsn(Opcodes.ALOAD, 1); + expected.visitInsn(Opcodes.ICONST_0); + expected.visitInsn(Opcodes.ICONST_1); + expected.visitInsn(Opcodes.BASTORE); + } + + @Test + public void testVariableNonStatic_IZObject() { + ProbeInserter pi = new ProbeInserter(0, "(IZLjava/lang/Object;)V", + actual, arrayStrategy); + pi.insertProbe(0); + + expected.visitLdcInsn("init"); + expected.visitVarInsn(Opcodes.ALOAD, 4); + expected.visitInsn(Opcodes.ICONST_0); + expected.visitInsn(Opcodes.ICONST_1); + expected.visitInsn(Opcodes.BASTORE); + } + + @Test + public void testVariableNonStatic_JD() { + ProbeInserter pi = new ProbeInserter(0, "(JD)V", actual, arrayStrategy); + pi.insertProbe(0); + + expected.visitLdcInsn("init"); + expected.visitVarInsn(Opcodes.ALOAD, 5); + expected.visitInsn(Opcodes.ICONST_0); + expected.visitInsn(Opcodes.ICONST_1); + expected.visitInsn(Opcodes.BASTORE); + } + + @Test + public void testVisitProlog() { + ProbeInserter pi = new ProbeInserter(0, "(I)V", actual, arrayStrategy); + Label label = new Label(); + pi.visitLabel(label); + pi.visitLineNumber(123, label); + pi.visitFrame(Opcodes.F_NEW, 1, new Object[] { "I" }, 0, new Object[0]); + pi.visitInsn(Opcodes.NOP); + + expected.visitFrame(Opcodes.F_NEW, 1, new Object[] { "I" }, 0, + new Object[0]); + expected.visitLdcInsn("init"); + expected.visitLabel(label); + expected.visitLineNumber(123, label); + expected.visitInsn(Opcodes.NOP); + } + + @Test + public void testVisitLabel() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + Label label = new Label(); + pi.visitInsn(Opcodes.NOP); + pi.visitLabel(label); + + expected.visitLdcInsn("init"); + expected.visitInsn(Opcodes.NOP); + expected.visitLabel(label); + } + + @Test + public void testVisitLineNumber() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + Label label = new Label(); + pi.visitInsn(Opcodes.NOP); + pi.visitLineNumber(123, label); + + expected.visitLdcInsn("init"); + expected.visitInsn(Opcodes.NOP); + expected.visitLineNumber(123, label); + } + + @Test + public void testVisitVarIns() { + ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy); + + pi.visitVarInsn(Opcodes.ALOAD, 0); + pi.visitVarInsn(Opcodes.ILOAD, 1); + pi.visitVarInsn(Opcodes.ILOAD, 2); + pi.visitVarInsn(Opcodes.ISTORE, 3); + pi.visitVarInsn(Opcodes.FSTORE, 4); + + expected.visitLdcInsn("init"); + // Argument variables stay at the same position: + expected.visitVarInsn(Opcodes.ALOAD, 0); + expected.visitVarInsn(Opcodes.ILOAD, 1); + expected.visitVarInsn(Opcodes.ILOAD, 2); + + // Local variables are shifted by one: + expected.visitVarInsn(Opcodes.ISTORE, 4); + expected.visitVarInsn(Opcodes.FSTORE, 5); + } + + @Test + public void testVisitIincInsn() { + ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy); + pi.visitIincInsn(0, 100); + pi.visitIincInsn(1, 101); + pi.visitIincInsn(2, 102); + pi.visitIincInsn(3, 103); + pi.visitIincInsn(4, 104); + + expected.visitLdcInsn("init"); + // Argument variables stay at the same position: + expected.visitIincInsn(0, 100); + expected.visitIincInsn(1, 101); + expected.visitIincInsn(2, 102); + + // Local variables are shifted by one: + expected.visitIincInsn(4, 103); + expected.visitIincInsn(5, 104); + } + + @Test + public void testVisitLocalVariable() { + ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy); + + pi.visitLocalVariable(null, null, null, null, null, 0); + pi.visitLocalVariable(null, null, null, null, null, 1); + pi.visitLocalVariable(null, null, null, null, null, 2); + pi.visitLocalVariable(null, null, null, null, null, 3); + pi.visitLocalVariable(null, null, null, null, null, 4); + + expected.visitLdcInsn("init"); + // Argument variables stay at the same position: + expected.visitLocalVariable(null, null, null, null, null, 0); + expected.visitLocalVariable(null, null, null, null, null, 1); + expected.visitLocalVariable(null, null, null, null, null, 2); + + // Local variables are shifted by one: + expected.visitLocalVariable(null, null, null, null, null, 4); + expected.visitLocalVariable(null, null, null, null, null, 5); + } + + @Test + public void testVisitIntInsn() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + pi.visitIntInsn(Opcodes.BIPUSH, 15); + + expected.visitLdcInsn("init"); + expected.visitIntInsn(Opcodes.BIPUSH, 15); + } + + @Test + public void testVisitTypeInsn() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + pi.visitTypeInsn(Opcodes.NEW, "Foo"); + + expected.visitLdcInsn("init"); + expected.visitTypeInsn(Opcodes.NEW, "Foo"); + } + + @Test + public void testVisitFieldInsn() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + pi.visitFieldInsn(Opcodes.GETFIELD, "Foo", "i", "I"); + + expected.visitLdcInsn("init"); + expected.visitFieldInsn(Opcodes.GETFIELD, "Foo", "i", "I"); + } + + @Test + public void testVisitMethodInsn() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + pi.visitMethodInsn(Opcodes.INVOKEINTERFACE, "Foo", "doit", "()V"); + + expected.visitLdcInsn("init"); + expected.visitMethodInsn(Opcodes.INVOKEINTERFACE, "Foo", "doit", "()V"); + } + + @Test + public void testVisitJumpInsn() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + Label label = new Label(); + pi.visitJumpInsn(Opcodes.GOTO, label); + + expected.visitLdcInsn("init"); + expected.visitJumpInsn(Opcodes.GOTO, label); + } + + @Test + public void testVisitLdcInsn() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + pi.visitLdcInsn("JaCoCo"); + + expected.visitLdcInsn("init"); + expected.visitLdcInsn("JaCoCo"); + } + + @Test + public void testVisitTableSwitchInsn() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + Label dflt = new Label(); + pi.visitTableSwitchInsn(0, 1, dflt, new Label[0]); + + expected.visitLdcInsn("init"); + expected.visitTableSwitchInsn(0, 1, dflt, new Label[0]); + } + + @Test + public void testVisitLookupSwitchInsn() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + Label dflt = new Label(); + pi.visitLookupSwitchInsn(dflt, new int[0], new Label[0]); + + expected.visitLdcInsn("init"); + expected.visitLookupSwitchInsn(dflt, new int[0], new Label[0]); + } + + @Test + public void testVisitMultiANewArrayInsn() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + pi.visitMultiANewArrayInsn("[[[I", 3); + + expected.visitLdcInsn("init"); + expected.visitMultiANewArrayInsn("[[[I", 3); + } + + @Test + public void testVisitMaxs1() { + ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy); + pi.visitInsn(Opcodes.NOP); + pi.visitMaxs(0, 8); + + expected.visitLdcInsn("init"); + expected.visitInsn(Opcodes.NOP); + expected.visitMaxs(5, 9); + } + + @Test + public void testVisitMaxs2() { + ProbeInserter pi = new ProbeInserter(0, "(II)V", actual, arrayStrategy); + pi.visitInsn(Opcodes.NOP); + pi.visitMaxs(10, 8); + + expected.visitLdcInsn("init"); + expected.visitInsn(Opcodes.NOP); + expected.visitMaxs(13, 9); + } + + @Test + public void testVisitFrame() { + ProbeInserter pi = new ProbeInserter(0, "(J)V", actual, arrayStrategy); + + pi.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo", Opcodes.LONG }, + 0, new Object[0]); + pi.visitInsn(Opcodes.NOP); + pi.visitFrame(Opcodes.F_NEW, 3, new Object[] { "Foo", Opcodes.LONG, + "java/lang/String" }, 0, new Object[0]); + + // The first (implicit) frame must not be modified: + expected.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo", + Opcodes.LONG }, 0, new Object[0]); + + expected.visitLdcInsn("init"); + expected.visitInsn(Opcodes.NOP); + + // Starting from the second frame on the probe variable is inserted: + expected.visitFrame(Opcodes.F_NEW, 4, new Object[] { "Foo", + Opcodes.LONG, "[Z", "java/lang/String" }, 0, new Object[0]); + } + + @Test + public void testVisitFrameDeadCode() { + ProbeInserter pi = new ProbeInserter(0, "(J)V", actual, arrayStrategy); + + pi.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo", Opcodes.LONG }, + 0, new Object[0]); + pi.visitInsn(Opcodes.RETURN); + + // Such sequences are generated by ASM to replace dead code, see + // http://asm.ow2.org/doc/developer-guide.html#deadcode + pi.visitFrame(Opcodes.F_NEW, 0, new Object[] {}, 1, + new Object[] { "java/lang/Throwable" }); + pi.visitInsn(Opcodes.NOP); + pi.visitInsn(Opcodes.NOP); + pi.visitInsn(Opcodes.ATHROW); + + // The first (implicit) frame must not be modified: + expected.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo", + Opcodes.LONG }, 0, new Object[0]); + expected.visitLdcInsn("init"); + expected.visitInsn(Opcodes.RETURN); + + // The locals in this frame are filled with TOP up to the probe variable + expected.visitFrame(Opcodes.F_NEW, 3, new Object[] { Opcodes.TOP, + Opcodes.TOP, "[Z", }, 1, new Object[] { "java/lang/Throwable" }); + expected.visitInsn(Opcodes.NOP); + expected.visitInsn(Opcodes.NOP); + expected.visitInsn(Opcodes.ATHROW); + } + + @Test(expected = IllegalArgumentException.class) + public void testVisitFrame_invalidType() { + ProbeInserter pi = new ProbeInserter(0, "()V", actual, arrayStrategy); + pi.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java index 52b77a5c..ea28d1cd 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/AgentOptionsTest.java @@ -1,324 +1,324 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-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 java.io.File;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link AgentOptions}.
- */
-public class AgentOptionsTest {
-
- private static File defaultAgentJarFile;
-
- @BeforeClass
- public static void beforeClass() {
- defaultAgentJarFile = new File("jacocoagent.jar");
- }
-
- @Test
- public void testDefaults() {
- AgentOptions options = new AgentOptions();
- assertEquals("jacoco.exec", options.getDestfile());
- assertTrue(options.getAppend());
- assertEquals("*", options.getIncludes());
- assertEquals("", options.getExcludes());
- assertEquals("sun.reflect.DelegatingClassLoader",
- options.getExclClassloader());
- assertNull(options.getSessionId());
- assertTrue(options.getDumpOnExit());
- assertEquals(6300, options.getPort());
- assertNull(options.getAddress());
- assertEquals(AgentOptions.OutputMode.file, options.getOutput());
- assertEquals("", options.toString());
- assertNull(options.getClassDumpDir());
- }
-
- @Test
- public void testEmptyOptions() {
- AgentOptions options = new AgentOptions("");
- assertEquals("", options.toString());
- }
-
- @Test
- public void testNullOptions() {
- AgentOptions options = new AgentOptions(null);
- assertEquals("", options.toString());
- }
-
- @Test
- public void testGetDestile() {
- AgentOptions options = new AgentOptions("destfile=/var/test.exec");
- assertEquals("/var/test.exec", options.getDestfile());
- }
-
- @Test
- public void testSetDestile() {
- AgentOptions options = new AgentOptions();
- options.setDestfile("/var/test.exec");
- assertEquals("/var/test.exec", options.getDestfile());
- assertEquals("destfile=/var/test.exec", options.toString());
- }
-
- @Test
- public void testGetAppendTrue() {
- AgentOptions options = new AgentOptions("append=true");
- assertTrue(options.getAppend());
- }
-
- @Test
- public void testGetAppendFalse() {
- AgentOptions options = new AgentOptions("append=false");
- assertFalse(options.getAppend());
- }
-
- @Test
- public void testSetAppendTrue() {
- AgentOptions options = new AgentOptions();
- options.setAppend(true);
- assertTrue(options.getAppend());
- assertEquals("append=true", options.toString());
- }
-
- @Test
- public void testSetAppendFalse() {
- AgentOptions options = new AgentOptions();
- options.setAppend(false);
- assertFalse(options.getAppend());
- assertEquals("append=false", options.toString());
- }
-
- @Test
- public void testGetExclClassloader() {
- AgentOptions options = new AgentOptions(
- "exclclassloader=org.jacoco.test.TestLoader");
- assertEquals("org.jacoco.test.TestLoader", options.getExclClassloader());
- }
-
- @Test
- public void testSetExclClassloader() {
- AgentOptions options = new AgentOptions();
- options.setExclClassloader("org.jacoco.test.TestLoader");
- assertEquals("org.jacoco.test.TestLoader", options.getExclClassloader());
- assertEquals("exclclassloader=org.jacoco.test.TestLoader",
- options.toString());
- }
-
- @Test
- public void testGetIncludes() {
- AgentOptions options = new AgentOptions("includes=org.*|com.*");
- assertEquals("org.*|com.*", options.getIncludes());
- }
-
- @Test
- public void testSetIncludes() {
- AgentOptions options = new AgentOptions();
- options.setIncludes("org.jacoco.*");
- assertEquals("org.jacoco.*", options.getIncludes());
- assertEquals("includes=org.jacoco.*", options.toString());
- }
-
- @Test
- public void testGetExcludes() {
- AgentOptions options = new AgentOptions("excludes=*Test");
- assertEquals("*Test", options.getExcludes());
- }
-
- @Test
- public void testSetExcludes() {
- AgentOptions options = new AgentOptions();
- options.setExcludes("org.jacoco.test.*");
- assertEquals("org.jacoco.test.*", options.getExcludes());
- assertEquals("excludes=org.jacoco.test.*", options.toString());
- }
-
- @Test
- public void testGetSessionId() {
- AgentOptions options = new AgentOptions("sessionid=testsession");
- assertEquals("testsession", options.getSessionId());
- }
-
- @Test
- public void testSetSessionId() {
- AgentOptions options = new AgentOptions();
- options.setSessionId("testsession");
- assertEquals("testsession", options.getSessionId());
- assertEquals("sessionid=testsession", options.toString());
- }
-
- @Test
- public void testGetDumpOnExit() {
- AgentOptions options = new AgentOptions("dumponexit=false");
- assertFalse(options.getDumpOnExit());
- }
-
- @Test
- public void testSetDumpOnExit() {
- AgentOptions options = new AgentOptions();
- options.setDumpOnExit(false);
- assertFalse(options.getDumpOnExit());
- }
-
- @Test
- public void testGetOutput() {
- AgentOptions options = new AgentOptions("output=tcpserver");
- assertEquals(AgentOptions.OutputMode.tcpserver, options.getOutput());
- }
-
- @Test
- public void testSetOutput1() {
- AgentOptions options = new AgentOptions();
- options.setOutput("tcpclient");
- assertEquals(AgentOptions.OutputMode.tcpclient, options.getOutput());
- }
-
- @Test
- public void testSetOutput2() {
- AgentOptions options = new AgentOptions();
- options.setOutput(AgentOptions.OutputMode.tcpclient);
- assertEquals(AgentOptions.OutputMode.tcpclient, options.getOutput());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidOutput1() {
- new AgentOptions("output=foo");
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidOutput2() {
- AgentOptions options = new AgentOptions();
- options.setOutput("foo");
- }
-
- @Test
- public void testGetPort() {
- AgentOptions options = new AgentOptions("port=1234");
- assertEquals(1234, options.getPort());
- }
-
- @Test
- public void testSetPort() {
- AgentOptions options = new AgentOptions();
- options.setPort(1234);
- assertEquals(1234, options.getPort());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testParseInvalidPort() {
- new AgentOptions("port=xxx");
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testSetNegativePort() {
- AgentOptions options = new AgentOptions();
- options.setPort(-1234);
- }
-
- @Test
- public void testGetAddress() {
- AgentOptions options = new AgentOptions("address=remotehost");
- assertEquals("remotehost", options.getAddress());
- }
-
- @Test
- public void testSetAddress() {
- AgentOptions options = new AgentOptions();
- options.setAddress("remotehost");
- assertEquals("remotehost", options.getAddress());
- }
-
- @Test
- public void testToString() {
- AgentOptions options = new AgentOptions();
- options.setDestfile("test.exec");
- options.setAppend(false);
- assertEquals("destfile=test.exec,append=false", options.toString());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidOptionFormat() {
- new AgentOptions("destfile");
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidOptionKey() {
- new AgentOptions("destfile=test.exec,something=true");
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidOptionValue() {
- AgentOptions options = new AgentOptions();
- options.setDestfile("invalid,name.exec");
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidPortOptionValue() {
- new AgentOptions("port=-1234");
- }
-
- @Test
- public void testGetClassDumpDir() {
- AgentOptions options = new AgentOptions("classdumpdir=target/dump");
- assertEquals("target/dump", options.getClassDumpDir());
- }
-
- @Test
- public void testSetClassDumpDir() {
- AgentOptions options = new AgentOptions();
- options.setClassDumpDir("target/dump");
- assertEquals("target/dump", options.getClassDumpDir());
- assertEquals("classdumpdir=target/dump", options.toString());
- }
-
- @Test
- public void testVMArgsWithNoOptions() {
- AgentOptions options = new AgentOptions();
- String vmArgument = options.getVMArgument(defaultAgentJarFile);
-
- assertEquals(
- String.format("-javaagent:%s=", defaultAgentJarFile.toString()),
- vmArgument);
- }
-
- @Test
- public void testVMArgsWithOneOption() {
- AgentOptions options = new AgentOptions();
- options.setAppend(true);
-
- String vmArgument = options.getVMArgument(defaultAgentJarFile);
-
- assertEquals(
- String.format("-javaagent:%s=append=true",
- defaultAgentJarFile.toString()), vmArgument);
- }
-
- @Test
- public void testVMArgsWithOptions() {
- AgentOptions options = new AgentOptions();
- options.setAppend(true);
- options.setDestfile("some test.exec");
- String vmArgument = options.getVMArgument(defaultAgentJarFile);
-
- assertEquals(String.format(
- "-javaagent:%s=destfile=some test.exec,append=true",
- defaultAgentJarFile.toString()), vmArgument);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +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 java.io.File; + +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Unit tests for {@link AgentOptions}. + */ +public class AgentOptionsTest { + + private static File defaultAgentJarFile; + + @BeforeClass + public static void beforeClass() { + defaultAgentJarFile = new File("jacocoagent.jar"); + } + + @Test + public void testDefaults() { + AgentOptions options = new AgentOptions(); + assertEquals("jacoco.exec", options.getDestfile()); + assertTrue(options.getAppend()); + assertEquals("*", options.getIncludes()); + assertEquals("", options.getExcludes()); + assertEquals("sun.reflect.DelegatingClassLoader", + options.getExclClassloader()); + assertNull(options.getSessionId()); + assertTrue(options.getDumpOnExit()); + assertEquals(6300, options.getPort()); + assertNull(options.getAddress()); + assertEquals(AgentOptions.OutputMode.file, options.getOutput()); + assertEquals("", options.toString()); + assertNull(options.getClassDumpDir()); + } + + @Test + public void testEmptyOptions() { + AgentOptions options = new AgentOptions(""); + assertEquals("", options.toString()); + } + + @Test + public void testNullOptions() { + AgentOptions options = new AgentOptions(null); + assertEquals("", options.toString()); + } + + @Test + public void testGetDestile() { + AgentOptions options = new AgentOptions("destfile=/var/test.exec"); + assertEquals("/var/test.exec", options.getDestfile()); + } + + @Test + public void testSetDestile() { + AgentOptions options = new AgentOptions(); + options.setDestfile("/var/test.exec"); + assertEquals("/var/test.exec", options.getDestfile()); + assertEquals("destfile=/var/test.exec", options.toString()); + } + + @Test + public void testGetAppendTrue() { + AgentOptions options = new AgentOptions("append=true"); + assertTrue(options.getAppend()); + } + + @Test + public void testGetAppendFalse() { + AgentOptions options = new AgentOptions("append=false"); + assertFalse(options.getAppend()); + } + + @Test + public void testSetAppendTrue() { + AgentOptions options = new AgentOptions(); + options.setAppend(true); + assertTrue(options.getAppend()); + assertEquals("append=true", options.toString()); + } + + @Test + public void testSetAppendFalse() { + AgentOptions options = new AgentOptions(); + options.setAppend(false); + assertFalse(options.getAppend()); + assertEquals("append=false", options.toString()); + } + + @Test + public void testGetExclClassloader() { + AgentOptions options = new AgentOptions( + "exclclassloader=org.jacoco.test.TestLoader"); + assertEquals("org.jacoco.test.TestLoader", options.getExclClassloader()); + } + + @Test + public void testSetExclClassloader() { + AgentOptions options = new AgentOptions(); + options.setExclClassloader("org.jacoco.test.TestLoader"); + assertEquals("org.jacoco.test.TestLoader", options.getExclClassloader()); + assertEquals("exclclassloader=org.jacoco.test.TestLoader", + options.toString()); + } + + @Test + public void testGetIncludes() { + AgentOptions options = new AgentOptions("includes=org.*|com.*"); + assertEquals("org.*|com.*", options.getIncludes()); + } + + @Test + public void testSetIncludes() { + AgentOptions options = new AgentOptions(); + options.setIncludes("org.jacoco.*"); + assertEquals("org.jacoco.*", options.getIncludes()); + assertEquals("includes=org.jacoco.*", options.toString()); + } + + @Test + public void testGetExcludes() { + AgentOptions options = new AgentOptions("excludes=*Test"); + assertEquals("*Test", options.getExcludes()); + } + + @Test + public void testSetExcludes() { + AgentOptions options = new AgentOptions(); + options.setExcludes("org.jacoco.test.*"); + assertEquals("org.jacoco.test.*", options.getExcludes()); + assertEquals("excludes=org.jacoco.test.*", options.toString()); + } + + @Test + public void testGetSessionId() { + AgentOptions options = new AgentOptions("sessionid=testsession"); + assertEquals("testsession", options.getSessionId()); + } + + @Test + public void testSetSessionId() { + AgentOptions options = new AgentOptions(); + options.setSessionId("testsession"); + assertEquals("testsession", options.getSessionId()); + assertEquals("sessionid=testsession", options.toString()); + } + + @Test + public void testGetDumpOnExit() { + AgentOptions options = new AgentOptions("dumponexit=false"); + assertFalse(options.getDumpOnExit()); + } + + @Test + public void testSetDumpOnExit() { + AgentOptions options = new AgentOptions(); + options.setDumpOnExit(false); + assertFalse(options.getDumpOnExit()); + } + + @Test + public void testGetOutput() { + AgentOptions options = new AgentOptions("output=tcpserver"); + assertEquals(AgentOptions.OutputMode.tcpserver, options.getOutput()); + } + + @Test + public void testSetOutput1() { + AgentOptions options = new AgentOptions(); + options.setOutput("tcpclient"); + assertEquals(AgentOptions.OutputMode.tcpclient, options.getOutput()); + } + + @Test + public void testSetOutput2() { + AgentOptions options = new AgentOptions(); + options.setOutput(AgentOptions.OutputMode.tcpclient); + assertEquals(AgentOptions.OutputMode.tcpclient, options.getOutput()); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidOutput1() { + new AgentOptions("output=foo"); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidOutput2() { + AgentOptions options = new AgentOptions(); + options.setOutput("foo"); + } + + @Test + public void testGetPort() { + AgentOptions options = new AgentOptions("port=1234"); + assertEquals(1234, options.getPort()); + } + + @Test + public void testSetPort() { + AgentOptions options = new AgentOptions(); + options.setPort(1234); + assertEquals(1234, options.getPort()); + } + + @Test(expected = IllegalArgumentException.class) + public void testParseInvalidPort() { + new AgentOptions("port=xxx"); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetNegativePort() { + AgentOptions options = new AgentOptions(); + options.setPort(-1234); + } + + @Test + public void testGetAddress() { + AgentOptions options = new AgentOptions("address=remotehost"); + assertEquals("remotehost", options.getAddress()); + } + + @Test + public void testSetAddress() { + AgentOptions options = new AgentOptions(); + options.setAddress("remotehost"); + assertEquals("remotehost", options.getAddress()); + } + + @Test + public void testToString() { + AgentOptions options = new AgentOptions(); + options.setDestfile("test.exec"); + options.setAppend(false); + assertEquals("destfile=test.exec,append=false", options.toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidOptionFormat() { + new AgentOptions("destfile"); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidOptionKey() { + new AgentOptions("destfile=test.exec,something=true"); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidOptionValue() { + AgentOptions options = new AgentOptions(); + options.setDestfile("invalid,name.exec"); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidPortOptionValue() { + new AgentOptions("port=-1234"); + } + + @Test + public void testGetClassDumpDir() { + AgentOptions options = new AgentOptions("classdumpdir=target/dump"); + assertEquals("target/dump", options.getClassDumpDir()); + } + + @Test + public void testSetClassDumpDir() { + AgentOptions options = new AgentOptions(); + options.setClassDumpDir("target/dump"); + assertEquals("target/dump", options.getClassDumpDir()); + assertEquals("classdumpdir=target/dump", options.toString()); + } + + @Test + public void testVMArgsWithNoOptions() { + AgentOptions options = new AgentOptions(); + String vmArgument = options.getVMArgument(defaultAgentJarFile); + + assertEquals( + String.format("-javaagent:%s=", defaultAgentJarFile.toString()), + vmArgument); + } + + @Test + public void testVMArgsWithOneOption() { + AgentOptions options = new AgentOptions(); + options.setAppend(true); + + String vmArgument = options.getVMArgument(defaultAgentJarFile); + + assertEquals( + String.format("-javaagent:%s=append=true", + defaultAgentJarFile.toString()), vmArgument); + } + + @Test + public void testVMArgsWithOptions() { + AgentOptions options = new AgentOptions(); + options.setAppend(true); + options.setDestfile("some test.exec"); + String vmArgument = options.getVMArgument(defaultAgentJarFile); + + assertEquals(String.format( + "-javaagent:%s=destfile=some test.exec,append=true", + defaultAgentJarFile.toString()), vmArgument); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/ExecutionDataAccessTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/ExecutionDataAccessTest.java index 4c0eb0ed..15368b60 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/ExecutionDataAccessTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/ExecutionDataAccessTest.java @@ -1,157 +1,157 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertSame;
-
-import java.util.concurrent.Callable;
-
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.test.TargetLoader;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-/**
- * Unit tests for {@link ExecutionDataAccess}.
- */
-public class ExecutionDataAccessTest {
-
- private ExecutionDataStore store;
-
- private Object access;
-
- @Before
- public void setup() {
- store = new ExecutionDataStore();
- access = new ExecutionDataAccess(store);
- }
-
- @Test
- public void testEqualsPositive() {
- assertEquals(access, access);
- assertEquals(access.hashCode(), access.hashCode());
- }
-
- @Test
- public void testEqualsNegative() {
- final ExecutionDataAccess other = new ExecutionDataAccess(store);
- assertFalse(access.equals(other));
- assertFalse(access.hashCode() == other.hashCode());
- }
-
- @Test
- public void testGetExecutionData1() {
- Object[] args = new Object[] { Long.valueOf(123), "Foo",
- Integer.valueOf(3) };
- access.equals(args);
- boolean[] data = (boolean[]) args[0];
- assertEquals(3, data.length, 0.0);
- assertFalse(data[0]);
- assertFalse(data[1]);
- assertFalse(data[2]);
- assertSame(store.get(123).getData(), data);
- assertEquals("Foo", store.get(123).getName());
- }
-
- @Test
- public void testGenerateArgumentArray() throws Exception {
- final ClassWriter writer = new ClassWriter(0);
- writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Sample", null,
- "java/lang/Object",
- new String[] { Type.getInternalName(Callable.class) });
-
- // Constructor
- MethodVisitor mv = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
- "()V", null, new String[0]);
- mv.visitCode();
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
- "()V");
- mv.visitInsn(Opcodes.RETURN);
- mv.visitMaxs(1, 1);
- mv.visitEnd();
-
- // call()
- mv = writer.visitMethod(Opcodes.ACC_PUBLIC, "call",
- "()Ljava/lang/Object;", null, new String[0]);
- mv.visitCode();
- ExecutionDataAccess.generateArgumentArray(1000, "Sample", 15, mv);
- mv.visitInsn(Opcodes.ARETURN);
- mv.visitMaxs(5, 1);
- mv.visitEnd();
-
- writer.visitEnd();
- final TargetLoader loader = new TargetLoader("Sample",
- writer.toByteArray());
- Callable<?> callable = (Callable<?>) loader.newTargetInstance();
- final Object[] args = (Object[]) callable.call();
- assertEquals(3, args.length, 0.0);
- assertEquals(Long.valueOf(1000), args[0]);
- assertEquals("Sample", args[1]);
- assertEquals(Integer.valueOf(15), args[2]);
- }
-
- @Test
- public void testGenerateAccessCall() throws Exception {
- final boolean[] data = store.get(Long.valueOf(1234), "Sample", 5)
- .getData();
-
- final ClassWriter writer = new ClassWriter(0);
- writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Sample", null,
- "java/lang/Object",
- new String[] { Type.getInternalName(Callable.class) });
-
- // Constructor
- MethodVisitor mv = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
- "(Ljava/lang/Object;)V", null, new String[0]);
- mv.visitCode();
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
- "()V");
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitVarInsn(Opcodes.ALOAD, 1);
- mv.visitFieldInsn(Opcodes.PUTFIELD, "Sample", "access",
- "Ljava/lang/Object;");
- mv.visitInsn(Opcodes.RETURN);
- mv.visitMaxs(2, 2);
- mv.visitEnd();
-
- // call()
- mv = writer.visitMethod(Opcodes.ACC_PUBLIC, "call",
- "()Ljava/lang/Object;", null, new String[0]);
- mv.visitCode();
- mv.visitVarInsn(Opcodes.ALOAD, 0);
- mv.visitFieldInsn(Opcodes.GETFIELD, "Sample", "access",
- "Ljava/lang/Object;");
- ExecutionDataAccess.generateAccessCall(1234, "Sample", 5, mv);
- mv.visitInsn(Opcodes.ARETURN);
- mv.visitMaxs(6, 1);
- mv.visitEnd();
-
- writer.visitField(Opcodes.ACC_PRIVATE, "access", "Ljava/lang/Object;",
- null, null);
-
- writer.visitEnd();
- final TargetLoader loader = new TargetLoader("Sample",
- writer.toByteArray());
- Callable<?> callable = (Callable<?>) loader.getTargetClass()
- .getConstructor(Object.class).newInstance(access);
- assertSame(data, callable.call());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; + +import java.util.concurrent.Callable; + +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.test.TargetLoader; +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; + +/** + * Unit tests for {@link ExecutionDataAccess}. + */ +public class ExecutionDataAccessTest { + + private ExecutionDataStore store; + + private Object access; + + @Before + public void setup() { + store = new ExecutionDataStore(); + access = new ExecutionDataAccess(store); + } + + @Test + public void testEqualsPositive() { + assertEquals(access, access); + assertEquals(access.hashCode(), access.hashCode()); + } + + @Test + public void testEqualsNegative() { + final ExecutionDataAccess other = new ExecutionDataAccess(store); + assertFalse(access.equals(other)); + assertFalse(access.hashCode() == other.hashCode()); + } + + @Test + public void testGetExecutionData1() { + Object[] args = new Object[] { Long.valueOf(123), "Foo", + Integer.valueOf(3) }; + access.equals(args); + boolean[] data = (boolean[]) args[0]; + assertEquals(3, data.length, 0.0); + assertFalse(data[0]); + assertFalse(data[1]); + assertFalse(data[2]); + assertSame(store.get(123).getData(), data); + assertEquals("Foo", store.get(123).getName()); + } + + @Test + public void testGenerateArgumentArray() throws Exception { + final ClassWriter writer = new ClassWriter(0); + writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Sample", null, + "java/lang/Object", + new String[] { Type.getInternalName(Callable.class) }); + + // Constructor + MethodVisitor mv = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", + "()V", null, new String[0]); + mv.visitCode(); + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", + "()V"); + mv.visitInsn(Opcodes.RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + + // call() + mv = writer.visitMethod(Opcodes.ACC_PUBLIC, "call", + "()Ljava/lang/Object;", null, new String[0]); + mv.visitCode(); + ExecutionDataAccess.generateArgumentArray(1000, "Sample", 15, mv); + mv.visitInsn(Opcodes.ARETURN); + mv.visitMaxs(5, 1); + mv.visitEnd(); + + writer.visitEnd(); + final TargetLoader loader = new TargetLoader("Sample", + writer.toByteArray()); + Callable<?> callable = (Callable<?>) loader.newTargetInstance(); + final Object[] args = (Object[]) callable.call(); + assertEquals(3, args.length, 0.0); + assertEquals(Long.valueOf(1000), args[0]); + assertEquals("Sample", args[1]); + assertEquals(Integer.valueOf(15), args[2]); + } + + @Test + public void testGenerateAccessCall() throws Exception { + final boolean[] data = store.get(Long.valueOf(1234), "Sample", 5) + .getData(); + + final ClassWriter writer = new ClassWriter(0); + writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Sample", null, + "java/lang/Object", + new String[] { Type.getInternalName(Callable.class) }); + + // Constructor + MethodVisitor mv = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", + "(Ljava/lang/Object;)V", null, new String[0]); + mv.visitCode(); + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", + "()V"); + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitVarInsn(Opcodes.ALOAD, 1); + mv.visitFieldInsn(Opcodes.PUTFIELD, "Sample", "access", + "Ljava/lang/Object;"); + mv.visitInsn(Opcodes.RETURN); + mv.visitMaxs(2, 2); + mv.visitEnd(); + + // call() + mv = writer.visitMethod(Opcodes.ACC_PUBLIC, "call", + "()Ljava/lang/Object;", null, new String[0]); + mv.visitCode(); + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitFieldInsn(Opcodes.GETFIELD, "Sample", "access", + "Ljava/lang/Object;"); + ExecutionDataAccess.generateAccessCall(1234, "Sample", 5, mv); + mv.visitInsn(Opcodes.ARETURN); + mv.visitMaxs(6, 1); + mv.visitEnd(); + + writer.visitField(Opcodes.ACC_PRIVATE, "access", "Ljava/lang/Object;", + null, null); + + writer.visitEnd(); + final TargetLoader loader = new TargetLoader("Sample", + writer.toByteArray()); + Callable<?> callable = (Callable<?>) loader.getTargetClass() + .getConstructor(Object.class).newInstance(access); + assertSame(data, callable.call()); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/LoggerRuntimeTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/LoggerRuntimeTest.java index f083bb13..12d1d87d 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/LoggerRuntimeTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/LoggerRuntimeTest.java @@ -1,24 +1,24 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-/**
- * Unit tests for {@link LoggerRuntime}.
- */
-public class LoggerRuntimeTest extends RuntimeTestBase {
-
- @Override
- IRuntime createRuntime() {
- return new LoggerRuntime();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +/** + * Unit tests for {@link LoggerRuntime}. + */ +public class LoggerRuntimeTest extends RuntimeTestBase { + + @Override + IRuntime createRuntime() { + return new LoggerRuntime(); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/ModifiedSystemClassRuntimeTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/ModifiedSystemClassRuntimeTest.java index 4a274570..8d2316bd 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/ModifiedSystemClassRuntimeTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/ModifiedSystemClassRuntimeTest.java @@ -1,170 +1,170 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-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;
-
-import java.lang.instrument.ClassDefinition;
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.Instrumentation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.jar.JarFile;
-
-import org.jacoco.core.test.TargetLoader;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link ModifiedSystemClassRuntime}.
- */
-public class ModifiedSystemClassRuntimeTest extends RuntimeTestBase {
-
- @Override
- IRuntime createRuntime() {
- return new ModifiedSystemClassRuntime(
- ModifiedSystemClassRuntimeTest.class, "accessField");
- }
-
- @Test(expected = RuntimeException.class)
- public void testCreateForNegative() throws Exception {
- InstrumentationMock inst = new InstrumentationMock();
- ModifiedSystemClassRuntime.createFor(inst, TARGET_CLASS_NAME);
- }
-
- /** This static member emulate the instrumented system class. */
- public static Object accessField;
-
- private static final String TARGET_CLASS_NAME = "org/jacoco/core/runtime/ModifiedSystemClassRuntimeTest";
-
- private static class InstrumentationMock implements Instrumentation {
-
- boolean added = false;
-
- boolean removed = false;
-
- public void addTransformer(ClassFileTransformer transformer) {
- assertFalse(added);
- added = true;
- try {
- // Our class should get instrumented:
- final byte[] data = TargetLoader
- .getClassDataAsBytes(ModifiedSystemClassRuntimeTest.class);
- verifyInstrumentedClass(TARGET_CLASS_NAME,
- transformer.transform(null, TARGET_CLASS_NAME, null,
- null, data));
-
- // Other classes will not be instrumented:
- assertNull(transformer.transform(getClass().getClassLoader(),
- "some/other/Class", null, null, new byte[0]));
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public boolean removeTransformer(ClassFileTransformer transformer) {
- assertTrue(added);
- assertFalse(removed);
- removed = true;
- return true;
- }
-
- public Class<?>[] getAllLoadedClasses() {
- fail();
- return null;
- }
-
- public Class<?>[] getInitiatedClasses(ClassLoader loader) {
- fail();
- return null;
- }
-
- public long getObjectSize(Object objectToSize) {
- fail();
- return 0;
- }
-
- public boolean isRedefineClassesSupported() {
- fail();
- return false;
- }
-
- public void redefineClasses(ClassDefinition[] definitions) {
- fail();
- }
-
- // JDK 1.6 Methods:
-
- @SuppressWarnings("unused")
- public void addTransformer(ClassFileTransformer transformer,
- boolean canRetransform) {
- fail();
- }
-
- @SuppressWarnings("unused")
- public void appendToBootstrapClassLoaderSearch(JarFile jarfile) {
- fail();
- }
-
- @SuppressWarnings("unused")
- public void appendToSystemClassLoaderSearch(JarFile jarfile) {
- fail();
- }
-
- @SuppressWarnings("unused")
- public boolean isModifiableClass(Class<?> theClass) {
- fail();
- return false;
- }
-
- @SuppressWarnings("unused")
- public boolean isNativeMethodPrefixSupported() {
- fail();
- return false;
- }
-
- @SuppressWarnings("unused")
- public boolean isRetransformClassesSupported() {
- fail();
- return false;
- }
-
- @SuppressWarnings("unused")
- public void retransformClasses(Class<?>... classes) {
- fail();
- }
-
- @SuppressWarnings("unused")
- public void setNativeMethodPrefix(ClassFileTransformer transformer,
- String prefix) {
- fail();
- }
-
- }
-
- private static void verifyInstrumentedClass(String name, byte[] source)
- throws Exception {
- name = name.replace('/', '.');
- final Class<?> targetClass = new TargetLoader(name, source)
- .getTargetClass();
-
- // Check added field:
- final Field f = targetClass.getField("$jacocoAccess");
- assertTrue(Modifier.isPublic(f.getModifiers()));
- assertTrue(Modifier.isStatic(f.getModifiers()));
- assertTrue(Modifier.isTransient(f.getModifiers()));
- assertEquals(Object.class, f.getType());
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +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; + +import java.lang.instrument.ClassDefinition; +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.Instrumentation; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.jar.JarFile; + +import org.jacoco.core.test.TargetLoader; +import org.junit.Test; + +/** + * Unit tests for {@link ModifiedSystemClassRuntime}. + */ +public class ModifiedSystemClassRuntimeTest extends RuntimeTestBase { + + @Override + IRuntime createRuntime() { + return new ModifiedSystemClassRuntime( + ModifiedSystemClassRuntimeTest.class, "accessField"); + } + + @Test(expected = RuntimeException.class) + public void testCreateForNegative() throws Exception { + InstrumentationMock inst = new InstrumentationMock(); + ModifiedSystemClassRuntime.createFor(inst, TARGET_CLASS_NAME); + } + + /** This static member emulate the instrumented system class. */ + public static Object accessField; + + private static final String TARGET_CLASS_NAME = "org/jacoco/core/runtime/ModifiedSystemClassRuntimeTest"; + + private static class InstrumentationMock implements Instrumentation { + + boolean added = false; + + boolean removed = false; + + public void addTransformer(ClassFileTransformer transformer) { + assertFalse(added); + added = true; + try { + // Our class should get instrumented: + final byte[] data = TargetLoader + .getClassDataAsBytes(ModifiedSystemClassRuntimeTest.class); + verifyInstrumentedClass(TARGET_CLASS_NAME, + transformer.transform(null, TARGET_CLASS_NAME, null, + null, data)); + + // Other classes will not be instrumented: + assertNull(transformer.transform(getClass().getClassLoader(), + "some/other/Class", null, null, new byte[0])); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public boolean removeTransformer(ClassFileTransformer transformer) { + assertTrue(added); + assertFalse(removed); + removed = true; + return true; + } + + public Class<?>[] getAllLoadedClasses() { + fail(); + return null; + } + + public Class<?>[] getInitiatedClasses(ClassLoader loader) { + fail(); + return null; + } + + public long getObjectSize(Object objectToSize) { + fail(); + return 0; + } + + public boolean isRedefineClassesSupported() { + fail(); + return false; + } + + public void redefineClasses(ClassDefinition[] definitions) { + fail(); + } + + // JDK 1.6 Methods: + + @SuppressWarnings("unused") + public void addTransformer(ClassFileTransformer transformer, + boolean canRetransform) { + fail(); + } + + @SuppressWarnings("unused") + public void appendToBootstrapClassLoaderSearch(JarFile jarfile) { + fail(); + } + + @SuppressWarnings("unused") + public void appendToSystemClassLoaderSearch(JarFile jarfile) { + fail(); + } + + @SuppressWarnings("unused") + public boolean isModifiableClass(Class<?> theClass) { + fail(); + return false; + } + + @SuppressWarnings("unused") + public boolean isNativeMethodPrefixSupported() { + fail(); + return false; + } + + @SuppressWarnings("unused") + public boolean isRetransformClassesSupported() { + fail(); + return false; + } + + @SuppressWarnings("unused") + public void retransformClasses(Class<?>... classes) { + fail(); + } + + @SuppressWarnings("unused") + public void setNativeMethodPrefix(ClassFileTransformer transformer, + String prefix) { + fail(); + } + + } + + private static void verifyInstrumentedClass(String name, byte[] source) + throws Exception { + name = name.replace('/', '.'); + final Class<?> targetClass = new TargetLoader(name, source) + .getTargetClass(); + + // Check added field: + final Field f = targetClass.getField("$jacocoAccess"); + assertTrue(Modifier.isPublic(f.getModifiers())); + assertTrue(Modifier.isStatic(f.getModifiers())); + assertTrue(Modifier.isTransient(f.getModifiers())); + assertEquals(Object.class, f.getType()); + } +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/RemoteControlReaderWriterTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/RemoteControlReaderWriterTest.java index fd103e50..0a5f8cae 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/RemoteControlReaderWriterTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/RemoteControlReaderWriterTest.java @@ -1,106 +1,106 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.jacoco.core.data.ExecutionDataReader;
-import org.jacoco.core.data.ExecutionDataReaderWriterTest;
-import org.jacoco.core.data.ExecutionDataWriter;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link ExecutionDataReader} and {@link ExecutionDataWriter}.
- * The tests don't care about the written binary format, they just verify
- * symmetry.
- */
-public class RemoteControlReaderWriterTest extends
- ExecutionDataReaderWriterTest {
-
- private RemoteControlWriter writer;
-
- @Before
- @Override
- public void setup() throws IOException {
- super.setup();
- writer = createWriter(buffer);
- }
-
- @Test(expected = IOException.class)
- public void testNoRemoteCommandVisitor() throws IOException {
- writer.visitDumpCommand(false, false);
- final RemoteControlReader reader = createReader();
- reader.read();
- }
-
- @Test
- public void testVisitDump1() throws IOException {
- testVisitDump(false, false);
- }
-
- @Test
- public void testVisitDump2() throws IOException {
- testVisitDump(false, true);
- }
-
- @Test
- public void testVisitDump3() throws IOException {
- testVisitDump(true, false);
- }
-
- @Test
- public void testVisitDump4() throws IOException {
- testVisitDump(true, true);
- }
-
- private void testVisitDump(boolean doDump, boolean doReset)
- throws IOException {
- writer.visitDumpCommand(doDump, doReset);
- final RemoteControlReader reader = createReader();
- final StringBuilder calls = new StringBuilder();
- reader.setRemoteCommandVisitor(new IRemoteCommandVisitor() {
-
- public void visitDumpCommand(boolean dump, boolean reset) {
- calls.append("cmd(" + dump + "," + reset + ")");
- }
- });
- assertFalse(reader.read());
- assertEquals("cmd(" + doDump + "," + doReset + ")", calls.toString());
- }
-
- @Test
- public void testSendCmdOk() throws IOException {
- writer.sendCmdOk();
- final RemoteControlReader reader = createReader();
- assertTrue(reader.read());
- }
-
- @Override
- protected RemoteControlReader createReader() throws IOException {
- return new RemoteControlReader(new ByteArrayInputStream(
- buffer.toByteArray()));
- }
-
- @Override
- protected RemoteControlWriter createWriter(OutputStream out)
- throws IOException {
- return new RemoteControlWriter(out);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.jacoco.core.data.ExecutionDataReader; +import org.jacoco.core.data.ExecutionDataReaderWriterTest; +import org.jacoco.core.data.ExecutionDataWriter; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link ExecutionDataReader} and {@link ExecutionDataWriter}. + * The tests don't care about the written binary format, they just verify + * symmetry. + */ +public class RemoteControlReaderWriterTest extends + ExecutionDataReaderWriterTest { + + private RemoteControlWriter writer; + + @Before + @Override + public void setup() throws IOException { + super.setup(); + writer = createWriter(buffer); + } + + @Test(expected = IOException.class) + public void testNoRemoteCommandVisitor() throws IOException { + writer.visitDumpCommand(false, false); + final RemoteControlReader reader = createReader(); + reader.read(); + } + + @Test + public void testVisitDump1() throws IOException { + testVisitDump(false, false); + } + + @Test + public void testVisitDump2() throws IOException { + testVisitDump(false, true); + } + + @Test + public void testVisitDump3() throws IOException { + testVisitDump(true, false); + } + + @Test + public void testVisitDump4() throws IOException { + testVisitDump(true, true); + } + + private void testVisitDump(boolean doDump, boolean doReset) + throws IOException { + writer.visitDumpCommand(doDump, doReset); + final RemoteControlReader reader = createReader(); + final StringBuilder calls = new StringBuilder(); + reader.setRemoteCommandVisitor(new IRemoteCommandVisitor() { + + public void visitDumpCommand(boolean dump, boolean reset) { + calls.append("cmd(" + dump + "," + reset + ")"); + } + }); + assertFalse(reader.read()); + assertEquals("cmd(" + doDump + "," + doReset + ")", calls.toString()); + } + + @Test + public void testSendCmdOk() throws IOException { + writer.sendCmdOk(); + final RemoteControlReader reader = createReader(); + assertTrue(reader.read()); + } + + @Override + protected RemoteControlReader createReader() throws IOException { + return new RemoteControlReader(new ByteArrayInputStream( + buffer.toByteArray())); + } + + @Override + protected RemoteControlWriter createWriter(OutputStream out) + throws IOException { + return new RemoteControlWriter(out); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/RuntimeTestBase.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/RuntimeTestBase.java index 88da37e8..9ff6ef35 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/RuntimeTestBase.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/RuntimeTestBase.java @@ -1,329 +1,329 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.IExecutionDataVisitor;
-import org.jacoco.core.data.ISessionInfoVisitor;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.core.internal.instr.InstrSupport;
-import org.jacoco.core.test.TargetLoader;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.EmptyVisitor;
-import org.objectweb.asm.commons.GeneratorAdapter;
-import org.objectweb.asm.commons.Method;
-
-/**
- * Abstract test base for {@link IRuntime} implementations.
- */
-public abstract class RuntimeTestBase {
-
- private IRuntime runtime;
-
- private TestStorage storage;
-
- abstract IRuntime createRuntime();
-
- @Before
- public void setup() throws Exception {
- runtime = createRuntime();
- runtime.startup();
- storage = new TestStorage();
- }
-
- @After
- public void shutdown() {
- runtime.shutdown();
- }
-
- @Test
- public void testGetSetSessionId() {
- assertNotNull(runtime.getSessionId());
- runtime.setSessionId("test-id");
- assertEquals("test-id", runtime.getSessionId());
- }
-
- @Test
- public void testCollectEmpty() {
- runtime.collect(storage, null, false);
- storage.assertSize(0);
- }
-
- @Test
- public void testDataAccessor() throws InstantiationException,
- IllegalAccessException {
- ITarget t = generateAndInstantiateClass(1234);
- runtime.collect(storage, null, false);
- storage.assertData(1234, t.get());
- }
-
- @Test
- public void testReset() throws InstantiationException,
- IllegalAccessException {
- final ITarget target = generateAndInstantiateClass(1000);
- target.a();
- target.b();
-
- runtime.reset();
-
- final boolean[] data = target.get();
- assertFalse(data[0]);
- assertFalse(data[1]);
- }
-
- @Test
- public void testCollectAndReset() throws InstantiationException,
- IllegalAccessException {
- final ITarget target = generateAndInstantiateClass(1001);
- target.a();
- target.b();
-
- runtime.collect(storage, null, true);
-
- final boolean[] data = target.get();
- storage.assertSize(1);
- storage.assertData(1001, data);
- assertFalse(data[0]);
- assertFalse(data[1]);
- }
-
- @Test
- public void testSessionInfo() throws Exception {
- final SessionInfo[] info = new SessionInfo[1];
- final ISessionInfoVisitor visitor = new ISessionInfoVisitor() {
- public void visitSessionInfo(SessionInfo i) {
- info[0] = i;
- }
- };
- runtime.setSessionId("test-session");
- final long t1 = System.currentTimeMillis();
- runtime.startup();
- runtime.collect(storage, visitor, true);
- final long t2 = System.currentTimeMillis();
- assertNotNull(info[0]);
- assertEquals("test-session", info[0].getId());
- assertTrue(info[0].getStartTimeStamp() >= t1);
- assertTrue(info[0].getDumpTimeStamp() <= t2);
-
- info[0] = null;
- runtime.collect(storage, visitor, true);
- final long t3 = System.currentTimeMillis();
- assertNotNull(info[0]);
- assertEquals("test-session", info[0].getId());
- assertTrue(info[0].getStartTimeStamp() >= t2);
- assertTrue(info[0].getDumpTimeStamp() <= t3);
- }
-
- @Test
- public void testNoLocalVariablesInDataAccessor()
- throws InstantiationException, IllegalAccessException {
- runtime.generateDataAccessor(1001, "Target", 5, new EmptyVisitor() {
- @Override
- public void visitVarInsn(int opcode, int var) {
- fail("No usage of local variables allowed.");
- }
- });
- }
-
- @Test
- public void testExecutionRecording() throws InstantiationException,
- IllegalAccessException {
- generateAndInstantiateClass(1001).a();
- runtime.collect(storage, null, false);
- storage.assertSize(1);
- final boolean[] data = storage.getData(1001);
- assertTrue(data[0]);
- assertFalse(data[1]);
- }
-
- @Test
- public void testLoadSameClassTwice() throws InstantiationException,
- IllegalAccessException {
- generateAndInstantiateClass(1001).a();
- generateAndInstantiateClass(1001).b();
- runtime.collect(storage, null, false);
- storage.assertSize(1);
- final boolean[] data = storage.getData(1001);
- assertTrue(data[0]);
- assertTrue(data[1]);
- }
-
- @Test
- public void testDisconnect() throws Exception {
- final ITarget target = generateAndInstantiateClass(1001);
- target.a();
- runtime.disconnect(target.getClass());
- assertNull(target.get());
- runtime.collect(storage, null, false);
- storage.assertSize(1);
- final boolean[] data = storage.getData(1001);
- assertTrue(data[0]);
- }
-
- @Test
- public void testDisconnectInterface() throws Exception {
- // No effect:
- runtime.disconnect(ITarget.class);
- }
-
- /**
- * Creates a new class with the given id, loads this class and instantiates
- * it. The constructor of the generated class will request the probe array
- * from the runtime under test.
- *
- * @param classid
- * @throws InstantiationException
- * @throws IllegalAccessException
- */
- private ITarget generateAndInstantiateClass(int classid)
- throws InstantiationException, IllegalAccessException {
-
- final String className = "org/jacoco/test/targets/RuntimeTestTarget_"
- + classid;
- Type classType = Type.getObjectType(className);
-
- final ClassWriter writer = new ClassWriter(0);
- writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null,
- "java/lang/Object",
- new String[] { Type.getInternalName(ITarget.class) });
-
- writer.visitField(InstrSupport.DATAFIELD_ACC,
- InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC, null,
- null);
-
- // Constructor
- GeneratorAdapter gen = new GeneratorAdapter(writer.visitMethod(
- Opcodes.ACC_PUBLIC, "<init>", "()V", null, new String[0]),
- Opcodes.ACC_PUBLIC, "<init>", "()V");
- gen.visitCode();
- gen.loadThis();
- gen.invokeConstructor(Type.getType(Object.class), new Method("<init>",
- "()V"));
- gen.loadThis();
- final int size = runtime.generateDataAccessor(classid, className, 2,
- gen);
- gen.putStatic(classType, InstrSupport.DATAFIELD_NAME,
- Type.getObjectType(InstrSupport.DATAFIELD_DESC));
- gen.returnValue();
- gen.visitMaxs(size + 1, 0);
- gen.visitEnd();
-
- // get()
- gen = new GeneratorAdapter(writer.visitMethod(Opcodes.ACC_PUBLIC,
- "get", "()[Z", null, new String[0]), Opcodes.ACC_PUBLIC, "get",
- "()[Z");
- gen.visitCode();
- gen.getStatic(classType, InstrSupport.DATAFIELD_NAME,
- Type.getObjectType(InstrSupport.DATAFIELD_DESC));
- gen.returnValue();
- gen.visitMaxs(1, 0);
- gen.visitEnd();
-
- // a()
- gen = new GeneratorAdapter(writer.visitMethod(Opcodes.ACC_PUBLIC, "a",
- "()V", null, new String[0]), Opcodes.ACC_PUBLIC, "a", "()V");
- gen.visitCode();
- gen.getStatic(classType, InstrSupport.DATAFIELD_NAME,
- Type.getObjectType(InstrSupport.DATAFIELD_DESC));
- gen.push(0);
- gen.push(1);
- gen.arrayStore(Type.BOOLEAN_TYPE);
- gen.returnValue();
- gen.visitMaxs(3, 0);
- gen.visitEnd();
-
- // b()
- gen = new GeneratorAdapter(writer.visitMethod(Opcodes.ACC_PUBLIC, "b",
- "()V", null, new String[0]), Opcodes.ACC_PUBLIC, "b", "()V");
- gen.visitCode();
- gen.getStatic(classType, InstrSupport.DATAFIELD_NAME,
- Type.getObjectType(InstrSupport.DATAFIELD_DESC));
- gen.push(1);
- gen.push(1);
- gen.arrayStore(Type.BOOLEAN_TYPE);
- gen.returnValue();
- gen.visitMaxs(3, 0);
- gen.visitEnd();
-
- writer.visitEnd();
-
- final TargetLoader loader = new TargetLoader(
- className.replace('/', '.'), writer.toByteArray());
- return (ITarget) loader.newTargetInstance();
- }
-
- /**
- * With this interface we modify and read coverage data of the generated
- * class.
- */
- public interface ITarget {
-
- /**
- * Returns a reference to the probe array.
- *
- * @return the probe array
- */
- boolean[] get();
-
- /**
- * The implementation will mark probe 0 as executed
- */
- void a();
-
- /**
- * The implementation will mark probe 1 as executed
- */
- void b();
-
- }
-
- private static class TestStorage implements IExecutionDataVisitor {
-
- private final Map<Long, boolean[]> data = new HashMap<Long, boolean[]>();
-
- public void assertSize(int size) {
- assertEquals(size, data.size(), 0.0);
- }
-
- public boolean[] getData(long classId) {
- return data.get(Long.valueOf(classId));
- }
-
- public void assertData(long classId, boolean[] expected) {
- assertSame(expected, getData(classId));
- }
-
- // === ICoverageDataVisitor ===
-
- public void visitClassExecution(final ExecutionData ed) {
- data.put(Long.valueOf(ed.getId()), ed.getData());
- }
-
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.HashMap; +import java.util.Map; + +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.IExecutionDataVisitor; +import org.jacoco.core.data.ISessionInfoVisitor; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.internal.instr.InstrSupport; +import org.jacoco.core.test.TargetLoader; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.EmptyVisitor; +import org.objectweb.asm.commons.GeneratorAdapter; +import org.objectweb.asm.commons.Method; + +/** + * Abstract test base for {@link IRuntime} implementations. + */ +public abstract class RuntimeTestBase { + + private IRuntime runtime; + + private TestStorage storage; + + abstract IRuntime createRuntime(); + + @Before + public void setup() throws Exception { + runtime = createRuntime(); + runtime.startup(); + storage = new TestStorage(); + } + + @After + public void shutdown() { + runtime.shutdown(); + } + + @Test + public void testGetSetSessionId() { + assertNotNull(runtime.getSessionId()); + runtime.setSessionId("test-id"); + assertEquals("test-id", runtime.getSessionId()); + } + + @Test + public void testCollectEmpty() { + runtime.collect(storage, null, false); + storage.assertSize(0); + } + + @Test + public void testDataAccessor() throws InstantiationException, + IllegalAccessException { + ITarget t = generateAndInstantiateClass(1234); + runtime.collect(storage, null, false); + storage.assertData(1234, t.get()); + } + + @Test + public void testReset() throws InstantiationException, + IllegalAccessException { + final ITarget target = generateAndInstantiateClass(1000); + target.a(); + target.b(); + + runtime.reset(); + + final boolean[] data = target.get(); + assertFalse(data[0]); + assertFalse(data[1]); + } + + @Test + public void testCollectAndReset() throws InstantiationException, + IllegalAccessException { + final ITarget target = generateAndInstantiateClass(1001); + target.a(); + target.b(); + + runtime.collect(storage, null, true); + + final boolean[] data = target.get(); + storage.assertSize(1); + storage.assertData(1001, data); + assertFalse(data[0]); + assertFalse(data[1]); + } + + @Test + public void testSessionInfo() throws Exception { + final SessionInfo[] info = new SessionInfo[1]; + final ISessionInfoVisitor visitor = new ISessionInfoVisitor() { + public void visitSessionInfo(SessionInfo i) { + info[0] = i; + } + }; + runtime.setSessionId("test-session"); + final long t1 = System.currentTimeMillis(); + runtime.startup(); + runtime.collect(storage, visitor, true); + final long t2 = System.currentTimeMillis(); + assertNotNull(info[0]); + assertEquals("test-session", info[0].getId()); + assertTrue(info[0].getStartTimeStamp() >= t1); + assertTrue(info[0].getDumpTimeStamp() <= t2); + + info[0] = null; + runtime.collect(storage, visitor, true); + final long t3 = System.currentTimeMillis(); + assertNotNull(info[0]); + assertEquals("test-session", info[0].getId()); + assertTrue(info[0].getStartTimeStamp() >= t2); + assertTrue(info[0].getDumpTimeStamp() <= t3); + } + + @Test + public void testNoLocalVariablesInDataAccessor() + throws InstantiationException, IllegalAccessException { + runtime.generateDataAccessor(1001, "Target", 5, new EmptyVisitor() { + @Override + public void visitVarInsn(int opcode, int var) { + fail("No usage of local variables allowed."); + } + }); + } + + @Test + public void testExecutionRecording() throws InstantiationException, + IllegalAccessException { + generateAndInstantiateClass(1001).a(); + runtime.collect(storage, null, false); + storage.assertSize(1); + final boolean[] data = storage.getData(1001); + assertTrue(data[0]); + assertFalse(data[1]); + } + + @Test + public void testLoadSameClassTwice() throws InstantiationException, + IllegalAccessException { + generateAndInstantiateClass(1001).a(); + generateAndInstantiateClass(1001).b(); + runtime.collect(storage, null, false); + storage.assertSize(1); + final boolean[] data = storage.getData(1001); + assertTrue(data[0]); + assertTrue(data[1]); + } + + @Test + public void testDisconnect() throws Exception { + final ITarget target = generateAndInstantiateClass(1001); + target.a(); + runtime.disconnect(target.getClass()); + assertNull(target.get()); + runtime.collect(storage, null, false); + storage.assertSize(1); + final boolean[] data = storage.getData(1001); + assertTrue(data[0]); + } + + @Test + public void testDisconnectInterface() throws Exception { + // No effect: + runtime.disconnect(ITarget.class); + } + + /** + * Creates a new class with the given id, loads this class and instantiates + * it. The constructor of the generated class will request the probe array + * from the runtime under test. + * + * @param classid + * @throws InstantiationException + * @throws IllegalAccessException + */ + private ITarget generateAndInstantiateClass(int classid) + throws InstantiationException, IllegalAccessException { + + final String className = "org/jacoco/test/targets/RuntimeTestTarget_" + + classid; + Type classType = Type.getObjectType(className); + + final ClassWriter writer = new ClassWriter(0); + writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null, + "java/lang/Object", + new String[] { Type.getInternalName(ITarget.class) }); + + writer.visitField(InstrSupport.DATAFIELD_ACC, + InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC, null, + null); + + // Constructor + GeneratorAdapter gen = new GeneratorAdapter(writer.visitMethod( + Opcodes.ACC_PUBLIC, "<init>", "()V", null, new String[0]), + Opcodes.ACC_PUBLIC, "<init>", "()V"); + gen.visitCode(); + gen.loadThis(); + gen.invokeConstructor(Type.getType(Object.class), new Method("<init>", + "()V")); + gen.loadThis(); + final int size = runtime.generateDataAccessor(classid, className, 2, + gen); + gen.putStatic(classType, InstrSupport.DATAFIELD_NAME, + Type.getObjectType(InstrSupport.DATAFIELD_DESC)); + gen.returnValue(); + gen.visitMaxs(size + 1, 0); + gen.visitEnd(); + + // get() + gen = new GeneratorAdapter(writer.visitMethod(Opcodes.ACC_PUBLIC, + "get", "()[Z", null, new String[0]), Opcodes.ACC_PUBLIC, "get", + "()[Z"); + gen.visitCode(); + gen.getStatic(classType, InstrSupport.DATAFIELD_NAME, + Type.getObjectType(InstrSupport.DATAFIELD_DESC)); + gen.returnValue(); + gen.visitMaxs(1, 0); + gen.visitEnd(); + + // a() + gen = new GeneratorAdapter(writer.visitMethod(Opcodes.ACC_PUBLIC, "a", + "()V", null, new String[0]), Opcodes.ACC_PUBLIC, "a", "()V"); + gen.visitCode(); + gen.getStatic(classType, InstrSupport.DATAFIELD_NAME, + Type.getObjectType(InstrSupport.DATAFIELD_DESC)); + gen.push(0); + gen.push(1); + gen.arrayStore(Type.BOOLEAN_TYPE); + gen.returnValue(); + gen.visitMaxs(3, 0); + gen.visitEnd(); + + // b() + gen = new GeneratorAdapter(writer.visitMethod(Opcodes.ACC_PUBLIC, "b", + "()V", null, new String[0]), Opcodes.ACC_PUBLIC, "b", "()V"); + gen.visitCode(); + gen.getStatic(classType, InstrSupport.DATAFIELD_NAME, + Type.getObjectType(InstrSupport.DATAFIELD_DESC)); + gen.push(1); + gen.push(1); + gen.arrayStore(Type.BOOLEAN_TYPE); + gen.returnValue(); + gen.visitMaxs(3, 0); + gen.visitEnd(); + + writer.visitEnd(); + + final TargetLoader loader = new TargetLoader( + className.replace('/', '.'), writer.toByteArray()); + return (ITarget) loader.newTargetInstance(); + } + + /** + * With this interface we modify and read coverage data of the generated + * class. + */ + public interface ITarget { + + /** + * Returns a reference to the probe array. + * + * @return the probe array + */ + boolean[] get(); + + /** + * The implementation will mark probe 0 as executed + */ + void a(); + + /** + * The implementation will mark probe 1 as executed + */ + void b(); + + } + + private static class TestStorage implements IExecutionDataVisitor { + + private final Map<Long, boolean[]> data = new HashMap<Long, boolean[]>(); + + public void assertSize(int size) { + assertEquals(size, data.size(), 0.0); + } + + public boolean[] getData(long classId) { + return data.get(Long.valueOf(classId)); + } + + public void assertData(long classId, boolean[] expected) { + assertSame(expected, getData(classId)); + } + + // === ICoverageDataVisitor === + + public void visitClassExecution(final ExecutionData ed) { + data.put(Long.valueOf(ed.getId()), ed.getData()); + } + + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/SystemPropertiesRuntimeTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/SystemPropertiesRuntimeTest.java index 354a32ad..b20bca30 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/SystemPropertiesRuntimeTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/SystemPropertiesRuntimeTest.java @@ -1,24 +1,24 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-/**
- * Unit tests for {@link SystemPropertiesRuntime}.
- */
-public class SystemPropertiesRuntimeTest extends RuntimeTestBase {
-
- @Override
- IRuntime createRuntime() {
- return new SystemPropertiesRuntime();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +/** + * Unit tests for {@link SystemPropertiesRuntime}. + */ +public class SystemPropertiesRuntimeTest extends RuntimeTestBase { + + @Override + IRuntime createRuntime() { + return new SystemPropertiesRuntime(); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/URLStreamHandlerRuntimeTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/URLStreamHandlerRuntimeTest.java index 23e5f654..5b909dd1 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/URLStreamHandlerRuntimeTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/URLStreamHandlerRuntimeTest.java @@ -1,24 +1,24 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-/**
- * Unit tests for {@link URLStreamHandlerRuntime}.
- */
-public class URLStreamHandlerRuntimeTest extends RuntimeTestBase {
-
- @Override
- IRuntime createRuntime() {
- return new URLStreamHandlerRuntime();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +/** + * Unit tests for {@link URLStreamHandlerRuntime}. + */ +public class URLStreamHandlerRuntimeTest extends RuntimeTestBase { + + @Override + IRuntime createRuntime() { + return new URLStreamHandlerRuntime(); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/runtime/WildcardMatcherTest.java b/org.jacoco.core.test/src/org/jacoco/core/runtime/WildcardMatcherTest.java index 3e123b37..75c8924e 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/runtime/WildcardMatcherTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/WildcardMatcherTest.java @@ -1,65 +1,65 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-public class WildcardMatcherTest {
-
- @Test
- public void testEmpty() {
- assertTrue(new WildcardMatcher("").matches(""));
- assertFalse(new WildcardMatcher("").matches("abc"));
- }
-
- @Test
- public void testExact() {
- assertTrue(new WildcardMatcher("abc/def.txt").matches("abc/def.txt"));
- }
-
- @Test
- public void testCaseSensitive() {
- assertFalse(new WildcardMatcher("abcdef").matches("abcDef"));
- assertFalse(new WildcardMatcher("ABCDEF").matches("AbCDEF"));
- }
-
- @Test
- public void testQuote() {
- assertFalse(new WildcardMatcher("rst.xyz").matches("rstAxyz"));
- assertTrue(new WildcardMatcher("(x)+").matches("(x)+"));
- }
-
- @Test
- public void testWildcards() {
- assertTrue(new WildcardMatcher("*").matches(""));
- assertTrue(new WildcardMatcher("*").matches("java/lang/Object"));
- assertTrue(new WildcardMatcher("*Test").matches("jacoco/MatcherTest"));
- assertTrue(new WildcardMatcher("Matcher*").matches("Matcher"));
- assertTrue(new WildcardMatcher("Matcher*").matches("MatcherTest"));
- assertTrue(new WildcardMatcher("a*b*a").matches("a-b-b-a"));
- assertFalse(new WildcardMatcher("a*b*a").matches("alaska"));
- assertTrue(new WildcardMatcher("Hello?orld").matches("HelloWorld"));
- assertFalse(new WildcardMatcher("Hello?orld").matches("HelloWWWorld"));
- assertTrue(new WildcardMatcher("?aco*").matches("jacoco"));
- }
-
- @Test
- public void testMultiExpression() {
- assertTrue(new WildcardMatcher("Hello:World").matches("World"));
- assertTrue(new WildcardMatcher("Hello:World").matches("World"));
- assertTrue(new WildcardMatcher("*Test:*Foo").matches("UnitTest"));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class WildcardMatcherTest { + + @Test + public void testEmpty() { + assertTrue(new WildcardMatcher("").matches("")); + assertFalse(new WildcardMatcher("").matches("abc")); + } + + @Test + public void testExact() { + assertTrue(new WildcardMatcher("abc/def.txt").matches("abc/def.txt")); + } + + @Test + public void testCaseSensitive() { + assertFalse(new WildcardMatcher("abcdef").matches("abcDef")); + assertFalse(new WildcardMatcher("ABCDEF").matches("AbCDEF")); + } + + @Test + public void testQuote() { + assertFalse(new WildcardMatcher("rst.xyz").matches("rstAxyz")); + assertTrue(new WildcardMatcher("(x)+").matches("(x)+")); + } + + @Test + public void testWildcards() { + assertTrue(new WildcardMatcher("*").matches("")); + assertTrue(new WildcardMatcher("*").matches("java/lang/Object")); + assertTrue(new WildcardMatcher("*Test").matches("jacoco/MatcherTest")); + assertTrue(new WildcardMatcher("Matcher*").matches("Matcher")); + assertTrue(new WildcardMatcher("Matcher*").matches("MatcherTest")); + assertTrue(new WildcardMatcher("a*b*a").matches("a-b-b-a")); + assertFalse(new WildcardMatcher("a*b*a").matches("alaska")); + assertTrue(new WildcardMatcher("Hello?orld").matches("HelloWorld")); + assertFalse(new WildcardMatcher("Hello?orld").matches("HelloWWWorld")); + assertTrue(new WildcardMatcher("?aco*").matches("jacoco")); + } + + @Test + public void testMultiExpression() { + assertTrue(new WildcardMatcher("Hello:World").matches("World")); + assertTrue(new WildcardMatcher("Hello:World").matches("World")); + assertTrue(new WildcardMatcher("*Test:*Foo").matches("UnitTest")); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java b/org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java index bb216a27..4fa9f69b 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java @@ -1,92 +1,92 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Loads a single class from a byte array.
- */
-public class TargetLoader extends ClassLoader {
-
- private final String sourcename;
-
- private final byte[] bytes;
-
- private final Class<?> clazz;
-
- public TargetLoader(final String name, final byte[] bytes) {
- super(TargetLoader.class.getClassLoader());
- this.sourcename = name;
- this.bytes = bytes;
- clazz = load(name);
- }
-
- public TargetLoader(final Class<?> source, final byte[] bytes) {
- super(TargetLoader.class.getClassLoader());
- this.sourcename = source.getName();
- this.bytes = bytes;
- clazz = load(source.getName());
- }
-
- private Class<?> load(final String sourcename) {
- try {
- return loadClass(sourcename);
- } catch (ClassNotFoundException e) {
- // must not happen
- throw new RuntimeException(e);
- }
- }
-
- public Class<?> getTargetClass() {
- return clazz;
- }
-
- public Object newTargetInstance() throws InstantiationException,
- IllegalAccessException {
- return clazz.newInstance();
- }
-
- public static InputStream getClassData(Class<?> clazz) {
- final String resource = "/" + clazz.getName().replace('.', '/')
- + ".class";
- return clazz.getResourceAsStream(resource);
- }
-
- public static byte[] getClassDataAsBytes(Class<?> clazz) throws IOException {
- InputStream in = getClassData(clazz);
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- byte[] buffer = new byte[0x100];
- int len;
- while ((len = in.read(buffer)) != -1) {
- out.write(buffer, 0, len);
- }
- in.close();
- return out.toByteArray();
- }
-
- @Override
- protected synchronized Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException {
- if (sourcename.equals(name)) {
- Class<?> c = defineClass(name, bytes, 0, bytes.length);
- if (resolve) {
- resolveClass(c);
- }
- return c;
- }
- return super.loadClass(name, resolve);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Loads a single class from a byte array. + */ +public class TargetLoader extends ClassLoader { + + private final String sourcename; + + private final byte[] bytes; + + private final Class<?> clazz; + + public TargetLoader(final String name, final byte[] bytes) { + super(TargetLoader.class.getClassLoader()); + this.sourcename = name; + this.bytes = bytes; + clazz = load(name); + } + + public TargetLoader(final Class<?> source, final byte[] bytes) { + super(TargetLoader.class.getClassLoader()); + this.sourcename = source.getName(); + this.bytes = bytes; + clazz = load(source.getName()); + } + + private Class<?> load(final String sourcename) { + try { + return loadClass(sourcename); + } catch (ClassNotFoundException e) { + // must not happen + throw new RuntimeException(e); + } + } + + public Class<?> getTargetClass() { + return clazz; + } + + public Object newTargetInstance() throws InstantiationException, + IllegalAccessException { + return clazz.newInstance(); + } + + public static InputStream getClassData(Class<?> clazz) { + final String resource = "/" + clazz.getName().replace('.', '/') + + ".class"; + return clazz.getResourceAsStream(resource); + } + + public static byte[] getClassDataAsBytes(Class<?> clazz) throws IOException { + InputStream in = getClassData(clazz); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[0x100]; + int len; + while ((len = in.read(buffer)) != -1) { + out.write(buffer, 0, len); + } + in.close(); + return out.toByteArray(); + } + + @Override + protected synchronized Class<?> loadClass(String name, boolean resolve) + throws ClassNotFoundException { + if (sourcename.equals(name)) { + Class<?> c = defineClass(name, bytes, 0, bytes.length); + if (resolve) { + resolveClass(c); + } + return c; + } + return super.loadClass(name, resolve); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/AnalysisTimeScenario.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/AnalysisTimeScenario.java index ffe3df60..f5a5b6c8 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/AnalysisTimeScenario.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/AnalysisTimeScenario.java @@ -1,52 +1,52 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf;
-
-import org.jacoco.core.analysis.Analyzer;
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.ICoverageVisitor;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.test.TargetLoader;
-
-/**
- * Scenario to measure the time taken by the instrumentation process itself.
- */
-public class AnalysisTimeScenario extends TimedScenario {
-
- private final Class<?> target;
-
- private final int count;
-
- protected AnalysisTimeScenario(Class<?> target, int count) {
- super(String.format("analysing %s classes", Integer.valueOf(count)));
- this.target = target;
- this.count = count;
- }
-
- @Override
- protected Runnable getInstrumentedRunnable() throws Exception {
- final byte[] bytes = TargetLoader.getClassDataAsBytes(target);
- final ExecutionDataStore executionData = new ExecutionDataStore();
- ICoverageVisitor visitor = new ICoverageVisitor() {
- public void visitCoverage(IClassCoverage coverage) {
- }
- };
- final Analyzer analyzer = new Analyzer(executionData, visitor);
- return new Runnable() {
- public void run() {
- for (int i = 0; i < count; i++) {
- analyzer.analyzeClass(bytes);
- }
- }
- };
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf; + +import org.jacoco.core.analysis.Analyzer; +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.ICoverageVisitor; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.test.TargetLoader; + +/** + * Scenario to measure the time taken by the instrumentation process itself. + */ +public class AnalysisTimeScenario extends TimedScenario { + + private final Class<?> target; + + private final int count; + + protected AnalysisTimeScenario(Class<?> target, int count) { + super(String.format("analysing %s classes", Integer.valueOf(count))); + this.target = target; + this.count = count; + } + + @Override + protected Runnable getInstrumentedRunnable() throws Exception { + final byte[] bytes = TargetLoader.getClassDataAsBytes(target); + final ExecutionDataStore executionData = new ExecutionDataStore(); + ICoverageVisitor visitor = new ICoverageVisitor() { + public void visitCoverage(IClassCoverage coverage) { + } + }; + final Analyzer analyzer = new Analyzer(executionData, visitor); + return new Runnable() { + public void run() { + for (int i = 0; i < count; i++) { + analyzer.analyzeClass(bytes); + } + } + }; + } +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/ExecuteInstrumentedCodeScenario.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/ExecuteInstrumentedCodeScenario.java index 92b219f1..513de2a8 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/ExecuteInstrumentedCodeScenario.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/ExecuteInstrumentedCodeScenario.java @@ -1,51 +1,51 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf;
-
-import org.jacoco.core.instr.Instrumenter;
-import org.jacoco.core.runtime.IRuntime;
-import org.jacoco.core.runtime.LoggerRuntime;
-import org.jacoco.core.test.TargetLoader;
-import org.objectweb.asm.ClassReader;
-
-/**
- * This scenario runs a given scenario twice and reports the execution time:
- * Once on its original version, once in a instrumented version.
- */
-public class ExecuteInstrumentedCodeScenario extends TimedScenario {
-
- private final Class<? extends Runnable> target;
-
- protected ExecuteInstrumentedCodeScenario(String description,
- Class<? extends Runnable> target) {
- super(description);
- this.target = target;
- }
-
- @Override
- protected Runnable getInstrumentedRunnable() throws Exception {
- ClassReader reader = new ClassReader(TargetLoader.getClassData(target));
- IRuntime runtime = new LoggerRuntime();
- runtime.startup();
- final Instrumenter instr = new Instrumenter(runtime);
- final byte[] instrumentedBuffer = instr.instrument(reader);
- final TargetLoader loader = new TargetLoader(target, instrumentedBuffer);
-
- return (Runnable) loader.newTargetInstance();
- }
-
- @Override
- protected Runnable getReferenceRunnable() throws Exception {
- return target.newInstance();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf; + +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.LoggerRuntime; +import org.jacoco.core.test.TargetLoader; +import org.objectweb.asm.ClassReader; + +/** + * This scenario runs a given scenario twice and reports the execution time: + * Once on its original version, once in a instrumented version. + */ +public class ExecuteInstrumentedCodeScenario extends TimedScenario { + + private final Class<? extends Runnable> target; + + protected ExecuteInstrumentedCodeScenario(String description, + Class<? extends Runnable> target) { + super(description); + this.target = target; + } + + @Override + protected Runnable getInstrumentedRunnable() throws Exception { + ClassReader reader = new ClassReader(TargetLoader.getClassData(target)); + IRuntime runtime = new LoggerRuntime(); + runtime.startup(); + final Instrumenter instr = new Instrumenter(runtime); + final byte[] instrumentedBuffer = instr.instrument(reader); + final TargetLoader loader = new TargetLoader(target, instrumentedBuffer); + + return (Runnable) loader.newTargetInstance(); + } + + @Override + protected Runnable getReferenceRunnable() throws Exception { + return target.newInstance(); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/IPerfOutput.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/IPerfOutput.java index 8a6cafa0..72e1f1eb 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/IPerfOutput.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/IPerfOutput.java @@ -1,48 +1,48 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf;
-
-/**
- * Interface to report performance figures to.
- */
-public interface IPerfOutput {
-
- /** Indicator for no reference time given */
- public static final long NO_REFERENCE = Long.MIN_VALUE;
-
- /**
- * Reports the result of a time measurement with a optional reference time
- * for comparison.
- *
- * @param description
- * textual description of the test case
- * @param duration
- * duration in nano seconds
- * @param reference
- * optional reference time in nano seconds
- */
- void writeTimeResult(String description, long duration, long reference);
-
- /**
- * Reports the result of a byte size measurement with a optional reference
- * size for comparison.
- *
- * @param description
- * textual description of the test case
- * @param size
- * size in bytes
- * @param reference
- * optional reference size in bytes
- */
- void writeByteResult(String description, long size, long reference);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf; + +/** + * Interface to report performance figures to. + */ +public interface IPerfOutput { + + /** Indicator for no reference time given */ + public static final long NO_REFERENCE = Long.MIN_VALUE; + + /** + * Reports the result of a time measurement with a optional reference time + * for comparison. + * + * @param description + * textual description of the test case + * @param duration + * duration in nano seconds + * @param reference + * optional reference time in nano seconds + */ + void writeTimeResult(String description, long duration, long reference); + + /** + * Reports the result of a byte size measurement with a optional reference + * size for comparison. + * + * @param description + * textual description of the test case + * @param size + * size in bytes + * @param reference + * optional reference size in bytes + */ + void writeByteResult(String description, long size, long reference); + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/IPerfScenario.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/IPerfScenario.java index ed0d02cb..adfafab2 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/IPerfScenario.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/IPerfScenario.java @@ -1,27 +1,27 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf;
-
-/**
- * Interface for a performance scenario.
- */
-public interface IPerfScenario {
-
- /**
- * Runs the performance scenario and reports the result to the given
- * interface.
- *
- * @param output
- */
- public void run(IPerfOutput output) throws Exception;
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf; + +/** + * Interface for a performance scenario. + */ +public interface IPerfScenario { + + /** + * Runs the performance scenario and reports the result to the given + * interface. + * + * @param output + */ + public void run(IPerfOutput output) throws Exception; + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/InstrumentationSizeSzenario.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/InstrumentationSizeSzenario.java index 6453f5fd..9568f555 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/InstrumentationSizeSzenario.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/InstrumentationSizeSzenario.java @@ -1,41 +1,41 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf;
-
-import org.jacoco.core.instr.Instrumenter;
-import org.jacoco.core.runtime.IRuntime;
-import org.jacoco.core.runtime.LoggerRuntime;
-import org.jacoco.core.test.TargetLoader;
-import org.objectweb.asm.ClassReader;
-
-/**
- * Scenario to measure the overhead in terms of additional byte code size
- * through instrumentation.
- */
-public class InstrumentationSizeSzenario implements IPerfScenario {
-
- private final Class<?> target;
-
- public InstrumentationSizeSzenario(Class<?> target) {
- this.target = target;
- }
-
- public void run(IPerfOutput output) throws Exception {
- final IRuntime runtime = new LoggerRuntime();
- ClassReader reader = new ClassReader(TargetLoader.getClassData(target));
- final Instrumenter instr = new Instrumenter(runtime);
- instr.instrument(reader);
- output.writeByteResult("instrumented class",
- instr.instrument(reader).length, reader.b.length);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf; + +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.LoggerRuntime; +import org.jacoco.core.test.TargetLoader; +import org.objectweb.asm.ClassReader; + +/** + * Scenario to measure the overhead in terms of additional byte code size + * through instrumentation. + */ +public class InstrumentationSizeSzenario implements IPerfScenario { + + private final Class<?> target; + + public InstrumentationSizeSzenario(Class<?> target) { + this.target = target; + } + + public void run(IPerfOutput output) throws Exception { + final IRuntime runtime = new LoggerRuntime(); + ClassReader reader = new ClassReader(TargetLoader.getClassData(target)); + final Instrumenter instr = new Instrumenter(runtime); + instr.instrument(reader); + output.writeByteResult("instrumented class", + instr.instrument(reader).length, reader.b.length); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/InstrumentationTimeScenario.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/InstrumentationTimeScenario.java index 581df93c..22503307 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/InstrumentationTimeScenario.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/InstrumentationTimeScenario.java @@ -1,46 +1,46 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf;
-
-import org.jacoco.core.instr.Instrumenter;
-import org.jacoco.core.runtime.LoggerRuntime;
-import org.jacoco.core.test.TargetLoader;
-
-/**
- * Scenario to measure the time taken by the instrumentation process itself.
- */
-public class InstrumentationTimeScenario extends TimedScenario {
-
- private final Class<?> target;
-
- private final int count;
-
- protected InstrumentationTimeScenario(Class<?> target, int count) {
- super(String.format("instrumenting %s classes", Integer.valueOf(count)));
- this.target = target;
- this.count = count;
- }
-
- @Override
- protected Runnable getInstrumentedRunnable() throws Exception {
- final byte[] bytes = TargetLoader.getClassDataAsBytes(target);
- final Instrumenter instr = new Instrumenter(new LoggerRuntime());
- return new Runnable() {
- public void run() {
- for (int i = 0; i < count; i++) {
- instr.instrument(bytes);
- }
- }
- };
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf; + +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.runtime.LoggerRuntime; +import org.jacoco.core.test.TargetLoader; + +/** + * Scenario to measure the time taken by the instrumentation process itself. + */ +public class InstrumentationTimeScenario extends TimedScenario { + + private final Class<?> target; + + private final int count; + + protected InstrumentationTimeScenario(Class<?> target, int count) { + super(String.format("instrumenting %s classes", Integer.valueOf(count))); + this.target = target; + this.count = count; + } + + @Override + protected Runnable getInstrumentedRunnable() throws Exception { + final byte[] bytes = TargetLoader.getClassDataAsBytes(target); + final Instrumenter instr = new Instrumenter(new LoggerRuntime()); + return new Runnable() { + public void run() { + for (int i = 0; i < count; i++) { + instr.instrument(bytes); + } + } + }; + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/PerfOutputWriter.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/PerfOutputWriter.java index 6586a97e..47652fe8 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/PerfOutputWriter.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/PerfOutputWriter.java @@ -1,80 +1,80 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf;
-
-import static java.lang.String.format;
-
-import java.io.PrintWriter;
-
-import org.jacoco.core.JaCoCo;
-
-/**
- * Formatted text output.
- */
-public class PerfOutputWriter implements IPerfOutput {
-
- private final PrintWriter writer;
-
- public PerfOutputWriter(final PrintWriter writer) {
- this.writer = writer;
- writeHeader();
- }
-
- private void writeHeader() {
- writer.printf("JaCoCo Performance Data%n%n");
- writer.printf("JaCoCo Version: %s%n", JaCoCo.VERSION);
- writer.printf("JVM Vendor: %s%n",
- System.getProperty("java.vm.vendor"));
- writer.printf("JVM Version: %s%n%n",
- System.getProperty("java.vm.version"));
- writer.println("scenario instr ref overhead");
- writer.println("----------------------------------------------------------");
- }
-
- public void writeTimeResult(final String description, final long duration,
- final long reference) {
- final double dms = (double) duration / 1000000;
- if (reference == NO_REFERENCE) {
- writeResult(description, dms, "%.2f", "ms");
- } else {
- final double rms = (double) reference / 1000000;
- writeResult(description, dms, rms, "%.2f", "ms");
- }
- }
-
- public void writeByteResult(String description, long size, long reference) {
- if (size == 0) {
- return;
- }
- if (reference == NO_REFERENCE) {
- writeResult(description, size, "%.0f", "bytes");
- } else {
- writeResult(description, size, reference, "%.0f", "bytes");
- }
- }
-
- private void writeResult(final String description, final double subject,
- String fmt, String unit) {
- writer.printf("%-30s%8s %-6s%n", description,
- format(fmt, Double.valueOf(subject)), unit);
- }
-
- private void writeResult(final String description, final double subject,
- final double reference, String fmt, String unit) {
- double overhead = 100 * (subject - reference) / reference;
- writer.printf("%-30s%8s%8s %-6s%4.0f%%%n", description,
- format(fmt, Double.valueOf(subject)),
- format(fmt, Double.valueOf(reference)), unit,
- Double.valueOf(overhead));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf; + +import static java.lang.String.format; + +import java.io.PrintWriter; + +import org.jacoco.core.JaCoCo; + +/** + * Formatted text output. + */ +public class PerfOutputWriter implements IPerfOutput { + + private final PrintWriter writer; + + public PerfOutputWriter(final PrintWriter writer) { + this.writer = writer; + writeHeader(); + } + + private void writeHeader() { + writer.printf("JaCoCo Performance Data%n%n"); + writer.printf("JaCoCo Version: %s%n", JaCoCo.VERSION); + writer.printf("JVM Vendor: %s%n", + System.getProperty("java.vm.vendor")); + writer.printf("JVM Version: %s%n%n", + System.getProperty("java.vm.version")); + writer.println("scenario instr ref overhead"); + writer.println("----------------------------------------------------------"); + } + + public void writeTimeResult(final String description, final long duration, + final long reference) { + final double dms = (double) duration / 1000000; + if (reference == NO_REFERENCE) { + writeResult(description, dms, "%.2f", "ms"); + } else { + final double rms = (double) reference / 1000000; + writeResult(description, dms, rms, "%.2f", "ms"); + } + } + + public void writeByteResult(String description, long size, long reference) { + if (size == 0) { + return; + } + if (reference == NO_REFERENCE) { + writeResult(description, size, "%.0f", "bytes"); + } else { + writeResult(description, size, reference, "%.0f", "bytes"); + } + } + + private void writeResult(final String description, final double subject, + String fmt, String unit) { + writer.printf("%-30s%8s %-6s%n", description, + format(fmt, Double.valueOf(subject)), unit); + } + + private void writeResult(final String description, final double subject, + final double reference, String fmt, String unit) { + double overhead = 100 * (subject - reference) / reference; + writer.printf("%-30s%8s%8s %-6s%4.0f%%%n", description, + format(fmt, Double.valueOf(subject)), + format(fmt, Double.valueOf(reference)), unit, + Double.valueOf(overhead)); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/PerformanceSuite.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/PerformanceSuite.java index d6b2f19d..c51f6260 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/PerformanceSuite.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/PerformanceSuite.java @@ -1,49 +1,49 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf;
-
-import java.io.PrintWriter;
-
-import org.jacoco.core.test.perf.targets.Target01;
-import org.jacoco.core.test.perf.targets.Target02;
-import org.jacoco.core.test.perf.targets.Target03;
-
-/**
- * The main test suite.
- */
-public class PerformanceSuite implements IPerfScenario {
-
- public void run(IPerfOutput output) throws Exception {
- new ExecuteInstrumentedCodeScenario("plain method calls",
- Target01.class).run(output);
- new ExecuteInstrumentedCodeScenario("loop only", Target02.class)
- .run(output);
- new ExecuteInstrumentedCodeScenario("game of life", Target03.class)
- .run(output);
- new InstrumentationSizeSzenario(Target03.class).run(output);
- new InstrumentationTimeScenario(Target03.class, 1000).run(output);
- new AnalysisTimeScenario(Target03.class, 1000).run(output);
- }
-
- public static void main(String[] args) throws Exception {
- final PrintWriter writer;
- if (args.length == 0) {
- writer = new PrintWriter(System.out, true);
- } else {
- writer = new PrintWriter(args[0]);
- }
- IPerfOutput output = new PerfOutputWriter(writer);
- new PerformanceSuite().run(output);
- writer.close();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf; + +import java.io.PrintWriter; + +import org.jacoco.core.test.perf.targets.Target01; +import org.jacoco.core.test.perf.targets.Target02; +import org.jacoco.core.test.perf.targets.Target03; + +/** + * The main test suite. + */ +public class PerformanceSuite implements IPerfScenario { + + public void run(IPerfOutput output) throws Exception { + new ExecuteInstrumentedCodeScenario("plain method calls", + Target01.class).run(output); + new ExecuteInstrumentedCodeScenario("loop only", Target02.class) + .run(output); + new ExecuteInstrumentedCodeScenario("game of life", Target03.class) + .run(output); + new InstrumentationSizeSzenario(Target03.class).run(output); + new InstrumentationTimeScenario(Target03.class, 1000).run(output); + new AnalysisTimeScenario(Target03.class, 1000).run(output); + } + + public static void main(String[] args) throws Exception { + final PrintWriter writer; + if (args.length == 0) { + writer = new PrintWriter(System.out, true); + } else { + writer = new PrintWriter(args[0]); + } + IPerfOutput output = new PerfOutputWriter(writer); + new PerformanceSuite().run(output); + writer.close(); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/TimedScenario.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/TimedScenario.java index a68da4da..5db65a13 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/TimedScenario.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/TimedScenario.java @@ -1,67 +1,67 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf;
-
-/**
- * Base class for execution time test scenarios.
- */
-public abstract class TimedScenario implements IPerfScenario {
-
- private static final int RUNS = 10;
-
- private final String description;
-
- protected TimedScenario(final String description) {
- this.description = description;
- }
-
- public void run(final IPerfOutput output) throws Exception {
- final long time = getMinimumTime(getInstrumentedRunnable());
- final Runnable refRunnable = getReferenceRunnable();
- final long reftime;
- if (refRunnable == null) {
- reftime = IPerfOutput.NO_REFERENCE;
- } else {
- reftime = getMinimumTime(refRunnable);
- }
- output.writeTimeResult(description, time, reftime);
- }
-
- /**
- * Runs the given subject several times and returns the minimum execution
- * time.
- *
- * @param subject
- * @return minimum execution time in nano seconds
- */
- private long getMinimumTime(final Runnable subject) {
- long min = Long.MAX_VALUE;
- for (int i = 0; i < RUNS; i++) {
- final long t = getTime(subject);
- min = Math.min(min, t);
- }
- return min;
- }
-
- private long getTime(final Runnable subject) {
- long start = System.nanoTime();
- subject.run();
- return System.nanoTime() - start;
- }
-
- protected abstract Runnable getInstrumentedRunnable() throws Exception;
-
- protected Runnable getReferenceRunnable() throws Exception {
- return null;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf; + +/** + * Base class for execution time test scenarios. + */ +public abstract class TimedScenario implements IPerfScenario { + + private static final int RUNS = 10; + + private final String description; + + protected TimedScenario(final String description) { + this.description = description; + } + + public void run(final IPerfOutput output) throws Exception { + final long time = getMinimumTime(getInstrumentedRunnable()); + final Runnable refRunnable = getReferenceRunnable(); + final long reftime; + if (refRunnable == null) { + reftime = IPerfOutput.NO_REFERENCE; + } else { + reftime = getMinimumTime(refRunnable); + } + output.writeTimeResult(description, time, reftime); + } + + /** + * Runs the given subject several times and returns the minimum execution + * time. + * + * @param subject + * @return minimum execution time in nano seconds + */ + private long getMinimumTime(final Runnable subject) { + long min = Long.MAX_VALUE; + for (int i = 0; i < RUNS; i++) { + final long t = getTime(subject); + min = Math.min(min, t); + } + return min; + } + + private long getTime(final Runnable subject) { + long start = System.nanoTime(); + subject.run(); + return System.nanoTime() - start; + } + + protected abstract Runnable getInstrumentedRunnable() throws Exception; + + protected Runnable getReferenceRunnable() throws Exception { + return null; + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target01.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target01.java index 4879b6a0..632c149e 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target01.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target01.java @@ -1,126 +1,126 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf.targets;
-
-/**
- * Plain method calls.
- */
-public class Target01 implements Runnable {
-
- @SuppressWarnings("unused")
- private int c;
-
- // 4 ^ 0 = 1 times
- public void run() {
- m1();
- m1();
- m1();
- m1();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 1 = 4 times
- public void m1() {
- m2();
- m2();
- m2();
- m2();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 2 == 16 times
- public void m2() {
- m3();
- m3();
- m3();
- m3();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 3 == 64 times
- public void m3() {
- m4();
- m4();
- m4();
- m4();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 4 == 256 times
- public void m4() {
- m5();
- m5();
- m5();
- m5();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 5 == 1,024 times
- public void m5() {
- m6();
- m6();
- m6();
- m6();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 6 == 4,096 times
- public void m6() {
- m7();
- m7();
- m7();
- m7();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 7 == 16,384 times
- public void m7() {
- m8();
- m8();
- m8();
- m8();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 8 == 65,536 times
- public void m8() {
- m9();
- m9();
- m9();
- m9();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 9 == 262,144 times
- public void m9() {
- m10();
- m10();
- m10();
- m10();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 10 == 1,048,576 times
- public void m10() {
- m11();
- m11();
- m11();
- m11();
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
- // 4 ^ 11 == 4,194,304 times
- public void m11() {
- c++; // some side effect, otherwise the JIT will remove the method
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf.targets; + +/** + * Plain method calls. + */ +public class Target01 implements Runnable { + + @SuppressWarnings("unused") + private int c; + + // 4 ^ 0 = 1 times + public void run() { + m1(); + m1(); + m1(); + m1(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 1 = 4 times + public void m1() { + m2(); + m2(); + m2(); + m2(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 2 == 16 times + public void m2() { + m3(); + m3(); + m3(); + m3(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 3 == 64 times + public void m3() { + m4(); + m4(); + m4(); + m4(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 4 == 256 times + public void m4() { + m5(); + m5(); + m5(); + m5(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 5 == 1,024 times + public void m5() { + m6(); + m6(); + m6(); + m6(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 6 == 4,096 times + public void m6() { + m7(); + m7(); + m7(); + m7(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 7 == 16,384 times + public void m7() { + m8(); + m8(); + m8(); + m8(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 8 == 65,536 times + public void m8() { + m9(); + m9(); + m9(); + m9(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 9 == 262,144 times + public void m9() { + m10(); + m10(); + m10(); + m10(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 10 == 1,048,576 times + public void m10() { + m11(); + m11(); + m11(); + m11(); + c++; // some side effect, otherwise the JIT will remove the method + } + + // 4 ^ 11 == 4,194,304 times + public void m11() { + c++; // some side effect, otherwise the JIT will remove the method + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target02.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target02.java index 55ffbfe9..c23b50bc 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target02.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target02.java @@ -1,27 +1,27 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf.targets;
-
-/**
- * Simple Loop.
- */
-public class Target02 implements Runnable {
-
- public void run() {
- @SuppressWarnings("unused")
- int count = 0;
- for (int i = 0; i < 10000000; i++) {
- count++;
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf.targets; + +/** + * Simple Loop. + */ +public class Target02 implements Runnable { + + public void run() { + @SuppressWarnings("unused") + int count = 0; + for (int i = 0; i < 10000000; i++) { + count++; + } + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target03.java b/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target03.java index 689d275e..124f48ab 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target03.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/perf/targets/Target03.java @@ -1,153 +1,153 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.perf.targets;
-
-import java.util.Random;
-
-/**
- * "Game of Life" implementation as a more reference scenario. Obviously the
- * implementation could be more elegant using several classes, but the test
- * runner targets one class only. Also one could think about more efficient
- * implementations which again is not the focus here.
- */
-public class Target03 implements Runnable {
-
- private final int width;
-
- private final int height;
-
- private boolean[][] field;
-
- public Target03(int width, int height) {
- this.width = width;
- this.height = height;
- this.field = createField();
- }
-
- public Target03() {
- this(64, 64);
- }
-
- private boolean[][] createField() {
- boolean[][] f = new boolean[height][];
- for (int i = 0; i < height; i++) {
- f[i] = new boolean[width];
- }
- return f;
- }
-
- public void set(int x, int y, boolean flag) {
- field[wrap(x, width)][wrap(y, height)] = flag;
- }
-
- public boolean get(int x, int y) {
- return field[wrap(x, width)][wrap(y, height)];
- }
-
- public void clear() {
- field = createField();
- }
-
- public void randomFill(long seed, int count) {
- Random r = new Random(seed);
- for (int i = 0; i < count; i++) {
- set(r.nextInt(), r.nextInt(), true);
- }
-
- }
-
- public void tick() {
- boolean[][] next = createField();
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- final int n = getNeighbors(x, y);
- if (get(x, y)) {
- next[x][y] = 2 <= n && n <= 3;
- } else {
- next[x][y] = n == 3;
- }
- }
- }
- field = next;
- }
-
- // Neighbor
- private int getNeighbors(int x, int y) {
- int count = 0;
- if (get(x - 1, y - 1)) {
- count++;
- }
- if (get(x + 0, y - 1)) {
- count++;
- }
- if (get(x + 1, y - 1)) {
- count++;
- }
- if (get(x + 1, y + 0)) {
- count++;
- }
- if (get(x + 1, y + 1)) {
- count++;
- }
- if (get(x + 0, y + 1)) {
- count++;
- }
- if (get(x - 1, y + 1)) {
- count++;
- }
- if (get(x - 1, y + 0)) {
- count++;
- }
- return count;
- }
-
- private int wrap(int value, int size) {
- int res = value % size;
- if (res < 0) {
- res += size;
- }
- return res;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- sb.append(get(x, y) ? 'O' : '.');
- }
- sb.append('\n');
- }
- return sb.toString();
- }
-
- public void run() {
- clear();
- randomFill(123, width * height / 2);
- for (int i = 0; i < 20; i++) {
- tick();
- }
- }
-
- // Demo
- public static void main(String[] args) {
- Target03 t = new Target03(10, 10);
- t.randomFill(123, 20);
-
- for (int i = 0; i < 10; i++) {
- System.out.println("Generation " + i + ":");
- System.out.println(t);
- t.tick();
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.perf.targets; + +import java.util.Random; + +/** + * "Game of Life" implementation as a more reference scenario. Obviously the + * implementation could be more elegant using several classes, but the test + * runner targets one class only. Also one could think about more efficient + * implementations which again is not the focus here. + */ +public class Target03 implements Runnable { + + private final int width; + + private final int height; + + private boolean[][] field; + + public Target03(int width, int height) { + this.width = width; + this.height = height; + this.field = createField(); + } + + public Target03() { + this(64, 64); + } + + private boolean[][] createField() { + boolean[][] f = new boolean[height][]; + for (int i = 0; i < height; i++) { + f[i] = new boolean[width]; + } + return f; + } + + public void set(int x, int y, boolean flag) { + field[wrap(x, width)][wrap(y, height)] = flag; + } + + public boolean get(int x, int y) { + return field[wrap(x, width)][wrap(y, height)]; + } + + public void clear() { + field = createField(); + } + + public void randomFill(long seed, int count) { + Random r = new Random(seed); + for (int i = 0; i < count; i++) { + set(r.nextInt(), r.nextInt(), true); + } + + } + + public void tick() { + boolean[][] next = createField(); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + final int n = getNeighbors(x, y); + if (get(x, y)) { + next[x][y] = 2 <= n && n <= 3; + } else { + next[x][y] = n == 3; + } + } + } + field = next; + } + + // Neighbor + private int getNeighbors(int x, int y) { + int count = 0; + if (get(x - 1, y - 1)) { + count++; + } + if (get(x + 0, y - 1)) { + count++; + } + if (get(x + 1, y - 1)) { + count++; + } + if (get(x + 1, y + 0)) { + count++; + } + if (get(x + 1, y + 1)) { + count++; + } + if (get(x + 0, y + 1)) { + count++; + } + if (get(x - 1, y + 1)) { + count++; + } + if (get(x - 1, y + 0)) { + count++; + } + return count; + } + + private int wrap(int value, int size) { + int res = value % size; + if (res < 0) { + res += size; + } + return res; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + sb.append(get(x, y) ? 'O' : '.'); + } + sb.append('\n'); + } + return sb.toString(); + } + + public void run() { + clear(); + randomFill(123, width * height / 2); + for (int i = 0; i < 20; i++) { + tick(); + } + } + + // Demo + public static void main(String[] args) { + Target03 t = new Target03(10, 10); + t.randomFill(123, 20); + + for (int i = 0; i < 10; i++) { + System.out.println("Generation " + i + ":"); + System.out.println(t); + t.tick(); + } + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/BooleanExpressionsTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/BooleanExpressionsTest.java index eb1f836a..e59dcf50 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/BooleanExpressionsTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/BooleanExpressionsTest.java @@ -1,85 +1,85 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.validation;
-
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.test.validation.targets.Target02;
-import org.junit.Test;
-
-/**
- * Tests of basic Java boolean expressions.
- */
-public class BooleanExpressionsTest extends ValidationTestBase {
-
- public BooleanExpressionsTest() {
- super(Target02.class);
- }
-
- @Override
- protected void run(final Class<?> targetClass) throws Exception {
- final Object instance = targetClass.newInstance();
- ((Runnable) instance).run();
- }
-
- @Test
- public void testCoverageResult() {
-
- // 1. Boolean comparison result (one case)
- assertLine("booleancmp1", ICounter.PARTLY_COVERED, 1, 1);
-
- // 2. Boolean comparison result (both cases)
- assertLine("booleancmp2", ICounter.FULLY_COVERED, 0, 2);
-
- // 3. And
- assertLine("andFF", ICounter.FULLY_COVERED, 1, 1);
- assertLine("andFT", ICounter.FULLY_COVERED, 1, 1);
- assertLine("andTF", ICounter.FULLY_COVERED, 1, 1);
- assertLine("andTT", ICounter.FULLY_COVERED, 1, 1);
-
- // 4. Conditional And
- assertLine("conditionalandFF", ICounter.PARTLY_COVERED, 3, 1);
- assertLine("conditionalandFT", ICounter.PARTLY_COVERED, 3, 1);
- assertLine("conditionalandTF", ICounter.FULLY_COVERED, 2, 2);
- assertLine("conditionalandTT", ICounter.FULLY_COVERED, 2, 2);
-
- // 5. Or
- assertLine("orFF", ICounter.FULLY_COVERED, 1, 1);
- assertLine("orFT", ICounter.FULLY_COVERED, 1, 1);
- assertLine("orTF", ICounter.FULLY_COVERED, 1, 1);
- assertLine("orTT", ICounter.FULLY_COVERED, 1, 1);
-
- // 6. Conditional Or
- assertLine("conditionalorFF", ICounter.FULLY_COVERED, 2, 2);
- assertLine("conditionalorFT", ICounter.FULLY_COVERED, 2, 2);
- assertLine("conditionalorTF", ICounter.PARTLY_COVERED, 3, 1);
- assertLine("conditionalorTT", ICounter.PARTLY_COVERED, 3, 1);
-
- // 7. Exclusive Or
- assertLine("xorFF", ICounter.FULLY_COVERED, 1, 1);
- assertLine("xorFT", ICounter.FULLY_COVERED, 1, 1);
- assertLine("xorTF", ICounter.FULLY_COVERED, 1, 1);
- assertLine("xorTT", ICounter.FULLY_COVERED, 1, 1);
-
- // 8. Conditional Operator
- assertLine("condT", ICounter.PARTLY_COVERED, 1, 1);
- assertLine("condF", ICounter.PARTLY_COVERED, 1, 1);
-
- // 9. Not (one case)
- assertLine("notT", ICounter.PARTLY_COVERED, 1, 1);
- assertLine("notF", ICounter.PARTLY_COVERED, 1, 1);
-
- // 10. Not (both cases)
- assertLine("notTF", ICounter.FULLY_COVERED, 0, 2);
-
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target02; +import org.junit.Test; + +/** + * Tests of basic Java boolean expressions. + */ +public class BooleanExpressionsTest extends ValidationTestBase { + + public BooleanExpressionsTest() { + super(Target02.class); + } + + @Override + protected void run(final Class<?> targetClass) throws Exception { + final Object instance = targetClass.newInstance(); + ((Runnable) instance).run(); + } + + @Test + public void testCoverageResult() { + + // 1. Boolean comparison result (one case) + assertLine("booleancmp1", ICounter.PARTLY_COVERED, 1, 1); + + // 2. Boolean comparison result (both cases) + assertLine("booleancmp2", ICounter.FULLY_COVERED, 0, 2); + + // 3. And + assertLine("andFF", ICounter.FULLY_COVERED, 1, 1); + assertLine("andFT", ICounter.FULLY_COVERED, 1, 1); + assertLine("andTF", ICounter.FULLY_COVERED, 1, 1); + assertLine("andTT", ICounter.FULLY_COVERED, 1, 1); + + // 4. Conditional And + assertLine("conditionalandFF", ICounter.PARTLY_COVERED, 3, 1); + assertLine("conditionalandFT", ICounter.PARTLY_COVERED, 3, 1); + assertLine("conditionalandTF", ICounter.FULLY_COVERED, 2, 2); + assertLine("conditionalandTT", ICounter.FULLY_COVERED, 2, 2); + + // 5. Or + assertLine("orFF", ICounter.FULLY_COVERED, 1, 1); + assertLine("orFT", ICounter.FULLY_COVERED, 1, 1); + assertLine("orTF", ICounter.FULLY_COVERED, 1, 1); + assertLine("orTT", ICounter.FULLY_COVERED, 1, 1); + + // 6. Conditional Or + assertLine("conditionalorFF", ICounter.FULLY_COVERED, 2, 2); + assertLine("conditionalorFT", ICounter.FULLY_COVERED, 2, 2); + assertLine("conditionalorTF", ICounter.PARTLY_COVERED, 3, 1); + assertLine("conditionalorTT", ICounter.PARTLY_COVERED, 3, 1); + + // 7. Exclusive Or + assertLine("xorFF", ICounter.FULLY_COVERED, 1, 1); + assertLine("xorFT", ICounter.FULLY_COVERED, 1, 1); + assertLine("xorTF", ICounter.FULLY_COVERED, 1, 1); + assertLine("xorTT", ICounter.FULLY_COVERED, 1, 1); + + // 8. Conditional Operator + assertLine("condT", ICounter.PARTLY_COVERED, 1, 1); + assertLine("condF", ICounter.PARTLY_COVERED, 1, 1); + + // 9. Not (one case) + assertLine("notT", ICounter.PARTLY_COVERED, 1, 1); + assertLine("notF", ICounter.PARTLY_COVERED, 1, 1); + + // 10. Not (both cases) + assertLine("notTF", ICounter.FULLY_COVERED, 0, 2); + + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ControlStructuresTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ControlStructuresTest.java index 5d2a5ab8..a512f93f 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ControlStructuresTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ControlStructuresTest.java @@ -1,139 +1,139 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.validation;
-
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.test.validation.targets.Target01;
-import org.junit.Test;
-
-/**
- * Tests of basic Java control structures.
- */
-public class ControlStructuresTest extends ValidationTestBase {
-
- public ControlStructuresTest() {
- super(Target01.class);
- }
-
- @Override
- protected void run(final Class<?> targetClass) throws Exception {
- final Object instance = targetClass.newInstance();
- ((Runnable) instance).run();
- }
-
- @Test
- public void testCoverageResult() {
-
- // 1. Direct unconditional execution
- assertLine("unconditional", ICounter.FULLY_COVERED);
-
- // 2. Missed if block
- assertLine("iffalse", ICounter.FULLY_COVERED, 1, 1);
- assertLine("missedif", ICounter.NOT_COVERED);
- assertLine("executedelse", ICounter.FULLY_COVERED);
-
- // 3. Executed if block
- assertLine("iftrue", ICounter.FULLY_COVERED, 1, 1);
- assertLine("executedif", ICounter.FULLY_COVERED);
- assertLine("missedelse", ICounter.NOT_COVERED);
-
- // 4. Missed while block
- // ECJ and javac produce different status here
- assertLine("whilefalse", 1, 1);
- assertLine("missedwhile", ICounter.NOT_COVERED);
-
- // 5. Always true while block
- assertLine("whiletrue", ICounter.FULLY_COVERED, 1, 1);
-
- // 6. Executed while block
- assertLine("whiletruefalse", ICounter.FULLY_COVERED, 0, 2);
- assertLine("executedwhile", ICounter.FULLY_COVERED);
-
- // 7. Executed do while block
- assertLine("executeddowhile", ICounter.FULLY_COVERED);
-
- // 8. Missed for block
- assertLine("missedforincrementer", ICounter.PARTLY_COVERED, 1, 1);
- assertLine("missedfor", ICounter.NOT_COVERED);
-
- // 9. Executed for block
- assertLine("executedforincrementer", ICounter.FULLY_COVERED, 0, 2);
- assertLine("executedfor", ICounter.FULLY_COVERED);
-
- // 10. Missed for each block
- assertLine("missedforeachincrementer", ICounter.PARTLY_COVERED, 1, 1);
- assertLine("missedforeach", ICounter.NOT_COVERED);
-
- // 11. Executed for each block
- assertLine("executedforeachincrementer", ICounter.FULLY_COVERED, 0, 2);
- assertLine("executedforeach", ICounter.FULLY_COVERED);
-
- // 12. Table switch with hit
- assertLine("tswitch1", ICounter.FULLY_COVERED, 3, 1);
- assertLine("tswitch1case1", ICounter.NOT_COVERED);
- assertLine("tswitch1case2", ICounter.FULLY_COVERED);
- assertLine("tswitch1case3", ICounter.NOT_COVERED);
- assertLine("tswitch1default", ICounter.NOT_COVERED);
-
- // 13. Continued table switch with hit
- assertLine("tswitch2", ICounter.FULLY_COVERED, 3, 1);
- assertLine("tswitch2case1", ICounter.NOT_COVERED);
- assertLine("tswitch2case2", ICounter.FULLY_COVERED);
- assertLine("tswitch2case3", ICounter.FULLY_COVERED);
- assertLine("tswitch2default", ICounter.FULLY_COVERED);
-
- // 14. Table switch without hit
- assertLine("tswitch2", ICounter.FULLY_COVERED, 3, 1);
- assertLine("tswitch3case1", ICounter.NOT_COVERED);
- assertLine("tswitch3case2", ICounter.NOT_COVERED);
- assertLine("tswitch3case3", ICounter.NOT_COVERED);
- assertLine("tswitch3default", ICounter.FULLY_COVERED);
-
- // 15. Lookup switch with hit
- assertLine("lswitch1", ICounter.FULLY_COVERED, 3, 1);
- assertLine("lswitch1case1", ICounter.NOT_COVERED);
- assertLine("lswitch1case2", ICounter.FULLY_COVERED);
- assertLine("lswitch1case3", ICounter.NOT_COVERED);
- assertLine("lswitch1default", ICounter.NOT_COVERED);
-
- // 16. Continued lookup switch with hit
- assertLine("lswitch2", ICounter.FULLY_COVERED, 3, 1);
- assertLine("lswitch2case1", ICounter.NOT_COVERED);
- assertLine("lswitch2case2", ICounter.FULLY_COVERED);
- assertLine("lswitch2case3", ICounter.FULLY_COVERED);
- assertLine("lswitch2default", ICounter.FULLY_COVERED);
-
- // 17. Lookup switch without hit
- assertLine("lswitch3", ICounter.FULLY_COVERED, 3, 1);
- assertLine("lswitch3case1", ICounter.NOT_COVERED);
- assertLine("lswitch3case2", ICounter.NOT_COVERED);
- assertLine("lswitch3case3", ICounter.NOT_COVERED);
- assertLine("lswitch3default", ICounter.FULLY_COVERED);
-
- // 18. Break statement
- assertLine("executedbreak", ICounter.FULLY_COVERED);
- assertLine("missedafterbreak", ICounter.NOT_COVERED);
-
- // 19. Continue statement
- assertLine("executedcontinue", ICounter.FULLY_COVERED);
- assertLine("missedaftercontinue", ICounter.NOT_COVERED);
-
- // 20. Return statement
- assertLine("return", ICounter.FULLY_COVERED);
- assertLine("afterreturn", ICounter.NOT_COVERED);
-
- // 21. Implicit return
- assertLine("implicitreturn", ICounter.FULLY_COVERED);
-
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target01; +import org.junit.Test; + +/** + * Tests of basic Java control structures. + */ +public class ControlStructuresTest extends ValidationTestBase { + + public ControlStructuresTest() { + super(Target01.class); + } + + @Override + protected void run(final Class<?> targetClass) throws Exception { + final Object instance = targetClass.newInstance(); + ((Runnable) instance).run(); + } + + @Test + public void testCoverageResult() { + + // 1. Direct unconditional execution + assertLine("unconditional", ICounter.FULLY_COVERED); + + // 2. Missed if block + assertLine("iffalse", ICounter.FULLY_COVERED, 1, 1); + assertLine("missedif", ICounter.NOT_COVERED); + assertLine("executedelse", ICounter.FULLY_COVERED); + + // 3. Executed if block + assertLine("iftrue", ICounter.FULLY_COVERED, 1, 1); + assertLine("executedif", ICounter.FULLY_COVERED); + assertLine("missedelse", ICounter.NOT_COVERED); + + // 4. Missed while block + // ECJ and javac produce different status here + assertLine("whilefalse", 1, 1); + assertLine("missedwhile", ICounter.NOT_COVERED); + + // 5. Always true while block + assertLine("whiletrue", ICounter.FULLY_COVERED, 1, 1); + + // 6. Executed while block + assertLine("whiletruefalse", ICounter.FULLY_COVERED, 0, 2); + assertLine("executedwhile", ICounter.FULLY_COVERED); + + // 7. Executed do while block + assertLine("executeddowhile", ICounter.FULLY_COVERED); + + // 8. Missed for block + assertLine("missedforincrementer", ICounter.PARTLY_COVERED, 1, 1); + assertLine("missedfor", ICounter.NOT_COVERED); + + // 9. Executed for block + assertLine("executedforincrementer", ICounter.FULLY_COVERED, 0, 2); + assertLine("executedfor", ICounter.FULLY_COVERED); + + // 10. Missed for each block + assertLine("missedforeachincrementer", ICounter.PARTLY_COVERED, 1, 1); + assertLine("missedforeach", ICounter.NOT_COVERED); + + // 11. Executed for each block + assertLine("executedforeachincrementer", ICounter.FULLY_COVERED, 0, 2); + assertLine("executedforeach", ICounter.FULLY_COVERED); + + // 12. Table switch with hit + assertLine("tswitch1", ICounter.FULLY_COVERED, 3, 1); + assertLine("tswitch1case1", ICounter.NOT_COVERED); + assertLine("tswitch1case2", ICounter.FULLY_COVERED); + assertLine("tswitch1case3", ICounter.NOT_COVERED); + assertLine("tswitch1default", ICounter.NOT_COVERED); + + // 13. Continued table switch with hit + assertLine("tswitch2", ICounter.FULLY_COVERED, 3, 1); + assertLine("tswitch2case1", ICounter.NOT_COVERED); + assertLine("tswitch2case2", ICounter.FULLY_COVERED); + assertLine("tswitch2case3", ICounter.FULLY_COVERED); + assertLine("tswitch2default", ICounter.FULLY_COVERED); + + // 14. Table switch without hit + assertLine("tswitch2", ICounter.FULLY_COVERED, 3, 1); + assertLine("tswitch3case1", ICounter.NOT_COVERED); + assertLine("tswitch3case2", ICounter.NOT_COVERED); + assertLine("tswitch3case3", ICounter.NOT_COVERED); + assertLine("tswitch3default", ICounter.FULLY_COVERED); + + // 15. Lookup switch with hit + assertLine("lswitch1", ICounter.FULLY_COVERED, 3, 1); + assertLine("lswitch1case1", ICounter.NOT_COVERED); + assertLine("lswitch1case2", ICounter.FULLY_COVERED); + assertLine("lswitch1case3", ICounter.NOT_COVERED); + assertLine("lswitch1default", ICounter.NOT_COVERED); + + // 16. Continued lookup switch with hit + assertLine("lswitch2", ICounter.FULLY_COVERED, 3, 1); + assertLine("lswitch2case1", ICounter.NOT_COVERED); + assertLine("lswitch2case2", ICounter.FULLY_COVERED); + assertLine("lswitch2case3", ICounter.FULLY_COVERED); + assertLine("lswitch2default", ICounter.FULLY_COVERED); + + // 17. Lookup switch without hit + assertLine("lswitch3", ICounter.FULLY_COVERED, 3, 1); + assertLine("lswitch3case1", ICounter.NOT_COVERED); + assertLine("lswitch3case2", ICounter.NOT_COVERED); + assertLine("lswitch3case3", ICounter.NOT_COVERED); + assertLine("lswitch3default", ICounter.FULLY_COVERED); + + // 18. Break statement + assertLine("executedbreak", ICounter.FULLY_COVERED); + assertLine("missedafterbreak", ICounter.NOT_COVERED); + + // 19. Continue statement + assertLine("executedcontinue", ICounter.FULLY_COVERED); + assertLine("missedaftercontinue", ICounter.NOT_COVERED); + + // 20. Return statement + assertLine("return", ICounter.FULLY_COVERED); + assertLine("afterreturn", ICounter.NOT_COVERED); + + // 21. Implicit return + assertLine("implicitreturn", ICounter.FULLY_COVERED); + + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ExceptionsTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ExceptionsTest.java index 1a8a04f0..885ee1a9 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ExceptionsTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ExceptionsTest.java @@ -1,98 +1,98 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.validation;
-
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.test.validation.targets.Target03;
-import org.junit.Test;
-
-/**
- * Tests of exception based control flow.
- */
-public class ExceptionsTest extends ValidationTestBase {
-
- public ExceptionsTest() {
- super(Target03.class);
- }
-
- @Override
- protected void run(final Class<?> targetClass) throws Exception {
- final Object instance = targetClass.newInstance();
- ((Runnable) instance).run();
- }
-
- @Test
- public void testCoverageResult() {
-
- // 1. Implicit Exception
- // Currently no coverage at all, as we don't see when a block aborts
- // somewhere in the middle.
- assertLine("implicitException.before", ICounter.NOT_COVERED);
- assertLine("implicitException.exception", ICounter.NOT_COVERED);
- assertLine("implicitException.after", ICounter.NOT_COVERED);
-
- // 2. Explicit Exception
- // Full coverage, as we recognize throw statements as block boundaries.
- assertLine("explicitException.before", ICounter.FULLY_COVERED);
- assertLine("explicitException.throw", ICounter.FULLY_COVERED);
-
- // 3. Try/Catch Block Without Exception Thrown
- assertLine("noExceptionTryCatch.beforeBlock", ICounter.FULLY_COVERED);
- assertLine("noExceptionTryCatch.tryBlock", ICounter.FULLY_COVERED);
- assertLine("noExceptionTryCatch.catchBlock", ICounter.NOT_COVERED);
-
- // 4. Try/Catch Block Without a Implicit Exception Thrown
- // As always with implicit exceptions we don't see when a block aborts
- // somewhere in the middle.
- assertLine("implicitExceptionTryCatch.beforeBlock",
- ICounter.FULLY_COVERED);
- assertLine("implicitExceptionTryCatch.before", ICounter.NOT_COVERED);
- assertLine("implicitExceptionTryCatch.exception", ICounter.NOT_COVERED);
- assertLine("implicitExceptionTryCatch.after", ICounter.NOT_COVERED);
- assertLine("implicitExceptionTryCatch.catchBlock",
- ICounter.FULLY_COVERED);
-
- // 5. Try/Catch Block With Exception Thrown Explicitly
- assertLine("explicitExceptionTryCatch.beforeBlock",
- ICounter.FULLY_COVERED);
- assertLine("explicitExceptionTryCatch.before", ICounter.FULLY_COVERED);
- assertLine("explicitExceptionTryCatch.throw", ICounter.FULLY_COVERED);
- assertLine("explicitExceptionTryCatch.catchBlock",
- ICounter.FULLY_COVERED);
-
- // 6. Finally Block Without Exception Thrown
- // Finally block is yellow as the exception path is missing.
- assertLine("noExceptionFinally.beforeBlock", ICounter.FULLY_COVERED);
- assertLine("noExceptionFinally.tryBlock", ICounter.FULLY_COVERED);
- assertLine("noExceptionFinally.finallyBlock", ICounter.PARTLY_COVERED);
-
- // 7. Finally Block With Implicit Exception
- // Finally block is yellow as the non-exception path is missing.
- assertLine("implicitExceptionFinally.beforeBlock",
- ICounter.FULLY_COVERED);
- assertLine("implicitExceptionFinally.before", ICounter.NOT_COVERED);
- assertLine("implicitExceptionFinally.exception", ICounter.NOT_COVERED);
- assertLine("implicitExceptionFinally.after", ICounter.NOT_COVERED);
- assertLine("implicitExceptionFinally.finallyBlock",
- ICounter.PARTLY_COVERED);
-
- // 8. Finally Block With Exception Thrown Explicitly
- assertLine("explicitExceptionFinally.beforeBlock",
- ICounter.FULLY_COVERED);
- assertLine("explicitExceptionFinally.before", ICounter.FULLY_COVERED);
- assertLine("explicitExceptionFinally.throw", ICounter.FULLY_COVERED);
- assertLine("explicitExceptionFinally.finallyBlock",
- ICounter.FULLY_COVERED);
-
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target03; +import org.junit.Test; + +/** + * Tests of exception based control flow. + */ +public class ExceptionsTest extends ValidationTestBase { + + public ExceptionsTest() { + super(Target03.class); + } + + @Override + protected void run(final Class<?> targetClass) throws Exception { + final Object instance = targetClass.newInstance(); + ((Runnable) instance).run(); + } + + @Test + public void testCoverageResult() { + + // 1. Implicit Exception + // Currently no coverage at all, as we don't see when a block aborts + // somewhere in the middle. + assertLine("implicitException.before", ICounter.NOT_COVERED); + assertLine("implicitException.exception", ICounter.NOT_COVERED); + assertLine("implicitException.after", ICounter.NOT_COVERED); + + // 2. Explicit Exception + // Full coverage, as we recognize throw statements as block boundaries. + assertLine("explicitException.before", ICounter.FULLY_COVERED); + assertLine("explicitException.throw", ICounter.FULLY_COVERED); + + // 3. Try/Catch Block Without Exception Thrown + assertLine("noExceptionTryCatch.beforeBlock", ICounter.FULLY_COVERED); + assertLine("noExceptionTryCatch.tryBlock", ICounter.FULLY_COVERED); + assertLine("noExceptionTryCatch.catchBlock", ICounter.NOT_COVERED); + + // 4. Try/Catch Block Without a Implicit Exception Thrown + // As always with implicit exceptions we don't see when a block aborts + // somewhere in the middle. + assertLine("implicitExceptionTryCatch.beforeBlock", + ICounter.FULLY_COVERED); + assertLine("implicitExceptionTryCatch.before", ICounter.NOT_COVERED); + assertLine("implicitExceptionTryCatch.exception", ICounter.NOT_COVERED); + assertLine("implicitExceptionTryCatch.after", ICounter.NOT_COVERED); + assertLine("implicitExceptionTryCatch.catchBlock", + ICounter.FULLY_COVERED); + + // 5. Try/Catch Block With Exception Thrown Explicitly + assertLine("explicitExceptionTryCatch.beforeBlock", + ICounter.FULLY_COVERED); + assertLine("explicitExceptionTryCatch.before", ICounter.FULLY_COVERED); + assertLine("explicitExceptionTryCatch.throw", ICounter.FULLY_COVERED); + assertLine("explicitExceptionTryCatch.catchBlock", + ICounter.FULLY_COVERED); + + // 6. Finally Block Without Exception Thrown + // Finally block is yellow as the exception path is missing. + assertLine("noExceptionFinally.beforeBlock", ICounter.FULLY_COVERED); + assertLine("noExceptionFinally.tryBlock", ICounter.FULLY_COVERED); + assertLine("noExceptionFinally.finallyBlock", ICounter.PARTLY_COVERED); + + // 7. Finally Block With Implicit Exception + // Finally block is yellow as the non-exception path is missing. + assertLine("implicitExceptionFinally.beforeBlock", + ICounter.FULLY_COVERED); + assertLine("implicitExceptionFinally.before", ICounter.NOT_COVERED); + assertLine("implicitExceptionFinally.exception", ICounter.NOT_COVERED); + assertLine("implicitExceptionFinally.after", ICounter.NOT_COVERED); + assertLine("implicitExceptionFinally.finallyBlock", + ICounter.PARTLY_COVERED); + + // 8. Finally Block With Exception Thrown Explicitly + assertLine("explicitExceptionFinally.beforeBlock", + ICounter.FULLY_COVERED); + assertLine("explicitExceptionFinally.before", ICounter.FULLY_COVERED); + assertLine("explicitExceptionFinally.throw", ICounter.FULLY_COVERED); + assertLine("explicitExceptionFinally.finallyBlock", + ICounter.FULLY_COVERED); + + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/Source.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/Source.java index 156fb78d..ec7a5c38 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/Source.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/Source.java @@ -1,116 +1,116 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.validation;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Reads a single source file and allows access to it through special probe
- * comments in the following format <code>//$line-<i>tag</i>$.
- */
-public class Source {
-
- /**
- * Reads the source for the given type from the <code>./src/</code> folder
- * relative to the working directory.
- *
- * @param type
- * type to load the source file for
- * @throws IOException
- * @throws
- */
- public static Source getSourceFor(final Class<?> type) throws IOException {
- String file = "src/" + type.getName().replace('.', '/') + ".java";
- return new Source(new FileReader(file));
- }
-
- private static final Pattern TAG_PATTERN = Pattern
- .compile("\\$line-(.*)\\$");
-
- private final List<String> lines = new ArrayList<String>();
-
- private final Map<String, Integer> tags = new HashMap<String, Integer>();
-
- /**
- * Reads a source file from the given reader.
- *
- * @param reader
- * @throws IOException
- */
- public Source(final Reader reader) throws IOException {
- final BufferedReader buffer = new BufferedReader(reader);
- for (String l = buffer.readLine(); l != null; l = buffer.readLine()) {
- addLine(l);
- }
- buffer.close();
- }
-
- private void addLine(final String l) {
- lines.add(l);
- final Matcher m = TAG_PATTERN.matcher(l);
- if (m.find()) {
- final String tag = m.group(1);
- if (tags.put(tag, Integer.valueOf(lines.size())) != null) {
- throw new IllegalArgumentException("Duplicate tag: " + tag);
- }
- }
- }
-
- /**
- * Returns all lines of the source file as a list.
- *
- * @return all lines of the source file
- */
- public List<String> getLines() {
- return Collections.unmodifiableList(lines);
- }
-
- /**
- * Returns the line with the given number
- *
- * @param nr
- * line number (first line is 1)
- * @return line content
- */
- public String getLine(int nr) {
- return lines.get(nr - 1);
- }
-
- /**
- * Returns the line number with the given tag
- *
- * @param tag
- * tag from a <code>//$line-<i>tag</i>$ marker
- * @return line number (first line is 1)
- * @throws NoSuchElementException
- * if there is no such tag
- */
- public int getLineNumber(String tag) throws NoSuchElementException {
- final Integer nr = tags.get(tag);
- if (nr == null) {
- throw new NoSuchElementException("Unknown tag: " + tag);
- }
- return nr.intValue();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Reads a single source file and allows access to it through special probe + * comments in the following format <code>//$line-<i>tag</i>$. + */ +public class Source { + + /** + * Reads the source for the given type from the <code>./src/</code> folder + * relative to the working directory. + * + * @param type + * type to load the source file for + * @throws IOException + * @throws + */ + public static Source getSourceFor(final Class<?> type) throws IOException { + String file = "src/" + type.getName().replace('.', '/') + ".java"; + return new Source(new FileReader(file)); + } + + private static final Pattern TAG_PATTERN = Pattern + .compile("\\$line-(.*)\\$"); + + private final List<String> lines = new ArrayList<String>(); + + private final Map<String, Integer> tags = new HashMap<String, Integer>(); + + /** + * Reads a source file from the given reader. + * + * @param reader + * @throws IOException + */ + public Source(final Reader reader) throws IOException { + final BufferedReader buffer = new BufferedReader(reader); + for (String l = buffer.readLine(); l != null; l = buffer.readLine()) { + addLine(l); + } + buffer.close(); + } + + private void addLine(final String l) { + lines.add(l); + final Matcher m = TAG_PATTERN.matcher(l); + if (m.find()) { + final String tag = m.group(1); + if (tags.put(tag, Integer.valueOf(lines.size())) != null) { + throw new IllegalArgumentException("Duplicate tag: " + tag); + } + } + } + + /** + * Returns all lines of the source file as a list. + * + * @return all lines of the source file + */ + public List<String> getLines() { + return Collections.unmodifiableList(lines); + } + + /** + * Returns the line with the given number + * + * @param nr + * line number (first line is 1) + * @return line content + */ + public String getLine(int nr) { + return lines.get(nr - 1); + } + + /** + * Returns the line number with the given tag + * + * @param tag + * tag from a <code>//$line-<i>tag</i>$ marker + * @return line number (first line is 1) + * @throws NoSuchElementException + * if there is no such tag + */ + public int getLineNumber(String tag) throws NoSuchElementException { + final Integer nr = tags.get(tag); + if (nr == null) { + throw new NoSuchElementException("Unknown tag: " + tag); + } + return nr.intValue(); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/SourceTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/SourceTest.java index 9a5e2392..1e7f1e02 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/SourceTest.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/SourceTest.java @@ -1,87 +1,87 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.validation;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.Arrays;
-import java.util.NoSuchElementException;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link Source}.
- */
-public class SourceTest {
-
- @Test
- public void testGetLines1() throws IOException {
- String src = "\na\nbb\n";
- final Source s = new Source(new StringReader(src));
- assertEquals(Arrays.asList("", "a", "bb"), s.getLines());
- }
-
- @Test
- public void testGetLines2() throws IOException {
- String src = "aa\nbb\n;";
- final Source s = new Source(new StringReader(src));
- assertEquals(Arrays.asList("aa", "bb", ";"), s.getLines());
- }
-
- @Test
- public void testGetLines3() throws IOException {
- String src = "xx\r\nyy";
- final Source s = new Source(new StringReader(src));
- assertEquals(Arrays.asList("xx", "yy"), s.getLines());
- }
-
- @Test
- public void testGetLine() throws IOException {
- String src = "Hello\n\nWorld!";
- final Source s = new Source(new StringReader(src));
- assertEquals("Hello", s.getLine(1));
- assertEquals("", s.getLine(2));
- assertEquals("World!", s.getLine(3));
- }
-
- @Test
- public void testGetLineNumber() throws IOException {
- String src = "a\nb$line-tag$\nc\nd\ne$line-tagx$\nf";
- final Source s = new Source(new StringReader(src));
- assertEquals(2, s.getLineNumber("tag"), 0.0);
- }
-
- @Test(expected = NoSuchElementException.class)
- public void testGetLineNumberNegative() throws IOException {
- String src = "a\nb$line-tag$\nc\nd\ne\nf";
- final Source s = new Source(new StringReader(src));
- s.getLineNumber("ag");
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testDuplicateTag() throws IOException {
- String src = "a\nb$line-tag$\nc\nd\ne$line-tag$\nf";
- new Source(new StringReader(src));
- }
-
- @Test
- public void testGetSourceFor() throws IOException {
- final Source s = Source.getSourceFor(SourceTest.class);
- // Here we are. $line-testGetSourceFor$
- final String l = s.getLine(s.getLineNumber("testGetSourceFor"));
- assertTrue(l, l.contains("Here we are."));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Arrays; +import java.util.NoSuchElementException; + +import org.junit.Test; + +/** + * Unit tests for {@link Source}. + */ +public class SourceTest { + + @Test + public void testGetLines1() throws IOException { + String src = "\na\nbb\n"; + final Source s = new Source(new StringReader(src)); + assertEquals(Arrays.asList("", "a", "bb"), s.getLines()); + } + + @Test + public void testGetLines2() throws IOException { + String src = "aa\nbb\n;"; + final Source s = new Source(new StringReader(src)); + assertEquals(Arrays.asList("aa", "bb", ";"), s.getLines()); + } + + @Test + public void testGetLines3() throws IOException { + String src = "xx\r\nyy"; + final Source s = new Source(new StringReader(src)); + assertEquals(Arrays.asList("xx", "yy"), s.getLines()); + } + + @Test + public void testGetLine() throws IOException { + String src = "Hello\n\nWorld!"; + final Source s = new Source(new StringReader(src)); + assertEquals("Hello", s.getLine(1)); + assertEquals("", s.getLine(2)); + assertEquals("World!", s.getLine(3)); + } + + @Test + public void testGetLineNumber() throws IOException { + String src = "a\nb$line-tag$\nc\nd\ne$line-tagx$\nf"; + final Source s = new Source(new StringReader(src)); + assertEquals(2, s.getLineNumber("tag"), 0.0); + } + + @Test(expected = NoSuchElementException.class) + public void testGetLineNumberNegative() throws IOException { + String src = "a\nb$line-tag$\nc\nd\ne\nf"; + final Source s = new Source(new StringReader(src)); + s.getLineNumber("ag"); + } + + @Test(expected = IllegalArgumentException.class) + public void testDuplicateTag() throws IOException { + String src = "a\nb$line-tag$\nc\nd\ne$line-tag$\nf"; + new Source(new StringReader(src)); + } + + @Test + public void testGetSourceFor() throws IOException { + final Source s = Source.getSourceFor(SourceTest.class); + // Here we are. $line-testGetSourceFor$ + final String l = s.getLine(s.getLineNumber("testGetSourceFor")); + assertTrue(l, l.contains("Here we are.")); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java index ab07913b..0485ac51 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java @@ -1,123 +1,123 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.validation;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Collection;
-
-import org.jacoco.core.analysis.Analyzer;
-import org.jacoco.core.analysis.CoverageBuilder;
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.ILine;
-import org.jacoco.core.analysis.ISourceFileCoverage;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.instr.Instrumenter;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.jacoco.core.runtime.IRuntime;
-import org.jacoco.core.runtime.SystemPropertiesRuntime;
-import org.jacoco.core.test.TargetLoader;
-import org.junit.Before;
-import org.objectweb.asm.ClassReader;
-
-/**
- * Base class for validation tests. It executes the given class under code
- * coverage and provides the coverage results for validation.
- */
-public abstract class ValidationTestBase {
-
- private static final String[] STATUS_NAME = new String[4];
-
- {
- STATUS_NAME[ICounter.EMPTY] = "NO_CODE";
- STATUS_NAME[ICounter.NOT_COVERED] = "NOT_COVERED";
- STATUS_NAME[ICounter.FULLY_COVERED] = "FULLY_COVERED";
- STATUS_NAME[ICounter.PARTLY_COVERED] = "PARTLY_COVERED";
- }
-
- protected final Class<?> target;
-
- protected IClassCoverage classCoverage;
-
- protected ISourceFileCoverage sourceCoverage;
-
- protected Source source;
-
- protected ValidationTestBase(final Class<?> target) {
- this.target = target;
- }
-
- @Before
- public void setup() throws Exception {
- final ClassReader reader = new ClassReader(
- TargetLoader.getClassData(target));
- final ExecutionDataStore store = execute(reader);
- analyze(reader, store);
- source = Source.getSourceFor(target);
- }
-
- private ExecutionDataStore execute(final ClassReader reader)
- throws Exception {
- IRuntime runtime = new SystemPropertiesRuntime();
- runtime.startup();
- final byte[] bytes = new Instrumenter(runtime).instrument(reader);
- final TargetLoader loader = new TargetLoader(target, bytes);
- run(loader.getTargetClass());
- final ExecutionDataStore store = new ExecutionDataStore();
- runtime.collect(store, null, false);
- runtime.shutdown();
- return store;
- }
-
- protected abstract void run(final Class<?> targetClass) throws Exception;
-
- private void analyze(final ClassReader reader,
- final ExecutionDataStore store) {
- final CoverageBuilder builder = new CoverageBuilder();
- final Analyzer analyzer = new Analyzer(store, builder);
- analyzer.analyzeClass(reader);
- final Collection<IClassCoverage> classes = builder.getClasses();
- assertEquals(1, classes.size(), 0.0);
- classCoverage = classes.iterator().next();
- final Collection<ISourceFileCoverage> files = builder.getSourceFiles();
- assertEquals(1, files.size(), 0.0);
- sourceCoverage = files.iterator().next();
- }
-
- protected void assertLine(final String tag, final int status) {
- final int nr = source.getLineNumber(tag);
- final ILine line = sourceCoverage.getLine(nr);
- final String msg = String.format("Status in line %s: %s",
- Integer.valueOf(nr), source.getLine(nr));
- final int insnStatus = line.getInstructionCounter().getStatus();
- assertEquals(msg, STATUS_NAME[status], STATUS_NAME[insnStatus]);
- }
-
- protected void assertLine(final String tag, final int missedBranches,
- final int coveredBranches) {
- final int nr = source.getLineNumber(tag);
- final ILine line = sourceCoverage.getLine(nr);
- final String msg = String.format("Branches in line %s: %s",
- Integer.valueOf(nr), source.getLine(nr));
- assertEquals(msg + " branches",
- CounterImpl.getInstance(missedBranches, coveredBranches),
- line.getBranchCounter());
- }
-
- protected void assertLine(final String tag, final int status,
- final int missedBranches, final int coveredBranches) {
- assertLine(tag, status);
- assertLine(tag, missedBranches, coveredBranches);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import static org.junit.Assert.assertEquals; + +import java.util.Collection; + +import org.jacoco.core.analysis.Analyzer; +import org.jacoco.core.analysis.CoverageBuilder; +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.ILine; +import org.jacoco.core.analysis.ISourceFileCoverage; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.SystemPropertiesRuntime; +import org.jacoco.core.test.TargetLoader; +import org.junit.Before; +import org.objectweb.asm.ClassReader; + +/** + * Base class for validation tests. It executes the given class under code + * coverage and provides the coverage results for validation. + */ +public abstract class ValidationTestBase { + + private static final String[] STATUS_NAME = new String[4]; + + { + STATUS_NAME[ICounter.EMPTY] = "NO_CODE"; + STATUS_NAME[ICounter.NOT_COVERED] = "NOT_COVERED"; + STATUS_NAME[ICounter.FULLY_COVERED] = "FULLY_COVERED"; + STATUS_NAME[ICounter.PARTLY_COVERED] = "PARTLY_COVERED"; + } + + protected final Class<?> target; + + protected IClassCoverage classCoverage; + + protected ISourceFileCoverage sourceCoverage; + + protected Source source; + + protected ValidationTestBase(final Class<?> target) { + this.target = target; + } + + @Before + public void setup() throws Exception { + final ClassReader reader = new ClassReader( + TargetLoader.getClassData(target)); + final ExecutionDataStore store = execute(reader); + analyze(reader, store); + source = Source.getSourceFor(target); + } + + private ExecutionDataStore execute(final ClassReader reader) + throws Exception { + IRuntime runtime = new SystemPropertiesRuntime(); + runtime.startup(); + final byte[] bytes = new Instrumenter(runtime).instrument(reader); + final TargetLoader loader = new TargetLoader(target, bytes); + run(loader.getTargetClass()); + final ExecutionDataStore store = new ExecutionDataStore(); + runtime.collect(store, null, false); + runtime.shutdown(); + return store; + } + + protected abstract void run(final Class<?> targetClass) throws Exception; + + private void analyze(final ClassReader reader, + final ExecutionDataStore store) { + final CoverageBuilder builder = new CoverageBuilder(); + final Analyzer analyzer = new Analyzer(store, builder); + analyzer.analyzeClass(reader); + final Collection<IClassCoverage> classes = builder.getClasses(); + assertEquals(1, classes.size(), 0.0); + classCoverage = classes.iterator().next(); + final Collection<ISourceFileCoverage> files = builder.getSourceFiles(); + assertEquals(1, files.size(), 0.0); + sourceCoverage = files.iterator().next(); + } + + protected void assertLine(final String tag, final int status) { + final int nr = source.getLineNumber(tag); + final ILine line = sourceCoverage.getLine(nr); + final String msg = String.format("Status in line %s: %s", + Integer.valueOf(nr), source.getLine(nr)); + final int insnStatus = line.getInstructionCounter().getStatus(); + assertEquals(msg, STATUS_NAME[status], STATUS_NAME[insnStatus]); + } + + protected void assertLine(final String tag, final int missedBranches, + final int coveredBranches) { + final int nr = source.getLineNumber(tag); + final ILine line = sourceCoverage.getLine(nr); + final String msg = String.format("Branches in line %s: %s", + Integer.valueOf(nr), source.getLine(nr)); + assertEquals(msg + " branches", + CounterImpl.getInstance(missedBranches, coveredBranches), + line.getBranchCounter()); + } + + protected void assertLine(final String tag, final int status, + final int missedBranches, final int coveredBranches) { + assertLine(tag, status); + assertLine(tag, missedBranches, coveredBranches); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java index 110664b5..15889173 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Stubs.java @@ -1,107 +1,107 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.validation.targets;
-
-/**
- * Collection of stub methods that are called from the coverage targets. *
- */
-public class Stubs {
-
- /**
- * Exception stub.
- */
- public static class StubException extends RuntimeException {
-
- static final long serialVersionUID = 0L;
-
- }
-
- /**
- * Superclass stub.
- */
- public static class SuperClass {
-
- public SuperClass(boolean arg) {
- }
-
- }
-
- /**
- * Dummy method.
- */
- public static void nop() {
- }
-
- /**
- * Dummy method.
- */
- public static void nop(int i) {
- }
-
- /**
- * Dummy method.
- */
- public static void nop(boolean b) {
- }
-
- /**
- * Dummy method.
- */
- public static void nop(Object o) {
- }
-
- /**
- * @return always <code>true</code>
- */
- public static boolean t() {
- return true;
- }
-
- /**
- * @return always <code>false</code>
- */
- public static boolean f() {
- return false;
- }
-
- /**
- * @return always <code>1</code>
- */
- public static int i1() {
- return 1;
- }
-
- /**
- * @return always <code>3</code>
- */
- public static int i2() {
- return 2;
- }
-
- /**
- * @return always <code>3</code>
- */
- public static int i3() {
- return 3;
- }
-
- /**
- * Always throws a {@link RuntimeException}.
- *
- * @throws StubException
- * always thrown
- */
- public static void ex() throws StubException {
- throw new StubException();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.validation.targets; + +/** + * Collection of stub methods that are called from the coverage targets. * + */ +public class Stubs { + + /** + * Exception stub. + */ + public static class StubException extends RuntimeException { + + static final long serialVersionUID = 0L; + + } + + /** + * Superclass stub. + */ + public static class SuperClass { + + public SuperClass(boolean arg) { + } + + } + + /** + * Dummy method. + */ + public static void nop() { + } + + /** + * Dummy method. + */ + public static void nop(int i) { + } + + /** + * Dummy method. + */ + public static void nop(boolean b) { + } + + /** + * Dummy method. + */ + public static void nop(Object o) { + } + + /** + * @return always <code>true</code> + */ + public static boolean t() { + return true; + } + + /** + * @return always <code>false</code> + */ + public static boolean f() { + return false; + } + + /** + * @return always <code>1</code> + */ + public static int i1() { + return 1; + } + + /** + * @return always <code>3</code> + */ + public static int i2() { + return 2; + } + + /** + * @return always <code>3</code> + */ + public static int i3() { + return 3; + } + + /** + * Always throws a {@link RuntimeException}. + * + * @throws StubException + * always thrown + */ + public static void ex() throws StubException { + throw new StubException(); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Target01.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Target01.java index f26b4805..4ad3e493 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Target01.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Target01.java @@ -1,216 +1,216 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.validation.targets;
-
-import static org.jacoco.core.test.validation.targets.Stubs.f;
-import static org.jacoco.core.test.validation.targets.Stubs.i2;
-import static org.jacoco.core.test.validation.targets.Stubs.nop;
-import static org.jacoco.core.test.validation.targets.Stubs.t;
-
-import java.util.Collections;
-
-/**
- * This target exercises a set of common Java control structures.
- */
-public class Target01 implements Runnable {
-
- public void run() {
-
- // 1. Unconditional execution
- nop(); // $line-unconditional$
-
- // 2. Missed if block
- if (f()) { // $line-iffalse$
- nop(); // $line-missedif$
- } else {
- nop(); // $line-executedelse$
- }
-
- // 3. Executed if block
- if (t()) { // $line-iftrue$
- nop(); // $line-executedif$
- } else {
- nop(); // $line-missedelse$
- }
-
- // 4. Missed while block
- while (f()) { // $line-whilefalse$
- nop(); // $line-missedwhile$
- }
-
- // 5. Always executed while block
- while (t()) { // $line-whiletrue$
- if (t()) {
- break;
- }
- }
-
- // 6. Executed while block
- int i = 0;
- while (i++ < 3) { // $line-whiletruefalse$
- nop(); // $line-executedwhile$
- }
-
- // 7. Executed do while block
- do {
- nop(); // $line-executeddowhile$
- } while (f());
-
- // 8. Missed for block
- for (nop(); f(); nop()) { // $line-missedforincrementer$
- nop(); // $line-missedfor$
- }
-
- // 9. Executed for block
- for (int j = 0; j < 1; j++) { // $line-executedforincrementer$
- nop(); // $line-executedfor$
- }
-
- // 10. Missed for each block
- for (Object o : Collections.emptyList()) { // $line-missedforeachincrementer$
- nop(o); // $line-missedforeach$
- }
-
- // 11. Executed for each block
- for (Object o : Collections.singleton(new Object())) { // $line-executedforeachincrementer$
- nop(o); // $line-executedforeach$
- }
-
- // 12. Table switch with hit
- switch (i2()) { // $line-tswitch1$
- case 1:
- nop(); // $line-tswitch1case1$
- break;
- case 2:
- nop(); // $line-tswitch1case2$
- break;
- case 3:
- nop(); // $line-tswitch1case3$
- break;
- default:
- nop(); // $line-tswitch1default$
- break;
- }
-
- // 13. Continued table switch with hit
- switch (i2()) { // $line-tswitch2$
- case 1:
- nop(); // $line-tswitch2case1$
- case 2:
- nop(); // $line-tswitch2case2$
- case 3:
- nop(); // $line-tswitch2case3$
- default:
- nop(); // $line-tswitch2default$
- }
-
- // 14. Table switch without hit
- switch (i2()) { // $line-tswitch3$
- case 3:
- nop(); // $line-tswitch3case1$
- break;
- case 4:
- nop(); // $line-tswitch3case2$
- break;
- case 5:
- nop(); // $line-tswitch3case3$
- break;
- default:
- nop(); // $line-tswitch3default$
- break;
- }
-
- // 15. Lookup switch with hit
- switch (i2()) { // $line-lswitch1$
- case -123:
- nop(); // $line-lswitch1case1$
- break;
- case 2:
- nop(); // $line-lswitch1case2$
- break;
- case 456:
- nop(); // $line-lswitch1case3$
- break;
- default:
- nop(); // $line-lswitch1default$
- break;
- }
-
- // 16. Continued lookup switch with hit
- switch (i2()) { // $line-lswitch2$
- case -123:
- nop(); // $line-lswitch2case1$
- case 2:
- nop(); // $line-lswitch2case2$
- case 456:
- nop(); // $line-lswitch2case3$
- default:
- nop(); // $line-lswitch2default$
- }
-
- // 17. Lookup switch without hit
- switch (i2()) { // $line-lswitch3$
- case -123:
- nop(); // $line-lswitch3case1$
- break;
- case 456:
- nop(); // $line-lswitch3case2$
- break;
- case 789:
- nop(); // $line-lswitch3case3$
- break;
- default:
- nop(); // $line-lswitch3default$
- break;
- }
-
- // 18. Break statement
- while (true) {
- if (t()) {
- break; // $line-executedbreak$
- }
- nop(); // $line-missedafterbreak$
- }
-
- // 19. Continue statement
- for (int j = 0; j < 1; j++) {
- if (t()) {
- continue; // $line-executedcontinue$
- }
- nop(); // $line-missedaftercontinue$
- }
-
- runReturn();
- runImplicitReturn();
-
- }
-
- private void runReturn() {
-
- // 20. Return statement
- if (t()) {
- return; // $line-return$
- }
- nop(); // $line-afterreturn$
-
- }
-
- private void runImplicitReturn() {
-
- // 21. Implicit return
- } // $line-implicitreturn$
-
- public static void main(String[] args) {
- new Target01().run();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.f; +import static org.jacoco.core.test.validation.targets.Stubs.i2; +import static org.jacoco.core.test.validation.targets.Stubs.nop; +import static org.jacoco.core.test.validation.targets.Stubs.t; + +import java.util.Collections; + +/** + * This target exercises a set of common Java control structures. + */ +public class Target01 implements Runnable { + + public void run() { + + // 1. Unconditional execution + nop(); // $line-unconditional$ + + // 2. Missed if block + if (f()) { // $line-iffalse$ + nop(); // $line-missedif$ + } else { + nop(); // $line-executedelse$ + } + + // 3. Executed if block + if (t()) { // $line-iftrue$ + nop(); // $line-executedif$ + } else { + nop(); // $line-missedelse$ + } + + // 4. Missed while block + while (f()) { // $line-whilefalse$ + nop(); // $line-missedwhile$ + } + + // 5. Always executed while block + while (t()) { // $line-whiletrue$ + if (t()) { + break; + } + } + + // 6. Executed while block + int i = 0; + while (i++ < 3) { // $line-whiletruefalse$ + nop(); // $line-executedwhile$ + } + + // 7. Executed do while block + do { + nop(); // $line-executeddowhile$ + } while (f()); + + // 8. Missed for block + for (nop(); f(); nop()) { // $line-missedforincrementer$ + nop(); // $line-missedfor$ + } + + // 9. Executed for block + for (int j = 0; j < 1; j++) { // $line-executedforincrementer$ + nop(); // $line-executedfor$ + } + + // 10. Missed for each block + for (Object o : Collections.emptyList()) { // $line-missedforeachincrementer$ + nop(o); // $line-missedforeach$ + } + + // 11. Executed for each block + for (Object o : Collections.singleton(new Object())) { // $line-executedforeachincrementer$ + nop(o); // $line-executedforeach$ + } + + // 12. Table switch with hit + switch (i2()) { // $line-tswitch1$ + case 1: + nop(); // $line-tswitch1case1$ + break; + case 2: + nop(); // $line-tswitch1case2$ + break; + case 3: + nop(); // $line-tswitch1case3$ + break; + default: + nop(); // $line-tswitch1default$ + break; + } + + // 13. Continued table switch with hit + switch (i2()) { // $line-tswitch2$ + case 1: + nop(); // $line-tswitch2case1$ + case 2: + nop(); // $line-tswitch2case2$ + case 3: + nop(); // $line-tswitch2case3$ + default: + nop(); // $line-tswitch2default$ + } + + // 14. Table switch without hit + switch (i2()) { // $line-tswitch3$ + case 3: + nop(); // $line-tswitch3case1$ + break; + case 4: + nop(); // $line-tswitch3case2$ + break; + case 5: + nop(); // $line-tswitch3case3$ + break; + default: + nop(); // $line-tswitch3default$ + break; + } + + // 15. Lookup switch with hit + switch (i2()) { // $line-lswitch1$ + case -123: + nop(); // $line-lswitch1case1$ + break; + case 2: + nop(); // $line-lswitch1case2$ + break; + case 456: + nop(); // $line-lswitch1case3$ + break; + default: + nop(); // $line-lswitch1default$ + break; + } + + // 16. Continued lookup switch with hit + switch (i2()) { // $line-lswitch2$ + case -123: + nop(); // $line-lswitch2case1$ + case 2: + nop(); // $line-lswitch2case2$ + case 456: + nop(); // $line-lswitch2case3$ + default: + nop(); // $line-lswitch2default$ + } + + // 17. Lookup switch without hit + switch (i2()) { // $line-lswitch3$ + case -123: + nop(); // $line-lswitch3case1$ + break; + case 456: + nop(); // $line-lswitch3case2$ + break; + case 789: + nop(); // $line-lswitch3case3$ + break; + default: + nop(); // $line-lswitch3default$ + break; + } + + // 18. Break statement + while (true) { + if (t()) { + break; // $line-executedbreak$ + } + nop(); // $line-missedafterbreak$ + } + + // 19. Continue statement + for (int j = 0; j < 1; j++) { + if (t()) { + continue; // $line-executedcontinue$ + } + nop(); // $line-missedaftercontinue$ + } + + runReturn(); + runImplicitReturn(); + + } + + private void runReturn() { + + // 20. Return statement + if (t()) { + return; // $line-return$ + } + nop(); // $line-afterreturn$ + + } + + private void runImplicitReturn() { + + // 21. Implicit return + } // $line-implicitreturn$ + + public static void main(String[] args) { + new Target01().run(); + } + +} diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Target02.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Target02.java index fb626b37..1725f4a5 100644 --- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Target02.java +++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/Target02.java @@ -1,124 +1,124 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.test.validation.targets;
-
-import static org.jacoco.core.test.validation.targets.Stubs.f;
-import static org.jacoco.core.test.validation.targets.Stubs.i1;
-import static org.jacoco.core.test.validation.targets.Stubs.i2;
-import static org.jacoco.core.test.validation.targets.Stubs.nop;
-import static org.jacoco.core.test.validation.targets.Stubs.t;
-
-/**
- * This target exercises boolean expressions.
- */
-public class Target02 implements Runnable {
-
- public void run() {
-
- // 1. Boolean comparison result (one case)
- nop(i2() > 3); // $line-booleancmp1$
-
- // 2. Boolean comparison result (both cases)
- for (int i = 0; i < 2; i++) {
- nop(i < 1); // $line-booleancmp2$
- }
-
- // 3. And
- if (f() & f()) { // $line-andFF$
- nop();
- }
- if (f() & t()) { // $line-andFT$
- nop();
- }
- if (t() & f()) { // $line-andTF$
- nop();
- }
- if (t() & t()) { // $line-andTT$
- nop();
- }
-
- // 4. Conditional And
- if (f() && f()) { // $line-conditionalandFF$
- nop();
- }
- if (f() && t()) { // $line-conditionalandFT$
- nop();
- }
- if (t() && f()) { // $line-conditionalandTF$
- nop();
- }
- if (t() && t()) { // $line-conditionalandTT$
- nop();
- }
-
- // 5. Or
- if (f() | f()) { // $line-orFF$
- nop();
- }
- if (f() | t()) { // $line-orFT$
- nop();
- }
- if (t() | f()) { // $line-orTF$
- nop();
- }
- if (t() | t()) { // $line-orTT$
- nop();
- }
-
- // 6. Conditional Or
- if (f() || f()) { // $line-conditionalorFF$
- nop();
- }
- if (f() || t()) { // $line-conditionalorFT$
- nop();
- }
- if (t() || f()) { // $line-conditionalorTF$
- nop();
- }
- if (t() || t()) { // $line-conditionalorTT$
- nop();
- }
-
- // 7. Exclusive Or
- if (f() ^ f()) { // $line-xorFF$
- nop();
- }
- if (f() ^ t()) { // $line-xorFT$
- nop();
- }
- if (t() ^ f()) { // $line-xorTF$
- nop();
- }
- if (t() ^ t()) { // $line-xorTT$
- nop();
- }
-
- // 8. Conditional Operator
- nop(t() ? i1() : i2()); // $line-condT$
- nop(f() ? i1() : i2()); // $line-condF$
-
- // 9. Not (one case)
- nop(!t()); // $line-notT$
- nop(!f()); // $line-notF$
-
- // 10. Not (both cases)
- for (boolean b : new boolean[] { true, false }) {
- nop(!b); // $line-notTF$
- }
-
- }
-
- public static void main(String[] args) {
- new Target02().run();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.f; +import static org.jacoco.core.test.validation.targets.Stubs.i1; +import static org.jacoco.core.test.validation.targets.Stubs.i2; +import static org.jacoco.core.test.validation.targets.Stubs.nop; +import static org.jacoco.core.test.validation.targets.Stubs.t; + +/** + * This target exercises boolean expressions. + */ +public class Target02 implements Runnable { + + public void run() { + + // 1. Boolean comparison result (one case) + nop(i2() > 3); // $line-booleancmp1$ + + // 2. Boolean comparison result (both cases) + for (int i = 0; i < 2; i++) { + nop(i < 1); // $line-booleancmp2$ + } + + // 3. And + if (f() & f()) { // $line-andFF$ + nop(); + } + if (f() & t()) { // $line-andFT$ + nop(); + } + if (t() & f()) { // $line-andTF$ + nop(); + } + if (t() & t()) { // $line-andTT$ + nop(); + } + + // 4. Conditional And + if (f() && f()) { // $line-conditionalandFF$ + nop(); + } + if (f() && t()) { // $line-conditionalandFT$ + nop(); + } + if (t() && f()) { // $line-conditionalandTF$ + nop(); + } + if (t() && t()) { // $line-conditionalandTT$ + nop(); + } + + // 5. Or + if (f() | f()) { // $line-orFF$ + nop(); + } + if (f() | t()) { // $line-orFT$ + nop(); + } + if (t() | f()) { // $line-orTF$ + nop(); + } + if (t() | t()) { // $line-orTT$ + nop(); + } + + // 6. Conditional Or + if (f() || f()) { // $line-conditionalorFF$ + nop(); + } + if (f() || t()) { // $line-conditionalorFT$ + nop(); + } + if (t() || f()) { // $line-conditionalorTF$ + nop(); + } + if (t() || t()) { // $line-conditionalorTT$ + nop(); + } + + // 7. Exclusive Or + if (f() ^ f()) { // $line-xorFF$ + nop(); + } + if (f() ^ t()) { // $line-xorFT$ + nop(); + } + if (t() ^ f()) { // $line-xorTF$ + nop(); + } + if (t() ^ t()) { // $line-xorTT$ + nop(); + } + + // 8. Conditional Operator + nop(t() ? i1() : i2()); // $line-condT$ + nop(f() ? i1() : i2()); // $line-condF$ + + // 9. Not (one case) + nop(!t()); // $line-notT$ + nop(!f()); // $line-notF$ + + // 10. Not (both cases) + for (boolean b : new boolean[] { true, false }) { + nop(!b); // $line-notTF$ + } + + } + + public static void main(String[] args) { + new Target02().run(); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/JaCoCo.java b/org.jacoco.core/src/org/jacoco/core/JaCoCo.java index 83d8769b..c79fd1d2 100644 --- a/org.jacoco.core/src/org/jacoco/core/JaCoCo.java +++ b/org.jacoco.core/src/org/jacoco/core/JaCoCo.java @@ -1,37 +1,37 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core;
-
-import java.util.ResourceBundle;
-
-/**
- * Static Meta information about JaCoCo.
- */
-public final class JaCoCo {
-
- /** Qualified build version of the JaCoCo core library. */
- public static final String VERSION;
-
- /** Absolute URL of the current JaCoCo home page */
- public static final String HOMEURL;
-
- static {
- final ResourceBundle bundle = ResourceBundle
- .getBundle("org.jacoco.core.jacoco");
- VERSION = bundle.getString("VERSION");
- HOMEURL = bundle.getString("HOMEURL");
- }
-
- private JaCoCo() {
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core; + +import java.util.ResourceBundle; + +/** + * Static Meta information about JaCoCo. + */ +public final class JaCoCo { + + /** Qualified build version of the JaCoCo core library. */ + public static final String VERSION; + + /** Absolute URL of the current JaCoCo home page */ + public static final String HOMEURL; + + static { + final ResourceBundle bundle = ResourceBundle + .getBundle("org.jacoco.core.jacoco"); + VERSION = bundle.getString("VERSION"); + HOMEURL = bundle.getString("HOMEURL"); + } + + private JaCoCo() { + } + +} 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 1b351d6d..b6400bcf 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java @@ -1,214 +1,214 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.StringTokenizer;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.internal.analysis.ClassAnalyzer;
-import org.jacoco.core.internal.analysis.ContentTypeDetector;
-import org.jacoco.core.internal.analysis.StringPool;
-import org.jacoco.core.internal.data.CRC64;
-import org.jacoco.core.internal.flow.ClassProbesAdapter;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-
-/**
- * An {@link Analyzer} instance processes a set of Java class files and
- * calculates coverage data for them. For each class file the result is reported
- * to a given {@link ICoverageVisitor} instance. In addition the
- * {@link Analyzer} requires a {@link ExecutionDataStore} instance that holds
- * the execution data for the classes to analyze. The {@link Analyzer} offers
- * several methods to analyze classes from a variety of sources.
- */
-public class Analyzer {
-
- private final ExecutionDataStore executionData;
-
- private final ICoverageVisitor coverageVisitor;
-
- private final StringPool stringPool;
-
- /**
- * Creates a new analyzer reporting to the given output.
- *
- * @param executionData
- * execution data
- * @param coverageVisitor
- * the output instance that will coverage data for every analyzed
- * class
- */
- public Analyzer(final ExecutionDataStore executionData,
- final ICoverageVisitor coverageVisitor) {
- this.executionData = executionData;
- this.coverageVisitor = coverageVisitor;
- this.stringPool = new StringPool();
- }
-
- /**
- * Creates an ASM class visitor for analysis.
- *
- * @param classid
- * id of the class calculated with {@link CRC64}
- * @return ASM visitor to write class definition to
- */
- private ClassVisitor createAnalyzingVisitor(final long classid) {
- final ExecutionData data = executionData.get(classid);
- final boolean[] classExec = data == null ? null : data.getData();
- final ClassAnalyzer analyzer = new ClassAnalyzer(classid, classExec,
- stringPool) {
- @Override
- public void visitEnd() {
- super.visitEnd();
- coverageVisitor.visitCoverage(getCoverage());
- }
- };
- return new ClassProbesAdapter(analyzer);
- }
-
- /**
- * Analyzes the class given as a ASM reader.
- *
- * @param reader
- * reader with class definitions
- */
- public void analyzeClass(final ClassReader reader) {
- final ClassVisitor visitor = createAnalyzingVisitor(CRC64
- .checksum(reader.b));
- reader.accept(visitor, 0);
- }
-
- /**
- * Analyzes the class definition from a given in-memory buffer.
- *
- * @param buffer
- * class definitions
- */
- public void analyzeClass(final byte[] buffer) {
- analyzeClass(new ClassReader(buffer));
- }
-
- /**
- * Analyzes the class definition from a given input stream.
- *
- * @param input
- * stream to read class definition from
- * @throws IOException
- */
- public void analyzeClass(final InputStream input) throws IOException {
- analyzeClass(new ClassReader(input));
- }
-
- /**
- * Analyzes all classes contained in the ZIP archive (jar, war, ear, etc.)
- * given as an input stream. Contained archives are read recursively.
- *
- * @param input
- * ZIP archive data
- * @return number of class files found
- * @throws IOException
- */
- public int analyzeArchive(final InputStream input) throws IOException {
- final ZipInputStream zip = new ZipInputStream(input);
- int count = 0;
- while (true) {
- final ZipEntry entry = zip.getNextEntry();
- if (entry == null) {
- break;
- }
- count += analyzeAll(zip);
- }
- return count;
- }
-
- /**
- * Analyzes all classes found in the given input stream. The input stream
- * may either represent a single class file or a ZIP archive that is
- * searched recursively for class files. All other content types are
- * ignored.
- *
- * @param input
- * input data
- * @return number of class files found
- * @throws IOException
- */
- public int analyzeAll(final InputStream input) throws IOException {
- final ContentTypeDetector detector = new ContentTypeDetector(input);
- switch (detector.getType()) {
- case ContentTypeDetector.CLASSFILE:
- analyzeClass(detector.getInputStream());
- return 1;
- case ContentTypeDetector.ZIPFILE:
- return analyzeArchive(detector.getInputStream());
- default:
- return 0;
- }
- }
-
- /**
- * Analyzes all class files contained in the given file or folder. Class
- * files as well as ZIP files are considered. Folders are searched
- * recursively.
- *
- * @param file
- * file or folder to look for class files
- * @return number of class files found
- * @throws IOException
- */
- public int analyzeAll(final File file) throws IOException {
- int count = 0;
- if (file.isDirectory()) {
- for (final File f : file.listFiles()) {
- count += analyzeAll(f);
- }
- } else {
- final InputStream in = new FileInputStream(file);
- try {
- count += analyzeAll(in);
- } finally {
- in.close();
- }
- }
- return count;
- }
-
- /**
- * Analyzes all classes from the given class path. Directories containing
- * class files as well as archive files are considered.
- *
- * @param path
- * path definition
- * @param basedir
- * optional base directory, if <code>null</code> the current
- * working directory is used as the base for relative path
- * entries
- * @return number of class files found
- * @throws IOException
- */
- public int analyzeAll(final String path, final File basedir)
- throws IOException {
- int count = 0;
- final StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
- while (st.hasMoreTokens()) {
- count += analyzeAll(new File(basedir, st.nextToken()));
- }
- return count;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.StringTokenizer; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.internal.analysis.ClassAnalyzer; +import org.jacoco.core.internal.analysis.ContentTypeDetector; +import org.jacoco.core.internal.analysis.StringPool; +import org.jacoco.core.internal.data.CRC64; +import org.jacoco.core.internal.flow.ClassProbesAdapter; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; + +/** + * An {@link Analyzer} instance processes a set of Java class files and + * calculates coverage data for them. For each class file the result is reported + * to a given {@link ICoverageVisitor} instance. In addition the + * {@link Analyzer} requires a {@link ExecutionDataStore} instance that holds + * the execution data for the classes to analyze. The {@link Analyzer} offers + * several methods to analyze classes from a variety of sources. + */ +public class Analyzer { + + private final ExecutionDataStore executionData; + + private final ICoverageVisitor coverageVisitor; + + private final StringPool stringPool; + + /** + * Creates a new analyzer reporting to the given output. + * + * @param executionData + * execution data + * @param coverageVisitor + * the output instance that will coverage data for every analyzed + * class + */ + public Analyzer(final ExecutionDataStore executionData, + final ICoverageVisitor coverageVisitor) { + this.executionData = executionData; + this.coverageVisitor = coverageVisitor; + this.stringPool = new StringPool(); + } + + /** + * Creates an ASM class visitor for analysis. + * + * @param classid + * id of the class calculated with {@link CRC64} + * @return ASM visitor to write class definition to + */ + private ClassVisitor createAnalyzingVisitor(final long classid) { + final ExecutionData data = executionData.get(classid); + final boolean[] classExec = data == null ? null : data.getData(); + final ClassAnalyzer analyzer = new ClassAnalyzer(classid, classExec, + stringPool) { + @Override + public void visitEnd() { + super.visitEnd(); + coverageVisitor.visitCoverage(getCoverage()); + } + }; + return new ClassProbesAdapter(analyzer); + } + + /** + * Analyzes the class given as a ASM reader. + * + * @param reader + * reader with class definitions + */ + public void analyzeClass(final ClassReader reader) { + final ClassVisitor visitor = createAnalyzingVisitor(CRC64 + .checksum(reader.b)); + reader.accept(visitor, 0); + } + + /** + * Analyzes the class definition from a given in-memory buffer. + * + * @param buffer + * class definitions + */ + public void analyzeClass(final byte[] buffer) { + analyzeClass(new ClassReader(buffer)); + } + + /** + * Analyzes the class definition from a given input stream. + * + * @param input + * stream to read class definition from + * @throws IOException + */ + public void analyzeClass(final InputStream input) throws IOException { + analyzeClass(new ClassReader(input)); + } + + /** + * Analyzes all classes contained in the ZIP archive (jar, war, ear, etc.) + * given as an input stream. Contained archives are read recursively. + * + * @param input + * ZIP archive data + * @return number of class files found + * @throws IOException + */ + public int analyzeArchive(final InputStream input) throws IOException { + final ZipInputStream zip = new ZipInputStream(input); + int count = 0; + while (true) { + final ZipEntry entry = zip.getNextEntry(); + if (entry == null) { + break; + } + count += analyzeAll(zip); + } + return count; + } + + /** + * Analyzes all classes found in the given input stream. The input stream + * may either represent a single class file or a ZIP archive that is + * searched recursively for class files. All other content types are + * ignored. + * + * @param input + * input data + * @return number of class files found + * @throws IOException + */ + public int analyzeAll(final InputStream input) throws IOException { + final ContentTypeDetector detector = new ContentTypeDetector(input); + switch (detector.getType()) { + case ContentTypeDetector.CLASSFILE: + analyzeClass(detector.getInputStream()); + return 1; + case ContentTypeDetector.ZIPFILE: + return analyzeArchive(detector.getInputStream()); + default: + return 0; + } + } + + /** + * Analyzes all class files contained in the given file or folder. Class + * files as well as ZIP files are considered. Folders are searched + * recursively. + * + * @param file + * file or folder to look for class files + * @return number of class files found + * @throws IOException + */ + public int analyzeAll(final File file) throws IOException { + int count = 0; + if (file.isDirectory()) { + for (final File f : file.listFiles()) { + count += analyzeAll(f); + } + } else { + final InputStream in = new FileInputStream(file); + try { + count += analyzeAll(in); + } finally { + in.close(); + } + } + return count; + } + + /** + * Analyzes all classes from the given class path. Directories containing + * class files as well as archive files are considered. + * + * @param path + * path definition + * @param basedir + * optional base directory, if <code>null</code> the current + * working directory is used as the base for relative path + * entries + * @return number of class files found + * @throws IOException + */ + public int analyzeAll(final String path, final File basedir) + throws IOException { + int count = 0; + final StringTokenizer st = new StringTokenizer(path, File.pathSeparator); + while (st.hasMoreTokens()) { + count += analyzeAll(new File(basedir, st.nextToken())); + } + return count; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/CounterComparator.java b/org.jacoco.core/src/org/jacoco/core/analysis/CounterComparator.java index 82c953ae..7469deee 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/CounterComparator.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/CounterComparator.java @@ -1,117 +1,117 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import java.io.Serializable;
-import java.util.Comparator;
-
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-
-/**
- * Collection of comparators to compare {@link ICounter} objects by different
- * criteria.
- */
-public abstract class CounterComparator implements Comparator<ICounter>,
- Serializable {
-
- private static final long serialVersionUID = -3777463066252746748L;
-
- /**
- * Compares the absolute number of total items.
- */
- public static final CounterComparator TOTALITEMS = new CounterComparator() {
-
- private static final long serialVersionUID = 8824120489765405662L;
-
- public int compare(final ICounter c1, final ICounter c2) {
- return c1.getTotalCount() - c2.getTotalCount();
- }
- };
-
- /**
- * Compares the absolute number of covered items.
- */
- public static final CounterComparator COVEREDITEMS = new CounterComparator() {
-
- private static final long serialVersionUID = 1L;
-
- public int compare(final ICounter c1, final ICounter c2) {
- return c1.getCoveredCount() - c2.getCoveredCount();
- }
- };
-
- /**
- * Compares the absolute number of missed items.
- */
- public static final CounterComparator MISSEDITEMS = new CounterComparator() {
-
- private static final long serialVersionUID = -2991039557556551206L;
-
- public int compare(final ICounter c1, final ICounter c2) {
- return c1.getMissedCount() - c2.getMissedCount();
- }
- };
-
- /**
- * Compares the ratio of covered items.
- */
- public static final CounterComparator COVEREDRATIO = new CounterComparator() {
-
- private static final long serialVersionUID = 7897690710299613918L;
-
- public int compare(final ICounter c1, final ICounter c2) {
- return Double.compare(c1.getCoveredRatio(), c2.getCoveredRatio());
- }
- };
-
- /**
- * Compares the ratio of missed items.
- */
- public static final CounterComparator MISSEDRATIO = new CounterComparator() {
-
- private static final long serialVersionUID = -5014193668057469357L;
-
- public int compare(final ICounter c1, final ICounter c2) {
- return Double.compare(c1.getMissedRatio(), c2.getMissedRatio());
- }
- };
-
- /**
- * Creates a new version of this comparator that sorts in reverse order.
- *
- * @return reverse comparator
- */
- public CounterComparator reverse() {
- final CounterComparator original = this;
- return new CounterComparator() {
-
- private static final long serialVersionUID = 7703349549732801967L;
-
- public int compare(final ICounter o1, final ICounter o2) {
- return original.compare(o2, o1);
- }
- };
- }
-
- /**
- * Creates a new comparator for {@link ICoverageNode} counters of the given
- * entity based on this counter sorting criteria.
- *
- * @param entity
- * counter entity to sort on
- * @return comparator for {@link ICoverageNode} elements
- */
- public NodeComparator on(final CounterEntity entity) {
- return new NodeComparator(this, entity);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import java.io.Serializable; +import java.util.Comparator; + +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; + +/** + * Collection of comparators to compare {@link ICounter} objects by different + * criteria. + */ +public abstract class CounterComparator implements Comparator<ICounter>, + Serializable { + + private static final long serialVersionUID = -3777463066252746748L; + + /** + * Compares the absolute number of total items. + */ + public static final CounterComparator TOTALITEMS = new CounterComparator() { + + private static final long serialVersionUID = 8824120489765405662L; + + public int compare(final ICounter c1, final ICounter c2) { + return c1.getTotalCount() - c2.getTotalCount(); + } + }; + + /** + * Compares the absolute number of covered items. + */ + public static final CounterComparator COVEREDITEMS = new CounterComparator() { + + private static final long serialVersionUID = 1L; + + public int compare(final ICounter c1, final ICounter c2) { + return c1.getCoveredCount() - c2.getCoveredCount(); + } + }; + + /** + * Compares the absolute number of missed items. + */ + public static final CounterComparator MISSEDITEMS = new CounterComparator() { + + private static final long serialVersionUID = -2991039557556551206L; + + public int compare(final ICounter c1, final ICounter c2) { + return c1.getMissedCount() - c2.getMissedCount(); + } + }; + + /** + * Compares the ratio of covered items. + */ + public static final CounterComparator COVEREDRATIO = new CounterComparator() { + + private static final long serialVersionUID = 7897690710299613918L; + + public int compare(final ICounter c1, final ICounter c2) { + return Double.compare(c1.getCoveredRatio(), c2.getCoveredRatio()); + } + }; + + /** + * Compares the ratio of missed items. + */ + public static final CounterComparator MISSEDRATIO = new CounterComparator() { + + private static final long serialVersionUID = -5014193668057469357L; + + public int compare(final ICounter c1, final ICounter c2) { + return Double.compare(c1.getMissedRatio(), c2.getMissedRatio()); + } + }; + + /** + * Creates a new version of this comparator that sorts in reverse order. + * + * @return reverse comparator + */ + public CounterComparator reverse() { + final CounterComparator original = this; + return new CounterComparator() { + + private static final long serialVersionUID = 7703349549732801967L; + + public int compare(final ICounter o1, final ICounter o2) { + return original.compare(o2, o1); + } + }; + } + + /** + * Creates a new comparator for {@link ICoverageNode} counters of the given + * entity based on this counter sorting criteria. + * + * @param entity + * counter entity to sort on + * @return comparator for {@link ICoverageNode} elements + */ + public NodeComparator on(final CounterEntity entity) { + return new NodeComparator(this, entity); + } + +} 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 38ea6594..bbf6c0b2 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/CoverageBuilder.java @@ -1,113 +1,113 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jacoco.core.internal.analysis.BundleCoverageImpl;
-import org.jacoco.core.internal.analysis.SourceFileCoverageImpl;
-
-/**
- * Builder for hierarchical {@link ICoverageNode} structures from single
- * {@link IClassCoverage} nodes. The nodes are feed into the builder through its
- * {@link ICoverageVisitor} interface. Afterwards the aggregated data can be
- * obtained with {@link #getClasses()}, {@link #getSourceFiles()} or
- * {@link #getBundle(String)} in the following hierarchy:
- *
- * <pre>
- * {@link IBundleCoverage}
- * +-- {@link IPackageCoverage}*
- * +-- {@link IClassCoverage}*
- * +-- {@link ISourceFileCoverage}*
- * </pre>
- */
-public class CoverageBuilder implements ICoverageVisitor {
-
- private final Map<String, IClassCoverage> classes;
-
- private final Map<String, ISourceFileCoverage> sourcefiles;
-
- /**
- * Create a new builder.
- *
- */
- public CoverageBuilder() {
- this.classes = new HashMap<String, IClassCoverage>();
- this.sourcefiles = new HashMap<String, ISourceFileCoverage>();
- }
-
- /**
- * Returns all class nodes currently contained in this builder.
- *
- * @return all class nodes
- */
- public Collection<IClassCoverage> getClasses() {
- return Collections.unmodifiableCollection(classes.values());
- }
-
- /**
- * Returns all source file nodes currently contained in this builder.
- *
- * @return all source file nodes
- */
- public Collection<ISourceFileCoverage> getSourceFiles() {
- return Collections.unmodifiableCollection(sourcefiles.values());
- }
-
- /**
- * Creates a bundle from all nodes currently contained in this bundle.
- *
- * @param name
- * Name of the bundle
- * @return bundle containing all classes and source files
- */
- public IBundleCoverage getBundle(final String name) {
- return new BundleCoverageImpl(name, classes.values(),
- sourcefiles.values());
- }
-
- // === IStructureVisitor ===
-
- public void visitCoverage(final IClassCoverage coverage) {
- // Only consider classes that actually contain code:
- if (coverage.getInstructionCounter().getTotalCount() > 0) {
- final String name = coverage.getName();
- final IClassCoverage dup = classes.put(name, coverage);
- if (dup != null && dup.getId() != coverage.getId()) {
- throw new IllegalStateException(
- "Can't add different class with same name: " + name);
- }
- final String source = coverage.getSourceFileName();
- if (source != null) {
- final SourceFileCoverageImpl sourceFile = getSourceFile(source,
- coverage.getPackageName());
- sourceFile.increment(coverage);
- }
- }
- }
-
- private SourceFileCoverageImpl getSourceFile(final String filename,
- final String packagename) {
- final String key = packagename + '/' + filename;
- SourceFileCoverageImpl sourcefile = (SourceFileCoverageImpl) sourcefiles
- .get(key);
- if (sourcefile == null) {
- sourcefile = new SourceFileCoverageImpl(filename, packagename);
- sourcefiles.put(key, sourcefile);
- }
- return sourcefile;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.jacoco.core.internal.analysis.BundleCoverageImpl; +import org.jacoco.core.internal.analysis.SourceFileCoverageImpl; + +/** + * Builder for hierarchical {@link ICoverageNode} structures from single + * {@link IClassCoverage} nodes. The nodes are feed into the builder through its + * {@link ICoverageVisitor} interface. Afterwards the aggregated data can be + * obtained with {@link #getClasses()}, {@link #getSourceFiles()} or + * {@link #getBundle(String)} in the following hierarchy: + * + * <pre> + * {@link IBundleCoverage} + * +-- {@link IPackageCoverage}* + * +-- {@link IClassCoverage}* + * +-- {@link ISourceFileCoverage}* + * </pre> + */ +public class CoverageBuilder implements ICoverageVisitor { + + private final Map<String, IClassCoverage> classes; + + private final Map<String, ISourceFileCoverage> sourcefiles; + + /** + * Create a new builder. + * + */ + public CoverageBuilder() { + this.classes = new HashMap<String, IClassCoverage>(); + this.sourcefiles = new HashMap<String, ISourceFileCoverage>(); + } + + /** + * Returns all class nodes currently contained in this builder. + * + * @return all class nodes + */ + public Collection<IClassCoverage> getClasses() { + return Collections.unmodifiableCollection(classes.values()); + } + + /** + * Returns all source file nodes currently contained in this builder. + * + * @return all source file nodes + */ + public Collection<ISourceFileCoverage> getSourceFiles() { + return Collections.unmodifiableCollection(sourcefiles.values()); + } + + /** + * Creates a bundle from all nodes currently contained in this bundle. + * + * @param name + * Name of the bundle + * @return bundle containing all classes and source files + */ + public IBundleCoverage getBundle(final String name) { + return new BundleCoverageImpl(name, classes.values(), + sourcefiles.values()); + } + + // === IStructureVisitor === + + public void visitCoverage(final IClassCoverage coverage) { + // Only consider classes that actually contain code: + if (coverage.getInstructionCounter().getTotalCount() > 0) { + final String name = coverage.getName(); + final IClassCoverage dup = classes.put(name, coverage); + if (dup != null && dup.getId() != coverage.getId()) { + throw new IllegalStateException( + "Can't add different class with same name: " + name); + } + final String source = coverage.getSourceFileName(); + if (source != null) { + final SourceFileCoverageImpl sourceFile = getSourceFile(source, + coverage.getPackageName()); + sourceFile.increment(coverage); + } + } + } + + private SourceFileCoverageImpl getSourceFile(final String filename, + final String packagename) { + final String key = packagename + '/' + filename; + SourceFileCoverageImpl sourcefile = (SourceFileCoverageImpl) sourcefiles + .get(key); + if (sourcefile == null) { + sourcefile = new SourceFileCoverageImpl(filename, packagename); + sourcefiles.put(key, sourcefile); + } + return sourcefile; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/CoverageNodeImpl.java b/org.jacoco.core/src/org/jacoco/core/analysis/CoverageNodeImpl.java index 4ef59f16..30030470 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/CoverageNodeImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/CoverageNodeImpl.java @@ -1,164 +1,164 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import java.util.Collection;
-
-import org.jacoco.core.internal.analysis.CounterImpl;
-
-/**
- * Base implementation for coverage data nodes.
- */
-public class CoverageNodeImpl implements ICoverageNode {
-
- private final ElementType elementType;
-
- private final String name;
-
- /** Counter for branches. */
- protected CounterImpl branchCounter;
-
- /** Counter for instructions. */
- protected CounterImpl instructionCounter;
-
- /** Counter for lines */
- protected CounterImpl lineCounter;
-
- /** Counter for complexity. */
- protected CounterImpl complexityCounter;
-
- /** Counter for methods. */
- protected CounterImpl methodCounter;
-
- /** Counter for classes. */
- protected CounterImpl classCounter;
-
- /**
- * Creates a new coverage data node.
- *
- * @param elementType
- * type of the element represented by this instance
- * @param name
- * name of this node
- */
- public CoverageNodeImpl(final ElementType elementType, final String name) {
- this.elementType = elementType;
- this.name = name;
- this.branchCounter = CounterImpl.COUNTER_0_0;
- this.instructionCounter = CounterImpl.COUNTER_0_0;
- this.complexityCounter = CounterImpl.COUNTER_0_0;
- this.methodCounter = CounterImpl.COUNTER_0_0;
- this.classCounter = CounterImpl.COUNTER_0_0;
- this.lineCounter = CounterImpl.COUNTER_0_0;
- }
-
- /**
- * Increments the counters by the values given by another element.
- *
- * @param child
- * counters to add
- */
- public void increment(final ICoverageNode child) {
- instructionCounter = instructionCounter.increment(child
- .getInstructionCounter());
- branchCounter = branchCounter.increment(child.getBranchCounter());
- lineCounter = lineCounter.increment(child.getLineCounter());
- complexityCounter = complexityCounter.increment(child
- .getComplexityCounter());
- methodCounter = methodCounter.increment(child.getMethodCounter());
- classCounter = classCounter.increment(child.getClassCounter());
- }
-
- /**
- * Increments the counters by the values given by the collection of
- * elements.
- *
- * @param children
- * list of nodes, which counters will be added to this node
- */
- public void increment(final Collection<? extends ICoverageNode> children) {
- for (final ICoverageNode child : children) {
- increment(child);
- }
- }
-
- // === ICoverageDataNode ===
-
- public ElementType getElementType() {
- return elementType;
- }
-
- public String getName() {
- return name;
- }
-
- public ICounter getInstructionCounter() {
- return instructionCounter;
- }
-
- public ICounter getBranchCounter() {
- return branchCounter;
- }
-
- public ICounter getLineCounter() {
- return lineCounter;
- }
-
- public ICounter getComplexityCounter() {
- return complexityCounter;
- }
-
- public ICounter getMethodCounter() {
- return methodCounter;
- }
-
- public ICounter getClassCounter() {
- return classCounter;
- }
-
- public ICounter getCounter(final CounterEntity entity) {
- switch (entity) {
- case INSTRUCTION:
- return getInstructionCounter();
- case BRANCH:
- return getBranchCounter();
- case LINE:
- return getLineCounter();
- case COMPLEXITY:
- return getComplexityCounter();
- case METHOD:
- return getMethodCounter();
- case CLASS:
- return getClassCounter();
- }
- throw new AssertionError(entity);
- }
-
- public ICoverageNode getPlainCopy() {
- final CoverageNodeImpl copy = new CoverageNodeImpl(elementType, name);
- copy.instructionCounter = CounterImpl.getInstance(instructionCounter);
- copy.branchCounter = CounterImpl.getInstance(branchCounter);
- copy.lineCounter = CounterImpl.getInstance(lineCounter);
- copy.complexityCounter = CounterImpl.getInstance(complexityCounter);
- copy.methodCounter = CounterImpl.getInstance(methodCounter);
- copy.classCounter = CounterImpl.getInstance(classCounter);
- return copy;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append(name).append(" [").append(elementType).append("]");
- return sb.toString();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import java.util.Collection; + +import org.jacoco.core.internal.analysis.CounterImpl; + +/** + * Base implementation for coverage data nodes. + */ +public class CoverageNodeImpl implements ICoverageNode { + + private final ElementType elementType; + + private final String name; + + /** Counter for branches. */ + protected CounterImpl branchCounter; + + /** Counter for instructions. */ + protected CounterImpl instructionCounter; + + /** Counter for lines */ + protected CounterImpl lineCounter; + + /** Counter for complexity. */ + protected CounterImpl complexityCounter; + + /** Counter for methods. */ + protected CounterImpl methodCounter; + + /** Counter for classes. */ + protected CounterImpl classCounter; + + /** + * Creates a new coverage data node. + * + * @param elementType + * type of the element represented by this instance + * @param name + * name of this node + */ + public CoverageNodeImpl(final ElementType elementType, final String name) { + this.elementType = elementType; + this.name = name; + this.branchCounter = CounterImpl.COUNTER_0_0; + this.instructionCounter = CounterImpl.COUNTER_0_0; + this.complexityCounter = CounterImpl.COUNTER_0_0; + this.methodCounter = CounterImpl.COUNTER_0_0; + this.classCounter = CounterImpl.COUNTER_0_0; + this.lineCounter = CounterImpl.COUNTER_0_0; + } + + /** + * Increments the counters by the values given by another element. + * + * @param child + * counters to add + */ + public void increment(final ICoverageNode child) { + instructionCounter = instructionCounter.increment(child + .getInstructionCounter()); + branchCounter = branchCounter.increment(child.getBranchCounter()); + lineCounter = lineCounter.increment(child.getLineCounter()); + complexityCounter = complexityCounter.increment(child + .getComplexityCounter()); + methodCounter = methodCounter.increment(child.getMethodCounter()); + classCounter = classCounter.increment(child.getClassCounter()); + } + + /** + * Increments the counters by the values given by the collection of + * elements. + * + * @param children + * list of nodes, which counters will be added to this node + */ + public void increment(final Collection<? extends ICoverageNode> children) { + for (final ICoverageNode child : children) { + increment(child); + } + } + + // === ICoverageDataNode === + + public ElementType getElementType() { + return elementType; + } + + public String getName() { + return name; + } + + public ICounter getInstructionCounter() { + return instructionCounter; + } + + public ICounter getBranchCounter() { + return branchCounter; + } + + public ICounter getLineCounter() { + return lineCounter; + } + + public ICounter getComplexityCounter() { + return complexityCounter; + } + + public ICounter getMethodCounter() { + return methodCounter; + } + + public ICounter getClassCounter() { + return classCounter; + } + + public ICounter getCounter(final CounterEntity entity) { + switch (entity) { + case INSTRUCTION: + return getInstructionCounter(); + case BRANCH: + return getBranchCounter(); + case LINE: + return getLineCounter(); + case COMPLEXITY: + return getComplexityCounter(); + case METHOD: + return getMethodCounter(); + case CLASS: + return getClassCounter(); + } + throw new AssertionError(entity); + } + + public ICoverageNode getPlainCopy() { + final CoverageNodeImpl copy = new CoverageNodeImpl(elementType, name); + copy.instructionCounter = CounterImpl.getInstance(instructionCounter); + copy.branchCounter = CounterImpl.getInstance(branchCounter); + copy.lineCounter = CounterImpl.getInstance(lineCounter); + copy.complexityCounter = CounterImpl.getInstance(complexityCounter); + copy.methodCounter = CounterImpl.getInstance(methodCounter); + copy.classCounter = CounterImpl.getInstance(classCounter); + return copy; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append(name).append(" [").append(elementType).append("]"); + return sb.toString(); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/IBundleCoverage.java b/org.jacoco.core/src/org/jacoco/core/analysis/IBundleCoverage.java index 3e9c0e09..b362940b 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/IBundleCoverage.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/IBundleCoverage.java @@ -1,30 +1,30 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import java.util.Collection;
-
-/**
- * Coverage data of a bundle. A bundle groups a collection of packages.
- *
- * @see IPackageCoverage
- */
-public interface IBundleCoverage extends ICoverageNode {
-
- /**
- * Returns all packages contained in this bundle.
- *
- * @return all packages
- */
- public Collection<IPackageCoverage> getPackages();
-
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import java.util.Collection; + +/** + * Coverage data of a bundle. A bundle groups a collection of packages. + * + * @see IPackageCoverage + */ +public interface IBundleCoverage extends ICoverageNode { + + /** + * Returns all packages contained in this bundle. + * + * @return all packages + */ + public Collection<IPackageCoverage> getPackages(); + }
\ No newline at end of file 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 4f131a58..919c1b61 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/IClassCoverage.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/IClassCoverage.java @@ -1,75 +1,75 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import java.util.Collection;
-
-/**
- * Coverage data of a single class containing methods. The name of this node is
- * the fully qualified class name in VM notation (slash separated).
- *
- * @see IMethodCoverage
- */
-public interface IClassCoverage extends ISourceNode {
-
- /**
- * Returns the identifier for this class which is the CRC64 signature of the
- * class definition.
- *
- * @return class identifier
- */
- public long getId();
-
- /**
- * Returns the VM signature of the class.
- *
- * @return VM signature of the class (may be <code>null</code>)
- */
- public String getSignature();
-
- /**
- * Returns the VM name of the superclass.
- *
- * @return VM name of the super class (may be <code>null</code>, i.e.
- * <code>java/lang/Object</code>)
- */
- public String getSuperName();
-
- /**
- * Returns the VM names of implemented/extended interfaces
- *
- * @return VM names of implemented/extended interfaces
- */
- public String[] getInterfaceNames();
-
- /**
- * Returns the VM name of the package this class belongs to.
- *
- * @return VM name of the package
- */
- public String getPackageName();
-
- /**
- * Returns the optional name of the corresponding source file.
- *
- * @return name of the corresponding source file
- */
- public String getSourceFileName();
-
- /**
- * Returns the methods included in this class.
- *
- * @return methods of this class
- */
- public Collection<IMethodCoverage> getMethods();
-
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import java.util.Collection; + +/** + * Coverage data of a single class containing methods. The name of this node is + * the fully qualified class name in VM notation (slash separated). + * + * @see IMethodCoverage + */ +public interface IClassCoverage extends ISourceNode { + + /** + * Returns the identifier for this class which is the CRC64 signature of the + * class definition. + * + * @return class identifier + */ + public long getId(); + + /** + * Returns the VM signature of the class. + * + * @return VM signature of the class (may be <code>null</code>) + */ + public String getSignature(); + + /** + * Returns the VM name of the superclass. + * + * @return VM name of the super class (may be <code>null</code>, i.e. + * <code>java/lang/Object</code>) + */ + public String getSuperName(); + + /** + * Returns the VM names of implemented/extended interfaces + * + * @return VM names of implemented/extended interfaces + */ + public String[] getInterfaceNames(); + + /** + * Returns the VM name of the package this class belongs to. + * + * @return VM name of the package + */ + public String getPackageName(); + + /** + * Returns the optional name of the corresponding source file. + * + * @return name of the corresponding source file + */ + public String getSourceFileName(); + + /** + * Returns the methods included in this class. + * + * @return methods of this class + */ + public Collection<IMethodCoverage> getMethods(); + }
\ No newline at end of file diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/ICounter.java b/org.jacoco.core/src/org/jacoco/core/analysis/ICounter.java index 41c7f893..e2135f5a 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/ICounter.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/ICounter.java @@ -1,89 +1,89 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-/**
- * A counter holds the missed and the covered number of particular items like
- * classes, methods, branches or instructions.
- */
-public interface ICounter {
-
- /**
- * Status flag for no items (value is 0x00).
- */
- public static final int EMPTY = 0x00;
-
- /**
- * Status flag when all items are not covered (value is 0x01).
- */
- public static final int NOT_COVERED = 0x01;
-
- /**
- * Status flag when all items are covered (value is 0x02).
- */
- public static final int FULLY_COVERED = 0x02;
-
- /**
- * Status flag when items are partly covered (value is 0x03).
- */
- public static final int PARTLY_COVERED = NOT_COVERED | FULLY_COVERED;
-
- /**
- * Returns the total count of items.
- *
- * @return total count of items
- */
- public int getTotalCount();
-
- /**
- * Returns the count of covered items.
- *
- * @return count of covered items
- */
- public int getCoveredCount();
-
- /**
- * Returns the count of missed items.
- *
- * @return count of missed items
- */
- public int getMissedCount();
-
- /**
- * Calculates the ratio of covered to total count items. If total count
- * items is 0 this method returns NaN.
- *
- * @return ratio of covered to total count items
- */
- public double getCoveredRatio();
-
- /**
- * Calculates the ratio of missed to total count items. If total count items
- * is 0 this method returns NaN.
- *
- * @return ratio of missed to total count items
- */
- public double getMissedRatio();
-
- /**
- * Returns the coverage status of this counter.
- *
- * @see ICounter#EMPTY
- * @see ICounter#NOT_COVERED
- * @see ICounter#PARTLY_COVERED
- * @see ICounter#FULLY_COVERED
- *
- * @return status of this line
- */
- public int getStatus();
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +/** + * A counter holds the missed and the covered number of particular items like + * classes, methods, branches or instructions. + */ +public interface ICounter { + + /** + * Status flag for no items (value is 0x00). + */ + public static final int EMPTY = 0x00; + + /** + * Status flag when all items are not covered (value is 0x01). + */ + public static final int NOT_COVERED = 0x01; + + /** + * Status flag when all items are covered (value is 0x02). + */ + public static final int FULLY_COVERED = 0x02; + + /** + * Status flag when items are partly covered (value is 0x03). + */ + public static final int PARTLY_COVERED = NOT_COVERED | FULLY_COVERED; + + /** + * Returns the total count of items. + * + * @return total count of items + */ + public int getTotalCount(); + + /** + * Returns the count of covered items. + * + * @return count of covered items + */ + public int getCoveredCount(); + + /** + * Returns the count of missed items. + * + * @return count of missed items + */ + public int getMissedCount(); + + /** + * Calculates the ratio of covered to total count items. If total count + * items is 0 this method returns NaN. + * + * @return ratio of covered to total count items + */ + public double getCoveredRatio(); + + /** + * Calculates the ratio of missed to total count items. If total count items + * is 0 this method returns NaN. + * + * @return ratio of missed to total count items + */ + public double getMissedRatio(); + + /** + * Returns the coverage status of this counter. + * + * @see ICounter#EMPTY + * @see ICounter#NOT_COVERED + * @see ICounter#PARTLY_COVERED + * @see ICounter#FULLY_COVERED + * + * @return status of this line + */ + public int getStatus(); + +} diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/ICoverageNode.java b/org.jacoco.core/src/org/jacoco/core/analysis/ICoverageNode.java index ab500c27..71ab908e 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/ICoverageNode.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/ICoverageNode.java @@ -1,144 +1,144 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-/**
- * Interface for hierarchical coverage data nodes with different coverage
- * counters.
- */
-public interface ICoverageNode {
-
- /**
- * Type of a Java element represented by a {@link ICoverageNode} instance.
- */
- public enum ElementType {
-
- /** Method */
- METHOD,
-
- /** Class */
- CLASS,
-
- /** Source File */
- SOURCEFILE,
-
- /** Java Package */
- PACKAGE,
-
- /** Bundle of Packages */
- BUNDLE,
-
- /** Logical Group of Bundles */
- GROUP,
-
- }
-
- /**
- * Different counter types supported by JaCoCo.
- */
- public enum CounterEntity {
-
- /** Counter for instructions */
- INSTRUCTION,
-
- /** Counter for branches */
- BRANCH,
-
- /** Counter for source lines */
- LINE,
-
- /** Counter for cyclomatic complexity */
- COMPLEXITY,
-
- /** Counter for methods */
- METHOD,
-
- /** Counter for classes */
- CLASS
- }
-
- /**
- * Returns the type of element represented by this node.
- *
- * @return type of this node
- */
- public abstract ElementType getElementType();
-
- /**
- * Returns the name of this node.
- *
- * @return name of this node
- */
- public String getName();
-
- /**
- * Returns the counter for byte code instructions.
- *
- * @return counter for instructions
- */
- public abstract ICounter getInstructionCounter();
-
- /**
- * Returns the counter for branches.
- *
- * @return counter for branches
- */
- public ICounter getBranchCounter();
-
- /**
- * Returns the counter for lines.
- *
- * @return counter for lines
- */
- public ICounter getLineCounter();
-
- /**
- * Returns the counter for cyclomatic complexity.
- *
- * @return counter for complexity
- */
- public ICounter getComplexityCounter();
-
- /**
- * Returns the counter for methods.
- *
- * @return counter for methods
- */
- public ICounter getMethodCounter();
-
- /**
- * Returns the counter for classes.
- *
- * @return counter for classes
- */
- public ICounter getClassCounter();
-
- /**
- * Generic access to the the counters.
- *
- * @param entity
- * entity we're we want to have the counter for
- * @return counter for the given entity
- */
- public ICounter getCounter(CounterEntity entity);
-
- /**
- * Creates a plain copy of this node. While {@link ICoverageNode}
- * implementations may contain heavy data structures, the copy returned by
- * this method is reduced to the counters only. This helps to save memory
- * while processing huge structures.
- *
- * @return copy with counters only
- */
- public ICoverageNode getPlainCopy();
-
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +/** + * Interface for hierarchical coverage data nodes with different coverage + * counters. + */ +public interface ICoverageNode { + + /** + * Type of a Java element represented by a {@link ICoverageNode} instance. + */ + public enum ElementType { + + /** Method */ + METHOD, + + /** Class */ + CLASS, + + /** Source File */ + SOURCEFILE, + + /** Java Package */ + PACKAGE, + + /** Bundle of Packages */ + BUNDLE, + + /** Logical Group of Bundles */ + GROUP, + + } + + /** + * Different counter types supported by JaCoCo. + */ + public enum CounterEntity { + + /** Counter for instructions */ + INSTRUCTION, + + /** Counter for branches */ + BRANCH, + + /** Counter for source lines */ + LINE, + + /** Counter for cyclomatic complexity */ + COMPLEXITY, + + /** Counter for methods */ + METHOD, + + /** Counter for classes */ + CLASS + } + + /** + * Returns the type of element represented by this node. + * + * @return type of this node + */ + public abstract ElementType getElementType(); + + /** + * Returns the name of this node. + * + * @return name of this node + */ + public String getName(); + + /** + * Returns the counter for byte code instructions. + * + * @return counter for instructions + */ + public abstract ICounter getInstructionCounter(); + + /** + * Returns the counter for branches. + * + * @return counter for branches + */ + public ICounter getBranchCounter(); + + /** + * Returns the counter for lines. + * + * @return counter for lines + */ + public ICounter getLineCounter(); + + /** + * Returns the counter for cyclomatic complexity. + * + * @return counter for complexity + */ + public ICounter getComplexityCounter(); + + /** + * Returns the counter for methods. + * + * @return counter for methods + */ + public ICounter getMethodCounter(); + + /** + * Returns the counter for classes. + * + * @return counter for classes + */ + public ICounter getClassCounter(); + + /** + * Generic access to the the counters. + * + * @param entity + * entity we're we want to have the counter for + * @return counter for the given entity + */ + public ICounter getCounter(CounterEntity entity); + + /** + * Creates a plain copy of this node. While {@link ICoverageNode} + * implementations may contain heavy data structures, the copy returned by + * this method is reduced to the counters only. This helps to save memory + * while processing huge structures. + * + * @return copy with counters only + */ + public ICoverageNode getPlainCopy(); + }
\ No newline at end of file diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/ICoverageVisitor.java b/org.jacoco.core/src/org/jacoco/core/analysis/ICoverageVisitor.java index 94a4ee5b..f21ad4db 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/ICoverageVisitor.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/ICoverageVisitor.java @@ -1,28 +1,28 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-/**
- * Interface for coverage data output as a stream of {@link IClassCoverage}
- * instances.
- */
-public interface ICoverageVisitor {
-
- /**
- * For analyzed class coverage data is emitted to this method.
- *
- * @param coverage
- * coverage data for a class
- */
- public void visitCoverage(IClassCoverage coverage);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +/** + * Interface for coverage data output as a stream of {@link IClassCoverage} + * instances. + */ +public interface ICoverageVisitor { + + /** + * For analyzed class coverage data is emitted to this method. + * + * @param coverage + * coverage data for a class + */ + public void visitCoverage(IClassCoverage coverage); + +} diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/ILine.java b/org.jacoco.core/src/org/jacoco/core/analysis/ILine.java index 1c4b6893..a384cd39 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/ILine.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/ILine.java @@ -1,47 +1,47 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-/**
- * The instruction and branch coverage of a single source line is described by
- * this interface.
- */
-public interface ILine {
-
- /**
- * Returns the instruction counter for this line.
- *
- * @return instruction counter
- */
- public ICounter getInstructionCounter();
-
- /**
- * Returns the branches counter for this line.
- *
- * @return branches counter
- */
- public ICounter getBranchCounter();
-
- /**
- * Returns the coverage status of this line, calculated from the
- * instructions counter and branch counter.
- *
- * @see ICounter#EMPTY
- * @see ICounter#NOT_COVERED
- * @see ICounter#PARTLY_COVERED
- * @see ICounter#FULLY_COVERED
- *
- * @return status of this line
- */
- public int getStatus();
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +/** + * The instruction and branch coverage of a single source line is described by + * this interface. + */ +public interface ILine { + + /** + * Returns the instruction counter for this line. + * + * @return instruction counter + */ + public ICounter getInstructionCounter(); + + /** + * Returns the branches counter for this line. + * + * @return branches counter + */ + public ICounter getBranchCounter(); + + /** + * Returns the coverage status of this line, calculated from the + * instructions counter and branch counter. + * + * @see ICounter#EMPTY + * @see ICounter#NOT_COVERED + * @see ICounter#PARTLY_COVERED + * @see ICounter#FULLY_COVERED + * + * @return status of this line + */ + public int getStatus(); + +} diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/IMethodCoverage.java b/org.jacoco.core/src/org/jacoco/core/analysis/IMethodCoverage.java index 0aae064a..40a4eec5 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/IMethodCoverage.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/IMethodCoverage.java @@ -1,34 +1,34 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-/**
- * Coverage data of a single method. The name of this node is the local method
- * name.
- */
-public interface IMethodCoverage extends ISourceNode {
-
- /**
- * Returns the parameter description of the method.
- *
- * @return parameter description
- */
- public String getDesc();
-
- /**
- * Returns the generic signature of the method if defined.
- *
- * @return generic signature or <code>null</code>
- */
- public String getSignature();
-
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +/** + * Coverage data of a single method. The name of this node is the local method + * name. + */ +public interface IMethodCoverage extends ISourceNode { + + /** + * Returns the parameter description of the method. + * + * @return parameter description + */ + public String getDesc(); + + /** + * Returns the generic signature of the method if defined. + * + * @return generic signature or <code>null</code> + */ + public String getSignature(); + }
\ No newline at end of file diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/IPackageCoverage.java b/org.jacoco.core/src/org/jacoco/core/analysis/IPackageCoverage.java index 9edcda63..0a889761 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/IPackageCoverage.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/IPackageCoverage.java @@ -1,40 +1,40 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import java.util.Collection;
-
-/**
- * Coverage data of a Java package containing classes and source files. The name
- * of this node is the package name in VM notation (slash separated). The name
- * of the default package is the empty string.
- *
- * @see IClassCoverage
- * @see ISourceFileCoverage
- */
-public interface IPackageCoverage extends ICoverageNode {
-
- /**
- * Returns all classes contained in this package.
- *
- * @return all classes
- */
- public Collection<IClassCoverage> getClasses();
-
- /**
- * Returns all source files in this package.
- *
- * @return all source files
- */
- public Collection<ISourceFileCoverage> getSourceFiles();
-
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import java.util.Collection; + +/** + * Coverage data of a Java package containing classes and source files. The name + * of this node is the package name in VM notation (slash separated). The name + * of the default package is the empty string. + * + * @see IClassCoverage + * @see ISourceFileCoverage + */ +public interface IPackageCoverage extends ICoverageNode { + + /** + * Returns all classes contained in this package. + * + * @return all classes + */ + public Collection<IClassCoverage> getClasses(); + + /** + * Returns all source files in this package. + * + * @return all source files + */ + public Collection<ISourceFileCoverage> getSourceFiles(); + }
\ No newline at end of file diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/ISourceFileCoverage.java b/org.jacoco.core/src/org/jacoco/core/analysis/ISourceFileCoverage.java index 7e9475dc..e3b079e7 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/ISourceFileCoverage.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/ISourceFileCoverage.java @@ -1,27 +1,27 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-/**
- * Coverage data of a single source file. The name of this node is the local
- * name of the source file.
- */
-public interface ISourceFileCoverage extends ISourceNode {
-
- /**
- * Returns the VM name of the package the source file belongs to.
- *
- * @return package name
- */
- public String getPackageName();
-
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +/** + * Coverage data of a single source file. The name of this node is the local + * name of the source file. + */ +public interface ISourceFileCoverage extends ISourceNode { + + /** + * Returns the VM name of the package the source file belongs to. + * + * @return package name + */ + public String getPackageName(); + }
\ No newline at end of file diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java b/org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java index bd979906..eda6cc0d 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/ISourceNode.java @@ -1,48 +1,48 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-/**
- * Interface for coverage nodes that have individual source lines like methods,
- * classes and source files.
- */
-public interface ISourceNode extends ICoverageNode {
-
- /** Place holder for unknown lines (no debug information) */
- public static int UNKNOWN_LINE = -1;
-
- /**
- * The number of the first line coverage information is available for. If no
- * line is contained, the method returns -1.
- *
- * @return number of the first line or {@link #UNKNOWN_LINE}
- */
- public int getFirstLine();
-
- /**
- * The number of the last line coverage information is available for. If no
- * line is contained, the method returns -1.
- *
- * @return number of the last line or {@link #UNKNOWN_LINE}
- */
- public int getLastLine();
-
- /**
- * Returns the line information for given line.
- *
- * @param nr
- * line number of interest
- * @return line information
- */
- public ILine getLine(int nr);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +/** + * Interface for coverage nodes that have individual source lines like methods, + * classes and source files. + */ +public interface ISourceNode extends ICoverageNode { + + /** Place holder for unknown lines (no debug information) */ + public static int UNKNOWN_LINE = -1; + + /** + * The number of the first line coverage information is available for. If no + * line is contained, the method returns -1. + * + * @return number of the first line or {@link #UNKNOWN_LINE} + */ + public int getFirstLine(); + + /** + * The number of the last line coverage information is available for. If no + * line is contained, the method returns -1. + * + * @return number of the last line or {@link #UNKNOWN_LINE} + */ + public int getLastLine(); + + /** + * Returns the line information for given line. + * + * @param nr + * line number of interest + * @return line information + */ + public ILine getLine(int nr); + +} diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/NodeComparator.java b/org.jacoco.core/src/org/jacoco/core/analysis/NodeComparator.java index 08960a61..2b1169bd 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/NodeComparator.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/NodeComparator.java @@ -1,87 +1,87 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.analysis;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-
-/**
- * Comparator to compare {@link ICoverageNode} objects by different counter
- * criteria.
- *
- * @see CounterComparator#on(ICoverageNode.CounterEntity)
- */
-public class NodeComparator implements Comparator<ICoverageNode>, Serializable {
-
- private static final long serialVersionUID = 8550521643608826519L;
-
- private final Comparator<ICounter> counterComparator;
-
- private final CounterEntity entity;
-
- NodeComparator(final Comparator<ICounter> counterComparator,
- final CounterEntity entity) {
- this.counterComparator = counterComparator;
- this.entity = entity;
- }
-
- /**
- * Creates a new composite comparator with a second search criterion.
- *
- * @param second
- * second criterion comparator
- *
- * @return composite comparator
- */
- public NodeComparator second(final Comparator<ICoverageNode> second) {
- final Comparator<ICoverageNode> first = this;
- return new NodeComparator(null, null) {
-
- private static final long serialVersionUID = -5515272752138802838L;
-
- @Override
- public int compare(final ICoverageNode o1, final ICoverageNode o2) {
- final int result = first.compare(o1, o2);
- return result == 0 ? second.compare(o1, o2) : result;
- }
- };
- }
-
- /**
- * Returns a sorted copy of the given collection of {@link ICoverageNode}
- * elements.
- *
- * @param <T>
- * actual type of the elements
- * @param summaries
- * collection to create a copy of
- * @return sorted copy
- */
- public <T extends ICoverageNode> List<T> sort(final Collection<T> summaries) {
- final List<T> result = new ArrayList<T>(summaries);
- Collections.sort(result, this);
- return result;
- }
-
- public int compare(final ICoverageNode n1, final ICoverageNode n2) {
- final ICounter c1 = n1.getCounter(entity);
- final ICounter c2 = n2.getCounter(entity);
- return counterComparator.compare(c1, c2);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.analysis; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; + +/** + * Comparator to compare {@link ICoverageNode} objects by different counter + * criteria. + * + * @see CounterComparator#on(ICoverageNode.CounterEntity) + */ +public class NodeComparator implements Comparator<ICoverageNode>, Serializable { + + private static final long serialVersionUID = 8550521643608826519L; + + private final Comparator<ICounter> counterComparator; + + private final CounterEntity entity; + + NodeComparator(final Comparator<ICounter> counterComparator, + final CounterEntity entity) { + this.counterComparator = counterComparator; + this.entity = entity; + } + + /** + * Creates a new composite comparator with a second search criterion. + * + * @param second + * second criterion comparator + * + * @return composite comparator + */ + public NodeComparator second(final Comparator<ICoverageNode> second) { + final Comparator<ICoverageNode> first = this; + return new NodeComparator(null, null) { + + private static final long serialVersionUID = -5515272752138802838L; + + @Override + public int compare(final ICoverageNode o1, final ICoverageNode o2) { + final int result = first.compare(o1, o2); + return result == 0 ? second.compare(o1, o2) : result; + } + }; + } + + /** + * Returns a sorted copy of the given collection of {@link ICoverageNode} + * elements. + * + * @param <T> + * actual type of the elements + * @param summaries + * collection to create a copy of + * @return sorted copy + */ + public <T extends ICoverageNode> List<T> sort(final Collection<T> summaries) { + final List<T> result = new ArrayList<T>(summaries); + Collections.sort(result, this); + return result; + } + + public int compare(final ICoverageNode n1, final ICoverageNode n2) { + final ICounter c1 = n1.getCounter(entity); + final ICounter c2 = n2.getCounter(entity); + return counterComparator.compare(c1, c2); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java index 63061e67..90760802 100644 --- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java +++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java @@ -1,157 +1,157 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.data;
-
-import static java.lang.String.format;
-
-import java.util.Arrays;
-
-/**
- * Execution data for a single Java class. While instances are immutable care
- * has to be taken about the probe data array of type <code>boolean[]</code>
- * which can be modified.
- */
-public final class ExecutionData {
-
- private final long id;
-
- private final String name;
-
- private final boolean[] data;
-
- /**
- * Creates a new {@link ExecutionData} object with the given probe data.
- *
- * @param id
- * class identifier
- * @param name
- * VM name
- * @param data
- * probe data
- */
- public ExecutionData(final long id, final String name, final boolean[] data) {
- this.id = id;
- this.name = name;
- this.data = data;
- }
-
- /**
- * Creates a new {@link ExecutionData} object with the given probe data
- * length. All probes are set to <code>false</code>.
- *
- * @param id
- * class identifier
- * @param name
- * VM name
- * @param dataLength
- * probe data length
- */
- public ExecutionData(final long id, final String name, final int dataLength) {
- this.id = id;
- this.name = name;
- this.data = new boolean[dataLength];
- }
-
- /**
- * Return the unique identifier for this class. The identifier is the CRC64
- * checksum of the raw class file definition.
- *
- * @return class identifier
- */
- public long getId() {
- return id;
- }
-
- /**
- * The VM name of the class.
- *
- * @return VM name
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the execution data probes. A value of <code>true</code> indicates
- * that the corresponding probe was executed.
- *
- * @return execution data
- */
- public boolean[] getData() {
- return data;
- }
-
- /**
- * Sets all probe data entries to <code>false</code>.
- */
- public void reset() {
- Arrays.fill(data, false);
- }
-
- /**
- * Merges the given execution data into the probe data of this object. I.e.
- * a probe entry in this object is marked as executed (<code>true</code>) if
- * this probe or the corresponding other probe was executed. The probe array
- * of the other object is not modified.
- *
- * @param other
- */
- public void merge(final ExecutionData other) {
- assertCompatibility(other.getId(), other.getName(),
- other.getData().length);
- final boolean[] otherData = other.getData();
- for (int i = 0; i < data.length; i++) {
- if (otherData[i]) {
- data[i] = true;
- }
- }
- }
-
- /**
- * Asserts that this execution data object is compatible with the given
- * parameters. The purpose of this check is to detect a very unlikely class
- * id collision.
- *
- * @param id
- * other class id, must be the same
- * @param name
- * other name, must be equal to this name
- * @param dataLength
- * probe data length, must be the same as for this data
- * @throws IllegalStateException
- * if the given parameters do not match this instance
- */
- public void assertCompatibility(final long id, final String name,
- final int dataLength) throws IllegalStateException {
- if (this.id != id) {
- throw new IllegalStateException(format(
- "Different ids (%016x and %016x).", Long.valueOf(this.id),
- Long.valueOf(id)));
- }
- if (!this.name.equals(name)) {
- throw new IllegalStateException(format(
- "Different class names %s and %s for id %016x.", this.name,
- name, Long.valueOf(id)));
- }
- if (this.data.length != dataLength) {
- throw new IllegalStateException(format(
- "Incompatible execution data for class %s with id %016x.",
- name, Long.valueOf(id)));
- }
- }
-
- @Override
- public String toString() {
- return String.format("ExecutionData [name=%s, id=%016x]", name,
- Long.valueOf(id));
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.data; + +import static java.lang.String.format; + +import java.util.Arrays; + +/** + * Execution data for a single Java class. While instances are immutable care + * has to be taken about the probe data array of type <code>boolean[]</code> + * which can be modified. + */ +public final class ExecutionData { + + private final long id; + + private final String name; + + private final boolean[] data; + + /** + * Creates a new {@link ExecutionData} object with the given probe data. + * + * @param id + * class identifier + * @param name + * VM name + * @param data + * probe data + */ + public ExecutionData(final long id, final String name, final boolean[] data) { + this.id = id; + this.name = name; + this.data = data; + } + + /** + * Creates a new {@link ExecutionData} object with the given probe data + * length. All probes are set to <code>false</code>. + * + * @param id + * class identifier + * @param name + * VM name + * @param dataLength + * probe data length + */ + public ExecutionData(final long id, final String name, final int dataLength) { + this.id = id; + this.name = name; + this.data = new boolean[dataLength]; + } + + /** + * Return the unique identifier for this class. The identifier is the CRC64 + * checksum of the raw class file definition. + * + * @return class identifier + */ + public long getId() { + return id; + } + + /** + * The VM name of the class. + * + * @return VM name + */ + public String getName() { + return name; + } + + /** + * Returns the execution data probes. A value of <code>true</code> indicates + * that the corresponding probe was executed. + * + * @return execution data + */ + public boolean[] getData() { + return data; + } + + /** + * Sets all probe data entries to <code>false</code>. + */ + public void reset() { + Arrays.fill(data, false); + } + + /** + * Merges the given execution data into the probe data of this object. I.e. + * a probe entry in this object is marked as executed (<code>true</code>) if + * this probe or the corresponding other probe was executed. The probe array + * of the other object is not modified. + * + * @param other + */ + public void merge(final ExecutionData other) { + assertCompatibility(other.getId(), other.getName(), + other.getData().length); + final boolean[] otherData = other.getData(); + for (int i = 0; i < data.length; i++) { + if (otherData[i]) { + data[i] = true; + } + } + } + + /** + * Asserts that this execution data object is compatible with the given + * parameters. The purpose of this check is to detect a very unlikely class + * id collision. + * + * @param id + * other class id, must be the same + * @param name + * other name, must be equal to this name + * @param dataLength + * probe data length, must be the same as for this data + * @throws IllegalStateException + * if the given parameters do not match this instance + */ + public void assertCompatibility(final long id, final String name, + final int dataLength) throws IllegalStateException { + if (this.id != id) { + throw new IllegalStateException(format( + "Different ids (%016x and %016x).", Long.valueOf(this.id), + Long.valueOf(id))); + } + if (!this.name.equals(name)) { + throw new IllegalStateException(format( + "Different class names %s and %s for id %016x.", this.name, + name, Long.valueOf(id))); + } + if (this.data.length != dataLength) { + throw new IllegalStateException(format( + "Incompatible execution data for class %s with id %016x.", + name, Long.valueOf(id))); + } + } + + @Override + public String toString() { + return String.format("ExecutionData [name=%s, id=%016x]", name, + Long.valueOf(id)); + } +} diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataReader.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataReader.java index ba24fd4d..ba74db4b 100644 --- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataReader.java +++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataReader.java @@ -1,151 +1,151 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.data;
-
-import static java.lang.String.format;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.jacoco.core.internal.data.CompactDataInput;
-
-/**
- * Deserialization of execution data from binary streams.
- */
-public class ExecutionDataReader {
-
- /** Underlying data input */
- protected final CompactDataInput in;
-
- private ISessionInfoVisitor sessionInfoVisitor = null;
-
- private IExecutionDataVisitor executionDataVisitor = null;
-
- private boolean firstBlock = true;
-
- /**
- * Creates a new reader based on the given input stream input. Depending on
- * the nature of the underlying stream input should be buffered as most data
- * is read in single bytes.
- *
- * @param input
- * input stream to read execution data from
- */
- public ExecutionDataReader(final InputStream input) {
- this.in = new CompactDataInput(input);
- }
-
- /**
- * Sets an listener for session information.
- *
- * @param visitor
- */
- public void setSessionInfoVisitor(final ISessionInfoVisitor visitor) {
- this.sessionInfoVisitor = visitor;
- }
-
- /**
- * Sets an listener for execution data.
- *
- * @param visitor
- */
- public void setExecutionDataVisitor(final IExecutionDataVisitor visitor) {
- this.executionDataVisitor = visitor;
- }
-
- /**
- * Reads all data and reports it to the corresponding visitors. The stream
- * is read until its end or a command confirmation has been sent.
- *
- * @return <code>true</code> if additional data can be expected after a
- * command has been executed. <code>false</code> if the end of the
- * stream has been reached.
- * @throws IOException
- * might be thrown by the underlying input stream
- */
- public boolean read() throws IOException {
- try {
- byte type;
- do {
- type = in.readByte();
- if (firstBlock && type != ExecutionDataWriter.BLOCK_HEADER) {
- throw new IOException("Invalid execution data file.");
- }
- firstBlock = false;
- } while (readBlock(type));
- return true;
- } catch (final EOFException e) {
- return false;
- }
- }
-
- /**
- * Reads a block of data identified by the given id. Subclasses may
- * overwrite this method to support additional block types.
- *
- * @param blocktype
- * block type
- * @return <code>true</code> if there are more blocks to read
- * @throws IOException
- * might be thrown by the underlying input stream
- */
- protected boolean readBlock(final byte blocktype) throws IOException {
- switch (blocktype) {
- case ExecutionDataWriter.BLOCK_HEADER:
- readHeader();
- return true;
- case ExecutionDataWriter.BLOCK_SESSIONINFO:
- readSessionInfo();
- return true;
- case ExecutionDataWriter.BLOCK_EXECUTIONDATA:
- readExecutionData();
- return true;
- default:
- throw new IOException(format("Unknown block type %x.",
- Byte.valueOf(blocktype)));
- }
- }
-
- private void readHeader() throws IOException {
- if (in.readChar() != ExecutionDataWriter.MAGIC_NUMBER) {
- throw new IOException("Invalid execution data file.");
- }
- final char version = in.readChar();
- if (version != ExecutionDataWriter.FORMAT_VERSION) {
- throw new IOException(format("Incompatible version %x.",
- Integer.valueOf(version)));
- }
- }
-
- private void readSessionInfo() throws IOException {
- if (sessionInfoVisitor == null) {
- throw new IOException("No session info visitor.");
- }
- final String id = in.readUTF();
- final long start = in.readLong();
- final long dump = in.readLong();
- sessionInfoVisitor.visitSessionInfo(new SessionInfo(id, start, dump));
- }
-
- private void readExecutionData() throws IOException {
- if (executionDataVisitor == null) {
- throw new IOException("No execution data visitor.");
- }
- final long id = in.readLong();
- final String name = in.readUTF();
- final boolean[] data = in.readBooleanArray();
- executionDataVisitor.visitClassExecution(new ExecutionData(id, name,
- data));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.data; + +import static java.lang.String.format; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; + +import org.jacoco.core.internal.data.CompactDataInput; + +/** + * Deserialization of execution data from binary streams. + */ +public class ExecutionDataReader { + + /** Underlying data input */ + protected final CompactDataInput in; + + private ISessionInfoVisitor sessionInfoVisitor = null; + + private IExecutionDataVisitor executionDataVisitor = null; + + private boolean firstBlock = true; + + /** + * Creates a new reader based on the given input stream input. Depending on + * the nature of the underlying stream input should be buffered as most data + * is read in single bytes. + * + * @param input + * input stream to read execution data from + */ + public ExecutionDataReader(final InputStream input) { + this.in = new CompactDataInput(input); + } + + /** + * Sets an listener for session information. + * + * @param visitor + */ + public void setSessionInfoVisitor(final ISessionInfoVisitor visitor) { + this.sessionInfoVisitor = visitor; + } + + /** + * Sets an listener for execution data. + * + * @param visitor + */ + public void setExecutionDataVisitor(final IExecutionDataVisitor visitor) { + this.executionDataVisitor = visitor; + } + + /** + * Reads all data and reports it to the corresponding visitors. The stream + * is read until its end or a command confirmation has been sent. + * + * @return <code>true</code> if additional data can be expected after a + * command has been executed. <code>false</code> if the end of the + * stream has been reached. + * @throws IOException + * might be thrown by the underlying input stream + */ + public boolean read() throws IOException { + try { + byte type; + do { + type = in.readByte(); + if (firstBlock && type != ExecutionDataWriter.BLOCK_HEADER) { + throw new IOException("Invalid execution data file."); + } + firstBlock = false; + } while (readBlock(type)); + return true; + } catch (final EOFException e) { + return false; + } + } + + /** + * Reads a block of data identified by the given id. Subclasses may + * overwrite this method to support additional block types. + * + * @param blocktype + * block type + * @return <code>true</code> if there are more blocks to read + * @throws IOException + * might be thrown by the underlying input stream + */ + protected boolean readBlock(final byte blocktype) throws IOException { + switch (blocktype) { + case ExecutionDataWriter.BLOCK_HEADER: + readHeader(); + return true; + case ExecutionDataWriter.BLOCK_SESSIONINFO: + readSessionInfo(); + return true; + case ExecutionDataWriter.BLOCK_EXECUTIONDATA: + readExecutionData(); + return true; + default: + throw new IOException(format("Unknown block type %x.", + Byte.valueOf(blocktype))); + } + } + + private void readHeader() throws IOException { + if (in.readChar() != ExecutionDataWriter.MAGIC_NUMBER) { + throw new IOException("Invalid execution data file."); + } + final char version = in.readChar(); + if (version != ExecutionDataWriter.FORMAT_VERSION) { + throw new IOException(format("Incompatible version %x.", + Integer.valueOf(version))); + } + } + + private void readSessionInfo() throws IOException { + if (sessionInfoVisitor == null) { + throw new IOException("No session info visitor."); + } + final String id = in.readUTF(); + final long start = in.readLong(); + final long dump = in.readLong(); + sessionInfoVisitor.visitSessionInfo(new SessionInfo(id, start, dump)); + } + + private void readExecutionData() throws IOException { + if (executionDataVisitor == null) { + throw new IOException("No execution data visitor."); + } + final long id = in.readLong(); + final String name = in.readUTF(); + final boolean[] data = in.readBooleanArray(); + executionDataVisitor.visitClassExecution(new ExecutionData(id, name, + data)); + } + +} 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 9ee1c28f..88b19cf0 100644 --- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java +++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java @@ -1,124 +1,124 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.data;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * In-memory data store for execution data. The data can be added through its
- * {@link IExecutionDataVisitor} interface. If execution data is provided
- * multiple times for the same class the data is merged, i.e. a probe is marked
- * as executed if it is reported as executed at least once. This allows to merge
- * coverage date from multiple runs. A instance of this class is not thread
- * safe.
- */
-public final class ExecutionDataStore implements IExecutionDataVisitor {
-
- private final Map<Long, ExecutionData> entries = new HashMap<Long, ExecutionData>();
-
- /**
- * Adds the given {@link ExecutionData} object into the store. If there is
- * already execution data with this same class id, this structure is merged
- * with the given one.
- *
- * @param data
- * execution data to add or merge
- * @throws IllegalStateException
- * if the given {@link ExecutionData} object is not compatible
- * to a corresponding one, that is already contained
- * @see ExecutionData#assertCompatibility(long, String, int)
- */
- public void put(final ExecutionData data) throws IllegalStateException {
- final Long id = Long.valueOf(data.getId());
- final ExecutionData entry = entries.get(id);
- if (entry == null) {
- entries.put(id, data);
- } else {
- entry.merge(data);
- }
- }
-
- /**
- * Returns the {@link ExecutionData} entry with the given id if it exists in
- * this store.
- *
- * @param id
- * class id
- * @return execution data or <code>null</code>
- */
- public ExecutionData get(final long id) {
- return entries.get(Long.valueOf(id));
- }
-
- /**
- * 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.
- *
- * @param id
- * class identifier
- * @param name
- * VM name of the class
- * @param dataLength
- * probe data length
- * @return execution data
- */
- public ExecutionData get(final Long id, final String name,
- final int dataLength) {
- ExecutionData entry = entries.get(id);
- if (entry == null) {
- entry = new ExecutionData(id.longValue(), name, dataLength);
- entries.put(id, entry);
- } else {
- entry.assertCompatibility(id.longValue(), name, dataLength);
- }
- return entry;
- }
-
- /**
- * Resets all execution data probes, i.e. marks them as not executed. The
- * execution data objects itself are not removed.
- */
- public void reset() {
- for (final ExecutionData executionData : this.entries.values()) {
- executionData.reset();
- }
- }
-
- /**
- * Returns a collection that represents current contents of the store.
- *
- * @return current contents
- */
- public Collection<ExecutionData> getContents() {
- return entries.values();
- }
-
- /**
- * Writes the content of the store to the given visitor interface.
- *
- * @param visitor
- * interface to write content to
- */
- public void accept(final IExecutionDataVisitor visitor) {
- for (final ExecutionData data : entries.values()) {
- visitor.visitClassExecution(data);
- }
- }
-
- // === IExecutionDataVisitor ===
-
- public void visitClassExecution(final ExecutionData data) {
- put(data);
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.data; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * In-memory data store for execution data. The data can be added through its + * {@link IExecutionDataVisitor} interface. If execution data is provided + * multiple times for the same class the data is merged, i.e. a probe is marked + * as executed if it is reported as executed at least once. This allows to merge + * coverage date from multiple runs. A instance of this class is not thread + * safe. + */ +public final class ExecutionDataStore implements IExecutionDataVisitor { + + private final Map<Long, ExecutionData> entries = new HashMap<Long, ExecutionData>(); + + /** + * Adds the given {@link ExecutionData} object into the store. If there is + * already execution data with this same class id, this structure is merged + * with the given one. + * + * @param data + * execution data to add or merge + * @throws IllegalStateException + * if the given {@link ExecutionData} object is not compatible + * to a corresponding one, that is already contained + * @see ExecutionData#assertCompatibility(long, String, int) + */ + public void put(final ExecutionData data) throws IllegalStateException { + final Long id = Long.valueOf(data.getId()); + final ExecutionData entry = entries.get(id); + if (entry == null) { + entries.put(id, data); + } else { + entry.merge(data); + } + } + + /** + * Returns the {@link ExecutionData} entry with the given id if it exists in + * this store. + * + * @param id + * class id + * @return execution data or <code>null</code> + */ + public ExecutionData get(final long id) { + return entries.get(Long.valueOf(id)); + } + + /** + * 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. + * + * @param id + * class identifier + * @param name + * VM name of the class + * @param dataLength + * probe data length + * @return execution data + */ + public ExecutionData get(final Long id, final String name, + final int dataLength) { + ExecutionData entry = entries.get(id); + if (entry == null) { + entry = new ExecutionData(id.longValue(), name, dataLength); + entries.put(id, entry); + } else { + entry.assertCompatibility(id.longValue(), name, dataLength); + } + return entry; + } + + /** + * Resets all execution data probes, i.e. marks them as not executed. The + * execution data objects itself are not removed. + */ + public void reset() { + for (final ExecutionData executionData : this.entries.values()) { + executionData.reset(); + } + } + + /** + * Returns a collection that represents current contents of the store. + * + * @return current contents + */ + public Collection<ExecutionData> getContents() { + return entries.values(); + } + + /** + * Writes the content of the store to the given visitor interface. + * + * @param visitor + * interface to write content to + */ + public void accept(final IExecutionDataVisitor visitor) { + for (final ExecutionData data : entries.values()) { + visitor.visitClassExecution(data); + } + } + + // === IExecutionDataVisitor === + + public void visitClassExecution(final ExecutionData data) { + put(data); + } +} diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataWriter.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataWriter.java index 2f42068e..33d8f627 100644 --- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataWriter.java +++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataWriter.java @@ -1,119 +1,119 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.data;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.jacoco.core.internal.data.CompactDataOutput;
-
-/**
- * Serialization of execution data into binary streams.
- */
-public class ExecutionDataWriter implements ISessionInfoVisitor,
- IExecutionDataVisitor {
-
- /** File format version, will be incremented for each incompatible change. */
- public static final char FORMAT_VERSION = 0x1006;
-
- /** Magic number in header for file format identification. */
- public static final char MAGIC_NUMBER = 0xC0C0;
-
- /** Block identifier for file headers. */
- public static final byte BLOCK_HEADER = 0x01;
-
- /** Block identifier for session information. */
- public static final byte BLOCK_SESSIONINFO = 0x10;
-
- /** Block identifier for execution data of a single class. */
- public static final byte BLOCK_EXECUTIONDATA = 0x11;
-
- /** Underlying data output */
- protected final CompactDataOutput out;
-
- /**
- * Creates a new writer based on the given output stream. Depending on the
- * nature of the underlying stream output should be buffered as most data is
- * written in single bytes.
- *
- * @param output
- * binary stream to write execution data to
- * @throws IOException
- * if the header can't be written
- */
- public ExecutionDataWriter(final OutputStream output) throws IOException {
- this.out = new CompactDataOutput(output);
- writeHeader();
- }
-
- /**
- * Writes an file header to identify the stream and its protocol version.
- *
- * @throws IOException
- */
- private void writeHeader() throws IOException {
- out.writeByte(BLOCK_HEADER);
- out.writeChar(MAGIC_NUMBER);
- out.writeChar(FORMAT_VERSION);
- }
-
- /**
- * Flushes the underlying stream.
- *
- * @throws IOException
- */
- public void flush() throws IOException {
- out.flush();
- }
-
- public void visitSessionInfo(final SessionInfo info) {
- try {
- out.writeByte(BLOCK_SESSIONINFO);
- out.writeUTF(info.getId());
- out.writeLong(info.getStartTimeStamp());
- out.writeLong(info.getDumpTimeStamp());
- } catch (final IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- public void visitClassExecution(final ExecutionData data) {
- try {
- out.writeByte(BLOCK_EXECUTIONDATA);
- out.writeLong(data.getId());
- out.writeUTF(data.getName());
- out.writeBooleanArray(data.getData());
- } catch (final IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Returns the first bytes of a file that represents a valid execution data
- * file. In any case every execution data file starts with the three bytes
- * <code>0x01 0xC0 0xC0</code>.
- *
- * @return first bytes of a execution data file
- */
- public static final byte[] getFileHeader() {
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- try {
- new ExecutionDataWriter(buffer);
- } catch (final IOException e) {
- // Must not happen with ByteArrayOutputStream
- throw new AssertionError(e);
- }
- return buffer.toByteArray();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.data; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.jacoco.core.internal.data.CompactDataOutput; + +/** + * Serialization of execution data into binary streams. + */ +public class ExecutionDataWriter implements ISessionInfoVisitor, + IExecutionDataVisitor { + + /** File format version, will be incremented for each incompatible change. */ + public static final char FORMAT_VERSION = 0x1006; + + /** Magic number in header for file format identification. */ + public static final char MAGIC_NUMBER = 0xC0C0; + + /** Block identifier for file headers. */ + public static final byte BLOCK_HEADER = 0x01; + + /** Block identifier for session information. */ + public static final byte BLOCK_SESSIONINFO = 0x10; + + /** Block identifier for execution data of a single class. */ + public static final byte BLOCK_EXECUTIONDATA = 0x11; + + /** Underlying data output */ + protected final CompactDataOutput out; + + /** + * Creates a new writer based on the given output stream. Depending on the + * nature of the underlying stream output should be buffered as most data is + * written in single bytes. + * + * @param output + * binary stream to write execution data to + * @throws IOException + * if the header can't be written + */ + public ExecutionDataWriter(final OutputStream output) throws IOException { + this.out = new CompactDataOutput(output); + writeHeader(); + } + + /** + * Writes an file header to identify the stream and its protocol version. + * + * @throws IOException + */ + private void writeHeader() throws IOException { + out.writeByte(BLOCK_HEADER); + out.writeChar(MAGIC_NUMBER); + out.writeChar(FORMAT_VERSION); + } + + /** + * Flushes the underlying stream. + * + * @throws IOException + */ + public void flush() throws IOException { + out.flush(); + } + + public void visitSessionInfo(final SessionInfo info) { + try { + out.writeByte(BLOCK_SESSIONINFO); + out.writeUTF(info.getId()); + out.writeLong(info.getStartTimeStamp()); + out.writeLong(info.getDumpTimeStamp()); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } + + public void visitClassExecution(final ExecutionData data) { + try { + out.writeByte(BLOCK_EXECUTIONDATA); + out.writeLong(data.getId()); + out.writeUTF(data.getName()); + out.writeBooleanArray(data.getData()); + } catch (final IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Returns the first bytes of a file that represents a valid execution data + * file. In any case every execution data file starts with the three bytes + * <code>0x01 0xC0 0xC0</code>. + * + * @return first bytes of a execution data file + */ + public static final byte[] getFileHeader() { + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + try { + new ExecutionDataWriter(buffer); + } catch (final IOException e) { + // Must not happen with ByteArrayOutputStream + throw new AssertionError(e); + } + return buffer.toByteArray(); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/data/IExecutionDataVisitor.java b/org.jacoco.core/src/org/jacoco/core/data/IExecutionDataVisitor.java index 15d1578c..94c5f0fb 100644 --- a/org.jacoco.core/src/org/jacoco/core/data/IExecutionDataVisitor.java +++ b/org.jacoco.core/src/org/jacoco/core/data/IExecutionDataVisitor.java @@ -1,29 +1,29 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.data;
-
-/**
- * Interface for data output of collected execution data. This interface is
- * meant to be implemented by parties that want to retrieve data from the
- * coverage runtime.
- */
-public interface IExecutionDataVisitor {
-
- /**
- * Provides execution data for a class.
- *
- * @param data
- * execution data for a class
- */
- public void visitClassExecution(ExecutionData data);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.data; + +/** + * Interface for data output of collected execution data. This interface is + * meant to be implemented by parties that want to retrieve data from the + * coverage runtime. + */ +public interface IExecutionDataVisitor { + + /** + * Provides execution data for a class. + * + * @param data + * execution data for a class + */ + public void visitClassExecution(ExecutionData data); + +} diff --git a/org.jacoco.core/src/org/jacoco/core/data/SessionInfo.java b/org.jacoco.core/src/org/jacoco/core/data/SessionInfo.java index 10157348..35cf1c90 100644 --- a/org.jacoco.core/src/org/jacoco/core/data/SessionInfo.java +++ b/org.jacoco.core/src/org/jacoco/core/data/SessionInfo.java @@ -1,83 +1,83 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.data;
-
-/**
- * Data object describing a session which was the source of execution data.
- * {@link SessionInfo} instances can be sorted by dump date through the
- * {@link Comparable} interface.
- */
-public class SessionInfo implements Comparable<SessionInfo> {
-
- private final String id;
-
- private final long start;
-
- private final long dump;
-
- /**
- * Create a immutable session info with the given data.
- *
- * @param id
- * arbitrary session identifier, must not be <code>null</code>
- * @param start
- * the epoc based time stamp when execution data recording has
- * been started
- * @param dump
- * the epoc based time stamp when execution data was collected
- */
- public SessionInfo(final String id, final long start, final long dump) {
- if (id == null) {
- throw new IllegalArgumentException();
- }
- this.id = id;
- this.start = start;
- this.dump = dump;
- }
-
- /**
- * @return identifier for this session
- */
- public String getId() {
- return id;
- }
-
- /**
- * @return the epoc based time stamp when execution data recording has been
- * started
- */
- public long getStartTimeStamp() {
- return start;
- }
-
- /**
- * @return the epoc based time stamp when execution data was collected
- */
- public long getDumpTimeStamp() {
- return dump;
- }
-
- public int compareTo(final SessionInfo other) {
- if (this.dump < other.dump) {
- return -1;
- }
- if (this.dump > other.dump) {
- return +1;
- }
- return 0;
- }
-
- @Override
- public String toString() {
- return "SessionInfo [" + id + "]";
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.data; + +/** + * Data object describing a session which was the source of execution data. + * {@link SessionInfo} instances can be sorted by dump date through the + * {@link Comparable} interface. + */ +public class SessionInfo implements Comparable<SessionInfo> { + + private final String id; + + private final long start; + + private final long dump; + + /** + * Create a immutable session info with the given data. + * + * @param id + * arbitrary session identifier, must not be <code>null</code> + * @param start + * the epoc based time stamp when execution data recording has + * been started + * @param dump + * the epoc based time stamp when execution data was collected + */ + public SessionInfo(final String id, final long start, final long dump) { + if (id == null) { + throw new IllegalArgumentException(); + } + this.id = id; + this.start = start; + this.dump = dump; + } + + /** + * @return identifier for this session + */ + public String getId() { + return id; + } + + /** + * @return the epoc based time stamp when execution data recording has been + * started + */ + public long getStartTimeStamp() { + return start; + } + + /** + * @return the epoc based time stamp when execution data was collected + */ + public long getDumpTimeStamp() { + return dump; + } + + public int compareTo(final SessionInfo other) { + if (this.dump < other.dump) { + return -1; + } + if (this.dump > other.dump) { + return +1; + } + return 0; + } + + @Override + public String toString() { + return "SessionInfo [" + id + "]"; + } +} diff --git a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java index 07aa6c57..57b1aad9 100644 --- a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java +++ b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java @@ -1,99 +1,99 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.instr;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.jacoco.core.internal.data.CRC64;
-import org.jacoco.core.internal.flow.ClassProbesAdapter;
-import org.jacoco.core.internal.instr.ClassInstrumenter;
-import org.jacoco.core.runtime.IExecutionDataAccessorGenerator;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-
-/**
- * Several APIs to instrument Java class definitions for coverage tracing.
- */
-public class Instrumenter {
-
- private final IExecutionDataAccessorGenerator accessGenerator;
-
- /**
- * Creates a new instance based on the given runtime.
- *
- * @param runtime
- * runtime used by the instrumented classes
- */
- public Instrumenter(final IExecutionDataAccessorGenerator runtime) {
- this.accessGenerator = runtime;
- }
-
- /**
- * Creates a ASM adapter for a class with the given id.
- *
- * @param classid
- * id of the class calculated with {@link CRC64}
- * @param cv
- * next class visitor in the chain
- * @return new visitor to write class definition to
- */
- private ClassVisitor createInstrumentingVisitor(final long classid,
- final ClassVisitor cv) {
- return new ClassProbesAdapter(new ClassInstrumenter(classid, accessGenerator,
- cv));
- }
-
- /**
- * Creates a instrumented version of the given class if possible.
- *
- * @param reader
- * definition of the class as ASM reader
- * @return instrumented definition or <code>null</code>
- *
- */
- public byte[] instrument(final ClassReader reader) {
- final ClassWriter writer = new ClassWriter(reader, 0);
- final ClassVisitor visitor = createInstrumentingVisitor(
- CRC64.checksum(reader.b), writer);
- reader.accept(visitor, ClassReader.EXPAND_FRAMES);
- return writer.toByteArray();
- }
-
- /**
- * Creates a instrumented version of the given class if possible.
- *
- * @param buffer
- * definition of the class
- * @return instrumented definition or <code>null</code>
- *
- */
- public byte[] instrument(final byte[] buffer) {
- return instrument(new ClassReader(buffer));
- }
-
- /**
- * Creates a instrumented version of the given class if possible.
- *
- * @param input
- * stream to read class definition from
- * @return instrumented definition or <code>null</code>
- * @throws IOException
- * if reading data from the stream fails
- *
- */
- public byte[] instrument(final InputStream input) throws IOException {
- return instrument(new ClassReader(input));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.instr; + +import java.io.IOException; +import java.io.InputStream; + +import org.jacoco.core.internal.data.CRC64; +import org.jacoco.core.internal.flow.ClassProbesAdapter; +import org.jacoco.core.internal.instr.ClassInstrumenter; +import org.jacoco.core.runtime.IExecutionDataAccessorGenerator; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; + +/** + * Several APIs to instrument Java class definitions for coverage tracing. + */ +public class Instrumenter { + + private final IExecutionDataAccessorGenerator accessGenerator; + + /** + * Creates a new instance based on the given runtime. + * + * @param runtime + * runtime used by the instrumented classes + */ + public Instrumenter(final IExecutionDataAccessorGenerator runtime) { + this.accessGenerator = runtime; + } + + /** + * Creates a ASM adapter for a class with the given id. + * + * @param classid + * id of the class calculated with {@link CRC64} + * @param cv + * next class visitor in the chain + * @return new visitor to write class definition to + */ + private ClassVisitor createInstrumentingVisitor(final long classid, + final ClassVisitor cv) { + return new ClassProbesAdapter(new ClassInstrumenter(classid, accessGenerator, + cv)); + } + + /** + * Creates a instrumented version of the given class if possible. + * + * @param reader + * definition of the class as ASM reader + * @return instrumented definition or <code>null</code> + * + */ + public byte[] instrument(final ClassReader reader) { + final ClassWriter writer = new ClassWriter(reader, 0); + final ClassVisitor visitor = createInstrumentingVisitor( + CRC64.checksum(reader.b), writer); + reader.accept(visitor, ClassReader.EXPAND_FRAMES); + return writer.toByteArray(); + } + + /** + * Creates a instrumented version of the given class if possible. + * + * @param buffer + * definition of the class + * @return instrumented definition or <code>null</code> + * + */ + public byte[] instrument(final byte[] buffer) { + return instrument(new ClassReader(buffer)); + } + + /** + * Creates a instrumented version of the given class if possible. + * + * @param input + * stream to read class definition from + * @return instrumented definition or <code>null</code> + * @throws IOException + * if reading data from the stream fails + * + */ + public byte[] instrument(final InputStream input) throws IOException { + return instrument(new ClassReader(input)); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/BundleCoverageImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/BundleCoverageImpl.java index 949f4a76..366ca742 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/BundleCoverageImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/BundleCoverageImpl.java @@ -1,116 +1,116 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.IPackageCoverage;
-import org.jacoco.core.analysis.ISourceFileCoverage;
-
-/**
- * Implementation of {@link IBundleCoverage}.
- */
-public class BundleCoverageImpl extends CoverageNodeImpl implements
- IBundleCoverage {
-
- private final Collection<IPackageCoverage> packages;
-
- /**
- * Creates a new instance of a bundle with the given name.
- *
- * @param name
- * name of this bundle
- * @param packages
- * collection of all packages contained in this bundle
- */
- public BundleCoverageImpl(final String name,
- final Collection<IPackageCoverage> packages) {
- super(ElementType.BUNDLE, name);
- this.packages = packages;
- increment(packages);
- }
-
- /**
- * Creates a new instance of a bundle with the given name. The packages are
- * calculated from the given classes and source files.
- *
- * @param name
- * name of this bundle
- * @param classes
- * all classes in this bundle
- * @param sourcefiles
- * all source files in this bundle
- */
- public BundleCoverageImpl(final String name,
- final Collection<IClassCoverage> classes,
- final Collection<ISourceFileCoverage> sourcefiles) {
- this(name, groupByPackage(classes, sourcefiles));
- }
-
- private static Collection<IPackageCoverage> groupByPackage(
- final Collection<IClassCoverage> classes,
- final Collection<ISourceFileCoverage> sourcefiles) {
- final Map<String, Collection<IClassCoverage>> classesByPackage = new HashMap<String, Collection<IClassCoverage>>();
- for (final IClassCoverage c : classes) {
- addByName(classesByPackage, c.getPackageName(), c);
- }
-
- final Map<String, Collection<ISourceFileCoverage>> sourceFilesByPackage = new HashMap<String, Collection<ISourceFileCoverage>>();
- for (final ISourceFileCoverage s : sourcefiles) {
- addByName(sourceFilesByPackage, s.getPackageName(), s);
- }
-
- final Set<String> packageNames = new HashSet<String>();
- packageNames.addAll(classesByPackage.keySet());
- packageNames.addAll(sourceFilesByPackage.keySet());
-
- final Collection<IPackageCoverage> result = new ArrayList<IPackageCoverage>();
- for (final String name : packageNames) {
- Collection<IClassCoverage> c = classesByPackage.get(name);
- if (c == null) {
- c = Collections.emptyList();
- }
- Collection<ISourceFileCoverage> s = sourceFilesByPackage.get(name);
- if (s == null) {
- s = Collections.emptyList();
- }
- result.add(new PackageCoverageImpl(name, c, s));
- }
- return result;
- }
-
- private static <T> void addByName(final Map<String, Collection<T>> map,
- final String name, final T value) {
- Collection<T> list = map.get(name);
- if (list == null) {
- list = new ArrayList<T>();
- map.put(name, list);
- }
- list.add(value);
- }
-
- // === IBundleCoverage implementation ===
-
- public Collection<IPackageCoverage> getPackages() {
- return packages;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.IPackageCoverage; +import org.jacoco.core.analysis.ISourceFileCoverage; + +/** + * Implementation of {@link IBundleCoverage}. + */ +public class BundleCoverageImpl extends CoverageNodeImpl implements + IBundleCoverage { + + private final Collection<IPackageCoverage> packages; + + /** + * Creates a new instance of a bundle with the given name. + * + * @param name + * name of this bundle + * @param packages + * collection of all packages contained in this bundle + */ + public BundleCoverageImpl(final String name, + final Collection<IPackageCoverage> packages) { + super(ElementType.BUNDLE, name); + this.packages = packages; + increment(packages); + } + + /** + * Creates a new instance of a bundle with the given name. The packages are + * calculated from the given classes and source files. + * + * @param name + * name of this bundle + * @param classes + * all classes in this bundle + * @param sourcefiles + * all source files in this bundle + */ + public BundleCoverageImpl(final String name, + final Collection<IClassCoverage> classes, + final Collection<ISourceFileCoverage> sourcefiles) { + this(name, groupByPackage(classes, sourcefiles)); + } + + private static Collection<IPackageCoverage> groupByPackage( + final Collection<IClassCoverage> classes, + final Collection<ISourceFileCoverage> sourcefiles) { + final Map<String, Collection<IClassCoverage>> classesByPackage = new HashMap<String, Collection<IClassCoverage>>(); + for (final IClassCoverage c : classes) { + addByName(classesByPackage, c.getPackageName(), c); + } + + final Map<String, Collection<ISourceFileCoverage>> sourceFilesByPackage = new HashMap<String, Collection<ISourceFileCoverage>>(); + for (final ISourceFileCoverage s : sourcefiles) { + addByName(sourceFilesByPackage, s.getPackageName(), s); + } + + final Set<String> packageNames = new HashSet<String>(); + packageNames.addAll(classesByPackage.keySet()); + packageNames.addAll(sourceFilesByPackage.keySet()); + + final Collection<IPackageCoverage> result = new ArrayList<IPackageCoverage>(); + for (final String name : packageNames) { + Collection<IClassCoverage> c = classesByPackage.get(name); + if (c == null) { + c = Collections.emptyList(); + } + Collection<ISourceFileCoverage> s = sourceFilesByPackage.get(name); + if (s == null) { + s = Collections.emptyList(); + } + result.add(new PackageCoverageImpl(name, c, s)); + } + return result; + } + + private static <T> void addByName(final Map<String, Collection<T>> map, + final String name, final T value) { + Collection<T> list = map.get(name); + if (list == null) { + list = new ArrayList<T>(); + map.put(name, list); + } + list.add(value); + } + + // === IBundleCoverage implementation === + + public Collection<IPackageCoverage> getPackages() { + return packages; + } + +} 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 dceca0b6..ce008f2f 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 @@ -1,129 +1,129 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import org.jacoco.core.analysis.IMethodCoverage;
-import org.jacoco.core.internal.flow.IClassProbesVisitor;
-import org.jacoco.core.internal.flow.IMethodProbesVisitor;
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Analyzes the structure of a class.
- */
-public class ClassAnalyzer implements IClassProbesVisitor {
-
- private final long classid;
- private final boolean executionData[];
- private final StringPool stringPool;
-
- private ClassCoverageImpl coverage;
-
- /**
- * Creates a new analyzer that builds coverage data for a class.
- *
- * @param classid
- * id of the class
- * @param executionData
- * 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[] executionData,
- final StringPool stringPool) {
- this.classid = classid;
- this.executionData = executionData;
- this.stringPool = stringPool;
- }
-
- /**
- * Returns the coverage data for this class after this visitor has been
- * processed.
- *
- * @return coverage data for this class
- */
- public ClassCoverageImpl getCoverage() {
- return coverage;
- }
-
- public void visit(final int version, final int access, final String name,
- final String signature, final String superName,
- final String[] interfaces) {
- this.coverage = new ClassCoverageImpl(stringPool.get(name), classid,
- stringPool.get(signature), stringPool.get(superName),
- stringPool.get(interfaces));
- }
-
- public void visitSource(final String source, final String debug) {
- this.coverage.setSourceFileName(stringPool.get(source));
- }
-
- public IMethodProbesVisitor visitMethod(final int access,
- final String name, final String desc, final String signature,
- final String[] exceptions) {
-
- // TODO: Use filter hook
- if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
- return null;
- }
-
- return new MethodAnalyzer(stringPool.get(name), stringPool.get(desc),
- stringPool.get(signature), executionData) {
- @Override
- public void visitEnd() {
- super.visitEnd();
- final IMethodCoverage methodCoverage = getCoverage();
- if (methodCoverage.getInstructionCounter().getTotalCount() > 0) {
- // Only consider methods that actually contain code
- coverage.addMethod(methodCoverage);
- }
- }
- };
- }
-
- public void visitTotalProbeCount(final int count) {
- // nothing to do
- }
-
- public AnnotationVisitor visitAnnotation(final String desc,
- final boolean visible) {
- // nothing to do
- return null;
- }
-
- public void visitAttribute(final Attribute attr) {
- // nothing to do
- }
-
- public FieldVisitor visitField(final int access, final String name,
- final String desc, final String signature, final Object value) {
- // nothing to do
- return null;
- }
-
- public void visitInnerClass(final String name, final String outerName,
- final String innerName, final int access) {
- // nothing to do
- }
-
- public void visitOuterClass(final String owner, final String name,
- final String desc) {
- // nothing to do
- }
-
- public void visitEnd() {
- // nothing to do
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import org.jacoco.core.analysis.IMethodCoverage; +import org.jacoco.core.internal.flow.IClassProbesVisitor; +import org.jacoco.core.internal.flow.IMethodProbesVisitor; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Attribute; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Analyzes the structure of a class. + */ +public class ClassAnalyzer implements IClassProbesVisitor { + + private final long classid; + private final boolean executionData[]; + private final StringPool stringPool; + + private ClassCoverageImpl coverage; + + /** + * Creates a new analyzer that builds coverage data for a class. + * + * @param classid + * id of the class + * @param executionData + * 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[] executionData, + final StringPool stringPool) { + this.classid = classid; + this.executionData = executionData; + this.stringPool = stringPool; + } + + /** + * Returns the coverage data for this class after this visitor has been + * processed. + * + * @return coverage data for this class + */ + public ClassCoverageImpl getCoverage() { + return coverage; + } + + public void visit(final int version, final int access, final String name, + final String signature, final String superName, + final String[] interfaces) { + this.coverage = new ClassCoverageImpl(stringPool.get(name), classid, + stringPool.get(signature), stringPool.get(superName), + stringPool.get(interfaces)); + } + + public void visitSource(final String source, final String debug) { + this.coverage.setSourceFileName(stringPool.get(source)); + } + + public IMethodProbesVisitor visitMethod(final int access, + final String name, final String desc, final String signature, + final String[] exceptions) { + + // TODO: Use filter hook + if ((access & Opcodes.ACC_SYNTHETIC) != 0) { + return null; + } + + return new MethodAnalyzer(stringPool.get(name), stringPool.get(desc), + stringPool.get(signature), executionData) { + @Override + public void visitEnd() { + super.visitEnd(); + final IMethodCoverage methodCoverage = getCoverage(); + if (methodCoverage.getInstructionCounter().getTotalCount() > 0) { + // Only consider methods that actually contain code + coverage.addMethod(methodCoverage); + } + } + }; + } + + public void visitTotalProbeCount(final int count) { + // nothing to do + } + + public AnnotationVisitor visitAnnotation(final String desc, + final boolean visible) { + // nothing to do + return null; + } + + public void visitAttribute(final Attribute attr) { + // nothing to do + } + + public FieldVisitor visitField(final int access, final String name, + final String desc, final String signature, final Object value) { + // nothing to do + return null; + } + + public void visitInnerClass(final String name, final String outerName, + final String innerName, final int access) { + // nothing to do + } + + public void visitOuterClass(final String owner, final String name, + final String desc) { + // nothing to do + } + + public void visitEnd() { + // nothing to do + } + +} 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 dd06a6bd..54479bbf 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 @@ -1,115 +1,115 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.IMethodCoverage;
-
-/**
- * Implementation of {@link IClassCoverage}.
- */
-public class ClassCoverageImpl extends SourceNodeImpl implements IClassCoverage {
-
- private final long id;
- private final String signature;
- private final String superName;
- private final String[] interfaces;
- private final Collection<IMethodCoverage> methods;
- private String sourceFileName;
-
- /**
- * Creates a class coverage data object with the given parameters.
- *
- * @param name
- * vm name of the class
- * @param id
- * class identifier
- * @param signature
- * vm signature of the class
- * @param superName
- * vm name of the superclass of this class
- * @param interfaces
- * vm names of interfaces of this class
- */
- public ClassCoverageImpl(final String name, final long id,
- final String signature, final String superName,
- final String[] interfaces) {
- super(ElementType.CLASS, name);
- this.id = id;
- this.signature = signature;
- this.superName = superName;
- this.interfaces = interfaces;
- this.methods = new ArrayList<IMethodCoverage>();
- this.classCounter = CounterImpl.COUNTER_1_0;
- }
-
- /**
- * Add a method to this class.
- *
- * @param method
- * method data to add
- */
- public void addMethod(final IMethodCoverage method) {
- this.methods.add(method);
- increment(method);
- // As class is considered as covered when at least one method is
- // covered:
- if (methodCounter.getCoveredCount() > 0) {
- this.classCounter = CounterImpl.COUNTER_0_1;
- }
- }
-
- /**
- * Sets the name of the corresponding source file for this class.
- *
- * @param sourceFileName
- * name of the source file
- */
- public void setSourceFileName(final String sourceFileName) {
- this.sourceFileName = sourceFileName;
- }
-
- // === IClassCoverage implementation ===
-
- public long getId() {
- return id;
- }
-
- public String getSignature() {
- return signature;
- }
-
- public String getSuperName() {
- return superName;
- }
-
- public String[] getInterfaceNames() {
- return interfaces;
- }
-
- public String getPackageName() {
- final int pos = getName().lastIndexOf('/');
- return pos == -1 ? "" : getName().substring(0, pos);
- }
-
- public String getSourceFileName() {
- return sourceFileName;
- }
-
- public Collection<IMethodCoverage> getMethods() {
- return methods;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import java.util.ArrayList; +import java.util.Collection; + +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.IMethodCoverage; + +/** + * Implementation of {@link IClassCoverage}. + */ +public class ClassCoverageImpl extends SourceNodeImpl implements IClassCoverage { + + private final long id; + private final String signature; + private final String superName; + private final String[] interfaces; + private final Collection<IMethodCoverage> methods; + private String sourceFileName; + + /** + * Creates a class coverage data object with the given parameters. + * + * @param name + * vm name of the class + * @param id + * class identifier + * @param signature + * vm signature of the class + * @param superName + * vm name of the superclass of this class + * @param interfaces + * vm names of interfaces of this class + */ + public ClassCoverageImpl(final String name, final long id, + final String signature, final String superName, + final String[] interfaces) { + super(ElementType.CLASS, name); + this.id = id; + this.signature = signature; + this.superName = superName; + this.interfaces = interfaces; + this.methods = new ArrayList<IMethodCoverage>(); + this.classCounter = CounterImpl.COUNTER_1_0; + } + + /** + * Add a method to this class. + * + * @param method + * method data to add + */ + public void addMethod(final IMethodCoverage method) { + this.methods.add(method); + increment(method); + // As class is considered as covered when at least one method is + // covered: + if (methodCounter.getCoveredCount() > 0) { + this.classCounter = CounterImpl.COUNTER_0_1; + } + } + + /** + * Sets the name of the corresponding source file for this class. + * + * @param sourceFileName + * name of the source file + */ + public void setSourceFileName(final String sourceFileName) { + this.sourceFileName = sourceFileName; + } + + // === IClassCoverage implementation === + + public long getId() { + return id; + } + + public String getSignature() { + return signature; + } + + public String getSuperName() { + return superName; + } + + public String[] getInterfaceNames() { + return interfaces; + } + + public String getPackageName() { + final int pos = getName().lastIndexOf('/'); + return pos == -1 ? "" : getName().substring(0, pos); + } + + public String getSourceFileName() { + return sourceFileName; + } + + public Collection<IMethodCoverage> getMethods() { + return methods; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ContentTypeDetector.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ContentTypeDetector.java index 33804396..d8e369fb 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ContentTypeDetector.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ContentTypeDetector.java @@ -1,103 +1,103 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.objectweb.asm.Opcodes;
-
-/**
- * Detector for content types of binary streams based on a magic headers.
- */
-public class ContentTypeDetector {
-
- /** Unknown file type */
- public static final int UNKNOWN = -1;
-
- /** File type Java class */
- public static final int CLASSFILE = 0xcafebabe;
-
- /** File type ZIP archive */
- public static final int ZIPFILE = 0x504b0304;
-
- private static final int BUFFER_SIZE = 8;
-
- private final InputStream in;
-
- private final int type;
-
- /**
- * Creates a new detector based on the given input. To process the complete
- * original input afterwards use the stream returned by
- * {@link #getInputStream()}.
- *
- * @param in
- * input to read the header from
- * @throws IOException
- */
- public ContentTypeDetector(final InputStream in) throws IOException {
- if (in.markSupported()) {
- this.in = in;
- } else {
- this.in = new BufferedInputStream(in, BUFFER_SIZE);
- }
- this.in.mark(BUFFER_SIZE);
- this.type = determineType(this.in);
- this.in.reset();
- }
-
- private static int determineType(final InputStream in) throws IOException {
- switch (readInt(in)) {
- case ZIPFILE:
- return ZIPFILE;
- case CLASSFILE:
- // also verify version to distinguish from Mach Object files:
- switch (readInt(in)) {
- case Opcodes.V1_1:
- case Opcodes.V1_2:
- case Opcodes.V1_3:
- case Opcodes.V1_4:
- case Opcodes.V1_5:
- case Opcodes.V1_6:
- case Opcodes.V1_7:
- return CLASSFILE;
- }
- }
- return UNKNOWN;
- }
-
- private static int readInt(final InputStream in) throws IOException {
- return in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read();
- }
-
- /**
- * Returns an input stream instance to read the complete content (including
- * the header) of the underlying stream.
- *
- * @return input stream containing the complete content
- */
- public InputStream getInputStream() {
- return in;
- }
-
- /**
- * Returns the detected file type.
- *
- * @return file type
- */
- public int getType() {
- return type;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.objectweb.asm.Opcodes; + +/** + * Detector for content types of binary streams based on a magic headers. + */ +public class ContentTypeDetector { + + /** Unknown file type */ + public static final int UNKNOWN = -1; + + /** File type Java class */ + public static final int CLASSFILE = 0xcafebabe; + + /** File type ZIP archive */ + public static final int ZIPFILE = 0x504b0304; + + private static final int BUFFER_SIZE = 8; + + private final InputStream in; + + private final int type; + + /** + * Creates a new detector based on the given input. To process the complete + * original input afterwards use the stream returned by + * {@link #getInputStream()}. + * + * @param in + * input to read the header from + * @throws IOException + */ + public ContentTypeDetector(final InputStream in) throws IOException { + if (in.markSupported()) { + this.in = in; + } else { + this.in = new BufferedInputStream(in, BUFFER_SIZE); + } + this.in.mark(BUFFER_SIZE); + this.type = determineType(this.in); + this.in.reset(); + } + + private static int determineType(final InputStream in) throws IOException { + switch (readInt(in)) { + case ZIPFILE: + return ZIPFILE; + case CLASSFILE: + // also verify version to distinguish from Mach Object files: + switch (readInt(in)) { + case Opcodes.V1_1: + case Opcodes.V1_2: + case Opcodes.V1_3: + case Opcodes.V1_4: + case Opcodes.V1_5: + case Opcodes.V1_6: + case Opcodes.V1_7: + return CLASSFILE; + } + } + return UNKNOWN; + } + + private static int readInt(final InputStream in) throws IOException { + return in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read(); + } + + /** + * Returns an input stream instance to read the complete content (including + * the header) of the underlying stream. + * + * @return input stream containing the complete content + */ + public InputStream getInputStream() { + return in; + } + + /** + * Returns the detected file type. + * + * @return file type + */ + public int getType() { + return type; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/CounterImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/CounterImpl.java index d9d2ac30..de156923 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/CounterImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/CounterImpl.java @@ -1,203 +1,203 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import org.jacoco.core.analysis.ICounter;
-
-/**
- * {@link ICounter} implementations. Implementing a factory pattern allows to
- * share counter instances.
- */
-public abstract class CounterImpl implements ICounter {
-
- /** Max counter value for which singletons are created */
- private static final int SINGLETON_LIMIT = 30;
-
- private static final CounterImpl[][] SINGLETONS = new CounterImpl[SINGLETON_LIMIT + 1][];
-
- static {
- for (int i = 0; i <= SINGLETON_LIMIT; i++) {
- SINGLETONS[i] = new CounterImpl[SINGLETON_LIMIT + 1];
- for (int j = 0; j <= SINGLETON_LIMIT; j++) {
- SINGLETONS[i][j] = new Fix(i, j);
- }
- }
- }
-
- /** Constant for Counter with 0/0 values. */
- public static final CounterImpl COUNTER_0_0 = SINGLETONS[0][0];
-
- /** Constant for Counter with 1/0 values. */
- public static final CounterImpl COUNTER_1_0 = SINGLETONS[1][0];
-
- /** Constant for Counter with 0/1 values. */
- public static final CounterImpl COUNTER_0_1 = SINGLETONS[0][1];
-
- /**
- * Mutable version of the counter.
- */
- private static class Var extends CounterImpl {
- public Var(final int missed, final int covered) {
- super(missed, covered);
- }
-
- @Override
- public CounterImpl increment(final int missed, final int covered) {
- this.missed += missed;
- this.covered += covered;
- return this;
- }
- }
-
- /**
- * Immutable version of the counter.
- */
- private static class Fix extends CounterImpl {
- public Fix(final int missed, final int covered) {
- super(missed, covered);
- }
-
- @Override
- public CounterImpl increment(final int missed, final int covered) {
- return getInstance(this.missed + missed, this.covered + covered);
- }
- }
-
- /**
- * Factory method to retrieve a counter with the given number of items.
- *
- * @param missed
- * number of missed items
- * @param covered
- * number of covered items
- * @return counter instance
- */
- public static CounterImpl getInstance(final int missed, final int covered) {
- if (missed <= SINGLETON_LIMIT && covered <= SINGLETON_LIMIT) {
- return SINGLETONS[missed][covered];
- } else {
- return new Var(missed, covered);
- }
- }
-
- /**
- * Factory method to retrieve a clone of the given counter.
- *
- * @param counter
- * counter to copy
- * @return counter instance
- */
- public static CounterImpl getInstance(final ICounter counter) {
- return getInstance(counter.getMissedCount(), counter.getCoveredCount());
- }
-
- /** number of missed items */
- protected int missed;
-
- /** number of covered items */
- protected int covered;
-
- /**
- * Creates a new instance with the given numbers.
- *
- * @param missed
- * number of missed items
- * @param covered
- * number of covered items
- */
- protected CounterImpl(final int missed, final int covered) {
- this.missed = missed;
- this.covered = covered;
- }
-
- /**
- * Returns a counter with values incremented by the numbers of the given
- * counter. It is up to the implementation whether this counter instance is
- * modified or a new instance is returned.
- *
- * @param counter
- * number of additional total and covered items
- * @return counter instance with incremented values
- */
- public CounterImpl increment(final ICounter counter) {
- return increment(counter.getMissedCount(), counter.getCoveredCount());
- }
-
- /**
- * Returns a counter with values incremented by the given numbers. It is up
- * to the implementation whether this counter instance is modified or a new
- * instance is returned.
- *
- * @param missed
- * number of missed items
- * @param covered
- * number of covered items
- * @return counter instance with incremented values
- */
- public abstract CounterImpl increment(int missed, int covered);
-
- // === ICounter implementation ===
-
- public int getTotalCount() {
- return missed + covered;
- }
-
- public int getCoveredCount() {
- return covered;
- }
-
- public int getMissedCount() {
- return missed;
- }
-
- public double getCoveredRatio() {
- return (double) covered / (missed + covered);
- }
-
- public double getMissedRatio() {
- return (double) missed / (missed + covered);
- }
-
- public int getStatus() {
- int status = covered > 0 ? FULLY_COVERED : EMPTY;
- if (missed > 0) {
- status |= NOT_COVERED;
- }
- return status;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (obj instanceof ICounter) {
- final ICounter that = (ICounter) obj;
- return this.missed == that.getMissedCount()
- && this.covered == that.getCoveredCount();
- } else {
- return false;
- }
- }
-
- @Override
- public int hashCode() {
- return missed ^ covered * 17;
- }
-
- @Override
- public String toString() {
- final StringBuilder b = new StringBuilder("Counter["); //$NON-NLS-1$
- b.append(getMissedCount());
- b.append('/').append(getCoveredCount());
- b.append(']');
- return b.toString();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import org.jacoco.core.analysis.ICounter; + +/** + * {@link ICounter} implementations. Implementing a factory pattern allows to + * share counter instances. + */ +public abstract class CounterImpl implements ICounter { + + /** Max counter value for which singletons are created */ + private static final int SINGLETON_LIMIT = 30; + + private static final CounterImpl[][] SINGLETONS = new CounterImpl[SINGLETON_LIMIT + 1][]; + + static { + for (int i = 0; i <= SINGLETON_LIMIT; i++) { + SINGLETONS[i] = new CounterImpl[SINGLETON_LIMIT + 1]; + for (int j = 0; j <= SINGLETON_LIMIT; j++) { + SINGLETONS[i][j] = new Fix(i, j); + } + } + } + + /** Constant for Counter with 0/0 values. */ + public static final CounterImpl COUNTER_0_0 = SINGLETONS[0][0]; + + /** Constant for Counter with 1/0 values. */ + public static final CounterImpl COUNTER_1_0 = SINGLETONS[1][0]; + + /** Constant for Counter with 0/1 values. */ + public static final CounterImpl COUNTER_0_1 = SINGLETONS[0][1]; + + /** + * Mutable version of the counter. + */ + private static class Var extends CounterImpl { + public Var(final int missed, final int covered) { + super(missed, covered); + } + + @Override + public CounterImpl increment(final int missed, final int covered) { + this.missed += missed; + this.covered += covered; + return this; + } + } + + /** + * Immutable version of the counter. + */ + private static class Fix extends CounterImpl { + public Fix(final int missed, final int covered) { + super(missed, covered); + } + + @Override + public CounterImpl increment(final int missed, final int covered) { + return getInstance(this.missed + missed, this.covered + covered); + } + } + + /** + * Factory method to retrieve a counter with the given number of items. + * + * @param missed + * number of missed items + * @param covered + * number of covered items + * @return counter instance + */ + public static CounterImpl getInstance(final int missed, final int covered) { + if (missed <= SINGLETON_LIMIT && covered <= SINGLETON_LIMIT) { + return SINGLETONS[missed][covered]; + } else { + return new Var(missed, covered); + } + } + + /** + * Factory method to retrieve a clone of the given counter. + * + * @param counter + * counter to copy + * @return counter instance + */ + public static CounterImpl getInstance(final ICounter counter) { + return getInstance(counter.getMissedCount(), counter.getCoveredCount()); + } + + /** number of missed items */ + protected int missed; + + /** number of covered items */ + protected int covered; + + /** + * Creates a new instance with the given numbers. + * + * @param missed + * number of missed items + * @param covered + * number of covered items + */ + protected CounterImpl(final int missed, final int covered) { + this.missed = missed; + this.covered = covered; + } + + /** + * Returns a counter with values incremented by the numbers of the given + * counter. It is up to the implementation whether this counter instance is + * modified or a new instance is returned. + * + * @param counter + * number of additional total and covered items + * @return counter instance with incremented values + */ + public CounterImpl increment(final ICounter counter) { + return increment(counter.getMissedCount(), counter.getCoveredCount()); + } + + /** + * Returns a counter with values incremented by the given numbers. It is up + * to the implementation whether this counter instance is modified or a new + * instance is returned. + * + * @param missed + * number of missed items + * @param covered + * number of covered items + * @return counter instance with incremented values + */ + public abstract CounterImpl increment(int missed, int covered); + + // === ICounter implementation === + + public int getTotalCount() { + return missed + covered; + } + + public int getCoveredCount() { + return covered; + } + + public int getMissedCount() { + return missed; + } + + public double getCoveredRatio() { + return (double) covered / (missed + covered); + } + + public double getMissedRatio() { + return (double) missed / (missed + covered); + } + + public int getStatus() { + int status = covered > 0 ? FULLY_COVERED : EMPTY; + if (missed > 0) { + status |= NOT_COVERED; + } + return status; + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof ICounter) { + final ICounter that = (ICounter) obj; + return this.missed == that.getMissedCount() + && this.covered == that.getCoveredCount(); + } else { + return false; + } + } + + @Override + public int hashCode() { + return missed ^ covered * 17; + } + + @Override + public String toString() { + final StringBuilder b = new StringBuilder("Counter["); //$NON-NLS-1$ + b.append(getMissedCount()); + b.append('/').append(getCoveredCount()); + b.append(']'); + return b.toString(); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/LineImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/LineImpl.java index 649052f5..9313d402 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/LineImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/LineImpl.java @@ -1,149 +1,149 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.ILine;
-
-/**
- * Implementation of {@link ILine}.
- */
-public abstract class LineImpl implements ILine {
-
- /** Max instruction counter value for which singletons are created */
- private static final int SINGLETON_INS_LIMIT = 8;
-
- /** Max branch counter value for which singletons are created */
- private static final int SINGLETON_BRA_LIMIT = 4;
-
- private static final LineImpl[][][][] SINGLETONS = new LineImpl[SINGLETON_INS_LIMIT + 1][][][];
-
- static {
- for (int i = 0; i <= SINGLETON_INS_LIMIT; i++) {
- SINGLETONS[i] = new LineImpl[SINGLETON_INS_LIMIT + 1][][];
- for (int j = 0; j <= SINGLETON_INS_LIMIT; j++) {
- SINGLETONS[i][j] = new LineImpl[SINGLETON_BRA_LIMIT + 1][];
- for (int k = 0; k <= SINGLETON_BRA_LIMIT; k++) {
- SINGLETONS[i][j][k] = new LineImpl[SINGLETON_BRA_LIMIT + 1];
- for (int l = 0; l <= SINGLETON_BRA_LIMIT; l++) {
- SINGLETONS[i][j][k][l] = new Fix(i, j, k, l);
- }
- }
- }
- }
- }
-
- /**
- * Empty line without instructions or branches.
- */
- public static final LineImpl EMPTY = SINGLETONS[0][0][0][0];
-
- private static LineImpl getInstance(final CounterImpl instructions,
- final CounterImpl branches) {
- final int im = instructions.getMissedCount();
- final int ic = instructions.getCoveredCount();
- final int bm = branches.getMissedCount();
- final int bc = branches.getCoveredCount();
- if (im <= SINGLETON_INS_LIMIT && ic <= SINGLETON_INS_LIMIT
- && bm <= SINGLETON_BRA_LIMIT && bc <= SINGLETON_BRA_LIMIT) {
- return SINGLETONS[im][ic][bm][bc];
- }
- return new Var(instructions, branches);
- }
-
- /**
- * Mutable version.
- */
- private static final class Var extends LineImpl {
- Var(final CounterImpl instructions, final CounterImpl branches) {
- super(instructions, branches);
- }
-
- @Override
- public LineImpl increment(final ICounter instructions,
- final ICounter branches) {
- this.instructions = this.instructions.increment(instructions);
- this.branches = this.branches.increment(branches);
- return this;
- }
- }
-
- /**
- * Immutable version.
- */
- private static final class Fix extends LineImpl {
- public Fix(final int im, final int ic, final int bm, final int bc) {
- super(CounterImpl.getInstance(im, ic), CounterImpl.getInstance(bm,
- bc));
- }
-
- @Override
- public LineImpl increment(final ICounter instructions,
- final ICounter branches) {
- return getInstance(this.instructions.increment(instructions),
- this.branches.increment(branches));
- }
- }
-
- /** instruction counter */
- protected CounterImpl instructions;
-
- /** branch counter */
- protected CounterImpl branches;
-
- private LineImpl(final CounterImpl instructions, final CounterImpl branches) {
- this.instructions = instructions;
- this.branches = branches;
- }
-
- /**
- * Adds the given counters to this line.
- *
- * @param instructions
- * instructions to add
- * @param branches
- * branches to add
- * @return instance with new counter values
- */
- public abstract LineImpl increment(final ICounter instructions,
- final ICounter branches);
-
- // === ILine implementation ===
-
- public int getStatus() {
- return instructions.getStatus() | branches.getStatus();
- }
-
- public ICounter getInstructionCounter() {
- return instructions;
- }
-
- public ICounter getBranchCounter() {
- return branches;
- }
-
- @Override
- public int hashCode() {
- return 23 * instructions.hashCode() ^ branches.hashCode();
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (obj instanceof ILine) {
- final ILine that = (ILine) obj;
- return this.instructions.equals(that.getInstructionCounter())
- && this.branches.equals(that.getBranchCounter());
- }
- return false;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.ILine; + +/** + * Implementation of {@link ILine}. + */ +public abstract class LineImpl implements ILine { + + /** Max instruction counter value for which singletons are created */ + private static final int SINGLETON_INS_LIMIT = 8; + + /** Max branch counter value for which singletons are created */ + private static final int SINGLETON_BRA_LIMIT = 4; + + private static final LineImpl[][][][] SINGLETONS = new LineImpl[SINGLETON_INS_LIMIT + 1][][][]; + + static { + for (int i = 0; i <= SINGLETON_INS_LIMIT; i++) { + SINGLETONS[i] = new LineImpl[SINGLETON_INS_LIMIT + 1][][]; + for (int j = 0; j <= SINGLETON_INS_LIMIT; j++) { + SINGLETONS[i][j] = new LineImpl[SINGLETON_BRA_LIMIT + 1][]; + for (int k = 0; k <= SINGLETON_BRA_LIMIT; k++) { + SINGLETONS[i][j][k] = new LineImpl[SINGLETON_BRA_LIMIT + 1]; + for (int l = 0; l <= SINGLETON_BRA_LIMIT; l++) { + SINGLETONS[i][j][k][l] = new Fix(i, j, k, l); + } + } + } + } + } + + /** + * Empty line without instructions or branches. + */ + public static final LineImpl EMPTY = SINGLETONS[0][0][0][0]; + + private static LineImpl getInstance(final CounterImpl instructions, + final CounterImpl branches) { + final int im = instructions.getMissedCount(); + final int ic = instructions.getCoveredCount(); + final int bm = branches.getMissedCount(); + final int bc = branches.getCoveredCount(); + if (im <= SINGLETON_INS_LIMIT && ic <= SINGLETON_INS_LIMIT + && bm <= SINGLETON_BRA_LIMIT && bc <= SINGLETON_BRA_LIMIT) { + return SINGLETONS[im][ic][bm][bc]; + } + return new Var(instructions, branches); + } + + /** + * Mutable version. + */ + private static final class Var extends LineImpl { + Var(final CounterImpl instructions, final CounterImpl branches) { + super(instructions, branches); + } + + @Override + public LineImpl increment(final ICounter instructions, + final ICounter branches) { + this.instructions = this.instructions.increment(instructions); + this.branches = this.branches.increment(branches); + return this; + } + } + + /** + * Immutable version. + */ + private static final class Fix extends LineImpl { + public Fix(final int im, final int ic, final int bm, final int bc) { + super(CounterImpl.getInstance(im, ic), CounterImpl.getInstance(bm, + bc)); + } + + @Override + public LineImpl increment(final ICounter instructions, + final ICounter branches) { + return getInstance(this.instructions.increment(instructions), + this.branches.increment(branches)); + } + } + + /** instruction counter */ + protected CounterImpl instructions; + + /** branch counter */ + protected CounterImpl branches; + + private LineImpl(final CounterImpl instructions, final CounterImpl branches) { + this.instructions = instructions; + this.branches = branches; + } + + /** + * Adds the given counters to this line. + * + * @param instructions + * instructions to add + * @param branches + * branches to add + * @return instance with new counter values + */ + public abstract LineImpl increment(final ICounter instructions, + final ICounter branches); + + // === ILine implementation === + + public int getStatus() { + return instructions.getStatus() | branches.getStatus(); + } + + public ICounter getInstructionCounter() { + return instructions; + } + + public ICounter getBranchCounter() { + return branches; + } + + @Override + public int hashCode() { + return 23 * instructions.hashCode() ^ branches.hashCode(); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof ILine) { + final ILine that = (ILine) obj; + return this.instructions.equals(that.getInstructionCounter()) + && this.branches.equals(that.getBranchCounter()); + } + return false; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageImpl.java index 7fd83fc1..9efe9252 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodCoverageImpl.java @@ -1,77 +1,77 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.IMethodCoverage;
-
-/**
- * Implementation of {@link IMethodCoverage}.
- */
-public class MethodCoverageImpl extends SourceNodeImpl implements
- IMethodCoverage {
-
- private final String desc;
-
- private final String signature;
-
- /**
- * Creates a method coverage data object with the given parameters.
- *
- * @param name
- * name of the method
- * @param desc
- * parameter description
- * @param signature
- * generic signature or <code>null</code>
- */
- public MethodCoverageImpl(final String name, final String desc,
- final String signature) {
- super(ElementType.METHOD, name);
- this.desc = desc;
- this.signature = signature;
- }
-
- @Override
- public void increment(final ICounter instructions, final ICounter branches,
- final int line) {
- super.increment(instructions, branches, line);
- // Additionally increment complexity counter:
- if (branches.getTotalCount() > 1) {
- final int c = Math.max(0, branches.getCoveredCount() - 1);
- final int m = Math.max(0, branches.getTotalCount() - c - 1);
- this.complexityCounter = this.complexityCounter.increment(m, c);
- }
- }
-
- /**
- * This method must be called exactly once after all instructions and
- * branches have been incremented for this method coverage node.
- */
- public void incrementMethodCounter() {
- final ICounter base = this.instructionCounter.getCoveredCount() == 0 ? CounterImpl.COUNTER_1_0
- : CounterImpl.COUNTER_0_1;
- this.methodCounter = this.methodCounter.increment(base);
- this.complexityCounter = this.complexityCounter.increment(base);
- }
-
- // === IMethodCoverage implementation ===
-
- public String getDesc() {
- return desc;
- }
-
- public String getSignature() {
- return signature;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.IMethodCoverage; + +/** + * Implementation of {@link IMethodCoverage}. + */ +public class MethodCoverageImpl extends SourceNodeImpl implements + IMethodCoverage { + + private final String desc; + + private final String signature; + + /** + * Creates a method coverage data object with the given parameters. + * + * @param name + * name of the method + * @param desc + * parameter description + * @param signature + * generic signature or <code>null</code> + */ + public MethodCoverageImpl(final String name, final String desc, + final String signature) { + super(ElementType.METHOD, name); + this.desc = desc; + this.signature = signature; + } + + @Override + public void increment(final ICounter instructions, final ICounter branches, + final int line) { + super.increment(instructions, branches, line); + // Additionally increment complexity counter: + if (branches.getTotalCount() > 1) { + final int c = Math.max(0, branches.getCoveredCount() - 1); + final int m = Math.max(0, branches.getTotalCount() - c - 1); + this.complexityCounter = this.complexityCounter.increment(m, c); + } + } + + /** + * This method must be called exactly once after all instructions and + * branches have been incremented for this method coverage node. + */ + public void incrementMethodCounter() { + final ICounter base = this.instructionCounter.getCoveredCount() == 0 ? CounterImpl.COUNTER_1_0 + : CounterImpl.COUNTER_0_1; + this.methodCounter = this.methodCounter.increment(base); + this.complexityCounter = this.complexityCounter.increment(base); + } + + // === IMethodCoverage implementation === + + public String getDesc() { + return desc; + } + + public String getSignature() { + return signature; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/PackageCoverageImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/PackageCoverageImpl.java index fc96d874..b62a7894 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/PackageCoverageImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/PackageCoverageImpl.java @@ -1,68 +1,68 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import java.util.Collection;
-
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.IPackageCoverage;
-import org.jacoco.core.analysis.ISourceFileCoverage;
-
-/**
- * Implementation of {@link IPackageCoverage}.
- */
-public class PackageCoverageImpl extends CoverageNodeImpl implements
- IPackageCoverage {
-
- private final Collection<IClassCoverage> classes;
-
- private final Collection<ISourceFileCoverage> sourceFiles;
-
- /**
- * Creates package node instance for a package with the given name.
- *
- * @param name
- * vm name of the package
- * @param classes
- * collection of all classes in this package
- * @param sourceFiles
- * collection of all source files in this package
- */
- public PackageCoverageImpl(final String name,
- final Collection<IClassCoverage> classes,
- final Collection<ISourceFileCoverage> sourceFiles) {
- super(ElementType.PACKAGE, name);
- this.classes = classes;
- this.sourceFiles = sourceFiles;
- increment(sourceFiles);
- for (final IClassCoverage c : classes) {
- // We need to add only classes without a source file reference.
- // Classes associated with a source file are already included in the
- // SourceFileCoverage objects.
- if (c.getSourceFileName() == null) {
- increment(c);
- }
- }
- }
-
- // === IPackageCoverage implementation ===
-
- public Collection<IClassCoverage> getClasses() {
- return classes;
- }
-
- public Collection<ISourceFileCoverage> getSourceFiles() {
- return sourceFiles;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import java.util.Collection; + +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.IPackageCoverage; +import org.jacoco.core.analysis.ISourceFileCoverage; + +/** + * Implementation of {@link IPackageCoverage}. + */ +public class PackageCoverageImpl extends CoverageNodeImpl implements + IPackageCoverage { + + private final Collection<IClassCoverage> classes; + + private final Collection<ISourceFileCoverage> sourceFiles; + + /** + * Creates package node instance for a package with the given name. + * + * @param name + * vm name of the package + * @param classes + * collection of all classes in this package + * @param sourceFiles + * collection of all source files in this package + */ + public PackageCoverageImpl(final String name, + final Collection<IClassCoverage> classes, + final Collection<ISourceFileCoverage> sourceFiles) { + super(ElementType.PACKAGE, name); + this.classes = classes; + this.sourceFiles = sourceFiles; + increment(sourceFiles); + for (final IClassCoverage c : classes) { + // We need to add only classes without a source file reference. + // Classes associated with a source file are already included in the + // SourceFileCoverage objects. + if (c.getSourceFileName() == null) { + increment(c); + } + } + } + + // === IPackageCoverage implementation === + + public Collection<IClassCoverage> getClasses() { + return classes; + } + + public Collection<ISourceFileCoverage> getSourceFiles() { + return sourceFiles; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceFileCoverageImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceFileCoverageImpl.java index 734b2e27..66cf3137 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceFileCoverageImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceFileCoverageImpl.java @@ -1,43 +1,43 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import org.jacoco.core.analysis.ISourceFileCoverage;
-
-/**
- * Implementation of {@link ISourceFileCoverage}.
- */
-public class SourceFileCoverageImpl extends SourceNodeImpl implements
- ISourceFileCoverage {
-
- private final String packagename;
-
- /**
- * Creates a source file data object with the given parameters.
- *
- * @param name
- * name of the source file
- * @param packagename
- * vm name of the package the source file belongs to
- */
- public SourceFileCoverageImpl(final String name, final String packagename) {
- super(ElementType.SOURCEFILE, name);
- this.packagename = packagename;
- }
-
- // === ISourceFileCoverage implementation ===
-
- public String getPackageName() {
- return packagename;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import org.jacoco.core.analysis.ISourceFileCoverage; + +/** + * Implementation of {@link ISourceFileCoverage}. + */ +public class SourceFileCoverageImpl extends SourceNodeImpl implements + ISourceFileCoverage { + + private final String packagename; + + /** + * Creates a source file data object with the given parameters. + * + * @param name + * name of the source file + * @param packagename + * vm name of the package the source file belongs to + */ + public SourceFileCoverageImpl(final String name, final String packagename) { + super(ElementType.SOURCEFILE, name); + this.packagename = packagename; + } + + // === ISourceFileCoverage implementation === + + public String getPackageName() { + return packagename; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java index 2af89f7b..82aadff1 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/SourceNodeImpl.java @@ -1,169 +1,169 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.ILine;
-import org.jacoco.core.analysis.ISourceNode;
-
-/**
- * Implementation of {@link ISourceNode}.
- */
-public class SourceNodeImpl extends CoverageNodeImpl implements ISourceNode {
-
- private LineImpl[] lines;
-
- /** first line number in {@link #lines} */
- private int offset;
-
- /**
- * Create a new source node implementation instance.
- *
- * @param elementType
- * element type
- * @param name
- * name of the element
- */
- public SourceNodeImpl(final ElementType elementType, final String name) {
- super(elementType, name);
- lines = null;
- offset = UNKNOWN_LINE;
- }
-
- /**
- * Make sure that the internal buffer can keep lines from first to last.
- * While the buffer is also incremented automatically, this method allows
- * optimization in case the total range in known in advance.
- *
- * @param first
- * first line number or {@link ISourceNode#UNKNOWN_LINE}
- * @param last
- * last line number or {@link ISourceNode#UNKNOWN_LINE}
- */
- public void ensureCapacity(final int first, final int last) {
- if (first == UNKNOWN_LINE || last == UNKNOWN_LINE) {
- return;
- }
- if (lines == null) {
- offset = first;
- lines = new LineImpl[last - first + 1];
- } else {
- final int newFirst = Math.min(getFirstLine(), first);
- final int newLast = Math.max(getLastLine(), last);
- final int newLength = newLast - newFirst + 1;
- if (newLength > lines.length) {
- final LineImpl[] newLines = new LineImpl[newLength];
- System.arraycopy(lines, 0, newLines, offset - newFirst,
- lines.length);
- offset = newFirst;
- lines = newLines;
- }
- }
- }
-
- /**
- * Increments all counters by the values of the given child. When
- * incrementing the line counter it is assumed that the child refers to the
- * same source file.
- *
- * @param child
- * child node to add
- */
- public void increment(final ISourceNode child) {
- instructionCounter = instructionCounter.increment(child
- .getInstructionCounter());
- branchCounter = branchCounter.increment(child.getBranchCounter());
- complexityCounter = complexityCounter.increment(child
- .getComplexityCounter());
- methodCounter = methodCounter.increment(child.getMethodCounter());
- classCounter = classCounter.increment(child.getClassCounter());
- final int firstLine = child.getFirstLine();
- if (firstLine != UNKNOWN_LINE) {
- final int lastLine = child.getLastLine();
- ensureCapacity(firstLine, lastLine);
- for (int i = firstLine; i <= lastLine; i++) {
- final ILine line = child.getLine(i);
- incrementLine(line.getInstructionCounter(),
- line.getBranchCounter(), i);
- }
- }
- }
-
- /**
- * Increments instructions and branches by the given counter values. If a
- * optional line number is specified the instructions and branches are added
- * to the given line. The line counter is incremented accordingly.
- *
- * @param instructions
- * instructions to add
- * @param branches
- * branches to add
- * @param line
- * optional line number or {@link ISourceNode#UNKNOWN_LINE}
- */
- public void increment(final ICounter instructions, final ICounter branches,
- final int line) {
- if (line != UNKNOWN_LINE) {
- incrementLine(instructions, branches, line);
- }
- instructionCounter = instructionCounter.increment(instructions);
- branchCounter = branchCounter.increment(branches);
- }
-
- private void incrementLine(final ICounter instructions,
- final ICounter branches, final int line) {
- ensureCapacity(line, line);
- final LineImpl l = getLine(line);
- final int oldTotal = l.getInstructionCounter().getTotalCount();
- final int oldCovered = l.getInstructionCounter().getCoveredCount();
- lines[line - offset] = l.increment(instructions, branches);
-
- // Increment line counter:
- if (instructions.getTotalCount() > 0) {
- if (instructions.getCoveredCount() == 0) {
- if (oldTotal == 0) {
- lineCounter = lineCounter
- .increment(CounterImpl.COUNTER_1_0);
- }
- } else {
- if (oldTotal == 0) {
- lineCounter = lineCounter
- .increment(CounterImpl.COUNTER_0_1);
- } else {
- if (oldCovered == 0) {
- lineCounter = lineCounter.increment(-1, +1);
- }
- }
- }
- }
- }
-
- // === ISourceNode implementation ===
-
- public int getFirstLine() {
- return offset;
- }
-
- public int getLastLine() {
- return lines == null ? UNKNOWN_LINE : (offset + lines.length - 1);
- }
-
- public LineImpl getLine(final int nr) {
- if (lines == null || nr < getFirstLine() || nr > getLastLine()) {
- return LineImpl.EMPTY;
- }
- final LineImpl line = lines[nr - offset];
- return line == null ? LineImpl.EMPTY : line;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.ILine; +import org.jacoco.core.analysis.ISourceNode; + +/** + * Implementation of {@link ISourceNode}. + */ +public class SourceNodeImpl extends CoverageNodeImpl implements ISourceNode { + + private LineImpl[] lines; + + /** first line number in {@link #lines} */ + private int offset; + + /** + * Create a new source node implementation instance. + * + * @param elementType + * element type + * @param name + * name of the element + */ + public SourceNodeImpl(final ElementType elementType, final String name) { + super(elementType, name); + lines = null; + offset = UNKNOWN_LINE; + } + + /** + * Make sure that the internal buffer can keep lines from first to last. + * While the buffer is also incremented automatically, this method allows + * optimization in case the total range in known in advance. + * + * @param first + * first line number or {@link ISourceNode#UNKNOWN_LINE} + * @param last + * last line number or {@link ISourceNode#UNKNOWN_LINE} + */ + public void ensureCapacity(final int first, final int last) { + if (first == UNKNOWN_LINE || last == UNKNOWN_LINE) { + return; + } + if (lines == null) { + offset = first; + lines = new LineImpl[last - first + 1]; + } else { + final int newFirst = Math.min(getFirstLine(), first); + final int newLast = Math.max(getLastLine(), last); + final int newLength = newLast - newFirst + 1; + if (newLength > lines.length) { + final LineImpl[] newLines = new LineImpl[newLength]; + System.arraycopy(lines, 0, newLines, offset - newFirst, + lines.length); + offset = newFirst; + lines = newLines; + } + } + } + + /** + * Increments all counters by the values of the given child. When + * incrementing the line counter it is assumed that the child refers to the + * same source file. + * + * @param child + * child node to add + */ + public void increment(final ISourceNode child) { + instructionCounter = instructionCounter.increment(child + .getInstructionCounter()); + branchCounter = branchCounter.increment(child.getBranchCounter()); + complexityCounter = complexityCounter.increment(child + .getComplexityCounter()); + methodCounter = methodCounter.increment(child.getMethodCounter()); + classCounter = classCounter.increment(child.getClassCounter()); + final int firstLine = child.getFirstLine(); + if (firstLine != UNKNOWN_LINE) { + final int lastLine = child.getLastLine(); + ensureCapacity(firstLine, lastLine); + for (int i = firstLine; i <= lastLine; i++) { + final ILine line = child.getLine(i); + incrementLine(line.getInstructionCounter(), + line.getBranchCounter(), i); + } + } + } + + /** + * Increments instructions and branches by the given counter values. If a + * optional line number is specified the instructions and branches are added + * to the given line. The line counter is incremented accordingly. + * + * @param instructions + * instructions to add + * @param branches + * branches to add + * @param line + * optional line number or {@link ISourceNode#UNKNOWN_LINE} + */ + public void increment(final ICounter instructions, final ICounter branches, + final int line) { + if (line != UNKNOWN_LINE) { + incrementLine(instructions, branches, line); + } + instructionCounter = instructionCounter.increment(instructions); + branchCounter = branchCounter.increment(branches); + } + + private void incrementLine(final ICounter instructions, + final ICounter branches, final int line) { + ensureCapacity(line, line); + final LineImpl l = getLine(line); + final int oldTotal = l.getInstructionCounter().getTotalCount(); + final int oldCovered = l.getInstructionCounter().getCoveredCount(); + lines[line - offset] = l.increment(instructions, branches); + + // Increment line counter: + if (instructions.getTotalCount() > 0) { + if (instructions.getCoveredCount() == 0) { + if (oldTotal == 0) { + lineCounter = lineCounter + .increment(CounterImpl.COUNTER_1_0); + } + } else { + if (oldTotal == 0) { + lineCounter = lineCounter + .increment(CounterImpl.COUNTER_0_1); + } else { + if (oldCovered == 0) { + lineCounter = lineCounter.increment(-1, +1); + } + } + } + } + } + + // === ISourceNode implementation === + + public int getFirstLine() { + return offset; + } + + public int getLastLine() { + return lines == null ? UNKNOWN_LINE : (offset + lines.length - 1); + } + + public LineImpl getLine(final int nr) { + if (lines == null || nr < getFirstLine() || nr > getLastLine()) { + return LineImpl.EMPTY; + } + final LineImpl line = lines[nr - offset]; + return line == null ? LineImpl.EMPTY : line; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/StringPool.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/StringPool.java index 0480a2ce..090dfd83 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/StringPool.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/StringPool.java @@ -1,73 +1,73 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - analysis and concept
- * Marc R. Hoffmann - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.core.internal.analysis;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Utility to normalize {@link String} instances in a way that if
- * <code>equals()</code> is <code>true</code> for two strings they will be
- * represented the same instance. While this is exactly what
- * {@link String#intern()} does, this implementation avoids VM specific side
- * effects and is supposed to be faster, as neither native code is called nor
- * synchronization is required for concurrent lookup.
- */
-public final class StringPool {
-
- private static final String[] EMPTY_ARRAY = new String[0];
-
- private final Map<String, String> pool = new HashMap<String, String>(1024);
-
- /**
- * Returns a normalized instance that is equal to the given {@link String} .
- *
- * @param s
- * any string or <code>null</code>
- * @return normalized instance or <code>null</code>
- */
- public String get(final String s) {
- if (s == null) {
- return null;
- }
- final String norm = pool.get(s);
- if (norm == null) {
- pool.put(s, s);
- return s;
- }
- return norm;
- }
-
- /**
- * Returns a modified version of the array with all string slots normalized.
- * It is up to the implementation to replace strings in the array instance
- * or return a new array instance.
- *
- * @param arr
- * String array or <code>null</code>
- * @return normalized instance or <code>null</code>
- */
- public String[] get(final String[] arr) {
- if (arr == null) {
- return null;
- }
- if (arr.length == 0) {
- return EMPTY_ARRAY;
- }
- for (int i = 0; i < arr.length; i++) {
- arr[i] = get(arr[i]);
- }
- return arr;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - analysis and concept + * Marc R. Hoffmann - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.internal.analysis; + +import java.util.HashMap; +import java.util.Map; + +/** + * Utility to normalize {@link String} instances in a way that if + * <code>equals()</code> is <code>true</code> for two strings they will be + * represented the same instance. While this is exactly what + * {@link String#intern()} does, this implementation avoids VM specific side + * effects and is supposed to be faster, as neither native code is called nor + * synchronization is required for concurrent lookup. + */ +public final class StringPool { + + private static final String[] EMPTY_ARRAY = new String[0]; + + private final Map<String, String> pool = new HashMap<String, String>(1024); + + /** + * Returns a normalized instance that is equal to the given {@link String} . + * + * @param s + * any string or <code>null</code> + * @return normalized instance or <code>null</code> + */ + public String get(final String s) { + if (s == null) { + return null; + } + final String norm = pool.get(s); + if (norm == null) { + pool.put(s, s); + return s; + } + return norm; + } + + /** + * Returns a modified version of the array with all string slots normalized. + * It is up to the implementation to replace strings in the array instance + * or return a new array instance. + * + * @param arr + * String array or <code>null</code> + * @return normalized instance or <code>null</code> + */ + public String[] get(final String[] arr) { + if (arr == null) { + return null; + } + if (arr.length == 0) { + return EMPTY_ARRAY; + } + for (int i = 0; i < arr.length; i++) { + arr[i] = get(arr[i]); + } + return arr; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/data/CRC64.java b/org.jacoco.core/src/org/jacoco/core/internal/data/CRC64.java index fe84e7ca..14f9ba7b 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/data/CRC64.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/data/CRC64.java @@ -1,63 +1,63 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.data;
-
-/**
- * CRC64 checksum calculator based on the polynom specified in ISO 3309. The
- * implementation is based on the following publications:
- *
- * <ul>
- * <li>http://en.wikipedia.org/wiki/Cyclic_redundancy_check</li>
- * <li>http://www.geocities.com/SiliconValley/Pines/8659/crc.htm</li>
- * </ul>
- */
-public final class CRC64 {
-
- private static final long POLY64REV = 0xd800000000000000L;
-
- private static final long[] LOOKUPTABLE;
-
- static {
- LOOKUPTABLE = new long[0x100];
- for (int i = 0; i < 0x100; i++) {
- long v = i;
- for (int j = 0; j < 8; j++) {
- if ((v & 1) == 1) {
- v = (v >>> 1) ^ POLY64REV;
- } else {
- v = (v >>> 1);
- }
- }
- LOOKUPTABLE[i] = v;
- }
- }
-
- /**
- * Calculates the CRC64 checksum for the given data array.
- *
- * @param data
- * data to calculate checksum for
- * @return checksum value
- */
- public static long checksum(final byte[] data) {
- long sum = 0;
- for (int i = 0; i < data.length; i++) {
- final int lookupidx = ((int) sum ^ data[i]) & 0xff;
- sum = (sum >>> 8) ^ LOOKUPTABLE[lookupidx];
- }
- return sum;
- }
-
- private CRC64() {
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.data; + +/** + * CRC64 checksum calculator based on the polynom specified in ISO 3309. The + * implementation is based on the following publications: + * + * <ul> + * <li>http://en.wikipedia.org/wiki/Cyclic_redundancy_check</li> + * <li>http://www.geocities.com/SiliconValley/Pines/8659/crc.htm</li> + * </ul> + */ +public final class CRC64 { + + private static final long POLY64REV = 0xd800000000000000L; + + private static final long[] LOOKUPTABLE; + + static { + LOOKUPTABLE = new long[0x100]; + for (int i = 0; i < 0x100; i++) { + long v = i; + for (int j = 0; j < 8; j++) { + if ((v & 1) == 1) { + v = (v >>> 1) ^ POLY64REV; + } else { + v = (v >>> 1); + } + } + LOOKUPTABLE[i] = v; + } + } + + /** + * Calculates the CRC64 checksum for the given data array. + * + * @param data + * data to calculate checksum for + * @return checksum value + */ + public static long checksum(final byte[] data) { + long sum = 0; + for (int i = 0; i < data.length; i++) { + final int lookupidx = ((int) sum ^ data[i]) & 0xff; + sum = (sum >>> 8) ^ LOOKUPTABLE[lookupidx]; + } + return sum; + } + + private CRC64() { + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/data/CompactDataInput.java b/org.jacoco.core/src/org/jacoco/core/internal/data/CompactDataInput.java index b4afed7b..6875a53f 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/data/CompactDataInput.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/data/CompactDataInput.java @@ -1,70 +1,70 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.data;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Additional data input methods for compact storage of data structures.
- *
- * @see CompactDataOutput
- */
-public class CompactDataInput extends DataInputStream {
-
- /**
- * Creates a new {@link CompactDataInput} that uses the specified underlying
- * input stream.
- *
- * @param in
- * underlying input stream
- */
- public CompactDataInput(final InputStream in) {
- super(in);
- }
-
- /**
- * Reads a variable length representation of an integer value.
- *
- * @return read value
- * @throws IOException
- * might be thrown by the underlying stream
- */
- public int readVarInt() throws IOException {
- final int value = 0xFF & readByte();
- if ((value & 0x80) == 0) {
- return value;
- }
- return (value & 0x7F) | (readVarInt() << 7);
- }
-
- /**
- * Reads a boolean array.
- *
- * @return boolean array
- * @throws IOException
- */
- public boolean[] readBooleanArray() throws IOException {
- final boolean[] value = new boolean[readVarInt()];
- int buffer = 0;
- for (int i = 0; i < value.length; i++) {
- if ((i % 8) == 0) {
- buffer = readByte();
- }
- value[i] = (buffer & 0x01) != 0;
- buffer >>>= 1;
- }
- return value;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.data; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Additional data input methods for compact storage of data structures. + * + * @see CompactDataOutput + */ +public class CompactDataInput extends DataInputStream { + + /** + * Creates a new {@link CompactDataInput} that uses the specified underlying + * input stream. + * + * @param in + * underlying input stream + */ + public CompactDataInput(final InputStream in) { + super(in); + } + + /** + * Reads a variable length representation of an integer value. + * + * @return read value + * @throws IOException + * might be thrown by the underlying stream + */ + public int readVarInt() throws IOException { + final int value = 0xFF & readByte(); + if ((value & 0x80) == 0) { + return value; + } + return (value & 0x7F) | (readVarInt() << 7); + } + + /** + * Reads a boolean array. + * + * @return boolean array + * @throws IOException + */ + public boolean[] readBooleanArray() throws IOException { + final boolean[] value = new boolean[readVarInt()]; + int buffer = 0; + for (int i = 0; i < value.length; i++) { + if ((i % 8) == 0) { + buffer = readByte(); + } + value[i] = (buffer & 0x01) != 0; + buffer >>>= 1; + } + return value; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/data/CompactDataOutput.java b/org.jacoco.core/src/org/jacoco/core/internal/data/CompactDataOutput.java index bcc65c6f..4b8489b6 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/data/CompactDataOutput.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/data/CompactDataOutput.java @@ -1,81 +1,81 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.data;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Additional data output methods for compact storage of data structures.
- *
- * @see CompactDataInput
- */
-public class CompactDataOutput extends DataOutputStream {
-
- /**
- * Creates a new {@link CompactDataOutput} instance that writes data to the
- * specified underlying output stream
- *
- * @param out
- * underlying output stream
- */
- public CompactDataOutput(final OutputStream out) {
- super(out);
- }
-
- /**
- * Writes a variable length representation of an integer value that reduces
- * the number of written bytes for small positive values. Depending on the
- * given value 1 to 5 bytes will be written to the underlying stream.
- *
- * @param value
- * value to write
- * @throws IOException
- */
- public void writeVarInt(final int value) throws IOException {
- if ((value & 0xFFFFFF80) == 0) {
- writeByte(value);
- } else {
- writeByte(0x80 | (value & 0x7F));
- writeVarInt(value >>> 7);
- }
- }
-
- /**
- * Writes a boolean array. Internally a sequence of boolean values is packed
- * into single bits.
- *
- * @param value
- * boolean array
- * @throws IOException
- */
- public void writeBooleanArray(final boolean[] value) throws IOException {
- writeVarInt(value.length);
- int buffer = 0;
- int bufferSize = 0;
- for (final boolean b : value) {
- if (b) {
- buffer |= 0x01 << bufferSize;
- }
- if (++bufferSize == 8) {
- writeByte(buffer);
- buffer = 0;
- bufferSize = 0;
- }
- }
- if (bufferSize > 0) {
- writeByte(buffer);
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.data; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Additional data output methods for compact storage of data structures. + * + * @see CompactDataInput + */ +public class CompactDataOutput extends DataOutputStream { + + /** + * Creates a new {@link CompactDataOutput} instance that writes data to the + * specified underlying output stream + * + * @param out + * underlying output stream + */ + public CompactDataOutput(final OutputStream out) { + super(out); + } + + /** + * Writes a variable length representation of an integer value that reduces + * the number of written bytes for small positive values. Depending on the + * given value 1 to 5 bytes will be written to the underlying stream. + * + * @param value + * value to write + * @throws IOException + */ + public void writeVarInt(final int value) throws IOException { + if ((value & 0xFFFFFF80) == 0) { + writeByte(value); + } else { + writeByte(0x80 | (value & 0x7F)); + writeVarInt(value >>> 7); + } + } + + /** + * Writes a boolean array. Internally a sequence of boolean values is packed + * into single bits. + * + * @param value + * boolean array + * @throws IOException + */ + public void writeBooleanArray(final boolean[] value) throws IOException { + writeVarInt(value.length); + int buffer = 0; + int bufferSize = 0; + for (final boolean b : value) { + if (b) { + buffer |= 0x01 << bufferSize; + } + if (++bufferSize == 8) { + writeByte(buffer); + buffer = 0; + bufferSize = 0; + } + } + if (bufferSize > 0) { + writeByte(buffer); + } + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/ClassProbesAdapter.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/ClassProbesAdapter.java index e542c3d1..d342dc79 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/flow/ClassProbesAdapter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/ClassProbesAdapter.java @@ -1,137 +1,137 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import org.objectweb.asm.ClassAdapter;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.commons.EmptyVisitor;
-
-/**
- * A {@link org.objectweb.asm.ClassVisitor} that calculates probes for every
- * method.
- */
-public class ClassProbesAdapter extends ClassAdapter implements
- IProbeIdGenerator {
-
- private static final IMethodProbesVisitor EMPTY_METHOD_PROBES_VISITOR;
-
- static {
- class Impl extends EmptyVisitor implements IMethodProbesVisitor {
-
- public void visitProbe(final int probeId) {
- // nothing to do
- }
-
- public void visitJumpInsnWithProbe(final int opcode,
- final Label label, final int probeId) {
- // nothing to do
- }
-
- public void visitInsnWithProbe(final int opcode, final int probeId) {
- // nothing to do
- }
-
- public void visitTableSwitchInsnWithProbes(final int min,
- final int max, final Label dflt, final Label[] labels) {
- // nothing to do
- }
-
- public void visitLookupSwitchInsnWithProbes(final Label dflt,
- final int[] keys, final Label[] labels) {
- // nothing to do
- }
- }
- EMPTY_METHOD_PROBES_VISITOR = new Impl();
- }
-
- private static class ProbeCounter implements IProbeIdGenerator {
- int count = 0;
-
- public int nextId() {
- return count++;
- }
- }
-
- private final IClassProbesVisitor cv;
-
- private int counter = 0;
-
- private boolean interfaceType;
-
- /**
- * Creates a new adapter that delegates to the given visitor.
- *
- * @param cv
- * instance to delegate to
- */
- public ClassProbesAdapter(final IClassProbesVisitor cv) {
- super(cv);
- this.cv = cv;
- }
-
- @Override
- public void visit(final int version, final int access, final String name,
- final String signature, final String superName,
- final String[] interfaces) {
- interfaceType = (access & Opcodes.ACC_INTERFACE) != 0;
- super.visit(version, access, name, signature, superName, interfaces);
- }
-
- @Override
- public final MethodVisitor visitMethod(final int access, final String name,
- final String desc, final String signature, final String[] exceptions) {
- final IMethodProbesVisitor methodProbes;
- final IMethodProbesVisitor mv = cv.visitMethod(access, name, desc,
- signature, exceptions);
- if (mv == null) {
- // We need to visit the method in any case, otherwise probe ids
- // are not reproducible
- methodProbes = EMPTY_METHOD_PROBES_VISITOR;
- } else {
- methodProbes = mv;
- }
- return new MethodSanitizer(null, access, name, desc, signature,
- exceptions) {
-
- @Override
- public void visitEnd() {
- super.visitEnd();
- this.accept(new LabelFlowAnalyzer());
- if (interfaceType) {
- final ProbeCounter probeCounter = new ProbeCounter();
- this.accept(new MethodProbesAdapter(
- EMPTY_METHOD_PROBES_VISITOR, probeCounter));
- cv.visitTotalProbeCount(probeCounter.count);
- }
- this.accept(new MethodProbesAdapter(methodProbes,
- ClassProbesAdapter.this));
- }
- };
- }
-
- @Override
- public void visitEnd() {
- if (!interfaceType) {
- cv.visitTotalProbeCount(counter);
- }
- super.visitEnd();
- }
-
- // === IProbeIdGenerator ===
-
- public int nextId() {
- return counter++;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +import org.objectweb.asm.ClassAdapter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.commons.EmptyVisitor; + +/** + * A {@link org.objectweb.asm.ClassVisitor} that calculates probes for every + * method. + */ +public class ClassProbesAdapter extends ClassAdapter implements + IProbeIdGenerator { + + private static final IMethodProbesVisitor EMPTY_METHOD_PROBES_VISITOR; + + static { + class Impl extends EmptyVisitor implements IMethodProbesVisitor { + + public void visitProbe(final int probeId) { + // nothing to do + } + + public void visitJumpInsnWithProbe(final int opcode, + final Label label, final int probeId) { + // nothing to do + } + + public void visitInsnWithProbe(final int opcode, final int probeId) { + // nothing to do + } + + public void visitTableSwitchInsnWithProbes(final int min, + final int max, final Label dflt, final Label[] labels) { + // nothing to do + } + + public void visitLookupSwitchInsnWithProbes(final Label dflt, + final int[] keys, final Label[] labels) { + // nothing to do + } + } + EMPTY_METHOD_PROBES_VISITOR = new Impl(); + } + + private static class ProbeCounter implements IProbeIdGenerator { + int count = 0; + + public int nextId() { + return count++; + } + } + + private final IClassProbesVisitor cv; + + private int counter = 0; + + private boolean interfaceType; + + /** + * Creates a new adapter that delegates to the given visitor. + * + * @param cv + * instance to delegate to + */ + public ClassProbesAdapter(final IClassProbesVisitor cv) { + super(cv); + this.cv = cv; + } + + @Override + public void visit(final int version, final int access, final String name, + final String signature, final String superName, + final String[] interfaces) { + interfaceType = (access & Opcodes.ACC_INTERFACE) != 0; + super.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public final MethodVisitor visitMethod(final int access, final String name, + final String desc, final String signature, final String[] exceptions) { + final IMethodProbesVisitor methodProbes; + final IMethodProbesVisitor mv = cv.visitMethod(access, name, desc, + signature, exceptions); + if (mv == null) { + // We need to visit the method in any case, otherwise probe ids + // are not reproducible + methodProbes = EMPTY_METHOD_PROBES_VISITOR; + } else { + methodProbes = mv; + } + return new MethodSanitizer(null, access, name, desc, signature, + exceptions) { + + @Override + public void visitEnd() { + super.visitEnd(); + this.accept(new LabelFlowAnalyzer()); + if (interfaceType) { + final ProbeCounter probeCounter = new ProbeCounter(); + this.accept(new MethodProbesAdapter( + EMPTY_METHOD_PROBES_VISITOR, probeCounter)); + cv.visitTotalProbeCount(probeCounter.count); + } + this.accept(new MethodProbesAdapter(methodProbes, + ClassProbesAdapter.this)); + } + }; + } + + @Override + public void visitEnd() { + if (!interfaceType) { + cv.visitTotalProbeCount(counter); + } + super.visitEnd(); + } + + // === IProbeIdGenerator === + + public int nextId() { + return counter++; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/IClassProbesVisitor.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/IClassProbesVisitor.java index 892601f3..6d457577 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/flow/IClassProbesVisitor.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/IClassProbesVisitor.java @@ -1,36 +1,36 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import org.objectweb.asm.ClassVisitor;
-
-/**
- * A {@link ClassVisitor} with additional methods to get probe insertion
- * information for each method
- */
-public interface IClassProbesVisitor extends ClassVisitor {
-
- public IMethodProbesVisitor visitMethod(int access, String name,
- String desc, String signature, String[] exceptions);
-
- /**
- * Reports the total number of encountered probes. For classes this method
- * is called just before {@link ClassVisitor#visitEnd()}. For interfaces
- * this method is called before the first method (the static initializer) is
- * emitted.
- *
- * @param count
- * total number of probes
- */
- public void visitTotalProbeCount(int count);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +import org.objectweb.asm.ClassVisitor; + +/** + * A {@link ClassVisitor} with additional methods to get probe insertion + * information for each method + */ +public interface IClassProbesVisitor extends ClassVisitor { + + public IMethodProbesVisitor visitMethod(int access, String name, + String desc, String signature, String[] exceptions); + + /** + * Reports the total number of encountered probes. For classes this method + * is called just before {@link ClassVisitor#visitEnd()}. For interfaces + * this method is called before the first method (the static initializer) is + * emitted. + * + * @param count + * total number of probes + */ + public void visitTotalProbeCount(int count); + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/IMethodProbesVisitor.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/IMethodProbesVisitor.java index d4007cd7..ff66ec10 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/flow/IMethodProbesVisitor.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/IMethodProbesVisitor.java @@ -1,109 +1,109 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-
-/**
- * A {@link MethodVisitor} with additional methods to get probe insertion
- * information.
- */
-public interface IMethodProbesVisitor extends MethodVisitor {
-
- /**
- * Visits an unconditional probe that should be inserted at the current
- * position.
- *
- * @param probeId
- * id of the probe to insert
- */
- public void visitProbe(int probeId);
-
- /**
- * Visits a jump instruction. A probe with the given id should be inserted
- * in a way that it is executed only when the jump to the given label is
- * executed.
- *
- * @param opcode
- * the opcode of the type instruction to be visited. This opcode
- * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
- * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
- * IF_ACMPEQ, IF_ACMPNE, GOTO, IFNULL or IFNONNULL.
- * @param label
- * the operand of the instruction to be visited. This operand is
- * a label that designates the instruction to which the jump
- * instruction may jump.
- * @param probeId
- * id of the probe
- * @see MethodVisitor#visitJumpInsn(int, Label)
- */
- void visitJumpInsnWithProbe(int opcode, Label label, int probeId);
-
- /**
- * Visits a zero operand instruction with a probe. This event is used only
- * for instructions that terminate the method. Therefore the probe must be
- * inserted before the actual instruction.
- *
- * @param opcode
- * the opcode of the instruction to be visited. This opcode is
- * either IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN or
- * ATHROW.
- * @param probeId
- * id of the probe
- * @see MethodVisitor#visitInsn(int)
- */
- void visitInsnWithProbe(int opcode, int probeId);
-
- /**
- * Visits a TABLESWITCH instruction with optional probes for each target
- * label. Implementations can be optimized based on the fact that the same
- * target labels will always have the same probe id within a call to this
- * method. The probe id for each label can be obtained with
- * {@link LabelInfo#getProbeId(Label)}.
- *
- * @param min
- * the minimum key value.
- * @param max
- * the maximum key value.
- * @param dflt
- * beginning of the default handler block.
- * @param labels
- * beginnings of the handler blocks. <code>labels[i]</code> is
- * the beginning of the handler block for the
- * <code>min + i</code> key.
- * @see MethodVisitor#visitTableSwitchInsn(int, int, Label, Label[])
- */
- public void visitTableSwitchInsnWithProbes(int min, int max, Label dflt,
- Label[] labels);
-
- /**
- * Visits a LOOKUPSWITCH instruction with optional probes for each target
- * label. Implementations can be optimized based on the fact that the same
- * target labels will always have the same probe id within a call to this
- * method. The probe id for each label can be obtained with
- * {@link LabelInfo#getProbeId(Label)}.
- *
- * @param dflt
- * beginning of the default handler block.
- * @param keys
- * the values of the keys.
- * @param labels
- * beginnings of the handler blocks. <code>labels[i]</code> is
- * the beginning of the handler block for the
- * <code>keys[i]</code> key.
- * @see MethodVisitor#visitLookupSwitchInsn(Label, int[], Label[])
- */
- public void visitLookupSwitchInsnWithProbes(Label dflt, int[] keys,
- Label[] labels);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; + +/** + * A {@link MethodVisitor} with additional methods to get probe insertion + * information. + */ +public interface IMethodProbesVisitor extends MethodVisitor { + + /** + * Visits an unconditional probe that should be inserted at the current + * position. + * + * @param probeId + * id of the probe to insert + */ + public void visitProbe(int probeId); + + /** + * Visits a jump instruction. A probe with the given id should be inserted + * in a way that it is executed only when the jump to the given label is + * executed. + * + * @param opcode + * the opcode of the type instruction to be visited. This opcode + * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, + * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, + * IF_ACMPEQ, IF_ACMPNE, GOTO, IFNULL or IFNONNULL. + * @param label + * the operand of the instruction to be visited. This operand is + * a label that designates the instruction to which the jump + * instruction may jump. + * @param probeId + * id of the probe + * @see MethodVisitor#visitJumpInsn(int, Label) + */ + void visitJumpInsnWithProbe(int opcode, Label label, int probeId); + + /** + * Visits a zero operand instruction with a probe. This event is used only + * for instructions that terminate the method. Therefore the probe must be + * inserted before the actual instruction. + * + * @param opcode + * the opcode of the instruction to be visited. This opcode is + * either IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN or + * ATHROW. + * @param probeId + * id of the probe + * @see MethodVisitor#visitInsn(int) + */ + void visitInsnWithProbe(int opcode, int probeId); + + /** + * Visits a TABLESWITCH instruction with optional probes for each target + * label. Implementations can be optimized based on the fact that the same + * target labels will always have the same probe id within a call to this + * method. The probe id for each label can be obtained with + * {@link LabelInfo#getProbeId(Label)}. + * + * @param min + * the minimum key value. + * @param max + * the maximum key value. + * @param dflt + * beginning of the default handler block. + * @param labels + * beginnings of the handler blocks. <code>labels[i]</code> is + * the beginning of the handler block for the + * <code>min + i</code> key. + * @see MethodVisitor#visitTableSwitchInsn(int, int, Label, Label[]) + */ + public void visitTableSwitchInsnWithProbes(int min, int max, Label dflt, + Label[] labels); + + /** + * Visits a LOOKUPSWITCH instruction with optional probes for each target + * label. Implementations can be optimized based on the fact that the same + * target labels will always have the same probe id within a call to this + * method. The probe id for each label can be obtained with + * {@link LabelInfo#getProbeId(Label)}. + * + * @param dflt + * beginning of the default handler block. + * @param keys + * the values of the keys. + * @param labels + * beginnings of the handler blocks. <code>labels[i]</code> is + * the beginning of the handler block for the + * <code>keys[i]</code> key. + * @see MethodVisitor#visitLookupSwitchInsn(Label, int[], Label[]) + */ + public void visitLookupSwitchInsnWithProbes(Label dflt, int[] keys, + Label[] labels); + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/IProbeIdGenerator.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/IProbeIdGenerator.java index f02b77ca..5f0090d1 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/flow/IProbeIdGenerator.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/IProbeIdGenerator.java @@ -1,26 +1,26 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-/**
- * Internal interface to create probe ids unique within a class.
- */
-public interface IProbeIdGenerator {
-
- /**
- * Returns the next unique probe id.
- *
- * @return unique probe id
- */
- int nextId();
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +/** + * Internal interface to create probe ids unique within a class. + */ +public interface IProbeIdGenerator { + + /** + * Returns the next unique probe id. + * + * @return unique probe id + */ + int nextId(); + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/Instruction.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/Instruction.java index 3291a3b8..e6816235 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/flow/Instruction.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/Instruction.java @@ -1,98 +1,98 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-/**
- * Representation of a byte code instruction for analysis. Internally used for
- * analysis.
- */
-public class Instruction {
-
- private final int line;
-
- private int branches;
-
- private int coveredBranches;
-
- private Instruction predecessor;
-
- /**
- * New instruction at the given line.
- *
- * @param line
- * source line this instruction belongs to
- */
- public Instruction(final int line) {
- this.line = line;
- this.branches = 0;
- this.coveredBranches = 0;
- }
-
- /**
- * Adds an branch to this instruction.
- */
- public void addBranch() {
- branches++;
- }
-
- /**
- * Sets the given instruction as a predecessor of this instruction. This
- * will add an branch to the predecessor.
- *
- * @see #addBranch()
- * @param predecessor
- * predecessor instruction
- */
- public void setPredecessor(final Instruction predecessor) {
- this.predecessor = predecessor;
- predecessor.addBranch();
- }
-
- /**
- * Marks one branch of this instruction as covered. Also recursively marks
- * all predecessor instructions as covered if this is the first covered
- * branch.
- */
- public void setCovered() {
- for (Instruction i = this; i != null && i.coveredBranches++ == 0;) {
- i = i.predecessor;
- }
- }
-
- /**
- * Returns the source line this instruction belongs to.
- *
- * @return corresponding source line
- */
- public int getLine() {
- return line;
- }
-
- /**
- * Returns the total number of branches starting from this instruction.
- *
- * @return total number of branches
- */
- public int getBranches() {
- return branches;
- }
-
- /**
- * Returns the number of covered branches starting from this instruction.
- *
- * @return number of covered branches
- */
- public int getCoveredBranches() {
- return coveredBranches;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +/** + * Representation of a byte code instruction for analysis. Internally used for + * analysis. + */ +public class Instruction { + + private final int line; + + private int branches; + + private int coveredBranches; + + private Instruction predecessor; + + /** + * New instruction at the given line. + * + * @param line + * source line this instruction belongs to + */ + public Instruction(final int line) { + this.line = line; + this.branches = 0; + this.coveredBranches = 0; + } + + /** + * Adds an branch to this instruction. + */ + public void addBranch() { + branches++; + } + + /** + * Sets the given instruction as a predecessor of this instruction. This + * will add an branch to the predecessor. + * + * @see #addBranch() + * @param predecessor + * predecessor instruction + */ + public void setPredecessor(final Instruction predecessor) { + this.predecessor = predecessor; + predecessor.addBranch(); + } + + /** + * Marks one branch of this instruction as covered. Also recursively marks + * all predecessor instructions as covered if this is the first covered + * branch. + */ + public void setCovered() { + for (Instruction i = this; i != null && i.coveredBranches++ == 0;) { + i = i.predecessor; + } + } + + /** + * Returns the source line this instruction belongs to. + * + * @return corresponding source line + */ + public int getLine() { + return line; + } + + /** + * Returns the total number of branches starting from this instruction. + * + * @return total number of branches + */ + public int getBranches() { + return branches; + } + + /** + * Returns the number of covered branches starting from this instruction. + * + * @return number of covered branches + */ + public int getCoveredBranches() { + return coveredBranches; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelFlowAnalyzer.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelFlowAnalyzer.java index f3ef877d..cf474826 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelFlowAnalyzer.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelFlowAnalyzer.java @@ -1,201 +1,201 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import org.objectweb.asm.AnnotationVisitor;
-import org.objectweb.asm.Attribute;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Method visitor to collect flow related information about the {@link Label}s
- * within a class. It calculates the properties "multitarget" and "successor"
- * that can afterwards be obtained via {@link LabelInfo}.
- */
-public final class LabelFlowAnalyzer implements MethodVisitor {
-
- /**
- * <code>true</code> if the current instruction is a potential successor of
- * the previous instruction. Accessible for testing.
- */
- boolean successor = false;
-
- /**
- * <code>true</code> for the very first instruction only. Accessible for
- * testing.
- */
- boolean first = true;
-
- public void visitTryCatchBlock(final Label start, final Label end,
- final Label handler, final String type) {
- // Enforce probes at the beginning and end of the block:
- LabelInfo.setTarget(start);
- LabelInfo.setTarget(handler);
- }
-
- public void visitJumpInsn(final int opcode, final Label label) {
- LabelInfo.setTarget(label);
- if (opcode == Opcodes.JSR) {
- throw new AssertionError("Subroutines not supported.");
- }
- successor = opcode != Opcodes.GOTO;
- first = false;
- }
-
- public void visitLabel(final Label label) {
- if (first) {
- LabelInfo.setTarget(label);
- }
- if (successor) {
- LabelInfo.setSuccessor(label);
- }
- }
-
- public void visitTableSwitchInsn(final int min, final int max,
- final Label dflt, final Label[] labels) {
- visitSwitchInsn(dflt, labels);
- }
-
- public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
- final Label[] labels) {
- visitSwitchInsn(dflt, labels);
- }
-
- private void visitSwitchInsn(final Label dflt, final Label[] labels) {
- LabelInfo.resetDone(dflt);
- LabelInfo.resetDone(labels);
- setTargetIfNotDone(dflt);
- for (final Label l : labels) {
- setTargetIfNotDone(l);
- }
- successor = false;
- first = false;
- }
-
- private static void setTargetIfNotDone(final Label label) {
- if (!LabelInfo.isDone(label)) {
- LabelInfo.setTarget(label);
- LabelInfo.setDone(label);
- }
- }
-
- public void visitInsn(final int opcode) {
- switch (opcode) {
- case Opcodes.RET:
- throw new AssertionError("Subroutines not supported.");
- case Opcodes.IRETURN:
- case Opcodes.LRETURN:
- case Opcodes.FRETURN:
- case Opcodes.DRETURN:
- case Opcodes.ARETURN:
- case Opcodes.RETURN:
- case Opcodes.ATHROW:
- successor = false;
- break;
- default:
- successor = true;
- break;
- }
- first = false;
- }
-
- public void visitIntInsn(final int opcode, final int operand) {
- successor = true;
- first = false;
- }
-
- public void visitVarInsn(final int opcode, final int var) {
- successor = true;
- first = false;
- }
-
- public void visitTypeInsn(final int opcode, final String type) {
- successor = true;
- first = false;
- }
-
- public void visitFieldInsn(final int opcode, final String owner,
- final String name, final String desc) {
- successor = true;
- first = false;
- }
-
- public void visitMethodInsn(final int opcode, final String owner,
- final String name, final String desc) {
- successor = true;
- first = false;
- }
-
- public void visitLdcInsn(final Object cst) {
- successor = true;
- first = false;
- }
-
- public void visitIincInsn(final int var, final int increment) {
- successor = true;
- first = false;
- }
-
- public void visitMultiANewArrayInsn(final String desc, final int dims) {
- successor = true;
- first = false;
- }
-
- public void visitAttribute(final Attribute attr) {
- // nothing to do
- }
-
- public AnnotationVisitor visitAnnotationDefault() {
- return null;
- }
-
- public AnnotationVisitor visitAnnotation(final String desc,
- final boolean visible) {
- // nothing to do
- return null;
- }
-
- public AnnotationVisitor visitParameterAnnotation(final int parameter,
- final String desc, final boolean visible) {
- // nothing to do
- return null;
- }
-
- public void visitLocalVariable(final String name, final String desc,
- final String signature, final Label start, final Label end,
- final int index) {
- // nothing to do
- }
-
- public void visitCode() {
- // nothing to do
- }
-
- public void visitLineNumber(final int line, final Label start) {
- // nothing to do
- }
-
- public void visitFrame(final int type, final int nLocal,
- final Object[] local, final int nStack, final Object[] stack) {
- // nothing to do
- }
-
- public void visitMaxs(final int maxStack, final int maxLocals) {
- // nothing to do
- }
-
- public void visitEnd() {
- // nothing to do
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Attribute; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Method visitor to collect flow related information about the {@link Label}s + * within a class. It calculates the properties "multitarget" and "successor" + * that can afterwards be obtained via {@link LabelInfo}. + */ +public final class LabelFlowAnalyzer implements MethodVisitor { + + /** + * <code>true</code> if the current instruction is a potential successor of + * the previous instruction. Accessible for testing. + */ + boolean successor = false; + + /** + * <code>true</code> for the very first instruction only. Accessible for + * testing. + */ + boolean first = true; + + public void visitTryCatchBlock(final Label start, final Label end, + final Label handler, final String type) { + // Enforce probes at the beginning and end of the block: + LabelInfo.setTarget(start); + LabelInfo.setTarget(handler); + } + + public void visitJumpInsn(final int opcode, final Label label) { + LabelInfo.setTarget(label); + if (opcode == Opcodes.JSR) { + throw new AssertionError("Subroutines not supported."); + } + successor = opcode != Opcodes.GOTO; + first = false; + } + + public void visitLabel(final Label label) { + if (first) { + LabelInfo.setTarget(label); + } + if (successor) { + LabelInfo.setSuccessor(label); + } + } + + public void visitTableSwitchInsn(final int min, final int max, + final Label dflt, final Label[] labels) { + visitSwitchInsn(dflt, labels); + } + + public void visitLookupSwitchInsn(final Label dflt, final int[] keys, + final Label[] labels) { + visitSwitchInsn(dflt, labels); + } + + private void visitSwitchInsn(final Label dflt, final Label[] labels) { + LabelInfo.resetDone(dflt); + LabelInfo.resetDone(labels); + setTargetIfNotDone(dflt); + for (final Label l : labels) { + setTargetIfNotDone(l); + } + successor = false; + first = false; + } + + private static void setTargetIfNotDone(final Label label) { + if (!LabelInfo.isDone(label)) { + LabelInfo.setTarget(label); + LabelInfo.setDone(label); + } + } + + public void visitInsn(final int opcode) { + switch (opcode) { + case Opcodes.RET: + throw new AssertionError("Subroutines not supported."); + case Opcodes.IRETURN: + case Opcodes.LRETURN: + case Opcodes.FRETURN: + case Opcodes.DRETURN: + case Opcodes.ARETURN: + case Opcodes.RETURN: + case Opcodes.ATHROW: + successor = false; + break; + default: + successor = true; + break; + } + first = false; + } + + public void visitIntInsn(final int opcode, final int operand) { + successor = true; + first = false; + } + + public void visitVarInsn(final int opcode, final int var) { + successor = true; + first = false; + } + + public void visitTypeInsn(final int opcode, final String type) { + successor = true; + first = false; + } + + public void visitFieldInsn(final int opcode, final String owner, + final String name, final String desc) { + successor = true; + first = false; + } + + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc) { + successor = true; + first = false; + } + + public void visitLdcInsn(final Object cst) { + successor = true; + first = false; + } + + public void visitIincInsn(final int var, final int increment) { + successor = true; + first = false; + } + + public void visitMultiANewArrayInsn(final String desc, final int dims) { + successor = true; + first = false; + } + + public void visitAttribute(final Attribute attr) { + // nothing to do + } + + public AnnotationVisitor visitAnnotationDefault() { + return null; + } + + public AnnotationVisitor visitAnnotation(final String desc, + final boolean visible) { + // nothing to do + return null; + } + + public AnnotationVisitor visitParameterAnnotation(final int parameter, + final String desc, final boolean visible) { + // nothing to do + return null; + } + + public void visitLocalVariable(final String name, final String desc, + final String signature, final Label start, final Label end, + final int index) { + // nothing to do + } + + public void visitCode() { + // nothing to do + } + + public void visitLineNumber(final int line, final Label start) { + // nothing to do + } + + public void visitFrame(final int type, final int nLocal, + final Object[] local, final int nStack, final Object[] stack) { + // nothing to do + } + + public void visitMaxs(final int maxStack, final int maxLocals) { + // nothing to do + } + + public void visitEnd() { + // nothing to do + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java b/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java index f2f0108f..17b574eb 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/flow/LabelInfo.java @@ -1,246 +1,246 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import org.objectweb.asm.Label;
-
-/**
- * Data container that is attached to {@link Label#info} objects to store flow
- * and instrumentation specific information. The information is only valid
- * locally in specific contexts.
- */
-public final class LabelInfo {
-
- /**
- * Reserved ID for "no probe".
- */
- public static final int NO_PROBE = -1;
-
- private boolean target = false;
-
- private boolean multiTarget = false;
-
- private boolean successor = false;
-
- private boolean done = false;
-
- private int probeid = NO_PROBE;
-
- private Label intermediate = null;
-
- private Instruction instruction = null;
-
- // instances are only created within this class
- private LabelInfo() {
- }
-
- /**
- * Defines that the given label is a jump target.
- *
- * @param label
- * label to define
- */
- public static void setTarget(final Label label) {
- final LabelInfo info = create(label);
- if (info.target || info.successor) {
- info.multiTarget = true;
- } else {
- info.target = true;
- }
- }
-
- /**
- * Defines that the given label is the possible successor of the previous
- * instruction in the method.
- *
- * @param label
- * label to define
- */
- public static void setSuccessor(final Label label) {
- final LabelInfo info = create(label);
- info.successor = true;
- if (info.target) {
- info.multiTarget = true;
- }
- }
-
- /**
- * Checks whether multiple control paths lead to a label. Control flow path
- * to a certain label are: jump targets, exception handlers and normal
- * control flow from its predecessor instruction (unless this a
- * unconditional jump or method exit).
- *
- * @param label
- * label to check
- * @return <code>true</code> if the given multiple control paths lead to the
- * given label
- */
- public static boolean isMultiTarget(final Label label) {
- final LabelInfo info = get(label);
- return info == null ? false : info.multiTarget;
- }
-
- /**
- * Checks whether this label is the possible successor of the previous
- * instruction in the method. This is the case if the predecessor isn't a
- * unconditional jump or method exit instruction.
- *
- * @param label
- * label to check
- * @return <code>true</code> if the label is a possible instruction
- * successor
- */
- public static boolean isSuccessor(final Label label) {
- final LabelInfo info = get(label);
- return info == null ? false : info.successor;
- }
-
- /**
- * Mark a given label as done.
- *
- * @param label
- * label to mark
- */
- public static void setDone(final Label label) {
- create(label).done = true;
- }
-
- /**
- * Resets the "done" status of a given label.
- *
- * @param label
- * label to reset
- */
- public static void resetDone(final Label label) {
- final LabelInfo info = get(label);
- if (info != null) {
- info.done = false;
- }
- }
-
- /**
- * Resets the "done" status of all given labels.
- *
- * @param labels
- * labels to reset
- */
- public static void resetDone(final Label[] labels) {
- for (final Label label : labels) {
- resetDone(label);
- }
- }
-
- /**
- * Checks whether this label is marked as done.
- *
- * @param label
- * label to check
- * @return <code>true</code> if this label is marked as done
- */
- public static boolean isDone(final Label label) {
- final LabelInfo info = get(label);
- return info == null ? false : info.done;
- }
-
- /**
- * Sets the given probe id to the given label.
- *
- * @param label
- * label to assign a probe to
- * @param id
- * id of the probe
- */
- public static void setProbeId(final Label label, final int id) {
- create(label).probeid = id;
- }
-
- /**
- * Returns the assigned probe id.
- *
- * @param label
- * label to check
- * @return probe id or {@link #NO_PROBE} if no probe is assigned to the
- * label
- */
- public static int getProbeId(final Label label) {
- final LabelInfo info = get(label);
- return info == null ? NO_PROBE : info.probeid;
- }
-
- /**
- * Defines an intermediate label for the given label. Such intermediate
- * labels are required during instrumentation to add probes to jump targets.
- *
- * @param label
- * label to define for
- * @param intermediate
- * intermediate label
- */
- public static void setIntermediateLabel(final Label label,
- final Label intermediate) {
- create(label).intermediate = intermediate;
- }
-
- /**
- * Returns the intermediate label for the given label if one has been
- * defined.
- *
- * @param label
- * label to look for
- * @return intermediate label or <code>null</code>
- */
- public static Label getIntermediateLabel(final Label label) {
- final LabelInfo info = get(label);
- return info == null ? null : info.intermediate;
- }
-
- /**
- * Sets the instruction corresponding to this label.
- *
- * @param label
- * label to set the instruction for
- * @param instruction
- * corresponding instruction
- */
- public static void setInstruction(final Label label,
- final Instruction instruction) {
- create(label).instruction = instruction;
- }
-
- /**
- * Returns the corresponding instruction for the given label if one has been
- * defined.
- *
- * @param label
- * label to look for
- * @return corresponding instruction or <code>null</code>
- */
- public static Instruction getInstruction(final Label label) {
- final LabelInfo info = get(label);
- return info == null ? null : info.instruction;
- }
-
- private static LabelInfo get(final Label label) {
- final Object info = label.info;
- return info instanceof LabelInfo ? (LabelInfo) info : null;
- }
-
- private static LabelInfo create(final Label label) {
- LabelInfo info = get(label);
- if (info == null) {
- info = new LabelInfo();
- label.info = info;
- }
- return info;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.flow; + +import org.objectweb.asm.Label; + +/** + * Data container that is attached to {@link Label#info} objects to store flow + * and instrumentation specific information. The information is only valid + * locally in specific contexts. + */ +public final class LabelInfo { + + /** + * Reserved ID for "no probe". + */ + public static final int NO_PROBE = -1; + + private boolean target = false; + + private boolean multiTarget = false; + + private boolean successor = false; + + private boolean done = false; + + private int probeid = NO_PROBE; + + private Label intermediate = null; + + private Instruction instruction = null; + + // instances are only created within this class + private LabelInfo() { + } + + /** + * Defines that the given label is a jump target. + * + * @param label + * label to define + */ + public static void setTarget(final Label label) { + final LabelInfo info = create(label); + if (info.target || info.successor) { + info.multiTarget = true; + } else { + info.target = true; + } + } + + /** + * Defines that the given label is the possible successor of the previous + * instruction in the method. + * + * @param label + * label to define + */ + public static void setSuccessor(final Label label) { + final LabelInfo info = create(label); + info.successor = true; + if (info.target) { + info.multiTarget = true; + } + } + + /** + * Checks whether multiple control paths lead to a label. Control flow path + * to a certain label are: jump targets, exception handlers and normal + * control flow from its predecessor instruction (unless this a + * unconditional jump or method exit). + * + * @param label + * label to check + * @return <code>true</code> if the given multiple control paths lead to the + * given label + */ + public static boolean isMultiTarget(final Label label) { + final LabelInfo info = get(label); + return info == null ? false : info.multiTarget; + } + + /** + * Checks whether this label is the possible successor of the previous + * instruction in the method. This is the case if the predecessor isn't a + * unconditional jump or method exit instruction. + * + * @param label + * label to check + * @return <code>true</code> if the label is a possible instruction + * successor + */ + public static boolean isSuccessor(final Label label) { + final LabelInfo info = get(label); + return info == null ? false : info.successor; + } + + /** + * Mark a given label as done. + * + * @param label + * label to mark + */ + public static void setDone(final Label label) { + create(label).done = true; + } + + /** + * Resets the "done" status of a given label. + * + * @param label + * label to reset + */ + public static void resetDone(final Label label) { + final LabelInfo info = get(label); + if (info != null) { + info.done = false; + } + } + + /** + * Resets the "done" status of all given labels. + * + * @param labels + * labels to reset + */ + public static void resetDone(final Label[] labels) { + for (final Label label : labels) { + resetDone(label); + } + } + + /** + * Checks whether this label is marked as done. + * + * @param label + * label to check + * @return <code>true</code> if this label is marked as done + */ + public static boolean isDone(final Label label) { + final LabelInfo info = get(label); + return info == null ? false : info.done; + } + + /** + * Sets the given probe id to the given label. + * + * @param label + * label to assign a probe to + * @param id + * id of the probe + */ + public static void setProbeId(final Label label, final int id) { + create(label).probeid = id; + } + + /** + * Returns the assigned probe id. + * + * @param label + * label to check + * @return probe id or {@link #NO_PROBE} if no probe is assigned to the + * label + */ + public static int getProbeId(final Label label) { + final LabelInfo info = get(label); + return info == null ? NO_PROBE : info.probeid; + } + + /** + * Defines an intermediate label for the given label. Such intermediate + * labels are required during instrumentation to add probes to jump targets. + * + * @param label + * label to define for + * @param intermediate + * intermediate label + */ + public static void setIntermediateLabel(final Label label, + final Label intermediate) { + create(label).intermediate = intermediate; + } + + /** + * Returns the intermediate label for the given label if one has been + * defined. + * + * @param label + * label to look for + * @return intermediate label or <code>null</code> + */ + public static Label getIntermediateLabel(final Label label) { + final LabelInfo info = get(label); + return info == null ? null : info.intermediate; + } + + /** + * Sets the instruction corresponding to this label. + * + * @param label + * label to set the instruction for + * @param instruction + * corresponding instruction + */ + public static void setInstruction(final Label label, + final Instruction instruction) { + create(label).instruction = instruction; + } + + /** + * Returns the corresponding instruction for the given label if one has been + * defined. + * + * @param label + * label to look for + * @return corresponding instruction or <code>null</code> + */ + public static Instruction getInstruction(final Label label) { + final LabelInfo info = get(label); + return info == null ? null : info.instruction; + } + + private static LabelInfo get(final Label label) { + final Object info = label.info; + return info instanceof LabelInfo ? (LabelInfo) info : null; + } + + private static LabelInfo create(final Label label) { + LabelInfo info = get(label); + if (info == null) { + info = new LabelInfo(); + label.info = info; + } + return info; + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java index a81f0ea2..50de87cb 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java @@ -1,246 +1,246 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import static java.lang.String.format;
-
-import org.jacoco.core.internal.flow.IClassProbesVisitor;
-import org.jacoco.core.internal.flow.IMethodProbesVisitor;
-import org.jacoco.core.runtime.IExecutionDataAccessorGenerator;
-import org.objectweb.asm.ClassAdapter;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Adapter that instruments a class for coverage tracing.
- */
-public class ClassInstrumenter extends ClassAdapter implements
- IClassProbesVisitor {
-
- private static final Object[] STACK_ARRZ = new Object[] { InstrSupport.DATAFIELD_DESC };
- private static final Object[] NO_LOCALS = new Object[0];
-
- private final long id;
-
- private final IExecutionDataAccessorGenerator accessorGenerator;
-
- private IProbeArrayStrategy probeArrayStrategy;
-
- private String className;
-
- private boolean withFrames;
-
- private int probeCount;
-
- /**
- * Emits a instrumented version of this class to the given class visitor.
- *
- * @param id
- * unique identifier given to this class
- * @param accessorGenerator
- * this generator will be used for instrumentation
- * @param cv
- * next delegate in the visitor chain will receive the
- * instrumented class
- */
- public ClassInstrumenter(final long id,
- final IExecutionDataAccessorGenerator accessorGenerator,
- final ClassVisitor cv) {
- super(cv);
- this.id = id;
- this.accessorGenerator = accessorGenerator;
- }
-
- @Override
- public void visit(final int version, final int access, final String name,
- final String signature, final String superName,
- final String[] interfaces) {
- this.className = name;
- withFrames = (version & 0xff) >= Opcodes.V1_6;
- if ((access & Opcodes.ACC_INTERFACE) == 0) {
- this.probeArrayStrategy = new ClassTypeStrategy();
- } else {
- this.probeArrayStrategy = new InterfaceTypeStrategy();
- }
- super.visit(version, access, name, signature, superName, interfaces);
- }
-
- @Override
- public FieldVisitor visitField(final int access, final String name,
- final String desc, final String signature, final Object value) {
- assertNotInstrumented(name, InstrSupport.DATAFIELD_NAME);
- return super.visitField(access, name, desc, signature, value);
- }
-
- @Override
- public IMethodProbesVisitor visitMethod(final int access,
- final String name, final String desc, final String signature,
- final String[] exceptions) {
-
- assertNotInstrumented(name, InstrSupport.INITMETHOD_NAME);
-
- final MethodVisitor mv = super.visitMethod(access, name, desc,
- signature, exceptions);
-
- if (mv == null) {
- return null;
- }
- final MethodVisitor frameEliminator = new DuplicateFrameEliminator(mv);
- final ProbeInserter probeVariableInserter = new ProbeInserter(access,
- desc, frameEliminator, probeArrayStrategy);
- final LazyFrameTracker frameTracker = new LazyFrameTracker(
- probeVariableInserter, className);
- return new MethodInstrumenter(frameTracker, probeVariableInserter,
- frameTracker);
- }
-
- public void visitTotalProbeCount(final int count) {
- probeCount = count;
- }
-
- @Override
- public void visitEnd() {
- probeArrayStrategy.addMembers(cv);
- super.visitEnd();
- }
-
- /**
- * Ensures that the given member does not correspond to a internal member
- * created by the instrumentation process. This would mean that the class
- * has been instrumented twice.
- *
- * @param member
- * name of the member to check
- * @param instrMember
- * name of a instrumentation member
- * @throws IllegalStateException
- * thrown if the member has the same name than the
- * instrumentation member
- */
- private void assertNotInstrumented(final String member,
- final String instrMember) throws IllegalStateException {
- if (member.equals(instrMember)) {
- throw new IllegalStateException(format(
- "Class %s is already instrumented.", className));
- }
- }
-
- // === probe array strategies ===
-
- private class ClassTypeStrategy implements IProbeArrayStrategy {
-
- public int storeInstance(final MethodVisitor mv, final int variable) {
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, className,
- InstrSupport.INITMETHOD_NAME, InstrSupport.INITMETHOD_DESC);
- mv.visitVarInsn(Opcodes.ASTORE, variable);
- return 1;
- }
-
- public void addMembers(final ClassVisitor delegate) {
- createDataField();
- createInitMethod(probeCount);
- }
-
- private void createDataField() {
- cv.visitField(InstrSupport.DATAFIELD_ACC,
- InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC,
- null, null);
- }
-
- private void createInitMethod(final int probeCount) {
- final MethodVisitor mv = cv.visitMethod(
- InstrSupport.INITMETHOD_ACC, InstrSupport.INITMETHOD_NAME,
- InstrSupport.INITMETHOD_DESC, null, null);
- mv.visitCode();
- if (withFrames) {
- mv.visitFrame(Opcodes.F_NEW, 0, NO_LOCALS, 0, STACK_ARRZ);
- }
-
- // Load the value of the static data field:
- mv.visitFieldInsn(Opcodes.GETSTATIC, className,
- InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC);
- mv.visitInsn(Opcodes.DUP);
-
- // Stack[1]: [Z
- // Stack[0]: [Z
-
- // Skip initialization when we already have a data array:
- final Label alreadyInitialized = new Label();
- mv.visitJumpInsn(Opcodes.IFNONNULL, alreadyInitialized);
-
- // Stack[0]: [Z
-
- mv.visitInsn(Opcodes.POP);
- final int size = genInitializeDataField(mv, probeCount);
-
- // Stack[0]: [Z
-
- // Return the class' probe array:
- if (withFrames) {
- mv.visitFrame(Opcodes.F_NEW, 0, NO_LOCALS, 1, STACK_ARRZ);
- }
- mv.visitLabel(alreadyInitialized);
- mv.visitInsn(Opcodes.ARETURN);
-
- mv.visitMaxs(Math.max(size, 2), 0); // Maximum local stack size is 2
- mv.visitEnd();
- }
-
- /**
- * Generates the byte code to initialize the static coverage data field
- * within this class.
- *
- * The code will push the [Z data array on the operand stack.
- *
- * @param mv
- * generator to emit code to
- */
- private int genInitializeDataField(final MethodVisitor mv,
- final int probeCount) {
- final int size = accessorGenerator.generateDataAccessor(id,
- className, probeCount, mv);
-
- // Stack[0]: [Z
-
- mv.visitInsn(Opcodes.DUP);
-
- // Stack[1]: [Z
- // Stack[0]: [Z
-
- mv.visitFieldInsn(Opcodes.PUTSTATIC, className,
- InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC);
-
- // Stack[0]: [Z
-
- return Math.max(size, 2); // Maximum local stack size is 2
- }
- }
-
- private class InterfaceTypeStrategy implements IProbeArrayStrategy {
-
- public int storeInstance(final MethodVisitor mv, final int variable) {
- final int maxStack = accessorGenerator.generateDataAccessor(id,
- className, probeCount, mv);
- mv.visitVarInsn(Opcodes.ASTORE, variable);
- return maxStack;
- }
-
- public void addMembers(final ClassVisitor delegate) {
- // nothing to do
- }
-
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.instr; + +import static java.lang.String.format; + +import org.jacoco.core.internal.flow.IClassProbesVisitor; +import org.jacoco.core.internal.flow.IMethodProbesVisitor; +import org.jacoco.core.runtime.IExecutionDataAccessorGenerator; +import org.objectweb.asm.ClassAdapter; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Adapter that instruments a class for coverage tracing. + */ +public class ClassInstrumenter extends ClassAdapter implements + IClassProbesVisitor { + + private static final Object[] STACK_ARRZ = new Object[] { InstrSupport.DATAFIELD_DESC }; + private static final Object[] NO_LOCALS = new Object[0]; + + private final long id; + + private final IExecutionDataAccessorGenerator accessorGenerator; + + private IProbeArrayStrategy probeArrayStrategy; + + private String className; + + private boolean withFrames; + + private int probeCount; + + /** + * Emits a instrumented version of this class to the given class visitor. + * + * @param id + * unique identifier given to this class + * @param accessorGenerator + * this generator will be used for instrumentation + * @param cv + * next delegate in the visitor chain will receive the + * instrumented class + */ + public ClassInstrumenter(final long id, + final IExecutionDataAccessorGenerator accessorGenerator, + final ClassVisitor cv) { + super(cv); + this.id = id; + this.accessorGenerator = accessorGenerator; + } + + @Override + public void visit(final int version, final int access, final String name, + final String signature, final String superName, + final String[] interfaces) { + this.className = name; + withFrames = (version & 0xff) >= Opcodes.V1_6; + if ((access & Opcodes.ACC_INTERFACE) == 0) { + this.probeArrayStrategy = new ClassTypeStrategy(); + } else { + this.probeArrayStrategy = new InterfaceTypeStrategy(); + } + super.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public FieldVisitor visitField(final int access, final String name, + final String desc, final String signature, final Object value) { + assertNotInstrumented(name, InstrSupport.DATAFIELD_NAME); + return super.visitField(access, name, desc, signature, value); + } + + @Override + public IMethodProbesVisitor visitMethod(final int access, + final String name, final String desc, final String signature, + final String[] exceptions) { + + assertNotInstrumented(name, InstrSupport.INITMETHOD_NAME); + + final MethodVisitor mv = super.visitMethod(access, name, desc, + signature, exceptions); + + if (mv == null) { + return null; + } + final MethodVisitor frameEliminator = new DuplicateFrameEliminator(mv); + final ProbeInserter probeVariableInserter = new ProbeInserter(access, + desc, frameEliminator, probeArrayStrategy); + final LazyFrameTracker frameTracker = new LazyFrameTracker( + probeVariableInserter, className); + return new MethodInstrumenter(frameTracker, probeVariableInserter, + frameTracker); + } + + public void visitTotalProbeCount(final int count) { + probeCount = count; + } + + @Override + public void visitEnd() { + probeArrayStrategy.addMembers(cv); + super.visitEnd(); + } + + /** + * Ensures that the given member does not correspond to a internal member + * created by the instrumentation process. This would mean that the class + * has been instrumented twice. + * + * @param member + * name of the member to check + * @param instrMember + * name of a instrumentation member + * @throws IllegalStateException + * thrown if the member has the same name than the + * instrumentation member + */ + private void assertNotInstrumented(final String member, + final String instrMember) throws IllegalStateException { + if (member.equals(instrMember)) { + throw new IllegalStateException(format( + "Class %s is already instrumented.", className)); + } + } + + // === probe array strategies === + + private class ClassTypeStrategy implements IProbeArrayStrategy { + + public int storeInstance(final MethodVisitor mv, final int variable) { + mv.visitMethodInsn(Opcodes.INVOKESTATIC, className, + InstrSupport.INITMETHOD_NAME, InstrSupport.INITMETHOD_DESC); + mv.visitVarInsn(Opcodes.ASTORE, variable); + return 1; + } + + public void addMembers(final ClassVisitor delegate) { + createDataField(); + createInitMethod(probeCount); + } + + private void createDataField() { + cv.visitField(InstrSupport.DATAFIELD_ACC, + InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC, + null, null); + } + + private void createInitMethod(final int probeCount) { + final MethodVisitor mv = cv.visitMethod( + InstrSupport.INITMETHOD_ACC, InstrSupport.INITMETHOD_NAME, + InstrSupport.INITMETHOD_DESC, null, null); + mv.visitCode(); + if (withFrames) { + mv.visitFrame(Opcodes.F_NEW, 0, NO_LOCALS, 0, STACK_ARRZ); + } + + // Load the value of the static data field: + mv.visitFieldInsn(Opcodes.GETSTATIC, className, + InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC); + mv.visitInsn(Opcodes.DUP); + + // Stack[1]: [Z + // Stack[0]: [Z + + // Skip initialization when we already have a data array: + final Label alreadyInitialized = new Label(); + mv.visitJumpInsn(Opcodes.IFNONNULL, alreadyInitialized); + + // Stack[0]: [Z + + mv.visitInsn(Opcodes.POP); + final int size = genInitializeDataField(mv, probeCount); + + // Stack[0]: [Z + + // Return the class' probe array: + if (withFrames) { + mv.visitFrame(Opcodes.F_NEW, 0, NO_LOCALS, 1, STACK_ARRZ); + } + mv.visitLabel(alreadyInitialized); + mv.visitInsn(Opcodes.ARETURN); + + mv.visitMaxs(Math.max(size, 2), 0); // Maximum local stack size is 2 + mv.visitEnd(); + } + + /** + * Generates the byte code to initialize the static coverage data field + * within this class. + * + * The code will push the [Z data array on the operand stack. + * + * @param mv + * generator to emit code to + */ + private int genInitializeDataField(final MethodVisitor mv, + final int probeCount) { + final int size = accessorGenerator.generateDataAccessor(id, + className, probeCount, mv); + + // Stack[0]: [Z + + mv.visitInsn(Opcodes.DUP); + + // Stack[1]: [Z + // Stack[0]: [Z + + mv.visitFieldInsn(Opcodes.PUTSTATIC, className, + InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC); + + // Stack[0]: [Z + + return Math.max(size, 2); // Maximum local stack size is 2 + } + } + + private class InterfaceTypeStrategy implements IProbeArrayStrategy { + + public int storeInstance(final MethodVisitor mv, final int variable) { + final int maxStack = accessorGenerator.generateDataAccessor(id, + className, probeCount, mv); + mv.visitVarInsn(Opcodes.ASTORE, variable); + return maxStack; + } + + public void addMembers(final ClassVisitor delegate) { + // nothing to do + } + + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/IProbeArrayStrategy.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/IProbeArrayStrategy.java index a4c2113e..674ceadc 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/instr/IProbeArrayStrategy.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/IProbeArrayStrategy.java @@ -1,43 +1,43 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-
-/**
- * Strategies to retrieve the probe array instance for each method within a
- * type. This abstraction is required as we need to follow a different strategy
- * depending on whether the instrumented type is a class or interface.
- */
-interface IProbeArrayStrategy {
-
- /**
- * Creates code that stores the probe array instance in the given variable.
- *
- * @param mv
- * visitor to create code
- * @param variable
- * variable index to store probe array to
- * @return maximum stack size required by the generated code
- */
- int storeInstance(MethodVisitor mv, int variable);
-
- /**
- * Adds additional class members required by this strategy.
- *
- * @param delegate
- * visitor to create fields and classes
- */
- void addMembers(ClassVisitor delegate);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.instr; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; + +/** + * Strategies to retrieve the probe array instance for each method within a + * type. This abstraction is required as we need to follow a different strategy + * depending on whether the instrumented type is a class or interface. + */ +interface IProbeArrayStrategy { + + /** + * Creates code that stores the probe array instance in the given variable. + * + * @param mv + * visitor to create code + * @param variable + * variable index to store probe array to + * @return maximum stack size required by the generated code + */ + int storeInstance(MethodVisitor mv, int variable); + + /** + * Adds additional class members required by this strategy. + * + * @param delegate + * visitor to create fields and classes + */ + void addMembers(ClassVisitor delegate); + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java index 5383a426..46972098 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java @@ -1,87 +1,87 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Constants and utilities for byte code instrumentation.
- */
-public final class InstrSupport {
-
- private InstrSupport() {
- }
-
- // === Data Field ===
-
- /**
- * Name of the field that stores coverage information of a class.
- */
- public static final String DATAFIELD_NAME = "$jacocoData";
-
- /**
- * Access modifiers of the field that stores coverage information of a
- * class.
- */
- public static final int DATAFIELD_ACC = Opcodes.ACC_SYNTHETIC
- | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT;
-
- /**
- * Data type of the field that stores coverage information for a class (
- * <code>boolean[]</code>).
- */
- public static final String DATAFIELD_DESC = "[Z";
-
- // === Init Method ===
-
- /**
- * Name of the initialization method.
- */
- public static final String INITMETHOD_NAME = "$jacocoInit";
-
- /**
- * Descriptor of the initialization method.
- */
- public static final String INITMETHOD_DESC = "()[Z";
-
- /**
- * Access modifiers of the initialization method.
- */
- public static final int INITMETHOD_ACC = Opcodes.ACC_SYNTHETIC
- | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
-
- // === Utilities ===
-
- /**
- * Generates the instruction to push the given int value on the stack.
- * Implementation taken from
- * {@link org.objectweb.asm.commons.GeneratorAdapter#push(int)}.
- *
- * @param mv
- * visitor to emit the instruction
- * @param value
- * the value to be pushed on the stack.
- */
- public static void push(final MethodVisitor mv, final int value) {
- if (value >= -1 && value <= 5) {
- mv.visitInsn(Opcodes.ICONST_0 + value);
- } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
- mv.visitIntInsn(Opcodes.BIPUSH, value);
- } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
- mv.visitIntInsn(Opcodes.SIPUSH, value);
- } else {
- mv.visitLdcInsn(Integer.valueOf(value));
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.instr; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Constants and utilities for byte code instrumentation. + */ +public final class InstrSupport { + + private InstrSupport() { + } + + // === Data Field === + + /** + * Name of the field that stores coverage information of a class. + */ + public static final String DATAFIELD_NAME = "$jacocoData"; + + /** + * Access modifiers of the field that stores coverage information of a + * class. + */ + public static final int DATAFIELD_ACC = Opcodes.ACC_SYNTHETIC + | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT; + + /** + * Data type of the field that stores coverage information for a class ( + * <code>boolean[]</code>). + */ + public static final String DATAFIELD_DESC = "[Z"; + + // === Init Method === + + /** + * Name of the initialization method. + */ + public static final String INITMETHOD_NAME = "$jacocoInit"; + + /** + * Descriptor of the initialization method. + */ + public static final String INITMETHOD_DESC = "()[Z"; + + /** + * Access modifiers of the initialization method. + */ + public static final int INITMETHOD_ACC = Opcodes.ACC_SYNTHETIC + | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL; + + // === Utilities === + + /** + * Generates the instruction to push the given int value on the stack. + * Implementation taken from + * {@link org.objectweb.asm.commons.GeneratorAdapter#push(int)}. + * + * @param mv + * visitor to emit the instruction + * @param value + * the value to be pushed on the stack. + */ + public static void push(final MethodVisitor mv, final int value) { + if (value >= -1 && value <= 5) { + mv.visitInsn(Opcodes.ICONST_0 + value); + } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { + mv.visitIntInsn(Opcodes.BIPUSH, value); + } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { + mv.visitIntInsn(Opcodes.SIPUSH, value); + } else { + mv.visitLdcInsn(Integer.valueOf(value)); + } + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/MethodInstrumenter.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/MethodInstrumenter.java index f203e019..9ec0b4cf 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/instr/MethodInstrumenter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/MethodInstrumenter.java @@ -1,182 +1,182 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import org.jacoco.core.internal.flow.IMethodProbesVisitor;
-import org.jacoco.core.internal.flow.LabelInfo;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodAdapter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * This method adapter inserts probes as requested by the
- * {@link IMethodProbesVisitor} events.
- */
-class MethodInstrumenter extends MethodAdapter implements IMethodProbesVisitor {
-
- private final IProbeInserter probeInserter;
- private final IFrameInserter frameInserter;
-
- /**
- * Create a new instrumenter instance for the given method.
- *
- * @param mv
- * next method visitor in the chain
- * @param probeInserter
- * call-back to insert probes where required
- * @param frameInserter
- * call-back to insert additional frames where required
- */
- public MethodInstrumenter(final MethodVisitor mv,
- final IProbeInserter probeInserter,
- final IFrameInserter frameInserter) {
- super(mv);
- this.probeInserter = probeInserter;
- this.frameInserter = frameInserter;
- }
-
- // === IMethodProbesVisitor ===
-
- public void visitProbe(final int probeId) {
- probeInserter.insertProbe(probeId);
- }
-
- public void visitInsnWithProbe(final int opcode, final int probeId) {
- probeInserter.insertProbe(probeId);
- mv.visitInsn(opcode);
- }
-
- public void visitJumpInsnWithProbe(final int opcode, final Label label,
- final int probeId) {
- if (opcode == Opcodes.GOTO) {
- probeInserter.insertProbe(probeId);
- mv.visitJumpInsn(Opcodes.GOTO, label);
- } else {
- final Label intermediate = new Label();
- mv.visitJumpInsn(getInverted(opcode), intermediate);
- probeInserter.insertProbe(probeId);
- mv.visitJumpInsn(Opcodes.GOTO, label);
- mv.visitLabel(intermediate);
- frameInserter.insertFrame();
- }
- }
-
- private int getInverted(final int opcode) {
- switch (opcode) {
- case Opcodes.IFEQ:
- return Opcodes.IFNE;
- case Opcodes.IFNE:
- return Opcodes.IFEQ;
- case Opcodes.IFLT:
- return Opcodes.IFGE;
- case Opcodes.IFGE:
- return Opcodes.IFLT;
- case Opcodes.IFGT:
- return Opcodes.IFLE;
- case Opcodes.IFLE:
- return Opcodes.IFGT;
- case Opcodes.IF_ICMPEQ:
- return Opcodes.IF_ICMPNE;
- case Opcodes.IF_ICMPNE:
- return Opcodes.IF_ICMPEQ;
- case Opcodes.IF_ICMPLT:
- return Opcodes.IF_ICMPGE;
- case Opcodes.IF_ICMPGE:
- return Opcodes.IF_ICMPLT;
- case Opcodes.IF_ICMPGT:
- return Opcodes.IF_ICMPLE;
- case Opcodes.IF_ICMPLE:
- return Opcodes.IF_ICMPGT;
- case Opcodes.IF_ACMPEQ:
- return Opcodes.IF_ACMPNE;
- case Opcodes.IF_ACMPNE:
- return Opcodes.IF_ACMPEQ;
- case Opcodes.IFNULL:
- return Opcodes.IFNONNULL;
- case Opcodes.IFNONNULL:
- return Opcodes.IFNULL;
- }
- throw new IllegalArgumentException();
- }
-
- public void visitTableSwitchInsnWithProbes(final int min, final int max,
- final Label dflt, final Label[] labels) {
- // 1. Calculate intermediate labels:
- LabelInfo.resetDone(dflt);
- LabelInfo.resetDone(labels);
- final Label newDflt = createIntermediate(dflt);
- final Label[] newLabels = createIntermediates(labels);
- mv.visitTableSwitchInsn(min, max, newDflt, newLabels);
-
- // 2. Insert probes:
- insertIntermediateProbes(dflt, labels);
- }
-
- public void visitLookupSwitchInsnWithProbes(final Label dflt,
- final int[] keys, final Label[] labels) {
- // 1. Calculate intermediate labels:
- LabelInfo.resetDone(dflt);
- LabelInfo.resetDone(labels);
- final Label newDflt = createIntermediate(dflt);
- final Label[] newLabels = createIntermediates(labels);
- mv.visitLookupSwitchInsn(newDflt, keys, newLabels);
-
- // 2. Insert probes:
- insertIntermediateProbes(dflt, labels);
- }
-
- private Label[] createIntermediates(final Label[] labels) {
- final Label[] intermediates = new Label[labels.length];
- for (int i = 0; i < labels.length; i++) {
- intermediates[i] = createIntermediate(labels[i]);
- }
- return intermediates;
- }
-
- private Label createIntermediate(final Label label) {
- final Label intermediate;
- if (LabelInfo.getProbeId(label) == LabelInfo.NO_PROBE) {
- intermediate = label;
- } else {
- if (LabelInfo.isDone(label)) {
- intermediate = LabelInfo.getIntermediateLabel(label);
- } else {
- intermediate = new Label();
- LabelInfo.setIntermediateLabel(label, intermediate);
- LabelInfo.setDone(label);
- }
- }
- return intermediate;
- }
-
- private void insertIntermediateProbe(final Label label) {
- final int probeId = LabelInfo.getProbeId(label);
- if (probeId != LabelInfo.NO_PROBE && !LabelInfo.isDone(label)) {
- mv.visitLabel(LabelInfo.getIntermediateLabel(label));
- frameInserter.insertFrame();
- probeInserter.insertProbe(probeId);
- mv.visitJumpInsn(Opcodes.GOTO, label);
- LabelInfo.setDone(label);
- }
- }
-
- private void insertIntermediateProbes(final Label dflt, final Label[] labels) {
- LabelInfo.resetDone(dflt);
- LabelInfo.resetDone(labels);
- insertIntermediateProbe(dflt);
- for (final Label l : labels) {
- insertIntermediateProbe(l);
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.instr; + +import org.jacoco.core.internal.flow.IMethodProbesVisitor; +import org.jacoco.core.internal.flow.LabelInfo; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodAdapter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * This method adapter inserts probes as requested by the + * {@link IMethodProbesVisitor} events. + */ +class MethodInstrumenter extends MethodAdapter implements IMethodProbesVisitor { + + private final IProbeInserter probeInserter; + private final IFrameInserter frameInserter; + + /** + * Create a new instrumenter instance for the given method. + * + * @param mv + * next method visitor in the chain + * @param probeInserter + * call-back to insert probes where required + * @param frameInserter + * call-back to insert additional frames where required + */ + public MethodInstrumenter(final MethodVisitor mv, + final IProbeInserter probeInserter, + final IFrameInserter frameInserter) { + super(mv); + this.probeInserter = probeInserter; + this.frameInserter = frameInserter; + } + + // === IMethodProbesVisitor === + + public void visitProbe(final int probeId) { + probeInserter.insertProbe(probeId); + } + + public void visitInsnWithProbe(final int opcode, final int probeId) { + probeInserter.insertProbe(probeId); + mv.visitInsn(opcode); + } + + public void visitJumpInsnWithProbe(final int opcode, final Label label, + final int probeId) { + if (opcode == Opcodes.GOTO) { + probeInserter.insertProbe(probeId); + mv.visitJumpInsn(Opcodes.GOTO, label); + } else { + final Label intermediate = new Label(); + mv.visitJumpInsn(getInverted(opcode), intermediate); + probeInserter.insertProbe(probeId); + mv.visitJumpInsn(Opcodes.GOTO, label); + mv.visitLabel(intermediate); + frameInserter.insertFrame(); + } + } + + private int getInverted(final int opcode) { + switch (opcode) { + case Opcodes.IFEQ: + return Opcodes.IFNE; + case Opcodes.IFNE: + return Opcodes.IFEQ; + case Opcodes.IFLT: + return Opcodes.IFGE; + case Opcodes.IFGE: + return Opcodes.IFLT; + case Opcodes.IFGT: + return Opcodes.IFLE; + case Opcodes.IFLE: + return Opcodes.IFGT; + case Opcodes.IF_ICMPEQ: + return Opcodes.IF_ICMPNE; + case Opcodes.IF_ICMPNE: + return Opcodes.IF_ICMPEQ; + case Opcodes.IF_ICMPLT: + return Opcodes.IF_ICMPGE; + case Opcodes.IF_ICMPGE: + return Opcodes.IF_ICMPLT; + case Opcodes.IF_ICMPGT: + return Opcodes.IF_ICMPLE; + case Opcodes.IF_ICMPLE: + return Opcodes.IF_ICMPGT; + case Opcodes.IF_ACMPEQ: + return Opcodes.IF_ACMPNE; + case Opcodes.IF_ACMPNE: + return Opcodes.IF_ACMPEQ; + case Opcodes.IFNULL: + return Opcodes.IFNONNULL; + case Opcodes.IFNONNULL: + return Opcodes.IFNULL; + } + throw new IllegalArgumentException(); + } + + public void visitTableSwitchInsnWithProbes(final int min, final int max, + final Label dflt, final Label[] labels) { + // 1. Calculate intermediate labels: + LabelInfo.resetDone(dflt); + LabelInfo.resetDone(labels); + final Label newDflt = createIntermediate(dflt); + final Label[] newLabels = createIntermediates(labels); + mv.visitTableSwitchInsn(min, max, newDflt, newLabels); + + // 2. Insert probes: + insertIntermediateProbes(dflt, labels); + } + + public void visitLookupSwitchInsnWithProbes(final Label dflt, + final int[] keys, final Label[] labels) { + // 1. Calculate intermediate labels: + LabelInfo.resetDone(dflt); + LabelInfo.resetDone(labels); + final Label newDflt = createIntermediate(dflt); + final Label[] newLabels = createIntermediates(labels); + mv.visitLookupSwitchInsn(newDflt, keys, newLabels); + + // 2. Insert probes: + insertIntermediateProbes(dflt, labels); + } + + private Label[] createIntermediates(final Label[] labels) { + final Label[] intermediates = new Label[labels.length]; + for (int i = 0; i < labels.length; i++) { + intermediates[i] = createIntermediate(labels[i]); + } + return intermediates; + } + + private Label createIntermediate(final Label label) { + final Label intermediate; + if (LabelInfo.getProbeId(label) == LabelInfo.NO_PROBE) { + intermediate = label; + } else { + if (LabelInfo.isDone(label)) { + intermediate = LabelInfo.getIntermediateLabel(label); + } else { + intermediate = new Label(); + LabelInfo.setIntermediateLabel(label, intermediate); + LabelInfo.setDone(label); + } + } + return intermediate; + } + + private void insertIntermediateProbe(final Label label) { + final int probeId = LabelInfo.getProbeId(label); + if (probeId != LabelInfo.NO_PROBE && !LabelInfo.isDone(label)) { + mv.visitLabel(LabelInfo.getIntermediateLabel(label)); + frameInserter.insertFrame(); + probeInserter.insertProbe(probeId); + mv.visitJumpInsn(Opcodes.GOTO, label); + LabelInfo.setDone(label); + } + } + + private void insertIntermediateProbes(final Label dflt, final Label[] labels) { + LabelInfo.resetDone(dflt); + LabelInfo.resetDone(labels); + insertIntermediateProbe(dflt); + for (final Label l : labels) { + insertIntermediateProbe(l); + } + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java index aa0c1271..363c7aba 100644 --- a/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java +++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java @@ -1,262 +1,262 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodAdapter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.tree.InsnList;
-import org.objectweb.asm.tree.LabelNode;
-import org.objectweb.asm.tree.LineNumberNode;
-
-/**
- * Internal utility to add probes into the control flow of a method. The code
- * for a probe simply sets a certain slot of a boolean array to true. In
- * addition the probe array has to be retrieved at the beginning of the method
- * and stored in a local variable.
- */
-class ProbeInserter extends MethodAdapter implements IProbeInserter {
-
- private final IProbeArrayStrategy arrayStrategy;
-
- /** Position of the inserted variable. */
- private final int variable;
-
- /** Index the inserted variable. */
- private final int variableIdx;
-
- /** Indicated whether the probe variable has already been inserted. */
- private boolean inserted;
-
- /** Maximum stack usage of the code to access the probe array. */
- private int accessorStackSize;
-
- /** Labels and line numbers preceding the first real instruction. */
- private final InsnList prolog;
-
- /**
- * Creates a new {@link ProbeInserter}.
- *
- * @param access
- * access flags of the adapted method.
- * @param desc
- * the method's descriptor
- * @param mv
- * the method visitor to which this adapter delegates calls
- * @param arrayStrategy
- * callback to create the code that retrieves the reference to
- * the probe array
- */
- ProbeInserter(final int access, final String desc, final MethodVisitor mv,
- final IProbeArrayStrategy arrayStrategy) {
- super(mv);
- this.arrayStrategy = arrayStrategy;
- int idx = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
- int pos = idx;
- for (final Type t : Type.getArgumentTypes(desc)) {
- idx++;
- pos += t.getSize();
- }
- variableIdx = idx;
- variable = pos;
- inserted = false;
- prolog = new InsnList();
- }
-
- public void insertProbe(final int id) {
-
- checkLoad();
- // For a probe we set the corresponding position in the boolean[] array
- // to true.
-
- mv.visitVarInsn(Opcodes.ALOAD, variable);
-
- // Stack[0]: [Z
-
- InstrSupport.push(mv, id);
-
- // Stack[1]: I
- // Stack[0]: [Z
-
- mv.visitInsn(Opcodes.ICONST_1);
-
- // Stack[2]: I
- // Stack[1]: I
- // Stack[0]: [Z
-
- mv.visitInsn(Opcodes.BASTORE);
- }
-
- private void checkLoad() {
- if (!inserted) {
- accessorStackSize = arrayStrategy.storeInstance(mv, variable);
- prolog.accept(mv);
- inserted = true;
- }
- }
-
- @Override
- public final void visitLabel(final Label label) {
- if (!inserted) {
- prolog.add(new LabelNode(label));
- } else {
- mv.visitLabel(label);
- }
- }
-
- @Override
- public void visitLineNumber(final int line, final Label start) {
- if (!inserted) {
- prolog.add(new LineNumberNode(line, new LabelNode(start)));
- } else {
- mv.visitLineNumber(line, start);
- }
- }
-
- @Override
- public final void visitVarInsn(final int opcode, final int var) {
- checkLoad();
- mv.visitVarInsn(opcode, map(var));
- }
-
- @Override
- public final void visitIincInsn(final int var, final int increment) {
- checkLoad();
- mv.visitIincInsn(map(var), increment);
- }
-
- @Override
- public final void visitLocalVariable(final String name, final String desc,
- final String signature, final Label start, final Label end,
- final int index) {
- checkLoad();
- mv.visitLocalVariable(name, desc, signature, start, end, map(index));
- }
-
- @Override
- public final void visitInsn(final int opcode) {
- checkLoad();
- mv.visitInsn(opcode);
- }
-
- @Override
- public final void visitIntInsn(final int opcode, final int operand) {
- checkLoad();
- mv.visitIntInsn(opcode, operand);
- }
-
- @Override
- public final void visitTypeInsn(final int opcode, final String type) {
- checkLoad();
- mv.visitTypeInsn(opcode, type);
- }
-
- @Override
- public final void visitFieldInsn(final int opcode, final String owner,
- final String name, final String desc) {
- checkLoad();
- mv.visitFieldInsn(opcode, owner, name, desc);
- }
-
- @Override
- public final void visitMethodInsn(final int opcode, final String owner,
- final String name, final String desc) {
- checkLoad();
- mv.visitMethodInsn(opcode, owner, name, desc);
- }
-
- @Override
- public final void visitJumpInsn(final int opcode, final Label label) {
- checkLoad();
- mv.visitJumpInsn(opcode, label);
- }
-
- @Override
- public final void visitLdcInsn(final Object cst) {
- checkLoad();
- mv.visitLdcInsn(cst);
- }
-
- @Override
- public final void visitTableSwitchInsn(final int min, final int max,
- final Label dflt, final Label[] labels) {
- checkLoad();
- mv.visitTableSwitchInsn(min, max, dflt, labels);
- }
-
- @Override
- public final void visitLookupSwitchInsn(final Label dflt, final int[] keys,
- final Label[] labels) {
- checkLoad();
- mv.visitLookupSwitchInsn(dflt, keys, labels);
- }
-
- @Override
- public final void visitMultiANewArrayInsn(final String desc, final int dims) {
- checkLoad();
- mv.visitMultiANewArrayInsn(desc, dims);
- }
-
- @Override
- public void visitMaxs(final int maxStack, final int maxLocals) {
- // Max stack size of the probe code is 3 which can add to the
- // original stack size depending on the probe locations. The accessor
- // stack size is an absolute maximum, as the accessor code is inserted
- // at the very beginning of each method when the stack size is empty.
- final int increasedStack = Math.max(maxStack + 3, accessorStackSize);
- mv.visitMaxs(increasedStack, maxLocals + 1);
- }
-
- private int map(final int var) {
- if (var < variable) {
- return var;
- } else {
- return var + 1;
- }
- }
-
- @Override
- public final void visitFrame(final int type, final int nLocal,
- final Object[] local, final int nStack, final Object[] stack) {
-
- if (type != Opcodes.F_NEW) { // uncompressed frame
- throw new IllegalArgumentException(
- "ClassReader.accept() should be called with EXPAND_FRAMES flag");
- }
-
- if (inserted) {
- final int n = Math.max(nLocal, variableIdx) + 1;
- final Object[] newLocal = new Object[n];
- for (int i = 0; i < n; i++) {
- if (i < variableIdx) {
- // For dead code it is possible to specify less locals than
- // we have method parameters.
- newLocal[i] = i < nLocal ? local[i] : Opcodes.TOP;
- continue;
- }
- if (i > variableIdx) {
- newLocal[i] = local[i - 1];
- continue;
- }
- newLocal[i] = InstrSupport.DATAFIELD_DESC;
- }
- mv.visitFrame(type, n, newLocal, nStack, stack);
- } else {
- mv.visitFrame(type, nLocal, local, nStack, stack);
- }
-
- checkLoad();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.internal.instr; + +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodAdapter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.LabelNode; +import org.objectweb.asm.tree.LineNumberNode; + +/** + * Internal utility to add probes into the control flow of a method. The code + * for a probe simply sets a certain slot of a boolean array to true. In + * addition the probe array has to be retrieved at the beginning of the method + * and stored in a local variable. + */ +class ProbeInserter extends MethodAdapter implements IProbeInserter { + + private final IProbeArrayStrategy arrayStrategy; + + /** Position of the inserted variable. */ + private final int variable; + + /** Index the inserted variable. */ + private final int variableIdx; + + /** Indicated whether the probe variable has already been inserted. */ + private boolean inserted; + + /** Maximum stack usage of the code to access the probe array. */ + private int accessorStackSize; + + /** Labels and line numbers preceding the first real instruction. */ + private final InsnList prolog; + + /** + * Creates a new {@link ProbeInserter}. + * + * @param access + * access flags of the adapted method. + * @param desc + * the method's descriptor + * @param mv + * the method visitor to which this adapter delegates calls + * @param arrayStrategy + * callback to create the code that retrieves the reference to + * the probe array + */ + ProbeInserter(final int access, final String desc, final MethodVisitor mv, + final IProbeArrayStrategy arrayStrategy) { + super(mv); + this.arrayStrategy = arrayStrategy; + int idx = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0; + int pos = idx; + for (final Type t : Type.getArgumentTypes(desc)) { + idx++; + pos += t.getSize(); + } + variableIdx = idx; + variable = pos; + inserted = false; + prolog = new InsnList(); + } + + public void insertProbe(final int id) { + + checkLoad(); + // For a probe we set the corresponding position in the boolean[] array + // to true. + + mv.visitVarInsn(Opcodes.ALOAD, variable); + + // Stack[0]: [Z + + InstrSupport.push(mv, id); + + // Stack[1]: I + // Stack[0]: [Z + + mv.visitInsn(Opcodes.ICONST_1); + + // Stack[2]: I + // Stack[1]: I + // Stack[0]: [Z + + mv.visitInsn(Opcodes.BASTORE); + } + + private void checkLoad() { + if (!inserted) { + accessorStackSize = arrayStrategy.storeInstance(mv, variable); + prolog.accept(mv); + inserted = true; + } + } + + @Override + public final void visitLabel(final Label label) { + if (!inserted) { + prolog.add(new LabelNode(label)); + } else { + mv.visitLabel(label); + } + } + + @Override + public void visitLineNumber(final int line, final Label start) { + if (!inserted) { + prolog.add(new LineNumberNode(line, new LabelNode(start))); + } else { + mv.visitLineNumber(line, start); + } + } + + @Override + public final void visitVarInsn(final int opcode, final int var) { + checkLoad(); + mv.visitVarInsn(opcode, map(var)); + } + + @Override + public final void visitIincInsn(final int var, final int increment) { + checkLoad(); + mv.visitIincInsn(map(var), increment); + } + + @Override + public final void visitLocalVariable(final String name, final String desc, + final String signature, final Label start, final Label end, + final int index) { + checkLoad(); + mv.visitLocalVariable(name, desc, signature, start, end, map(index)); + } + + @Override + public final void visitInsn(final int opcode) { + checkLoad(); + mv.visitInsn(opcode); + } + + @Override + public final void visitIntInsn(final int opcode, final int operand) { + checkLoad(); + mv.visitIntInsn(opcode, operand); + } + + @Override + public final void visitTypeInsn(final int opcode, final String type) { + checkLoad(); + mv.visitTypeInsn(opcode, type); + } + + @Override + public final void visitFieldInsn(final int opcode, final String owner, + final String name, final String desc) { + checkLoad(); + mv.visitFieldInsn(opcode, owner, name, desc); + } + + @Override + public final void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc) { + checkLoad(); + mv.visitMethodInsn(opcode, owner, name, desc); + } + + @Override + public final void visitJumpInsn(final int opcode, final Label label) { + checkLoad(); + mv.visitJumpInsn(opcode, label); + } + + @Override + public final void visitLdcInsn(final Object cst) { + checkLoad(); + mv.visitLdcInsn(cst); + } + + @Override + public final void visitTableSwitchInsn(final int min, final int max, + final Label dflt, final Label[] labels) { + checkLoad(); + mv.visitTableSwitchInsn(min, max, dflt, labels); + } + + @Override + public final void visitLookupSwitchInsn(final Label dflt, final int[] keys, + final Label[] labels) { + checkLoad(); + mv.visitLookupSwitchInsn(dflt, keys, labels); + } + + @Override + public final void visitMultiANewArrayInsn(final String desc, final int dims) { + checkLoad(); + mv.visitMultiANewArrayInsn(desc, dims); + } + + @Override + public void visitMaxs(final int maxStack, final int maxLocals) { + // Max stack size of the probe code is 3 which can add to the + // original stack size depending on the probe locations. The accessor + // stack size is an absolute maximum, as the accessor code is inserted + // at the very beginning of each method when the stack size is empty. + final int increasedStack = Math.max(maxStack + 3, accessorStackSize); + mv.visitMaxs(increasedStack, maxLocals + 1); + } + + private int map(final int var) { + if (var < variable) { + return var; + } else { + return var + 1; + } + } + + @Override + public final void visitFrame(final int type, final int nLocal, + final Object[] local, final int nStack, final Object[] stack) { + + if (type != Opcodes.F_NEW) { // uncompressed frame + throw new IllegalArgumentException( + "ClassReader.accept() should be called with EXPAND_FRAMES flag"); + } + + if (inserted) { + final int n = Math.max(nLocal, variableIdx) + 1; + final Object[] newLocal = new Object[n]; + for (int i = 0; i < n; i++) { + if (i < variableIdx) { + // For dead code it is possible to specify less locals than + // we have method parameters. + newLocal[i] = i < nLocal ? local[i] : Opcodes.TOP; + continue; + } + if (i > variableIdx) { + newLocal[i] = local[i - 1]; + continue; + } + newLocal[i] = InstrSupport.DATAFIELD_DESC; + } + mv.visitFrame(type, n, newLocal, nStack, stack); + } else { + mv.visitFrame(type, nLocal, local, nStack, stack); + } + + checkLoad(); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/jacoco.properties b/org.jacoco.core/src/org/jacoco/core/jacoco.properties index 6f5972e7..d9c32698 100644 --- a/org.jacoco.core/src/org/jacoco/core/jacoco.properties +++ b/org.jacoco.core/src/org/jacoco/core/jacoco.properties @@ -1,2 +1,2 @@ -VERSION=$qualified.bundle.version$
+VERSION=$qualified.bundle.version$ HOMEURL=$jacoco.home.url$
\ No newline at end of file diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/AbstractRuntime.java b/org.jacoco.core/src/org/jacoco/core/runtime/AbstractRuntime.java index c1462eb1..63d89a57 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/AbstractRuntime.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/AbstractRuntime.java @@ -1,105 +1,105 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import java.lang.reflect.Field;
-import java.util.Random;
-
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.data.IExecutionDataVisitor;
-import org.jacoco.core.data.ISessionInfoVisitor;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.core.internal.instr.InstrSupport;
-
-/**
- * Base {@link IRuntime} implementation.
- */
-public abstract class AbstractRuntime implements IRuntime {
-
- /** store for execution data */
- protected final ExecutionDataStore store;
-
- /** access for this runtime instance */
- protected final ExecutionDataAccess access;
-
- private long startTimeStamp;
-
- private String sessionId;
-
- /**
- * Creates a new runtime.
- */
- protected AbstractRuntime() {
- store = new ExecutionDataStore();
- access = new ExecutionDataAccess(store);
- sessionId = createRandomId();
- }
-
- /**
- * Subclasses need to call this method in their {@link #startup()}
- * implementation to record the timestamp of session startup.
- */
- protected final void setStartTimeStamp() {
- startTimeStamp = System.currentTimeMillis();
- }
-
- public void setSessionId(final String id) {
- sessionId = id;
- }
-
- public String getSessionId() {
- return sessionId;
- }
-
- public final void collect(final IExecutionDataVisitor executionDataVisitor,
- final ISessionInfoVisitor sessionInfoVisitor, final boolean reset) {
- synchronized (store) {
- if (sessionInfoVisitor != null) {
- final SessionInfo info = new SessionInfo(sessionId,
- startTimeStamp, System.currentTimeMillis());
- sessionInfoVisitor.visitSessionInfo(info);
- }
- store.accept(executionDataVisitor);
- if (reset) {
- reset();
- }
- }
- }
-
- public final void reset() {
- synchronized (store) {
- store.reset();
- setStartTimeStamp();
- }
- }
-
- public void disconnect(final Class<?> type) throws Exception {
- if (!type.isInterface()) {
- final Field dataField = type
- .getDeclaredField(InstrSupport.DATAFIELD_NAME);
- dataField.setAccessible(true);
- dataField.set(null, null);
- }
- }
-
- private static final Random RANDOM = new Random();
-
- /**
- * Creates a random session identifier.
- *
- * @return random session identifier
- */
- public static String createRandomId() {
- return Integer.toHexString(RANDOM.nextInt());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import java.lang.reflect.Field; +import java.util.Random; + +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.IExecutionDataVisitor; +import org.jacoco.core.data.ISessionInfoVisitor; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.internal.instr.InstrSupport; + +/** + * Base {@link IRuntime} implementation. + */ +public abstract class AbstractRuntime implements IRuntime { + + /** store for execution data */ + protected final ExecutionDataStore store; + + /** access for this runtime instance */ + protected final ExecutionDataAccess access; + + private long startTimeStamp; + + private String sessionId; + + /** + * Creates a new runtime. + */ + protected AbstractRuntime() { + store = new ExecutionDataStore(); + access = new ExecutionDataAccess(store); + sessionId = createRandomId(); + } + + /** + * Subclasses need to call this method in their {@link #startup()} + * implementation to record the timestamp of session startup. + */ + protected final void setStartTimeStamp() { + startTimeStamp = System.currentTimeMillis(); + } + + public void setSessionId(final String id) { + sessionId = id; + } + + public String getSessionId() { + return sessionId; + } + + public final void collect(final IExecutionDataVisitor executionDataVisitor, + final ISessionInfoVisitor sessionInfoVisitor, final boolean reset) { + synchronized (store) { + if (sessionInfoVisitor != null) { + final SessionInfo info = new SessionInfo(sessionId, + startTimeStamp, System.currentTimeMillis()); + sessionInfoVisitor.visitSessionInfo(info); + } + store.accept(executionDataVisitor); + if (reset) { + reset(); + } + } + } + + public final void reset() { + synchronized (store) { + store.reset(); + setStartTimeStamp(); + } + } + + public void disconnect(final Class<?> type) throws Exception { + if (!type.isInterface()) { + final Field dataField = type + .getDeclaredField(InstrSupport.DATAFIELD_NAME); + dataField.setAccessible(true); + dataField.set(null, null); + } + } + + private static final Random RANDOM = new Random(); + + /** + * Creates a random session identifier. + * + * @return random session identifier + */ + public static String createRandomId() { + return Integer.toHexString(RANDOM.nextInt()); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java b/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java index 16067a6c..b3744f6b 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/AgentOptions.java @@ -1,507 +1,507 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import static java.lang.String.format;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Utility to create and parse options for the runtime agent. Options are
- * represented as a string in the following format:
- *
- * <pre>
- * key1=value1,key2=value2,key3=value3
- * </pre>
- */
-public final class AgentOptions {
-
- /**
- * Specifies the output file for execution data. Default is
- * <code>jacoco.exec</code> in the working directory.
- */
- public static final String DESTFILE = "destfile";
-
- /**
- * Specifies whether execution data should be appended to the output file.
- * Default is <code>true</code>.
- */
- public static final String APPEND = "append";
-
- /**
- * Wildcard expression for class names that should be included for code
- * coverage. Default is <code>*</code> (all classes included).
- *
- * @see WildcardMatcher
- */
- public static final String INCLUDES = "includes";
-
- /**
- * Wildcard expression for class names that should be excluded from code
- * coverage. Default is the empty string (no exclusions).
- *
- * @see WildcardMatcher
- */
- public static final String EXCLUDES = "excludes";
-
- /**
- * Wildcard expression for class loaders names for classes that should be
- * excluded from code coverage. This means all classes loaded by a class
- * loader which full qualified name matches this expression will be ignored
- * for code coverage regardless of all other filtering settings. Default is
- * <code>sun.reflect.DelegatingClassLoader</code>.
- *
- * @see WildcardMatcher
- */
- public static final String EXCLCLASSLOADER = "exclclassloader";
-
- /**
- * Specifies a session identifier that is written with the execution data.
- * Without this parameter a random identifier is created by the agent.
- */
- public static final String SESSIONID = "sessionid";
-
- /**
- * Specifies whether the agent will automatically dump coverage data on VM
- * exit. Default is <code>true</code>.
- */
- public static final String DUMPONEXIT = "dumponexit";
-
- /**
- * Specifies the output mode. Default is
- * <code>{@link OutputMode#file}</code>.
- *
- * @see OutputMode#file
- * @see OutputMode#tcpserver
- * @see OutputMode#tcpclient
- */
- public static final String OUTPUT = "output";
-
- /**
- * Possible values for {@link AgentOptions#OUTPUT}.
- */
- public static enum OutputMode {
-
- /**
- * Value for the {@link AgentOptions#OUTPUT} parameter: At VM
- * termination execution data is written to the file specified by
- * {@link AgentOptions#DESTFILE}.
- */
- file,
-
- /**
- * Value for the {@link AgentOptions#OUTPUT} parameter: The agent
- * listens for incoming connections on a TCP port specified by
- * {@link AgentOptions#ADDRESS} and {@link AgentOptions#PORT}.
- */
- tcpserver,
-
- /**
- * Value for the {@link AgentOptions#OUTPUT} parameter: At startup the
- * agent connects to a TCP port specified by the
- * {@link AgentOptions#ADDRESS} and {@link AgentOptions#PORT} attribute.
- */
- tcpclient,
-
- /**
- * Value for the {@link AgentOptions#OUTPUT} parameter: At startup the
- * agent creates MBean.
- */
- mbean
-
- }
-
- /**
- * The IP address or DNS name the tcpserver binds to or the tcpclient
- * connects to. Default is defined by {@link #DEFAULT_ADDRESS}.
- */
- public static final String ADDRESS = "address";
-
- /**
- * Default value for the "address" agent option.
- */
- public static final String DEFAULT_ADDRESS = null;
-
- /**
- * The port the tcpserver binds to or the tcpclient connects to. In
- * tcpserver mode the port must be available, which means that if multiple
- * JaCoCo agents should run on the same machine, different ports have to be
- * specified. Default is defined by {@link #DEFAULT_PORT}.
- */
- public static final String PORT = "port";
-
- /**
- * Default value for the "port" agent option.
- */
- public static final int DEFAULT_PORT = 6300;
-
- /**
- * Specifies where the agent dumps all class files it encounters. The
- * location is specified as a relative path to the working directory.
- * Default is <code>null</code> (no dumps).
- */
- public static final String CLASSDUMPDIR = "classdumpdir";
-
- private static final Collection<String> VALID_OPTIONS = Arrays.asList(
- DESTFILE, APPEND, INCLUDES, EXCLUDES, EXCLCLASSLOADER, SESSIONID,
- DUMPONEXIT, OUTPUT, ADDRESS, PORT, CLASSDUMPDIR);
-
- private final Map<String, String> options;
-
- /**
- * New instance with all values set to default.
- */
- public AgentOptions() {
- this.options = new HashMap<String, String>();
- }
-
- /**
- * New instance parsed from the given option string.
- *
- * @param optionstr
- * string to parse or <code>null</code>
- */
- public AgentOptions(final String optionstr) {
- this();
- if (optionstr != null && optionstr.length() > 0) {
- for (final String entry : optionstr.split(",")) {
- final int pos = entry.indexOf('=');
- if (pos == -1) {
- throw new IllegalArgumentException(format(
- "Invalid agent option syntax \"%s\".", optionstr));
- }
- final String key = entry.substring(0, pos);
- if (!VALID_OPTIONS.contains(key)) {
- throw new IllegalArgumentException(format(
- "Unknown agent option \"%s\".", key));
- }
-
- final String value = entry.substring(pos + 1);
- setOption(key, value);
- }
-
- validateAll();
- }
- }
-
- private void validateAll() {
- validatePort(getPort());
- getOutput();
- }
-
- private void validatePort(final int port) {
- if (port < 0) {
- throw new IllegalArgumentException("port must be positive");
- }
- }
-
- /**
- * Returns the output file location.
- *
- * @return output file location
- */
- public String getDestfile() {
- return getOption(DESTFILE, "jacoco.exec");
- }
-
- /**
- * Sets the output file location.
- *
- * @param destfile
- * output file location
- */
- public void setDestfile(final String destfile) {
- setOption(DESTFILE, destfile);
- }
-
- /**
- * Returns whether the output should be appended to an existing file.
- *
- * @return <code>true</code>, when the output should be appended
- */
- public boolean getAppend() {
- return getOption(APPEND, true);
- }
-
- /**
- * Sets whether the output should be appended to an existing file.
- *
- * @param append
- * <code>true</code>, when the output should be appended
- */
- public void setAppend(final boolean append) {
- setOption(APPEND, append);
- }
-
- /**
- * Returns the wildcard expression for classes to include.
- *
- * @return wildcard expression for classes to include
- * @see WildcardMatcher
- */
- public String getIncludes() {
- return getOption(INCLUDES, "*");
- }
-
- /**
- * Sets the wildcard expression for classes to include.
- *
- * @param includes
- * wildcard expression for classes to include
- * @see WildcardMatcher
- */
- public void setIncludes(final String includes) {
- setOption(INCLUDES, includes);
- }
-
- /**
- * Returns the wildcard expression for classes to exclude.
- *
- * @return wildcard expression for classes to exclude
- * @see WildcardMatcher
- */
- public String getExcludes() {
- return getOption(EXCLUDES, "");
- }
-
- /**
- * Sets the wildcard expression for classes to exclude.
- *
- * @param excludes
- * wildcard expression for classes to exclude
- * @see WildcardMatcher
- */
- public void setExcludes(final String excludes) {
- setOption(EXCLUDES, excludes);
- }
-
- /**
- * Returns the wildcard expression for excluded class loaders.
- *
- * @return expression for excluded class loaders
- * @see WildcardMatcher
- */
- public String getExclClassloader() {
- return getOption(EXCLCLASSLOADER, "sun.reflect.DelegatingClassLoader");
- }
-
- /**
- * Sets the wildcard expression for excluded class loaders.
- *
- * @param expression
- * expression for excluded class loaders
- * @see WildcardMatcher
- */
- public void setExclClassloader(final String expression) {
- setOption(EXCLCLASSLOADER, expression);
- }
-
- /**
- * Returns the session identifier.
- *
- * @return session identifier
- */
- public String getSessionId() {
- return getOption(SESSIONID, null);
- }
-
- /**
- * Sets the session identifier.
- *
- * @param id
- * session identifier
- */
- public void setSessionId(final String id) {
- setOption(SESSIONID, id);
- }
-
- /**
- * Returns whether coverage data should be dumped on exit
- *
- * @return <code>true</code> if coverage data will be written on VM exit
- */
- public boolean getDumpOnExit() {
- return getOption(DUMPONEXIT, true);
- }
-
- /**
- * Sets whether coverage data should be dumped on exit
- *
- * @param dumpOnExit
- * <code>true</code> if coverage data should be written on VM
- * exit
- */
- public void setDumpOnExit(final boolean dumpOnExit) {
- setOption(DUMPONEXIT, dumpOnExit);
- }
-
- /**
- * Returns the port on which to listen to when the output is
- * <code>tcpserver</code> or the port to connect to when output is
- * <code>tcpclient</code>.
- *
- * @return port to listen on or connect to
- */
- public int getPort() {
- return getOption(PORT, DEFAULT_PORT);
- }
-
- /**
- * Sets the port on which to listen to when output is <code>tcpserver</code>
- * or the port to connect to when output is <code>tcpclient</code>
- *
- * @param port
- */
- public void setPort(final int port) {
- validatePort(port);
- setOption(PORT, port);
- }
-
- /**
- * Gets the hostname or IP address to listen to when output is
- * <code>tcpserver</code> or connect to when output is
- * <code>tcpclient</code>
- *
- * @return Hostname or IP address
- */
- public String getAddress() {
- return getOption(ADDRESS, DEFAULT_ADDRESS);
- }
-
- /**
- * Sets the hostname or IP address to listen to when output is
- * <code>tcpserver</cose> or connect to when output is <code>tcpclient</code>
- *
- * @param address
- * Hostname or IP address
- */
- public void setAddress(final String address) {
- setOption(ADDRESS, address);
- }
-
- /**
- * Returns the output mode
- *
- * @return current output mode
- */
- public OutputMode getOutput() {
- final String value = options.get(OUTPUT);
- return value == null ? OutputMode.file : OutputMode.valueOf(value);
- }
-
- /**
- * Sets the output mode
- *
- * @param output
- * Output mode
- */
- public void setOutput(final String output) {
- setOutput(OutputMode.valueOf(output));
- }
-
- /**
- * Sets the output mode
- *
- * @param output
- * Output mode
- */
- public void setOutput(final OutputMode output) {
- setOption(OUTPUT, output.name());
- }
-
- /**
- * Returns the location of the directory where class files should be dumped
- * to.
- *
- * @return dump location or <code>null</code> (no dumps)
- */
- public String getClassDumpDir() {
- return getOption(CLASSDUMPDIR, null);
- }
-
- /**
- * Sets the directory where class files should be dumped to.
- *
- * @param location
- * dump location or <code>null</code> (no dumps)
- */
- public void setClassDumpDir(final String location) {
- setOption(CLASSDUMPDIR, location);
- }
-
- private void setOption(final String key, final int value) {
- setOption(key, Integer.toString(value));
- }
-
- private void setOption(final String key, final boolean value) {
- setOption(key, Boolean.toString(value));
- }
-
- private void setOption(final String key, final String value) {
- if (value.contains(",")) {
- throw new IllegalArgumentException(format(
- "Invalid character in option argument \"%s\"", value));
- }
- options.put(key, value);
- }
-
- private String getOption(final String key, final String defaultValue) {
- final String value = options.get(key);
- return value == null ? defaultValue : value;
- }
-
- private boolean getOption(final String key, final boolean defaultValue) {
- final String value = options.get(key);
- return value == null ? defaultValue : Boolean.parseBoolean(value);
- }
-
- private int getOption(final String key, final int defaultValue) {
- final String value = options.get(key);
- return value == null ? defaultValue : Integer.parseInt(value);
- }
-
- /**
- * Generate required JVM argument string based on current configuration and
- * supplied agent jar location
- *
- * @param agentJarFile
- * location of the JaCoCo Agent Jar
- * @return Argument to pass to create new VM with coverage enabled
- */
- public String getVMArgument(final File agentJarFile) {
- return format("-javaagent:%s=%s", agentJarFile, this);
- }
-
- /**
- * Creates a string representation that can be passed to the agent via the
- * command line. Might be the empty string, if no options are set.
- */
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- for (final String key : VALID_OPTIONS) {
- final String value = options.get(key);
- if (value != null) {
- if (sb.length() > 0) {
- sb.append(',');
- }
- sb.append(key).append('=').append(value);
- }
- }
- return sb.toString();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import static java.lang.String.format; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * Utility to create and parse options for the runtime agent. Options are + * represented as a string in the following format: + * + * <pre> + * key1=value1,key2=value2,key3=value3 + * </pre> + */ +public final class AgentOptions { + + /** + * Specifies the output file for execution data. Default is + * <code>jacoco.exec</code> in the working directory. + */ + public static final String DESTFILE = "destfile"; + + /** + * Specifies whether execution data should be appended to the output file. + * Default is <code>true</code>. + */ + public static final String APPEND = "append"; + + /** + * Wildcard expression for class names that should be included for code + * coverage. Default is <code>*</code> (all classes included). + * + * @see WildcardMatcher + */ + public static final String INCLUDES = "includes"; + + /** + * Wildcard expression for class names that should be excluded from code + * coverage. Default is the empty string (no exclusions). + * + * @see WildcardMatcher + */ + public static final String EXCLUDES = "excludes"; + + /** + * Wildcard expression for class loaders names for classes that should be + * excluded from code coverage. This means all classes loaded by a class + * loader which full qualified name matches this expression will be ignored + * for code coverage regardless of all other filtering settings. Default is + * <code>sun.reflect.DelegatingClassLoader</code>. + * + * @see WildcardMatcher + */ + public static final String EXCLCLASSLOADER = "exclclassloader"; + + /** + * Specifies a session identifier that is written with the execution data. + * Without this parameter a random identifier is created by the agent. + */ + public static final String SESSIONID = "sessionid"; + + /** + * Specifies whether the agent will automatically dump coverage data on VM + * exit. Default is <code>true</code>. + */ + public static final String DUMPONEXIT = "dumponexit"; + + /** + * Specifies the output mode. Default is + * <code>{@link OutputMode#file}</code>. + * + * @see OutputMode#file + * @see OutputMode#tcpserver + * @see OutputMode#tcpclient + */ + public static final String OUTPUT = "output"; + + /** + * Possible values for {@link AgentOptions#OUTPUT}. + */ + public static enum OutputMode { + + /** + * Value for the {@link AgentOptions#OUTPUT} parameter: At VM + * termination execution data is written to the file specified by + * {@link AgentOptions#DESTFILE}. + */ + file, + + /** + * Value for the {@link AgentOptions#OUTPUT} parameter: The agent + * listens for incoming connections on a TCP port specified by + * {@link AgentOptions#ADDRESS} and {@link AgentOptions#PORT}. + */ + tcpserver, + + /** + * Value for the {@link AgentOptions#OUTPUT} parameter: At startup the + * agent connects to a TCP port specified by the + * {@link AgentOptions#ADDRESS} and {@link AgentOptions#PORT} attribute. + */ + tcpclient, + + /** + * Value for the {@link AgentOptions#OUTPUT} parameter: At startup the + * agent creates MBean. + */ + mbean + + } + + /** + * The IP address or DNS name the tcpserver binds to or the tcpclient + * connects to. Default is defined by {@link #DEFAULT_ADDRESS}. + */ + public static final String ADDRESS = "address"; + + /** + * Default value for the "address" agent option. + */ + public static final String DEFAULT_ADDRESS = null; + + /** + * The port the tcpserver binds to or the tcpclient connects to. In + * tcpserver mode the port must be available, which means that if multiple + * JaCoCo agents should run on the same machine, different ports have to be + * specified. Default is defined by {@link #DEFAULT_PORT}. + */ + public static final String PORT = "port"; + + /** + * Default value for the "port" agent option. + */ + public static final int DEFAULT_PORT = 6300; + + /** + * Specifies where the agent dumps all class files it encounters. The + * location is specified as a relative path to the working directory. + * Default is <code>null</code> (no dumps). + */ + public static final String CLASSDUMPDIR = "classdumpdir"; + + private static final Collection<String> VALID_OPTIONS = Arrays.asList( + DESTFILE, APPEND, INCLUDES, EXCLUDES, EXCLCLASSLOADER, SESSIONID, + DUMPONEXIT, OUTPUT, ADDRESS, PORT, CLASSDUMPDIR); + + private final Map<String, String> options; + + /** + * New instance with all values set to default. + */ + public AgentOptions() { + this.options = new HashMap<String, String>(); + } + + /** + * New instance parsed from the given option string. + * + * @param optionstr + * string to parse or <code>null</code> + */ + public AgentOptions(final String optionstr) { + this(); + if (optionstr != null && optionstr.length() > 0) { + for (final String entry : optionstr.split(",")) { + final int pos = entry.indexOf('='); + if (pos == -1) { + throw new IllegalArgumentException(format( + "Invalid agent option syntax \"%s\".", optionstr)); + } + final String key = entry.substring(0, pos); + if (!VALID_OPTIONS.contains(key)) { + throw new IllegalArgumentException(format( + "Unknown agent option \"%s\".", key)); + } + + final String value = entry.substring(pos + 1); + setOption(key, value); + } + + validateAll(); + } + } + + private void validateAll() { + validatePort(getPort()); + getOutput(); + } + + private void validatePort(final int port) { + if (port < 0) { + throw new IllegalArgumentException("port must be positive"); + } + } + + /** + * Returns the output file location. + * + * @return output file location + */ + public String getDestfile() { + return getOption(DESTFILE, "jacoco.exec"); + } + + /** + * Sets the output file location. + * + * @param destfile + * output file location + */ + public void setDestfile(final String destfile) { + setOption(DESTFILE, destfile); + } + + /** + * Returns whether the output should be appended to an existing file. + * + * @return <code>true</code>, when the output should be appended + */ + public boolean getAppend() { + return getOption(APPEND, true); + } + + /** + * Sets whether the output should be appended to an existing file. + * + * @param append + * <code>true</code>, when the output should be appended + */ + public void setAppend(final boolean append) { + setOption(APPEND, append); + } + + /** + * Returns the wildcard expression for classes to include. + * + * @return wildcard expression for classes to include + * @see WildcardMatcher + */ + public String getIncludes() { + return getOption(INCLUDES, "*"); + } + + /** + * Sets the wildcard expression for classes to include. + * + * @param includes + * wildcard expression for classes to include + * @see WildcardMatcher + */ + public void setIncludes(final String includes) { + setOption(INCLUDES, includes); + } + + /** + * Returns the wildcard expression for classes to exclude. + * + * @return wildcard expression for classes to exclude + * @see WildcardMatcher + */ + public String getExcludes() { + return getOption(EXCLUDES, ""); + } + + /** + * Sets the wildcard expression for classes to exclude. + * + * @param excludes + * wildcard expression for classes to exclude + * @see WildcardMatcher + */ + public void setExcludes(final String excludes) { + setOption(EXCLUDES, excludes); + } + + /** + * Returns the wildcard expression for excluded class loaders. + * + * @return expression for excluded class loaders + * @see WildcardMatcher + */ + public String getExclClassloader() { + return getOption(EXCLCLASSLOADER, "sun.reflect.DelegatingClassLoader"); + } + + /** + * Sets the wildcard expression for excluded class loaders. + * + * @param expression + * expression for excluded class loaders + * @see WildcardMatcher + */ + public void setExclClassloader(final String expression) { + setOption(EXCLCLASSLOADER, expression); + } + + /** + * Returns the session identifier. + * + * @return session identifier + */ + public String getSessionId() { + return getOption(SESSIONID, null); + } + + /** + * Sets the session identifier. + * + * @param id + * session identifier + */ + public void setSessionId(final String id) { + setOption(SESSIONID, id); + } + + /** + * Returns whether coverage data should be dumped on exit + * + * @return <code>true</code> if coverage data will be written on VM exit + */ + public boolean getDumpOnExit() { + return getOption(DUMPONEXIT, true); + } + + /** + * Sets whether coverage data should be dumped on exit + * + * @param dumpOnExit + * <code>true</code> if coverage data should be written on VM + * exit + */ + public void setDumpOnExit(final boolean dumpOnExit) { + setOption(DUMPONEXIT, dumpOnExit); + } + + /** + * Returns the port on which to listen to when the output is + * <code>tcpserver</code> or the port to connect to when output is + * <code>tcpclient</code>. + * + * @return port to listen on or connect to + */ + public int getPort() { + return getOption(PORT, DEFAULT_PORT); + } + + /** + * Sets the port on which to listen to when output is <code>tcpserver</code> + * or the port to connect to when output is <code>tcpclient</code> + * + * @param port + */ + public void setPort(final int port) { + validatePort(port); + setOption(PORT, port); + } + + /** + * Gets the hostname or IP address to listen to when output is + * <code>tcpserver</code> or connect to when output is + * <code>tcpclient</code> + * + * @return Hostname or IP address + */ + public String getAddress() { + return getOption(ADDRESS, DEFAULT_ADDRESS); + } + + /** + * Sets the hostname or IP address to listen to when output is + * <code>tcpserver</cose> or connect to when output is <code>tcpclient</code> + * + * @param address + * Hostname or IP address + */ + public void setAddress(final String address) { + setOption(ADDRESS, address); + } + + /** + * Returns the output mode + * + * @return current output mode + */ + public OutputMode getOutput() { + final String value = options.get(OUTPUT); + return value == null ? OutputMode.file : OutputMode.valueOf(value); + } + + /** + * Sets the output mode + * + * @param output + * Output mode + */ + public void setOutput(final String output) { + setOutput(OutputMode.valueOf(output)); + } + + /** + * Sets the output mode + * + * @param output + * Output mode + */ + public void setOutput(final OutputMode output) { + setOption(OUTPUT, output.name()); + } + + /** + * Returns the location of the directory where class files should be dumped + * to. + * + * @return dump location or <code>null</code> (no dumps) + */ + public String getClassDumpDir() { + return getOption(CLASSDUMPDIR, null); + } + + /** + * Sets the directory where class files should be dumped to. + * + * @param location + * dump location or <code>null</code> (no dumps) + */ + public void setClassDumpDir(final String location) { + setOption(CLASSDUMPDIR, location); + } + + private void setOption(final String key, final int value) { + setOption(key, Integer.toString(value)); + } + + private void setOption(final String key, final boolean value) { + setOption(key, Boolean.toString(value)); + } + + private void setOption(final String key, final String value) { + if (value.contains(",")) { + throw new IllegalArgumentException(format( + "Invalid character in option argument \"%s\"", value)); + } + options.put(key, value); + } + + private String getOption(final String key, final String defaultValue) { + final String value = options.get(key); + return value == null ? defaultValue : value; + } + + private boolean getOption(final String key, final boolean defaultValue) { + final String value = options.get(key); + return value == null ? defaultValue : Boolean.parseBoolean(value); + } + + private int getOption(final String key, final int defaultValue) { + final String value = options.get(key); + return value == null ? defaultValue : Integer.parseInt(value); + } + + /** + * Generate required JVM argument string based on current configuration and + * supplied agent jar location + * + * @param agentJarFile + * location of the JaCoCo Agent Jar + * @return Argument to pass to create new VM with coverage enabled + */ + public String getVMArgument(final File agentJarFile) { + return format("-javaagent:%s=%s", agentJarFile, this); + } + + /** + * Creates a string representation that can be passed to the agent via the + * command line. Might be the empty string, if no options are set. + */ + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + for (final String key : VALID_OPTIONS) { + final String value = options.get(key); + if (value != null) { + if (sb.length() > 0) { + sb.append(','); + } + sb.append(key).append('=').append(value); + } + } + return sb.toString(); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/ExecutionDataAccess.java b/org.jacoco.core/src/org/jacoco/core/runtime/ExecutionDataAccess.java index 4c531f49..be526719 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/ExecutionDataAccess.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/ExecutionDataAccess.java @@ -1,172 +1,172 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.internal.instr.InstrSupport;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * This class implements the access from instrumented classes to execution data
- * storage in the runtime. Instead of directly referencing JaCoCo implementation
- * classes the access is decoupled through a JRE API. This avoids dependencies
- * from instrumented classes on JaCoCo APIs.
- *
- * The JRE interface method used is {@link Object#equals(Object)} where the
- * passed argument is an {@link Object} array containing the class id (
- * {@link Long}), the class vm name ({@link String}) and the probe count (
- * {@link Integer}). After the method call the probe array instance is stored in
- * the first slot of the {@link Object} array.
- */
-class ExecutionDataAccess {
-
- private final ExecutionDataStore store;
-
- ExecutionDataAccess(final ExecutionDataStore store) {
- this.store = store;
- }
-
- /**
- * Retrieves the execution probe array for a given class. The passed
- * {@link Object} array instance is used for parameters and the return value
- * as follows. Call parameters:
- *
- * <ul>
- * <li>args[0]: class id ({@link Long})
- * <li>args[1]: vm class name ({@link String})
- * <li>args[2]: probe count ({@link Integer})
- * </ul>
- *
- * Return value:
- *
- * <ul>
- * <li>args[0]: probe array (<code>boolean[]</code>)
- * </ul>
- *
- * @param args
- * parameter array of length 3
- */
- public void getExecutionData(final Object[] args) {
- final Long classid = (Long) args[0];
- final String name = (String) args[1];
- final int probecount = ((Integer) args[2]).intValue();
- synchronized (store) {
- args[0] = store.get(classid, name, probecount).getData();
- }
- }
-
- /**
- * Generates code that creates the argument array for the
- * <code>getExecutionData()</code> method. The array instance is left on the
- * operand stack. The generated code requires a stack size of 5.
- *
- * @param classid
- * class identifier
- * @param classname
- * VM class name
- * @param probecount
- * probe count for this class
- * @param mv
- * visitor to emit generated code
- */
- public static void generateArgumentArray(final long classid,
- final String classname, final int probecount, final MethodVisitor mv) {
- mv.visitInsn(Opcodes.ICONST_3);
- mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
-
- // Class Id:
- mv.visitInsn(Opcodes.DUP);
- mv.visitInsn(Opcodes.ICONST_0);
- mv.visitLdcInsn(Long.valueOf(classid));
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
- "(J)Ljava/lang/Long;");
- mv.visitInsn(Opcodes.AASTORE);
-
- // Class Name:
- mv.visitInsn(Opcodes.DUP);
- mv.visitInsn(Opcodes.ICONST_1);
- mv.visitLdcInsn(classname);
- mv.visitInsn(Opcodes.AASTORE);
-
- // Probe Count:
- mv.visitInsn(Opcodes.DUP);
- mv.visitInsn(Opcodes.ICONST_2);
- InstrSupport.push(mv, probecount);
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer",
- "valueOf", "(I)Ljava/lang/Integer;");
- mv.visitInsn(Opcodes.AASTORE);
- }
-
- /**
- * Generates the code that calls the runtime data access through the JRE API
- * method {@link Object#equals(Object)}. The code pops a {@link Object}
- * instance from the stack and pushes the probe array of type
- * <code>boolean[]</code> on the operand stack. The generated code requires
- * a stack size of 6.
- *
- * @param classid
- * @param classname
- * @param probecount
- * @param mv
- */
- public static void generateAccessCall(final long classid,
- final String classname, final int probecount, final MethodVisitor mv) {
- // stack[0]: Ljava/lang/Object;
-
- generateArgumentArray(classid, classname, probecount, mv);
-
- // stack[1]: [Ljava/lang/Object;
- // stack[0]: Ljava/lang/Object;
-
- mv.visitInsn(Opcodes.DUP_X1);
-
- // stack[2]: [Ljava/lang/Object;
- // stack[1]: Ljava/lang/Object;
- // stack[0]: [Ljava/lang/Object;
-
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals",
- "(Ljava/lang/Object;)Z");
- mv.visitInsn(Opcodes.POP);
-
- // stack[0]: [Ljava/lang/Object;
-
- mv.visitInsn(Opcodes.ICONST_0);
- mv.visitInsn(Opcodes.AALOAD);
-
- // stack[0]: [Z
-
- mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC);
- }
-
- /**
- * In violation of the regular semantic of {@link Object#equals(Object)}
- * this implementation is used as the interface to the execution data store.
- *
- * @param args
- * the arguments as an {@link Object} array
- * @return has no meaning
- */
- @Override
- public boolean equals(final Object args) {
- if (args instanceof Object[]) {
- getExecutionData((Object[]) args);
- }
- return super.equals(args);
- }
-
- @Override
- public int hashCode() {
- return super.hashCode();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.internal.instr.InstrSupport; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * This class implements the access from instrumented classes to execution data + * storage in the runtime. Instead of directly referencing JaCoCo implementation + * classes the access is decoupled through a JRE API. This avoids dependencies + * from instrumented classes on JaCoCo APIs. + * + * The JRE interface method used is {@link Object#equals(Object)} where the + * passed argument is an {@link Object} array containing the class id ( + * {@link Long}), the class vm name ({@link String}) and the probe count ( + * {@link Integer}). After the method call the probe array instance is stored in + * the first slot of the {@link Object} array. + */ +class ExecutionDataAccess { + + private final ExecutionDataStore store; + + ExecutionDataAccess(final ExecutionDataStore store) { + this.store = store; + } + + /** + * Retrieves the execution probe array for a given class. The passed + * {@link Object} array instance is used for parameters and the return value + * as follows. Call parameters: + * + * <ul> + * <li>args[0]: class id ({@link Long}) + * <li>args[1]: vm class name ({@link String}) + * <li>args[2]: probe count ({@link Integer}) + * </ul> + * + * Return value: + * + * <ul> + * <li>args[0]: probe array (<code>boolean[]</code>) + * </ul> + * + * @param args + * parameter array of length 3 + */ + public void getExecutionData(final Object[] args) { + final Long classid = (Long) args[0]; + final String name = (String) args[1]; + final int probecount = ((Integer) args[2]).intValue(); + synchronized (store) { + args[0] = store.get(classid, name, probecount).getData(); + } + } + + /** + * Generates code that creates the argument array for the + * <code>getExecutionData()</code> method. The array instance is left on the + * operand stack. The generated code requires a stack size of 5. + * + * @param classid + * class identifier + * @param classname + * VM class name + * @param probecount + * probe count for this class + * @param mv + * visitor to emit generated code + */ + public static void generateArgumentArray(final long classid, + final String classname, final int probecount, final MethodVisitor mv) { + mv.visitInsn(Opcodes.ICONST_3); + mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); + + // Class Id: + mv.visitInsn(Opcodes.DUP); + mv.visitInsn(Opcodes.ICONST_0); + mv.visitLdcInsn(Long.valueOf(classid)); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", + "(J)Ljava/lang/Long;"); + mv.visitInsn(Opcodes.AASTORE); + + // Class Name: + mv.visitInsn(Opcodes.DUP); + mv.visitInsn(Opcodes.ICONST_1); + mv.visitLdcInsn(classname); + mv.visitInsn(Opcodes.AASTORE); + + // Probe Count: + mv.visitInsn(Opcodes.DUP); + mv.visitInsn(Opcodes.ICONST_2); + InstrSupport.push(mv, probecount); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", + "valueOf", "(I)Ljava/lang/Integer;"); + mv.visitInsn(Opcodes.AASTORE); + } + + /** + * Generates the code that calls the runtime data access through the JRE API + * method {@link Object#equals(Object)}. The code pops a {@link Object} + * instance from the stack and pushes the probe array of type + * <code>boolean[]</code> on the operand stack. The generated code requires + * a stack size of 6. + * + * @param classid + * @param classname + * @param probecount + * @param mv + */ + public static void generateAccessCall(final long classid, + final String classname, final int probecount, final MethodVisitor mv) { + // stack[0]: Ljava/lang/Object; + + generateArgumentArray(classid, classname, probecount, mv); + + // stack[1]: [Ljava/lang/Object; + // stack[0]: Ljava/lang/Object; + + mv.visitInsn(Opcodes.DUP_X1); + + // stack[2]: [Ljava/lang/Object; + // stack[1]: Ljava/lang/Object; + // stack[0]: [Ljava/lang/Object; + + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals", + "(Ljava/lang/Object;)Z"); + mv.visitInsn(Opcodes.POP); + + // stack[0]: [Ljava/lang/Object; + + mv.visitInsn(Opcodes.ICONST_0); + mv.visitInsn(Opcodes.AALOAD); + + // stack[0]: [Z + + mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC); + } + + /** + * In violation of the regular semantic of {@link Object#equals(Object)} + * this implementation is used as the interface to the execution data store. + * + * @param args + * the arguments as an {@link Object} array + * @return has no meaning + */ + @Override + public boolean equals(final Object args) { + if (args instanceof Object[]) { + getExecutionData((Object[]) args); + } + return super.equals(args); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/IRuntime.java b/org.jacoco.core/src/org/jacoco/core/runtime/IRuntime.java index e045d91c..7d0d5e8c 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/IRuntime.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/IRuntime.java @@ -1,95 +1,95 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import org.jacoco.core.data.IExecutionDataVisitor;
-import org.jacoco.core.data.ISessionInfoVisitor;
-
-/**
- * This interface represents a particular mechanism to collect execution
- * information in the target VM at runtime.
- */
-public interface IRuntime extends IExecutionDataAccessorGenerator {
-
- /**
- * Sets a session identifier for this runtime. The identifier is used when
- * execution data is collected. If no identifier is explicitly set a
- * identifier is generated from the host name and a random number. This
- * method can be called at any time.
- *
- * @see #collect(IExecutionDataVisitor, ISessionInfoVisitor, boolean)
- * @param id
- * new session identifier
- */
- public void setSessionId(String id);
-
- /**
- * Get the current a session identifier for this runtime.
- *
- * @see #setSessionId(String)
- * @return current session identifier
- */
- public String getSessionId();
-
- /**
- * Starts the coverage runtime. This method MUST be called before any class
- * instrumented for this runtime is loaded.
- *
- * @throws Exception
- * any internal problem during startup
- */
- public void startup() throws Exception;
-
- /**
- * Allows the coverage runtime to cleanup internals. This class should be
- * called when classes instrumented for this runtime are not used any more.
- */
- public void shutdown();
-
- /**
- * Collects the current execution data and writes it to the given
- * {@link IExecutionDataVisitor} object. This method must only be called
- * between {@link #startup()} and {@link #shutdown()}.
- *
- * @param executionDataVisitor
- * handler to write coverage data to
- * @param sessionInfoVisitor
- * optional visitor to write session information to or
- * <code>null</code> if session information is not required
- * @param reset
- * if <code>true</code> the current coverage information is also
- * cleared
- */
- public void collect(IExecutionDataVisitor executionDataVisitor,
- ISessionInfoVisitor sessionInfoVisitor, boolean reset);
-
- /**
- * Resets all coverage information. This method must only be called between
- * {@link #startup()} and {@link #shutdown()}.
- */
- public void reset();
-
- /**
- * Clears the execution data buffered in the given instrumented type. It
- * forces the class to re-connect to the runtime the next time it is
- * executed. This method is used by the agent and is required when a class
- * has been redefined. Note that a call to this method does not actually
- * reset the data that is already stored in the runtime.
- *
- * @param type
- * class to clear
- * @throws Exception
- * if clearing the data is not possible
- */
- public void disconnect(final Class<?> type) throws Exception;
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import org.jacoco.core.data.IExecutionDataVisitor; +import org.jacoco.core.data.ISessionInfoVisitor; + +/** + * This interface represents a particular mechanism to collect execution + * information in the target VM at runtime. + */ +public interface IRuntime extends IExecutionDataAccessorGenerator { + + /** + * Sets a session identifier for this runtime. The identifier is used when + * execution data is collected. If no identifier is explicitly set a + * identifier is generated from the host name and a random number. This + * method can be called at any time. + * + * @see #collect(IExecutionDataVisitor, ISessionInfoVisitor, boolean) + * @param id + * new session identifier + */ + public void setSessionId(String id); + + /** + * Get the current a session identifier for this runtime. + * + * @see #setSessionId(String) + * @return current session identifier + */ + public String getSessionId(); + + /** + * Starts the coverage runtime. This method MUST be called before any class + * instrumented for this runtime is loaded. + * + * @throws Exception + * any internal problem during startup + */ + public void startup() throws Exception; + + /** + * Allows the coverage runtime to cleanup internals. This class should be + * called when classes instrumented for this runtime are not used any more. + */ + public void shutdown(); + + /** + * Collects the current execution data and writes it to the given + * {@link IExecutionDataVisitor} object. This method must only be called + * between {@link #startup()} and {@link #shutdown()}. + * + * @param executionDataVisitor + * handler to write coverage data to + * @param sessionInfoVisitor + * optional visitor to write session information to or + * <code>null</code> if session information is not required + * @param reset + * if <code>true</code> the current coverage information is also + * cleared + */ + public void collect(IExecutionDataVisitor executionDataVisitor, + ISessionInfoVisitor sessionInfoVisitor, boolean reset); + + /** + * Resets all coverage information. This method must only be called between + * {@link #startup()} and {@link #shutdown()}. + */ + public void reset(); + + /** + * Clears the execution data buffered in the given instrumented type. It + * forces the class to re-connect to the runtime the next time it is + * executed. This method is used by the agent and is required when a class + * has been redefined. Note that a call to this method does not actually + * reset the data that is already stored in the runtime. + * + * @param type + * class to clear + * @throws Exception + * if clearing the data is not possible + */ + public void disconnect(final Class<?> type) throws Exception; + +} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/LoggerRuntime.java b/org.jacoco.core/src/org/jacoco/core/runtime/LoggerRuntime.java index a44fb4df..c8851aba 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/LoggerRuntime.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/LoggerRuntime.java @@ -1,188 +1,188 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-
-import org.jacoco.core.internal.instr.InstrSupport;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * This {@link IRuntime} implementation uses the Java logging API to report
- * coverage data.
- * <p>
- *
- * The implementation uses a dedicated log channel. Instrumented classes call
- * {@link Logger#log(Level, String, Object[])} with the class identifier in the
- * first slot of the parameter array. The runtime implements a {@link Handler}
- * for this channel that puts the probe data structure into the first slot of
- * the parameter array.
- */
-public class LoggerRuntime extends AbstractRuntime {
-
- private static final String CHANNEL = "jacoco-runtime";
-
- private final String key;
-
- private final Logger logger;
-
- private final Handler handler;
-
- /**
- * Creates a new runtime.
- */
- public LoggerRuntime() {
- super();
- this.key = Integer.toHexString(hashCode());
- this.logger = configureLogger();
- this.handler = new RuntimeHandler();
- }
-
- private Logger configureLogger() {
- final Logger l = Logger.getLogger(CHANNEL);
- l.setUseParentHandlers(false);
- l.setLevel(Level.ALL);
- return l;
- }
-
- public int generateDataAccessor(final long classid, final String classname,
- final int probecount, final MethodVisitor mv) {
-
- // The data accessor performs the following steps:
- //
- // final Object[] args = new Object[3];
- // args[0] = Long.valueOf(classid);
- // args[1] = classname;
- // args[2] = Integer.valueOf(probecount);
- // Logger.getLogger(CHANNEL).log(Level.INFO, key, args);
- // final byte[] probedata = (byte[]) args[0];
- //
- // Note that local variable 'args' is used at two places. As were not
- // allowed to allocate local variables we have to keep this value with
- // DUP and SWAP operations on the operand stack.
-
- // 1. Create parameter array:
-
- ExecutionDataAccess.generateArgumentArray(classid, classname,
- probecount, mv);
-
- // Stack[0]: [Ljava/lang/Object;
-
- mv.visitInsn(Opcodes.DUP);
-
- // Stack[1]: [Ljava/lang/Object;
- // Stack[0]: [Ljava/lang/Object;
-
- // 2. Call Logger:
-
- mv.visitLdcInsn(CHANNEL);
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/logging/Logger",
- "getLogger", "(Ljava/lang/String;)Ljava/util/logging/Logger;");
-
- // Stack[2]: Ljava/util/logging/Logger;
- // Stack[1]: [Ljava/lang/Object;
- // Stack[0]: [Ljava/lang/Object;
-
- mv.visitInsn(Opcodes.SWAP);
-
- // Stack[2]: [Ljava/lang/Object;
- // Stack[1]: Ljava/util/logging/Logger;
- // Stack[0]: [Ljava/lang/Object;
-
- mv.visitFieldInsn(Opcodes.GETSTATIC, "java/util/logging/Level", "INFO",
- "Ljava/util/logging/Level;");
-
- // Stack[3]: Ljava/util/logging/Level;
- // Stack[2]: [Ljava/lang/Object;
- // Stack[1]: Ljava/util/logging/Logger;
- // Stack[0]: [Ljava/lang/Object;
-
- mv.visitInsn(Opcodes.SWAP);
-
- // Stack[3]: [Ljava/lang/Object;
- // Stack[2]: Ljava/util/logging/Level;
- // Stack[1]: Ljava/util/logging/Logger;
- // Stack[0]: [Ljava/lang/Object;
-
- mv.visitLdcInsn(key);
-
- // Stack[4]: Ljava/lang/String;
- // Stack[3]: [Ljava/lang/Object;
- // Stack[2]: Ljava/util/logging/Level;
- // Stack[1]: Ljava/util/logging/Logger;
- // Stack[0]: [Ljava/lang/Object;
-
- mv.visitInsn(Opcodes.SWAP);
-
- // Stack[4]: [Ljava/lang/Object;
- // Stack[3]: Ljava/lang/String;
- // Stack[2]: Ljava/util/logging/Level;
- // Stack[1]: Ljava/util/logging/Logger;
- // Stack[0]: [Ljava/lang/Object;
-
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/logging/Logger",
- "log",
- "(Ljava/util/logging/Level;Ljava/lang/String;[Ljava/lang/Object;)V");
-
- // Stack[0]: [Ljava/lang/Object;
-
- // 3. Load data structure from parameter array:
-
- mv.visitInsn(Opcodes.ICONST_0);
- mv.visitInsn(Opcodes.AALOAD);
- mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC);
-
- // Stack[0]: [Z
-
- return 5; // Maximum local stack size is 5
- }
-
- public void startup() {
- setStartTimeStamp();
- this.logger.addHandler(handler);
- }
-
- public void shutdown() {
- this.logger.removeHandler(handler);
- }
-
- private class RuntimeHandler extends Handler {
-
- @Override
- public void publish(final LogRecord record) {
- if (key.equals(record.getMessage())) {
- access.getExecutionData(record.getParameters());
- }
- }
-
- @Override
- public void flush() {
- // nothing to do
- }
-
- @Override
- public void close() throws SecurityException {
- // The Java logging framework removes and closes all handlers on JVM
- // shutdown. As soon as our handler has been removed, all classes
- // that might get instrumented during shutdown (e.g. loaded by other
- // shutdown hooks) will fail to initialize. Therefore we add ourself
- // again here. This is a nasty hack that might fail in some Java
- // implementations.
- logger.addHandler(handler);
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import org.jacoco.core.internal.instr.InstrSupport; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * This {@link IRuntime} implementation uses the Java logging API to report + * coverage data. + * <p> + * + * The implementation uses a dedicated log channel. Instrumented classes call + * {@link Logger#log(Level, String, Object[])} with the class identifier in the + * first slot of the parameter array. The runtime implements a {@link Handler} + * for this channel that puts the probe data structure into the first slot of + * the parameter array. + */ +public class LoggerRuntime extends AbstractRuntime { + + private static final String CHANNEL = "jacoco-runtime"; + + private final String key; + + private final Logger logger; + + private final Handler handler; + + /** + * Creates a new runtime. + */ + public LoggerRuntime() { + super(); + this.key = Integer.toHexString(hashCode()); + this.logger = configureLogger(); + this.handler = new RuntimeHandler(); + } + + private Logger configureLogger() { + final Logger l = Logger.getLogger(CHANNEL); + l.setUseParentHandlers(false); + l.setLevel(Level.ALL); + return l; + } + + public int generateDataAccessor(final long classid, final String classname, + final int probecount, final MethodVisitor mv) { + + // The data accessor performs the following steps: + // + // final Object[] args = new Object[3]; + // args[0] = Long.valueOf(classid); + // args[1] = classname; + // args[2] = Integer.valueOf(probecount); + // Logger.getLogger(CHANNEL).log(Level.INFO, key, args); + // final byte[] probedata = (byte[]) args[0]; + // + // Note that local variable 'args' is used at two places. As were not + // allowed to allocate local variables we have to keep this value with + // DUP and SWAP operations on the operand stack. + + // 1. Create parameter array: + + ExecutionDataAccess.generateArgumentArray(classid, classname, + probecount, mv); + + // Stack[0]: [Ljava/lang/Object; + + mv.visitInsn(Opcodes.DUP); + + // Stack[1]: [Ljava/lang/Object; + // Stack[0]: [Ljava/lang/Object; + + // 2. Call Logger: + + mv.visitLdcInsn(CHANNEL); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/logging/Logger", + "getLogger", "(Ljava/lang/String;)Ljava/util/logging/Logger;"); + + // Stack[2]: Ljava/util/logging/Logger; + // Stack[1]: [Ljava/lang/Object; + // Stack[0]: [Ljava/lang/Object; + + mv.visitInsn(Opcodes.SWAP); + + // Stack[2]: [Ljava/lang/Object; + // Stack[1]: Ljava/util/logging/Logger; + // Stack[0]: [Ljava/lang/Object; + + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/util/logging/Level", "INFO", + "Ljava/util/logging/Level;"); + + // Stack[3]: Ljava/util/logging/Level; + // Stack[2]: [Ljava/lang/Object; + // Stack[1]: Ljava/util/logging/Logger; + // Stack[0]: [Ljava/lang/Object; + + mv.visitInsn(Opcodes.SWAP); + + // Stack[3]: [Ljava/lang/Object; + // Stack[2]: Ljava/util/logging/Level; + // Stack[1]: Ljava/util/logging/Logger; + // Stack[0]: [Ljava/lang/Object; + + mv.visitLdcInsn(key); + + // Stack[4]: Ljava/lang/String; + // Stack[3]: [Ljava/lang/Object; + // Stack[2]: Ljava/util/logging/Level; + // Stack[1]: Ljava/util/logging/Logger; + // Stack[0]: [Ljava/lang/Object; + + mv.visitInsn(Opcodes.SWAP); + + // Stack[4]: [Ljava/lang/Object; + // Stack[3]: Ljava/lang/String; + // Stack[2]: Ljava/util/logging/Level; + // Stack[1]: Ljava/util/logging/Logger; + // Stack[0]: [Ljava/lang/Object; + + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/logging/Logger", + "log", + "(Ljava/util/logging/Level;Ljava/lang/String;[Ljava/lang/Object;)V"); + + // Stack[0]: [Ljava/lang/Object; + + // 3. Load data structure from parameter array: + + mv.visitInsn(Opcodes.ICONST_0); + mv.visitInsn(Opcodes.AALOAD); + mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC); + + // Stack[0]: [Z + + return 5; // Maximum local stack size is 5 + } + + public void startup() { + setStartTimeStamp(); + this.logger.addHandler(handler); + } + + public void shutdown() { + this.logger.removeHandler(handler); + } + + private class RuntimeHandler extends Handler { + + @Override + public void publish(final LogRecord record) { + if (key.equals(record.getMessage())) { + access.getExecutionData(record.getParameters()); + } + } + + @Override + public void flush() { + // nothing to do + } + + @Override + public void close() throws SecurityException { + // The Java logging framework removes and closes all handlers on JVM + // shutdown. As soon as our handler has been removed, all classes + // that might get instrumented during shutdown (e.g. loaded by other + // shutdown hooks) will fail to initialize. Therefore we add ourself + // again here. This is a nasty hack that might fail in some Java + // implementations. + logger.addHandler(handler); + } + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java b/org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java index a09190a0..f2960289 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java @@ -1,178 +1,178 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import static java.lang.String.format;
-
-import java.lang.instrument.ClassFileTransformer;
-import java.lang.instrument.IllegalClassFormatException;
-import java.lang.instrument.Instrumentation;
-import java.lang.reflect.Field;
-import java.security.ProtectionDomain;
-
-import org.objectweb.asm.ClassAdapter;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * This {@link IRuntime} implementation works with a modified system class. A
- * new static method is added to a bootstrap class that will be used by
- * instrumented classes. As the system class itself needs to be instrumented
- * this runtime requires a Java agent.
- */
-public class ModifiedSystemClassRuntime extends AbstractRuntime {
-
- private static final String ACCESS_FIELD_TYPE = "Ljava/lang/Object;";
-
- private final Class<?> systemClass;
-
- private final String systemClassName;
-
- private final String accessFieldName;
-
- /**
- * Creates a new runtime based on the given class and members.
- *
- * @param systemClass
- * system class that contains the execution data
- * @param accessFieldName
- * name of the public static runtime access field
- *
- */
- public ModifiedSystemClassRuntime(final Class<?> systemClass,
- final String accessFieldName) {
- super();
- this.systemClass = systemClass;
- this.systemClassName = systemClass.getName().replace('.', '/');
- this.accessFieldName = accessFieldName;
- }
-
- public void startup() throws Exception {
- setStartTimeStamp();
- final Field field = systemClass.getField(accessFieldName);
- field.set(null, new ExecutionDataAccess(store));
- }
-
- public void shutdown() {
- // nothing to do
- }
-
- public int generateDataAccessor(final long classid, final String classname,
- final int probecount, final MethodVisitor mv) {
-
- mv.visitFieldInsn(Opcodes.GETSTATIC, systemClassName, accessFieldName,
- ACCESS_FIELD_TYPE);
-
- ExecutionDataAccess.generateAccessCall(classid, classname, probecount,
- mv);
-
- return 6;
- }
-
- /**
- * Creates a new {@link ModifiedSystemClassRuntime} using the given class as
- * the data container. Members are creates with internal default names. The
- * given class must not have been loaded before by the agent.
- *
- * @param inst
- * instrumentation interface
- * @param className
- * VM name of the class to use
- * @return new runtime instance
- *
- * @throws ClassNotFoundException
- * id the given class can not be found
- */
- public static IRuntime createFor(final Instrumentation inst,
- final String className) throws ClassNotFoundException {
- return createFor(inst, className, "$jacocoAccess");
- }
-
- /**
- * Creates a new {@link ModifiedSystemClassRuntime} using the given class as
- * the data container. The given class must not have been loaded before by
- * the agent.
- *
- * @param inst
- * instrumentation interface
- * @param className
- * VM name of the class to use
- * @param accessFieldName
- * name of the added runtime access field
- * @return new runtime instance
- *
- * @throws ClassNotFoundException
- * id the given class can not be found
- */
- public static IRuntime createFor(final Instrumentation inst,
- final String className, final String accessFieldName)
- throws ClassNotFoundException {
- final ClassFileTransformer transformer = new ClassFileTransformer() {
- public byte[] transform(final ClassLoader loader,
- final String name, final Class<?> classBeingRedefined,
- final ProtectionDomain protectionDomain, final byte[] source)
- throws IllegalClassFormatException {
- if (name.equals(className)) {
- return instrument(source, accessFieldName);
- }
- return null;
- }
- };
- inst.addTransformer(transformer);
- final Class<?> clazz = Class.forName(className.replace('/', '.'));
- inst.removeTransformer(transformer);
- try {
- clazz.getField(accessFieldName);
- } catch (final NoSuchFieldException e) {
- throw new RuntimeException(format(
- "Class %s could not be instrumented.", className), e);
- }
- return new ModifiedSystemClassRuntime(clazz, accessFieldName);
- }
-
- /**
- * Adds the static access method and data field to the given class
- * definition.
- *
- * @param source
- * class definition source
- * @param accessFieldName
- * name of the runtime access field
- * @return instrumented version with added members
- */
- public static byte[] instrument(final byte[] source,
- final String accessFieldName) {
- final ClassReader reader = new ClassReader(source);
- final ClassWriter writer = new ClassWriter(reader, 0);
- reader.accept(new ClassAdapter(writer) {
-
- @Override
- public void visitEnd() {
- createDataField(cv, accessFieldName);
- super.visitEnd();
- }
-
- }, ClassReader.EXPAND_FRAMES);
- return writer.toByteArray();
- }
-
- private static void createDataField(final ClassVisitor visitor,
- final String dataField) {
- visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
- | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_TRANSIENT, dataField,
- ACCESS_FIELD_TYPE, null, null);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import static java.lang.String.format; + +import java.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.lang.reflect.Field; +import java.security.ProtectionDomain; + +import org.objectweb.asm.ClassAdapter; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * This {@link IRuntime} implementation works with a modified system class. A + * new static method is added to a bootstrap class that will be used by + * instrumented classes. As the system class itself needs to be instrumented + * this runtime requires a Java agent. + */ +public class ModifiedSystemClassRuntime extends AbstractRuntime { + + private static final String ACCESS_FIELD_TYPE = "Ljava/lang/Object;"; + + private final Class<?> systemClass; + + private final String systemClassName; + + private final String accessFieldName; + + /** + * Creates a new runtime based on the given class and members. + * + * @param systemClass + * system class that contains the execution data + * @param accessFieldName + * name of the public static runtime access field + * + */ + public ModifiedSystemClassRuntime(final Class<?> systemClass, + final String accessFieldName) { + super(); + this.systemClass = systemClass; + this.systemClassName = systemClass.getName().replace('.', '/'); + this.accessFieldName = accessFieldName; + } + + public void startup() throws Exception { + setStartTimeStamp(); + final Field field = systemClass.getField(accessFieldName); + field.set(null, new ExecutionDataAccess(store)); + } + + public void shutdown() { + // nothing to do + } + + public int generateDataAccessor(final long classid, final String classname, + final int probecount, final MethodVisitor mv) { + + mv.visitFieldInsn(Opcodes.GETSTATIC, systemClassName, accessFieldName, + ACCESS_FIELD_TYPE); + + ExecutionDataAccess.generateAccessCall(classid, classname, probecount, + mv); + + return 6; + } + + /** + * Creates a new {@link ModifiedSystemClassRuntime} using the given class as + * the data container. Members are creates with internal default names. The + * given class must not have been loaded before by the agent. + * + * @param inst + * instrumentation interface + * @param className + * VM name of the class to use + * @return new runtime instance + * + * @throws ClassNotFoundException + * id the given class can not be found + */ + public static IRuntime createFor(final Instrumentation inst, + final String className) throws ClassNotFoundException { + return createFor(inst, className, "$jacocoAccess"); + } + + /** + * Creates a new {@link ModifiedSystemClassRuntime} using the given class as + * the data container. The given class must not have been loaded before by + * the agent. + * + * @param inst + * instrumentation interface + * @param className + * VM name of the class to use + * @param accessFieldName + * name of the added runtime access field + * @return new runtime instance + * + * @throws ClassNotFoundException + * id the given class can not be found + */ + public static IRuntime createFor(final Instrumentation inst, + final String className, final String accessFieldName) + throws ClassNotFoundException { + final ClassFileTransformer transformer = new ClassFileTransformer() { + public byte[] transform(final ClassLoader loader, + final String name, final Class<?> classBeingRedefined, + final ProtectionDomain protectionDomain, final byte[] source) + throws IllegalClassFormatException { + if (name.equals(className)) { + return instrument(source, accessFieldName); + } + return null; + } + }; + inst.addTransformer(transformer); + final Class<?> clazz = Class.forName(className.replace('/', '.')); + inst.removeTransformer(transformer); + try { + clazz.getField(accessFieldName); + } catch (final NoSuchFieldException e) { + throw new RuntimeException(format( + "Class %s could not be instrumented.", className), e); + } + return new ModifiedSystemClassRuntime(clazz, accessFieldName); + } + + /** + * Adds the static access method and data field to the given class + * definition. + * + * @param source + * class definition source + * @param accessFieldName + * name of the runtime access field + * @return instrumented version with added members + */ + public static byte[] instrument(final byte[] source, + final String accessFieldName) { + final ClassReader reader = new ClassReader(source); + final ClassWriter writer = new ClassWriter(reader, 0); + reader.accept(new ClassAdapter(writer) { + + @Override + public void visitEnd() { + createDataField(cv, accessFieldName); + super.visitEnd(); + } + + }, ClassReader.EXPAND_FRAMES); + return writer.toByteArray(); + } + + private static void createDataField(final ClassVisitor visitor, + final String dataField) { + visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC + | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_TRANSIENT, dataField, + ACCESS_FIELD_TYPE, null, null); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlReader.java b/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlReader.java index 456fccfe..c293b20b 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlReader.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlReader.java @@ -1,69 +1,69 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.jacoco.core.data.ExecutionDataReader;
-
-/**
- * {@link ExecutionDataReader} with commands added for runtime remote control.
- */
-public class RemoteControlReader extends ExecutionDataReader {
-
- private IRemoteCommandVisitor remoteCommandVisitor;
-
- /**
- * Create a new read based on the given input stream.
- *
- * @param input
- * input stream to read commands from
- * @throws IOException
- * if the stream does not have a valid header
- */
- public RemoteControlReader(final InputStream input) throws IOException {
- super(input);
- }
-
- @Override
- protected boolean readBlock(final byte blockid) throws IOException {
- switch (blockid) {
- case RemoteControlWriter.BLOCK_CMDDUMP:
- readDumpCommand();
- return true;
- case RemoteControlWriter.BLOCK_CMDOK:
- return false;
- default:
- return super.readBlock(blockid);
- }
- }
-
- /**
- * Sets an listener for agent commands.
- *
- * @param visitor
- */
- public void setRemoteCommandVisitor(final IRemoteCommandVisitor visitor) {
- this.remoteCommandVisitor = visitor;
- }
-
- private void readDumpCommand() throws IOException {
- if (remoteCommandVisitor == null) {
- throw new IOException("No remote command visitor.");
- }
- final boolean dump = in.readBoolean();
- final boolean reset = in.readBoolean();
- remoteCommandVisitor.visitDumpCommand(dump, reset);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import java.io.IOException; +import java.io.InputStream; + +import org.jacoco.core.data.ExecutionDataReader; + +/** + * {@link ExecutionDataReader} with commands added for runtime remote control. + */ +public class RemoteControlReader extends ExecutionDataReader { + + private IRemoteCommandVisitor remoteCommandVisitor; + + /** + * Create a new read based on the given input stream. + * + * @param input + * input stream to read commands from + * @throws IOException + * if the stream does not have a valid header + */ + public RemoteControlReader(final InputStream input) throws IOException { + super(input); + } + + @Override + protected boolean readBlock(final byte blockid) throws IOException { + switch (blockid) { + case RemoteControlWriter.BLOCK_CMDDUMP: + readDumpCommand(); + return true; + case RemoteControlWriter.BLOCK_CMDOK: + return false; + default: + return super.readBlock(blockid); + } + } + + /** + * Sets an listener for agent commands. + * + * @param visitor + */ + public void setRemoteCommandVisitor(final IRemoteCommandVisitor visitor) { + this.remoteCommandVisitor = visitor; + } + + private void readDumpCommand() throws IOException { + if (remoteCommandVisitor == null) { + throw new IOException("No remote command visitor."); + } + final boolean dump = in.readBoolean(); + final boolean reset = in.readBoolean(); + remoteCommandVisitor.visitDumpCommand(dump, reset); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlWriter.java b/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlWriter.java index 5a204d85..b3b4527d 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlWriter.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/RemoteControlWriter.java @@ -1,61 +1,61 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.jacoco.core.data.ExecutionDataWriter;
-
-/**
- * {@link ExecutionDataWriter} with commands added for runtime remote control.
- */
-public class RemoteControlWriter extends ExecutionDataWriter implements
- IRemoteCommandVisitor {
-
- /** Block identifier to confirm successful command execution. */
- public static final byte BLOCK_CMDOK = 0x20;
-
- /** Block identifier for dump command */
- public static final byte BLOCK_CMDDUMP = 0x40;
-
- /**
- * Creates a new writer based on the given output stream.
- *
- * @param output
- * stream to write commands to
- * @throws IOException
- * if the header can't be written
- */
- public RemoteControlWriter(final OutputStream output) throws IOException {
- super(output);
- }
-
- /**
- * Sends a confirmation that a commands has been successfully executed and
- * the response is completed.
- *
- * @throws IOException
- * in case of problems with the remote connection
- */
- public void sendCmdOk() throws IOException {
- out.writeByte(RemoteControlWriter.BLOCK_CMDOK);
- }
-
- public void visitDumpCommand(final boolean dump, final boolean reset)
- throws IOException {
- out.writeByte(RemoteControlWriter.BLOCK_CMDDUMP);
- out.writeBoolean(dump);
- out.writeBoolean(reset);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import java.io.IOException; +import java.io.OutputStream; + +import org.jacoco.core.data.ExecutionDataWriter; + +/** + * {@link ExecutionDataWriter} with commands added for runtime remote control. + */ +public class RemoteControlWriter extends ExecutionDataWriter implements + IRemoteCommandVisitor { + + /** Block identifier to confirm successful command execution. */ + public static final byte BLOCK_CMDOK = 0x20; + + /** Block identifier for dump command */ + public static final byte BLOCK_CMDDUMP = 0x40; + + /** + * Creates a new writer based on the given output stream. + * + * @param output + * stream to write commands to + * @throws IOException + * if the header can't be written + */ + public RemoteControlWriter(final OutputStream output) throws IOException { + super(output); + } + + /** + * Sends a confirmation that a commands has been successfully executed and + * the response is completed. + * + * @throws IOException + * in case of problems with the remote connection + */ + public void sendCmdOk() throws IOException { + out.writeByte(RemoteControlWriter.BLOCK_CMDOK); + } + + public void visitDumpCommand(final boolean dump, final boolean reset) + throws IOException { + out.writeByte(RemoteControlWriter.BLOCK_CMDDUMP); + out.writeBoolean(dump); + out.writeBoolean(reset); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/SystemPropertiesRuntime.java b/org.jacoco.core/src/org/jacoco/core/runtime/SystemPropertiesRuntime.java index 4d010d8a..196872d6 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/SystemPropertiesRuntime.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/SystemPropertiesRuntime.java @@ -1,75 +1,75 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * This {@link IRuntime} implementation makes the execution data available
- * through a special entry in the {@link System#getProperties()} hash table. The
- * advantage is, that the instrumented classes do not get dependencies to other
- * classes than the JRE library itself.
- *
- * This runtime may cause problems in environments with security restrictions,
- * in applications that replace the system properties or in applications that
- * fail if non-String values are placed in the system properties.
- */
-public class SystemPropertiesRuntime extends AbstractRuntime {
-
- private static final String KEYPREFIX = "jacoco-";
-
- private final String key;
-
- /**
- * Creates a new runtime.
- */
- public SystemPropertiesRuntime() {
- super();
- this.key = KEYPREFIX + Integer.toHexString(hashCode());
- }
-
- public int generateDataAccessor(final long classid, final String classname,
- final int probecount, final MethodVisitor mv) {
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System",
- "getProperties", "()Ljava/util/Properties;");
-
- // Stack[0]: Ljava/util/Properties;
-
- mv.visitLdcInsn(key);
-
- // Stack[1]: Ljava/lang/String;
- // Stack[0]: Ljava/util/Properties;
-
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/Properties",
- "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
-
- // Stack[0]: Ljava/lang/Object;
-
- ExecutionDataAccess.generateAccessCall(classid, classname, probecount,
- mv);
-
- // Stack[0]: [Z
-
- return 6; // Maximum local stack size is 3
- }
-
- public void startup() {
- setStartTimeStamp();
- System.getProperties().put(key, access);
- }
-
- public void shutdown() {
- System.getProperties().remove(key);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * This {@link IRuntime} implementation makes the execution data available + * through a special entry in the {@link System#getProperties()} hash table. The + * advantage is, that the instrumented classes do not get dependencies to other + * classes than the JRE library itself. + * + * This runtime may cause problems in environments with security restrictions, + * in applications that replace the system properties or in applications that + * fail if non-String values are placed in the system properties. + */ +public class SystemPropertiesRuntime extends AbstractRuntime { + + private static final String KEYPREFIX = "jacoco-"; + + private final String key; + + /** + * Creates a new runtime. + */ + public SystemPropertiesRuntime() { + super(); + this.key = KEYPREFIX + Integer.toHexString(hashCode()); + } + + public int generateDataAccessor(final long classid, final String classname, + final int probecount, final MethodVisitor mv) { + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", + "getProperties", "()Ljava/util/Properties;"); + + // Stack[0]: Ljava/util/Properties; + + mv.visitLdcInsn(key); + + // Stack[1]: Ljava/lang/String; + // Stack[0]: Ljava/util/Properties; + + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/Properties", + "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); + + // Stack[0]: Ljava/lang/Object; + + ExecutionDataAccess.generateAccessCall(classid, classname, probecount, + mv); + + // Stack[0]: [Z + + return 6; // Maximum local stack size is 3 + } + + public void startup() { + setStartTimeStamp(); + System.getProperties().put(key, access); + } + + public void shutdown() { + System.getProperties().remove(key); + } + +} diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/WildcardMatcher.java b/org.jacoco.core/src/org/jacoco/core/runtime/WildcardMatcher.java index 9951d20b..70fb8b5d 100644 --- a/org.jacoco.core/src/org/jacoco/core/runtime/WildcardMatcher.java +++ b/org.jacoco.core/src/org/jacoco/core/runtime/WildcardMatcher.java @@ -1,73 +1,73 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.core.runtime;
-
-import java.util.regex.Pattern;
-
-/**
- * Matches strings against <code>?</code>/<code>*</code> wildcard expressions.
- * Multiple expressions can be separated with a colon (:). In this case the
- * expression matches if at least one part matches.
- */
-public class WildcardMatcher {
-
- private final Pattern pattern;
-
- /**
- * Creates a new matcher with the given expression.
- *
- * @param expression
- * wildcard expressions
- */
- public WildcardMatcher(final String expression) {
- final String[] parts = expression.split("\\:");
- final StringBuilder regex = new StringBuilder(expression.length() * 2);
- boolean next = false;
- for (final String part : parts) {
- if (next) {
- regex.append('|');
- }
- regex.append('(').append(toRegex(part)).append(')');
- next = true;
- }
- pattern = Pattern.compile(regex.toString());
- }
-
- private static CharSequence toRegex(final String expression) {
- final StringBuilder regex = new StringBuilder(expression.length() * 2);
- for (final char c : expression.toCharArray()) {
- switch (c) {
- case '?':
- regex.append(".?");
- break;
- case '*':
- regex.append(".*");
- break;
- default:
- regex.append(Pattern.quote(String.valueOf(c)));
- }
- }
- return regex;
- }
-
- /**
- * Matches the given string against the expressions of this matcher.
- *
- * @param s
- * string to test
- * @return <code>true</code>, if the expression matches
- */
- public boolean matches(final String s) {
- return pattern.matcher(s).matches();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.core.runtime; + +import java.util.regex.Pattern; + +/** + * Matches strings against <code>?</code>/<code>*</code> wildcard expressions. + * Multiple expressions can be separated with a colon (:). In this case the + * expression matches if at least one part matches. + */ +public class WildcardMatcher { + + private final Pattern pattern; + + /** + * Creates a new matcher with the given expression. + * + * @param expression + * wildcard expressions + */ + public WildcardMatcher(final String expression) { + final String[] parts = expression.split("\\:"); + final StringBuilder regex = new StringBuilder(expression.length() * 2); + boolean next = false; + for (final String part : parts) { + if (next) { + regex.append('|'); + } + regex.append('(').append(toRegex(part)).append(')'); + next = true; + } + pattern = Pattern.compile(regex.toString()); + } + + private static CharSequence toRegex(final String expression) { + final StringBuilder regex = new StringBuilder(expression.length() * 2); + for (final char c : expression.toCharArray()) { + switch (c) { + case '?': + regex.append(".?"); + break; + case '*': + regex.append(".*"); + break; + default: + regex.append(Pattern.quote(String.valueOf(c))); + } + } + return regex; + } + + /** + * Matches the given string against the expressions of this matcher. + * + * @param s + * string to test + * @return <code>true</code>, if the expression matches + */ + public boolean matches(final String s) { + return pattern.matcher(s).matches(); + } + +} diff --git a/org.jacoco.examples/src/org/jacoco/examples/CoreTutorial.java b/org.jacoco.examples/src/org/jacoco/examples/CoreTutorial.java index f4976b65..99037c82 100644 --- a/org.jacoco.examples/src/org/jacoco/examples/CoreTutorial.java +++ b/org.jacoco.examples/src/org/jacoco/examples/CoreTutorial.java @@ -1,179 +1,179 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.examples;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jacoco.core.analysis.Analyzer;
-import org.jacoco.core.analysis.CoverageBuilder;
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.instr.Instrumenter;
-import org.jacoco.core.runtime.IRuntime;
-import org.jacoco.core.runtime.LoggerRuntime;
-
-/**
- * Example usage of the JaCoCo core API. In this tutorial a single target class
- * will be instrumented and executed. Finally the coverage information will be
- * dumped.
- */
-public final class CoreTutorial {
-
- /**
- * The test target we want to see code coverage for.
- */
- public static class TestTarget implements Runnable {
-
- public void run() {
- final int n = 7;
- final String status = isPrime(n) ? "prime" : "not prime";
- System.out.printf("%s is %s%n", Integer.valueOf(n), status);
- }
-
- private boolean isPrime(final int n) {
- for (int i = 2; i * i <= n; i++) {
- if ((n ^ i) == 0) {
- return false;
- }
- }
- return true;
- }
-
- }
-
- /**
- * A class loader that loads classes from in-memory data.
- */
- public static class MemoryClassLoader extends ClassLoader {
-
- private final Map<String, byte[]> definitions = new HashMap<String, byte[]>();
-
- /**
- * Add a in-memory representation of a class.
- *
- * @param name
- * name of the class
- * @param bytes
- * class definition
- */
- public void addDefinition(final String name, final byte[] bytes) {
- definitions.put(name, bytes);
- }
-
- @Override
- protected Class<?> loadClass(final String name, final boolean resolve)
- throws ClassNotFoundException {
- final byte[] bytes = definitions.get(name);
- if (bytes != null) {
- return defineClass(name, bytes, 0, bytes.length);
- }
- return super.loadClass(name, resolve);
- }
-
- }
-
- private InputStream getTargetClass(final String name) {
- final String resource = '/' + name.replace('.', '/') + ".class";
- return getClass().getResourceAsStream(resource);
- }
-
- private void printCounter(final String unit, final ICounter counter) {
- final Integer missed = Integer.valueOf(counter.getMissedCount());
- final Integer total = Integer.valueOf(counter.getTotalCount());
- System.out.printf("%s of %s %s missed%n", missed, total, unit);
- }
-
- private String getColor(final int status) {
- switch (status) {
- case ICounter.NOT_COVERED:
- return "red";
- case ICounter.PARTLY_COVERED:
- return "yellow";
- case ICounter.FULLY_COVERED:
- return "green";
- }
- return "";
- }
-
- private void runTutorial() throws Exception {
- final String targetName = TestTarget.class.getName();
-
- // For instrumentation and runtime we need a IRuntime instance
- // to collect execution data:
- final IRuntime runtime = new LoggerRuntime();
-
- // The Instrumenter creates a modified version of our test target class
- // that contains additional probes for execution data recording:
- final Instrumenter instr = new Instrumenter(runtime);
- final byte[] instrumented = instr
- .instrument(getTargetClass(targetName));
-
- // Now we're ready to run our instrumented class and need to startup the
- // runtime first:
- runtime.startup();
-
- // In this tutorial we use a special class loader to directly load the
- // instrumented class definition from a byte[] instances.
- final MemoryClassLoader memoryClassLoader = new MemoryClassLoader();
- memoryClassLoader.addDefinition(targetName, instrumented);
- final Class<?> targetClass = memoryClassLoader.loadClass(targetName);
-
- // Here we execute our test target class through its Runnable interface:
- final Runnable targetInstance = (Runnable) targetClass.newInstance();
- targetInstance.run();
-
- // At the end of test execution we collect execution data and shutdown
- // the runtime:
- final ExecutionDataStore executionData = new ExecutionDataStore();
- runtime.collect(executionData, null, false);
- runtime.shutdown();
-
- // Together with the original class definition we can calculate coverage
- // information:
- final CoverageBuilder coverageBuilder = new CoverageBuilder();
- final Analyzer analyzer = new Analyzer(executionData, coverageBuilder);
- analyzer.analyzeClass(getTargetClass(targetName));
-
- // Let's dump some metrics and line coverage information:
- for (final IClassCoverage cc : coverageBuilder.getClasses()) {
- System.out.printf("Coverage of class %s%n", cc.getName());
-
- printCounter("instructions", cc.getInstructionCounter());
- printCounter("branches", cc.getBranchCounter());
- printCounter("lines", cc.getLineCounter());
- printCounter("methods", cc.getMethodCounter());
- printCounter("complexity", cc.getComplexityCounter());
-
- for (int i = cc.getFirstLine(); i <= cc.getLastLine(); i++) {
- System.out.printf("Line %s: %s%n", Integer.valueOf(i),
- getColor(cc.getLine(i).getStatus()));
- }
- }
- }
-
- /**
- * Execute the example.
- *
- * @param args
- * @throws Exception
- */
- public static void main(final String[] args) throws Exception {
- new CoreTutorial().runTutorial();
- }
-
- private CoreTutorial() {
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.examples; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.jacoco.core.analysis.Analyzer; +import org.jacoco.core.analysis.CoverageBuilder; +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.LoggerRuntime; + +/** + * Example usage of the JaCoCo core API. In this tutorial a single target class + * will be instrumented and executed. Finally the coverage information will be + * dumped. + */ +public final class CoreTutorial { + + /** + * The test target we want to see code coverage for. + */ + public static class TestTarget implements Runnable { + + public void run() { + final int n = 7; + final String status = isPrime(n) ? "prime" : "not prime"; + System.out.printf("%s is %s%n", Integer.valueOf(n), status); + } + + private boolean isPrime(final int n) { + for (int i = 2; i * i <= n; i++) { + if ((n ^ i) == 0) { + return false; + } + } + return true; + } + + } + + /** + * A class loader that loads classes from in-memory data. + */ + public static class MemoryClassLoader extends ClassLoader { + + private final Map<String, byte[]> definitions = new HashMap<String, byte[]>(); + + /** + * Add a in-memory representation of a class. + * + * @param name + * name of the class + * @param bytes + * class definition + */ + public void addDefinition(final String name, final byte[] bytes) { + definitions.put(name, bytes); + } + + @Override + protected Class<?> loadClass(final String name, final boolean resolve) + throws ClassNotFoundException { + final byte[] bytes = definitions.get(name); + if (bytes != null) { + return defineClass(name, bytes, 0, bytes.length); + } + return super.loadClass(name, resolve); + } + + } + + private InputStream getTargetClass(final String name) { + final String resource = '/' + name.replace('.', '/') + ".class"; + return getClass().getResourceAsStream(resource); + } + + private void printCounter(final String unit, final ICounter counter) { + final Integer missed = Integer.valueOf(counter.getMissedCount()); + final Integer total = Integer.valueOf(counter.getTotalCount()); + System.out.printf("%s of %s %s missed%n", missed, total, unit); + } + + private String getColor(final int status) { + switch (status) { + case ICounter.NOT_COVERED: + return "red"; + case ICounter.PARTLY_COVERED: + return "yellow"; + case ICounter.FULLY_COVERED: + return "green"; + } + return ""; + } + + private void runTutorial() throws Exception { + final String targetName = TestTarget.class.getName(); + + // For instrumentation and runtime we need a IRuntime instance + // to collect execution data: + final IRuntime runtime = new LoggerRuntime(); + + // The Instrumenter creates a modified version of our test target class + // that contains additional probes for execution data recording: + final Instrumenter instr = new Instrumenter(runtime); + final byte[] instrumented = instr + .instrument(getTargetClass(targetName)); + + // Now we're ready to run our instrumented class and need to startup the + // runtime first: + runtime.startup(); + + // In this tutorial we use a special class loader to directly load the + // instrumented class definition from a byte[] instances. + final MemoryClassLoader memoryClassLoader = new MemoryClassLoader(); + memoryClassLoader.addDefinition(targetName, instrumented); + final Class<?> targetClass = memoryClassLoader.loadClass(targetName); + + // Here we execute our test target class through its Runnable interface: + final Runnable targetInstance = (Runnable) targetClass.newInstance(); + targetInstance.run(); + + // At the end of test execution we collect execution data and shutdown + // the runtime: + final ExecutionDataStore executionData = new ExecutionDataStore(); + runtime.collect(executionData, null, false); + runtime.shutdown(); + + // Together with the original class definition we can calculate coverage + // information: + final CoverageBuilder coverageBuilder = new CoverageBuilder(); + final Analyzer analyzer = new Analyzer(executionData, coverageBuilder); + analyzer.analyzeClass(getTargetClass(targetName)); + + // Let's dump some metrics and line coverage information: + for (final IClassCoverage cc : coverageBuilder.getClasses()) { + System.out.printf("Coverage of class %s%n", cc.getName()); + + printCounter("instructions", cc.getInstructionCounter()); + printCounter("branches", cc.getBranchCounter()); + printCounter("lines", cc.getLineCounter()); + printCounter("methods", cc.getMethodCounter()); + printCounter("complexity", cc.getComplexityCounter()); + + for (int i = cc.getFirstLine(); i <= cc.getLastLine(); i++) { + System.out.printf("Line %s: %s%n", Integer.valueOf(i), + getColor(cc.getLine(i).getStatus())); + } + } + } + + /** + * Execute the example. + * + * @param args + * @throws Exception + */ + public static void main(final String[] args) throws Exception { + new CoreTutorial().runTutorial(); + } + + private CoreTutorial() { + } + +} diff --git a/org.jacoco.examples/src/org/jacoco/examples/ExecutionDataClient.java b/org.jacoco.examples/src/org/jacoco/examples/ExecutionDataClient.java index ba13afde..8ed01ce0 100644 --- a/org.jacoco.examples/src/org/jacoco/examples/ExecutionDataClient.java +++ b/org.jacoco.examples/src/org/jacoco/examples/ExecutionDataClient.java @@ -1,65 +1,65 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.examples;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-
-import org.jacoco.core.runtime.RemoteControlReader;
-import org.jacoco.core.runtime.RemoteControlWriter;
-
-/**
- * This example connects to a coverage agent that run in output mode
- * <code>tcpserver</code> and requests execution data. The collected data is
- * dumped to a local file.
- */
-public final class ExecutionDataClient {
-
- private static final String DESTFILE = "jacoco-client.exec";
-
- private static final String ADDRESS = "localhost";
-
- private static final int PORT = 6300;
-
- /**
- * Starts the execution data request.
- *
- * @param args
- * @throws IOException
- */
- public static void main(final String[] args) throws IOException {
- final FileOutputStream localFile = new FileOutputStream(DESTFILE);
- final RemoteControlWriter localWriter = new RemoteControlWriter(
- localFile);
-
- // Open a socket to the coverage agent:
- final Socket socket = new Socket(InetAddress.getByName(ADDRESS), PORT);
- final RemoteControlWriter writer = new RemoteControlWriter(
- socket.getOutputStream());
- final RemoteControlReader reader = new RemoteControlReader(
- socket.getInputStream());
- reader.setSessionInfoVisitor(localWriter);
- reader.setExecutionDataVisitor(localWriter);
-
- // Send a dump command and read the response:
- writer.visitDumpCommand(true, false);
- reader.read();
-
- socket.close();
- localFile.close();
- }
-
- private ExecutionDataClient() {
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.examples; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; + +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; + +/** + * This example connects to a coverage agent that run in output mode + * <code>tcpserver</code> and requests execution data. The collected data is + * dumped to a local file. + */ +public final class ExecutionDataClient { + + private static final String DESTFILE = "jacoco-client.exec"; + + private static final String ADDRESS = "localhost"; + + private static final int PORT = 6300; + + /** + * Starts the execution data request. + * + * @param args + * @throws IOException + */ + public static void main(final String[] args) throws IOException { + final FileOutputStream localFile = new FileOutputStream(DESTFILE); + final RemoteControlWriter localWriter = new RemoteControlWriter( + localFile); + + // Open a socket to the coverage agent: + final Socket socket = new Socket(InetAddress.getByName(ADDRESS), PORT); + final RemoteControlWriter writer = new RemoteControlWriter( + socket.getOutputStream()); + final RemoteControlReader reader = new RemoteControlReader( + socket.getInputStream()); + reader.setSessionInfoVisitor(localWriter); + reader.setExecutionDataVisitor(localWriter); + + // Send a dump command and read the response: + writer.visitDumpCommand(true, false); + reader.read(); + + socket.close(); + localFile.close(); + } + + private ExecutionDataClient() { + } +} diff --git a/org.jacoco.examples/src/org/jacoco/examples/ExecutionDataServer.java b/org.jacoco.examples/src/org/jacoco/examples/ExecutionDataServer.java index 755d9d44..9dd6ce57 100644 --- a/org.jacoco.examples/src/org/jacoco/examples/ExecutionDataServer.java +++ b/org.jacoco.examples/src/org/jacoco/examples/ExecutionDataServer.java @@ -1,110 +1,110 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.examples;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.ExecutionDataWriter;
-import org.jacoco.core.data.IExecutionDataVisitor;
-import org.jacoco.core.data.ISessionInfoVisitor;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.core.runtime.RemoteControlReader;
-import org.jacoco.core.runtime.RemoteControlWriter;
-
-/**
- * This example starts a socket server to collect coverage from agents that run
- * in output mode <code>tcpclient</code>. The collected data is dumped to a
- * local file.
- */
-public final class ExecutionDataServer {
-
- private static final String DESTFILE = "jacoco-server.exec";
-
- private static final String ADDRESS = "localhost";
-
- private static final int PORT = 6300;
-
- /**
- * Start the server as a standalone program.
- *
- * @param args
- * @throws IOException
- */
- public static void main(final String[] args) throws IOException {
- final ExecutionDataWriter fileWriter = new ExecutionDataWriter(
- new FileOutputStream(DESTFILE));
- final ServerSocket server = new ServerSocket(PORT, 0,
- InetAddress.getByName(ADDRESS));
- while (true) {
- final Handler handler = new Handler(server.accept(), fileWriter);
- new Thread(handler).start();
- }
- }
-
- private static class Handler implements Runnable, ISessionInfoVisitor,
- IExecutionDataVisitor {
-
- private final Socket socket;
-
- private final RemoteControlReader reader;
-
- private final ExecutionDataWriter fileWriter;
-
- Handler(final Socket socket, final ExecutionDataWriter fileWriter)
- throws IOException {
- this.socket = socket;
- this.fileWriter = fileWriter;
-
- // Just send a valid header:
- new RemoteControlWriter(socket.getOutputStream());
-
- reader = new RemoteControlReader(socket.getInputStream());
- reader.setSessionInfoVisitor(this);
- reader.setExecutionDataVisitor(this);
- }
-
- public void run() {
- try {
- while (reader.read()) {
- }
- socket.close();
- synchronized (fileWriter) {
- fileWriter.flush();
- }
- } catch (final IOException e) {
- e.printStackTrace();
- }
- }
-
- public void visitSessionInfo(final SessionInfo info) {
- System.out.printf("Retrieving execution Data for session: %s%n",
- info.getId());
- synchronized (fileWriter) {
- fileWriter.visitSessionInfo(info);
- }
- }
-
- public void visitClassExecution(final ExecutionData data) {
- synchronized (fileWriter) {
- fileWriter.visitClassExecution(data);
- }
- }
- }
-
- private ExecutionDataServer() {
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.examples; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; + +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.ExecutionDataWriter; +import org.jacoco.core.data.IExecutionDataVisitor; +import org.jacoco.core.data.ISessionInfoVisitor; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.runtime.RemoteControlReader; +import org.jacoco.core.runtime.RemoteControlWriter; + +/** + * This example starts a socket server to collect coverage from agents that run + * in output mode <code>tcpclient</code>. The collected data is dumped to a + * local file. + */ +public final class ExecutionDataServer { + + private static final String DESTFILE = "jacoco-server.exec"; + + private static final String ADDRESS = "localhost"; + + private static final int PORT = 6300; + + /** + * Start the server as a standalone program. + * + * @param args + * @throws IOException + */ + public static void main(final String[] args) throws IOException { + final ExecutionDataWriter fileWriter = new ExecutionDataWriter( + new FileOutputStream(DESTFILE)); + final ServerSocket server = new ServerSocket(PORT, 0, + InetAddress.getByName(ADDRESS)); + while (true) { + final Handler handler = new Handler(server.accept(), fileWriter); + new Thread(handler).start(); + } + } + + private static class Handler implements Runnable, ISessionInfoVisitor, + IExecutionDataVisitor { + + private final Socket socket; + + private final RemoteControlReader reader; + + private final ExecutionDataWriter fileWriter; + + Handler(final Socket socket, final ExecutionDataWriter fileWriter) + throws IOException { + this.socket = socket; + this.fileWriter = fileWriter; + + // Just send a valid header: + new RemoteControlWriter(socket.getOutputStream()); + + reader = new RemoteControlReader(socket.getInputStream()); + reader.setSessionInfoVisitor(this); + reader.setExecutionDataVisitor(this); + } + + public void run() { + try { + while (reader.read()) { + } + socket.close(); + synchronized (fileWriter) { + fileWriter.flush(); + } + } catch (final IOException e) { + e.printStackTrace(); + } + } + + public void visitSessionInfo(final SessionInfo info) { + System.out.printf("Retrieving execution Data for session: %s%n", + info.getId()); + synchronized (fileWriter) { + fileWriter.visitSessionInfo(info); + } + } + + public void visitClassExecution(final ExecutionData data) { + synchronized (fileWriter) { + fileWriter.visitClassExecution(data); + } + } + } + + private ExecutionDataServer() { + } +} diff --git a/org.jacoco.examples/src/org/jacoco/examples/ReportGenerator.java b/org.jacoco.examples/src/org/jacoco/examples/ReportGenerator.java index ccd6ccef..dc10780c 100644 --- a/org.jacoco.examples/src/org/jacoco/examples/ReportGenerator.java +++ b/org.jacoco.examples/src/org/jacoco/examples/ReportGenerator.java @@ -1,153 +1,153 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.examples;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-import org.jacoco.core.analysis.Analyzer;
-import org.jacoco.core.analysis.CoverageBuilder;
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.data.ExecutionDataReader;
-import org.jacoco.core.data.ExecutionDataStore;
-import org.jacoco.core.data.SessionInfoStore;
-import org.jacoco.report.DirectorySourceFileLocator;
-import org.jacoco.report.FileMultiReportOutput;
-import org.jacoco.report.IReportVisitor;
-import org.jacoco.report.html.HTMLFormatter;
-
-/**
- * This example creates a HTML report for eclipse like projects based on a
- * single execution data store called jacoco.exec. The report contains no
- * grouping information.
- *
- * The class files under test must be compiled with debug information, otherwise
- * source highlighting will not work.
- */
-public class ReportGenerator {
-
- private final String title;
-
- private final File executionDataFile;
- private final File classesDirectory;
- private final File sourceDirectory;
- private final File reportDirectory;
-
- private ExecutionDataStore executionDataStore;
- private SessionInfoStore sessionInfoStore;
-
- /**
- * Create a new generator based for the given project.
- *
- * @param projectDirectory
- */
- public ReportGenerator(final File projectDirectory) {
- this.title = projectDirectory.getName();
- this.executionDataFile = new File(projectDirectory, "jacoco.exec");
- this.classesDirectory = new File(projectDirectory, "bin");
- this.sourceDirectory = new File(projectDirectory, "src");
- this.reportDirectory = new File(projectDirectory, "coveragereport");
- }
-
- /**
- * Create the report.
- *
- * @throws IOException
- */
- public void create() throws IOException {
-
- // Read the jacoco.exec file. Multiple data stores could be merged
- // at this point
- loadExecutionData();
-
- // Run the structure analyzer on a single class folder to build up
- // the coverage model. The process would be similar if your classes
- // were in a jar file. Typically you would create a bundle for each
- // class folder and each jar you want in your report. If you have
- // more than one bundle you will need to add a grouping node to your
- // report
- final IBundleCoverage bundleCoverage = analyzeStructure();
-
- createReport(bundleCoverage);
-
- }
-
- private void createReport(final IBundleCoverage bundleCoverage)
- throws IOException {
-
- // Create a concrete report visitor based on some supplied
- // configuration. In this case we use the defaults
- final HTMLFormatter htmlFormatter = new HTMLFormatter();
- final IReportVisitor visitor = htmlFormatter
- .createVisitor(new FileMultiReportOutput(reportDirectory));
-
- // Initialize the report with all of the execution and session
- // information. At this point the report doesn't know about the
- // structure of the report being created
- visitor.visitInfo(sessionInfoStore.getInfos(),
- executionDataStore.getContents());
-
- // Populate the report structure with the bundle coverage information.
- // Call visitGroup if you need groups in your report.
- visitor.visitBundle(bundleCoverage, new DirectorySourceFileLocator(
- sourceDirectory, "utf-8", 4));
-
- // Signal end of structure information to allow report to write all
- // information out
- visitor.visitEnd();
-
- }
-
- private void loadExecutionData() throws IOException {
- final FileInputStream fis = new FileInputStream(executionDataFile);
- final ExecutionDataReader executionDataReader = new ExecutionDataReader(
- fis);
- executionDataStore = new ExecutionDataStore();
- sessionInfoStore = new SessionInfoStore();
-
- executionDataReader.setExecutionDataVisitor(executionDataStore);
- executionDataReader.setSessionInfoVisitor(sessionInfoStore);
-
- while (executionDataReader.read()) {
- }
-
- fis.close();
- }
-
- private IBundleCoverage analyzeStructure() throws IOException {
- final CoverageBuilder coverageBuilder = new CoverageBuilder();
- final Analyzer analyzer = new Analyzer(executionDataStore,
- coverageBuilder);
-
- analyzer.analyzeAll(classesDirectory);
-
- return coverageBuilder.getBundle(title);
- }
-
- /**
- * Starts the report generation process
- *
- * @param args
- * Arguments to the application. This will be the location of the
- * eclipse projects that will be used to generate reports for
- * @throws IOException
- */
- public static void main(final String[] args) throws IOException {
- for (int i = 0; i < args.length; i++) {
- final ReportGenerator generator = new ReportGenerator(new File(
- args[i]));
- generator.create();
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.examples; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import org.jacoco.core.analysis.Analyzer; +import org.jacoco.core.analysis.CoverageBuilder; +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.data.ExecutionDataReader; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.SessionInfoStore; +import org.jacoco.report.DirectorySourceFileLocator; +import org.jacoco.report.FileMultiReportOutput; +import org.jacoco.report.IReportVisitor; +import org.jacoco.report.html.HTMLFormatter; + +/** + * This example creates a HTML report for eclipse like projects based on a + * single execution data store called jacoco.exec. The report contains no + * grouping information. + * + * The class files under test must be compiled with debug information, otherwise + * source highlighting will not work. + */ +public class ReportGenerator { + + private final String title; + + private final File executionDataFile; + private final File classesDirectory; + private final File sourceDirectory; + private final File reportDirectory; + + private ExecutionDataStore executionDataStore; + private SessionInfoStore sessionInfoStore; + + /** + * Create a new generator based for the given project. + * + * @param projectDirectory + */ + public ReportGenerator(final File projectDirectory) { + this.title = projectDirectory.getName(); + this.executionDataFile = new File(projectDirectory, "jacoco.exec"); + this.classesDirectory = new File(projectDirectory, "bin"); + this.sourceDirectory = new File(projectDirectory, "src"); + this.reportDirectory = new File(projectDirectory, "coveragereport"); + } + + /** + * Create the report. + * + * @throws IOException + */ + public void create() throws IOException { + + // Read the jacoco.exec file. Multiple data stores could be merged + // at this point + loadExecutionData(); + + // Run the structure analyzer on a single class folder to build up + // the coverage model. The process would be similar if your classes + // were in a jar file. Typically you would create a bundle for each + // class folder and each jar you want in your report. If you have + // more than one bundle you will need to add a grouping node to your + // report + final IBundleCoverage bundleCoverage = analyzeStructure(); + + createReport(bundleCoverage); + + } + + private void createReport(final IBundleCoverage bundleCoverage) + throws IOException { + + // Create a concrete report visitor based on some supplied + // configuration. In this case we use the defaults + final HTMLFormatter htmlFormatter = new HTMLFormatter(); + final IReportVisitor visitor = htmlFormatter + .createVisitor(new FileMultiReportOutput(reportDirectory)); + + // Initialize the report with all of the execution and session + // information. At this point the report doesn't know about the + // structure of the report being created + visitor.visitInfo(sessionInfoStore.getInfos(), + executionDataStore.getContents()); + + // Populate the report structure with the bundle coverage information. + // Call visitGroup if you need groups in your report. + visitor.visitBundle(bundleCoverage, new DirectorySourceFileLocator( + sourceDirectory, "utf-8", 4)); + + // Signal end of structure information to allow report to write all + // information out + visitor.visitEnd(); + + } + + private void loadExecutionData() throws IOException { + final FileInputStream fis = new FileInputStream(executionDataFile); + final ExecutionDataReader executionDataReader = new ExecutionDataReader( + fis); + executionDataStore = new ExecutionDataStore(); + sessionInfoStore = new SessionInfoStore(); + + executionDataReader.setExecutionDataVisitor(executionDataStore); + executionDataReader.setSessionInfoVisitor(sessionInfoStore); + + while (executionDataReader.read()) { + } + + fis.close(); + } + + private IBundleCoverage analyzeStructure() throws IOException { + final CoverageBuilder coverageBuilder = new CoverageBuilder(); + final Analyzer analyzer = new Analyzer(executionDataStore, + coverageBuilder); + + analyzer.analyzeAll(classesDirectory); + + return coverageBuilder.getBundle(title); + } + + /** + * Starts the report generation process + * + * @param args + * Arguments to the application. This will be the location of the + * eclipse projects that will be used to generate reports for + * @throws IOException + */ + public static void main(final String[] args) throws IOException { + for (int i = 0; i < args.length; i++) { + final ReportGenerator generator = new ReportGenerator(new File( + args[i])); + generator.create(); + } + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/FileMultiReportOutputTest.java b/org.jacoco.report.test/src/org/jacoco/report/FileMultiReportOutputTest.java index e94009ba..de265200 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/FileMultiReportOutputTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/FileMultiReportOutputTest.java @@ -1,61 +1,61 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-/**
- * Unit tests for {@link FileMultiReportOutput}.
- */
-public class FileMultiReportOutputTest {
-
- @Rule
- public TemporaryFolder folder = new TemporaryFolder();
-
- @Test
- public void testCreateFileWithDirectories() throws IOException {
- final IMultiReportOutput output = new FileMultiReportOutput(
- folder.getRoot());
- final OutputStream stream = output.createFile("a/b/c/test");
- stream.write(1);
- stream.write(2);
- stream.write(3);
- stream.close();
- output.close();
-
- final InputStream actual = new FileInputStream(new File(
- folder.getRoot(), "a/b/c/test"));
- assertEquals(1, actual.read());
- assertEquals(2, actual.read());
- assertEquals(3, actual.read());
- assertEquals(-1, actual.read());
- }
-
- @Test(expected = IOException.class)
- public void testCreateFileNegative() throws IOException {
- folder.newFile("a");
- final IMultiReportOutput output = new FileMultiReportOutput(
- folder.getRoot());
- output.createFile("a/b/c/test");
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +/** + * Unit tests for {@link FileMultiReportOutput}. + */ +public class FileMultiReportOutputTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void testCreateFileWithDirectories() throws IOException { + final IMultiReportOutput output = new FileMultiReportOutput( + folder.getRoot()); + final OutputStream stream = output.createFile("a/b/c/test"); + stream.write(1); + stream.write(2); + stream.write(3); + stream.close(); + output.close(); + + final InputStream actual = new FileInputStream(new File( + folder.getRoot(), "a/b/c/test")); + assertEquals(1, actual.read()); + assertEquals(2, actual.read()); + assertEquals(3, actual.read()); + assertEquals(-1, actual.read()); + } + + @Test(expected = IOException.class) + public void testCreateFileNegative() throws IOException { + folder.newFile("a"); + final IMultiReportOutput output = new FileMultiReportOutput( + folder.getRoot()); + output.createFile("a/b/c/test"); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/JavaNamesTest.java b/org.jacoco.report.test/src/org/jacoco/report/JavaNamesTest.java index c0c001ff..78c265ef 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/JavaNamesTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/JavaNamesTest.java @@ -1,156 +1,156 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link JavaNames}.
- */
-public class JavaNamesTest {
-
- private ILanguageNames names;
-
- @Before
- public void setup() {
- names = new JavaNames();
- }
-
- @Test
- public void testGetPackageName1() {
- assertEquals("default", names.getPackageName(""));
- }
-
- @Test
- public void testGetPackageName2() {
- assertEquals("java.lang", names.getPackageName("java/lang"));
- }
-
- @Test
- public void testGetClassName1() {
- assertEquals("Main", names.getClassName("Main", null, null, null));
- }
-
- @Test
- public void testGetClassName2() {
- assertEquals("Object",
- names.getClassName("java/lang/Object", null, null, null));
- }
-
- @Test
- public void testGetClassName3() {
- assertEquals("Map.Entry",
- names.getClassName("java/util/Map$Entry", null, null, null));
- }
-
- @Test
- public void testGetClassName4() {
- assertEquals("Bar.new Object() {...}", names.getClassName(
- "com/foo/Bar$1", null, "java/lang/Object", new String[0]));
- }
-
- @Test
- public void testGetClassName5() {
- assertEquals("Bar.new ISample() {...}", names.getClassName(
- "com/foo/Bar$1", null, "java/lang/Object",
- new String[] { "org/foo/ISample" }));
- }
-
- @Test
- public void testGetClassName6() {
- assertEquals("Bar.1",
- names.getClassName("com/foo/Bar$1", null, null, null));
- }
-
- @Test
- public void testGetClassName7() {
- assertEquals("Strange.",
- names.getClassName("com/foo/Strange$", null, null, null));
- }
-
- @Test
- public void testGetQualifiedClassName1() {
- assertEquals("Foo", names.getQualifiedClassName("Foo"));
- }
-
- @Test
- public void testGetQualifiedClassName2() {
- assertEquals("java.lang.Object",
- names.getQualifiedClassName("java/lang/Object"));
- }
-
- @Test
- public void testGetQualifiedClassName3() {
- assertEquals("java.util.Map.Entry",
- names.getQualifiedClassName("java/util/Map$Entry"));
- }
-
- @Test
- public void testGetMethodName1() {
- assertEquals("wait()",
- names.getMethodName("java/lang/Object", "wait", "()V", null));
- }
-
- @Test
- public void testGetMethodName2() {
- assertEquals("remove(Object)",
- names.getMethodName("java/util/Collection", "remove",
- "(Ljava/lang/Object;)V", null));
- }
-
- @Test
- public void testGetMethodName3() {
- assertEquals("remove(int)",
- names.getMethodName("java/util/List", "remove", "(I)V", null));
- }
-
- @Test
- public void testGetMethodName4() {
- assertEquals("add(int, Object)", names.getMethodName("java/util/List",
- "add", "(ILjava/lang/Object;)V", null));
- }
-
- @Test
- public void testGetMethodName5() {
- assertEquals("sort(Object[])", names.getMethodName("java/util/Arrays",
- "sort", "([Ljava/lang/Object;)V", null));
- }
-
- @Test
- public void testGetMethodName6() {
- assertEquals("Object()",
- names.getMethodName("java/lang/Object", "<init>", "()V", null));
- }
-
- @Test
- public void testGetMethodName7() {
- assertEquals("static {...}", names.getMethodName(
- "com/example/SomeClass", "<clinit>", "()V", null));
- }
-
- @Test
- public void testGetMethodName8() {
- assertEquals("update(Map.Entry)", names.getMethodName(
- "com/example/SomeClass", "update", "(Ljava/util/Map$Entry;)V",
- null));
- }
-
- @Test
- public void testGetMethodName9() {
- assertEquals("{...}", names.getMethodName("com/example/SomeClass$1",
- "<init>", "()V", null));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link JavaNames}. + */ +public class JavaNamesTest { + + private ILanguageNames names; + + @Before + public void setup() { + names = new JavaNames(); + } + + @Test + public void testGetPackageName1() { + assertEquals("default", names.getPackageName("")); + } + + @Test + public void testGetPackageName2() { + assertEquals("java.lang", names.getPackageName("java/lang")); + } + + @Test + public void testGetClassName1() { + assertEquals("Main", names.getClassName("Main", null, null, null)); + } + + @Test + public void testGetClassName2() { + assertEquals("Object", + names.getClassName("java/lang/Object", null, null, null)); + } + + @Test + public void testGetClassName3() { + assertEquals("Map.Entry", + names.getClassName("java/util/Map$Entry", null, null, null)); + } + + @Test + public void testGetClassName4() { + assertEquals("Bar.new Object() {...}", names.getClassName( + "com/foo/Bar$1", null, "java/lang/Object", new String[0])); + } + + @Test + public void testGetClassName5() { + assertEquals("Bar.new ISample() {...}", names.getClassName( + "com/foo/Bar$1", null, "java/lang/Object", + new String[] { "org/foo/ISample" })); + } + + @Test + public void testGetClassName6() { + assertEquals("Bar.1", + names.getClassName("com/foo/Bar$1", null, null, null)); + } + + @Test + public void testGetClassName7() { + assertEquals("Strange.", + names.getClassName("com/foo/Strange$", null, null, null)); + } + + @Test + public void testGetQualifiedClassName1() { + assertEquals("Foo", names.getQualifiedClassName("Foo")); + } + + @Test + public void testGetQualifiedClassName2() { + assertEquals("java.lang.Object", + names.getQualifiedClassName("java/lang/Object")); + } + + @Test + public void testGetQualifiedClassName3() { + assertEquals("java.util.Map.Entry", + names.getQualifiedClassName("java/util/Map$Entry")); + } + + @Test + public void testGetMethodName1() { + assertEquals("wait()", + names.getMethodName("java/lang/Object", "wait", "()V", null)); + } + + @Test + public void testGetMethodName2() { + assertEquals("remove(Object)", + names.getMethodName("java/util/Collection", "remove", + "(Ljava/lang/Object;)V", null)); + } + + @Test + public void testGetMethodName3() { + assertEquals("remove(int)", + names.getMethodName("java/util/List", "remove", "(I)V", null)); + } + + @Test + public void testGetMethodName4() { + assertEquals("add(int, Object)", names.getMethodName("java/util/List", + "add", "(ILjava/lang/Object;)V", null)); + } + + @Test + public void testGetMethodName5() { + assertEquals("sort(Object[])", names.getMethodName("java/util/Arrays", + "sort", "([Ljava/lang/Object;)V", null)); + } + + @Test + public void testGetMethodName6() { + assertEquals("Object()", + names.getMethodName("java/lang/Object", "<init>", "()V", null)); + } + + @Test + public void testGetMethodName7() { + assertEquals("static {...}", names.getMethodName( + "com/example/SomeClass", "<clinit>", "()V", null)); + } + + @Test + public void testGetMethodName8() { + assertEquals("update(Map.Entry)", names.getMethodName( + "com/example/SomeClass", "update", "(Ljava/util/Map$Entry;)V", + null)); + } + + @Test + public void testGetMethodName9() { + assertEquals("{...}", names.getMethodName("com/example/SomeClass$1", + "<init>", "()V", null)); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/MemoryMultiReportOutput.java b/org.jacoco.report.test/src/org/jacoco/report/MemoryMultiReportOutput.java index d6e492cb..5d51d2fa 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/MemoryMultiReportOutput.java +++ b/org.jacoco.report.test/src/org/jacoco/report/MemoryMultiReportOutput.java @@ -1,86 +1,86 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * In-memory report output for test purposes.
- */
-public class MemoryMultiReportOutput implements IMultiReportOutput {
-
- private final Map<String, ByteArrayOutputStream> files = new HashMap<String, ByteArrayOutputStream>();
-
- private final Set<String> open = new HashSet<String>();
-
- private boolean closed = false;
-
- public OutputStream createFile(final String path) throws IOException {
- assertFalse("Duplicate output " + path, files.containsKey(path));
- open.add(path);
- final ByteArrayOutputStream out = new ByteArrayOutputStream() {
- @Override
- public void close() throws IOException {
- open.remove(path);
- super.close();
- }
- };
- files.put(path, out);
- return out;
- }
-
- public void close() throws IOException {
- closed = true;
- }
-
- public void assertEmpty() {
- assertEquals(Collections.emptySet(), files.keySet());
- }
-
- public void assertFile(String path) {
- assertNotNull(String.format("Missing file %s. Actual files are %s.",
- path, files.keySet()), files.get(path));
- }
-
- public void assertSingleFile(String path) {
- assertEquals(Collections.singleton(path), files.keySet());
- }
-
- public byte[] getFile(String path) {
- assertFile(path);
- return files.get(path).toByteArray();
- }
-
- public InputStream getFileAsStream(String path) {
- return new ByteArrayInputStream(getFile(path));
- }
-
- public void assertAllClosed() {
- assertEquals(Collections.emptySet(), open);
- assertTrue(closed);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * In-memory report output for test purposes. + */ +public class MemoryMultiReportOutput implements IMultiReportOutput { + + private final Map<String, ByteArrayOutputStream> files = new HashMap<String, ByteArrayOutputStream>(); + + private final Set<String> open = new HashSet<String>(); + + private boolean closed = false; + + public OutputStream createFile(final String path) throws IOException { + assertFalse("Duplicate output " + path, files.containsKey(path)); + open.add(path); + final ByteArrayOutputStream out = new ByteArrayOutputStream() { + @Override + public void close() throws IOException { + open.remove(path); + super.close(); + } + }; + files.put(path, out); + return out; + } + + public void close() throws IOException { + closed = true; + } + + public void assertEmpty() { + assertEquals(Collections.emptySet(), files.keySet()); + } + + public void assertFile(String path) { + assertNotNull(String.format("Missing file %s. Actual files are %s.", + path, files.keySet()), files.get(path)); + } + + public void assertSingleFile(String path) { + assertEquals(Collections.singleton(path), files.keySet()); + } + + public byte[] getFile(String path) { + assertFile(path); + return files.get(path).toByteArray(); + } + + public InputStream getFileAsStream(String path) { + return new ByteArrayInputStream(getFile(path)); + } + + public void assertAllClosed() { + assertEquals(Collections.emptySet(), open); + assertTrue(closed); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/MemoryOutput.java b/org.jacoco.report.test/src/org/jacoco/report/MemoryOutput.java index 6e88e81e..883964d3 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/MemoryOutput.java +++ b/org.jacoco.report.test/src/org/jacoco/report/MemoryOutput.java @@ -1,42 +1,42 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * In-memory report output for test purposes.
- */
-public class MemoryOutput extends ByteArrayOutputStream {
-
- private boolean closed = false;
-
- @Override
- public void close() throws IOException {
- super.close();
- closed = true;
- }
-
- public InputStream getContentsAsStream() {
- return new ByteArrayInputStream(toByteArray());
- }
-
- public void assertClosed() {
- assertTrue(closed);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * In-memory report output for test purposes. + */ +public class MemoryOutput extends ByteArrayOutputStream { + + private boolean closed = false; + + @Override + public void close() throws IOException { + super.close(); + closed = true; + } + + public InputStream getContentsAsStream() { + return new ByteArrayInputStream(toByteArray()); + } + + public void assertClosed() { + assertTrue(closed); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/MultiReportVisitorTest.java b/org.jacoco.report.test/src/org/jacoco/report/MultiReportVisitorTest.java index c69b5903..c9669a72 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/MultiReportVisitorTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/MultiReportVisitorTest.java @@ -1,129 +1,129 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.analysis.IPackageCoverage;
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.core.internal.analysis.BundleCoverageImpl;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link MultiReportVisitor}.
- */
-public class MultiReportVisitorTest {
-
- private static class MockVisitor extends MockGroupVisitor implements
- IReportVisitor {
-
- MockVisitor() {
- super("Report");
- }
-
- private boolean visitInfosCalled = false;
-
- private boolean visitEndCalled = false;
-
- public void visitInfo(List<SessionInfo> sessionInfos,
- Collection<ExecutionData> executionData) throws IOException {
- visitInfosCalled = true;
- }
-
- public void visitEnd() throws IOException {
- visitEndCalled = true;
- }
-
- @Override
- public String toString() {
- assertTrue("visitInfos() has not been called", visitInfosCalled);
- assertTrue("visitEnd() has not been called", visitEndCalled);
- return super.toString();
- }
-
- }
-
- private static class MockGroupVisitor implements IReportGroupVisitor {
-
- private final String name;
-
- private final List<MockGroupVisitor> children = new ArrayList<MockGroupVisitor>();
-
- MockGroupVisitor(String name) {
- this.name = name;
- }
-
- public void visitBundle(IBundleCoverage bundle,
- ISourceFileLocator locator) throws IOException {
- children.add(new MockGroupVisitor(bundle.getName()));
- }
-
- public IReportGroupVisitor visitGroup(String name) throws IOException {
- MockGroupVisitor child = new MockGroupVisitor(name);
- children.add(child);
- return child;
- }
-
- @Override
- public String toString() {
- return name + children;
- }
- }
-
- private IBundleCoverage createBundle(String name) {
- final Collection<IPackageCoverage> packages = Collections.emptyList();
- return new BundleCoverageImpl(name, packages);
- }
-
- private static final String MOCK_REPORT = "Report[g1[b1[], b2[]], g2[]]";
-
- private void createMockReport(IReportVisitor visitor) throws IOException {
- final List<SessionInfo> sessions = Collections.emptyList();
- final List<ExecutionData> executionData = Collections.emptyList();
- visitor.visitInfo(sessions, executionData);
- IReportGroupVisitor g1 = visitor.visitGroup("g1");
- g1.visitBundle(createBundle("b1"), null);
- g1.visitBundle(createBundle("b2"), null);
- visitor.visitGroup("g2");
- visitor.visitEnd();
- }
-
- @Test
- public void testMockFormatter() throws IOException {
- MockVisitor visitor = new MockVisitor();
- createMockReport(visitor);
- assertEquals(MOCK_REPORT, visitor.toString());
- }
-
- @Test
- public void testMultiFormatter() throws IOException {
- IReportVisitor mock1 = new MockVisitor();
- IReportVisitor mock2 = new MockVisitor();
- IReportVisitor mock3 = new MockVisitor();
- List<IReportVisitor> visitors = Arrays.asList(mock1, mock2, mock3);
- MultiReportVisitor multi = new MultiReportVisitor(visitors);
- createMockReport(multi);
- assertEquals(MOCK_REPORT, mock1.toString());
- assertEquals(MOCK_REPORT, mock2.toString());
- assertEquals(MOCK_REPORT, mock3.toString());
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.analysis.IPackageCoverage; +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.core.internal.analysis.BundleCoverageImpl; +import org.junit.Test; + +/** + * Unit tests for {@link MultiReportVisitor}. + */ +public class MultiReportVisitorTest { + + private static class MockVisitor extends MockGroupVisitor implements + IReportVisitor { + + MockVisitor() { + super("Report"); + } + + private boolean visitInfosCalled = false; + + private boolean visitEndCalled = false; + + public void visitInfo(List<SessionInfo> sessionInfos, + Collection<ExecutionData> executionData) throws IOException { + visitInfosCalled = true; + } + + public void visitEnd() throws IOException { + visitEndCalled = true; + } + + @Override + public String toString() { + assertTrue("visitInfos() has not been called", visitInfosCalled); + assertTrue("visitEnd() has not been called", visitEndCalled); + return super.toString(); + } + + } + + private static class MockGroupVisitor implements IReportGroupVisitor { + + private final String name; + + private final List<MockGroupVisitor> children = new ArrayList<MockGroupVisitor>(); + + MockGroupVisitor(String name) { + this.name = name; + } + + public void visitBundle(IBundleCoverage bundle, + ISourceFileLocator locator) throws IOException { + children.add(new MockGroupVisitor(bundle.getName())); + } + + public IReportGroupVisitor visitGroup(String name) throws IOException { + MockGroupVisitor child = new MockGroupVisitor(name); + children.add(child); + return child; + } + + @Override + public String toString() { + return name + children; + } + } + + private IBundleCoverage createBundle(String name) { + final Collection<IPackageCoverage> packages = Collections.emptyList(); + return new BundleCoverageImpl(name, packages); + } + + private static final String MOCK_REPORT = "Report[g1[b1[], b2[]], g2[]]"; + + private void createMockReport(IReportVisitor visitor) throws IOException { + final List<SessionInfo> sessions = Collections.emptyList(); + final List<ExecutionData> executionData = Collections.emptyList(); + visitor.visitInfo(sessions, executionData); + IReportGroupVisitor g1 = visitor.visitGroup("g1"); + g1.visitBundle(createBundle("b1"), null); + g1.visitBundle(createBundle("b2"), null); + visitor.visitGroup("g2"); + visitor.visitEnd(); + } + + @Test + public void testMockFormatter() throws IOException { + MockVisitor visitor = new MockVisitor(); + createMockReport(visitor); + assertEquals(MOCK_REPORT, visitor.toString()); + } + + @Test + public void testMultiFormatter() throws IOException { + IReportVisitor mock1 = new MockVisitor(); + IReportVisitor mock2 = new MockVisitor(); + IReportVisitor mock3 = new MockVisitor(); + List<IReportVisitor> visitors = Arrays.asList(mock1, mock2, mock3); + MultiReportVisitor multi = new MultiReportVisitor(visitors); + createMockReport(multi); + assertEquals(MOCK_REPORT, mock1.toString()); + assertEquals(MOCK_REPORT, mock2.toString()); + assertEquals(MOCK_REPORT, mock3.toString()); + } +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/csv/CSVGroupHandlerTest.java b/org.jacoco.report.test/src/org/jacoco/report/csv/CSVGroupHandlerTest.java index 04b90cc4..b3d3be27 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/csv/CSVGroupHandlerTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/csv/CSVGroupHandlerTest.java @@ -1,70 +1,70 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.csv;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.BufferedReader;
-import java.io.StringReader;
-import java.io.StringWriter;
-
-import org.jacoco.report.IReportGroupVisitor;
-import org.jacoco.report.JavaNames;
-import org.jacoco.report.ReportStructureTestDriver;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link CSVGroupHandler}.
- */
-public class CSVGroupHandlerTest {
-
- private IReportGroupVisitor handler;
-
- private StringWriter result;
-
- private ReportStructureTestDriver driver;
-
- @Before
- public void setup() throws Exception {
- result = new StringWriter();
- final DelimitedWriter dw = new DelimitedWriter(result);
- final ClassRowWriter rw = new ClassRowWriter(dw, new JavaNames());
- handler = new CSVGroupHandler(rw);
- driver = new ReportStructureTestDriver();
- }
-
- @Test
- public void testVisitBundle() throws Exception {
- driver.sendBundle(handler);
- final BufferedReader reader = getResultReader();
- reader.readLine();
- assertEquals(
- "bundle,org.jacoco.example,FooClass,10,15,1,2,0,3,1,2,0,1",
- reader.readLine());
- }
-
- @Test
- public void testVisitGroup() throws Exception {
- driver.sendGroup(handler);
- final BufferedReader reader = getResultReader();
- reader.readLine();
- assertEquals(
- "group/bundle,org.jacoco.example,FooClass,10,15,1,2,0,3,1,2,0,1",
- reader.readLine());
- }
-
- private BufferedReader getResultReader() {
- return new BufferedReader(new StringReader(result.toString()));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.csv; + +import static org.junit.Assert.assertEquals; + +import java.io.BufferedReader; +import java.io.StringReader; +import java.io.StringWriter; + +import org.jacoco.report.IReportGroupVisitor; +import org.jacoco.report.JavaNames; +import org.jacoco.report.ReportStructureTestDriver; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link CSVGroupHandler}. + */ +public class CSVGroupHandlerTest { + + private IReportGroupVisitor handler; + + private StringWriter result; + + private ReportStructureTestDriver driver; + + @Before + public void setup() throws Exception { + result = new StringWriter(); + final DelimitedWriter dw = new DelimitedWriter(result); + final ClassRowWriter rw = new ClassRowWriter(dw, new JavaNames()); + handler = new CSVGroupHandler(rw); + driver = new ReportStructureTestDriver(); + } + + @Test + public void testVisitBundle() throws Exception { + driver.sendBundle(handler); + final BufferedReader reader = getResultReader(); + reader.readLine(); + assertEquals( + "bundle,org.jacoco.example,FooClass,10,15,1,2,0,3,1,2,0,1", + reader.readLine()); + } + + @Test + public void testVisitGroup() throws Exception { + driver.sendGroup(handler); + final BufferedReader reader = getResultReader(); + reader.readLine(); + assertEquals( + "group/bundle,org.jacoco.example,FooClass,10,15,1,2,0,3,1,2,0,1", + reader.readLine()); + } + + private BufferedReader getResultReader() { + return new BufferedReader(new StringReader(result.toString())); + } + +} 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 bde27480..df205c40 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 @@ -1,94 +1,94 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.csv;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.BufferedReader;
-import java.io.StringReader;
-import java.io.StringWriter;
-
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.internal.analysis.ClassCoverageImpl;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.jacoco.report.ILanguageNames;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link ClassRowWriter}.
- */
-public class ClassRowWriterTest {
-
- private StringWriter result;
-
- private ClassRowWriter writer;
-
- @Before
- public void setup() throws Exception {
- ILanguageNames names = new ILanguageNames() {
- public String getClassName(String vmname, String vmsignature,
- String vmsuperclass, String[] vminterfaces) {
- return vmname;
- }
-
- public String getPackageName(String vmname) {
- return vmname;
- }
-
- public String getQualifiedClassName(String vmname) {
- throw new AssertionError();
- }
-
- public String getMethodName(String vmclassname,
- String vmmethodname, String vmdesc, String vmsignature) {
- throw new AssertionError();
- }
- };
- result = new StringWriter();
- writer = new ClassRowWriter(new DelimitedWriter(result), names);
- }
-
- @Test
- public void TestHeader() throws Exception {
- BufferedReader reader = getResultReader();
- assertEquals(
- "GROUP,PACKAGE,CLASS,INSTRUCTION_MISSED,INSTRUCTION_COVERED,BRANCH_MISSED,BRANCH_COVERED,LINE_MISSED,LINE_COVERED,COMPLEXITY_MISSED,COMPLEXITY_COVERED,METHOD_MISSED,METHOD_COVERED",
- reader.readLine());
- }
-
- @Test
- public void TestRow() throws Exception {
- IClassCoverage node = new ClassCoverageImpl("test/package/Foo", 123,
- null, "java/lang/Object", null) {
- {
- instructionCounter = CounterImpl.getInstance(1, 11);
- branchCounter = CounterImpl.getInstance(2, 22);
- lineCounter = CounterImpl.getInstance(3, 33);
- complexityCounter = CounterImpl.getInstance(4, 44);
- methodCounter = CounterImpl.getInstance(5, 55);
- classCounter = CounterImpl.getInstance(6, 66);
- }
- };
- writer.writeRow("group", "test/package", node);
- BufferedReader reader = getResultReader();
- reader.readLine();
- assertEquals(
- "group,test/package,test/package/Foo,1,11,2,22,3,33,4,44,5,55",
- reader.readLine());
- }
-
- private BufferedReader getResultReader() {
- return new BufferedReader(new StringReader(result.toString()));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.csv; + +import static org.junit.Assert.assertEquals; + +import java.io.BufferedReader; +import java.io.StringReader; +import java.io.StringWriter; + +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.internal.analysis.ClassCoverageImpl; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.report.ILanguageNames; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link ClassRowWriter}. + */ +public class ClassRowWriterTest { + + private StringWriter result; + + private ClassRowWriter writer; + + @Before + public void setup() throws Exception { + ILanguageNames names = new ILanguageNames() { + public String getClassName(String vmname, String vmsignature, + String vmsuperclass, String[] vminterfaces) { + return vmname; + } + + public String getPackageName(String vmname) { + return vmname; + } + + public String getQualifiedClassName(String vmname) { + throw new AssertionError(); + } + + public String getMethodName(String vmclassname, + String vmmethodname, String vmdesc, String vmsignature) { + throw new AssertionError(); + } + }; + result = new StringWriter(); + writer = new ClassRowWriter(new DelimitedWriter(result), names); + } + + @Test + public void TestHeader() throws Exception { + BufferedReader reader = getResultReader(); + assertEquals( + "GROUP,PACKAGE,CLASS,INSTRUCTION_MISSED,INSTRUCTION_COVERED,BRANCH_MISSED,BRANCH_COVERED,LINE_MISSED,LINE_COVERED,COMPLEXITY_MISSED,COMPLEXITY_COVERED,METHOD_MISSED,METHOD_COVERED", + reader.readLine()); + } + + @Test + public void TestRow() throws Exception { + IClassCoverage node = new ClassCoverageImpl("test/package/Foo", 123, + null, "java/lang/Object", null) { + { + instructionCounter = CounterImpl.getInstance(1, 11); + branchCounter = CounterImpl.getInstance(2, 22); + lineCounter = CounterImpl.getInstance(3, 33); + complexityCounter = CounterImpl.getInstance(4, 44); + methodCounter = CounterImpl.getInstance(5, 55); + classCounter = CounterImpl.getInstance(6, 66); + } + }; + writer.writeRow("group", "test/package", node); + BufferedReader reader = getResultReader(); + reader.readLine(); + assertEquals( + "group,test/package,test/package/Foo,1,11,2,22,3,33,4,44,5,55", + reader.readLine()); + } + + private BufferedReader getResultReader() { + return new BufferedReader(new StringReader(result.toString())); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/csv/DelimitedWriterTest.java b/org.jacoco.report.test/src/org/jacoco/report/csv/DelimitedWriterTest.java index f0371166..f1fdcd05 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/csv/DelimitedWriterTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/csv/DelimitedWriterTest.java @@ -1,118 +1,118 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.report.csv;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link DelimitedWriter}
- */
-public class DelimitedWriterTest {
-
- private StringWriter result;
- private DelimitedWriter writer;
-
- private static final String NEW_LINE = System.getProperty("line.separator");
-
- @Before
- public void setUp() {
- result = new StringWriter();
- writer = new DelimitedWriter(result);
- }
-
- @Test
- public void testNoWrites() throws IOException {
- assertResult("");
- }
-
- @Test
- public void testSingleField() throws IOException {
- writer.write("test");
- assertResult("test");
- }
-
- @Test
- public void testFieldContainingDelimiter() throws IOException {
- writer.write("value,1");
- assertResult("\"value,1\"");
- }
-
- @Test
- public void testFieldContainingDelimiterAndQuote() throws IOException {
- writer.write("\",\"");
- assertResult("\"\"\",\"\"\"");
- }
-
- @Test
- public void testWriteEmptyHeader() throws IOException {
- writer.write(new String[] {});
- assertResult("");
- }
-
- @Test
- public void testWriteHeader() throws IOException {
- writer.write("header1", "header2", "header3");
- assertResult("header1,header2,header3");
- }
-
- @Test
- public void testMultipleFieldsOnOneLine() throws IOException {
- writer.write("test1");
- writer.write("test2");
- assertResult("test1,test2");
- }
-
- @Test
- public void testMultipleFieldsOnMultipleLines() throws IOException {
- writer.write("test1");
- writer.write("test2");
- writer.nextLine();
- writer.write("test3");
- writer.write("test4");
- assertResult("test1,test2" + NEW_LINE + "test3,test4");
- }
-
- @Test
- public void testAutoEscapedField() throws IOException {
- writer.write("\"\"");
- assertResult("\"\"\"\"\"\"");
- }
-
- @Test
- public void testWordWithSpace() throws IOException {
- writer.write("space test");
- assertResult("space test");
- }
-
- @Test
- public void testInt() throws IOException {
- writer.write(-123000);
- assertResult("-123000");
- }
-
- @Test
- public void testInts() throws IOException {
- writer.write(1, 20, 300);
- assertResult("1,20,300");
- }
-
- private void assertResult(String expected) throws IOException {
- writer.close();
- assertEquals(expected, result.toString());
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.report.csv; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.StringWriter; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link DelimitedWriter} + */ +public class DelimitedWriterTest { + + private StringWriter result; + private DelimitedWriter writer; + + private static final String NEW_LINE = System.getProperty("line.separator"); + + @Before + public void setUp() { + result = new StringWriter(); + writer = new DelimitedWriter(result); + } + + @Test + public void testNoWrites() throws IOException { + assertResult(""); + } + + @Test + public void testSingleField() throws IOException { + writer.write("test"); + assertResult("test"); + } + + @Test + public void testFieldContainingDelimiter() throws IOException { + writer.write("value,1"); + assertResult("\"value,1\""); + } + + @Test + public void testFieldContainingDelimiterAndQuote() throws IOException { + writer.write("\",\""); + assertResult("\"\"\",\"\"\""); + } + + @Test + public void testWriteEmptyHeader() throws IOException { + writer.write(new String[] {}); + assertResult(""); + } + + @Test + public void testWriteHeader() throws IOException { + writer.write("header1", "header2", "header3"); + assertResult("header1,header2,header3"); + } + + @Test + public void testMultipleFieldsOnOneLine() throws IOException { + writer.write("test1"); + writer.write("test2"); + assertResult("test1,test2"); + } + + @Test + public void testMultipleFieldsOnMultipleLines() throws IOException { + writer.write("test1"); + writer.write("test2"); + writer.nextLine(); + writer.write("test3"); + writer.write("test4"); + assertResult("test1,test2" + NEW_LINE + "test3,test4"); + } + + @Test + public void testAutoEscapedField() throws IOException { + writer.write("\"\""); + assertResult("\"\"\"\"\"\""); + } + + @Test + public void testWordWithSpace() throws IOException { + writer.write("space test"); + assertResult("space test"); + } + + @Test + public void testInt() throws IOException { + writer.write(-123000); + assertResult("-123000"); + } + + @Test + public void testInts() throws IOException { + writer.write(1, 20, 300); + assertResult("1,20,300"); + } + + private void assertResult(String expected) throws IOException { + writer.close(); + assertEquals(expected, result.toString()); + } +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/NormalizedFileNamesTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/NormalizedFileNamesTest.java index be810306..6b21b68b 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/NormalizedFileNamesTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/NormalizedFileNamesTest.java @@ -1,76 +1,76 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link NormalizedFileNames}.
- */
-public class NormalizedFileNamesTest {
-
- private NormalizedFileNames nfn;
-
- @Before
- public void setup() {
- nfn = new NormalizedFileNames();
- }
-
- @Test
- public void testKeepLegalCharacters() {
- String id = "Foo-bar_$15.class";
- assertEquals(id, nfn.getFileName(id));
- }
-
- @Test
- public void testReplaceIllegalCharacters() {
- String id = "A/b C;";
- assertEquals("A_b_C_", nfn.getFileName(id));
- }
-
- @Test
- public void testSameInstance() {
- // If no normalization is required we should get the same instance.
- String id = new String("Example.html");
- assertSame(id, nfn.getFileName(id));
- assertSame(id, nfn.getFileName(new String("Example.html")));
- }
-
- @Test
- public void testReplaceIllegalCharactersNonUnique() {
- assertEquals("F__", nfn.getFileName("F__"));
- assertEquals("F__~1", nfn.getFileName("F**"));
- assertEquals("F__~2", nfn.getFileName("F??"));
-
- // Mapping must be reproducible
- assertEquals("F__", nfn.getFileName("F__"));
- assertEquals("F__~1", nfn.getFileName("F**"));
- assertEquals("F__~2", nfn.getFileName("F??"));
- }
-
- @Test
- public void testCaseAware() {
- assertEquals("Hello", nfn.getFileName("Hello"));
- assertEquals("HELLO~1", nfn.getFileName("HELLO"));
- assertEquals("HeLLo~2", nfn.getFileName("HeLLo"));
-
- // Mapping must be reproducible
- assertEquals("Hello", nfn.getFileName("Hello"));
- assertEquals("HELLO~1", nfn.getFileName("HELLO"));
- assertEquals("HeLLo~2", nfn.getFileName("HeLLo"));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link NormalizedFileNames}. + */ +public class NormalizedFileNamesTest { + + private NormalizedFileNames nfn; + + @Before + public void setup() { + nfn = new NormalizedFileNames(); + } + + @Test + public void testKeepLegalCharacters() { + String id = "Foo-bar_$15.class"; + assertEquals(id, nfn.getFileName(id)); + } + + @Test + public void testReplaceIllegalCharacters() { + String id = "A/b C;"; + assertEquals("A_b_C_", nfn.getFileName(id)); + } + + @Test + public void testSameInstance() { + // If no normalization is required we should get the same instance. + String id = new String("Example.html"); + assertSame(id, nfn.getFileName(id)); + assertSame(id, nfn.getFileName(new String("Example.html"))); + } + + @Test + public void testReplaceIllegalCharactersNonUnique() { + assertEquals("F__", nfn.getFileName("F__")); + assertEquals("F__~1", nfn.getFileName("F**")); + assertEquals("F__~2", nfn.getFileName("F??")); + + // Mapping must be reproducible + assertEquals("F__", nfn.getFileName("F__")); + assertEquals("F__~1", nfn.getFileName("F**")); + assertEquals("F__~2", nfn.getFileName("F??")); + } + + @Test + public void testCaseAware() { + assertEquals("Hello", nfn.getFileName("Hello")); + assertEquals("HELLO~1", nfn.getFileName("HELLO")); + assertEquals("HeLLo~2", nfn.getFileName("HeLLo")); + + // Mapping must be reproducible + assertEquals("Hello", nfn.getFileName("Hello")); + assertEquals("HELLO~1", nfn.getFileName("HELLO")); + assertEquals("HeLLo~2", nfn.getFileName("HeLLo")); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/ReportOutputFolderTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/ReportOutputFolderTest.java index bc597fbf..8b82e14b 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/ReportOutputFolderTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/ReportOutputFolderTest.java @@ -1,106 +1,106 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-import java.io.IOException;
-
-import org.jacoco.report.MemoryMultiReportOutput;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link ReportOutputFolder}.
- */
-public class ReportOutputFolderTest {
-
- private MemoryMultiReportOutput output;
-
- private ReportOutputFolder root;
-
- @Before
- public void setup() {
- output = new MemoryMultiReportOutput();
- root = new ReportOutputFolder(output);
- }
-
- @After
- public void teardown() throws IOException {
- output.close();
- output.assertAllClosed();
- }
-
- @Test
- public void testFileInRoot() throws IOException {
- root.createFile("test.html").close();
- output.assertSingleFile("test.html");
- }
-
- @Test
- public void testSubfolderInstance() throws IOException {
- final ReportOutputFolder folder1 = root.subFolder("folder1");
- final ReportOutputFolder folder2 = root.subFolder("folder1");
- assertSame(folder1, folder2);
- }
-
- @Test
- public void testFileInSubFolder() throws IOException {
- root.subFolder("folderA").subFolder("folderB").createFile("test.html")
- .close();
- output.assertSingleFile("folderA/folderB/test.html");
- output.close();
- output.assertAllClosed();
- }
-
- @Test
- public void testRelativeLinkInSameFolder() throws IOException {
- final ReportOutputFolder base = root.subFolder("f1").subFolder("f2");
- assertEquals("test.html", base.getLink(base, "test.html"));
- }
-
- @Test
- public void testRelativeLinkInParentFolder() throws IOException {
- final ReportOutputFolder base = root.subFolder("f1").subFolder("f2");
- assertEquals("../../test.html", root.getLink(base, "test.html"));
- }
-
- @Test
- public void testRelativeLinkInSubFolder() throws IOException {
- final ReportOutputFolder folder = root.subFolder("f1").subFolder("f2");
- assertEquals("f1/f2/test.html", folder.getLink(root, "test.html"));
- }
-
- @Test
- public void testRelativeLinkInSibling1() throws IOException {
- final ReportOutputFolder folder = root.subFolder("f1").subFolder("f2");
- final ReportOutputFolder base = root.subFolder("g1").subFolder("g2");
- assertEquals("../../f1/f2/test.html", folder.getLink(base, "test.html"));
- }
-
- @Test
- public void testRelativeLinkInSibling2() throws IOException {
- final ReportOutputFolder folder = root.subFolder("f1").subFolder("f2");
- final ReportOutputFolder base = root.subFolder("f1").subFolder("g2");
- assertEquals("../f2/test.html", folder.getLink(base, "test.html"));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testInvalidRelativeLink() throws IOException {
- final ReportOutputFolder folder = root.subFolder("f1").subFolder("f2");
- final ReportOutputFolder base = new ReportOutputFolder(
- new MemoryMultiReportOutput()).subFolder("g1");
- folder.getLink(base, "test.html");
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import java.io.IOException; + +import org.jacoco.report.MemoryMultiReportOutput; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link ReportOutputFolder}. + */ +public class ReportOutputFolderTest { + + private MemoryMultiReportOutput output; + + private ReportOutputFolder root; + + @Before + public void setup() { + output = new MemoryMultiReportOutput(); + root = new ReportOutputFolder(output); + } + + @After + public void teardown() throws IOException { + output.close(); + output.assertAllClosed(); + } + + @Test + public void testFileInRoot() throws IOException { + root.createFile("test.html").close(); + output.assertSingleFile("test.html"); + } + + @Test + public void testSubfolderInstance() throws IOException { + final ReportOutputFolder folder1 = root.subFolder("folder1"); + final ReportOutputFolder folder2 = root.subFolder("folder1"); + assertSame(folder1, folder2); + } + + @Test + public void testFileInSubFolder() throws IOException { + root.subFolder("folderA").subFolder("folderB").createFile("test.html") + .close(); + output.assertSingleFile("folderA/folderB/test.html"); + output.close(); + output.assertAllClosed(); + } + + @Test + public void testRelativeLinkInSameFolder() throws IOException { + final ReportOutputFolder base = root.subFolder("f1").subFolder("f2"); + assertEquals("test.html", base.getLink(base, "test.html")); + } + + @Test + public void testRelativeLinkInParentFolder() throws IOException { + final ReportOutputFolder base = root.subFolder("f1").subFolder("f2"); + assertEquals("../../test.html", root.getLink(base, "test.html")); + } + + @Test + public void testRelativeLinkInSubFolder() throws IOException { + final ReportOutputFolder folder = root.subFolder("f1").subFolder("f2"); + assertEquals("f1/f2/test.html", folder.getLink(root, "test.html")); + } + + @Test + public void testRelativeLinkInSibling1() throws IOException { + final ReportOutputFolder folder = root.subFolder("f1").subFolder("f2"); + final ReportOutputFolder base = root.subFolder("g1").subFolder("g2"); + assertEquals("../../f1/f2/test.html", folder.getLink(base, "test.html")); + } + + @Test + public void testRelativeLinkInSibling2() throws IOException { + final ReportOutputFolder folder = root.subFolder("f1").subFolder("f2"); + final ReportOutputFolder base = root.subFolder("f1").subFolder("g2"); + assertEquals("../f2/test.html", folder.getLink(base, "test.html")); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidRelativeLink() throws IOException { + final ReportOutputFolder folder = root.subFolder("f1").subFolder("f2"); + final ReportOutputFolder base = new ReportOutputFolder( + new MemoryMultiReportOutput()).subFolder("g1"); + folder.getLink(base, "test.html"); + } +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLDocumentTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLDocumentTest.java index 7257d783..c29be43b 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLDocumentTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLDocumentTest.java @@ -1,85 +1,85 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link HTMLDocument}.
- */
-public class HTMLDocumentTest {
-
- @Test
- public void testWriter() throws IOException {
- StringWriter buffer = new StringWriter();
- new HTMLDocument(buffer, "UTF-8").close();
- assertEquals(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
- + "<html xmlns=\"http://www.w3.org/1999/xhtml\"/>",
- buffer.toString());
- }
-
- @Test
- public void testStream() throws IOException {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- new HTMLDocument(buffer, "UTF-8").close();
- assertEquals(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
- + "<html xmlns=\"http://www.w3.org/1999/xhtml\"/>",
- buffer.toString("UTF-8"));
- }
-
- @Test
- public void testHead() throws IOException {
- StringWriter buffer = new StringWriter();
- final HTMLDocument doc = new HTMLDocument(buffer, "UTF-8");
- doc.head();
- doc.close();
- assertEquals(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
- + "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head/></html>",
- buffer.toString());
- }
-
- @Test
- public void testBody() throws IOException {
- StringWriter buffer = new StringWriter();
- final HTMLDocument doc = new HTMLDocument(buffer, "UTF-8");
- doc.body();
- doc.close();
- assertEquals(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
- + "<html xmlns=\"http://www.w3.org/1999/xhtml\"><body/></html>",
- buffer.toString());
- }
-
- @Test
- public void testMinimalHTMLDocument() throws Exception {
- StringWriter buffer = new StringWriter();
- final HTMLDocument doc = new HTMLDocument(buffer, "UTF-8");
- doc.head().title();
- doc.body();
- doc.close();
- new HTMLSupport().parse(buffer.toString());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringWriter; + +import org.junit.Test; + +/** + * Unit tests for {@link HTMLDocument}. + */ +public class HTMLDocumentTest { + + @Test + public void testWriter() throws IOException { + StringWriter buffer = new StringWriter(); + new HTMLDocument(buffer, "UTF-8").close(); + assertEquals( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + + "<html xmlns=\"http://www.w3.org/1999/xhtml\"/>", + buffer.toString()); + } + + @Test + public void testStream() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + new HTMLDocument(buffer, "UTF-8").close(); + assertEquals( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + + "<html xmlns=\"http://www.w3.org/1999/xhtml\"/>", + buffer.toString("UTF-8")); + } + + @Test + public void testHead() throws IOException { + StringWriter buffer = new StringWriter(); + final HTMLDocument doc = new HTMLDocument(buffer, "UTF-8"); + doc.head(); + doc.close(); + assertEquals( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + + "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head/></html>", + buffer.toString()); + } + + @Test + public void testBody() throws IOException { + StringWriter buffer = new StringWriter(); + final HTMLDocument doc = new HTMLDocument(buffer, "UTF-8"); + doc.body(); + doc.close(); + assertEquals( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + + "<html xmlns=\"http://www.w3.org/1999/xhtml\"><body/></html>", + buffer.toString()); + } + + @Test + public void testMinimalHTMLDocument() throws Exception { + StringWriter buffer = new StringWriter(); + final HTMLDocument doc = new HTMLDocument(buffer, "UTF-8"); + doc.head().title(); + doc.body(); + doc.close(); + new HTMLSupport().parse(buffer.toString()); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLElementTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLElementTest.java index f05285c8..ce663396 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLElementTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLElementTest.java @@ -1,241 +1,241 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link HTMLElement}.
- */
-public class HTMLElementTest {
-
- private StringWriter buffer;
-
- private HTMLElement root;
-
- @Before
- public void setUp() throws IOException {
- buffer = new StringWriter();
- root = new HTMLElement(buffer, "root") {
- {
- beginOpenTag();
- }
- };
- }
-
- @Test
- public void testMeta() throws IOException {
- root.meta("key", "value");
- root.close();
- assertEquals(
- "<root><meta http-equiv=\"key\" content=\"value\"/></root>",
- buffer.toString());
- }
-
- @Test
- public void testLink() throws IOException {
- root.link("stylesheet", "style.css", "text/css");
- root.close();
- assertEquals(
- "<root><link rel=\"stylesheet\" href=\"style.css\" type=\"text/css\"/></root>",
- buffer.toString());
- }
-
- @Test
- public void testTitle() throws IOException {
- root.title();
- root.close();
- assertEquals("<root><title/></root>", buffer.toString());
- }
-
- @Test
- public void testH1() throws IOException {
- root.h1();
- root.close();
- assertEquals("<root><h1/></root>", buffer.toString());
- }
-
- @Test
- public void testP() throws IOException {
- root.p();
- root.close();
- assertEquals("<root><p/></root>", buffer.toString());
- }
-
- @Test
- public void testSpan1() throws IOException {
- root.span();
- root.close();
- assertEquals("<root><span/></root>", buffer.toString());
- }
-
- @Test
- public void testSpan2() throws IOException {
- root.span("abc");
- root.close();
- assertEquals("<root><span class=\"abc\"/></root>", buffer.toString());
- }
-
- @Test
- public void testSpan3() throws IOException {
- root.span("abc", "xy");
- root.close();
- assertEquals("<root><span class=\"abc\" id=\"xy\"/></root>",
- buffer.toString());
- }
-
- @Test
- public void testPre() throws IOException {
- root.pre("mystyle");
- root.close();
- assertEquals("<root><pre class=\"mystyle\"/></root>", buffer.toString());
- }
-
- @Test
- public void testDiv() throws IOException {
- root.div("mystyle");
- root.close();
- assertEquals("<root><div class=\"mystyle\"/></root>", buffer.toString());
- }
-
- @Test
- public void testCode() throws IOException {
- root.code().text("0xCAFEBABE");
- root.close();
- assertEquals("<root><code>0xCAFEBABE</code></root>", buffer.toString());
- }
-
- @Test
- public void testA1() throws IOException {
- root.a("http://www.jacoco.org/");
- root.close();
- assertEquals("<root><a href=\"http://www.jacoco.org/\"/></root>",
- buffer.toString());
- }
-
- @Test
- public void testA2() throws IOException {
- root.a("http://www.jacoco.org/", "extern");
- root.close();
- assertEquals(
- "<root><a href=\"http://www.jacoco.org/\" class=\"extern\"/></root>",
- buffer.toString());
- }
-
- @Test
- public void testALinkable1() throws IOException {
- root.a(new LinkableStub(null, "here", null), null);
- root.close();
- assertEquals("<root><span>here</span></root>", buffer.toString());
- }
-
- @Test
- public void testALinkable2() throws IOException {
- root.a(new LinkableStub(null, "here", "blue"), null);
- root.close();
- assertEquals("<root><span class=\"blue\">here</span></root>",
- buffer.toString());
- }
-
- @Test
- public void testALinkable3() throws IOException {
- root.a(new LinkableStub("index.html", "here", null), null);
- root.close();
- assertEquals("<root><a href=\"index.html\">here</a></root>",
- buffer.toString());
- }
-
- @Test
- public void testALinkable4() throws IOException {
- root.a(new LinkableStub("index.html", "here", "red"), null);
- root.close();
- assertEquals(
- "<root><a href=\"index.html\" class=\"red\">here</a></root>",
- buffer.toString());
- }
-
- @Test
- public void testTable() throws IOException {
- root.table("tablestyle");
- root.close();
- assertEquals(
- "<root><table class=\"tablestyle\" cellspacing=\"0\"/></root>",
- buffer.toString());
- }
-
- @Test
- public void testThead() throws IOException {
- root.thead();
- root.close();
- assertEquals("<root><thead/></root>", buffer.toString());
- }
-
- @Test
- public void testTfoot() throws IOException {
- root.tfoot();
- root.close();
- assertEquals("<root><tfoot/></root>", buffer.toString());
- }
-
- @Test
- public void testTbody() throws IOException {
- root.tbody();
- root.close();
- assertEquals("<root><tbody/></root>", buffer.toString());
- }
-
- @Test
- public void testTr() throws IOException {
- root.tr();
- root.close();
- assertEquals("<root><tr/></root>", buffer.toString());
- }
-
- @Test
- public void testTd1() throws IOException {
- root.td();
- root.close();
- assertEquals("<root><td/></root>", buffer.toString());
- }
-
- @Test
- public void testTd2() throws IOException {
- root.td("mystyle");
- root.close();
- assertEquals("<root><td class=\"mystyle\"/></root>", buffer.toString());
- }
-
- @Test
- public void testImg() throws IOException {
- root.img("sample.gif", 16, 32, "Hello");
- root.close();
- assertEquals(
- "<root><img src=\"sample.gif\" width=\"16\" height=\"32\" title=\"Hello\" alt=\"Hello\"/></root>",
- buffer.toString());
- }
-
- @Test
- public void testScript() throws IOException {
- root.script("text/javascript", "file.js");
- root.close();
- assertEquals(
- "<root><script type=\"text/javascript\" src=\"file.js\"></script></root>",
- buffer.toString());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.StringWriter; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link HTMLElement}. + */ +public class HTMLElementTest { + + private StringWriter buffer; + + private HTMLElement root; + + @Before + public void setUp() throws IOException { + buffer = new StringWriter(); + root = new HTMLElement(buffer, "root") { + { + beginOpenTag(); + } + }; + } + + @Test + public void testMeta() throws IOException { + root.meta("key", "value"); + root.close(); + assertEquals( + "<root><meta http-equiv=\"key\" content=\"value\"/></root>", + buffer.toString()); + } + + @Test + public void testLink() throws IOException { + root.link("stylesheet", "style.css", "text/css"); + root.close(); + assertEquals( + "<root><link rel=\"stylesheet\" href=\"style.css\" type=\"text/css\"/></root>", + buffer.toString()); + } + + @Test + public void testTitle() throws IOException { + root.title(); + root.close(); + assertEquals("<root><title/></root>", buffer.toString()); + } + + @Test + public void testH1() throws IOException { + root.h1(); + root.close(); + assertEquals("<root><h1/></root>", buffer.toString()); + } + + @Test + public void testP() throws IOException { + root.p(); + root.close(); + assertEquals("<root><p/></root>", buffer.toString()); + } + + @Test + public void testSpan1() throws IOException { + root.span(); + root.close(); + assertEquals("<root><span/></root>", buffer.toString()); + } + + @Test + public void testSpan2() throws IOException { + root.span("abc"); + root.close(); + assertEquals("<root><span class=\"abc\"/></root>", buffer.toString()); + } + + @Test + public void testSpan3() throws IOException { + root.span("abc", "xy"); + root.close(); + assertEquals("<root><span class=\"abc\" id=\"xy\"/></root>", + buffer.toString()); + } + + @Test + public void testPre() throws IOException { + root.pre("mystyle"); + root.close(); + assertEquals("<root><pre class=\"mystyle\"/></root>", buffer.toString()); + } + + @Test + public void testDiv() throws IOException { + root.div("mystyle"); + root.close(); + assertEquals("<root><div class=\"mystyle\"/></root>", buffer.toString()); + } + + @Test + public void testCode() throws IOException { + root.code().text("0xCAFEBABE"); + root.close(); + assertEquals("<root><code>0xCAFEBABE</code></root>", buffer.toString()); + } + + @Test + public void testA1() throws IOException { + root.a("http://www.jacoco.org/"); + root.close(); + assertEquals("<root><a href=\"http://www.jacoco.org/\"/></root>", + buffer.toString()); + } + + @Test + public void testA2() throws IOException { + root.a("http://www.jacoco.org/", "extern"); + root.close(); + assertEquals( + "<root><a href=\"http://www.jacoco.org/\" class=\"extern\"/></root>", + buffer.toString()); + } + + @Test + public void testALinkable1() throws IOException { + root.a(new LinkableStub(null, "here", null), null); + root.close(); + assertEquals("<root><span>here</span></root>", buffer.toString()); + } + + @Test + public void testALinkable2() throws IOException { + root.a(new LinkableStub(null, "here", "blue"), null); + root.close(); + assertEquals("<root><span class=\"blue\">here</span></root>", + buffer.toString()); + } + + @Test + public void testALinkable3() throws IOException { + root.a(new LinkableStub("index.html", "here", null), null); + root.close(); + assertEquals("<root><a href=\"index.html\">here</a></root>", + buffer.toString()); + } + + @Test + public void testALinkable4() throws IOException { + root.a(new LinkableStub("index.html", "here", "red"), null); + root.close(); + assertEquals( + "<root><a href=\"index.html\" class=\"red\">here</a></root>", + buffer.toString()); + } + + @Test + public void testTable() throws IOException { + root.table("tablestyle"); + root.close(); + assertEquals( + "<root><table class=\"tablestyle\" cellspacing=\"0\"/></root>", + buffer.toString()); + } + + @Test + public void testThead() throws IOException { + root.thead(); + root.close(); + assertEquals("<root><thead/></root>", buffer.toString()); + } + + @Test + public void testTfoot() throws IOException { + root.tfoot(); + root.close(); + assertEquals("<root><tfoot/></root>", buffer.toString()); + } + + @Test + public void testTbody() throws IOException { + root.tbody(); + root.close(); + assertEquals("<root><tbody/></root>", buffer.toString()); + } + + @Test + public void testTr() throws IOException { + root.tr(); + root.close(); + assertEquals("<root><tr/></root>", buffer.toString()); + } + + @Test + public void testTd1() throws IOException { + root.td(); + root.close(); + assertEquals("<root><td/></root>", buffer.toString()); + } + + @Test + public void testTd2() throws IOException { + root.td("mystyle"); + root.close(); + assertEquals("<root><td class=\"mystyle\"/></root>", buffer.toString()); + } + + @Test + public void testImg() throws IOException { + root.img("sample.gif", 16, 32, "Hello"); + root.close(); + assertEquals( + "<root><img src=\"sample.gif\" width=\"16\" height=\"32\" title=\"Hello\" alt=\"Hello\"/></root>", + buffer.toString()); + } + + @Test + public void testScript() throws IOException { + root.script("text/javascript", "file.js"); + root.close(); + assertEquals( + "<root><script type=\"text/javascript\" src=\"file.js\"></script></root>", + buffer.toString()); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLSupport.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLSupport.java index fdae38c8..ade776b2 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLSupport.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/HTMLSupport.java @@ -1,27 +1,27 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.jacoco.report.internal.xml.XMLSupport;
-
-/**
- * Support for verifying XHTML documents.
- */
-public class HTMLSupport extends XMLSupport {
-
- public HTMLSupport() throws ParserConfigurationException {
- super(HTMLSupport.class);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html; + +import javax.xml.parsers.ParserConfigurationException; + +import org.jacoco.report.internal.xml.XMLSupport; + +/** + * Support for verifying XHTML documents. + */ +public class HTMLSupport extends XMLSupport { + + public HTMLSupport() throws ParserConfigurationException { + super(HTMLSupport.class); + } + +} 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 7cad96c2..b4ef9d71 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 @@ -1,81 +1,81 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.internal.analysis.ClassCoverageImpl;
-import org.jacoco.core.internal.analysis.MethodCoverageImpl;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-
-/**
- * Unit tests for {@link ClassPage}.
- */
-public class ClassPageTest extends PageTestBase {
-
- private ClassCoverageImpl node;
-
- private ClassPage page;
-
- @Before
- @Override
- public void setup() throws Exception {
- super.setup();
- node = new ClassCoverageImpl("org/jacoco/example/Foo", 123, 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));
- }
-
- @Test
- public void testContents() throws Exception {
- page = new ClassPage(node, null, null, rootFolder, context);
- page.render();
-
- final Document doc = support.parse(output.getFile("Foo.html"));
- assertEquals("el_method", support.findStr(doc,
- "/html/body/table[1]/tbody/tr[1]/td[1]/span/@class"));
- assertEquals("a()", support.findStr(doc,
- "/html/body/table[1]/tbody/tr[1]/td[1]/span"));
- assertEquals("b()", support.findStr(doc,
- "/html/body/table[1]/tbody/tr[2]/td[1]/span"));
- assertEquals("c()", support.findStr(doc,
- "/html/body/table[1]/tbody/tr[3]/td[1]/span"));
- }
-
- @Test
- public void testGetFileName() throws IOException {
- page = new ClassPage(node, null, null, rootFolder, context);
- assertEquals("Foo.html", page.getFileName());
- }
-
- @Test
- public void testGetFileNameDefault() throws IOException {
- IClassCoverage defaultNode = new ClassCoverageImpl("Foo", 123, null,
- "java/lang/Object", null);
- page = new ClassPage(defaultNode, null, null, rootFolder, context);
- assertEquals("Foo.html", page.getFileName());
- }
-
- @Test
- public void testGetLinkLabel() throws IOException {
- page = new ClassPage(node, null, null, rootFolder, context);
- assertEquals("Foo", page.getLinkLabel());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.internal.analysis.ClassCoverageImpl; +import org.jacoco.core.internal.analysis.MethodCoverageImpl; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; + +/** + * Unit tests for {@link ClassPage}. + */ +public class ClassPageTest extends PageTestBase { + + private ClassCoverageImpl node; + + private ClassPage page; + + @Before + @Override + public void setup() throws Exception { + super.setup(); + node = new ClassCoverageImpl("org/jacoco/example/Foo", 123, 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)); + } + + @Test + public void testContents() throws Exception { + page = new ClassPage(node, null, null, rootFolder, context); + page.render(); + + final Document doc = support.parse(output.getFile("Foo.html")); + assertEquals("el_method", support.findStr(doc, + "/html/body/table[1]/tbody/tr[1]/td[1]/span/@class")); + assertEquals("a()", support.findStr(doc, + "/html/body/table[1]/tbody/tr[1]/td[1]/span")); + assertEquals("b()", support.findStr(doc, + "/html/body/table[1]/tbody/tr[2]/td[1]/span")); + assertEquals("c()", support.findStr(doc, + "/html/body/table[1]/tbody/tr[3]/td[1]/span")); + } + + @Test + public void testGetFileName() throws IOException { + page = new ClassPage(node, null, null, rootFolder, context); + assertEquals("Foo.html", page.getFileName()); + } + + @Test + public void testGetFileNameDefault() throws IOException { + IClassCoverage defaultNode = new ClassCoverageImpl("Foo", 123, null, + "java/lang/Object", null); + page = new ClassPage(defaultNode, null, null, rootFolder, context); + assertEquals("Foo.html", page.getFileName()); + } + + @Test + public void testGetLinkLabel() throws IOException { + page = new ClassPage(node, null, null, rootFolder, context); + assertEquals("Foo", page.getLinkLabel()); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/MethodItemTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/MethodItemTest.java index 765204cd..61bc9368 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/MethodItemTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/MethodItemTest.java @@ -1,89 +1,89 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.jacoco.core.internal.analysis.MethodCoverageImpl;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.ILinkable;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link MethodItem}.
- */
-public class MethodItemTest {
-
- private MethodCoverageImpl node;
-
- @Before
- public void setup() {
- node = new MethodCoverageImpl("test", "()V", null);
- }
-
- @Test
- public void testGetNode() {
- final MethodItem item = new MethodItem(node, "test()", null);
- assertSame(node, item.getNode());
- }
-
- @Test
- public void testGetLinkLabel() {
- final MethodItem item = new MethodItem(node, "test()", null);
- assertEquals("test()", item.getLinkLabel());
- }
-
- @Test
- public void testGetLinkStyle() {
- final MethodItem item = new MethodItem(node, "test()", null);
- assertEquals("el_method", item.getLinkStyle());
- }
-
- @Test
- public void testGetLinkNone() {
- final MethodItem item = new MethodItem(node, "test()", null);
- assertNull(item.getLink(null));
- }
-
- @Test
- public void testGetLink() {
- final MethodItem item = new MethodItem(node, "test()", new SourceLink());
- assertEquals("../Source.java", item.getLink(null));
- }
-
- @Test
- public void testGetLinkWithLine() {
- node.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 15);
- final MethodItem item = new MethodItem(node, "test()", new SourceLink());
- assertEquals("../Source.java#L15", item.getLink(null));
- }
-
- private static class SourceLink implements ILinkable {
-
- public String getLinkStyle() {
- return "el_source";
- }
-
- public String getLinkLabel() {
- return "Source.java";
- }
-
- public String getLink(ReportOutputFolder base) {
- return "../Source.java";
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.core.internal.analysis.MethodCoverageImpl; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.ILinkable; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link MethodItem}. + */ +public class MethodItemTest { + + private MethodCoverageImpl node; + + @Before + public void setup() { + node = new MethodCoverageImpl("test", "()V", null); + } + + @Test + public void testGetNode() { + final MethodItem item = new MethodItem(node, "test()", null); + assertSame(node, item.getNode()); + } + + @Test + public void testGetLinkLabel() { + final MethodItem item = new MethodItem(node, "test()", null); + assertEquals("test()", item.getLinkLabel()); + } + + @Test + public void testGetLinkStyle() { + final MethodItem item = new MethodItem(node, "test()", null); + assertEquals("el_method", item.getLinkStyle()); + } + + @Test + public void testGetLinkNone() { + final MethodItem item = new MethodItem(node, "test()", null); + assertNull(item.getLink(null)); + } + + @Test + public void testGetLink() { + final MethodItem item = new MethodItem(node, "test()", new SourceLink()); + assertEquals("../Source.java", item.getLink(null)); + } + + @Test + public void testGetLinkWithLine() { + node.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 15); + final MethodItem item = new MethodItem(node, "test()", new SourceLink()); + assertEquals("../Source.java#L15", item.getLink(null)); + } + + private static class SourceLink implements ILinkable { + + public String getLinkStyle() { + return "el_source"; + } + + public String getLinkLabel() { + return "Source.java"; + } + + public String getLink(ReportOutputFolder base) { + return "../Source.java"; + } + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/NodePageTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/NodePageTest.java index c211a23f..00e6d341 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/NodePageTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/NodePageTest.java @@ -1,81 +1,81 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link NodePage}.
- */
-public class NodePageTest extends PageTestBase {
-
- private CoverageNodeImpl node;
-
- private NodePage<ICoverageNode> page;
-
- private class TestNodePage extends NodePage<ICoverageNode> {
-
- protected TestNodePage(ICoverageNode node, ReportPage parent) {
- super(node, parent, rootFolder, NodePageTest.this.context);
- }
-
- @Override
- protected void content(HTMLElement body) throws IOException {
- }
-
- @Override
- protected String getFileName() {
- return "index.html";
- }
-
- }
-
- @Before
- @Override
- public void setup() throws Exception {
- super.setup();
- node = new CoverageNodeImpl(ElementType.GROUP, "Test");
- page = new TestNodePage(node, null);
- }
-
- @Test
- public void testGetNode() throws IOException {
- assertSame(node, page.getNode());
- }
-
- @Test
- public void testGetLinkLabel() throws IOException {
- assertEquals("Test", page.getLinkLabel());
- }
-
- @Test
- public void testGetLinkStyle1() throws IOException {
- assertEquals("el_report", page.getLinkStyle());
- }
-
- @Test
- public void testGetLinkStyle2() throws IOException {
- final TestNodePage group = new TestNodePage(node, page);
- assertEquals("el_group", group.getLinkStyle());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import java.io.IOException; + +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.report.internal.html.HTMLElement; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link NodePage}. + */ +public class NodePageTest extends PageTestBase { + + private CoverageNodeImpl node; + + private NodePage<ICoverageNode> page; + + private class TestNodePage extends NodePage<ICoverageNode> { + + protected TestNodePage(ICoverageNode node, ReportPage parent) { + super(node, parent, rootFolder, NodePageTest.this.context); + } + + @Override + protected void content(HTMLElement body) throws IOException { + } + + @Override + protected String getFileName() { + return "index.html"; + } + + } + + @Before + @Override + public void setup() throws Exception { + super.setup(); + node = new CoverageNodeImpl(ElementType.GROUP, "Test"); + page = new TestNodePage(node, null); + } + + @Test + public void testGetNode() throws IOException { + assertSame(node, page.getNode()); + } + + @Test + public void testGetLinkLabel() throws IOException { + assertEquals("Test", page.getLinkLabel()); + } + + @Test + public void testGetLinkStyle1() throws IOException { + assertEquals("el_report", page.getLinkStyle()); + } + + @Test + public void testGetLinkStyle2() throws IOException { + final TestNodePage group = new TestNodePage(node, page); + assertEquals("el_group", group.getLinkStyle()); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/PageTestBase.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/PageTestBase.java index 534b101d..56705a8d 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/PageTestBase.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/PageTestBase.java @@ -1,99 +1,99 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import java.io.IOException;
-import java.util.Locale;
-
-import org.jacoco.report.ILanguageNames;
-import org.jacoco.report.JavaNames;
-import org.jacoco.report.MemoryMultiReportOutput;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLSupport;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-import org.jacoco.report.internal.html.ILinkable;
-import org.jacoco.report.internal.html.LinkableStub;
-import org.jacoco.report.internal.html.index.IIndexUpdate;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.jacoco.report.internal.html.resources.Styles;
-import org.jacoco.report.internal.html.table.LabelColumn;
-import org.jacoco.report.internal.html.table.Table;
-import org.junit.After;
-
-/**
- * Unit tests for {@link ReportPage}.
- */
-public abstract class PageTestBase {
-
- protected MemoryMultiReportOutput output;
-
- protected ReportOutputFolder rootFolder;
-
- protected IHTMLReportContext context;
-
- protected HTMLSupport support;
-
- protected void setup() throws Exception {
- output = new MemoryMultiReportOutput();
- rootFolder = new ReportOutputFolder(output);
- final Resources resources = new Resources(rootFolder);
- final Table table = new Table();
- table.add("Element", null, new LabelColumn(), true);
- context = new IHTMLReportContext() {
-
- public ILanguageNames getLanguageNames() {
- return new JavaNames();
- }
-
- public Resources getResources() {
- return resources;
- }
-
- public Table getTable() {
- return table;
- }
-
- public String getFooterText() {
- return "CustomFooter";
- }
-
- public ILinkable getSessionsPage() {
- return new LinkableStub("sessions.html", "Sessions",
- Styles.EL_SESSION);
- }
-
- public String getOutputEncoding() {
- return "UTF-8";
- }
-
- public IIndexUpdate getIndexUpdate() {
- return new IIndexUpdate() {
- public void addClass(ILinkable link, long classid) {
- }
- };
- }
-
- public Locale getLocale() {
- return Locale.ENGLISH;
- }
-
- };
- support = new HTMLSupport();
- }
-
- @After
- public void teardown() throws IOException {
- output.close();
- output.assertAllClosed();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import java.io.IOException; +import java.util.Locale; + +import org.jacoco.report.ILanguageNames; +import org.jacoco.report.JavaNames; +import org.jacoco.report.MemoryMultiReportOutput; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLSupport; +import org.jacoco.report.internal.html.IHTMLReportContext; +import org.jacoco.report.internal.html.ILinkable; +import org.jacoco.report.internal.html.LinkableStub; +import org.jacoco.report.internal.html.index.IIndexUpdate; +import org.jacoco.report.internal.html.resources.Resources; +import org.jacoco.report.internal.html.resources.Styles; +import org.jacoco.report.internal.html.table.LabelColumn; +import org.jacoco.report.internal.html.table.Table; +import org.junit.After; + +/** + * Unit tests for {@link ReportPage}. + */ +public abstract class PageTestBase { + + protected MemoryMultiReportOutput output; + + protected ReportOutputFolder rootFolder; + + protected IHTMLReportContext context; + + protected HTMLSupport support; + + protected void setup() throws Exception { + output = new MemoryMultiReportOutput(); + rootFolder = new ReportOutputFolder(output); + final Resources resources = new Resources(rootFolder); + final Table table = new Table(); + table.add("Element", null, new LabelColumn(), true); + context = new IHTMLReportContext() { + + public ILanguageNames getLanguageNames() { + return new JavaNames(); + } + + public Resources getResources() { + return resources; + } + + public Table getTable() { + return table; + } + + public String getFooterText() { + return "CustomFooter"; + } + + public ILinkable getSessionsPage() { + return new LinkableStub("sessions.html", "Sessions", + Styles.EL_SESSION); + } + + public String getOutputEncoding() { + return "UTF-8"; + } + + public IIndexUpdate getIndexUpdate() { + return new IIndexUpdate() { + public void addClass(ILinkable link, long classid) { + } + }; + } + + public Locale getLocale() { + return Locale.ENGLISH; + } + + }; + support = new HTMLSupport(); + } + + @After + public void teardown() throws IOException { + output.close(); + output.assertAllClosed(); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ReportPageTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ReportPageTest.java index 27f5f8f3..ac26218f 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ReportPageTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/ReportPageTest.java @@ -1,128 +1,128 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.HTMLSupport;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-
-/**
- * Unit tests for {@link ReportPage}.
- */
-public class ReportPageTest extends PageTestBase {
-
- private ReportPage rootpage;
-
- private ReportPage page;
-
- private class TestReportPage extends ReportPage {
-
- private final String label;
- private final String style;
-
- protected TestReportPage(String label, String style, ReportPage parent) {
- super(parent, rootFolder, ReportPageTest.this.context);
- this.label = label;
- this.style = style;
- }
-
- @Override
- protected void content(HTMLElement body) throws IOException {
- body.div("testcontent").text("Hello Test");
- }
-
- @Override
- protected String getFileName() {
- return label + ".html";
- }
-
- public String getLinkLabel() {
- return label;
- }
-
- public String getLinkStyle() {
- return style;
- }
-
- }
-
- @Before
- @Override
- public void setup() throws Exception {
- super.setup();
- rootpage = new TestReportPage("Report", "el_report", null);
- page = new TestReportPage("Test", "el_group", rootpage);
- }
-
- @Test
- public void testIsRootPage1() {
- assertFalse(page.isRootPage());
- }
-
- @Test
- public void testIsRootPage2() {
- assertTrue(rootpage.isRootPage());
- }
-
- @Test
- public void testGetLink() throws IOException {
- ReportOutputFolder base = rootFolder.subFolder("here");
- assertEquals("../Test.html", page.getLink(base));
- }
-
- @Test
- public void testPageContent() throws Exception {
- page.render();
- final HTMLSupport support = new HTMLSupport();
- final Document doc = support.parse(output.getFile("Test.html"));
-
- // language
- assertEquals("en", support.findStr(doc, "/html/@lang"));
-
- // style sheet
- assertEquals(".resources/report.css", support.findStr(doc,
- "/html/head/link[@rel='stylesheet']/@href"));
-
- // bread crumb
- assertEquals("Report", support.findStr(doc,
- "/html/body/div[@class='breadcrumb']/a[1]/text()"));
- assertEquals("Report.html", support.findStr(doc,
- "/html/body/div[@class='breadcrumb']/a[1]/@href"));
- assertEquals("el_report", support.findStr(doc,
- "/html/body/div[@class='breadcrumb']/a[1]/@class"));
- assertEquals("Test", support.findStr(doc,
- "/html/body/div[@class='breadcrumb']/span[2]/text()"));
- assertEquals("el_group", support.findStr(doc,
- "/html/body/div[@class='breadcrumb']/span[2]/@class"));
-
- // Header
- assertEquals("Test", support.findStr(doc, "/html/body/h1/text()"));
-
- // Content
- assertEquals("Hello Test", support.findStr(doc,
- "/html/body/div[@class='testcontent']/text()"));
-
- // Footer
- assertEquals("CustomFooter",
- support.findStr(doc, "/html/body/div[@class='footer']/text()"));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.HTMLSupport; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; + +/** + * Unit tests for {@link ReportPage}. + */ +public class ReportPageTest extends PageTestBase { + + private ReportPage rootpage; + + private ReportPage page; + + private class TestReportPage extends ReportPage { + + private final String label; + private final String style; + + protected TestReportPage(String label, String style, ReportPage parent) { + super(parent, rootFolder, ReportPageTest.this.context); + this.label = label; + this.style = style; + } + + @Override + protected void content(HTMLElement body) throws IOException { + body.div("testcontent").text("Hello Test"); + } + + @Override + protected String getFileName() { + return label + ".html"; + } + + public String getLinkLabel() { + return label; + } + + public String getLinkStyle() { + return style; + } + + } + + @Before + @Override + public void setup() throws Exception { + super.setup(); + rootpage = new TestReportPage("Report", "el_report", null); + page = new TestReportPage("Test", "el_group", rootpage); + } + + @Test + public void testIsRootPage1() { + assertFalse(page.isRootPage()); + } + + @Test + public void testIsRootPage2() { + assertTrue(rootpage.isRootPage()); + } + + @Test + public void testGetLink() throws IOException { + ReportOutputFolder base = rootFolder.subFolder("here"); + assertEquals("../Test.html", page.getLink(base)); + } + + @Test + public void testPageContent() throws Exception { + page.render(); + final HTMLSupport support = new HTMLSupport(); + final Document doc = support.parse(output.getFile("Test.html")); + + // language + assertEquals("en", support.findStr(doc, "/html/@lang")); + + // style sheet + assertEquals(".resources/report.css", support.findStr(doc, + "/html/head/link[@rel='stylesheet']/@href")); + + // bread crumb + assertEquals("Report", support.findStr(doc, + "/html/body/div[@class='breadcrumb']/a[1]/text()")); + assertEquals("Report.html", support.findStr(doc, + "/html/body/div[@class='breadcrumb']/a[1]/@href")); + assertEquals("el_report", support.findStr(doc, + "/html/body/div[@class='breadcrumb']/a[1]/@class")); + assertEquals("Test", support.findStr(doc, + "/html/body/div[@class='breadcrumb']/span[2]/text()")); + assertEquals("el_group", support.findStr(doc, + "/html/body/div[@class='breadcrumb']/span[2]/@class")); + + // Header + assertEquals("Test", support.findStr(doc, "/html/body/h1/text()")); + + // Content + assertEquals("Hello Test", support.findStr(doc, + "/html/body/div[@class='testcontent']/text()")); + + // Footer + assertEquals("CustomFooter", + support.findStr(doc, "/html/body/div[@class='footer']/text()")); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/SourceHighlighterTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/SourceHighlighterTest.java index 7e9752ff..0eeb3c05 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/SourceHighlighterTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/page/SourceHighlighterTest.java @@ -1,153 +1,153 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.Locale;
-
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.jacoco.core.internal.analysis.SourceNodeImpl;
-import org.jacoco.report.internal.html.HTMLDocument;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.HTMLSupport;
-import org.jacoco.report.internal.html.resources.Styles;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-
-/**
- * Unit tests for {@link SourceHighlighter}.
- */
-public class SourceHighlighterTest {
-
- private HTMLSupport htmlSupport;
-
- private StringWriter buffer;
-
- private HTMLDocument html;
-
- private HTMLElement parent;
-
- private SourceHighlighter sourceHighlighter;
-
- private SourceNodeImpl source;
-
- @Before
- public void setup() throws Exception {
- htmlSupport = new HTMLSupport();
- source = new SourceNodeImpl(ElementType.SOURCEFILE, "Foo.java");
- buffer = new StringWriter();
- html = new HTMLDocument(buffer, "UTF-8");
- html.head().title();
- parent = html.body();
- sourceHighlighter = new SourceHighlighter(Locale.US);
- }
-
- @Test
- public void testDefaultTabWidth() throws Exception {
- final String src = "\tA";
- sourceHighlighter.render(parent, source, new StringReader(src));
- html.close();
- final Document doc = htmlSupport.parse(buffer.toString());
-
- // Assert that we no longer replace tabs with spaces
- assertEquals("\tA\n", htmlSupport.findStr(doc, "//pre/text()"));
- }
-
- @Test
- public void testDefaultLanguage() throws Exception {
- sourceHighlighter.render(parent, source, new StringReader(""));
- html.close();
- final Document doc = htmlSupport.parse(buffer.toString());
- assertEquals("source lang-java linenums",
- htmlSupport.findStr(doc, "//pre/@class"));
- }
-
- @Test
- public void testSetLanguage() throws Exception {
- sourceHighlighter.setLanguage("scala");
- sourceHighlighter.render(parent, source, new StringReader(""));
- html.close();
- final Document doc = htmlSupport.parse(buffer.toString());
- assertEquals("source lang-scala linenums",
- htmlSupport.findStr(doc, "//pre/@class"));
- }
-
- @Test
- public void testHighlighting() throws Exception {
- final String src = "A\nB\nC\nD";
- source.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 1);
- source.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 2);
- source.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, 2);
- source.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, 3);
- sourceHighlighter.render(parent, source, new StringReader(src));
- html.close();
- final Document doc = htmlSupport.parse(buffer.toString());
- assertEquals(Styles.NOT_COVERED,
- htmlSupport.findStr(doc, "//pre/span[text() = 'A']/@class"));
- assertEquals(Styles.PARTLY_COVERED,
- htmlSupport.findStr(doc, "//pre/span[text() = 'B']/@class"));
- assertEquals(Styles.FULLY_COVERED,
- htmlSupport.findStr(doc, "//pre/span[text() = 'C']/@class"));
- assertEquals("",
- htmlSupport.findStr(doc, "//pre/span[text() = 'D']/@class"));
- }
-
- @Test
- public void testHighlightNone() throws Exception {
- sourceHighlighter.highlight(parent, source.getLine(1), 1);
- html.close();
- final Document doc = htmlSupport.parse(buffer.toString());
- assertEquals("", htmlSupport.findStr(doc, "//pre"));
- }
-
- @Test
- public void testHighlightBranchesFC() throws Exception {
- source.increment(CounterImpl.COUNTER_0_1,
- CounterImpl.getInstance(0, 5), 1);
- sourceHighlighter.highlight(parent.pre(null), source.getLine(1), 1);
- html.close();
- final Document doc = htmlSupport.parse(buffer.toString());
- assertEquals("fc bfc", htmlSupport.findStr(doc, "//pre/span/@class"));
- assertEquals("All 5 branches covered.",
- htmlSupport.findStr(doc, "//pre/span/@title"));
- }
-
- @Test
- public void testHighlightBranchesPC() throws Exception {
- source.increment(CounterImpl.COUNTER_0_1,
- CounterImpl.getInstance(2, 3), 1);
- sourceHighlighter.highlight(parent.pre(null), source.getLine(1), 1);
- html.close();
- final Document doc = htmlSupport.parse(buffer.toString());
- assertEquals("pc bpc", htmlSupport.findStr(doc, "//pre/span/@class"));
- assertEquals("2 of 5 branches missed.",
- htmlSupport.findStr(doc, "//pre/span/@title"));
- }
-
- @Test
- public void testHighlightBranchesNC() throws Exception {
- source.increment(CounterImpl.COUNTER_0_1,
- CounterImpl.getInstance(5, 0), 1);
- sourceHighlighter.highlight(parent.pre(null), source.getLine(1), 1);
- html.close();
- final Document doc = htmlSupport.parse(buffer.toString());
- assertEquals("pc bnc", htmlSupport.findStr(doc, "//pre/span/@class"));
- assertEquals("All 5 branches missed.",
- htmlSupport.findStr(doc, "//pre/span/@title"));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import static org.junit.Assert.assertEquals; + +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Locale; + +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.core.internal.analysis.SourceNodeImpl; +import org.jacoco.report.internal.html.HTMLDocument; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.HTMLSupport; +import org.jacoco.report.internal.html.resources.Styles; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; + +/** + * Unit tests for {@link SourceHighlighter}. + */ +public class SourceHighlighterTest { + + private HTMLSupport htmlSupport; + + private StringWriter buffer; + + private HTMLDocument html; + + private HTMLElement parent; + + private SourceHighlighter sourceHighlighter; + + private SourceNodeImpl source; + + @Before + public void setup() throws Exception { + htmlSupport = new HTMLSupport(); + source = new SourceNodeImpl(ElementType.SOURCEFILE, "Foo.java"); + buffer = new StringWriter(); + html = new HTMLDocument(buffer, "UTF-8"); + html.head().title(); + parent = html.body(); + sourceHighlighter = new SourceHighlighter(Locale.US); + } + + @Test + public void testDefaultTabWidth() throws Exception { + final String src = "\tA"; + sourceHighlighter.render(parent, source, new StringReader(src)); + html.close(); + final Document doc = htmlSupport.parse(buffer.toString()); + + // Assert that we no longer replace tabs with spaces + assertEquals("\tA\n", htmlSupport.findStr(doc, "//pre/text()")); + } + + @Test + public void testDefaultLanguage() throws Exception { + sourceHighlighter.render(parent, source, new StringReader("")); + html.close(); + final Document doc = htmlSupport.parse(buffer.toString()); + assertEquals("source lang-java linenums", + htmlSupport.findStr(doc, "//pre/@class")); + } + + @Test + public void testSetLanguage() throws Exception { + sourceHighlighter.setLanguage("scala"); + sourceHighlighter.render(parent, source, new StringReader("")); + html.close(); + final Document doc = htmlSupport.parse(buffer.toString()); + assertEquals("source lang-scala linenums", + htmlSupport.findStr(doc, "//pre/@class")); + } + + @Test + public void testHighlighting() throws Exception { + final String src = "A\nB\nC\nD"; + source.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 1); + source.increment(CounterImpl.COUNTER_1_0, CounterImpl.COUNTER_0_0, 2); + source.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, 2); + source.increment(CounterImpl.COUNTER_0_1, CounterImpl.COUNTER_0_0, 3); + sourceHighlighter.render(parent, source, new StringReader(src)); + html.close(); + final Document doc = htmlSupport.parse(buffer.toString()); + assertEquals(Styles.NOT_COVERED, + htmlSupport.findStr(doc, "//pre/span[text() = 'A']/@class")); + assertEquals(Styles.PARTLY_COVERED, + htmlSupport.findStr(doc, "//pre/span[text() = 'B']/@class")); + assertEquals(Styles.FULLY_COVERED, + htmlSupport.findStr(doc, "//pre/span[text() = 'C']/@class")); + assertEquals("", + htmlSupport.findStr(doc, "//pre/span[text() = 'D']/@class")); + } + + @Test + public void testHighlightNone() throws Exception { + sourceHighlighter.highlight(parent, source.getLine(1), 1); + html.close(); + final Document doc = htmlSupport.parse(buffer.toString()); + assertEquals("", htmlSupport.findStr(doc, "//pre")); + } + + @Test + public void testHighlightBranchesFC() throws Exception { + source.increment(CounterImpl.COUNTER_0_1, + CounterImpl.getInstance(0, 5), 1); + sourceHighlighter.highlight(parent.pre(null), source.getLine(1), 1); + html.close(); + final Document doc = htmlSupport.parse(buffer.toString()); + assertEquals("fc bfc", htmlSupport.findStr(doc, "//pre/span/@class")); + assertEquals("All 5 branches covered.", + htmlSupport.findStr(doc, "//pre/span/@title")); + } + + @Test + public void testHighlightBranchesPC() throws Exception { + source.increment(CounterImpl.COUNTER_0_1, + CounterImpl.getInstance(2, 3), 1); + sourceHighlighter.highlight(parent.pre(null), source.getLine(1), 1); + html.close(); + final Document doc = htmlSupport.parse(buffer.toString()); + assertEquals("pc bpc", htmlSupport.findStr(doc, "//pre/span/@class")); + assertEquals("2 of 5 branches missed.", + htmlSupport.findStr(doc, "//pre/span/@title")); + } + + @Test + public void testHighlightBranchesNC() throws Exception { + source.increment(CounterImpl.COUNTER_0_1, + CounterImpl.getInstance(5, 0), 1); + sourceHighlighter.highlight(parent.pre(null), source.getLine(1), 1); + html.close(); + final Document doc = htmlSupport.parse(buffer.toString()); + assertEquals("pc bnc", htmlSupport.findStr(doc, "//pre/span/@class")); + assertEquals("All 5 branches missed.", + htmlSupport.findStr(doc, "//pre/span/@title")); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/resources/ResourcesTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/resources/ResourcesTest.java index 8548fe27..a3d0c6b9 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/resources/ResourcesTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/resources/ResourcesTest.java @@ -1,86 +1,86 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.resources;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.report.MemoryMultiReportOutput;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link Resources}.
- */
-public class ResourcesTest {
-
- private MemoryMultiReportOutput output;
-
- private ReportOutputFolder root;
-
- private Resources resources;
-
- @Before
- public void setup() {
- output = new MemoryMultiReportOutput();
- root = new ReportOutputFolder(output);
- resources = new Resources(root);
- }
-
- @Test
- public void testGetLink() {
- ReportOutputFolder base = root.subFolder("f1").subFolder("f2");
- assertEquals("../../.resources/test.png",
- resources.getLink(base, "test.png"));
-
- }
-
- @Test
- public void testCopyResources() throws IOException {
- resources.copyResources();
- output.assertFile(".resources/branchfc.gif");
- output.assertFile(".resources/branchnc.gif");
- output.assertFile(".resources/branchpc.gif");
- output.assertFile(".resources/bundle.gif");
- output.assertFile(".resources/class.gif");
- output.assertFile(".resources/down.gif");
- output.assertFile(".resources/greenbar.gif");
- output.assertFile(".resources/group.gif");
- output.assertFile(".resources/method.gif");
- output.assertFile(".resources/package.gif");
- output.assertFile(".resources/prettify.css");
- output.assertFile(".resources/prettify.js");
- output.assertFile(".resources/redbar.gif");
- output.assertFile(".resources/report.css");
- output.assertFile(".resources/report.gif");
- output.assertFile(".resources/class.gif");
- output.assertFile(".resources/sort.js");
- output.assertFile(".resources/source.gif");
- output.assertFile(".resources/up.gif");
- }
-
- @Test
- public void testGetElementStyle() {
- assertEquals("el_group", Resources.getElementStyle(ElementType.GROUP));
- assertEquals("el_bundle", Resources.getElementStyle(ElementType.BUNDLE));
- assertEquals("el_package",
- Resources.getElementStyle(ElementType.PACKAGE));
- assertEquals("el_source",
- Resources.getElementStyle(ElementType.SOURCEFILE));
- assertEquals("el_class", Resources.getElementStyle(ElementType.CLASS));
- assertEquals("el_method", Resources.getElementStyle(ElementType.METHOD));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.resources; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.report.MemoryMultiReportOutput; +import org.jacoco.report.internal.ReportOutputFolder; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link Resources}. + */ +public class ResourcesTest { + + private MemoryMultiReportOutput output; + + private ReportOutputFolder root; + + private Resources resources; + + @Before + public void setup() { + output = new MemoryMultiReportOutput(); + root = new ReportOutputFolder(output); + resources = new Resources(root); + } + + @Test + public void testGetLink() { + ReportOutputFolder base = root.subFolder("f1").subFolder("f2"); + assertEquals("../../.resources/test.png", + resources.getLink(base, "test.png")); + + } + + @Test + public void testCopyResources() throws IOException { + resources.copyResources(); + output.assertFile(".resources/branchfc.gif"); + output.assertFile(".resources/branchnc.gif"); + output.assertFile(".resources/branchpc.gif"); + output.assertFile(".resources/bundle.gif"); + output.assertFile(".resources/class.gif"); + output.assertFile(".resources/down.gif"); + output.assertFile(".resources/greenbar.gif"); + output.assertFile(".resources/group.gif"); + output.assertFile(".resources/method.gif"); + output.assertFile(".resources/package.gif"); + output.assertFile(".resources/prettify.css"); + output.assertFile(".resources/prettify.js"); + output.assertFile(".resources/redbar.gif"); + output.assertFile(".resources/report.css"); + output.assertFile(".resources/report.gif"); + output.assertFile(".resources/class.gif"); + output.assertFile(".resources/sort.js"); + output.assertFile(".resources/source.gif"); + output.assertFile(".resources/up.gif"); + } + + @Test + public void testGetElementStyle() { + assertEquals("el_group", Resources.getElementStyle(ElementType.GROUP)); + assertEquals("el_bundle", Resources.getElementStyle(ElementType.BUNDLE)); + assertEquals("el_package", + Resources.getElementStyle(ElementType.PACKAGE)); + assertEquals("el_source", + Resources.getElementStyle(ElementType.SOURCEFILE)); + assertEquals("el_class", Resources.getElementStyle(ElementType.CLASS)); + assertEquals("el_method", Resources.getElementStyle(ElementType.METHOD)); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/resources/StylesTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/resources/StylesTest.java index 50c93fe3..f783728c 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/resources/StylesTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/resources/StylesTest.java @@ -1,44 +1,44 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.resources;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link Styles}.
- */
-public class StylesTest {
-
- @Test
- public void testCombine1() {
- assertEquals(null, Styles.combine());
- }
-
- @Test
- public void testCombine2() {
- assertEquals(null, Styles.combine((String) null));
- }
-
- @Test
- public void testCombine3() {
- assertEquals("aaa", Styles.combine("aaa"));
- }
-
- @Test
- public void testCombine4() {
- assertEquals("aaa bbb ccc",
- Styles.combine("aaa", null, "bbb", "ccc", null));
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.resources; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +/** + * Unit tests for {@link Styles}. + */ +public class StylesTest { + + @Test + public void testCombine1() { + assertEquals(null, Styles.combine()); + } + + @Test + public void testCombine2() { + assertEquals(null, Styles.combine((String) null)); + } + + @Test + public void testCombine3() { + assertEquals("aaa", Styles.combine("aaa")); + } + + @Test + public void testCombine4() { + assertEquals("aaa bbb ccc", + Styles.combine("aaa", null, "bbb", "ccc", null)); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/BarColumnTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/BarColumnTest.java index 115d3623..ba5e33dd 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/BarColumnTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/BarColumnTest.java @@ -1,236 +1,236 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Locale;
-
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.jacoco.report.MemoryMultiReportOutput;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLDocument;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.HTMLSupport;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-
-/**
- * Unit tests for {@link BarColumn}.
- */
-public class BarColumnTest {
-
- private MemoryMultiReportOutput output;
-
- private ReportOutputFolder root;
-
- private Resources resources;
-
- private HTMLDocument doc;
-
- private HTMLElement td;
-
- private HTMLSupport support;
-
- private IColumnRenderer column;
-
- @Before
- public void setup() throws Exception {
- output = new MemoryMultiReportOutput();
- root = new ReportOutputFolder(output);
- resources = new Resources(root);
- doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8");
- doc.head().title();
- td = doc.body().table("somestyle").tr().td();
- support = new HTMLSupport();
- column = new BarColumn(CounterEntity.LINE, Locale.ENGLISH);
- }
-
- @After
- public void teardown() throws IOException {
- output.close();
- output.assertAllClosed();
- }
-
- @Test
- public void testInit() throws Exception {
- final ITableItem i = createItem(6, 24);
- assertTrue(column.init(Arrays.asList(i), i.getNode()));
- doc.close();
- }
-
- @Test
- public void testFooter() throws Exception {
- column.footer(td, createNode(15, 5), resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("15 of 20",
- support.findStr(doc, "/html/body/table/tr/td/text()"));
- }
-
- @Test
- public void testBarWidths() throws Exception {
- final ITableItem i1 = createItem(15, 5);
- final ITableItem i2 = createItem(6, 24);
- column.init(Arrays.asList(i1, i2), createNode(21, 29));
- column.item(td, i1, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
-
- assertEquals("2",
- support.findStr(doc, "count(/html/body/table/tr[1]/td/img)"));
-
- // red bar
- assertEquals(".resources/redbar.gif",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@src"));
- assertEquals("15",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@alt"));
- assertEquals("60",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@width"));
-
- // green bar
- assertEquals(".resources/greenbar.gif",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[2]/@src"));
- assertEquals("5",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[2]/@alt"));
- assertEquals("20",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[2]/@width"));
- }
-
- @Test
- public void testRedBarOnly() throws Exception {
- final ITableItem i1 = createItem(20, 0);
- column.init(Arrays.asList(i1), createNode(20, 0));
- column.item(td, i1, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
-
- assertEquals("1",
- support.findStr(doc, "count(/html/body/table/tr[1]/td/img)"));
-
- // red bar
- assertEquals(".resources/redbar.gif",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@src"));
- assertEquals("20",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@alt"));
- assertEquals("120",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@width"));
- }
-
- @Test
- public void testGreenBarOnly() throws Exception {
- final ITableItem i1 = createItem(00, 20);
- column.init(Arrays.asList(i1), createNode(00, 20));
- column.item(td, i1, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
-
- assertEquals("1",
- support.findStr(doc, "count(/html/body/table/tr[1]/td/img)"));
-
- // red bar
- assertEquals(".resources/greenbar.gif",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@src"));
- assertEquals("20",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@alt"));
- assertEquals("120",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@width"));
- }
-
- @Test
- public void testNoBars() throws Exception {
- final ITableItem i1 = createItem(00, 00);
- column.init(Arrays.asList(i1), createNode(00, 00));
- column.item(td, i1, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
-
- assertEquals("0",
- support.findStr(doc, "count(/html/body/table/tr[1]/td/img)"));
- }
-
- @Test
- public void testLocale() throws Exception {
- final BarColumn col = new BarColumn(CounterEntity.LINE, Locale.FRENCH);
- final ITableItem i1 = createItem(0, 123456);
- col.init(Arrays.asList(i1), createNode(00, 20));
- col.item(td, i1, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
-
- assertEquals("123\u00a0456",
- support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@alt"));
- }
-
- @Test
- public void testComparator1() throws Exception {
- final Comparator<ITableItem> c = column.getComparator();
- final ITableItem i1 = createItem(50, 50);
- final ITableItem i2 = createItem(20, 80);
- assertTrue(c.compare(i1, i2) < 0);
- assertTrue(c.compare(i2, i1) > 0);
- assertEquals(0, c.compare(i1, i1));
- doc.close();
- }
-
- @Test
- public void testComparator2() throws Exception {
- final Comparator<ITableItem> c = column.getComparator();
- final ITableItem i1 = createItem(50, 60);
- final ITableItem i2 = createItem(50, 50);
- assertTrue(c.compare(i1, i2) < 0);
- assertTrue(c.compare(i2, i1) > 0);
- assertEquals(0, c.compare(i1, i1));
- doc.close();
- }
-
- private ITableItem createItem(final int missed, final int covered) {
- final ICoverageNode node = createNode(missed, covered);
- return new ITableItem() {
- public String getLinkLabel() {
- return "Foo";
- }
-
- public String getLink(ReportOutputFolder base) {
- return null;
- }
-
- public String getLinkStyle() {
- return Resources.getElementStyle(node.getElementType());
- }
-
- public ICoverageNode getNode() {
- return node;
- }
- };
- }
-
- private CoverageNodeImpl createNode(final int missed, final int covered) {
- return new CoverageNodeImpl(ElementType.GROUP, "Foo") {
- {
- this.lineCounter = CounterImpl.getInstance(missed, covered);
- }
- };
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Locale; + +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.report.MemoryMultiReportOutput; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLDocument; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.HTMLSupport; +import org.jacoco.report.internal.html.resources.Resources; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; + +/** + * Unit tests for {@link BarColumn}. + */ +public class BarColumnTest { + + private MemoryMultiReportOutput output; + + private ReportOutputFolder root; + + private Resources resources; + + private HTMLDocument doc; + + private HTMLElement td; + + private HTMLSupport support; + + private IColumnRenderer column; + + @Before + public void setup() throws Exception { + output = new MemoryMultiReportOutput(); + root = new ReportOutputFolder(output); + resources = new Resources(root); + doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8"); + doc.head().title(); + td = doc.body().table("somestyle").tr().td(); + support = new HTMLSupport(); + column = new BarColumn(CounterEntity.LINE, Locale.ENGLISH); + } + + @After + public void teardown() throws IOException { + output.close(); + output.assertAllClosed(); + } + + @Test + public void testInit() throws Exception { + final ITableItem i = createItem(6, 24); + assertTrue(column.init(Arrays.asList(i), i.getNode())); + doc.close(); + } + + @Test + public void testFooter() throws Exception { + column.footer(td, createNode(15, 5), resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("15 of 20", + support.findStr(doc, "/html/body/table/tr/td/text()")); + } + + @Test + public void testBarWidths() throws Exception { + final ITableItem i1 = createItem(15, 5); + final ITableItem i2 = createItem(6, 24); + column.init(Arrays.asList(i1, i2), createNode(21, 29)); + column.item(td, i1, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + + assertEquals("2", + support.findStr(doc, "count(/html/body/table/tr[1]/td/img)")); + + // red bar + assertEquals(".resources/redbar.gif", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@src")); + assertEquals("15", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@alt")); + assertEquals("60", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@width")); + + // green bar + assertEquals(".resources/greenbar.gif", + support.findStr(doc, "/html/body/table/tr[1]/td/img[2]/@src")); + assertEquals("5", + support.findStr(doc, "/html/body/table/tr[1]/td/img[2]/@alt")); + assertEquals("20", + support.findStr(doc, "/html/body/table/tr[1]/td/img[2]/@width")); + } + + @Test + public void testRedBarOnly() throws Exception { + final ITableItem i1 = createItem(20, 0); + column.init(Arrays.asList(i1), createNode(20, 0)); + column.item(td, i1, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + + assertEquals("1", + support.findStr(doc, "count(/html/body/table/tr[1]/td/img)")); + + // red bar + assertEquals(".resources/redbar.gif", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@src")); + assertEquals("20", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@alt")); + assertEquals("120", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@width")); + } + + @Test + public void testGreenBarOnly() throws Exception { + final ITableItem i1 = createItem(00, 20); + column.init(Arrays.asList(i1), createNode(00, 20)); + column.item(td, i1, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + + assertEquals("1", + support.findStr(doc, "count(/html/body/table/tr[1]/td/img)")); + + // red bar + assertEquals(".resources/greenbar.gif", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@src")); + assertEquals("20", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@alt")); + assertEquals("120", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@width")); + } + + @Test + public void testNoBars() throws Exception { + final ITableItem i1 = createItem(00, 00); + column.init(Arrays.asList(i1), createNode(00, 00)); + column.item(td, i1, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + + assertEquals("0", + support.findStr(doc, "count(/html/body/table/tr[1]/td/img)")); + } + + @Test + public void testLocale() throws Exception { + final BarColumn col = new BarColumn(CounterEntity.LINE, Locale.FRENCH); + final ITableItem i1 = createItem(0, 123456); + col.init(Arrays.asList(i1), createNode(00, 20)); + col.item(td, i1, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + + assertEquals("123\u00a0456", + support.findStr(doc, "/html/body/table/tr[1]/td/img[1]/@alt")); + } + + @Test + public void testComparator1() throws Exception { + final Comparator<ITableItem> c = column.getComparator(); + final ITableItem i1 = createItem(50, 50); + final ITableItem i2 = createItem(20, 80); + assertTrue(c.compare(i1, i2) < 0); + assertTrue(c.compare(i2, i1) > 0); + assertEquals(0, c.compare(i1, i1)); + doc.close(); + } + + @Test + public void testComparator2() throws Exception { + final Comparator<ITableItem> c = column.getComparator(); + final ITableItem i1 = createItem(50, 60); + final ITableItem i2 = createItem(50, 50); + assertTrue(c.compare(i1, i2) < 0); + assertTrue(c.compare(i2, i1) > 0); + assertEquals(0, c.compare(i1, i1)); + doc.close(); + } + + private ITableItem createItem(final int missed, final int covered) { + final ICoverageNode node = createNode(missed, covered); + return new ITableItem() { + public String getLinkLabel() { + return "Foo"; + } + + public String getLink(ReportOutputFolder base) { + return null; + } + + public String getLinkStyle() { + return Resources.getElementStyle(node.getElementType()); + } + + public ICoverageNode getNode() { + return node; + } + }; + } + + private CoverageNodeImpl createNode(final int missed, final int covered) { + return new CoverageNodeImpl(ElementType.GROUP, "Foo") { + { + this.lineCounter = CounterImpl.getInstance(missed, covered); + } + }; + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/CounterColumnTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/CounterColumnTest.java index 6a84a4e0..6d877fe6 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/CounterColumnTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/CounterColumnTest.java @@ -1,227 +1,227 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Locale;
-
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.jacoco.report.MemoryMultiReportOutput;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLDocument;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.HTMLSupport;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-
-/**
- * Unit tests for {@link CounterColumn}.
- */
-public class CounterColumnTest {
-
- private MemoryMultiReportOutput output;
-
- private ReportOutputFolder root;
-
- private Resources resources;
-
- private HTMLDocument doc;
-
- private HTMLElement td;
-
- private HTMLSupport support;
-
- private Locale locale;
-
- @Before
- public void setup() throws Exception {
- output = new MemoryMultiReportOutput();
- root = new ReportOutputFolder(output);
- resources = new Resources(root);
- doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8");
- doc.head().title();
- td = doc.body().table("somestyle").tr().td();
- support = new HTMLSupport();
- locale = Locale.ENGLISH;
- }
-
- @After
- public void teardown() throws IOException {
- output.close();
- output.assertAllClosed();
- }
-
- @Test
- public void testInitVisible() throws Exception {
- IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE,
- locale);
- final ITableItem item = createItem(0, 3);
- assertTrue(column.init(Arrays.asList(item), item.getNode()));
- doc.close();
- }
-
- @Test
- public void testInitInvisible() throws Exception {
- IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE,
- locale);
- final ITableItem item = createItem(0, 0);
- assertFalse(column.init(Arrays.asList(item), createNode(1, 0)));
- doc.close();
- }
-
- @Test
- public void testItemTotal() throws Exception {
- IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE,
- locale);
- final ITableItem item = createItem(100, 50);
- column.init(Collections.singletonList(item), item.getNode());
- column.item(td, item, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("150",
- support.findStr(doc, "/html/body/table/tr/td[1]/text()"));
- }
-
- @Test
- public void testItemMissed() throws Exception {
- IColumnRenderer column = CounterColumn.newMissed(CounterEntity.LINE,
- locale);
- final ITableItem item = createItem(100, 50);
- column.init(Collections.singletonList(item), item.getNode());
- column.item(td, item, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("100",
- support.findStr(doc, "/html/body/table/tr/td[1]/text()"));
- }
-
- @Test
- public void testItemCovered() throws Exception {
- IColumnRenderer column = CounterColumn.newCovered(CounterEntity.LINE,
- locale);
- final ITableItem item = createItem(100, 50);
- column.init(Collections.singletonList(item), item.getNode());
- column.item(td, item, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("50",
- support.findStr(doc, "/html/body/table/tr/td[1]/text()"));
- }
-
- @Test
- public void testLocale() throws Exception {
- IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE,
- Locale.ITALIAN);
- final ITableItem item = createItem(1000, 0);
- column.init(Collections.singletonList(item), item.getNode());
- column.item(td, item, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("1.000",
- support.findStr(doc, "/html/body/table/tr/td[1]/text()"));
- }
-
- @Test
- public void testFooter() throws Exception {
- IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE,
- locale);
- final ITableItem item = createItem(20, 60);
- column.init(Collections.singletonList(item), item.getNode());
- column.footer(td, item.getNode(), resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("80",
- support.findStr(doc, "/html/body/table/tr/td[1]/text()"));
- }
-
- @Test
- public void testComparatorTotal() throws Exception {
- IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE,
- locale);
- final Comparator<ITableItem> c = column.getComparator();
- final ITableItem i1 = createItem(30, 0);
- final ITableItem i2 = createItem(40, 0);
- assertEquals(0, c.compare(i1, i1));
- assertTrue(c.compare(i1, i2) > 0);
- assertTrue(c.compare(i2, i1) < 0);
- doc.close();
- }
-
- @Test
- public void testComparatorCovered() throws Exception {
- IColumnRenderer column = CounterColumn.newCovered(CounterEntity.LINE,
- locale);
- final Comparator<ITableItem> c = column.getComparator();
- final ITableItem i1 = createItem(70, 30);
- final ITableItem i2 = createItem(50, 50);
- assertEquals(0, c.compare(i1, i1));
- assertTrue(c.compare(i1, i2) > 0);
- assertTrue(c.compare(i2, i1) < 0);
- doc.close();
- }
-
- @Test
- public void testComparatorMissed() throws Exception {
- IColumnRenderer column = CounterColumn.newMissed(CounterEntity.LINE,
- locale);
- final Comparator<ITableItem> c = column.getComparator();
- final ITableItem i1 = createItem(20, 80);
- final ITableItem i2 = createItem(50, 50);
- assertEquals(0, c.compare(i1, i1));
- assertTrue(c.compare(i1, i2) > 0);
- assertTrue(c.compare(i2, i1) < 0);
- doc.close();
- }
-
- private ITableItem createItem(final int missed, final int covered) {
- final ICoverageNode node = createNode(missed, covered);
- return new ITableItem() {
- public String getLinkLabel() {
- return "Foo";
- }
-
- public String getLink(ReportOutputFolder base) {
- return null;
- }
-
- public String getLinkStyle() {
- return Resources.getElementStyle(node.getElementType());
- }
-
- public ICoverageNode getNode() {
- return node;
- }
- };
- }
-
- private CoverageNodeImpl createNode(final int missed, final int covered) {
- return new CoverageNodeImpl(ElementType.GROUP, "Foo") {
- {
- this.lineCounter = CounterImpl.getInstance(missed, covered);
- }
- };
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Locale; + +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.report.MemoryMultiReportOutput; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLDocument; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.HTMLSupport; +import org.jacoco.report.internal.html.resources.Resources; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; + +/** + * Unit tests for {@link CounterColumn}. + */ +public class CounterColumnTest { + + private MemoryMultiReportOutput output; + + private ReportOutputFolder root; + + private Resources resources; + + private HTMLDocument doc; + + private HTMLElement td; + + private HTMLSupport support; + + private Locale locale; + + @Before + public void setup() throws Exception { + output = new MemoryMultiReportOutput(); + root = new ReportOutputFolder(output); + resources = new Resources(root); + doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8"); + doc.head().title(); + td = doc.body().table("somestyle").tr().td(); + support = new HTMLSupport(); + locale = Locale.ENGLISH; + } + + @After + public void teardown() throws IOException { + output.close(); + output.assertAllClosed(); + } + + @Test + public void testInitVisible() throws Exception { + IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE, + locale); + final ITableItem item = createItem(0, 3); + assertTrue(column.init(Arrays.asList(item), item.getNode())); + doc.close(); + } + + @Test + public void testInitInvisible() throws Exception { + IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE, + locale); + final ITableItem item = createItem(0, 0); + assertFalse(column.init(Arrays.asList(item), createNode(1, 0))); + doc.close(); + } + + @Test + public void testItemTotal() throws Exception { + IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE, + locale); + final ITableItem item = createItem(100, 50); + column.init(Collections.singletonList(item), item.getNode()); + column.item(td, item, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("150", + support.findStr(doc, "/html/body/table/tr/td[1]/text()")); + } + + @Test + public void testItemMissed() throws Exception { + IColumnRenderer column = CounterColumn.newMissed(CounterEntity.LINE, + locale); + final ITableItem item = createItem(100, 50); + column.init(Collections.singletonList(item), item.getNode()); + column.item(td, item, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("100", + support.findStr(doc, "/html/body/table/tr/td[1]/text()")); + } + + @Test + public void testItemCovered() throws Exception { + IColumnRenderer column = CounterColumn.newCovered(CounterEntity.LINE, + locale); + final ITableItem item = createItem(100, 50); + column.init(Collections.singletonList(item), item.getNode()); + column.item(td, item, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("50", + support.findStr(doc, "/html/body/table/tr/td[1]/text()")); + } + + @Test + public void testLocale() throws Exception { + IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE, + Locale.ITALIAN); + final ITableItem item = createItem(1000, 0); + column.init(Collections.singletonList(item), item.getNode()); + column.item(td, item, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("1.000", + support.findStr(doc, "/html/body/table/tr/td[1]/text()")); + } + + @Test + public void testFooter() throws Exception { + IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE, + locale); + final ITableItem item = createItem(20, 60); + column.init(Collections.singletonList(item), item.getNode()); + column.footer(td, item.getNode(), resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("80", + support.findStr(doc, "/html/body/table/tr/td[1]/text()")); + } + + @Test + public void testComparatorTotal() throws Exception { + IColumnRenderer column = CounterColumn.newTotal(CounterEntity.LINE, + locale); + final Comparator<ITableItem> c = column.getComparator(); + final ITableItem i1 = createItem(30, 0); + final ITableItem i2 = createItem(40, 0); + assertEquals(0, c.compare(i1, i1)); + assertTrue(c.compare(i1, i2) > 0); + assertTrue(c.compare(i2, i1) < 0); + doc.close(); + } + + @Test + public void testComparatorCovered() throws Exception { + IColumnRenderer column = CounterColumn.newCovered(CounterEntity.LINE, + locale); + final Comparator<ITableItem> c = column.getComparator(); + final ITableItem i1 = createItem(70, 30); + final ITableItem i2 = createItem(50, 50); + assertEquals(0, c.compare(i1, i1)); + assertTrue(c.compare(i1, i2) > 0); + assertTrue(c.compare(i2, i1) < 0); + doc.close(); + } + + @Test + public void testComparatorMissed() throws Exception { + IColumnRenderer column = CounterColumn.newMissed(CounterEntity.LINE, + locale); + final Comparator<ITableItem> c = column.getComparator(); + final ITableItem i1 = createItem(20, 80); + final ITableItem i2 = createItem(50, 50); + assertEquals(0, c.compare(i1, i1)); + assertTrue(c.compare(i1, i2) > 0); + assertTrue(c.compare(i2, i1) < 0); + doc.close(); + } + + private ITableItem createItem(final int missed, final int covered) { + final ICoverageNode node = createNode(missed, covered); + return new ITableItem() { + public String getLinkLabel() { + return "Foo"; + } + + public String getLink(ReportOutputFolder base) { + return null; + } + + public String getLinkStyle() { + return Resources.getElementStyle(node.getElementType()); + } + + public ICoverageNode getNode() { + return node; + } + }; + } + + private CoverageNodeImpl createNode(final int missed, final int covered) { + return new CoverageNodeImpl(ElementType.GROUP, "Foo") { + { + this.lineCounter = CounterImpl.getInstance(missed, covered); + } + }; + } +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/LabelColumnTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/LabelColumnTest.java index a5f05f48..0689a12c 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/LabelColumnTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/LabelColumnTest.java @@ -1,148 +1,148 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.report.MemoryMultiReportOutput;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLDocument;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.HTMLSupport;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-
-/**
- * Unit tests for {@link LabelColumn}.
- */
-public class LabelColumnTest {
-
- private MemoryMultiReportOutput output;
-
- private ReportOutputFolder root;
-
- private Resources resources;
-
- private HTMLDocument doc;
-
- private HTMLElement td;
-
- private HTMLSupport support;
-
- private IColumnRenderer column;
-
- @Before
- public void setup() throws Exception {
- output = new MemoryMultiReportOutput();
- root = new ReportOutputFolder(output);
- resources = new Resources(root);
- doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8");
- doc.head().title();
- td = doc.body().table("somestyle").tr().td();
- support = new HTMLSupport();
- column = new LabelColumn();
- }
-
- @After
- public void teardown() throws IOException {
- output.close();
- output.assertAllClosed();
- }
-
- @Test
- public void testInit() throws Exception {
- assertTrue(column.init(null, null));
- doc.close();
- }
-
- @Test
- public void testFooter() throws Exception {
- column.footer(td, new CoverageNodeImpl(ElementType.GROUP, "Foo"),
- resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("Total",
- support.findStr(doc, "/html/body/table/tr/td/text()"));
- }
-
- @Test
- public void testItemWithoutLink() throws Exception {
- column.item(td, createItem("Abc", null), resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("Abc",
- support.findStr(doc, "/html/body/table/tr/td/span/text()"));
- assertEquals("el_group",
- support.findStr(doc, "/html/body/table/tr/td/span/@class"));
- }
-
- @Test
- public void testItemWithLink() throws Exception {
- column.item(td, createItem("Def", "def.html"), resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("Def",
- support.findStr(doc, "/html/body/table/tr/td/a/text()"));
- assertEquals("def.html",
- support.findStr(doc, "/html/body/table/tr/td/a/@href"));
- assertEquals("el_group",
- support.findStr(doc, "/html/body/table/tr/td/a/@class"));
- }
-
- @Test
- public void testComparator1() throws Exception {
- final ITableItem i1 = createItem("abcdef", null);
- final ITableItem i2 = createItem("aBcDeF", null);
- assertEquals(0, column.getComparator().compare(i1, i2));
- doc.close();
- }
-
- @Test
- public void testComparator2() throws Exception {
- final ITableItem i1 = createItem("hello", null);
- final ITableItem i2 = createItem("world", null);
- assertTrue(column.getComparator().compare(i1, i2) < 0);
- assertTrue(column.getComparator().compare(i2, i1) > 0);
- doc.close();
- }
-
- private ITableItem createItem(final String name, final String link) {
- final ICoverageNode node = new CoverageNodeImpl(ElementType.GROUP, name);
- return new ITableItem() {
- public String getLinkLabel() {
- return name;
- }
-
- public String getLink(ReportOutputFolder base) {
- return link;
- }
-
- public String getLinkStyle() {
- return Resources.getElementStyle(node.getElementType());
- }
-
- public ICoverageNode getNode() {
- return node;
- }
- };
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.report.MemoryMultiReportOutput; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLDocument; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.HTMLSupport; +import org.jacoco.report.internal.html.resources.Resources; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; + +/** + * Unit tests for {@link LabelColumn}. + */ +public class LabelColumnTest { + + private MemoryMultiReportOutput output; + + private ReportOutputFolder root; + + private Resources resources; + + private HTMLDocument doc; + + private HTMLElement td; + + private HTMLSupport support; + + private IColumnRenderer column; + + @Before + public void setup() throws Exception { + output = new MemoryMultiReportOutput(); + root = new ReportOutputFolder(output); + resources = new Resources(root); + doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8"); + doc.head().title(); + td = doc.body().table("somestyle").tr().td(); + support = new HTMLSupport(); + column = new LabelColumn(); + } + + @After + public void teardown() throws IOException { + output.close(); + output.assertAllClosed(); + } + + @Test + public void testInit() throws Exception { + assertTrue(column.init(null, null)); + doc.close(); + } + + @Test + public void testFooter() throws Exception { + column.footer(td, new CoverageNodeImpl(ElementType.GROUP, "Foo"), + resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("Total", + support.findStr(doc, "/html/body/table/tr/td/text()")); + } + + @Test + public void testItemWithoutLink() throws Exception { + column.item(td, createItem("Abc", null), resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("Abc", + support.findStr(doc, "/html/body/table/tr/td/span/text()")); + assertEquals("el_group", + support.findStr(doc, "/html/body/table/tr/td/span/@class")); + } + + @Test + public void testItemWithLink() throws Exception { + column.item(td, createItem("Def", "def.html"), resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("Def", + support.findStr(doc, "/html/body/table/tr/td/a/text()")); + assertEquals("def.html", + support.findStr(doc, "/html/body/table/tr/td/a/@href")); + assertEquals("el_group", + support.findStr(doc, "/html/body/table/tr/td/a/@class")); + } + + @Test + public void testComparator1() throws Exception { + final ITableItem i1 = createItem("abcdef", null); + final ITableItem i2 = createItem("aBcDeF", null); + assertEquals(0, column.getComparator().compare(i1, i2)); + doc.close(); + } + + @Test + public void testComparator2() throws Exception { + final ITableItem i1 = createItem("hello", null); + final ITableItem i2 = createItem("world", null); + assertTrue(column.getComparator().compare(i1, i2) < 0); + assertTrue(column.getComparator().compare(i2, i1) > 0); + doc.close(); + } + + private ITableItem createItem(final String name, final String link) { + final ICoverageNode node = new CoverageNodeImpl(ElementType.GROUP, name); + return new ITableItem() { + public String getLinkLabel() { + return name; + } + + public String getLink(ReportOutputFolder base) { + return link; + } + + public String getLinkStyle() { + return Resources.getElementStyle(node.getElementType()); + } + + public ICoverageNode getNode() { + return node; + } + }; + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/PercentageColumnTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/PercentageColumnTest.java index 70210655..3c47ab2d 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/PercentageColumnTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/PercentageColumnTest.java @@ -1,169 +1,169 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.Comparator;
-import java.util.Locale;
-
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.jacoco.report.MemoryMultiReportOutput;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLDocument;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.HTMLSupport;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-
-/**
- * Unit tests for {@link PercentageColumn}.
- */
-public class PercentageColumnTest {
-
- private MemoryMultiReportOutput output;
-
- private ReportOutputFolder root;
-
- private Resources resources;
-
- private HTMLDocument doc;
-
- private HTMLElement td;
-
- private HTMLSupport support;
-
- private IColumnRenderer column;
-
- @Before
- public void setup() throws Exception {
- output = new MemoryMultiReportOutput();
- root = new ReportOutputFolder(output);
- resources = new Resources(root);
- doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8");
- doc.head().title();
- td = doc.body().table("somestyle").tr().td();
- support = new HTMLSupport();
- column = new PercentageColumn(CounterEntity.LINE, Locale.ENGLISH);
- }
-
- @After
- public void teardown() throws IOException {
- output.close();
- output.assertAllClosed();
- }
-
- @Test
- public void testInit() throws Exception {
- assertTrue(column.init(null, null));
- doc.close();
- }
-
- @Test
- public void testItem1() throws Exception {
- final ITableItem item = createItem(100, 50);
- column.item(td, item, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("33%",
- support.findStr(doc, "/html/body/table/tr/td[1]/text()"));
- }
-
- @Test
- public void testItem2() throws Exception {
- final ITableItem item = createItem(0, 0);
- column.item(td, item, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("n/a",
- support.findStr(doc, "/html/body/table/tr/td[1]/text()"));
- }
-
- @Test
- public void testLocale() throws Exception {
- IColumnRenderer column = new PercentageColumn(CounterEntity.LINE,
- Locale.FRENCH);
- final ITableItem item = createItem(0, 1000);
- column.item(td, item, resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("100 %",
- support.findStr(doc, "/html/body/table/tr/td[1]/text()"));
- }
-
- @Test
- public void testFooter1() throws Exception {
- final ITableItem item = createItem(20, 60);
- column.footer(td, item.getNode(), resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("75%", support.findStr(doc, "/html/body/table/tr"));
- }
-
- @Test
- public void testFooter2() throws Exception {
- final ITableItem item = createItem(0, 0);
- column.footer(td, item.getNode(), resources, root);
- doc.close();
- final Document doc = support.parse(output.getFile("Test.html"));
- assertEquals("n/a", support.findStr(doc, "/html/body/table/tr"));
- }
-
- @Test
- public void testComparator() throws Exception {
- final Comparator<ITableItem> c = column.getComparator();
- final ITableItem i1 = createItem(50, 50);
- final ITableItem i2 = createItem(800, 200);
- assertTrue(c.compare(i1, i2) < 0);
- assertTrue(c.compare(i2, i1) > 0);
- assertEquals(0, c.compare(i1, i1));
- doc.close();
- }
-
- private ITableItem createItem(final int missed, final int covered) {
- final ICoverageNode node = createNode(missed, covered);
- return new ITableItem() {
- public String getLinkLabel() {
- return "Foo";
- }
-
- public String getLink(ReportOutputFolder base) {
- return null;
- }
-
- public String getLinkStyle() {
- return Resources.getElementStyle(node.getElementType());
- }
-
- public ICoverageNode getNode() {
- return node;
- }
- };
- }
-
- private CoverageNodeImpl createNode(final int missed, final int covered) {
- return new CoverageNodeImpl(ElementType.GROUP, "Foo") {
- {
- this.lineCounter = CounterImpl.getInstance(missed, covered);
- }
- };
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Comparator; +import java.util.Locale; + +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.report.MemoryMultiReportOutput; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLDocument; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.HTMLSupport; +import org.jacoco.report.internal.html.resources.Resources; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; + +/** + * Unit tests for {@link PercentageColumn}. + */ +public class PercentageColumnTest { + + private MemoryMultiReportOutput output; + + private ReportOutputFolder root; + + private Resources resources; + + private HTMLDocument doc; + + private HTMLElement td; + + private HTMLSupport support; + + private IColumnRenderer column; + + @Before + public void setup() throws Exception { + output = new MemoryMultiReportOutput(); + root = new ReportOutputFolder(output); + resources = new Resources(root); + doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8"); + doc.head().title(); + td = doc.body().table("somestyle").tr().td(); + support = new HTMLSupport(); + column = new PercentageColumn(CounterEntity.LINE, Locale.ENGLISH); + } + + @After + public void teardown() throws IOException { + output.close(); + output.assertAllClosed(); + } + + @Test + public void testInit() throws Exception { + assertTrue(column.init(null, null)); + doc.close(); + } + + @Test + public void testItem1() throws Exception { + final ITableItem item = createItem(100, 50); + column.item(td, item, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("33%", + support.findStr(doc, "/html/body/table/tr/td[1]/text()")); + } + + @Test + public void testItem2() throws Exception { + final ITableItem item = createItem(0, 0); + column.item(td, item, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("n/a", + support.findStr(doc, "/html/body/table/tr/td[1]/text()")); + } + + @Test + public void testLocale() throws Exception { + IColumnRenderer column = new PercentageColumn(CounterEntity.LINE, + Locale.FRENCH); + final ITableItem item = createItem(0, 1000); + column.item(td, item, resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("100 %", + support.findStr(doc, "/html/body/table/tr/td[1]/text()")); + } + + @Test + public void testFooter1() throws Exception { + final ITableItem item = createItem(20, 60); + column.footer(td, item.getNode(), resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("75%", support.findStr(doc, "/html/body/table/tr")); + } + + @Test + public void testFooter2() throws Exception { + final ITableItem item = createItem(0, 0); + column.footer(td, item.getNode(), resources, root); + doc.close(); + final Document doc = support.parse(output.getFile("Test.html")); + assertEquals("n/a", support.findStr(doc, "/html/body/table/tr")); + } + + @Test + public void testComparator() throws Exception { + final Comparator<ITableItem> c = column.getComparator(); + final ITableItem i1 = createItem(50, 50); + final ITableItem i2 = createItem(800, 200); + assertTrue(c.compare(i1, i2) < 0); + assertTrue(c.compare(i2, i1) > 0); + assertEquals(0, c.compare(i1, i1)); + doc.close(); + } + + private ITableItem createItem(final int missed, final int covered) { + final ICoverageNode node = createNode(missed, covered); + return new ITableItem() { + public String getLinkLabel() { + return "Foo"; + } + + public String getLink(ReportOutputFolder base) { + return null; + } + + public String getLinkStyle() { + return Resources.getElementStyle(node.getElementType()); + } + + public ICoverageNode getNode() { + return node; + } + }; + } + + private CoverageNodeImpl createNode(final int missed, final int covered) { + return new CoverageNodeImpl(ElementType.GROUP, "Foo") { + { + this.lineCounter = CounterImpl.getInstance(missed, covered); + } + }; + } +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/TableTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/TableTest.java index 3bd5d53c..dcc216c4 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/TableTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/html/table/TableTest.java @@ -1,285 +1,285 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-
-import org.jacoco.core.analysis.CounterComparator;
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.core.internal.analysis.CounterImpl;
-import org.jacoco.report.MemoryMultiReportOutput;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLDocument;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.HTMLSupport;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.w3c.dom.Document;
-
-/**
- * Unit tests for {@link Table}.
- */
-public class TableTest {
-
- private MemoryMultiReportOutput output;
-
- private ReportOutputFolder root;
-
- private Resources resources;
-
- private HTMLDocument doc;
-
- private HTMLElement body;
-
- private Table table;
-
- @Before
- public void setup() throws IOException {
- output = new MemoryMultiReportOutput();
- root = new ReportOutputFolder(output);
- resources = new Resources(root);
- doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8");
- doc.head().title();
- body = doc.body();
- table = new Table();
- }
-
- @After
- public void teardown() throws IOException {
- output.close();
- output.assertAllClosed();
- }
-
- @Test
- public void testCallbackSequence() throws IOException {
- final IColumnRenderer recorder = new StubRenderer(
- CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)) {
-
- private final StringBuilder store = new StringBuilder();
-
- @Override
- public boolean init(List<? extends ITableItem> items,
- ICoverageNode total) {
- store.append("init-");
- return true;
- }
-
- @Override
- public void footer(HTMLElement td, ICoverageNode total,
- Resources resources, ReportOutputFolder base) {
- store.append("footer-");
- }
-
- @Override
- public void item(HTMLElement td, ITableItem item,
- Resources resources, ReportOutputFolder base) {
- store.append("item").append(item.getLinkLabel()).append("-");
- }
-
- @Override
- public String toString() {
- return store.toString();
- }
-
- };
- final List<ITableItem> items = Arrays.asList(createItem("A", 1),
- createItem("B", 2), createItem("C", 3));
- table.add("Header", null, recorder, false);
- table.render(body, items, createTotal("Sum", 6), resources, root);
- doc.close();
- assertEquals("init-footer-itemA-itemB-itemC-", recorder.toString());
- }
-
- @Test
- public void testInvisible() throws IOException {
- final IColumnRenderer column = new StubRenderer(
- CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)) {
-
- @Override
- public boolean init(List<? extends ITableItem> items,
- ICoverageNode total) {
- return false;
- }
-
- @Override
- public void footer(HTMLElement td, ICoverageNode total,
- Resources resources, ReportOutputFolder base) {
- fail();
- }
-
- @Override
- public void item(HTMLElement td, ITableItem item,
- Resources resources, ReportOutputFolder base) {
- fail();
- }
- };
- final List<ITableItem> items = Arrays.asList(createItem("A", 1));
- table.add("Header", null, column, false);
- table.render(body, items, createTotal("Sum", 1), resources, root);
- doc.close();
- }
-
- @Test(expected = IllegalStateException.class)
- public void testTwoDefaultSorts() throws IOException {
- doc.close();
- table.add("Header1", null, new StubRenderer(
- CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), true);
- table.add("Header2", null, new StubRenderer(
- CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), true);
- }
-
- @Test
- public void testSortIds() throws Exception {
- final List<ITableItem> items = Arrays.asList(createItem("C", 3),
- createItem("E", 4), createItem("A", 1), createItem("D", 2));
- table.add("Forward", null, new StubRenderer(
- CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), false);
- table.add(
- "Reverse",
- null,
- new StubRenderer(CounterComparator.TOTALITEMS.reverse().on(
- CounterEntity.CLASS)), false);
- table.render(body, items, createTotal("Sum", 6), resources, root);
- doc.close();
-
- final HTMLSupport support = new HTMLSupport();
- final Document doc = support.parse(output.getFile("Test.html"));
-
- // The elements in Column 1 are sorted in forward order:
- assertEquals("sortable",
- support.findStr(doc, "/html/body/table/thead/tr/td[1]/@class"));
- assertEquals("a",
- support.findStr(doc, "/html/body/table/thead/tr/td[1]/@id"));
- assertEquals("a2",
- support.findStr(doc, "/html/body/table/tbody/tr[1]/td[1]/@id"));
- assertEquals("a3",
- support.findStr(doc, "/html/body/table/tbody/tr[2]/td[1]/@id"));
- assertEquals("a0",
- support.findStr(doc, "/html/body/table/tbody/tr[3]/td[1]/@id"));
- assertEquals("a1",
- support.findStr(doc, "/html/body/table/tbody/tr[4]/td[1]/@id"));
-
- // The elements in Column 2 are sorted in reverse order:
- assertEquals("sortable",
- support.findStr(doc, "/html/body/table/thead/tr/td[2]/@class"));
- assertEquals("b",
- support.findStr(doc, "/html/body/table/thead/tr/td[2]/@id"));
- assertEquals("b1",
- support.findStr(doc, "/html/body/table/tbody/tr[1]/td[2]/@id"));
- assertEquals("b0",
- support.findStr(doc, "/html/body/table/tbody/tr[2]/td[2]/@id"));
- assertEquals("b3",
- support.findStr(doc, "/html/body/table/tbody/tr[3]/td[2]/@id"));
- assertEquals("b2",
- support.findStr(doc, "/html/body/table/tbody/tr[4]/td[2]/@id"));
- }
-
- @Test
- public void testDefaultSorting() throws Exception {
- final List<ITableItem> items = Arrays.asList(createItem("C", 3),
- createItem("E", 5), createItem("A", 1), createItem("D", 4),
- createItem("B", 2));
- table.add("Forward", null, new StubRenderer(
- CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), true);
- table.render(body, items, createTotal("Sum", 1), resources, root);
- doc.close();
-
- final HTMLSupport support = new HTMLSupport();
- final Document doc = support.parse(output.getFile("Test.html"));
-
- assertEquals("down sortable",
- support.findStr(doc, "/html/body/table/thead/tr/td[1]/@class"));
- assertEquals("A",
- support.findStr(doc, "/html/body/table/tbody/tr[1]/td[1]"));
- assertEquals("B",
- support.findStr(doc, "/html/body/table/tbody/tr[2]/td[1]"));
- assertEquals("C",
- support.findStr(doc, "/html/body/table/tbody/tr[3]/td[1]"));
- assertEquals("D",
- support.findStr(doc, "/html/body/table/tbody/tr[4]/td[1]"));
- assertEquals("E",
- support.findStr(doc, "/html/body/table/tbody/tr[5]/td[1]"));
- }
-
- private ITableItem createItem(final String name, final int count) {
- final ICoverageNode node = new CoverageNodeImpl(ElementType.GROUP, name) {
- {
- this.classCounter = CounterImpl.getInstance(count, 0);
- }
- };
- return new ITableItem() {
- public String getLinkLabel() {
- return name;
- }
-
- public String getLink(ReportOutputFolder base) {
- return name + ".html";
- }
-
- public String getLinkStyle() {
- return Resources.getElementStyle(node.getElementType());
- }
-
- public ICoverageNode getNode() {
- return node;
- }
- };
- }
-
- private ICoverageNode createTotal(final String name, final int count) {
- return new CoverageNodeImpl(ElementType.GROUP, name) {
- {
- this.classCounter = CounterImpl.getInstance(count, 0);
- }
- };
- }
-
- private static class StubRenderer implements IColumnRenderer {
-
- private final Comparator<ITableItem> comparator;
-
- StubRenderer(Comparator<ICoverageNode> comparator) {
- this.comparator = new TableItemComparator(comparator);
- }
-
- public boolean init(List<? extends ITableItem> items,
- ICoverageNode total) {
- return true;
- }
-
- public void footer(HTMLElement td, ICoverageNode total,
- Resources resources, ReportOutputFolder base) {
- }
-
- public void item(HTMLElement td, ITableItem item, Resources resources,
- ReportOutputFolder base) throws IOException {
- td.text(item.getLinkLabel());
- }
-
- public Comparator<ITableItem> getComparator() {
- return comparator;
- }
-
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import org.jacoco.core.analysis.CounterComparator; +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.report.MemoryMultiReportOutput; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLDocument; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.HTMLSupport; +import org.jacoco.report.internal.html.resources.Resources; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; + +/** + * Unit tests for {@link Table}. + */ +public class TableTest { + + private MemoryMultiReportOutput output; + + private ReportOutputFolder root; + + private Resources resources; + + private HTMLDocument doc; + + private HTMLElement body; + + private Table table; + + @Before + public void setup() throws IOException { + output = new MemoryMultiReportOutput(); + root = new ReportOutputFolder(output); + resources = new Resources(root); + doc = new HTMLDocument(root.createFile("Test.html"), "UTF-8"); + doc.head().title(); + body = doc.body(); + table = new Table(); + } + + @After + public void teardown() throws IOException { + output.close(); + output.assertAllClosed(); + } + + @Test + public void testCallbackSequence() throws IOException { + final IColumnRenderer recorder = new StubRenderer( + CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)) { + + private final StringBuilder store = new StringBuilder(); + + @Override + public boolean init(List<? extends ITableItem> items, + ICoverageNode total) { + store.append("init-"); + return true; + } + + @Override + public void footer(HTMLElement td, ICoverageNode total, + Resources resources, ReportOutputFolder base) { + store.append("footer-"); + } + + @Override + public void item(HTMLElement td, ITableItem item, + Resources resources, ReportOutputFolder base) { + store.append("item").append(item.getLinkLabel()).append("-"); + } + + @Override + public String toString() { + return store.toString(); + } + + }; + final List<ITableItem> items = Arrays.asList(createItem("A", 1), + createItem("B", 2), createItem("C", 3)); + table.add("Header", null, recorder, false); + table.render(body, items, createTotal("Sum", 6), resources, root); + doc.close(); + assertEquals("init-footer-itemA-itemB-itemC-", recorder.toString()); + } + + @Test + public void testInvisible() throws IOException { + final IColumnRenderer column = new StubRenderer( + CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)) { + + @Override + public boolean init(List<? extends ITableItem> items, + ICoverageNode total) { + return false; + } + + @Override + public void footer(HTMLElement td, ICoverageNode total, + Resources resources, ReportOutputFolder base) { + fail(); + } + + @Override + public void item(HTMLElement td, ITableItem item, + Resources resources, ReportOutputFolder base) { + fail(); + } + }; + final List<ITableItem> items = Arrays.asList(createItem("A", 1)); + table.add("Header", null, column, false); + table.render(body, items, createTotal("Sum", 1), resources, root); + doc.close(); + } + + @Test(expected = IllegalStateException.class) + public void testTwoDefaultSorts() throws IOException { + doc.close(); + table.add("Header1", null, new StubRenderer( + CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), true); + table.add("Header2", null, new StubRenderer( + CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), true); + } + + @Test + public void testSortIds() throws Exception { + final List<ITableItem> items = Arrays.asList(createItem("C", 3), + createItem("E", 4), createItem("A", 1), createItem("D", 2)); + table.add("Forward", null, new StubRenderer( + CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), false); + table.add( + "Reverse", + null, + new StubRenderer(CounterComparator.TOTALITEMS.reverse().on( + CounterEntity.CLASS)), false); + table.render(body, items, createTotal("Sum", 6), resources, root); + doc.close(); + + final HTMLSupport support = new HTMLSupport(); + final Document doc = support.parse(output.getFile("Test.html")); + + // The elements in Column 1 are sorted in forward order: + assertEquals("sortable", + support.findStr(doc, "/html/body/table/thead/tr/td[1]/@class")); + assertEquals("a", + support.findStr(doc, "/html/body/table/thead/tr/td[1]/@id")); + assertEquals("a2", + support.findStr(doc, "/html/body/table/tbody/tr[1]/td[1]/@id")); + assertEquals("a3", + support.findStr(doc, "/html/body/table/tbody/tr[2]/td[1]/@id")); + assertEquals("a0", + support.findStr(doc, "/html/body/table/tbody/tr[3]/td[1]/@id")); + assertEquals("a1", + support.findStr(doc, "/html/body/table/tbody/tr[4]/td[1]/@id")); + + // The elements in Column 2 are sorted in reverse order: + assertEquals("sortable", + support.findStr(doc, "/html/body/table/thead/tr/td[2]/@class")); + assertEquals("b", + support.findStr(doc, "/html/body/table/thead/tr/td[2]/@id")); + assertEquals("b1", + support.findStr(doc, "/html/body/table/tbody/tr[1]/td[2]/@id")); + assertEquals("b0", + support.findStr(doc, "/html/body/table/tbody/tr[2]/td[2]/@id")); + assertEquals("b3", + support.findStr(doc, "/html/body/table/tbody/tr[3]/td[2]/@id")); + assertEquals("b2", + support.findStr(doc, "/html/body/table/tbody/tr[4]/td[2]/@id")); + } + + @Test + public void testDefaultSorting() throws Exception { + final List<ITableItem> items = Arrays.asList(createItem("C", 3), + createItem("E", 5), createItem("A", 1), createItem("D", 4), + createItem("B", 2)); + table.add("Forward", null, new StubRenderer( + CounterComparator.TOTALITEMS.on(CounterEntity.CLASS)), true); + table.render(body, items, createTotal("Sum", 1), resources, root); + doc.close(); + + final HTMLSupport support = new HTMLSupport(); + final Document doc = support.parse(output.getFile("Test.html")); + + assertEquals("down sortable", + support.findStr(doc, "/html/body/table/thead/tr/td[1]/@class")); + assertEquals("A", + support.findStr(doc, "/html/body/table/tbody/tr[1]/td[1]")); + assertEquals("B", + support.findStr(doc, "/html/body/table/tbody/tr[2]/td[1]")); + assertEquals("C", + support.findStr(doc, "/html/body/table/tbody/tr[3]/td[1]")); + assertEquals("D", + support.findStr(doc, "/html/body/table/tbody/tr[4]/td[1]")); + assertEquals("E", + support.findStr(doc, "/html/body/table/tbody/tr[5]/td[1]")); + } + + private ITableItem createItem(final String name, final int count) { + final ICoverageNode node = new CoverageNodeImpl(ElementType.GROUP, name) { + { + this.classCounter = CounterImpl.getInstance(count, 0); + } + }; + return new ITableItem() { + public String getLinkLabel() { + return name; + } + + public String getLink(ReportOutputFolder base) { + return name + ".html"; + } + + public String getLinkStyle() { + return Resources.getElementStyle(node.getElementType()); + } + + public ICoverageNode getNode() { + return node; + } + }; + } + + private ICoverageNode createTotal(final String name, final int count) { + return new CoverageNodeImpl(ElementType.GROUP, name) { + { + this.classCounter = CounterImpl.getInstance(count, 0); + } + }; + } + + private static class StubRenderer implements IColumnRenderer { + + private final Comparator<ITableItem> comparator; + + StubRenderer(Comparator<ICoverageNode> comparator) { + this.comparator = new TableItemComparator(comparator); + } + + public boolean init(List<? extends ITableItem> items, + ICoverageNode total) { + return true; + } + + public void footer(HTMLElement td, ICoverageNode total, + Resources resources, ReportOutputFolder base) { + } + + public void item(HTMLElement td, ITableItem item, Resources resources, + ReportOutputFolder base) throws IOException { + td.text(item.getLinkLabel()); + } + + public Comparator<ITableItem> getComparator() { + return comparator; + } + + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/LocalEntityResolver.java b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/LocalEntityResolver.java index 19408b40..f738c5ce 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/LocalEntityResolver.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/LocalEntityResolver.java @@ -1,45 +1,45 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.xml;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-/**
- * Loader for local DTD definitions to avoid network access.
- */
-class LocalEntityResolver implements EntityResolver {
-
- private final Class<?> resourceDelegate;
-
- public LocalEntityResolver(Class<?> resourceDelegate) {
- this.resourceDelegate = resourceDelegate;
- }
-
- public InputSource resolveEntity(final String publicId, String systemId)
- throws SAXException, IOException {
- final int sep = systemId.lastIndexOf('/');
- if (sep != -1) {
- systemId = systemId.substring(sep + 1);
- }
- final InputStream in = resourceDelegate.getResourceAsStream(systemId);
- if (in == null) {
- throw new IOException("No local copy for " + systemId);
- }
- return new InputSource(in);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.xml; + +import java.io.IOException; +import java.io.InputStream; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Loader for local DTD definitions to avoid network access. + */ +class LocalEntityResolver implements EntityResolver { + + private final Class<?> resourceDelegate; + + public LocalEntityResolver(Class<?> resourceDelegate) { + this.resourceDelegate = resourceDelegate; + } + + public InputSource resolveEntity(final String publicId, String systemId) + throws SAXException, IOException { + final int sep = systemId.lastIndexOf('/'); + if (sep != -1) { + systemId = systemId.substring(sep + 1); + } + final InputStream in = resourceDelegate.getResourceAsStream(systemId); + if (in == null) { + throw new IOException("No local copy for " + systemId); + } + return new InputSource(in); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLDocumentTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLDocumentTest.java index 193c7fdc..95e4d02b 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLDocumentTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLDocumentTest.java @@ -1,93 +1,93 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.xml;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.junit.Test;
-
-/**
- * Unit tests for {@link XMLDocument}.
- */
-public class XMLDocumentTest {
-
- @Test
- public void testNoDoctype() throws IOException {
- StringWriter writer = new StringWriter();
- new XMLDocument("test", null, null, "UTF-8", false, writer).close();
- assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test/>",
- writer.toString());
- }
-
- @Test
- public void testNoDoctypeStandalone() throws IOException {
- StringWriter writer = new StringWriter();
- new XMLDocument("test", null, null, "UTF-8", true, writer).close();
- assertEquals(
- "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
- + "<test/>", writer.toString());
- }
-
- @Test
- public void testDoctype() throws IOException {
- StringWriter writer = new StringWriter();
- new XMLDocument("test", "sample", "sample.dtd", "UTF-8", false, writer)
- .close();
- assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- + "<!DOCTYPE test PUBLIC \"sample\" \"sample.dtd\"><test/>",
- writer.toString());
- }
-
- @Test
- public void testDoctypeStandalone() throws IOException {
- StringWriter writer = new StringWriter();
- new XMLDocument("test", "sample", "sample.dtd", "UTF-8", true, writer)
- .close();
- assertEquals(
- "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
- + "<!DOCTYPE test PUBLIC \"sample\" \"sample.dtd\">"
- + "<test/>", writer.toString());
- }
-
- @Test
- public void testStream() throws IOException {
- ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- new XMLDocument("test", null, null, "UTF-8", false, buffer).text(
- "\u00CD\u307e").close();
- assertEquals(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test>\u00CD\u307e</test>",
- buffer.toString("UTF-8"));
- }
-
- @Test
- public void testClose() throws IOException {
- class CloseVerifier extends StringWriter {
-
- boolean closed = false;
-
- @Override
- public void close() throws IOException {
- closed = true;
- super.close();
- }
- }
- CloseVerifier verifier = new CloseVerifier();
- new XMLDocument("test", null, null, "UTF-8", false, verifier).close();
- assertTrue(verifier.closed);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringWriter; + +import org.junit.Test; + +/** + * Unit tests for {@link XMLDocument}. + */ +public class XMLDocumentTest { + + @Test + public void testNoDoctype() throws IOException { + StringWriter writer = new StringWriter(); + new XMLDocument("test", null, null, "UTF-8", false, writer).close(); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?><test/>", + writer.toString()); + } + + @Test + public void testNoDoctypeStandalone() throws IOException { + StringWriter writer = new StringWriter(); + new XMLDocument("test", null, null, "UTF-8", true, writer).close(); + assertEquals( + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + + "<test/>", writer.toString()); + } + + @Test + public void testDoctype() throws IOException { + StringWriter writer = new StringWriter(); + new XMLDocument("test", "sample", "sample.dtd", "UTF-8", false, writer) + .close(); + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<!DOCTYPE test PUBLIC \"sample\" \"sample.dtd\"><test/>", + writer.toString()); + } + + @Test + public void testDoctypeStandalone() throws IOException { + StringWriter writer = new StringWriter(); + new XMLDocument("test", "sample", "sample.dtd", "UTF-8", true, writer) + .close(); + assertEquals( + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + + "<!DOCTYPE test PUBLIC \"sample\" \"sample.dtd\">" + + "<test/>", writer.toString()); + } + + @Test + public void testStream() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + new XMLDocument("test", null, null, "UTF-8", false, buffer).text( + "\u00CD\u307e").close(); + assertEquals( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test>\u00CD\u307e</test>", + buffer.toString("UTF-8")); + } + + @Test + public void testClose() throws IOException { + class CloseVerifier extends StringWriter { + + boolean closed = false; + + @Override + public void close() throws IOException { + closed = true; + super.close(); + } + } + CloseVerifier verifier = new CloseVerifier(); + new XMLDocument("test", null, null, "UTF-8", false, verifier).close(); + assertTrue(verifier.closed); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLElementTest.java b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLElementTest.java index e1746324..955bed94 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLElementTest.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLElementTest.java @@ -1,146 +1,146 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.xml;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.IOException;
-import java.io.StringWriter;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Unit tests for {@link XMLElement}.
- */
-public class XMLElementTest {
-
- private StringWriter buffer;
-
- private XMLElement root;
-
- @Before
- public void setUp() throws IOException {
- buffer = new StringWriter();
- root = new XMLElement(buffer, "root");
- root.beginOpenTag();
- }
-
- @Test
- public void testEmptyNode() throws IOException {
- root.close();
- // Second close has no effect:
- root.close();
- assertEquals("<root/>", buffer.toString());
- }
-
- @Test(expected = IOException.class)
- public void testAddAttributeToClosedNode() throws IOException {
- root.close();
- root.attr("attr", "value");
- }
-
- @Test(expected = IOException.class)
- public void testAddChildToClosedNode() throws IOException {
- root.close();
- root.element("child");
- }
-
- @Test(expected = IOException.class)
- public void testAddTextToClosedNode() throws IOException {
- root.close();
- root.text("text");
- }
-
- @Test
- public void testNestedElement() throws IOException {
- root.element("world");
- root.close();
- assertEquals("<root><world/></root>", buffer.toString());
- }
-
- @Test
- public void test2NestedElements() throws IOException {
- root.element("world");
- root.element("universe");
- root.close();
- assertEquals("<root><world/><universe/></root>", buffer.toString());
- }
-
- @Test
- public void testText() throws IOException {
- root.text("world");
- root.close();
- assertEquals("<root>world</root>", buffer.toString());
- }
-
- @Test
- public void testMixedContent() throws IOException {
- root.element("tag1");
- root.text("world");
- root.element("tag2");
- root.close();
- assertEquals("<root><tag1/>world<tag2/></root>", buffer.toString());
- }
-
- @Test
- public void testQuotedText() throws IOException {
- root.text("<black&white\">");
- root.close();
- assertEquals("<root><black&white"></root>",
- buffer.toString());
- }
-
- @Test
- public void testNullAttributes() throws IOException {
- root.attr("id", null);
- root.close();
- assertEquals("<root/>", buffer.toString());
- }
-
- @Test
- public void testStringAttributes() throws IOException {
- root.attr("id", "12345").attr("quote", "<\">");
- root.close();
- assertEquals("<root id=\"12345\" quote=\"<">\"/>",
- buffer.toString());
- }
-
- @Test
- public void testIntAttributes() throws IOException {
- root.attr("missed", 0).attr("total", 123);
- root.close();
- assertEquals("<root missed=\"0\" total=\"123\"/>", buffer.toString());
- }
-
- @Test
- public void testLongAttributes() throws IOException {
- root.attr("min", Long.MIN_VALUE).attr("max", Long.MAX_VALUE);
- root.close();
- assertEquals(
- "<root min=\"-9223372036854775808\" max=\"9223372036854775807\"/>",
- buffer.toString());
- }
-
- @Test(expected = IOException.class)
- public void testInvalidAttributeOutput1() throws IOException {
- root.text("text");
- root.attr("id", "12345");
- }
-
- @Test(expected = IOException.class)
- public void testInvalidAttributeOutput2() throws IOException {
- root.element("child");
- root.attr("id", "12345");
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.xml; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.StringWriter; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link XMLElement}. + */ +public class XMLElementTest { + + private StringWriter buffer; + + private XMLElement root; + + @Before + public void setUp() throws IOException { + buffer = new StringWriter(); + root = new XMLElement(buffer, "root"); + root.beginOpenTag(); + } + + @Test + public void testEmptyNode() throws IOException { + root.close(); + // Second close has no effect: + root.close(); + assertEquals("<root/>", buffer.toString()); + } + + @Test(expected = IOException.class) + public void testAddAttributeToClosedNode() throws IOException { + root.close(); + root.attr("attr", "value"); + } + + @Test(expected = IOException.class) + public void testAddChildToClosedNode() throws IOException { + root.close(); + root.element("child"); + } + + @Test(expected = IOException.class) + public void testAddTextToClosedNode() throws IOException { + root.close(); + root.text("text"); + } + + @Test + public void testNestedElement() throws IOException { + root.element("world"); + root.close(); + assertEquals("<root><world/></root>", buffer.toString()); + } + + @Test + public void test2NestedElements() throws IOException { + root.element("world"); + root.element("universe"); + root.close(); + assertEquals("<root><world/><universe/></root>", buffer.toString()); + } + + @Test + public void testText() throws IOException { + root.text("world"); + root.close(); + assertEquals("<root>world</root>", buffer.toString()); + } + + @Test + public void testMixedContent() throws IOException { + root.element("tag1"); + root.text("world"); + root.element("tag2"); + root.close(); + assertEquals("<root><tag1/>world<tag2/></root>", buffer.toString()); + } + + @Test + public void testQuotedText() throws IOException { + root.text("<black&white\">"); + root.close(); + assertEquals("<root><black&white"></root>", + buffer.toString()); + } + + @Test + public void testNullAttributes() throws IOException { + root.attr("id", null); + root.close(); + assertEquals("<root/>", buffer.toString()); + } + + @Test + public void testStringAttributes() throws IOException { + root.attr("id", "12345").attr("quote", "<\">"); + root.close(); + assertEquals("<root id=\"12345\" quote=\"<">\"/>", + buffer.toString()); + } + + @Test + public void testIntAttributes() throws IOException { + root.attr("missed", 0).attr("total", 123); + root.close(); + assertEquals("<root missed=\"0\" total=\"123\"/>", buffer.toString()); + } + + @Test + public void testLongAttributes() throws IOException { + root.attr("min", Long.MIN_VALUE).attr("max", Long.MAX_VALUE); + root.close(); + assertEquals( + "<root min=\"-9223372036854775808\" max=\"9223372036854775807\"/>", + buffer.toString()); + } + + @Test(expected = IOException.class) + public void testInvalidAttributeOutput1() throws IOException { + root.text("text"); + root.attr("id", "12345"); + } + + @Test(expected = IOException.class) + public void testInvalidAttributeOutput2() throws IOException { + root.element("child"); + root.attr("id", "12345"); + } + +} diff --git a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLSupport.java b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLSupport.java index c441ae15..e7fe66d4 100644 --- a/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLSupport.java +++ b/org.jacoco.report.test/src/org/jacoco/report/internal/xml/XMLSupport.java @@ -1,90 +1,90 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.xml;
-
-import static org.junit.Assert.fail;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.StringReader;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-import org.w3c.dom.Document;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-/**
- * Test utility to parse, validate and query XML documents.
- */
-public class XMLSupport {
-
- private final DocumentBuilder builder;
-
- private XPath xpath;
-
- public XMLSupport(Class<?> resourceDelegate)
- throws ParserConfigurationException {
- final DocumentBuilderFactory builderFactory = DocumentBuilderFactory
- .newInstance();
- builderFactory.setValidating(true);
- builder = builderFactory.newDocumentBuilder();
- builder.setEntityResolver(new LocalEntityResolver(resourceDelegate));
- builder.setErrorHandler(new ErrorHandler() {
- public void error(SAXParseException exception) throws SAXException {
- fail(exception.getMessage());
- }
-
- public void fatalError(SAXParseException exception)
- throws SAXException {
- fail(exception.getMessage());
- }
-
- public void warning(SAXParseException exception)
- throws SAXException {
- fail(exception.getMessage());
- }
- });
- }
-
- private XPath getXPath() {
- if (xpath == null) {
- xpath = XPathFactory.newInstance().newXPath();
- }
- return xpath;
- }
-
- public Document parse(String document) throws SAXException, IOException,
- ParserConfigurationException {
- return builder.parse(new InputSource(new StringReader(document)));
- }
-
- public Document parse(byte[] document) throws SAXException, IOException,
- ParserConfigurationException {
- return builder
- .parse(new InputSource(new ByteArrayInputStream(document)));
- }
-
- public String findStr(final Document doc, final String query)
- throws XPathExpressionException {
- return (String) getXPath().evaluate(query, doc, XPathConstants.STRING);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.xml; + +import static org.junit.Assert.fail; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * Test utility to parse, validate and query XML documents. + */ +public class XMLSupport { + + private final DocumentBuilder builder; + + private XPath xpath; + + public XMLSupport(Class<?> resourceDelegate) + throws ParserConfigurationException { + final DocumentBuilderFactory builderFactory = DocumentBuilderFactory + .newInstance(); + builderFactory.setValidating(true); + builder = builderFactory.newDocumentBuilder(); + builder.setEntityResolver(new LocalEntityResolver(resourceDelegate)); + builder.setErrorHandler(new ErrorHandler() { + public void error(SAXParseException exception) throws SAXException { + fail(exception.getMessage()); + } + + public void fatalError(SAXParseException exception) + throws SAXException { + fail(exception.getMessage()); + } + + public void warning(SAXParseException exception) + throws SAXException { + fail(exception.getMessage()); + } + }); + } + + private XPath getXPath() { + if (xpath == null) { + xpath = XPathFactory.newInstance().newXPath(); + } + return xpath; + } + + public Document parse(String document) throws SAXException, IOException, + ParserConfigurationException { + return builder.parse(new InputSource(new StringReader(document))); + } + + public Document parse(byte[] document) throws SAXException, IOException, + ParserConfigurationException { + return builder + .parse(new InputSource(new ByteArrayInputStream(document))); + } + + public String findStr(final Document doc, final String query) + throws XPathExpressionException { + return (String) getXPath().evaluate(query, doc, XPathConstants.STRING); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/DirectorySourceFileLocator.java b/org.jacoco.report/src/org/jacoco/report/DirectorySourceFileLocator.java index 6ab9dab8..6cac0da0 100644 --- a/org.jacoco.report/src/org/jacoco/report/DirectorySourceFileLocator.java +++ b/org.jacoco.report/src/org/jacoco/report/DirectorySourceFileLocator.java @@ -1,56 +1,56 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Locator for source files that picks source files from a given directory in
- * the file system.
- */
-public class DirectorySourceFileLocator extends InputStreamSourceFileLocator {
-
- private final File directory;
-
- /**
- * Creates a new locator that searches for source files in the given
- * directory.
- *
- * @param directory
- * directory to search for source file
- * @param encoding
- * encoding of the source files, <code>null</code> for platform
- * default encoding
- * @param tabWidth
- * tab width in source files as number of blanks
- *
- */
- public DirectorySourceFileLocator(final File directory,
- final String encoding, final int tabWidth) {
- super(encoding, tabWidth);
- this.directory = directory;
- }
-
- @Override
- protected InputStream getSourceStream(final String path) throws IOException {
- final File file = new File(directory, path);
- if (file.exists()) {
- return new FileInputStream(file);
- } else {
- return null;
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Locator for source files that picks source files from a given directory in + * the file system. + */ +public class DirectorySourceFileLocator extends InputStreamSourceFileLocator { + + private final File directory; + + /** + * Creates a new locator that searches for source files in the given + * directory. + * + * @param directory + * directory to search for source file + * @param encoding + * encoding of the source files, <code>null</code> for platform + * default encoding + * @param tabWidth + * tab width in source files as number of blanks + * + */ + public DirectorySourceFileLocator(final File directory, + final String encoding, final int tabWidth) { + super(encoding, tabWidth); + this.directory = directory; + } + + @Override + protected InputStream getSourceStream(final String path) throws IOException { + final File file = new File(directory, path); + if (file.exists()) { + return new FileInputStream(file); + } else { + return null; + } + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/FileMultiReportOutput.java b/org.jacoco.report/src/org/jacoco/report/FileMultiReportOutput.java index 08faffac..eaecc793 100644 --- a/org.jacoco.report/src/org/jacoco/report/FileMultiReportOutput.java +++ b/org.jacoco.report/src/org/jacoco/report/FileMultiReportOutput.java @@ -1,53 +1,53 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import static java.lang.String.format;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Implementation of {@link IMultiReportOutput} that writes files directly to a
- * given directory.
- */
-public class FileMultiReportOutput implements IMultiReportOutput {
-
- private final File basedir;
-
- /**
- * Creates a new instance for document output in the given base directory.
- *
- * @param basedir
- */
- public FileMultiReportOutput(final File basedir) {
- this.basedir = basedir;
- }
-
- public OutputStream createFile(final String path) throws IOException {
- final File file = new File(basedir, path);
- final File parent = file.getParentFile();
- parent.mkdirs();
- if (!parent.isDirectory()) {
- throw new IOException(format("Can't create directory %s.", parent));
- }
- return new BufferedOutputStream(new FileOutputStream(file));
- }
-
- public void close() throws IOException {
- // nothing to do here
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import static java.lang.String.format; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * Implementation of {@link IMultiReportOutput} that writes files directly to a + * given directory. + */ +public class FileMultiReportOutput implements IMultiReportOutput { + + private final File basedir; + + /** + * Creates a new instance for document output in the given base directory. + * + * @param basedir + */ + public FileMultiReportOutput(final File basedir) { + this.basedir = basedir; + } + + public OutputStream createFile(final String path) throws IOException { + final File file = new File(basedir, path); + final File parent = file.getParentFile(); + parent.mkdirs(); + if (!parent.isDirectory()) { + throw new IOException(format("Can't create directory %s.", parent)); + } + return new BufferedOutputStream(new FileOutputStream(file)); + } + + public void close() throws IOException { + // nothing to do here + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/ILanguageNames.java b/org.jacoco.report/src/org/jacoco/report/ILanguageNames.java index e82af4b0..79387390 100644 --- a/org.jacoco.report/src/org/jacoco/report/ILanguageNames.java +++ b/org.jacoco.report/src/org/jacoco/report/ILanguageNames.java @@ -1,70 +1,70 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-/**
- * Interface to create programming language specific names from VM names.
- */
-public interface ILanguageNames {
-
- /**
- * Calculates the language specific name of a package.
- *
- * @param vmname
- * vm name of a package
- * @return language specific notation for the package
- */
- public String getPackageName(String vmname);
-
- /**
- * Calculates the language specific name of a class.
- *
- * @param vmname
- * vm name of a class
- * @param vmsignature
- * vm signature of the class (may be <code>null</code>)
- * @param vmsuperclass
- * vm name of the superclass of the class (may be
- * <code>null</code>)
- * @param vminterfaces
- * vm names of interfaces of the class (may be <code>null</code>)
- * @return language specific notation of the class
- */
- public String getClassName(String vmname, String vmsignature,
- String vmsuperclass, String[] vminterfaces);
-
- /**
- * Calculates the language specific qualified name of a class.
- *
- * @param vmname
- * vm name of a class
- * @return language specific qualified notation of the class
- */
- public String getQualifiedClassName(String vmname);
-
- /**
- * Calculates the language specific name of a method.
- *
- * @param vmclassname
- * vm name of a containing class
- * @param vmmethodname
- * vm name of the method
- * @param vmdesc
- * vm parameter description of the method
- * @param vmsignature
- * vm signature of the method (may be <code>null</code>)
- * @return language specific notation for the method
- */
- public String getMethodName(String vmclassname, String vmmethodname,
- String vmdesc, String vmsignature);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +/** + * Interface to create programming language specific names from VM names. + */ +public interface ILanguageNames { + + /** + * Calculates the language specific name of a package. + * + * @param vmname + * vm name of a package + * @return language specific notation for the package + */ + public String getPackageName(String vmname); + + /** + * Calculates the language specific name of a class. + * + * @param vmname + * vm name of a class + * @param vmsignature + * vm signature of the class (may be <code>null</code>) + * @param vmsuperclass + * vm name of the superclass of the class (may be + * <code>null</code>) + * @param vminterfaces + * vm names of interfaces of the class (may be <code>null</code>) + * @return language specific notation of the class + */ + public String getClassName(String vmname, String vmsignature, + String vmsuperclass, String[] vminterfaces); + + /** + * Calculates the language specific qualified name of a class. + * + * @param vmname + * vm name of a class + * @return language specific qualified notation of the class + */ + public String getQualifiedClassName(String vmname); + + /** + * Calculates the language specific name of a method. + * + * @param vmclassname + * vm name of a containing class + * @param vmmethodname + * vm name of the method + * @param vmdesc + * vm parameter description of the method + * @param vmsignature + * vm signature of the method (may be <code>null</code>) + * @return language specific notation for the method + */ + public String getMethodName(String vmclassname, String vmmethodname, + String vmdesc, String vmsignature); + +} diff --git a/org.jacoco.report/src/org/jacoco/report/IMultiReportOutput.java b/org.jacoco.report/src/org/jacoco/report/IMultiReportOutput.java index 36f9cc91..5f64e537 100644 --- a/org.jacoco.report/src/org/jacoco/report/IMultiReportOutput.java +++ b/org.jacoco.report/src/org/jacoco/report/IMultiReportOutput.java @@ -1,42 +1,42 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Interface to emit multiple binary files.
- */
-public interface IMultiReportOutput {
-
- /**
- * Creates a file at the given local path. The returned {@link OutputStream}
- * has to be closed before the next document is created.
- *
- * @param path
- * local path to the new document
- * @return output for the content
- * @throws IOException
- * if the creation fails
- */
- public OutputStream createFile(String path) throws IOException;
-
- /**
- * Closes the underlying resource container.
- *
- * @throws IOException
- * if closing fails
- */
- public void close() throws IOException;
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Interface to emit multiple binary files. + */ +public interface IMultiReportOutput { + + /** + * Creates a file at the given local path. The returned {@link OutputStream} + * has to be closed before the next document is created. + * + * @param path + * local path to the new document + * @return output for the content + * @throws IOException + * if the creation fails + */ + public OutputStream createFile(String path) throws IOException; + + /** + * Closes the underlying resource container. + * + * @throws IOException + * if closing fails + */ + public void close() throws IOException; + +} diff --git a/org.jacoco.report/src/org/jacoco/report/IReportGroupVisitor.java b/org.jacoco.report/src/org/jacoco/report/IReportGroupVisitor.java index 9bfcfde5..4b322242 100644 --- a/org.jacoco.report/src/org/jacoco/report/IReportGroupVisitor.java +++ b/org.jacoco.report/src/org/jacoco/report/IReportGroupVisitor.java @@ -1,64 +1,64 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-
-/**
- * Output-Interface for hierarchical report structures. To allow sequential
- * processing and save memory the group structure has to be traversed in a
- * "deep first" fashion. The interface is implemented by the report formatters
- * and can be used to emit coverage report structures.
- *
- * The following constraints apply in using {@link IReportGroupVisitor} instances:
- *
- * <ul>
- * <li>A visitor instance can be used to either submit bundles (
- * {@link #visitBundle(IBundleCoverage, ISourceFileLocator)}) or groups
- * {@link #visitGroup(String)}). Bundles and groups are not allowed for the same
- * visitor.</li>
- * <li>When creating nested groups with {@link #visitGroup(String)} the
- * hierarchy has to be processed in a "deep first" manner.</li>
- * </ul>
- */
-public interface IReportGroupVisitor {
-
- /**
- * Called to add a bundle to the the report.
- *
- * @param bundle
- * a bundle to include in the report
- * @param locator
- * source locator for this bundle
- * @throws IOException
- * in case of IO problems with the report writer
- */
- void visitBundle(IBundleCoverage bundle, ISourceFileLocator locator)
- throws IOException;
-
- /**
- * Called to add a new group to the report. The returned
- * {@link IReportGroupVisitor} instance can be used to add nested bundles or
- * groups. The content of the group has to be completed before this or any
- * parent visitor can be used again ("deep first").
- *
- * @param name
- * name of the group
- * @return visitor for the group's content
- * @throws IOException
- * in case of IO problems with the report writer
- */
- IReportGroupVisitor visitGroup(String name) throws IOException;
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import java.io.IOException; + +import org.jacoco.core.analysis.IBundleCoverage; + +/** + * Output-Interface for hierarchical report structures. To allow sequential + * processing and save memory the group structure has to be traversed in a + * "deep first" fashion. The interface is implemented by the report formatters + * and can be used to emit coverage report structures. + * + * The following constraints apply in using {@link IReportGroupVisitor} instances: + * + * <ul> + * <li>A visitor instance can be used to either submit bundles ( + * {@link #visitBundle(IBundleCoverage, ISourceFileLocator)}) or groups + * {@link #visitGroup(String)}). Bundles and groups are not allowed for the same + * visitor.</li> + * <li>When creating nested groups with {@link #visitGroup(String)} the + * hierarchy has to be processed in a "deep first" manner.</li> + * </ul> + */ +public interface IReportGroupVisitor { + + /** + * Called to add a bundle to the the report. + * + * @param bundle + * a bundle to include in the report + * @param locator + * source locator for this bundle + * @throws IOException + * in case of IO problems with the report writer + */ + void visitBundle(IBundleCoverage bundle, ISourceFileLocator locator) + throws IOException; + + /** + * Called to add a new group to the report. The returned + * {@link IReportGroupVisitor} instance can be used to add nested bundles or + * groups. The content of the group has to be completed before this or any + * parent visitor can be used again ("deep first"). + * + * @param name + * name of the group + * @return visitor for the group's content + * @throws IOException + * in case of IO problems with the report writer + */ + IReportGroupVisitor visitGroup(String name) throws IOException; + +} diff --git a/org.jacoco.report/src/org/jacoco/report/IReportVisitor.java b/org.jacoco.report/src/org/jacoco/report/IReportVisitor.java index f288d591..5fe4bf0e 100644 --- a/org.jacoco.report/src/org/jacoco/report/IReportVisitor.java +++ b/org.jacoco.report/src/org/jacoco/report/IReportVisitor.java @@ -1,52 +1,52 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.SessionInfo;
-
-/**
- * Interface for all implementations to retrieve structured report data. Unlike
- * nested {@link IReportGroupVisitor} instances the root visitor accepts exactly one
- * bundle or group.
- */
-public interface IReportVisitor extends IReportGroupVisitor {
-
- /**
- * Initializes the report with global information. This method has to be
- * called before any other method can be called.
- *
- * @param sessionInfos
- * list of chronological ordered {@link SessionInfo} objects
- * where execution data has been collected for this report.
- * @param executionData
- * collection of all {@link ExecutionData} objects that are
- * considered for this report
- * @throws IOException
- * in case of IO problems with the report writer
- */
- public void visitInfo(List<SessionInfo> sessionInfos,
- Collection<ExecutionData> executionData) throws IOException;
-
- /**
- * Has to be called after all report data has been emitted.
- *
- * @throws IOException
- * in case of IO problems with the report writer
- */
- public void visitEnd() throws IOException;
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.SessionInfo; + +/** + * Interface for all implementations to retrieve structured report data. Unlike + * nested {@link IReportGroupVisitor} instances the root visitor accepts exactly one + * bundle or group. + */ +public interface IReportVisitor extends IReportGroupVisitor { + + /** + * Initializes the report with global information. This method has to be + * called before any other method can be called. + * + * @param sessionInfos + * list of chronological ordered {@link SessionInfo} objects + * where execution data has been collected for this report. + * @param executionData + * collection of all {@link ExecutionData} objects that are + * considered for this report + * @throws IOException + * in case of IO problems with the report writer + */ + public void visitInfo(List<SessionInfo> sessionInfos, + Collection<ExecutionData> executionData) throws IOException; + + /** + * Has to be called after all report data has been emitted. + * + * @throws IOException + * in case of IO problems with the report writer + */ + public void visitEnd() throws IOException; + +} diff --git a/org.jacoco.report/src/org/jacoco/report/ISourceFileLocator.java b/org.jacoco.report/src/org/jacoco/report/ISourceFileLocator.java index b9a77d01..2730784d 100644 --- a/org.jacoco.report/src/org/jacoco/report/ISourceFileLocator.java +++ b/org.jacoco.report/src/org/jacoco/report/ISourceFileLocator.java @@ -1,44 +1,44 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * Interface to look-up source files that will be included with the report.
- */
-public interface ISourceFileLocator {
-
- /**
- * Tries to locate the given source file and opens a reader with the
- * appropriate encoding.
- *
- * @param packageName
- * VM name of the package
- * @param fileName
- * name of the source file
- * @return reader if the file could be located, <code>null</code> otherwise
- * @throws IOException
- * in case of problems while opening the file
- */
- public Reader getSourceFile(String packageName, String fileName)
- throws IOException;
-
- /**
- * Returns number of blank characters that represent a tab in source code.
- *
- * @return tab width as number of blanks
- */
- public int getTabWidth();
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import java.io.IOException; +import java.io.Reader; + +/** + * Interface to look-up source files that will be included with the report. + */ +public interface ISourceFileLocator { + + /** + * Tries to locate the given source file and opens a reader with the + * appropriate encoding. + * + * @param packageName + * VM name of the package + * @param fileName + * name of the source file + * @return reader if the file could be located, <code>null</code> otherwise + * @throws IOException + * in case of problems while opening the file + */ + public Reader getSourceFile(String packageName, String fileName) + throws IOException; + + /** + * Returns number of blank characters that represent a tab in source code. + * + * @return tab width as number of blanks + */ + public int getTabWidth(); + +} diff --git a/org.jacoco.report/src/org/jacoco/report/InputStreamSourceFileLocator.java b/org.jacoco.report/src/org/jacoco/report/InputStreamSourceFileLocator.java index 8dea3611..f9e62f72 100644 --- a/org.jacoco.report/src/org/jacoco/report/InputStreamSourceFileLocator.java +++ b/org.jacoco.report/src/org/jacoco/report/InputStreamSourceFileLocator.java @@ -1,81 +1,81 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-
-/**
- * Abstract base class for {@link ISourceFileLocator} locator implementations
- * based on {@link InputStream}s. It handles the encoding and tab width.
- */
-public abstract class InputStreamSourceFileLocator implements
- ISourceFileLocator {
-
- private final String encoding;
- private final int tabWidth;
-
- /**
- * Creates a new locator with the given specification.
- *
- * @param encoding
- * encoding of the source files, <code>null</code> for platform
- * default encoding
- * @param tabWidth
- * tab width in source files as number of blanks
- *
- */
- protected InputStreamSourceFileLocator(final String encoding,
- final int tabWidth) {
- this.encoding = encoding;
- this.tabWidth = tabWidth;
- }
-
- public Reader getSourceFile(final String packageName, final String fileName)
- throws IOException {
- final InputStream in;
- if (packageName.length() > 0) {
- in = getSourceStream(packageName + "/" + fileName);
- } else {
- in = getSourceStream(fileName);
- }
-
- if (in == null) {
- return null;
- }
-
- if (encoding == null) {
- return new InputStreamReader(in);
- } else {
- return new InputStreamReader(in, encoding);
- }
- }
-
- public int getTabWidth() {
- return tabWidth;
- }
-
- /**
- * Tries to locate the given source file and opens its binary content.
- *
- * @param path
- * local path to the resource
- * @return stream if the file could be located, <code>null</code> otherwise
- * @throws IOException
- * in case of problems while opening the stream
- */
- protected abstract InputStream getSourceStream(String path)
- throws IOException;
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +/** + * Abstract base class for {@link ISourceFileLocator} locator implementations + * based on {@link InputStream}s. It handles the encoding and tab width. + */ +public abstract class InputStreamSourceFileLocator implements + ISourceFileLocator { + + private final String encoding; + private final int tabWidth; + + /** + * Creates a new locator with the given specification. + * + * @param encoding + * encoding of the source files, <code>null</code> for platform + * default encoding + * @param tabWidth + * tab width in source files as number of blanks + * + */ + protected InputStreamSourceFileLocator(final String encoding, + final int tabWidth) { + this.encoding = encoding; + this.tabWidth = tabWidth; + } + + public Reader getSourceFile(final String packageName, final String fileName) + throws IOException { + final InputStream in; + if (packageName.length() > 0) { + in = getSourceStream(packageName + "/" + fileName); + } else { + in = getSourceStream(fileName); + } + + if (in == null) { + return null; + } + + if (encoding == null) { + return new InputStreamReader(in); + } else { + return new InputStreamReader(in, encoding); + } + } + + public int getTabWidth() { + return tabWidth; + } + + /** + * Tries to locate the given source file and opens its binary content. + * + * @param path + * local path to the resource + * @return stream if the file could be located, <code>null</code> otherwise + * @throws IOException + * in case of problems while opening the stream + */ + protected abstract InputStream getSourceStream(String path) + throws IOException; + +} diff --git a/org.jacoco.report/src/org/jacoco/report/JavaNames.java b/org.jacoco.report/src/org/jacoco/report/JavaNames.java index 25d216d4..67001a43 100644 --- a/org.jacoco.report/src/org/jacoco/report/JavaNames.java +++ b/org.jacoco.report/src/org/jacoco/report/JavaNames.java @@ -1,115 +1,115 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import org.objectweb.asm.Type;
-
-/**
- * Names for the Java language.
- */
-public class JavaNames implements ILanguageNames {
-
- public String getPackageName(final String vmname) {
- if (vmname.length() == 0) {
- return "default";
- }
- return vmname.replace('/', '.');
- }
-
- private String getClassName(final String vmname) {
- final int pos = vmname.lastIndexOf('/');
- final String name = pos == -1 ? vmname : vmname.substring(pos + 1);
- return name.replace('$', '.');
- }
-
- private boolean isAnonymous(final String vmname) {
- final int dollarPosition = vmname.lastIndexOf('$');
- if (dollarPosition == -1) {
- return false;
- }
- final int internalPosition = dollarPosition + 1;
- if (internalPosition == vmname.length()) {
- // shouldn't happen for classes compiled from Java source
- return false;
- }
- // assume non-identifier start character for anonymous classes
- final char start = vmname.charAt(internalPosition);
- return !Character.isJavaIdentifierStart(start);
- }
-
- public String getClassName(final String vmname, final String vmsignature,
- final String vmsuperclass, final String[] vminterfaces) {
- if (isAnonymous(vmname)) {
- final String vmsupertype;
- if (vminterfaces != null && vminterfaces.length > 0) {
- vmsupertype = vminterfaces[0];
- } else if (vmsuperclass != null) {
- vmsupertype = vmsuperclass;
- } else {
- vmsupertype = null;
- }
- // append Eclipse style label, e.g. "Foo.new Bar() {...}"
- if (vmsupertype != null) {
- final StringBuilder builder = new StringBuilder();
- final String vmenclosing = vmname.substring(0,
- vmname.lastIndexOf('$'));
- builder.append(getClassName(vmenclosing)).append(".new ")
- .append(getClassName(vmsupertype)).append("() {...}");
- return builder.toString();
- }
- }
- return getClassName(vmname);
- }
-
- public String getQualifiedClassName(final String vmname) {
- return vmname.replace('/', '.').replace('$', '.');
- }
-
- public String getMethodName(final String vmclassname,
- final String vmmethodname, final String vmdesc,
- final String vmsignature) {
- if ("<clinit>".equals(vmmethodname)) {
- return "static {...}";
- }
- final StringBuilder result = new StringBuilder();
- if ("<init>".equals(vmmethodname)) {
- if (isAnonymous(vmclassname)) {
- return "{...}";
- } else {
- result.append(getClassName(vmclassname));
- }
- } else {
- result.append(vmmethodname);
- }
- result.append('(');
- final Type[] arguments = Type.getArgumentTypes(vmdesc);
- boolean comma = false;
- for (final Type arg : arguments) {
- if (comma) {
- result.append(", ");
- } else {
- comma = true;
- }
- result.append(getShortTypeName(arg));
- }
- result.append(')');
- return result.toString();
- }
-
- private String getShortTypeName(final Type type) {
- final String name = type.getClassName();
- final int pos = name.lastIndexOf('.');
- final String shortName = pos == -1 ? name : name.substring(pos + 1);
- return shortName.replace('$', '.');
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import org.objectweb.asm.Type; + +/** + * Names for the Java language. + */ +public class JavaNames implements ILanguageNames { + + public String getPackageName(final String vmname) { + if (vmname.length() == 0) { + return "default"; + } + return vmname.replace('/', '.'); + } + + private String getClassName(final String vmname) { + final int pos = vmname.lastIndexOf('/'); + final String name = pos == -1 ? vmname : vmname.substring(pos + 1); + return name.replace('$', '.'); + } + + private boolean isAnonymous(final String vmname) { + final int dollarPosition = vmname.lastIndexOf('$'); + if (dollarPosition == -1) { + return false; + } + final int internalPosition = dollarPosition + 1; + if (internalPosition == vmname.length()) { + // shouldn't happen for classes compiled from Java source + return false; + } + // assume non-identifier start character for anonymous classes + final char start = vmname.charAt(internalPosition); + return !Character.isJavaIdentifierStart(start); + } + + public String getClassName(final String vmname, final String vmsignature, + final String vmsuperclass, final String[] vminterfaces) { + if (isAnonymous(vmname)) { + final String vmsupertype; + if (vminterfaces != null && vminterfaces.length > 0) { + vmsupertype = vminterfaces[0]; + } else if (vmsuperclass != null) { + vmsupertype = vmsuperclass; + } else { + vmsupertype = null; + } + // append Eclipse style label, e.g. "Foo.new Bar() {...}" + if (vmsupertype != null) { + final StringBuilder builder = new StringBuilder(); + final String vmenclosing = vmname.substring(0, + vmname.lastIndexOf('$')); + builder.append(getClassName(vmenclosing)).append(".new ") + .append(getClassName(vmsupertype)).append("() {...}"); + return builder.toString(); + } + } + return getClassName(vmname); + } + + public String getQualifiedClassName(final String vmname) { + return vmname.replace('/', '.').replace('$', '.'); + } + + public String getMethodName(final String vmclassname, + final String vmmethodname, final String vmdesc, + final String vmsignature) { + if ("<clinit>".equals(vmmethodname)) { + return "static {...}"; + } + final StringBuilder result = new StringBuilder(); + if ("<init>".equals(vmmethodname)) { + if (isAnonymous(vmclassname)) { + return "{...}"; + } else { + result.append(getClassName(vmclassname)); + } + } else { + result.append(vmmethodname); + } + result.append('('); + final Type[] arguments = Type.getArgumentTypes(vmdesc); + boolean comma = false; + for (final Type arg : arguments) { + if (comma) { + result.append(", "); + } else { + comma = true; + } + result.append(getShortTypeName(arg)); + } + result.append(')'); + return result.toString(); + } + + private String getShortTypeName(final Type type) { + final String name = type.getClassName(); + final int pos = name.lastIndexOf('.'); + final String shortName = pos == -1 ? name : name.substring(pos + 1); + return shortName.replace('$', '.'); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/MultiReportVisitor.java b/org.jacoco.report/src/org/jacoco/report/MultiReportVisitor.java index 56431a9e..d8f4d0c6 100644 --- a/org.jacoco.report/src/org/jacoco/report/MultiReportVisitor.java +++ b/org.jacoco.report/src/org/jacoco/report/MultiReportVisitor.java @@ -1,81 +1,81 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.SessionInfo;
-
-/**
- * A report visitor that is composed from multiple other visitors. This can be
- * used to create more than one report format in one run.
- */
-public class MultiReportVisitor extends MultiGroupVisitor implements
- IReportVisitor {
-
- private final List<IReportVisitor> visitors;
-
- /**
- * New visitor delegating to all given visitors.
- *
- * @param visitors
- * visitors to delegate to
- */
- public MultiReportVisitor(final List<IReportVisitor> visitors) {
- super(visitors);
- this.visitors = visitors;
- }
-
- public void visitInfo(final List<SessionInfo> sessionInfos,
- final Collection<ExecutionData> executionData) throws IOException {
- for (final IReportVisitor v : visitors) {
- v.visitInfo(sessionInfos, executionData);
- }
- }
-
- public void visitEnd() throws IOException {
- for (final IReportVisitor v : visitors) {
- v.visitEnd();
- }
- }
-
-}
-
-class MultiGroupVisitor implements IReportGroupVisitor {
-
- private final List<? extends IReportGroupVisitor> visitors;
-
- MultiGroupVisitor(final List<? extends IReportGroupVisitor> visitors) {
- this.visitors = visitors;
- }
-
- public void visitBundle(final IBundleCoverage bundle,
- final ISourceFileLocator locator) throws IOException {
- for (final IReportGroupVisitor v : visitors) {
- v.visitBundle(bundle, locator);
- }
- }
-
- public IReportGroupVisitor visitGroup(final String name) throws IOException {
- final List<IReportGroupVisitor> children = new ArrayList<IReportGroupVisitor>();
- for (final IReportGroupVisitor v : visitors) {
- children.add(v.visitGroup(name));
- }
- return new MultiGroupVisitor(children);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.SessionInfo; + +/** + * A report visitor that is composed from multiple other visitors. This can be + * used to create more than one report format in one run. + */ +public class MultiReportVisitor extends MultiGroupVisitor implements + IReportVisitor { + + private final List<IReportVisitor> visitors; + + /** + * New visitor delegating to all given visitors. + * + * @param visitors + * visitors to delegate to + */ + public MultiReportVisitor(final List<IReportVisitor> visitors) { + super(visitors); + this.visitors = visitors; + } + + public void visitInfo(final List<SessionInfo> sessionInfos, + final Collection<ExecutionData> executionData) throws IOException { + for (final IReportVisitor v : visitors) { + v.visitInfo(sessionInfos, executionData); + } + } + + public void visitEnd() throws IOException { + for (final IReportVisitor v : visitors) { + v.visitEnd(); + } + } + +} + +class MultiGroupVisitor implements IReportGroupVisitor { + + private final List<? extends IReportGroupVisitor> visitors; + + MultiGroupVisitor(final List<? extends IReportGroupVisitor> visitors) { + this.visitors = visitors; + } + + public void visitBundle(final IBundleCoverage bundle, + final ISourceFileLocator locator) throws IOException { + for (final IReportGroupVisitor v : visitors) { + v.visitBundle(bundle, locator); + } + } + + public IReportGroupVisitor visitGroup(final String name) throws IOException { + final List<IReportGroupVisitor> children = new ArrayList<IReportGroupVisitor>(); + for (final IReportGroupVisitor v : visitors) { + children.add(v.visitGroup(name)); + } + return new MultiGroupVisitor(children); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/MultiSourceFileLocator.java b/org.jacoco.report/src/org/jacoco/report/MultiSourceFileLocator.java index cd70fd0d..30e16c36 100644 --- a/org.jacoco.report/src/org/jacoco/report/MultiSourceFileLocator.java +++ b/org.jacoco.report/src/org/jacoco/report/MultiSourceFileLocator.java @@ -1,68 +1,68 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Locator that searches source files in multiple {@link ISourceFileLocator}
- * instances. For each lookup request the first locator that returns a
- * {@link Reader} for source content is selected.
- */
-public class MultiSourceFileLocator implements ISourceFileLocator {
-
- private final int tabWidth;
-
- private final List<ISourceFileLocator> delegates;
-
- /**
- * Creates a new empty locator.
- *
- * @param tabWidth
- * tab width in source files as number of blanks used for all
- * source files
- */
- public MultiSourceFileLocator(final int tabWidth) {
- this.tabWidth = tabWidth;
- this.delegates = new ArrayList<ISourceFileLocator>();
- }
-
- /**
- * Adds the given locator. Locators are queried in the sequence they have
- * been added.
- *
- * @param locator
- * Additional locator to query
- */
- public void add(final ISourceFileLocator locator) {
- delegates.add(locator);
- }
-
- public Reader getSourceFile(final String packageName, final String fileName)
- throws IOException {
- for (final ISourceFileLocator d : delegates) {
- final Reader reader = d.getSourceFile(packageName, fileName);
- if (reader != null) {
- return reader;
- }
- }
- return null;
- }
-
- public int getTabWidth() {
- return tabWidth;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report; + +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; + +/** + * Locator that searches source files in multiple {@link ISourceFileLocator} + * instances. For each lookup request the first locator that returns a + * {@link Reader} for source content is selected. + */ +public class MultiSourceFileLocator implements ISourceFileLocator { + + private final int tabWidth; + + private final List<ISourceFileLocator> delegates; + + /** + * Creates a new empty locator. + * + * @param tabWidth + * tab width in source files as number of blanks used for all + * source files + */ + public MultiSourceFileLocator(final int tabWidth) { + this.tabWidth = tabWidth; + this.delegates = new ArrayList<ISourceFileLocator>(); + } + + /** + * Adds the given locator. Locators are queried in the sequence they have + * been added. + * + * @param locator + * Additional locator to query + */ + public void add(final ISourceFileLocator locator) { + delegates.add(locator); + } + + public Reader getSourceFile(final String packageName, final String fileName) + throws IOException { + for (final ISourceFileLocator d : delegates) { + final Reader reader = d.getSourceFile(packageName, fileName); + if (reader != null) { + return reader; + } + } + return null; + } + + public int getTabWidth() { + return tabWidth; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/csv/CSVFormatter.java b/org.jacoco.report/src/org/jacoco/report/csv/CSVFormatter.java index 01520ba0..75aa12b2 100644 --- a/org.jacoco.report/src/org/jacoco/report/csv/CSVFormatter.java +++ b/org.jacoco.report/src/org/jacoco/report/csv/CSVFormatter.java @@ -1,99 +1,99 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.report.csv;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.util.Collection;
-import java.util.List;
-
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.report.ILanguageNames;
-import org.jacoco.report.IReportVisitor;
-import org.jacoco.report.JavaNames;
-
-/**
- * Report formatter that will create a single CSV file. By default the filename
- * used will be the name of the session.
- */
-public class CSVFormatter {
-
- private ILanguageNames languageNames = new JavaNames();
-
- private String outputEncoding = "UTF-8";
-
- /**
- * Sets the implementation for language name display. Java language names
- * are defined by default.
- *
- * @param languageNames
- * converter for language specific names
- */
- public void setLanguageNames(final ILanguageNames languageNames) {
- this.languageNames = languageNames;
- }
-
- /**
- * Returns the language names call-back used in this report.
- *
- * @return language names
- */
- public ILanguageNames getLanguageNames() {
- return languageNames;
- }
-
- /**
- * Sets the encoding used for generated CSV document. Default is UTF-8.
- *
- * @param outputEncoding
- * CSV output encoding
- */
- public void setOutputEncoding(final String outputEncoding) {
- this.outputEncoding = outputEncoding;
- }
-
- /**
- * Creates a new visitor to write a report to the given stream.
- *
- * @param output
- * output stream to write the report to
- * @return visitor to emit the report data to
- * @throws IOException
- * in case of problems with the output stream
- */
- public IReportVisitor createVisitor(final OutputStream output)
- throws IOException {
- final DelimitedWriter writer = new DelimitedWriter(
- new OutputStreamWriter(output, outputEncoding));
- final ClassRowWriter rowWriter = new ClassRowWriter(writer,
- languageNames);
- class Visitor extends CSVGroupHandler implements IReportVisitor {
- Visitor() {
- super(rowWriter);
- }
-
- public void visitInfo(final List<SessionInfo> sessionInfos,
- final Collection<ExecutionData> executionData)
- throws IOException {
- // Info not used for CSV report
- }
-
- public void visitEnd() throws IOException {
- writer.close();
- }
- }
- return new Visitor();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.report.csv; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.Collection; +import java.util.List; + +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.report.ILanguageNames; +import org.jacoco.report.IReportVisitor; +import org.jacoco.report.JavaNames; + +/** + * Report formatter that will create a single CSV file. By default the filename + * used will be the name of the session. + */ +public class CSVFormatter { + + private ILanguageNames languageNames = new JavaNames(); + + private String outputEncoding = "UTF-8"; + + /** + * Sets the implementation for language name display. Java language names + * are defined by default. + * + * @param languageNames + * converter for language specific names + */ + public void setLanguageNames(final ILanguageNames languageNames) { + this.languageNames = languageNames; + } + + /** + * Returns the language names call-back used in this report. + * + * @return language names + */ + public ILanguageNames getLanguageNames() { + return languageNames; + } + + /** + * Sets the encoding used for generated CSV document. Default is UTF-8. + * + * @param outputEncoding + * CSV output encoding + */ + public void setOutputEncoding(final String outputEncoding) { + this.outputEncoding = outputEncoding; + } + + /** + * Creates a new visitor to write a report to the given stream. + * + * @param output + * output stream to write the report to + * @return visitor to emit the report data to + * @throws IOException + * in case of problems with the output stream + */ + public IReportVisitor createVisitor(final OutputStream output) + throws IOException { + final DelimitedWriter writer = new DelimitedWriter( + new OutputStreamWriter(output, outputEncoding)); + final ClassRowWriter rowWriter = new ClassRowWriter(writer, + languageNames); + class Visitor extends CSVGroupHandler implements IReportVisitor { + Visitor() { + super(rowWriter); + } + + public void visitInfo(final List<SessionInfo> sessionInfos, + final Collection<ExecutionData> executionData) + throws IOException { + // Info not used for CSV report + } + + public void visitEnd() throws IOException { + writer.close(); + } + } + return new Visitor(); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/csv/CSVGroupHandler.java b/org.jacoco.report/src/org/jacoco/report/csv/CSVGroupHandler.java index 97e8ceb2..cdd22a0d 100644 --- a/org.jacoco.report/src/org/jacoco/report/csv/CSVGroupHandler.java +++ b/org.jacoco.report/src/org/jacoco/report/csv/CSVGroupHandler.java @@ -1,59 +1,59 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.report.csv;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.IPackageCoverage;
-import org.jacoco.report.IReportGroupVisitor;
-import org.jacoco.report.ISourceFileLocator;
-
-/**
- * Report visitor that handles coverage information for groups.
- */
-class CSVGroupHandler implements IReportGroupVisitor {
-
- private final ClassRowWriter writer;
-
- private final String groupName;
-
- public CSVGroupHandler(final ClassRowWriter writer) {
- this(writer, null);
- }
-
- private CSVGroupHandler(final ClassRowWriter writer, final String groupName) {
- this.writer = writer;
- this.groupName = groupName;
- }
-
- public void visitBundle(final IBundleCoverage bundle,
- final ISourceFileLocator locator) throws IOException {
- final String name = appendName(bundle.getName());
- for (final IPackageCoverage p : bundle.getPackages()) {
- final String packageName = p.getName();
- for (final IClassCoverage c : p.getClasses()) {
- writer.writeRow(name, packageName, c);
- }
- }
- }
-
- public IReportGroupVisitor visitGroup(final String name) throws IOException {
- return new CSVGroupHandler(writer, appendName(name));
- }
-
- private String appendName(final String name) {
- return groupName == null ? name : (groupName + "/" + name);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.report.csv; + +import java.io.IOException; + +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.IPackageCoverage; +import org.jacoco.report.IReportGroupVisitor; +import org.jacoco.report.ISourceFileLocator; + +/** + * Report visitor that handles coverage information for groups. + */ +class CSVGroupHandler implements IReportGroupVisitor { + + private final ClassRowWriter writer; + + private final String groupName; + + public CSVGroupHandler(final ClassRowWriter writer) { + this(writer, null); + } + + private CSVGroupHandler(final ClassRowWriter writer, final String groupName) { + this.writer = writer; + this.groupName = groupName; + } + + public void visitBundle(final IBundleCoverage bundle, + final ISourceFileLocator locator) throws IOException { + final String name = appendName(bundle.getName()); + for (final IPackageCoverage p : bundle.getPackages()) { + final String packageName = p.getName(); + for (final IClassCoverage c : p.getClasses()) { + writer.writeRow(name, packageName, c); + } + } + } + + public IReportGroupVisitor visitGroup(final String name) throws IOException { + return new CSVGroupHandler(writer, appendName(name)); + } + + private String appendName(final String name) { + return groupName == null ? name : (groupName + "/" + name); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/csv/ClassRowWriter.java b/org.jacoco.report/src/org/jacoco/report/csv/ClassRowWriter.java index abaf95f4..fc9fc1b0 100644 --- a/org.jacoco.report/src/org/jacoco/report/csv/ClassRowWriter.java +++ b/org.jacoco.report/src/org/jacoco/report/csv/ClassRowWriter.java @@ -1,92 +1,92 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.report.csv;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.report.ILanguageNames;
-
-/**
- * Writer for rows in the CVS report representing the summary data of a single
- * class.
- */
-class ClassRowWriter {
-
- private static final CounterEntity[] COUNTERS = { CounterEntity.INSTRUCTION,
- CounterEntity.BRANCH, CounterEntity.LINE,
- CounterEntity.COMPLEXITY, CounterEntity.METHOD };
-
- private final DelimitedWriter writer;
-
- private final ILanguageNames languageNames;
-
- /**
- * Creates a new row writer that writes class information to the given CSV
- * writer.
- *
- * @param writer
- * writer for csv output
- * @param languageNames
- * converter for Java identifiers
- * @throws IOException
- * in case of problems with the writer
- */
- public ClassRowWriter(final DelimitedWriter writer,
- final ILanguageNames languageNames) throws IOException {
- this.writer = writer;
- this.languageNames = languageNames;
- writeHeader();
- }
-
- private void writeHeader() throws IOException {
- writer.write("GROUP", "PACKAGE", "CLASS");
- for (final CounterEntity entity : COUNTERS) {
- writer.write(entity.name() + "_MISSED");
- writer.write(entity.name() + "_COVERED");
- }
- writer.nextLine();
- }
-
- /**
- * Writes the class summary information as a row.
- *
- * @param groupName
- * name of the group
- * @param packageName
- * vm name of the package
- * @param node
- * class coverage data
- * @throws IOException
- * in case of problems with the writer
- */
- public void writeRow(final String groupName, final String packageName,
- final IClassCoverage node) throws IOException {
- writer.write(groupName);
- writer.write(languageNames.getPackageName(packageName));
- final String className = languageNames.getClassName(node.getName(),
- node.getSignature(), node.getSuperName(),
- node.getInterfaceNames());
- writer.write(className);
-
- for (final CounterEntity entity : COUNTERS) {
- final ICounter counter = node.getCounter(entity);
- writer.write(counter.getMissedCount());
- writer.write(counter.getCoveredCount());
- }
-
- writer.nextLine();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.report.csv; + +import java.io.IOException; + +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.report.ILanguageNames; + +/** + * Writer for rows in the CVS report representing the summary data of a single + * class. + */ +class ClassRowWriter { + + private static final CounterEntity[] COUNTERS = { CounterEntity.INSTRUCTION, + CounterEntity.BRANCH, CounterEntity.LINE, + CounterEntity.COMPLEXITY, CounterEntity.METHOD }; + + private final DelimitedWriter writer; + + private final ILanguageNames languageNames; + + /** + * Creates a new row writer that writes class information to the given CSV + * writer. + * + * @param writer + * writer for csv output + * @param languageNames + * converter for Java identifiers + * @throws IOException + * in case of problems with the writer + */ + public ClassRowWriter(final DelimitedWriter writer, + final ILanguageNames languageNames) throws IOException { + this.writer = writer; + this.languageNames = languageNames; + writeHeader(); + } + + private void writeHeader() throws IOException { + writer.write("GROUP", "PACKAGE", "CLASS"); + for (final CounterEntity entity : COUNTERS) { + writer.write(entity.name() + "_MISSED"); + writer.write(entity.name() + "_COVERED"); + } + writer.nextLine(); + } + + /** + * Writes the class summary information as a row. + * + * @param groupName + * name of the group + * @param packageName + * vm name of the package + * @param node + * class coverage data + * @throws IOException + * in case of problems with the writer + */ + public void writeRow(final String groupName, final String packageName, + final IClassCoverage node) throws IOException { + writer.write(groupName); + writer.write(languageNames.getPackageName(packageName)); + final String className = languageNames.getClassName(node.getName(), + node.getSignature(), node.getSuperName(), + node.getInterfaceNames()); + writer.write(className); + + for (final CounterEntity entity : COUNTERS) { + final ICounter counter = node.getCounter(entity); + writer.write(counter.getMissedCount()); + writer.write(counter.getCoveredCount()); + } + + writer.nextLine(); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/csv/DelimitedWriter.java b/org.jacoco.report/src/org/jacoco/report/csv/DelimitedWriter.java index 1b095390..086d5223 100644 --- a/org.jacoco.report/src/org/jacoco/report/csv/DelimitedWriter.java +++ b/org.jacoco.report/src/org/jacoco/report/csv/DelimitedWriter.java @@ -1,170 +1,170 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.report.csv;
-
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * Helper class for writing out CSV or tab delimited files.
- * <p>
- * <strong>Example Usage:</strong>
- *
- * <pre>
- * delimitedWriter.writeFields("header1", "header2", ...);
- * for each line to be written {
- * delimitedWriter.writeField(value1);
- * delimitedWriter.writeField(value2);
- * delimitedWriter.nextLine();
- * }
- * delimitedWriter.close();
- * </pre>
- *
- * </p>
- */
-class DelimitedWriter {
- private static final String QUOTE = "\"";
- private static final String ESCAPED_QUOTE = "\"\"";
-
- private static final char DEFAULT_DELIMITER = ',';
- private static final String NEW_LINE = System.getProperty("line.separator");
- private final char delimiter;
- private final Writer delegate;
- private int fieldPosition = 0;
-
- /**
- * Creates a new Delimited writer using the default delimiter
- *
- * @param delegate
- * Writer to delegate all writes to
- */
- public DelimitedWriter(final Writer delegate) {
- this(delegate, DEFAULT_DELIMITER);
- }
-
- /**
- * Creates a new Delimited writer using the default delimiter
- *
- * @param delegate
- * Writer to delegate all writes to
- * @param delimiter
- * delimiter to use (usually a comma, tab or space)
- */
- public DelimitedWriter(final Writer delegate, final char delimiter) {
- this.delegate = delegate;
- this.delimiter = delimiter;
- }
-
- /**
- * Write multiple fields at once. Values will be auto escaped and quoted as
- * needed. Each value will be separated using the current delimiter
- *
- * @param fields
- * Values to write
- * @throws IOException
- * Error writing to the underlying writer object
- */
- public void write(final String... fields) throws IOException {
- for (final String field : fields) {
- write(field);
- }
- }
-
- /**
- * Write a single value. Values will be auto escaped and quoted as needed.
- * If this is not the first field of the current line the value will be
- * prepended with the current delimiter
- *
- * @param field
- * Value to write
- * @throws IOException
- * Error writing to the underlying writer object
- */
- public void write(final String field) throws IOException {
- if (fieldPosition != 0) {
- delegate.write(delimiter);
- }
- delegate.write(escape(field));
- fieldPosition++;
- }
-
- /**
- * Write a single integer value.
- *
- * @param value
- * Value to write
- * @throws IOException
- * Error writing to the underlying writer object
- */
- public void write(final int value) throws IOException {
- write(Integer.toString(value));
- }
-
- /**
- * Write muliple integer values
- *
- * @param values
- * values to write
- * @throws IOException
- * Error writing to the underlying writer object
- */
- public void write(final int... values) throws IOException {
- for (final int value : values) {
- write(Integer.toString(value));
- }
- }
-
- /**
- * Output a new line and advance the writer to the next line. The line
- * delimiter is the default for the platform.
- *
- * @throws IOException
- * Error writing to the underlying writer object
- */
- public void nextLine() throws IOException {
- delegate.write(NEW_LINE);
- fieldPosition = 0;
- }
-
- /**
- * Close the underlying writer object. Once closed all write operations will
- * fail
- *
- * @throws IOException
- * Error closing the underlying writer object
- */
- public void close() throws IOException {
- delegate.close();
- }
-
- /**
- * Escapes any occurrences of the quote character in value by replacing it
- * with a double quote. Also Quotes the value if a quote or delimiter value
- * is found.
- *
- * @param value
- * String that needs escaping
- * @return New string with all values escaped
- */
- private String escape(final String value) {
- String escapedValue = value;
-
- // Escape and quote if the source value contains the delimiter
- // or the quote character
- if (value.indexOf(QUOTE) != -1 || value.indexOf(delimiter) != -1) {
- escapedValue = value.replace(QUOTE, ESCAPED_QUOTE);
- escapedValue = QUOTE + escapedValue + QUOTE;
- }
-
- return escapedValue;
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.report.csv; + +import java.io.IOException; +import java.io.Writer; + +/** + * Helper class for writing out CSV or tab delimited files. + * <p> + * <strong>Example Usage:</strong> + * + * <pre> + * delimitedWriter.writeFields("header1", "header2", ...); + * for each line to be written { + * delimitedWriter.writeField(value1); + * delimitedWriter.writeField(value2); + * delimitedWriter.nextLine(); + * } + * delimitedWriter.close(); + * </pre> + * + * </p> + */ +class DelimitedWriter { + private static final String QUOTE = "\""; + private static final String ESCAPED_QUOTE = "\"\""; + + private static final char DEFAULT_DELIMITER = ','; + private static final String NEW_LINE = System.getProperty("line.separator"); + private final char delimiter; + private final Writer delegate; + private int fieldPosition = 0; + + /** + * Creates a new Delimited writer using the default delimiter + * + * @param delegate + * Writer to delegate all writes to + */ + public DelimitedWriter(final Writer delegate) { + this(delegate, DEFAULT_DELIMITER); + } + + /** + * Creates a new Delimited writer using the default delimiter + * + * @param delegate + * Writer to delegate all writes to + * @param delimiter + * delimiter to use (usually a comma, tab or space) + */ + public DelimitedWriter(final Writer delegate, final char delimiter) { + this.delegate = delegate; + this.delimiter = delimiter; + } + + /** + * Write multiple fields at once. Values will be auto escaped and quoted as + * needed. Each value will be separated using the current delimiter + * + * @param fields + * Values to write + * @throws IOException + * Error writing to the underlying writer object + */ + public void write(final String... fields) throws IOException { + for (final String field : fields) { + write(field); + } + } + + /** + * Write a single value. Values will be auto escaped and quoted as needed. + * If this is not the first field of the current line the value will be + * prepended with the current delimiter + * + * @param field + * Value to write + * @throws IOException + * Error writing to the underlying writer object + */ + public void write(final String field) throws IOException { + if (fieldPosition != 0) { + delegate.write(delimiter); + } + delegate.write(escape(field)); + fieldPosition++; + } + + /** + * Write a single integer value. + * + * @param value + * Value to write + * @throws IOException + * Error writing to the underlying writer object + */ + public void write(final int value) throws IOException { + write(Integer.toString(value)); + } + + /** + * Write muliple integer values + * + * @param values + * values to write + * @throws IOException + * Error writing to the underlying writer object + */ + public void write(final int... values) throws IOException { + for (final int value : values) { + write(Integer.toString(value)); + } + } + + /** + * Output a new line and advance the writer to the next line. The line + * delimiter is the default for the platform. + * + * @throws IOException + * Error writing to the underlying writer object + */ + public void nextLine() throws IOException { + delegate.write(NEW_LINE); + fieldPosition = 0; + } + + /** + * Close the underlying writer object. Once closed all write operations will + * fail + * + * @throws IOException + * Error closing the underlying writer object + */ + public void close() throws IOException { + delegate.close(); + } + + /** + * Escapes any occurrences of the quote character in value by replacing it + * with a double quote. Also Quotes the value if a quote or delimiter value + * is found. + * + * @param value + * String that needs escaping + * @return New string with all values escaped + */ + private String escape(final String value) { + String escapedValue = value; + + // Escape and quote if the source value contains the delimiter + // or the quote character + if (value.indexOf(QUOTE) != -1 || value.indexOf(delimiter) != -1) { + escapedValue = value.replace(QUOTE, ESCAPED_QUOTE); + escapedValue = QUOTE + escapedValue + QUOTE; + } + + return escapedValue; + } +} diff --git a/org.jacoco.report/src/org/jacoco/report/html/HTMLFormatter.java b/org.jacoco.report/src/org/jacoco/report/html/HTMLFormatter.java index 25fa42ed..30c12338 100644 --- a/org.jacoco.report/src/org/jacoco/report/html/HTMLFormatter.java +++ b/org.jacoco.report/src/org/jacoco/report/html/HTMLFormatter.java @@ -1,238 +1,238 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.html;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-import java.util.Locale;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.report.ILanguageNames;
-import org.jacoco.report.IMultiReportOutput;
-import org.jacoco.report.IReportGroupVisitor;
-import org.jacoco.report.IReportVisitor;
-import org.jacoco.report.ISourceFileLocator;
-import org.jacoco.report.JavaNames;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLGroupVisitor;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-import org.jacoco.report.internal.html.ILinkable;
-import org.jacoco.report.internal.html.index.ElementIndex;
-import org.jacoco.report.internal.html.index.IIndexUpdate;
-import org.jacoco.report.internal.html.page.BundlePage;
-import org.jacoco.report.internal.html.page.ReportPage;
-import org.jacoco.report.internal.html.page.SessionsPage;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.jacoco.report.internal.html.resources.Styles;
-import org.jacoco.report.internal.html.table.BarColumn;
-import org.jacoco.report.internal.html.table.CounterColumn;
-import org.jacoco.report.internal.html.table.LabelColumn;
-import org.jacoco.report.internal.html.table.PercentageColumn;
-import org.jacoco.report.internal.html.table.Table;
-
-/**
- * Formatter for coverage reports in multiple HTML pages.
- */
-public class HTMLFormatter implements IHTMLReportContext {
-
- private ILanguageNames languageNames = new JavaNames();
-
- private Locale locale = Locale.getDefault();
-
- private String footerText = "";
-
- private String outputEncoding = "UTF-8";
-
- private Resources resources;
-
- private ElementIndex index;
-
- private SessionsPage sessionsPage;
-
- private Table table;
-
- /**
- * New instance with default settings.
- */
- public HTMLFormatter() {
- }
-
- /**
- * Sets the implementation for language name display. Java language names
- * are defined by default.
- *
- * @param languageNames
- * converter for language specific names
- */
- public void setLanguageNames(final ILanguageNames languageNames) {
- this.languageNames = languageNames;
- }
-
- /**
- * Sets the locale used for report rendering. The current default locale is
- * used by default.
- *
- * @param locale
- * locale used for report rendering
- */
- public void setLocale(final Locale locale) {
- this.locale = locale;
- }
-
- /**
- * Sets the optional text that should be included in every footer page.
- *
- * @param footerText
- * footer text
- */
- public void setFooterText(final String footerText) {
- this.footerText = footerText;
- }
-
- /**
- * Sets the encoding used for generated HTML pages. Default is UTF-8.
- *
- * @param outputEncoding
- * HTML output encoding
- */
- public void setOutputEncoding(final String outputEncoding) {
- this.outputEncoding = outputEncoding;
- }
-
- // === IHTMLReportContext ===
-
- public ILanguageNames getLanguageNames() {
- return languageNames;
- }
-
- public Resources getResources() {
- return resources;
- }
-
- public Table getTable() {
- if (table == null) {
- table = createTable();
- }
- return table;
- }
-
- private Table createTable() {
- final Table t = new Table();
- t.add("Element", null, new LabelColumn(), false);
- t.add("Missed Instructions", Styles.BAR, new BarColumn(CounterEntity.INSTRUCTION,
- locale), true);
- t.add("Cov.", Styles.CTR2,
- new PercentageColumn(CounterEntity.INSTRUCTION, locale), false);
- t.add("Missed Branches", Styles.BAR, new BarColumn(CounterEntity.BRANCH, locale),
- false);
- t.add("Cov.", Styles.CTR2, new PercentageColumn(CounterEntity.BRANCH, locale),
- false);
- addMissedTotalColumns(t, "Cxty", CounterEntity.COMPLEXITY);
- addMissedTotalColumns(t, "Lines", CounterEntity.LINE);
- addMissedTotalColumns(t, "Methods", CounterEntity.METHOD);
- addMissedTotalColumns(t, "Classes", CounterEntity.CLASS);
- return t;
- }
-
- private void addMissedTotalColumns(final Table table, final String label,
- final CounterEntity entity) {
- table.add("Missed", Styles.CTR1,
- CounterColumn.newMissed(entity, locale), false);
- table.add(label, Styles.CTR2, CounterColumn.newTotal(entity, locale),
- false);
- }
-
- public String getFooterText() {
- return footerText;
- }
-
- public ILinkable getSessionsPage() {
- return sessionsPage;
- }
-
- public String getOutputEncoding() {
- return outputEncoding;
- }
-
- public IIndexUpdate getIndexUpdate() {
- return index;
- }
-
- public Locale getLocale() {
- return locale;
- }
-
- /**
- * Creates a new visitor to write a report to the given output.
- *
- * @param output
- * output to write the report to
- * @return visitor to emit the report data to
- * @throws IOException
- * in case of problems with the output stream
- */
- public IReportVisitor createVisitor(final IMultiReportOutput output)
- throws IOException {
- final ReportOutputFolder root = new ReportOutputFolder(output);
- resources = new Resources(root);
- resources.copyResources();
- index = new ElementIndex(root);
- return new IReportVisitor() {
-
- private List<SessionInfo> sessionInfos;
- private Collection<ExecutionData> executionData;
-
- private HTMLGroupVisitor groupHandler;
-
- public void visitInfo(final List<SessionInfo> sessionInfos,
- final Collection<ExecutionData> executionData)
- throws IOException {
- this.sessionInfos = sessionInfos;
- this.executionData = executionData;
- }
-
- public void visitBundle(final IBundleCoverage bundle,
- final ISourceFileLocator locator) throws IOException {
- final BundlePage page = new BundlePage(bundle, null, locator,
- root, HTMLFormatter.this);
- createSessionsPage(page);
- page.render();
- }
-
- public IReportGroupVisitor visitGroup(final String name)
- throws IOException {
- groupHandler = new HTMLGroupVisitor(null, root,
- HTMLFormatter.this, name);
- createSessionsPage(groupHandler.getPage());
- return groupHandler;
-
- }
-
- private void createSessionsPage(final ReportPage rootpage) {
- sessionsPage = new SessionsPage(sessionInfos, executionData,
- index, rootpage, root, HTMLFormatter.this);
- }
-
- public void visitEnd() throws IOException {
- if (groupHandler != null) {
- groupHandler.visitEnd();
- }
- sessionsPage.render();
- output.close();
- }
- };
- }
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.html; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.report.ILanguageNames; +import org.jacoco.report.IMultiReportOutput; +import org.jacoco.report.IReportGroupVisitor; +import org.jacoco.report.IReportVisitor; +import org.jacoco.report.ISourceFileLocator; +import org.jacoco.report.JavaNames; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLGroupVisitor; +import org.jacoco.report.internal.html.IHTMLReportContext; +import org.jacoco.report.internal.html.ILinkable; +import org.jacoco.report.internal.html.index.ElementIndex; +import org.jacoco.report.internal.html.index.IIndexUpdate; +import org.jacoco.report.internal.html.page.BundlePage; +import org.jacoco.report.internal.html.page.ReportPage; +import org.jacoco.report.internal.html.page.SessionsPage; +import org.jacoco.report.internal.html.resources.Resources; +import org.jacoco.report.internal.html.resources.Styles; +import org.jacoco.report.internal.html.table.BarColumn; +import org.jacoco.report.internal.html.table.CounterColumn; +import org.jacoco.report.internal.html.table.LabelColumn; +import org.jacoco.report.internal.html.table.PercentageColumn; +import org.jacoco.report.internal.html.table.Table; + +/** + * Formatter for coverage reports in multiple HTML pages. + */ +public class HTMLFormatter implements IHTMLReportContext { + + private ILanguageNames languageNames = new JavaNames(); + + private Locale locale = Locale.getDefault(); + + private String footerText = ""; + + private String outputEncoding = "UTF-8"; + + private Resources resources; + + private ElementIndex index; + + private SessionsPage sessionsPage; + + private Table table; + + /** + * New instance with default settings. + */ + public HTMLFormatter() { + } + + /** + * Sets the implementation for language name display. Java language names + * are defined by default. + * + * @param languageNames + * converter for language specific names + */ + public void setLanguageNames(final ILanguageNames languageNames) { + this.languageNames = languageNames; + } + + /** + * Sets the locale used for report rendering. The current default locale is + * used by default. + * + * @param locale + * locale used for report rendering + */ + public void setLocale(final Locale locale) { + this.locale = locale; + } + + /** + * Sets the optional text that should be included in every footer page. + * + * @param footerText + * footer text + */ + public void setFooterText(final String footerText) { + this.footerText = footerText; + } + + /** + * Sets the encoding used for generated HTML pages. Default is UTF-8. + * + * @param outputEncoding + * HTML output encoding + */ + public void setOutputEncoding(final String outputEncoding) { + this.outputEncoding = outputEncoding; + } + + // === IHTMLReportContext === + + public ILanguageNames getLanguageNames() { + return languageNames; + } + + public Resources getResources() { + return resources; + } + + public Table getTable() { + if (table == null) { + table = createTable(); + } + return table; + } + + private Table createTable() { + final Table t = new Table(); + t.add("Element", null, new LabelColumn(), false); + t.add("Missed Instructions", Styles.BAR, new BarColumn(CounterEntity.INSTRUCTION, + locale), true); + t.add("Cov.", Styles.CTR2, + new PercentageColumn(CounterEntity.INSTRUCTION, locale), false); + t.add("Missed Branches", Styles.BAR, new BarColumn(CounterEntity.BRANCH, locale), + false); + t.add("Cov.", Styles.CTR2, new PercentageColumn(CounterEntity.BRANCH, locale), + false); + addMissedTotalColumns(t, "Cxty", CounterEntity.COMPLEXITY); + addMissedTotalColumns(t, "Lines", CounterEntity.LINE); + addMissedTotalColumns(t, "Methods", CounterEntity.METHOD); + addMissedTotalColumns(t, "Classes", CounterEntity.CLASS); + return t; + } + + private void addMissedTotalColumns(final Table table, final String label, + final CounterEntity entity) { + table.add("Missed", Styles.CTR1, + CounterColumn.newMissed(entity, locale), false); + table.add(label, Styles.CTR2, CounterColumn.newTotal(entity, locale), + false); + } + + public String getFooterText() { + return footerText; + } + + public ILinkable getSessionsPage() { + return sessionsPage; + } + + public String getOutputEncoding() { + return outputEncoding; + } + + public IIndexUpdate getIndexUpdate() { + return index; + } + + public Locale getLocale() { + return locale; + } + + /** + * Creates a new visitor to write a report to the given output. + * + * @param output + * output to write the report to + * @return visitor to emit the report data to + * @throws IOException + * in case of problems with the output stream + */ + public IReportVisitor createVisitor(final IMultiReportOutput output) + throws IOException { + final ReportOutputFolder root = new ReportOutputFolder(output); + resources = new Resources(root); + resources.copyResources(); + index = new ElementIndex(root); + return new IReportVisitor() { + + private List<SessionInfo> sessionInfos; + private Collection<ExecutionData> executionData; + + private HTMLGroupVisitor groupHandler; + + public void visitInfo(final List<SessionInfo> sessionInfos, + final Collection<ExecutionData> executionData) + throws IOException { + this.sessionInfos = sessionInfos; + this.executionData = executionData; + } + + public void visitBundle(final IBundleCoverage bundle, + final ISourceFileLocator locator) throws IOException { + final BundlePage page = new BundlePage(bundle, null, locator, + root, HTMLFormatter.this); + createSessionsPage(page); + page.render(); + } + + public IReportGroupVisitor visitGroup(final String name) + throws IOException { + groupHandler = new HTMLGroupVisitor(null, root, + HTMLFormatter.this, name); + createSessionsPage(groupHandler.getPage()); + return groupHandler; + + } + + private void createSessionsPage(final ReportPage rootpage) { + sessionsPage = new SessionsPage(sessionInfos, executionData, + index, rootpage, root, HTMLFormatter.this); + } + + public void visitEnd() throws IOException { + if (groupHandler != null) { + groupHandler.visitEnd(); + } + sessionsPage.render(); + output.close(); + } + }; + } +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/AbstractGroupVisitor.java b/org.jacoco.report/src/org/jacoco/report/internal/AbstractGroupVisitor.java index 8b5721c4..2a1a0a32 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/AbstractGroupVisitor.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/AbstractGroupVisitor.java @@ -1,102 +1,102 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.CoverageNodeImpl;
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.report.IReportGroupVisitor;
-import org.jacoco.report.ISourceFileLocator;
-
-/**
- * Internal base visitor to calculate group counter summaries for hierarchical
- * reports.
- */
-public abstract class AbstractGroupVisitor implements IReportGroupVisitor {
-
- /** coverage node for this group to total counters */
- protected final CoverageNodeImpl total;
-
- private AbstractGroupVisitor lastChild;
-
- /**
- * Creates a new group with the given name.
- *
- * @param name
- * name for the coverage node created internally
- */
- protected AbstractGroupVisitor(final String name) {
- total = new CoverageNodeImpl(ElementType.GROUP, name);
- }
-
- public final void visitBundle(final IBundleCoverage bundle,
- final ISourceFileLocator locator) throws IOException {
- finalizeLastChild();
- total.increment(bundle);
- handleBundle(bundle, locator);
- }
-
- /**
- * Called to handle the given bundle in a specific way.
- *
- * @param bundle
- * @param locator
- * @throws IOException
- */
- protected abstract void handleBundle(IBundleCoverage bundle,
- ISourceFileLocator locator) throws IOException;
-
- public final IReportGroupVisitor visitGroup(final String name)
- throws IOException {
- finalizeLastChild();
- lastChild = handleGroup(name);
- return lastChild;
- }
-
- /**
- * Called to handle a group with the given name in a specific way.
- *
- * @param name
- * @return created child group
- * @throws IOException
- */
- protected abstract AbstractGroupVisitor handleGroup(final String name)
- throws IOException;
-
- /**
- * Must be called at the end of every group.
- *
- * @throws IOException
- */
- public final void visitEnd() throws IOException {
- finalizeLastChild();
- handleEnd();
- }
-
- /**
- * Called to handle the end of this group in a specific way.
- *
- * @throws IOException
- */
- protected abstract void handleEnd() throws IOException;
-
- private void finalizeLastChild() throws IOException {
- if (lastChild != null) {
- lastChild.visitEnd();
- total.increment(lastChild.total);
- lastChild = null;
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal; + +import java.io.IOException; + +import org.jacoco.core.analysis.CoverageNodeImpl; +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.report.IReportGroupVisitor; +import org.jacoco.report.ISourceFileLocator; + +/** + * Internal base visitor to calculate group counter summaries for hierarchical + * reports. + */ +public abstract class AbstractGroupVisitor implements IReportGroupVisitor { + + /** coverage node for this group to total counters */ + protected final CoverageNodeImpl total; + + private AbstractGroupVisitor lastChild; + + /** + * Creates a new group with the given name. + * + * @param name + * name for the coverage node created internally + */ + protected AbstractGroupVisitor(final String name) { + total = new CoverageNodeImpl(ElementType.GROUP, name); + } + + public final void visitBundle(final IBundleCoverage bundle, + final ISourceFileLocator locator) throws IOException { + finalizeLastChild(); + total.increment(bundle); + handleBundle(bundle, locator); + } + + /** + * Called to handle the given bundle in a specific way. + * + * @param bundle + * @param locator + * @throws IOException + */ + protected abstract void handleBundle(IBundleCoverage bundle, + ISourceFileLocator locator) throws IOException; + + public final IReportGroupVisitor visitGroup(final String name) + throws IOException { + finalizeLastChild(); + lastChild = handleGroup(name); + return lastChild; + } + + /** + * Called to handle a group with the given name in a specific way. + * + * @param name + * @return created child group + * @throws IOException + */ + protected abstract AbstractGroupVisitor handleGroup(final String name) + throws IOException; + + /** + * Must be called at the end of every group. + * + * @throws IOException + */ + public final void visitEnd() throws IOException { + finalizeLastChild(); + handleEnd(); + } + + /** + * Called to handle the end of this group in a specific way. + * + * @throws IOException + */ + protected abstract void handleEnd() throws IOException; + + private void finalizeLastChild() throws IOException { + if (lastChild != null) { + lastChild.visitEnd(); + total.increment(lastChild.total); + lastChild = null; + } + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/NormalizedFileNames.java b/org.jacoco.report/src/org/jacoco/report/internal/NormalizedFileNames.java index 4afe9ecc..ab04b1c8 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/NormalizedFileNames.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/NormalizedFileNames.java @@ -1,90 +1,90 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal;
-
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Internal utility to create normalized file names from string ids. The file
- * names generated by an instance of this class have the following properties:
- *
- * <ul>
- * <li>The same input id is mapped to the same file name.</li>
- * <li>Different ids are mapped to different file names.</li>
- * <li>For safe characters the file name corresponds to the input id, other
- * characters are replaced by <code>_</code> (underscore).</li>
- * <li>File names are case aware, i.e. the same file name but with different
- * upper/lower case characters is not possible.</li>
- * <li>If unique filenames can't directly created from the ids, additional
- * suffixes are appended.</li>
- * </ul>
- */
-class NormalizedFileNames {
-
- private static final BitSet LEGAL_CHARS = new BitSet();
-
- static {
- final String legal = "abcdefghijklmnopqrstuvwxyz"
- + "ABCDEFGHIJKLMNOPQRSTUVWYXZ0123456789$-._";
- for (final char c : legal.toCharArray()) {
- LEGAL_CHARS.set(c);
- }
- }
-
- private final Map<String, String> mapping = new HashMap<String, String>();
-
- private final Set<String> usedNames = new HashSet<String>();
-
- public String getFileName(final String id) {
- String name = mapping.get(id);
- if (name != null) {
- return name;
- }
- name = replaceIllegalChars(id);
- name = ensureUniqueness(name);
- mapping.put(id, name);
- return name;
- }
-
- private String replaceIllegalChars(final String s) {
- final StringBuilder sb = new StringBuilder(s.length());
- boolean modified = false;
- for (int i = 0; i < s.length(); i++) {
- final char c = s.charAt(i);
- if (LEGAL_CHARS.get(c)) {
- sb.append(c);
- } else {
- sb.append('_');
- modified = true;
- }
- }
- return modified ? sb.toString() : s;
- }
-
- private String ensureUniqueness(final String s) {
- String unique = s;
- String lower = unique.toLowerCase(Locale.ENGLISH);
- int idx = 1;
- while (usedNames.contains(lower)) {
- unique = s + '~' + idx++;
- lower = unique.toLowerCase(Locale.ENGLISH);
- }
- usedNames.add(lower);
- return unique;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal; + +import java.util.BitSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +/** + * Internal utility to create normalized file names from string ids. The file + * names generated by an instance of this class have the following properties: + * + * <ul> + * <li>The same input id is mapped to the same file name.</li> + * <li>Different ids are mapped to different file names.</li> + * <li>For safe characters the file name corresponds to the input id, other + * characters are replaced by <code>_</code> (underscore).</li> + * <li>File names are case aware, i.e. the same file name but with different + * upper/lower case characters is not possible.</li> + * <li>If unique filenames can't directly created from the ids, additional + * suffixes are appended.</li> + * </ul> + */ +class NormalizedFileNames { + + private static final BitSet LEGAL_CHARS = new BitSet(); + + static { + final String legal = "abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWYXZ0123456789$-._"; + for (final char c : legal.toCharArray()) { + LEGAL_CHARS.set(c); + } + } + + private final Map<String, String> mapping = new HashMap<String, String>(); + + private final Set<String> usedNames = new HashSet<String>(); + + public String getFileName(final String id) { + String name = mapping.get(id); + if (name != null) { + return name; + } + name = replaceIllegalChars(id); + name = ensureUniqueness(name); + mapping.put(id, name); + return name; + } + + private String replaceIllegalChars(final String s) { + final StringBuilder sb = new StringBuilder(s.length()); + boolean modified = false; + for (int i = 0; i < s.length(); i++) { + final char c = s.charAt(i); + if (LEGAL_CHARS.get(c)) { + sb.append(c); + } else { + sb.append('_'); + modified = true; + } + } + return modified ? sb.toString() : s; + } + + private String ensureUniqueness(final String s) { + String unique = s; + String lower = unique.toLowerCase(Locale.ENGLISH); + int idx = 1; + while (usedNames.contains(lower)) { + unique = s + '~' + idx++; + lower = unique.toLowerCase(Locale.ENGLISH); + } + usedNames.add(lower); + return unique; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/ReportOutputFolder.java b/org.jacoco.report/src/org/jacoco/report/internal/ReportOutputFolder.java index 9f263ce3..f4ad0d8a 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/ReportOutputFolder.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/ReportOutputFolder.java @@ -1,126 +1,126 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jacoco.report.IMultiReportOutput;
-
-/**
- * Logical representation of a folder in the output structure. This utility
- * ensures valid and unique file names and helps to create relative links.
- */
-public class ReportOutputFolder {
-
- private final IMultiReportOutput output;
-
- private final ReportOutputFolder parent;
-
- private final String path;
-
- /** Cached sub-folder instances to guarantee stable normalization */
- private final Map<String, ReportOutputFolder> subFolders = new HashMap<String, ReportOutputFolder>();
-
- private final NormalizedFileNames fileNames;
-
- /**
- * Creates a new root folder for the given output.
- *
- * @param output
- * output for generated files
- */
- public ReportOutputFolder(final IMultiReportOutput output) {
- this(output, null, "");
- }
-
- /**
- * Creates a new root folder for the given output.
- *
- * @param output
- * output for generated files
- */
- private ReportOutputFolder(final IMultiReportOutput output,
- final ReportOutputFolder parent, final String path) {
- this.output = output;
- this.parent = parent;
- this.path = path;
- fileNames = new NormalizedFileNames();
- }
-
- /**
- * Creates a sub-folder with the given name.
- *
- * @param name
- * name of the sub-folder
- * @return handle for output into the sub-folder
- */
- public ReportOutputFolder subFolder(final String name) {
- final String normalizedName = normalize(name);
- ReportOutputFolder folder = subFolders.get(normalizedName);
- if (folder != null) {
- return folder;
- }
- folder = new ReportOutputFolder(output, this, path + normalizedName
- + "/");
- subFolders.put(normalizedName, folder);
- return folder;
- }
-
- /**
- * Creates a new file in this folder with the given local name.
- *
- * @param name
- * name of the sub-folder
- * @return handle for output into the sub-folder
- * @throws IOException
- * if the file creation fails
- */
- public OutputStream createFile(final String name) throws IOException {
- return output.createFile(path + normalize(name));
- }
-
- /**
- * Returns a link relative to a given base to a resource within this folder.
- *
- * @param base
- * base to create the relative link from
- * @param name
- * name of the file or folder in this folder
- * @return relative link
- * @throws IllegalArgumentException
- * if this folder and the base do not have the same root
- */
- public String getLink(final ReportOutputFolder base, final String name) {
- if (base.isAncestorOf(this)) {
- return this.path.substring(base.path.length()) + normalize(name);
- }
- if (base.parent == null) {
- throw new IllegalArgumentException("Folders with different roots.");
- }
- return "../" + this.getLink(base.parent, name);
- }
-
- private boolean isAncestorOf(final ReportOutputFolder folder) {
- if (this == folder) {
- return true;
- }
- return folder.parent == null ? false : isAncestorOf(folder.parent);
- }
-
- private String normalize(final String name) {
- return fileNames.getFileName(name);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + +import org.jacoco.report.IMultiReportOutput; + +/** + * Logical representation of a folder in the output structure. This utility + * ensures valid and unique file names and helps to create relative links. + */ +public class ReportOutputFolder { + + private final IMultiReportOutput output; + + private final ReportOutputFolder parent; + + private final String path; + + /** Cached sub-folder instances to guarantee stable normalization */ + private final Map<String, ReportOutputFolder> subFolders = new HashMap<String, ReportOutputFolder>(); + + private final NormalizedFileNames fileNames; + + /** + * Creates a new root folder for the given output. + * + * @param output + * output for generated files + */ + public ReportOutputFolder(final IMultiReportOutput output) { + this(output, null, ""); + } + + /** + * Creates a new root folder for the given output. + * + * @param output + * output for generated files + */ + private ReportOutputFolder(final IMultiReportOutput output, + final ReportOutputFolder parent, final String path) { + this.output = output; + this.parent = parent; + this.path = path; + fileNames = new NormalizedFileNames(); + } + + /** + * Creates a sub-folder with the given name. + * + * @param name + * name of the sub-folder + * @return handle for output into the sub-folder + */ + public ReportOutputFolder subFolder(final String name) { + final String normalizedName = normalize(name); + ReportOutputFolder folder = subFolders.get(normalizedName); + if (folder != null) { + return folder; + } + folder = new ReportOutputFolder(output, this, path + normalizedName + + "/"); + subFolders.put(normalizedName, folder); + return folder; + } + + /** + * Creates a new file in this folder with the given local name. + * + * @param name + * name of the sub-folder + * @return handle for output into the sub-folder + * @throws IOException + * if the file creation fails + */ + public OutputStream createFile(final String name) throws IOException { + return output.createFile(path + normalize(name)); + } + + /** + * Returns a link relative to a given base to a resource within this folder. + * + * @param base + * base to create the relative link from + * @param name + * name of the file or folder in this folder + * @return relative link + * @throws IllegalArgumentException + * if this folder and the base do not have the same root + */ + public String getLink(final ReportOutputFolder base, final String name) { + if (base.isAncestorOf(this)) { + return this.path.substring(base.path.length()) + normalize(name); + } + if (base.parent == null) { + throw new IllegalArgumentException("Folders with different roots."); + } + return "../" + this.getLink(base.parent, name); + } + + private boolean isAncestorOf(final ReportOutputFolder folder) { + if (this == folder) { + return true; + } + return folder.parent == null ? false : isAncestorOf(folder.parent); + } + + private String normalize(final String name) { + return fileNames.getFileName(name); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLDocument.java b/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLDocument.java index ee6d9373..fc220608 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLDocument.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLDocument.java @@ -1,97 +1,97 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Writer;
-
-import org.jacoco.report.internal.xml.XMLDocument;
-
-/**
- * {@link XMLDocument} that declares its content type to be XHTML 1.0 Strict and
- * produces {@link HTMLElement}s as children.
- */
-public class HTMLDocument extends XMLDocument {
-
- private static final String ROOT = "html";
-
- private static final String PUBID = "-//W3C//DTD XHTML 1.0 Strict//EN";
-
- private static final String SYSTEM = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";
-
- private static final String XMLNS = "xmlns";
-
- private static final String XHTML_NAMESPACE_URL = "http://www.w3.org/1999/xhtml";
-
- /**
- * Creates a new HTML document based on the given writer.
- *
- * @param writer
- * writer for content output
- * @param encoding
- * document encoding
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLDocument(final Writer writer, final String encoding)
- throws IOException {
- super(ROOT, PUBID, SYSTEM, encoding, false, writer);
- attr(XMLNS, XHTML_NAMESPACE_URL);
- }
-
- /**
- * Creates a new HTML document based on the given stream.
- *
- * @param output
- * stream for content output
- * @param encoding
- * document encoding
- * @throws IOException
- * in case of problems with the stream
- */
- public HTMLDocument(final OutputStream output, final String encoding)
- throws IOException {
- super(ROOT, PUBID, SYSTEM, encoding, false, output);
- attr(XMLNS, XHTML_NAMESPACE_URL);
- }
-
- @Override
- public HTMLElement element(final String name) throws IOException {
- final HTMLElement element = new HTMLElement(writer, name);
- addChildElement(element);
- return element;
- }
-
- /**
- * Creates a 'head' element.
- *
- * @return 'head' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement head() throws IOException {
- return element("head");
- }
-
- /**
- * Creates a 'body' element.
- *
- * @return 'body' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement body() throws IOException {
- return element("body");
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + +import org.jacoco.report.internal.xml.XMLDocument; + +/** + * {@link XMLDocument} that declares its content type to be XHTML 1.0 Strict and + * produces {@link HTMLElement}s as children. + */ +public class HTMLDocument extends XMLDocument { + + private static final String ROOT = "html"; + + private static final String PUBID = "-//W3C//DTD XHTML 1.0 Strict//EN"; + + private static final String SYSTEM = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"; + + private static final String XMLNS = "xmlns"; + + private static final String XHTML_NAMESPACE_URL = "http://www.w3.org/1999/xhtml"; + + /** + * Creates a new HTML document based on the given writer. + * + * @param writer + * writer for content output + * @param encoding + * document encoding + * @throws IOException + * in case of problems with the writer + */ + public HTMLDocument(final Writer writer, final String encoding) + throws IOException { + super(ROOT, PUBID, SYSTEM, encoding, false, writer); + attr(XMLNS, XHTML_NAMESPACE_URL); + } + + /** + * Creates a new HTML document based on the given stream. + * + * @param output + * stream for content output + * @param encoding + * document encoding + * @throws IOException + * in case of problems with the stream + */ + public HTMLDocument(final OutputStream output, final String encoding) + throws IOException { + super(ROOT, PUBID, SYSTEM, encoding, false, output); + attr(XMLNS, XHTML_NAMESPACE_URL); + } + + @Override + public HTMLElement element(final String name) throws IOException { + final HTMLElement element = new HTMLElement(writer, name); + addChildElement(element); + return element; + } + + /** + * Creates a 'head' element. + * + * @return 'head' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement head() throws IOException { + return element("head"); + } + + /** + * Creates a 'body' element. + * + * @return 'body' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement body() throws IOException { + return element("body"); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLElement.java b/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLElement.java index 47da3b35..11ccf89e 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLElement.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLElement.java @@ -1,396 +1,396 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.xml.XMLElement;
-
-/**
- * A {@link XMLElement} with utility methods to create XHTML documents. It
- * provides methods of HTML tags to avoid magic strings in the generators.
- */
-public class HTMLElement extends XMLElement {
-
- /**
- * Creates a new element for a HTML document.
- *
- * @param writer
- * all output will be written directly to this
- * @param name
- * element name
- */
- protected HTMLElement(final Writer writer, final String name) {
- super(writer, name);
- }
-
- @Override
- public HTMLElement element(final String name) throws IOException {
- final HTMLElement element = new HTMLElement(writer, name);
- addChildElement(element);
- return element;
- }
-
- private void classattr(final String classattr) throws IOException {
- attr("class", classattr);
- }
-
- /**
- * Creates a 'meta' element.
- *
- * @param httpequivattr
- * value of the http-equiv attribute
- * @param contentattr
- * value for the content attribute
- * @return 'meta' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement meta(final String httpequivattr, final String contentattr)
- throws IOException {
- final HTMLElement meta = element("meta");
- meta.attr("http-equiv", httpequivattr);
- meta.attr("content", contentattr);
- return meta;
- }
-
- /**
- * Creates a 'link' element.
- *
- * @param relattr
- * value of the rel attribute
- * @param hrefattr
- * value for the href attribute
- * @param typeattr
- * value for the type attribute
- * @return 'link' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement link(final String relattr, final String hrefattr,
- final String typeattr) throws IOException {
- final HTMLElement link = element("link");
- link.attr("rel", relattr);
- link.attr("href", hrefattr);
- link.attr("type", typeattr);
- return link;
- }
-
- /**
- * Creates a 'title' element.
- *
- * @return 'title' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement title() throws IOException {
- return element("title");
- }
-
- /**
- * Creates a 'h1' element.
- *
- * @return 'h1' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement h1() throws IOException {
- return element("h1");
- }
-
- /**
- * Creates a 'p' element.
- *
- * @return 'p' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement p() throws IOException {
- return element("p");
- }
-
- /**
- * Creates a 'span' element.
- *
- * @return 'span' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement span() throws IOException {
- return element("span");
- }
-
- /**
- * Creates a 'span' element.
- *
- * @param classattr
- * value of the class attribute
- * @return 'span' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement span(final String classattr) throws IOException {
- final HTMLElement span = span();
- span.classattr(classattr);
- return span;
- }
-
- /**
- * Creates a 'span' element.
- *
- * @param classattr
- * value of the class attribute
- * @param idattr
- * value of the id attribute
- * @return 'span' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement span(final String classattr, final String idattr)
- throws IOException {
- final HTMLElement span = span(classattr);
- span.attr("id", idattr);
- return span;
- }
-
- /**
- * Creates a 'div' element.
- *
- * @param classattr
- * value of the class attribute
- * @return 'div' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement div(final String classattr) throws IOException {
- final HTMLElement div = element("div");
- div.classattr(classattr);
- return div;
- }
-
- /**
- * Creates a 'code' element.
- *
- * @return 'code' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement code() throws IOException {
- return element("code");
- }
-
- /**
- * Creates a 'pre' element.
- *
- * @param classattr
- * value of the class attribute
- * @return 'pre' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement pre(final String classattr) throws IOException {
- final HTMLElement pre = element("pre");
- pre.classattr(classattr);
- return pre;
- }
-
- /**
- * Creates a 'a' element.
- *
- * @param hrefattr
- * value of the href attribute
- * @return 'a' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement a(final String hrefattr) throws IOException {
- final HTMLElement a = element("a");
- a.attr("href", hrefattr);
- return a;
- }
-
- /**
- * Creates a 'a' element.
- *
- * @param hrefattr
- * value of the href attribute
- * @param classattr
- * value of the class attribute
- * @return 'a' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement a(final String hrefattr, final String classattr)
- throws IOException {
- final HTMLElement a = a(hrefattr);
- a.classattr(classattr);
- return a;
- }
-
- /**
- * Creates a link to the given {@link ILinkable}.
- *
- * @param linkable
- * object to link to
- * @param base
- * base folder where the link should be placed
- * @return 'a' element or 'span' element, if the link target does not exist
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement a(final ILinkable linkable, final ReportOutputFolder base)
- throws IOException {
- final HTMLElement a;
- final String link = linkable.getLink(base);
- if (link == null) {
- a = span(linkable.getLinkStyle());
- } else {
- a = a(link, linkable.getLinkStyle());
- }
- a.text(linkable.getLinkLabel());
- return a;
- }
-
- /**
- * Creates a 'table' element.
- *
- * @param classattr
- * value of the class attribute
- * @return 'table' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement table(final String classattr) throws IOException {
- final HTMLElement table = element("table");
- table.classattr(classattr);
- table.attr("cellspacing", "0");
- return table;
- }
-
- /**
- * Creates a 'thead' element.
- *
- * @return 'thead' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement thead() throws IOException {
- return element("thead");
- }
-
- /**
- * Creates a 'tfoot' element.
- *
- * @return 'tfoot' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement tfoot() throws IOException {
- return element("tfoot");
- }
-
- /**
- * Creates a 'tbody' element.
- *
- * @return 'tbody' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement tbody() throws IOException {
- return element("tbody");
- }
-
- /**
- * Creates a 'tr' element.
- *
- * @return 'tr' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement tr() throws IOException {
- return element("tr");
- }
-
- /**
- * Creates a 'td' element.
- *
- * @return 'td' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement td() throws IOException {
- return element("td");
- }
-
- /**
- * Creates a 'td' element.
- *
- * @param classattr
- * value of the class attribute
- * @return 'td' element
- * @throws IOException
- * in case of problems with the writer
- */
- public HTMLElement td(final String classattr) throws IOException {
- final HTMLElement td = td();
- td.classattr(classattr);
- return td;
- }
-
- /**
- * Creates a 'img' element.
- *
- * @param srcattr
- * value of the src attribute
- * @param widthattr
- * value of the width attribute
- * @param heightattr
- * value of the height attribute
- * @param titleattr
- * value of the title and alt attribute
- * @throws IOException
- * in case of problems with the writer
- */
- public void img(final String srcattr, final int widthattr,
- final int heightattr, final String titleattr) throws IOException {
- final HTMLElement img = element("img");
- img.attr("src", srcattr);
- img.attr("width", widthattr);
- img.attr("height", heightattr);
- img.attr("title", titleattr);
- img.attr("alt", titleattr);
- img.close();
- }
-
- /**
- * Creates a 'script' element.
- *
- * @param typeattr
- * value of the type attribute
- * @param srcattr
- * value of the src attribute
- * @throws IOException
- * in case of problems with the writer
- */
- public void script(final String typeattr, final String srcattr)
- throws IOException {
- final HTMLElement script = element("script");
- script.attr("type", typeattr);
- script.attr("src", srcattr);
- // Enforce open and closing tag otherwise it won't work in browsers:
- script.text("");
- script.close();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html; + +import java.io.IOException; +import java.io.Writer; + +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.xml.XMLElement; + +/** + * A {@link XMLElement} with utility methods to create XHTML documents. It + * provides methods of HTML tags to avoid magic strings in the generators. + */ +public class HTMLElement extends XMLElement { + + /** + * Creates a new element for a HTML document. + * + * @param writer + * all output will be written directly to this + * @param name + * element name + */ + protected HTMLElement(final Writer writer, final String name) { + super(writer, name); + } + + @Override + public HTMLElement element(final String name) throws IOException { + final HTMLElement element = new HTMLElement(writer, name); + addChildElement(element); + return element; + } + + private void classattr(final String classattr) throws IOException { + attr("class", classattr); + } + + /** + * Creates a 'meta' element. + * + * @param httpequivattr + * value of the http-equiv attribute + * @param contentattr + * value for the content attribute + * @return 'meta' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement meta(final String httpequivattr, final String contentattr) + throws IOException { + final HTMLElement meta = element("meta"); + meta.attr("http-equiv", httpequivattr); + meta.attr("content", contentattr); + return meta; + } + + /** + * Creates a 'link' element. + * + * @param relattr + * value of the rel attribute + * @param hrefattr + * value for the href attribute + * @param typeattr + * value for the type attribute + * @return 'link' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement link(final String relattr, final String hrefattr, + final String typeattr) throws IOException { + final HTMLElement link = element("link"); + link.attr("rel", relattr); + link.attr("href", hrefattr); + link.attr("type", typeattr); + return link; + } + + /** + * Creates a 'title' element. + * + * @return 'title' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement title() throws IOException { + return element("title"); + } + + /** + * Creates a 'h1' element. + * + * @return 'h1' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement h1() throws IOException { + return element("h1"); + } + + /** + * Creates a 'p' element. + * + * @return 'p' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement p() throws IOException { + return element("p"); + } + + /** + * Creates a 'span' element. + * + * @return 'span' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement span() throws IOException { + return element("span"); + } + + /** + * Creates a 'span' element. + * + * @param classattr + * value of the class attribute + * @return 'span' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement span(final String classattr) throws IOException { + final HTMLElement span = span(); + span.classattr(classattr); + return span; + } + + /** + * Creates a 'span' element. + * + * @param classattr + * value of the class attribute + * @param idattr + * value of the id attribute + * @return 'span' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement span(final String classattr, final String idattr) + throws IOException { + final HTMLElement span = span(classattr); + span.attr("id", idattr); + return span; + } + + /** + * Creates a 'div' element. + * + * @param classattr + * value of the class attribute + * @return 'div' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement div(final String classattr) throws IOException { + final HTMLElement div = element("div"); + div.classattr(classattr); + return div; + } + + /** + * Creates a 'code' element. + * + * @return 'code' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement code() throws IOException { + return element("code"); + } + + /** + * Creates a 'pre' element. + * + * @param classattr + * value of the class attribute + * @return 'pre' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement pre(final String classattr) throws IOException { + final HTMLElement pre = element("pre"); + pre.classattr(classattr); + return pre; + } + + /** + * Creates a 'a' element. + * + * @param hrefattr + * value of the href attribute + * @return 'a' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement a(final String hrefattr) throws IOException { + final HTMLElement a = element("a"); + a.attr("href", hrefattr); + return a; + } + + /** + * Creates a 'a' element. + * + * @param hrefattr + * value of the href attribute + * @param classattr + * value of the class attribute + * @return 'a' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement a(final String hrefattr, final String classattr) + throws IOException { + final HTMLElement a = a(hrefattr); + a.classattr(classattr); + return a; + } + + /** + * Creates a link to the given {@link ILinkable}. + * + * @param linkable + * object to link to + * @param base + * base folder where the link should be placed + * @return 'a' element or 'span' element, if the link target does not exist + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement a(final ILinkable linkable, final ReportOutputFolder base) + throws IOException { + final HTMLElement a; + final String link = linkable.getLink(base); + if (link == null) { + a = span(linkable.getLinkStyle()); + } else { + a = a(link, linkable.getLinkStyle()); + } + a.text(linkable.getLinkLabel()); + return a; + } + + /** + * Creates a 'table' element. + * + * @param classattr + * value of the class attribute + * @return 'table' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement table(final String classattr) throws IOException { + final HTMLElement table = element("table"); + table.classattr(classattr); + table.attr("cellspacing", "0"); + return table; + } + + /** + * Creates a 'thead' element. + * + * @return 'thead' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement thead() throws IOException { + return element("thead"); + } + + /** + * Creates a 'tfoot' element. + * + * @return 'tfoot' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement tfoot() throws IOException { + return element("tfoot"); + } + + /** + * Creates a 'tbody' element. + * + * @return 'tbody' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement tbody() throws IOException { + return element("tbody"); + } + + /** + * Creates a 'tr' element. + * + * @return 'tr' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement tr() throws IOException { + return element("tr"); + } + + /** + * Creates a 'td' element. + * + * @return 'td' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement td() throws IOException { + return element("td"); + } + + /** + * Creates a 'td' element. + * + * @param classattr + * value of the class attribute + * @return 'td' element + * @throws IOException + * in case of problems with the writer + */ + public HTMLElement td(final String classattr) throws IOException { + final HTMLElement td = td(); + td.classattr(classattr); + return td; + } + + /** + * Creates a 'img' element. + * + * @param srcattr + * value of the src attribute + * @param widthattr + * value of the width attribute + * @param heightattr + * value of the height attribute + * @param titleattr + * value of the title and alt attribute + * @throws IOException + * in case of problems with the writer + */ + public void img(final String srcattr, final int widthattr, + final int heightattr, final String titleattr) throws IOException { + final HTMLElement img = element("img"); + img.attr("src", srcattr); + img.attr("width", widthattr); + img.attr("height", heightattr); + img.attr("title", titleattr); + img.attr("alt", titleattr); + img.close(); + } + + /** + * Creates a 'script' element. + * + * @param typeattr + * value of the type attribute + * @param srcattr + * value of the src attribute + * @throws IOException + * in case of problems with the writer + */ + public void script(final String typeattr, final String srcattr) + throws IOException { + final HTMLElement script = element("script"); + script.attr("type", typeattr); + script.attr("src", srcattr); + // Enforce open and closing tag otherwise it won't work in browsers: + script.text(""); + script.close(); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLGroupVisitor.java b/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLGroupVisitor.java index 2330166c..54b4c528 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLGroupVisitor.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/HTMLGroupVisitor.java @@ -1,86 +1,86 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.report.ISourceFileLocator;
-import org.jacoco.report.internal.AbstractGroupVisitor;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.page.BundlePage;
-import org.jacoco.report.internal.html.page.GroupPage;
-import org.jacoco.report.internal.html.page.NodePage;
-import org.jacoco.report.internal.html.page.ReportPage;
-
-/**
- * Group visitor for HTML reports.
- */
-public class HTMLGroupVisitor extends AbstractGroupVisitor {
-
- private final ReportOutputFolder folder;
-
- private final IHTMLReportContext context;
-
- private final GroupPage page;
-
- /**
- * Create a new group handler.
- *
- * @param parent
- * @param folder
- * @param context
- * @param name
- */
- public HTMLGroupVisitor(final ReportPage parent,
- final ReportOutputFolder folder, final IHTMLReportContext context,
- final String name) {
- super(name);
- this.folder = folder;
- this.context = context;
- page = new GroupPage(total, parent, folder, context);
- }
-
- /**
- * Returns the page rendered for this group.
- *
- * @return page for this group
- */
- public NodePage<ICoverageNode> getPage() {
- return page;
- }
-
- @Override
- protected void handleBundle(final IBundleCoverage bundle,
- final ISourceFileLocator locator) throws IOException {
- final BundlePage bundlepage = new BundlePage(bundle, page, locator,
- folder.subFolder(bundle.getName()), context);
- bundlepage.render();
- page.addItem(bundlepage);
- }
-
- @Override
- protected AbstractGroupVisitor handleGroup(final String name)
- throws IOException {
- final HTMLGroupVisitor handler = new HTMLGroupVisitor(page,
- folder.subFolder(name), context, name);
- page.addItem(handler.getPage());
- return handler;
- }
-
- @Override
- protected void handleEnd() throws IOException {
- page.render();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html; + +import java.io.IOException; + +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.report.ISourceFileLocator; +import org.jacoco.report.internal.AbstractGroupVisitor; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.page.BundlePage; +import org.jacoco.report.internal.html.page.GroupPage; +import org.jacoco.report.internal.html.page.NodePage; +import org.jacoco.report.internal.html.page.ReportPage; + +/** + * Group visitor for HTML reports. + */ +public class HTMLGroupVisitor extends AbstractGroupVisitor { + + private final ReportOutputFolder folder; + + private final IHTMLReportContext context; + + private final GroupPage page; + + /** + * Create a new group handler. + * + * @param parent + * @param folder + * @param context + * @param name + */ + public HTMLGroupVisitor(final ReportPage parent, + final ReportOutputFolder folder, final IHTMLReportContext context, + final String name) { + super(name); + this.folder = folder; + this.context = context; + page = new GroupPage(total, parent, folder, context); + } + + /** + * Returns the page rendered for this group. + * + * @return page for this group + */ + public NodePage<ICoverageNode> getPage() { + return page; + } + + @Override + protected void handleBundle(final IBundleCoverage bundle, + final ISourceFileLocator locator) throws IOException { + final BundlePage bundlepage = new BundlePage(bundle, page, locator, + folder.subFolder(bundle.getName()), context); + bundlepage.render(); + page.addItem(bundlepage); + } + + @Override + protected AbstractGroupVisitor handleGroup(final String name) + throws IOException { + final HTMLGroupVisitor handler = new HTMLGroupVisitor(page, + folder.subFolder(name), context, name); + page.addItem(handler.getPage()); + return handler; + } + + @Override + protected void handleEnd() throws IOException { + page.render(); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/IHTMLReportContext.java b/org.jacoco.report/src/org/jacoco/report/internal/html/IHTMLReportContext.java index 6bf4b388..4763a5d6 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/IHTMLReportContext.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/IHTMLReportContext.java @@ -1,82 +1,82 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html;
-
-import java.util.Locale;
-
-import org.jacoco.report.ILanguageNames;
-import org.jacoco.report.internal.html.index.IIndexUpdate;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.jacoco.report.internal.html.table.Table;
-
-/**
- * Context and configuration information during creation of a HTML report.
- */
-public interface IHTMLReportContext {
-
- /**
- * Returns the static resources used in this report.
- *
- * @return static resources
- */
- public Resources getResources();
-
- /**
- * Returns the language names call-back used in this report.
- *
- * @return language names
- */
- public ILanguageNames getLanguageNames();
-
- /**
- * Returns a table for rendering coverage nodes.
- *
- * @return table for rendering
- */
- public Table getTable();
-
- /**
- * Returns a string of textual information to include in every page footer.
- *
- * @return footer text or empty string
- */
- public String getFooterText();
-
- /**
- * Returns the link to the sessions page.
- *
- * @return sessions page link
- */
- public ILinkable getSessionsPage();
-
- /**
- * Returns the encoding of the generated HTML documents.
- *
- * @return encoding for generated HTML documents
- */
- public String getOutputEncoding();
-
- /**
- * Returns the service for index updates.
- *
- * @return sevice for indes updates
- */
- public IIndexUpdate getIndexUpdate();
-
- /**
- * Returns the locale used to format numbers and dates.
- *
- * @return locale for numbers and dates
- */
- public Locale getLocale();
-
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html; + +import java.util.Locale; + +import org.jacoco.report.ILanguageNames; +import org.jacoco.report.internal.html.index.IIndexUpdate; +import org.jacoco.report.internal.html.resources.Resources; +import org.jacoco.report.internal.html.table.Table; + +/** + * Context and configuration information during creation of a HTML report. + */ +public interface IHTMLReportContext { + + /** + * Returns the static resources used in this report. + * + * @return static resources + */ + public Resources getResources(); + + /** + * Returns the language names call-back used in this report. + * + * @return language names + */ + public ILanguageNames getLanguageNames(); + + /** + * Returns a table for rendering coverage nodes. + * + * @return table for rendering + */ + public Table getTable(); + + /** + * Returns a string of textual information to include in every page footer. + * + * @return footer text or empty string + */ + public String getFooterText(); + + /** + * Returns the link to the sessions page. + * + * @return sessions page link + */ + public ILinkable getSessionsPage(); + + /** + * Returns the encoding of the generated HTML documents. + * + * @return encoding for generated HTML documents + */ + public String getOutputEncoding(); + + /** + * Returns the service for index updates. + * + * @return sevice for indes updates + */ + public IIndexUpdate getIndexUpdate(); + + /** + * Returns the locale used to format numbers and dates. + * + * @return locale for numbers and dates + */ + public Locale getLocale(); + }
\ No newline at end of file diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/BundlePage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/BundlePage.java index 8fb04186..e3be26e3 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/BundlePage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/BundlePage.java @@ -1,80 +1,80 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.IPackageCoverage;
-import org.jacoco.report.ISourceFileLocator;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-
-/**
- * Page showing coverage information for a bundle. The page contains a table
- * with all packages of the bundle.
- */
-public class BundlePage extends TablePage<ICoverageNode> {
-
- private final ISourceFileLocator locator;
-
- private IBundleCoverage bundle;
-
- /**
- * Creates a new visitor in the given context.
- *
- * @param bundle
- * @param parent
- * @param locator
- * @param folder
- * @param context
- */
- public BundlePage(final IBundleCoverage bundle, final ReportPage parent,
- final ISourceFileLocator locator, final ReportOutputFolder folder,
- final IHTMLReportContext context) {
- super(bundle.getPlainCopy(), parent, folder, context);
- this.bundle = bundle;
- this.locator = locator;
- }
-
- @Override
- public void render() throws IOException {
- renderPackages();
- super.render();
- // Don't keep the bundle structure in memory
- bundle = null;
- }
-
- private void renderPackages() throws IOException {
- for (final IPackageCoverage p : bundle.getPackages()) {
- final String packagename = p.getName();
- final String foldername = packagename.length() == 0 ? "default"
- : packagename.replace('/', '.');
- final PackagePage page = new PackagePage(p, this, locator,
- folder.subFolder(foldername), context);
- page.render();
- addItem(page);
- }
- }
-
- @Override
- protected String getOnload() {
- return "initialSort(['breadcrumb', 'coveragetable'])";
- }
-
- @Override
- protected String getFileName() {
- return "index.html";
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import java.io.IOException; + +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.IPackageCoverage; +import org.jacoco.report.ISourceFileLocator; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.IHTMLReportContext; + +/** + * Page showing coverage information for a bundle. The page contains a table + * with all packages of the bundle. + */ +public class BundlePage extends TablePage<ICoverageNode> { + + private final ISourceFileLocator locator; + + private IBundleCoverage bundle; + + /** + * Creates a new visitor in the given context. + * + * @param bundle + * @param parent + * @param locator + * @param folder + * @param context + */ + public BundlePage(final IBundleCoverage bundle, final ReportPage parent, + final ISourceFileLocator locator, final ReportOutputFolder folder, + final IHTMLReportContext context) { + super(bundle.getPlainCopy(), parent, folder, context); + this.bundle = bundle; + this.locator = locator; + } + + @Override + public void render() throws IOException { + renderPackages(); + super.render(); + // Don't keep the bundle structure in memory + bundle = null; + } + + private void renderPackages() throws IOException { + for (final IPackageCoverage p : bundle.getPackages()) { + final String packagename = p.getName(); + final String foldername = packagename.length() == 0 ? "default" + : packagename.replace('/', '.'); + final PackagePage page = new PackagePage(p, this, locator, + folder.subFolder(foldername), context); + page.render(); + addItem(page); + } + } + + @Override + protected String getOnload() { + return "initialSort(['breadcrumb', 'coveragetable'])"; + } + + @Override + protected String getFileName() { + return "index.html"; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/ClassPage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/ClassPage.java index ec09d9a2..4aefa0ad 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/ClassPage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/ClassPage.java @@ -1,79 +1,79 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.IMethodCoverage;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-import org.jacoco.report.internal.html.ILinkable;
-
-/**
- * Page showing coverage information for a class as a table of methods. The
- * methods are linked to the corresponding source file.
- */
-public class ClassPage extends TablePage<IClassCoverage> {
-
- private final ILinkable sourcePage;
-
- /**
- * Creates a new visitor in the given context.
- *
- * @param classNode
- * @param parent
- * @param sourcePage
- * corresponding source page or <code>null</code>
- * @param folder
- * @param context
- */
- public ClassPage(final IClassCoverage classNode, final ReportPage parent,
- final ILinkable sourcePage, final ReportOutputFolder folder,
- final IHTMLReportContext context) {
- super(classNode, parent, folder, context);
- this.sourcePage = sourcePage;
- context.getIndexUpdate().addClass(this, classNode.getId());
- }
-
- @Override
- protected String getOnload() {
- return "initialSort(['breadcrumb'])";
- }
-
- @Override
- public void render() throws IOException {
- for (final IMethodCoverage m : getNode().getMethods()) {
- final String label = context.getLanguageNames().getMethodName(
- getNode().getName(), m.getName(), m.getDesc(),
- m.getSignature());
- addItem(new MethodItem(m, label, sourcePage));
- }
- super.render();
- }
-
- @Override
- protected String getFileName() {
- final String vmname = getNode().getName();
- final int pos = vmname.lastIndexOf('/');
- final String shortname = pos == -1 ? vmname : vmname.substring(pos + 1);
- return shortname + ".html";
- }
-
- @Override
- public String getLinkLabel() {
- return context.getLanguageNames().getClassName(getNode().getName(),
- getNode().getSignature(), getNode().getSuperName(),
- getNode().getInterfaceNames());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import java.io.IOException; + +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.IMethodCoverage; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.IHTMLReportContext; +import org.jacoco.report.internal.html.ILinkable; + +/** + * Page showing coverage information for a class as a table of methods. The + * methods are linked to the corresponding source file. + */ +public class ClassPage extends TablePage<IClassCoverage> { + + private final ILinkable sourcePage; + + /** + * Creates a new visitor in the given context. + * + * @param classNode + * @param parent + * @param sourcePage + * corresponding source page or <code>null</code> + * @param folder + * @param context + */ + public ClassPage(final IClassCoverage classNode, final ReportPage parent, + final ILinkable sourcePage, final ReportOutputFolder folder, + final IHTMLReportContext context) { + super(classNode, parent, folder, context); + this.sourcePage = sourcePage; + context.getIndexUpdate().addClass(this, classNode.getId()); + } + + @Override + protected String getOnload() { + return "initialSort(['breadcrumb'])"; + } + + @Override + public void render() throws IOException { + for (final IMethodCoverage m : getNode().getMethods()) { + final String label = context.getLanguageNames().getMethodName( + getNode().getName(), m.getName(), m.getDesc(), + m.getSignature()); + addItem(new MethodItem(m, label, sourcePage)); + } + super.render(); + } + + @Override + protected String getFileName() { + final String vmname = getNode().getName(); + final int pos = vmname.lastIndexOf('/'); + final String shortname = pos == -1 ? vmname : vmname.substring(pos + 1); + return shortname + ".html"; + } + + @Override + public String getLinkLabel() { + return context.getLanguageNames().getClassName(getNode().getName(), + getNode().getSignature(), getNode().getSuperName(), + getNode().getInterfaceNames()); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/GroupPage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/GroupPage.java index 156b5d8d..a42ed137 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/GroupPage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/GroupPage.java @@ -1,47 +1,47 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-
-/**
- * Page showing coverage information for a node that groups other nodes. The
- * page shows a table of linked nodes.
- */
-public class GroupPage extends TablePage<ICoverageNode> {
-
- /**
- * Creates a new visitor in the given context.
- *
- * @param node
- * @param parent
- * @param folder
- * @param context
- */
- public GroupPage(final ICoverageNode node, final ReportPage parent,
- final ReportOutputFolder folder, final IHTMLReportContext context) {
- super(node, parent, folder, context);
- }
-
- @Override
- protected String getOnload() {
- return "initialSort(['breadcrumb', 'coveragetable'])";
- }
-
- @Override
- protected String getFileName() {
- return "index.html";
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.IHTMLReportContext; + +/** + * Page showing coverage information for a node that groups other nodes. The + * page shows a table of linked nodes. + */ +public class GroupPage extends TablePage<ICoverageNode> { + + /** + * Creates a new visitor in the given context. + * + * @param node + * @param parent + * @param folder + * @param context + */ + public GroupPage(final ICoverageNode node, final ReportPage parent, + final ReportOutputFolder folder, final IHTMLReportContext context) { + super(node, parent, folder, context); + } + + @Override + protected String getOnload() { + return "initialSort(['breadcrumb', 'coveragetable'])"; + } + + @Override + protected String getFileName() { + return "index.html"; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/MethodItem.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/MethodItem.java index b88a0c6c..42aa64ad 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/MethodItem.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/MethodItem.java @@ -1,61 +1,61 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.IMethodCoverage;
-import org.jacoco.core.analysis.ISourceNode;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.ILinkable;
-import org.jacoco.report.internal.html.resources.Styles;
-import org.jacoco.report.internal.html.table.ITableItem;
-
-/**
- * Table items representing a method.
- */
-final class MethodItem implements ITableItem {
-
- private final IMethodCoverage node;
-
- private final String label;
-
- private final ILinkable sourcePage;
-
- MethodItem(final IMethodCoverage node, final String label,
- final ILinkable sourcePage) {
- this.node = node;
- this.label = label;
- this.sourcePage = sourcePage;
- }
-
- public String getLinkLabel() {
- return label;
- }
-
- public String getLinkStyle() {
- return Styles.EL_METHOD;
- }
-
- public String getLink(final ReportOutputFolder base) {
- if (sourcePage == null) {
- return null;
- }
- final String link = sourcePage.getLink(base);
- final int first = node.getFirstLine();
- return first != ISourceNode.UNKNOWN_LINE ? link + "#L" + first : link;
- }
-
- public ICoverageNode getNode() {
- return node;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.IMethodCoverage; +import org.jacoco.core.analysis.ISourceNode; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.ILinkable; +import org.jacoco.report.internal.html.resources.Styles; +import org.jacoco.report.internal.html.table.ITableItem; + +/** + * Table items representing a method. + */ +final class MethodItem implements ITableItem { + + private final IMethodCoverage node; + + private final String label; + + private final ILinkable sourcePage; + + MethodItem(final IMethodCoverage node, final String label, + final ILinkable sourcePage) { + this.node = node; + this.label = label; + this.sourcePage = sourcePage; + } + + public String getLinkLabel() { + return label; + } + + public String getLinkStyle() { + return Styles.EL_METHOD; + } + + public String getLink(final ReportOutputFolder base) { + if (sourcePage == null) { + return null; + } + final String link = sourcePage.getLink(base); + final int first = node.getFirstLine(); + return first != ISourceNode.UNKNOWN_LINE ? link + "#L" + first : link; + } + + public ICoverageNode getNode() { + return node; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/NodePage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/NodePage.java index dc5b55b7..3f7e044a 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/NodePage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/NodePage.java @@ -1,70 +1,70 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.jacoco.report.internal.html.resources.Styles;
-import org.jacoco.report.internal.html.table.ITableItem;
-
-/**
- * Report page that represents a coverage node.
- *
- * @param <NodeType>
- * type of the node represented by this page
- */
-public abstract class NodePage<NodeType extends ICoverageNode> extends
- ReportPage implements ITableItem {
-
- private final NodeType node;
-
- /**
- * Creates a new node page.
- *
- * @param node
- * corresponding node
- * @param parent
- * optional hierarchical parent
- * @param folder
- * base folder to create this report in
- * @param context
- * settings context
- */
- protected NodePage(final NodeType node, final ReportPage parent,
- final ReportOutputFolder folder, final IHTMLReportContext context) {
- super(parent, folder, context);
- this.node = node;
- }
-
- // === ILinkable ===
-
- public String getLinkStyle() {
- if (isRootPage()) {
- return Styles.EL_REPORT;
- } else {
- return Resources.getElementStyle(node.getElementType());
- }
- }
-
- public String getLinkLabel() {
- return node.getName();
- }
-
- // === ICoverageTableItem ===
-
- public NodeType getNode() {
- return node;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.IHTMLReportContext; +import org.jacoco.report.internal.html.resources.Resources; +import org.jacoco.report.internal.html.resources.Styles; +import org.jacoco.report.internal.html.table.ITableItem; + +/** + * Report page that represents a coverage node. + * + * @param <NodeType> + * type of the node represented by this page + */ +public abstract class NodePage<NodeType extends ICoverageNode> extends + ReportPage implements ITableItem { + + private final NodeType node; + + /** + * Creates a new node page. + * + * @param node + * corresponding node + * @param parent + * optional hierarchical parent + * @param folder + * base folder to create this report in + * @param context + * settings context + */ + protected NodePage(final NodeType node, final ReportPage parent, + final ReportOutputFolder folder, final IHTMLReportContext context) { + super(parent, folder, context); + this.node = node; + } + + // === ILinkable === + + public String getLinkStyle() { + if (isRootPage()) { + return Styles.EL_REPORT; + } else { + return Resources.getElementStyle(node.getElementType()); + } + } + + public String getLinkLabel() { + return node.getName(); + } + + // === ICoverageTableItem === + + public NodeType getNode() { + return node; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/PackagePage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/PackagePage.java index 8aeebaa6..54576da6 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/PackagePage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/PackagePage.java @@ -1,101 +1,101 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.IPackageCoverage;
-import org.jacoco.core.analysis.ISourceFileCoverage;
-import org.jacoco.report.ISourceFileLocator;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-import org.jacoco.report.internal.html.ILinkable;
-
-/**
- * Page showing coverage information for a Java package. The page contains a
- * table with all classes of the package.
- */
-public class PackagePage extends TablePage<IPackageCoverage> {
-
- private final ISourceFileLocator locator;
-
- /**
- * Creates a new visitor in the given context.
- *
- * @param node
- * @param parent
- * @param locator
- * @param folder
- * @param context
- */
- public PackagePage(final IPackageCoverage node, final ReportPage parent,
- final ISourceFileLocator locator, final ReportOutputFolder folder,
- final IHTMLReportContext context) {
- super(node, parent, folder, context);
- this.locator = locator;
- }
-
- @Override
- public void render() throws IOException {
- final Map<String, ILinkable> sourceFiles = renderSourceFiles();
- renderClasses(sourceFiles);
- super.render();
- }
-
- private final Map<String, ILinkable> renderSourceFiles() throws IOException {
- final Map<String, ILinkable> sourceFiles = new HashMap<String, ILinkable>();
- final String packagename = getNode().getName();
- for (final ISourceFileCoverage s : getNode().getSourceFiles()) {
- final String sourcename = s.getName();
- final Reader reader = locator
- .getSourceFile(packagename, sourcename);
- if (reader != null) {
- final SourceFilePage sourcePage = new SourceFilePage(s, reader,
- locator.getTabWidth(), this, folder, context);
- sourcePage.render();
- sourceFiles.put(sourcename, sourcePage);
- }
-
- }
- return sourceFiles;
- }
-
- private void renderClasses(final Map<String, ILinkable> sourceFiles)
- throws IOException {
- for (final IClassCoverage c : getNode().getClasses()) {
- final ClassPage page = new ClassPage(c, this, sourceFiles.get(c
- .getSourceFileName()), folder, context);
- page.render();
- addItem(page);
- }
- }
-
- @Override
- protected String getOnload() {
- return "initialSort(['breadcrumb', 'coveragetable'])";
- }
-
- @Override
- protected String getFileName() {
- return "index.html";
- }
-
- @Override
- public String getLinkLabel() {
- return context.getLanguageNames().getPackageName(getNode().getName());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import java.io.IOException; +import java.io.Reader; +import java.util.HashMap; +import java.util.Map; + +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.IPackageCoverage; +import org.jacoco.core.analysis.ISourceFileCoverage; +import org.jacoco.report.ISourceFileLocator; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.IHTMLReportContext; +import org.jacoco.report.internal.html.ILinkable; + +/** + * Page showing coverage information for a Java package. The page contains a + * table with all classes of the package. + */ +public class PackagePage extends TablePage<IPackageCoverage> { + + private final ISourceFileLocator locator; + + /** + * Creates a new visitor in the given context. + * + * @param node + * @param parent + * @param locator + * @param folder + * @param context + */ + public PackagePage(final IPackageCoverage node, final ReportPage parent, + final ISourceFileLocator locator, final ReportOutputFolder folder, + final IHTMLReportContext context) { + super(node, parent, folder, context); + this.locator = locator; + } + + @Override + public void render() throws IOException { + final Map<String, ILinkable> sourceFiles = renderSourceFiles(); + renderClasses(sourceFiles); + super.render(); + } + + private final Map<String, ILinkable> renderSourceFiles() throws IOException { + final Map<String, ILinkable> sourceFiles = new HashMap<String, ILinkable>(); + final String packagename = getNode().getName(); + for (final ISourceFileCoverage s : getNode().getSourceFiles()) { + final String sourcename = s.getName(); + final Reader reader = locator + .getSourceFile(packagename, sourcename); + if (reader != null) { + final SourceFilePage sourcePage = new SourceFilePage(s, reader, + locator.getTabWidth(), this, folder, context); + sourcePage.render(); + sourceFiles.put(sourcename, sourcePage); + } + + } + return sourceFiles; + } + + private void renderClasses(final Map<String, ILinkable> sourceFiles) + throws IOException { + for (final IClassCoverage c : getNode().getClasses()) { + final ClassPage page = new ClassPage(c, this, sourceFiles.get(c + .getSourceFileName()), folder, context); + page.render(); + addItem(page); + } + } + + @Override + protected String getOnload() { + return "initialSort(['breadcrumb', 'coveragetable'])"; + } + + @Override + protected String getFileName() { + return "index.html"; + } + + @Override + public String getLinkLabel() { + return context.getLanguageNames().getPackageName(getNode().getName()); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/ReportPage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/ReportPage.java index 9c4c2b61..429d62b0 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/ReportPage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/ReportPage.java @@ -1,172 +1,172 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import java.io.IOException;
-
-import org.jacoco.core.JaCoCo;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLDocument;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-import org.jacoco.report.internal.html.ILinkable;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.jacoco.report.internal.html.resources.Styles;
-
-/**
- * Base class for HTML page generators. It renders the page skeleton with the
- * breadcrumb, the title and the footer. Every report page is part of a
- * hierarchy and has a parent page (except the root page).
- */
-public abstract class ReportPage implements ILinkable {
-
- private final ReportPage parent;
-
- /** output folder for this node */
- protected final ReportOutputFolder folder;
-
- /** context for this report */
- protected final IHTMLReportContext context;
-
- /**
- * Creates a new report page.
- *
- * @param parent
- * optional hierarchical parent
- * @param folder
- * base folder to create this report in
- * @param context
- * settings context
- */
- protected ReportPage(final ReportPage parent,
- final ReportOutputFolder folder, final IHTMLReportContext context) {
- this.parent = parent;
- this.context = context;
- this.folder = folder;
- }
-
- /**
- * Checks whether this is the root page of the report.
- *
- * @return <code>true</code> if this is the root page
- */
- protected final boolean isRootPage() {
- return parent == null;
- }
-
- /**
- * Renders this page's content and optionally additional pages. This method
- * must be called at most once.
- *
- * @throws IOException
- */
- public void render() throws IOException {
- final HTMLDocument doc = new HTMLDocument(
- folder.createFile(getFileName()), context.getOutputEncoding());
- doc.attr("lang", context.getLocale().getLanguage());
- head(doc.head());
- body(doc.body());
- doc.close();
- }
-
- /**
- * Creates the elements within the head element.
- *
- * @param head
- * head tag of the page
- * @throws IOException
- * in case of IO problems with the report writer
- */
- protected void head(final HTMLElement head) throws IOException {
- head.meta("Content-Type", "text/html;charset=UTF-8");
- head.link("stylesheet",
- context.getResources().getLink(folder, Resources.STYLESHEET),
- "text/css");
- head.link("shortcut icon",
- context.getResources().getLink(folder, "report.gif"),
- "image/gif");
- head.title().text(getLinkLabel());
- }
-
- private void body(final HTMLElement body) throws IOException {
- body.attr("onload", getOnload());
- final HTMLElement navigation = body.div(Styles.BREADCRUMB);
- navigation.attr("id", "breadcrumb");
- infoLinks(navigation.span(Styles.RIGHT));
- breadcrumb(navigation, folder);
- body.h1().text(getLinkLabel());
- content(body);
- footer(body);
- }
-
- /**
- * Returns the onload handler for this page.
- *
- * @return handler or <code>null</code>
- */
- protected String getOnload() {
- return null;
- }
-
- private void infoLinks(final HTMLElement span) throws IOException {
- span.a(context.getSessionsPage(), folder);
- }
-
- private void breadcrumb(final HTMLElement div, final ReportOutputFolder base)
- throws IOException {
- breadcrumbParent(parent, div, base);
- div.span(getLinkStyle()).text(getLinkLabel());
- }
-
- private static void breadcrumbParent(final ReportPage page,
- final HTMLElement div, final ReportOutputFolder base)
- throws IOException {
- if (page != null) {
- breadcrumbParent(page.parent, div, base);
- div.a(page, base);
- div.text(" > ");
- }
- }
-
- private void footer(final HTMLElement body) throws IOException {
- final HTMLElement footer = body.div(Styles.FOOTER);
- final HTMLElement versioninfo = footer.span(Styles.RIGHT);
- versioninfo.text("Created with ");
- versioninfo.a(JaCoCo.HOMEURL).text("JaCoCo");
- versioninfo.text(" ").text(JaCoCo.VERSION);
- footer.text(context.getFooterText());
- }
-
- /**
- * Specifies the local file name of this page.
- *
- * @return local file name
- */
- protected abstract String getFileName();
-
- /**
- * Creates the actual content of the page.
- *
- * @param body
- * body tag of the page
- * @throws IOException
- * in case of IO problems with the report writer
- */
- protected abstract void content(final HTMLElement body) throws IOException;
-
- // === ILinkable ===
-
- public final String getLink(final ReportOutputFolder base) {
- return folder.getLink(base, getFileName());
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import java.io.IOException; + +import org.jacoco.core.JaCoCo; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLDocument; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.IHTMLReportContext; +import org.jacoco.report.internal.html.ILinkable; +import org.jacoco.report.internal.html.resources.Resources; +import org.jacoco.report.internal.html.resources.Styles; + +/** + * Base class for HTML page generators. It renders the page skeleton with the + * breadcrumb, the title and the footer. Every report page is part of a + * hierarchy and has a parent page (except the root page). + */ +public abstract class ReportPage implements ILinkable { + + private final ReportPage parent; + + /** output folder for this node */ + protected final ReportOutputFolder folder; + + /** context for this report */ + protected final IHTMLReportContext context; + + /** + * Creates a new report page. + * + * @param parent + * optional hierarchical parent + * @param folder + * base folder to create this report in + * @param context + * settings context + */ + protected ReportPage(final ReportPage parent, + final ReportOutputFolder folder, final IHTMLReportContext context) { + this.parent = parent; + this.context = context; + this.folder = folder; + } + + /** + * Checks whether this is the root page of the report. + * + * @return <code>true</code> if this is the root page + */ + protected final boolean isRootPage() { + return parent == null; + } + + /** + * Renders this page's content and optionally additional pages. This method + * must be called at most once. + * + * @throws IOException + */ + public void render() throws IOException { + final HTMLDocument doc = new HTMLDocument( + folder.createFile(getFileName()), context.getOutputEncoding()); + doc.attr("lang", context.getLocale().getLanguage()); + head(doc.head()); + body(doc.body()); + doc.close(); + } + + /** + * Creates the elements within the head element. + * + * @param head + * head tag of the page + * @throws IOException + * in case of IO problems with the report writer + */ + protected void head(final HTMLElement head) throws IOException { + head.meta("Content-Type", "text/html;charset=UTF-8"); + head.link("stylesheet", + context.getResources().getLink(folder, Resources.STYLESHEET), + "text/css"); + head.link("shortcut icon", + context.getResources().getLink(folder, "report.gif"), + "image/gif"); + head.title().text(getLinkLabel()); + } + + private void body(final HTMLElement body) throws IOException { + body.attr("onload", getOnload()); + final HTMLElement navigation = body.div(Styles.BREADCRUMB); + navigation.attr("id", "breadcrumb"); + infoLinks(navigation.span(Styles.RIGHT)); + breadcrumb(navigation, folder); + body.h1().text(getLinkLabel()); + content(body); + footer(body); + } + + /** + * Returns the onload handler for this page. + * + * @return handler or <code>null</code> + */ + protected String getOnload() { + return null; + } + + private void infoLinks(final HTMLElement span) throws IOException { + span.a(context.getSessionsPage(), folder); + } + + private void breadcrumb(final HTMLElement div, final ReportOutputFolder base) + throws IOException { + breadcrumbParent(parent, div, base); + div.span(getLinkStyle()).text(getLinkLabel()); + } + + private static void breadcrumbParent(final ReportPage page, + final HTMLElement div, final ReportOutputFolder base) + throws IOException { + if (page != null) { + breadcrumbParent(page.parent, div, base); + div.a(page, base); + div.text(" > "); + } + } + + private void footer(final HTMLElement body) throws IOException { + final HTMLElement footer = body.div(Styles.FOOTER); + final HTMLElement versioninfo = footer.span(Styles.RIGHT); + versioninfo.text("Created with "); + versioninfo.a(JaCoCo.HOMEURL).text("JaCoCo"); + versioninfo.text(" ").text(JaCoCo.VERSION); + footer.text(context.getFooterText()); + } + + /** + * Specifies the local file name of this page. + * + * @return local file name + */ + protected abstract String getFileName(); + + /** + * Creates the actual content of the page. + * + * @param body + * body tag of the page + * @throws IOException + * in case of IO problems with the report writer + */ + protected abstract void content(final HTMLElement body) throws IOException; + + // === ILinkable === + + public final String getLink(final ReportOutputFolder base) { + return folder.getLink(base, getFileName()); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/SessionsPage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/SessionsPage.java index 353058c9..e93ad471 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/SessionsPage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/SessionsPage.java @@ -1,154 +1,154 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import java.io.IOException;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.List;
-
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.report.ILanguageNames;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-import org.jacoco.report.internal.html.index.ElementIndex;
-import org.jacoco.report.internal.html.resources.Styles;
-
-/**
- * Page to display information about sessions covered by this report.
- */
-public class SessionsPage extends ReportPage {
-
- private static final String MSG_SESSIONS = "This coverage report is based "
- + "on execution data from the following sessions:";
-
- private static final String MSG_NO_SESSIONS = "No session information available.";
-
- private static final String MSG_EXECDATA = "Execution data for the "
- + "following classes is considered in this report:";
-
- private static final String MSG_NO_EXECDATA = "No execution data available.";
-
- private final List<SessionInfo> sessionInfos;
-
- private final DateFormat dateFormat;
-
- private final List<ExecutionData> executionData;
-
- private final ElementIndex index;
-
- /**
- * Creates a new page page to display session information.
- *
- * @param sessionInfos
- * @param executionData
- * @param index
- * @param parent
- * @param folder
- * @param context
- */
- public SessionsPage(final List<SessionInfo> sessionInfos,
- final Collection<ExecutionData> executionData,
- final ElementIndex index, final ReportPage parent,
- final ReportOutputFolder folder, final IHTMLReportContext context) {
- super(parent, folder, context);
- this.sessionInfos = sessionInfos;
- this.executionData = new ArrayList<ExecutionData>(executionData);
- this.index = index;
- dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT,
- DateFormat.DEFAULT, context.getLocale());
- final ILanguageNames names = context.getLanguageNames();
- Collections.sort(this.executionData, new Comparator<ExecutionData>() {
- public int compare(final ExecutionData e1, final ExecutionData e2) {
- return names.getQualifiedClassName(e1.getName()).compareTo(
- names.getQualifiedClassName(e2.getName()));
- }
- });
- }
-
- @Override
- protected void content(final HTMLElement body) throws IOException {
- if (sessionInfos.isEmpty()) {
- body.p().text(MSG_NO_SESSIONS);
- } else {
- body.p().text(MSG_SESSIONS);
- sessionTable(body);
- }
- if (executionData.isEmpty()) {
- body.p().text(MSG_NO_EXECDATA);
- } else {
- body.p().text(MSG_EXECDATA);
- executionDataTable(body);
- }
- }
-
- private void sessionTable(final HTMLElement body) throws IOException {
- final HTMLElement table = body.table(Styles.COVERAGETABLE);
- {
- final HTMLElement tr = table.thead().tr();
- tr.td().text("Session");
- tr.td().text("Start Time");
- tr.td().text("Dump Time");
- }
- final HTMLElement tbody = table.tbody();
- for (final SessionInfo i : sessionInfos) {
- final HTMLElement tr = tbody.tr();
- tr.td().span(Styles.EL_SESSION).text(i.getId());
- tr.td().text(dateFormat.format(new Date(i.getStartTimeStamp())));
- tr.td().text(dateFormat.format(new Date(i.getDumpTimeStamp())));
- }
- }
-
- private void executionDataTable(final HTMLElement body) throws IOException {
- final HTMLElement table = body.table(Styles.COVERAGETABLE);
- {
- final HTMLElement tr = table.thead().tr();
- tr.td().text("Class");
- tr.td().text("Id");
- }
- final HTMLElement tbody = table.tbody();
- final ILanguageNames names = context.getLanguageNames();
- for (final ExecutionData e : executionData) {
- final HTMLElement tr = tbody.tr();
- final String link = index.getLinkToClass(e.getId());
- final String qualifiedName = names.getQualifiedClassName(e
- .getName());
- if (link == null) {
- tr.td().span(Styles.EL_CLASS).text(qualifiedName);
- } else {
- tr.td().a(link, Styles.EL_CLASS).text(qualifiedName);
- }
- final String id = String.format("%016x", Long.valueOf(e.getId()));
- tr.td().code().text(id);
- }
- }
-
- @Override
- protected String getFileName() {
- return ".sessions.html";
- }
-
- public String getLinkStyle() {
- return Styles.EL_SESSION;
- }
-
- public String getLinkLabel() {
- return "Sessions";
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import java.io.IOException; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.report.ILanguageNames; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.IHTMLReportContext; +import org.jacoco.report.internal.html.index.ElementIndex; +import org.jacoco.report.internal.html.resources.Styles; + +/** + * Page to display information about sessions covered by this report. + */ +public class SessionsPage extends ReportPage { + + private static final String MSG_SESSIONS = "This coverage report is based " + + "on execution data from the following sessions:"; + + private static final String MSG_NO_SESSIONS = "No session information available."; + + private static final String MSG_EXECDATA = "Execution data for the " + + "following classes is considered in this report:"; + + private static final String MSG_NO_EXECDATA = "No execution data available."; + + private final List<SessionInfo> sessionInfos; + + private final DateFormat dateFormat; + + private final List<ExecutionData> executionData; + + private final ElementIndex index; + + /** + * Creates a new page page to display session information. + * + * @param sessionInfos + * @param executionData + * @param index + * @param parent + * @param folder + * @param context + */ + public SessionsPage(final List<SessionInfo> sessionInfos, + final Collection<ExecutionData> executionData, + final ElementIndex index, final ReportPage parent, + final ReportOutputFolder folder, final IHTMLReportContext context) { + super(parent, folder, context); + this.sessionInfos = sessionInfos; + this.executionData = new ArrayList<ExecutionData>(executionData); + this.index = index; + dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, + DateFormat.DEFAULT, context.getLocale()); + final ILanguageNames names = context.getLanguageNames(); + Collections.sort(this.executionData, new Comparator<ExecutionData>() { + public int compare(final ExecutionData e1, final ExecutionData e2) { + return names.getQualifiedClassName(e1.getName()).compareTo( + names.getQualifiedClassName(e2.getName())); + } + }); + } + + @Override + protected void content(final HTMLElement body) throws IOException { + if (sessionInfos.isEmpty()) { + body.p().text(MSG_NO_SESSIONS); + } else { + body.p().text(MSG_SESSIONS); + sessionTable(body); + } + if (executionData.isEmpty()) { + body.p().text(MSG_NO_EXECDATA); + } else { + body.p().text(MSG_EXECDATA); + executionDataTable(body); + } + } + + private void sessionTable(final HTMLElement body) throws IOException { + final HTMLElement table = body.table(Styles.COVERAGETABLE); + { + final HTMLElement tr = table.thead().tr(); + tr.td().text("Session"); + tr.td().text("Start Time"); + tr.td().text("Dump Time"); + } + final HTMLElement tbody = table.tbody(); + for (final SessionInfo i : sessionInfos) { + final HTMLElement tr = tbody.tr(); + tr.td().span(Styles.EL_SESSION).text(i.getId()); + tr.td().text(dateFormat.format(new Date(i.getStartTimeStamp()))); + tr.td().text(dateFormat.format(new Date(i.getDumpTimeStamp()))); + } + } + + private void executionDataTable(final HTMLElement body) throws IOException { + final HTMLElement table = body.table(Styles.COVERAGETABLE); + { + final HTMLElement tr = table.thead().tr(); + tr.td().text("Class"); + tr.td().text("Id"); + } + final HTMLElement tbody = table.tbody(); + final ILanguageNames names = context.getLanguageNames(); + for (final ExecutionData e : executionData) { + final HTMLElement tr = tbody.tr(); + final String link = index.getLinkToClass(e.getId()); + final String qualifiedName = names.getQualifiedClassName(e + .getName()); + if (link == null) { + tr.td().span(Styles.EL_CLASS).text(qualifiedName); + } else { + tr.td().a(link, Styles.EL_CLASS).text(qualifiedName); + } + final String id = String.format("%016x", Long.valueOf(e.getId())); + tr.td().code().text(id); + } + } + + @Override + protected String getFileName() { + return ".sessions.html"; + } + + public String getLinkStyle() { + return Styles.EL_SESSION; + } + + public String getLinkLabel() { + return "Sessions"; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/SourceFilePage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/SourceFilePage.java index b378e472..44cdead4 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/SourceFilePage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/SourceFilePage.java @@ -1,85 +1,85 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import static java.lang.String.format;
-
-import java.io.IOException;
-import java.io.Reader;
-
-import org.jacoco.core.analysis.ISourceFileCoverage;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-import org.jacoco.report.internal.html.resources.Resources;
-
-/**
- * Page showing the content of a source file with numbered and highlighted
- * source lines.
- */
-public class SourceFilePage extends NodePage<ISourceFileCoverage> {
-
- private final Reader sourceReader;
-
- private final int tabWidth;
-
- /**
- * Creates a new page with given information.
- *
- * @param sourceFileNode
- * @param sourceReader
- * @param tabWidth
- * @param parent
- * @param folder
- * @param context
- */
- public SourceFilePage(final ISourceFileCoverage sourceFileNode,
- final Reader sourceReader, final int tabWidth,
- final ReportPage parent, final ReportOutputFolder folder,
- final IHTMLReportContext context) {
- super(sourceFileNode, parent, folder, context);
- this.sourceReader = sourceReader;
- this.tabWidth = tabWidth;
- }
-
- @Override
- protected void content(final HTMLElement body) throws IOException {
- final SourceHighlighter hl = new SourceHighlighter(context.getLocale());
- hl.render(body, getNode(), sourceReader);
- sourceReader.close();
- }
-
- @Override
- protected void head(final HTMLElement head) throws IOException {
- super.head(head);
- head.link(
- "stylesheet",
- context.getResources().getLink(folder,
- Resources.PRETTIFY_STYLESHEET), "text/css");
- head.script(
- "text/javascript",
- context.getResources().getLink(folder,
- Resources.PRETTIFY_SCRIPT));
- }
-
- @Override
- protected String getOnload() {
- return format("window['PR_TAB_WIDTH']=%d;prettyPrint()",
- Integer.valueOf(tabWidth));
- }
-
- @Override
- protected String getFileName() {
- return getNode().getName() + ".html";
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import static java.lang.String.format; + +import java.io.IOException; +import java.io.Reader; + +import org.jacoco.core.analysis.ISourceFileCoverage; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.IHTMLReportContext; +import org.jacoco.report.internal.html.resources.Resources; + +/** + * Page showing the content of a source file with numbered and highlighted + * source lines. + */ +public class SourceFilePage extends NodePage<ISourceFileCoverage> { + + private final Reader sourceReader; + + private final int tabWidth; + + /** + * Creates a new page with given information. + * + * @param sourceFileNode + * @param sourceReader + * @param tabWidth + * @param parent + * @param folder + * @param context + */ + public SourceFilePage(final ISourceFileCoverage sourceFileNode, + final Reader sourceReader, final int tabWidth, + final ReportPage parent, final ReportOutputFolder folder, + final IHTMLReportContext context) { + super(sourceFileNode, parent, folder, context); + this.sourceReader = sourceReader; + this.tabWidth = tabWidth; + } + + @Override + protected void content(final HTMLElement body) throws IOException { + final SourceHighlighter hl = new SourceHighlighter(context.getLocale()); + hl.render(body, getNode(), sourceReader); + sourceReader.close(); + } + + @Override + protected void head(final HTMLElement head) throws IOException { + super.head(head); + head.link( + "stylesheet", + context.getResources().getLink(folder, + Resources.PRETTIFY_STYLESHEET), "text/css"); + head.script( + "text/javascript", + context.getResources().getLink(folder, + Resources.PRETTIFY_SCRIPT)); + } + + @Override + protected String getOnload() { + return format("window['PR_TAB_WIDTH']=%d;prettyPrint()", + Integer.valueOf(tabWidth)); + } + + @Override + protected String getFileName() { + return getNode().getName() + ".html"; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/SourceHighlighter.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/SourceHighlighter.java index 483496e2..8b7e191e 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/SourceHighlighter.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/SourceHighlighter.java @@ -1,131 +1,131 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Locale;
-
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.ILine;
-import org.jacoco.core.analysis.ISourceNode;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.resources.Styles;
-
-/**
- * Creates a highlighted output of a source file.
- */
-final class SourceHighlighter {
-
- private final Locale locale;
-
- private String lang;
-
- /**
- * Creates a new highlighter with default settings.
- *
- * @param locale
- * locale for tooltip rendering
- */
- public SourceHighlighter(final Locale locale) {
- this.locale = locale;
- lang = "java";
- }
-
- /**
- * Specifies the source language. This value might be used for syntax
- * highlighting. Default is "java".
- *
- * @param lang
- * source language identifier
- */
- public void setLanguage(final String lang) {
- this.lang = lang;
- }
-
- /**
- * Highlights the given source file.
- *
- * @param parent
- * parent HTML element
- * @param source
- * highlighting information
- * @param contents
- * contents of the source file
- * @throws IOException
- * problems while reading the source file or writing the output
- */
- public void render(final HTMLElement parent, final ISourceNode source,
- final Reader contents) throws IOException {
- final HTMLElement pre = parent.pre(Styles.SOURCE + " lang-" + lang
- + " linenums");
- final BufferedReader lineBuffer = new BufferedReader(contents);
- String line;
- int nr = 0;
- while ((line = lineBuffer.readLine()) != null) {
- nr++;
- renderCodeLine(pre, line, source.getLine(nr), nr);
- }
- }
-
- private void renderCodeLine(final HTMLElement pre, final String linesrc,
- final ILine line, final int lineNr) throws IOException {
- highlight(pre, line, lineNr).text(linesrc);
- pre.text("\n");
- }
-
- HTMLElement highlight(final HTMLElement pre, final ILine line,
- final int lineNr) throws IOException {
- final String style;
- switch (line.getStatus()) {
- case ICounter.NOT_COVERED:
- style = Styles.NOT_COVERED;
- break;
- case ICounter.FULLY_COVERED:
- style = Styles.FULLY_COVERED;
- break;
- case ICounter.PARTLY_COVERED:
- style = Styles.PARTLY_COVERED;
- break;
- default:
- return pre;
- }
-
- final String lineId = "L" + Integer.toString(lineNr);
- final ICounter branches = line.getBranchCounter();
- switch (branches.getStatus()) {
- case ICounter.NOT_COVERED:
- return span(pre, lineId, style, Styles.BRANCH_NOT_COVERED,
- "All %2$d branches missed.", branches);
- case ICounter.FULLY_COVERED:
- return span(pre, lineId, style, Styles.BRANCH_FULLY_COVERED,
- "All %2$d branches covered.", branches);
- case ICounter.PARTLY_COVERED:
- return span(pre, lineId, style, Styles.BRANCH_PARTLY_COVERED,
- "%1$d of %2$d branches missed.", branches);
- default:
- return pre.span(style, lineId);
- }
- }
-
- private HTMLElement span(final HTMLElement parent, final String id,
- final String style1, final String style2, final String title,
- final ICounter branches) throws IOException {
- final HTMLElement span = parent.span(style1 + " " + style2, id);
- final Integer missed = Integer.valueOf(branches.getMissedCount());
- final Integer total = Integer.valueOf(branches.getTotalCount());
- span.attr("title", String.format(locale, title, missed, total));
- return span;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.Locale; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.ILine; +import org.jacoco.core.analysis.ISourceNode; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.resources.Styles; + +/** + * Creates a highlighted output of a source file. + */ +final class SourceHighlighter { + + private final Locale locale; + + private String lang; + + /** + * Creates a new highlighter with default settings. + * + * @param locale + * locale for tooltip rendering + */ + public SourceHighlighter(final Locale locale) { + this.locale = locale; + lang = "java"; + } + + /** + * Specifies the source language. This value might be used for syntax + * highlighting. Default is "java". + * + * @param lang + * source language identifier + */ + public void setLanguage(final String lang) { + this.lang = lang; + } + + /** + * Highlights the given source file. + * + * @param parent + * parent HTML element + * @param source + * highlighting information + * @param contents + * contents of the source file + * @throws IOException + * problems while reading the source file or writing the output + */ + public void render(final HTMLElement parent, final ISourceNode source, + final Reader contents) throws IOException { + final HTMLElement pre = parent.pre(Styles.SOURCE + " lang-" + lang + + " linenums"); + final BufferedReader lineBuffer = new BufferedReader(contents); + String line; + int nr = 0; + while ((line = lineBuffer.readLine()) != null) { + nr++; + renderCodeLine(pre, line, source.getLine(nr), nr); + } + } + + private void renderCodeLine(final HTMLElement pre, final String linesrc, + final ILine line, final int lineNr) throws IOException { + highlight(pre, line, lineNr).text(linesrc); + pre.text("\n"); + } + + HTMLElement highlight(final HTMLElement pre, final ILine line, + final int lineNr) throws IOException { + final String style; + switch (line.getStatus()) { + case ICounter.NOT_COVERED: + style = Styles.NOT_COVERED; + break; + case ICounter.FULLY_COVERED: + style = Styles.FULLY_COVERED; + break; + case ICounter.PARTLY_COVERED: + style = Styles.PARTLY_COVERED; + break; + default: + return pre; + } + + final String lineId = "L" + Integer.toString(lineNr); + final ICounter branches = line.getBranchCounter(); + switch (branches.getStatus()) { + case ICounter.NOT_COVERED: + return span(pre, lineId, style, Styles.BRANCH_NOT_COVERED, + "All %2$d branches missed.", branches); + case ICounter.FULLY_COVERED: + return span(pre, lineId, style, Styles.BRANCH_FULLY_COVERED, + "All %2$d branches covered.", branches); + case ICounter.PARTLY_COVERED: + return span(pre, lineId, style, Styles.BRANCH_PARTLY_COVERED, + "%1$d of %2$d branches missed.", branches); + default: + return pre.span(style, lineId); + } + } + + private HTMLElement span(final HTMLElement parent, final String id, + final String style1, final String style2, final String title, + final ICounter branches) throws IOException { + final HTMLElement span = parent.span(style1 + " " + style2, id); + final Integer missed = Integer.valueOf(branches.getMissedCount()); + final Integer total = Integer.valueOf(branches.getTotalCount()); + span.attr("title", String.format(locale, title, missed, total)); + return span; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/page/TablePage.java b/org.jacoco.report/src/org/jacoco/report/internal/html/page/TablePage.java index 956f2ba4..81c25275 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/page/TablePage.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/page/TablePage.java @@ -1,78 +1,78 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.page;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.IHTMLReportContext;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.jacoco.report.internal.html.table.ITableItem;
-
-/**
- * Report page that contains a table of items linked to other pages.
- *
- * @param <NodeType>
- * type of the node represented by this page
- */
-public abstract class TablePage<NodeType extends ICoverageNode> extends
- NodePage<NodeType> {
-
- private final List<ITableItem> items = new ArrayList<ITableItem>();
-
- /**
- * Creates a new node page.
- *
- * @param node
- * corresponding node
- * @param parent
- * optional hierarchical parent
- * @param folder
- * base folder to create this report in
- * @param context
- * settings context
- */
- protected TablePage(final NodeType node, final ReportPage parent,
- final ReportOutputFolder folder, final IHTMLReportContext context) {
- super(node, parent, folder, context);
- }
-
- /**
- * Adds the given item to the table. Method must be called before the page
- * is rendered.
- *
- * @param item
- */
- public void addItem(final ITableItem item) {
- items.add(item);
- }
-
- @Override
- protected void head(final HTMLElement head) throws IOException {
- super.head(head);
- head.script("text/javascript",
- context.getResources().getLink(folder, Resources.SORT_SCRIPT));
- }
-
- @Override
- protected void content(final HTMLElement body) throws IOException {
- context.getTable().render(body, items, getNode(),
- context.getResources(), folder);
- // free memory, otherwise we will keep the complete page tree:
- items.clear();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.page; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.IHTMLReportContext; +import org.jacoco.report.internal.html.resources.Resources; +import org.jacoco.report.internal.html.table.ITableItem; + +/** + * Report page that contains a table of items linked to other pages. + * + * @param <NodeType> + * type of the node represented by this page + */ +public abstract class TablePage<NodeType extends ICoverageNode> extends + NodePage<NodeType> { + + private final List<ITableItem> items = new ArrayList<ITableItem>(); + + /** + * Creates a new node page. + * + * @param node + * corresponding node + * @param parent + * optional hierarchical parent + * @param folder + * base folder to create this report in + * @param context + * settings context + */ + protected TablePage(final NodeType node, final ReportPage parent, + final ReportOutputFolder folder, final IHTMLReportContext context) { + super(node, parent, folder, context); + } + + /** + * Adds the given item to the table. Method must be called before the page + * is rendered. + * + * @param item + */ + public void addItem(final ITableItem item) { + items.add(item); + } + + @Override + protected void head(final HTMLElement head) throws IOException { + super.head(head); + head.script("text/javascript", + context.getResources().getLink(folder, Resources.SORT_SCRIPT)); + } + + @Override + protected void content(final HTMLElement body) throws IOException { + context.getTable().render(body, items, getNode(), + context.getResources(), folder); + // free memory, otherwise we will keep the complete page tree: + items.clear(); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/resources/Resources.java b/org.jacoco.report/src/org/jacoco/report/internal/html/resources/Resources.java index f6264c77..b94ae6a1 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/resources/Resources.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/resources/Resources.java @@ -1,136 +1,136 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.resources;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.jacoco.core.analysis.ICoverageNode.ElementType;
-import org.jacoco.report.internal.ReportOutputFolder;
-
-/**
- * Static resource that are included with the coverage report and might be
- * referenced from created HTML pages.
- */
-public class Resources {
-
- /** The name of the style sheet */
- public static final String STYLESHEET = "report.css";
-
- /** The name of the prettify style sheet */
- public static final String PRETTIFY_STYLESHEET = "prettify.css";
-
- /** The name of the prettify script */
- public static final String PRETTIFY_SCRIPT = "prettify.js";
-
- /** The name of the sort script */
- public static final String SORT_SCRIPT = "sort.js";
-
- /** The name of the red part of the coverage bar */
- public static final String REDBAR = "redbar.gif";
-
- /** The name of the green part of the coverage bar */
- public static final String GREENBAR = "greenbar.gif";
-
- private final ReportOutputFolder folder;
-
- /**
- * Attaches resources to the report with the given root folder.
- *
- * @param root
- * root folder of the report
- */
- public Resources(final ReportOutputFolder root) {
- folder = root.subFolder(".resources");
- }
-
- /**
- * Returns a relative link to a static resource.
- *
- * @param base
- * base folder from where the link should be created
- * @param name
- * name of the static resource, see constants in this class
- * @return relative link
- */
- public String getLink(final ReportOutputFolder base, final String name) {
- return folder.getLink(base, name);
- }
-
- /**
- * Determines the style sheet class for the given element type.
- *
- * @param type
- * type of the element
- * @return style class name
- */
- public static String getElementStyle(final ElementType type) {
- switch (type) {
- case GROUP:
- return Styles.EL_GROUP;
- case BUNDLE:
- return Styles.EL_BUNDLE;
- case PACKAGE:
- return Styles.EL_PACKAGE;
- case SOURCEFILE:
- return Styles.EL_SOURCE;
- case CLASS:
- return Styles.EL_CLASS;
- case METHOD:
- return Styles.EL_METHOD;
- }
- throw new AssertionError("Unknown element type: " + type);
- }
-
- /**
- * Copies all static resources into the report.
- *
- * @throws IOException
- * if the resources can't be written to the report
- */
- public void copyResources() throws IOException {
- copyResource(STYLESHEET);
- copyResource("report.gif");
- copyResource("group.gif");
- copyResource("bundle.gif");
- copyResource("package.gif");
- copyResource("source.gif");
- copyResource("class.gif");
- copyResource("method.gif");
- copyResource("session.gif");
- copyResource("sort.gif");
- copyResource("up.gif");
- copyResource("down.gif");
- copyResource("branchfc.gif");
- copyResource("branchnc.gif");
- copyResource("branchpc.gif");
- copyResource(REDBAR);
- copyResource(GREENBAR);
- copyResource(PRETTIFY_STYLESHEET);
- copyResource(PRETTIFY_SCRIPT);
- copyResource(SORT_SCRIPT);
- }
-
- private void copyResource(final String name) throws IOException {
- final InputStream in = Resources.class.getResourceAsStream(name);
- final OutputStream out = folder.createFile(name);
- final byte[] buffer = new byte[256];
- int len;
- while ((len = in.read(buffer)) != -1) {
- out.write(buffer, 0, len);
- }
- in.close();
- out.close();
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.resources; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.jacoco.core.analysis.ICoverageNode.ElementType; +import org.jacoco.report.internal.ReportOutputFolder; + +/** + * Static resource that are included with the coverage report and might be + * referenced from created HTML pages. + */ +public class Resources { + + /** The name of the style sheet */ + public static final String STYLESHEET = "report.css"; + + /** The name of the prettify style sheet */ + public static final String PRETTIFY_STYLESHEET = "prettify.css"; + + /** The name of the prettify script */ + public static final String PRETTIFY_SCRIPT = "prettify.js"; + + /** The name of the sort script */ + public static final String SORT_SCRIPT = "sort.js"; + + /** The name of the red part of the coverage bar */ + public static final String REDBAR = "redbar.gif"; + + /** The name of the green part of the coverage bar */ + public static final String GREENBAR = "greenbar.gif"; + + private final ReportOutputFolder folder; + + /** + * Attaches resources to the report with the given root folder. + * + * @param root + * root folder of the report + */ + public Resources(final ReportOutputFolder root) { + folder = root.subFolder(".resources"); + } + + /** + * Returns a relative link to a static resource. + * + * @param base + * base folder from where the link should be created + * @param name + * name of the static resource, see constants in this class + * @return relative link + */ + public String getLink(final ReportOutputFolder base, final String name) { + return folder.getLink(base, name); + } + + /** + * Determines the style sheet class for the given element type. + * + * @param type + * type of the element + * @return style class name + */ + public static String getElementStyle(final ElementType type) { + switch (type) { + case GROUP: + return Styles.EL_GROUP; + case BUNDLE: + return Styles.EL_BUNDLE; + case PACKAGE: + return Styles.EL_PACKAGE; + case SOURCEFILE: + return Styles.EL_SOURCE; + case CLASS: + return Styles.EL_CLASS; + case METHOD: + return Styles.EL_METHOD; + } + throw new AssertionError("Unknown element type: " + type); + } + + /** + * Copies all static resources into the report. + * + * @throws IOException + * if the resources can't be written to the report + */ + public void copyResources() throws IOException { + copyResource(STYLESHEET); + copyResource("report.gif"); + copyResource("group.gif"); + copyResource("bundle.gif"); + copyResource("package.gif"); + copyResource("source.gif"); + copyResource("class.gif"); + copyResource("method.gif"); + copyResource("session.gif"); + copyResource("sort.gif"); + copyResource("up.gif"); + copyResource("down.gif"); + copyResource("branchfc.gif"); + copyResource("branchnc.gif"); + copyResource("branchpc.gif"); + copyResource(REDBAR); + copyResource(GREENBAR); + copyResource(PRETTIFY_STYLESHEET); + copyResource(PRETTIFY_SCRIPT); + copyResource(SORT_SCRIPT); + } + + private void copyResource(final String name) throws IOException { + final InputStream in = Resources.class.getResourceAsStream(name); + final OutputStream out = folder.createFile(name); + final byte[] buffer = new byte[256]; + int len; + while ((len = in.read(buffer)) != -1) { + out.write(buffer, 0, len); + } + in.close(); + out.close(); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/resources/Styles.java b/org.jacoco.report/src/org/jacoco/report/internal/html/resources/Styles.java index 7d3b9f9f..6dbf0ef8 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/resources/Styles.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/resources/Styles.java @@ -1,120 +1,120 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.resources;
-
-/**
- * Constants for styles defined by the report style sheet.
- */
-public final class Styles {
-
- /** Breadcrumb bar */
- public static final String BREADCRUMB = "breadcrumb";
-
- /** Footer */
- public static final String FOOTER = "footer";
-
- /** Text block aligned to the right */
- public static final String RIGHT = "right";
-
- /** Report element */
- public static final String EL_REPORT = "el_report";
-
- /** Sessions element */
- public static final String EL_SESSION = "el_session";
-
- /** Group element */
- public static final String EL_GROUP = "el_group";
-
- /** Bundle element */
- public static final String EL_BUNDLE = "el_bundle";
-
- /** Package element */
- public static final String EL_PACKAGE = "el_package";
-
- /** Source file element */
- public static final String EL_SOURCE = "el_source";
-
- /** Class element */
- public static final String EL_CLASS = "el_class";
-
- /** Method element */
- public static final String EL_METHOD = "el_method";
-
- /** Coverage table */
- public static final String COVERAGETABLE = "coverage";
-
- /** Table cells for a graphical bar */
- public static final String BAR = "bar";
-
- /** Table cells for the first column of a counter */
- public static final String CTR1 = "ctr1";
-
- /** Table cells for the second column of a counter */
- public static final String CTR2 = "ctr2";
-
- /** Table header for sortable columns */
- public static final String SORTABLE = "sortable";
-
- /** Table header for column sorted upwards */
- public static final String UP = "up";
-
- /** Table header for column sorted downwards */
- public static final String DOWN = "down";
-
- /** Block of source code */
- public static final String SOURCE = "source";
-
- /** Line number before each source line */
- public static final String NR = "nr";
-
- /** Part of source code where instructions are not covered */
- public static final String NOT_COVERED = "nc";
-
- /** Part of source code where instructions are partly covered */
- public static final String PARTLY_COVERED = "pc";
-
- /** Part of source code where instructions are is fully covered */
- public static final String FULLY_COVERED = "fc";
-
- /** Part of source code where branches are not covered */
- public static final String BRANCH_NOT_COVERED = "bnc";
-
- /** Part of source code where branches are partly covered */
- public static final String BRANCH_PARTLY_COVERED = "bpc";
-
- /** Part of source code where branches are fully covered */
- public static final String BRANCH_FULLY_COVERED = "bfc";
-
- /**
- * Returns a combined style from the given styles.
- *
- * @param styles
- * list of separate styles, entries might be null
- * @return combined style or <code>null</code> if no style is given
- */
- public static String combine(final String... styles) {
- final StringBuilder sb = new StringBuilder();
- for (final String style : styles) {
- if (style != null) {
- if (sb.length() > 0) {
- sb.append(" ");
- }
- sb.append(style);
- }
- }
- return sb.length() == 0 ? null : sb.toString();
- }
-
- private Styles() {
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.resources; + +/** + * Constants for styles defined by the report style sheet. + */ +public final class Styles { + + /** Breadcrumb bar */ + public static final String BREADCRUMB = "breadcrumb"; + + /** Footer */ + public static final String FOOTER = "footer"; + + /** Text block aligned to the right */ + public static final String RIGHT = "right"; + + /** Report element */ + public static final String EL_REPORT = "el_report"; + + /** Sessions element */ + public static final String EL_SESSION = "el_session"; + + /** Group element */ + public static final String EL_GROUP = "el_group"; + + /** Bundle element */ + public static final String EL_BUNDLE = "el_bundle"; + + /** Package element */ + public static final String EL_PACKAGE = "el_package"; + + /** Source file element */ + public static final String EL_SOURCE = "el_source"; + + /** Class element */ + public static final String EL_CLASS = "el_class"; + + /** Method element */ + public static final String EL_METHOD = "el_method"; + + /** Coverage table */ + public static final String COVERAGETABLE = "coverage"; + + /** Table cells for a graphical bar */ + public static final String BAR = "bar"; + + /** Table cells for the first column of a counter */ + public static final String CTR1 = "ctr1"; + + /** Table cells for the second column of a counter */ + public static final String CTR2 = "ctr2"; + + /** Table header for sortable columns */ + public static final String SORTABLE = "sortable"; + + /** Table header for column sorted upwards */ + public static final String UP = "up"; + + /** Table header for column sorted downwards */ + public static final String DOWN = "down"; + + /** Block of source code */ + public static final String SOURCE = "source"; + + /** Line number before each source line */ + public static final String NR = "nr"; + + /** Part of source code where instructions are not covered */ + public static final String NOT_COVERED = "nc"; + + /** Part of source code where instructions are partly covered */ + public static final String PARTLY_COVERED = "pc"; + + /** Part of source code where instructions are is fully covered */ + public static final String FULLY_COVERED = "fc"; + + /** Part of source code where branches are not covered */ + public static final String BRANCH_NOT_COVERED = "bnc"; + + /** Part of source code where branches are partly covered */ + public static final String BRANCH_PARTLY_COVERED = "bpc"; + + /** Part of source code where branches are fully covered */ + public static final String BRANCH_FULLY_COVERED = "bfc"; + + /** + * Returns a combined style from the given styles. + * + * @param styles + * list of separate styles, entries might be null + * @return combined style or <code>null</code> if no style is given + */ + public static String combine(final String... styles) { + final StringBuilder sb = new StringBuilder(); + for (final String style : styles) { + if (style != null) { + if (sb.length() > 0) { + sb.append(" "); + } + sb.append(style); + } + } + return sb.length() == 0 ? null : sb.toString(); + } + + private Styles() { + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/resources/report.css b/org.jacoco.report/src/org/jacoco/report/internal/html/resources/report.css index 27e6ca7f..98d385f2 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/resources/report.css +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/resources/report.css @@ -1,236 +1,236 @@ -body, td {
- font-family:sans-serif;
- font-size:10pt;
-}
-
-h1 {
- font-weight:bold;
- font-size:18pt;
-}
-
-.breadcrumb {
- border:#d6d3ce 1px solid;
- padding:2px 4px 2px 4px;
-}
-
-
-.el_report {
- padding-left:18px;
- background-image:url(report.gif);
- background-position:left center;
- background-repeat:no-repeat;
-}
-
-.el_group {
- padding-left:18px;
- background-image:url(group.gif);
- background-position:left center;
- background-repeat:no-repeat;
-}
-
-.el_bundle {
- padding-left:18px;
- background-image:url(bundle.gif);
- background-position:left center;
- background-repeat:no-repeat;
-}
-
-.el_package {
- padding-left:18px;
- background-image:url(package.gif);
- background-position:left center;
- background-repeat:no-repeat;
-}
-
-.el_class {
- padding-left:18px;
- background-image:url(class.gif);
- background-position:left center;
- background-repeat:no-repeat;
-}
-
-.el_source {
- padding-left:18px;
- background-image:url(source.gif);
- background-position:left center;
- background-repeat:no-repeat;
-}
-
-.el_method {
- padding-left:18px;
- background-image:url(method.gif);
- background-position:left center;
- background-repeat:no-repeat;
-}
-
-.el_session {
- padding-left:18px;
- background-image:url(session.gif);
- background-position:left center;
- background-repeat:no-repeat;
-}
-
-pre.source {
- border:#d6d3ce 1px solid;
- font-family:monospace;
-}
-
-pre.source ol {
- margin-bottom: 0px;
- margin-top: 0px;
-}
-
-pre.source li {
- border-left: 1px solid #D6D3CE;
- color: #A0A0A0;
- padding-left: 0px;
-}
-
-pre.source span.fc {
- background-color:#ccffcc;
-}
-
-pre.source span.nc {
- background-color:#ffcccc;
-}
-
-pre.source span.pc {
- background-color:#ffffcc;
-}
-
-pre.source span.bfc {
- background-image: url(branchfc.gif);
- background-repeat: no-repeat;
- background-position: 2px center;
-}
-
-pre.source span.bfc:hover {
- background-color:#80ff80;
-}
-
-pre.source span.bnc {
- background-image: url(branchnc.gif);
- background-repeat: no-repeat;
- background-position: 2px center;
-}
-
-pre.source span.bnc:hover {
- background-color:#ff8080;
-}
-
-pre.source span.bpc {
- background-image: url(branchpc.gif);
- background-repeat: no-repeat;
- background-position: 2px center;
-}
-
-pre.source span.bpc:hover {
- background-color:#ffff80;
-}
-
-table.coverage {
- empty-cells:show;
- border-collapse:collapse;
-}
-
-table.coverage thead {
- background-color:#e0e0e0;
-}
-
-table.coverage thead td {
- white-space:nowrap;
- padding:2px 14px 0px 6px;
- border-bottom:#b0b0b0 1px solid;
-}
-
-table.coverage thead td.bar {
- border-left:#cccccc 1px solid;
-}
-
-table.coverage thead td.ctr1 {
- text-align:right;
- border-left:#cccccc 1px solid;
-}
-
-table.coverage thead td.ctr2 {
- text-align:right;
- padding-left:2px;
-}
-
-table.coverage thead td.sortable {
- cursor:pointer;
- background-image:url(sort.gif);
- background-position:right center;
- background-repeat:no-repeat;
-}
-
-table.coverage thead td.up {
- background-image:url(up.gif);
-}
-
-table.coverage thead td.down {
- background-image:url(down.gif);
-}
-
-table.coverage tbody td {
- white-space:nowrap;
- padding:2px 6px 2px 6px;
- border-bottom:#d6d3ce 1px solid;
-}
-
-table.coverage tbody tr:hover {
- background: #f0f0d0 !important;
-}
-
-table.coverage tbody td.bar {
- border-left:#e8e8e8 1px solid;
-}
-
-table.coverage tbody td.ctr1 {
- text-align:right;
- padding-right:14px;
- border-left:#e8e8e8 1px solid;
-}
-
-table.coverage tbody td.ctr2 {
- text-align:right;
- padding-right:14px;
- padding-left:2px;
-}
-
-table.coverage tfoot td {
- white-space:nowrap;
- padding:2px 6px 2px 6px;
-}
-
-table.coverage tfoot td.bar {
- border-left:#e8e8e8 1px solid;
-}
-
-table.coverage tfoot td.ctr1 {
- text-align:right;
- padding-right:14px;
- border-left:#e8e8e8 1px solid;
-}
-
-table.coverage tfoot td.ctr2 {
- text-align:right;
- padding-right:14px;
- padding-left:2px;
-}
-
-.footer {
- margin-top:20px;
- border-top:#d6d3ce 1px solid;
- padding-top:2px;
- font-size:8pt;
- color:#a0a0a0;
-}
-
-.footer a {
- color:#a0a0a0;
-}
-
-.right {
- float:right;
-}
+body, td { + font-family:sans-serif; + font-size:10pt; +} + +h1 { + font-weight:bold; + font-size:18pt; +} + +.breadcrumb { + border:#d6d3ce 1px solid; + padding:2px 4px 2px 4px; +} + + +.el_report { + padding-left:18px; + background-image:url(report.gif); + background-position:left center; + background-repeat:no-repeat; +} + +.el_group { + padding-left:18px; + background-image:url(group.gif); + background-position:left center; + background-repeat:no-repeat; +} + +.el_bundle { + padding-left:18px; + background-image:url(bundle.gif); + background-position:left center; + background-repeat:no-repeat; +} + +.el_package { + padding-left:18px; + background-image:url(package.gif); + background-position:left center; + background-repeat:no-repeat; +} + +.el_class { + padding-left:18px; + background-image:url(class.gif); + background-position:left center; + background-repeat:no-repeat; +} + +.el_source { + padding-left:18px; + background-image:url(source.gif); + background-position:left center; + background-repeat:no-repeat; +} + +.el_method { + padding-left:18px; + background-image:url(method.gif); + background-position:left center; + background-repeat:no-repeat; +} + +.el_session { + padding-left:18px; + background-image:url(session.gif); + background-position:left center; + background-repeat:no-repeat; +} + +pre.source { + border:#d6d3ce 1px solid; + font-family:monospace; +} + +pre.source ol { + margin-bottom: 0px; + margin-top: 0px; +} + +pre.source li { + border-left: 1px solid #D6D3CE; + color: #A0A0A0; + padding-left: 0px; +} + +pre.source span.fc { + background-color:#ccffcc; +} + +pre.source span.nc { + background-color:#ffcccc; +} + +pre.source span.pc { + background-color:#ffffcc; +} + +pre.source span.bfc { + background-image: url(branchfc.gif); + background-repeat: no-repeat; + background-position: 2px center; +} + +pre.source span.bfc:hover { + background-color:#80ff80; +} + +pre.source span.bnc { + background-image: url(branchnc.gif); + background-repeat: no-repeat; + background-position: 2px center; +} + +pre.source span.bnc:hover { + background-color:#ff8080; +} + +pre.source span.bpc { + background-image: url(branchpc.gif); + background-repeat: no-repeat; + background-position: 2px center; +} + +pre.source span.bpc:hover { + background-color:#ffff80; +} + +table.coverage { + empty-cells:show; + border-collapse:collapse; +} + +table.coverage thead { + background-color:#e0e0e0; +} + +table.coverage thead td { + white-space:nowrap; + padding:2px 14px 0px 6px; + border-bottom:#b0b0b0 1px solid; +} + +table.coverage thead td.bar { + border-left:#cccccc 1px solid; +} + +table.coverage thead td.ctr1 { + text-align:right; + border-left:#cccccc 1px solid; +} + +table.coverage thead td.ctr2 { + text-align:right; + padding-left:2px; +} + +table.coverage thead td.sortable { + cursor:pointer; + background-image:url(sort.gif); + background-position:right center; + background-repeat:no-repeat; +} + +table.coverage thead td.up { + background-image:url(up.gif); +} + +table.coverage thead td.down { + background-image:url(down.gif); +} + +table.coverage tbody td { + white-space:nowrap; + padding:2px 6px 2px 6px; + border-bottom:#d6d3ce 1px solid; +} + +table.coverage tbody tr:hover { + background: #f0f0d0 !important; +} + +table.coverage tbody td.bar { + border-left:#e8e8e8 1px solid; +} + +table.coverage tbody td.ctr1 { + text-align:right; + padding-right:14px; + border-left:#e8e8e8 1px solid; +} + +table.coverage tbody td.ctr2 { + text-align:right; + padding-right:14px; + padding-left:2px; +} + +table.coverage tfoot td { + white-space:nowrap; + padding:2px 6px 2px 6px; +} + +table.coverage tfoot td.bar { + border-left:#e8e8e8 1px solid; +} + +table.coverage tfoot td.ctr1 { + text-align:right; + padding-right:14px; + border-left:#e8e8e8 1px solid; +} + +table.coverage tfoot td.ctr2 { + text-align:right; + padding-right:14px; + padding-left:2px; +} + +.footer { + margin-top:20px; + border-top:#d6d3ce 1px solid; + padding-top:2px; + font-size:8pt; + color:#a0a0a0; +} + +.footer a { + color:#a0a0a0; +} + +.right { + float:right; +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/table/BarColumn.java b/org.jacoco.report/src/org/jacoco/report/internal/html/table/BarColumn.java index 5acdffba..0e060ba8 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/table/BarColumn.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/table/BarColumn.java @@ -1,109 +1,109 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import java.io.IOException;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Locale;
-
-import org.jacoco.core.analysis.CounterComparator;
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.resources.Resources;
-
-/**
- * Column with a graphical bar that represents the total amount of items in with
- * length, and the coverage ratio with a red/green sections. The implementation
- * is stateful, instances must not be used in parallel.
- */
-public class BarColumn implements IColumnRenderer {
-
- private static final int WIDTH = 120;
-
- private final CounterEntity entity;
-
- private final NumberFormat integerFormat;
-
- private int max;
-
- private final Comparator<ITableItem> comparator;
-
- /**
- * Creates a new column that is based on the {@link ICounter} for the given
- * entity.
- *
- * @param entity
- * counter entity for visualization
- * @param locale
- * locale for rendering numbers
- */
- public BarColumn(final CounterEntity entity, final Locale locale) {
- this.entity = entity;
- this.integerFormat = DecimalFormat.getIntegerInstance(locale);
- this.comparator = new TableItemComparator(CounterComparator.MISSEDITEMS
- .reverse().on(entity)
- .second(CounterComparator.TOTALITEMS.reverse().on(entity)));
- }
-
- public boolean init(final List<? extends ITableItem> items,
- final ICoverageNode total) {
- this.max = 0;
- for (final ITableItem item : items) {
- final int count = item.getNode().getCounter(entity).getTotalCount();
- if (count > this.max) {
- this.max = count;
- }
- }
- return true;
- }
-
- public void footer(final HTMLElement td, final ICoverageNode total,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- final ICounter counter = total.getCounter(entity);
- td.text(integerFormat.format(counter.getMissedCount())).text(" of ")
- .text(integerFormat.format(counter.getTotalCount()));
- }
-
- public void item(final HTMLElement td, final ITableItem item,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- if (max > 0) {
- final ICounter counter = item.getNode().getCounter(entity);
- final int missed = counter.getMissedCount();
- bar(td, missed, Resources.REDBAR, resources, base);
- final int covered = counter.getCoveredCount();
- bar(td, covered, Resources.GREENBAR, resources, base);
- }
- }
-
- private void bar(final HTMLElement td, final int count, final String image,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- final int width = count * WIDTH / max;
- if (width > 0) {
- td.img(resources.getLink(base, image), width, 10,
- integerFormat.format(count));
- }
- }
-
- public Comparator<ITableItem> getComparator() {
- return comparator;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; + +import org.jacoco.core.analysis.CounterComparator; +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.resources.Resources; + +/** + * Column with a graphical bar that represents the total amount of items in with + * length, and the coverage ratio with a red/green sections. The implementation + * is stateful, instances must not be used in parallel. + */ +public class BarColumn implements IColumnRenderer { + + private static final int WIDTH = 120; + + private final CounterEntity entity; + + private final NumberFormat integerFormat; + + private int max; + + private final Comparator<ITableItem> comparator; + + /** + * Creates a new column that is based on the {@link ICounter} for the given + * entity. + * + * @param entity + * counter entity for visualization + * @param locale + * locale for rendering numbers + */ + public BarColumn(final CounterEntity entity, final Locale locale) { + this.entity = entity; + this.integerFormat = DecimalFormat.getIntegerInstance(locale); + this.comparator = new TableItemComparator(CounterComparator.MISSEDITEMS + .reverse().on(entity) + .second(CounterComparator.TOTALITEMS.reverse().on(entity))); + } + + public boolean init(final List<? extends ITableItem> items, + final ICoverageNode total) { + this.max = 0; + for (final ITableItem item : items) { + final int count = item.getNode().getCounter(entity).getTotalCount(); + if (count > this.max) { + this.max = count; + } + } + return true; + } + + public void footer(final HTMLElement td, final ICoverageNode total, + final Resources resources, final ReportOutputFolder base) + throws IOException { + final ICounter counter = total.getCounter(entity); + td.text(integerFormat.format(counter.getMissedCount())).text(" of ") + .text(integerFormat.format(counter.getTotalCount())); + } + + public void item(final HTMLElement td, final ITableItem item, + final Resources resources, final ReportOutputFolder base) + throws IOException { + if (max > 0) { + final ICounter counter = item.getNode().getCounter(entity); + final int missed = counter.getMissedCount(); + bar(td, missed, Resources.REDBAR, resources, base); + final int covered = counter.getCoveredCount(); + bar(td, covered, Resources.GREENBAR, resources, base); + } + } + + private void bar(final HTMLElement td, final int count, final String image, + final Resources resources, final ReportOutputFolder base) + throws IOException { + final int width = count * WIDTH / max; + if (width > 0) { + td.img(resources.getLink(base, image), width, 10, + integerFormat.format(count)); + } + } + + public Comparator<ITableItem> getComparator() { + return comparator; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/table/CounterColumn.java b/org.jacoco.report/src/org/jacoco/report/internal/html/table/CounterColumn.java index b81d5191..5ae7f6da 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/table/CounterColumn.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/table/CounterColumn.java @@ -1,161 +1,161 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import java.io.IOException;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Locale;
-
-import org.jacoco.core.analysis.CounterComparator;
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.resources.Resources;
-
-/**
- * Column that prints the counter values of entities for each item and a summary
- * in the footer. If the total number of items is zero, no column is emitted at
- * all. The implementation is stateful, instances must not be used in parallel.
- */
-public abstract class CounterColumn implements IColumnRenderer {
-
- /**
- * Creates a new column that shows the total count for the given entity.
- *
- * @param entity
- * counter entity for this column
- * @param locale
- * locale for rendering numbers
- * @return column instance
- */
- public static CounterColumn newTotal(final CounterEntity entity,
- final Locale locale) {
- return new CounterColumn(entity, locale, CounterComparator.TOTALITEMS
- .reverse().on(entity)) {
- @Override
- protected int getValue(final ICounter counter) {
- return counter.getTotalCount();
- }
- };
- }
-
- /**
- * Creates a new column that shows the missed count for the given entity.
- *
- * @param entity
- * counter entity for this column
- * @param locale
- * locale for rendering numbers
- * @return column instance
- */
- public static CounterColumn newMissed(final CounterEntity entity,
- final Locale locale) {
- return new CounterColumn(entity, locale, CounterComparator.MISSEDITEMS
- .reverse().on(entity)) {
- @Override
- protected int getValue(final ICounter counter) {
- return counter.getMissedCount();
- }
- };
- }
-
- /**
- * Creates a new column that shows the covered count for the given entity.
- *
- * @param entity
- * counter entity for this column
- * @param locale
- * locale for rendering numbers
- * @return column instance
- */
- public static CounterColumn newCovered(final CounterEntity entity,
- final Locale locale) {
- return new CounterColumn(entity, locale, CounterComparator.COVEREDITEMS
- .reverse().on(entity)) {
- @Override
- protected int getValue(final ICounter counter) {
- return counter.getCoveredCount();
- }
- };
- }
-
- private final CounterEntity entity;
-
- private final NumberFormat integerFormat;
-
- private final Comparator<ITableItem> comparator;
-
- /**
- * Creates a new column that is based on the {@link ICounter} for the given
- * entity.
- *
- * @param entity
- * counter entity for this column
- * @param locale
- * locale for rendering numbers
- * @param comparator
- * comparator for the nodes of this column
- */
- protected CounterColumn(final CounterEntity entity, final Locale locale,
- final Comparator<ICoverageNode> comparator) {
- this.entity = entity;
- this.integerFormat = DecimalFormat.getIntegerInstance(locale);
- this.comparator = new TableItemComparator(comparator);
- }
-
- public boolean init(final List<? extends ITableItem> items,
- final ICoverageNode total) {
- for (final ITableItem i : items) {
- if (i.getNode().getCounter(entity).getTotalCount() > 0) {
- return true;
- }
- }
- return false;
- }
-
- public void footer(final HTMLElement td, final ICoverageNode total,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- cell(td, total);
- }
-
- public void item(final HTMLElement td, final ITableItem item,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- cell(td, item.getNode());
- }
-
- private void cell(final HTMLElement td, final ICoverageNode node)
- throws IOException {
- final int value = getValue(node.getCounter(entity));
- td.text(integerFormat.format(value));
- }
-
- public Comparator<ITableItem> getComparator() {
- return comparator;
- }
-
- /**
- * Retrieves the respective value from the counter.
- *
- * @param counter
- * counter object
- * @return value of interest
- */
- protected abstract int getValue(ICounter counter);
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; + +import org.jacoco.core.analysis.CounterComparator; +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.resources.Resources; + +/** + * Column that prints the counter values of entities for each item and a summary + * in the footer. If the total number of items is zero, no column is emitted at + * all. The implementation is stateful, instances must not be used in parallel. + */ +public abstract class CounterColumn implements IColumnRenderer { + + /** + * Creates a new column that shows the total count for the given entity. + * + * @param entity + * counter entity for this column + * @param locale + * locale for rendering numbers + * @return column instance + */ + public static CounterColumn newTotal(final CounterEntity entity, + final Locale locale) { + return new CounterColumn(entity, locale, CounterComparator.TOTALITEMS + .reverse().on(entity)) { + @Override + protected int getValue(final ICounter counter) { + return counter.getTotalCount(); + } + }; + } + + /** + * Creates a new column that shows the missed count for the given entity. + * + * @param entity + * counter entity for this column + * @param locale + * locale for rendering numbers + * @return column instance + */ + public static CounterColumn newMissed(final CounterEntity entity, + final Locale locale) { + return new CounterColumn(entity, locale, CounterComparator.MISSEDITEMS + .reverse().on(entity)) { + @Override + protected int getValue(final ICounter counter) { + return counter.getMissedCount(); + } + }; + } + + /** + * Creates a new column that shows the covered count for the given entity. + * + * @param entity + * counter entity for this column + * @param locale + * locale for rendering numbers + * @return column instance + */ + public static CounterColumn newCovered(final CounterEntity entity, + final Locale locale) { + return new CounterColumn(entity, locale, CounterComparator.COVEREDITEMS + .reverse().on(entity)) { + @Override + protected int getValue(final ICounter counter) { + return counter.getCoveredCount(); + } + }; + } + + private final CounterEntity entity; + + private final NumberFormat integerFormat; + + private final Comparator<ITableItem> comparator; + + /** + * Creates a new column that is based on the {@link ICounter} for the given + * entity. + * + * @param entity + * counter entity for this column + * @param locale + * locale for rendering numbers + * @param comparator + * comparator for the nodes of this column + */ + protected CounterColumn(final CounterEntity entity, final Locale locale, + final Comparator<ICoverageNode> comparator) { + this.entity = entity; + this.integerFormat = DecimalFormat.getIntegerInstance(locale); + this.comparator = new TableItemComparator(comparator); + } + + public boolean init(final List<? extends ITableItem> items, + final ICoverageNode total) { + for (final ITableItem i : items) { + if (i.getNode().getCounter(entity).getTotalCount() > 0) { + return true; + } + } + return false; + } + + public void footer(final HTMLElement td, final ICoverageNode total, + final Resources resources, final ReportOutputFolder base) + throws IOException { + cell(td, total); + } + + public void item(final HTMLElement td, final ITableItem item, + final Resources resources, final ReportOutputFolder base) + throws IOException { + cell(td, item.getNode()); + } + + private void cell(final HTMLElement td, final ICoverageNode node) + throws IOException { + final int value = getValue(node.getCounter(entity)); + td.text(integerFormat.format(value)); + } + + public Comparator<ITableItem> getComparator() { + return comparator; + } + + /** + * Retrieves the respective value from the counter. + * + * @param counter + * counter object + * @return value of interest + */ + protected abstract int getValue(ICounter counter); + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/table/IColumnRenderer.java b/org.jacoco.report/src/org/jacoco/report/internal/html/table/IColumnRenderer.java index 0085bec4..741303f5 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/table/IColumnRenderer.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/table/IColumnRenderer.java @@ -1,82 +1,82 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import java.io.IOException;
-import java.util.Comparator;
-import java.util.List;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.resources.Resources;
-
-/**
- * Renderer for a single column of a coverage table. The methods are always
- * called in the sequence <code>init header footer item*</code>. Implementations
- * might be stateful.
- */
-public interface IColumnRenderer {
-
- /**
- * Initializes the column before any output method is called.
- *
- * @param items
- * all items that will be displayed in the table
- * @param total
- * the summary of all coverage data items in the table
- * @return <code>true</code> if the column should be visible
- */
- public boolean init(List<? extends ITableItem> items, ICoverageNode total);
-
- /**
- * Renders the footer for this column.
- *
- * @param td
- * the parent table cell
- * @param total
- * the summary of all coverage data items in the table
- * @param resources
- * static resources that might be referenced
- * @param base
- * base folder of the table
- * @throws IOException
- * in case of IO problems with the element output
- */
- public void footer(HTMLElement td, ICoverageNode total,
- Resources resources, ReportOutputFolder base) throws IOException;
-
- /**
- * Renders a single item in this column.
- *
- * @param td
- * the parent table cell
- * @param item
- * the item to display
- * @param resources
- * static resources that might be referenced
- * @param base
- * base folder of the table
- * @throws IOException
- * in case of IO problems with the element output
- */
- public void item(HTMLElement td, ITableItem item, Resources resources,
- ReportOutputFolder base) throws IOException;
-
- /**
- * Returns the comparator to sort this table column.
- *
- * @return comparator for this column
- */
- public Comparator<ITableItem> getComparator();
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import java.io.IOException; +import java.util.Comparator; +import java.util.List; + +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.resources.Resources; + +/** + * Renderer for a single column of a coverage table. The methods are always + * called in the sequence <code>init header footer item*</code>. Implementations + * might be stateful. + */ +public interface IColumnRenderer { + + /** + * Initializes the column before any output method is called. + * + * @param items + * all items that will be displayed in the table + * @param total + * the summary of all coverage data items in the table + * @return <code>true</code> if the column should be visible + */ + public boolean init(List<? extends ITableItem> items, ICoverageNode total); + + /** + * Renders the footer for this column. + * + * @param td + * the parent table cell + * @param total + * the summary of all coverage data items in the table + * @param resources + * static resources that might be referenced + * @param base + * base folder of the table + * @throws IOException + * in case of IO problems with the element output + */ + public void footer(HTMLElement td, ICoverageNode total, + Resources resources, ReportOutputFolder base) throws IOException; + + /** + * Renders a single item in this column. + * + * @param td + * the parent table cell + * @param item + * the item to display + * @param resources + * static resources that might be referenced + * @param base + * base folder of the table + * @throws IOException + * in case of IO problems with the element output + */ + public void item(HTMLElement td, ITableItem item, Resources resources, + ReportOutputFolder base) throws IOException; + + /** + * Returns the comparator to sort this table column. + * + * @return comparator for this column + */ + public Comparator<ITableItem> getComparator(); + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/table/ITableItem.java b/org.jacoco.report/src/org/jacoco/report/internal/html/table/ITableItem.java index d6ab6859..5d019c33 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/table/ITableItem.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/table/ITableItem.java @@ -1,29 +1,29 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.report.internal.html.ILinkable;
-
-/**
- * Interface for a item (row) in a coverage data table.
- */
-public interface ITableItem extends ILinkable {
-
- /**
- * Returns the corresponding node data.
- *
- * @return node data
- */
- public ICoverageNode getNode();
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.report.internal.html.ILinkable; + +/** + * Interface for a item (row) in a coverage data table. + */ +public interface ITableItem extends ILinkable { + + /** + * Returns the corresponding node data. + * + * @return node data + */ + public ICoverageNode getNode(); + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/table/LabelColumn.java b/org.jacoco.report/src/org/jacoco/report/internal/html/table/LabelColumn.java index 13a884d1..f61a63e9 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/table/LabelColumn.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/table/LabelColumn.java @@ -1,56 +1,56 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import java.io.IOException;
-import java.util.Comparator;
-import java.util.List;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.resources.Resources;
-
-/**
- * Column for the item label. The implementation is stateless, instances might
- * be used in parallel.
- */
-public class LabelColumn implements IColumnRenderer {
-
- private static final Comparator<ITableItem> COMPARATOR = new Comparator<ITableItem>() {
- public int compare(final ITableItem i1, final ITableItem i2) {
- return i1.getLinkLabel().compareToIgnoreCase(i2.getLinkLabel());
- }
- };
-
- public boolean init(final List<? extends ITableItem> items,
- final ICoverageNode total) {
- return true;
- }
-
- public void footer(final HTMLElement td, final ICoverageNode total,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- td.text("Total");
- }
-
- public void item(final HTMLElement td, final ITableItem item,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- td.a(item, base);
- }
-
- public Comparator<ITableItem> getComparator() {
- return COMPARATOR;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import java.io.IOException; +import java.util.Comparator; +import java.util.List; + +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.resources.Resources; + +/** + * Column for the item label. The implementation is stateless, instances might + * be used in parallel. + */ +public class LabelColumn implements IColumnRenderer { + + private static final Comparator<ITableItem> COMPARATOR = new Comparator<ITableItem>() { + public int compare(final ITableItem i1, final ITableItem i2) { + return i1.getLinkLabel().compareToIgnoreCase(i2.getLinkLabel()); + } + }; + + public boolean init(final List<? extends ITableItem> items, + final ICoverageNode total) { + return true; + } + + public void footer(final HTMLElement td, final ICoverageNode total, + final Resources resources, final ReportOutputFolder base) + throws IOException { + td.text("Total"); + } + + public void item(final HTMLElement td, final ITableItem item, + final Resources resources, final ReportOutputFolder base) + throws IOException { + td.a(item, base); + } + + public Comparator<ITableItem> getComparator() { + return COMPARATOR; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/table/PercentageColumn.java b/org.jacoco.report/src/org/jacoco/report/internal/html/table/PercentageColumn.java index 5a105c99..72645895 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/table/PercentageColumn.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/table/PercentageColumn.java @@ -1,90 +1,90 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import java.io.IOException;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Locale;
-
-import org.jacoco.core.analysis.CounterComparator;
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.resources.Resources;
-
-/**
- * Column that prints the coverage percentage for each item and the total
- * percentage in the footer. The implementation is stateless, instances might be
- * used in parallel.
- */
-public class PercentageColumn implements IColumnRenderer {
-
- private final CounterEntity entity;
-
- private final NumberFormat percentageFormat;
-
- private final Comparator<ITableItem> comparator;
-
- /**
- * Creates a new column that is based on the {@link ICounter} for the given
- * entity.
- *
- * @param entity
- * counter entity for this column
- * @param locale
- * locale for rendering numbers
- */
- public PercentageColumn(final CounterEntity entity, final Locale locale) {
- this.entity = entity;
- this.percentageFormat = DecimalFormat.getPercentInstance(locale);
- comparator = new TableItemComparator(
- CounterComparator.MISSEDRATIO.on(entity));
- }
-
- public boolean init(final List<? extends ITableItem> items,
- final ICoverageNode total) {
- return true;
- }
-
- public void footer(final HTMLElement td, final ICoverageNode total,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- cell(td, total);
- }
-
- public void item(final HTMLElement td, final ITableItem item,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- cell(td, item.getNode());
- }
-
- private void cell(final HTMLElement td, final ICoverageNode node)
- throws IOException {
- final ICounter counter = node.getCounter(entity);
- final int total = counter.getTotalCount();
- if (total == 0) {
- td.text("n/a");
- } else {
- td.text(percentageFormat.format(counter.getCoveredRatio()));
- }
- }
-
- public Comparator<ITableItem> getComparator() {
- return comparator;
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; + +import org.jacoco.core.analysis.CounterComparator; +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.resources.Resources; + +/** + * Column that prints the coverage percentage for each item and the total + * percentage in the footer. The implementation is stateless, instances might be + * used in parallel. + */ +public class PercentageColumn implements IColumnRenderer { + + private final CounterEntity entity; + + private final NumberFormat percentageFormat; + + private final Comparator<ITableItem> comparator; + + /** + * Creates a new column that is based on the {@link ICounter} for the given + * entity. + * + * @param entity + * counter entity for this column + * @param locale + * locale for rendering numbers + */ + public PercentageColumn(final CounterEntity entity, final Locale locale) { + this.entity = entity; + this.percentageFormat = DecimalFormat.getPercentInstance(locale); + comparator = new TableItemComparator( + CounterComparator.MISSEDRATIO.on(entity)); + } + + public boolean init(final List<? extends ITableItem> items, + final ICoverageNode total) { + return true; + } + + public void footer(final HTMLElement td, final ICoverageNode total, + final Resources resources, final ReportOutputFolder base) + throws IOException { + cell(td, total); + } + + public void item(final HTMLElement td, final ITableItem item, + final Resources resources, final ReportOutputFolder base) + throws IOException { + cell(td, item.getNode()); + } + + private void cell(final HTMLElement td, final ICoverageNode node) + throws IOException { + final ICounter counter = node.getCounter(entity); + final int total = counter.getTotalCount(); + if (total == 0) { + td.text("n/a"); + } else { + td.text(percentageFormat.format(counter.getCoveredRatio())); + } + } + + public Comparator<ITableItem> getComparator() { + return comparator; + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/table/Table.java b/org.jacoco.report/src/org/jacoco/report/internal/html/table/Table.java index 896445da..1e3cb35a 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/table/Table.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/table/Table.java @@ -1,195 +1,195 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.report.internal.ReportOutputFolder;
-import org.jacoco.report.internal.html.HTMLElement;
-import org.jacoco.report.internal.html.resources.Resources;
-import org.jacoco.report.internal.html.resources.Styles;
-
-/**
- * Renderer for a table of {@link ITableItem}s.
- */
-public class Table {
-
- private final List<Column> columns;
-
- private Comparator<ITableItem> defaultComparator;
-
- /**
- * Create a new table without any columns yet.
- */
- public Table() {
- this.columns = new ArrayList<Table.Column>();
- }
-
- /**
- * Adds a new column with the given properties to the table.
- *
- * @param header
- * column header caption
- * @param style
- * optional CSS style class name for the td-Elements of this
- * column
- * @param renderer
- * callback for column rendering
- * @param defaultSorting
- * If <code>true</code>, this column is the default sorting
- * column. Only one column can be selected for default sorting.
- *
- */
- public void add(final String header, final String style,
- final IColumnRenderer renderer, final boolean defaultSorting) {
- columns.add(new Column(columns.size(), header, style, renderer,
- defaultSorting));
- if (defaultSorting) {
- if (defaultComparator != null) {
- throw new IllegalStateException(
- "Default sorting only allowed for one column.");
- }
- this.defaultComparator = renderer.getComparator();
- }
- }
-
- /**
- * Renders a table for the given icon
- *
- * @param parent
- * parent element in which the table is created
- * @param items
- * items that will make the table rows
- * @param total
- * the summary of all coverage data items in the table static
- * resources that might be referenced
- * @param resources
- * static resources that might be referenced
- * @param base
- * base folder of the table
- * @throws IOException
- * in case of IO problems with the element output
- */
- public void render(final HTMLElement parent,
- final List<? extends ITableItem> items, final ICoverageNode total,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- final List<? extends ITableItem> sortedItems = sort(items);
- final HTMLElement table = parent.table(Styles.COVERAGETABLE);
- table.attr("id", "coveragetable");
- header(table, sortedItems, total);
- footer(table, total, resources, base);
- body(table, sortedItems, resources, base);
- }
-
- private void header(final HTMLElement table,
- final List<? extends ITableItem> items, final ICoverageNode total)
- throws IOException {
- final HTMLElement tr = table.thead().tr();
- for (final Column c : columns) {
- c.init(tr, items, total);
- }
- }
-
- private void footer(final HTMLElement table, final ICoverageNode total,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- final HTMLElement tr = table.tfoot().tr();
- for (final Column c : columns) {
- c.footer(tr, total, resources, base);
- }
- }
-
- private void body(final HTMLElement table,
- final List<? extends ITableItem> items, final Resources resources,
- final ReportOutputFolder base) throws IOException {
- final HTMLElement tbody = table.tbody();
- int idx = 0;
- for (final ITableItem item : items) {
- final HTMLElement tr = tbody.tr();
- for (final Column c : columns) {
- c.body(tr, idx, item, resources, base);
- }
- idx++;
- }
- }
-
- private List<? extends ITableItem> sort(
- final List<? extends ITableItem> items) {
- if (defaultComparator != null) {
- final ArrayList<ITableItem> result = new ArrayList<ITableItem>(
- items);
- Collections.sort(result, defaultComparator);
- return result;
- }
- return items;
- }
-
- private static class Column {
-
- private final char idprefix;
- private final String header;
- private final IColumnRenderer renderer;
- private final SortIndex<ITableItem> index;
- private final String style, headerStyle;
-
- private boolean visible;
-
- Column(final int idx, final String header, final String style,
- final IColumnRenderer renderer, final boolean defaultSorting) {
- this.idprefix = (char) ('a' + idx);
- this.header = header;
- this.renderer = renderer;
- index = new SortIndex<ITableItem>(renderer.getComparator());
- this.style = style;
- this.headerStyle = Styles.combine(defaultSorting ? Styles.DOWN
- : null, Styles.SORTABLE, style);
- }
-
- void init(final HTMLElement tr, final List<? extends ITableItem> items,
- final ICoverageNode total) throws IOException {
- visible = renderer.init(items, total);
- if (visible) {
- index.init(items);
- final HTMLElement td = tr.td(headerStyle);
- td.attr("id", String.valueOf(idprefix));
- td.attr("onclick", "toggleSort(this)");
- td.text(header);
- }
- }
-
- void footer(final HTMLElement tr, final ICoverageNode total,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- if (visible) {
- renderer.footer(tr.td(style), total, resources, base);
- }
- }
-
- void body(final HTMLElement tr, final int idx, final ITableItem item,
- final Resources resources, final ReportOutputFolder base)
- throws IOException {
- if (visible) {
- final HTMLElement td = tr.td(style);
- td.attr("id", idprefix + String.valueOf(index.getPosition(idx)));
- renderer.item(td, item, resources, base);
- }
- }
-
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.report.internal.ReportOutputFolder; +import org.jacoco.report.internal.html.HTMLElement; +import org.jacoco.report.internal.html.resources.Resources; +import org.jacoco.report.internal.html.resources.Styles; + +/** + * Renderer for a table of {@link ITableItem}s. + */ +public class Table { + + private final List<Column> columns; + + private Comparator<ITableItem> defaultComparator; + + /** + * Create a new table without any columns yet. + */ + public Table() { + this.columns = new ArrayList<Table.Column>(); + } + + /** + * Adds a new column with the given properties to the table. + * + * @param header + * column header caption + * @param style + * optional CSS style class name for the td-Elements of this + * column + * @param renderer + * callback for column rendering + * @param defaultSorting + * If <code>true</code>, this column is the default sorting + * column. Only one column can be selected for default sorting. + * + */ + public void add(final String header, final String style, + final IColumnRenderer renderer, final boolean defaultSorting) { + columns.add(new Column(columns.size(), header, style, renderer, + defaultSorting)); + if (defaultSorting) { + if (defaultComparator != null) { + throw new IllegalStateException( + "Default sorting only allowed for one column."); + } + this.defaultComparator = renderer.getComparator(); + } + } + + /** + * Renders a table for the given icon + * + * @param parent + * parent element in which the table is created + * @param items + * items that will make the table rows + * @param total + * the summary of all coverage data items in the table static + * resources that might be referenced + * @param resources + * static resources that might be referenced + * @param base + * base folder of the table + * @throws IOException + * in case of IO problems with the element output + */ + public void render(final HTMLElement parent, + final List<? extends ITableItem> items, final ICoverageNode total, + final Resources resources, final ReportOutputFolder base) + throws IOException { + final List<? extends ITableItem> sortedItems = sort(items); + final HTMLElement table = parent.table(Styles.COVERAGETABLE); + table.attr("id", "coveragetable"); + header(table, sortedItems, total); + footer(table, total, resources, base); + body(table, sortedItems, resources, base); + } + + private void header(final HTMLElement table, + final List<? extends ITableItem> items, final ICoverageNode total) + throws IOException { + final HTMLElement tr = table.thead().tr(); + for (final Column c : columns) { + c.init(tr, items, total); + } + } + + private void footer(final HTMLElement table, final ICoverageNode total, + final Resources resources, final ReportOutputFolder base) + throws IOException { + final HTMLElement tr = table.tfoot().tr(); + for (final Column c : columns) { + c.footer(tr, total, resources, base); + } + } + + private void body(final HTMLElement table, + final List<? extends ITableItem> items, final Resources resources, + final ReportOutputFolder base) throws IOException { + final HTMLElement tbody = table.tbody(); + int idx = 0; + for (final ITableItem item : items) { + final HTMLElement tr = tbody.tr(); + for (final Column c : columns) { + c.body(tr, idx, item, resources, base); + } + idx++; + } + } + + private List<? extends ITableItem> sort( + final List<? extends ITableItem> items) { + if (defaultComparator != null) { + final ArrayList<ITableItem> result = new ArrayList<ITableItem>( + items); + Collections.sort(result, defaultComparator); + return result; + } + return items; + } + + private static class Column { + + private final char idprefix; + private final String header; + private final IColumnRenderer renderer; + private final SortIndex<ITableItem> index; + private final String style, headerStyle; + + private boolean visible; + + Column(final int idx, final String header, final String style, + final IColumnRenderer renderer, final boolean defaultSorting) { + this.idprefix = (char) ('a' + idx); + this.header = header; + this.renderer = renderer; + index = new SortIndex<ITableItem>(renderer.getComparator()); + this.style = style; + this.headerStyle = Styles.combine(defaultSorting ? Styles.DOWN + : null, Styles.SORTABLE, style); + } + + void init(final HTMLElement tr, final List<? extends ITableItem> items, + final ICoverageNode total) throws IOException { + visible = renderer.init(items, total); + if (visible) { + index.init(items); + final HTMLElement td = tr.td(headerStyle); + td.attr("id", String.valueOf(idprefix)); + td.attr("onclick", "toggleSort(this)"); + td.text(header); + } + } + + void footer(final HTMLElement tr, final ICoverageNode total, + final Resources resources, final ReportOutputFolder base) + throws IOException { + if (visible) { + renderer.footer(tr.td(style), total, resources, base); + } + } + + void body(final HTMLElement tr, final int idx, final ITableItem item, + final Resources resources, final ReportOutputFolder base) + throws IOException { + if (visible) { + final HTMLElement td = tr.td(style); + td.attr("id", idprefix + String.valueOf(index.getPosition(idx))); + renderer.item(td, item, resources, base); + } + } + + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/html/table/TableItemComparator.java b/org.jacoco.report/src/org/jacoco/report/internal/html/table/TableItemComparator.java index 33426107..68dbc9a4 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/html/table/TableItemComparator.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/html/table/TableItemComparator.java @@ -1,33 +1,33 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.html.table;
-
-import java.util.Comparator;
-
-import org.jacoco.core.analysis.ICoverageNode;
-
-/**
- * Adapter to sort table items based on their coverage nodes.
- */
-class TableItemComparator implements Comparator<ITableItem> {
-
- private final Comparator<ICoverageNode> comparator;
-
- TableItemComparator(final Comparator<ICoverageNode> comparator) {
- this.comparator = comparator;
- }
-
- public int compare(final ITableItem i1, final ITableItem i2) {
- return comparator.compare(i1.getNode(), i2.getNode());
- }
-
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.html.table; + +import java.util.Comparator; + +import org.jacoco.core.analysis.ICoverageNode; + +/** + * Adapter to sort table items based on their coverage nodes. + */ +class TableItemComparator implements Comparator<ITableItem> { + + private final Comparator<ICoverageNode> comparator; + + TableItemComparator(final Comparator<ICoverageNode> comparator) { + this.comparator = comparator; + } + + public int compare(final ITableItem i1, final ITableItem i2) { + return comparator.compare(i1.getNode(), i2.getNode()); + } + }
\ No newline at end of file diff --git a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLCoverageWriter.java b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLCoverageWriter.java index 79e3a616..f359bd3e 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLCoverageWriter.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLCoverageWriter.java @@ -1,154 +1,154 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.xml;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.analysis.IClassCoverage;
-import org.jacoco.core.analysis.ICounter;
-import org.jacoco.core.analysis.ICoverageNode;
-import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
-import org.jacoco.core.analysis.ILine;
-import org.jacoco.core.analysis.IMethodCoverage;
-import org.jacoco.core.analysis.IPackageCoverage;
-import org.jacoco.core.analysis.ISourceFileCoverage;
-import org.jacoco.core.analysis.ISourceNode;
-
-/**
- * Serializes coverage data as XML fragments.
- */
-public final class XMLCoverageWriter {
-
- /**
- * Creates a child element with a name attribute.
- *
- * @param parent
- * parent element
- * @param tagname
- * name of the child tag
- * @param name
- * value of the name attribute
- * @return child element
- * @throws IOException
- */
- public static XMLElement createChild(final XMLElement parent,
- final String tagname, final String name) throws IOException {
- final XMLElement child = parent.element(tagname);
- child.attr("name", name);
- return child;
- }
-
- /**
- * Writes the structure of a given bundle.
- *
- * @param bundle
- * bundle coverage data
- * @param element
- * container element for the bundle data
- * @throws IOException
- */
- public static void writeBundle(final IBundleCoverage bundle,
- final XMLElement element) throws IOException {
- for (final IPackageCoverage p : bundle.getPackages()) {
- writePackage(p, element);
- }
- writeCounters(bundle, element);
- }
-
- private static void writePackage(final IPackageCoverage p,
- final XMLElement parent) throws IOException {
- final XMLElement element = createChild(parent, "package", p.getName());
- for (final IClassCoverage c : p.getClasses()) {
- writeClass(c, element);
- }
- for (final ISourceFileCoverage s : p.getSourceFiles()) {
- writeSourceFile(s, element);
- }
- writeCounters(p, element);
- }
-
- private static void writeClass(final IClassCoverage c,
- final XMLElement parent) throws IOException {
- final XMLElement element = createChild(parent, "class", c.getName());
- for (final IMethodCoverage m : c.getMethods()) {
- writeMethod(m, element);
- }
- writeCounters(c, element);
- }
-
- private static void writeMethod(final IMethodCoverage m,
- final XMLElement parent) throws IOException {
- final XMLElement element = createChild(parent, "method", m.getName());
- element.attr("desc", m.getDesc());
- final int line = m.getFirstLine();
- if (line != -1) {
- element.attr("line", line);
- }
- writeCounters(m, element);
- }
-
- private static void writeSourceFile(final ISourceFileCoverage s,
- final XMLElement parent) throws IOException {
- final XMLElement element = createChild(parent, "sourcefile",
- s.getName());
- writeLines(s, element);
- writeCounters(s, element);
- }
-
- /**
- * Writes all non-zero counters of the given node.
- *
- * @param node
- * node to retrieve counters from
- * @param parent
- * container for the counter elements
- * @throws IOException
- */
- public static void writeCounters(final ICoverageNode node,
- final XMLElement parent) throws IOException {
- for (final CounterEntity counterEntity : CounterEntity.values()) {
- final ICounter counter = node.getCounter(counterEntity);
- if (counter.getTotalCount() > 0) {
- final XMLElement counterNode = parent.element("counter");
- counterNode.attr("type", counterEntity.name());
- writeCounter(counterNode, "missed", "covered", counter);
- counterNode.close();
- }
- }
- }
-
- private static void writeLines(final ISourceNode source,
- final XMLElement parent) throws IOException {
- final int last = source.getLastLine();
- for (int nr = source.getFirstLine(); nr <= last; nr++) {
- final ILine line = source.getLine(nr);
- if (line.getStatus() != ICounter.EMPTY) {
- final XMLElement element = parent.element("line");
- element.attr("nr", nr);
- writeCounter(element, "mi", "ci", line.getInstructionCounter());
- writeCounter(element, "mb", "cb", line.getBranchCounter());
- }
- }
- }
-
- private static void writeCounter(final XMLElement element,
- final String missedattr, final String coveredattr,
- final ICounter counter) throws IOException {
- element.attr(missedattr, counter.getMissedCount());
- element.attr(coveredattr, counter.getCoveredCount());
- }
-
- private XMLCoverageWriter() {
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.xml; + +import java.io.IOException; + +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.ICoverageNode; +import org.jacoco.core.analysis.ICoverageNode.CounterEntity; +import org.jacoco.core.analysis.ILine; +import org.jacoco.core.analysis.IMethodCoverage; +import org.jacoco.core.analysis.IPackageCoverage; +import org.jacoco.core.analysis.ISourceFileCoverage; +import org.jacoco.core.analysis.ISourceNode; + +/** + * Serializes coverage data as XML fragments. + */ +public final class XMLCoverageWriter { + + /** + * Creates a child element with a name attribute. + * + * @param parent + * parent element + * @param tagname + * name of the child tag + * @param name + * value of the name attribute + * @return child element + * @throws IOException + */ + public static XMLElement createChild(final XMLElement parent, + final String tagname, final String name) throws IOException { + final XMLElement child = parent.element(tagname); + child.attr("name", name); + return child; + } + + /** + * Writes the structure of a given bundle. + * + * @param bundle + * bundle coverage data + * @param element + * container element for the bundle data + * @throws IOException + */ + public static void writeBundle(final IBundleCoverage bundle, + final XMLElement element) throws IOException { + for (final IPackageCoverage p : bundle.getPackages()) { + writePackage(p, element); + } + writeCounters(bundle, element); + } + + private static void writePackage(final IPackageCoverage p, + final XMLElement parent) throws IOException { + final XMLElement element = createChild(parent, "package", p.getName()); + for (final IClassCoverage c : p.getClasses()) { + writeClass(c, element); + } + for (final ISourceFileCoverage s : p.getSourceFiles()) { + writeSourceFile(s, element); + } + writeCounters(p, element); + } + + private static void writeClass(final IClassCoverage c, + final XMLElement parent) throws IOException { + final XMLElement element = createChild(parent, "class", c.getName()); + for (final IMethodCoverage m : c.getMethods()) { + writeMethod(m, element); + } + writeCounters(c, element); + } + + private static void writeMethod(final IMethodCoverage m, + final XMLElement parent) throws IOException { + final XMLElement element = createChild(parent, "method", m.getName()); + element.attr("desc", m.getDesc()); + final int line = m.getFirstLine(); + if (line != -1) { + element.attr("line", line); + } + writeCounters(m, element); + } + + private static void writeSourceFile(final ISourceFileCoverage s, + final XMLElement parent) throws IOException { + final XMLElement element = createChild(parent, "sourcefile", + s.getName()); + writeLines(s, element); + writeCounters(s, element); + } + + /** + * Writes all non-zero counters of the given node. + * + * @param node + * node to retrieve counters from + * @param parent + * container for the counter elements + * @throws IOException + */ + public static void writeCounters(final ICoverageNode node, + final XMLElement parent) throws IOException { + for (final CounterEntity counterEntity : CounterEntity.values()) { + final ICounter counter = node.getCounter(counterEntity); + if (counter.getTotalCount() > 0) { + final XMLElement counterNode = parent.element("counter"); + counterNode.attr("type", counterEntity.name()); + writeCounter(counterNode, "missed", "covered", counter); + counterNode.close(); + } + } + } + + private static void writeLines(final ISourceNode source, + final XMLElement parent) throws IOException { + final int last = source.getLastLine(); + for (int nr = source.getFirstLine(); nr <= last; nr++) { + final ILine line = source.getLine(nr); + if (line.getStatus() != ICounter.EMPTY) { + final XMLElement element = parent.element("line"); + element.attr("nr", nr); + writeCounter(element, "mi", "ci", line.getInstructionCounter()); + writeCounter(element, "mb", "cb", line.getBranchCounter()); + } + } + } + + private static void writeCounter(final XMLElement element, + final String missedattr, final String coveredattr, + final ICounter counter) throws IOException { + element.attr(missedattr, counter.getMissedCount()); + element.attr(coveredattr, counter.getCoveredCount()); + } + + private XMLCoverageWriter() { + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLDocument.java b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLDocument.java index 9fcb2012..7ca92636 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLDocument.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLDocument.java @@ -1,111 +1,111 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.xml;
-
-import static java.lang.String.format;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-
-/**
- * Root element of an XML document. Each instance represents a separate output
- * document.
- *
- * @see XMLElement
- */
-public class XMLDocument extends XMLElement {
-
- /** XML header template */
- private static final String HEADER = "<?xml version=\"1.0\" encoding=\"%s\"?>";
-
- /** XML header template for standalone documents */
- private static final String HEADER_STANDALONE = "<?xml version=\"1.0\" encoding=\"%s\" standalone=\"yes\"?>";
-
- /** DOCTYPE declaration template */
- private static final String DOCTYPE = "<!DOCTYPE %s PUBLIC \"%s\" \"%s\">";
-
- /**
- * Writes a new document to the given writer. The document might contain a
- * document type declaration.
- *
- * @param rootnode
- * name of the root node
- * @param pubId
- * optional doctype identifier or <code>null</code>
- * @param system
- * system reference, required if doctype is given
- * @param encoding
- * encoding that will be specified in the header
- * @param standalone
- * <code>true</code> if this is a standalone document
- * @param writer
- * writer for content output
- * @throws IOException
- * in case of problems with the writer
- */
- public XMLDocument(final String rootnode, final String pubId,
- final String system, final String encoding,
- final boolean standalone, final Writer writer) throws IOException {
- super(writer, rootnode);
- writeHeader(rootnode, pubId, system, encoding, standalone, writer);
- beginOpenTag();
- }
-
- /**
- * Writes a new document to the given binary stream. The document might
- * contain a document type declaration.
- *
- * @param rootnode
- * name of the root node
- * @param pubId
- * optional doctype identifier or <code>null</code>
- * @param system
- * system reference, required if doctype is given
- * @param encoding
- * encoding of the XML document
- * @param standalone
- * <code>true</code> if this is a standalone document
- * @param output
- * output for content output
- * @throws IOException
- * in case of problems with the writer
- */
- public XMLDocument(final String rootnode, final String pubId,
- final String system, final String encoding,
- final boolean standalone, final OutputStream output)
- throws IOException {
- this(rootnode, pubId, system, encoding, standalone,
- new OutputStreamWriter(output, encoding));
- }
-
- @Override
- public void close() throws IOException {
- super.close();
- writer.close();
- }
-
- private static void writeHeader(final String rootnode, final String pubId,
- final String system, final String encoding,
- final boolean standalone, final Writer writer) throws IOException {
- if (standalone) {
- writer.write(format(HEADER_STANDALONE, encoding));
- } else {
- writer.write(format(HEADER, encoding));
- }
- if (pubId != null) {
- writer.write(format(DOCTYPE, rootnode, pubId, system));
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.xml; + +import static java.lang.String.format; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +/** + * Root element of an XML document. Each instance represents a separate output + * document. + * + * @see XMLElement + */ +public class XMLDocument extends XMLElement { + + /** XML header template */ + private static final String HEADER = "<?xml version=\"1.0\" encoding=\"%s\"?>"; + + /** XML header template for standalone documents */ + private static final String HEADER_STANDALONE = "<?xml version=\"1.0\" encoding=\"%s\" standalone=\"yes\"?>"; + + /** DOCTYPE declaration template */ + private static final String DOCTYPE = "<!DOCTYPE %s PUBLIC \"%s\" \"%s\">"; + + /** + * Writes a new document to the given writer. The document might contain a + * document type declaration. + * + * @param rootnode + * name of the root node + * @param pubId + * optional doctype identifier or <code>null</code> + * @param system + * system reference, required if doctype is given + * @param encoding + * encoding that will be specified in the header + * @param standalone + * <code>true</code> if this is a standalone document + * @param writer + * writer for content output + * @throws IOException + * in case of problems with the writer + */ + public XMLDocument(final String rootnode, final String pubId, + final String system, final String encoding, + final boolean standalone, final Writer writer) throws IOException { + super(writer, rootnode); + writeHeader(rootnode, pubId, system, encoding, standalone, writer); + beginOpenTag(); + } + + /** + * Writes a new document to the given binary stream. The document might + * contain a document type declaration. + * + * @param rootnode + * name of the root node + * @param pubId + * optional doctype identifier or <code>null</code> + * @param system + * system reference, required if doctype is given + * @param encoding + * encoding of the XML document + * @param standalone + * <code>true</code> if this is a standalone document + * @param output + * output for content output + * @throws IOException + * in case of problems with the writer + */ + public XMLDocument(final String rootnode, final String pubId, + final String system, final String encoding, + final boolean standalone, final OutputStream output) + throws IOException { + this(rootnode, pubId, system, encoding, standalone, + new OutputStreamWriter(output, encoding)); + } + + @Override + public void close() throws IOException { + super.close(); + writer.close(); + } + + private static void writeHeader(final String rootnode, final String pubId, + final String system, final String encoding, + final boolean standalone, final Writer writer) throws IOException { + if (standalone) { + writer.write(format(HEADER_STANDALONE, encoding)); + } else { + writer.write(format(HEADER, encoding)); + } + if (pubId != null) { + writer.write(format(DOCTYPE, rootnode, pubId, system)); + } + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java index 14b0a409..52f2b3c3 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLElement.java @@ -1,262 +1,262 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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
- *
- *******************************************************************************/
-package org.jacoco.report.internal.xml;
-
-import static java.lang.String.format;
-
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * Simple API to create well formed XML streams. A {@link XMLElement} instance
- * represents a single element in a XML document.
- *
- * @see XMLDocument
- */
-public class XMLElement {
-
- private static final char SPACE = ' ';
-
- private static final char EQ = '=';
-
- private static final char LT = '<';
-
- private static final char GT = '>';
-
- private static final char QUOT = '"';
-
- private static final char AMP = '&';
-
- private static final char SLASH = '/';
-
- /** Writer for content output */
- protected final Writer writer;
-
- private final String name;
-
- private boolean openTagDone;
-
- private boolean closed;
-
- private XMLElement lastchild;
-
- /**
- * Creates a new element for a XML document.
- *
- * @param writer
- * all output will be written directly to this
- * @param name
- * element name
- */
- protected XMLElement(final Writer writer, final String name) {
- this.writer = writer;
- this.name = name;
- this.openTagDone = false;
- this.closed = false;
- this.lastchild = null;
- }
-
- /**
- * Emits the beginning of the open tag. This method has to be called before
- * other other methods are called on this element.
- *
- * @throws IOException
- * in case of problems with the writer
- */
- protected void beginOpenTag() throws IOException {
- writer.write(LT);
- writer.write(name);
- }
-
- private void finishOpenTag() throws IOException {
- if (!openTagDone) {
- writer.append(GT);
- openTagDone = true;
- }
- }
-
- /**
- * Adds the given child to this element. This will close all previous child
- * elements.
- *
- * @param child
- * child element to add
- * @throws IOException
- * in case of invalid nesting or problems with the writer
- */
- protected void addChildElement(final XMLElement child) throws IOException {
- if (closed) {
- throw new IOException(format("Element %s already closed.", name));
- }
- finishOpenTag();
- if (lastchild != null) {
- lastchild.close();
- }
- child.beginOpenTag();
- lastchild = child;
- }
-
- private void quote(final String text) throws IOException {
- final int len = text.length();
- for (int i = 0; i < len; i++) {
- final char c = text.charAt(i);
- switch (c) {
- case LT:
- writer.write("<");
- break;
- case GT:
- writer.write(">");
- break;
- case QUOT:
- writer.write(""");
- break;
- case AMP:
- writer.write("&");
- break;
- default:
- writer.write(c);
- }
- }
- }
-
- /**
- * Adds an attribute to this element. May only be called before an child
- * element is added or this element has been closed. The attribute value
- * will be quoted. If the value is <code>null</code> the attribute will not
- * be added.
- *
- * @param name
- * attribute name
- * @param value
- * attribute value or <code>null</code>
- *
- * @return this element
- * @throws IOException
- * in case of problems with the writer
- */
- public XMLElement attr(final String name, final String value)
- throws IOException {
- if (value == null) {
- return this;
- }
- if (closed || openTagDone) {
- throw new IOException(format("Element %s already closed.",
- this.name));
- }
- writer.write(SPACE);
- writer.write(name);
- writer.write(EQ);
- writer.write(QUOT);
- quote(value);
- writer.write(QUOT);
- return this;
- }
-
- /**
- * Adds an attribute to this element. May only be called before an child
- * element is added or this element has been closed. The attribute value is
- * the decimal representation of the given int value.
- *
- * @param name
- * attribute name
- * @param value
- * attribute value
- *
- * @return this element
- * @throws IOException
- * in case of problems with the writer
- */
- public XMLElement attr(final String name, final int value)
- throws IOException {
- return attr(name, String.valueOf(value));
- }
-
- /**
- * Adds an attribute to this element. May only be called before an child
- * element is added or this element has been closed. The attribute value is
- * the decimal representation of the given long value.
- *
- * @param name
- * attribute name
- * @param value
- * attribute value
- *
- * @return this element
- * @throws IOException
- * in case of problems with the writer
- */
- public XMLElement attr(final String name, final long value)
- throws IOException {
- return attr(name, String.valueOf(value));
- }
-
- /**
- * Adds the given text as a child to this node. The text will be quoted.
- *
- * @param text
- * text to add
- * @return this element
- * @throws IOException
- * in case of problems with the writer
- */
- public XMLElement text(final String text) throws IOException {
- if (closed) {
- throw new IOException(format("Element %s already closed.", name));
- }
- finishOpenTag();
- if (lastchild != null) {
- lastchild.close();
- }
- quote(text);
- return this;
- }
-
- /**
- * Creates a new child element for this element,
- *
- * @param name
- * name of the child element
- * @return child element instance
- * @throws IOException
- * in case of problems with the writer
- */
- public XMLElement element(final String name) throws IOException {
- final XMLElement element = new XMLElement(writer, name);
- addChildElement(element);
- return element;
- }
-
- /**
- * Closes this element if it has not been closed before.
- *
- * @throws IOException
- * in case of problems with the writer
- */
- public void close() throws IOException {
- if (!closed) {
- if (lastchild != null) {
- lastchild.close();
- }
- if (openTagDone) {
- writer.write(LT);
- writer.write(SLASH);
- writer.write(name);
- } else {
- writer.write(SLASH);
- }
- writer.write(GT);
- closed = true;
- openTagDone = true;
- }
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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 + * + *******************************************************************************/ +package org.jacoco.report.internal.xml; + +import static java.lang.String.format; + +import java.io.IOException; +import java.io.Writer; + +/** + * Simple API to create well formed XML streams. A {@link XMLElement} instance + * represents a single element in a XML document. + * + * @see XMLDocument + */ +public class XMLElement { + + private static final char SPACE = ' '; + + private static final char EQ = '='; + + private static final char LT = '<'; + + private static final char GT = '>'; + + private static final char QUOT = '"'; + + private static final char AMP = '&'; + + private static final char SLASH = '/'; + + /** Writer for content output */ + protected final Writer writer; + + private final String name; + + private boolean openTagDone; + + private boolean closed; + + private XMLElement lastchild; + + /** + * Creates a new element for a XML document. + * + * @param writer + * all output will be written directly to this + * @param name + * element name + */ + protected XMLElement(final Writer writer, final String name) { + this.writer = writer; + this.name = name; + this.openTagDone = false; + this.closed = false; + this.lastchild = null; + } + + /** + * Emits the beginning of the open tag. This method has to be called before + * other other methods are called on this element. + * + * @throws IOException + * in case of problems with the writer + */ + protected void beginOpenTag() throws IOException { + writer.write(LT); + writer.write(name); + } + + private void finishOpenTag() throws IOException { + if (!openTagDone) { + writer.append(GT); + openTagDone = true; + } + } + + /** + * Adds the given child to this element. This will close all previous child + * elements. + * + * @param child + * child element to add + * @throws IOException + * in case of invalid nesting or problems with the writer + */ + protected void addChildElement(final XMLElement child) throws IOException { + if (closed) { + throw new IOException(format("Element %s already closed.", name)); + } + finishOpenTag(); + if (lastchild != null) { + lastchild.close(); + } + child.beginOpenTag(); + lastchild = child; + } + + private void quote(final String text) throws IOException { + final int len = text.length(); + for (int i = 0; i < len; i++) { + final char c = text.charAt(i); + switch (c) { + case LT: + writer.write("<"); + break; + case GT: + writer.write(">"); + break; + case QUOT: + writer.write("""); + break; + case AMP: + writer.write("&"); + break; + default: + writer.write(c); + } + } + } + + /** + * Adds an attribute to this element. May only be called before an child + * element is added or this element has been closed. The attribute value + * will be quoted. If the value is <code>null</code> the attribute will not + * be added. + * + * @param name + * attribute name + * @param value + * attribute value or <code>null</code> + * + * @return this element + * @throws IOException + * in case of problems with the writer + */ + public XMLElement attr(final String name, final String value) + throws IOException { + if (value == null) { + return this; + } + if (closed || openTagDone) { + throw new IOException(format("Element %s already closed.", + this.name)); + } + writer.write(SPACE); + writer.write(name); + writer.write(EQ); + writer.write(QUOT); + quote(value); + writer.write(QUOT); + return this; + } + + /** + * Adds an attribute to this element. May only be called before an child + * element is added or this element has been closed. The attribute value is + * the decimal representation of the given int value. + * + * @param name + * attribute name + * @param value + * attribute value + * + * @return this element + * @throws IOException + * in case of problems with the writer + */ + public XMLElement attr(final String name, final int value) + throws IOException { + return attr(name, String.valueOf(value)); + } + + /** + * Adds an attribute to this element. May only be called before an child + * element is added or this element has been closed. The attribute value is + * the decimal representation of the given long value. + * + * @param name + * attribute name + * @param value + * attribute value + * + * @return this element + * @throws IOException + * in case of problems with the writer + */ + public XMLElement attr(final String name, final long value) + throws IOException { + return attr(name, String.valueOf(value)); + } + + /** + * Adds the given text as a child to this node. The text will be quoted. + * + * @param text + * text to add + * @return this element + * @throws IOException + * in case of problems with the writer + */ + public XMLElement text(final String text) throws IOException { + if (closed) { + throw new IOException(format("Element %s already closed.", name)); + } + finishOpenTag(); + if (lastchild != null) { + lastchild.close(); + } + quote(text); + return this; + } + + /** + * Creates a new child element for this element, + * + * @param name + * name of the child element + * @return child element instance + * @throws IOException + * in case of problems with the writer + */ + public XMLElement element(final String name) throws IOException { + final XMLElement element = new XMLElement(writer, name); + addChildElement(element); + return element; + } + + /** + * Closes this element if it has not been closed before. + * + * @throws IOException + * in case of problems with the writer + */ + public void close() throws IOException { + if (!closed) { + if (lastchild != null) { + lastchild.close(); + } + if (openTagDone) { + writer.write(LT); + writer.write(SLASH); + writer.write(name); + } else { + writer.write(SLASH); + } + writer.write(GT); + closed = true; + openTagDone = true; + } + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLGroupVisitor.java b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLGroupVisitor.java index a012db89..e9867f85 100644 --- a/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLGroupVisitor.java +++ b/org.jacoco.report/src/org/jacoco/report/internal/xml/XMLGroupVisitor.java @@ -1,70 +1,70 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak - initial API and implementation
- * Marc R. Hoffmann - generalized structure, line info
- *
- *******************************************************************************/
-package org.jacoco.report.internal.xml;
-
-import java.io.IOException;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.report.ISourceFileLocator;
-import org.jacoco.report.internal.AbstractGroupVisitor;
-
-/**
- * A {@link org.jacoco.report.IReportGroupVisitor} that transforms the report
- * structure into XML elements.
- */
-public class XMLGroupVisitor extends AbstractGroupVisitor {
-
- /** XML element of this group */
- protected final XMLElement element;
-
- /**
- * New handler for a group with the given name.
- *
- * @param element
- * XML-Element representing this coverage node. The start tag
- * must not be closed yet to allow adding additional attributes.
- * @param name
- * name of the group
- * @throws IOException
- * in case of problems with the underlying writer
- */
- public XMLGroupVisitor(final XMLElement element, final String name)
- throws IOException {
- super(name);
- this.element = element;
- }
-
- @Override
- protected void handleBundle(final IBundleCoverage bundle,
- final ISourceFileLocator locator) throws IOException {
- final XMLElement child = createChild(bundle.getName());
- XMLCoverageWriter.writeBundle(bundle, child);
- }
-
- @Override
- protected AbstractGroupVisitor handleGroup(final String name)
- throws IOException {
- final XMLElement child = createChild(name);
- return new XMLGroupVisitor(child, name);
- }
-
- @Override
- protected void handleEnd() throws IOException {
- XMLCoverageWriter.writeCounters(total, element);
- }
-
- private XMLElement createChild(final String name) throws IOException {
- return XMLCoverageWriter.createChild(element, "group", name);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak - initial API and implementation + * Marc R. Hoffmann - generalized structure, line info + * + *******************************************************************************/ +package org.jacoco.report.internal.xml; + +import java.io.IOException; + +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.report.ISourceFileLocator; +import org.jacoco.report.internal.AbstractGroupVisitor; + +/** + * A {@link org.jacoco.report.IReportGroupVisitor} that transforms the report + * structure into XML elements. + */ +public class XMLGroupVisitor extends AbstractGroupVisitor { + + /** XML element of this group */ + protected final XMLElement element; + + /** + * New handler for a group with the given name. + * + * @param element + * XML-Element representing this coverage node. The start tag + * must not be closed yet to allow adding additional attributes. + * @param name + * name of the group + * @throws IOException + * in case of problems with the underlying writer + */ + public XMLGroupVisitor(final XMLElement element, final String name) + throws IOException { + super(name); + this.element = element; + } + + @Override + protected void handleBundle(final IBundleCoverage bundle, + final ISourceFileLocator locator) throws IOException { + final XMLElement child = createChild(bundle.getName()); + XMLCoverageWriter.writeBundle(bundle, child); + } + + @Override + protected AbstractGroupVisitor handleGroup(final String name) + throws IOException { + final XMLElement child = createChild(name); + return new XMLGroupVisitor(child, name); + } + + @Override + protected void handleEnd() throws IOException { + XMLCoverageWriter.writeCounters(total, element); + } + + private XMLElement createChild(final String name) throws IOException { + return XMLCoverageWriter.createChild(element, "group", name); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/xml/XMLFormatter.java b/org.jacoco.report/src/org/jacoco/report/xml/XMLFormatter.java index d59c557c..18f24c51 100644 --- a/org.jacoco.report/src/org/jacoco/report/xml/XMLFormatter.java +++ b/org.jacoco.report/src/org/jacoco/report/xml/XMLFormatter.java @@ -1,110 +1,110 @@ -/*******************************************************************************
- * Copyright (c) 2009, 2012 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:
- * Brock Janiczak -initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.report.xml;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Collection;
-import java.util.List;
-
-import org.jacoco.core.analysis.IBundleCoverage;
-import org.jacoco.core.data.ExecutionData;
-import org.jacoco.core.data.SessionInfo;
-import org.jacoco.report.IReportVisitor;
-import org.jacoco.report.ISourceFileLocator;
-import org.jacoco.report.internal.AbstractGroupVisitor;
-import org.jacoco.report.internal.xml.XMLCoverageWriter;
-import org.jacoco.report.internal.xml.XMLDocument;
-import org.jacoco.report.internal.xml.XMLElement;
-import org.jacoco.report.internal.xml.XMLGroupVisitor;
-
-/**
- * Report formatter that creates a single XML file for a coverage session
- */
-public class XMLFormatter {
-
- private static final String PUBID = "-//JACOCO//DTD Report 1.0//EN";
-
- private static final String SYSTEM = "report.dtd";
-
- private String outputEncoding = "UTF-8";
-
- /**
- * Sets the encoding used for generated XML document. Default is UTF-8.
- *
- * @param outputEncoding
- * XML output encoding
- */
- public void setOutputEncoding(final String outputEncoding) {
- this.outputEncoding = outputEncoding;
- }
-
- /**
- * Creates a new visitor to write a report to the given stream.
- *
- * @param output
- * output stream to write the report to
- * @return visitor to emit the report data to
- * @throws IOException
- * in case of problems with the output stream
- */
- public IReportVisitor createVisitor(final OutputStream output)
- throws IOException {
- final XMLElement root = new XMLDocument("report", PUBID, SYSTEM,
- outputEncoding, true, output);
- class RootVisitor extends XMLGroupVisitor implements IReportVisitor {
-
- RootVisitor(final XMLElement element) throws IOException {
- super(element, null);
- }
-
- private List<SessionInfo> sessionInfos;
-
- public void visitInfo(final List<SessionInfo> sessionInfos,
- final Collection<ExecutionData> executionData)
- throws IOException {
- this.sessionInfos = sessionInfos;
- }
-
- @Override
- protected void handleBundle(final IBundleCoverage bundle,
- final ISourceFileLocator locator) throws IOException {
- writeHeader(bundle.getName());
- XMLCoverageWriter.writeBundle(bundle, element);
- }
-
- @Override
- protected AbstractGroupVisitor handleGroup(final String name)
- throws IOException {
- writeHeader(name);
- return new XMLGroupVisitor(element, name);
- }
-
- private void writeHeader(final String name) throws IOException {
- element.attr("name", name);
- for (final SessionInfo i : sessionInfos) {
- final XMLElement sessioninfo = root.element("sessioninfo");
- sessioninfo.attr("id", i.getId());
- sessioninfo.attr("start", i.getStartTimeStamp());
- sessioninfo.attr("dump", i.getDumpTimeStamp());
- }
- }
-
- @Override
- protected void handleEnd() throws IOException {
- element.close();
- }
- }
- return new RootVisitor(root);
- }
-
-}
+/******************************************************************************* + * Copyright (c) 2009, 2012 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: + * Brock Janiczak -initial API and implementation + * + *******************************************************************************/ +package org.jacoco.report.xml; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collection; +import java.util.List; + +import org.jacoco.core.analysis.IBundleCoverage; +import org.jacoco.core.data.ExecutionData; +import org.jacoco.core.data.SessionInfo; +import org.jacoco.report.IReportVisitor; +import org.jacoco.report.ISourceFileLocator; +import org.jacoco.report.internal.AbstractGroupVisitor; +import org.jacoco.report.internal.xml.XMLCoverageWriter; +import org.jacoco.report.internal.xml.XMLDocument; +import org.jacoco.report.internal.xml.XMLElement; +import org.jacoco.report.internal.xml.XMLGroupVisitor; + +/** + * Report formatter that creates a single XML file for a coverage session + */ +public class XMLFormatter { + + private static final String PUBID = "-//JACOCO//DTD Report 1.0//EN"; + + private static final String SYSTEM = "report.dtd"; + + private String outputEncoding = "UTF-8"; + + /** + * Sets the encoding used for generated XML document. Default is UTF-8. + * + * @param outputEncoding + * XML output encoding + */ + public void setOutputEncoding(final String outputEncoding) { + this.outputEncoding = outputEncoding; + } + + /** + * Creates a new visitor to write a report to the given stream. + * + * @param output + * output stream to write the report to + * @return visitor to emit the report data to + * @throws IOException + * in case of problems with the output stream + */ + public IReportVisitor createVisitor(final OutputStream output) + throws IOException { + final XMLElement root = new XMLDocument("report", PUBID, SYSTEM, + outputEncoding, true, output); + class RootVisitor extends XMLGroupVisitor implements IReportVisitor { + + RootVisitor(final XMLElement element) throws IOException { + super(element, null); + } + + private List<SessionInfo> sessionInfos; + + public void visitInfo(final List<SessionInfo> sessionInfos, + final Collection<ExecutionData> executionData) + throws IOException { + this.sessionInfos = sessionInfos; + } + + @Override + protected void handleBundle(final IBundleCoverage bundle, + final ISourceFileLocator locator) throws IOException { + writeHeader(bundle.getName()); + XMLCoverageWriter.writeBundle(bundle, element); + } + + @Override + protected AbstractGroupVisitor handleGroup(final String name) + throws IOException { + writeHeader(name); + return new XMLGroupVisitor(element, name); + } + + private void writeHeader(final String name) throws IOException { + element.attr("name", name); + for (final SessionInfo i : sessionInfos) { + final XMLElement sessioninfo = root.element("sessioninfo"); + sessioninfo.attr("id", i.getId()); + sessioninfo.attr("start", i.getStartTimeStamp()); + sessioninfo.attr("dump", i.getDumpTimeStamp()); + } + } + + @Override + protected void handleEnd() throws IOException { + element.close(); + } + } + return new RootVisitor(root); + } + +} diff --git a/org.jacoco.report/src/org/jacoco/report/xml/report.dtd b/org.jacoco.report/src/org/jacoco/report/xml/report.dtd index 46b497b3..5e6184a8 100644 --- a/org.jacoco.report/src/org/jacoco/report/xml/report.dtd +++ b/org.jacoco.report/src/org/jacoco/report/xml/report.dtd @@ -1,84 +1,84 @@ -<!--
- Copyright (c) 2009, 2012 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:
- Brock Janiczak - initial API and implementation
- Marc R. Hoffmann - generalized report structure, line info, documentation
-
- $Id: $
--->
-
-<!-- This DTD describes the JaCoCo XML report format. It is identified by the
- following identifiers:
-
- PUBID = "-//JACOCO//DTD Report 1.0//EN"
- SYSTEM = "report.dtd"
--->
-
-<!-- report root node -->
-<!ELEMENT report (sessioninfo*, (group* | package*), counter*)>
- <!ATTLIST report name CDATA #REQUIRED>
-
-<!-- information about a session which contributed execution data -->
-<!ELEMENT sessioninfo EMPTY>
- <!-- session id -->
- <!ATTLIST sessioninfo id CDATA #REQUIRED>
- <!-- start time stamp -->
- <!ATTLIST sessioninfo start CDATA #REQUIRED>
- <!-- dump time stamp -->
- <!ATTLIST sessioninfo dump CDATA #REQUIRED>
-
-<!-- representation of a group -->
-<!ELEMENT group ((group* | package*), counter*)>
- <!-- group name -->
- <!ATTLIST group name CDATA #REQUIRED>
-
-<!-- representation of a package -->
-<!ELEMENT package ((class | sourcefile)*, counter*)>
- <!-- package name in VM notation -->
- <!ATTLIST package name CDATA #REQUIRED>
-
-<!-- representation of a class -->
-<!ELEMENT class (method*, counter*)>
- <!-- fully qualified VM name -->
- <!ATTLIST class name CDATA #REQUIRED>
-
-<!-- representation of a method -->
-<!ELEMENT method (counter*)>
- <!-- method name -->
- <!ATTLIST method name CDATA #REQUIRED>
- <!-- method parameter description -->
- <!ATTLIST method desc CDATA #REQUIRED>
- <!-- first source line number of this method -->
- <!ATTLIST method line CDATA #IMPLIED>
-
-<!-- representation of a source file -->
-<!ELEMENT sourcefile (line*, counter*)>
- <!-- local source file name -->
- <!ATTLIST sourcefile name CDATA #REQUIRED>
-
-<!-- representation of a source line -->
-<!ELEMENT line EMPTY>
- <!-- line number -->
- <!ATTLIST line nr CDATA #REQUIRED>
- <!-- number of missed instructions -->
- <!ATTLIST line mi CDATA #IMPLIED>
- <!-- number of covered instructions -->
- <!ATTLIST line ci CDATA #IMPLIED>
- <!-- number of missed branches -->
- <!ATTLIST line mb CDATA #IMPLIED>
- <!-- number of covered branches -->
- <!ATTLIST line cb CDATA #IMPLIED>
-
-<!-- coverage data counter for different metrics -->
-<!ELEMENT counter EMPTY>
- <!-- metric type -->
- <!ATTLIST counter type (INSTRUCTION|BRANCH|LINE|COMPLEXITY|METHOD|CLASS) #REQUIRED>
- <!-- number of missed items -->
- <!ATTLIST counter missed CDATA #REQUIRED>
- <!-- number of covered items -->
+<!-- + Copyright (c) 2009, 2012 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: + Brock Janiczak - initial API and implementation + Marc R. Hoffmann - generalized report structure, line info, documentation + + $Id: $ +--> + +<!-- This DTD describes the JaCoCo XML report format. It is identified by the + following identifiers: + + PUBID = "-//JACOCO//DTD Report 1.0//EN" + SYSTEM = "report.dtd" +--> + +<!-- report root node --> +<!ELEMENT report (sessioninfo*, (group* | package*), counter*)> + <!ATTLIST report name CDATA #REQUIRED> + +<!-- information about a session which contributed execution data --> +<!ELEMENT sessioninfo EMPTY> + <!-- session id --> + <!ATTLIST sessioninfo id CDATA #REQUIRED> + <!-- start time stamp --> + <!ATTLIST sessioninfo start CDATA #REQUIRED> + <!-- dump time stamp --> + <!ATTLIST sessioninfo dump CDATA #REQUIRED> + +<!-- representation of a group --> +<!ELEMENT group ((group* | package*), counter*)> + <!-- group name --> + <!ATTLIST group name CDATA #REQUIRED> + +<!-- representation of a package --> +<!ELEMENT package ((class | sourcefile)*, counter*)> + <!-- package name in VM notation --> + <!ATTLIST package name CDATA #REQUIRED> + +<!-- representation of a class --> +<!ELEMENT class (method*, counter*)> + <!-- fully qualified VM name --> + <!ATTLIST class name CDATA #REQUIRED> + +<!-- representation of a method --> +<!ELEMENT method (counter*)> + <!-- method name --> + <!ATTLIST method name CDATA #REQUIRED> + <!-- method parameter description --> + <!ATTLIST method desc CDATA #REQUIRED> + <!-- first source line number of this method --> + <!ATTLIST method line CDATA #IMPLIED> + +<!-- representation of a source file --> +<!ELEMENT sourcefile (line*, counter*)> + <!-- local source file name --> + <!ATTLIST sourcefile name CDATA #REQUIRED> + +<!-- representation of a source line --> +<!ELEMENT line EMPTY> + <!-- line number --> + <!ATTLIST line nr CDATA #REQUIRED> + <!-- number of missed instructions --> + <!ATTLIST line mi CDATA #IMPLIED> + <!-- number of covered instructions --> + <!ATTLIST line ci CDATA #IMPLIED> + <!-- number of missed branches --> + <!ATTLIST line mb CDATA #IMPLIED> + <!-- number of covered branches --> + <!ATTLIST line cb CDATA #IMPLIED> + +<!-- coverage data counter for different metrics --> +<!ELEMENT counter EMPTY> + <!-- metric type --> + <!ATTLIST counter type (INSTRUCTION|BRANCH|LINE|COMPLEXITY|METHOD|CLASS) #REQUIRED> + <!-- number of missed items --> + <!ATTLIST counter missed CDATA #REQUIRED> + <!-- number of covered items --> <!ATTLIST counter covered CDATA #REQUIRED>
\ No newline at end of file |