diff options
author | Evgeny Mandrikov <Godin@users.noreply.github.com> | 2018-07-21 22:47:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-21 22:47:34 +0200 |
commit | 88e67b3f121121161f29f15ab8c45e6fc7ecd6d4 (patch) | |
tree | 0eb5e7cc76a8cf440f3011daadbbd8a23a6acca1 /org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation | |
parent | 753d6532d56892d037ff7958ea30c9bc27f6e8e4 (diff) | |
download | jacoco-88e67b3f121121161f29f15ab8c45e6fc7ecd6d4.tar.gz |
Extract "validation" tests into separate modules (#711)
Diffstat (limited to 'org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation')
34 files changed, 2788 insertions, 0 deletions
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/AnnotationInitializerTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/AnnotationInitializerTest.java new file mode 100644 index 00000000..60a38339 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/AnnotationInitializerTest.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.AnnotationInitializer; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Test of initializer in annotations. + */ +public class AnnotationInitializerTest extends ValidationTestBase { + + public AnnotationInitializerTest() { + super(AnnotationInitializer.class); + } + + @Override + protected void run(Class<?> targetClass) throws Exception { + // Instrumentation should not add members, + // otherwise sun.reflect.annotation.AnnotationInvocationHandler + // can throw java.lang.annotation.AnnotationFormatError + assertEquals(1, targetClass.getDeclaredFields().length); + assertEquals(1, targetClass.getDeclaredMethods().length); + + // Force initialization + targetClass.getField("CONST").get(null); + } + + @Test + public void testCoverageResult() { + assertLine("const", ICounter.FULLY_COVERED); + assertLine("value", ICounter.EMPTY); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/BadCycleClassTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/BadCycleClassTest.java new file mode 100644 index 00000000..aa646ddf --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/BadCycleClassTest.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.BadCycleClass; +import org.junit.Test; + +/** + * Test of "bad cycles" with classes. + */ +public class BadCycleClassTest extends ValidationTestBase { + + public BadCycleClassTest() throws Exception { + super(BadCycleClass.class); + } + + @Test + public void test() throws Exception { + assertLine("childinit", ICounter.FULLY_COVERED); + assertLine("childsomeMethod", ICounter.FULLY_COVERED); + assertLine("childclinit", ICounter.FULLY_COVERED); + + // The cycle causes a constructor and instance method to be called + // before the static initializer of a class: + assertLogEvents("childinit", "childsomeMethod", "childclinit", + "childinit"); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/BooleanExpressionsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/BooleanExpressionsTest.java new file mode 100644 index 00000000..64dee474 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/BooleanExpressionsTest.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target02; +import org.junit.Test; + +/** + * Tests of basic Java boolean expressions. + */ +public class BooleanExpressionsTest extends ValidationTestBase { + + public BooleanExpressionsTest() { + super(Target02.class); + } + + @Test + public void testCoverageResult() { + + // 1. Boolean comparison result (one case) + assertLine("booleancmp1", ICounter.PARTLY_COVERED, 1, 1); + + // 2. Boolean comparison result (both cases) + assertLine("booleancmp2", ICounter.FULLY_COVERED, 0, 2); + + // 3. And + assertLine("andFF", ICounter.FULLY_COVERED, 1, 1); + assertLine("andFT", ICounter.FULLY_COVERED, 1, 1); + assertLine("andTF", ICounter.FULLY_COVERED, 1, 1); + assertLine("andTT", ICounter.FULLY_COVERED, 1, 1); + + // 4. Conditional And + assertLine("conditionalandFF", ICounter.PARTLY_COVERED, 3, 1); + assertLine("conditionalandFT", ICounter.PARTLY_COVERED, 3, 1); + assertLine("conditionalandTF", ICounter.FULLY_COVERED, 2, 2); + assertLine("conditionalandTT", ICounter.FULLY_COVERED, 2, 2); + + // 5. Or + assertLine("orFF", ICounter.FULLY_COVERED, 1, 1); + assertLine("orFT", ICounter.FULLY_COVERED, 1, 1); + assertLine("orTF", ICounter.FULLY_COVERED, 1, 1); + assertLine("orTT", ICounter.FULLY_COVERED, 1, 1); + + // 6. Conditional Or + assertLine("conditionalorFF", ICounter.FULLY_COVERED, 2, 2); + assertLine("conditionalorFT", ICounter.FULLY_COVERED, 2, 2); + assertLine("conditionalorTF", ICounter.PARTLY_COVERED, 3, 1); + assertLine("conditionalorTT", ICounter.PARTLY_COVERED, 3, 1); + + // 7. Exclusive Or + assertLine("xorFF", ICounter.FULLY_COVERED, 1, 1); + assertLine("xorFT", ICounter.FULLY_COVERED, 1, 1); + assertLine("xorTF", ICounter.FULLY_COVERED, 1, 1); + assertLine("xorTT", ICounter.FULLY_COVERED, 1, 1); + + // 8. Conditional Operator + assertLine("condT", ICounter.PARTLY_COVERED, 1, 1); + assertLine("condF", ICounter.PARTLY_COVERED, 1, 1); + + // 9. Not (one case) + assertLine("notT", ICounter.PARTLY_COVERED, 1, 1); + assertLine("notF", ICounter.PARTLY_COVERED, 1, 1); + + // 10. Not (both cases) + assertLine("notTF", ICounter.FULLY_COVERED, 0, 2); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ClassFileVersionsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ClassFileVersionsTest.java new file mode 100644 index 00000000..87d78a21 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ClassFileVersionsTest.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * 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.test.validation; + +import static org.junit.Assert.assertEquals; +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static org.objectweb.asm.Opcodes.ACC_SUPER; +import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.F_NEW; +import static org.objectweb.asm.Opcodes.IFEQ; +import static org.objectweb.asm.Opcodes.ILOAD; +import static org.objectweb.asm.Opcodes.INVOKESPECIAL; +import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; +import static org.objectweb.asm.Opcodes.POP; +import static org.objectweb.asm.Opcodes.RETURN; +import static org.objectweb.asm.Opcodes.V1_1; +import static org.objectweb.asm.Opcodes.V1_2; +import static org.objectweb.asm.Opcodes.V1_3; +import static org.objectweb.asm.Opcodes.V1_4; +import static org.objectweb.asm.Opcodes.V1_5; +import static org.objectweb.asm.Opcodes.V1_6; +import static org.objectweb.asm.Opcodes.V1_7; +import static org.objectweb.asm.Opcodes.V1_8; +import static org.objectweb.asm.Opcodes.V9; + +import java.io.IOException; + +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.internal.BytecodeVersion; +import org.jacoco.core.internal.instr.InstrSupport; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.SystemPropertiesRuntime; +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Test class inserted stackmap frames for different class file versions. + */ +public class ClassFileVersionsTest { + + @Test + public void test_1_1() throws IOException { + testVersion(V1_1, false); + } + + @Test + public void test_1_2() throws IOException { + testVersion(V1_2, false); + } + + @Test + public void test_1_3() throws IOException { + testVersion(V1_3, false); + } + + @Test + public void test_1_4() throws IOException { + testVersion(V1_4, false); + } + + @Test + public void test_1_5() throws IOException { + testVersion(V1_5, false); + } + + @Test + public void test_1_6() throws IOException { + testVersion(V1_6, true); + } + + @Test + public void test_1_7() throws IOException { + testVersion(V1_7, true); + } + + @Test + public void test_1_8() throws IOException { + testVersion(V1_8, true); + } + + @Test + public void test_9() throws IOException { + testVersion(V9, true); + } + + @Test + public void test_10() throws IOException { + testVersion(BytecodeVersion.V10, true); + } + + private void testVersion(int version, boolean frames) throws IOException { + final byte[] original = createClass(version, frames); + + IRuntime runtime = new SystemPropertiesRuntime(); + Instrumenter instrumenter = new Instrumenter(runtime); + byte[] instrumented = instrumenter.instrument(original, "TestTarget"); + + assertFrames(instrumented, frames); + } + + private void assertFrames(byte[] source, final boolean expected) { + int version = BytecodeVersion.get(source); + source = BytecodeVersion.downgradeIfNeeded(version, source); + new ClassReader(source) + .accept(new ClassVisitor(InstrSupport.ASM_API_VERSION) { + + @Override + public MethodVisitor visitMethod(int access, String name, + String desc, String signature, + String[] exceptions) { + return new MethodVisitor(InstrSupport.ASM_API_VERSION) { + boolean frames = false; + + @Override + public void visitFrame(int type, int nLocal, + Object[] local, int nStack, + Object[] stack) { + frames = true; + } + + @Override + public void visitEnd() { + assertEquals(Boolean.valueOf(expected), + Boolean.valueOf(frames)); + } + }; + } + }, 0); + } + + /** + * Creates a class that requires a frame before the return statement. Also + * for this class instrumentation should insert another frame. + * + * <code><pre> + * public class Sample { + * public Sample(boolean b){ + * if(b){ + * toString(); + * } + * return; + * } + * } + * </pre></code> + */ + private byte[] createClass(int version, boolean frames) { + + ClassWriter cw = new ClassWriter(0); + MethodVisitor mv; + + cw.visit(version, ACC_PUBLIC + ACC_SUPER, "org/jacoco/test/Sample", + null, "java/lang/Object", null); + + mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Z)V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", + false); + mv.visitVarInsn(ILOAD, 1); + Label l1 = new Label(); + mv.visitJumpInsn(IFEQ, l1); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", + "()Ljava/lang/String;", false); + mv.visitInsn(POP); + mv.visitLabel(l1); + if (frames) { + mv.visitFrame(F_NEW, 2, + new Object[] { "org/jacoco/test/Sample", Opcodes.INTEGER }, + 0, new Object[] {}); + } + mv.visitInsn(RETURN); + mv.visitMaxs(1, 2); + mv.visitEnd(); + + cw.visitEnd(); + + return cw.toByteArray(); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ClassInitializerTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ClassInitializerTest.java new file mode 100644 index 00000000..f87e705c --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ClassInitializerTest.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target05; +import org.junit.Test; + +/** + * Tests of static initializer in classes. + */ +public class ClassInitializerTest extends ValidationTestBase { + + public ClassInitializerTest() { + super(Target05.class); + } + + @Test + public void testCoverageResult() { + + assertLine("const1", ICounter.EMPTY); + assertLine("const2", ICounter.EMPTY); + + assertLine("const3", ICounter.FULLY_COVERED); + assertLine("const4", ICounter.FULLY_COVERED); + + assertLine("field1", ICounter.FULLY_COVERED); + assertLine("field2", ICounter.FULLY_COVERED); + assertLine("field3", ICounter.FULLY_COVERED); + assertLine("field4", ICounter.FULLY_COVERED); + + assertLine("staticblock", ICounter.FULLY_COVERED); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ControlStructuresTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ControlStructuresTest.java new file mode 100644 index 00000000..37db4c14 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ControlStructuresTest.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target01; +import org.junit.Test; + +/** + * Tests of basic Java control structures. + */ +public class ControlStructuresTest extends ValidationTestBase { + + public ControlStructuresTest() { + super(Target01.class); + } + + @Test + public void testCoverageResult() { + + // 1. Direct unconditional execution + assertLine("unconditional", ICounter.FULLY_COVERED); + + // 2. Missed if block + assertLine("iffalse", ICounter.FULLY_COVERED, 1, 1); + assertLine("missedif", ICounter.NOT_COVERED); + assertLine("executedelse", ICounter.FULLY_COVERED); + + // 3. Executed if block + assertLine("iftrue", ICounter.FULLY_COVERED, 1, 1); + assertLine("executedif", ICounter.FULLY_COVERED); + assertLine("missedelse", ICounter.NOT_COVERED); + + // 4. Missed while block + assertLine("whilefalse", ICounter.FULLY_COVERED, 1, 1); + assertLine("missedwhile", ICounter.NOT_COVERED); + + // 5. Always true while block + assertLine("whiletrue", ICounter.FULLY_COVERED, 1, 1); + + // 6. Executed while block + assertLine("whiletruefalse", ICounter.FULLY_COVERED, 0, 2); + assertLine("executedwhile", ICounter.FULLY_COVERED); + + // 7. Executed do while block + assertLine("executeddowhile", ICounter.FULLY_COVERED); + assertLine("executeddowhilefalse", ICounter.FULLY_COVERED, 1, 1); + + // 8. Missed for block + assertLine("missedforincrementer", ICounter.PARTLY_COVERED, 1, 1); + assertLine("missedfor", ICounter.NOT_COVERED); + + // 9. Executed for block + assertLine("executedforincrementer", ICounter.FULLY_COVERED, 0, 2); + assertLine("executedfor", ICounter.FULLY_COVERED); + + // 10. Missed for each block + assertLine("missedforeachincrementer", ICounter.PARTLY_COVERED, 1, 1); + assertLine("missedforeach", ICounter.NOT_COVERED); + + // 11. Executed for each block + assertLine("executedforeachincrementer", ICounter.FULLY_COVERED, 0, 2); + assertLine("executedforeach", ICounter.FULLY_COVERED); + + // 12. Table switch with hit + assertLine("tswitch1", ICounter.FULLY_COVERED, 3, 1); + assertLine("tswitch1case1", ICounter.NOT_COVERED); + assertLine("tswitch1case2", ICounter.FULLY_COVERED); + assertLine("tswitch1case3", ICounter.NOT_COVERED); + assertLine("tswitch1default", ICounter.NOT_COVERED); + + // 13. Continued table switch with hit + assertLine("tswitch2", ICounter.FULLY_COVERED, 3, 1); + assertLine("tswitch2case1", ICounter.NOT_COVERED); + assertLine("tswitch2case2", ICounter.FULLY_COVERED); + assertLine("tswitch2case3", ICounter.FULLY_COVERED); + assertLine("tswitch2default", ICounter.FULLY_COVERED); + + // 14. Table switch without hit + assertLine("tswitch2", ICounter.FULLY_COVERED, 3, 1); + assertLine("tswitch3case1", ICounter.NOT_COVERED); + assertLine("tswitch3case2", ICounter.NOT_COVERED); + assertLine("tswitch3case3", ICounter.NOT_COVERED); + assertLine("tswitch3default", ICounter.FULLY_COVERED); + + // 15. Lookup switch with hit + assertLine("lswitch1", ICounter.FULLY_COVERED, 3, 1); + assertLine("lswitch1case1", ICounter.NOT_COVERED); + assertLine("lswitch1case2", ICounter.FULLY_COVERED); + assertLine("lswitch1case3", ICounter.NOT_COVERED); + assertLine("lswitch1default", ICounter.NOT_COVERED); + + // 16. Continued lookup switch with hit + assertLine("lswitch2", ICounter.FULLY_COVERED, 3, 1); + assertLine("lswitch2case1", ICounter.NOT_COVERED); + assertLine("lswitch2case2", ICounter.FULLY_COVERED); + assertLine("lswitch2case3", ICounter.FULLY_COVERED); + assertLine("lswitch2default", ICounter.FULLY_COVERED); + + // 17. Lookup switch without hit + assertLine("lswitch3", ICounter.FULLY_COVERED, 3, 1); + assertLine("lswitch3case1", ICounter.NOT_COVERED); + assertLine("lswitch3case2", ICounter.NOT_COVERED); + assertLine("lswitch3case3", ICounter.NOT_COVERED); + assertLine("lswitch3default", ICounter.FULLY_COVERED); + + // 18. Break statement + assertLine("executedbreak", ICounter.FULLY_COVERED); + assertLine("missedafterbreak", ICounter.NOT_COVERED); + + // 19. Continue statement + assertLine("executedcontinue", ICounter.FULLY_COVERED); + assertLine("missedaftercontinue", ICounter.NOT_COVERED); + + // 20. Conditional return statement + assertLine("conditionalreturn", ICounter.FULLY_COVERED); + assertLine("afterconditionalreturn", ICounter.NOT_COVERED); + + // 21. Implicit return + assertLine("implicitreturn", ICounter.FULLY_COVERED); + + // 22. Explicit return + assertLine("explicitreturn", ICounter.FULLY_COVERED); + assertLine("afterexplicitreturn", ICounter.EMPTY); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/CyclomaticComplexityTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/CyclomaticComplexityTest.java new file mode 100644 index 00000000..122612ce --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/CyclomaticComplexityTest.java @@ -0,0 +1,280 @@ +/******************************************************************************* + * 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.test.validation; + +import static org.jacoco.core.test.validation.targets.Stubs.nop; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.Collection; + +import org.jacoco.core.analysis.Analyzer; +import org.jacoco.core.analysis.CoverageBuilder; +import org.jacoco.core.analysis.IClassCoverage; +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.analysis.IMethodCoverage; +import org.jacoco.core.data.ExecutionDataStore; +import org.jacoco.core.data.SessionInfoStore; +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.internal.analysis.CounterImpl; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.RuntimeData; +import org.jacoco.core.runtime.SystemPropertiesRuntime; +import org.jacoco.core.test.TargetLoader; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Various tests for cyclomatic complexity of methods. + */ +public class CyclomaticComplexityTest { + + public interface Target { + public void test(int arg); + } + + private RuntimeData data; + private IRuntime runtime; + private byte[] bytes; + private Target target; + + @Before + public void setup() throws Exception { + data = new RuntimeData(); + runtime = new SystemPropertiesRuntime(); + runtime.startup(data); + } + + @After + public void teardown() { + runtime.shutdown(); + } + + public static class Simple implements Target { + public void test(int arg) { + nop(); + nop(); + nop(); + } + } + + @Test + public void testSimple1() throws Exception { + instrument(Simple.class); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(1, 0), complexity); + } + + @Test + public void testSimple2() throws Exception { + instrument(Simple.class); + target.test(0); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(0, 1), complexity); + } + + public static class If implements Target { + public void test(int arg) { + if (arg == 0) { + nop(); + } + } + } + + @Test + public void testIf1() throws Exception { + instrument(If.class); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(2, 0), complexity); + } + + @Test + public void testIf2() throws Exception { + instrument(If.class); + target.test(0); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(1, 1), complexity); + } + + @Test + public void testIf3() throws Exception { + instrument(If.class); + target.test(0); + target.test(1); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(0, 2), complexity); + } + + public static class TwoIf implements Target { + public void test(int arg) { + if (arg < 0) { + nop(); + } + if (arg > 0) { + nop(); + } + } + } + + @Test + public void testTwoIf1() throws Exception { + instrument(TwoIf.class); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(3, 0), complexity); + } + + @Test + public void testTwoIf2() throws Exception { + instrument(TwoIf.class); + target.test(-1); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(2, 1), complexity); + } + + @Test + public void testTwoIf3() throws Exception { + instrument(TwoIf.class); + target.test(-1); + target.test(0); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(1, 2), complexity); + } + + @Test + public void testTwoIf4() throws Exception { + instrument(TwoIf.class); + target.test(-1); + target.test(+1); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(0, 3), complexity); + } + + public static class NestedIf implements Target { + public void test(int arg) { + if (arg >= 0) { + if (arg == 0) { + nop(); + } + nop(); + } + } + } + + @Test + public void testNestedIf1() throws Exception { + instrument(NestedIf.class); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(3, 0), complexity); + } + + @Test + public void testNestedIf2() throws Exception { + instrument(NestedIf.class); + target.test(-1); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(2, 1), complexity); + } + + @Test + public void testNestedIf3() throws Exception { + instrument(NestedIf.class); + target.test(-1); + target.test(0); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(1, 2), complexity); + } + + @Test + public void testNestedIf4() throws Exception { + instrument(NestedIf.class); + target.test(-1); + target.test(0); + target.test(+1); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(0, 3), complexity); + } + + public static class Switch implements Target { + public void test(int arg) { + switch (arg) { + case 1: + nop(); + break; + case 2: + nop(); + break; + } + } + } + + @Test + public void testSwitch1() throws Exception { + instrument(Switch.class); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(3, 0), complexity); + } + + @Test + public void testSwitch2() throws Exception { + instrument(Switch.class); + target.test(0); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(2, 1), complexity); + } + + @Test + public void testSwitch3() throws Exception { + instrument(Switch.class); + target.test(0); + target.test(1); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(1, 2), complexity); + } + + @Test + public void testSwitch4() throws Exception { + instrument(Switch.class); + target.test(0); + target.test(1); + target.test(2); + final ICounter complexity = analyze(); + assertEquals(CounterImpl.getInstance(0, 3), complexity); + } + + private void instrument(final Class<? extends Target> clazz) + throws Exception { + bytes = TargetLoader.getClassDataAsBytes(clazz); + final byte[] instrumented = new Instrumenter(runtime).instrument(bytes, + "TestTarget"); + final TargetLoader loader = new TargetLoader(); + target = (Target) loader.add(clazz, instrumented).newInstance(); + } + + private ICounter analyze() throws IOException { + final CoverageBuilder builder = new CoverageBuilder(); + final ExecutionDataStore store = new ExecutionDataStore(); + data.collect(store, new SessionInfoStore(), false); + final Analyzer analyzer = new Analyzer(store, builder); + analyzer.analyzeClass(bytes, "TestTarget"); + final Collection<IClassCoverage> classes = builder.getClasses(); + assertEquals(1, classes.size(), 0.0); + final IClassCoverage classCoverage = classes.iterator().next(); + for (final IMethodCoverage m : classCoverage.getMethods()) { + if (m.getName().equals("test")) { + return m.getComplexityCounter(); + } + } + throw new AssertionError("No test() method."); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/EnumImplicitMethodsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/EnumImplicitMethodsTest.java new file mode 100644 index 00000000..fbd9e540 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/EnumImplicitMethodsTest.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.EnumImplicitMethods; +import org.junit.Test; + +/** + * Test of an implicit methods and static initializer in enums. + */ +public class EnumImplicitMethodsTest extends ValidationTestBase { + + public EnumImplicitMethodsTest() { + super(EnumImplicitMethods.class); + } + + @Test + public void testCoverageResult() { + assertMethodCount(5); + + assertLine("classdef", ICounter.FULLY_COVERED); + assertLine("customValueOfMethod", ICounter.NOT_COVERED); + assertLine("customValuesMethod", ICounter.NOT_COVERED); + + assertLine("const", ICounter.PARTLY_COVERED); + assertLine("staticblock", ICounter.FULLY_COVERED); + assertLine("super", ICounter.FULLY_COVERED); + assertLine("constructor", ICounter.FULLY_COVERED); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ExceptionsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ExceptionsTest.java new file mode 100644 index 00000000..c68bd374 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ExceptionsTest.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target03; +import org.junit.Test; + +/** + * Tests of exception based control flow. + */ +public class ExceptionsTest extends ValidationTestBase { + + public ExceptionsTest() { + super(Target03.class); + } + + @Test + public void testCoverageResult() { + + // 0. Implicit NullPointerException + // Currently no coverage at all, as we don't see when a block aborts + // somewhere in the middle. + assertLine("implicitNullPointerException.before", ICounter.NOT_COVERED); + assertLine("implicitNullPointerException.exception", + ICounter.NOT_COVERED); + assertLine("implicitNullPointerException.after", ICounter.NOT_COVERED); + + // 1. Implicit Exception + assertLine("implicitException.before", ICounter.FULLY_COVERED); + assertLine("implicitException.exception", ICounter.NOT_COVERED); + assertLine("implicitException.after", ICounter.NOT_COVERED); + + // 2. Explicit Exception + // Full coverage, as we recognize throw statements as block boundaries. + assertLine("explicitException.before", ICounter.FULLY_COVERED); + assertLine("explicitException.throw", ICounter.FULLY_COVERED); + + // 3. Try/Catch Block Without Exception Thrown + assertLine("noExceptionTryCatch.beforeBlock", ICounter.FULLY_COVERED); + assertLine("noExceptionTryCatch.tryBlock", ICounter.FULLY_COVERED); + assertLine("noExceptionTryCatch.catch", + isJDKCompiler ? ICounter.NOT_COVERED : ICounter.PARTLY_COVERED); + assertLine("noExceptionTryCatch.catchBlock", ICounter.NOT_COVERED); + assertLine("noExceptionTryCatch.catchBlockEnd", + isJDKCompiler ? ICounter.FULLY_COVERED : ICounter.EMPTY); + assertLine("noExceptionTryCatch.afterBlock", ICounter.FULLY_COVERED); + + // 4. Try/Catch Block With Exception Thrown Implicitly + assertLine("implicitExceptionTryCatch.beforeBlock", + ICounter.FULLY_COVERED); + assertLine("implicitExceptionTryCatch.before", ICounter.FULLY_COVERED); + assertLine("implicitExceptionTryCatch.exception", ICounter.NOT_COVERED); + assertLine("implicitExceptionTryCatch.after", ICounter.NOT_COVERED); + assertLine("implicitExceptionTryCatch.catch", isJDKCompiler + ? ICounter.FULLY_COVERED : ICounter.PARTLY_COVERED); + assertLine("implicitExceptionTryCatch.catchBlock", + ICounter.FULLY_COVERED); + assertLine("implicitExceptionTryCatch.catchBlockEnd", + isJDKCompiler ? ICounter.NOT_COVERED : ICounter.EMPTY); + assertLine("implicitExceptionTryCatch.afterBlock", + ICounter.FULLY_COVERED); + + // 5. Try/Catch Block With Exception Thrown Implicitly After Condition + // As the try/catch block is entered at one branch of the condition + // should be marked as executed + assertLine("implicitExceptionTryCatchAfterCondition.condition", + ICounter.FULLY_COVERED, 1, 1); + assertLine("implicitExceptionTryCatchAfterCondition.exception", + ICounter.NOT_COVERED); + assertLine("implicitExceptionTryCatchAfterCondition.catchBlock", + ICounter.FULLY_COVERED); + + // 6. Try/Catch Block With Exception Thrown Explicitly + assertLine("explicitExceptionTryCatch.beforeBlock", + ICounter.FULLY_COVERED); + assertLine("explicitExceptionTryCatch.before", ICounter.FULLY_COVERED); + assertLine("explicitExceptionTryCatch.throw", ICounter.FULLY_COVERED); + assertLine("explicitExceptionTryCatch.catch", ICounter.FULLY_COVERED); + assertLine("explicitExceptionTryCatch.catchBlock", + ICounter.FULLY_COVERED); + assertLine("explicitExceptionTryCatch.catchBlockEnd", ICounter.EMPTY); + assertLine("explicitExceptionTryCatch.afterBlock", + ICounter.FULLY_COVERED); + + // 7. Finally Block Without Exception Thrown + assertLine("noExceptionFinally.beforeBlock", ICounter.FULLY_COVERED); + assertLine("noExceptionFinally.tryBlock", ICounter.FULLY_COVERED); + assertLine("noExceptionFinally.finally", + isJDKCompiler ? ICounter.EMPTY : ICounter.FULLY_COVERED); + assertLine("noExceptionFinally.finallyBlock", ICounter.FULLY_COVERED); + assertLine("noExceptionFinally.finallyBlockEnd", ICounter.EMPTY); + assertLine("noExceptionFinally.afterBlock", ICounter.FULLY_COVERED); + + // 8. Finally Block With Implicit Exception + assertLine("implicitExceptionFinally.beforeBlock", + ICounter.FULLY_COVERED); + assertLine("implicitExceptionFinally.before", ICounter.FULLY_COVERED); + assertLine("implicitExceptionFinally.exception", ICounter.NOT_COVERED); + assertLine("implicitExceptionFinally.after", ICounter.NOT_COVERED); + assertLine("implicitExceptionFinally.finally", + isJDKCompiler ? ICounter.EMPTY : ICounter.NOT_COVERED); + assertLine("implicitExceptionFinally.finallyBlock", + ICounter.FULLY_COVERED); + assertLine("implicitExceptionFinally.finallyBlockEnd", ICounter.EMPTY); + assertLine("implicitExceptionFinally.afterBlock", ICounter.NOT_COVERED); + + // 9. Finally Block With Exception Thrown Explicitly + assertLine("explicitExceptionFinally.beforeBlock", + ICounter.FULLY_COVERED); + assertLine("explicitExceptionFinally.before", ICounter.FULLY_COVERED); + assertLine("explicitExceptionFinally.throw", ICounter.FULLY_COVERED); + assertLine("explicitExceptionFinally.finally", + isJDKCompiler ? ICounter.EMPTY : ICounter.FULLY_COVERED); + assertLine("explicitExceptionFinally.finallyBlock", + ICounter.FULLY_COVERED); + assertLine("explicitExceptionFinally.finallyBlockEnd", + isJDKCompiler ? ICounter.EMPTY : ICounter.FULLY_COVERED); + assertLine("explicitExceptionFinally.afterBlock", ICounter.EMPTY); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ExplicitInitialFrameTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ExplicitInitialFrameTest.java new file mode 100644 index 00000000..1c0a02f1 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ExplicitInitialFrameTest.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target11; +import org.junit.Test; + +/** + * Test for a methods having a explicit initial frame. + */ +public class ExplicitInitialFrameTest extends ValidationTestBase { + + public ExplicitInitialFrameTest() { + super(Target11.class); + } + + @Test + public void testCoverageResult() { + + assertLine("dowhilebody", ICounter.FULLY_COVERED); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/FieldInitializationInTwoConstructorsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/FieldInitializationInTwoConstructorsTest.java new file mode 100644 index 00000000..6896bf6d --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/FieldInitializationInTwoConstructorsTest.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target09; +import org.junit.Test; + +/** + * Test of field initialization in two constructors. + */ +public class FieldInitializationInTwoConstructorsTest extends + ValidationTestBase { + + public FieldInitializationInTwoConstructorsTest() { + super(Target09.class); + } + + @Test + public void testCoverageResult() { + + assertLine("field1", ICounter.PARTLY_COVERED); + assertLine("field2", ICounter.PARTLY_COVERED); + assertLine("constr1", ICounter.FULLY_COVERED); + assertLine("constr2", ICounter.NOT_COVERED); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/FramesTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/FramesTest.java new file mode 100644 index 00000000..9ab062b6 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/FramesTest.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * 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.test.validation; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.internal.BytecodeVersion; +import org.jacoco.core.internal.instr.InstrSupport; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.SystemPropertiesRuntime; +import org.jacoco.core.test.TargetLoader; +import org.jacoco.core.test.validation.targets.Target01; +import org.jacoco.core.test.validation.targets.Target02; +import org.jacoco.core.test.validation.targets.Target03; +import org.jacoco.core.test.validation.targets.Target04; +import org.jacoco.core.test.validation.targets.Target05; +import org.jacoco.core.test.validation.targets.Target06; +import org.jacoco.core.test.validation.targets.Target07; +import org.jacoco.core.test.validation.targets.Target08; +import org.jacoco.core.test.validation.targets.Target09; +import org.jacoco.core.test.validation.targets.Target10; +import org.jacoco.core.test.validation.targets.Target11; +import org.jacoco.core.test.validation.targets.Target12; +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.util.TraceClassVisitor; + +/** + * Tests whether stackmap frames are correctly adjusted. + */ +public class FramesTest { + + /** + * Stack sizes calculated for instrumented classes might be sometimes bigger + * than actually needed. This is an acceptable tradeoff in favor of keeping + * track of the actual stack sizes. For test assertions we need to replace + * max stack sizes with constant value. + */ + private static class MaxStackEliminator extends ClassVisitor { + public MaxStackEliminator(ClassVisitor cv) { + super(InstrSupport.ASM_API_VERSION, cv); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, + String signature, String[] exceptions) { + final MethodVisitor mv = super.visitMethod(access, name, desc, + signature, exceptions); + return new MethodVisitor(InstrSupport.ASM_API_VERSION, mv) { + @Override + public void visitMaxs(int maxStack, int maxLocals) { + super.visitMaxs(-1, maxLocals); + } + }; + } + } + + private void testFrames(Class<?> target) throws IOException { + testFrames(TargetLoader.getClassDataAsBytes(target)); + } + + private void testFrames(byte[] source) throws IOException { + IRuntime runtime = new SystemPropertiesRuntime(); + Instrumenter instrumenter = new Instrumenter(runtime); + source = calculateFrames(source); + byte[] actual = instrumenter.instrument(source, "TestTarget"); + byte[] expected = calculateFrames(actual); + + assertEquals(dump(expected), dump(actual)); + } + + private byte[] calculateFrames(byte[] source) { + source = BytecodeVersion.downgradeIfNeeded(BytecodeVersion.get(source), + source); + + ClassReader rc = new ClassReader(source); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + + // Adjust Version to 1.6 to enable frames: + rc.accept(new ClassVisitor(InstrSupport.ASM_API_VERSION, cw) { + + @Override + public void visit(int version, int access, String name, + String signature, String superName, String[] interfaces) { + super.visit(Opcodes.V1_6, access, name, signature, superName, + interfaces); + } + }, 0); + return cw.toByteArray(); + } + + private String dump(byte[] bytes) { + final StringWriter buffer = new StringWriter(); + final PrintWriter writer = new PrintWriter(buffer); + new ClassReader(bytes).accept( + new MaxStackEliminator(new TraceClassVisitor(writer)), + ClassReader.EXPAND_FRAMES); + return buffer.toString(); + } + + @Test + public void testTarget01() throws IOException { + testFrames(Target01.class); + } + + @Test + public void testTarget02() throws IOException { + testFrames(Target02.class); + } + + @Test + public void testTarget03() throws IOException { + testFrames(Target03.class); + } + + @Test + public void testTarget04() throws IOException { + testFrames(Target04.class); + } + + @Test + public void testTarget05() throws IOException { + testFrames(Target05.class); + } + + @Test + public void testTarget06() throws IOException { + testFrames(Target06.class); + } + + @Test + public void testTarget07() throws IOException { + testFrames(Target07.class); + } + + @Test + public void testTarget08() throws IOException { + testFrames(Target08.class); + } + + @Test + public void testTarget09() throws IOException { + testFrames(Target09.class); + } + + @Test + public void testTarget10() throws IOException { + testFrames(Target10.class); + } + + @Test + public void testTarget11() throws IOException { + testFrames(Target11.class); + } + + @Test + public void testTarget12() throws IOException { + testFrames(Target12.class); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ImplicitDefaultConstructorTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ImplicitDefaultConstructorTest.java new file mode 100644 index 00000000..09872e8d --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ImplicitDefaultConstructorTest.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target06; +import org.junit.Test; + +/** + * Test of a implicit default constructor. + * + * @see PrivateEmptyDefaultConstructorTest + */ +public class ImplicitDefaultConstructorTest extends ValidationTestBase { + + public ImplicitDefaultConstructorTest() { + super(Target06.class); + } + + @Test + public void testCoverageResult() { + + assertLine("classdef", ICounter.FULLY_COVERED); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ImplicitFieldInitializationTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ImplicitFieldInitializationTest.java new file mode 100644 index 00000000..769593d7 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ImplicitFieldInitializationTest.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target08; +import org.junit.Test; + +/** + * Test of a implicit field initialization. + */ +public class ImplicitFieldInitializationTest extends ValidationTestBase { + + public ImplicitFieldInitializationTest() { + super(Target08.class); + } + + @Test + public void testCoverageResult() { + + assertLine("classdef", ICounter.FULLY_COVERED); + assertLine("field1", ICounter.EMPTY); + assertLine("field2", ICounter.FULLY_COVERED); + assertLine("field3", ICounter.EMPTY); + assertLine("field4", ICounter.FULLY_COVERED); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/InterfaceClassInitializerTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/InterfaceClassInitializerTest.java new file mode 100644 index 00000000..5675dbb0 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/InterfaceClassInitializerTest.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target04; +import org.junit.Test; + +/** + * Tests of static initializer in interfaces. + */ +public class InterfaceClassInitializerTest extends ValidationTestBase { + + public InterfaceClassInitializerTest() { + super(Target04.class); + } + + @Override + protected void run(final Class<?> targetClass) throws Exception { + // Force class initialization + targetClass.getField("CONST1").get(null); + } + + @Test + public void testCoverageResult() { + + assertLine("const1", ICounter.EMPTY); + assertLine("const2", ICounter.EMPTY); + + assertLine("const3", ICounter.FULLY_COVERED); + assertLine("const4", ICounter.FULLY_COVERED); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/PrivateEmptyDefaultConstructorTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/PrivateEmptyDefaultConstructorTest.java new file mode 100644 index 00000000..1d144b7d --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/PrivateEmptyDefaultConstructorTest.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target07; +import org.junit.Test; + +/** + * Test of a private empty default constructor. + * + * @see ImplicitDefaultConstructorTest + */ +public class PrivateEmptyDefaultConstructorTest extends ValidationTestBase { + + public PrivateEmptyDefaultConstructorTest() { + super(Target07.class); + } + + @Test + public void testCoverageResult() { + + assertLine("classdef", ICounter.EMPTY); + assertLine("super", ICounter.EMPTY); + assertLine("constructor", ICounter.EMPTY); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ProbesBeforeSuperConstructorTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ProbesBeforeSuperConstructorTest.java new file mode 100644 index 00000000..88b1ae54 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ProbesBeforeSuperConstructorTest.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.test.validation; + +import org.jacoco.core.analysis.ICounter; +import org.jacoco.core.test.validation.targets.Target10; +import org.junit.Test; + +/** + * Test of probes before the super constructor call. + */ +public class ProbesBeforeSuperConstructorTest extends ValidationTestBase { + + public ProbesBeforeSuperConstructorTest() { + super(Target10.class); + } + + @Test + public void testCoverageResult() { + + assertLine("super", ICounter.PARTLY_COVERED, 3, 1); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ResizeInstructionsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ResizeInstructionsTest.java new file mode 100644 index 00000000..fe6d134a --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/ResizeInstructionsTest.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * 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: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.test.validation; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.internal.BytecodeVersion; +import org.jacoco.core.internal.instr.InstrSupport; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.RuntimeData; +import org.jacoco.core.runtime.SystemPropertiesRuntime; +import org.jacoco.core.test.TargetLoader; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public class ResizeInstructionsTest { + + private final IRuntime runtime = new SystemPropertiesRuntime(); + private final Instrumenter instrumenter = new Instrumenter(runtime); + + private boolean computedCommonSuperClass = false; + + @Before + public void setup() throws Exception { + runtime.startup(new RuntimeData()); + } + + @After + public void teardown() { + runtime.shutdown(); + } + + private class Inner { + } + + /** + * Test of ASM bug + * <a href="https://gitlab.ow2.org/asm/asm/issues/317792">#317792</a>. + */ + @Test + public void should_not_loose_InnerClasses_attribute() throws Exception { + byte[] source = TargetLoader.getClassDataAsBytes(Inner.class); + final int version = BytecodeVersion.get(source); + source = BytecodeVersion.downgradeIfNeeded(version, source); + + final ClassReader cr = new ClassReader(source); + final ClassWriter cw = new ClassWriter(0); + cr.accept(new ClassVisitor(InstrSupport.ASM_API_VERSION, cw) { + @Override + public void visitEnd() { + final MethodVisitor mv = cv.visitMethod(0, "m", "()V", null, + null); + mv.visitCode(); + addCauseOfResizeInstructions(mv); + mv.visitInsn(Opcodes.NOP); + mv.visitMaxs(2, 1); + mv.visitEnd(); + super.visitEnd(); + } + }, 0); + source = cw.toByteArray(); + BytecodeVersion.set(source, version); + + final byte[] bytes = instrumenter.instrument(source, ""); + + final TargetLoader targetLoader = new TargetLoader(); + final Class<?> outer = targetLoader.add(ResizeInstructionsTest.class, + TargetLoader.getClassDataAsBytes(ResizeInstructionsTest.class)); + final Class<?> inner = targetLoader.add(Inner.class, bytes); + assertSame(outer, inner.getEnclosingClass()); + assertNotNull(inner.getEnclosingClass()); + assertSame(outer, inner.getDeclaringClass()); + assertNotNull(inner.getDeclaringClass()); + } + + /** + * Test of ASM bug + * <a href= "https://gitlab.ow2.org/asm/asm/issues/317630">#317630</a> that + * caused {@code java.lang.ClassNotFoundException}. + */ + @Test + public void should_not_require_computation_of_common_superclass() + throws Exception { + final String className = "Example"; + + final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES) { + @Override + protected String getCommonSuperClass(final String type1, + final String type2) { + computedCommonSuperClass |= className.equals(type1) + || className.equals(type2); + return "java/lang/Object"; + } + }; + cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, className, null, + "java/lang/Object", null); + final MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "m", "()V", + null, null); + mv.visitCode(); + addCauseOfResizeInstructions(mv); + addCauseOfGetCommonSuperClass(mv); + mv.visitMaxs(1, 1); + mv.visitEnd(); + cw.visitEnd(); + final byte[] original = cw.toByteArray(); + assertTrue(computedCommonSuperClass); + new TargetLoader().add(className, original); + + final byte[] instrumented = instrumenter.instrument(original, + className); + new TargetLoader().add(className, instrumented); + } + + /** + * Adds code that requires + * {@link ClassWriter#getCommonSuperClass(String, String)}. + * + * <pre> + * Object o = this; + * while (true) { + * o = (Integer) null; + * } + * </pre> + */ + private static void addCauseOfGetCommonSuperClass(final MethodVisitor mv) { + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitVarInsn(Opcodes.ASTORE, 1); + Label label = new Label(); + mv.visitLabel(label); + mv.visitInsn(Opcodes.ACONST_NULL); + mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Integer"); + mv.visitVarInsn(Opcodes.ASTORE, 1); + mv.visitJumpInsn(Opcodes.GOTO, label); + } + + /** + * Adds code that triggers usage of + * {@link org.objectweb.asm.MethodWriter#COMPUTE_INSERTED_FRAMES} during + * instrumentation. + */ + private static void addCauseOfResizeInstructions(final MethodVisitor mv) { + mv.visitInsn(Opcodes.ICONST_0); + mv.visitInsn(Opcodes.ICONST_1); + final Label target = new Label(); + mv.visitJumpInsn(Opcodes.IFLE, target); + for (int i = 0; i < Short.MAX_VALUE; i++) { + mv.visitInsn(Opcodes.NOP); + } + mv.visitLabel(target); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/StructuredLockingTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/StructuredLockingTest.java new file mode 100644 index 00000000..823ab787 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/StructuredLockingTest.java @@ -0,0 +1,202 @@ +/******************************************************************************* + * 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.test.validation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.jacoco.core.instr.Instrumenter; +import org.jacoco.core.internal.BytecodeVersion; +import org.jacoco.core.runtime.IRuntime; +import org.jacoco.core.runtime.SystemPropertiesRuntime; +import org.jacoco.core.test.TargetLoader; +import org.jacoco.core.test.validation.targets.Target12; +import org.junit.Test; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.TryCatchBlockNode; +import org.objectweb.asm.tree.VarInsnNode; +import org.objectweb.asm.tree.analysis.Analyzer; +import org.objectweb.asm.tree.analysis.AnalyzerException; +import org.objectweb.asm.tree.analysis.BasicInterpreter; +import org.objectweb.asm.tree.analysis.BasicValue; +import org.objectweb.asm.tree.analysis.Frame; +import org.objectweb.asm.tree.analysis.Interpreter; + +/** + * Tests that the invariants specified in <a href= + * "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-2.html#jvms-2.11.10">chapter + * 2.11.10 of the JVM Spec</a> do also hold for instrumented classes. + * + * This is important because JIT compiler in HotSpot JVM ignores methods with + * unstructured locking, so that they executed by interpreter. Android Runtime + * also doesn't optimize such methods. + * + * TODO verification implemented here is incomplete - in particular it is unable + * to catch problem described in https://github.com/jacoco/jacoco/issues/626 + */ +public class StructuredLockingTest { + + @Test + public void testTarget12() throws Exception { + testMonitorExit(Target12.class); + } + + private void testMonitorExit(Class<?> target) throws Exception { + assertStructuredLocking(TargetLoader.getClassDataAsBytes(target)); + } + + private void assertStructuredLocking(byte[] source) throws Exception { + IRuntime runtime = new SystemPropertiesRuntime(); + Instrumenter instrumenter = new Instrumenter(runtime); + byte[] instrumented = instrumenter.instrument(source, "TestTarget"); + + final int version = BytecodeVersion.get(instrumented); + instrumented = BytecodeVersion.downgradeIfNeeded(version, instrumented); + + ClassNode cn = new ClassNode(); + new ClassReader(instrumented).accept(cn, 0); + for (MethodNode mn : cn.methods) { + assertStructuredLocking(cn.name, mn); + } + } + + private void assertStructuredLocking(String owner, MethodNode mn) + throws Exception { + Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>( + new BasicInterpreter()) { + + @Override + protected Frame<BasicValue> newFrame(int nLocals, int nStack) { + return new LockFrame(nLocals, nStack); + } + + @Override + protected Frame<BasicValue> newFrame(Frame<? extends BasicValue> src) { + return new LockFrame(src); + } + }; + + Frame<BasicValue>[] frames = analyzer.analyze(owner, mn); + + // Make sure no locks are left when method exits: + for (int i = 0; i < frames.length; i++) { + AbstractInsnNode insn = mn.instructions.get(i); + switch (insn.getOpcode()) { + case Opcodes.IRETURN: + case Opcodes.LRETURN: + case Opcodes.FRETURN: + case Opcodes.DRETURN: + case Opcodes.ARETURN: + case Opcodes.RETURN: + ((LockFrame) frames[i]).assertNoLock("Exit with lock"); + break; + case Opcodes.ATHROW: + List<TryCatchBlockNode> handlers = analyzer.getHandlers(i); + if (handlers == null || handlers.isEmpty()) { + ((LockFrame) frames[i]).assertNoLock("Exit with lock"); + } + break; + } + } + + // Only instructions protected by a catch-all handler can hold locks: + for (int i = 0; i < frames.length; i++) { + AbstractInsnNode insn = mn.instructions.get(i); + if (insn.getOpcode() > 0) { + boolean catchAll = false; + List<TryCatchBlockNode> handlers = analyzer.getHandlers(i); + if (handlers != null) { + for (TryCatchBlockNode node : handlers) { + catchAll |= node.type == null; + } + } + if (!catchAll) { + ((LockFrame) frames[i]) + .assertNoLock("No handlers for insn with lock"); + } + } + } + + } + + /** + * A Frame implementation that keeps track of the locking state. It is + * assumed that the monitor objects are stored in local variables. + */ + private static class LockFrame extends Frame<BasicValue> { + + Set<Integer> locks; + + public LockFrame(final int nLocals, final int nStack) { + super(nLocals, nStack); + locks = new HashSet<Integer>(); + } + + public LockFrame(Frame<? extends BasicValue> src) { + super(src); + } + + @Override + public Frame<BasicValue> init(Frame<? extends BasicValue> src) { + locks = new HashSet<Integer>(((LockFrame) src).locks); + return super.init(src); + } + + @Override + public void execute(AbstractInsnNode insn, + Interpreter<BasicValue> interpreter) throws AnalyzerException { + super.execute(insn, interpreter); + switch (insn.getOpcode()) { + case Opcodes.MONITORENTER: + // Lock is stored in a local variable: + enter(((VarInsnNode) insn.getPrevious()).var); + break; + case Opcodes.MONITOREXIT: + // Lock is stored in a local variable: + exit(((VarInsnNode) insn.getPrevious()).var); + break; + } + } + + void enter(int lock) { + assertTrue("multiple ENTER for lock " + lock, + locks.add(Integer.valueOf(lock))); + } + + void exit(int lock) { + assertTrue("invalid EXIT for lock " + lock, + locks.remove(Integer.valueOf(lock))); + } + + @Override + public boolean merge(Frame<? extends BasicValue> frame, + Interpreter<BasicValue> interpreter) throws AnalyzerException { + this.locks.addAll(((LockFrame) frame).locks); + return super.merge(frame, interpreter); + } + + void assertNoLock(String message) { + assertEquals(message, Collections.emptySet(), locks); + + } + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/AnnotationInitializer.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/AnnotationInitializer.java new file mode 100644 index 00000000..f7b9e0af --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/AnnotationInitializer.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * 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: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.test.validation.targets; + +/** + * This test target is an annotation with an initializer. + */ +public @interface AnnotationInitializer { + + Object CONST = new Object(); // $line-const$ + + int value() default 0; // $line-value$ + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/BadCycleClass.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/BadCycleClass.java new file mode 100644 index 00000000..c1826646 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/BadCycleClass.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.test.validation.targets; + +public class BadCycleClass { + + public static class Base { + static final Child b = new Child(); + + static { + b.someMethod(); + } + } + + public static class Child extends Base { + + static { + Stubs.logEvent("childclinit"); // $line-childclinit$ + } + + public Child() { + Stubs.logEvent("childinit"); // $line-childinit$ + } + + void someMethod() { + Stubs.logEvent("childsomeMethod"); // $line-childsomeMethod$ + } + + } + + public static void main(String[] args) { + new Child(); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/EnumImplicitMethods.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/EnumImplicitMethods.java new file mode 100644 index 00000000..afbc46fd --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/EnumImplicitMethods.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * 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: + * Evgeny Mandrikov - initial API and implementation + * + *******************************************************************************/ +package org.jacoco.core.test.validation.targets; + +public enum EnumImplicitMethods { // $line-classdef$ + + CONST(Stubs.f() ? new Object() : new Object()); // $line-const$ + + static { + } // $line-staticblock$ + + /** + * Unlike in {@link Target07 regular classes}, even if enum has explicit + * constructor, {@code clinit} method in any case has a reference to the + * line of enum definition. + */ + EnumImplicitMethods(Object o) { // $line-super$ + } // $line-constructor$ + + /** + * This method should not be excluded from analysis unlike implicitly + * created {@link #valueOf(String)} method that refers to the line of enum + * definition in case of javac and to the first line in case of ECJ. + */ + public void valueOf() { + } // $line-customValueOfMethod$ + + /** + * This method should not be excluded from analysis unlike implicitly + * created {@link #values()} method that refers to the line of enum + * definition in case of javac and to the first line in case of ECJ. + */ + public void values(Object o) { + } // $line-customValuesMethod$ + + public static void main(String[] args) { + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target01.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target01.java new file mode 100644 index 00000000..81d00fa5 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target01.java @@ -0,0 +1,293 @@ +/******************************************************************************* + * 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.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.f; +import static org.jacoco.core.test.validation.targets.Stubs.i2; +import static org.jacoco.core.test.validation.targets.Stubs.nop; +import static org.jacoco.core.test.validation.targets.Stubs.t; + +import java.util.Collections; + +/** + * This target exercises a set of common Java control structures. + */ +public class Target01 { + + public static void main(String[] args) { + + unconditionalExecution(); + missedIfBlock(); + executedIfBlock(); + missedWhileBlock(); + alwaysExecutedWhileBlock(); + executedWhileBlock(); + executedDoWhileBlock(); + missedForBlock(); + executedForBlock(); + missedForEachBlock(); + executedForEachBlock(); + tableSwitchWithHit(); + continuedTableSwitchWithHit(); + tableSwitchWithoutHit(); + lookupSwitchWithHit(); + continuedLookupSwitchWithHit(); + lookupSwitchWithoutHit(); + breakStatement(); + continueStatement(); + conditionalReturn(); + implicitReturn(); + explicitReturn(); + + } + + private static void unconditionalExecution() { + + nop(); // $line-unconditional$ + + } + + private static void missedIfBlock() { + + if (f()) { // $line-iffalse$ + nop(); // $line-missedif$ + } else { + nop(); // $line-executedelse$ + } + + } + + private static void executedIfBlock() { + + if (t()) { // $line-iftrue$ + nop(); // $line-executedif$ + } else { + nop(); // $line-missedelse$ + } + + } + + private static void missedWhileBlock() { + + while (f()) { // $line-whilefalse$ + nop(); // $line-missedwhile$ + } + + } + + private static void alwaysExecutedWhileBlock() { + + while (t()) { // $line-whiletrue$ + if (t()) { + break; + } + } + + } + + private static void executedWhileBlock() { + + int i = 0; + while (i++ < 3) { // $line-whiletruefalse$ + nop(); // $line-executedwhile$ + } + + } + + private static void executedDoWhileBlock() { + + do { + nop(); // $line-executeddowhile$ + } while (f()); // $line-executeddowhilefalse$ + + } + + private static void missedForBlock() { + + for (nop(); f(); nop()) { // $line-missedforincrementer$ + nop(); // $line-missedfor$ + } + + } + + private static void executedForBlock() { + + for (int j = 0; j < 1; j++) { // $line-executedforincrementer$ + nop(); // $line-executedfor$ + } + + } + + private static void missedForEachBlock() { + + for (Object o : Collections.emptyList()) { // $line-missedforeachincrementer$ + nop(o); // $line-missedforeach$ + } + + } + + private static void executedForEachBlock() { + + for (Object o : Collections.singleton(new Object())) { // $line-executedforeachincrementer$ + nop(o); // $line-executedforeach$ + } + + } + + private static void tableSwitchWithHit() { + + switch (i2()) { // $line-tswitch1$ + case 1: + nop(); // $line-tswitch1case1$ + break; + case 2: + nop(); // $line-tswitch1case2$ + break; + case 3: + nop(); // $line-tswitch1case3$ + break; + default: + nop(); // $line-tswitch1default$ + break; + } + + } + + private static void continuedTableSwitchWithHit() { + + switch (i2()) { // $line-tswitch2$ + case 1: + nop(); // $line-tswitch2case1$ + case 2: + nop(); // $line-tswitch2case2$ + case 3: + nop(); // $line-tswitch2case3$ + default: + nop(); // $line-tswitch2default$ + } + + } + + private static void tableSwitchWithoutHit() { + + switch (i2()) { // $line-tswitch3$ + case 3: + nop(); // $line-tswitch3case1$ + break; + case 4: + nop(); // $line-tswitch3case2$ + break; + case 5: + nop(); // $line-tswitch3case3$ + break; + default: + nop(); // $line-tswitch3default$ + break; + } + + } + + private static void lookupSwitchWithHit() { + + switch (i2()) { // $line-lswitch1$ + case -123: + nop(); // $line-lswitch1case1$ + break; + case 2: + nop(); // $line-lswitch1case2$ + break; + case 456: + nop(); // $line-lswitch1case3$ + break; + default: + nop(); // $line-lswitch1default$ + break; + } + + } + + private static void continuedLookupSwitchWithHit() { + + switch (i2()) { // $line-lswitch2$ + case -123: + nop(); // $line-lswitch2case1$ + case 2: + nop(); // $line-lswitch2case2$ + case 456: + nop(); // $line-lswitch2case3$ + default: + nop(); // $line-lswitch2default$ + } + + } + + private static void lookupSwitchWithoutHit() { + + switch (i2()) { // $line-lswitch3$ + case -123: + nop(); // $line-lswitch3case1$ + break; + case 456: + nop(); // $line-lswitch3case2$ + break; + case 789: + nop(); // $line-lswitch3case3$ + break; + default: + nop(); // $line-lswitch3default$ + break; + } + + } + + private static void breakStatement() { + + while (true) { + if (t()) { + break; // $line-executedbreak$ + } + nop(); // $line-missedafterbreak$ + } + + } + + private static void continueStatement() { + + for (int j = 0; j < 1; j++) { + if (t()) { + continue; // $line-executedcontinue$ + } + nop(); // $line-missedaftercontinue$ + } + + } + + private static void conditionalReturn() { + + if (t()) { + return; // $line-conditionalreturn$ + } + nop(); // $line-afterconditionalreturn$ + + } + + private static void implicitReturn() { + + } // $line-implicitreturn$ + + private static void explicitReturn() { + + return; // $line-explicitreturn$ + + } // $line-afterexplicitreturn$ + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target02.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target02.java new file mode 100644 index 00000000..62e22ef9 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target02.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * 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.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.f; +import static org.jacoco.core.test.validation.targets.Stubs.i1; +import static org.jacoco.core.test.validation.targets.Stubs.i2; +import static org.jacoco.core.test.validation.targets.Stubs.nop; +import static org.jacoco.core.test.validation.targets.Stubs.t; + +/** + * This target exercises boolean expressions. + */ +public class Target02 { + + public static void main(String[] args) { + + // 1. Boolean comparison result (one case) + nop(i2() > 3); // $line-booleancmp1$ + + // 2. Boolean comparison result (both cases) + for (int i = 0; i < 2; i++) { + nop(i < 1); // $line-booleancmp2$ + } + + // 3. And + if (f() & f()) { // $line-andFF$ + nop(); + } + if (f() & t()) { // $line-andFT$ + nop(); + } + if (t() & f()) { // $line-andTF$ + nop(); + } + if (t() & t()) { // $line-andTT$ + nop(); + } + + // 4. Conditional And + if (f() && f()) { // $line-conditionalandFF$ + nop(); + } + if (f() && t()) { // $line-conditionalandFT$ + nop(); + } + if (t() && f()) { // $line-conditionalandTF$ + nop(); + } + if (t() && t()) { // $line-conditionalandTT$ + nop(); + } + + // 5. Or + if (f() | f()) { // $line-orFF$ + nop(); + } + if (f() | t()) { // $line-orFT$ + nop(); + } + if (t() | f()) { // $line-orTF$ + nop(); + } + if (t() | t()) { // $line-orTT$ + nop(); + } + + // 6. Conditional Or + if (f() || f()) { // $line-conditionalorFF$ + nop(); + } + if (f() || t()) { // $line-conditionalorFT$ + nop(); + } + if (t() || f()) { // $line-conditionalorTF$ + nop(); + } + if (t() || t()) { // $line-conditionalorTT$ + nop(); + } + + // 7. Exclusive Or + if (f() ^ f()) { // $line-xorFF$ + nop(); + } + if (f() ^ t()) { // $line-xorFT$ + nop(); + } + if (t() ^ f()) { // $line-xorTF$ + nop(); + } + if (t() ^ t()) { // $line-xorTT$ + nop(); + } + + // 8. Conditional Operator + nop(t() ? i1() : i2()); // $line-condT$ + nop(f() ? i1() : i2()); // $line-condF$ + + // 9. Not (one case) + nop(!t()); // $line-notT$ + nop(!f()); // $line-notF$ + + // 10. Not (both cases) + for (boolean b : new boolean[] { true, false }) { + nop(!b); // $line-notTF$ + } + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target03.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target03.java new file mode 100644 index 00000000..b4418edd --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target03.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * 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.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.ex; +import static org.jacoco.core.test.validation.targets.Stubs.f; +import static org.jacoco.core.test.validation.targets.Stubs.nop; + +import org.jacoco.core.test.validation.targets.Stubs.StubException; + +/** + * This target produces exception based control flow examples. + */ +public class Target03 { + + public static void main(String[] args) { + + try { + implicitNullPointerException(null); + } catch (NullPointerException e) { + } + try { + implicitException(); + } catch (StubException e) { + } + try { + explicitException(); + } catch (StubException e) { + } + noExceptionTryCatch(); + implicitExceptionTryCatch(); + implicitExceptionTryCatchAfterCondition(); + explicitExceptionTryCatch(); + noExceptionFinally(); + try { + explicitExceptionFinally(); + } catch (StubException e) { + } + try { + implicitExceptionFinally(); + } catch (StubException e) { + } + } + + private static void implicitNullPointerException(int[] a) { + nop(); // $line-implicitNullPointerException.before$ + a[0] = 0; // $line-implicitNullPointerException.exception$ + nop(); // $line-implicitNullPointerException.after$ + } + + private static void implicitException() { + nop(); // $line-implicitException.before$ + ex(); // $line-implicitException.exception$ + nop(); // $line-implicitException.after$ + } + + private static void explicitException() { + nop(); // $line-explicitException.before$ + throw new StubException(); // $line-explicitException.throw$ + } + + private static void noExceptionTryCatch() { + nop(); // $line-noExceptionTryCatch.beforeBlock$ + try { + nop(); // $line-noExceptionTryCatch.tryBlock$ + } catch (StubException e) { // $line-noExceptionTryCatch.catch$ + nop(); // $line-noExceptionTryCatch.catchBlock$ + } // $line-noExceptionTryCatch.catchBlockEnd$ + } // $line-noExceptionTryCatch.afterBlock$ + + private static void implicitExceptionTryCatch() { + nop(); // $line-implicitExceptionTryCatch.beforeBlock$ + try { + nop(); // $line-implicitExceptionTryCatch.before$ + ex(); // $line-implicitExceptionTryCatch.exception$ + nop(); // $line-implicitExceptionTryCatch.after$ + } catch (StubException e) { // $line-implicitExceptionTryCatch.catch$ + nop(); // $line-implicitExceptionTryCatch.catchBlock$ + } // $line-implicitExceptionTryCatch.catchBlockEnd$ + } // $line-implicitExceptionTryCatch.afterBlock$ + + private static void implicitExceptionTryCatchAfterCondition() { + if (f()) { // $line-implicitExceptionTryCatchAfterCondition.condition$ + return; + } + try { + ex(); // $line-implicitExceptionTryCatchAfterCondition.exception$ + } catch (StubException e) { + nop(); // $line-implicitExceptionTryCatchAfterCondition.catchBlock$ + } + } + + private static void explicitExceptionTryCatch() { + nop(); // $line-explicitExceptionTryCatch.beforeBlock$ + try { + nop(); // $line-explicitExceptionTryCatch.before$ + throw new StubException(); // $line-explicitExceptionTryCatch.throw$ + } catch (StubException e) { // $line-explicitExceptionTryCatch.catch$ + nop(); // $line-explicitExceptionTryCatch.catchBlock$ + } // $line-explicitExceptionTryCatch.catchBlockEnd$ + } // $line-explicitExceptionTryCatch.afterBlock$ + + private static void noExceptionFinally() { + nop(); // $line-noExceptionFinally.beforeBlock$ + try { + nop(); // $line-noExceptionFinally.tryBlock$ + } finally { // $line-noExceptionFinally.finally$ + nop(); // $line-noExceptionFinally.finallyBlock$ + } // $line-noExceptionFinally.finallyBlockEnd$ + } // $line-noExceptionFinally.afterBlock$ + + private static void implicitExceptionFinally() { + nop(); // $line-implicitExceptionFinally.beforeBlock$ + try { + nop(); // $line-implicitExceptionFinally.before$ + ex(); // $line-implicitExceptionFinally.exception$ + nop(); // $line-implicitExceptionFinally.after$ + } finally { // $line-implicitExceptionFinally.finally$ + nop(); // $line-implicitExceptionFinally.finallyBlock$ + } // $line-implicitExceptionFinally.finallyBlockEnd$ + } // $line-implicitExceptionFinally.afterBlock$ + + private static void explicitExceptionFinally() { + nop(); // $line-explicitExceptionFinally.beforeBlock$ + try { + nop(); // $line-explicitExceptionFinally.before$ + throw new StubException(); // $line-explicitExceptionFinally.throw$ + } finally { // $line-explicitExceptionFinally.finally$ + nop(); // $line-explicitExceptionFinally.finallyBlock$ + } // $line-explicitExceptionFinally.finallyBlockEnd$ + } // $line-explicitExceptionFinally.afterBlock$ + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target04.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target04.java new file mode 100644 index 00000000..8384744b --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target04.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.i1; + +/** + * This test target is an interface with a class initializer. + */ +public interface Target04 { + + // No code required to initialize these fields: + + static final int CONST1 = 12345; // $line-const1$ + + static final String CONST2 = "const"; // $line-const2$ + + // These fields are initialized within <clinit> + + static final int CONST3 = i1(); // $line-const3$ + + static final Object CONST4 = new Object(); // $line-const4$ + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target05.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target05.java new file mode 100644 index 00000000..ef5c3989 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target05.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * 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.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.i1; + +/** + * This test target is a class with a static initializer. + */ +public class Target05 { + + // No code required to initialize these fields: + + public static final int CONST1 = 3; // $line-const1$ + + public static final String CONST2 = "Hello"; // $line-const2$ + + // These fields are initialized within <clinit> + + public static final int CONST3 = i1(); // $line-const3$ + + public static final Object CONST4 = new Object(); // $line-const4$ + + public static int field1 = 3; // $line-field1$ + + public static String field2 = "Hello"; // $line-field2$ + + public static int field3 = i1(); // $line-field3$ + + public static Object field4 = new Object(); // $line-field4$ + + static { + Stubs.nop(); // $line-staticblock$ + } + + private Target05() { + } + + public static void main(String[] args) { + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target06.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target06.java new file mode 100644 index 00000000..f6bc75e8 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target06.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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.test.validation.targets; + +/** + * This test target is a class with a implicit default constructor. + * + * @see Target07 explicit constructor + */ +public class Target06 { // $line-classdef$ + + public static void main(String[] args) { + new Target06(); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target07.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target07.java new file mode 100644 index 00000000..18c3ba52 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target07.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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.test.validation.targets; + +/** + * This test target is a private empty default constructor. + * + * @see Target06 implicit constructor + */ +public class Target07 { // $line-classdef$ + + private Target07() { // $line-super$ + } // $line-constructor$ + + public static void main(String[] args) { + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target08.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target08.java new file mode 100644 index 00000000..1fe938aa --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target08.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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.test.validation.targets; + +/** + * This test target has instance members with implicit initializers. + */ +public class Target08 { // $line-classdef$ + + Object field1; // $line-field1$ + + Object field2 = this; // $line-field2$ + + int field3; // $line-field3$ + + int field4 = 2000; // $line-field4$ + + public static void main(String[] args) { + new Target08(); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target09.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target09.java new file mode 100644 index 00000000..a8589d1d --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target09.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.test.validation.targets; + +/** + * This test target has instance members with initialization in two + * constructors. + */ +public class Target09 { + + Object field1 = null; // $line-field1$ + + int field2 = 123; // $line-field2$ + + public Target09() { + } // $line-constr1$ + + public Target09(String arg) { + } // $line-constr2$ + + public static void main(String[] args) { + new Target09(); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target10.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target10.java new file mode 100644 index 00000000..bb4496e9 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target10.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.f; +import static org.jacoco.core.test.validation.targets.Stubs.t; + +import org.jacoco.core.test.validation.targets.Stubs.SuperClass; + +/** + * This test target has a constructor containing control structures before the + * superclass constructor is called. + */ +public class Target10 extends SuperClass { + + public Target10() { + super(t() || f()); // $line-super$ + } + + public static void main(String[] args) { + new Target10(); + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target11.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target11.java new file mode 100644 index 00000000..d393cb7f --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target11.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * 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.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.f; +import static org.jacoco.core.test.validation.targets.Stubs.nop; + +/** + * This test target needs an explicit initial frame as the first instruction + * already is a jump target. + */ +public class Target11 { + + public static void main(String[] args) { + + do { + nop(); // $line-dowhilebody$ + } while (f()); + + } + +} diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target12.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target12.java new file mode 100644 index 00000000..5ee2e324 --- /dev/null +++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/targets/Target12.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.test.validation.targets; + +import static org.jacoco.core.test.validation.targets.Stubs.nop; + +/** + * This target uses synchronized blocks which compile to try/catch statements. + */ +public class Target12 { + + static void simple() { + Object lock1 = new Object(); + synchronized (lock1) { + nop(); + } + } + + static void nested() { + Object lock1 = new Object(); + synchronized (lock1) { + nop(); + Object lock2 = new Object(); + synchronized (lock2) { + nop(); + } + nop(); + } + + } + + public static void main(String[] args) { + simple(); + nested(); + } + +} |