Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add threshold-uncovered option #173

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions __tests__/integrations/cli/__snapshots__/test-exit-value.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ Object {
}
`;

exports[`CLI exit value should exit with code 0 when uncovered_count <= thresholdUncovered 1`] = `
Object {
"error": null,
"exitCode": 0,
}
`;

exports[`CLI exit value should exit with code 2 when total coverage is lower than the custom threshold 1`] = `
Object {
"error": [Error: Command failed: flow-coverage-report.js -i "src/*.js" --threshold 22
Flow Coverage 16% is below the required threshold 22%
Flow Coverage: 16% is below the required threshold 22%
],
"exitCode": 2,
}
Expand All @@ -19,7 +26,16 @@ Flow Coverage 16% is below the required threshold 22%
exports[`CLI exit value should exit with code 2 when total coverage is lower than the default threshold 1`] = `
Object {
"error": [Error: Command failed: flow-coverage-report.js -i "src/*.js"
Flow Coverage 16% is below the required threshold 80%
Flow Coverage: 16% is below the required threshold 80%
],
"exitCode": 2,
}
`;

exports[`CLI exit value should exit with code 2 when uncovered_count > thresholdUncovered 1`] = `
Object {
"error": [Error: Command failed: flow-coverage-report.js -i "src/*.js" --threshold-uncovered 3
Flow Coverage: uncovered count is higher than the uncoveredThreshold
],
"exitCode": 2,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
exports[`--percent-decimals option should round percent values using the requested precision 1`] = `
Object {
"error": [Error: Command failed: flow-coverage-report.js --percent-decimals 2 -i "src/**.js"
Flow Coverage 16.67% is below the required threshold 80%
Flow Coverage: 16.67% is below the required threshold 80%
],
"exitCode": 2,
"filteredStdout": Array [
"│ src/main.js │ flow │ 16.67 % │ 6 │ 1 │ 5 │",
"│ project-decimal-coverage │ 16.67 % │ 6 │ 1 │ 5 │",
],
"stderr": "Flow Coverage 16.67% is below the required threshold 80%
"stderr": "Flow Coverage: 16.67% is below the required threshold 80%
",
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Object {
"filteredStdout": Array [
"│ src/url.js │ flow │ 0 % │ 9 │ 0 │ 9 │",
],
"stderr": "Flow Coverage 0% is below the required threshold 80%
"stderr": "Flow Coverage: 0% is below the required threshold 80%
",
}
`;
18 changes: 18 additions & 0 deletions __tests__/integrations/cli/test-exit-value.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,22 @@ describe('CLI exit value', async () => {

expect({exitCode, error}).toMatchSnapshot();
});

it('should exit with code 2 when uncovered_count > thresholdUncovered', async () => {
const {exitCode, error} = await runFlowCoverageReport([
'-i', `"src/*.js"`,
'--threshold-uncovered', '3'
], {cwd: testProjectDir});

expect({exitCode, error}).toMatchSnapshot();
});

it('should exit with code 0 when uncovered_count <= thresholdUncovered', async () => {
const {exitCode, error} = await runFlowCoverageReport([
'-i', `"src/*.js"`,
'--threshold-uncovered', '10'
], {cwd: testProjectDir});

expect({exitCode, error}).toMatchSnapshot();
});
});
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"scripts": {
"ava": "nyc ava --verbose",
"build": "rimraf dist && babel -d dist src --only src/lib --source-maps",
"dev": "babel -d dist src --only src/lib --source-maps --watch",
"update-flow-typed": "rimraf flow-typed && flow-typed install -s -i dev",
"flow-coverage": "bin/flow-coverage-report.js",
"flow-check": "flow check",
Expand Down Expand Up @@ -185,7 +186,7 @@
"\\.jsx$": "babel-jest"
},
"transformIgnorePatterns": [
"node_modules/(?!(svgo)/)"
"node_modules/(?!(svgo|badge-up)/)"
],
"testEnvironment": "node",
"testMatch": [
Expand Down
1 change: 1 addition & 0 deletions src/__tests__/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const FLOW_COVERAGE_SUMMARY_DATA = {
covered_count: 5,
uncovered_count: 5,
threshold: 40,
uncoveredThreshold: 3,
percent: 50,
globIncludePatterns: [firstGlob, secondGlob],
files: allFiles.reduce((acc, filename) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<FlowCoverageMeterBar /> 1`] = `
exports[`<FlowCoverageMeterBar /> percent <= threshold 1`] = `
<div
className="row red"
style={
Expand All @@ -11,3 +11,15 @@ exports[`<FlowCoverageMeterBar /> 1`] = `
}
/>
`;

exports[`<FlowCoverageMeterBar /> uncoveredCount <= thresholdUncovered 1`] = `
<div
className="row green"
style={
Object {
"height": 12,
"padding": 0,
}
}
/>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,45 @@ exports[`<FlowCoverageSummaryTable /> 2`] = `
</tbody>
</table>
`;

exports[`<FlowCoverageSummaryTable /> 3`] = `
<table
className="ui small celled table"
>
<thead>
<tr>
<th>
Percent
</th>
<th>
Total
</th>
<th>
Covered
</th>
<th>
Uncovered
</th>
</tr>
</thead>
<tbody>
<tr
className="positive"
>
<td>
50
%
</td>
<td>
10
</td>
<td>
5
</td>
<td>
5
</td>
</tr>
</tbody>
</table>
`;
28 changes: 20 additions & 8 deletions src/__tests__/react-components/test-coverage-meter-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,26 @@ import {BASE_DIR} from './common';

const REACT_COMPONENT = `${BASE_DIR}/coverage-meter-bar`;

test('<FlowCoverageMeterBar />', () => {
const FlowCoverageMeterBar = require(REACT_COMPONENT).default;
const props = {
percent: 20,
threshold: 80
};
const tree = renderer.create(<FlowCoverageMeterBar {...props}/>).toJSON();
expect(tree).toMatchSnapshot();
describe('<FlowCoverageMeterBar />', () => {
test('percent <= threshold', () => {
const FlowCoverageMeterBar = require(REACT_COMPONENT).default;
const props = {
percent: 20,
threshold: 80
};
const tree = renderer.create(<FlowCoverageMeterBar {...props}/>).toJSON();
expect(tree).toMatchSnapshot();
});

test('uncoveredCount <= thresholdUncovered', () => {
const FlowCoverageMeterBar = require(REACT_COMPONENT).default;
const props = {
uncoveredCount: 20,
thresholdUncovered: 30
};
const tree = renderer.create(<FlowCoverageMeterBar {...props}/>).toJSON();
expect(tree).toMatchSnapshot();
});
});

test.skip('<FlowCoverageMeterBar /> with missing props');
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,19 @@ test('<FlowCoverageSummaryTable />', () => {
const positiveSummaryTree = renderer.create(<FlowCoverageSummaryTable {...positiveSummaryProps}/>).toJSON();
expect(positiveSummaryTree).toMatchSnapshot();

// Expect positive with higher threshold.
// Expect negative with higher threshold.
const negativeSummaryProps = {
coverageSummaryData: {...FLOW_COVERAGE_SUMMARY_DATA, threshold: 90}
};
const negativeSummaryTree = renderer.create(<FlowCoverageSummaryTable {...negativeSummaryProps}/>).toJSON();
expect(negativeSummaryTree).toMatchSnapshot();

// Expect negative with uncovered_count >= thresholdUncovered
const negativeSummaryUncoveredProps = {
coverageSummaryData: {...FLOW_COVERAGE_SUMMARY_DATA, uncoveredThreshold: 4}
};
const negativeSummaryUncoveredTree = renderer.create(<FlowCoverageSummaryTable {...negativeSummaryUncoveredProps}/>).toJSON();
expect(negativeSummaryUncoveredTree).toMatchSnapshot();
});

test.skip('<FlowCoverageSummaryTable /> with missing props');
2 changes: 2 additions & 0 deletions src/__tests__/test-flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ const testCollectFlowCoverage = async ({
globIncludePatterns,
globExcludePatterns,
threshold: 80,
thresholdUncovered: 3,
concurrentFiles: 5,
strictCoverage,
excludeNonFlow
Expand Down Expand Up @@ -462,6 +463,7 @@ const testCollectFlowCoverage = async ({
concurrentFiles: 5,
percent: 50,
threshold: 80,
thresholdUncovered: 3,
/* eslint-disable camelcase */
covered_count: excludeNonFlow ? 4 : 5,
uncovered_count: excludeNonFlow ? 4 : 5,
Expand Down
4 changes: 4 additions & 0 deletions src/lib/cli/args.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ export default function processArgv(argv: Array<string>): any {
type: 'number',
describe: `the minimum coverage percent requested (defaults to ${defaultConfig.threshold})`
})
.options('threshold-uncovered', {
type: 'number',
describe: `the maximum number of uncovered lines`
})
.options('percent-decimals', {
alias: ['percentDecimanls'],
type: 'number',
Expand Down
4 changes: 3 additions & 1 deletion src/lib/cli/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type ConfigParams = {|
globExcludePatterns?: Array<string>,
globIncludePatterns: Array<string>,
threshold: number,
thresholdUncovered: number,
percentDecimals: number,
outputDir: string,
concurrentFiles?: number,
Expand Down Expand Up @@ -58,11 +59,12 @@ export const defaultConfig: DefaultConfigParams = {
projectDir: path.resolve(process.cwd()),
globExcludePatterns: ['node_modules/**'],
globIncludePatterns: [],
threshold: 80,
percentDecimals: 0,
outputDir: './flow-coverage',
concurrentFiles: 1,
strictCoverage: false,
threshold: 80,
thresholdUncovered: 0,
excludeNonFlow: false,
noConfig: false,
htmlTemplateOptions: {
Expand Down
15 changes: 12 additions & 3 deletions src/lib/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,19 @@ exports.run = () => {
}

generateFlowCoverageReport({...args}).then(([coverageSummaryData]) => {
const {percent, threshold} = coverageSummaryData;
if (percent < threshold) {
/* eslint-disable camelcase */
const {percent, threshold, thresholdUncovered, uncovered_count} = coverageSummaryData;

if (thresholdUncovered && uncovered_count > thresholdUncovered) {
/* eslint-enable camelcase */
console.error(
`Flow Coverage: uncovered count is higher than the uncoveredThreshold`
);
process.exit(2); // eslint-disable-line unicorn/no-process-exit
}
if (!thresholdUncovered && percent < threshold) {
console.error(
`Flow Coverage ${percent}% is below the required threshold ${threshold}%`
`Flow Coverage: ${percent}% is below the required threshold ${threshold}%`
);
process.exit(2); // eslint-disable-line unicorn/no-process-exit
}
Expand Down
7 changes: 5 additions & 2 deletions src/lib/components/body-coverage-sourcefile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default function HTMLReportBodySourceFile(props: FlowCoverageSourceFileRe
}
const {percent} = coverageData;

const threshold = coverageSummaryData.threshold;
const {threshold, thresholdUncovered} = coverageSummaryData;

if (!threshold) {
throw new Error('Missing threshold in coverageSummaryData');
Expand All @@ -84,9 +84,11 @@ export default function HTMLReportBodySourceFile(props: FlowCoverageSourceFileRe

let meterBar;

/* eslint-disable camelcase */
if (props.htmlTemplateOptions && props.htmlTemplateOptions.showMeterBar) {
meterBar = <FlowCoverageMeterBar percent={percent} threshold={threshold}/>;
meterBar = <FlowCoverageMeterBar percent={percent} threshold={threshold} thresholdUncovered={thresholdUncovered} uncoveredCount={uncovered_count}/>;
}
/* eslint-enable camelcase */

return (
<body>
Expand Down Expand Up @@ -117,6 +119,7 @@ export default function HTMLReportBodySourceFile(props: FlowCoverageSourceFileRe
isFlow: coverageData.isFlow,
percent,
threshold,
thresholdUncovered,
/* eslint-disable camelcase */
covered_count,
uncovered_count
Expand Down
10 changes: 9 additions & 1 deletion src/lib/components/body-coverage-summary.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default function HTMLReportBodySummary(props: FlowCoverageSummaryReportPr
flowCoverageStderr: fileSummary.flowCoverageStderr,
disableLink: false,
threshold: summary.threshold,
thresholdUncovered: summary.thresholdUncovered,
annotation: fileSummary.annotation,
percent: fileSummary.percent,
/* eslint-disable camelcase */
Expand All @@ -61,7 +62,14 @@ export default function HTMLReportBodySummary(props: FlowCoverageSummaryReportPr
let meterBar;

if (props.htmlTemplateOptions && props.htmlTemplateOptions.showMeterBar) {
meterBar = <FlowCoverageMeterBar percent={percent} threshold={summary.threshold}/>;
meterBar = (
<FlowCoverageMeterBar
percent={percent}
threshold={summary.threshold}
thresholdUncovered={summary.thresholdUncovered}
uncoveredCount={summary.uncovered_count}
/>
);
}

return (
Expand Down
13 changes: 11 additions & 2 deletions src/lib/components/coverage-file-table-row.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default function FlowCoverageFileTableRow(
percent: number,
disableLink: boolean,
threshold: number,
thresholdUncovered: number,
isError: boolean,
isFlow: boolean,
flowCoverageError: ?string,
Expand All @@ -37,10 +38,18 @@ export default function FlowCoverageFileTableRow(
isError,
isFlow,
disableLink,
threshold
threshold,
thresholdUncovered
} = props;

const aboveThreshold = percent >= threshold;
let aboveThreshold;

if (thresholdUncovered) {
aboveThreshold = uncovered_count <= thresholdUncovered;
} else {
aboveThreshold = percent >= threshold;
}

let className = (!isError && isFlow && aboveThreshold) ?
'positive' : 'negative';

Expand Down
Loading