stigmergy 1.2.0 → 1.2.6
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/LICENSE +18 -18
- package/README.md +28 -223
- package/STIGMERGY.md +61 -61
- package/docs/PROJECT_CONSTITUTION.md +433 -433
- package/docs/PROJECT_STRUCTURE_CURRENT.md +80 -80
- package/examples/calculator-example.js +72 -72
- package/examples/cline_usage_examples.md +364 -364
- package/examples/encryption-example.js +67 -67
- package/examples/json-parser-example.js +120 -120
- package/examples/json-validation-example.js +64 -64
- package/examples/rest-client-example.js +52 -52
- package/examples/rest_client_example.js +54 -54
- package/package.json +36 -15
- package/scripts/build.js +74 -74
- package/scripts/post-deployment-config.js +296 -296
- package/scripts/preinstall-check.js +173 -173
- package/scripts/publish.js +58 -268
- package/scripts/run-layered-tests.js +247 -0
- package/scripts/safe-install.js +139 -139
- package/scripts/simple-publish.js +57 -59
- package/src/adapters/claude/install_claude_integration.js +292 -0
- package/src/adapters/codebuddy/install_codebuddy_integration.js +349 -0
- package/src/adapters/codex/install_codex_integration.js +395 -0
- package/src/adapters/copilot/install_copilot_integration.js +716 -0
- package/src/adapters/gemini/install_gemini_integration.js +304 -0
- package/src/adapters/iflow/install_iflow_integration.js +304 -0
- package/src/adapters/qoder/install_qoder_integration.js +1090 -0
- package/src/adapters/qwen/install_qwen_integration.js +285 -0
- package/src/auth.js +173 -173
- package/src/auth_command.js +208 -208
- package/src/calculator.js +313 -313
- package/src/cli/router.js +417 -38
- package/src/core/cache_cleaner.js +767 -744
- package/src/core/cli_help_analyzer.js +680 -674
- package/src/core/cli_parameter_handler.js +132 -127
- package/src/core/cli_tools.js +89 -89
- package/src/core/coordination/index.js +16 -16
- package/src/core/coordination/nodejs/AdapterManager.js +102 -89
- package/src/core/coordination/nodejs/CLCommunication.js +132 -124
- package/src/core/coordination/nodejs/CLIIntegrationManager.js +272 -236
- package/src/core/coordination/nodejs/HealthChecker.js +76 -77
- package/src/core/coordination/nodejs/HookDeploymentManager.js +263 -190
- package/src/core/coordination/nodejs/StatisticsCollector.js +71 -71
- package/src/core/coordination/nodejs/index.js +90 -72
- package/src/core/coordination/nodejs/utils/Logger.js +29 -29
- package/src/core/enhanced_installer.js +479 -456
- package/src/core/enhanced_uninstaller.js +638 -618
- package/src/core/error_handler.js +406 -406
- package/src/core/installer.js +815 -294
- package/src/core/memory_manager.js +83 -83
- package/src/core/rest_client.js +160 -160
- package/src/core/smart_router.js +249 -146
- package/src/core/upgrade_manager.js +76 -59
- package/src/data_encryption.js +143 -143
- package/src/data_structures.js +440 -440
- package/src/deploy.js +55 -55
- package/src/index.js +30 -30
- package/src/test/cli-availability-checker.js +194 -0
- package/src/test/test-environment.js +289 -0
- package/src/utils/helpers.js +35 -35
- package/src/utils.js +921 -915
- package/src/weatherProcessor.js +228 -228
- package/test/cache-cleaner-implemented.test.js +0 -328
- package/test/cache-cleaner.test.js +0 -390
- package/test/calculator.test.js +0 -215
- package/test/collision-test.js +0 -26
- package/test/comprehensive-enhanced-features.test.js +0 -252
- package/test/comprehensive-execution-test.js +0 -428
- package/test/conflict-prevention-test.js +0 -95
- package/test/cross-cli-detection-test.js +0 -33
- package/test/csv-processing-test.js +0 -36
- package/test/deploy-hooks-test.js +0 -250
- package/test/e2e/claude-cli-test.js +0 -128
- package/test/e2e/collaboration-test.js +0 -75
- package/test/e2e/comprehensive-test.js +0 -431
- package/test/e2e/error-handling-test.js +0 -90
- package/test/e2e/individual-tool-test.js +0 -143
- package/test/e2e/other-cli-test.js +0 -130
- package/test/e2e/qoder-cli-test.js +0 -128
- package/test/e2e/run-e2e-tests.js +0 -73
- package/test/e2e/test-data.js +0 -88
- package/test/e2e/test-utils.js +0 -222
- package/test/encryption-simple-test.js +0 -110
- package/test/encryption.test.js +0 -129
- package/test/enhanced-main-alignment.test.js +0 -298
- package/test/enhanced-uninstaller-implemented.test.js +0 -271
- package/test/enhanced-uninstaller.test.js +0 -284
- package/test/error-handling-test.js +0 -341
- package/test/fibonacci.test.js +0 -178
- package/test/final-deploy-test.js +0 -221
- package/test/final-install-test.js +0 -226
- package/test/hash-table-demo.js +0 -33
- package/test/hash-table-test.js +0 -26
- package/test/hash_table_test.js +0 -114
- package/test/hook-system-integration-test.js +0 -307
- package/test/iflow-integration-test.js +0 -292
- package/test/improved-install-test.js +0 -362
- package/test/install-command-test.js +0 -370
- package/test/json-parser-test.js +0 -161
- package/test/json-validation-test.js +0 -164
- package/test/natural-language-skills-test.js +0 -320
- package/test/nl-integration-test.js +0 -179
- package/test/parameter-parsing-test.js +0 -143
- package/test/plugin-deployment-test.js +0 -316
- package/test/postinstall-test.js +0 -269
- package/test/python-plugins-test.js +0 -259
- package/test/real-test.js +0 -435
- package/test/remaining-adapters-test.js +0 -256
- package/test/rest-client-test.js +0 -56
- package/test/rest_client.test.js +0 -85
- package/test/safe-installation-cleaner.test.js +0 -343
- package/test/simple-iflow-hook-test.js +0 -137
- package/test/stigmergy-upgrade-test.js +0 -243
- package/test/system-compatibility-test.js +0 -467
- package/test/tdd-deploy-fix-test.js +0 -324
- package/test/tdd-fixes-test.js +0 -211
- package/test/third-party-skills-test.js +0 -321
- package/test/tool-selection-integration-test.js +0 -158
- package/test/unit/calculator-full.test.js +0 -191
- package/test/unit/calculator-simple.test.js +0 -96
- package/test/unit/calculator.test.js +0 -97
- package/test/unit/cli-scanner.test.js +0 -291
- package/test/unit/cli_parameter_handler.test.js +0 -116
- package/test/unit/cross-cli-executor.test.js +0 -399
- package/test/weather-processor.test.js +0 -104
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple test script for encryption functions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const { encryptData, decryptData, generateKey } = require('../src/utils');
|
|
6
|
-
|
|
7
|
-
console.log('Testing encryption functions...');
|
|
8
|
-
console.log('================================');
|
|
9
|
-
|
|
10
|
-
// Test 1: Generate key
|
|
11
|
-
console.log('Test 1: Key generation');
|
|
12
|
-
let secretKey;
|
|
13
|
-
try {
|
|
14
|
-
secretKey = generateKey();
|
|
15
|
-
console.log('✓ Generated 32-byte key');
|
|
16
|
-
console.log('✓ Key type:', typeof secretKey);
|
|
17
|
-
} catch (error) {
|
|
18
|
-
console.error('✗ Key generation failed:', error.message);
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Test 2: Encrypt string data
|
|
23
|
-
console.log('\nTest 2: String encryption');
|
|
24
|
-
let encryptedObj;
|
|
25
|
-
try {
|
|
26
|
-
const plaintext = 'Hello, World!';
|
|
27
|
-
encryptedObj = encryptData(plaintext, secretKey);
|
|
28
|
-
console.log('✓ String encryption successful');
|
|
29
|
-
console.log('✓ Encrypted object has required properties');
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.error('✗ String encryption failed:', error.message);
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Test 3: Decrypt data
|
|
36
|
-
console.log('\nTest 3: Data decryption');
|
|
37
|
-
try {
|
|
38
|
-
const decrypted = decryptData(encryptedObj, secretKey);
|
|
39
|
-
console.log('✓ Data decryption successful');
|
|
40
|
-
console.log('✓ Decrypted data matches original');
|
|
41
|
-
} catch (error) {
|
|
42
|
-
console.error('✗ Data decryption failed:', error.message);
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Test 4: Data integrity
|
|
47
|
-
console.log('\nTest 4: Data integrity');
|
|
48
|
-
try {
|
|
49
|
-
const originalData = 'Confidential information';
|
|
50
|
-
const encrypted = encryptData(originalData, secretKey);
|
|
51
|
-
const decrypted = decryptData(encrypted, secretKey);
|
|
52
|
-
|
|
53
|
-
if (originalData === decrypted) {
|
|
54
|
-
console.log('✓ Data integrity maintained');
|
|
55
|
-
} else {
|
|
56
|
-
console.error('✗ Data integrity check failed');
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
} catch (error) {
|
|
60
|
-
console.error('✗ Data integrity test failed:', error.message);
|
|
61
|
-
process.exit(1);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Test 5: Unicode support
|
|
65
|
-
console.log('\nTest 5: Unicode support');
|
|
66
|
-
try {
|
|
67
|
-
const unicodeData = 'Hello, 世界! 🌍 Welcome to 数据加密!';
|
|
68
|
-
const encrypted = encryptData(unicodeData, secretKey);
|
|
69
|
-
const decrypted = decryptData(encrypted, secretKey);
|
|
70
|
-
|
|
71
|
-
if (unicodeData === decrypted) {
|
|
72
|
-
console.log('✓ Unicode data handled correctly');
|
|
73
|
-
} else {
|
|
74
|
-
console.error('✗ Unicode test failed');
|
|
75
|
-
process.exit(1);
|
|
76
|
-
}
|
|
77
|
-
} catch (error) {
|
|
78
|
-
console.error('✗ Unicode test failed:', error.message);
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Test 6: Error handling
|
|
83
|
-
console.log('\nTest 6: Error handling');
|
|
84
|
-
try {
|
|
85
|
-
encryptData('', secretKey);
|
|
86
|
-
console.error('✗ Empty data validation failed');
|
|
87
|
-
process.exit(1);
|
|
88
|
-
} catch (error) {
|
|
89
|
-
if (error.message === 'Data to encrypt cannot be empty') {
|
|
90
|
-
console.log('✓ Empty data validation works');
|
|
91
|
-
} else {
|
|
92
|
-
console.error('✗ Unexpected error for empty data:', error.message);
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
encryptData('test data', null);
|
|
99
|
-
console.error('✗ Missing key validation failed');
|
|
100
|
-
process.exit(1);
|
|
101
|
-
} catch (error) {
|
|
102
|
-
if (error.message === 'Secret key is required') {
|
|
103
|
-
console.log('✓ Missing key validation works');
|
|
104
|
-
} else {
|
|
105
|
-
console.error('✗ Unexpected error for missing key:', error.message);
|
|
106
|
-
process.exit(1);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
console.log('\nAll tests passed! 🎉');
|
package/test/encryption.test.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test suite for encryption functions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const { encryptData, decryptData, generateKey } = require('../src/utils');
|
|
6
|
-
|
|
7
|
-
describe('Encryption Functions', () => {
|
|
8
|
-
let secretKey;
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
// Generate a new key for each test
|
|
12
|
-
secretKey = generateKey();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
describe('generateKey()', () => {
|
|
16
|
-
test('should generate a 32-byte key by default', () => {
|
|
17
|
-
const key = generateKey();
|
|
18
|
-
expect(key).toBeInstanceOf(Buffer);
|
|
19
|
-
expect(key.length).toBe(32);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test('should generate a key of specified length', () => {
|
|
23
|
-
const key = generateKey(16);
|
|
24
|
-
expect(key).toBeInstanceOf(Buffer);
|
|
25
|
-
expect(key.length).toBe(16);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe('encryptData()', () => {
|
|
30
|
-
test('should encrypt string data', () => {
|
|
31
|
-
const plaintext = 'Hello, World!';
|
|
32
|
-
const encryptedObj = encryptData(plaintext, secretKey);
|
|
33
|
-
|
|
34
|
-
expect(encryptedObj).toHaveProperty('encryptedData');
|
|
35
|
-
expect(encryptedObj).toHaveProperty('iv');
|
|
36
|
-
expect(encryptedObj).toHaveProperty('authTag');
|
|
37
|
-
expect(typeof encryptedObj.encryptedData).toBe('string');
|
|
38
|
-
expect(typeof encryptedObj.iv).toBe('string');
|
|
39
|
-
expect(typeof encryptedObj.authTag).toBe('string');
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('should encrypt buffer data', () => {
|
|
43
|
-
const plaintext = Buffer.from('Hello, World!', 'utf8');
|
|
44
|
-
const encryptedObj = encryptData(plaintext, secretKey);
|
|
45
|
-
|
|
46
|
-
expect(encryptedObj).toHaveProperty('encryptedData');
|
|
47
|
-
expect(encryptedObj).toHaveProperty('iv');
|
|
48
|
-
expect(encryptedObj).toHaveProperty('authTag');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test('should throw error for empty data', () => {
|
|
52
|
-
expect(() => encryptData('', secretKey)).toThrow('Data to encrypt cannot be empty');
|
|
53
|
-
expect(() => encryptData(null, secretKey)).toThrow('Data to encrypt cannot be empty');
|
|
54
|
-
expect(() => encryptData(undefined, secretKey)).toThrow('Data to encrypt cannot be empty');
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test('should throw error for missing secret key', () => {
|
|
58
|
-
expect(() => encryptData('test data', null)).toThrow('Secret key is required');
|
|
59
|
-
expect(() => encryptData('test data', undefined)).toThrow('Secret key is required');
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
describe('decryptData()', () => {
|
|
64
|
-
test('should decrypt encrypted data correctly', () => {
|
|
65
|
-
const plaintext = 'Secret message for testing';
|
|
66
|
-
const encryptedObj = encryptData(plaintext, secretKey);
|
|
67
|
-
const decrypted = decryptData(encryptedObj, secretKey);
|
|
68
|
-
|
|
69
|
-
expect(decrypted).toBe(plaintext);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('should decrypt buffer data correctly', () => {
|
|
73
|
-
const plaintext = Buffer.from('Secret message for testing', 'utf8');
|
|
74
|
-
const encryptedObj = encryptData(plaintext, secretKey);
|
|
75
|
-
const decrypted = decryptData(encryptedObj, secretKey);
|
|
76
|
-
|
|
77
|
-
expect(decrypted).toBe('Secret message for testing');
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test('should throw error for invalid encrypted object', () => {
|
|
81
|
-
expect(() => decryptData({}, secretKey)).toThrow('Invalid encrypted object');
|
|
82
|
-
expect(() => decryptData({ encryptedData: 'test' }, secretKey)).toThrow('Invalid encrypted object');
|
|
83
|
-
expect(() => decryptData(null, secretKey)).toThrow('Invalid encrypted object');
|
|
84
|
-
expect(() => decryptData(undefined, secretKey)).toThrow('Invalid encrypted object');
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
test('should throw error for missing secret key', () => {
|
|
88
|
-
const encryptedObj = encryptData('test data', secretKey);
|
|
89
|
-
expect(() => decryptData(encryptedObj, null)).toThrow('Secret key is required');
|
|
90
|
-
expect(() => decryptData(encryptedObj, undefined)).toThrow('Secret key is required');
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test('should throw error for tampered data', () => {
|
|
94
|
-
const plaintext = 'Original message';
|
|
95
|
-
const encryptedObj = encryptData(plaintext, secretKey);
|
|
96
|
-
|
|
97
|
-
// Tamper with the encrypted data
|
|
98
|
-
encryptedObj.encryptedData = 'tampered' + encryptedObj.encryptedData;
|
|
99
|
-
|
|
100
|
-
expect(() => decryptData(encryptedObj, secretKey)).toThrow();
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe('encrypt/decrypt integration', () => {
|
|
105
|
-
test('should maintain data integrity through encrypt/decrypt cycle', () => {
|
|
106
|
-
const originalData = 'This is a test of the encryption system.';
|
|
107
|
-
const encryptedObj = encryptData(originalData, secretKey);
|
|
108
|
-
const decryptedData = decryptData(encryptedObj, secretKey);
|
|
109
|
-
|
|
110
|
-
expect(decryptedData).toBe(originalData);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
test('should work with unicode characters', () => {
|
|
114
|
-
const originalData = 'Hello, 世界! 🌍 💻';
|
|
115
|
-
const encryptedObj = encryptData(originalData, secretKey);
|
|
116
|
-
const decryptedData = decryptData(encryptedObj, secretKey);
|
|
117
|
-
|
|
118
|
-
expect(decryptedData).toBe(originalData);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
test('should work with empty strings', () => {
|
|
122
|
-
const originalData = '';
|
|
123
|
-
const encryptedObj = encryptData(originalData, secretKey);
|
|
124
|
-
const decryptedData = decryptData(encryptedObj, secretKey);
|
|
125
|
-
|
|
126
|
-
expect(decryptedData).toBe(originalData);
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
});
|
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Enhanced Main.js 功能对齐测试 - TDD驱动开发
|
|
5
|
-
* 基于main.js完整功能,测试enhanced版本的对齐情况
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const { strict: assert } = require('assert');
|
|
9
|
-
const { spawn } = require('child_process');
|
|
10
|
-
const fs = require('fs').promises;
|
|
11
|
-
const path = require('path');
|
|
12
|
-
|
|
13
|
-
class EnhancedMainAlignTest {
|
|
14
|
-
constructor() {
|
|
15
|
-
this.testResults = [];
|
|
16
|
-
this.mainJsPath = path.join(process.cwd(), 'package', 'src', 'main.js');
|
|
17
|
-
this.enhancedJsPath = path.join(process.cwd(), 'package', 'src', 'enhanced-main.js');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// TDD测试:命令行参数支持
|
|
21
|
-
async testCommandLineArguments() {
|
|
22
|
-
console.log('🧪 测试命令行参数支持...');
|
|
23
|
-
|
|
24
|
-
const requiredCommands = [
|
|
25
|
-
'init', 'status', 'scan', 'deploy',
|
|
26
|
-
'validate', 'check-project', 'clean', 'install'
|
|
27
|
-
];
|
|
28
|
-
|
|
29
|
-
for (const cmd of requiredCommands) {
|
|
30
|
-
try {
|
|
31
|
-
const result = await this.runCommand(this.enhancedJsPath, [cmd, '--help'], { timeout: 5000 });
|
|
32
|
-
this.addTest(`命令支持: ${cmd}`, result.exitCode === 0);
|
|
33
|
-
} catch (error) {
|
|
34
|
-
this.addTest(`命令支持: ${cmd}`, false, error.message);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// TDD测试:项目初始化功能
|
|
40
|
-
async testProjectInitialization() {
|
|
41
|
-
console.log('🧪 测试项目初始化功能...');
|
|
42
|
-
|
|
43
|
-
const testProjectDir = path.join(process.cwd(), 'test-project-temp');
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
// 创建测试目录
|
|
47
|
-
await fs.mkdir(testProjectDir, { recursive: true });
|
|
48
|
-
|
|
49
|
-
// 测试初始化
|
|
50
|
-
const result = await this.runCommand(this.enhancedJsPath, ['init', testProjectDir]);
|
|
51
|
-
|
|
52
|
-
// 验证配置文件生成
|
|
53
|
-
const configPath = path.join(testProjectDir, '.stigmergy-project', 'stigmergy-config.json');
|
|
54
|
-
const configExists = await this.fileExists(configPath);
|
|
55
|
-
|
|
56
|
-
// 验证配置内容
|
|
57
|
-
let configValid = false;
|
|
58
|
-
if (configExists) {
|
|
59
|
-
const config = JSON.parse(await fs.readFile(configPath, 'utf8'));
|
|
60
|
-
configValid = config.projectType && config.adapters && Array.isArray(config.adapters);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
this.addTest('项目初始化:生成配置文件', configExists);
|
|
64
|
-
this.addTest('项目初始化:配置内容有效', configValid);
|
|
65
|
-
this.addTest('项目初始化:命令执行成功', result.exitCode === 0);
|
|
66
|
-
|
|
67
|
-
// 清理测试目录
|
|
68
|
-
await fs.rm(testProjectDir, { recursive: true, force: true });
|
|
69
|
-
|
|
70
|
-
} catch (error) {
|
|
71
|
-
this.addTest('项目初始化功能', false, error.message);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// TDD测试:状态检查功能
|
|
76
|
-
async testStatusCheck() {
|
|
77
|
-
console.log('🧪 测试状态检查功能...');
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
const result = await this.runCommand(this.enhancedJsPath, ['status']);
|
|
81
|
-
const hasStatusOutput = result.stdout.includes('全局配置') ||
|
|
82
|
-
result.stdout.includes('项目配置') ||
|
|
83
|
-
result.stdout.includes('可用适配器');
|
|
84
|
-
|
|
85
|
-
this.addTest('状态检查:命令执行', result.exitCode === 0);
|
|
86
|
-
this.addTest('状态检查:输出格式正确', hasStatusOutput);
|
|
87
|
-
|
|
88
|
-
} catch (error) {
|
|
89
|
-
this.addTest('状态检查功能', false, error.message);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// TDD测试:配置验证功能
|
|
94
|
-
async testConfigurationValidation() {
|
|
95
|
-
console.log('🧪 测试配置验证功能...');
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
// 测试项目验证
|
|
99
|
-
const projectResult = await this.runCommand(this.enhancedJsPath, ['validate', 'project']);
|
|
100
|
-
|
|
101
|
-
// 测试全局验证
|
|
102
|
-
const globalResult = await this.runCommand(this.enhancedJsPath, ['validate', 'global']);
|
|
103
|
-
|
|
104
|
-
this.addTest('配置验证:项目验证', projectResult.exitCode === 0);
|
|
105
|
-
this.addTest('配置验证:全局验证', globalResult.exitCode === 0);
|
|
106
|
-
|
|
107
|
-
} catch (error) {
|
|
108
|
-
this.addTest('配置验证功能', false, error.message);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// TDD测试:适配器管理功能
|
|
113
|
-
async testAdapterManager() {
|
|
114
|
-
console.log('🧪 测试适配器管理功能...');
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
// 测试适配器加载
|
|
118
|
-
const result = await this.runCommand(this.enhancedJsPath, ['deploy']);
|
|
119
|
-
|
|
120
|
-
this.addTest('适配器管理:部署功能', result.exitCode === 0);
|
|
121
|
-
|
|
122
|
-
} catch (error) {
|
|
123
|
-
this.addTest('适配器管理功能', false, error.message);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// TDD测试:工具扫描功能
|
|
128
|
-
async testToolScanning() {
|
|
129
|
-
console.log('🧪 测试工具扫描功能...');
|
|
130
|
-
|
|
131
|
-
try {
|
|
132
|
-
const result = await this.runCommand(this.enhancedJsPath, ['scan']);
|
|
133
|
-
|
|
134
|
-
const hasToolList = result.stdout.includes('Claude CLI') ||
|
|
135
|
-
result.stdout.includes('Gemini CLI') ||
|
|
136
|
-
result.stdout.includes('扫描');
|
|
137
|
-
|
|
138
|
-
const hasInstallationPrompt = result.stdout.includes('安装') ||
|
|
139
|
-
result.stdout.includes('缺失');
|
|
140
|
-
|
|
141
|
-
this.addTest('工具扫描:命令执行', result.exitCode === 0);
|
|
142
|
-
this.addTest('工具扫描:工具列表显示', hasToolList);
|
|
143
|
-
this.addTest('工具扫描:安装提示', hasInstallationPrompt);
|
|
144
|
-
|
|
145
|
-
} catch (error) {
|
|
146
|
-
this.addTest('工具扫描功能', false, error.message);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// TDD测试:缓存清理功能
|
|
151
|
-
async testCacheCleaning() {
|
|
152
|
-
console.log('🧪 测试缓存清理功能...');
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
const result = await this.runCommand(this.enhancedJsPath, ['clean']);
|
|
156
|
-
|
|
157
|
-
this.addTest('缓存清理:命令执行', result.exitCode === 0);
|
|
158
|
-
|
|
159
|
-
} catch (error) {
|
|
160
|
-
this.addTest('缓存清理功能', false, error.message);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// 运行命令的辅助方法
|
|
165
|
-
async runCommand(scriptPath, args = [], options = {}) {
|
|
166
|
-
return new Promise((resolve) => {
|
|
167
|
-
const child = spawn('node', [scriptPath, ...args], {
|
|
168
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
169
|
-
cwd: process.cwd(),
|
|
170
|
-
...options
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
let stdout = '';
|
|
174
|
-
let stderr = '';
|
|
175
|
-
|
|
176
|
-
child.stdout.on('data', (data) => {
|
|
177
|
-
stdout += data.toString();
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
child.stderr.on('data', (data) => {
|
|
181
|
-
stderr += data.toString();
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
child.on('close', (code) => {
|
|
185
|
-
resolve({
|
|
186
|
-
exitCode: code,
|
|
187
|
-
stdout: stdout,
|
|
188
|
-
stderr: stderr
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
// 处理交互式命令 - 发送输入
|
|
193
|
-
if (args.includes('scan')) {
|
|
194
|
-
// 对于scan命令,发送"N"来跳过安装
|
|
195
|
-
setTimeout(() => {
|
|
196
|
-
child.stdin.write('N\n');
|
|
197
|
-
child.stdin.end();
|
|
198
|
-
}, 3000);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// 超时处理
|
|
202
|
-
setTimeout(() => {
|
|
203
|
-
child.kill();
|
|
204
|
-
resolve({
|
|
205
|
-
exitCode: -1,
|
|
206
|
-
stdout: stdout,
|
|
207
|
-
stderr: 'Command timeout'
|
|
208
|
-
});
|
|
209
|
-
}, options.timeout || 30000);
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// 检查文件是否存在
|
|
214
|
-
async fileExists(filePath) {
|
|
215
|
-
try {
|
|
216
|
-
await fs.access(filePath);
|
|
217
|
-
return true;
|
|
218
|
-
} catch {
|
|
219
|
-
return false;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// 添加测试结果
|
|
224
|
-
addTest(testName, passed, error = '') {
|
|
225
|
-
this.testResults.push({
|
|
226
|
-
test: testName,
|
|
227
|
-
passed: passed,
|
|
228
|
-
error: error
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
const status = passed ? '✅' : '❌';
|
|
232
|
-
console.log(` ${status} ${testName}`);
|
|
233
|
-
if (error) {
|
|
234
|
-
console.log(` 错误: ${error}`);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// 生成测试报告
|
|
239
|
-
generateReport() {
|
|
240
|
-
const totalTests = this.testResults.length;
|
|
241
|
-
const passedTests = this.testResults.filter(r => r.passed).length;
|
|
242
|
-
const failedTests = totalTests - passedTests;
|
|
243
|
-
|
|
244
|
-
console.log('\n📊 测试报告');
|
|
245
|
-
console.log('='.repeat(50));
|
|
246
|
-
console.log(`总测试数: ${totalTests}`);
|
|
247
|
-
console.log(`通过: ${passedTests} ✅`);
|
|
248
|
-
console.log(`失败: ${failedTests} ❌`);
|
|
249
|
-
console.log(`通过率: ${((passedTests / totalTests) * 100).toFixed(1)}%`);
|
|
250
|
-
|
|
251
|
-
if (failedTests > 0) {
|
|
252
|
-
console.log('\n❌ 失败的测试:');
|
|
253
|
-
this.testResults
|
|
254
|
-
.filter(r => !r.passed)
|
|
255
|
-
.forEach(r => {
|
|
256
|
-
console.log(` - ${r.test}: ${r.error}`);
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
return {
|
|
261
|
-
total: totalTests,
|
|
262
|
-
passed: passedTests,
|
|
263
|
-
failed: failedTests,
|
|
264
|
-
passRate: (passedTests / totalTests) * 100
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// 运行所有测试
|
|
269
|
-
async runAllTests() {
|
|
270
|
-
console.log('🚀 开始Enhanced Main.js功能对齐测试');
|
|
271
|
-
console.log('='.repeat(50));
|
|
272
|
-
|
|
273
|
-
await this.testCommandLineArguments();
|
|
274
|
-
await this.testProjectInitialization();
|
|
275
|
-
await this.testStatusCheck();
|
|
276
|
-
await this.testConfigurationValidation();
|
|
277
|
-
await this.testAdapterManager();
|
|
278
|
-
await this.testToolScanning();
|
|
279
|
-
await this.testCacheCleaning();
|
|
280
|
-
|
|
281
|
-
return this.generateReport();
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// 如果直接运行此文件
|
|
286
|
-
if (require.main === module) {
|
|
287
|
-
const tester = new EnhancedMainAlignTest();
|
|
288
|
-
tester.runAllTests()
|
|
289
|
-
.then(report => {
|
|
290
|
-
process.exit(report.failed > 0 ? 1 : 0);
|
|
291
|
-
})
|
|
292
|
-
.catch(error => {
|
|
293
|
-
console.error('测试执行失败:', error);
|
|
294
|
-
process.exit(1);
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
module.exports = EnhancedMainAlignTest;
|