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,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple unit tests for Calculator class
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const Calculator = require('../../src/calculator');
|
|
6
|
-
|
|
7
|
-
console.log("Testing Calculator class...");
|
|
8
|
-
|
|
9
|
-
const calc = new Calculator();
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
// Test basic operations
|
|
13
|
-
console.log("\n1. Testing basic arithmetic operations:");
|
|
14
|
-
|
|
15
|
-
// Addition
|
|
16
|
-
const sum = calc.add(5, 3);
|
|
17
|
-
console.log(`calc.add(5, 3) = ${sum}`);
|
|
18
|
-
|
|
19
|
-
// Subtraction
|
|
20
|
-
const difference = calc.subtract(10, 4);
|
|
21
|
-
console.log(`calc.subtract(10, 4) = ${difference}`);
|
|
22
|
-
|
|
23
|
-
// Multiplication
|
|
24
|
-
const product = calc.multiply(6, 7);
|
|
25
|
-
console.log(`calc.multiply(6, 7) = ${product}`);
|
|
26
|
-
|
|
27
|
-
// Division
|
|
28
|
-
const quotient = calc.divide(15, 3);
|
|
29
|
-
console.log(`calc.divide(15, 3) = ${quotient}`);
|
|
30
|
-
|
|
31
|
-
// Power
|
|
32
|
-
const powerResult = calc.power(2, 3);
|
|
33
|
-
console.log(`calc.power(2, 3) = ${powerResult}`);
|
|
34
|
-
|
|
35
|
-
// Square root
|
|
36
|
-
const sqrtResult = calc.sqrt(16);
|
|
37
|
-
console.log(`calc.sqrt(16) = ${sqrtResult}`);
|
|
38
|
-
|
|
39
|
-
// Factorial
|
|
40
|
-
const factorialResult = calc.factorial(5);
|
|
41
|
-
console.log(`calc.factorial(5) = ${factorialResult}`);
|
|
42
|
-
|
|
43
|
-
// Percentage
|
|
44
|
-
const percentageResult = calc.percentage(25, 100);
|
|
45
|
-
console.log(`calc.percentage(25, 100) = ${percentageResult}%`);
|
|
46
|
-
|
|
47
|
-
console.log("\n✅ Basic operations tests passed!");
|
|
48
|
-
|
|
49
|
-
// Test calculation chain
|
|
50
|
-
console.log("\n2. Testing calculation chain:");
|
|
51
|
-
const chainResult = calc.chain(10).add(5).multiply(2).subtract(4).divide(2).equals();
|
|
52
|
-
console.log(`calc.chain(10).add(5).multiply(2).subtract(4).divide(2).equals() = ${chainResult}`);
|
|
53
|
-
console.log("✅ Chain operations test passed!");
|
|
54
|
-
|
|
55
|
-
console.log("\n✅ All tests passed!");
|
|
56
|
-
} catch (error) {
|
|
57
|
-
console.error("❌ Test failed:", error.message);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Test error cases
|
|
61
|
-
console.log("\n3. Testing error handling:");
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
calc.divide(10, 0);
|
|
65
|
-
console.log("❌ Should have thrown an error for division by zero");
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.log("✅ Correctly threw error for division by zero:", error.message);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
calc.sqrt(-4);
|
|
72
|
-
console.log("❌ Should have thrown an error for square root of negative number");
|
|
73
|
-
} catch (error) {
|
|
74
|
-
console.log("✅ Correctly threw error for square root of negative number:", error.message);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
calc.factorial(-5);
|
|
79
|
-
console.log("❌ Should have thrown an error for factorial of negative number");
|
|
80
|
-
} catch (error) {
|
|
81
|
-
console.log("✅ Correctly threw error for factorial of negative number:", error.message);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
calc.percentage(50, 0);
|
|
86
|
-
console.log("❌ Should have thrown an error for percentage with zero as whole");
|
|
87
|
-
} catch (error) {
|
|
88
|
-
console.log("✅ Correctly threw error for percentage with zero as whole:", error.message);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
calc.chain(10).divide(0);
|
|
93
|
-
console.log("❌ Should have thrown an error for chain division by zero");
|
|
94
|
-
} catch (error) {
|
|
95
|
-
console.log("✅ Correctly threw error for chain division by zero:", error.message);
|
|
96
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for Calculator class following project patterns
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const Calculator = require('../../src/calculator');
|
|
6
|
-
|
|
7
|
-
// Test suite for Calculator
|
|
8
|
-
describe('Calculator', () => {
|
|
9
|
-
let calc;
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
calc = new Calculator();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
describe('Basic Operations', () => {
|
|
16
|
-
test('should add two numbers correctly', () => {
|
|
17
|
-
expect(calc.add(5, 3)).toBe(8);
|
|
18
|
-
expect(calc.add(-2, 7)).toBe(5);
|
|
19
|
-
expect(calc.add(0, 0)).toBe(0);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test('should subtract two numbers correctly', () => {
|
|
23
|
-
expect(calc.subtract(10, 4)).toBe(6);
|
|
24
|
-
expect(calc.subtract(5, 8)).toBe(-3);
|
|
25
|
-
expect(calc.subtract(0, 0)).toBe(0);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test('should multiply two numbers correctly', () => {
|
|
29
|
-
expect(calc.multiply(6, 7)).toBe(42);
|
|
30
|
-
expect(calc.multiply(-3, 4)).toBe(-12);
|
|
31
|
-
expect(calc.multiply(0, 100)).toBe(0);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
test('should divide two numbers correctly', () => {
|
|
35
|
-
expect(calc.divide(15, 3)).toBe(5);
|
|
36
|
-
expect(calc.divide(7, 2)).toBe(3.5);
|
|
37
|
-
expect(calc.divide(-10, 2)).toBe(-5);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test('should throw error when dividing by zero', () => {
|
|
41
|
-
expect(() => calc.divide(10, 0)).toThrow('Cannot divide by zero');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('should calculate power correctly', () => {
|
|
45
|
-
expect(calc.power(2, 3)).toBe(8);
|
|
46
|
-
expect(calc.power(5, 0)).toBe(1);
|
|
47
|
-
expect(calc.power(10, 2)).toBe(100);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test('should calculate square root correctly', () => {
|
|
51
|
-
expect(calc.sqrt(16)).toBe(4);
|
|
52
|
-
expect(calc.sqrt(0)).toBe(0);
|
|
53
|
-
expect(calc.sqrt(1)).toBe(1);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
test('should throw error when calculating square root of negative number', () => {
|
|
57
|
-
expect(() => calc.sqrt(-4)).toThrow('Cannot calculate square root of negative number');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test('should calculate factorial correctly', () => {
|
|
61
|
-
expect(calc.factorial(5)).toBe(120);
|
|
62
|
-
expect(calc.factorial(0)).toBe(1);
|
|
63
|
-
expect(calc.factorial(1)).toBe(1);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test('should throw error when calculating factorial of negative number', () => {
|
|
67
|
-
expect(() => calc.factorial(-5)).toThrow('Cannot calculate factorial of negative number');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test('should calculate percentage correctly', () => {
|
|
71
|
-
expect(calc.percentage(25, 100)).toBe(25);
|
|
72
|
-
expect(calc.percentage(10, 50)).toBe(20);
|
|
73
|
-
expect(calc.percentage(0, 100)).toBe(0);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
test('should throw error when calculating percentage with zero as whole', () => {
|
|
77
|
-
expect(() => calc.percentage(50, 0)).toThrow('Cannot calculate percentage with zero as whole');
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
describe('Calculation Chain', () => {
|
|
82
|
-
test('should chain calculations correctly', () => {
|
|
83
|
-
const result = calc.chain(10).add(5).multiply(2).subtract(4).divide(2).equals();
|
|
84
|
-
// ((10 + 5) * 2 - 4) / 2 = (30 - 4) / 2 = 26 / 2 = 13
|
|
85
|
-
expect(result).toBe(13);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
test('should throw error when dividing by zero in chain', () => {
|
|
89
|
-
expect(() => calc.chain(10).divide(0)).toThrow('Cannot divide by zero');
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
test('should return current value without ending chain', () => {
|
|
93
|
-
const chain = calc.chain(5).add(3);
|
|
94
|
-
expect(chain.value()).toBe(8);
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
});
|
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TDD: CLI Scanner Unit Tests
|
|
3
|
-
* 测试驱动开发 - 先写测试,再写实现
|
|
4
|
-
* 使用ANSI编码,无Unicode字符
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const assert = require('assert');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
|
|
10
|
-
// 测试目标类 - 尚未实现
|
|
11
|
-
class CLIScanner {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.scanResults = new Map();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async scanForCLI(cliName) {
|
|
17
|
-
throw new Error('Not implemented yet - TDD approach');
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async detectInstalledCLIs() {
|
|
21
|
-
throw new Error('Not implemented yet - TDD approach');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
validateCLIExecutable(command) {
|
|
25
|
-
throw new Error('Not implemented yet - TDD approach');
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
describe('CLI Scanner Unit Tests - ANSI Encoding, Node.js First', () => {
|
|
30
|
-
let scanner;
|
|
31
|
-
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
scanner = new CLIScanner();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
describe('Basic CLI Detection', () => {
|
|
37
|
-
it('should detect node command is available', async () => {
|
|
38
|
-
// 测试最基础的情况 - node命令应该可用
|
|
39
|
-
const result = await scanner.scanForCLI('node');
|
|
40
|
-
|
|
41
|
-
assert.strictEqual(result.cliName, 'node');
|
|
42
|
-
assert.strictEqual(result.available, true);
|
|
43
|
-
assert.ok(result.version);
|
|
44
|
-
assert.ok(result.path);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('should detect npm command is available', async () => {
|
|
48
|
-
const result = await scanner.scanForCLI('npm');
|
|
49
|
-
|
|
50
|
-
assert.strictEqual(result.cliName, 'npm');
|
|
51
|
-
assert.strictEqual(result.available, true);
|
|
52
|
-
assert.ok(result.version);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should handle non-existent CLI gracefully', async () => {
|
|
56
|
-
const result = await scanner.scanForCLI('non-existent-cli-12345');
|
|
57
|
-
|
|
58
|
-
assert.strictEqual(result.cliName, 'non-existent-cli-12345');
|
|
59
|
-
assert.strictEqual(result.available, false);
|
|
60
|
-
assert.ok(result.error);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
describe('AI CLI Detection', () => {
|
|
65
|
-
it('should detect Claude CLI if installed', async () => {
|
|
66
|
-
const result = await scanner.scanForCLI('claude');
|
|
67
|
-
|
|
68
|
-
assert.strictEqual(result.cliName, 'claude');
|
|
69
|
-
assert(typeof result.available === 'boolean');
|
|
70
|
-
|
|
71
|
-
if (result.available) {
|
|
72
|
-
assert.ok(result.version);
|
|
73
|
-
assert.ok(result.path);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should detect Gemini CLI if installed', async () => {
|
|
78
|
-
const result = await scanner.scanForCLI('gemini');
|
|
79
|
-
|
|
80
|
-
assert.strictEqual(result.cliName, 'gemini');
|
|
81
|
-
assert(typeof result.available === 'boolean');
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should detect Qwen CLI if installed', async () => {
|
|
85
|
-
const result = await scanner.scanForCLI('qwen');
|
|
86
|
-
|
|
87
|
-
assert.strictEqual(result.cliName, 'qwen');
|
|
88
|
-
assert(typeof result.available === 'boolean');
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe('CLI Validation', () => {
|
|
93
|
-
it('should validate valid Windows commands', () => {
|
|
94
|
-
if (process.platform === 'win32') {
|
|
95
|
-
assert.ok(scanner.validateCLIExecutable('cmd'));
|
|
96
|
-
assert.ok(scanner.validateCLIExecutable('powershell'));
|
|
97
|
-
assert.ok(scanner.validateCLIExecutable('node'));
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('should validate valid Unix commands', () => {
|
|
102
|
-
if (process.platform !== 'win32') {
|
|
103
|
-
assert.ok(scanner.validateCLIExecutable('sh'));
|
|
104
|
-
assert.ok(scanner.validateCLIExecutable('ls'));
|
|
105
|
-
assert.ok(scanner.validateCLIExecutable('node'));
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('should reject invalid commands', () => {
|
|
110
|
-
assert.strictEqual(scanner.validateCLIExecutable(''), false);
|
|
111
|
-
assert.strictEqual(scanner.validateCLIExecutable('non-existent-command-12345'), false);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
describe('Batch Detection', () => {
|
|
116
|
-
it('should detect all basic development tools', async () => {
|
|
117
|
-
const tools = ['node', 'npm', 'git'];
|
|
118
|
-
const results = await scanner.detectInstalledCLIs(tools);
|
|
119
|
-
|
|
120
|
-
assert.ok(results.size >= 2); // 至少node和npm应该可用
|
|
121
|
-
assert.ok(results.has('node'));
|
|
122
|
-
assert.ok(results.has('npm'));
|
|
123
|
-
|
|
124
|
-
// node和npm都应该可用
|
|
125
|
-
assert.strictEqual(results.get('node').available, true);
|
|
126
|
-
assert.strictEqual(results.get('npm').available, true);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should handle mixed available/unavailable tools', async () => {
|
|
130
|
-
const tools = ['node', 'non-existent-cli', 'npm'];
|
|
131
|
-
const results = await scanner.detectInstalledCLIs(tools);
|
|
132
|
-
|
|
133
|
-
assert.strictEqual(results.size, 3);
|
|
134
|
-
assert.ok(results.has('node'));
|
|
135
|
-
assert.ok(results.has('npm'));
|
|
136
|
-
assert.ok(results.has('non-existent-cli'));
|
|
137
|
-
|
|
138
|
-
assert.strictEqual(results.get('node').available, true);
|
|
139
|
-
assert.strictEqual(results.get('npm').available, true);
|
|
140
|
-
assert.strictEqual(results.get('non-existent-cli').available, false);
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
describe('Error Handling', () => {
|
|
145
|
-
it('should handle null input gracefully', async () => {
|
|
146
|
-
try {
|
|
147
|
-
await scanner.scanForCLI(null);
|
|
148
|
-
assert.fail('Should have thrown an error');
|
|
149
|
-
} catch (error) {
|
|
150
|
-
assert.ok(error.message.includes('Invalid CLI name'));
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it('should handle empty string gracefully', async () => {
|
|
155
|
-
try {
|
|
156
|
-
await scanner.scanForCLI('');
|
|
157
|
-
assert.fail('Should have thrown an error');
|
|
158
|
-
} catch (error) {
|
|
159
|
-
assert.ok(error.message.includes('Invalid CLI name'));
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('should handle timeout during scanning', async () => {
|
|
164
|
-
// 测试超时处理
|
|
165
|
-
const timeoutMs = 1000;
|
|
166
|
-
const startTime = Date.now();
|
|
167
|
-
|
|
168
|
-
try {
|
|
169
|
-
await scanner.scanForCLI('sleep-command-that-does-not-exist', { timeout: timeoutMs });
|
|
170
|
-
} catch (error) {
|
|
171
|
-
const elapsed = Date.now() - startTime;
|
|
172
|
-
assert.ok(elapsed < timeoutMs + 1000); // 允许一些误差
|
|
173
|
-
assert.ok(error.message.includes('timeout') || error.message.includes('not found'));
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
describe('Platform Specific Tests', () => {
|
|
179
|
-
it('should work on Windows', async () => {
|
|
180
|
-
if (process.platform === 'win32') {
|
|
181
|
-
const result = await scanner.scanForCLI('node');
|
|
182
|
-
assert.strictEqual(result.available, true);
|
|
183
|
-
assert.ok(result.path.includes('.exe') || result.path.includes('node'));
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it('should work on Unix-like systems', async () => {
|
|
188
|
-
if (process.platform !== 'win32') {
|
|
189
|
-
const result = await scanner.scanForCLI('node');
|
|
190
|
-
assert.strictEqual(result.available, true);
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
describe('Performance Tests', () => {
|
|
196
|
-
it('should scan multiple CLIs efficiently', async () => {
|
|
197
|
-
const tools = ['node', 'npm', 'git', 'code'];
|
|
198
|
-
const startTime = Date.now();
|
|
199
|
-
|
|
200
|
-
const results = await scanner.detectInstalledCLIs(tools);
|
|
201
|
-
|
|
202
|
-
const elapsed = Date.now() - startTime;
|
|
203
|
-
assert.ok(elapsed < 5000); // 应该在5秒内完成
|
|
204
|
-
assert.strictEqual(results.size, tools.length);
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it('should cache scan results', async () => {
|
|
208
|
-
const cliName = 'node';
|
|
209
|
-
|
|
210
|
-
// 第一次扫描
|
|
211
|
-
const startTime1 = Date.now();
|
|
212
|
-
const result1 = await scanner.scanForCLI(cliName);
|
|
213
|
-
const time1 = Date.now() - startTime1;
|
|
214
|
-
|
|
215
|
-
// 第二次扫描(应该使用缓存)
|
|
216
|
-
const startTime2 = Date.now();
|
|
217
|
-
const result2 = await scanner.scanForCLI(cliName);
|
|
218
|
-
const time2 = Date.now() - startTime2;
|
|
219
|
-
|
|
220
|
-
assert.deepStrictEqual(result1, result2);
|
|
221
|
-
assert.ok(time2 <= time1); // 缓存应该更快或相等
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
// 运行测试
|
|
227
|
-
if (require.main === module) {
|
|
228
|
-
console.log('Running CLI Scanner Unit Tests...');
|
|
229
|
-
|
|
230
|
-
// 简单的测试运行器
|
|
231
|
-
const testMethods = [
|
|
232
|
-
'should detect node command is available',
|
|
233
|
-
'should detect npm command is available',
|
|
234
|
-
'should handle non-existent CLI gracefully',
|
|
235
|
-
'should validate valid Windows commands',
|
|
236
|
-
'should reject invalid commands',
|
|
237
|
-
'should handle null input gracefully'
|
|
238
|
-
];
|
|
239
|
-
|
|
240
|
-
(async () => {
|
|
241
|
-
const scanner = new CLIScanner();
|
|
242
|
-
let passed = 0;
|
|
243
|
-
let failed = 0;
|
|
244
|
-
|
|
245
|
-
for (const testName of testMethods) {
|
|
246
|
-
try {
|
|
247
|
-
console.log(`Testing: ${testName}`);
|
|
248
|
-
|
|
249
|
-
if (testName.includes('node')) {
|
|
250
|
-
const result = await scanner.scanForCLI('node');
|
|
251
|
-
if (result.available) {
|
|
252
|
-
console.log(`[PASS] ${testName}`);
|
|
253
|
-
passed++;
|
|
254
|
-
} else {
|
|
255
|
-
console.log(`[FAIL] ${testName} - Node not available`);
|
|
256
|
-
failed++;
|
|
257
|
-
}
|
|
258
|
-
} else if (testName.includes('npm')) {
|
|
259
|
-
const result = await scanner.scanForCLI('npm');
|
|
260
|
-
if (result.available) {
|
|
261
|
-
console.log(`[PASS] ${testName}`);
|
|
262
|
-
passed++;
|
|
263
|
-
} else {
|
|
264
|
-
console.log(`[FAIL] ${testName} - NPM not available`);
|
|
265
|
-
failed++;
|
|
266
|
-
}
|
|
267
|
-
} else if (testName.includes('non-existent')) {
|
|
268
|
-
try {
|
|
269
|
-
await scanner.scanForCLI('non-existent-cli-12345');
|
|
270
|
-
console.log(`[FAIL] ${testName} - Should have thrown error`);
|
|
271
|
-
failed++;
|
|
272
|
-
} catch (error) {
|
|
273
|
-
console.log(`[PASS] ${testName}`);
|
|
274
|
-
passed++;
|
|
275
|
-
}
|
|
276
|
-
} else {
|
|
277
|
-
console.log(`[SKIP] ${testName} - Implementation needed`);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
} catch (error) {
|
|
281
|
-
console.log(`[ERROR] ${testName} - ${error.message}`);
|
|
282
|
-
failed++;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
console.log(`\nTest Results: ${passed} passed, ${failed} failed`);
|
|
287
|
-
console.log('Implementation needed for full TDD approach.');
|
|
288
|
-
})();
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
module.exports = CLIScanner;
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
// Unit tests for CLI Parameter Handler
|
|
2
|
-
const CLIParameterHandler = require('../../src/core/cli_parameter_handler');
|
|
3
|
-
|
|
4
|
-
// Mock CLI pattern data for testing
|
|
5
|
-
const mockCLIPatterns = {
|
|
6
|
-
claude: {
|
|
7
|
-
commandStructure: {
|
|
8
|
-
nonInteractiveSupport: true,
|
|
9
|
-
promptFlag: '-p',
|
|
10
|
-
nonInteractiveFlag: '--print',
|
|
11
|
-
executionPattern: 'flag-based'
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
codex: {
|
|
15
|
-
commandStructure: {
|
|
16
|
-
nonInteractiveSupport: true,
|
|
17
|
-
promptFlag: '-p',
|
|
18
|
-
nonInteractiveFlag: '--print',
|
|
19
|
-
executionPattern: 'subcommand-based'
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
iflow: {
|
|
23
|
-
commandStructure: {
|
|
24
|
-
nonInteractiveSupport: true,
|
|
25
|
-
promptFlag: '-p',
|
|
26
|
-
executionPattern: 'flag-based'
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
generic: {
|
|
30
|
-
commandStructure: {
|
|
31
|
-
nonInteractiveSupport: false,
|
|
32
|
-
executionPattern: 'interactive-default'
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
// Test cases
|
|
38
|
-
const testCases = [
|
|
39
|
-
{
|
|
40
|
-
name: 'Claude CLI with pattern data',
|
|
41
|
-
toolName: 'claude',
|
|
42
|
-
prompt: 'Write a function to add two numbers',
|
|
43
|
-
cliPattern: mockCLIPatterns.claude,
|
|
44
|
-
expected: ['-p', '"Write a function to add two numbers"']
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: 'Codex CLI with subcommand pattern',
|
|
48
|
-
toolName: 'codex',
|
|
49
|
-
prompt: 'Generate a Fibonacci function',
|
|
50
|
-
cliPattern: mockCLIPatterns.codex,
|
|
51
|
-
expected: ['exec', '-p', '"Generate a Fibonacci function"']
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
name: 'iFlow CLI with pattern data',
|
|
55
|
-
toolName: 'iflow',
|
|
56
|
-
prompt: 'Check if number is even',
|
|
57
|
-
cliPattern: mockCLIPatterns.iflow,
|
|
58
|
-
expected: ['-p', '"Check if number is even"']
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: 'Generic CLI without pattern data',
|
|
62
|
-
toolName: 'generic',
|
|
63
|
-
prompt: 'Generic prompt',
|
|
64
|
-
cliPattern: mockCLIPatterns.generic,
|
|
65
|
-
expected: ['"Generic prompt"']
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
name: 'Unknown CLI without pattern data',
|
|
69
|
-
toolName: 'unknown',
|
|
70
|
-
prompt: 'Unknown prompt',
|
|
71
|
-
cliPattern: null,
|
|
72
|
-
expected: ['"Unknown prompt"']
|
|
73
|
-
}
|
|
74
|
-
];
|
|
75
|
-
|
|
76
|
-
// Run tests
|
|
77
|
-
console.log('Running CLI Parameter Handler Unit Tests...\n');
|
|
78
|
-
|
|
79
|
-
let passedTests = 0;
|
|
80
|
-
let totalTests = testCases.length;
|
|
81
|
-
|
|
82
|
-
for (const testCase of testCases) {
|
|
83
|
-
try {
|
|
84
|
-
const result = CLIParameterHandler.generateArguments(
|
|
85
|
-
testCase.toolName,
|
|
86
|
-
testCase.prompt,
|
|
87
|
-
testCase.cliPattern
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
// Compare results
|
|
91
|
-
const passed = JSON.stringify(result) === JSON.stringify(testCase.expected);
|
|
92
|
-
|
|
93
|
-
console.log(`Test: ${testCase.name}`);
|
|
94
|
-
console.log(`Expected: ${JSON.stringify(testCase.expected)}`);
|
|
95
|
-
console.log(`Actual: ${JSON.stringify(result)}`);
|
|
96
|
-
console.log(`Status: ${passed ? 'PASS' : 'FAIL'}\n`);
|
|
97
|
-
|
|
98
|
-
if (passed) {
|
|
99
|
-
passedTests++;
|
|
100
|
-
}
|
|
101
|
-
} catch (error) {
|
|
102
|
-
console.log(`Test: ${testCase.name}`);
|
|
103
|
-
console.log(`Error: ${error.message}`);
|
|
104
|
-
console.log(`Status: FAIL\n`);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
console.log(`\nUnit Test Results: ${passedTests}/${totalTests} tests passed`);
|
|
109
|
-
|
|
110
|
-
if (passedTests === totalTests) {
|
|
111
|
-
console.log('All unit tests passed!');
|
|
112
|
-
process.exit(0);
|
|
113
|
-
} else {
|
|
114
|
-
console.log('Some unit tests failed!');
|
|
115
|
-
process.exit(1);
|
|
116
|
-
}
|