stryker-html-reporter
Version:
An html reporter for the JavaScript mutation testing framework Stryker
154 lines • 7.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var _ = require("lodash");
var typedHtml = require("typed-html");
var resultTable_1 = require("./resultTable");
var layout_1 = require("./layout");
var report_1 = require("stryker-api/report");
var mutantTable_1 = require("./mutantTable");
function sourceFile(result, sourceFile, mutants, breadcrumb, thresholds) {
var numberedMutants = _
.sortBy(mutants, function (m) { return m.range[0]; })
.map(function (mutant, index) { return ({ mutant: mutant, index: index }); });
return layout_1.layout(breadcrumb, typedHtml.createElement("div", { class: 'col-lg-12' },
typedHtml.createElement("div", { class: 'row' },
typedHtml.createElement("div", { class: 'col-sm-11' }, resultTable_1.resultTable(result, result.name, thresholds))),
typedHtml.createElement("div", { class: 'row' },
typedHtml.createElement("div", { class: 'col-lg-7' },
legend(mutants),
code(sourceFile, numberedMutants)),
typedHtml.createElement("div", { class: 'col-lg-5' }, mutantTable_1.mutantTable(numberedMutants, sourceFile ? sourceFile.content : '')))));
}
exports.sourceFile = sourceFile;
function legend(mutants) {
function displayCheckbox(state, isChecked) {
var filtered = mutants.filter(function (mutant) { return mutant.status === state; });
if (filtered.length) {
return typedHtml.createElement("div", { class: 'form-check form-check-inline' },
typedHtml.createElement("label", { class: 'form-check-label' },
typedHtml.createElement("input", { class: 'form-check-input stryker-display', checked: isChecked, value: state.toString(), type: 'checkbox' }),
report_1.MutantStatus[state],
" ", "(" + filtered.length + ")"));
}
else {
return '';
}
}
return typedHtml.createElement("div", { class: 'row legend' },
typedHtml.createElement("form", { class: 'col-md-12', novalidate: 'novalidate' },
displayCheckbox(report_1.MutantStatus.NoCoverage, true),
displayCheckbox(report_1.MutantStatus.Survived, true),
displayCheckbox(report_1.MutantStatus.Killed, false),
displayCheckbox(report_1.MutantStatus.TimedOut, false),
displayCheckbox(report_1.MutantStatus.RuntimeError, false),
displayCheckbox(report_1.MutantStatus.TranspileError, false),
typedHtml.createElement("a", { href: '#', class: 'stryker-collapse-expand-all' }, "Expand all")));
}
function code(sourceFile, mutants) {
if (sourceFile) {
return annotateCode(sourceFile, mutants);
}
else {
return typedHtml.createElement("pre", null,
typedHtml.createElement("code", null, "The source code itself was not reported at the `stryker-html-reporter`. Please report this issue at https://github.com/stryker-mutator/stryker/issues"));
}
}
function annotateCode(sourceFile, numberedMutants) {
var currentCursorMutantStatuses = {
killed: 0,
noCoverage: 0,
survived: 0,
timeout: 0
};
var maxIndex = sourceFile.content.length - 1;
var adjustCurrentMutantResult = function (valueToAdd) { return function (numberedMutant) {
switch (numberedMutant.mutant.status) {
case report_1.MutantStatus.Killed:
currentCursorMutantStatuses.killed += valueToAdd;
break;
case report_1.MutantStatus.Survived:
currentCursorMutantStatuses.survived += valueToAdd;
break;
case report_1.MutantStatus.TimedOut:
currentCursorMutantStatuses.timeout += valueToAdd;
break;
case report_1.MutantStatus.NoCoverage:
currentCursorMutantStatuses.noCoverage += valueToAdd;
break;
}
}; };
var determineBackground = function () {
if (currentCursorMutantStatuses.survived > 0) {
return getContextClassForStatus(report_1.MutantStatus.Survived) + '-light';
}
else if (currentCursorMutantStatuses.noCoverage > 0) {
return getContextClassForStatus(report_1.MutantStatus.NoCoverage) + '-light';
}
else if (currentCursorMutantStatuses.timeout > 0) {
return getContextClassForStatus(report_1.MutantStatus.TimedOut) + '-light';
}
else if (currentCursorMutantStatuses.killed > 0) {
return getContextClassForStatus(report_1.MutantStatus.Killed) + '-light';
}
return null;
};
var annotate = function (char, index) {
var mutantsStarting = numberedMutants.filter(function (m) { return m.mutant.range[0] === index; });
var mutantsEnding = numberedMutants.filter(function (m) { return m.mutant.range[1] === index; });
mutantsStarting.forEach(adjustCurrentMutantResult(1));
mutantsEnding.forEach(adjustCurrentMutantResult(-1));
var backgroundColorAnnotation = mutantsStarting.length || mutantsEnding.length || index === 0 ? "<span class=\"bg-" + determineBackground() + "\">" : '';
var backgroundColorEndAnnotation = ((mutantsStarting.length || mutantsEnding.length) && index > 0) || index === maxIndex ? '</span>' : '';
try {
var mutantsAnnotations = mutantsStarting.map(function (m) {
return typedHtml.createElement("a", { href: '#', class: 'stryker-mutant-button', tabindex: '0', title: m.mutant.mutatorName, "data-content": getMutantContent(m.mutant), "data-mutant-status-annotation": getContextClassForStatus(m.mutant.status), "data-mutant-status": m.mutant.status, "data-mutant": m.index },
typedHtml.createElement("span", { class: "badge badge-" + getContextClassForStatus(m.mutant.status) }, m.index))
+ typedHtml.createElement("span", { class: 'badge badge-info stryker-mutant-replacement', hidden: 'hidden', "data-mutant": m.index }, escapeHtml(m.mutant.replacement));
});
var originalCodeStartAnnotations = mutantsStarting.map(function (m) { return "<span class=\"stryker-original-code\" data-mutant=\"" + m.index + "\">"; });
var originalCodeEndAnnotations = mutantsEnding.map(function () { return '</span>'; });
return "" + backgroundColorEndAnnotation + originalCodeEndAnnotations.join('') + mutantsAnnotations.join('') + originalCodeStartAnnotations.join('') + backgroundColorAnnotation + escapeHtml(char);
}
catch (err) {
console.log(err);
}
};
return typedHtml.createElement("pre", null,
typedHtml.createElement("code", { class: 'lang-javascript' }, mapString(sourceFile.content, annotate).join('')));
}
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
function getMutantContent(mutant) {
return "status: " + report_1.MutantStatus[mutant.status];
}
function getContextClassForStatus(status) {
switch (status) {
case report_1.MutantStatus.Killed:
return 'success';
case report_1.MutantStatus.NoCoverage:
case report_1.MutantStatus.Survived:
return 'danger';
case report_1.MutantStatus.TimedOut:
return 'warning';
case report_1.MutantStatus.RuntimeError:
case report_1.MutantStatus.TranspileError:
return 'secondary';
}
}
/**
* A `map` function, as in [1, 2].map(i => i+1), but for a string
*/
function mapString(source, fn) {
var results = [];
for (var i = 0; i < source.length; i++) {
results.push(fn(source[i], i));
}
return results;
}
//# sourceMappingURL=sourceFile.js.map