All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.conqat.engine.sourcecode.coverage.TestCoverageUtils Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) CQSE GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.conqat.engine.sourcecode.coverage;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.conqat.engine.commons.findings.location.ILineAdjuster;
import org.conqat.engine.commons.findings.location.LocationAdjuster;
import org.conqat.lib.commons.collections.CompactLines;
import org.conqat.lib.commons.collections.UnmodifiableList;
import org.conqat.lib.commons.region.SimpleRegion;

/**
 * Utility methods for dealing with coverage information.
 */
public class TestCoverageUtils {

	private static final Logger LOGGER = LogManager.getLogger();

	/**
	 * Adjusts line coverage information for a file to coverage information for a changed file. The
	 * changes to the file are described by a location adjuster. Due to the nature of coverage, each
	 * small change could affect the coverage globally, hence this is only a rough approximation. This
	 * method is robust w.r.t lines numbers that are out of the range w.r.t. the given
	 * {@link LocationAdjuster}. Such invalid lines are logged as error to the given logger.
	 *
	 * @param coverageInfo
	 *            this may be null and then the result is null as well.
	 */
	public static LineCoverageInfo adjustCoverageInfo(LineCoverageInfo coverageInfo, ILineAdjuster adjuster,
			String appendToErrorMessage, boolean reportInvalidLines) {
		if (coverageInfo == null) {
			return null;
		}

		LineCoverageInfo adjustedCoverageInfo = new LineCoverageInfo(coverageInfo.getUploadCommitTimestamp(),
				coverageInfo.getCodeCommitTimestamp(), coverageInfo.isMethodAccurate());

		for (ELineCoverage lineCoverageType : ELineCoverage.values()) {
			CompactLines relevantLines = lineCoverageType.getRelevantLines(coverageInfo);
			adjustLines(relevantLines, lineCoverageType, adjustedCoverageInfo, adjuster, appendToErrorMessage,
					reportInvalidLines);
		}

		return adjustedCoverageInfo;
	}

	/**
	 * Adjusts line coverage information for a file to coverage information for a changed file. The
	 * changes to the file are described by a location adjuster. Due to the nature of coverage, each
	 * small change could affect the coverage globally, hence this is only a rough approximation. This
	 * method is robust w.r.t lines numbers that are out of the range w.r.t. the given
	 * {@link LocationAdjuster}. Such invalid lines are logged as error to the given logger.
	 *
	 * @param coverageInfo
	 *            this may be null and then the result is null as well.
	 */
	public static LineCoverageInfo adjustCoverageInfo(LineCoverageInfo coverageInfo, ILineAdjuster adjuster,
			String appendToErrorMessage) {
		return adjustCoverageInfo(coverageInfo, adjuster, appendToErrorMessage, true);
	}

	/**
	 * Adjusts the given lines using a location adjuster and fills them into the provided coverage info.
	 * Invalid lines, i.e. lines numbers that are out of range w.r.t the given {@link LocationAdjuster}
	 * are logged as error to the given logger.
	 *
	 * @param lines
	 *            the line numbers (one-based)
	 */
	private static void adjustLines(CompactLines lines, ELineCoverage coverageType,
			LineCoverageInfo adjustedCoverageInfo, ILineAdjuster adjuster, String appendToErrorMessage,
			boolean reportInvalidLines) {
		Set invalidLines = new HashSet<>();
		for (int line : lines) {
			SimpleRegion adjustedLines = adjuster.adjustLine(line, invalidLines);
			if (adjustedLines == null) {
				continue;
			}
			for (int adjustedLine = adjustedLines.getStart(); adjustedLine <= adjustedLines.getEnd(); ++adjustedLine) {
				adjustedCoverageInfo.addLineCoverage(adjustedLine, coverageType);
			}
		}
		if (reportInvalidLines) {
			reportInvalidLines(appendToErrorMessage, invalidLines, adjuster);
		}
	}

	/** Logs a warning if the invalid lines are not empty. */
	public static void reportInvalidLines(String appendToErrorMessage, Set invalidLines,
			ILineAdjuster adjuster) {
		if (!invalidLines.isEmpty()) {
			LOGGER.warn("Encountered invalid lines: " + invalidLines + ". Line count: "
					+ adjuster.getOriginalLineCount() + ". " + appendToErrorMessage);
		}
	}

	/**
	 * Adjusts the line information of the given probole coverage using the specified location adjuster.
	 */
	public static void adjustProbeBasedCoverage(ProbeCoverageInfo probeCoverageInfo, LocationAdjuster adjuster,
			String appendToErrorMessage, boolean reportInvalidLines) {
		if (probeCoverageInfo == null) {
			return;
		}
		Set invalidLines = new HashSet<>();
		UnmodifiableList probes = probeCoverageInfo.getProbes();
		List validProbes = new ArrayList<>();
		for (CoverageProbeBase probe : probes) {
			SimpleRegion adjustedRegion = adjuster.adjustLine(probe.getLine(), invalidLines);
			if (adjustedRegion != null) {
				validProbes.add(probe);
				probe.setLine(adjustedRegion.getStart());
			}
		}
		if (reportInvalidLines) {
			reportInvalidLines(appendToErrorMessage, invalidLines, adjuster);
		}
		probeCoverageInfo.setProbes(validProbes);
	}

	/**
	 * Adjusts the line information of the given probole coverage using the specified location adjuster.
	 */
	public static void adjustProbeBasedCoverage(ProbeCoverageInfo probeCoverageInfo, LocationAdjuster adjuster,
			String appendToErrorMessage) {
		adjustProbeBasedCoverage(probeCoverageInfo, adjuster, appendToErrorMessage, true);
	}

	/**
	 * Adjust the line-coverage to expand to full statements (= shallow entity start and end)
	 */
	public static void adjustCoverageToStatements(LineCoverageInfo coverage,
			TokenElementLineInfo tokenElementLineInfo) {
		coverage.extendCoverageToStatements(tokenElementLineInfo.getMultilineStatementRegions());
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy