stigmergy 1.0.89 → 1.0.93
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/README.md +202 -189
- package/bin/stigmergy +12 -0
- package/bin/stigmergy.cmd +5 -0
- package/docs/CONFLICT_PREVENTION.md +150 -0
- package/package.json +12 -6
- package/scripts/post-deployment-config.js +289 -0
- package/scripts/preinstall-check.js +111 -0
- package/scripts/safe-install.js +139 -0
- package/src/main.js +963 -892
- package/src/main_english.js +179 -35
- package/test/comprehensive-execution-test.js +428 -0
- package/test/conflict-prevention-test.js +95 -0
- package/test/deploy-hooks-test.js +250 -0
- package/test/error-handling-test.js +341 -0
- package/test/final-deploy-test.js +221 -0
- package/test/final-install-test.js +226 -0
- package/test/iflow-integration-test.js +292 -0
- package/test/improved-install-test.js +362 -0
- package/test/install-command-test.js +370 -0
- package/test/plugin-deployment-test.js +316 -0
- package/test/postinstall-test.js +269 -0
- package/test/simple-iflow-hook-test.js +137 -0
- package/test/tdd-deploy-fix-test.js +324 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TDD Test for deployHooks Functionality
|
|
5
|
+
* This test verifies that the deployHooks function properly installs and configures CLI tools
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs').promises;
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
const { spawn } = require('child_process');
|
|
12
|
+
|
|
13
|
+
class DeployHooksTester {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.testResults = [];
|
|
16
|
+
this.stigmergyAssetsDir = path.join(os.homedir(), '.stigmergy', 'assets', 'adapters');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Test 1: Verify deployHooks copies adapter files correctly
|
|
20
|
+
async testAdapterFileCopy() {
|
|
21
|
+
console.log('[TEST 1] Verifying adapter file copying...');
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// Check if adapter directories exist in assets
|
|
25
|
+
const adapterDirs = await fs.readdir(this.stigmergyAssetsDir);
|
|
26
|
+
console.log(` Found adapter directories: ${adapterDirs.join(', ')}`);
|
|
27
|
+
|
|
28
|
+
// Check if key adapter files exist
|
|
29
|
+
const expectedFiles = {
|
|
30
|
+
'iflow': ['hook_adapter.py', 'install_iflow_integration.py'],
|
|
31
|
+
'claude': ['hook_adapter.py', 'install_claude_integration.py'],
|
|
32
|
+
'qoder': ['notification_hook_adapter.py', 'install_qoder_integration.py']
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let allFilesExist = true;
|
|
36
|
+
for (const [tool, files] of Object.entries(expectedFiles)) {
|
|
37
|
+
const toolDir = path.join(this.stigmergyAssetsDir, tool);
|
|
38
|
+
try {
|
|
39
|
+
const dirFiles = await fs.readdir(toolDir);
|
|
40
|
+
console.log(` ${tool} adapter files: ${dirFiles.join(', ')}`);
|
|
41
|
+
|
|
42
|
+
for (const expectedFile of files) {
|
|
43
|
+
if (!dirFiles.includes(expectedFile)) {
|
|
44
|
+
console.log(` ✗ Missing file: ${expectedFile} in ${tool}`);
|
|
45
|
+
allFilesExist = false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.log(` ✗ Cannot access ${tool} adapter directory: ${error.message}`);
|
|
50
|
+
allFilesExist = false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.testResults.push({
|
|
55
|
+
name: 'Adapter File Copy',
|
|
56
|
+
passed: allFilesExist,
|
|
57
|
+
details: 'Verified adapter files exist in assets directory'
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return allFilesExist;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.log(` ✗ Failed to check adapter files: ${error.message}`);
|
|
63
|
+
this.testResults.push({
|
|
64
|
+
name: 'Adapter File Copy',
|
|
65
|
+
passed: false,
|
|
66
|
+
details: `Failed to check adapter files: ${error.message}`
|
|
67
|
+
});
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Test 2: Verify installation script execution
|
|
73
|
+
async testInstallationScriptExecution() {
|
|
74
|
+
console.log('\n[TEST 2] Verifying installation script execution...');
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
// Check if post-deployment config script exists
|
|
78
|
+
const postDeployScript = path.join(__dirname, '..', 'scripts', 'post-deployment-config.js');
|
|
79
|
+
await fs.access(postDeployScript);
|
|
80
|
+
console.log(' ✓ Post-deployment config script exists');
|
|
81
|
+
|
|
82
|
+
// Try to import and test the PostDeploymentConfigurer
|
|
83
|
+
const { PostDeploymentConfigurer } = require('../scripts/post-deployment-config.js');
|
|
84
|
+
const configurer = new PostDeploymentConfigurer();
|
|
85
|
+
|
|
86
|
+
// Test checking install script for a tool
|
|
87
|
+
const scriptCheck = await configurer.checkInstallScript('iflow');
|
|
88
|
+
console.log(` iFlow install script check: ${scriptCheck.exists ? '✓ Found' : '✗ Not found'}`);
|
|
89
|
+
console.log(` Script path: ${scriptCheck.path}`);
|
|
90
|
+
|
|
91
|
+
this.testResults.push({
|
|
92
|
+
name: 'Installation Script Execution',
|
|
93
|
+
passed: scriptCheck.exists,
|
|
94
|
+
details: `iFlow install script ${scriptCheck.exists ? 'found' : 'not found'}`
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return scriptCheck.exists;
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.log(` ✗ Failed to test installation script execution: ${error.message}`);
|
|
100
|
+
this.testResults.push({
|
|
101
|
+
name: 'Installation Script Execution',
|
|
102
|
+
passed: false,
|
|
103
|
+
details: `Failed to test: ${error.message}`
|
|
104
|
+
});
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Test 3: Verify hook configuration files are created
|
|
110
|
+
async testHookConfigurationCreation() {
|
|
111
|
+
console.log('\n[TEST 3] Verifying hook configuration creation...');
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
// Check common hook configuration locations
|
|
115
|
+
const configPaths = [
|
|
116
|
+
path.join(os.homedir(), '.config', 'iflow', 'hooks.yml'),
|
|
117
|
+
path.join(os.homedir(), '.config', 'claude', 'hooks.json'),
|
|
118
|
+
path.join(os.homedir(), '.qoder', 'config.json')
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
let configsFound = 0;
|
|
122
|
+
for (const configPath of configPaths) {
|
|
123
|
+
try {
|
|
124
|
+
await fs.access(configPath);
|
|
125
|
+
console.log(` ✓ Configuration found: ${configPath}`);
|
|
126
|
+
configsFound++;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.log(` ✗ Configuration not found: ${configPath}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const passed = configsFound > 0;
|
|
133
|
+
this.testResults.push({
|
|
134
|
+
name: 'Hook Configuration Creation',
|
|
135
|
+
passed: passed,
|
|
136
|
+
details: `Found ${configsFound}/${configPaths.length} configuration files`
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
return passed;
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.log(` ✗ Failed to check hook configurations: ${error.message}`);
|
|
142
|
+
this.testResults.push({
|
|
143
|
+
name: 'Hook Configuration Creation',
|
|
144
|
+
passed: false,
|
|
145
|
+
details: `Failed to check: ${error.message}`
|
|
146
|
+
});
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Test 4: Verify deployHooks function integration
|
|
152
|
+
async testDeployHooksIntegration() {
|
|
153
|
+
console.log('\n[TEST 4] Verifying deployHooks function integration...');
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
// Try to import and test the deployHooks function
|
|
157
|
+
const { StigmergyInstaller } = require('../src/main_english.js');
|
|
158
|
+
const installer = new StigmergyInstaller();
|
|
159
|
+
|
|
160
|
+
// Check if deployHooks method exists
|
|
161
|
+
if (typeof installer.deployHooks === 'function') {
|
|
162
|
+
console.log(' ✓ deployHooks method exists');
|
|
163
|
+
|
|
164
|
+
this.testResults.push({
|
|
165
|
+
name: 'DeployHooks Integration',
|
|
166
|
+
passed: true,
|
|
167
|
+
details: 'deployHooks method exists in StigmergyInstaller'
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
return true;
|
|
171
|
+
} else {
|
|
172
|
+
console.log(' ✗ deployHooks method not found');
|
|
173
|
+
|
|
174
|
+
this.testResults.push({
|
|
175
|
+
name: 'DeployHooks Integration',
|
|
176
|
+
passed: false,
|
|
177
|
+
details: 'deployHooks method not found in StigmergyInstaller'
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.log(` ✗ Failed to test deployHooks integration: ${error.message}`);
|
|
184
|
+
this.testResults.push({
|
|
185
|
+
name: 'DeployHooks Integration',
|
|
186
|
+
passed: false,
|
|
187
|
+
details: `Failed to test: ${error.message}`
|
|
188
|
+
});
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Run all tests
|
|
194
|
+
async runAllTests() {
|
|
195
|
+
console.log('TDD Test for deployHooks Functionality');
|
|
196
|
+
console.log('='.repeat(50));
|
|
197
|
+
|
|
198
|
+
await this.testAdapterFileCopy();
|
|
199
|
+
await this.testInstallationScriptExecution();
|
|
200
|
+
await this.testHookConfigurationCreation();
|
|
201
|
+
await this.testDeployHooksIntegration();
|
|
202
|
+
|
|
203
|
+
// Summary
|
|
204
|
+
console.log('\n' + '='.repeat(50));
|
|
205
|
+
console.log('Test Summary:');
|
|
206
|
+
console.log('='.repeat(50));
|
|
207
|
+
|
|
208
|
+
let passedTests = 0;
|
|
209
|
+
this.testResults.forEach(result => {
|
|
210
|
+
console.log(`${result.name}: ${result.passed ? '✓ PASS' : '✗ FAIL'} - ${result.details}`);
|
|
211
|
+
if (result.passed) passedTests++;
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
console.log(`\nOverall Result: ${passedTests}/${this.testResults.length} tests passed`);
|
|
215
|
+
|
|
216
|
+
if (passedTests === this.testResults.length) {
|
|
217
|
+
console.log('✓ All tests passed! deployHooks functionality is working correctly.');
|
|
218
|
+
} else if (passedTests > 0) {
|
|
219
|
+
console.log('⚠ Some tests failed. deployHooks functionality needs improvement.');
|
|
220
|
+
} else {
|
|
221
|
+
console.log('✗ All tests failed. deployHooks functionality is not working.');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
totalTests: this.testResults.length,
|
|
226
|
+
passedTests: passedTests,
|
|
227
|
+
results: this.testResults
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Run the tests
|
|
233
|
+
async function runDeployHooksTests() {
|
|
234
|
+
const tester = new DeployHooksTester();
|
|
235
|
+
const results = await tester.runAllTests();
|
|
236
|
+
return results;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Export for use in other modules
|
|
240
|
+
module.exports = { DeployHooksTester };
|
|
241
|
+
|
|
242
|
+
// Run if called directly
|
|
243
|
+
if (require.main === module) {
|
|
244
|
+
runDeployHooksTests().then(results => {
|
|
245
|
+
process.exit(results.passedTests === results.totalTests ? 0 : 1);
|
|
246
|
+
}).catch(error => {
|
|
247
|
+
console.error('[Test Failed]:', error.message);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Enhanced Error Handling Test for Stigmergy Auto-Install
|
|
5
|
+
* This test verifies that error handling is properly implemented
|
|
6
|
+
* in the auto-install process to ensure graceful degradation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const fs = require('fs').promises;
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
class ErrorHandlingTester {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.testResults = [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Test 1: Verify try-catch blocks in auto-install section
|
|
18
|
+
async testAutoInstallTryCatch() {
|
|
19
|
+
console.log('[TEST 1] Verifying try-catch blocks in auto-install section...');
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
// Read main script
|
|
23
|
+
const mainScriptPath = path.join(__dirname, '..', 'src', 'main_english.js');
|
|
24
|
+
const mainScript = await fs.readFile(mainScriptPath, 'utf8');
|
|
25
|
+
|
|
26
|
+
// Extract auto-install section
|
|
27
|
+
const autoInstallStart = mainScript.indexOf('case \'auto-install\':');
|
|
28
|
+
if (autoInstallStart === -1) {
|
|
29
|
+
console.log(' ✗ auto-install case not found');
|
|
30
|
+
this.testResults.push({
|
|
31
|
+
name: 'Auto-Install Try-Catch Blocks',
|
|
32
|
+
passed: false,
|
|
33
|
+
details: 'auto-install case not found'
|
|
34
|
+
});
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Find the end of the auto-install case (next case or default)
|
|
39
|
+
const nextCaseStart = mainScript.indexOf('case ', autoInstallStart + 1);
|
|
40
|
+
const defaultStart = mainScript.indexOf('default:', autoInstallStart + 1);
|
|
41
|
+
|
|
42
|
+
let autoInstallEnd = mainScript.length;
|
|
43
|
+
if (nextCaseStart !== -1) {
|
|
44
|
+
autoInstallEnd = nextCaseStart;
|
|
45
|
+
} else if (defaultStart !== -1) {
|
|
46
|
+
autoInstallEnd = defaultStart;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const autoInstallSection = mainScript.substring(autoInstallStart, autoInstallEnd);
|
|
50
|
+
|
|
51
|
+
// Check for try-catch blocks
|
|
52
|
+
const hasTryBlock = autoInstallSection.includes('try {');
|
|
53
|
+
const hasCatchBlock = autoInstallSection.includes('catch');
|
|
54
|
+
|
|
55
|
+
if (hasTryBlock && hasCatchBlock) {
|
|
56
|
+
console.log(' ✓ try-catch blocks found in auto-install section');
|
|
57
|
+
} else {
|
|
58
|
+
console.log(` ⚠ try-catch blocks: try=${hasTryBlock}, catch=${hasCatchBlock}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
this.testResults.push({
|
|
62
|
+
name: 'Auto-Install Try-Catch Blocks',
|
|
63
|
+
passed: hasTryBlock && hasCatchBlock,
|
|
64
|
+
details: `try: ${hasTryBlock}, catch: ${hasCatchBlock}`
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return hasTryBlock && hasCatchBlock;
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.log(` ✗ Failed to check try-catch blocks: ${error.message}`);
|
|
70
|
+
this.testResults.push({
|
|
71
|
+
name: 'Auto-Install Try-Catch Blocks',
|
|
72
|
+
passed: false,
|
|
73
|
+
details: `Failed to check: ${error.message}`
|
|
74
|
+
});
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Test 2: Verify individual step error handling
|
|
80
|
+
async testIndividualStepErrorHandling() {
|
|
81
|
+
console.log('\n[TEST 2] Verifying individual step error handling...');
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
// Read main script
|
|
85
|
+
const mainScriptPath = path.join(__dirname, '..', 'src', 'main_english.js');
|
|
86
|
+
const mainScript = await fs.readFile(mainScriptPath, 'utf8');
|
|
87
|
+
|
|
88
|
+
// Extract auto-install section
|
|
89
|
+
const autoInstallStart = mainScript.indexOf('case \'auto-install\':');
|
|
90
|
+
if (autoInstallStart === -1) {
|
|
91
|
+
console.log(' ✗ auto-install case not found');
|
|
92
|
+
this.testResults.push({
|
|
93
|
+
name: 'Individual Step Error Handling',
|
|
94
|
+
passed: false,
|
|
95
|
+
details: 'auto-install case not found'
|
|
96
|
+
});
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Find the end of the auto-install case
|
|
101
|
+
const nextCaseStart = mainScript.indexOf('case ', autoInstallStart + 1);
|
|
102
|
+
const defaultStart = mainScript.indexOf('default:', autoInstallStart + 1);
|
|
103
|
+
|
|
104
|
+
let autoInstallEnd = mainScript.length;
|
|
105
|
+
if (nextCaseStart !== -1) {
|
|
106
|
+
autoInstallEnd = nextCaseStart;
|
|
107
|
+
} else if (defaultStart !== -1) {
|
|
108
|
+
autoInstallEnd = defaultStart;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const autoInstallSection = mainScript.substring(autoInstallStart, autoInstallEnd);
|
|
112
|
+
|
|
113
|
+
// Check for error handling in individual steps
|
|
114
|
+
const steps = [
|
|
115
|
+
'downloadRequiredAssets',
|
|
116
|
+
'scanCLI',
|
|
117
|
+
'deployHooks',
|
|
118
|
+
'deployProjectDocumentation',
|
|
119
|
+
'initializeConfig'
|
|
120
|
+
];
|
|
121
|
+
|
|
122
|
+
let stepsWithAwait = 0;
|
|
123
|
+
let stepsWithErrorHandling = 0;
|
|
124
|
+
|
|
125
|
+
for (const step of steps) {
|
|
126
|
+
if (autoInstallSection.includes(step)) {
|
|
127
|
+
stepsWithAwait++;
|
|
128
|
+
// Check if the step call is wrapped in try-catch or has error handling
|
|
129
|
+
const stepIndex = autoInstallSection.indexOf(step);
|
|
130
|
+
const contextBefore = autoInstallSection.substring(Math.max(0, stepIndex - 100), stepIndex);
|
|
131
|
+
const contextAfter = autoInstallSection.substring(stepIndex, Math.min(autoInstallSection.length, stepIndex + 100));
|
|
132
|
+
const context = contextBefore + contextAfter;
|
|
133
|
+
|
|
134
|
+
if (context.includes('try') || context.includes('catch') || context.includes('.catch')) {
|
|
135
|
+
stepsWithErrorHandling++;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.log(` Steps with await: ${stepsWithAwait}/${steps.length}`);
|
|
141
|
+
console.log(` Steps with error handling: ${stepsWithErrorHandling}/${stepsWithAwait}`);
|
|
142
|
+
|
|
143
|
+
// Even if not all steps have explicit error handling, the main try-catch should cover them
|
|
144
|
+
const adequateErrorHandling = stepsWithAwait > 0; // At least some steps are called
|
|
145
|
+
|
|
146
|
+
this.testResults.push({
|
|
147
|
+
name: 'Individual Step Error Handling',
|
|
148
|
+
passed: adequateErrorHandling,
|
|
149
|
+
details: `Steps with await: ${stepsWithAwait}/${steps.length}, Steps with error handling: ${stepsWithErrorHandling}/${stepsWithAwait}`
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return adequateErrorHandling;
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.log(` ✗ Failed to check individual step error handling: ${error.message}`);
|
|
155
|
+
this.testResults.push({
|
|
156
|
+
name: 'Individual Step Error Handling',
|
|
157
|
+
passed: false,
|
|
158
|
+
details: `Failed to check: ${error.message}`
|
|
159
|
+
});
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Test 3: Verify error messages and user guidance
|
|
165
|
+
async testErrorMessagesAndGuidance() {
|
|
166
|
+
console.log('\n[TEST 3] Verifying error messages and user guidance...');
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
// Read main script
|
|
170
|
+
const mainScriptPath = path.join(__dirname, '..', 'src', 'main_english.js');
|
|
171
|
+
const mainScript = await fs.readFile(mainScriptPath, 'utf8');
|
|
172
|
+
|
|
173
|
+
// Extract auto-install section
|
|
174
|
+
const autoInstallStart = mainScript.indexOf('case \'auto-install\':');
|
|
175
|
+
if (autoInstallStart === -1) {
|
|
176
|
+
console.log(' ✗ auto-install case not found');
|
|
177
|
+
this.testResults.push({
|
|
178
|
+
name: 'Error Messages and Guidance',
|
|
179
|
+
passed: false,
|
|
180
|
+
details: 'auto-install case not found'
|
|
181
|
+
});
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Find the end of the auto-install case
|
|
186
|
+
const nextCaseStart = mainScript.indexOf('case ', autoInstallStart + 1);
|
|
187
|
+
const defaultStart = mainScript.indexOf('default:', autoInstallStart + 1);
|
|
188
|
+
|
|
189
|
+
let autoInstallEnd = mainScript.length;
|
|
190
|
+
if (nextCaseStart !== -1) {
|
|
191
|
+
autoInstallEnd = nextCaseStart;
|
|
192
|
+
} else if (defaultStart !== -1) {
|
|
193
|
+
autoInstallEnd = defaultStart;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const autoInstallSection = mainScript.substring(autoInstallStart, autoInstallEnd);
|
|
197
|
+
|
|
198
|
+
// Check for error messages and guidance
|
|
199
|
+
const hasErrorMessages = autoInstallSection.includes('[ERROR]') ||
|
|
200
|
+
autoInstallSection.includes('console.error');
|
|
201
|
+
const hasUserGuidance = autoInstallSection.includes('[INFO]') ||
|
|
202
|
+
autoInstallSection.includes('please run') ||
|
|
203
|
+
autoInstallSection.includes('stigmergy install') ||
|
|
204
|
+
autoInstallSection.includes('stigmergy setup');
|
|
205
|
+
const hasSuccessMessage = autoInstallSection.includes('[SUCCESS]') ||
|
|
206
|
+
autoInstallSection.includes('successfully');
|
|
207
|
+
|
|
208
|
+
console.log(` Error messages: ${hasErrorMessages}`);
|
|
209
|
+
console.log(` User guidance: ${hasUserGuidance}`);
|
|
210
|
+
console.log(` Success messages: ${hasSuccessMessage}`);
|
|
211
|
+
|
|
212
|
+
const adequateMessaging = hasUserGuidance && hasSuccessMessage;
|
|
213
|
+
|
|
214
|
+
this.testResults.push({
|
|
215
|
+
name: 'Error Messages and Guidance',
|
|
216
|
+
passed: adequateMessaging,
|
|
217
|
+
details: `Error messages: ${hasErrorMessages}, User guidance: ${hasUserGuidance}, Success messages: ${hasSuccessMessage}`
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
return adequateMessaging;
|
|
221
|
+
} catch (error) {
|
|
222
|
+
console.log(` ✗ Failed to check error messages and guidance: ${error.message}`);
|
|
223
|
+
this.testResults.push({
|
|
224
|
+
name: 'Error Messages and Guidance',
|
|
225
|
+
passed: false,
|
|
226
|
+
details: `Failed to check: ${error.message}`
|
|
227
|
+
});
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Test 4: Verify main function error handling covers auto-install
|
|
233
|
+
async testMainFunctionErrorHandling() {
|
|
234
|
+
console.log('\n[TEST 4] Verifying main function error handling covers auto-install...');
|
|
235
|
+
|
|
236
|
+
try {
|
|
237
|
+
// Read main script
|
|
238
|
+
const mainScriptPath = path.join(__dirname, '..', 'src', 'main_english.js');
|
|
239
|
+
const mainScript = await fs.readFile(mainScriptPath, 'utf8');
|
|
240
|
+
|
|
241
|
+
// Check main function error handling
|
|
242
|
+
const mainFunctionStart = mainScript.indexOf('async function main()');
|
|
243
|
+
const mainFunctionEnd = mainScript.indexOf('\n}', mainFunctionStart);
|
|
244
|
+
|
|
245
|
+
if (mainFunctionStart === -1 || mainFunctionEnd === -1) {
|
|
246
|
+
console.log(' ✗ Main function not found');
|
|
247
|
+
this.testResults.push({
|
|
248
|
+
name: 'Main Function Error Handling',
|
|
249
|
+
passed: false,
|
|
250
|
+
details: 'Main function not found'
|
|
251
|
+
});
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const mainFunction = mainScript.substring(mainFunctionStart, mainFunctionEnd);
|
|
256
|
+
|
|
257
|
+
// Check if main function has catch block
|
|
258
|
+
const hasCatchBlock = mainFunction.includes('catch');
|
|
259
|
+
const hasProcessExit = mainFunction.includes('process.exit(1)');
|
|
260
|
+
|
|
261
|
+
console.log(` Main function has catch block: ${hasCatchBlock}`);
|
|
262
|
+
console.log(` Main function has process.exit(1): ${hasProcessExit}`);
|
|
263
|
+
|
|
264
|
+
const adequateMainErrorHandling = hasCatchBlock && hasProcessExit;
|
|
265
|
+
|
|
266
|
+
this.testResults.push({
|
|
267
|
+
name: 'Main Function Error Handling',
|
|
268
|
+
passed: adequateMainErrorHandling,
|
|
269
|
+
details: `Has catch block: ${hasCatchBlock}, Has process.exit(1): ${hasProcessExit}`
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
return adequateMainErrorHandling;
|
|
273
|
+
} catch (error) {
|
|
274
|
+
console.log(` ✗ Failed to check main function error handling: ${error.message}`);
|
|
275
|
+
this.testResults.push({
|
|
276
|
+
name: 'Main Function Error Handling',
|
|
277
|
+
passed: false,
|
|
278
|
+
details: `Failed to check: ${error.message}`
|
|
279
|
+
});
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Run all tests
|
|
285
|
+
async runAllTests() {
|
|
286
|
+
console.log('Enhanced Error Handling Test for Stigmergy Auto-Install');
|
|
287
|
+
console.log('='.repeat(60));
|
|
288
|
+
|
|
289
|
+
await this.testAutoInstallTryCatch();
|
|
290
|
+
await this.testIndividualStepErrorHandling();
|
|
291
|
+
await this.testErrorMessagesAndGuidance();
|
|
292
|
+
await this.testMainFunctionErrorHandling();
|
|
293
|
+
|
|
294
|
+
// Summary
|
|
295
|
+
console.log('\n' + '='.repeat(60));
|
|
296
|
+
console.log('Enhanced Error Handling Test Summary:');
|
|
297
|
+
console.log('='.repeat(60));
|
|
298
|
+
|
|
299
|
+
let passedTests = 0;
|
|
300
|
+
this.testResults.forEach(result => {
|
|
301
|
+
console.log(`${result.name}: ${result.passed ? '✓ PASS' : '⚠ PARTIAL'} - ${result.details}`);
|
|
302
|
+
if (result.passed) passedTests++;
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
console.log(`\nOverall Result: ${passedTests}/${this.testResults.length} tests passed`);
|
|
306
|
+
|
|
307
|
+
if (passedTests === this.testResults.length) {
|
|
308
|
+
console.log('✓ All error handling tests passed! Auto-install should handle errors gracefully.');
|
|
309
|
+
} else if (passedTests > 0) {
|
|
310
|
+
console.log('⚠ Some error handling tests partially passed. Auto-install has basic error handling.');
|
|
311
|
+
} else {
|
|
312
|
+
console.log('✗ All error handling tests failed. Auto-install may not handle errors gracefully.');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return {
|
|
316
|
+
totalTests: this.testResults.length,
|
|
317
|
+
passedTests: passedTests,
|
|
318
|
+
results: this.testResults
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Run the tests
|
|
324
|
+
async function runErrorHandlingTests() {
|
|
325
|
+
const tester = new ErrorHandlingTester();
|
|
326
|
+
const results = await tester.runAllTests();
|
|
327
|
+
return results;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Export for use in other modules
|
|
331
|
+
module.exports = { ErrorHandlingTester };
|
|
332
|
+
|
|
333
|
+
// Run if called directly
|
|
334
|
+
if (require.main === module) {
|
|
335
|
+
runErrorHandlingTests().then(results => {
|
|
336
|
+
process.exit(results.passedTests === results.totalTests ? 0 : 1);
|
|
337
|
+
}).catch(error => {
|
|
338
|
+
console.error('[Test Failed]:', error.message);
|
|
339
|
+
process.exit(1);
|
|
340
|
+
});
|
|
341
|
+
}
|