/* * Copyright (c) 2006 Rogério Liesenfeld * This file is subject to the terms of the MIT license (see LICENSE.txt). */ package mockit.coverage.data; import java.io.*; import java.util.*; import javax.annotation.*; import mockit.coverage.*; import mockit.coverage.dataItems.*; import mockit.coverage.lines.*; import mockit.coverage.paths.*; import static mockit.coverage.Metrics.*; /** * Coverage data gathered for the lines and branches of a single source file. */ public final class FileCoverageData implements Serializable { private static final long serialVersionUID = 3508572808457541012L; @Nonnull private static final PerFileLineCoverage NO_LINE_INFO = new PerFileLineCoverage(); @Nonnull private static final PerFilePathCoverage NO_PATH_INFO = new PerFilePathCoverage(); @Nonnull private static final PerFileDataCoverage NO_DATA_INFO = new PerFileDataCoverage(); @Nonnull public PerFileLineCoverage lineCoverageInfo; @Nonnull public PerFilePathCoverage pathCoverageInfo; @Nonnull public PerFileDataCoverage dataCoverageInfo; // Used for fast indexed access. public final int index; // Used for output styling in the HTML report. @Nullable public String kindOfTopLevelType; // Used to track the last time the ".class" file was modified, to decide if merging can be done. long lastModified; private final boolean loadedAfterTestCompletion; public FileCoverageData(int index, @Nullable String kindOfTopLevelType) { this.index = index; this.kindOfTopLevelType = kindOfTopLevelType; lineCoverageInfo = LineCoverage.active ? new PerFileLineCoverage() : NO_LINE_INFO; pathCoverageInfo = PathCoverage.active ? new PerFilePathCoverage() : NO_PATH_INFO; dataCoverageInfo = DataCoverage.active ? new PerFileDataCoverage() : NO_DATA_INFO; loadedAfterTestCompletion = TestRun.isTerminated(); } public boolean wasLoadedAfterTestCompletion() { return loadedAfterTestCompletion; } @Nonnull public PerFileLineCoverage getLineCoverageData() { return lineCoverageInfo; } public void addMethod(@Nonnull MethodCoverageData methodData) { pathCoverageInfo.addMethod(methodData); } @Nonnull public Collection<MethodCoverageData> getMethods() { List<MethodCoverageData> methods = new ArrayList<MethodCoverageData>(pathCoverageInfo.firstLineToMethodData.values()); Collections.sort(methods, new Comparator<MethodCoverageData>() { @Override public int compare(MethodCoverageData m1, MethodCoverageData m2) { int l1 = m1.getFirstLineInBody(); int l2 = m2.getFirstLineInBody(); if (l1 == l2) { return 0; } return l1 < l2 ? -1 : 1; } }); return methods; } @Nonnull public PerFileCoverage getPerFileCoverage(@Nonnull Metrics metric) { switch (metric) { case LineCoverage: return lineCoverageInfo; case PathCoverage: return pathCoverageInfo; default: return dataCoverageInfo; } } public int getTotalItemsForAllMetrics() { int totalItems = 0; if (lineCoverageInfo != NO_LINE_INFO) { totalItems += lineCoverageInfo.getTotalItems(); } if (pathCoverageInfo != NO_PATH_INFO) { totalItems += pathCoverageInfo.getTotalItems(); } if (dataCoverageInfo != NO_DATA_INFO) { totalItems += dataCoverageInfo.getTotalItems(); } return totalItems; } void mergeWithDataFromPreviousTestRun(@Nonnull FileCoverageData previousInfo) { if (lineCoverageInfo == NO_LINE_INFO) { lineCoverageInfo = previousInfo.lineCoverageInfo; } else if (previousInfo.lineCoverageInfo != NO_LINE_INFO) { lineCoverageInfo.mergeInformation(previousInfo.lineCoverageInfo); } if (pathCoverageInfo == NO_PATH_INFO) { pathCoverageInfo = previousInfo.pathCoverageInfo; } else if (previousInfo.pathCoverageInfo != NO_PATH_INFO) { pathCoverageInfo.mergeInformation(previousInfo.pathCoverageInfo); } if (dataCoverageInfo == NO_DATA_INFO) { dataCoverageInfo = previousInfo.dataCoverageInfo; } else if (previousInfo.dataCoverageInfo != NO_DATA_INFO) { dataCoverageInfo.mergeInformation(previousInfo.dataCoverageInfo); } } void reset() { lineCoverageInfo.reset(); pathCoverageInfo.reset(); } }