/* * Copyright (c) 2006 Rogério Liesenfeld * This file is subject to the terms of the MIT license (see LICENSE.txt). */ package integrationTests; import java.lang.reflect.*; import java.util.*; import javax.annotation.*; import static java.lang.reflect.Modifier.*; import org.junit.*; import static org.junit.Assert.*; import mockit.coverage.*; import mockit.coverage.data.*; import mockit.coverage.dataItems.*; import mockit.coverage.lines.*; import mockit.coverage.paths.*; public class CoverageTest { @Nullable protected static FileCoverageData fileData; @Nullable private static String testedClassSimpleName; @Nullable protected MethodCoverageData methodData; private int currentPathIndex = -1; @Before public final void findCoverageData() throws Exception { Field testedField = getClass().getDeclaredField("tested"); Class<?> testedClass = testedField.getType(); if (testedClass != Object.class) { findFileDate(testedClass); setTestedFieldToNewInstanceIfApplicable(testedField); } } private void findFileDate(@Nonnull Class<?> testedClass) { testedClassSimpleName = testedClass.getSimpleName(); String classFilePath = testedClass.getName().replace('.', '/') + ".java"; Map<String, FileCoverageData> data = CoverageData.instance().getRawFileToFileData(); fileData = data.get(classFilePath); assertNotNull("FileCoverageData not found for " + classFilePath, fileData); } private void setTestedFieldToNewInstanceIfApplicable(@Nonnull Field testedField) throws Exception { Class<?> testedClass = testedField.getType(); if (!testedClass.isEnum() && !isAbstract(testedClass.getModifiers()) && !isFinal(testedField.getModifiers())) { testedField.setAccessible(true); if (testedField.get(this) == null) { //noinspection ClassNewInstance Object newTestedInstance = testedClass.newInstance(); testedField.set(this, newTestedInstance); } } } @Nonnull private FileCoverageData fileData() { if (fileData == null) { Object testedInstance; try { Field testedField = getClass().getDeclaredField("tested"); testedInstance = testedField.get(this); } catch (NoSuchFieldException | IllegalAccessException e) { throw new RuntimeException(e); } Class<?> testedClass = testedInstance.getClass(); findFileDate(testedClass); } return fileData; } protected final void assertLines(int startingLine, int endingLine, int expectedLinesExecuted) { PerFileLineCoverage lineCoverageInfo = fileData().lineCoverageInfo; int lineCount = lineCoverageInfo.getLineCount(); assertTrue("Starting line not found", lineCount >= startingLine); assertTrue("Ending line not found", lineCount >= endingLine); int linesExecuted = 0; for (int line = startingLine; line <= endingLine; line++) { if (lineCoverageInfo.getExecutionCount(line) > 0) { linesExecuted++; } } assertEquals("Unexpected number of lines executed:", expectedLinesExecuted, linesExecuted); } protected final void assertLine( int line, int expectedSegments, int expectedCoveredSegments, int... expectedExecutionCounts) { PerFileLineCoverage info = fileData().lineCoverageInfo; LineCoverageData lineData = info.getLineData(line); assertEquals("Segments:", expectedSegments, info.getNumberOfSegments(line)); assertEquals("Covered segments:", expectedCoveredSegments, lineData.getNumberOfCoveredSegments()); assertEquals("Execution count:", expectedExecutionCounts[0], info.getExecutionCount(line)); for (int i = 1; i < expectedExecutionCounts.length; i++) { BranchCoverageData segmentData = lineData.getBranchData(i - 1); int executionCount = segmentData.getExecutionCount(); assertEquals( "Execution count for line " + line + ", segment " + i + ':', expectedExecutionCounts[i], executionCount); List<CallPoint> callPoints = segmentData.getCallPoints(); if (callPoints != null) { int callPointCount = 0; for (CallPoint callPoint : callPoints) { callPointCount++; callPointCount += callPoint.getRepetitionCount(); } assertEquals("Missing call points for line " + line + ", segment " + i, executionCount, callPointCount); } } } protected final void assertBranchingPoints( int line, int expectedSourcesAndTargets, int expectedCoveredSourcesAndTargets) { PerFileLineCoverage lineCoverageInfo = fileData().lineCoverageInfo; LineCoverageData lineData = lineCoverageInfo.getLineData(line); int sourcesAndTargets = lineCoverageInfo.getNumberOfBranchingSourcesAndTargets(line); assertEquals("Sources and targets:", expectedSourcesAndTargets, sourcesAndTargets); int coveredSourcesAndTargets = lineData.getNumberOfCoveredBranchingSourcesAndTargets(); // assertEquals("Covered sources and targets:", expectedCoveredSourcesAndTargets, coveredSourcesAndTargets); } protected final void findMethodData(int firstLineOfMethodBody) { methodData = fileData().pathCoverageInfo.firstLineToMethodData.get(firstLineOfMethodBody); assertNotNull("Method not found with first line " + firstLineOfMethodBody, methodData); } protected final void assertPaths(int expectedPaths, int expectedCoveredPaths, int expectedExecutionCount) { assertEquals("Number of paths:", expectedPaths, methodData.getTotalPaths()); assertEquals("Number of covered paths:", expectedCoveredPaths, methodData.getCoveredPaths()); assertEquals("Execution count for all paths:", expectedExecutionCount, methodData.getExecutionCount()); } protected final void assertMethodLines(int startingLine, int endingLine) { assertEquals(startingLine, methodData.getFirstLineInBody()); assertEquals(endingLine, methodData.getLastLineInBody()); } @Nonnull protected final Path assertPath(int expectedNodeCount, int expectedExecutionCount) { int i = currentPathIndex + 1; currentPathIndex = -1; Path path = methodData.paths.get(i); assertEquals("Path node count:", expectedNodeCount, path.getNodes().size()); assertEquals("Path execution count:", expectedExecutionCount, path.getExecutionCount()); currentPathIndex = i; return path; } protected final void assertRegularPath(int expectedNodeCount, int expectedExecutionCount) { Path path = assertPath(expectedNodeCount, expectedExecutionCount); assertFalse("Path is shadowed", path.isShadowed()); } protected final void assertShadowedPath(int expectedNodeCount, int expectedExecutionCount) { Path path = assertPath(expectedNodeCount, expectedExecutionCount); assertTrue("Path is not shadowed", path.isShadowed()); } @After public final void verifyThatAllPathsWereAccountedFor() { int nextPathIndex = currentPathIndex + 1; if (methodData != null && nextPathIndex > 0) { assertEquals("Path " + nextPathIndex + " was not verified;", nextPathIndex, methodData.paths.size()); } } protected final void assertFieldIgnored(@Nonnull String fieldName) { String fieldId = testedClassSimpleName + '.' + fieldName; PerFileDataCoverage info = fileData().dataCoverageInfo; assertFalse( "Field " + fieldName + " should not have static coverage data", info.staticFieldsData.containsKey(fieldId)); assertFalse( "Field " + fieldName + " should not have instance coverage data", info.instanceFieldsData.containsKey(fieldId)); } protected static void assertStaticFieldCovered(@Nonnull String fieldName) { assertTrue("Static field " + fieldName + " should be covered", isStaticFieldCovered(fieldName)); } private static boolean isStaticFieldCovered(@Nonnull String fieldName) { String classAndFieldNames = testedClassSimpleName + '.' + fieldName; StaticFieldData staticFieldData = fileData.dataCoverageInfo.staticFieldsData.get(classAndFieldNames); return staticFieldData.isCovered(); } protected static void assertStaticFieldUncovered(@Nonnull String fieldName) { assertFalse("Static field " + fieldName + " should not be covered", isStaticFieldCovered(fieldName)); } protected static void assertInstanceFieldCovered(@Nonnull String fieldName) { assertTrue("Instance field " + fieldName + " should be covered", isInstanceFieldCovered(fieldName)); } private static boolean isInstanceFieldCovered(@Nonnull String fieldName) { return getInstanceFieldData(fieldName).isCovered(); } private static InstanceFieldData getInstanceFieldData(@Nonnull String fieldName) { String classAndFieldNames = testedClassSimpleName + '.' + fieldName; return fileData.dataCoverageInfo.instanceFieldsData.get(classAndFieldNames); } protected static void assertInstanceFieldUncovered(@Nonnull String fieldName) { assertFalse("Instance field " + fieldName + " should not be covered", isInstanceFieldCovered(fieldName)); } protected static void assertInstanceFieldUncovered(@Nonnull String fieldName, @Nonnull Object... uncoveredInstances) { String msg = "Instance field " + fieldName + " should not be covered"; InstanceFieldData fieldData = getInstanceFieldData(fieldName); List<Integer> ownerInstances = fieldData.getOwnerInstancesWithUnreadAssignments(); assertEquals(msg, uncoveredInstances.length, ownerInstances.size()); for (Object uncoveredInstance : uncoveredInstances) { Integer instanceId = System.identityHashCode(uncoveredInstance); assertTrue(msg, ownerInstances.contains(instanceId)); } } protected static void verifyDataCoverage(int expectedItems, int expectedCoveredItems, int expectedCoverage) { PerFileDataCoverage info = fileData.dataCoverageInfo; assertEquals("Total data items:", expectedItems, info.getTotalItems()); assertEquals("Covered data items:", expectedCoveredItems, info.getCoveredItems()); assertEquals("Data coverage:", expectedCoverage, info.getCoveragePercentage()); } }