/
searchConfigs.spec.js
139 lines (104 loc) Β· 4.65 KB
/
searchConfigs.spec.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import path from 'path'
import { fileURLToPath } from 'url'
import { jest } from '@jest/globals'
import { normalizePath } from '../../lib/normalizePath.js'
jest.unstable_mockModule('../../lib/resolveConfig.js', () => ({
/** Unfortunately necessary due to non-ESM tests. */
resolveConfig: (configPath) => {
try {
return require.resolve(configPath)
} catch {
return configPath
}
},
}))
jest.unstable_mockModule('../../lib/execGit.js', () => ({
execGit: jest.fn(async () => {
/** Mock fails by default */
return ''
}),
}))
jest.unstable_mockModule('../../lib/loadConfig.js', () => ({
loadConfig: jest.fn(async () => {
/** Mock fails by default */
return {}
}),
}))
const { execGit } = await import('../../lib/execGit.js')
const { loadConfig } = await import('../../lib/loadConfig.js')
const { searchConfigs } = await import('../../lib/searchConfigs.js')
const __dirname = path.dirname(fileURLToPath(import.meta.url))
describe('searchConfigs', () => {
afterEach(() => {
jest.clearAllMocks()
})
it('should throw for invalid config object', async () => {
await expect(searchConfigs({ configObject: {} })).rejects.toThrowError()
})
it('should return config for valid config object', async () => {
await expect(searchConfigs({ configObject: { '*.js': 'eslint' } })).resolves.toEqual({
'': { '*.js': 'eslint' },
})
})
it('should return empty object for invalid config path', async () => {
await expect(
searchConfigs({ configPath: path.join(__dirname, 'missing.json') })
).resolves.toEqual({})
})
it('should return config for valid config path', async () => {
const configPath = '.lintstagedrc.json'
const config = { '*.js': 'eslint' }
loadConfig.mockReturnValueOnce({ config, configPath })
await expect(searchConfigs({ configPath })).resolves.toEqual({
[configPath]: config,
})
})
it('should return empty object when no config files found', async () => {
await expect(searchConfigs({})).resolves.toEqual({})
})
it('should return empty object when no valid config files found', async () => {
execGit.mockResolvedValueOnce(`.lintstagedrc.json\u0000`)
await expect(searchConfigs({})).resolves.toEqual({})
})
it('should return config found from git', async () => {
const configFile = '.lintstagedrc.json'
const configPath = normalizePath(path.join(process.cwd(), configFile))
const config = { '*.js': 'eslint' }
execGit.mockResolvedValueOnce(`${configFile}\u0000`)
loadConfig.mockResolvedValueOnce({ config, filepath: configPath })
await expect(searchConfigs({})).resolves.toEqual({ [configPath]: config })
})
it('should return auto-discovered config from cwd when not found from git', async () => {
const configPath = normalizePath(path.join(process.cwd(), '.lintstagedrc.json'))
const config = { '*.js': 'eslint' }
loadConfig.mockResolvedValueOnce({ config, filepath: configPath })
await expect(searchConfigs({})).resolves.toEqual({ [configPath]: config })
})
it('should sort configs so that deepest is first', async () => {
const config = { '*.js': 'eslint' }
execGit.mockResolvedValueOnce(
`H .lintstagedrc.json\u0000H even/deeper/.lintstagedrc.json\u0000H deeper/.lintstagedrc.json\u0000`
)
const topLevelConfig = normalizePath(path.join(process.cwd(), '.lintstagedrc.json'))
const deeperConfig = normalizePath(path.join(process.cwd(), 'deeper/.lintstagedrc.json'))
const evenDeeperConfig = normalizePath(
path.join(process.cwd(), 'even/deeper/.lintstagedrc.json')
)
loadConfig.mockResolvedValueOnce({ config, filepath: topLevelConfig })
loadConfig.mockResolvedValueOnce({ config, filepath: deeperConfig })
loadConfig.mockResolvedValueOnce({ config, filepath: evenDeeperConfig })
const configs = await searchConfigs({})
expect(Object.keys(configs)).toEqual([evenDeeperConfig, deeperConfig, topLevelConfig])
})
it('should ignore config files skipped from the worktree (sparse checkout)', async () => {
const config = { '*.js': 'eslint' }
execGit.mockResolvedValueOnce(`H .lintstagedrc.json\u0000S skipped/.lintstagedrc.json\u0000`)
const topLevelConfig = normalizePath(path.join(process.cwd(), '.lintstagedrc.json'))
const skippedConfig = normalizePath(path.join(process.cwd(), 'skipped/.lintstagedrc.json'))
loadConfig.mockResolvedValueOnce({ config, filepath: topLevelConfig })
// Mock will return config for skipped file, but it should not be read
loadConfig.mockResolvedValueOnce({ config, filepath: skippedConfig })
const configs = await searchConfigs({})
expect(Object.keys(configs)).toEqual([topLevelConfig])
})
})