stigmergy 1.2.0 → 1.2.8
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 +31 -211
- package/STIGMERGY.md +70 -61
- package/docs/MULTI_USER_WIKI_COLLABORATION_SYSTEM.md +523 -0
- package/docs/PROJECT_CONSTITUTION.md +433 -433
- package/docs/PROJECT_STRUCTURE_CURRENT.md +80 -80
- package/docs/PROMPT_BASED_SKILLS_SYSTEM_DESIGN.md +458 -0
- package/docs/SKILL_IMPLEMENTATION_CONSTRAINTS_AND_ALIGNMENT.md +423 -0
- package/docs/TECHNICAL_FEASIBILITY_ANALYSIS.md +308 -0
- 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/multilingual-hook-demo.js +125 -0
- package/examples/rest-client-example.js +52 -52
- package/examples/rest_client_example.js +54 -54
- package/package.json +38 -20
- package/scripts/build.js +74 -74
- package/scripts/dependency-analyzer.js +101 -0
- package/scripts/generate-cli-docs.js +64 -0
- package/scripts/post-deployment-config.js +296 -296
- package/scripts/postuninstall.js +46 -0
- package/scripts/preinstall-check.js +173 -173
- package/scripts/preuninstall.js +75 -0
- 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/cli/router.js +562 -39
- package/src/core/cache_cleaner.js +82 -59
- package/src/core/cli_help_analyzer.js +297 -291
- package/src/core/cli_parameter_handler.js +5 -0
- package/src/core/cli_tools.js +6 -6
- package/src/core/coordination/index.js +2 -2
- package/src/core/coordination/nodejs/AdapterManager.js +30 -17
- package/src/core/coordination/nodejs/CLCommunication.js +28 -20
- package/src/core/coordination/nodejs/CLIIntegrationManager.js +72 -36
- package/src/core/coordination/nodejs/HealthChecker.js +13 -14
- package/src/core/coordination/nodejs/HookDeploymentManager.js +325 -63
- package/src/core/coordination/nodejs/StatisticsCollector.js +6 -6
- package/src/core/coordination/nodejs/index.js +29 -11
- package/src/core/coordination/nodejs/utils/Logger.js +1 -1
- package/src/core/enhanced_installer.js +92 -69
- package/src/core/enhanced_uninstaller.js +73 -53
- package/src/core/installer.js +815 -294
- package/src/core/multilingual/language-pattern-manager.js +172 -0
- package/src/core/smart_router.js +141 -26
- package/src/core/upgrade_manager.js +91 -46
- package/src/data_structures.js +1 -1
- package/src/deploy.js +2 -2
- package/src/index.js +3 -3
- package/src/test/cli-availability-checker.js +194 -0
- package/src/test/test-environment.js +289 -0
- package/src/utils/helpers.js +2 -2
- package/src/utils.js +7 -1
- package/test/multilingual/hook-deployment.test.js +91 -0
- package/test/multilingual/language-pattern-manager.test.js +140 -0
- package/test/multilingual/system-test.js +85 -0
- 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
package/scripts/publish.js
CHANGED
|
@@ -1,268 +1,58 @@
|
|
|
1
|
-
#!/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
throw new Error(`版本格式不正确: ${pkg.version}`);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// 检查仓库URL
|
|
63
|
-
if (!pkg.repository?.url) {
|
|
64
|
-
throw new Error('缺少repository.url');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
this.log('所有检查通过', 'success');
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async buildProject() {
|
|
71
|
-
this.log('构建项目...', 'info');
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
// 清理之前的构建
|
|
75
|
-
execSync('rm -rf dist', { cwd: this.rootDir });
|
|
76
|
-
|
|
77
|
-
// 创建dist目录
|
|
78
|
-
execSync('mkdir -p dist', { cwd: this.rootDir });
|
|
79
|
-
|
|
80
|
-
// 复制必要文件
|
|
81
|
-
const filesToCopy = [
|
|
82
|
-
'src/index.js',
|
|
83
|
-
'src/adapters/',
|
|
84
|
-
'src/templates/',
|
|
85
|
-
'package.json',
|
|
86
|
-
'README.md',
|
|
87
|
-
'LICENSE'
|
|
88
|
-
];
|
|
89
|
-
|
|
90
|
-
for (const file of filesToCopy) {
|
|
91
|
-
if (file.endsWith('/')) {
|
|
92
|
-
execSync(`cp -r ${file} dist/`, { cwd: this.rootDir });
|
|
93
|
-
} else {
|
|
94
|
-
execSync(`cp ${file} dist/`, { cwd: this.rootDir });
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// 复制bin文件
|
|
99
|
-
execSync('mkdir -p dist/bin', { cwd: this.rootDir });
|
|
100
|
-
execSync('cp bin/* dist/bin/', { cwd: this.rootDir });
|
|
101
|
-
|
|
102
|
-
// 生成package.json用于发布
|
|
103
|
-
const publishPackage = await this.readPackage();
|
|
104
|
-
const publishConfig = {
|
|
105
|
-
...publishPackage,
|
|
106
|
-
files: [
|
|
107
|
-
'src/index.js',
|
|
108
|
-
'src/adapters/**',
|
|
109
|
-
'src/templates/**',
|
|
110
|
-
'bin/**',
|
|
111
|
-
'README.md',
|
|
112
|
-
'LICENSE'
|
|
113
|
-
],
|
|
114
|
-
main: 'src/index.js',
|
|
115
|
-
bin: {
|
|
116
|
-
'stigmergy-cli': 'src/index.js'
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
await writeFile(
|
|
121
|
-
join(this.rootDir, 'dist/package.json'),
|
|
122
|
-
JSON.stringify(publishConfig, null, 2),
|
|
123
|
-
'utf8'
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
this.log('构建完成', 'success');
|
|
127
|
-
} catch (error) {
|
|
128
|
-
this.log(`构建失败: ${error.message}`, 'error');
|
|
129
|
-
throw error;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async runTests() {
|
|
134
|
-
this.log('运行测试...', 'info');
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
execSync('npm test', { cwd: this.rootDir, stdio: 'inherit' });
|
|
138
|
-
this.log('测试通过', 'success');
|
|
139
|
-
} catch (error) {
|
|
140
|
-
this.log(`测试失败: ${error.message}`, 'error');
|
|
141
|
-
throw error;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async publishToNPM(dryRun = false) {
|
|
146
|
-
this.log('准备发布到npm...', 'info');
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
// 检查是否已登录npm
|
|
150
|
-
try {
|
|
151
|
-
execSync('npm whoami', { stdio: 'pipe' });
|
|
152
|
-
this.log('npm登录状态: 已登录', 'success');
|
|
153
|
-
} catch {
|
|
154
|
-
this.log('请先登录npm: npm login', 'warning');
|
|
155
|
-
throw new Error('需要先登录npm');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// 检查包名是否可用
|
|
159
|
-
const pkg = await this.readPackage();
|
|
160
|
-
try {
|
|
161
|
-
execSync(`npm view ${pkg.name}`, { stdio: 'pipe' });
|
|
162
|
-
this.log(`包名 ${pkg.name} 已存在,将覆盖发布`, 'warning');
|
|
163
|
-
} catch {
|
|
164
|
-
this.log(`包名 ${pkg.name} 可用`, 'success');
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// 发布命令
|
|
168
|
-
const publishCmd = dryRun ? 'npm publish --dry-run' : 'npm publish --access public';
|
|
169
|
-
|
|
170
|
-
if (dryRun) {
|
|
171
|
-
this.log('模拟发布中...', 'info');
|
|
172
|
-
execSync(publishCmd, { cwd: join(this.rootDir, 'dist'), stdio: 'inherit' });
|
|
173
|
-
this.log('模拟发布完成', 'success');
|
|
174
|
-
} else {
|
|
175
|
-
this.log('发布到npm...', 'info');
|
|
176
|
-
execSync(publishCmd, { cwd: join(this.rootDir, 'dist'), stdio: 'inherit' });
|
|
177
|
-
this.log('发布成功!', 'success');
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
} catch (error) {
|
|
181
|
-
this.log(`发布失败: ${error.message}`, 'error');
|
|
182
|
-
throw error;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async versionUpdate(type = 'patch') {
|
|
187
|
-
this.log(`更新版本 (${type})...`, 'info');
|
|
188
|
-
|
|
189
|
-
try {
|
|
190
|
-
execSync(`npm version ${type}`, { cwd: this.rootDir, stdio: 'inherit' });
|
|
191
|
-
this.log('版本更新完成', 'success');
|
|
192
|
-
} catch (error) {
|
|
193
|
-
this.log(`版本更新失败: ${error.message}`, 'error');
|
|
194
|
-
throw error;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async showHelp() {
|
|
199
|
-
console.log(`
|
|
200
|
-
🚀 Stigmergy CLI 发布工具
|
|
201
|
-
|
|
202
|
-
用法: node scripts/publish.js [选项]
|
|
203
|
-
|
|
204
|
-
选项:
|
|
205
|
-
--dry-run 模拟发布,不实际上传到npm
|
|
206
|
-
--patch 更新补丁版本 (默认)
|
|
207
|
-
--minor 更新次版本
|
|
208
|
-
--major 更新主版本
|
|
209
|
-
--help, -h 显示帮助信息
|
|
210
|
-
|
|
211
|
-
示例:
|
|
212
|
-
node scripts/publish.js # 发布到npm
|
|
213
|
-
node scripts/publish.js --dry-run # 模拟发布
|
|
214
|
-
node scripts/publish.js --minor # 更新次版本并发布
|
|
215
|
-
node scripts/publish.js --help # 显示帮助
|
|
216
|
-
|
|
217
|
-
工作流程:
|
|
218
|
-
1. 检查发布要求
|
|
219
|
-
2. 运行测试
|
|
220
|
-
3. 构建项目
|
|
221
|
-
4. 更新版本 (可选)
|
|
222
|
-
5. 发布到npm
|
|
223
|
-
`);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
async function main() {
|
|
228
|
-
const publisher = new NPMPublisher();
|
|
229
|
-
const args = process.argv.slice(2);
|
|
230
|
-
|
|
231
|
-
// 显示帮助
|
|
232
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
233
|
-
publisher.showHelp();
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
try {
|
|
238
|
-
// 检查发布要求
|
|
239
|
-
await publisher.checkRequirements();
|
|
240
|
-
|
|
241
|
-
// 运行测试
|
|
242
|
-
await publisher.runTests();
|
|
243
|
-
|
|
244
|
-
// 构建项目
|
|
245
|
-
await publisher.buildProject();
|
|
246
|
-
|
|
247
|
-
// 处理版本更新
|
|
248
|
-
let versionType = 'patch';
|
|
249
|
-
if (args.includes('--minor')) versionType = 'minor';
|
|
250
|
-
if (args.includes('--major')) versionType = 'major';
|
|
251
|
-
|
|
252
|
-
if (versionType !== 'patch') {
|
|
253
|
-
await publisher.versionUpdate(versionType);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// 发布到npm
|
|
257
|
-
const dryRun = args.includes('--dry-run');
|
|
258
|
-
await publisher.publishToNPM(dryRun);
|
|
259
|
-
|
|
260
|
-
} catch (error) {
|
|
261
|
-
console.error('发布失败:', error.message);
|
|
262
|
-
process.exit(1);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
267
|
-
main();
|
|
268
|
-
}
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Release script for Stigmergy CLI v1.2.1
|
|
3
|
+
|
|
4
|
+
echo "=========================================="
|
|
5
|
+
echo "Stigmergy CLI v1.2.1 Release Preparation"
|
|
6
|
+
echo "=========================================="
|
|
7
|
+
|
|
8
|
+
echo ""
|
|
9
|
+
echo "Changes in v1.2.1:"
|
|
10
|
+
echo "- Added 'call' command implementation to modular architecture"
|
|
11
|
+
echo "- Moved old main.js and main_english.js implementations to archive directory"
|
|
12
|
+
echo "- Fixed missing call command functionality in new system"
|
|
13
|
+
echo "- Updated version from 1.2.0 to 1.2.1"
|
|
14
|
+
echo ""
|
|
15
|
+
|
|
16
|
+
# Verify package
|
|
17
|
+
echo "Verifying package..."
|
|
18
|
+
npm pack
|
|
19
|
+
echo "Package stigmergy-1.2.1.tgz created successfully"
|
|
20
|
+
|
|
21
|
+
# Show important files for verification
|
|
22
|
+
echo ""
|
|
23
|
+
echo "Important files to verify before publishing:"
|
|
24
|
+
echo "- package.json: version updated to 1.2.1"
|
|
25
|
+
echo "- CHANGELOG.md: updated with v1.2.1 changes"
|
|
26
|
+
echo "- src/cli/router.js: contains call command implementation"
|
|
27
|
+
echo "- archive/main.js.backup: old implementation preserved"
|
|
28
|
+
|
|
29
|
+
# Instructions for publishing
|
|
30
|
+
echo ""
|
|
31
|
+
echo "=========================================="
|
|
32
|
+
echo "Publishing Instructions (for maintainers):"
|
|
33
|
+
echo "=========================================="
|
|
34
|
+
echo ""
|
|
35
|
+
echo "Before publishing, ensure you have:"
|
|
36
|
+
echo "1. npm login credentials"
|
|
37
|
+
echo "2. Two-factor authentication set up (if required)"
|
|
38
|
+
echo "3. Permissions to publish to 'stigmergy' package"
|
|
39
|
+
echo ""
|
|
40
|
+
echo "To publish the package, run:"
|
|
41
|
+
echo " npm publish"
|
|
42
|
+
echo ""
|
|
43
|
+
echo "To publish a specific tag (e.g., beta):"
|
|
44
|
+
echo " npm publish --tag beta"
|
|
45
|
+
echo ""
|
|
46
|
+
echo "After publishing, verify the release:"
|
|
47
|
+
echo " npm view stigmergy@1.2.1"
|
|
48
|
+
echo ""
|
|
49
|
+
echo "=========================================="
|
|
50
|
+
echo "Git Tagging Commands:"
|
|
51
|
+
echo "=========================================="
|
|
52
|
+
echo "After successful npm publish, tag the release:"
|
|
53
|
+
echo " git add ."
|
|
54
|
+
echo " git commit -m \"Release v1.2.1 - Add call command to modular architecture\""
|
|
55
|
+
echo " git tag -a v1.2.1 -m \"Release v1.2.1\""
|
|
56
|
+
echo " git push origin main"
|
|
57
|
+
echo " git push origin v1.2.1"
|
|
58
|
+
echo "=========================================="
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Layered Test Runner
|
|
5
|
+
* Executes tests in layers with appropriate filtering based on CLI availability
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const CLIAvailabilityChecker = require('../src/test/cli-availability-checker');
|
|
11
|
+
|
|
12
|
+
class LayeredTestRunner {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.baseDir = path.resolve(__dirname, '..');
|
|
15
|
+
this.coverageDir = path.join(this.baseDir, 'coverage');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Run all test layers
|
|
20
|
+
*/
|
|
21
|
+
async runAll(options = {}) {
|
|
22
|
+
console.log('🧪 Stigmergy CLI Layered Test Runner');
|
|
23
|
+
console.log('=====================================\n');
|
|
24
|
+
|
|
25
|
+
const { skipE2E = false, onlyAvailable = false } = options;
|
|
26
|
+
|
|
27
|
+
// Check CLI availability
|
|
28
|
+
console.log('1. Checking CLI tool availability...');
|
|
29
|
+
const availabilityChecker = new CLIAvailabilityChecker();
|
|
30
|
+
await availabilityChecker.printAvailabilityReport();
|
|
31
|
+
|
|
32
|
+
// Layer 1: Unit Tests
|
|
33
|
+
console.log('\n2. Running Unit Tests...');
|
|
34
|
+
const unitResult = await this.runUnitTests();
|
|
35
|
+
|
|
36
|
+
// Layer 2: Integration Tests
|
|
37
|
+
console.log('\n3. Running Integration Tests...');
|
|
38
|
+
const integrationResult = await this.runIntegrationTests();
|
|
39
|
+
|
|
40
|
+
// Layer 3: E2E Tests (optional)
|
|
41
|
+
let e2eResult = null;
|
|
42
|
+
if (!skipE2E) {
|
|
43
|
+
console.log('\n4. Running E2E Tests...');
|
|
44
|
+
e2eResult = await this.runE2ETests(onlyAvailable);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Generate report
|
|
48
|
+
this.printSummary({
|
|
49
|
+
unit: unitResult,
|
|
50
|
+
integration: integrationResult,
|
|
51
|
+
e2e: e2eResult
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Exit with appropriate code
|
|
55
|
+
const allPassed = this.allTestsPassed(unitResult, integrationResult, e2eResult);
|
|
56
|
+
process.exit(allPassed ? 0 : 1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Run unit tests
|
|
61
|
+
*/
|
|
62
|
+
async runUnitTests() {
|
|
63
|
+
return this.runJest('tests/unit', {
|
|
64
|
+
coverage: true,
|
|
65
|
+
coverageDirectory: 'coverage/unit',
|
|
66
|
+
testPathIgnorePatterns: ['<rootDir>/tests/e2e/', '<rootDir>/tests/integration/']
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Run integration tests
|
|
72
|
+
*/
|
|
73
|
+
async runIntegrationTests() {
|
|
74
|
+
return this.runJest('tests/integration', {
|
|
75
|
+
coverage: true,
|
|
76
|
+
coverageDirectory: 'coverage/integration',
|
|
77
|
+
testPathIgnorePatterns: ['<rootDir>/tests/unit/', '<rootDir>/tests/e2e/']
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Run E2E tests
|
|
83
|
+
*/
|
|
84
|
+
async runE2ETests(onlyAvailable = false) {
|
|
85
|
+
const env = onlyAvailable ? { ONLY_AVAILABLE_CLIS: 'true' } : {};
|
|
86
|
+
|
|
87
|
+
return this.runJest('tests/e2e', {
|
|
88
|
+
coverage: false, // Usually not needed for E2E
|
|
89
|
+
testTimeout: 60000, // Longer timeout for E2E
|
|
90
|
+
maxWorkers: 1, // Run E2E tests serially to avoid conflicts
|
|
91
|
+
env
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Run Jest with specific options
|
|
97
|
+
*/
|
|
98
|
+
async runJest(testPath, options = {}) {
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
const args = [
|
|
101
|
+
testPath,
|
|
102
|
+
'--verbose',
|
|
103
|
+
'--no-cache',
|
|
104
|
+
`--testTimeout=${options.testTimeout || 30000}`,
|
|
105
|
+
`--maxWorkers=${options.maxWorkers || 4}`
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
if (options.coverage) {
|
|
109
|
+
args.push('--coverage');
|
|
110
|
+
args.push(`--coverageDirectory=${options.coverageDirectory}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (options.testPathIgnorePatterns) {
|
|
114
|
+
options.testPathIgnorePatterns.forEach(pattern => {
|
|
115
|
+
args.push('--testPathIgnorePatterns=' + pattern);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const jestPath = process.platform === 'win32'
|
|
120
|
+
? path.join(this.baseDir, 'node_modules', '.bin', 'jest.cmd')
|
|
121
|
+
: path.join(this.baseDir, 'node_modules', '.bin', 'jest');
|
|
122
|
+
|
|
123
|
+
const child = spawn(jestPath, args, {
|
|
124
|
+
cwd: this.baseDir,
|
|
125
|
+
stdio: 'pipe',
|
|
126
|
+
env: { ...process.env, ...options.env }
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
let stdout = '';
|
|
130
|
+
let stderr = '';
|
|
131
|
+
|
|
132
|
+
child.stdout.on('data', (data) => {
|
|
133
|
+
stdout += data.toString();
|
|
134
|
+
process.stdout.write(data);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
child.stderr.on('data', (data) => {
|
|
138
|
+
stderr += data.toString();
|
|
139
|
+
process.stderr.write(data);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
child.on('close', (code) => {
|
|
143
|
+
resolve({
|
|
144
|
+
success: code === 0,
|
|
145
|
+
exitCode: code,
|
|
146
|
+
stdout,
|
|
147
|
+
stderr
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Check if all tests passed
|
|
155
|
+
*/
|
|
156
|
+
allTestsPassed(unit, integration, e2e) {
|
|
157
|
+
const results = [unit, integration];
|
|
158
|
+
if (e2e) results.push(e2e);
|
|
159
|
+
|
|
160
|
+
return results.every(result => result && result.success);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Print test summary
|
|
165
|
+
*/
|
|
166
|
+
printSummary(results) {
|
|
167
|
+
console.log('\n=====================================');
|
|
168
|
+
console.log('Test Layer Summary:');
|
|
169
|
+
console.log('=====================================');
|
|
170
|
+
|
|
171
|
+
const layers = [
|
|
172
|
+
{ name: 'Unit Tests', result: results.unit },
|
|
173
|
+
{ name: 'Integration Tests', result: results.integration },
|
|
174
|
+
{ name: 'E2E Tests', result: results.e2e, optional: true }
|
|
175
|
+
];
|
|
176
|
+
|
|
177
|
+
let allPassed = true;
|
|
178
|
+
|
|
179
|
+
layers.forEach(layer => {
|
|
180
|
+
if (!layer.result) {
|
|
181
|
+
console.log(`${layer.name}: SKIPPED`);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const status = layer.result.success ? 'PASS' : 'FAIL';
|
|
186
|
+
console.log(`${layer.name}: ${status} (exit code: ${layer.result.exitCode})`);
|
|
187
|
+
|
|
188
|
+
if (!layer.result.success) {
|
|
189
|
+
allPassed = false;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
console.log('=====================================');
|
|
194
|
+
console.log(`Overall: ${allPassed ? '�?ALL TESTS PASSED' : '�?SOME TESTS FAILED'}`);
|
|
195
|
+
console.log('=====================================\n');
|
|
196
|
+
|
|
197
|
+
if (allPassed) {
|
|
198
|
+
console.log('🎉 Ready for deployment!');
|
|
199
|
+
} else {
|
|
200
|
+
console.log('�?Please fix failing tests before deployment.');
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// CLI interface
|
|
206
|
+
async function main() {
|
|
207
|
+
const args = process.argv.slice(2);
|
|
208
|
+
const options = {};
|
|
209
|
+
|
|
210
|
+
if (args.includes('--skip-e2e')) {
|
|
211
|
+
options.skipE2E = true;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (args.includes('--only-available')) {
|
|
215
|
+
options.onlyAvailable = true;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
219
|
+
console.log(`
|
|
220
|
+
Usage: node scripts/run-layered-tests.js [options]
|
|
221
|
+
|
|
222
|
+
Options:
|
|
223
|
+
--skip-e2e Skip end-to-end tests
|
|
224
|
+
--only-available Only test with available CLI tools
|
|
225
|
+
--help, -h Show this help message
|
|
226
|
+
|
|
227
|
+
Examples:
|
|
228
|
+
node scripts/run-layered-tests.js
|
|
229
|
+
node scripts/run-layered-tests.js --skip-e2e
|
|
230
|
+
node scripts/run-layered-tests.js --only-available
|
|
231
|
+
`);
|
|
232
|
+
process.exit(0);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const runner = new LayeredTestRunner();
|
|
236
|
+
await runner.runAll(options);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Run if called directly
|
|
240
|
+
if (require.main === module) {
|
|
241
|
+
main().catch(error => {
|
|
242
|
+
console.error('Test runner failed:', error);
|
|
243
|
+
process.exit(1);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
module.exports = LayeredTestRunner;
|