aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core.test/src/org
diff options
context:
space:
mode:
authorMarc R. Hoffmann <hoffmann@mountainminds.com>2018-11-15 00:39:53 +0100
committerEvgeny Mandrikov <Godin@users.noreply.github.com>2018-11-15 00:39:53 +0100
commit4d4d02e6dbfb17f454bf4579ee13209e9f035154 (patch)
treef3d360b65f13e8a8955b2b837cc759b20bd78a6a /org.jacoco.core.test/src/org
parent470a132fc8001a8c2f76bfe19dba5bc0366fd665 (diff)
downloadjacoco-4d4d02e6dbfb17f454bf4579ee13209e9f035154.tar.gz
Refactor coverage analysis package (#744)
* Encapsulate insn/branch status tracking in Instruction * Move Instruction to the analysis package * Encapsulate Instruction building in new class InstructionsBuilder * Separate coverage calculation from filtering
Diffstat (limited to 'org.jacoco.core.test/src/org')
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/InstructionTest.java173
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/InstructionsBuilderTest.java189
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodAnalyzerTest.java13
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageCalculatorTest.java224
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/flow/InstructionTest.java124
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelInfoTest.java6
6 files changed, 598 insertions, 131 deletions
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/InstructionTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/InstructionTest.java
new file mode 100644
index 00000000..ec740e80
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/InstructionTest.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link Instruction}.
+ */
+public class InstructionTest {
+
+ private Instruction instruction;
+
+ @Before
+ public void setup() {
+ instruction = new Instruction(123);
+ }
+
+ @Test
+ public void getLine_should_return_line_number() {
+ assertEquals(123, instruction.getLine());
+ }
+
+ @Test
+ public void new_instance_should_have_no_coverage_and_no_branches() {
+ assertEquals(CounterImpl.COUNTER_1_0,
+ instruction.getInstructionCounter());
+ assertEquals(CounterImpl.COUNTER_0_0, instruction.getBranchCounter());
+ }
+
+ @Test
+ public void addBranchWithInstruction_should_not_increment_branches_when_only_one_branch_is_added() {
+ instruction.addBranch(new Instruction(122), 0);
+
+ assertEquals(CounterImpl.COUNTER_0_0, instruction.getBranchCounter());
+ }
+
+ @Test
+ public void addBranchWithInstruction_should_increment_branches_when_two_branches_are_added() {
+ instruction.addBranch(new Instruction(122), 0);
+ instruction.addBranch(new Instruction(123), 1);
+
+ assertEquals(CounterImpl.getInstance(2, 0),
+ instruction.getBranchCounter());
+ }
+
+ @Test
+ public void addBranchWithInstruction_should_propagate_existing_coverage_status() {
+ final Instruction target = new Instruction(122);
+ target.addBranch(true, 0);
+
+ instruction.addBranch(target, 0);
+
+ assertEquals(CounterImpl.COUNTER_0_1,
+ instruction.getInstructionCounter());
+ }
+
+ @Test
+ public void addBranchWithProbe_should_increment_branches_when_covered() {
+ instruction.addBranch(true, 0);
+ instruction.addBranch(true, 1);
+
+ assertEquals(CounterImpl.getInstance(0, 1),
+ instruction.getInstructionCounter());
+ assertEquals(CounterImpl.getInstance(0, 2),
+ instruction.getBranchCounter());
+ }
+
+ @Test
+ public void addBranchWithProbe_should_increment_branches_when_not_covered() {
+ instruction.addBranch(false, 0);
+ instruction.addBranch(false, 1);
+
+ assertEquals(CounterImpl.getInstance(1, 0),
+ instruction.getInstructionCounter());
+ assertEquals(CounterImpl.getInstance(2, 0),
+ instruction.getBranchCounter());
+ }
+
+ @Test
+ public void addBranchWithProbe_should_increment_branches_when_partly_covered() {
+ instruction.addBranch(false, 0);
+ instruction.addBranch(true, 1);
+
+ assertEquals(CounterImpl.getInstance(0, 1),
+ instruction.getInstructionCounter());
+ assertEquals(CounterImpl.getInstance(1, 1),
+ instruction.getBranchCounter());
+ }
+
+ @Test
+ public void addBranchWithProbe_should_propagate_coverage_status_to_existing_predecessors() {
+ final Instruction i1 = new Instruction(124);
+ final Instruction i2 = new Instruction(125);
+ instruction.addBranch(i1, 3);
+ i1.addBranch(i2, 5);
+
+ i2.addBranch(true, 8);
+
+ assertEquals(CounterImpl.COUNTER_0_1,
+ instruction.getInstructionCounter());
+ }
+
+ @Test
+ public void addBranch_should_count_large_number_of_branches() {
+ for (int branch = 0; branch < 0x1000; branch++) {
+ instruction.addBranch(true, branch);
+ }
+
+ assertEquals(CounterImpl.getInstance(0, 0x1000),
+ instruction.getBranchCounter());
+ }
+
+ @Test
+ public void addBranch_should_propagate_coverage_status_over_very_long_sequence() {
+ Instruction next = instruction;
+ for (int i = 0; i < 0x10000; i++) {
+ final Instruction insn = new Instruction(i);
+ next.addBranch(insn, 0);
+ next = insn;
+ }
+ next.addBranch(true, 0);
+
+ assertEquals(CounterImpl.COUNTER_0_1,
+ instruction.getInstructionCounter());
+ }
+
+ @Test
+ public void merge_should_calculate_superset_of_covered_branches() {
+ final Instruction i1 = new Instruction(124);
+ i1.addBranch(false, 1);
+ i1.addBranch(false, 2);
+ i1.addBranch(true, 3);
+ i1.addBranch(true, 4);
+ final Instruction i2 = new Instruction(124);
+ i2.addBranch(false, 1);
+ i2.addBranch(true, 2);
+ i2.addBranch(false, 3);
+ i2.addBranch(true, 4);
+
+ instruction = i1.merge(i2);
+
+ assertEquals(CounterImpl.getInstance(1, 3),
+ instruction.getBranchCounter());
+ }
+
+ @Test
+ public void replaceBranches_should_calculate_coverage_on_new_branches() {
+ Instruction i1 = new Instruction(1);
+ Instruction i2 = new Instruction(2);
+ Instruction i3 = new Instruction(3);
+ i3.addBranch(true, 0);
+
+ instruction = instruction.replaceBranches(Arrays.asList(i1, i2, i3));
+
+ assertEquals(CounterImpl.getInstance(2, 1),
+ instruction.getBranchCounter());
+ }
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/InstructionsBuilderTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/InstructionsBuilderTest.java
new file mode 100644
index 00000000..32dea10f
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/InstructionsBuilderTest.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.jacoco.core.analysis.ISourceFileCoverage;
+import org.jacoco.core.internal.flow.LabelInfo;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.InsnNode;
+
+/**
+ * Unit tests for {@link InstructionsBuilder}.
+ */
+public class InstructionsBuilderTest {
+
+ private InstructionsBuilder builder;
+
+ @Before
+ public void setup() {
+ builder = new InstructionsBuilder(new boolean[] { false, true });
+ }
+
+ @Test
+ public void current_line_number_should_be_applied_to_instructions() {
+ InsnNode i1 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i1);
+
+ builder.setCurrentLine(10);
+ InsnNode i2 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i2);
+ InsnNode i3 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i3);
+
+ builder.setCurrentLine(20);
+ InsnNode i4 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i4);
+
+ Map<AbstractInsnNode, Instruction> map = builder.getInstructions();
+ assertEquals(ISourceFileCoverage.UNKNOWN_LINE, map.get(i1).getLine());
+ assertEquals(10, map.get(i2).getLine());
+ assertEquals(10, map.get(i3).getLine());
+ assertEquals(20, map.get(i4).getLine());
+ }
+
+ @Test
+ public void null_probearray_should_not_mark_instruction_as_covered() {
+ builder = new InstructionsBuilder(null);
+
+ InsnNode i1 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i1);
+ builder.addProbe(5, 0);
+
+ Map<AbstractInsnNode, Instruction> map = builder.getInstructions();
+ assertEquals(CounterImpl.COUNTER_1_0,
+ map.get(i1).getInstructionCounter());
+ }
+
+ @Test
+ public void unexecuted_probe_should_not_mark_instruction_as_covered() {
+ InsnNode i1 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i1);
+ builder.addProbe(0, 0);
+
+ Map<AbstractInsnNode, Instruction> map = builder.getInstructions();
+ assertEquals(CounterImpl.COUNTER_1_0,
+ map.get(i1).getInstructionCounter());
+ }
+
+ @Test
+ public void executed_probe_should_mark_instruction_as_covered() {
+ InsnNode i1 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i1);
+ builder.addProbe(1, 0);
+
+ Map<AbstractInsnNode, Instruction> map = builder.getInstructions();
+ assertEquals(CounterImpl.COUNTER_0_1,
+ map.get(i1).getInstructionCounter());
+ }
+
+ @Test
+ public void subsequent_instructions_should_be_linked_by_default() {
+ InsnNode i1 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i1);
+
+ InsnNode i2 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i2);
+
+ // mark i2 as covered
+ builder.addProbe(1, 0);
+
+ // coverage should be propagated to i1
+ Map<AbstractInsnNode, Instruction> map = builder.getInstructions();
+ assertEquals(CounterImpl.COUNTER_0_1,
+ map.get(i1).getInstructionCounter());
+ }
+
+ @Test
+ public void subsequent_instructions_should_not_be_linked_when_noSuccessor_was_called() {
+ InsnNode i1 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i1);
+ builder.noSuccessor();
+
+ InsnNode i2 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i2);
+
+ // mark i2 as covered
+ builder.addProbe(1, 0);
+
+ // coverage should not be propagated to i1
+ Map<AbstractInsnNode, Instruction> map = builder.getInstructions();
+ assertEquals(CounterImpl.COUNTER_1_0,
+ map.get(i1).getInstructionCounter());
+ }
+
+ @Test
+ public void subsequent_instructions_should_be_linked_after_label_marked_as_successor() {
+ InsnNode i1 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i1);
+
+ Label l = new Label();
+ LabelInfo.setSuccessor(l);
+ builder.addLabel(l);
+ InsnNode i2 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i2);
+
+ // mark i2 as covered
+ builder.addProbe(1, 0);
+
+ // coverage should be propagated to i1
+ Map<AbstractInsnNode, Instruction> map = builder.getInstructions();
+ assertEquals(CounterImpl.COUNTER_0_1,
+ map.get(i1).getInstructionCounter());
+ }
+
+ @Test
+ public void subsequent_instructions_should_not_be_linked_after_label_not_marked_as_successor() {
+ InsnNode i1 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i1);
+
+ builder.addLabel(new Label());
+ InsnNode i2 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i2);
+
+ // mark i2 as covered
+ builder.addProbe(1, 0);
+
+ // coverage should not be propagated to i1
+ Map<AbstractInsnNode, Instruction> map = builder.getInstructions();
+ assertEquals(CounterImpl.COUNTER_1_0,
+ map.get(i1).getInstructionCounter());
+ }
+
+ @Test
+ public void jumps_should_propagate_coverage_status() {
+ InsnNode i1 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i1);
+ Label l2 = new Label();
+ builder.addJump(l2, 0);
+
+ builder.addLabel(l2);
+ InsnNode i2 = new InsnNode(Opcodes.NOP);
+ builder.addInstruction(i2);
+
+ // mark i2 as covered
+ builder.addProbe(1, 0);
+
+ // coverage should be propagated to i1
+ Map<AbstractInsnNode, Instruction> map = builder.getInstructions();
+ assertEquals(CounterImpl.COUNTER_0_1,
+ map.get(i1).getInstructionCounter());
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodAnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodAnalyzerTest.java
index d0484093..3260ae1e 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodAnalyzerTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodAnalyzerTest.java
@@ -884,14 +884,21 @@ public class MethodAnalyzerTest implements IProbeIdGenerator {
private void runMethodAnalzer(IFilter filter) {
LabelFlowAnalyzer.markLabels(method);
- final MethodAnalyzer analyzer = new MethodAnalyzer("doit", "()V", null,
- probes, filter, new FilterContextMock());
+ InstructionsBuilder builder = new InstructionsBuilder(probes);
+ final MethodAnalyzer analyzer = new MethodAnalyzer(builder);
+
final MethodProbesAdapter probesAdapter = new MethodProbesAdapter(
analyzer, this);
// note that CheckMethodAdapter verifies that this test does not violate
// contracts of ASM API
analyzer.accept(method, new CheckMethodAdapter(probesAdapter));
- result = analyzer.getCoverage();
+
+ MethodCoverageImpl mc = new MethodCoverageImpl("doit", "V()", null);
+ MethodCoverageCalculator mcc = new MethodCoverageCalculator(
+ builder.getInstructions());
+ filter.filter(method, new FilterContextMock(), mcc);
+ mcc.calculate(mc);
+ result = mc;
}
private void assertLine(int nr, int insnMissed, int insnCovered,
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageCalculatorTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageCalculatorTest.java
new file mode 100644
index 00000000..776dfb60
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodCoverageCalculatorTest.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.jacoco.core.analysis.ISourceFileCoverage;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
+
+/**
+ * Unit tests for {@link MethodCoverageCalculator}.
+ */
+public class MethodCoverageCalculatorTest {
+
+ private Map<AbstractInsnNode, Instruction> instructions;
+
+ // The purpose of this list is to link instruction nodes
+ private InsnList list;
+
+ private MethodCoverageImpl coverage;
+
+ @Before
+ public void setup() {
+ instructions = new HashMap<AbstractInsnNode, Instruction>();
+ coverage = new MethodCoverageImpl("run", "()V", null);
+ list = new InsnList();
+ }
+
+ @Test
+ public void should_report_instructions() {
+ addInsn(1, true);
+ addInsn(2, true);
+ addInsn(2, false);
+ addInsn(3, false);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.calculate(coverage);
+
+ assertLine(1, 0, 1, 0, 0);
+ assertLine(2, 1, 1, 0, 0);
+ assertLine(3, 1, 0, 0, 0);
+ }
+
+ @Test
+ public void should_report_instructions_with_branches() {
+ addInsn(1, false, false);
+ addInsn(2, false, false, true);
+ addInsn(3, false, true, true);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.calculate(coverage);
+
+ assertLine(1, 1, 0, 2, 0);
+ assertLine(2, 0, 1, 2, 1);
+ assertLine(3, 0, 1, 1, 2);
+ }
+
+ @Test
+ public void should_ignore_single_instruction() {
+ addInsn(1, true);
+ InsnNode i1 = addInsn(1, false);
+ addInsn(2, true);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.ignore(i1, i1);
+ c.calculate(coverage);
+
+ assertLine(1, 0, 1, 0, 0); // only one instruction not filtered
+ assertLine(2, 0, 1, 0, 0);
+ }
+
+ @Test
+ public void should_ignore_instruction_range() {
+ addInsn(1, true);
+ InsnNode i1 = addInsn(2, false);
+ addInsn(2, false);
+ addInsn(2, false);
+ addInsn(2, false);
+ InsnNode i2 = addInsn(2, false);
+ addInsn(3, true);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.ignore(i1, i2);
+ c.calculate(coverage);
+
+ assertLine(1, 0, 1, 0, 0);
+ assertLine(2, 0, 0, 0, 0); // all instructions filtered in line 2
+ assertLine(3, 0, 1, 0, 0);
+ }
+
+ @Test
+ public void should_merge_instructions() {
+ addInsn(1, true);
+ InsnNode i1 = addInsn(2, false, true);
+ InsnNode i2 = addInsn(2, true, false);
+ addInsn(3, true);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.merge(i1, i2);
+ c.calculate(coverage);
+
+ assertLine(1, 0, 1, 0, 0);
+ assertLine(2, 0, 1, 0, 2); // one fully covered instruction left
+ assertLine(3, 0, 1, 0, 0);
+ }
+
+ @Test
+ public void should_merge_multiple_instructions() {
+ InsnNode i1 = addInsn(1, true, false, false);
+ InsnNode i2 = addInsn(1, false, true, false);
+ InsnNode i3 = addInsn(1, false, false, true);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.merge(i1, i2);
+ c.merge(i2, i3);
+ c.calculate(coverage);
+
+ assertLine(1, 0, 1, 0, 3); // one fully covered instruction left
+ }
+
+ @Test
+ public void should_merge_instructions_redundant() {
+ addInsn(1, true);
+ InsnNode i1 = addInsn(2, false, true);
+ InsnNode i2 = addInsn(2, true, false);
+ addInsn(3, true);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.merge(i1, i2);
+ c.merge(i2, i1);
+ c.calculate(coverage);
+
+ assertLine(1, 0, 1, 0, 0);
+ assertLine(2, 0, 1, 0, 2); // one fully covered instruction left
+ assertLine(3, 0, 1, 0, 0);
+ }
+
+ @Test
+ public void should_replace_branches() {
+ InsnNode i1 = addInsn(1);
+ InsnNode i2 = addInsn(2, true);
+ InsnNode i3 = addInsn(2, true);
+ InsnNode i4 = addInsn(2, false);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.replaceBranches(i1,
+ new HashSet<AbstractInsnNode>(Arrays.asList(i2, i3, i4)));
+ c.calculate(coverage);
+
+ assertLine(1, 0, 1, 1, 2); // branches coverage status replaced
+ assertLine(2, 1, 2, 0, 0); // still in place
+ }
+
+ @Test
+ public void should_replace_branches_with_merged_instructions() {
+ InsnNode i1 = addInsn(1, false, false, false);
+ InsnNode i2 = addInsn(2, true);
+ InsnNode i3 = addInsn(2, false);
+ InsnNode i4 = addInsn(2, false);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.merge(i4, i3);
+ c.merge(i3, i2);
+ c.replaceBranches(i1,
+ new HashSet<AbstractInsnNode>(Arrays.asList(i2, i3, i4)));
+ c.calculate(coverage);
+
+ assertLine(1, 0, 1, 0, 3);
+ }
+
+ @Test
+ public void should_work_without_lines() {
+ addInsn(ISourceFileCoverage.UNKNOWN_LINE, false);
+ addInsn(ISourceFileCoverage.UNKNOWN_LINE, false);
+ addInsn(ISourceFileCoverage.UNKNOWN_LINE, true);
+
+ MethodCoverageCalculator c = new MethodCoverageCalculator(instructions);
+ c.calculate(coverage);
+
+ assertEquals(ISourceFileCoverage.UNKNOWN_LINE, coverage.getFirstLine());
+ assertEquals(ISourceFileCoverage.UNKNOWN_LINE, coverage.getLastLine());
+ assertEquals(CounterImpl.getInstance(2, 1),
+ coverage.getInstructionCounter());
+ }
+
+ private void assertLine(int idx, int mi, int ci, int mb, int cb) {
+ assertEquals("instructions", CounterImpl.getInstance(mi, ci),
+ coverage.getLine(idx).getInstructionCounter());
+ assertEquals("branches", CounterImpl.getInstance(mb, cb),
+ coverage.getLine(idx).getBranchCounter());
+ }
+
+ private InsnNode addInsn(int line, boolean... branches) {
+ Instruction i = new Instruction(line);
+ int idx = 0;
+ for (boolean covered : branches) {
+ i.addBranch(covered, idx++);
+ }
+ InsnNode node = new InsnNode(Opcodes.NOP);
+ list.add(node);
+ instructions.put(node, i);
+ return node;
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/InstructionTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/InstructionTest.java
deleted file mode 100644
index 950827c1..00000000
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/InstructionTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Marc R. Hoffmann - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.core.internal.flow;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.tree.InsnNode;
-
-/**
- * Unit tests for {@link Instruction}.
- */
-public class InstructionTest {
-
- private Instruction instruction;
-
- @Before
- public void setup() {
- instruction = new Instruction(new InsnNode(Opcodes.NOP), 123);
- }
-
- @Test
- public void testInit() {
- final InsnNode node = new InsnNode(Opcodes.NOP);
- instruction = new Instruction(node, 123);
- assertSame(node, instruction.getNode());
- assertEquals(123, instruction.getLine());
- assertEquals(0, instruction.getBranches());
- assertEquals(0, instruction.getCoveredBranches());
- }
-
- @Test
- public void testAddBranch() {
- instruction.addBranch();
- assertEquals(1, instruction.getBranches());
- instruction.addBranch();
- assertEquals(2, instruction.getBranches());
- instruction.addBranch();
- assertEquals(3, instruction.getBranches());
- assertEquals(0, instruction.getCoveredBranches());
- }
-
- @Test
- public void testSetPredecessor() {
- final Instruction predecessor = new Instruction(
- new InsnNode(Opcodes.NOP), 122);
- instruction.setPredecessor(predecessor, 0);
- assertEquals(1, predecessor.getBranches());
- }
-
- @Test
- public void setCovered_should_mark_branch_in_predecessor() {
- final Instruction i = new Instruction(new InsnNode(Opcodes.NOP), 122);
- i.setCovered(2);
- assertEquals(1, i.getCoveredBranches());
- assertEquals("{2}", i.toString());
-
- final Instruction s1 = new Instruction(new InsnNode(Opcodes.NOP), 123);
- s1.setPredecessor(i, 1);
- s1.setCovered(0);
- assertEquals("{0}", s1.toString());
- assertEquals(1, s1.getCoveredBranches());
- assertEquals("{1, 2}", i.toString());
- assertEquals(2, i.getCoveredBranches());
-
- final Instruction s2 = new Instruction(new InsnNode(Opcodes.NOP), 124);
- s2.setPredecessor(i, 0);
- s2.setCovered(1);
- assertEquals("{0}", s1.toString());
- assertEquals(1, s2.getCoveredBranches());
- assertEquals("{0, 1, 2}", i.toString());
- assertEquals(3, i.getCoveredBranches());
- }
-
- @Test
- public void should_use_BitSet_to_hold_information_about_branches_of_big_switches() {
- for (int branch = 0; branch < 256; branch++) {
- instruction.setCovered(branch);
- }
- assertEquals(256, instruction.getCoveredBranches());
- }
-
- @Test
- public void merge_should_add_covered_branches_from_another_instruction() {
- final Instruction i1 = new Instruction(new InsnNode(Opcodes.NOP), 123);
- i1.setCovered(0);
- final Instruction i2 = new Instruction(new InsnNode(Opcodes.NOP), 123);
- i2.setCovered(1);
- i1.merge(i2);
- assertEquals("{0, 1}", i1.toString());
- assertEquals(2, i1.getCoveredBranches());
- assertEquals("{1}", i2.toString());
- }
-
- @Test
- public void testSetCoveredOnLongSequence() {
- final Instruction first = new Instruction(new InsnNode(Opcodes.NOP), 0);
- Instruction next = first;
- for (int i = 0; i < 0x10000; i++) {
- final Instruction insn = new Instruction(new InsnNode(Opcodes.NOP),
- i);
- insn.setPredecessor(next, 0);
- next = insn;
- }
-
- // The implementation must not cause an StackOverflowError even on very
- // long sequences:
- next.setCovered(0);
- assertEquals(1, first.getCoveredBranches());
- }
-
-}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelInfoTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelInfoTest.java
index 85007950..1ed75724 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelInfoTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/flow/LabelInfoTest.java
@@ -17,11 +17,10 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import org.jacoco.core.internal.analysis.Instruction;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.Label;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.tree.InsnNode;
/**
* Unit tests for {@link LabelInfoTest}.
@@ -161,8 +160,7 @@ public class LabelInfoTest {
@Test
public void testSetInstruction() {
- final Instruction instruction = new Instruction(
- new InsnNode(Opcodes.NOP), 123);
+ final Instruction instruction = new Instruction(123);
LabelInfo.setInstruction(label, instruction);
assertSame(instruction, LabelInfo.getInstruction(label));
}