org.jacoco.core.test.validation.java5.FinallyTest.java Source code

Java tutorial

Introduction

Here is the source code for org.jacoco.core.test.validation.java5.FinallyTest.java

Source

/*******************************************************************************
 * Copyright (c) 2009, 2019 Mountainminds GmbH & Co. KG and Contributors
 * This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *    Evgeny Mandrikov - initial API and implementation
 *
 *******************************************************************************/
package org.jacoco.core.test.validation.java5;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.jacoco.core.internal.instr.InstrSupport;
import org.jacoco.core.test.TargetLoader;
import org.jacoco.core.test.validation.Source.Line;
import org.jacoco.core.test.validation.ValidationTestBase;
import org.jacoco.core.test.validation.java5.targets.FinallyTarget;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.LineNumberNode;
import org.objectweb.asm.tree.MethodNode;

/**
 * Test of filtering of duplicated bytecode that is generated for finally block.
 */
public class FinallyTest extends ValidationTestBase {

    private Map<Integer, String> tags;

    public FinallyTest() {
        super(FinallyTarget.class);
    }

    @Before
    @Override
    public void setup() throws Exception {
        super.setup();
        tags = new HashMap<Integer, String>();
    }

    public void assertFinally(final Line line) {
        if (isJDKCompiler) {
            assertEmpty(line);
        } else {
            assertFullyCovered(line);
        }
    }

    public void assertTwoRegions1(final Line line) {
        if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
            // https://bugs.openjdk.java.net/browse/JDK-7008643
            assertPartlyCovered(line);
        } else {
            assertFullyCovered(line);
        }
    }

    public void assertTwoRegionsReturn1(final Line line) {
        if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
            // https://bugs.openjdk.java.net/browse/JDK-7008643
            assertEmpty(line);
        } else {
            assertFullyCovered(line);
        }
    }

    public void assertTwoRegionsReturn2(final Line line) {
        if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
            // https://bugs.openjdk.java.net/browse/JDK-7008643
            assertEmpty(line);
        } else {
            assertNotCovered(line);
        }
    }

    public void assertEmptyTry1(final Line line) {
        if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
            // compiler bug fixed in javac >= 1.8:
            assertPartlyCovered(line);
        } else {
            assertFullyCovered(line);
        }
    }

    public void assertEmptyTry2(final Line line) {
        if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
            // compiler bug fixed in javac >= 1.8:
            assertFullyCovered(line);
        } else {
            assertEmpty(line);
        }
    }

    public void assertAlwaysCompletesAbruptly0(final Line line) {
        if (isJDKCompiler) {
            // uncovered case:
            assertEmpty(line);
        } else {
            assertPartlyCovered(line);
        }
    }

    public void assertAlwaysCompletesAbruptly1(final Line line) {
        if (isJDKCompiler) {
            // uncovered case:
            assertPartlyCovered(line);
        } else {
            assertFullyCovered(line);
        }
    }

    @Test
    @Override
    public void execute_assertions_in_comments() throws IOException {
        super.execute_assertions_in_comments();
        gotos();
    }

    /**
     * This test studies placement of GOTO instructions.
     */
    private void gotos() throws IOException {

        final Set<String> expected = new HashSet<String>();

        if (isJDKCompiler) {
            expected.add("example.2");
        } else {
            expected.add("example.0");
        }

        expected.add("breakStatement.for");
        if (isJDKCompiler) {
            if (JAVA_VERSION.isBefore("10")) {
                // https://bugs.openjdk.java.net/browse/JDK-8180141
                expected.add("breakStatement.1");
            } else {
                expected.add("breakStatement");
            }
            expected.add("breakStatement.2");
        } else {
            expected.add("breakStatement");
        }

        if (isJDKCompiler) {
            expected.add("emptyCatch.2");
        } else {
            expected.add("emptyCatch");
            expected.add("emptyCatch.1");
        }

        if (isJDKCompiler) {
            expected.add("catchNotExecuted.2");
        } else {
            expected.add("catchNotExecuted");
            expected.add("catchNotExecuted.1");
        }

        if (isJDKCompiler) {
            expected.add("nested.5");
            expected.add("nested.6");
        } else {
            expected.add("nested.0");
            expected.add("nested.3");
        }

        if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
            expected.add("emptyTry.2");
        }

        if (!isJDKCompiler) {
            expected.add("alwaysCompletesAbruptly.0");
        }

        assertEquals(expected, getTagsWithGotos());
    }

    private Set<String> getTagsWithGotos() throws IOException {
        final Set<String> gotoTags = new HashSet<String>();

        byte[] b = TargetLoader.getClassDataAsBytes(FinallyTarget.class);

        final ClassNode classNode = new ClassNode();
        InstrSupport.classReaderFor(b).accept(classNode, 0);
        for (final MethodNode m : classNode.methods) {
            if ("main".equals(m.name)) {
                // skip it
                continue;
            }
            int lineNumber = -1;
            for (AbstractInsnNode i : m.instructions) {
                if (AbstractInsnNode.LINE == i.getType()) {
                    lineNumber = ((LineNumberNode) i).line;
                }
                if (Opcodes.GOTO == i.getOpcode()) {
                    String tag = tags.get(Integer.valueOf(lineNumber));
                    if (tag == null) {
                        throw new AssertionError("No tag at line " + lineNumber);
                    }
                    gotoTags.add(tag);
                }
            }
        }

        return gotoTags;
    }

    public void tag(final Line line, String tag) {
        assertFalse("duplicate tag " + tag, tags.containsValue(tag));
        assertNull("duplicate tag in " + line, tags.put(Integer.valueOf(line.getNr()), tag));
    }

}