lfify 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/cd.yml +4 -2
- package/.github/workflows/ci.yml +26 -26
- package/.lfifyrc-sample.json +2 -1
- package/.prettierignore +5 -0
- package/.prettierrc +9 -0
- package/.vscode/extensions.json +3 -0
- package/.vscode/launch.json +2 -4
- package/.vscode/settings.json +16 -0
- package/CHANGELOG.md +29 -0
- package/README.md +8 -6
- package/__fixtures__/already-lf/src/file.js +1 -0
- package/__fixtures__/cli-override/.lfifyrc.json +6 -0
- package/__fixtures__/cli-override/src/a.js +1 -0
- package/__fixtures__/cli-override/src/b.txt +1 -0
- package/__fixtures__/default-sensible/_git/config +2 -0
- package/__fixtures__/default-sensible/_node_modules/pkg/index.js +1 -0
- package/__fixtures__/default-sensible/src/app.js +1 -0
- package/__fixtures__/default-sensible/src/readme.txt +2 -0
- package/__fixtures__/with-config/.lfifyrc.json +6 -0
- package/__fixtures__/with-config/doc.txt +1 -0
- package/__fixtures__/with-config/lib/main.js +1 -0
- package/__fixtures__/with-config/skip/other.js +1 -0
- package/__mocks__/path.js +1 -1
- package/eslint.config.mjs +7 -5
- package/index.cjs +157 -61
- package/index.e2e.test.js +140 -0
- package/index.test.js +169 -103
- package/package.json +13 -4
- package/__mocks__/fs.js +0 -56
- package/__mocks__/micromatch.js +0 -39
package/index.test.js
CHANGED
|
@@ -1,89 +1,92 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'
|
|
1
|
+
const mock = require('mock-fs');
|
|
2
|
+
const {
|
|
3
|
+
readConfig,
|
|
4
|
+
parseArgs,
|
|
5
|
+
processFile,
|
|
6
|
+
resolveConfig,
|
|
7
|
+
shouldProcessFile,
|
|
8
|
+
SENSIBLE_DEFAULTS,
|
|
9
|
+
} = require('./index.cjs');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
|
|
12
|
+
function baseMock(overrides = {}) {
|
|
13
|
+
return {
|
|
14
|
+
'src/file1.txt': 'hello\r\nworld\r\n',
|
|
15
|
+
'src/file2.js': 'console.log("test");\r\n',
|
|
16
|
+
'src/subdir/file3.txt': 'test\r\n',
|
|
17
|
+
'test/file1.txt': 'hello\r\nworld\r\n',
|
|
18
|
+
'test/file2.js': 'console.log("test");\r\n',
|
|
19
|
+
'test/subdir/file3.txt': 'test\r\n',
|
|
20
|
+
'node_modules/file.js': 'console.log("test");\r\n',
|
|
21
|
+
'node_modules/subdir/file4.txt': 'test\r\n',
|
|
22
|
+
'index.js': 'console.log("test");\r\n',
|
|
23
|
+
...overrides,
|
|
18
24
|
};
|
|
25
|
+
}
|
|
19
26
|
|
|
27
|
+
describe('CRLF to LF Converter', () => {
|
|
20
28
|
let originalArgv;
|
|
21
29
|
|
|
22
30
|
beforeEach(() => {
|
|
23
|
-
|
|
24
|
-
require('fs').__setMockFiles(MOCK_FILE_INFO);
|
|
31
|
+
mock(baseMock());
|
|
25
32
|
originalArgv = process.argv;
|
|
26
33
|
});
|
|
27
34
|
|
|
28
35
|
afterEach(() => {
|
|
36
|
+
mock.restore();
|
|
29
37
|
process.argv = originalArgv;
|
|
30
38
|
});
|
|
31
39
|
|
|
32
40
|
describe('readConfig', () => {
|
|
33
41
|
it('should return config when valid config file is provided', async () => {
|
|
34
|
-
// arrange
|
|
35
42
|
const validConfig = {
|
|
36
43
|
entry: './',
|
|
37
44
|
include: ['*.js'],
|
|
38
|
-
exclude: ['node_modules/**']
|
|
45
|
+
exclude: ['node_modules/**'],
|
|
39
46
|
};
|
|
40
|
-
|
|
47
|
+
mock(baseMock({ '.lfifyrc.json': JSON.stringify(validConfig) }));
|
|
41
48
|
|
|
42
|
-
// act
|
|
43
49
|
const config = await readConfig('.lfifyrc.json');
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
expect(config).toEqual(
|
|
52
|
+
expect.objectContaining({
|
|
53
|
+
entry: expect.any(String),
|
|
54
|
+
include: expect.any(Array),
|
|
55
|
+
exclude: expect.any(Array),
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
51
58
|
});
|
|
52
59
|
|
|
53
60
|
it('should throw error when config file is not found', async () => {
|
|
54
|
-
// act & assert
|
|
55
61
|
await expect(readConfig('.lfifyrc.json')).rejects.toThrow();
|
|
56
62
|
});
|
|
57
63
|
|
|
58
64
|
it('should throw error when config file is invalid json', async () => {
|
|
59
|
-
|
|
60
|
-
require('fs').__setConfig('invalid json');
|
|
65
|
+
mock(baseMock({ '.lfifyrc.json': 'invalid json' }));
|
|
61
66
|
|
|
62
|
-
// act & assert
|
|
63
67
|
await expect(readConfig('.lfifyrc.json')).rejects.toThrow();
|
|
64
68
|
});
|
|
65
69
|
});
|
|
66
70
|
|
|
67
71
|
describe('parseArgs', () => {
|
|
68
72
|
it('should return config path when --config option is provided', () => {
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
process.argv = [
|
|
74
|
+
'node',
|
|
75
|
+
'lfify',
|
|
76
|
+
'--config',
|
|
77
|
+
'./path/for/test/.lfifyrc.json',
|
|
78
|
+
];
|
|
71
79
|
|
|
72
|
-
// act
|
|
73
80
|
const options = parseArgs();
|
|
74
81
|
|
|
75
|
-
// assert
|
|
76
82
|
expect(options.configPath).toBe('./path/for/test/.lfifyrc.json');
|
|
77
83
|
});
|
|
78
84
|
|
|
79
85
|
it('should return default config path when --config option is not provided', () => {
|
|
80
|
-
// arrange
|
|
81
86
|
process.argv = ['node', 'lfify'];
|
|
82
87
|
|
|
83
|
-
// act
|
|
84
88
|
const options = parseArgs();
|
|
85
89
|
|
|
86
|
-
// assert
|
|
87
90
|
expect(options.configPath).toBe('.lfifyrc.json');
|
|
88
91
|
});
|
|
89
92
|
|
|
@@ -94,7 +97,14 @@ describe('CRLF to LF Converter', () => {
|
|
|
94
97
|
});
|
|
95
98
|
|
|
96
99
|
it('should return multiple include patterns when multiple --include options are provided', () => {
|
|
97
|
-
process.argv = [
|
|
100
|
+
process.argv = [
|
|
101
|
+
'node',
|
|
102
|
+
'lfify',
|
|
103
|
+
'--include',
|
|
104
|
+
'**/*.js',
|
|
105
|
+
'--include',
|
|
106
|
+
'**/*.ts',
|
|
107
|
+
];
|
|
98
108
|
const options = parseArgs();
|
|
99
109
|
expect(options.include).toEqual(['**/*.js', '**/*.ts']);
|
|
100
110
|
});
|
|
@@ -106,33 +116,45 @@ describe('CRLF to LF Converter', () => {
|
|
|
106
116
|
});
|
|
107
117
|
|
|
108
118
|
it('should return multiple exclude patterns when multiple --exclude options are provided', () => {
|
|
109
|
-
process.argv = [
|
|
119
|
+
process.argv = [
|
|
120
|
+
'node',
|
|
121
|
+
'lfify',
|
|
122
|
+
'--exclude',
|
|
123
|
+
'dist/**',
|
|
124
|
+
'--exclude',
|
|
125
|
+
'coverage/**',
|
|
126
|
+
];
|
|
110
127
|
const options = parseArgs();
|
|
111
|
-
expect(options.exclude).toEqual(['
|
|
128
|
+
expect(options.exclude).toEqual(['dist/**', 'coverage/**']);
|
|
112
129
|
});
|
|
113
130
|
|
|
114
131
|
it('should return entry path when --entry option is provided', () => {
|
|
115
132
|
process.argv = ['node', 'lfify', '--entry', './src'];
|
|
116
133
|
const options = parseArgs();
|
|
117
|
-
expect(options.entry).
|
|
134
|
+
expect(options.entry).toContain('src');
|
|
118
135
|
});
|
|
119
136
|
|
|
120
137
|
it('should handle all options together', () => {
|
|
121
138
|
process.argv = [
|
|
122
|
-
'node',
|
|
123
|
-
'
|
|
124
|
-
'--
|
|
125
|
-
'
|
|
126
|
-
'--
|
|
127
|
-
'
|
|
139
|
+
'node',
|
|
140
|
+
'lfify',
|
|
141
|
+
'--config',
|
|
142
|
+
'custom.json',
|
|
143
|
+
'--include',
|
|
144
|
+
'*.js',
|
|
145
|
+
'--exclude',
|
|
146
|
+
'dist/**',
|
|
147
|
+
'--entry',
|
|
148
|
+
'./lib',
|
|
149
|
+
'--log-level',
|
|
150
|
+
'info',
|
|
128
151
|
];
|
|
129
152
|
const options = parseArgs();
|
|
130
|
-
expect(options).
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
});
|
|
153
|
+
expect(options.configPath).toBe('custom.json');
|
|
154
|
+
expect(options.include).toEqual(['*.js']);
|
|
155
|
+
expect(options.exclude).toEqual(['dist/**']);
|
|
156
|
+
expect(options.entry).toContain('lib');
|
|
157
|
+
expect(options.logLevel).toBe('info');
|
|
136
158
|
});
|
|
137
159
|
|
|
138
160
|
it('should return undefined for include/exclude/entry when not provided', () => {
|
|
@@ -142,77 +164,76 @@ describe('CRLF to LF Converter', () => {
|
|
|
142
164
|
expect(options.exclude).toBeUndefined();
|
|
143
165
|
expect(options.entry).toBeUndefined();
|
|
144
166
|
});
|
|
167
|
+
|
|
168
|
+
it('should return logLevel when --log-level option is provided', () => {
|
|
169
|
+
process.argv = ['node', 'lfify', '--log-level', 'warn'];
|
|
170
|
+
const options = parseArgs();
|
|
171
|
+
expect(options.logLevel).toBe('warn');
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should accept error, warn, info for --log-level', () => {
|
|
175
|
+
for (const level of ['error', 'warn', 'info']) {
|
|
176
|
+
process.argv = ['node', 'lfify', '--log-level', level];
|
|
177
|
+
expect(parseArgs().logLevel).toBe(level);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
145
180
|
});
|
|
146
181
|
|
|
147
182
|
describe('shouldProcessFile', () => {
|
|
148
183
|
it('should return true when file matches include pattern and does not match exclude pattern', () => {
|
|
149
|
-
const config = {
|
|
150
|
-
|
|
151
|
-
exclude: ['node_modules/**']
|
|
152
|
-
};
|
|
153
|
-
expect(shouldProcessFile('src/file.js', config)).toBe(true);
|
|
184
|
+
const config = { include: ['**/*.js'], exclude: ['node_modules/**'] };
|
|
185
|
+
expect(shouldProcessFile('src/app.js', config)).toBe(true);
|
|
154
186
|
});
|
|
155
187
|
|
|
156
188
|
it('should return false when file matches exclude pattern', () => {
|
|
157
|
-
const config = {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
expect(shouldProcessFile('node_modules/package/index.js', config)).toBe(false);
|
|
189
|
+
const config = { include: ['**/*.js'], exclude: ['node_modules/**'] };
|
|
190
|
+
expect(shouldProcessFile('node_modules/pkg/index.js', config)).toBe(
|
|
191
|
+
false,
|
|
192
|
+
);
|
|
162
193
|
});
|
|
163
194
|
|
|
164
195
|
it('should return false when file does not match include pattern', () => {
|
|
165
|
-
const config = {
|
|
166
|
-
|
|
167
|
-
exclude: ['node_modules/**']
|
|
168
|
-
};
|
|
169
|
-
expect(shouldProcessFile('src/file.txt', config)).toBe(false);
|
|
196
|
+
const config = { include: ['**/*.js'], exclude: ['node_modules/**'] };
|
|
197
|
+
expect(shouldProcessFile('src/readme.txt', config)).toBe(false);
|
|
170
198
|
});
|
|
171
199
|
|
|
172
200
|
it('should handle multiple include patterns', () => {
|
|
173
201
|
const config = {
|
|
174
202
|
include: ['**/*.js', '**/*.ts'],
|
|
175
|
-
exclude: []
|
|
203
|
+
exclude: ['node_modules/**'],
|
|
176
204
|
};
|
|
177
|
-
expect(shouldProcessFile('src/
|
|
178
|
-
expect(shouldProcessFile('src/
|
|
179
|
-
expect(shouldProcessFile('src/file.txt', config)).toBe(false);
|
|
205
|
+
expect(shouldProcessFile('src/app.js', config)).toBe(true);
|
|
206
|
+
expect(shouldProcessFile('src/app.ts', config)).toBe(true);
|
|
180
207
|
});
|
|
181
208
|
|
|
182
209
|
it('should handle multiple exclude patterns', () => {
|
|
183
210
|
const config = {
|
|
184
211
|
include: ['**/*.js'],
|
|
185
|
-
exclude: ['node_modules/**', 'dist/**', '
|
|
212
|
+
exclude: ['node_modules/**', 'dist/**', 'build/**', 'coverage/**'],
|
|
186
213
|
};
|
|
187
214
|
expect(shouldProcessFile('src/file.js', config)).toBe(true);
|
|
188
|
-
expect(shouldProcessFile('node_modules/pkg/
|
|
215
|
+
expect(shouldProcessFile('node_modules/pkg/file.js', config)).toBe(false);
|
|
189
216
|
expect(shouldProcessFile('dist/bundle.js', config)).toBe(false);
|
|
190
|
-
expect(shouldProcessFile('test/unit.js', config)).toBe(
|
|
217
|
+
expect(shouldProcessFile('test/unit.js', config)).toBe(true);
|
|
191
218
|
});
|
|
192
219
|
});
|
|
193
220
|
|
|
194
221
|
describe('processFile', () => {
|
|
195
222
|
it('should convert CRLF to LF when file is processed', async () => {
|
|
196
|
-
// arrange
|
|
197
223
|
const shouldbe = 'hello\nworld\n';
|
|
198
224
|
|
|
199
|
-
// act
|
|
200
225
|
await processFile('./src/file1.txt');
|
|
201
|
-
const content = await
|
|
226
|
+
const content = await fs.promises.readFile('./src/file1.txt', 'utf8');
|
|
202
227
|
|
|
203
|
-
// assert
|
|
204
228
|
expect(content).toBe(shouldbe);
|
|
205
229
|
});
|
|
206
230
|
|
|
207
231
|
it('should not modify file when no CRLF exists', async () => {
|
|
208
|
-
|
|
209
|
-
require('fs').__setMockFiles({ './src/clean.txt': 'hello\nworld\n' });
|
|
232
|
+
mock(baseMock({ 'src/clean.txt': 'hello\nworld\n' }));
|
|
210
233
|
|
|
211
|
-
// act
|
|
212
234
|
await processFile('./src/clean.txt');
|
|
213
|
-
const content = await
|
|
235
|
+
const content = await fs.promises.readFile('./src/clean.txt', 'utf8');
|
|
214
236
|
|
|
215
|
-
// assert
|
|
216
237
|
expect(content).toBe('hello\nworld\n');
|
|
217
238
|
});
|
|
218
239
|
});
|
|
@@ -222,7 +243,7 @@ describe('CRLF to LF Converter', () => {
|
|
|
222
243
|
const options = {
|
|
223
244
|
include: ['**/*.js'],
|
|
224
245
|
exclude: ['node_modules/**'],
|
|
225
|
-
entry: './src'
|
|
246
|
+
entry: './src',
|
|
226
247
|
};
|
|
227
248
|
const config = await resolveConfig(options);
|
|
228
249
|
|
|
@@ -239,28 +260,36 @@ describe('CRLF to LF Converter', () => {
|
|
|
239
260
|
});
|
|
240
261
|
|
|
241
262
|
it('should override config file values with CLI options', async () => {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
263
|
+
mock(
|
|
264
|
+
baseMock({
|
|
265
|
+
'.lfifyrc.json': JSON.stringify({
|
|
266
|
+
entry: './',
|
|
267
|
+
include: ['**/*.md'],
|
|
268
|
+
exclude: ['dist/**'],
|
|
269
|
+
}),
|
|
270
|
+
}),
|
|
271
|
+
);
|
|
247
272
|
|
|
248
273
|
const options = {
|
|
249
274
|
configPath: '.lfifyrc.json',
|
|
250
|
-
include: ['**/*.js']
|
|
275
|
+
include: ['**/*.js'],
|
|
251
276
|
};
|
|
252
277
|
const config = await resolveConfig(options);
|
|
253
278
|
|
|
254
|
-
expect(config.include).toEqual(['**/*.js']);
|
|
255
|
-
expect(config.exclude).toEqual(['dist/**']);
|
|
279
|
+
expect(config.include).toEqual(['**/*.js']);
|
|
280
|
+
expect(config.exclude).toEqual(['dist/**']);
|
|
256
281
|
});
|
|
257
282
|
|
|
258
283
|
it('should load config file when configPath is provided and file exists', async () => {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
284
|
+
mock(
|
|
285
|
+
baseMock({
|
|
286
|
+
'.lfifyrc.json': JSON.stringify({
|
|
287
|
+
entry: './lib',
|
|
288
|
+
include: ['**/*.ts'],
|
|
289
|
+
exclude: ['test/**'],
|
|
290
|
+
}),
|
|
291
|
+
}),
|
|
292
|
+
);
|
|
264
293
|
|
|
265
294
|
const options = { configPath: '.lfifyrc.json' };
|
|
266
295
|
const config = await resolveConfig(options);
|
|
@@ -270,7 +299,6 @@ describe('CRLF to LF Converter', () => {
|
|
|
270
299
|
});
|
|
271
300
|
|
|
272
301
|
it('should use defaults when config file not found and no CLI options', async () => {
|
|
273
|
-
// No config file set up - mock will throw ENOENT
|
|
274
302
|
const options = { configPath: 'nonexistent.json' };
|
|
275
303
|
const config = await resolveConfig(options);
|
|
276
304
|
|
|
@@ -293,5 +321,43 @@ describe('CRLF to LF Converter', () => {
|
|
|
293
321
|
expect(config.include).toEqual(SENSIBLE_DEFAULTS.include);
|
|
294
322
|
expect(config.exclude).toEqual(['custom/**']);
|
|
295
323
|
});
|
|
324
|
+
|
|
325
|
+
it('should include logLevel in config, defaulting to error', async () => {
|
|
326
|
+
const config = await resolveConfig({});
|
|
327
|
+
expect(config.logLevel).toBe('error');
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it('should use logLevel from config file when provided', async () => {
|
|
331
|
+
mock(
|
|
332
|
+
baseMock({
|
|
333
|
+
'.lfifyrc.json': JSON.stringify({
|
|
334
|
+
entry: './',
|
|
335
|
+
include: ['**/*.js'],
|
|
336
|
+
exclude: ['node_modules/**'],
|
|
337
|
+
logLevel: 'info',
|
|
338
|
+
}),
|
|
339
|
+
}),
|
|
340
|
+
);
|
|
341
|
+
const config = await resolveConfig({ configPath: '.lfifyrc.json' });
|
|
342
|
+
expect(config.logLevel).toBe('info');
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('should override config file logLevel with CLI --log-level', async () => {
|
|
346
|
+
mock(
|
|
347
|
+
baseMock({
|
|
348
|
+
'.lfifyrc.json': JSON.stringify({
|
|
349
|
+
entry: './',
|
|
350
|
+
include: ['**/*.js'],
|
|
351
|
+
exclude: ['node_modules/**'],
|
|
352
|
+
logLevel: 'warn',
|
|
353
|
+
}),
|
|
354
|
+
}),
|
|
355
|
+
);
|
|
356
|
+
const config = await resolveConfig({
|
|
357
|
+
configPath: '.lfifyrc.json',
|
|
358
|
+
logLevel: 'info',
|
|
359
|
+
});
|
|
360
|
+
expect(config.logLevel).toBe('info');
|
|
361
|
+
});
|
|
296
362
|
});
|
|
297
|
-
});
|
|
363
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lfify",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "make your crlf to lf",
|
|
6
6
|
"main": "index.cjs",
|
|
@@ -9,15 +9,20 @@
|
|
|
9
9
|
"lfify": "./index.cjs"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"test": "
|
|
13
|
-
"
|
|
12
|
+
"test": "npm run test:unit && npm run test:e2e",
|
|
13
|
+
"test:unit": "jest --testPathPattern=\"index\\.test\\.js\"",
|
|
14
|
+
"test:e2e": "jest --testPathPattern=\"index\\.e2e\\.test\\.js\"",
|
|
15
|
+
"lint": "eslint .",
|
|
16
|
+
"format": "prettier --write .",
|
|
17
|
+
"format:check": "prettier --check ."
|
|
14
18
|
},
|
|
15
19
|
"repository": {
|
|
16
20
|
"type": "git",
|
|
17
21
|
"url": "https://github.com/GyeongHoKim/lfify.git"
|
|
18
22
|
},
|
|
19
23
|
"publishConfig": {
|
|
20
|
-
"registry": "https://registry.npmjs.org",
|
|
24
|
+
"registry": "https://registry.npmjs.org/",
|
|
25
|
+
"provenance": true,
|
|
21
26
|
"tag": "latest"
|
|
22
27
|
},
|
|
23
28
|
"keywords": [
|
|
@@ -42,8 +47,12 @@
|
|
|
42
47
|
"@semantic-release/npm": "^13.1.3",
|
|
43
48
|
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
44
49
|
"eslint": "^9.15.0",
|
|
50
|
+
"eslint-config-prettier": "^10.1.8",
|
|
51
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
45
52
|
"globals": "^15.12.0",
|
|
46
53
|
"jest": "^29.7.0",
|
|
54
|
+
"mock-fs": "^5.5.0",
|
|
55
|
+
"prettier": "^3.8.1",
|
|
47
56
|
"semantic-release": "^25.0.2"
|
|
48
57
|
}
|
|
49
58
|
}
|
package/__mocks__/fs.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
const fs = jest.createMockFromModule('fs');
|
|
2
|
-
|
|
3
|
-
const mockFiles = new Map();
|
|
4
|
-
|
|
5
|
-
function __setMockFiles(newMockFiles) {
|
|
6
|
-
mockFiles.clear();
|
|
7
|
-
for (const [path, content] of Object.entries(newMockFiles)) {
|
|
8
|
-
mockFiles.set(path, content);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function __setConfig(stringifiedConfig, path = '.lfifyrc.json') {
|
|
13
|
-
mockFiles.set(path, stringifiedConfig);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const promises = {
|
|
17
|
-
/* eslint-disable-next-line no-unused-vars */
|
|
18
|
-
readFile: jest.fn().mockImplementation((path, ...rest) => {
|
|
19
|
-
if (mockFiles.has(path)) {
|
|
20
|
-
return Promise.resolve(mockFiles.get(path));
|
|
21
|
-
}
|
|
22
|
-
const error = new Error(`ENOENT: no such file or directory, open '${path}'`);
|
|
23
|
-
error.code = 'ENOENT';
|
|
24
|
-
return Promise.reject(error);
|
|
25
|
-
}),
|
|
26
|
-
|
|
27
|
-
writeFile: jest.fn().mockImplementation((path, content) => {
|
|
28
|
-
mockFiles.set(path, content);
|
|
29
|
-
return Promise.resolve();
|
|
30
|
-
}),
|
|
31
|
-
|
|
32
|
-
/* eslint-disable-next-line no-unused-vars */
|
|
33
|
-
readdir: jest.fn().mockImplementation((path, ...rest) => {
|
|
34
|
-
const entries = [];
|
|
35
|
-
for (const filePath of mockFiles.keys()) {
|
|
36
|
-
if (filePath.startsWith(path)) {
|
|
37
|
-
const relativePath = filePath.slice(path.length + 1);
|
|
38
|
-
const name = relativePath.split('/')[0];
|
|
39
|
-
if (name && !entries.some(e => e.name === name)) {
|
|
40
|
-
entries.push({
|
|
41
|
-
name,
|
|
42
|
-
isFile: () => !name.includes('/'),
|
|
43
|
-
isDirectory: () => name.includes('/')
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return Promise.resolve(entries);
|
|
49
|
-
})
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
fs.promises = promises;
|
|
53
|
-
fs.__setMockFiles = __setMockFiles;
|
|
54
|
-
fs.__setConfig = __setConfig;
|
|
55
|
-
|
|
56
|
-
module.exports = fs;
|
package/__mocks__/micromatch.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
const micromatch = jest.createMockFromModule('micromatch');
|
|
2
|
-
|
|
3
|
-
micromatch.isMatch = jest.fn().mockImplementation((filePath, patterns) => {
|
|
4
|
-
if (!Array.isArray(patterns)) {
|
|
5
|
-
patterns = [patterns];
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
// 간단한 glob 패턴 매칭 구현
|
|
9
|
-
return patterns.some(pattern => {
|
|
10
|
-
// 정확한 매칭
|
|
11
|
-
if (pattern === filePath) return true;
|
|
12
|
-
|
|
13
|
-
// glob 패턴을 정규식으로 변환
|
|
14
|
-
// 플레이스홀더를 사용해서 순서 문제 해결
|
|
15
|
-
const GLOBSTAR_SLASH = '___GLOBSTARSLASH___';
|
|
16
|
-
const GLOBSTAR = '___GLOBSTAR___';
|
|
17
|
-
|
|
18
|
-
let regexPattern = pattern
|
|
19
|
-
// **/ 패턴을 플레이스홀더로 임시 변환
|
|
20
|
-
.replace(/\*\*\//g, GLOBSTAR_SLASH)
|
|
21
|
-
// ** 패턴을 플레이스홀더로 임시 변환
|
|
22
|
-
.replace(/\*\*/g, GLOBSTAR)
|
|
23
|
-
// {a,b} 패턴
|
|
24
|
-
.replace(/\{([^}]+)\}/g, (_, group) => `(${group.split(',').join('|')})`)
|
|
25
|
-
// 특수문자 이스케이프 (*, ?, / 제외)
|
|
26
|
-
.replace(/[.+^$|()[\]\\]/g, '\\$&')
|
|
27
|
-
// * 패턴: 슬래시를 제외한 모든 것 매칭
|
|
28
|
-
.replace(/\*/g, '[^/]*')
|
|
29
|
-
// ? 패턴: 슬래시를 제외한 한 문자 매칭
|
|
30
|
-
.replace(/\?/g, '[^/]')
|
|
31
|
-
// 플레이스홀더를 실제 정규식으로 변환
|
|
32
|
-
.replace(new RegExp(GLOBSTAR_SLASH, 'g'), '(?:.*/)?')
|
|
33
|
-
.replace(new RegExp(GLOBSTAR, 'g'), '.*');
|
|
34
|
-
|
|
35
|
-
return new RegExp(`^${regexPattern}$`).test(filePath);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
module.exports = micromatch;
|