stryker
Version:
The extendable JavaScript mutation testing framework
147 lines • 7.28 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var _ = require("lodash");
var report_1 = require("stryker-api/report");
var objectUtils_1 = require("./utils/objectUtils");
var plugin_1 = require("stryker-api/plugin");
var defaultScoreIfNoValidMutants = 100;
var ScoreResultCalculator = /** @class */ (function () {
function ScoreResultCalculator(log) {
this.log = log;
}
ScoreResultCalculator.prototype.calculate = function (results) {
var scoreResult = this.calculateScoreResult(results, '');
return this.wrapIfSingleFileScoreResult(scoreResult);
};
ScoreResultCalculator.prototype.determineExitCode = function (score, thresholds) {
var breaking = thresholds && thresholds.break;
var formattedScore = score.mutationScore.toFixed(2);
if (typeof breaking === 'number') {
if (score.mutationScore < breaking) {
this.log.error("Final mutation score " + formattedScore + " under breaking threshold " + breaking + ", setting exit code to 1 (failure).");
this.log.info('(improve mutation score or set `thresholds.break = null` to prevent this error in the future)');
objectUtils_1.setExitCode(1);
}
else {
this.log.info("Final mutation score of " + formattedScore + " is greater than or equal to break threshold " + breaking);
}
}
else {
this.log.debug('No breaking threshold configured. Won\'t fail the build no matter how low your mutation score is. Set `thresholds.break` to change this behavior.');
}
};
ScoreResultCalculator.prototype.wrapIfSingleFileScoreResult = function (scoreResult) {
if (scoreResult.representsFile) {
return this.copy(scoreResult, {
childResults: [
this.copy(scoreResult, { name: path.basename(scoreResult.name) })
],
name: path.dirname(scoreResult.name)
});
}
else {
return scoreResult;
}
};
ScoreResultCalculator.prototype.calculateScoreResult = function (results, basePath) {
var numbers = this.countNumbers(results);
var facts = this.determineFacts(basePath, results);
return objectUtils_1.freezeRecursively(_.assign(numbers, facts));
};
ScoreResultCalculator.prototype.copy = function (defaults, overrides) {
return Object.assign({}, defaults, overrides);
};
ScoreResultCalculator.prototype.determineFacts = function (basePath, results) {
var name = this.determineCommonBasePath(results, basePath);
var childResults = this.calculateChildScores(results, name, basePath);
return {
childResults: childResults,
name: name,
path: path.join(basePath, name),
representsFile: childResults.length === 0 && results.length > 0
};
};
ScoreResultCalculator.prototype.compareScoreResults = function (a, b) {
var sortValue = function (scoreResult) {
// Directories first
if (scoreResult.representsFile) {
return "1" + scoreResult.name;
}
else {
return "0" + scoreResult.name;
}
};
return sortValue(a).localeCompare(sortValue(b));
};
ScoreResultCalculator.prototype.calculateChildScores = function (results, parentName, basePath) {
var _this = this;
var childrenBasePath = parentName.length ? path.join(basePath, parentName) + path.sep : '';
var resultsGroupedByFiles = _.groupBy(results, function (result) { return result.sourceFilePath.substr(childrenBasePath.length); });
var uniqueFiles = Object.keys(resultsGroupedByFiles);
if (uniqueFiles.length > 1) {
var filesGroupedByDirectory_1 = _.groupBy(uniqueFiles, function (file) { return file.split(path.sep)[0]; });
return Object.keys(filesGroupedByDirectory_1)
.map(function (directory) { return _this.calculateScoreResult(_.flatMap(filesGroupedByDirectory_1[directory], function (file) { return resultsGroupedByFiles[file]; }), childrenBasePath); })
.sort(this.compareScoreResults);
}
else {
return [];
}
};
ScoreResultCalculator.prototype.determineCommonBasePath = function (results, basePath) {
var uniqueFiles = _.uniq(results.map(function (result) { return result.sourceFilePath; }));
var uniqueFileDirectories = uniqueFiles.map(function (file) { return file.substr(basePath.length).split(path.sep); });
if (uniqueFileDirectories.length) {
return uniqueFileDirectories.reduce(this.filterDirectories).join(path.sep);
}
else {
return '';
}
};
ScoreResultCalculator.prototype.filterDirectories = function (previousDirectories, currentDirectories) {
for (var i = 0; i < previousDirectories.length; i++) {
if (previousDirectories[i] !== currentDirectories[i]) {
return previousDirectories.splice(0, i);
}
}
return previousDirectories;
};
ScoreResultCalculator.prototype.countNumbers = function (mutantResults) {
var count = function (mutantResult) { return mutantResults.filter(function (_) { return _.status === mutantResult; }).length; };
var killed = count(report_1.MutantStatus.Killed);
var timedOut = count(report_1.MutantStatus.TimedOut);
var survived = count(report_1.MutantStatus.Survived);
var noCoverage = count(report_1.MutantStatus.NoCoverage);
var runtimeErrors = count(report_1.MutantStatus.RuntimeError);
var transpileErrors = count(report_1.MutantStatus.TranspileError);
var totalDetected = timedOut + killed;
var totalUndetected = survived + noCoverage;
var totalCovered = totalDetected + survived;
var totalValid = totalUndetected + totalDetected;
var totalInvalid = runtimeErrors + transpileErrors;
var totalMutants = totalValid + totalInvalid;
var mutationScore = totalValid > 0 ? totalDetected / totalValid * 100 : defaultScoreIfNoValidMutants;
var mutationScoreBasedOnCoveredCode = totalValid > 0 ? totalDetected / totalCovered * 100 || 0 : defaultScoreIfNoValidMutants;
return {
killed: killed,
mutationScore: mutationScore,
mutationScoreBasedOnCoveredCode: mutationScoreBasedOnCoveredCode,
noCoverage: noCoverage,
runtimeErrors: runtimeErrors,
survived: survived,
timedOut: timedOut,
totalCovered: totalCovered,
totalDetected: totalDetected,
totalInvalid: totalInvalid,
totalMutants: totalMutants,
totalUndetected: totalUndetected,
totalValid: totalValid,
transpileErrors: transpileErrors
};
};
ScoreResultCalculator.inject = plugin_1.tokens(plugin_1.commonTokens.logger);
return ScoreResultCalculator;
}());
exports.default = ScoreResultCalculator;
//# sourceMappingURL=ScoreResultCalculator.js.map
;