vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850

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.
Files changed (192) hide show
  1. package/package.json +1 -1
  2. package/src/agents/AgentCheckDiscoveryService.js +180 -0
  3. package/src/agents/AgentCheckService.js +18 -261
  4. package/src/agents/AgentCheckStatisticsService.js +195 -0
  5. package/src/agents/EnvironmentConfigurationManager.js +31 -380
  6. package/src/agents/InstallationType.js +19 -6
  7. package/src/agents/SimpleAgentCheckService.js +472 -0
  8. package/src/agents/config-managers/ConfigUtils.js +72 -0
  9. package/src/agents/config-managers/DefaultConfig.js +58 -0
  10. package/src/agents/config-managers/EnvVarLoader.js +66 -0
  11. package/src/agents/config-managers/FileConfigLoader.js +124 -0
  12. package/src/agents/config-managers/TypeConverters.js +61 -0
  13. package/src/agents/config-managers/VariableMappings.js +92 -0
  14. package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
  15. package/src/agents/discovery/AgentDiscoveryService.js +29 -403
  16. package/src/agents/discovery/agent-validator.js +262 -0
  17. package/src/agents/discovery/discovery-results.js +176 -0
  18. package/src/agents/discovery/discovery-scanner.js +268 -0
  19. package/src/agents/discovery/discovery-utils.js +161 -0
  20. package/src/agents/discovery/executable-analyzer.js +290 -0
  21. package/src/agents/discovery/history-manager.js +310 -0
  22. package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
  23. package/src/agents/verification/ResultAnalyzer.js +30 -431
  24. package/src/agents/verification/analysis-utils.js +310 -0
  25. package/src/agents/verification/batch-analyzer.js +440 -0
  26. package/src/agents/verification/pattern-recognizer.js +369 -0
  27. package/src/agents/verification/report-generator.js +320 -0
  28. package/src/agents/verification/test-analyzer.js +290 -0
  29. package/src/agents/windows/InstallerFactory.js +4 -0
  30. package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
  31. package/src/analysis/analysis-engine.js +314 -0
  32. package/src/analysis/ast-analyzer.js +342 -0
  33. package/src/analysis/boundary-detector-refactored.js +378 -0
  34. package/src/analysis/boundary-detector.js +200 -603
  35. package/src/analysis/boundary-scanner.js +609 -0
  36. package/src/analysis/boundary-types.js +118 -0
  37. package/src/analysis/boundary-utils.js +293 -0
  38. package/src/analysis/deadline-priority-calculator.js +18 -0
  39. package/src/analysis/detection-methods.js +347 -0
  40. package/src/analysis/importance-priority-calculator.js +18 -0
  41. package/src/analysis/priority/factor-calculators.js +204 -0
  42. package/src/analysis/priority/factor-helpers.js +71 -0
  43. package/src/analysis/priority/priority-constants.js +73 -0
  44. package/src/analysis/priority/priority-factor-calculators.js +301 -0
  45. package/src/analysis/priority/reasons-generator.js +44 -0
  46. package/src/analysis/priority-calculator.js +15 -580
  47. package/src/analysis/strategy-generator.js +16 -66
  48. package/src/analysis/type-priority-calculator.js +18 -0
  49. package/src/analysis/urgency-priority-calculator.js +18 -0
  50. package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
  51. package/src/commands/disable-requirement.js +60 -0
  52. package/src/commands/disable-spec.js +60 -0
  53. package/src/commands/enable-requirement.js +60 -0
  54. package/src/commands/enable-spec.js +60 -0
  55. package/src/commands/registry.js +1 -6
  56. package/src/commands/requirements.js +8 -2
  57. package/src/ide-integration/applescript-manager.cjs +9 -24
  58. package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
  59. package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
  60. package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
  61. package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
  62. package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
  63. package/src/ide-integration/cdp-manager.js +28 -573
  64. package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
  65. package/src/ide-integration/ide-openers/claude-opener.js +171 -0
  66. package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
  67. package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
  68. package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
  69. package/src/ide-integration/macos-ide-manager.js +20 -582
  70. package/src/ide-integration/macos-quota-checker.js +164 -0
  71. package/src/ide-integration/macos-text-sender.js +19 -38
  72. package/src/ide-integration/provider-manager.cjs +52 -7
  73. package/src/index.cjs +6 -0
  74. package/src/index.js +10 -0
  75. package/src/llm/direct-llm-manager.cjs +501 -0
  76. package/src/localization/translations/en-part1.js +363 -0
  77. package/src/localization/translations/en-part2.js +320 -0
  78. package/src/localization/translations/en.js +4 -687
  79. package/src/localization/translations/es-part1.js +363 -0
  80. package/src/localization/translations/es-part2.js +320 -0
  81. package/src/localization/translations/es.js +4 -688
  82. package/src/models/file-analysis-collection.js +139 -0
  83. package/src/models/file-analysis-metrics.js +50 -0
  84. package/src/models/file-analysis.js +15 -262
  85. package/src/models/plan-manager.js +410 -0
  86. package/src/models/refactoring-models.js +380 -0
  87. package/src/models/refactoring-plan-refactored.js +81 -0
  88. package/src/models/refactoring-plan.js +2 -663
  89. package/src/monitoring/alert-system.js +4 -45
  90. package/src/monitoring/continuous-scan-notifications.js +37 -191
  91. package/src/monitoring/notification-handlers/base-handler.js +58 -0
  92. package/src/monitoring/notification-handlers/error-handler.js +36 -0
  93. package/src/monitoring/notification-handlers/index.js +21 -0
  94. package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
  95. package/src/monitoring/notification-handlers/progress-handler.js +48 -0
  96. package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
  97. package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
  98. package/src/provider-registry.js +8 -0
  99. package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
  100. package/src/refactoring/boundary/boundary-detector.js +26 -596
  101. package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
  102. package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
  103. package/src/refactoring/boundary/detectors/class-detector.js +247 -0
  104. package/src/refactoring/boundary/detectors/config-detector.js +270 -0
  105. package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
  106. package/src/refactoring/boundary/detectors/function-detector.js +248 -0
  107. package/src/refactoring/boundary/detectors/module-detector.js +249 -0
  108. package/src/refactoring/boundary/detectors/object-detector.js +247 -0
  109. package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
  110. package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
  111. package/src/refactoring/circular-dependency-resolver-original.js +16 -76
  112. package/src/refactoring/code-mover-refactored.js +309 -0
  113. package/src/refactoring/code-mover.js +48 -355
  114. package/src/refactoring/execution-status.js +18 -0
  115. package/src/refactoring/execution-strategies.js +172 -0
  116. package/src/refactoring/file-splitter-core.js +568 -0
  117. package/src/refactoring/file-splitter-types.js +136 -0
  118. package/src/refactoring/file-splitter.js +2 -682
  119. package/src/refactoring/functionality-validator.js +11 -51
  120. package/src/refactoring/import-manager-refactored.js +385 -0
  121. package/src/refactoring/import-manager.js +112 -487
  122. package/src/refactoring/import-models.js +189 -0
  123. package/src/refactoring/import-parser.js +306 -0
  124. package/src/refactoring/move-executor.js +431 -0
  125. package/src/refactoring/move-utils.js +368 -0
  126. package/src/refactoring/operation-executor.js +76 -0
  127. package/src/refactoring/plan-creator.js +36 -0
  128. package/src/refactoring/plan-executor.js +143 -0
  129. package/src/refactoring/plan-validator.js +68 -0
  130. package/src/refactoring/refactoring-executor-result.js +70 -0
  131. package/src/refactoring/refactoring-executor.js +34 -569
  132. package/src/refactoring/refactoring-operation.js +94 -0
  133. package/src/refactoring/refactoring-plan.js +69 -0
  134. package/src/refactoring/refactoring-rollback.js +22 -527
  135. package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
  136. package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
  137. package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
  138. package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
  139. package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
  140. package/src/refactoring/test-validator.js +32 -448
  141. package/src/refactoring/validation/baseline-runner.js +71 -0
  142. package/src/refactoring/validation/report-generator.js +136 -0
  143. package/src/refactoring/validation/result-comparator.js +92 -0
  144. package/src/refactoring/validation/test-suite.js +59 -0
  145. package/src/refactoring/validation/test-validation-result.js +83 -0
  146. package/src/refactoring/validation/validation-runner.js +95 -0
  147. package/src/refactoring/validation/validation-status.js +18 -0
  148. package/src/rui/commands/AgentCommandParser.js +60 -369
  149. package/src/rui/commands/AgentResponseFormatter.js +7 -47
  150. package/src/rui/commands/parsers/CommandMapper.js +148 -0
  151. package/src/rui/commands/parsers/CommandValidator.js +228 -0
  152. package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
  153. package/src/rui/commands/parsers/TokenParser.js +69 -0
  154. package/src/rui/commands/parsers/tokenizer.js +153 -0
  155. package/src/utils/current-requirement-operations.js +50 -1
  156. package/src/utils/report-generator.js +18 -514
  157. package/src/utils/report-generators/analysis-generator.js +115 -0
  158. package/src/utils/report-generators/base-generator.js +141 -0
  159. package/src/utils/report-generators/compliance-generator.js +41 -0
  160. package/src/utils/report-generators/format-handlers.js +185 -0
  161. package/src/utils/report-generators/refactoring-generator.js +46 -0
  162. package/src/utils/report-generators/validation-generator.js +63 -0
  163. package/src/utils/requirement-enable-disable.js +265 -0
  164. package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
  165. package/src/utils/requirement-helpers/requirement-mover.js +88 -1
  166. package/src/utils/requirement-helpers.js +5 -2
  167. package/src/utils/smoke-test-cli.js +45 -8
  168. package/src/utils/specification-enable-disable.js +122 -0
  169. package/src/utils/specification-helpers.js +30 -4
  170. package/src/utils/specification-migration.js +5 -5
  171. package/src/utils/test-comparator.js +118 -0
  172. package/src/utils/test-config.js +54 -0
  173. package/src/utils/test-executor.js +133 -0
  174. package/src/utils/test-parser.js +215 -0
  175. package/src/utils/test-runner-baseline.js +63 -0
  176. package/src/utils/test-runner-core.js +98 -0
  177. package/src/utils/test-runner-report.js +39 -0
  178. package/src/utils/test-runner-validation.js +71 -0
  179. package/src/utils/test-runner.js +11 -535
  180. package/src/validation/comparison-analyzer.js +333 -0
  181. package/src/validation/compliance-reporter-new.js +282 -0
  182. package/src/validation/compliance-reporter-refactored.js +344 -0
  183. package/src/validation/compliance-reporter.js +278 -591
  184. package/src/validation/compliance-utils.js +278 -0
  185. package/src/validation/html-generator.js +446 -0
  186. package/src/validation/metrics/category-calculator.js +137 -0
  187. package/src/validation/metrics/metrics-helpers.js +155 -0
  188. package/src/validation/metrics/overview-calculator.js +85 -0
  189. package/src/validation/metrics/overview-metrics.js +41 -0
  190. package/src/validation/metrics/quality-calculator.js +166 -0
  191. package/src/validation/metrics/size-calculator.js +69 -0
  192. package/src/validation/metrics-calculator.js +27 -551
@@ -5,571 +5,47 @@
5
5
  * Provides test execution, result analysis, and regression detection.
6
6
  */
7
7
 
8
- const { execSync, spawn } = require('child_process');
9
- const fs = require('fs');
10
- const path = require('path');
11
-
12
- /**
13
- * Test result types
14
- */
15
- const TEST_RESULT_TYPES = {
16
- PASS: 'pass',
17
- FAIL: 'fail',
18
- SKIP: 'skip',
19
- ERROR: 'error'
20
- };
8
+ const { TestRunnerCore, TEST_RESULT_TYPES } = require('./test-runner-core');
9
+ const { runBaseline } = require('./test-runner-baseline');
10
+ const { runValidation, runSpecific } = require('./test-runner-validation');
11
+ const { generateReport } = require('./test-runner-report');
21
12
 
22
13
  /**
23
14
  * Test runner class
24
15
  */
25
- class TestRunner {
16
+ class TestRunner extends TestRunnerCore {
26
17
  constructor(options = {}) {
27
- this.options = {
28
- testCommand: 'npm test',
29
- testDir: 'tests',
30
- timeout: 300000, // 5 minutes
31
- retries: 0,
32
- verbose: false,
33
- ...options
34
- };
35
-
36
- this.baselineResults = null;
37
- this.currentResults = null;
38
- this.regressionDetected = false;
18
+ super(options);
39
19
  }
40
20
 
41
21
  /**
42
22
  * Run baseline tests before refactoring
43
23
  */
44
24
  async runBaseline() {
45
- console.log('Running baseline tests...');
46
-
47
- try {
48
- const results = await this.executeTests();
49
- this.baselineResults = results;
50
-
51
- console.log(`Baseline completed: ${results.passed}/${results.total} passed`);
52
- return results;
53
- } catch (error) {
54
- throw new Error(`Baseline test execution failed: ${error.message}`);
55
- }
25
+ return runBaseline(this);
56
26
  }
57
27
 
58
28
  /**
59
29
  * Run tests after refactoring
60
30
  */
61
31
  async runValidation() {
62
- if (!this.baselineResults) {
63
- throw new Error('Baseline results not available. Run baseline first.');
64
- }
65
-
66
- console.log('Running validation tests...');
67
-
68
- try {
69
- const results = await this.executeTests();
70
- this.currentResults = results;
71
-
72
- // Compare with baseline
73
- const comparison = this.compareResults(this.baselineResults, results);
74
- this.regressionDetected = comparison.hasRegressions;
75
-
76
- console.log(`Validation completed: ${results.passed}/${results.total} passed`);
77
-
78
- if (this.regressionDetected) {
79
- console.log(`⚠️ Regressions detected: ${comparison.regressions.length}`);
80
- }
81
-
82
- return {
83
- results,
84
- comparison,
85
- hasRegressions: this.regressionDetected
86
- };
87
- } catch (error) {
88
- throw new Error(`Validation test execution failed: ${error.message}`);
89
- }
90
- }
91
-
92
- /**
93
- * Execute tests and collect results
94
- */
95
- async executeTests() {
96
- return new Promise((resolve, reject) => {
97
- const startTime = Date.now();
98
- let output = '';
99
- let errorOutput = '';
100
-
101
- try {
102
- // Use npm test with JSON reporter if available
103
- const testProcess = spawn('npm', ['test', '--', '--json', '--verbose'], {
104
- stdio: ['pipe', 'pipe', 'pipe'],
105
- cwd: process.cwd()
106
- });
107
-
108
- testProcess.stdout.on('data', (data) => {
109
- output += data.toString();
110
- if (this.options.verbose) {
111
- process.stdout.write(data);
112
- }
113
- });
114
-
115
- testProcess.stderr.on('data', (data) => {
116
- errorOutput += data.toString();
117
- if (this.options.verbose) {
118
- process.stderr.write(data);
119
- }
120
- });
121
-
122
- testProcess.on('close', (code) => {
123
- const duration = Date.now() - startTime;
124
-
125
- try {
126
- const results = this.parseTestOutput(output, errorOutput, code, duration);
127
- resolve(results);
128
- } catch (parseError) {
129
- // Fallback to basic parsing
130
- const fallbackResults = this.parseBasicOutput(output, errorOutput, code, duration);
131
- resolve(fallbackResults);
132
- }
133
- });
134
-
135
- testProcess.on('error', (error) => {
136
- reject(new Error(`Test process failed: ${error.message}`));
137
- });
138
-
139
- // Set timeout
140
- if (this.options.timeout) {
141
- setTimeout(() => {
142
- testProcess.kill('SIGKILL');
143
- reject(new Error(`Test execution timed out after ${this.options.timeout}ms`));
144
- }, this.options.timeout);
145
- }
146
-
147
- } catch (error) {
148
- reject(new Error(`Failed to start test process: ${error.message}`));
149
- }
150
- });
151
- }
152
-
153
- /**
154
- * Parse test output (Jest JSON format)
155
- */
156
- parseTestOutput(stdout, stderr, exitCode, duration) {
157
- try {
158
- // Try to parse JSON output
159
- const jsonMatch = stdout.match(/\{[\s\S]*\}/);
160
- if (jsonMatch) {
161
- const jsonData = JSON.parse(jsonMatch[0]);
162
- return this.parseJestResults(jsonData, duration);
163
- }
164
- } catch (error) {
165
- // JSON parsing failed, fall back to basic parsing
166
- }
167
-
168
- return this.parseBasicOutput(stdout, stderr, exitCode, duration);
169
- }
170
-
171
- /**
172
- * Parse Jest results
173
- */
174
- parseJestResults(jsonData, duration) {
175
- const results = {
176
- total: 0,
177
- passed: 0,
178
- failed: 0,
179
- skipped: 0,
180
- errors: 0,
181
- duration,
182
- suites: [],
183
- tests: [],
184
- coverage: null
185
- };
186
-
187
- if (jsonData.numTotalTests) {
188
- results.total = jsonData.numTotalTests;
189
- results.passed = jsonData.numPassedTests || 0;
190
- results.failed = jsonData.numFailedTests || 0;
191
- results.skipped = jsonData.numPendingTests || 0;
192
- }
193
-
194
- if (jsonData.testResults) {
195
- for (const testSuite of jsonData.testResults) {
196
- const suite = {
197
- name: testSuite.name,
198
- file: testSuite.testFilePath,
199
- passed: 0,
200
- failed: 0,
201
- skipped: 0,
202
- duration: testSuite.perfStats?.end || 0,
203
- tests: []
204
- };
205
-
206
- if (testSuite.assertionResults) {
207
- for (const test of testSuite.assertionResults) {
208
- const testResult = {
209
- title: test.title,
210
- fullName: test.fullName,
211
- status: test.status,
212
- duration: test.duration || 0,
213
- failureMessages: test.failureMessages || []
214
- };
215
-
216
- suite.tests.push(testResult);
217
- results.tests.push(testResult);
218
-
219
- switch (test.status) {
220
- case 'passed':
221
- suite.passed++;
222
- break;
223
- case 'failed':
224
- suite.failed++;
225
- break;
226
- case 'pending':
227
- suite.skipped++;
228
- break;
229
- }
230
- }
231
- }
232
-
233
- results.suites.push(suite);
234
- }
235
- }
236
-
237
- if (jsonData.coverageMap) {
238
- results.coverage = this.parseCoverageData(jsonData.coverageMap);
239
- }
240
-
241
- return results;
242
- }
243
-
244
- /**
245
- * Parse basic test output
246
- */
247
- parseBasicOutput(stdout, stderr, exitCode, duration) {
248
- const results = {
249
- total: 0,
250
- passed: 0,
251
- failed: 0,
252
- skipped: 0,
253
- errors: 0,
254
- duration,
255
- suites: [],
256
- tests: [],
257
- coverage: null
258
- };
259
-
260
- // Parse Jest-style output
261
- const testMatch = stdout.match(/(\d+)\s+tests?\s+(\d+)\s+failed/);
262
- if (testMatch) {
263
- results.total = parseInt(testMatch[1]);
264
- results.failed = parseInt(testMatch[2]);
265
- results.passed = results.total - results.failed;
266
- }
267
-
268
- // Parse pass/fail summary
269
- const passMatch = stdout.match(/(\d+)\s+passing/);
270
- if (passMatch) {
271
- results.passed = parseInt(passMatch[1]);
272
- }
273
-
274
- const failMatch = stdout.match(/(\d+)\s+failing/);
275
- if (failMatch) {
276
- results.failed = parseInt(failMatch[1]);
277
- }
278
-
279
- const skipMatch = stdout.match(/(\d+)\s+skipping/);
280
- if (skipMatch) {
281
- results.skipped = parseInt(skipMatch[1]);
282
- }
283
-
284
- // Extract individual test results
285
- const testLines = stdout.split('\n');
286
- for (const line of testLines) {
287
- const testMatch = line.match(/^(✓|✗|○)\s+(.+)$/);
288
- if (testMatch) {
289
- const status = testMatch[1] === '✓' ? 'passed' :
290
- testMatch[1] === '✗' ? 'failed' : 'skipped';
291
- const title = testMatch[2];
292
-
293
- results.tests.push({
294
- title,
295
- status,
296
- duration: 0,
297
- failureMessages: status === 'failed' ? [line] : []
298
- });
299
- }
300
- }
301
-
302
- return results;
303
- }
304
-
305
- /**
306
- * Parse coverage data
307
- */
308
- parseCoverageData(coverageMap) {
309
- const coverage = {
310
- lines: { total: 0, covered: 0, percentage: 0 },
311
- functions: { total: 0, covered: 0, percentage: 0 },
312
- branches: { total: 0, covered: 0, percentage: 0 },
313
- statements: { total: 0, covered: 0, percentage: 0 }
314
- };
315
-
316
- for (const [filePath, fileCoverage] of Object.entries(coverageMap)) {
317
- // Parse line coverage
318
- if (fileCoverage.l) {
319
- const lines = Object.values(fileCoverage.l);
320
- coverage.lines.total += lines.length;
321
- coverage.lines.covered += lines.filter(count => count > 0).length;
322
- }
323
-
324
- // Parse function coverage
325
- if (fileCoverage.f) {
326
- const functions = Object.values(fileCoverage.f);
327
- coverage.functions.total += functions.length;
328
- coverage.functions.covered += functions.filter(count => count > 0).length;
329
- }
330
-
331
- // Parse branch coverage
332
- if (fileCoverage.b) {
333
- for (const branches of Object.values(fileCoverage.b)) {
334
- coverage.branches.total += branches.length;
335
- coverage.branches.covered += branches.filter(count => count > 0).length;
336
- }
337
- }
338
-
339
- // Parse statement coverage
340
- if (fileCoverage.s) {
341
- const statements = Object.values(fileCoverage.s);
342
- coverage.statements.total += statements.length;
343
- coverage.statements.covered += statements.filter(count => count > 0).length;
344
- }
345
- }
346
-
347
- // Calculate percentages
348
- for (const metric of Object.values(coverage)) {
349
- metric.percentage = metric.total > 0 ?
350
- Math.round((metric.covered / metric.total) * 100) : 0;
351
- }
352
-
353
- return coverage;
354
- }
355
-
356
- /**
357
- * Compare baseline and current results
358
- */
359
- compareResults(baseline, current) {
360
- const comparison = {
361
- hasRegressions: false,
362
- regressions: [],
363
- improvements: [],
364
- unchanged: [],
365
- summary: {
366
- baseline: {
367
- total: baseline.total,
368
- passed: baseline.passed,
369
- failed: baseline.failed,
370
- duration: baseline.duration
371
- },
372
- current: {
373
- total: current.total,
374
- passed: current.passed,
375
- failed: current.failed,
376
- duration: current.duration
377
- }
378
- }
379
- };
380
-
381
- // Check for test count changes
382
- if (current.total < baseline.total) {
383
- comparison.regressions.push({
384
- type: 'missing_tests',
385
- message: `${baseline.total - current.total} tests are missing`,
386
- severity: 'high'
387
- });
388
- comparison.hasRegressions = true;
389
- }
390
-
391
- if (current.total > baseline.total) {
392
- comparison.improvements.push({
393
- type: 'new_tests',
394
- message: `${current.total - baseline.total} new tests added`,
395
- severity: 'info'
396
- });
397
- }
398
-
399
- // Check for test failures
400
- if (current.failed > baseline.failed) {
401
- comparison.regressions.push({
402
- type: 'new_failures',
403
- message: `${current.failed - baseline.failed} new test failures`,
404
- severity: 'high'
405
- });
406
- comparison.hasRegressions = true;
407
- }
408
-
409
- if (current.failed < baseline.failed) {
410
- comparison.improvements.push({
411
- type: 'fixed_failures',
412
- message: `${baseline.failed - current.failed} test failures fixed`,
413
- severity: 'good'
414
- });
415
- }
416
-
417
- // Check for performance regression
418
- const performanceIncrease = current.duration - baseline.duration;
419
- const performancePercent = (performanceIncrease / baseline.duration) * 100;
420
-
421
- if (performanceIncrease > 5000 && performancePercent > 10) { // 5s and 10%
422
- comparison.regressions.push({
423
- type: 'performance',
424
- message: `Test execution increased by ${Math.round(performancePercent)}% (${Math.round(performanceIncrease/1000)}s)`,
425
- severity: 'medium'
426
- });
427
- comparison.hasRegressions = true;
428
- }
429
-
430
- // Compare individual test results
431
- const baselineTests = new Map();
432
- for (const test of baseline.tests) {
433
- baselineTests.set(test.fullName, test);
434
- }
435
-
436
- for (const test of current.tests) {
437
- const baselineTest = baselineTests.get(test.fullName);
438
-
439
- if (!baselineTest) {
440
- comparison.improvements.push({
441
- type: 'new_test',
442
- message: `New test: ${test.title}`,
443
- severity: 'info'
444
- });
445
- } else if (baselineTest.status === 'passed' && test.status === 'failed') {
446
- comparison.regressions.push({
447
- type: 'test_regression',
448
- message: `Test now failing: ${test.title}`,
449
- severity: 'high',
450
- test: test
451
- });
452
- comparison.hasRegressions = true;
453
- } else if (baselineTest.status === 'failed' && test.status === 'passed') {
454
- comparison.improvements.push({
455
- type: 'test_fixed',
456
- message: `Test now passing: ${test.title}`,
457
- severity: 'good'
458
- });
459
- }
460
- }
461
-
462
- return comparison;
32
+ return runValidation(this);
463
33
  }
464
34
 
465
35
  /**
466
36
  * Run specific test files
467
37
  */
468
38
  async runSpecificTests(testFiles) {
469
- console.log(`Running ${testFiles.length} specific tests...`);
470
-
471
- const testArgs = ['test', '--', ...testFiles];
472
-
473
- return new Promise((resolve, reject) => {
474
- const startTime = Date.now();
475
- let output = '';
476
- let errorOutput = '';
477
-
478
- const testProcess = spawn('npm', testArgs, {
479
- stdio: ['pipe', 'pipe', 'pipe'],
480
- cwd: process.cwd()
481
- });
482
-
483
- testProcess.stdout.on('data', (data) => {
484
- output += data.toString();
485
- if (this.options.verbose) {
486
- process.stdout.write(data);
487
- }
488
- });
489
-
490
- testProcess.stderr.on('data', (data) => {
491
- errorOutput += data.toString();
492
- if (this.options.verbose) {
493
- process.stderr.write(data);
494
- }
495
- });
496
-
497
- testProcess.on('close', (code) => {
498
- const duration = Date.now() - startTime;
499
- const results = this.parseBasicOutput(output, errorOutput, code, duration);
500
- resolve(results);
501
- });
502
-
503
- testProcess.on('error', (error) => {
504
- reject(new Error(`Test process failed: ${error.message}`));
505
- });
39
+ return runSpecific(testFiles, {
40
+ verbose: this.options.verbose
506
41
  });
507
42
  }
508
43
 
509
- /**
510
- * Check if tests are available
511
- */
512
- checkTestAvailability() {
513
- const testPaths = [
514
- 'package.json',
515
- 'tests',
516
- '__tests__',
517
- 'test',
518
- 'spec'
519
- ];
520
-
521
- for (const testPath of testPaths) {
522
- if (fs.existsSync(testPath)) {
523
- return true;
524
- }
525
- }
526
-
527
- return false;
528
- }
529
-
530
- /**
531
- * Get test configuration
532
- */
533
- getTestConfig() {
534
- try {
535
- const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
536
- return {
537
- hasTestScript: !!packageJson.scripts?.test,
538
- testScript: packageJson.scripts?.test,
539
- jestConfig: packageJson.jest,
540
- dependencies: {
541
- jest: packageJson.dependencies?.jest || packageJson.devDependencies?.jest,
542
- mocha: packageJson.dependencies?.mocha || packageJson.devDependencies?.mocha,
543
- jasmine: packageJson.dependencies?.jasmine || packageJson.devDependencies?.jasmine
544
- }
545
- };
546
- } catch (error) {
547
- return { hasTestScript: false };
548
- }
549
- }
550
-
551
44
  /**
552
45
  * Generate test report
553
46
  */
554
47
  generateReport() {
555
- if (!this.currentResults) {
556
- throw new Error('No test results available. Run tests first.');
557
- }
558
-
559
- const report = {
560
- timestamp: new Date().toISOString(),
561
- baseline: this.baselineResults,
562
- current: this.currentResults,
563
- comparison: this.compareResults(this.baselineResults, this.currentResults),
564
- config: this.getTestConfig(),
565
- summary: {
566
- hasRegressions: this.regressionDetected,
567
- testCountChanged: this.baselineResults.total !== this.currentResults.total,
568
- performanceChanged: Math.abs(this.currentResults.duration - this.baselineResults.duration) > 1000
569
- }
570
- };
571
-
572
- return report;
48
+ return generateReport(this);
573
49
  }
574
50
  }
575
51