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,427 @@
|
|
|
1
|
+
jest.mock('../../src/core/plugins/pluginRegistry');
|
|
2
|
+
|
|
3
|
+
const pluginManager = require('../../src/core/plugins/pluginManager');
|
|
4
|
+
const pluginRegistry = require('../../src/core/plugins/pluginRegistry');
|
|
5
|
+
|
|
6
|
+
describe('Core Plugins - pluginManager', () => {
|
|
7
|
+
let consoleLogSpy;
|
|
8
|
+
let mockPlugin;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
12
|
+
jest.clearAllMocks();
|
|
13
|
+
|
|
14
|
+
mockPlugin = {
|
|
15
|
+
name: 'test-plugin',
|
|
16
|
+
enabled: true,
|
|
17
|
+
commands: new Map([
|
|
18
|
+
['cmd1', {
|
|
19
|
+
name: 'cmd1',
|
|
20
|
+
handler: jest.fn().mockResolvedValue('result1'),
|
|
21
|
+
description: 'Command 1',
|
|
22
|
+
args: ['arg1']
|
|
23
|
+
}],
|
|
24
|
+
['cmd2', {
|
|
25
|
+
name: 'cmd2',
|
|
26
|
+
handler: jest.fn().mockResolvedValue('result2'),
|
|
27
|
+
description: 'Command 2',
|
|
28
|
+
args: []
|
|
29
|
+
}]
|
|
30
|
+
]),
|
|
31
|
+
executeCommand: jest.fn().mockResolvedValue('executed')
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
pluginRegistry.get.mockReturnValue(mockPlugin);
|
|
35
|
+
pluginRegistry.listActive.mockReturnValue([mockPlugin]);
|
|
36
|
+
pluginRegistry.loadPluginConfig.mockReturnValue({
|
|
37
|
+
plugins: {
|
|
38
|
+
'test-plugin': {
|
|
39
|
+
version: '1.0.0',
|
|
40
|
+
enabled: true
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
consoleLogSpy.mockRestore();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('executeCommand', () => {
|
|
51
|
+
test('doit exécuter commande d\'un plugin', async () => {
|
|
52
|
+
const result = await pluginManager.executeCommand('test-plugin', 'cmd1');
|
|
53
|
+
|
|
54
|
+
expect(pluginRegistry.get).toHaveBeenCalledWith('test-plugin');
|
|
55
|
+
expect(mockPlugin.executeCommand).toHaveBeenCalledWith('cmd1', [], {});
|
|
56
|
+
expect(result).toBe('executed');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('doit passer args et options', async () => {
|
|
60
|
+
await pluginManager.executeCommand('test-plugin', 'cmd1', ['arg'], { opt: true });
|
|
61
|
+
|
|
62
|
+
expect(mockPlugin.executeCommand).toHaveBeenCalledWith('cmd1', ['arg'], { opt: true });
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('doit utiliser valeurs par défaut pour args et options', async () => {
|
|
66
|
+
await pluginManager.executeCommand('test-plugin', 'cmd1');
|
|
67
|
+
|
|
68
|
+
expect(mockPlugin.executeCommand).toHaveBeenCalledWith('cmd1', [], {});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('doit throw si plugin non trouvé', async () => {
|
|
72
|
+
pluginRegistry.get.mockReturnValue(null);
|
|
73
|
+
|
|
74
|
+
await expect(
|
|
75
|
+
pluginManager.executeCommand('unknown-plugin', 'cmd1')
|
|
76
|
+
).rejects.toThrow('Plugin unknown-plugin non trouve');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('doit throw si plugin désactivé', async () => {
|
|
80
|
+
mockPlugin.enabled = false;
|
|
81
|
+
|
|
82
|
+
await expect(
|
|
83
|
+
pluginManager.executeCommand('test-plugin', 'cmd1')
|
|
84
|
+
).rejects.toThrow('Plugin test-plugin est desactive');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('doit gérer erreur d\'exécution', async () => {
|
|
88
|
+
const error = new Error('Execution failed');
|
|
89
|
+
mockPlugin.executeCommand.mockRejectedValue(error);
|
|
90
|
+
|
|
91
|
+
await expect(
|
|
92
|
+
pluginManager.executeCommand('test-plugin', 'cmd1')
|
|
93
|
+
).rejects.toThrow('Execution failed');
|
|
94
|
+
|
|
95
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
96
|
+
expect.stringContaining('Erreur lors de l\'execution'),
|
|
97
|
+
expect.stringContaining('Execution failed')
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('doit afficher nom du plugin et commande dans erreur', async () => {
|
|
102
|
+
mockPlugin.executeCommand.mockRejectedValue(new Error('Test error'));
|
|
103
|
+
|
|
104
|
+
await expect(
|
|
105
|
+
pluginManager.executeCommand('test-plugin', 'special-cmd')
|
|
106
|
+
).rejects.toThrow();
|
|
107
|
+
|
|
108
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
109
|
+
expect.stringContaining('test-plugin:special-cmd'),
|
|
110
|
+
expect.any(String)
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('doit retourner résultat de executeCommand', async () => {
|
|
115
|
+
mockPlugin.executeCommand.mockResolvedValue({ data: 'test' });
|
|
116
|
+
|
|
117
|
+
const result = await pluginManager.executeCommand('test-plugin', 'cmd1');
|
|
118
|
+
|
|
119
|
+
expect(result).toEqual({ data: 'test' });
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe('listCommands', () => {
|
|
124
|
+
test('doit lister toutes les commandes actives', () => {
|
|
125
|
+
const commands = pluginManager.listCommands();
|
|
126
|
+
|
|
127
|
+
expect(commands).toHaveLength(2);
|
|
128
|
+
expect(commands[0]).toMatchObject({
|
|
129
|
+
plugin: 'test-plugin',
|
|
130
|
+
command: 'cmd1',
|
|
131
|
+
description: 'Command 1',
|
|
132
|
+
args: ['arg1']
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('doit retourner array vide si aucun plugin actif', () => {
|
|
137
|
+
pluginRegistry.listActive.mockReturnValue([]);
|
|
138
|
+
|
|
139
|
+
const commands = pluginManager.listCommands();
|
|
140
|
+
|
|
141
|
+
expect(commands).toEqual([]);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('doit inclure commandes de plusieurs plugins', () => {
|
|
145
|
+
const plugin2 = {
|
|
146
|
+
name: 'plugin2',
|
|
147
|
+
enabled: true,
|
|
148
|
+
commands: new Map([
|
|
149
|
+
['cmd3', {
|
|
150
|
+
name: 'cmd3',
|
|
151
|
+
description: 'Command 3',
|
|
152
|
+
args: []
|
|
153
|
+
}]
|
|
154
|
+
])
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
pluginRegistry.listActive.mockReturnValue([mockPlugin, plugin2]);
|
|
158
|
+
|
|
159
|
+
const commands = pluginManager.listCommands();
|
|
160
|
+
|
|
161
|
+
expect(commands).toHaveLength(3);
|
|
162
|
+
expect(commands.find(c => c.command === 'cmd3')).toBeDefined();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('doit inclure toutes les propriétés de commande', () => {
|
|
166
|
+
const commands = pluginManager.listCommands();
|
|
167
|
+
|
|
168
|
+
expect(commands[0]).toHaveProperty('plugin');
|
|
169
|
+
expect(commands[0]).toHaveProperty('command');
|
|
170
|
+
expect(commands[0]).toHaveProperty('description');
|
|
171
|
+
expect(commands[0]).toHaveProperty('args');
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test('doit gérer plugin sans commandes', () => {
|
|
175
|
+
const emptyPlugin = {
|
|
176
|
+
name: 'empty-plugin',
|
|
177
|
+
enabled: true,
|
|
178
|
+
commands: new Map()
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
pluginRegistry.listActive.mockReturnValue([emptyPlugin]);
|
|
182
|
+
|
|
183
|
+
const commands = pluginManager.listCommands();
|
|
184
|
+
|
|
185
|
+
expect(commands).toEqual([]);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
describe('displayCommands', () => {
|
|
190
|
+
test('doit afficher commandes disponibles', () => {
|
|
191
|
+
pluginManager.displayCommands();
|
|
192
|
+
|
|
193
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
194
|
+
expect.stringContaining('Commandes disponibles')
|
|
195
|
+
);
|
|
196
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
197
|
+
expect.stringContaining('test-plugin')
|
|
198
|
+
);
|
|
199
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
200
|
+
expect.stringContaining('cmd1')
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test('doit afficher message si aucune commande', () => {
|
|
205
|
+
pluginRegistry.listActive.mockReturnValue([]);
|
|
206
|
+
|
|
207
|
+
pluginManager.displayCommands();
|
|
208
|
+
|
|
209
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
210
|
+
expect.stringContaining('Aucune commande disponible')
|
|
211
|
+
);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test('doit grouper commandes par plugin', () => {
|
|
215
|
+
pluginManager.displayCommands();
|
|
216
|
+
|
|
217
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
218
|
+
expect.stringContaining('test-plugin:')
|
|
219
|
+
);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test('doit afficher args si présents', () => {
|
|
223
|
+
pluginManager.displayCommands();
|
|
224
|
+
|
|
225
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
226
|
+
const cmd1Call = calls.find(c => c.includes('cmd1'));
|
|
227
|
+
|
|
228
|
+
expect(cmd1Call).toContain('arg1');
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test('doit afficher description si présente', () => {
|
|
232
|
+
pluginManager.displayCommands();
|
|
233
|
+
|
|
234
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
235
|
+
const cmd1Call = calls.find(c => c.includes('cmd1'));
|
|
236
|
+
|
|
237
|
+
expect(cmd1Call).toContain('Command 1');
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test('doit gérer commande sans args', () => {
|
|
241
|
+
pluginManager.displayCommands();
|
|
242
|
+
|
|
243
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
244
|
+
const cmd2Call = calls.find(c => c.includes('cmd2') && !c.includes('cmd1'));
|
|
245
|
+
|
|
246
|
+
expect(cmd2Call).toBeDefined();
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test('doit gérer commande sans description', () => {
|
|
250
|
+
mockPlugin.commands.set('cmd-no-desc', {
|
|
251
|
+
name: 'cmd-no-desc',
|
|
252
|
+
description: '',
|
|
253
|
+
args: []
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
pluginManager.displayCommands();
|
|
257
|
+
|
|
258
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
259
|
+
const cmdCall = calls.find(c => c.includes('cmd-no-desc'));
|
|
260
|
+
|
|
261
|
+
expect(cmdCall).toBeDefined();
|
|
262
|
+
expect(cmdCall).not.toContain(' - ');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test('doit afficher plusieurs plugins', () => {
|
|
266
|
+
const plugin2 = {
|
|
267
|
+
name: 'plugin2',
|
|
268
|
+
enabled: true,
|
|
269
|
+
commands: new Map([
|
|
270
|
+
['cmd3', {
|
|
271
|
+
name: 'cmd3',
|
|
272
|
+
description: 'Command 3',
|
|
273
|
+
args: []
|
|
274
|
+
}]
|
|
275
|
+
])
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
pluginRegistry.listActive.mockReturnValue([mockPlugin, plugin2]);
|
|
279
|
+
|
|
280
|
+
pluginManager.displayCommands();
|
|
281
|
+
|
|
282
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
283
|
+
expect.stringContaining('plugin2:')
|
|
284
|
+
);
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
describe('listPlugins', () => {
|
|
289
|
+
test('doit afficher plugins installés', () => {
|
|
290
|
+
pluginManager.listPlugins();
|
|
291
|
+
|
|
292
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
293
|
+
expect.stringContaining('Plugins installes')
|
|
294
|
+
);
|
|
295
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
296
|
+
expect.stringContaining('test-plugin')
|
|
297
|
+
);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
test('doit afficher message si aucun plugin', () => {
|
|
301
|
+
pluginRegistry.loadPluginConfig.mockReturnValue({ plugins: {} });
|
|
302
|
+
|
|
303
|
+
pluginManager.listPlugins();
|
|
304
|
+
|
|
305
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
306
|
+
expect.stringContaining('Aucun plugin installe')
|
|
307
|
+
);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test('doit afficher message si config.plugins est undefined', () => {
|
|
311
|
+
pluginRegistry.loadPluginConfig.mockReturnValue({});
|
|
312
|
+
|
|
313
|
+
pluginManager.listPlugins();
|
|
314
|
+
|
|
315
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
316
|
+
expect.stringContaining('Aucun plugin installe')
|
|
317
|
+
);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
test('doit afficher statut actif', () => {
|
|
321
|
+
pluginManager.listPlugins();
|
|
322
|
+
|
|
323
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
324
|
+
const pluginCall = calls.find(c => c.includes('test-plugin'));
|
|
325
|
+
|
|
326
|
+
expect(pluginCall).toContain('Actif');
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
test('doit afficher statut inactif', () => {
|
|
330
|
+
pluginRegistry.loadPluginConfig.mockReturnValue({
|
|
331
|
+
plugins: {
|
|
332
|
+
'disabled-plugin': {
|
|
333
|
+
version: '1.0.0',
|
|
334
|
+
enabled: false
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
pluginRegistry.get.mockReturnValue(null);
|
|
339
|
+
|
|
340
|
+
pluginManager.listPlugins();
|
|
341
|
+
|
|
342
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
343
|
+
const pluginCall = calls.find(c => c.includes('disabled-plugin'));
|
|
344
|
+
|
|
345
|
+
expect(pluginCall).toContain('Inactif');
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
test('doit afficher version du plugin', () => {
|
|
349
|
+
pluginManager.listPlugins();
|
|
350
|
+
|
|
351
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
352
|
+
const pluginCall = calls.find(c => c.includes('test-plugin'));
|
|
353
|
+
|
|
354
|
+
expect(pluginCall).toContain('1.0.0');
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test('doit afficher nombre de commandes', () => {
|
|
358
|
+
pluginManager.listPlugins();
|
|
359
|
+
|
|
360
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
361
|
+
const pluginCall = calls.find(c => c.includes('test-plugin'));
|
|
362
|
+
|
|
363
|
+
expect(pluginCall).toContain('2 commande(s)');
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
test('doit afficher 0 commandes si plugin non chargé', () => {
|
|
367
|
+
pluginRegistry.get.mockReturnValue(null);
|
|
368
|
+
|
|
369
|
+
pluginManager.listPlugins();
|
|
370
|
+
|
|
371
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
372
|
+
const pluginCall = calls.find(c => c.includes('test-plugin'));
|
|
373
|
+
|
|
374
|
+
expect(pluginCall).toContain('0 commande(s)');
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
test('doit afficher description si disponible', () => {
|
|
378
|
+
mockPlugin.description = 'Test plugin description';
|
|
379
|
+
|
|
380
|
+
pluginManager.listPlugins();
|
|
381
|
+
|
|
382
|
+
const calls = consoleLogSpy.mock.calls.map(c => c.join(' '));
|
|
383
|
+
const descCall = calls.find(c => c.includes('Test plugin description'));
|
|
384
|
+
|
|
385
|
+
expect(descCall).toBeDefined();
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
test('doit gérer plugin sans description', () => {
|
|
389
|
+
mockPlugin.description = '';
|
|
390
|
+
|
|
391
|
+
pluginManager.listPlugins();
|
|
392
|
+
|
|
393
|
+
// Ne doit pas crasher
|
|
394
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
describe('module singleton', () => {
|
|
399
|
+
test('doit être une instance unique', () => {
|
|
400
|
+
const instance1 = require('../../src/core/plugins/pluginManager');
|
|
401
|
+
const instance2 = require('../../src/core/plugins/pluginManager');
|
|
402
|
+
|
|
403
|
+
expect(instance1).toBe(instance2);
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
describe('intégration', () => {
|
|
408
|
+
test('doit gérer workflow complet', async () => {
|
|
409
|
+
// List commands
|
|
410
|
+
const commands = pluginManager.listCommands();
|
|
411
|
+
expect(commands).toHaveLength(2);
|
|
412
|
+
|
|
413
|
+
// Display commands
|
|
414
|
+
pluginManager.displayCommands();
|
|
415
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
416
|
+
|
|
417
|
+
// Execute command
|
|
418
|
+
const result = await pluginManager.executeCommand('test-plugin', 'cmd1');
|
|
419
|
+
expect(result).toBe('executed');
|
|
420
|
+
|
|
421
|
+
// List plugins
|
|
422
|
+
consoleLogSpy.mockClear();
|
|
423
|
+
pluginManager.listPlugins();
|
|
424
|
+
expect(consoleLogSpy).toHaveBeenCalled();
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
});
|