diff --git a/README.md b/README.md index 65a94fe..aa15aac 100644 --- a/README.md +++ b/README.md @@ -63,11 +63,12 @@ $ jest-it-up --help Usage: jest-it-up [options] Options: - -c, --config path to a Jest config file (default: 'jest.config.js') - -m, --margin minimum threshold increase (default: 0) - -i, --interactive ask for confirmation before applying changes - -s, --silent do not output messages - -d, --dry-run process but do not change files - -v, --version output the version number - -h, --help display help for command + -c, --config path to a Jest config file (default: 'jest.config.js') + -m, --margin minimum threshold increase (default: 0) + -t, --tolerance threshold difference from actual coverage + -i, --interactive ask for confirmation before applying changes + -s, --silent do not output messages + -d, --dry-run process but do not change files + -v, --version output the version number + -h, --help display help for command ``` diff --git a/bin/jest-it-up b/bin/jest-it-up index 8197f7a..fef76ed 100755 --- a/bin/jest-it-up +++ b/bin/jest-it-up @@ -7,6 +7,12 @@ const jestItUp = require('../lib') program .option('-c, --config ', 'path to a Jest config file', 'jest.config.js') .option('-m, --margin ', 'minimum threshold increase', parseFloat, 0) + .option( + '-t, --tolerance ', + 'threshold difference from actual coverage', + parseFloat, + 0, + ) .option('-i, --interactive', 'ask for confirmation before applying changes') .option('-s, --silent', 'do not output messages') .option('-d, --dry-run', 'process but do not change files') diff --git a/lib/__tests__/getNewThresholds.test.js b/lib/__tests__/getNewThresholds.test.js index 1b32c32..21ce790 100644 --- a/lib/__tests__/getNewThresholds.test.js +++ b/lib/__tests__/getNewThresholds.test.js @@ -20,8 +20,14 @@ it('returns new thresholds if coverages are higher', () => { statements: { pct: 50 }, } const margin = 0 + const tolerance = 0 - const newThresholds = getNewThresholds(thresholds, coverages, margin) + const newThresholds = getNewThresholds( + thresholds, + coverages, + margin, + tolerance, + ) expect(newThresholds).toStrictEqual({ branches: { diff: 70, next: 80, prev: 10 }, @@ -45,11 +51,74 @@ it('only returns new thresholds if coverages are above the margin', () => { statements: { pct: 50 }, } const margin = 50 + const tolerance = 0 - const newThresholds = getNewThresholds(thresholds, coverages, margin) + const newThresholds = getNewThresholds( + thresholds, + coverages, + margin, + tolerance, + ) expect(newThresholds).toStrictEqual({ branches: { diff: 70, next: 80, prev: 10 }, functions: { diff: 50, next: 70, prev: 20 }, }) }) + +it('should return new thresholds if coverage - tolerance is higher than the current threshold', () => { + const thresholds = { + branches: 10, + functions: 20, + lines: 30, + statements: 40, + } + const coverages = { + branches: { pct: 80 }, + functions: { pct: 70 }, + lines: { pct: 60 }, + statements: { pct: 50 }, + } + const margin = 0 + const tolerance = 10 + + const newThresholds = getNewThresholds( + thresholds, + coverages, + margin, + tolerance, + ) + + expect(newThresholds).toStrictEqual({ + branches: { diff: 60, next: 70, prev: 10 }, + functions: { diff: 40, next: 60, prev: 20 }, + lines: { diff: 20, next: 50, prev: 30 }, + statements: { diff: 0, next: 40, prev: 40 }, + }) +}) + +it('should not return new thresholds if coverage - tolerance is lower than the current threshold', () => { + const thresholds = { + branches: 10, + functions: 20, + lines: 30, + statements: 40, + } + const coverages = { + branches: { pct: 80 }, + functions: { pct: 70 }, + lines: { pct: 60 }, + statements: { pct: 50 }, + } + const margin = 0 + const tolerance = 100 + + const newThresholds = getNewThresholds( + thresholds, + coverages, + margin, + tolerance, + ) + + expect(newThresholds).toStrictEqual({}) +}) diff --git a/lib/__tests__/index.test.js b/lib/__tests__/index.test.js index 68b0e5d..09cd5aa 100644 --- a/lib/__tests__/index.test.js +++ b/lib/__tests__/index.test.js @@ -34,7 +34,7 @@ it('runs with with default options', async () => { expect(getData).toHaveBeenCalledWith('/workingDir/jest.config.js') expect(getNewThresholds).toHaveBeenCalledTimes(1) - expect(getNewThresholds).toHaveBeenCalledWith('thresholds', 'coverages', 0) + expect(getNewThresholds).toHaveBeenCalledWith('thresholds', 'coverages', 0, 0) expect(getChanges).toHaveBeenCalledTimes(1) expect(getChanges).toHaveBeenCalledWith( @@ -71,7 +71,12 @@ it('runs with custom margin', async () => { await jestItUp({ margin: 10 }) expect(getNewThresholds).toHaveBeenCalledTimes(1) - expect(getNewThresholds).toHaveBeenCalledWith('thresholds', 'coverages', 10) + expect(getNewThresholds).toHaveBeenCalledWith( + 'thresholds', + 'coverages', + 10, + 0, + ) }) it.each([true, false])( @@ -124,3 +129,15 @@ it('runs with custom config', async () => { expect(getData).toHaveBeenCalledTimes(1) expect(getData).toHaveBeenCalledWith('/workingDir/customDir/jest.config.js') }) + +it('runs with custom tolerance', async () => { + await jestItUp({ tolerance: 10 }) + + expect(getNewThresholds).toHaveBeenCalledTimes(1) + expect(getNewThresholds).toHaveBeenCalledWith( + 'thresholds', + 'coverages', + 0, + 10, + ) +}) diff --git a/lib/getNewThresholds.js b/lib/getNewThresholds.js index 279452d..a0be152 100644 --- a/lib/getNewThresholds.js +++ b/lib/getNewThresholds.js @@ -1,14 +1,16 @@ -const getNewThresholds = (thresholds, coverages, margin) => +const getNewThresholds = (thresholds, coverages, margin, tolerance) => Object.entries(thresholds).reduce((acc, [type, threshold]) => { const { pct: coverage } = coverages[type] + const desiredCoverage = coverage - tolerance + // Only update threshold if new coverage is higher than // current threshold + margin - if (coverage >= threshold + margin) { + if (desiredCoverage >= threshold + margin) { acc[type] = { prev: threshold, - next: coverage, - diff: +(coverage - threshold).toFixed(2), + next: desiredCoverage, + diff: +(desiredCoverage - threshold).toFixed(2), } } diff --git a/lib/index.js b/lib/index.js index 4b1b003..1cd1417 100644 --- a/lib/index.js +++ b/lib/index.js @@ -14,12 +14,18 @@ module.exports = async ({ dryRun = false, interactive = false, margin = 0, + tolerance = 0, silent = false, } = {}) => { const configPath = path.resolve(process.cwd(), config) const { thresholds, coverages } = await getData(configPath) - const newThresholds = getNewThresholds(thresholds, coverages, margin) + const newThresholds = getNewThresholds( + thresholds, + coverages, + margin, + tolerance, + ) const { changes, data } = getChanges(configPath, newThresholds) if (!silent) {