Skip to content
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
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ module.exports = {
functions: 0,
lines: 0,
statements: 0
},
'./src/**/*.module.ts': { // coverage key with pattern
branches: 50, // or your current numbers for the patterned threshold key
functions: 50,
lines: 50,
statements: 50
}
}
}
Expand All @@ -66,9 +72,17 @@ Options:
-c, --config <path> path to a Jest config file (default: 'jest.config.js')
-m, --margin <margin> minimum threshold increase (default: 0)
-t, --tolerance <tolerance> threshold difference from actual coverage
-k, --thresholdKeys <keys> comma-separated list of threshold keys to consider (default: 'global')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jest calls these "paths", I think we should do the same for consistency. Also, we should probably use a variadic option:

Suggested change
-k, --thresholdKeys <keys> comma-separated list of threshold keys to consider (default: 'global')
-p, --threshold-path <paths...> comma-separated list of threshold keys to consider (default: 'global')

-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
```

jest-it-up only considers the `global` threshold key by default. To update custom threshold keys, you can use the `--thresholdKeys` option when running the script. For example, to update the `global` and `./src/**/*.module.ts` threshold keys, you can run:

```console
$ jest-it-up --thresholdKeys global,"./src/**/*.module.ts"
```
This will update the specified threshold keys (global and custom) and leave others unchanged.
5 changes: 5 additions & 0 deletions bin/jest-it-up
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ program
parseFloat,
0,
)
.option(
'-k, --threshold-keys <keys>',
`comma-separated list of threshold keys to consider (default: 'global')`,
'global',
)
.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')
Expand Down
79 changes: 60 additions & 19 deletions lib/__tests__/getChanges.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ require('ansi-colors').enabled = false

const getChanges = require('../getChanges')

console.warn = jest.fn()
const configPath = './jest.config.js'
const getContents = (
level1 = 'coverageThreshold',
Expand All @@ -18,38 +19,33 @@ const getContents = (
},
}`
const getNewThresholds = (
level2 = 'global',
newThresholds = {
branches: { diff: 70, next: 80, prev: 10 },
functions: { diff: 50, next: 70, prev: 20 },
lines: { diff: 30, next: 60, prev: 30 },
statements: { diff: 10, next: 50, prev: 40 },
},
) => newThresholds
) => ({ [level2]: newThresholds })

jest.mock('fs')

// Mock console.warn
jest.spyOn(console, 'warn').mockImplementation(() => {})
beforeEach(() => {
console.warn.mockReset()
})

it('returns the original contents and no changes if no new thresholds', () => {
const contents = getContents()
const newThresholds = getNewThresholds({})
const newThresholds = getNewThresholds('global', {})

fs.readFileSync.mockReturnValue(contents)
const { changes, data } = getChanges(configPath, newThresholds)

expect(fs.readFileSync).toHaveBeenCalledTimes(1)
expect(fs.readFileSync).toHaveBeenCalledWith(configPath, 'utf8')
expect(changes).toStrictEqual([])
expect(data).toMatchInlineSnapshot(`
"module.exports = {
coverageThreshold: {
global: {
branches: 10,
functions: 20,
lines: 30,
statements: 40,
},
},
}"
`)
expect(data).toBe(contents)
})

Expand All @@ -61,10 +57,10 @@ it('returns the new contents and changes if new thresholds', () => {
const { changes, data } = getChanges(configPath, newThresholds)

expect(changes).toStrictEqual([
'branches 10 → 80 +70',
'functions 20 → 70 +50',
'lines 30 → 60 +30',
'statements 40 → 50 +10',
'global branches 10 → 80 +70',
'global functions 20 → 70 +50',
'global lines 30 → 60 +30',
'global statements 40 → 50 +10',
])
expect(data).toMatchInlineSnapshot(`
"module.exports = {
Expand All @@ -89,7 +85,12 @@ it.each([
'returns the original contents and no changes if no matches #%#',
(level1, level2) => {
const contents = getContents(level1, level2)
const newThresholds = getNewThresholds()
const newThresholds = getNewThresholds(level2, {
branches: { diff: 0, next: 10, prev: 10 },
functions: { diff: 0, next: 20, prev: 20 },
lines: { diff: 0, next: 30, prev: 30 },
statements: { diff: 0, next: 40, prev: 40 },
})

fs.readFileSync.mockReturnValueOnce(contents)
const { changes, data } = getChanges(configPath, newThresholds)
Expand All @@ -98,3 +99,43 @@ it.each([
expect(data).toBe(contents)
},
)

it('returns changes for an updated custom threshold', () => {
fs.readFileSync.mockReturnValue(`
module.exports = {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use the getContents helper with level2 = './src/modules/**/*.module.ts' to generate this mock data.

coverageThreshold: {
global: {
branches: 0,
functions: 0,
lines: 0,
statements: 0,
},
'./src/modules/**/*.module.ts': {
branches: 50,
functions: 60,
lines: 70,
statements: 80,
},
},
}
`)

const changes = getChanges('./jest.config.js', {
'./src/modules/**/*.module.ts': {
branches: { prev: 50, next: 55, diff: 5 },
functions: { prev: 60, next: 65, diff: 5 },
lines: { prev: 70, next: 75, diff: 5 },
statements: { prev: 80, next: 85, diff: 5 },
},
})

expect(changes).toEqual({
data: expect.any(String),
changes: [
'./src/modules/**/*.module.ts branches 50 → 55 +5',
'./src/modules/**/*.module.ts functions 60 → 65 +5',
'./src/modules/**/*.module.ts lines 70 → 75 +5',
'./src/modules/**/*.module.ts statements 80 → 85 +5',
],
})
})
89 changes: 74 additions & 15 deletions lib/__tests__/getData.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ it('returns parsed config and report contents', async () => {
virtual: true,
})

const data = await getData(configPath)
const data = await getData(configPath, ['global'])

expect(fs.readFileSync).toHaveBeenCalledTimes(1)
expect(fs.readFileSync).toHaveBeenCalledWith(
Expand All @@ -49,10 +49,12 @@ it('returns parsed config and report contents', async () => {
statements: { pct: 50 },
},
thresholds: {
branches: 10,
functions: 20,
lines: 30,
statements: 40,
global: {
branches: 10,
functions: 20,
lines: 30,
statements: 40,
},
},
})
})
Expand All @@ -62,7 +64,7 @@ it('returns parsed async config and report contents', async () => {
virtual: true,
})

const data = await getData(configPath)
const data = await getData(configPath, ['global'])

expect(fs.readFileSync).toHaveBeenCalledTimes(1)
expect(fs.readFileSync).toHaveBeenCalledWith(
Expand All @@ -77,10 +79,12 @@ it('returns parsed async config and report contents', async () => {
statements: { pct: 50 },
},
thresholds: {
branches: 10,
functions: 20,
lines: 30,
statements: 40,
global: {
branches: 10,
functions: 20,
lines: 30,
statements: 40,
},
},
})
})
Expand All @@ -95,7 +99,7 @@ it('returns parsed config and report contents when a custom coverage directory i
{ virtual: true },
)

const data = await getData(configPath)
const data = await getData(configPath, ['global'])

expect(fs.readFileSync).toHaveBeenCalledTimes(1)
expect(fs.readFileSync).toHaveBeenCalledWith(
Expand All @@ -110,10 +114,65 @@ it('returns parsed config and report contents when a custom coverage directory i
statements: { pct: 50 },
},
thresholds: {
branches: 10,
functions: 20,
lines: 30,
statements: 40,
global: {
branches: 10,
functions: 20,
lines: 30,
statements: 40,
},
},
})
})

it('returns all threshold objects when no thresholdKeys parameter is provided', async () => {
jest.mock('../jest.config.js', () => ({ coverageThreshold }), {
virtual: true,
})

const data = await getData(configPath)

expect(fs.readFileSync).toHaveBeenCalledTimes(1)
expect(fs.readFileSync).toHaveBeenCalledWith(
'/workingDir/coverage/coverage-summary.json',
'utf8',
)
expect(data).toStrictEqual({
coverages: {
branches: { pct: 80 },
functions: { pct: 70 },
lines: { pct: 60 },
statements: { pct: 50 },
},
thresholds: {
global: {
branches: 10,
functions: 20,
lines: 30,
statements: 40,
},
},
})
})

it('returns an empty thresholds object when an empty thresholdKeys array is provided', async () => {
jest.mock('../jest.config.js', () => ({ coverageThreshold }), {
virtual: true,
})

const data = await getData(configPath, [])

expect(fs.readFileSync).toHaveBeenCalledTimes(1)
expect(fs.readFileSync).toHaveBeenCalledWith(
'/workingDir/coverage/coverage-summary.json',
'utf8',
)
expect(data).toStrictEqual({
coverages: {
branches: { pct: 80 },
functions: { pct: 70 },
lines: { pct: 60 },
statements: { pct: 50 },
},
thresholds: {},
})
})
Loading