vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1642
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates refactoring operations by running tests and ensuring functionality is preserved.
|
|
5
|
+
* Provides comprehensive test validation and regression detection.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { TestRunner } = require('../utils/test-runner');
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Validation status
|
|
14
|
+
*/
|
|
15
|
+
const VALIDATION_STATUS = {
|
|
16
|
+
PENDING: 'pending',
|
|
17
|
+
RUNNING: 'running',
|
|
18
|
+
PASSED: 'passed',
|
|
19
|
+
FAILED: 'failed',
|
|
20
|
+
SKIPPED: 'skipped',
|
|
21
|
+
ERROR: 'error'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Test validation result class
|
|
26
|
+
*/
|
|
27
|
+
class TestValidationResult {
|
|
28
|
+
constructor(operationId) {
|
|
29
|
+
this.operationId = operationId;
|
|
30
|
+
this.status = VALIDATION_STATUS.PENDING;
|
|
31
|
+
this.baselineResults = null;
|
|
32
|
+
this.validationResults = null;
|
|
33
|
+
this.comparison = null;
|
|
34
|
+
this.duration = 0;
|
|
35
|
+
this.errors = [];
|
|
36
|
+
this.warnings = [];
|
|
37
|
+
this.metadata = {
|
|
38
|
+
validatedAt: new Date().toISOString(),
|
|
39
|
+
testFramework: 'jest',
|
|
40
|
+
environment: process.env.NODE_ENV || 'test'
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setStatus(status) {
|
|
45
|
+
this.status = status;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
setBaselineResults(results) {
|
|
49
|
+
this.baselineResults = results;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
setValidationResults(results) {
|
|
53
|
+
this.validationResults = results;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setComparison(comparison) {
|
|
57
|
+
this.comparison = comparison;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
setDuration(duration) {
|
|
61
|
+
this.duration = duration;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
addError(error) {
|
|
65
|
+
this.errors.push({
|
|
66
|
+
message: error.message,
|
|
67
|
+
timestamp: new Date().toISOString(),
|
|
68
|
+
stack: error.stack
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
addWarning(warning) {
|
|
73
|
+
this.warnings.push({
|
|
74
|
+
message: warning,
|
|
75
|
+
timestamp: new Date().toISOString()
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
isSuccessful() {
|
|
80
|
+
return this.status === VALIDATION_STATUS.PASSED &&
|
|
81
|
+
this.errors.length === 0 &&
|
|
82
|
+
(!this.comparison || !this.comparison.hasRegressions);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
getSummary() {
|
|
86
|
+
return {
|
|
87
|
+
operationId: this.operationId,
|
|
88
|
+
status: this.status,
|
|
89
|
+
duration: this.duration,
|
|
90
|
+
baselineTests: this.baselineResults?.total || 0,
|
|
91
|
+
validationTests: this.validationResults?.total || 0,
|
|
92
|
+
hasRegressions: this.comparison?.hasRegressions || false,
|
|
93
|
+
errorCount: this.errors.length,
|
|
94
|
+
warningCount: this.warnings.length
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Test suite class
|
|
101
|
+
*/
|
|
102
|
+
class TestSuite {
|
|
103
|
+
constructor(name, pattern, options = {}) {
|
|
104
|
+
this.name = name;
|
|
105
|
+
this.pattern = pattern;
|
|
106
|
+
this.options = {
|
|
107
|
+
timeout: 30000,
|
|
108
|
+
retries: 0,
|
|
109
|
+
parallel: true,
|
|
110
|
+
...options
|
|
111
|
+
};
|
|
112
|
+
this.results = null;
|
|
113
|
+
this.lastRun = null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async run() {
|
|
117
|
+
const testRunner = new TestRunner({
|
|
118
|
+
timeout: this.options.timeout,
|
|
119
|
+
retries: this.options.retries
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
this.results = await testRunner.runSpecificTests([this.pattern]);
|
|
124
|
+
this.lastRun = new Date().toISOString();
|
|
125
|
+
return this.results;
|
|
126
|
+
} catch (error) {
|
|
127
|
+
this.results = {
|
|
128
|
+
total: 0,
|
|
129
|
+
passed: 0,
|
|
130
|
+
failed: 0,
|
|
131
|
+
skipped: 0,
|
|
132
|
+
errors: [error],
|
|
133
|
+
duration: 0
|
|
134
|
+
};
|
|
135
|
+
this.lastRun = new Date().toISOString();
|
|
136
|
+
return this.results;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
getSummary() {
|
|
141
|
+
return {
|
|
142
|
+
name: this.name,
|
|
143
|
+
pattern: this.pattern,
|
|
144
|
+
lastRun: this.lastRun,
|
|
145
|
+
results: this.results
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Test validator class
|
|
152
|
+
*/
|
|
153
|
+
class TestValidator {
|
|
154
|
+
constructor(options = {}) {
|
|
155
|
+
this.options = {
|
|
156
|
+
runBaseline: true,
|
|
157
|
+
runValidation: true,
|
|
158
|
+
compareResults: true,
|
|
159
|
+
failOnRegression: true,
|
|
160
|
+
testTimeout: 60000,
|
|
161
|
+
maxRetries: 2,
|
|
162
|
+
parallelTests: true,
|
|
163
|
+
...options
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
this.testRunner = new TestRunner({
|
|
167
|
+
timeout: this.options.testTimeout,
|
|
168
|
+
retries: this.options.maxRetries
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
this.testSuites = new Map();
|
|
172
|
+
this.validationResults = new Map();
|
|
173
|
+
this.globalBaseline = null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Add test suite
|
|
178
|
+
*/
|
|
179
|
+
addTestSuite(name, pattern, options = {}) {
|
|
180
|
+
const suite = new TestSuite(name, pattern, options);
|
|
181
|
+
this.testSuites.set(name, suite);
|
|
182
|
+
return suite;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Setup default test suites
|
|
187
|
+
*/
|
|
188
|
+
setupDefaultTestSuites() {
|
|
189
|
+
// Unit tests
|
|
190
|
+
this.addTestSuite('unit', '**/*.test.js', {
|
|
191
|
+
timeout: 30000,
|
|
192
|
+
parallel: true
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Integration tests
|
|
196
|
+
this.addTestSuite('integration', '**/*.integration.test.js', {
|
|
197
|
+
timeout: 60000,
|
|
198
|
+
parallel: false
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// E2E tests
|
|
202
|
+
this.addTestSuite('e2e', '**/*.e2e.test.js', {
|
|
203
|
+
timeout: 120000,
|
|
204
|
+
parallel: false
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Refactoring-specific tests
|
|
208
|
+
this.addTestSuite('refactoring', '**/*.refactor.test.js', {
|
|
209
|
+
timeout: 45000,
|
|
210
|
+
parallel: true
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Run baseline tests
|
|
216
|
+
*/
|
|
217
|
+
async runBaseline() {
|
|
218
|
+
console.log('Running baseline tests...');
|
|
219
|
+
|
|
220
|
+
const startTime = Date.now();
|
|
221
|
+
const results = {
|
|
222
|
+
total: 0,
|
|
223
|
+
passed: 0,
|
|
224
|
+
failed: 0,
|
|
225
|
+
skipped: 0,
|
|
226
|
+
duration: 0,
|
|
227
|
+
suites: {}
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
try {
|
|
231
|
+
// Run all test suites
|
|
232
|
+
for (const [name, suite] of this.testSuites) {
|
|
233
|
+
console.log(`Running ${name} tests...`);
|
|
234
|
+
const suiteResults = await suite.run();
|
|
235
|
+
|
|
236
|
+
results.suites[name] = suiteResults;
|
|
237
|
+
results.total += suiteResults.total || 0;
|
|
238
|
+
results.passed += suiteResults.passed || 0;
|
|
239
|
+
results.failed += suiteResults.failed || 0;
|
|
240
|
+
results.skipped += suiteResults.skipped || 0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
results.duration = (Date.now() - startTime) / 1000;
|
|
244
|
+
|
|
245
|
+
this.globalBaseline = results;
|
|
246
|
+
|
|
247
|
+
console.log(`Baseline completed: ${results.passed}/${results.total} passed`);
|
|
248
|
+
|
|
249
|
+
if (results.failed > 0) {
|
|
250
|
+
console.warn(`${results.failed} baseline tests failed`);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return results;
|
|
254
|
+
|
|
255
|
+
} catch (error) {
|
|
256
|
+
console.error('Baseline test execution failed:', error.message);
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Validate refactoring operation
|
|
263
|
+
*/
|
|
264
|
+
async validateOperation(operationId, affectedFiles = []) {
|
|
265
|
+
const validation = new TestValidationResult(operationId);
|
|
266
|
+
const startTime = Date.now();
|
|
267
|
+
|
|
268
|
+
try {
|
|
269
|
+
validation.setStatus(VALIDATION_STATUS.RUNNING);
|
|
270
|
+
|
|
271
|
+
// Run validation tests
|
|
272
|
+
if (this.options.runValidation) {
|
|
273
|
+
console.log(`Running validation tests for operation: ${operationId}`);
|
|
274
|
+
|
|
275
|
+
const validationResults = await this.runValidationTests(affectedFiles);
|
|
276
|
+
validation.setValidationResults(validationResults);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Compare with baseline
|
|
280
|
+
if (this.options.compareResults && this.globalBaseline) {
|
|
281
|
+
console.log('Comparing results with baseline...');
|
|
282
|
+
|
|
283
|
+
const comparison = this.compareWithBaseline(validation.validationResults);
|
|
284
|
+
validation.setComparison(comparison);
|
|
285
|
+
|
|
286
|
+
// Fail on regression if enabled
|
|
287
|
+
if (this.options.failOnRegression && comparison.hasRegressions) {
|
|
288
|
+
throw new Error(`Test regressions detected: ${comparison.regressions.length} failures`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
validation.setStatus(VALIDATION_STATUS.PASSED);
|
|
293
|
+
|
|
294
|
+
} catch (error) {
|
|
295
|
+
validation.addError(error);
|
|
296
|
+
validation.setStatus(VALIDATION_STATUS.FAILED);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
validation.setDuration((Date.now() - startTime) / 1000);
|
|
300
|
+
this.validationResults.set(operationId, validation);
|
|
301
|
+
|
|
302
|
+
return validation;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Run validation tests for affected files
|
|
307
|
+
*/
|
|
308
|
+
async runValidationTests(affectedFiles) {
|
|
309
|
+
const results = {
|
|
310
|
+
total: 0,
|
|
311
|
+
passed: 0,
|
|
312
|
+
failed: 0,
|
|
313
|
+
skipped: 0,
|
|
314
|
+
duration: 0,
|
|
315
|
+
suites: {}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const startTime = Date.now();
|
|
319
|
+
|
|
320
|
+
try {
|
|
321
|
+
// Determine which test suites to run based on affected files
|
|
322
|
+
const relevantSuites = this.getRelevantTestSuites(affectedFiles);
|
|
323
|
+
|
|
324
|
+
for (const suiteName of relevantSuites) {
|
|
325
|
+
const suite = this.testSuites.get(suiteName);
|
|
326
|
+
if (suite) {
|
|
327
|
+
console.log(`Running ${suiteName} validation tests...`);
|
|
328
|
+
|
|
329
|
+
const suiteResults = await suite.run();
|
|
330
|
+
results.suites[suiteName] = suiteResults;
|
|
331
|
+
|
|
332
|
+
results.total += suiteResults.total || 0;
|
|
333
|
+
results.passed += suiteResults.passed || 0;
|
|
334
|
+
results.failed += suiteResults.failed || 0;
|
|
335
|
+
results.skipped += suiteResults.skipped || 0;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
results.duration = (Date.now() - startTime) / 1000;
|
|
340
|
+
|
|
341
|
+
console.log(`Validation completed: ${results.passed}/${results.total} passed`);
|
|
342
|
+
|
|
343
|
+
return results;
|
|
344
|
+
|
|
345
|
+
} catch (error) {
|
|
346
|
+
console.error('Validation test execution failed:', error.message);
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Get relevant test suites for affected files
|
|
353
|
+
*/
|
|
354
|
+
getRelevantTestSuites(affectedFiles) {
|
|
355
|
+
const relevantSuites = new Set();
|
|
356
|
+
|
|
357
|
+
for (const filePath of affectedFiles) {
|
|
358
|
+
// Check if file is a test file
|
|
359
|
+
if (filePath.includes('.test.') || filePath.includes('.spec.')) {
|
|
360
|
+
relevantSuites.add('unit');
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Check file path to determine relevant suites
|
|
365
|
+
if (filePath.includes('/test/') || filePath.includes('/tests/')) {
|
|
366
|
+
relevantSuites.add('unit');
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (filePath.includes('/integration/')) {
|
|
370
|
+
relevantSuites.add('integration');
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (filePath.includes('/e2e/')) {
|
|
374
|
+
relevantSuites.add('e2e');
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// For refactoring operations, always run unit and refactoring tests
|
|
378
|
+
relevantSuites.add('unit');
|
|
379
|
+
relevantSuites.add('refactoring');
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return Array.from(relevantSuites);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Compare validation results with baseline
|
|
387
|
+
*/
|
|
388
|
+
compareWithBaseline(validationResults) {
|
|
389
|
+
if (!this.globalBaseline || !validationResults) {
|
|
390
|
+
return {
|
|
391
|
+
hasRegressions: false,
|
|
392
|
+
regressions: [],
|
|
393
|
+
improvements: [],
|
|
394
|
+
unchanged: []
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const comparison = {
|
|
399
|
+
hasRegressions: false,
|
|
400
|
+
regressions: [],
|
|
401
|
+
improvements: [],
|
|
402
|
+
unchanged: []
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
// Compare overall results
|
|
406
|
+
const baselineTotal = this.globalBaseline.total || 0;
|
|
407
|
+
const validationTotal = validationResults.total || 0;
|
|
408
|
+
|
|
409
|
+
if (validationTotal < baselineTotal) {
|
|
410
|
+
comparison.regressions.push({
|
|
411
|
+
type: 'missing_tests',
|
|
412
|
+
message: `${baselineTotal - validationTotal} tests are missing`,
|
|
413
|
+
severity: 'high'
|
|
414
|
+
});
|
|
415
|
+
comparison.hasRegressions = true;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const baselineFailed = this.globalBaseline.failed || 0;
|
|
419
|
+
const validationFailed = validationResults.failed || 0;
|
|
420
|
+
|
|
421
|
+
if (validationFailed > baselineFailed) {
|
|
422
|
+
comparison.regressions.push({
|
|
423
|
+
type: 'new_failures',
|
|
424
|
+
message: `${validationFailed - baselineFailed} new test failures`,
|
|
425
|
+
severity: 'critical'
|
|
426
|
+
});
|
|
427
|
+
comparison.hasRegressions = true;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (validationFailed < baselineFailed) {
|
|
431
|
+
comparison.improvements.push({
|
|
432
|
+
type: 'fixed_failures',
|
|
433
|
+
message: `${baselineFailed - validationFailed} test failures fixed`,
|
|
434
|
+
severity: 'good'
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Compare individual test suites
|
|
439
|
+
for (const [suiteName, baselineSuite] of Object.entries(this.globalBaseline.suites || {})) {
|
|
440
|
+
const validationSuite = validationResults.suites?.[suiteName];
|
|
441
|
+
|
|
442
|
+
if (validationSuite) {
|
|
443
|
+
if (validationSuite.failed > (baselineSuite.failed || 0)) {
|
|
444
|
+
comparison.regressions.push({
|
|
445
|
+
type: 'suite_regression',
|
|
446
|
+
message: `${suiteName} suite: ${validationSuite.failed} failures (baseline: ${baselineSuite.failed || 0})`,
|
|
447
|
+
severity: 'high',
|
|
448
|
+
suite: suiteName
|
|
449
|
+
});
|
|
450
|
+
comparison.hasRegressions = true;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return comparison;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Validate multiple operations
|
|
460
|
+
*/
|
|
461
|
+
async validateOperations(operations) {
|
|
462
|
+
const results = [];
|
|
463
|
+
|
|
464
|
+
for (const operation of operations) {
|
|
465
|
+
const result = await this.validateOperation(
|
|
466
|
+
operation.id,
|
|
467
|
+
operation.affectedFiles || []
|
|
468
|
+
);
|
|
469
|
+
results.push(result);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
return results;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Get validation summary
|
|
477
|
+
*/
|
|
478
|
+
getValidationSummary() {
|
|
479
|
+
const summary = {
|
|
480
|
+
totalValidations: this.validationResults.size,
|
|
481
|
+
successful: 0,
|
|
482
|
+
failed: 0,
|
|
483
|
+
withRegressions: 0,
|
|
484
|
+
averageDuration: 0,
|
|
485
|
+
errors: [],
|
|
486
|
+
warnings: []
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
let totalDuration = 0;
|
|
490
|
+
|
|
491
|
+
for (const validation of this.validationResults.values()) {
|
|
492
|
+
if (validation.isSuccessful()) {
|
|
493
|
+
summary.successful++;
|
|
494
|
+
} else {
|
|
495
|
+
summary.failed++;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
if (validation.comparison?.hasRegressions) {
|
|
499
|
+
summary.withRegressions++;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
totalDuration += validation.duration;
|
|
503
|
+
summary.errors.push(...validation.errors);
|
|
504
|
+
summary.warnings.push(...validation.warnings);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
summary.averageDuration = summary.totalValidations > 0 ?
|
|
508
|
+
totalDuration / summary.totalValidations : 0;
|
|
509
|
+
|
|
510
|
+
return summary;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Check if tests are available
|
|
515
|
+
*/
|
|
516
|
+
checkTestAvailability() {
|
|
517
|
+
return this.testRunner.checkTestAvailability();
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Get test configuration
|
|
522
|
+
*/
|
|
523
|
+
getTestConfiguration() {
|
|
524
|
+
return this.testRunner.getTestConfig();
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Reset validation state
|
|
529
|
+
*/
|
|
530
|
+
reset() {
|
|
531
|
+
this.validationResults.clear();
|
|
532
|
+
this.globalBaseline = null;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Export validation results
|
|
537
|
+
*/
|
|
538
|
+
exportResults(format = 'json') {
|
|
539
|
+
const exportData = {
|
|
540
|
+
metadata: {
|
|
541
|
+
exportedAt: new Date().toISOString(),
|
|
542
|
+
validatorVersion: '1.0.0',
|
|
543
|
+
options: this.options
|
|
544
|
+
},
|
|
545
|
+
baseline: this.globalBaseline,
|
|
546
|
+
validations: Array.from(this.validationResults.entries()).map(([id, validation]) => ({
|
|
547
|
+
operationId: id,
|
|
548
|
+
...validation.getSummary()
|
|
549
|
+
})),
|
|
550
|
+
summary: this.getValidationSummary()
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
if (format === 'json') {
|
|
554
|
+
return JSON.stringify(exportData, null, 2);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return exportData;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Generate test report
|
|
562
|
+
*/
|
|
563
|
+
generateReport() {
|
|
564
|
+
const summary = this.getValidationSummary();
|
|
565
|
+
|
|
566
|
+
return {
|
|
567
|
+
title: 'Test Validation Report',
|
|
568
|
+
generatedAt: new Date().toISOString(),
|
|
569
|
+
summary,
|
|
570
|
+
baseline: this.globalBaseline,
|
|
571
|
+
validations: Array.from(this.validationResults.values()),
|
|
572
|
+
recommendations: this.generateRecommendations(summary)
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Generate recommendations based on validation results
|
|
578
|
+
*/
|
|
579
|
+
generateRecommendations(summary) {
|
|
580
|
+
const recommendations = [];
|
|
581
|
+
|
|
582
|
+
if (summary.failed > 0) {
|
|
583
|
+
recommendations.push({
|
|
584
|
+
type: 'fix_failures',
|
|
585
|
+
priority: 'high',
|
|
586
|
+
title: `Fix ${summary.failed} Failed Validations`,
|
|
587
|
+
description: 'Some refactoring operations failed validation. Review errors and fix issues.',
|
|
588
|
+
action: 'Review validation errors and fix failing tests'
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
if (summary.withRegressions > 0) {
|
|
593
|
+
recommendations.push({
|
|
594
|
+
type: 'address_regressions',
|
|
595
|
+
priority: 'critical',
|
|
596
|
+
title: `Address ${summary.withRegressions} Test Regressions`,
|
|
597
|
+
description: 'Test regressions were detected. Refactoring may have broken existing functionality.',
|
|
598
|
+
action: 'Review regression details and fix broken functionality'
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
if (summary.averageDuration > 30) {
|
|
603
|
+
recommendations.push({
|
|
604
|
+
type: 'optimize_performance',
|
|
605
|
+
priority: 'medium',
|
|
606
|
+
title: 'Optimize Test Performance',
|
|
607
|
+
description: 'Test validation is taking longer than expected. Consider optimizing test suite.',
|
|
608
|
+
action: 'Review test performance and optimize slow tests'
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
if (summary.errors.length > 0) {
|
|
613
|
+
recommendations.push({
|
|
614
|
+
type: 'fix_errors',
|
|
615
|
+
priority: 'high',
|
|
616
|
+
title: 'Fix Validation Errors',
|
|
617
|
+
description: 'Validation errors occurred during test execution.',
|
|
618
|
+
action: 'Review error messages and fix validation issues'
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
return recommendations;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
module.exports = {
|
|
627
|
+
TestValidator,
|
|
628
|
+
TestValidationResult,
|
|
629
|
+
TestSuite,
|
|
630
|
+
VALIDATION_STATUS
|
|
631
|
+
};
|