stigmergy 1.1.6 โ†’ 1.2.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.
@@ -0,0 +1,390 @@
1
+ /**
2
+ * TDD Tests for Enhanced Cache Cleaner
3
+ *
4
+ * Test-first approach to ensure comprehensive cache cleaning before installation
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const os = require('os');
10
+
11
+ class CacheCleanerTests {
12
+ constructor() {
13
+ this.testDir = path.join(os.tmpdir(), 'stigmergy-cache-test');
14
+ this.testResults = [];
15
+ this.mockCachePaths = [];
16
+ }
17
+
18
+ async runAllTests() {
19
+ console.log('๐Ÿงน Running Enhanced Cache Cleaner TDD Tests...\n');
20
+
21
+ await this.setupTestEnvironment();
22
+
23
+ try {
24
+ await this.testStigmergyCacheCleaning();
25
+ await this.testNPXCacheCleaning();
26
+ await this.testNPMCacheCleaning();
27
+ await this.testCLIConfigCacheCleaning();
28
+ await this.testTemporaryFileCleanup();
29
+ await this.testSelectiveCacheCleaning();
30
+ await this.testCacheCleaningPerformance();
31
+ await this.testErrorRecovery();
32
+
33
+ this.printResults();
34
+ } finally {
35
+ await this.cleanupTestEnvironment();
36
+ }
37
+ }
38
+
39
+ async setupTestEnvironment() {
40
+ console.log('๐Ÿ“‹ Setting up cache test environment...');
41
+
42
+ // Create test directory structure
43
+ fs.mkdirSync(this.testDir, { recursive: true });
44
+
45
+ // Create mock Stigmergy cache
46
+ const stigmergyCache = path.join(this.testDir, '.stigmergy');
47
+ fs.mkdirSync(stigmergyCache, { recursive: true });
48
+ fs.mkdirSync(path.join(stigmergyCache, 'cache'), { recursive: true });
49
+ fs.mkdirSync(path.join(stigmergyCache, 'hooks'), { recursive: true });
50
+
51
+ // Create mock cache files
52
+ this.mockCachePaths = [
53
+ path.join(stigmergyCache, 'config.json'),
54
+ path.join(stigmergyCache, 'auth.json'),
55
+ path.join(stigmergyCache, 'error.log'),
56
+ path.join(stigmergyCache, 'cache', 'cli-cache.json'),
57
+ path.join(stigmergyCache, 'cache', 'temp-cache.tmp'),
58
+ path.join(stigmergyCache, 'memory.json')
59
+ ];
60
+
61
+ this.mockCachePaths.forEach(file => {
62
+ fs.writeFileSync(file, 'mock cache content');
63
+ });
64
+
65
+ // Create mock Stigmergy test directory
66
+ const stigmergyTest = path.join(this.testDir, '.stigmergy-test');
67
+ fs.mkdirSync(stigmergyTest, { recursive: true });
68
+ fs.writeFileSync(path.join(stigmergyTest, 'test-config.json'), '{}');
69
+
70
+ // Create mock NPX cache directories
71
+ const npxCacheBase = path.join(this.testDir, 'npm-cache', '_npx');
72
+ fs.mkdirSync(npxCacheBase, { recursive: true });
73
+
74
+ const npxCacheIds = ['abc123', 'def456', 'ghi789'];
75
+ npxCacheIds.forEach(id => {
76
+ const npxCache = path.join(npxCacheBase, id);
77
+ fs.mkdirSync(npxCache, { recursive: true });
78
+
79
+ // Some contain Stigmergy, some don't
80
+ if (id !== 'def456') {
81
+ const stigmergyPath = path.join(npxCache, 'node_modules', 'stigmergy');
82
+ fs.mkdirSync(stigmergyPath, { recursive: true });
83
+ fs.writeFileSync(path.join(stigmergyPath, 'package.json'), '{}');
84
+ }
85
+ });
86
+
87
+ // Create mock CLI configuration caches
88
+ ['claude', 'gemini', 'qwen'].forEach(cli => {
89
+ const cliConfig = path.join(this.testDir, `.${cli}`);
90
+ fs.mkdirSync(cliConfig, { recursive: true });
91
+ fs.mkdirSync(path.join(cliConfig, 'cache'), { recursive: true });
92
+ fs.writeFileSync(path.join(cliConfig, 'cache', 'stigmergy-cache.json'), '{}');
93
+ fs.writeFileSync(path.join(cliConfig, 'stigmergy-integration.json'), '{}');
94
+ });
95
+
96
+ // Create temporary files
97
+ const tempDir = path.join(this.testDir, 'temp');
98
+ fs.mkdirSync(tempDir, { recursive: true });
99
+ fs.writeFileSync(path.join(tempDir, 'stigmergy-temp.tmp'), 'temp data');
100
+ fs.writeFileSync(path.join(tempDir, 'stigmergy-lock.lock'), 'lock file');
101
+
102
+ console.log('โœ… Cache test environment setup complete\n');
103
+ }
104
+
105
+ async testStigmergyCacheCleaning() {
106
+ console.log('๐Ÿ—‚๏ธ TEST 1: Stigmergy Cache Cleaning');
107
+
108
+ // Verify Stigmergy cache exists
109
+ const stigmergyCache = path.join(this.testDir, '.stigmergy');
110
+ const beforeCleanup = fs.existsSync(stigmergyCache);
111
+ this.assert(beforeCleanup, 'Stigmergy cache should exist before cleanup');
112
+
113
+ // TODO: After implementing CacheCleaner
114
+ // const cleaner = new CacheCleaner();
115
+ // const result = await cleaner.cleanStigmergyCache({
116
+ // includeConfig: true,
117
+ // includeCache: true,
118
+ // includeLogs: true
119
+ // });
120
+
121
+ // TODO: Verify cleanup results
122
+ // this.assert(result.removedFiles > 0, 'Should remove Stigmergy cache files');
123
+ // this.assert(!fs.existsSync(stigmergyCache), 'Stigmergy cache directory should be removed');
124
+
125
+ this.recordResult('Stigmergy Cache Cleaning', 'โณ Pending implementation');
126
+ }
127
+
128
+ async testNPXCacheCleaning() {
129
+ console.log('๐Ÿ“ฆ TEST 2: NPX Cache Cleaning');
130
+
131
+ const npxCacheBase = path.join(this.testDir, 'npm-cache', '_npx');
132
+ const beforeCleanup = fs.existsSync(npxCacheBase);
133
+ this.assert(beforeCleanup, 'NPX cache should exist before cleanup');
134
+
135
+ // Count Stigmergy entries before cleanup
136
+ const stigmergyEntriesBefore = this.countStigmergyNPXEntries(npxCacheBase);
137
+ this.assert(stigmergyEntriesBefore > 0, 'Should have Stigmergy entries in NPX cache');
138
+
139
+ // TODO: After implementing NPXCacheCleaner
140
+ // const cleaner = new NPXCacheCleaner();
141
+ // const result = await cleaner.cleanStigmergyFromNPXCache({
142
+ // dryRun: false,
143
+ // force: true
144
+ // });
145
+
146
+ // TODO: Verify cleanup
147
+ // this.assert(result.removedEntries === stigmergyEntriesBefore,
148
+ // 'Should remove all Stigmergy entries from NPX cache');
149
+ // this.assert(fs.existsSync(npxCacheBase), 'Should preserve non-Stigmergy NPX cache');
150
+
151
+ this.recordResult('NPX Cache Cleaning', 'โณ Pending implementation');
152
+ }
153
+
154
+ async testNPMCacheCleaning() {
155
+ console.log('๐Ÿ“ฆ TEST 3: NPM Cache Cleaning');
156
+
157
+ // Create mock NPM cache with Stigmergy
158
+ const npmCache = path.join(this.testDir, 'npm-cache');
159
+ const npmModules = path.join(npmCache, 'stigmergy-cli', 'node_modules');
160
+ fs.mkdirSync(npmModules, { recursive: true });
161
+ fs.writeFileSync(path.join(npmModules, 'stigmergy'), 'mock binary');
162
+
163
+ const beforeCleanup = fs.existsSync(npmModules);
164
+ this.assert(beforeCleanup, 'NPM cache should exist before cleanup');
165
+
166
+ // TODO: After implementing NPMCacheCleaner
167
+ // const cleaner = new NPMCacheCleaner();
168
+ // const result = await cleaner.cleanNPMCache({
169
+ // includeStigmergy: true,
170
+ // includeGlobal: false
171
+ // });
172
+
173
+ // TODO: Verify cleanup
174
+ // this.assert(result.success, 'NPM cache cleaning should succeed');
175
+ // this.assert(!fs.existsSync(npmModules), 'Stigmergy NPM modules should be removed');
176
+
177
+ this.recordResult('NPM Cache Cleaning', 'โณ Pending implementation');
178
+ }
179
+
180
+ async testCLIConfigCacheCleaning() {
181
+ console.log('โš™๏ธ TEST 4: CLI Configuration Cache Cleaning');
182
+
183
+ const cliConfigs = ['claude', 'gemini', 'qwen'];
184
+ const beforeCleanup = cliConfigs.every(cli => {
185
+ const cliConfig = path.join(this.testDir, `.${cli}`);
186
+ return fs.existsSync(cliConfig);
187
+ });
188
+ this.assert(beforeCleanup, 'CLI configurations should exist before cleanup');
189
+
190
+ // TODO: After implementing CLIConfigCleaner
191
+ // const cleaner = new CLIConfigCleaner();
192
+ // const result = await cleaner.cleanCLIConfigurations(cliConfigs, {
193
+ // removeStigmergyFiles: true,
194
+ // preserveNativeConfig: true
195
+ // });
196
+
197
+ // TODO: Verify cleanup
198
+ // this.assert(result.cleanedCLIs.length === cliConfigs.length,
199
+ // 'Should clean all specified CLI configurations');
200
+ // cliConfigs.forEach(cli => {
201
+ // const stigmergyFile = path.join(this.testDir, `.${cli}`, 'stigmergy-integration.json');
202
+ // this.assert(!fs.existsSync(stigmergyFile),
203
+ // `Should remove Stigmergy files from ${cli} config`);
204
+ // });
205
+
206
+ this.recordResult('CLI Config Cache Cleaning', 'โณ Pending implementation');
207
+ }
208
+
209
+ async testTemporaryFileCleanup() {
210
+ console.log('๐Ÿ—‘๏ธ TEST 5: Temporary File Cleanup');
211
+
212
+ const tempDir = path.join(this.testDir, 'temp');
213
+ const tempFiles = fs.readdirSync(tempDir);
214
+ this.assert(tempFiles.length > 0, 'Should have temporary files before cleanup');
215
+
216
+ // TODO: After implementing TempFileCleaner
217
+ // const cleaner = new TempFileCleaner();
218
+ // const result = await cleaner.cleanTemporaryFiles({
219
+ // patterns: ['*stigmergy*', '*.tmp', '*.lock'],
220
+ // directories: [tempDir, os.tmpdir()]
221
+ // });
222
+
223
+ // TODO: Verify cleanup
224
+ // this.assert(result.removedFiles.length > 0, 'Should remove temporary files');
225
+ // const remainingFiles = fs.readdirSync(tempDir).filter(f =>
226
+ // f.includes('stigmergy') || f.endsWith('.tmp') || f.endsWith('.lock')
227
+ // );
228
+ // this.assert(remainingFiles.length === 0, 'Should remove all Stigmergy temporary files');
229
+
230
+ this.recordResult('Temporary File Cleanup', 'โณ Pending implementation');
231
+ }
232
+
233
+ async testSelectiveCacheCleaning() {
234
+ console.log('๐ŸŽฏ TEST 6: Selective Cache Cleaning');
235
+
236
+ // Create selective cache structure
237
+ const selectiveCache = path.join(this.testDir, '.stigmergy-selective');
238
+ fs.mkdirSync(selectiveCache, { recursive: true });
239
+ fs.mkdirSync(path.join(selectiveCache, 'important'), { recursive: true });
240
+ fs.mkdirSync(path.join(selectiveCache, 'cache'), { recursive: true });
241
+
242
+ fs.writeFileSync(path.join(selectiveCache, 'important', 'user-backup.json'), '{}');
243
+ fs.writeFileSync(path.join(selectiveCache, 'cache', 'auto-cache.tmp'), 'temp');
244
+
245
+ // TODO: After implementing selective cleaning
246
+ // const cleaner = new CacheCleaner();
247
+ // const result = await cleaner.selectiveClean({
248
+ // targetDirectory: selectiveCache,
249
+ // preservePatterns: ['**/important/**', '*.backup.json'],
250
+ // removePatterns: ['**/cache/**', '*.tmp']
251
+ // });
252
+
253
+ // TODO: Verify selective cleanup
254
+ // this.assert(fs.existsSync(path.join(selectiveCache, 'important', 'user-backup.json')),
255
+ // 'Should preserve important files');
256
+ // this.assert(!fs.existsSync(path.join(selectiveCache, 'cache')),
257
+ // 'Should remove cache directories');
258
+
259
+ this.recordResult('Selective Cache Cleaning', 'โณ Pending implementation');
260
+ }
261
+
262
+ async testCacheCleaningPerformance() {
263
+ console.log('โšก TEST 7: Cache Cleaning Performance');
264
+
265
+ // Create many small cache files for performance testing
266
+ const perfCache = path.join(this.testDir, '.stigmergy-perf');
267
+ fs.mkdirSync(perfCache, { recursive: true });
268
+
269
+ for (let i = 0; i < 100; i++) {
270
+ fs.writeFileSync(path.join(perfCache, `cache-${i}.tmp`), `data ${i}`);
271
+ }
272
+
273
+ const startTime = Date.now();
274
+
275
+ // TODO: After implementing performance-optimized cleaner
276
+ // const cleaner = new CacheCleaner();
277
+ // const result = await cleaner.cleanWithPerformance({
278
+ // targetDirectory: perfCache,
279
+ // batchSize: 10,
280
+ // parallel: true
281
+ // });
282
+
283
+ const endTime = Date.now();
284
+ const duration = endTime - startTime;
285
+
286
+ // TODO: Verify performance requirements
287
+ // this.assert(duration < 5000, 'Cache cleaning should complete within 5 seconds');
288
+ // this.assert(result.removedFiles === 100, 'Should remove all cache files');
289
+
290
+ this.recordResult('Cache Cleaning Performance', `โณ Pending (${duration}ms)`);
291
+ }
292
+
293
+ async testErrorRecovery() {
294
+ console.log('๐Ÿ›ก๏ธ TEST 8: Error Recovery');
295
+
296
+ // Test with protected/locked files
297
+ const protectedFile = path.join(this.testDir, 'protected-stigmergy.lock');
298
+ fs.writeFileSync(protectedFile, 'protected');
299
+
300
+ // Test with non-existent paths
301
+ const nonExistent = path.join(this.testDir, 'does-not-exist');
302
+
303
+ // TODO: After implementing error recovery
304
+ // const cleaner = new CacheCleaner();
305
+ //
306
+ // // Should handle non-existent paths gracefully
307
+ // const result1 = await cleaner.cleanDirectory(nonExistent);
308
+ // this.assert(!result1.error, 'Should handle non-existent paths');
309
+ //
310
+ // // Should handle permission errors gracefully
311
+ // const result2 = await cleaner.cleanFile(protectedFile);
312
+ // this.assert(result2.error, 'Should detect permission errors');
313
+ // this.assert(result2.action === 'skip', 'Should skip protected files');
314
+ //
315
+ // // Should continue processing despite errors
316
+ // const result3 = await cleaner.batchClean([nonExistent, protectedFile]);
317
+ // this.assert(result3.processed > 0 || result3.errors.length > 0,
318
+ // 'Should process batch with mixed results');
319
+
320
+ this.recordResult('Error Recovery', 'โณ Pending implementation');
321
+ }
322
+
323
+ countStigmergyNPXEntries(npxCacheBase) {
324
+ let count = 0;
325
+ if (fs.existsSync(npxCacheBase)) {
326
+ const entries = fs.readdirSync(npxCacheBase);
327
+ entries.forEach(entry => {
328
+ const stigmergyPath = path.join(npxCacheBase, entry, 'node_modules', 'stigmergy');
329
+ if (fs.existsSync(stigmergyPath)) {
330
+ count++;
331
+ }
332
+ });
333
+ }
334
+ return count;
335
+ }
336
+
337
+ assert(condition, message) {
338
+ if (condition) {
339
+ console.log(` โœ… ${message}`);
340
+ } else {
341
+ console.log(` โŒ ${message}`);
342
+ throw new Error(`Assertion failed: ${message}`);
343
+ }
344
+ }
345
+
346
+ recordResult(testName, status) {
347
+ this.testResults.push({ name: testName, status });
348
+ }
349
+
350
+ printResults() {
351
+ console.log('\n๐Ÿ“Š CACHE CLEANER TEST RESULTS:');
352
+ console.log('=' .repeat(50));
353
+
354
+ this.testResults.forEach(result => {
355
+ console.log(`${result.status} ${result.name}`);
356
+ });
357
+
358
+ const pending = this.testResults.filter(r => r.status.includes('Pending')).length;
359
+ const total = this.testResults.length;
360
+
361
+ console.log('\n๐Ÿ“ˆ Summary:');
362
+ console.log(`Total tests: ${total}`);
363
+ console.log(`Pending implementation: ${pending}`);
364
+ console.log(`Ready for implementation: ${pending}/${total}`);
365
+
366
+ if (pending === total) {
367
+ console.log('\n๐Ÿš€ All cache cleaner test cases defined successfully!');
368
+ console.log('๐Ÿ’ก Ready to implement the comprehensive cache cleaning functionality.');
369
+ }
370
+ }
371
+
372
+ async cleanupTestEnvironment() {
373
+ console.log('\n๐Ÿงน Cleaning up cache test environment...');
374
+
375
+ try {
376
+ fs.rmSync(this.testDir, { recursive: true, force: true });
377
+ console.log('โœ… Cache test environment cleaned up');
378
+ } catch (error) {
379
+ console.warn('โš ๏ธ Warning: Could not clean up cache test environment:', error.message);
380
+ }
381
+ }
382
+ }
383
+
384
+ // Run tests if this file is executed directly
385
+ if (require.main === module) {
386
+ const tests = new CacheCleanerTests();
387
+ tests.runAllTests().catch(console.error);
388
+ }
389
+
390
+ module.exports = CacheCleanerTests;
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Comprehensive Enhanced Features Test
3
+ *
4
+ * Tests all enhanced installation and uninstallation features together
5
+ */
6
+
7
+ const EnhancedInstaller = require('../src/core/enhanced_installer');
8
+ const EnhancedUninstaller = require('../src/core/enhanced_uninstaller');
9
+ const CacheCleaner = require('../src/core/cache_cleaner');
10
+
11
+ class ComprehensiveEnhancedFeaturesTest {
12
+ constructor() {
13
+ this.testResults = [];
14
+ }
15
+
16
+ async runAllTests() {
17
+ console.log('๐Ÿงช Running Comprehensive Enhanced Features Tests...\n');
18
+
19
+ try {
20
+ await this.testEnhancedInstallerPlan();
21
+ await this.testCacheCleanerStandalone();
22
+ await this.testEnhancedUninstallerPlan();
23
+ await this.testIntegrationWorkflow();
24
+
25
+ this.printResults();
26
+ } catch (error) {
27
+ console.error('โŒ Test suite failed:', error.message);
28
+ this.testResults.push({
29
+ name: 'Test Suite',
30
+ status: 'โŒ',
31
+ error: error.message
32
+ });
33
+ }
34
+ }
35
+
36
+ async testEnhancedInstallerPlan() {
37
+ console.log('๐Ÿ“‹ TEST 1: Enhanced Installer Plan Creation');
38
+
39
+ try {
40
+ const installer = new EnhancedInstaller({
41
+ dryRun: true,
42
+ verbose: false
43
+ });
44
+
45
+ // Create installation plan
46
+ const plan = await installer.createInstallationPlan();
47
+
48
+ // Verify plan structure
49
+ this.assert(plan !== undefined, 'Should create installation plan');
50
+ this.assert(typeof plan.estimatedTime === 'number', 'Should estimate installation time');
51
+ this.assert(typeof plan.estimatedSpace === 'number', 'Should estimate required space');
52
+
53
+ console.log(` โœ… Plan created with ${plan.installation.toolCount} tools to install`);
54
+ console.log(` โฑ๏ธ Estimated time: ${Math.ceil(plan.estimatedTime / 1000)} seconds`);
55
+ console.log(` ๐Ÿ’พ Estimated space: ${this.formatBytes(plan.estimatedSpace)}`);
56
+
57
+ this.recordResult('Enhanced Installer Plan', 'โœ…');
58
+
59
+ } catch (error) {
60
+ console.log(` โŒ Error: ${error.message}`);
61
+ this.recordResult('Enhanced Installer Plan', 'โŒ');
62
+ }
63
+ }
64
+
65
+ async testCacheCleanerStandalone() {
66
+ console.log('๐Ÿงน TEST 2: Cache Cleaner Standalone');
67
+
68
+ try {
69
+ const cleaner = new CacheCleaner({
70
+ dryRun: true,
71
+ verbose: false
72
+ });
73
+
74
+ // Test selective cleaning
75
+ const testDir = require('os').tmpdir();
76
+ await cleaner.selectiveClean(testDir, {
77
+ preservePatterns: ['*.log'],
78
+ removePatterns: ['*.tmp']
79
+ });
80
+
81
+ // Test performance mode (dry run)
82
+ await cleaner.cleanWithPerformance(testDir, {
83
+ batchSize: 10,
84
+ parallel: false
85
+ });
86
+
87
+ console.log(' โœ… Selective cleaning test passed');
88
+ console.log(' โœ… Performance mode test passed');
89
+
90
+ this.recordResult('Cache Cleaner Standalone', 'โœ…');
91
+
92
+ } catch (error) {
93
+ console.log(` โŒ Error: ${error.message}`);
94
+ this.recordResult('Cache Cleaner Standalone', 'โŒ');
95
+ }
96
+ }
97
+
98
+ async testEnhancedUninstallerPlan() {
99
+ console.log('๐Ÿ—‘๏ธ TEST 3: Enhanced Uninstaller Plan');
100
+
101
+ try {
102
+ const uninstaller = new EnhancedUninstaller({
103
+ dryRun: true,
104
+ verbose: false
105
+ });
106
+
107
+ // Create uninstall plan
108
+ const plan = await uninstaller.createUninstallPlan();
109
+
110
+ // Verify plan structure
111
+ this.assert(plan !== undefined, 'Should create uninstall plan');
112
+ this.assert(Array.isArray(plan.files), 'Should list files to remove');
113
+ this.assert(Array.isArray(plan.directories), 'Should list directories to remove');
114
+
115
+ console.log(` โœ… Uninstall plan created`);
116
+ console.log(` ๐Ÿ“ Files to remove: ${plan.files.length}`);
117
+ console.log(` ๐Ÿ“‚ Directories to remove: ${plan.directories.length}`);
118
+ console.log(` ๐Ÿ’พ Estimated space to free: ${this.formatBytes(plan.estimatedSize)}`);
119
+
120
+ this.recordResult('Enhanced Uninstaller Plan', 'โœ…');
121
+
122
+ } catch (error) {
123
+ console.log(` โŒ Error: ${error.message}`);
124
+ this.recordResult('Enhanced Uninstaller Plan', 'โŒ');
125
+ }
126
+ }
127
+
128
+ async testIntegrationWorkflow() {
129
+ console.log('๐Ÿ”„ TEST 4: Integration Workflow');
130
+
131
+ try {
132
+ // Test 1: Cache cleaner dry run
133
+ const cleaner = new CacheCleaner({ dryRun: true });
134
+ const cleanResults = await cleaner.cleanAllCaches({
135
+ cleanStigmergy: false,
136
+ cleanNPX: false,
137
+ cleanNPM: false,
138
+ cleanCLI: false,
139
+ cleanTemp: true
140
+ });
141
+
142
+ this.assert(cleanResults.filesRemoved === 0, 'Dry run should not remove files');
143
+
144
+ // Test 2: Enhanced installer dry run
145
+ const installer = new EnhancedInstaller({
146
+ dryRun: true,
147
+ cleanBeforeInstall: true,
148
+ cleanTempFiles: true
149
+ });
150
+
151
+ const installResults = await installer.enhancedInstall({
152
+ cleanStigmergy: false,
153
+ cleanNPX: false,
154
+ cleanNPM: false,
155
+ cleanCLI: false,
156
+ cleanTemp: true
157
+ });
158
+
159
+ this.assert(installResults.cacheCleaning.success, 'Cache cleaning should succeed in dry run');
160
+
161
+ // Test 3: Enhanced uninstaller dry run
162
+ const uninstaller = new EnhancedUninstaller({ dryRun: true });
163
+ const uninstallResults = await uninstaller.completeUninstall();
164
+
165
+ this.assert(uninstallResults.filesRemoved === 0, 'Dry run uninstall should not remove files');
166
+
167
+ console.log(' โœ… Cache cleaner workflow test passed');
168
+ console.log(' โœ… Enhanced installer workflow test passed');
169
+ console.log(' โœ… Enhanced uninstaller workflow test passed');
170
+
171
+ this.recordResult('Integration Workflow', 'โœ…');
172
+
173
+ } catch (error) {
174
+ console.log(` โŒ Error: ${error.message}`);
175
+ this.recordResult('Integration Workflow', 'โŒ');
176
+ }
177
+ }
178
+
179
+ formatBytes(bytes) {
180
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
181
+ if (bytes === 0) return '0 Bytes';
182
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
183
+ return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
184
+ }
185
+
186
+ assert(condition, message) {
187
+ if (condition) {
188
+ console.log(` โœ… ${message}`);
189
+ } else {
190
+ console.log(` โŒ ${message}`);
191
+ throw new Error(`Assertion failed: ${message}`);
192
+ }
193
+ }
194
+
195
+ recordResult(testName, status) {
196
+ this.testResults.push({ name: testName, status });
197
+ }
198
+
199
+ printResults() {
200
+ console.log('\n๐Ÿ“Š COMPREHENSIVE ENHANCED FEATURES TEST RESULTS:');
201
+ console.log('=' .repeat(60));
202
+
203
+ this.testResults.forEach(result => {
204
+ if (result.error) {
205
+ console.log(`${result.status} ${result.name}: ${result.error}`);
206
+ } else {
207
+ console.log(`${result.status} ${result.name}`);
208
+ }
209
+ });
210
+
211
+ const passed = this.testResults.filter(r => r.status === 'โœ…').length;
212
+ const total = this.testResults.length;
213
+
214
+ console.log('\n๐Ÿ“ˆ Summary:');
215
+ console.log(`Total tests: ${total}`);
216
+ console.log(`Passed: ${passed}`);
217
+ console.log(`Failed: ${total - passed}`);
218
+
219
+ if (passed === total) {
220
+ console.log('\n๐ŸŽ‰ All enhanced features tests passed!');
221
+ console.log('โœ… Enhanced installation and uninstallation features are ready!');
222
+ console.log('\n๐Ÿ“š Available Features:');
223
+ console.log(' ๐Ÿ” Dry run mode for all operations');
224
+ console.log(' ๐Ÿงน Comprehensive cache cleaning');
225
+ console.log(' ๐Ÿ“ฆ Enhanced installer with pre-cleaning');
226
+ console.log(' ๐Ÿ—‘๏ธ Complete uninstaller with full cleanup');
227
+ console.log(' โšก Performance-optimized operations');
228
+ console.log(' ๐ŸŽฏ Selective cleaning with patterns');
229
+ console.log(' ๐Ÿ›ก๏ธ Error recovery and force mode');
230
+ } else {
231
+ console.log('\nโŒ Some tests failed. Review the implementation.');
232
+ }
233
+
234
+ console.log('\n๐Ÿ’ก Usage Examples:');
235
+ console.log(' # Create installation plan');
236
+ console.log(' node -e "const EI=require(\'./src/core/enhanced_installer\'); new EI().createInstallationPlan()"');
237
+ console.log('');
238
+ console.log(' # Quick cache clean');
239
+ console.log(' node -e "const EI=require(\'./src/core/enhanced_installer\'); new EI().quickCacheClean()"');
240
+ console.log('');
241
+ console.log(' # Dry run uninstall');
242
+ console.log(' node -e "const EU=require(\'./src/core/enhanced_uninstaller\'); new EU({dryRun:true}).completeUninstall()"');
243
+ }
244
+ }
245
+
246
+ // Run tests if this file is executed directly
247
+ if (require.main === module) {
248
+ const tests = new ComprehensiveEnhancedFeaturesTest();
249
+ tests.runAllTests().catch(console.error);
250
+ }
251
+
252
+ module.exports = ComprehensiveEnhancedFeaturesTest;