UNPKG

stryker-html-reporter

Version:

An html reporter for the JavaScript mutation testing framework Stryker

154 lines 7.92 kB
"use strict"; 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, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&#039;'); } 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