aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core.test/src
diff options
context:
space:
mode:
authorMarc R. Hoffmann <hoffmann@mountainminds.com>2009-06-07 21:08:18 +0000
committerMarc R. Hoffmann <hoffmann@mountainminds.com>2009-06-07 21:08:18 +0000
commit045cfd8578cbb8b0297e35c4846a8e3f4aa0db06 (patch)
treeef17e1caae6ee7b27e15454f8437c7b1ebe0eb0c /org.jacoco.core.test/src
parent5c2b4d032cb0df5ff0d89bcdd319bf6336da7414 (diff)
downloadjacoco-045cfd8578cbb8b0297e35c4846a8e3f4aa0db06.tar.gz
JaCoCo initial drop.
Diffstat (limited to 'org.jacoco.core.test/src')
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/data/AbstractCounterTest.java133
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/data/BlockCoverageDataTest.java59
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/data/ClassCoverageDataTest.java105
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/data/CounterImplTest.java85
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataStoreTest.java103
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/data/LinesImplTest.java314
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/data/MethodCoverageDataTest.java91
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/data/SourceFileCoverageDataTest.java38
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/instr/BlockMethodAdapterTest.java318
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/instr/CRC64Test.java72
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/instr/IntSetTest.java100
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/instr/MethodInstrumenterTest.java75
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/runtime/SystemPropertiesRuntimeTest.java207
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/ClassDataRecorder.java156
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/InstrumentationScenariosTest.java127
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/MethodRecorder.java62
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/RuntimePerformancetest.java139
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java74
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Stubs.java92
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target02.java25
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target20.java38
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_cinit_01.java29
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_cinit_02.java27
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_01.java25
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_02.java28
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_03.java27
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_04.java30
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_05.java33
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_performance_01.java111
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_performance_02.java34
30 files changed, 2757 insertions, 0 deletions
diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/AbstractCounterTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/AbstractCounterTest.java
new file mode 100644
index 00000000..11c0cee1
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/data/AbstractCounterTest.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link AbstractCounter}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class AbstractCounterTest {
+
+ private AbstractCounter getInstance(int total, int covered) {
+ return new AbstractCounter(total, covered) {
+ };
+ }
+
+ @Test
+ public void testGetTotalGetCovered() {
+ AbstractCounter c = CounterImpl.getInstance(33, 12);
+ assertEquals(33, c.getTotalCount(), 0.0);
+ assertEquals(12, c.getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testGetRatio1() {
+ AbstractCounter c = getInstance(20, 10);
+ assertEquals(0.5, c.getRatio(), 0.0);
+ }
+
+ @Test
+ public void testGetRatio2() {
+ AbstractCounter c = getInstance(20, 0);
+ assertEquals(0.0, c.getRatio(), 0.0);
+ }
+
+ @Test
+ public void testGetRatio3() {
+ AbstractCounter c = getInstance(0, 20);
+ assertEquals(Double.POSITIVE_INFINITY, c.getRatio(), 0.0);
+ }
+
+ @Test
+ public void testGetRatio4() {
+ AbstractCounter c = getInstance(0, 0);
+ assertTrue(Double.isNaN(c.getRatio()));
+ }
+
+ @Test
+ public void testCompareTo1() {
+ AbstractCounter c1 = getInstance(20, 10);
+ AbstractCounter c2 = getInstance(30, 10);
+ assertTrue(c1.compareTo(c2) > 0);
+ }
+
+ @Test
+ public void testCompareTo2() {
+ AbstractCounter c1 = getInstance(20, 10);
+ AbstractCounter c2 = getInstance(30, 15);
+ assertEquals(0, c1.compareTo(c2), 0.0);
+ }
+
+ @Test
+ public void testEquals1() {
+ AbstractCounter c1 = getInstance(300, 123);
+ AbstractCounter c2 = getInstance(300, 123);
+ assertEquals(c1, c2);
+ }
+
+ @Test
+ public void testEquals2() {
+ AbstractCounter c1 = getInstance(300, 123);
+ AbstractCounter c2 = getInstance(400, 123);
+ assertFalse(c1.equals(c2));
+ }
+
+ @Test
+ public void testEquals3() {
+ AbstractCounter c1 = getInstance(300, 123);
+ AbstractCounter c2 = getInstance(300, 124);
+ assertFalse(c1.equals(c2));
+ }
+
+ @Test
+ public void testEquals4() {
+ AbstractCounter c = getInstance(300, 123);
+ assertFalse(c.equals(new Integer(123)));
+ }
+
+ @Test
+ public void testHashCode1() {
+ AbstractCounter c1 = getInstance(300, 123);
+ AbstractCounter c2 = getInstance(300, 123);
+ assertEquals(c1.hashCode(), c2.hashCode(), 0.0);
+ }
+
+ @Test
+ public void testHashCode2() {
+ AbstractCounter c1 = getInstance(300, 123);
+ AbstractCounter c2 = getInstance(400, 123);
+ assertFalse(c1.hashCode() == c2.hashCode());
+ }
+
+ @Test
+ public void testHashCode3() {
+ AbstractCounter c1 = getInstance(300, 123);
+ AbstractCounter c2 = getInstance(300, 124);
+ assertFalse(c1.hashCode() == c2.hashCode());
+ }
+
+ @Test
+ public void testToString() {
+ AbstractCounter c = getInstance(300, 123);
+ assertEquals("Counter[123/300]", c.toString());
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/BlockCoverageDataTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/BlockCoverageDataTest.java
new file mode 100644
index 00000000..2ba49c6a
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/data/BlockCoverageDataTest.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.data;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Unit test for {@link BlockCoverageData}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class BlockCoverageDataTest {
+
+ @Test
+ public void testGetType() {
+ ICoverageData data = new BlockCoverageData(0, new int[0], false);
+ assertEquals(ICoverageData.ElementType.BLOCK, data.getElementType());
+ }
+
+ @Test
+ public void testNotCovered() {
+ ICoverageData data = new BlockCoverageData(15, new int[0], false);
+ assertEquals(15, data.getInstructionCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getInstructionCounter().getCoveredCount(), 0.0);
+ assertEquals(1, data.getBlockCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getBlockCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getMethodCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getMethodCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testCovered() {
+ ICoverageData data = new BlockCoverageData(15, new int[0], true);
+ assertEquals(15, data.getInstructionCounter().getTotalCount(), 0.0);
+ assertEquals(15, data.getInstructionCounter().getCoveredCount(), 0.0);
+ assertEquals(1, data.getBlockCounter().getTotalCount(), 0.0);
+ assertEquals(1, data.getBlockCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getMethodCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getMethodCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getCoveredCount(), 0.0);
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/ClassCoverageDataTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/ClassCoverageDataTest.java
new file mode 100644
index 00000000..0cc2e163
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/data/ClassCoverageDataTest.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.data;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+
+import org.junit.Test;
+
+/**
+ * Unit test for {@link ClassCoverageData}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class ClassCoverageDataTest {
+
+ @Test
+ public void testProperties() {
+ ClassCoverageData data = new ClassCoverageData("Sample", "testbundle",
+ new ArrayList<ICoverageData>());
+ assertEquals(ICoverageData.ElementType.CLASS, data.getElementType());
+ assertEquals("Sample", data.getName());
+ assertEquals("testbundle", data.getBundle());
+ }
+
+ @Test
+ public void testGetPackageName1() {
+ ClassCoverageData data = new ClassCoverageData("ClassInDefaultPackage",
+ "testbundle", new ArrayList<ICoverageData>());
+ assertEquals("", data.getPackagename());
+ }
+
+ @Test
+ public void testGetPackageName2() {
+ ClassCoverageData data = new ClassCoverageData(
+ "org/jacoco/examples/Sample", "testbundle",
+ new ArrayList<ICoverageData>());
+ assertEquals("org/jacoco/examples", data.getPackagename());
+ }
+
+ @Test
+ public void testEmptyClass() {
+ ICoverageData data = new ClassCoverageData("Sample", null,
+ new ArrayList<ICoverageData>());
+ assertEquals(0, data.getInstructionCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getInstructionCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getBlockCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getBlockCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getMethodCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getMethodCounter().getCoveredCount(), 0.0);
+ assertEquals(1, data.getClassCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testNotCovered() {
+ final ArrayList<ICoverageData> methods = new ArrayList<ICoverageData>();
+ methods.add(createMethod(false));
+ methods.add(createMethod(false));
+ ICoverageData data = new ClassCoverageData("Sample", null, methods);
+ assertEquals(10, data.getInstructionCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getInstructionCounter().getCoveredCount(), 0.0);
+ assertEquals(2, data.getBlockCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getBlockCounter().getCoveredCount(), 0.0);
+ assertEquals(2, data.getMethodCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getMethodCounter().getCoveredCount(), 0.0);
+ assertEquals(1, data.getClassCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testCovered() {
+ final ArrayList<ICoverageData> methods = new ArrayList<ICoverageData>();
+ methods.add(createMethod(false));
+ methods.add(createMethod(true));
+ ICoverageData data = new ClassCoverageData("Sample", null, methods);
+ assertEquals(10, data.getInstructionCounter().getTotalCount(), 0.0);
+ assertEquals(5, data.getInstructionCounter().getCoveredCount(), 0.0);
+ assertEquals(2, data.getBlockCounter().getTotalCount(), 0.0);
+ assertEquals(1, data.getBlockCounter().getCoveredCount(), 0.0);
+ assertEquals(2, data.getMethodCounter().getTotalCount(), 0.0);
+ assertEquals(1, data.getMethodCounter().getCoveredCount(), 0.0);
+ assertEquals(1, data.getClassCounter().getTotalCount(), 0.0);
+ assertEquals(1, data.getClassCounter().getCoveredCount(), 0.0);
+ }
+
+ private ICoverageData createMethod(boolean covered) {
+ final ArrayList<ICoverageData> blocks = new ArrayList<ICoverageData>();
+ blocks.add(new BlockCoverageData(5, new int[0], covered));
+ return new MethodCoverageData("sample", "()V", null, blocks);
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/CounterImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/CounterImplTest.java
new file mode 100644
index 00000000..d8fa7f52
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/data/CounterImplTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.data;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link CounterImpl}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class CounterImplTest {
+
+ @Test
+ public void testGetInstance1() {
+ AbstractCounter c = CounterImpl.getInstance(0, 0);
+ assertEquals(0, c.getTotalCount(), 0.0);
+ assertEquals(0, c.getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testGetInstance2() {
+ AbstractCounter c = CounterImpl.getInstance(33, 15);
+ assertEquals(33, c.getTotalCount(), 0.0);
+ assertEquals(15, c.getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testGetInstance3() {
+ AbstractCounter c = CounterImpl.getInstance(17, true);
+ assertEquals(17, c.getTotalCount(), 0.0);
+ assertEquals(17, c.getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testGetInstance4() {
+ AbstractCounter c = CounterImpl.getInstance(17, false);
+ assertEquals(17, c.getTotalCount(), 0.0);
+ assertEquals(0, c.getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testGetInstance5() {
+ AbstractCounter c = CounterImpl.getInstance(true);
+ assertEquals(1, c.getTotalCount(), 0.0);
+ assertEquals(1, c.getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testGetInstance6() {
+ AbstractCounter c = CounterImpl.getInstance(false);
+ assertEquals(1, c.getTotalCount(), 0.0);
+ assertEquals(0, c.getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testIncrement1() {
+ CounterImpl c = CounterImpl.getInstance(1, 1);
+ c = c.increment(CounterImpl.getInstance(2, 1));
+ assertEquals(3, c.getTotalCount(), 0.0);
+ assertEquals(2, c.getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testIncrement2() {
+ CounterImpl c = CounterImpl.getInstance(11, 5);
+ c = c.increment(CounterImpl.getInstance(7, 3));
+ assertEquals(18, c.getTotalCount(), 0.0);
+ assertEquals(8, c.getCoveredCount(), 0.0);
+ }
+
+}
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
new file mode 100644
index 00000000..dad6af45
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/data/ExecutionDataStoreTest.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.data;
+
+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 java.util.Collections;
+import java.util.HashMap;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link ExecutionDataStore}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class ExecutionDataStoreTest implements IExecutionDataOutput {
+
+ private ExecutionDataStore store;
+
+ private HashMap<Long, boolean[][]> output;
+
+ @Before
+ public void setup() {
+ store = new ExecutionDataStore();
+ output = new HashMap<Long, boolean[][]>();
+ }
+
+ @Test
+ public void testEmpty() {
+ assertNull(store.getBlockdata(123));
+ store.writeTo(this);
+ assertEquals(Collections.emptyMap(), output);
+ }
+
+ @Test
+ public void testPut() {
+ boolean[][] data = new boolean[][] { new boolean[] { false },
+ new boolean[] { false, true } };
+ store.classExecution(1000, data);
+ assertSame(data, store.getBlockdata(1000));
+ store.writeTo(this);
+ assertEquals(Collections.singletonMap(Long.valueOf(1000), data), output);
+ }
+
+ @Test
+ public void testMerge() {
+ boolean[][] data1 = new boolean[][] { new boolean[] { false, true },
+ new boolean[] { false, true } };
+ store.classExecution(1000, data1);
+ boolean[][] data2 = new boolean[][] { new boolean[] { false, true },
+ new boolean[] { true, false } };
+ store.classExecution(1000, data2);
+
+ final boolean[][] result = store.getBlockdata(1000);
+ assertFalse(result[0][0]);
+ assertTrue(result[0][1]);
+ assertTrue(result[1][0]);
+ assertTrue(result[1][1]);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testNegative1() {
+ boolean[][] data1 = new boolean[][] { new boolean[] { false },
+ new boolean[] { false } };
+ store.classExecution(1000, data1);
+ boolean[][] data2 = new boolean[][] { new boolean[] { false },
+ new boolean[] { false }, new boolean[] { false } };
+ store.classExecution(1000, data2);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testNegative2() {
+ boolean[][] data1 = new boolean[][] { new boolean[] { false, false } };
+ store.classExecution(1000, data1);
+ boolean[][] data2 = new boolean[][] { new boolean[] { false, false,
+ false } };
+ store.classExecution(1000, data2);
+ }
+
+ // === IExecutionDataOutput ===
+
+ public void classExecution(long id, boolean[][] blockdata) {
+ output.put(Long.valueOf(id), blockdata);
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/LinesImplTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/LinesImplTest.java
new file mode 100644
index 00000000..3f8f6185
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/data/LinesImplTest.java
@@ -0,0 +1,314 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.data;
+
+import static org.jacoco.core.data.ILines.FULLY_COVERED;
+import static org.jacoco.core.data.ILines.NOT_COVERED;
+import static org.jacoco.core.data.ILines.NO_CODE;
+import static org.jacoco.core.data.ILines.PARTLY_COVERED;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link LinesImpl}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class LinesImplTest {
+
+ @Test
+ public void testEmpty1() {
+ ILines c = new LinesImpl();
+ assertEquals(0, c.getTotalCount(), 0.0);
+ assertEquals(0, c.getCoveredCount(), 0.0);
+ assertEquals(-1, c.getFirstLine(), 0.0);
+ assertEquals(-1, c.getLastLine(), 0.0);
+ assertEquals(NO_CODE, c.getStatus(5), 0.0);
+ }
+
+ @Test
+ public void testEmpty2() {
+ ILines c = new LinesImpl(new int[0], false);
+ assertEquals(0, c.getTotalCount(), 0.0);
+ assertEquals(0, c.getCoveredCount(), 0.0);
+ assertEquals(-1, c.getFirstLine(), 0.0);
+ assertEquals(-1, c.getLastLine(), 0.0);
+ assertEquals(NO_CODE, c.getStatus(5), 0.0);
+ }
+
+ @Test
+ public void testEmpty3() {
+ ILines c = new LinesImpl(new int[0], true);
+ assertEquals(0, c.getTotalCount(), 0.0);
+ assertEquals(0, c.getCoveredCount(), 0.0);
+ assertEquals(-1, c.getFirstLine(), 0.0);
+ assertEquals(-1, c.getLastLine(), 0.0);
+ assertEquals(NO_CODE, c.getStatus(5), 0.0);
+ }
+
+ @Test
+ public void testInitNotCovered() {
+ ILines c = new LinesImpl(new int[] { 5, 7, 10 }, false);
+ assertEquals(3, c.getTotalCount(), 0.0);
+ assertEquals(0, c.getCoveredCount(), 0.0);
+ assertEquals(5, c.getFirstLine(), 0.0);
+ assertEquals(10, c.getLastLine(), 0.0);
+ assertEquals(NO_CODE, c.getStatus(4), 0.0);
+ assertEquals(NOT_COVERED, c.getStatus(5), 0.0);
+ assertEquals(NO_CODE, c.getStatus(6), 0.0);
+ assertEquals(NOT_COVERED, c.getStatus(7), 0.0);
+ assertEquals(NO_CODE, c.getStatus(8), 0.0);
+ assertEquals(NO_CODE, c.getStatus(9), 0.0);
+ assertEquals(NOT_COVERED, c.getStatus(10), 0.0);
+ assertEquals(NO_CODE, c.getStatus(11), 0.0);
+ }
+
+ @Test
+ public void testInitCovered() {
+ ILines c = new LinesImpl(new int[] { 5, 7, 10 }, true);
+ assertEquals(3, c.getTotalCount(), 0.0);
+ assertEquals(3, c.getCoveredCount(), 0.0);
+ assertEquals(5, c.getFirstLine(), 0.0);
+ assertEquals(10, c.getLastLine(), 0.0);
+ assertEquals(NO_CODE, c.getStatus(4), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(5), 0.0);
+ assertEquals(NO_CODE, c.getStatus(6), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(7), 0.0);
+ assertEquals(NO_CODE, c.getStatus(8), 0.0);
+ assertEquals(NO_CODE, c.getStatus(9), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(10), 0.0);
+ assertEquals(NO_CODE, c.getStatus(11), 0.0);
+ }
+
+ @Test
+ public void testIncrement1() {
+ // 1: N + N = N
+ // 2: N + . = N
+ // 3: . + . = .
+ // 4: . + N = N
+ // 5: N + N = N
+ // ============
+ // 4 total, 0 covered
+ LinesImpl c = new LinesImpl(new int[] { 1, 2, 5 }, false);
+ c.increment(new LinesImpl(new int[] { 1, 4, 5 }, false));
+ assertEquals(4, c.getTotalCount(), 0.0);
+ assertEquals(0, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(5, c.getLastLine(), 0.0);
+ assertEquals(NOT_COVERED, c.getStatus(1), 0.0);
+ assertEquals(NOT_COVERED, c.getStatus(2), 0.0);
+ assertEquals(NO_CODE, c.getStatus(3), 0.0);
+ assertEquals(NOT_COVERED, c.getStatus(4), 0.0);
+ assertEquals(NOT_COVERED, c.getStatus(5), 0.0);
+ }
+
+ @Test
+ public void testIncrement2() {
+ // 1: F + F = F
+ // 2: F + . = F
+ // 3: . + F = F
+ // 4: F + F = F
+ // ============
+ // 4 total, 4 covered
+ LinesImpl c = new LinesImpl(new int[] { 1, 2, 4 }, true);
+ c.increment(new LinesImpl(new int[] { 1, 3, 4 }, true));
+ assertEquals(4, c.getTotalCount(), 0.0);
+ assertEquals(4, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(4, c.getLastLine(), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(1), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(2), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(3), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(4), 0.0);
+ }
+
+ @Test
+ public void testIncrement3() {
+ // 1: F + N = P
+ // ============
+ // 1 total, 1 covered
+ LinesImpl c = new LinesImpl(new int[] { 1 }, true);
+ c.increment(new LinesImpl(new int[] { 1 }, false));
+ assertEquals(1, c.getTotalCount(), 0.0);
+ assertEquals(1, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(1, c.getLastLine(), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(1), 0.0);
+ }
+
+ @Test
+ public void testIncrement4() {
+ // 1: N + F = P
+ // ============
+ // 1 total, 1 covered
+ LinesImpl c = new LinesImpl(new int[] { 1 }, false);
+ c.increment(new LinesImpl(new int[] { 1 }, true));
+ assertEquals(1, c.getTotalCount(), 0.0);
+ assertEquals(1, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(1, c.getLastLine(), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(1), 0.0);
+ }
+
+ @Test
+ public void testIncrement5() {
+ // 1: P + P = P
+ // 2: P + . = P
+ // 3: . + . = .
+ // 4: . + P = P
+ // 5: P + P = P
+ // ============
+ // 4 total, 4 covered
+ LinesImpl c = createPartyCovered(1, 2, 5);
+ c.increment(createPartyCovered(1, 4, 5));
+ assertEquals(4, c.getTotalCount(), 0.0);
+ assertEquals(4, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(5, c.getLastLine(), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(1), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(2), 0.0);
+ assertEquals(NO_CODE, c.getStatus(3), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(4), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(5), 0.0);
+ }
+
+ @Test
+ public void testIncrement6() {
+ // 1: P + N = P
+ // ============
+ // 1 total, 1 covered
+ LinesImpl c = createPartyCovered(1);
+ c.increment(new LinesImpl(new int[] { 1 }, false));
+ assertEquals(1, c.getTotalCount(), 0.0);
+ assertEquals(1, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(1, c.getLastLine(), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(1), 0.0);
+ }
+
+ @Test
+ public void testIncrement7() {
+ // 1: N + P = P
+ // ============
+ // 1 total, 1 covered
+ LinesImpl c = new LinesImpl(new int[] { 1 }, false);
+ c.increment(createPartyCovered(1));
+ assertEquals(1, c.getTotalCount(), 0.0);
+ assertEquals(1, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(1, c.getLastLine(), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(1), 0.0);
+ }
+
+ @Test
+ public void testIncrement8() {
+ // 1: P + F = P
+ // ============
+ // 1 total, 1 covered
+ LinesImpl c = createPartyCovered(1);
+ c.increment(new LinesImpl(new int[] { 1 }, true));
+ assertEquals(1, c.getTotalCount(), 0.0);
+ assertEquals(1, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(1, c.getLastLine(), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(1), 0.0);
+ }
+
+ @Test
+ public void testIncrement9() {
+ // 1: F + P = P
+ // ============
+ // 1 total, 1 covered
+ LinesImpl c = new LinesImpl(new int[] { 1 }, true);
+ c.increment(createPartyCovered(1));
+ assertEquals(1, c.getTotalCount(), 0.0);
+ assertEquals(1, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(1, c.getLastLine(), 0.0);
+ assertEquals(PARTLY_COVERED, c.getStatus(1), 0.0);
+ }
+
+ @Test
+ public void testIncrementEmpty() {
+ LinesImpl c = new LinesImpl(new int[] { 1 }, true);
+ c.increment(new LinesImpl());
+ assertEquals(1, c.getTotalCount(), 0.0);
+ assertEquals(1, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(1, c.getLastLine(), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(1), 0.0);
+ }
+
+ @Test
+ public void testIncreaseLeft() {
+ // 1: . + F = F
+ // 2: F + F = F
+ // 3: F + F = F
+ // ============
+ // 3 total, 3 covered
+ LinesImpl c = new LinesImpl(new int[] { 2, 3 }, true);
+ c.increment(new LinesImpl(new int[] { 1, 2, 3 }, true));
+ assertEquals(3, c.getTotalCount(), 0.0);
+ assertEquals(3, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(3, c.getLastLine(), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(1), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(2), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(3), 0.0);
+ }
+
+ @Test
+ public void testIncreaseRight() {
+ // 1: F + F = F
+ // 2: F + F = F
+ // 3: . + F = F
+ // ============
+ // 3 total, 3 covered
+ LinesImpl c = new LinesImpl(new int[] { 1, 2 }, true);
+ c.increment(new LinesImpl(new int[] { 1, 2, 3 }, true));
+ assertEquals(3, c.getTotalCount(), 0.0);
+ assertEquals(3, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(3, c.getLastLine(), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(1), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(2), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(3), 0.0);
+ }
+
+ @Test
+ public void testIncreaseBoth() {
+ // 1: . + F = F
+ // 2: F + F = F
+ // 3: . + F = F
+ // ============
+ // 3 total, 3 covered
+ LinesImpl c = new LinesImpl(new int[] { 2 }, true);
+ c.increment(new LinesImpl(new int[] { 1, 2, 3 }, true));
+ assertEquals(3, c.getTotalCount(), 0.0);
+ assertEquals(3, c.getCoveredCount(), 0.0);
+ assertEquals(1, c.getFirstLine(), 0.0);
+ assertEquals(3, c.getLastLine(), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(1), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(2), 0.0);
+ assertEquals(FULLY_COVERED, c.getStatus(3), 0.0);
+ }
+
+ private LinesImpl createPartyCovered(int... lines) {
+ LinesImpl c = new LinesImpl(lines, true);
+ c.increment(new LinesImpl(lines, false));
+ return c;
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/MethodCoverageDataTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/MethodCoverageDataTest.java
new file mode 100644
index 00000000..b79f19c3
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/data/MethodCoverageDataTest.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.data;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+
+import org.junit.Test;
+
+/**
+ * Unit test for {@link MethodCoverageData}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class MethodCoverageDataTest {
+
+ @Test
+ public void testProperties() {
+ // Example: java.util.Collections.emptySet()
+ MethodCoverageData data = new MethodCoverageData("emptySet",
+ "()Ljava/util/Set;",
+ "<T:Ljava/lang/Object;>()Ljava/util/Set<TT;>;",
+ new ArrayList<ICoverageData>());
+ assertEquals(ICoverageData.ElementType.METHOD, data.getElementType());
+ assertEquals("emptySet", data.getName());
+ assertEquals("()Ljava/util/Set;", data.getDesc());
+ assertEquals("<T:Ljava/lang/Object;>()Ljava/util/Set<TT;>;", data
+ .getSignature());
+ }
+
+ @Test
+ public void testEmptyMethod() {
+ ICoverageData data = new MethodCoverageData("sample", "()V", null,
+ new ArrayList<ICoverageData>());
+ assertEquals(0, data.getInstructionCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getInstructionCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getBlockCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getBlockCounter().getCoveredCount(), 0.0);
+ assertEquals(1, data.getMethodCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getMethodCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testNotCovered() {
+ final ArrayList<ICoverageData> blocks = new ArrayList<ICoverageData>();
+ blocks.add(new BlockCoverageData(5, new int[0], false));
+ blocks.add(new BlockCoverageData(8, new int[0], false));
+ ICoverageData data = new MethodCoverageData("sample", "()V", null,
+ blocks);
+ assertEquals(13, data.getInstructionCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getInstructionCounter().getCoveredCount(), 0.0);
+ assertEquals(2, data.getBlockCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getBlockCounter().getCoveredCount(), 0.0);
+ assertEquals(1, data.getMethodCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getMethodCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getCoveredCount(), 0.0);
+ }
+
+ @Test
+ public void testCovered() {
+ final ArrayList<ICoverageData> blocks = new ArrayList<ICoverageData>();
+ blocks.add(new BlockCoverageData(5, new int[0], true));
+ blocks.add(new BlockCoverageData(8, new int[0], false));
+ ICoverageData data = new MethodCoverageData("sample", "()V", null,
+ blocks);
+ assertEquals(13, data.getInstructionCounter().getTotalCount(), 0.0);
+ assertEquals(5, data.getInstructionCounter().getCoveredCount(), 0.0);
+ assertEquals(2, data.getBlockCounter().getTotalCount(), 0.0);
+ assertEquals(1, data.getBlockCounter().getCoveredCount(), 0.0);
+ assertEquals(1, data.getMethodCounter().getTotalCount(), 0.0);
+ assertEquals(1, data.getMethodCounter().getCoveredCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getTotalCount(), 0.0);
+ assertEquals(0, data.getClassCounter().getCoveredCount(), 0.0);
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/data/SourceFileCoverageDataTest.java b/org.jacoco.core.test/src/org/jacoco/core/data/SourceFileCoverageDataTest.java
new file mode 100644
index 00000000..a62001aa
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/data/SourceFileCoverageDataTest.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.data;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * Unit test for {@link SourceFileCoverageData}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class SourceFileCoverageDataTest {
+
+ @Test
+ public void testProperties() {
+ SourceFileCoverageData data = new SourceFileCoverageData("Sample.java",
+ "org/jacoco/examples", "samples");
+ assertEquals(ICoverageData.ElementType.SOURCEFILE, data
+ .getElementType());
+ assertEquals("Sample.java", data.getFilename());
+ assertEquals("org/jacoco/examples", data.getPackagename());
+ assertEquals("samples", data.getBundle());
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/BlockMethodAdapterTest.java b/org.jacoco.core.test/src/org/jacoco/core/instr/BlockMethodAdapterTest.java
new file mode 100644
index 00000000..d164101a
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/instr/BlockMethodAdapterTest.java
@@ -0,0 +1,318 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.instr;
+
+import static org.junit.Assert.assertEquals;
+
+import org.jacoco.core.instr.BlockMethodAdapter;
+import org.jacoco.core.test.MethodRecorder;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Unit tests for {@link BufferedMethodVisitor}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class BlockMethodAdapterTest {
+
+ private MethodVisitor adapter;
+
+ private MethodRecorder expected;
+
+ private MethodRecorder actual;
+
+ @Before
+ public void setup() {
+ actual = new MethodRecorder();
+ expected = new MethodRecorder();
+ adapter = new BlockMethodAdapter(actual, 0, "test", "()V", null, null);
+ }
+
+ void sampleReturn() {
+ return;
+ }
+
+ @Test
+ public void testReturn() {
+ adapter.visitCode();
+ adapter.visitInsn(Opcodes.RETURN);
+ adapter.visitMaxs(0, 1);
+ adapter.visitEnd();
+
+ expected.visitCode();
+ expected.visitBlockEndBeforeJump(0);
+ expected.visitInsn(Opcodes.RETURN);
+ expected.visitBlockEnd(0);
+ expected.visitMaxs(0, 1);
+ expected.visitEnd();
+
+ assertEquals(expected, actual);
+ }
+
+ void sampleThrow() {
+ throw new RuntimeException();
+ }
+
+ @Test
+ public void testThrow() {
+ adapter.visitCode();
+ adapter.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
+ adapter.visitInsn(Opcodes.DUP);
+ adapter.visitMethodInsn(Opcodes.INVOKESPECIAL,
+ "java/lang/RuntimeException", "<init>", "()V");
+ adapter.visitInsn(Opcodes.ATHROW);
+ adapter.visitMaxs(2, 1);
+ adapter.visitEnd();
+
+ expected.visitCode();
+ expected.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
+ expected.visitInsn(Opcodes.DUP);
+ expected.visitMethodInsn(Opcodes.INVOKESPECIAL,
+ "java/lang/RuntimeException", "<init>", "()V");
+ expected.visitBlockEndBeforeJump(0);
+ expected.visitInsn(Opcodes.ATHROW);
+ expected.visitBlockEnd(0);
+ expected.visitMaxs(2, 1);
+ expected.visitEnd();
+
+ assertEquals(expected, actual);
+ }
+
+ int sampleIf(int x) {
+ if (x > 0) {
+ x++;
+ }
+ return x;
+ }
+
+ @Test
+ public void testIf() {
+ Label label0 = new Label();
+
+ adapter.visitCode();
+ adapter.visitVarInsn(Opcodes.ILOAD, 1);
+ adapter.visitJumpInsn(Opcodes.IFLE, label0);
+ adapter.visitIincInsn(1, 1);
+ adapter.visitLabel(label0);
+ adapter.visitVarInsn(Opcodes.ILOAD, 1);
+ adapter.visitInsn(Opcodes.IRETURN);
+ adapter.visitMaxs(1, 2);
+ adapter.visitEnd();
+
+ expected.visitCode();
+ expected.visitVarInsn(Opcodes.ILOAD, 1);
+ expected.visitBlockEndBeforeJump(0);
+ expected.visitJumpInsn(Opcodes.IFLE, label0);
+ expected.visitBlockEnd(0);
+ expected.visitIincInsn(1, 1);
+ expected.visitBlockEndBeforeJump(1);
+ expected.visitBlockEnd(1);
+ expected.visitLabel(label0);
+ expected.visitVarInsn(Opcodes.ILOAD, 1);
+ expected.visitBlockEndBeforeJump(2);
+ expected.visitInsn(Opcodes.IRETURN);
+ expected.visitBlockEnd(2);
+ expected.visitMaxs(1, 2);
+ expected.visitEnd();
+
+ assertEquals(expected, actual);
+ }
+
+ int sampleTableSwitchp(int a) {
+ int result = 0;
+ switch (a) {
+ case 1:
+ result += 10;
+ default:
+ result += 20;
+ }
+ return result;
+ }
+
+ @Test
+ public void testTableSwitch() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+
+ adapter.visitCode();
+ adapter.visitInsn(Opcodes.ICONST_0);
+ adapter.visitVarInsn(Opcodes.ISTORE, 2);
+ adapter.visitVarInsn(Opcodes.ILOAD, 1);
+ adapter.visitTableSwitchInsn(1, 1, label1, new Label[] { label0 });
+ adapter.visitLabel(label0);
+ adapter.visitIincInsn(2, 10);
+ adapter.visitLabel(label1);
+ adapter.visitIincInsn(2, 20);
+ adapter.visitVarInsn(Opcodes.ILOAD, 2);
+ adapter.visitInsn(Opcodes.IRETURN);
+ adapter.visitMaxs(1, 3);
+ adapter.visitEnd();
+
+ expected.visitCode();
+ expected.visitInsn(Opcodes.ICONST_0);
+ expected.visitVarInsn(Opcodes.ISTORE, 2);
+ expected.visitVarInsn(Opcodes.ILOAD, 1);
+ expected.visitBlockEndBeforeJump(0);
+ expected.visitTableSwitchInsn(1, 1, label1, new Label[] { label0 });
+ expected.visitBlockEnd(0);
+ expected.visitLabel(label0);
+ expected.visitIincInsn(2, 10);
+ expected.visitBlockEndBeforeJump(1);
+ expected.visitBlockEnd(1);
+ expected.visitLabel(label1);
+ expected.visitIincInsn(2, 20);
+ expected.visitVarInsn(Opcodes.ILOAD, 2);
+ expected.visitBlockEndBeforeJump(2);
+ expected.visitInsn(Opcodes.IRETURN);
+ expected.visitBlockEnd(2);
+ expected.visitMaxs(1, 3);
+ expected.visitEnd();
+
+ assertEquals(expected, actual);
+ }
+
+ int sampleLookupSwitch(int a) {
+ int result = 0;
+ switch (a) {
+ case 1:
+ result += 10;
+ case 100:
+ result += 20;
+ default:
+ result += 40;
+ }
+ return result;
+ }
+
+ @Test
+ public void testLookupSwitch() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+
+ adapter.visitCode();
+ adapter.visitInsn(Opcodes.ICONST_0);
+ adapter.visitVarInsn(Opcodes.ISTORE, 2);
+ adapter.visitVarInsn(Opcodes.ILOAD, 1);
+ adapter.visitLookupSwitchInsn(label2, new int[] { 1, 100 },
+ new Label[] { label0, label1 });
+ adapter.visitLabel(label0);
+ adapter.visitIincInsn(2, 10);
+ adapter.visitLabel(label1);
+ adapter.visitIincInsn(2, 20);
+ adapter.visitLabel(label2);
+ adapter.visitIincInsn(2, 40);
+ adapter.visitVarInsn(Opcodes.ILOAD, 2);
+ adapter.visitInsn(Opcodes.IRETURN);
+ adapter.visitMaxs(1, 3);
+ adapter.visitEnd();
+
+ expected.visitCode();
+ expected.visitInsn(Opcodes.ICONST_0);
+ expected.visitVarInsn(Opcodes.ISTORE, 2);
+ expected.visitVarInsn(Opcodes.ILOAD, 1);
+ expected.visitBlockEndBeforeJump(0);
+ expected.visitLookupSwitchInsn(label2, new int[] { 1, 100 },
+ new Label[] { label0, label1 });
+ expected.visitBlockEnd(0);
+ expected.visitLabel(label0);
+ expected.visitIincInsn(2, 10);
+ expected.visitBlockEndBeforeJump(1);
+ expected.visitBlockEnd(1);
+ expected.visitLabel(label1);
+ expected.visitIincInsn(2, 20);
+ expected.visitBlockEndBeforeJump(2);
+ expected.visitBlockEnd(2);
+ expected.visitLabel(label2);
+ expected.visitIincInsn(2, 40);
+ expected.visitVarInsn(Opcodes.ILOAD, 2);
+ expected.visitBlockEndBeforeJump(3);
+ expected.visitInsn(Opcodes.IRETURN);
+ expected.visitBlockEnd(3);
+ expected.visitMaxs(1, 3);
+ expected.visitEnd();
+
+ assertEquals(expected, actual);
+ }
+
+ boolean sampleTryCatch(Runnable job) {
+ try {
+ job.run();
+ } catch (IllegalStateException e) {
+ return false;
+ }
+ return true;
+ }
+
+ @Test
+ public void testTryCatch() {
+ Label label0 = new Label();
+ Label label1 = new Label();
+ Label label2 = new Label();
+ Label label3 = new Label();
+
+ adapter.visitCode();
+ adapter.visitTryCatchBlock(label0, label1, label2,
+ "java/lang/IllegalStateException");
+ adapter.visitLabel(label0);
+ adapter.visitVarInsn(Opcodes.ALOAD, 1);
+ adapter.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Runnable",
+ "run", "()V");
+ adapter.visitLabel(label1);
+ adapter.visitJumpInsn(Opcodes.GOTO, label3);
+ adapter.visitLabel(label2);
+ adapter.visitVarInsn(Opcodes.ASTORE, 2);
+ adapter.visitInsn(Opcodes.ICONST_0);
+ adapter.visitInsn(Opcodes.IRETURN);
+ adapter.visitLabel(label3);
+ adapter.visitInsn(Opcodes.ICONST_1);
+ adapter.visitInsn(Opcodes.IRETURN);
+ adapter.visitMaxs(1, 3);
+ adapter.visitEnd();
+
+ expected.visitCode();
+ expected.visitTryCatchBlock(label0, label1, label2,
+ "java/lang/IllegalStateException");
+ expected.visitLabel(label0);
+ expected.visitVarInsn(Opcodes.ALOAD, 1);
+ expected.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Runnable",
+ "run", "()V");
+ expected.visitBlockEndBeforeJump(0);
+ expected.visitBlockEnd(0);
+ expected.visitLabel(label1);
+ expected.visitBlockEndBeforeJump(1);
+ expected.visitJumpInsn(Opcodes.GOTO, label3);
+ expected.visitBlockEnd(1);
+ expected.visitLabel(label2);
+ expected.visitVarInsn(Opcodes.ASTORE, 2);
+ expected.visitInsn(Opcodes.ICONST_0);
+ expected.visitBlockEndBeforeJump(2);
+ expected.visitInsn(Opcodes.IRETURN);
+ expected.visitBlockEnd(2);
+ expected.visitLabel(label3);
+ expected.visitInsn(Opcodes.ICONST_1);
+ expected.visitBlockEndBeforeJump(3);
+ expected.visitInsn(Opcodes.IRETURN);
+ expected.visitBlockEnd(3);
+ expected.visitMaxs(1, 3);
+ expected.visitEnd();
+
+ assertEquals(expected, actual);
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/CRC64Test.java b/org.jacoco.core.test/src/org/jacoco/core/instr/CRC64Test.java
new file mode 100644
index 00000000..0483ea7f
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/instr/CRC64Test.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.instr;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.UnsupportedEncodingException;
+
+import org.jacoco.core.instr.CRC64;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link CRC64}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class CRC64Test {
+
+ @Test
+ public void test0() throws UnsupportedEncodingException {
+ final long sum = CRC64.checksum(new byte[0]);
+ assertTrue(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"));
+ assertTrue(0xE3DCADD69B01ADD1L == sum);
+ }
+
+ /**
+ * Example generated with http://fsumfe.sourceforge.net/
+ *
+ * @throws UnsupportedEncodingException
+ */
+ @Test
+ public void test2() throws UnsupportedEncodingException {
+ final long sum = CRC64.checksum(new byte[] { (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff });
+ assertTrue(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"));
+ assertTrue(0xD8016B38AAD48308L == sum);
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/IntSetTest.java b/org.jacoco.core.test/src/org/jacoco/core/instr/IntSetTest.java
new file mode 100644
index 00000000..11da3c5f
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/instr/IntSetTest.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.instr;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.jacoco.core.instr.IntSet;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link IntSet}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class IntSetTest {
+
+ private IntSet intset;
+
+ @Before
+ public void setup() {
+ intset = new IntSet();
+ }
+
+ @Test
+ public void testEmptySet() {
+ assertFalse(intset.contains(15));
+ assertContents();
+ }
+
+ @Test
+ public void testAdd1() {
+ intset.add(17);
+ intset.add(-1);
+ intset.add(0);
+ intset.add(20);
+ assertContents(-1, 0, 17, 20);
+ }
+
+ @Test
+ public void testAdd2() {
+ intset.add(11);
+ intset.add(33);
+ intset.add(11);
+ intset.add(33);
+ assertContents(11, 33);
+ }
+
+ @Test
+ public void testAdd3() {
+ final int[] expected = new int[100];
+ for (int i = 0; i < expected.length; i++) {
+ expected[i] = i;
+ intset.add(i);
+ }
+ assertContents(expected);
+ }
+
+ @Test
+ public void testContains() {
+ intset.add(11);
+ intset.add(15);
+ assertFalse(intset.contains(-11));
+ assertTrue(intset.contains(11));
+ assertTrue(intset.contains(15));
+ assertFalse(intset.contains(16));
+ }
+
+ @Test
+ public void testClear() {
+ intset.add(3);
+ intset.add(17);
+ intset.clear();
+ assertContents();
+ }
+
+ private void assertContents(int... expected) {
+ final int[] actual = intset.toArray();
+ assertEquals(expected.length, actual.length, 0.0);
+ for (int i = 0; i < expected.length; i++) {
+ final Integer e = Integer.valueOf(expected[i]);
+ final Integer a = Integer.valueOf(actual[i]);
+ assertEquals("element at " + i, e, a);
+ }
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/MethodInstrumenterTest.java b/org.jacoco.core.test/src/org/jacoco/core/instr/MethodInstrumenterTest.java
new file mode 100644
index 00000000..f3c6011f
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/instr/MethodInstrumenterTest.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.instr;
+
+import static org.junit.Assert.assertEquals;
+
+import org.jacoco.core.instr.MethodInstrumenter;
+import org.jacoco.core.test.MethodRecorder;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * Unit tests for {@link MethodInstrumenter}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class MethodInstrumenterTest {
+
+ private MethodInstrumenter instrumenter;
+
+ private MethodRecorder expected;
+
+ private MethodRecorder actual;
+
+ @Before
+ public void setup() {
+ actual = new MethodRecorder();
+ expected = new MethodRecorder();
+ instrumenter = new MethodInstrumenter(actual, 0, "test", "()V", 333,
+ Type.getObjectType("Target"));
+ }
+
+ void sampleReturn() {
+ return;
+ }
+
+ @Test
+ public void testReturn() {
+ instrumenter.visitCode();
+ instrumenter.visitBlockEndBeforeJump(0);
+ instrumenter.visitInsn(Opcodes.RETURN);
+ instrumenter.visitBlockEnd(0);
+ instrumenter.visitMaxs(0, 1);
+ instrumenter.visitEnd();
+
+ expected.visitCode();
+ expected.visitIntInsn(Opcodes.SIPUSH, 333);
+ expected.visitMethodInsn(Opcodes.INVOKESTATIC, "Target", "$jacocoInit",
+ "(I)[Z");
+ expected.visitVarInsn(Opcodes.ASTORE, 1);
+ expected.visitVarInsn(Opcodes.ALOAD, 1);
+ expected.visitInsn(Opcodes.ICONST_0);
+ expected.visitInsn(Opcodes.ICONST_1);
+ expected.visitInsn(Opcodes.BASTORE);
+ expected.visitInsn(Opcodes.RETURN);
+ // max stack size is not calculated by the MethodInstrumenter
+ expected.visitMaxs(0, 2);
+ expected.visitEnd();
+
+ assertEquals(expected, actual);
+ }
+}
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
new file mode 100644
index 00000000..fbbe6294
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/runtime/SystemPropertiesRuntimeTest.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+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.HashMap;
+import java.util.Map;
+
+import org.jacoco.core.data.IClassStructureOutput;
+import org.jacoco.core.data.IExecutionDataOutput;
+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.GeneratorAdapter;
+import org.objectweb.asm.commons.Method;
+
+/**
+ * Unit tests for {@link SystemPropertiesRuntime}.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class SystemPropertiesRuntimeTest {
+
+ private IRuntime runtime;
+
+ private TestStorage storage;
+
+ @Before
+ public void setup() {
+ runtime = new SystemPropertiesRuntime();
+ runtime.startup();
+ storage = new TestStorage();
+ }
+
+ @After
+ public void shutdown() {
+ runtime.shutdown();
+ }
+
+ @Test
+ public void testCollectEmpty() {
+ runtime.collect(storage, false);
+ storage.assertSize(0);
+ }
+
+ @Test
+ public void testCollect1() throws InstantiationException,
+ IllegalAccessException {
+ final boolean[][] data1 = new boolean[3][];
+ generateAndInstantiateClass(1001, data1);
+ runtime.collect(storage, false);
+ storage.assertSize(1);
+ storage.assertData(1001, data1);
+ }
+
+ @Test
+ public void testCollect2() throws InstantiationException,
+ IllegalAccessException {
+ final boolean[][] data1 = new boolean[3][];
+ final boolean[][] data2 = new boolean[5][];
+ generateAndInstantiateClass(1001, data1);
+ generateAndInstantiateClass(1002, data2);
+ runtime.collect(storage, false);
+ storage.assertSize(2);
+ storage.assertData(1001, data1);
+ storage.assertData(1002, data2);
+ }
+
+ @Test
+ public void testReset() throws InstantiationException,
+ IllegalAccessException {
+ final boolean[][] data1 = new boolean[1][];
+ data1[0] = new boolean[] { true, true, true };
+ generateAndInstantiateClass(1001, data1);
+ runtime.reset();
+ assertFalse(data1[0][0]);
+ assertFalse(data1[0][1]);
+ assertFalse(data1[0][2]);
+ }
+
+ @Test
+ public void testCollectAndReset() throws InstantiationException,
+ IllegalAccessException {
+ final boolean[][] data1 = new boolean[1][];
+ data1[0] = new boolean[] { true, true, true };
+ generateAndInstantiateClass(1001, data1);
+ runtime.collect(storage, true);
+ storage.assertSize(1);
+ storage.assertData(1001, data1);
+ assertFalse(data1[0][0]);
+ assertFalse(data1[0][1]);
+ assertFalse(data1[0][2]);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testShutdown() {
+ runtime.shutdown();
+ runtime.collect(storage, false);
+ }
+
+ /**
+ * Creates a new class with the given id, loads this class and injects the
+ * given data instance into the class. Used to check whether the data is
+ * properly collected in the runtime.
+ *
+ * @param classId
+ * @param data
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ */
+ private void generateAndInstantiateClass(int classId, boolean[][] data)
+ throws InstantiationException, IllegalAccessException {
+
+ final String className = "org/jacoco/test/targets/SystemPropertiesRuntimeTestTarget";
+ final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null,
+ "java/lang/Object", new String[] { Type
+ .getInternalName(IWriteAccess.class) });
+
+ // 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.returnValue();
+ gen.visitMaxs(0, 0);
+ gen.visitEnd();
+ writer.visitEnd();
+
+ // set()
+ gen = new GeneratorAdapter(writer.visitMethod(Opcodes.ACC_PUBLIC,
+ "set", "([[Z)V", null, new String[0]), Opcodes.ACC_PUBLIC,
+ "set", "([[Z)V");
+ gen.visitCode();
+ gen.loadArg(0);
+ runtime.generateRegistration(classId, gen);
+ gen.returnValue();
+ gen.visitMaxs(0, 0);
+ gen.visitEnd();
+ writer.visitEnd();
+
+ final TargetLoader loader = new TargetLoader(className
+ .replace('/', '.'), writer.toByteArray());
+ ((IWriteAccess) loader.newInstance()).set(data);
+ }
+
+ /**
+ * With this interface we inject sample coverage data into the generated
+ * classes.
+ */
+ public interface IWriteAccess {
+
+ void set(boolean[][] data);
+
+ }
+
+ private static class TestStorage implements IExecutionDataOutput {
+
+ 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));
+ }
+
+ // === ICoverageDataOutput ===
+
+ public void classExecution(long id, boolean[][] blockdata) {
+ data.put(Long.valueOf(id), blockdata);
+ }
+
+ public IClassStructureOutput classStructure(long id, String name,
+ String bundle) {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/ClassDataRecorder.java b/org.jacoco.core.test/src/org/jacoco/core/test/ClassDataRecorder.java
new file mode 100644
index 00000000..b5786a7d
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/ClassDataRecorder.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jacoco.core.data.IClassStructureOutput;
+import org.jacoco.core.data.IExecutionDataOutput;
+import org.jacoco.core.data.IMethodStructureOutput;
+import org.jacoco.core.data.IStructureOutput;
+
+/**
+ * Recorder for structure as well as coverage data for a single class providing
+ * different assertion mechanisms for testing.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+class ClassDataRecorder implements IExecutionDataOutput, IStructureOutput,
+ IClassStructureOutput {
+
+ public static class MethodDataRecorder implements IMethodStructureOutput {
+
+ private final int id;
+
+ private final String name, desc, signature;
+
+ private final List<BlockData> blocks = new ArrayList<BlockData>();
+
+ MethodDataRecorder(int id, String name, String desc, String signature) {
+ this.id = id;
+ this.name = name;
+ this.desc = desc;
+ this.signature = signature;
+ }
+
+ public void block(int id, int instructionCount, int[] lineNumbers) {
+ assertTrue("Unexpected block id " + id, blocks.size() == id);
+ blocks.add(new BlockData(instructionCount, lineNumbers));
+ }
+
+ public void end() {
+ }
+
+ public BlockData getBlock(int id) {
+ return blocks.get(id);
+ }
+ }
+
+ public static class BlockData {
+
+ private final int instructionCount;
+
+ private final int[] lineNumbers;
+
+ private boolean covered;
+
+ BlockData(int instructionCount, int[] lineNumbers) {
+ this.instructionCount = instructionCount;
+ this.lineNumbers = lineNumbers;
+ }
+
+ void setCovered(boolean covered) {
+ this.covered = covered;
+ }
+
+ public void assertCovered() {
+ assertTrue(covered);
+ }
+
+ public void assertNotCovered() {
+ assertFalse(covered);
+ }
+
+ public void assertLines(int... expected) {
+ assertTrue("Unexpected line count " + lineNumbers.length,
+ expected.length == lineNumbers.length);
+ for (int i = 0; i < expected.length; i++) {
+ final Integer e = Integer.valueOf(expected[i]);
+ final Integer a = Integer.valueOf(lineNumbers[i]);
+ assertTrue("Unexpected line " + a, e == a);
+ }
+ }
+
+ }
+
+ private long classid = -1L;
+
+ private final List<MethodDataRecorder> methods = new ArrayList<MethodDataRecorder>();
+
+ private final Map<String, MethodDataRecorder> methodsByName = new HashMap<String, MethodDataRecorder>();
+
+ public MethodDataRecorder getMethod(String name) {
+ MethodDataRecorder m = methodsByName.get(name);
+ assertNotNull("Unkown method " + name, m);
+ return m;
+ }
+
+ // === ICoverageDataOutput ===
+
+ public void classExecution(long id, boolean[][] blockdata) {
+ assertTrue("Coverage and structure data for the same class only.",
+ classid == id);
+ assertTrue("Unexpected method count " + blockdata.length, methods
+ .size() == blockdata.length);
+ for (int i = 0; i < blockdata.length; i++) {
+ final MethodDataRecorder m = methods.get(i);
+ for (int j = 0; j < blockdata[i].length; j++) {
+ m.getBlock(j).setCovered(blockdata[i][j]);
+ }
+ }
+ }
+
+ // === IStructureOutput ===
+
+ public IClassStructureOutput classStructure(long id, String name,
+ String bundle) {
+ assertTrue("Recorder can be used for a single class only.", id != -1);
+ classid = id;
+ return this;
+ }
+
+ // === IClassStructureOutput ===
+
+ public void sourceFile(String name) {
+ }
+
+ public IMethodStructureOutput methodStructure(int id, String name,
+ String desc, String signature) {
+ MethodDataRecorder m = new MethodDataRecorder(id, name, desc, signature);
+ methods.add(m);
+ methodsByName.put(name, m);
+ return m;
+ }
+
+ public void end() {
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/InstrumentationScenariosTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/InstrumentationScenariosTest.java
new file mode 100644
index 00000000..4159a9f7
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/InstrumentationScenariosTest.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test;
+
+import java.io.IOException;
+
+import org.jacoco.core.instr.Analyzer;
+import org.jacoco.core.instr.Instrumenter;
+import org.jacoco.core.runtime.IRuntime;
+import org.jacoco.core.runtime.SystemPropertiesRuntime;
+import org.jacoco.core.test.ClassDataRecorder.BlockData;
+import org.jacoco.core.test.targets.Target_cinit_01;
+import org.jacoco.core.test.targets.Target_cinit_02;
+import org.jacoco.core.test.targets.Target_init_01;
+import org.jacoco.core.test.targets.Target_init_02;
+import org.jacoco.core.test.targets.Target_init_03;
+import org.jacoco.core.test.targets.Target_init_04;
+import org.jacoco.core.test.targets.Target_init_05;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.ClassReader;
+
+/**
+ * Component tests for several different test scenarios. Each tests loads a
+ * instrumented class, creates a instance of it and executes it if it implements
+ * the {@link Runnable} interface. Afterwards several assertions about the
+ * structure and the coverage data are performed. *
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class InstrumentationScenariosTest {
+
+ private IRuntime runtime;
+
+ @Before
+ public void setup() {
+ runtime = new SystemPropertiesRuntime();
+ runtime.startup();
+ }
+
+ @Test
+ public void init_01() throws Exception {
+ final ClassDataRecorder rec = runScenario(Target_init_01.class);
+ final BlockData block0 = rec.getMethod("<init>").getBlock(0);
+ block0.assertLines(23);
+ block0.assertCovered();
+ }
+
+ @Test
+ public void init_02() throws Exception {
+ final ClassDataRecorder rec = runScenario(Target_init_02.class);
+ final BlockData block0 = rec.getMethod("<init>").getBlock(0);
+ block0.assertLines(25, 26);
+ block0.assertCovered();
+ }
+
+ @Test
+ public void init_03() throws Exception {
+ final ClassDataRecorder rec = runScenario(Target_init_03.class);
+ final BlockData block0 = rec.getMethod("<init>").getBlock(0);
+ block0.assertLines(23, 25);
+ block0.assertCovered();
+ }
+
+ @Test
+ public void init_04() throws Exception {
+ final ClassDataRecorder rec = runScenario(Target_init_04.class);
+ final BlockData block0 = rec.getMethod("<init>").getBlock(0);
+ block0.assertLines(25, 27, 28);
+ block0.assertCovered();
+ }
+
+ @Test
+ public void init_05() throws Exception {
+ final ClassDataRecorder rec = runScenario(Target_init_05.class);
+ final BlockData block0 = rec.getMethod("<init>").getBlock(0);
+ block0.assertLines(30);
+ block0.assertCovered();
+ }
+
+ @Test
+ public void cinit_01() throws Exception {
+ final ClassDataRecorder rec = runScenario(Target_cinit_01.class);
+ final BlockData block0 = rec.getMethod("<clinit>").getBlock(0);
+ block0.assertCovered();
+ }
+
+ @Test
+ public void cinit_02() throws Exception {
+ final ClassDataRecorder rec = runScenario(Target_cinit_02.class);
+ final BlockData block0 = rec.getMethod("<clinit>").getBlock(0);
+ block0.assertCovered();
+ }
+
+ private ClassDataRecorder runScenario(Class<?> clazz) throws IOException,
+ InstantiationException, IllegalAccessException {
+
+ ClassReader reader = new ClassReader(TargetLoader.getClassData(clazz));
+
+ final ClassDataRecorder rec = new ClassDataRecorder();
+ final Analyzer analyzer = new Analyzer(rec);
+ analyzer.analyze(reader, null);
+
+ final Instrumenter instr = new Instrumenter(runtime);
+ final byte[] instrumentedBuffer = instr.instrument(reader);
+ final TargetLoader loader = new TargetLoader(clazz, instrumentedBuffer);
+
+ final Object obj = loader.newInstance();
+ if (obj instanceof Runnable) {
+ ((Runnable) obj).run();
+ }
+
+ runtime.collect(rec, false);
+ return rec;
+ }
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/MethodRecorder.java b/org.jacoco.core.test/src/org/jacoco/core/test/MethodRecorder.java
new file mode 100644
index 00000000..0c887216
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/MethodRecorder.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.jacoco.core.instr.IBlockMethodVisitor;
+import org.objectweb.asm.util.TraceMethodVisitor;
+
+/**
+ * Recorder of method events for test verification.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class MethodRecorder extends TraceMethodVisitor implements
+ IBlockMethodVisitor {
+
+ @SuppressWarnings("unchecked")
+ public void visitBlockEndBeforeJump(int id) {
+ text.add(tab2 + "BlockEndBeforeJump #" + id + "\n");
+ }
+
+ @SuppressWarnings("unchecked")
+ public void visitBlockEnd(int id) {
+ text.add(tab2 + "BlockEnd #" + id + "\n");
+ }
+
+ @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/test/RuntimePerformancetest.java b/org.jacoco.core.test/src/org/jacoco/core/test/RuntimePerformancetest.java
new file mode 100644
index 00000000..c5c22035
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/RuntimePerformancetest.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+
+import org.jacoco.core.instr.Instrumenter;
+import org.jacoco.core.runtime.IRuntime;
+import org.jacoco.core.runtime.SystemPropertiesRuntime;
+import org.jacoco.core.test.targets.Target_performance_01;
+import org.jacoco.core.test.targets.Target_performance_02;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.ClassReader;
+
+/**
+ * Component tests for several different test scenarios. Each tests loads a
+ * instrumented class, creates a instance of it and executes it if it implements
+ * the {@link Runnable} interface. Afterwards several assertions about the
+ * structure and the coverage data are performed. *
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class RuntimePerformancetest {
+
+ private IRuntime runtime;
+
+ @Before
+ public void setup() {
+ runtime = new SystemPropertiesRuntime();
+ runtime.startup();
+ }
+
+ @Test
+ public void performance01() throws Exception {
+ Runnable reference = new Target_performance_01();
+ runPerformanceComparison(reference.toString(), reference,
+ getInstrumentedRunnable(Target_performance_01.class));
+ }
+
+ @Test
+ public void performance02() throws Exception {
+ Runnable reference = new Target_performance_02();
+ runPerformanceComparison(reference.toString(), reference,
+ getInstrumentedRunnable(Target_performance_02.class));
+ }
+
+ @Test
+ public void performance03() throws Exception {
+ int count = 10000;
+ runPerformance("Instrumenting " + count + " classes",
+ new InstrumentationProcess(Target_performance_02.class, count));
+ }
+
+ // TODO class initialization
+
+ private class InstrumentationProcess implements Runnable {
+
+ private final byte[] buffer;
+
+ private final int count;
+
+ InstrumentationProcess(Class<?> clazz, int count) throws IOException {
+ final String resource = "/" + clazz.getName().replace('.', '/')
+ + ".class";
+ final InputStream in = getClass().getResourceAsStream(resource);
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ int c;
+ while ((c = in.read()) != -1) {
+ out.write(c);
+ }
+ this.buffer = out.toByteArray();
+ this.count = count;
+ }
+
+ public void run() {
+ for (int i = 0; i < count; i++) {
+ ClassReader reader = new ClassReader(buffer);
+
+ final Instrumenter instr = new Instrumenter(runtime);
+ instr.instrument(reader);
+ }
+ }
+
+ }
+
+ private Runnable getInstrumentedRunnable(Class<? extends Runnable> clazz)
+ throws IOException, InstantiationException, IllegalAccessException {
+
+ final String resource = "/" + clazz.getName().replace('.', '/')
+ + ".class";
+ ClassReader reader = new ClassReader(getClass().getResourceAsStream(
+ resource));
+
+ final Instrumenter instr = new Instrumenter(runtime);
+ final byte[] instrumentedBuffer = instr.instrument(reader);
+ final TargetLoader loader = new TargetLoader(clazz, instrumentedBuffer);
+
+ return (Runnable) loader.newInstance();
+ }
+
+ private void runPerformanceComparison(String description,
+ Runnable reference, Runnable subject) {
+ long referenceTime = timer(reference);
+ long subjectTime = timer(subject);
+ double factor = (double) subjectTime / (double) referenceTime;
+ System.out.printf(Locale.US,
+ "%s reference=%.2fms subject=%.2fms factor=%.2f\n",
+ description, (double) referenceTime / 1000000,
+ (double) subjectTime / 1000000, factor);
+ }
+
+ private void runPerformance(String description, Runnable subject) {
+ long subjectTime = timer(subject);
+ System.out.printf(Locale.US, "%s subject=%.2fms", description,
+ (double) subjectTime / 1000000);
+ }
+
+ private long timer(Runnable subject) {
+ long start = System.nanoTime();
+ subject.run();
+ return System.nanoTime() - start;
+ }
+
+}
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
new file mode 100644
index 00000000..595af6d8
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/TargetLoader.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test;
+
+import java.io.InputStream;
+
+/**
+ * Loads a single class from a byte array.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class TargetLoader {
+
+ private final Class<?> clazz;
+
+ public TargetLoader(final String name, final byte[] bytes) {
+ clazz = load(name, bytes);
+ }
+
+ public TargetLoader(final Class<?> source, final byte[] bytes) {
+ clazz = load(source.getName(), bytes);
+ }
+
+ private Class<?> load(final String sourcename, final byte[] bytes) {
+ final ClassLoader cl = new ClassLoader(this.getClass().getClassLoader()) {
+
+ @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);
+ }
+ };
+ try {
+ return cl.loadClass(sourcename);
+ } catch (ClassNotFoundException e) {
+ // must not happen
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Class<?> getClazz() {
+ return clazz;
+ }
+
+ public Object newInstance() throws InstantiationException,
+ IllegalAccessException {
+ return clazz.newInstance();
+ }
+
+ public static InputStream getClassData(Class<?> clazz) {
+ final String resource = "/" + clazz.getName().replace('.', '/')
+ + ".class";
+ return clazz.getResourceAsStream(resource);
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Stubs.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Stubs.java
new file mode 100644
index 00000000..02026186
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Stubs.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+/**
+ * Collection of stub methods that are called from the coverage targets. *
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Stubs {
+
+ /**
+ * Does nothing.
+ */
+ public static void nop() {
+ }
+
+ /**
+ * @return always <code>true</code>
+ */
+ public static boolean t() {
+ return true;
+ }
+
+ /**
+ * @return always <code>false</code>
+ */
+ public static boolean f() {
+ return false;
+ }
+
+ /**
+ * Marker method m1.
+ */
+ public static void m1() {
+ }
+
+ /**
+ * Marker method m1.
+ */
+ public static boolean m1(boolean value) {
+ return value;
+ }
+
+ /**
+ * Marker method m1.
+ */
+ public static void m2() {
+ }
+
+ /**
+ * Marker method m1.
+ */
+ public static boolean m2(boolean value) {
+ return value;
+ }
+
+ /**
+ * Marker method m1.
+ */
+ public static void m3() {
+ }
+
+ /**
+ * Marker method m1.
+ */
+ public static boolean m3(boolean value) {
+ return value;
+ }
+
+ public static class Base {
+
+ public Base() {
+ }
+
+ public Base(boolean b) {
+ }
+
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target02.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target02.java
new file mode 100644
index 00000000..a89975e9
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target02.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+/**
+ * Empty interface.
+ *
+ * CHANGING LINE NUMBERS WILL BREAK TESTS!
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public interface Target02 {
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target20.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target20.java
new file mode 100644
index 00000000..e6b2a113
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target20.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+import static org.jacoco.core.test.targets.Stubs.m1;
+import static org.jacoco.core.test.targets.Stubs.m2;
+import static org.jacoco.core.test.targets.Stubs.m3;
+import static org.jacoco.core.test.targets.Stubs.t;
+
+/**
+ * Empty class.
+ *
+ * CHANGING LINE NUMBERS WILL BREAK TESTS!
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target20 implements Runnable {
+
+ public void run() {
+ if (m1(t())) { // ........... 31
+ m2(); // ................ 32
+ } else {
+ m3(); // ................ 34
+ }
+ } // ............................ 36
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_cinit_01.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_cinit_01.java
new file mode 100644
index 00000000..f00d81aa
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_cinit_01.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+/**
+ * Class with static initializer.
+ *
+ * CHANGING LINE NUMBERS WILL BREAK TESTS!
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target_cinit_01 { // ..... 23: Block 0 (<clinit> return)
+
+ static {
+ Stubs.nop(); // ............... 26: Block 0 (<clinit>)
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_cinit_02.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_cinit_02.java
new file mode 100644
index 00000000..6d606532
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_cinit_02.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+/**
+ * Class with implicit static initializer.
+ *
+ * CHANGING LINE NUMBERS WILL BREAK TESTS!
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target_cinit_02 { // ........... 23: Block 0 (<clinit> return)
+
+ static int field = 123; // .............. 25: Block 0 (<clinit>)
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_01.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_01.java
new file mode 100644
index 00000000..1e62a60f
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_01.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+/**
+ * Empty class.
+ *
+ * CHANGING LINE NUMBERS WILL BREAK TESTS!
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target_init_01 { // ................ 23: Block 0 (<init>)
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_02.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_02.java
new file mode 100644
index 00000000..9b43f900
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_02.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+/**
+ * Class with empty constructor.
+ *
+ * CHANGING LINE NUMBERS WILL BREAK TESTS!
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target_init_02 {
+
+ public Target_init_02() { // ........... 25: Block 0
+ } // ............................. 26: Block 0
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_03.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_03.java
new file mode 100644
index 00000000..674dff93
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_03.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+/**
+ * Class with implicit field initialization.
+ *
+ * CHANGING LINE NUMBERS WILL BREAK TESTS!
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target_init_03 { // ................. 23: Block 0 (<init>)
+
+ private final int field = 123; // ...... 25: Block 0 (<init>)
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_04.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_04.java
new file mode 100644
index 00000000..622a1ca9
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_04.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+/**
+ * Class with empty constructor and implicit field initialization.
+ *
+ * CHANGING LINE NUMBERS WILL BREAK TESTS!
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target_init_04 {
+
+ private final int field = 123; // ..... 25: Block 0 (<init>)
+
+ public Target_init_04() { // ................ 27: Block 0 (<init>)
+ } // .................................. 28: Block 0 (<init>)
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_05.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_05.java
new file mode 100644
index 00000000..c357fc20
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_init_05.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+package org.jacoco.core.test.targets;
+
+import static org.jacoco.core.test.targets.Stubs.m1;
+import static org.jacoco.core.test.targets.Stubs.m2;
+import static org.jacoco.core.test.targets.Stubs.t;
+
+/**
+ * Blocks finished before the super constructor is called.
+ *
+ * CHANGING LINE NUMBERS WILL BREAK TESTS!
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target_init_05 extends Stubs.Base {
+
+ public Target_init_05() {
+ super(t() ? m1(t()) : m2(t())); // ........ 30:
+ } // .......................................... 31:
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_performance_01.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_performance_01.java
new file mode 100644
index 00000000..0b64269f
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_performance_01.java
@@ -0,0 +1,111 @@
+package org.jacoco.core.test.targets;
+
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others All rights
+ * reserved. This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0 which accompanies this
+ * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+
+/**
+ * 1,398,101 plain method calls.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target_performance_01 implements Runnable {
+
+ // 4 ^ 0 = 1 times
+ public void run() {
+ m1();
+ m1();
+ m1();
+ m1();
+ }
+
+ // 4 ^ 1 = 4 times
+ private void m1() {
+ m2();
+ m2();
+ m2();
+ m2();
+ }
+
+ // 4 ^ 2 == 16 times
+ private void m2() {
+ m3();
+ m3();
+ m3();
+ m3();
+ }
+
+ // 4 ^ 3 == 64 times
+ private void m3() {
+ m4();
+ m4();
+ m4();
+ m4();
+ }
+
+ // 4 ^ 4 == 256 times
+ private void m4() {
+ m5();
+ m5();
+ m5();
+ m5();
+ }
+
+ // 4 ^ 5 == 1,024 times
+ private void m5() {
+ m6();
+ m6();
+ m6();
+ m6();
+ }
+
+ // 4 ^ 6 == 4,096 times
+ private void m6() {
+ m7();
+ m7();
+ m7();
+ m7();
+ }
+
+ // 4 ^ 7 == 16,384 times
+ private void m7() {
+ m8();
+ m8();
+ m8();
+ m8();
+ }
+
+ // 4 ^ 8 == 65,536 times
+ private void m8() {
+ m9();
+ m9();
+ m9();
+ m9();
+ }
+
+ // 4 ^ 9 == 262,144 times
+ private void m9() {
+ m10();
+ m10();
+ m10();
+ m10();
+ }
+
+ // 4 ^ 10 == 1,048,576 times
+ private void m10() {
+ }
+
+ @Override
+ public String toString() {
+ return "plain method calls";
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_performance_02.java b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_performance_02.java
new file mode 100644
index 00000000..ef0badbf
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/targets/Target_performance_02.java
@@ -0,0 +1,34 @@
+package org.jacoco.core.test.targets;
+
+/*******************************************************************************
+ * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others All rights
+ * reserved. This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0 which accompanies this
+ * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Marc R. Hoffmann - initial API and implementation
+ *
+ * $Id: $
+ *******************************************************************************/
+
+/**
+ * Loop within a method.
+ *
+ * @author Marc R. Hoffmann
+ * @version $Revision: $
+ */
+public class Target_performance_02 implements Runnable {
+
+ public void run() {
+ int count = 0;
+ for (int i = 0; i < 2000000; i++) {
+ count++;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "loop";
+ }
+
+}