Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

danger-plugin-coverage

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

danger-plugin-coverage - npm Package Compare versions

Comparing version 1.5.0 to 1.6.0

117

dist/plugin.js

@@ -93,4 +93,3 @@ "use strict";

const getShortPath = filePath => {
const maxChars = 40;
const getShortPath = (filePath, maxChars) => {
const parts = filePath.split('/').reverse().filter(x => x);

@@ -104,10 +103,14 @@

let currentChars = 0;
parts.forEach(part => {
if (currentChars < maxChars) {
parts.forEach((part, index) => {
const isLastPart = parts.length - 1 === index;
currentChars += part.length + 1; // +1 for the path seperator
const prefixLength = !isLastPart ? 3 : 0;
if (currentChars + prefixLength < maxChars) {
shortParts.push(part);
currentChars += part.length + 1; // +1 for the path seperator
}
});
if (shortParts.length < parts.length - 1) {
if (shortParts.length < parts.length) {
shortParts.push('..');

@@ -119,2 +122,26 @@ }

/**
* Insert whitespace into a path so that it wraps within the Markdown table.
*/
const getWrappedPath = filePath => {
const parts = filePath.split('/');
const maxPerLine = 25;
let currentChars = 0;
return parts.map((pathPart, i) => {
var _parts;
const isLastPart = parts.length - 1 === i;
const newPart = isLastPart ? pathPart : `${pathPart}/`;
currentChars += pathPart.length;
if (currentChars + (((_parts = parts[i + 1]) === null || _parts === void 0 ? void 0 : _parts.length) || 0) > maxPerLine) {
currentChars = 0;
return `${newPart}<br>`;
}
return newPart;
}).join('');
};
/**
* Check if we have passed the thresholds for the given percentages.

@@ -135,3 +162,8 @@ */

const buildRow = (file, threshold) => {
const buildRow = (file, {
threshold,
maxChars,
maxUncovered,
wrapFilenames
}) => {
var _danger$git, _danger$git$commits;

@@ -144,7 +176,8 @@

const filePath = _path.default.relative(process.cwd(), file.$.path);
const longPath = _path.default.relative(process.cwd(), file.$.path);
const shortPath = getShortPath(filePath);
const fileLink = `../blob/${sha}/${filePath}`;
const fileCell = sha ? `[${shortPath}](${fileLink})` : shortPath;
const shortPath = getShortPath(longPath, maxChars);
const readablePath = wrapFilenames ? getWrappedPath(shortPath) : shortPath;
const fileLink = `../blob/${sha}/${longPath}`;
const fileCell = sha ? `[${readablePath}](${fileLink})` : readablePath;
const percentages = getMetricPercentages(fileMetrics);

@@ -158,3 +191,2 @@ const noLines = !fileMetrics.lines;

const maxUncovered = 3;
let uncoveredCell = fileMetrics.uncoveredLines.slice(0, maxUncovered).map(line => {

@@ -183,3 +215,7 @@ const lineNumber = line.$.num;

const buildTable = (files, maxRows, threshold, showAllFiles) => {
const buildTable = (files, opts) => {
const {
maxRows,
showAllFiles
} = opts;
const headings = [`${showAllFiles ? '' : 'Impacted '}Files`, '% Stmts', '% Branch', '% Funcs', '% Lines', 'Uncovered Lines', ''];

@@ -189,3 +225,3 @@ const headingRow = joinRow(headings);

], []));
const allFileRows = files.map(file => buildRow(file, threshold));
const allFileRows = files.map(file => buildRow(file, opts));
const mainFileRows = allFileRows.slice(0, maxRows);

@@ -220,3 +256,7 @@ const extraFileRows = allFileRows.slice(maxRows);

const buildSummary = (metrics, successMessage, failureMessage, threshold) => {
const buildSummary = (metrics, {
successMessage,
failureMessage,
threshold
}) => {
const percentages = getMetricPercentages(metrics);

@@ -249,3 +289,5 @@ const passed = hasPassed(threshold, percentages);

const getRelevantFiles = (coverageXml, showAllFiles) => {
const getRelevantFiles = (coverageXml, {
showAllFiles
}) => {
var _danger$git2, _danger$git3;

@@ -268,20 +310,25 @@

const coverage = async ({
successMessage = ':+1: Test coverage is looking good.',
failureMessage = 'Test coverage is looking a little low for the files created ' + 'or modified in this PR, perhaps we need to improve this.',
cloverReportPath,
maxRows = 5,
showAllFiles = false,
warnOnNoReport = true,
threshold = {
statements: 80,
branches: 80,
functions: 80,
lines: 80
}
} = {}) => {
const coverageXml = await (0, _report.getCoverageReport)(cloverReportPath);
const coverage = async (initialOpts = {}) => {
const opts = {
successMessage: ':+1: Test coverage is looking good.',
failureMessage: 'Test coverage is looking a little low for the files created ' + 'or modified in this PR, perhaps we need to improve this.',
cloverReportPath: null,
maxRows: 3,
maxChars: 100,
maxUncovered: 10,
wrapFilenames: true,
showAllFiles: false,
warnOnNoReport: true,
threshold: {
statements: 80,
branches: 80,
functions: 80,
lines: 80
},
...initialOpts
};
const coverageXml = await (0, _report.getCoverageReport)(opts.cloverReportPath);
if (!coverageXml) {
if (warnOnNoReport) {
if (opts.warnOnNoReport) {
warn('No coverage report was detected. ' + 'Please output a report in the `clover.xml` format before running danger');

@@ -293,3 +340,3 @@ }

const relevantFiles = getRelevantFiles(coverageXml, showAllFiles);
const relevantFiles = getRelevantFiles(coverageXml, opts);

@@ -301,4 +348,4 @@ if (!relevantFiles.length) {

const combinedMetrics = getCombinedMetrics(relevantFiles);
const table = buildTable(relevantFiles, maxRows, threshold, showAllFiles);
const summary = buildSummary(combinedMetrics, successMessage, failureMessage, threshold);
const table = buildTable(relevantFiles, opts);
const summary = buildSummary(combinedMetrics, opts);
const report = ['## Coverage Report', summary, table].join(newLine + newLine);

@@ -305,0 +352,0 @@ markdown(report);

{
"name": "danger-plugin-coverage",
"version": "1.5.0",
"version": "1.6.0",
"description": "A Danger plugin to report code coverage.",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -86,2 +86,5 @@ # danger-plugin-coverage

| `maxRows` | The number of rows to show (additional rows will be collapsed within a `<details>` element). |
| `maxChars` | The maximum number of characters to allow in a file name cell. |
| `maxUncovered` | The maximum number of uncovered lines to show. |
| `wrapFilenames` | Wrap long file names to help the table fit in a PR comment. |
| `threshold` | The thresholds at which to show the failure messaging. |

@@ -100,3 +103,6 @@ | `warnOnNoReport` | Show a warning if no coverage report was detected. |

cloverReportPath: './coverage/clover.xml',
maxRows: 5,
maxRows: 3,
maxChars: 100,
maxUncovered: 10,
wrapFilenames: true,
warnOnNoReport: true,

@@ -103,0 +109,0 @@ showAllFiles: false,

@@ -76,4 +76,3 @@ import path from 'path';

*/
const getShortPath = (filePath) => {
const maxChars = 40;
const getShortPath = (filePath, maxChars) => {
const parts = filePath.split('/').reverse().filter((x) => x);

@@ -89,10 +88,13 @@

parts.forEach((part) => {
if (currentChars < maxChars) {
parts.forEach((part, index) => {
const isLastPart = parts.length - 1 === index;
currentChars += part.length + 1; // +1 for the path seperator
const prefixLength = (!isLastPart ? 3 : 0);
if (currentChars + prefixLength < maxChars) {
shortParts.push(part);
currentChars += part.length + 1; // +1 for the path seperator
}
});
if (shortParts.length < parts.length - 1) {
if (shortParts.length < parts.length) {
shortParts.push('..');

@@ -105,2 +107,24 @@ }

/**
* Insert whitespace into a path so that it wraps within the Markdown table.
*/
const getWrappedPath = (filePath) => {
const parts = filePath.split('/');
const maxPerLine = 25;
let currentChars = 0;
return parts.map((pathPart, i) => {
const isLastPart = parts.length - 1 === i;
const newPart = isLastPart ? pathPart : `${pathPart}/`;
currentChars += pathPart.length;
if (currentChars + (parts[i + 1]?.length || 0) > maxPerLine) {
currentChars = 0;
return `${newPart}<br>`;
}
return newPart;
}).join('');
};
/**
* Check if we have passed the thresholds for the given percentages.

@@ -123,11 +147,19 @@ */

*/
const buildRow = (file, threshold) => {
const buildRow = (file, {
threshold,
maxChars,
maxUncovered,
wrapFilenames,
}) => {
const fileMetrics = getFileMetrics(file);
const { sha } = danger.git?.commits?.[danger.git.commits.length - 1] || {};
const filePath = path.relative(process.cwd(), file.$.path);
const shortPath = getShortPath(filePath);
const fileLink = `../blob/${sha}/${filePath}`;
const fileCell = sha ? `[${shortPath}](${fileLink})` : shortPath;
const longPath = path.relative(process.cwd(), file.$.path);
const shortPath = getShortPath(longPath, maxChars);
const readablePath = wrapFilenames ? getWrappedPath(shortPath) : shortPath;
const fileLink = `../blob/${sha}/${longPath}`;
const fileCell = sha ? `[${readablePath}](${fileLink})` : readablePath;
const percentages = getMetricPercentages(fileMetrics);

@@ -142,3 +174,2 @@

const maxUncovered = 3;
let uncoveredCell = fileMetrics

@@ -180,3 +211,8 @@ .uncoveredLines

*/
const buildTable = (files, maxRows, threshold, showAllFiles) => {
const buildTable = (files, opts) => {
const {
maxRows,
showAllFiles,
} = opts;
const headings = [

@@ -200,3 +236,3 @@ `${showAllFiles ? '' : 'Impacted '}Files`,

const allFileRows = files.map((file) => buildRow(file, threshold));
const allFileRows = files.map((file) => buildRow(file, opts));
const mainFileRows = allFileRows.slice(0, maxRows);

@@ -245,3 +281,3 @@ const extraFileRows = allFileRows.slice(maxRows);

*/
const buildSummary = (metrics, successMessage, failureMessage, threshold) => {
const buildSummary = (metrics, { successMessage, failureMessage, threshold }) => {
const percentages = getMetricPercentages(metrics);

@@ -288,3 +324,3 @@ const passed = hasPassed(threshold, percentages);

*/
const getRelevantFiles = (coverageXml, showAllFiles) => {
const getRelevantFiles = (coverageXml, { showAllFiles }) => {
const files = getFlatFiles(coverageXml);

@@ -310,21 +346,27 @@ const allFiles = [

*/
export const coverage = async ({
successMessage = ':+1: Test coverage is looking good.',
failureMessage = 'Test coverage is looking a little low for the files created '
+ 'or modified in this PR, perhaps we need to improve this.',
cloverReportPath,
maxRows = 5,
showAllFiles = false,
warnOnNoReport = true,
threshold = {
statements: 80,
branches: 80,
functions: 80,
lines: 80,
},
} = {}) => {
const coverageXml = await getCoverageReport(cloverReportPath);
export const coverage = async (initialOpts = {}) => {
const opts = {
successMessage: ':+1: Test coverage is looking good.',
failureMessage: 'Test coverage is looking a little low for the files created '
+ 'or modified in this PR, perhaps we need to improve this.',
cloverReportPath: null,
maxRows: 3,
maxChars: 100,
maxUncovered: 10,
wrapFilenames: true,
showAllFiles: false,
warnOnNoReport: true,
threshold: {
statements: 80,
branches: 80,
functions: 80,
lines: 80,
},
...initialOpts,
};
const coverageXml = await getCoverageReport(opts.cloverReportPath);
if (!coverageXml) {
if (warnOnNoReport) {
if (opts.warnOnNoReport) {
warn('No coverage report was detected. '

@@ -336,3 +378,3 @@ + 'Please output a report in the `clover.xml` format before running danger');

const relevantFiles = getRelevantFiles(coverageXml, showAllFiles);
const relevantFiles = getRelevantFiles(coverageXml, opts);

@@ -344,4 +386,4 @@ if (!relevantFiles.length) {

const combinedMetrics = getCombinedMetrics(relevantFiles);
const table = buildTable(relevantFiles, maxRows, threshold, showAllFiles);
const summary = buildSummary(combinedMetrics, successMessage, failureMessage, threshold);
const table = buildTable(relevantFiles, opts);
const summary = buildSummary(combinedMetrics, opts);
const report = [

@@ -348,0 +390,0 @@ '## Coverage Report',

@@ -228,3 +228,3 @@ import path from 'path';

expect(lines).toContain(successMessage);
expect(lines).toContain('and 5 more...');
expect(lines).toContain('and 7 more...');
});

@@ -298,4 +298,4 @@

it('shortens long paths', async () => {
const seg = 'xxxxxxxxxx';
it('shortens and wraps long paths', async () => {
const seg = new Array(10).fill('x').join('');
const longPath = new Array(10).fill(seg).join('/');

@@ -325,3 +325,3 @@ const file = getFileXml(longPath, DEFAULT_METRICS, [DEFAULT_LINE]);

expect(lines).toContain(
`|../${seg}/${seg}/${seg}/${seg}|100|100|100|100||:white_check_mark:|`,
`|../${seg}/${seg}/<br>${seg}/${seg}/<br>${seg}/${seg}/<br>${seg}/${seg}|100|100|100|100||:white_check_mark:|`,
);

@@ -452,33 +452,14 @@ });

it('reports uncovered lines', async () => {
const fileOne = getFileXml(path.join(process.cwd(), '/src/one.js'), DEFAULT_METRICS, [
{
num: 1,
count: 0,
type: 'stmt',
},
{
num: 2,
count: 0,
type: 'stmt',
},
{
num: 3,
count: 0,
type: 'stmt',
},
{
num: 4,
count: 0,
type: 'stmt',
},
]);
const getUncoveredLine = (num) => ({
num,
count: 0,
type: 'stmt',
});
const fileTwo = getFileXml(path.join(process.cwd(), '/src/two.js'), DEFAULT_METRICS, [
{
num: 1,
count: 0,
type: 'stmt',
},
]);
const fileOneLines = new Array(11).fill().map((_, i) => getUncoveredLine(i + 1));
const fileOne = getFileXml(path.join(process.cwd(), '/src/one.js'), DEFAULT_METRICS, fileOneLines);
const fileTwoLines = [getUncoveredLine(1)];
const fileTwo = getFileXml(path.join(process.cwd(), '/src/two.js'), DEFAULT_METRICS, fileTwoLines);
const xmlReport = wrapXmlReport([

@@ -509,3 +490,3 @@ fileOne,

expect(report).toMatchSnapshot();
expect(lines).toContain('|src/one.js|100|100|100|0|1, 2, 3...|:x:|');
expect(lines).toContain('|src/one.js|100|100|100|0|1, 2, 3, 4, 5, 6, 7, 8, 9, 10...|:x:|');
expect(lines).toContain('|src/two.js|100|100|100|0|1|:x:|');

@@ -512,0 +493,0 @@ });

@@ -201,2 +201,28 @@ import path from 'path';

});
it('makes paths even shorter', async () => {
const longPath = 'ab/cd/ef/gh/ij/kl/mn'; // 20 chars
const file = getFileXml(longPath, DEFAULT_METRICS, [DEFAULT_LINE]);
const xmlReport = wrapXmlReport(file);
mockFs({
[CLOVER_PATH]: xmlReport,
});
Object.assign(danger, {
git: {
created_files: [longPath],
modified_files: [],
},
});
await coverage({ maxChars: 10 });
const report = getMarkdownReport();
const lines = report.split('\n');
expect(report).toMatchSnapshot();
expect(lines).toContain('|../kl/mn|100|100|100|100||:white_check_mark:|');
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc