push-guardian 1.0.0
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/.dockerignore +15 -0
- package/.pushguardian-plugins.json +10 -0
- package/Dockerfile +41 -0
- package/Dockerfile.dev +20 -0
- package/README.md +386 -0
- package/TECHNO.md +139 -0
- package/babel.config.js +1 -0
- package/developper_utils.md +119 -0
- package/docker-compose.yml +41 -0
- package/docs/PLUGINS.md +223 -0
- package/docs/technical/architecture.md +298 -0
- package/docs/technical/performance-guide.md +390 -0
- package/docs/technical/plugin-persistence.md +169 -0
- package/docs/technical/plugins-guide.md +409 -0
- package/jest.config.js +22 -0
- package/package.json +53 -0
- package/plugins/example-plugin/index.js +55 -0
- package/plugins/example-plugin/plugin.json +8 -0
- package/scripts/coverage-report.js +75 -0
- package/src/cli/command/config.js +33 -0
- package/src/cli/command/install.js +137 -0
- package/src/cli/command/mirror.js +90 -0
- package/src/cli/command/performance.js +160 -0
- package/src/cli/command/plugin.js +171 -0
- package/src/cli/command/security.js +152 -0
- package/src/cli/command/shell.js +238 -0
- package/src/cli/command/validate.js +54 -0
- package/src/cli/index.js +23 -0
- package/src/cli/install/codeQualityTools.js +156 -0
- package/src/cli/install/hooks.js +89 -0
- package/src/cli/install/mirroring.js +299 -0
- package/src/core/codeQualityTools/configAnalyzer.js +216 -0
- package/src/core/codeQualityTools/configGenerator.js +381 -0
- package/src/core/codeQualityTools/configManager.js +65 -0
- package/src/core/codeQualityTools/fileDetector.js +62 -0
- package/src/core/codeQualityTools/languageTools.js +104 -0
- package/src/core/codeQualityTools/toolInstaller.js +53 -0
- package/src/core/configManager.js +43 -0
- package/src/core/errorCMD.js +9 -0
- package/src/core/interactiveMenu/interactiveMenu.js +73 -0
- package/src/core/mirroring/branchSynchronizer.js +59 -0
- package/src/core/mirroring/generate.js +114 -0
- package/src/core/mirroring/repoManager.js +112 -0
- package/src/core/mirroring/syncManager.js +176 -0
- package/src/core/module/env-loader.js +109 -0
- package/src/core/performance/metricsCollector.js +217 -0
- package/src/core/performance/performanceAnalyzer.js +182 -0
- package/src/core/plugins/basePlugin.js +89 -0
- package/src/core/plugins/pluginManager.js +123 -0
- package/src/core/plugins/pluginRegistry.js +215 -0
- package/src/core/validator.js +53 -0
- package/src/hooks/constrains/constrains.js +174 -0
- package/src/hooks/constrains/constraintEngine.js +140 -0
- package/src/utils/chalk-wrapper.js +26 -0
- package/src/utils/exec-wrapper.js +6 -0
- package/tests/fixtures/mock-eslint-config-array.js +8 -0
- package/tests/fixtures/mock-eslint-config-single.js +6 -0
- package/tests/fixtures/mockLoadedPlugin.js +11 -0
- package/tests/setup.js +28 -0
- package/tests/unit/basePlugin.test.js +355 -0
- package/tests/unit/branchSynchronizer.test.js +308 -0
- package/tests/unit/cli-commands.test.js +144 -0
- package/tests/unit/codeQualityConfigManager.test.js +233 -0
- package/tests/unit/codeQualityTools.test.js +36 -0
- package/tests/unit/command-install.test.js +247 -0
- package/tests/unit/command-mirror.test.js +179 -0
- package/tests/unit/command-performance.test.js +169 -0
- package/tests/unit/command-plugin.test.js +288 -0
- package/tests/unit/command-security.test.js +277 -0
- package/tests/unit/command-shell.test.js +325 -0
- package/tests/unit/configAnalyzer.test.js +593 -0
- package/tests/unit/configGenerator.test.js +808 -0
- package/tests/unit/configManager.test.js +195 -0
- package/tests/unit/constrains.test.js +463 -0
- package/tests/unit/constraint.test.js +554 -0
- package/tests/unit/env-loader.test.js +279 -0
- package/tests/unit/fileDetector.test.js +171 -0
- package/tests/unit/install-codeQualityTools.test.js +343 -0
- package/tests/unit/install-hooks.test.js +280 -0
- package/tests/unit/install-mirroring.test.js +731 -0
- package/tests/unit/install-modules.test.js +81 -0
- package/tests/unit/interactiveMenu.test.js +426 -0
- package/tests/unit/languageTools.test.js +244 -0
- package/tests/unit/metricsCollector.test.js +354 -0
- package/tests/unit/mirroring-generate.test.js +96 -0
- package/tests/unit/modules-exist.test.js +96 -0
- package/tests/unit/performanceAnalyzer.test.js +473 -0
- package/tests/unit/pluginManager.test.js +427 -0
- package/tests/unit/pluginRegistry.test.js +592 -0
- package/tests/unit/repoManager.test.js +469 -0
- package/tests/unit/reviewAppManager.test.js +5 -0
- package/tests/unit/security-command.test.js +43 -0
- package/tests/unit/syncManager.test.js +494 -0
- package/tests/unit/toolInstaller.test.js +240 -0
- package/tests/unit/utils.test.js +144 -0
- package/tests/unit/validator.test.js +215 -0
|
@@ -0,0 +1,808 @@
|
|
|
1
|
+
let fs = require('fs');
|
|
2
|
+
|
|
3
|
+
jest.mock('fs');
|
|
4
|
+
|
|
5
|
+
describe('Core codeQualityTools - configGenerator', () => {
|
|
6
|
+
let configGenerator;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
jest.clearAllMocks();
|
|
10
|
+
jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
11
|
+
jest.resetModules();
|
|
12
|
+
fs = require('fs');
|
|
13
|
+
|
|
14
|
+
fs.existsSync.mockReturnValue(false);
|
|
15
|
+
fs.readFileSync.mockReturnValue('');
|
|
16
|
+
fs.writeFileSync.mockImplementation(() => {});
|
|
17
|
+
|
|
18
|
+
configGenerator = require('../../src/core/codeQualityTools/configGenerator');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
console.log.mockRestore();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('shouldSkipConfigUpdate', () => {
|
|
26
|
+
test('doit retourner true si tous outils configurés', () => {
|
|
27
|
+
const selectedTools = ['JavaScript (ESLint)'];
|
|
28
|
+
const existingPlugins = new Set();
|
|
29
|
+
const existingFilesPatterns = new Set(['**/*.js']);
|
|
30
|
+
|
|
31
|
+
const result = configGenerator.shouldSkipConfigUpdate(
|
|
32
|
+
selectedTools,
|
|
33
|
+
existingPlugins,
|
|
34
|
+
existingFilesPatterns
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
expect(typeof result).toBe('boolean');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('doit retourner false si outils non configurés', () => {
|
|
41
|
+
const selectedTools = ['TypeScript (TypeScript ESLint)'];
|
|
42
|
+
const existingPlugins = new Set();
|
|
43
|
+
const existingFilesPatterns = new Set();
|
|
44
|
+
|
|
45
|
+
const result = configGenerator.shouldSkipConfigUpdate(
|
|
46
|
+
selectedTools,
|
|
47
|
+
existingPlugins,
|
|
48
|
+
existingFilesPatterns
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
expect(typeof result).toBe('boolean');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('doit afficher message si skip', () => {
|
|
55
|
+
const selectedTools = [];
|
|
56
|
+
const existingPlugins = new Set();
|
|
57
|
+
const existingFilesPatterns = new Set();
|
|
58
|
+
|
|
59
|
+
configGenerator.shouldSkipConfigUpdate(
|
|
60
|
+
selectedTools,
|
|
61
|
+
existingPlugins,
|
|
62
|
+
existingFilesPatterns
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
expect(console.log).toHaveBeenCalled();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe('generateImports', () => {
|
|
70
|
+
test('doit générer imports de base', () => {
|
|
71
|
+
const selectedTools = [];
|
|
72
|
+
const existingPlugins = new Set();
|
|
73
|
+
|
|
74
|
+
const result = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
75
|
+
|
|
76
|
+
expect(result).toContain('@eslint/js');
|
|
77
|
+
expect(result).toContain('eslint-plugin-prettier');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('doit ajouter import TypeScript', () => {
|
|
81
|
+
const selectedTools = ['TypeScript (TypeScript ESLint)'];
|
|
82
|
+
const existingPlugins = new Set();
|
|
83
|
+
|
|
84
|
+
const result = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
85
|
+
|
|
86
|
+
expect(result).toContain('typescript');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('doit ajouter import JSON', () => {
|
|
90
|
+
const selectedTools = ['JSON (ESLint Plugin)'];
|
|
91
|
+
const existingPlugins = new Set();
|
|
92
|
+
|
|
93
|
+
const result = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
94
|
+
|
|
95
|
+
expect(result).toContain('json');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('doit ajouter import Markdown', () => {
|
|
99
|
+
const selectedTools = ['Markdown (ESLint Plugin)'];
|
|
100
|
+
const existingPlugins = new Set();
|
|
101
|
+
|
|
102
|
+
const result = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
103
|
+
|
|
104
|
+
expect(result).toContain('markdown');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
test('doit ajouter import YAML', () => {
|
|
108
|
+
const selectedTools = ['YAML (ESLint Plugin)'];
|
|
109
|
+
const existingPlugins = new Set();
|
|
110
|
+
|
|
111
|
+
const result = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
112
|
+
|
|
113
|
+
expect(result).toContain('yaml');
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('doit ajouter import HTML', () => {
|
|
117
|
+
const selectedTools = ['HTML (ESLint Plugin)'];
|
|
118
|
+
const existingPlugins = new Set();
|
|
119
|
+
|
|
120
|
+
const result = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
121
|
+
|
|
122
|
+
expect(result).toContain('html');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('doit ajouter import Nuxt', () => {
|
|
126
|
+
const selectedTools = ['Nuxt (ESLint Plugin)'];
|
|
127
|
+
const existingPlugins = new Set();
|
|
128
|
+
|
|
129
|
+
const result = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
130
|
+
|
|
131
|
+
expect(result).toContain('nuxt');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('ne doit pas dupliquer imports existants', () => {
|
|
135
|
+
const selectedTools = ['TypeScript (TypeScript ESLint)'];
|
|
136
|
+
const existingPlugins = new Set(['typescript']);
|
|
137
|
+
|
|
138
|
+
const result = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
139
|
+
|
|
140
|
+
const tsCount = (result.match(/typescript/g) || []).length;
|
|
141
|
+
expect(tsCount).toBeLessThanOrEqual(1);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
describe('generateNewConfigs', () => {
|
|
146
|
+
test('doit générer configs pour outils sélectionnés', () => {
|
|
147
|
+
const selectedTools = ['JavaScript (ESLint)'];
|
|
148
|
+
const existingPlugins = new Set();
|
|
149
|
+
const existingFilesPatterns = new Set();
|
|
150
|
+
|
|
151
|
+
const result = configGenerator.generateNewConfigs(
|
|
152
|
+
selectedTools,
|
|
153
|
+
existingPlugins,
|
|
154
|
+
existingFilesPatterns
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
expect(Array.isArray(result)).toBe(true);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test('doit générer config TypeScript', () => {
|
|
161
|
+
const selectedTools = ['TypeScript (TypeScript ESLint)'];
|
|
162
|
+
const existingPlugins = new Set();
|
|
163
|
+
const existingFilesPatterns = new Set();
|
|
164
|
+
|
|
165
|
+
const result = configGenerator.generateNewConfigs(
|
|
166
|
+
selectedTools,
|
|
167
|
+
existingPlugins,
|
|
168
|
+
existingFilesPatterns
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
expect(Array.isArray(result)).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test('doit générer config JSON', () => {
|
|
175
|
+
const selectedTools = ['JSON (ESLint Plugin)'];
|
|
176
|
+
const existingPlugins = new Set();
|
|
177
|
+
const existingFilesPatterns = new Set();
|
|
178
|
+
|
|
179
|
+
const result = configGenerator.generateNewConfigs(
|
|
180
|
+
selectedTools,
|
|
181
|
+
existingPlugins,
|
|
182
|
+
existingFilesPatterns
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
expect(Array.isArray(result)).toBe(true);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test('ne doit pas générer config si déjà existante', () => {
|
|
189
|
+
const selectedTools = ['TypeScript (TypeScript ESLint)'];
|
|
190
|
+
const existingPlugins = new Set(['typescript']);
|
|
191
|
+
const existingFilesPatterns = new Set(['**/*.ts']);
|
|
192
|
+
|
|
193
|
+
const result = configGenerator.generateNewConfigs(
|
|
194
|
+
selectedTools,
|
|
195
|
+
existingPlugins,
|
|
196
|
+
existingFilesPatterns
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
expect(Array.isArray(result)).toBe(true);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
describe('buildNewConfigContent', () => {
|
|
204
|
+
test('doit construire nouveau contenu de config', () => {
|
|
205
|
+
const imports = 'const js = require("@eslint/js");';
|
|
206
|
+
const newConfigs = ['{ files: ["**/*.js"] }'];
|
|
207
|
+
|
|
208
|
+
const result = configGenerator.buildNewConfigContent(imports, newConfigs);
|
|
209
|
+
|
|
210
|
+
expect(result).toContain('module.exports');
|
|
211
|
+
expect(result).toContain(imports);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test('doit inclure configs recommandées', () => {
|
|
215
|
+
const imports = 'const js = require("@eslint/js");';
|
|
216
|
+
const newConfigs = [];
|
|
217
|
+
|
|
218
|
+
const result = configGenerator.buildNewConfigContent(imports, newConfigs);
|
|
219
|
+
|
|
220
|
+
expect(result).toContain('js.configs.recommended');
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe('fonctions de génération de code', () => {
|
|
225
|
+
const emptyPlugins = new Set();
|
|
226
|
+
const emptyPatterns = new Set();
|
|
227
|
+
|
|
228
|
+
test('generateJavaScriptCode doit générer config JS', () => {
|
|
229
|
+
const result = configGenerator.generateJavaScriptCode(emptyPlugins, emptyPatterns);
|
|
230
|
+
|
|
231
|
+
expect(result).toBeDefined();
|
|
232
|
+
expect(result).toContain('files');
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test('generateJavaScriptCode doit retourner null si pattern jsx déjà présent', () => {
|
|
236
|
+
const result = configGenerator.generateJavaScriptCode(emptyPlugins, new Set(['*.jsx']));
|
|
237
|
+
|
|
238
|
+
expect(result).toBeNull();
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test('generateTypeScriptCode doit générer config TS', () => {
|
|
242
|
+
const result = configGenerator.generateTypeScriptCode(emptyPlugins, emptyPatterns);
|
|
243
|
+
|
|
244
|
+
expect(result).toBeDefined();
|
|
245
|
+
expect(result).toContain('files');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test('generateJSONCode doit générer config JSON', () => {
|
|
249
|
+
const result = configGenerator.generateJSONCode(emptyPlugins, emptyPatterns);
|
|
250
|
+
|
|
251
|
+
expect(result).toBeDefined();
|
|
252
|
+
expect(result).toContain('files');
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test('generateMarkdownCode doit générer config Markdown', () => {
|
|
256
|
+
const result = configGenerator.generateMarkdownCode(emptyPlugins, emptyPatterns);
|
|
257
|
+
|
|
258
|
+
expect(result).toBeDefined();
|
|
259
|
+
expect(result).toContain('files');
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
test('generateYAMLCode doit générer config YAML', () => {
|
|
263
|
+
const result = configGenerator.generateYAMLCode(emptyPlugins, emptyPatterns);
|
|
264
|
+
|
|
265
|
+
expect(result).toBeDefined();
|
|
266
|
+
expect(result).toContain('files');
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test('generateHTMLCode doit générer config HTML', () => {
|
|
270
|
+
const result = configGenerator.generateHTMLCode(emptyPlugins, emptyPatterns);
|
|
271
|
+
|
|
272
|
+
expect(result).toBeDefined();
|
|
273
|
+
expect(result).toContain('files');
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
test('generateNuxtCode doit générer config Nuxt', () => {
|
|
277
|
+
const result = configGenerator.generateNuxtCode(emptyPlugins, emptyPatterns);
|
|
278
|
+
|
|
279
|
+
expect(result).toBeDefined();
|
|
280
|
+
expect(result).toContain('files');
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
describe('analyzeExistingConfig', () => {
|
|
285
|
+
test('doit analyser item de config', () => {
|
|
286
|
+
const item = {
|
|
287
|
+
plugins: { typescript: {} },
|
|
288
|
+
files: ['**/*.ts']
|
|
289
|
+
};
|
|
290
|
+
const existingPlugins = new Set();
|
|
291
|
+
const existingFilesPatterns = new Set();
|
|
292
|
+
|
|
293
|
+
configGenerator.analyzeExistingConfig(item, existingPlugins, existingFilesPatterns);
|
|
294
|
+
|
|
295
|
+
expect(existingPlugins.size).toBeGreaterThanOrEqual(0);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test('doit détecter plugins dans config', () => {
|
|
299
|
+
const item = {
|
|
300
|
+
plugins: {
|
|
301
|
+
typescript: {},
|
|
302
|
+
json: {}
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
const existingPlugins = new Set();
|
|
306
|
+
const existingFilesPatterns = new Set();
|
|
307
|
+
|
|
308
|
+
configGenerator.analyzeExistingConfig(item, existingPlugins, existingFilesPatterns);
|
|
309
|
+
|
|
310
|
+
expect(existingPlugins.size).toBeGreaterThanOrEqual(0);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
test('doit détecter files patterns', () => {
|
|
314
|
+
const item = {
|
|
315
|
+
files: ['**/*.ts', '**/*.js']
|
|
316
|
+
};
|
|
317
|
+
const existingPlugins = new Set();
|
|
318
|
+
const existingFilesPatterns = new Set();
|
|
319
|
+
|
|
320
|
+
configGenerator.analyzeExistingConfig(item, existingPlugins, existingFilesPatterns);
|
|
321
|
+
|
|
322
|
+
expect(existingFilesPatterns.size).toBeGreaterThanOrEqual(0);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test('doit gérer files en chaîne simple', () => {
|
|
326
|
+
const item = {
|
|
327
|
+
files: '**/*.json'
|
|
328
|
+
};
|
|
329
|
+
const existingPlugins = new Set();
|
|
330
|
+
const existingFilesPatterns = new Set();
|
|
331
|
+
|
|
332
|
+
configGenerator.analyzeExistingConfig(item, existingPlugins, existingFilesPatterns);
|
|
333
|
+
|
|
334
|
+
expect(existingFilesPatterns.has('**/*.json')).toBe(true);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
describe('tool mappings', () => {
|
|
339
|
+
test('doit retourner les plugins attendus pour chaque outil', () => {
|
|
340
|
+
expect(configGenerator.getPluginNameForTool('JavaScript (ESLint)')).toBeNull();
|
|
341
|
+
expect(configGenerator.getPluginNameForTool('TypeScript (TypeScript ESLint)')).toBe('typescript');
|
|
342
|
+
expect(configGenerator.getPluginNameForTool('JSON (ESLint Plugin)')).toBe('json');
|
|
343
|
+
expect(configGenerator.getPluginNameForTool('Markdown (ESLint Plugin)')).toBe('markdown');
|
|
344
|
+
expect(configGenerator.getPluginNameForTool('YAML (ESLint Plugin)')).toBe('yml');
|
|
345
|
+
expect(configGenerator.getPluginNameForTool('HTML (ESLint Plugin)')).toBe('html');
|
|
346
|
+
expect(configGenerator.getPluginNameForTool('Nuxt (ESLint Plugin)')).toBe('nuxt');
|
|
347
|
+
expect(configGenerator.getPluginNameForTool('Unknown Tool')).toBeUndefined();
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
test('doit retourner les patterns attendus pour chaque outil', () => {
|
|
351
|
+
expect(configGenerator.getFilePatternsForTool('JavaScript (ESLint)')).toEqual(['**/*.js', '**/*.jsx']);
|
|
352
|
+
expect(configGenerator.getFilePatternsForTool('TypeScript (TypeScript ESLint)')).toEqual(['**/*.ts', '**/*.tsx']);
|
|
353
|
+
expect(configGenerator.getFilePatternsForTool('JSON (ESLint Plugin)')).toEqual(['**/*.json']);
|
|
354
|
+
expect(configGenerator.getFilePatternsForTool('Markdown (ESLint Plugin)')).toEqual(['**/*.md']);
|
|
355
|
+
expect(configGenerator.getFilePatternsForTool('YAML (ESLint Plugin)')).toEqual(['**/*.yaml', '**/*.yml']);
|
|
356
|
+
expect(configGenerator.getFilePatternsForTool('HTML (ESLint Plugin)')).toEqual(['**/*.html']);
|
|
357
|
+
expect(configGenerator.getFilePatternsForTool('Nuxt (ESLint Plugin)')).toEqual(['**/*.vue']);
|
|
358
|
+
expect(configGenerator.getFilePatternsForTool('Unknown Tool')).toEqual([]);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
describe('buildConfigContent', () => {
|
|
363
|
+
test('doit construire contenu pour nouvelle config', () => {
|
|
364
|
+
const selectedTools = ['JavaScript (ESLint)'];
|
|
365
|
+
const existingConfig = [];
|
|
366
|
+
const existingPlugins = new Set();
|
|
367
|
+
const existingFilesPatterns = new Set();
|
|
368
|
+
const imports = 'const js = require("@eslint/js");';
|
|
369
|
+
|
|
370
|
+
const result = configGenerator.buildConfigContent(
|
|
371
|
+
selectedTools,
|
|
372
|
+
existingConfig,
|
|
373
|
+
existingPlugins,
|
|
374
|
+
existingFilesPatterns,
|
|
375
|
+
imports
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
expect(result).toContain('module.exports');
|
|
379
|
+
expect(result).toContain(imports);
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
test('doit gérer config existante', () => {
|
|
383
|
+
const selectedTools = ['TypeScript (TypeScript ESLint)'];
|
|
384
|
+
const existingConfig = [{ files: ['**/*.js'] }];
|
|
385
|
+
const existingPlugins = new Set();
|
|
386
|
+
const existingFilesPatterns = new Set(['**/*.js']);
|
|
387
|
+
const imports = 'const typescript = require("typescript");';
|
|
388
|
+
|
|
389
|
+
const result = configGenerator.buildConfigContent(
|
|
390
|
+
selectedTools,
|
|
391
|
+
existingConfig,
|
|
392
|
+
existingPlugins,
|
|
393
|
+
existingFilesPatterns,
|
|
394
|
+
imports
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
expect(result).toBeDefined();
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
test('doit retourner null si newConfigs vide', () => {
|
|
401
|
+
const selectedTools = [];
|
|
402
|
+
const existingConfig = [];
|
|
403
|
+
const existingPlugins = new Set();
|
|
404
|
+
const existingFilesPatterns = new Set();
|
|
405
|
+
const imports = '';
|
|
406
|
+
|
|
407
|
+
const result = configGenerator.buildConfigContent(
|
|
408
|
+
selectedTools,
|
|
409
|
+
existingConfig,
|
|
410
|
+
existingPlugins,
|
|
411
|
+
existingFilesPatterns,
|
|
412
|
+
imports
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
expect(result).toBeNull();
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
test('doit appeler buildNewConfigContent si pas de config existante', () => {
|
|
419
|
+
const selectedTools = ['JavaScript (ESLint)'];
|
|
420
|
+
const existingConfig = [];
|
|
421
|
+
const existingPlugins = new Set();
|
|
422
|
+
const existingFilesPatterns = new Set();
|
|
423
|
+
const imports = 'const js = require("@eslint/js");';
|
|
424
|
+
|
|
425
|
+
const result = configGenerator.buildConfigContent(
|
|
426
|
+
selectedTools,
|
|
427
|
+
existingConfig,
|
|
428
|
+
existingPlugins,
|
|
429
|
+
existingFilesPatterns,
|
|
430
|
+
imports
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
expect(result).toContain('js.configs.recommended');
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
test('doit appeler buildMergedConfigContent si config existante', () => {
|
|
437
|
+
const selectedTools = ['TypeScript (TypeScript ESLint)'];
|
|
438
|
+
const existingConfig = [{ files: ['**/*.js'] }];
|
|
439
|
+
const existingPlugins = new Set();
|
|
440
|
+
const existingFilesPatterns = new Set(['**/*.js']);
|
|
441
|
+
const imports = 'const typescript = require("typescript");';
|
|
442
|
+
|
|
443
|
+
const result = configGenerator.buildConfigContent(
|
|
444
|
+
selectedTools,
|
|
445
|
+
existingConfig,
|
|
446
|
+
existingPlugins,
|
|
447
|
+
existingFilesPatterns,
|
|
448
|
+
imports
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
expect(result).toBeDefined();
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
describe('serializeConfig', () => {
|
|
456
|
+
test('doit sérialiser config simple', () => {
|
|
457
|
+
const config = { files: ['**/*.js'] };
|
|
458
|
+
|
|
459
|
+
const result = configGenerator.serializeConfig(config);
|
|
460
|
+
|
|
461
|
+
expect(result).toContain('files');
|
|
462
|
+
expect(result).toContain('**/*.js');
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
test('doit gérer fonctions dans config', () => {
|
|
466
|
+
const config = {
|
|
467
|
+
files: ['**/*.ts'],
|
|
468
|
+
rules: {
|
|
469
|
+
test: () => {}
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
const result = configGenerator.serializeConfig(config);
|
|
474
|
+
|
|
475
|
+
expect(result).toBeDefined();
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
test('doit sérialiser une fonction nommée', () => {
|
|
479
|
+
function namedRule() {
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const config = {
|
|
484
|
+
files: ['**/*.js'],
|
|
485
|
+
rules: {
|
|
486
|
+
myRule: namedRule
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
const result = configGenerator.serializeConfig(config);
|
|
491
|
+
|
|
492
|
+
expect(result).toContain('[Function: namedRule]');
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
test('doit sérialiser une fonction anonyme', () => {
|
|
496
|
+
const config = {
|
|
497
|
+
files: ['**/*.js'],
|
|
498
|
+
rules: {
|
|
499
|
+
inline: new Function('return true;')
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
const result = configGenerator.serializeConfig(config);
|
|
504
|
+
|
|
505
|
+
expect(result).toContain('[Function: anonymous]');
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
test('doit gérer plugins avec simplification', () => {
|
|
509
|
+
const config = {
|
|
510
|
+
files: ['**/*.ts'],
|
|
511
|
+
plugins: {
|
|
512
|
+
typescript: {}
|
|
513
|
+
}
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
const result = configGenerator.serializeConfig(config);
|
|
517
|
+
|
|
518
|
+
expect(result).toContain('plugins');
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
test('doit détecter références circulaires', () => {
|
|
522
|
+
const config = { files: ['**/*.js'] };
|
|
523
|
+
config.self = config;
|
|
524
|
+
|
|
525
|
+
const result = configGenerator.serializeConfig(config);
|
|
526
|
+
|
|
527
|
+
expect(result).toBeDefined();
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
test('doit gérer objets imbriqués', () => {
|
|
531
|
+
const config = {
|
|
532
|
+
files: ['**/*.ts'],
|
|
533
|
+
rules: {
|
|
534
|
+
'@typescript-eslint/no-unused-vars': ['error', {
|
|
535
|
+
argsIgnorePattern: '^_'
|
|
536
|
+
}]
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
const result = configGenerator.serializeConfig(config);
|
|
541
|
+
|
|
542
|
+
expect(result).toContain('rules');
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
test('doit gérer arrays', () => {
|
|
546
|
+
const config = {
|
|
547
|
+
files: ['**/*.js', '**/*.jsx'],
|
|
548
|
+
ignores: ['node_modules/**', 'dist/**']
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
const result = configGenerator.serializeConfig(config);
|
|
552
|
+
|
|
553
|
+
expect(result).toContain('files');
|
|
554
|
+
expect(result).toContain('ignores');
|
|
555
|
+
});
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
describe('buildMergedConfigContent', () => {
|
|
559
|
+
test('doit fusionner imports et configs', () => {
|
|
560
|
+
const imports = 'const typescript = require("typescript");';
|
|
561
|
+
const existingConfig = [{ files: ['**/*.js'] }];
|
|
562
|
+
const newConfigs = [{ files: ['**/*.ts'] }];
|
|
563
|
+
|
|
564
|
+
const result = configGenerator.buildMergedConfigContent(imports, existingConfig, newConfigs);
|
|
565
|
+
|
|
566
|
+
expect(result).toContain('module.exports');
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
test('doit ajouter nouvelles configs', () => {
|
|
570
|
+
const imports = '';
|
|
571
|
+
const existingConfig = [];
|
|
572
|
+
const newConfigs = ['{ files: ["**/*.ts"] }'];
|
|
573
|
+
|
|
574
|
+
const result = configGenerator.buildMergedConfigContent(imports, existingConfig, newConfigs);
|
|
575
|
+
|
|
576
|
+
expect(result).toContain('module.exports');
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
test('doit inclure imports dans le résultat', () => {
|
|
580
|
+
const imports = 'const json = require("eslint-plugin-json");';
|
|
581
|
+
const existingConfig = [];
|
|
582
|
+
const newConfigs = [];
|
|
583
|
+
|
|
584
|
+
const result = configGenerator.buildMergedConfigContent(imports, existingConfig, newConfigs);
|
|
585
|
+
|
|
586
|
+
expect(result).toContain('json');
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
describe('test de génération complète', () => {
|
|
591
|
+
test('doit générer imports pour TypeScript', () => {
|
|
592
|
+
const selectedTools = ['TypeScript (TypeScript ESLint)'];
|
|
593
|
+
const existingPlugins = new Set();
|
|
594
|
+
|
|
595
|
+
const imports = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
596
|
+
|
|
597
|
+
expect(imports).toContain('typescript');
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
test('doit générer imports pour JSON', () => {
|
|
601
|
+
const selectedTools = ['JSON (ESLint Plugin)'];
|
|
602
|
+
const existingPlugins = new Set();
|
|
603
|
+
|
|
604
|
+
const imports = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
605
|
+
|
|
606
|
+
expect(imports).toContain('json');
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
test('doit générer imports pour plusieurs outils', () => {
|
|
610
|
+
const selectedTools = [
|
|
611
|
+
'TypeScript (TypeScript ESLint)',
|
|
612
|
+
'JSON (ESLint Plugin)',
|
|
613
|
+
'Markdown (ESLint Plugin)'
|
|
614
|
+
];
|
|
615
|
+
const existingPlugins = new Set();
|
|
616
|
+
|
|
617
|
+
const imports = configGenerator.generateImports(selectedTools, existingPlugins);
|
|
618
|
+
|
|
619
|
+
expect(imports).toContain('typescript');
|
|
620
|
+
expect(imports).toContain('json');
|
|
621
|
+
expect(imports).toContain('markdown');
|
|
622
|
+
});
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
describe('edge cases', () => {
|
|
626
|
+
test('doit gérer selectedTools vide', () => {
|
|
627
|
+
const selectedTools = [];
|
|
628
|
+
const existingPlugins = new Set();
|
|
629
|
+
const existingFilesPatterns = new Set();
|
|
630
|
+
|
|
631
|
+
const result = configGenerator.generateNewConfigs(
|
|
632
|
+
selectedTools,
|
|
633
|
+
existingPlugins,
|
|
634
|
+
existingFilesPatterns
|
|
635
|
+
);
|
|
636
|
+
|
|
637
|
+
expect(Array.isArray(result)).toBe(true);
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
test('doit gérer outil non reconnu', () => {
|
|
641
|
+
const selectedTools = ['Unknown Tool'];
|
|
642
|
+
const existingPlugins = new Set();
|
|
643
|
+
const existingFilesPatterns = new Set();
|
|
644
|
+
|
|
645
|
+
const result = configGenerator.generateNewConfigs(
|
|
646
|
+
selectedTools,
|
|
647
|
+
existingPlugins,
|
|
648
|
+
existingFilesPatterns
|
|
649
|
+
);
|
|
650
|
+
|
|
651
|
+
expect(Array.isArray(result)).toBe(true);
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
test('generateNuxtCode doit gérer patterns existants', () => {
|
|
655
|
+
const existingPlugins = new Set();
|
|
656
|
+
const existingFilesPatterns = new Set(['**/*.vue']);
|
|
657
|
+
|
|
658
|
+
const result = configGenerator.generateNuxtCode(existingPlugins, existingFilesPatterns);
|
|
659
|
+
|
|
660
|
+
expect(result).toBeDefined();
|
|
661
|
+
});
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
describe('generateMarkdownCode - conditions de retour null', () => {
|
|
665
|
+
test('doit retourner null si plugin markdown existe', () => {
|
|
666
|
+
const existingPlugins = new Set(['markdown']);
|
|
667
|
+
const existingFilesPatterns = new Set();
|
|
668
|
+
|
|
669
|
+
const result = configGenerator.generateMarkdownCode(existingPlugins, existingFilesPatterns);
|
|
670
|
+
|
|
671
|
+
expect(result).toBeNull();
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
test('doit retourner null si config markdown existe', () => {
|
|
675
|
+
const existingPlugins = new Set();
|
|
676
|
+
const existingFilesPatterns = new Set(['**/*.md']);
|
|
677
|
+
|
|
678
|
+
const result = configGenerator.generateMarkdownCode(existingPlugins, existingFilesPatterns);
|
|
679
|
+
|
|
680
|
+
expect(result).toBeNull();
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
test('doit générer config si ni plugin ni pattern', () => {
|
|
684
|
+
const existingPlugins = new Set();
|
|
685
|
+
const existingFilesPatterns = new Set();
|
|
686
|
+
|
|
687
|
+
const result = configGenerator.generateMarkdownCode(existingPlugins, existingFilesPatterns);
|
|
688
|
+
|
|
689
|
+
expect(result).not.toBeNull();
|
|
690
|
+
expect(result).toContain('**/*.md');
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
describe('generateYAMLCode - conditions de retour null', () => {
|
|
695
|
+
test('doit retourner null si plugin yaml existe', () => {
|
|
696
|
+
const existingPlugins = new Set(['yml']);
|
|
697
|
+
const existingFilesPatterns = new Set();
|
|
698
|
+
|
|
699
|
+
const result = configGenerator.generateYAMLCode(existingPlugins, existingFilesPatterns);
|
|
700
|
+
|
|
701
|
+
expect(result).toBeNull();
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
test('doit retourner null si pattern yaml existe', () => {
|
|
705
|
+
const existingPlugins = new Set();
|
|
706
|
+
const existingFilesPatterns = new Set(['**/*.yaml']);
|
|
707
|
+
|
|
708
|
+
const result = configGenerator.generateYAMLCode(existingPlugins, existingFilesPatterns);
|
|
709
|
+
|
|
710
|
+
expect(result).toBeNull();
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
test('doit retourner null si pattern yml existe', () => {
|
|
714
|
+
const existingPlugins = new Set();
|
|
715
|
+
const existingFilesPatterns = new Set(['**/*.yml']);
|
|
716
|
+
|
|
717
|
+
const result = configGenerator.generateYAMLCode(existingPlugins, existingFilesPatterns);
|
|
718
|
+
|
|
719
|
+
expect(result).toBeNull();
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
test('doit générer config si ni plugin ni pattern', () => {
|
|
723
|
+
const existingPlugins = new Set();
|
|
724
|
+
const existingFilesPatterns = new Set();
|
|
725
|
+
|
|
726
|
+
const result = configGenerator.generateYAMLCode(existingPlugins, existingFilesPatterns);
|
|
727
|
+
|
|
728
|
+
expect(result).not.toBeNull();
|
|
729
|
+
expect(result).toContain('**/*.yaml');
|
|
730
|
+
});
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
describe('generateHTMLCode - conditions de retour null', () => {
|
|
734
|
+
test('doit retourner null si plugin html existe', () => {
|
|
735
|
+
const existingPlugins = new Set(['html']);
|
|
736
|
+
const existingFilesPatterns = new Set();
|
|
737
|
+
|
|
738
|
+
const result = configGenerator.generateHTMLCode(existingPlugins, existingFilesPatterns);
|
|
739
|
+
|
|
740
|
+
expect(result).toBeNull();
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
test('doit retourner null si config html existe', () => {
|
|
744
|
+
const existingPlugins = new Set();
|
|
745
|
+
const existingFilesPatterns = new Set(['**/*.html']);
|
|
746
|
+
|
|
747
|
+
const result = configGenerator.generateHTMLCode(existingPlugins, existingFilesPatterns);
|
|
748
|
+
|
|
749
|
+
expect(result).toBeNull();
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
test('doit générer config si ni plugin ni pattern', () => {
|
|
753
|
+
const existingPlugins = new Set();
|
|
754
|
+
const existingFilesPatterns = new Set();
|
|
755
|
+
|
|
756
|
+
const result = configGenerator.generateHTMLCode(existingPlugins, existingFilesPatterns);
|
|
757
|
+
|
|
758
|
+
expect(result).not.toBeNull();
|
|
759
|
+
expect(result).toContain('**/*.html');
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
describe('generateNuxtCode - conditions de retour null', () => {
|
|
764
|
+
test('doit retourner null si plugin nuxt existe', () => {
|
|
765
|
+
const existingPlugins = new Set(['nuxt']);
|
|
766
|
+
const existingFilesPatterns = new Set();
|
|
767
|
+
|
|
768
|
+
const result = configGenerator.generateNuxtCode(existingPlugins, existingFilesPatterns);
|
|
769
|
+
|
|
770
|
+
expect(result).toBeNull();
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
test('doit retourner null si config nuxt existe', () => {
|
|
774
|
+
const existingPlugins = new Set();
|
|
775
|
+
const existingFilesPatterns = new Set(['**/*.vue']);
|
|
776
|
+
|
|
777
|
+
const result = configGenerator.generateNuxtCode(existingPlugins, existingFilesPatterns);
|
|
778
|
+
|
|
779
|
+
expect(result).toBeNull();
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
test('doit générer config si ni plugin ni pattern', () => {
|
|
783
|
+
const existingPlugins = new Set();
|
|
784
|
+
const existingFilesPatterns = new Set();
|
|
785
|
+
|
|
786
|
+
const result = configGenerator.generateNuxtCode(existingPlugins, existingFilesPatterns);
|
|
787
|
+
|
|
788
|
+
expect(result).not.toBeNull();
|
|
789
|
+
expect(result).toContain('**/*.nuxt');
|
|
790
|
+
});
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
describe('createNewConfig', () => {
|
|
794
|
+
test('doit créer eslint.config.js avec imports et configs', async () => {
|
|
795
|
+
fs.writeFileSync.mockImplementation(() => {});
|
|
796
|
+
|
|
797
|
+
await configGenerator.createNewConfig(['TypeScript (TypeScript ESLint)']);
|
|
798
|
+
|
|
799
|
+
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
|
800
|
+
'eslint.config.js',
|
|
801
|
+
expect.stringContaining('module.exports = [')
|
|
802
|
+
);
|
|
803
|
+
expect(console.log).toHaveBeenCalledWith(
|
|
804
|
+
expect.stringContaining('Nouvelle configuration ESLint créée')
|
|
805
|
+
);
|
|
806
|
+
});
|
|
807
|
+
});
|
|
808
|
+
});
|