@agentic-qe/v3 3.0.0-alpha.3
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 +429 -0
- package/dist/benchmarks/performance-benchmarks.d.ts +92 -0
- package/dist/benchmarks/performance-benchmarks.d.ts.map +1 -0
- package/dist/benchmarks/performance-benchmarks.js +477 -0
- package/dist/benchmarks/performance-benchmarks.js.map +1 -0
- package/dist/benchmarks/run-benchmarks.d.ts +12 -0
- package/dist/benchmarks/run-benchmarks.d.ts.map +1 -0
- package/dist/benchmarks/run-benchmarks.js +260 -0
- package/dist/benchmarks/run-benchmarks.js.map +1 -0
- package/dist/causal-discovery/causal-graph.d.ts +104 -0
- package/dist/causal-discovery/causal-graph.d.ts.map +1 -0
- package/dist/causal-discovery/causal-graph.js +384 -0
- package/dist/causal-discovery/causal-graph.js.map +1 -0
- package/dist/causal-discovery/discovery-engine.d.ts +120 -0
- package/dist/causal-discovery/discovery-engine.d.ts.map +1 -0
- package/dist/causal-discovery/discovery-engine.js +332 -0
- package/dist/causal-discovery/discovery-engine.js.map +1 -0
- package/dist/causal-discovery/index.d.ts +50 -0
- package/dist/causal-discovery/index.d.ts.map +1 -0
- package/dist/causal-discovery/index.js +69 -0
- package/dist/causal-discovery/index.js.map +1 -0
- package/dist/causal-discovery/types.d.ts +257 -0
- package/dist/causal-discovery/types.d.ts.map +1 -0
- package/dist/causal-discovery/types.js +72 -0
- package/dist/causal-discovery/types.js.map +1 -0
- package/dist/causal-discovery/weight-matrix.d.ts +130 -0
- package/dist/causal-discovery/weight-matrix.d.ts.map +1 -0
- package/dist/causal-discovery/weight-matrix.js +380 -0
- package/dist/causal-discovery/weight-matrix.js.map +1 -0
- package/dist/cli/commands/qe-tools.d.ts +27 -0
- package/dist/cli/commands/qe-tools.d.ts.map +1 -0
- package/dist/cli/commands/qe-tools.js +524 -0
- package/dist/cli/commands/qe-tools.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1725 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/compatibility/agent-mapper.d.ts +45 -0
- package/dist/compatibility/agent-mapper.d.ts.map +1 -0
- package/dist/compatibility/agent-mapper.js +256 -0
- package/dist/compatibility/agent-mapper.js.map +1 -0
- package/dist/compatibility/cli-adapter.d.ts +53 -0
- package/dist/compatibility/cli-adapter.d.ts.map +1 -0
- package/dist/compatibility/cli-adapter.js +247 -0
- package/dist/compatibility/cli-adapter.js.map +1 -0
- package/dist/compatibility/config-migrator.d.ts +42 -0
- package/dist/compatibility/config-migrator.d.ts.map +1 -0
- package/dist/compatibility/config-migrator.js +280 -0
- package/dist/compatibility/config-migrator.js.map +1 -0
- package/dist/compatibility/index.d.ts +58 -0
- package/dist/compatibility/index.d.ts.map +1 -0
- package/dist/compatibility/index.js +90 -0
- package/dist/compatibility/index.js.map +1 -0
- package/dist/compatibility/mcp-adapter.d.ts +38 -0
- package/dist/compatibility/mcp-adapter.d.ts.map +1 -0
- package/dist/compatibility/mcp-adapter.js +202 -0
- package/dist/compatibility/mcp-adapter.js.map +1 -0
- package/dist/compatibility/types.d.ts +161 -0
- package/dist/compatibility/types.d.ts.map +1 -0
- package/dist/compatibility/types.js +5 -0
- package/dist/compatibility/types.js.map +1 -0
- package/dist/coordination/claims/claim-repository.d.ts +64 -0
- package/dist/coordination/claims/claim-repository.d.ts.map +1 -0
- package/dist/coordination/claims/claim-repository.js +524 -0
- package/dist/coordination/claims/claim-repository.js.map +1 -0
- package/dist/coordination/claims/claim-service.d.ts +45 -0
- package/dist/coordination/claims/claim-service.d.ts.map +1 -0
- package/dist/coordination/claims/claim-service.js +523 -0
- package/dist/coordination/claims/claim-service.js.map +1 -0
- package/dist/coordination/claims/handoff-manager.d.ts +95 -0
- package/dist/coordination/claims/handoff-manager.d.ts.map +1 -0
- package/dist/coordination/claims/handoff-manager.js +380 -0
- package/dist/coordination/claims/handoff-manager.js.map +1 -0
- package/dist/coordination/claims/index.d.ts +121 -0
- package/dist/coordination/claims/index.d.ts.map +1 -0
- package/dist/coordination/claims/index.js +129 -0
- package/dist/coordination/claims/index.js.map +1 -0
- package/dist/coordination/claims/interfaces.d.ts +471 -0
- package/dist/coordination/claims/interfaces.d.ts.map +1 -0
- package/dist/coordination/claims/interfaces.js +14 -0
- package/dist/coordination/claims/interfaces.js.map +1 -0
- package/dist/coordination/claims/work-stealing.d.ts +88 -0
- package/dist/coordination/claims/work-stealing.d.ts.map +1 -0
- package/dist/coordination/claims/work-stealing.js +335 -0
- package/dist/coordination/claims/work-stealing.js.map +1 -0
- package/dist/coordination/cross-domain-router.d.ts +104 -0
- package/dist/coordination/cross-domain-router.d.ts.map +1 -0
- package/dist/coordination/cross-domain-router.js +365 -0
- package/dist/coordination/cross-domain-router.js.map +1 -0
- package/dist/coordination/index.d.ts +14 -0
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +29 -0
- package/dist/coordination/index.js.map +1 -0
- package/dist/coordination/interfaces.d.ts +482 -0
- package/dist/coordination/interfaces.d.ts.map +1 -0
- package/dist/coordination/interfaces.js +6 -0
- package/dist/coordination/interfaces.js.map +1 -0
- package/dist/coordination/protocol-executor.d.ts +119 -0
- package/dist/coordination/protocol-executor.d.ts.map +1 -0
- package/dist/coordination/protocol-executor.js +528 -0
- package/dist/coordination/protocol-executor.js.map +1 -0
- package/dist/coordination/protocols/code-intelligence-index.d.ts +204 -0
- package/dist/coordination/protocols/code-intelligence-index.d.ts.map +1 -0
- package/dist/coordination/protocols/code-intelligence-index.js +568 -0
- package/dist/coordination/protocols/code-intelligence-index.js.map +1 -0
- package/dist/coordination/protocols/defect-investigation.d.ts +202 -0
- package/dist/coordination/protocols/defect-investigation.d.ts.map +1 -0
- package/dist/coordination/protocols/defect-investigation.js +734 -0
- package/dist/coordination/protocols/defect-investigation.js.map +1 -0
- package/dist/coordination/protocols/index.d.ts +11 -0
- package/dist/coordination/protocols/index.d.ts.map +1 -0
- package/dist/coordination/protocols/index.js +11 -0
- package/dist/coordination/protocols/index.js.map +1 -0
- package/dist/coordination/protocols/learning-consolidation.d.ts +249 -0
- package/dist/coordination/protocols/learning-consolidation.d.ts.map +1 -0
- package/dist/coordination/protocols/learning-consolidation.js +811 -0
- package/dist/coordination/protocols/learning-consolidation.js.map +1 -0
- package/dist/coordination/protocols/morning-sync.d.ts +255 -0
- package/dist/coordination/protocols/morning-sync.d.ts.map +1 -0
- package/dist/coordination/protocols/morning-sync.js +730 -0
- package/dist/coordination/protocols/morning-sync.js.map +1 -0
- package/dist/coordination/protocols/quality-gate.d.ts +303 -0
- package/dist/coordination/protocols/quality-gate.d.ts.map +1 -0
- package/dist/coordination/protocols/quality-gate.js +924 -0
- package/dist/coordination/protocols/quality-gate.js.map +1 -0
- package/dist/coordination/protocols/security-audit.d.ts +263 -0
- package/dist/coordination/protocols/security-audit.d.ts.map +1 -0
- package/dist/coordination/protocols/security-audit.js +1159 -0
- package/dist/coordination/protocols/security-audit.js.map +1 -0
- package/dist/coordination/queen-coordinator.d.ts +214 -0
- package/dist/coordination/queen-coordinator.d.ts.map +1 -0
- package/dist/coordination/queen-coordinator.js +808 -0
- package/dist/coordination/queen-coordinator.js.map +1 -0
- package/dist/coordination/result-saver.d.ts +82 -0
- package/dist/coordination/result-saver.d.ts.map +1 -0
- package/dist/coordination/result-saver.js +536 -0
- package/dist/coordination/result-saver.js.map +1 -0
- package/dist/coordination/task-executor.d.ts +50 -0
- package/dist/coordination/task-executor.d.ts.map +1 -0
- package/dist/coordination/task-executor.js +965 -0
- package/dist/coordination/task-executor.js.map +1 -0
- package/dist/coordination/workflow-orchestrator.d.ts +362 -0
- package/dist/coordination/workflow-orchestrator.d.ts.map +1 -0
- package/dist/coordination/workflow-orchestrator.js +1298 -0
- package/dist/coordination/workflow-orchestrator.js.map +1 -0
- package/dist/domains/chaos-resilience/coordinator.d.ts +108 -0
- package/dist/domains/chaos-resilience/coordinator.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/coordinator.js +775 -0
- package/dist/domains/chaos-resilience/coordinator.js.map +1 -0
- package/dist/domains/chaos-resilience/index.d.ts +13 -0
- package/dist/domains/chaos-resilience/index.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/index.js +21 -0
- package/dist/domains/chaos-resilience/index.js.map +1 -0
- package/dist/domains/chaos-resilience/interfaces.d.ts +528 -0
- package/dist/domains/chaos-resilience/interfaces.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/interfaces.js +8 -0
- package/dist/domains/chaos-resilience/interfaces.js.map +1 -0
- package/dist/domains/chaos-resilience/plugin.d.ts +97 -0
- package/dist/domains/chaos-resilience/plugin.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/plugin.js +466 -0
- package/dist/domains/chaos-resilience/plugin.js.map +1 -0
- package/dist/domains/chaos-resilience/services/chaos-engineer.d.ts +97 -0
- package/dist/domains/chaos-resilience/services/chaos-engineer.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/services/chaos-engineer.js +875 -0
- package/dist/domains/chaos-resilience/services/chaos-engineer.js.map +1 -0
- package/dist/domains/chaos-resilience/services/index.d.ts +8 -0
- package/dist/domains/chaos-resilience/services/index.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/services/index.js +8 -0
- package/dist/domains/chaos-resilience/services/index.js.map +1 -0
- package/dist/domains/chaos-resilience/services/load-tester.d.ts +71 -0
- package/dist/domains/chaos-resilience/services/load-tester.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/services/load-tester.js +588 -0
- package/dist/domains/chaos-resilience/services/load-tester.js.map +1 -0
- package/dist/domains/chaos-resilience/services/performance-profiler.d.ts +70 -0
- package/dist/domains/chaos-resilience/services/performance-profiler.d.ts.map +1 -0
- package/dist/domains/chaos-resilience/services/performance-profiler.js +642 -0
- package/dist/domains/chaos-resilience/services/performance-profiler.js.map +1 -0
- package/dist/domains/code-intelligence/coordinator.d.ts +104 -0
- package/dist/domains/code-intelligence/coordinator.d.ts.map +1 -0
- package/dist/domains/code-intelligence/coordinator.js +436 -0
- package/dist/domains/code-intelligence/coordinator.js.map +1 -0
- package/dist/domains/code-intelligence/index.d.ts +13 -0
- package/dist/domains/code-intelligence/index.d.ts.map +1 -0
- package/dist/domains/code-intelligence/index.js +21 -0
- package/dist/domains/code-intelligence/index.js.map +1 -0
- package/dist/domains/code-intelligence/interfaces.d.ts +130 -0
- package/dist/domains/code-intelligence/interfaces.d.ts.map +1 -0
- package/dist/domains/code-intelligence/interfaces.js +6 -0
- package/dist/domains/code-intelligence/interfaces.js.map +1 -0
- package/dist/domains/code-intelligence/plugin.d.ts +75 -0
- package/dist/domains/code-intelligence/plugin.d.ts.map +1 -0
- package/dist/domains/code-intelligence/plugin.js +279 -0
- package/dist/domains/code-intelligence/plugin.js.map +1 -0
- package/dist/domains/code-intelligence/services/impact-analyzer.d.ts +80 -0
- package/dist/domains/code-intelligence/services/impact-analyzer.d.ts.map +1 -0
- package/dist/domains/code-intelligence/services/impact-analyzer.js +391 -0
- package/dist/domains/code-intelligence/services/impact-analyzer.js.map +1 -0
- package/dist/domains/code-intelligence/services/index.d.ts +8 -0
- package/dist/domains/code-intelligence/services/index.d.ts.map +1 -0
- package/dist/domains/code-intelligence/services/index.js +8 -0
- package/dist/domains/code-intelligence/services/index.js.map +1 -0
- package/dist/domains/code-intelligence/services/knowledge-graph.d.ts +101 -0
- package/dist/domains/code-intelligence/services/knowledge-graph.d.ts.map +1 -0
- package/dist/domains/code-intelligence/services/knowledge-graph.js +822 -0
- package/dist/domains/code-intelligence/services/knowledge-graph.js.map +1 -0
- package/dist/domains/code-intelligence/services/semantic-analyzer.d.ts +141 -0
- package/dist/domains/code-intelligence/services/semantic-analyzer.d.ts.map +1 -0
- package/dist/domains/code-intelligence/services/semantic-analyzer.js +661 -0
- package/dist/domains/code-intelligence/services/semantic-analyzer.js.map +1 -0
- package/dist/domains/contract-testing/coordinator.d.ts +114 -0
- package/dist/domains/contract-testing/coordinator.d.ts.map +1 -0
- package/dist/domains/contract-testing/coordinator.js +805 -0
- package/dist/domains/contract-testing/coordinator.js.map +1 -0
- package/dist/domains/contract-testing/index.d.ts +13 -0
- package/dist/domains/contract-testing/index.d.ts.map +1 -0
- package/dist/domains/contract-testing/index.js +21 -0
- package/dist/domains/contract-testing/index.js.map +1 -0
- package/dist/domains/contract-testing/interfaces.d.ts +344 -0
- package/dist/domains/contract-testing/interfaces.d.ts.map +1 -0
- package/dist/domains/contract-testing/interfaces.js +8 -0
- package/dist/domains/contract-testing/interfaces.js.map +1 -0
- package/dist/domains/contract-testing/plugin.d.ts +112 -0
- package/dist/domains/contract-testing/plugin.d.ts.map +1 -0
- package/dist/domains/contract-testing/plugin.js +491 -0
- package/dist/domains/contract-testing/plugin.js.map +1 -0
- package/dist/domains/contract-testing/services/api-compatibility.d.ts +53 -0
- package/dist/domains/contract-testing/services/api-compatibility.d.ts.map +1 -0
- package/dist/domains/contract-testing/services/api-compatibility.js +535 -0
- package/dist/domains/contract-testing/services/api-compatibility.js.map +1 -0
- package/dist/domains/contract-testing/services/contract-validator.d.ts +100 -0
- package/dist/domains/contract-testing/services/contract-validator.d.ts.map +1 -0
- package/dist/domains/contract-testing/services/contract-validator.js +1398 -0
- package/dist/domains/contract-testing/services/contract-validator.js.map +1 -0
- package/dist/domains/contract-testing/services/index.d.ts +8 -0
- package/dist/domains/contract-testing/services/index.d.ts.map +1 -0
- package/dist/domains/contract-testing/services/index.js +8 -0
- package/dist/domains/contract-testing/services/index.js.map +1 -0
- package/dist/domains/contract-testing/services/schema-validator.d.ts +65 -0
- package/dist/domains/contract-testing/services/schema-validator.d.ts.map +1 -0
- package/dist/domains/contract-testing/services/schema-validator.js +860 -0
- package/dist/domains/contract-testing/services/schema-validator.js.map +1 -0
- package/dist/domains/coverage-analysis/coordinator.d.ts +66 -0
- package/dist/domains/coverage-analysis/coordinator.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/coordinator.js +353 -0
- package/dist/domains/coverage-analysis/coordinator.js.map +1 -0
- package/dist/domains/coverage-analysis/index.d.ts +33 -0
- package/dist/domains/coverage-analysis/index.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/index.js +39 -0
- package/dist/domains/coverage-analysis/index.js.map +1 -0
- package/dist/domains/coverage-analysis/interfaces.d.ts +134 -0
- package/dist/domains/coverage-analysis/interfaces.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/interfaces.js +6 -0
- package/dist/domains/coverage-analysis/interfaces.js.map +1 -0
- package/dist/domains/coverage-analysis/plugin.d.ts +37 -0
- package/dist/domains/coverage-analysis/plugin.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/plugin.js +133 -0
- package/dist/domains/coverage-analysis/plugin.js.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.d.ts +49 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.js +342 -0
- package/dist/domains/coverage-analysis/services/coverage-analyzer.js.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-embedder.d.ts +165 -0
- package/dist/domains/coverage-analysis/services/coverage-embedder.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-embedder.js +550 -0
- package/dist/domains/coverage-analysis/services/coverage-embedder.js.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-parser.d.ts +203 -0
- package/dist/domains/coverage-analysis/services/coverage-parser.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/coverage-parser.js +506 -0
- package/dist/domains/coverage-analysis/services/coverage-parser.js.map +1 -0
- package/dist/domains/coverage-analysis/services/gap-detector.d.ts +61 -0
- package/dist/domains/coverage-analysis/services/gap-detector.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/gap-detector.js +474 -0
- package/dist/domains/coverage-analysis/services/gap-detector.js.map +1 -0
- package/dist/domains/coverage-analysis/services/hnsw-index.d.ts +260 -0
- package/dist/domains/coverage-analysis/services/hnsw-index.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/hnsw-index.js +482 -0
- package/dist/domains/coverage-analysis/services/hnsw-index.js.map +1 -0
- package/dist/domains/coverage-analysis/services/index.d.ts +13 -0
- package/dist/domains/coverage-analysis/services/index.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/index.js +16 -0
- package/dist/domains/coverage-analysis/services/index.js.map +1 -0
- package/dist/domains/coverage-analysis/services/risk-scorer.d.ts +62 -0
- package/dist/domains/coverage-analysis/services/risk-scorer.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/risk-scorer.js +412 -0
- package/dist/domains/coverage-analysis/services/risk-scorer.js.map +1 -0
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.d.ts +237 -0
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.d.ts.map +1 -0
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.js +499 -0
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.js.map +1 -0
- package/dist/domains/defect-intelligence/coordinator.d.ts +104 -0
- package/dist/domains/defect-intelligence/coordinator.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/coordinator.js +423 -0
- package/dist/domains/defect-intelligence/coordinator.js.map +1 -0
- package/dist/domains/defect-intelligence/index.d.ts +13 -0
- package/dist/domains/defect-intelligence/index.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/index.js +21 -0
- package/dist/domains/defect-intelligence/index.js.map +1 -0
- package/dist/domains/defect-intelligence/interfaces.d.ts +127 -0
- package/dist/domains/defect-intelligence/interfaces.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/interfaces.js +6 -0
- package/dist/domains/defect-intelligence/interfaces.js.map +1 -0
- package/dist/domains/defect-intelligence/plugin.d.ts +76 -0
- package/dist/domains/defect-intelligence/plugin.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/plugin.js +287 -0
- package/dist/domains/defect-intelligence/plugin.js.map +1 -0
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.d.ts +188 -0
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.js +298 -0
- package/dist/domains/defect-intelligence/services/causal-root-cause-analyzer.js.map +1 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.d.ts +129 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.js +674 -0
- package/dist/domains/defect-intelligence/services/defect-predictor.js.map +1 -0
- package/dist/domains/defect-intelligence/services/index.d.ts +9 -0
- package/dist/domains/defect-intelligence/services/index.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/index.js +10 -0
- package/dist/domains/defect-intelligence/services/index.js.map +1 -0
- package/dist/domains/defect-intelligence/services/pattern-learner.d.ts +96 -0
- package/dist/domains/defect-intelligence/services/pattern-learner.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/pattern-learner.js +548 -0
- package/dist/domains/defect-intelligence/services/pattern-learner.js.map +1 -0
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.d.ts +60 -0
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.d.ts.map +1 -0
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.js +465 -0
- package/dist/domains/defect-intelligence/services/root-cause-analyzer.js.map +1 -0
- package/dist/domains/domain-interface.d.ts +32 -0
- package/dist/domains/domain-interface.d.ts.map +1 -0
- package/dist/domains/domain-interface.js +61 -0
- package/dist/domains/domain-interface.js.map +1 -0
- package/dist/domains/index.d.ts +20 -0
- package/dist/domains/index.d.ts.map +1 -0
- package/dist/domains/index.js +22 -0
- package/dist/domains/index.js.map +1 -0
- package/dist/domains/learning-optimization/coordinator.d.ts +107 -0
- package/dist/domains/learning-optimization/coordinator.d.ts.map +1 -0
- package/dist/domains/learning-optimization/coordinator.js +849 -0
- package/dist/domains/learning-optimization/coordinator.js.map +1 -0
- package/dist/domains/learning-optimization/index.d.ts +14 -0
- package/dist/domains/learning-optimization/index.d.ts.map +1 -0
- package/dist/domains/learning-optimization/index.js +22 -0
- package/dist/domains/learning-optimization/index.js.map +1 -0
- package/dist/domains/learning-optimization/interfaces.d.ts +453 -0
- package/dist/domains/learning-optimization/interfaces.d.ts.map +1 -0
- package/dist/domains/learning-optimization/interfaces.js +8 -0
- package/dist/domains/learning-optimization/interfaces.js.map +1 -0
- package/dist/domains/learning-optimization/plugin.d.ts +116 -0
- package/dist/domains/learning-optimization/plugin.d.ts.map +1 -0
- package/dist/domains/learning-optimization/plugin.js +523 -0
- package/dist/domains/learning-optimization/plugin.js.map +1 -0
- package/dist/domains/learning-optimization/services/index.d.ts +9 -0
- package/dist/domains/learning-optimization/services/index.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/index.js +9 -0
- package/dist/domains/learning-optimization/services/index.js.map +1 -0
- package/dist/domains/learning-optimization/services/learning-coordinator.d.ts +98 -0
- package/dist/domains/learning-optimization/services/learning-coordinator.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/learning-coordinator.js +730 -0
- package/dist/domains/learning-optimization/services/learning-coordinator.js.map +1 -0
- package/dist/domains/learning-optimization/services/metrics-optimizer.d.ts +89 -0
- package/dist/domains/learning-optimization/services/metrics-optimizer.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/metrics-optimizer.js +598 -0
- package/dist/domains/learning-optimization/services/metrics-optimizer.js.map +1 -0
- package/dist/domains/learning-optimization/services/production-intel.d.ts +137 -0
- package/dist/domains/learning-optimization/services/production-intel.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/production-intel.js +649 -0
- package/dist/domains/learning-optimization/services/production-intel.js.map +1 -0
- package/dist/domains/learning-optimization/services/transfer-specialist.d.ts +86 -0
- package/dist/domains/learning-optimization/services/transfer-specialist.d.ts.map +1 -0
- package/dist/domains/learning-optimization/services/transfer-specialist.js +495 -0
- package/dist/domains/learning-optimization/services/transfer-specialist.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/gate-controller.d.ts +117 -0
- package/dist/domains/quality-assessment/coherence/gate-controller.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/gate-controller.js +414 -0
- package/dist/domains/quality-assessment/coherence/gate-controller.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/index.d.ts +102 -0
- package/dist/domains/quality-assessment/coherence/index.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/index.js +122 -0
- package/dist/domains/quality-assessment/coherence/index.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/lambda-calculator.d.ts +93 -0
- package/dist/domains/quality-assessment/coherence/lambda-calculator.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/lambda-calculator.js +293 -0
- package/dist/domains/quality-assessment/coherence/lambda-calculator.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/partition-detector.d.ts +109 -0
- package/dist/domains/quality-assessment/coherence/partition-detector.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/partition-detector.js +338 -0
- package/dist/domains/quality-assessment/coherence/partition-detector.js.map +1 -0
- package/dist/domains/quality-assessment/coherence/types.d.ts +239 -0
- package/dist/domains/quality-assessment/coherence/types.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coherence/types.js +62 -0
- package/dist/domains/quality-assessment/coherence/types.js.map +1 -0
- package/dist/domains/quality-assessment/coordinator.d.ts +98 -0
- package/dist/domains/quality-assessment/coordinator.d.ts.map +1 -0
- package/dist/domains/quality-assessment/coordinator.js +391 -0
- package/dist/domains/quality-assessment/coordinator.js.map +1 -0
- package/dist/domains/quality-assessment/index.d.ts +15 -0
- package/dist/domains/quality-assessment/index.d.ts.map +1 -0
- package/dist/domains/quality-assessment/index.js +27 -0
- package/dist/domains/quality-assessment/index.js.map +1 -0
- package/dist/domains/quality-assessment/interfaces.d.ts +140 -0
- package/dist/domains/quality-assessment/interfaces.d.ts.map +1 -0
- package/dist/domains/quality-assessment/interfaces.js +6 -0
- package/dist/domains/quality-assessment/interfaces.js.map +1 -0
- package/dist/domains/quality-assessment/plugin.d.ts +75 -0
- package/dist/domains/quality-assessment/plugin.d.ts.map +1 -0
- package/dist/domains/quality-assessment/plugin.js +294 -0
- package/dist/domains/quality-assessment/plugin.js.map +1 -0
- package/dist/domains/quality-assessment/services/coherence-gate.d.ts +109 -0
- package/dist/domains/quality-assessment/services/coherence-gate.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/coherence-gate.js +234 -0
- package/dist/domains/quality-assessment/services/coherence-gate.js.map +1 -0
- package/dist/domains/quality-assessment/services/deployment-advisor.d.ts +83 -0
- package/dist/domains/quality-assessment/services/deployment-advisor.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/deployment-advisor.js +384 -0
- package/dist/domains/quality-assessment/services/deployment-advisor.js.map +1 -0
- package/dist/domains/quality-assessment/services/index.d.ts +9 -0
- package/dist/domains/quality-assessment/services/index.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/index.js +12 -0
- package/dist/domains/quality-assessment/services/index.js.map +1 -0
- package/dist/domains/quality-assessment/services/quality-analyzer.d.ts +74 -0
- package/dist/domains/quality-assessment/services/quality-analyzer.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/quality-analyzer.js +518 -0
- package/dist/domains/quality-assessment/services/quality-analyzer.js.map +1 -0
- package/dist/domains/quality-assessment/services/quality-gate.d.ts +57 -0
- package/dist/domains/quality-assessment/services/quality-gate.d.ts.map +1 -0
- package/dist/domains/quality-assessment/services/quality-gate.js +244 -0
- package/dist/domains/quality-assessment/services/quality-gate.js.map +1 -0
- package/dist/domains/requirements-validation/coordinator.d.ts +89 -0
- package/dist/domains/requirements-validation/coordinator.d.ts.map +1 -0
- package/dist/domains/requirements-validation/coordinator.js +574 -0
- package/dist/domains/requirements-validation/coordinator.js.map +1 -0
- package/dist/domains/requirements-validation/index.d.ts +13 -0
- package/dist/domains/requirements-validation/index.d.ts.map +1 -0
- package/dist/domains/requirements-validation/index.js +21 -0
- package/dist/domains/requirements-validation/index.js.map +1 -0
- package/dist/domains/requirements-validation/interfaces.d.ts +236 -0
- package/dist/domains/requirements-validation/interfaces.d.ts.map +1 -0
- package/dist/domains/requirements-validation/interfaces.js +8 -0
- package/dist/domains/requirements-validation/interfaces.js.map +1 -0
- package/dist/domains/requirements-validation/plugin.d.ts +103 -0
- package/dist/domains/requirements-validation/plugin.d.ts.map +1 -0
- package/dist/domains/requirements-validation/plugin.js +351 -0
- package/dist/domains/requirements-validation/plugin.js.map +1 -0
- package/dist/domains/requirements-validation/services/bdd-scenario-writer.d.ts +58 -0
- package/dist/domains/requirements-validation/services/bdd-scenario-writer.d.ts.map +1 -0
- package/dist/domains/requirements-validation/services/bdd-scenario-writer.js +521 -0
- package/dist/domains/requirements-validation/services/bdd-scenario-writer.js.map +1 -0
- package/dist/domains/requirements-validation/services/index.d.ts +8 -0
- package/dist/domains/requirements-validation/services/index.d.ts.map +1 -0
- package/dist/domains/requirements-validation/services/index.js +8 -0
- package/dist/domains/requirements-validation/services/index.js.map +1 -0
- package/dist/domains/requirements-validation/services/requirements-validator.d.ts +51 -0
- package/dist/domains/requirements-validation/services/requirements-validator.d.ts.map +1 -0
- package/dist/domains/requirements-validation/services/requirements-validator.js +423 -0
- package/dist/domains/requirements-validation/services/requirements-validator.js.map +1 -0
- package/dist/domains/requirements-validation/services/testability-scorer.d.ts +79 -0
- package/dist/domains/requirements-validation/services/testability-scorer.d.ts.map +1 -0
- package/dist/domains/requirements-validation/services/testability-scorer.js +502 -0
- package/dist/domains/requirements-validation/services/testability-scorer.js.map +1 -0
- package/dist/domains/security-compliance/coordinator.d.ts +91 -0
- package/dist/domains/security-compliance/coordinator.d.ts.map +1 -0
- package/dist/domains/security-compliance/coordinator.js +497 -0
- package/dist/domains/security-compliance/coordinator.js.map +1 -0
- package/dist/domains/security-compliance/index.d.ts +13 -0
- package/dist/domains/security-compliance/index.d.ts.map +1 -0
- package/dist/domains/security-compliance/index.js +21 -0
- package/dist/domains/security-compliance/index.js.map +1 -0
- package/dist/domains/security-compliance/interfaces.d.ts +342 -0
- package/dist/domains/security-compliance/interfaces.d.ts.map +1 -0
- package/dist/domains/security-compliance/interfaces.js +8 -0
- package/dist/domains/security-compliance/interfaces.js.map +1 -0
- package/dist/domains/security-compliance/plugin.d.ts +81 -0
- package/dist/domains/security-compliance/plugin.d.ts.map +1 -0
- package/dist/domains/security-compliance/plugin.js +302 -0
- package/dist/domains/security-compliance/plugin.js.map +1 -0
- package/dist/domains/security-compliance/services/compliance-validator.d.ts +102 -0
- package/dist/domains/security-compliance/services/compliance-validator.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/compliance-validator.js +925 -0
- package/dist/domains/security-compliance/services/compliance-validator.js.map +1 -0
- package/dist/domains/security-compliance/services/index.d.ts +8 -0
- package/dist/domains/security-compliance/services/index.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/index.js +8 -0
- package/dist/domains/security-compliance/services/index.js.map +1 -0
- package/dist/domains/security-compliance/services/security-auditor.d.ts +174 -0
- package/dist/domains/security-compliance/services/security-auditor.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/security-auditor.js +1763 -0
- package/dist/domains/security-compliance/services/security-auditor.js.map +1 -0
- package/dist/domains/security-compliance/services/security-scanner.d.ts +185 -0
- package/dist/domains/security-compliance/services/security-scanner.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/security-scanner.js +1911 -0
- package/dist/domains/security-compliance/services/security-scanner.js.map +1 -0
- package/dist/domains/security-compliance/services/semgrep-integration.d.ts +95 -0
- package/dist/domains/security-compliance/services/semgrep-integration.d.ts.map +1 -0
- package/dist/domains/security-compliance/services/semgrep-integration.js +209 -0
- package/dist/domains/security-compliance/services/semgrep-integration.js.map +1 -0
- package/dist/domains/test-execution/coordinator.d.ts +91 -0
- package/dist/domains/test-execution/coordinator.d.ts.map +1 -0
- package/dist/domains/test-execution/coordinator.js +280 -0
- package/dist/domains/test-execution/coordinator.js.map +1 -0
- package/dist/domains/test-execution/index.d.ts +11 -0
- package/dist/domains/test-execution/index.d.ts.map +1 -0
- package/dist/domains/test-execution/index.js +19 -0
- package/dist/domains/test-execution/index.js.map +1 -0
- package/dist/domains/test-execution/interfaces.d.ts +95 -0
- package/dist/domains/test-execution/interfaces.d.ts.map +1 -0
- package/dist/domains/test-execution/interfaces.js +6 -0
- package/dist/domains/test-execution/interfaces.js.map +1 -0
- package/dist/domains/test-execution/plugin.d.ts +27 -0
- package/dist/domains/test-execution/plugin.d.ts.map +1 -0
- package/dist/domains/test-execution/plugin.js +137 -0
- package/dist/domains/test-execution/plugin.js.map +1 -0
- package/dist/domains/test-execution/services/flaky-detector.d.ts +189 -0
- package/dist/domains/test-execution/services/flaky-detector.d.ts.map +1 -0
- package/dist/domains/test-execution/services/flaky-detector.js +834 -0
- package/dist/domains/test-execution/services/flaky-detector.js.map +1 -0
- package/dist/domains/test-execution/services/index.d.ts +8 -0
- package/dist/domains/test-execution/services/index.d.ts.map +1 -0
- package/dist/domains/test-execution/services/index.js +8 -0
- package/dist/domains/test-execution/services/index.js.map +1 -0
- package/dist/domains/test-execution/services/retry-handler.d.ts +169 -0
- package/dist/domains/test-execution/services/retry-handler.d.ts.map +1 -0
- package/dist/domains/test-execution/services/retry-handler.js +536 -0
- package/dist/domains/test-execution/services/retry-handler.js.map +1 -0
- package/dist/domains/test-execution/services/test-executor.d.ts +112 -0
- package/dist/domains/test-execution/services/test-executor.d.ts.map +1 -0
- package/dist/domains/test-execution/services/test-executor.js +657 -0
- package/dist/domains/test-execution/services/test-executor.js.map +1 -0
- package/dist/domains/test-generation/coordinator.d.ts +104 -0
- package/dist/domains/test-generation/coordinator.d.ts.map +1 -0
- package/dist/domains/test-generation/coordinator.js +446 -0
- package/dist/domains/test-generation/coordinator.js.map +1 -0
- package/dist/domains/test-generation/index.d.ts +12 -0
- package/dist/domains/test-generation/index.d.ts.map +1 -0
- package/dist/domains/test-generation/index.js +20 -0
- package/dist/domains/test-generation/index.js.map +1 -0
- package/dist/domains/test-generation/interfaces.d.ts +92 -0
- package/dist/domains/test-generation/interfaces.d.ts.map +1 -0
- package/dist/domains/test-generation/interfaces.js +6 -0
- package/dist/domains/test-generation/interfaces.js.map +1 -0
- package/dist/domains/test-generation/plugin.d.ts +70 -0
- package/dist/domains/test-generation/plugin.d.ts.map +1 -0
- package/dist/domains/test-generation/plugin.js +240 -0
- package/dist/domains/test-generation/plugin.js.map +1 -0
- package/dist/domains/test-generation/services/index.d.ts +7 -0
- package/dist/domains/test-generation/services/index.d.ts.map +1 -0
- package/dist/domains/test-generation/services/index.js +7 -0
- package/dist/domains/test-generation/services/index.js.map +1 -0
- package/dist/domains/test-generation/services/pattern-matcher.d.ts +276 -0
- package/dist/domains/test-generation/services/pattern-matcher.d.ts.map +1 -0
- package/dist/domains/test-generation/services/pattern-matcher.js +1271 -0
- package/dist/domains/test-generation/services/pattern-matcher.js.map +1 -0
- package/dist/domains/test-generation/services/test-generator.d.ts +226 -0
- package/dist/domains/test-generation/services/test-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/services/test-generator.js +2230 -0
- package/dist/domains/test-generation/services/test-generator.js.map +1 -0
- package/dist/domains/visual-accessibility/coordinator.d.ts +118 -0
- package/dist/domains/visual-accessibility/coordinator.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/coordinator.js +623 -0
- package/dist/domains/visual-accessibility/coordinator.js.map +1 -0
- package/dist/domains/visual-accessibility/index.d.ts +13 -0
- package/dist/domains/visual-accessibility/index.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/index.js +21 -0
- package/dist/domains/visual-accessibility/index.js.map +1 -0
- package/dist/domains/visual-accessibility/interfaces.d.ts +360 -0
- package/dist/domains/visual-accessibility/interfaces.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/interfaces.js +8 -0
- package/dist/domains/visual-accessibility/interfaces.js.map +1 -0
- package/dist/domains/visual-accessibility/plugin.d.ts +92 -0
- package/dist/domains/visual-accessibility/plugin.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/plugin.js +343 -0
- package/dist/domains/visual-accessibility/plugin.js.map +1 -0
- package/dist/domains/visual-accessibility/services/accessibility-tester.d.ts +115 -0
- package/dist/domains/visual-accessibility/services/accessibility-tester.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/accessibility-tester.js +794 -0
- package/dist/domains/visual-accessibility/services/accessibility-tester.js.map +1 -0
- package/dist/domains/visual-accessibility/services/axe-core-audit.d.ts +219 -0
- package/dist/domains/visual-accessibility/services/axe-core-audit.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/axe-core-audit.js +427 -0
- package/dist/domains/visual-accessibility/services/axe-core-audit.js.map +1 -0
- package/dist/domains/visual-accessibility/services/index.d.ts +8 -0
- package/dist/domains/visual-accessibility/services/index.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/index.js +8 -0
- package/dist/domains/visual-accessibility/services/index.js.map +1 -0
- package/dist/domains/visual-accessibility/services/responsive-tester.d.ts +149 -0
- package/dist/domains/visual-accessibility/services/responsive-tester.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/responsive-tester.js +667 -0
- package/dist/domains/visual-accessibility/services/responsive-tester.js.map +1 -0
- package/dist/domains/visual-accessibility/services/visual-tester.d.ts +78 -0
- package/dist/domains/visual-accessibility/services/visual-tester.d.ts.map +1 -0
- package/dist/domains/visual-accessibility/services/visual-tester.js +335 -0
- package/dist/domains/visual-accessibility/services/visual-tester.js.map +1 -0
- package/dist/early-exit/early-exit-controller.d.ts +158 -0
- package/dist/early-exit/early-exit-controller.d.ts.map +1 -0
- package/dist/early-exit/early-exit-controller.js +354 -0
- package/dist/early-exit/early-exit-controller.js.map +1 -0
- package/dist/early-exit/early-exit-decision.d.ts +110 -0
- package/dist/early-exit/early-exit-decision.d.ts.map +1 -0
- package/dist/early-exit/early-exit-decision.js +241 -0
- package/dist/early-exit/early-exit-decision.js.map +1 -0
- package/dist/early-exit/index.d.ts +38 -0
- package/dist/early-exit/index.d.ts.map +1 -0
- package/dist/early-exit/index.js +53 -0
- package/dist/early-exit/index.js.map +1 -0
- package/dist/early-exit/quality-signal.d.ts +61 -0
- package/dist/early-exit/quality-signal.d.ts.map +1 -0
- package/dist/early-exit/quality-signal.js +306 -0
- package/dist/early-exit/quality-signal.js.map +1 -0
- package/dist/early-exit/speculative-executor.d.ts +131 -0
- package/dist/early-exit/speculative-executor.d.ts.map +1 -0
- package/dist/early-exit/speculative-executor.js +385 -0
- package/dist/early-exit/speculative-executor.js.map +1 -0
- package/dist/early-exit/types.d.ts +271 -0
- package/dist/early-exit/types.d.ts.map +1 -0
- package/dist/early-exit/types.js +69 -0
- package/dist/early-exit/types.js.map +1 -0
- package/dist/feedback/coverage-learner.d.ts +117 -0
- package/dist/feedback/coverage-learner.d.ts.map +1 -0
- package/dist/feedback/coverage-learner.js +367 -0
- package/dist/feedback/coverage-learner.js.map +1 -0
- package/dist/feedback/feedback-loop.d.ts +170 -0
- package/dist/feedback/feedback-loop.d.ts.map +1 -0
- package/dist/feedback/feedback-loop.js +281 -0
- package/dist/feedback/feedback-loop.js.map +1 -0
- package/dist/feedback/index.d.ts +17 -0
- package/dist/feedback/index.d.ts.map +1 -0
- package/dist/feedback/index.js +20 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/feedback/pattern-promotion.d.ts +126 -0
- package/dist/feedback/pattern-promotion.d.ts.map +1 -0
- package/dist/feedback/pattern-promotion.js +282 -0
- package/dist/feedback/pattern-promotion.js.map +1 -0
- package/dist/feedback/quality-score-calculator.d.ts +93 -0
- package/dist/feedback/quality-score-calculator.d.ts.map +1 -0
- package/dist/feedback/quality-score-calculator.js +285 -0
- package/dist/feedback/quality-score-calculator.js.map +1 -0
- package/dist/feedback/test-outcome-tracker.d.ts +103 -0
- package/dist/feedback/test-outcome-tracker.d.ts.map +1 -0
- package/dist/feedback/test-outcome-tracker.js +347 -0
- package/dist/feedback/test-outcome-tracker.js.map +1 -0
- package/dist/feedback/types.d.ts +322 -0
- package/dist/feedback/types.d.ts.map +1 -0
- package/dist/feedback/types.js +60 -0
- package/dist/feedback/types.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/init/agents-installer.d.ts +88 -0
- package/dist/init/agents-installer.d.ts.map +1 -0
- package/dist/init/agents-installer.js +441 -0
- package/dist/init/agents-installer.js.map +1 -0
- package/dist/init/index.d.ts +18 -0
- package/dist/init/index.d.ts.map +1 -0
- package/dist/init/index.js +14 -0
- package/dist/init/index.js.map +1 -0
- package/dist/init/init-wizard.d.ts +107 -0
- package/dist/init/init-wizard.d.ts.map +1 -0
- package/dist/init/init-wizard.js +906 -0
- package/dist/init/init-wizard.js.map +1 -0
- package/dist/init/project-analyzer.d.ts +95 -0
- package/dist/init/project-analyzer.d.ts.map +1 -0
- package/dist/init/project-analyzer.js +608 -0
- package/dist/init/project-analyzer.js.map +1 -0
- package/dist/init/self-configurator.d.ts +74 -0
- package/dist/init/self-configurator.d.ts.map +1 -0
- package/dist/init/self-configurator.js +384 -0
- package/dist/init/self-configurator.js.map +1 -0
- package/dist/init/skills-installer.d.ts +88 -0
- package/dist/init/skills-installer.d.ts.map +1 -0
- package/dist/init/skills-installer.js +386 -0
- package/dist/init/skills-installer.js.map +1 -0
- package/dist/init/types.d.ts +280 -0
- package/dist/init/types.d.ts.map +1 -0
- package/dist/init/types.js +110 -0
- package/dist/init/types.js.map +1 -0
- package/dist/integrations/ruvector/ast-complexity.d.ts +134 -0
- package/dist/integrations/ruvector/ast-complexity.d.ts.map +1 -0
- package/dist/integrations/ruvector/ast-complexity.js +383 -0
- package/dist/integrations/ruvector/ast-complexity.js.map +1 -0
- package/dist/integrations/ruvector/coverage-router.d.ts +128 -0
- package/dist/integrations/ruvector/coverage-router.d.ts.map +1 -0
- package/dist/integrations/ruvector/coverage-router.js +463 -0
- package/dist/integrations/ruvector/coverage-router.js.map +1 -0
- package/dist/integrations/ruvector/diff-risk-classifier.d.ts +129 -0
- package/dist/integrations/ruvector/diff-risk-classifier.d.ts.map +1 -0
- package/dist/integrations/ruvector/diff-risk-classifier.js +569 -0
- package/dist/integrations/ruvector/diff-risk-classifier.js.map +1 -0
- package/dist/integrations/ruvector/fallback.d.ts +138 -0
- package/dist/integrations/ruvector/fallback.d.ts.map +1 -0
- package/dist/integrations/ruvector/fallback.js +737 -0
- package/dist/integrations/ruvector/fallback.js.map +1 -0
- package/dist/integrations/ruvector/graph-boundaries.d.ts +151 -0
- package/dist/integrations/ruvector/graph-boundaries.d.ts.map +1 -0
- package/dist/integrations/ruvector/graph-boundaries.js +627 -0
- package/dist/integrations/ruvector/graph-boundaries.js.map +1 -0
- package/dist/integrations/ruvector/index.d.ts +82 -0
- package/dist/integrations/ruvector/index.d.ts.map +1 -0
- package/dist/integrations/ruvector/index.js +254 -0
- package/dist/integrations/ruvector/index.js.map +1 -0
- package/dist/integrations/ruvector/interfaces.d.ts +488 -0
- package/dist/integrations/ruvector/interfaces.d.ts.map +1 -0
- package/dist/integrations/ruvector/interfaces.js +64 -0
- package/dist/integrations/ruvector/interfaces.js.map +1 -0
- package/dist/integrations/ruvector/q-learning-router.d.ts +128 -0
- package/dist/integrations/ruvector/q-learning-router.d.ts.map +1 -0
- package/dist/integrations/ruvector/q-learning-router.js +427 -0
- package/dist/integrations/ruvector/q-learning-router.js.map +1 -0
- package/dist/kernel/agent-coordinator.d.ts +22 -0
- package/dist/kernel/agent-coordinator.d.ts.map +1 -0
- package/dist/kernel/agent-coordinator.js +113 -0
- package/dist/kernel/agent-coordinator.js.map +1 -0
- package/dist/kernel/agentdb-backend.d.ts +131 -0
- package/dist/kernel/agentdb-backend.d.ts.map +1 -0
- package/dist/kernel/agentdb-backend.js +359 -0
- package/dist/kernel/agentdb-backend.js.map +1 -0
- package/dist/kernel/event-bus.d.ts +18 -0
- package/dist/kernel/event-bus.d.ts.map +1 -0
- package/dist/kernel/event-bus.js +99 -0
- package/dist/kernel/event-bus.js.map +1 -0
- package/dist/kernel/hybrid-backend.d.ts +124 -0
- package/dist/kernel/hybrid-backend.d.ts.map +1 -0
- package/dist/kernel/hybrid-backend.js +395 -0
- package/dist/kernel/hybrid-backend.js.map +1 -0
- package/dist/kernel/index.d.ts +16 -0
- package/dist/kernel/index.d.ts.map +1 -0
- package/dist/kernel/index.js +17 -0
- package/dist/kernel/index.js.map +1 -0
- package/dist/kernel/interfaces.d.ts +174 -0
- package/dist/kernel/interfaces.d.ts.map +1 -0
- package/dist/kernel/interfaces.js +6 -0
- package/dist/kernel/interfaces.js.map +1 -0
- package/dist/kernel/kernel.d.ts +50 -0
- package/dist/kernel/kernel.d.ts.map +1 -0
- package/dist/kernel/kernel.js +228 -0
- package/dist/kernel/kernel.js.map +1 -0
- package/dist/kernel/memory-backend.d.ts +28 -0
- package/dist/kernel/memory-backend.d.ts.map +1 -0
- package/dist/kernel/memory-backend.js +126 -0
- package/dist/kernel/memory-backend.js.map +1 -0
- package/dist/kernel/memory-factory.d.ts +100 -0
- package/dist/kernel/memory-factory.d.ts.map +1 -0
- package/dist/kernel/memory-factory.js +209 -0
- package/dist/kernel/memory-factory.js.map +1 -0
- package/dist/kernel/plugin-loader.d.ts +36 -0
- package/dist/kernel/plugin-loader.d.ts.map +1 -0
- package/dist/kernel/plugin-loader.js +145 -0
- package/dist/kernel/plugin-loader.js.map +1 -0
- package/dist/learning/index.d.ts +58 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +90 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/pattern-store.d.ts +242 -0
- package/dist/learning/pattern-store.d.ts.map +1 -0
- package/dist/learning/pattern-store.js +657 -0
- package/dist/learning/pattern-store.js.map +1 -0
- package/dist/learning/qe-guidance.d.ts +125 -0
- package/dist/learning/qe-guidance.d.ts.map +1 -0
- package/dist/learning/qe-guidance.js +712 -0
- package/dist/learning/qe-guidance.js.map +1 -0
- package/dist/learning/qe-hooks.d.ts +111 -0
- package/dist/learning/qe-hooks.d.ts.map +1 -0
- package/dist/learning/qe-hooks.js +475 -0
- package/dist/learning/qe-hooks.js.map +1 -0
- package/dist/learning/qe-patterns.d.ts +203 -0
- package/dist/learning/qe-patterns.d.ts.map +1 -0
- package/dist/learning/qe-patterns.js +181 -0
- package/dist/learning/qe-patterns.js.map +1 -0
- package/dist/learning/qe-reasoning-bank.d.ts +263 -0
- package/dist/learning/qe-reasoning-bank.d.ts.map +1 -0
- package/dist/learning/qe-reasoning-bank.js +617 -0
- package/dist/learning/qe-reasoning-bank.js.map +1 -0
- package/dist/learning/real-embeddings.d.ts +61 -0
- package/dist/learning/real-embeddings.d.ts.map +1 -0
- package/dist/learning/real-embeddings.js +219 -0
- package/dist/learning/real-embeddings.js.map +1 -0
- package/dist/learning/real-qe-reasoning-bank.d.ts +182 -0
- package/dist/learning/real-qe-reasoning-bank.d.ts.map +1 -0
- package/dist/learning/real-qe-reasoning-bank.js +597 -0
- package/dist/learning/real-qe-reasoning-bank.js.map +1 -0
- package/dist/learning/sqlite-persistence.d.ts +121 -0
- package/dist/learning/sqlite-persistence.d.ts.map +1 -0
- package/dist/learning/sqlite-persistence.js +438 -0
- package/dist/learning/sqlite-persistence.js.map +1 -0
- package/dist/mcp/entry.d.ts +13 -0
- package/dist/mcp/entry.d.ts.map +1 -0
- package/dist/mcp/entry.js +53 -0
- package/dist/mcp/entry.js.map +1 -0
- package/dist/mcp/handlers/agent-handlers.d.ts +62 -0
- package/dist/mcp/handlers/agent-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/agent-handlers.js +173 -0
- package/dist/mcp/handlers/agent-handlers.js.map +1 -0
- package/dist/mcp/handlers/core-handlers.d.ts +30 -0
- package/dist/mcp/handlers/core-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/core-handlers.js +250 -0
- package/dist/mcp/handlers/core-handlers.js.map +1 -0
- package/dist/mcp/handlers/domain-handlers.d.ts +135 -0
- package/dist/mcp/handlers/domain-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/domain-handlers.js +990 -0
- package/dist/mcp/handlers/domain-handlers.js.map +1 -0
- package/dist/mcp/handlers/index.d.ts +10 -0
- package/dist/mcp/handlers/index.d.ts.map +1 -0
- package/dist/mcp/handlers/index.js +15 -0
- package/dist/mcp/handlers/index.js.map +1 -0
- package/dist/mcp/handlers/memory-handlers.d.ts +53 -0
- package/dist/mcp/handlers/memory-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/memory-handlers.js +228 -0
- package/dist/mcp/handlers/memory-handlers.js.map +1 -0
- package/dist/mcp/handlers/task-handlers.d.ts +26 -0
- package/dist/mcp/handlers/task-handlers.d.ts.map +1 -0
- package/dist/mcp/handlers/task-handlers.js +293 -0
- package/dist/mcp/handlers/task-handlers.js.map +1 -0
- package/dist/mcp/index.d.ts +12 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +18 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/metrics/index.d.ts +6 -0
- package/dist/mcp/metrics/index.d.ts.map +1 -0
- package/dist/mcp/metrics/index.js +6 -0
- package/dist/mcp/metrics/index.js.map +1 -0
- package/dist/mcp/metrics/metrics-collector.d.ts +154 -0
- package/dist/mcp/metrics/metrics-collector.d.ts.map +1 -0
- package/dist/mcp/metrics/metrics-collector.js +377 -0
- package/dist/mcp/metrics/metrics-collector.js.map +1 -0
- package/dist/mcp/protocol-server.d.ts +66 -0
- package/dist/mcp/protocol-server.d.ts.map +1 -0
- package/dist/mcp/protocol-server.js +600 -0
- package/dist/mcp/protocol-server.js.map +1 -0
- package/dist/mcp/security/cve-prevention.d.ts +150 -0
- package/dist/mcp/security/cve-prevention.d.ts.map +1 -0
- package/dist/mcp/security/cve-prevention.js +570 -0
- package/dist/mcp/security/cve-prevention.js.map +1 -0
- package/dist/mcp/security/index.d.ts +116 -0
- package/dist/mcp/security/index.d.ts.map +1 -0
- package/dist/mcp/security/index.js +184 -0
- package/dist/mcp/security/index.js.map +1 -0
- package/dist/mcp/security/oauth21-provider.d.ts +229 -0
- package/dist/mcp/security/oauth21-provider.d.ts.map +1 -0
- package/dist/mcp/security/oauth21-provider.js +558 -0
- package/dist/mcp/security/oauth21-provider.js.map +1 -0
- package/dist/mcp/security/rate-limiter.d.ts +191 -0
- package/dist/mcp/security/rate-limiter.d.ts.map +1 -0
- package/dist/mcp/security/rate-limiter.js +437 -0
- package/dist/mcp/security/rate-limiter.js.map +1 -0
- package/dist/mcp/security/sampling-server.d.ts +289 -0
- package/dist/mcp/security/sampling-server.d.ts.map +1 -0
- package/dist/mcp/security/sampling-server.js +450 -0
- package/dist/mcp/security/sampling-server.js.map +1 -0
- package/dist/mcp/security/schema-validator.d.ts +197 -0
- package/dist/mcp/security/schema-validator.d.ts.map +1 -0
- package/dist/mcp/security/schema-validator.js +633 -0
- package/dist/mcp/security/schema-validator.js.map +1 -0
- package/dist/mcp/server.d.ts +46 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +576 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tool-registry.d.ts +98 -0
- package/dist/mcp/tool-registry.d.ts.map +1 -0
- package/dist/mcp/tool-registry.js +321 -0
- package/dist/mcp/tool-registry.js.map +1 -0
- package/dist/mcp/tools/base.d.ts +186 -0
- package/dist/mcp/tools/base.d.ts.map +1 -0
- package/dist/mcp/tools/base.js +249 -0
- package/dist/mcp/tools/base.js.map +1 -0
- package/dist/mcp/tools/chaos-resilience/inject.d.ts +61 -0
- package/dist/mcp/tools/chaos-resilience/inject.d.ts.map +1 -0
- package/dist/mcp/tools/chaos-resilience/inject.js +520 -0
- package/dist/mcp/tools/chaos-resilience/inject.js.map +1 -0
- package/dist/mcp/tools/code-intelligence/analyze.d.ts +140 -0
- package/dist/mcp/tools/code-intelligence/analyze.d.ts.map +1 -0
- package/dist/mcp/tools/code-intelligence/analyze.js +570 -0
- package/dist/mcp/tools/code-intelligence/analyze.js.map +1 -0
- package/dist/mcp/tools/contract-testing/validate.d.ts +90 -0
- package/dist/mcp/tools/contract-testing/validate.d.ts.map +1 -0
- package/dist/mcp/tools/contract-testing/validate.js +515 -0
- package/dist/mcp/tools/contract-testing/validate.js.map +1 -0
- package/dist/mcp/tools/coverage-analysis/index.d.ts +111 -0
- package/dist/mcp/tools/coverage-analysis/index.d.ts.map +1 -0
- package/dist/mcp/tools/coverage-analysis/index.js +577 -0
- package/dist/mcp/tools/coverage-analysis/index.js.map +1 -0
- package/dist/mcp/tools/defect-intelligence/predict.d.ts +67 -0
- package/dist/mcp/tools/defect-intelligence/predict.d.ts.map +1 -0
- package/dist/mcp/tools/defect-intelligence/predict.js +359 -0
- package/dist/mcp/tools/defect-intelligence/predict.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +40 -0
- package/dist/mcp/tools/index.d.ts.map +1 -0
- package/dist/mcp/tools/index.js +82 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/learning-optimization/optimize.d.ts +123 -0
- package/dist/mcp/tools/learning-optimization/optimize.d.ts.map +1 -0
- package/dist/mcp/tools/learning-optimization/optimize.js +563 -0
- package/dist/mcp/tools/learning-optimization/optimize.js.map +1 -0
- package/dist/mcp/tools/quality-assessment/evaluate.d.ts +83 -0
- package/dist/mcp/tools/quality-assessment/evaluate.d.ts.map +1 -0
- package/dist/mcp/tools/quality-assessment/evaluate.js +277 -0
- package/dist/mcp/tools/quality-assessment/evaluate.js.map +1 -0
- package/dist/mcp/tools/registry.d.ts +79 -0
- package/dist/mcp/tools/registry.d.ts.map +1 -0
- package/dist/mcp/tools/registry.js +181 -0
- package/dist/mcp/tools/registry.js.map +1 -0
- package/dist/mcp/tools/requirements-validation/validate.d.ts +81 -0
- package/dist/mcp/tools/requirements-validation/validate.d.ts.map +1 -0
- package/dist/mcp/tools/requirements-validation/validate.js +270 -0
- package/dist/mcp/tools/requirements-validation/validate.js.map +1 -0
- package/dist/mcp/tools/security-compliance/scan.d.ts +75 -0
- package/dist/mcp/tools/security-compliance/scan.d.ts.map +1 -0
- package/dist/mcp/tools/security-compliance/scan.js +258 -0
- package/dist/mcp/tools/security-compliance/scan.js.map +1 -0
- package/dist/mcp/tools/test-execution/execute.d.ts +65 -0
- package/dist/mcp/tools/test-execution/execute.d.ts.map +1 -0
- package/dist/mcp/tools/test-execution/execute.js +196 -0
- package/dist/mcp/tools/test-execution/execute.js.map +1 -0
- package/dist/mcp/tools/test-generation/generate.d.ts +53 -0
- package/dist/mcp/tools/test-generation/generate.d.ts.map +1 -0
- package/dist/mcp/tools/test-generation/generate.js +437 -0
- package/dist/mcp/tools/test-generation/generate.js.map +1 -0
- package/dist/mcp/tools/visual-accessibility/index.d.ts +144 -0
- package/dist/mcp/tools/visual-accessibility/index.d.ts.map +1 -0
- package/dist/mcp/tools/visual-accessibility/index.js +562 -0
- package/dist/mcp/tools/visual-accessibility/index.js.map +1 -0
- package/dist/mcp/transport/index.d.ts +12 -0
- package/dist/mcp/transport/index.d.ts.map +1 -0
- package/dist/mcp/transport/index.js +21 -0
- package/dist/mcp/transport/index.js.map +1 -0
- package/dist/mcp/transport/stdio.d.ts +95 -0
- package/dist/mcp/transport/stdio.d.ts.map +1 -0
- package/dist/mcp/transport/stdio.js +226 -0
- package/dist/mcp/transport/stdio.js.map +1 -0
- package/dist/mcp/types.d.ts +455 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +6 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/neural-optimizer/index.d.ts +55 -0
- package/dist/neural-optimizer/index.d.ts.map +1 -0
- package/dist/neural-optimizer/index.js +57 -0
- package/dist/neural-optimizer/index.js.map +1 -0
- package/dist/neural-optimizer/replay-buffer.d.ts +126 -0
- package/dist/neural-optimizer/replay-buffer.d.ts.map +1 -0
- package/dist/neural-optimizer/replay-buffer.js +355 -0
- package/dist/neural-optimizer/replay-buffer.js.map +1 -0
- package/dist/neural-optimizer/swarm-topology.d.ts +157 -0
- package/dist/neural-optimizer/swarm-topology.d.ts.map +1 -0
- package/dist/neural-optimizer/swarm-topology.js +384 -0
- package/dist/neural-optimizer/swarm-topology.js.map +1 -0
- package/dist/neural-optimizer/topology-optimizer.d.ts +137 -0
- package/dist/neural-optimizer/topology-optimizer.d.ts.map +1 -0
- package/dist/neural-optimizer/topology-optimizer.js +656 -0
- package/dist/neural-optimizer/topology-optimizer.js.map +1 -0
- package/dist/neural-optimizer/types.d.ts +333 -0
- package/dist/neural-optimizer/types.d.ts.map +1 -0
- package/dist/neural-optimizer/types.js +57 -0
- package/dist/neural-optimizer/types.js.map +1 -0
- package/dist/neural-optimizer/value-network.d.ts +129 -0
- package/dist/neural-optimizer/value-network.d.ts.map +1 -0
- package/dist/neural-optimizer/value-network.js +278 -0
- package/dist/neural-optimizer/value-network.js.map +1 -0
- package/dist/optimization/auto-tuner.d.ts +207 -0
- package/dist/optimization/auto-tuner.d.ts.map +1 -0
- package/dist/optimization/auto-tuner.js +641 -0
- package/dist/optimization/auto-tuner.js.map +1 -0
- package/dist/optimization/index.d.ts +16 -0
- package/dist/optimization/index.d.ts.map +1 -0
- package/dist/optimization/index.js +14 -0
- package/dist/optimization/index.js.map +1 -0
- package/dist/optimization/metric-collectors.d.ts +145 -0
- package/dist/optimization/metric-collectors.d.ts.map +1 -0
- package/dist/optimization/metric-collectors.js +401 -0
- package/dist/optimization/metric-collectors.js.map +1 -0
- package/dist/optimization/qe-workers.d.ts +143 -0
- package/dist/optimization/qe-workers.d.ts.map +1 -0
- package/dist/optimization/qe-workers.js +510 -0
- package/dist/optimization/qe-workers.js.map +1 -0
- package/dist/optimization/tuning-algorithm.d.ts +93 -0
- package/dist/optimization/tuning-algorithm.d.ts.map +1 -0
- package/dist/optimization/tuning-algorithm.js +278 -0
- package/dist/optimization/tuning-algorithm.js.map +1 -0
- package/dist/optimization/types.d.ts +211 -0
- package/dist/optimization/types.d.ts.map +1 -0
- package/dist/optimization/types.js +81 -0
- package/dist/optimization/types.js.map +1 -0
- package/dist/routing/index.d.ts +15 -0
- package/dist/routing/index.d.ts.map +1 -0
- package/dist/routing/index.js +17 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/qe-agent-registry.d.ts +58 -0
- package/dist/routing/qe-agent-registry.d.ts.map +1 -0
- package/dist/routing/qe-agent-registry.js +909 -0
- package/dist/routing/qe-agent-registry.js.map +1 -0
- package/dist/routing/qe-task-router.d.ts +82 -0
- package/dist/routing/qe-task-router.d.ts.map +1 -0
- package/dist/routing/qe-task-router.js +453 -0
- package/dist/routing/qe-task-router.js.map +1 -0
- package/dist/routing/routing-feedback.d.ts +82 -0
- package/dist/routing/routing-feedback.d.ts.map +1 -0
- package/dist/routing/routing-feedback.js +272 -0
- package/dist/routing/routing-feedback.js.map +1 -0
- package/dist/routing/types.d.ts +225 -0
- package/dist/routing/types.d.ts.map +1 -0
- package/dist/routing/types.js +27 -0
- package/dist/routing/types.js.map +1 -0
- package/dist/shared/embeddings/embedding-cache.d.ts +62 -0
- package/dist/shared/embeddings/embedding-cache.d.ts.map +1 -0
- package/dist/shared/embeddings/embedding-cache.js +136 -0
- package/dist/shared/embeddings/embedding-cache.js.map +1 -0
- package/dist/shared/embeddings/index.d.ts +35 -0
- package/dist/shared/embeddings/index.d.ts.map +1 -0
- package/dist/shared/embeddings/index.js +33 -0
- package/dist/shared/embeddings/index.js.map +1 -0
- package/dist/shared/embeddings/nomic-embedder.d.ts +128 -0
- package/dist/shared/embeddings/nomic-embedder.d.ts.map +1 -0
- package/dist/shared/embeddings/nomic-embedder.js +322 -0
- package/dist/shared/embeddings/nomic-embedder.js.map +1 -0
- package/dist/shared/embeddings/ollama-client.d.ts +40 -0
- package/dist/shared/embeddings/ollama-client.d.ts.map +1 -0
- package/dist/shared/embeddings/ollama-client.js +140 -0
- package/dist/shared/embeddings/ollama-client.js.map +1 -0
- package/dist/shared/embeddings/types.d.ts +136 -0
- package/dist/shared/embeddings/types.d.ts.map +1 -0
- package/dist/shared/embeddings/types.js +26 -0
- package/dist/shared/embeddings/types.js.map +1 -0
- package/dist/shared/entities/agent.d.ts +40 -0
- package/dist/shared/entities/agent.d.ts.map +1 -0
- package/dist/shared/entities/agent.js +107 -0
- package/dist/shared/entities/agent.js.map +1 -0
- package/dist/shared/entities/base-entity.d.ts +37 -0
- package/dist/shared/entities/base-entity.d.ts.map +1 -0
- package/dist/shared/entities/base-entity.js +56 -0
- package/dist/shared/entities/base-entity.js.map +1 -0
- package/dist/shared/entities/index.d.ts +6 -0
- package/dist/shared/entities/index.d.ts.map +1 -0
- package/dist/shared/entities/index.js +6 -0
- package/dist/shared/entities/index.js.map +1 -0
- package/dist/shared/events/domain-events.d.ts +194 -0
- package/dist/shared/events/domain-events.d.ts.map +1 -0
- package/dist/shared/events/domain-events.js +74 -0
- package/dist/shared/events/domain-events.js.map +1 -0
- package/dist/shared/events/index.d.ts +5 -0
- package/dist/shared/events/index.d.ts.map +1 -0
- package/dist/shared/events/index.js +5 -0
- package/dist/shared/events/index.js.map +1 -0
- package/dist/shared/git/git-analyzer.d.ts +135 -0
- package/dist/shared/git/git-analyzer.d.ts.map +1 -0
- package/dist/shared/git/git-analyzer.js +562 -0
- package/dist/shared/git/git-analyzer.js.map +1 -0
- package/dist/shared/git/index.d.ts +6 -0
- package/dist/shared/git/index.d.ts.map +1 -0
- package/dist/shared/git/index.js +5 -0
- package/dist/shared/git/index.js.map +1 -0
- package/dist/shared/http/http-client.d.ts +92 -0
- package/dist/shared/http/http-client.d.ts.map +1 -0
- package/dist/shared/http/http-client.js +295 -0
- package/dist/shared/http/http-client.js.map +1 -0
- package/dist/shared/http/index.d.ts +5 -0
- package/dist/shared/http/index.d.ts.map +1 -0
- package/dist/shared/http/index.js +5 -0
- package/dist/shared/http/index.js.map +1 -0
- package/dist/shared/index.d.ts +18 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +17 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/io/file-reader.d.ts +107 -0
- package/dist/shared/io/file-reader.d.ts.map +1 -0
- package/dist/shared/io/file-reader.js +408 -0
- package/dist/shared/io/file-reader.js.map +1 -0
- package/dist/shared/io/index.d.ts +6 -0
- package/dist/shared/io/index.d.ts.map +1 -0
- package/dist/shared/io/index.js +12 -0
- package/dist/shared/io/index.js.map +1 -0
- package/dist/shared/llm/cache.d.ts +163 -0
- package/dist/shared/llm/cache.d.ts.map +1 -0
- package/dist/shared/llm/cache.js +368 -0
- package/dist/shared/llm/cache.js.map +1 -0
- package/dist/shared/llm/circuit-breaker.d.ts +117 -0
- package/dist/shared/llm/circuit-breaker.d.ts.map +1 -0
- package/dist/shared/llm/circuit-breaker.js +294 -0
- package/dist/shared/llm/circuit-breaker.js.map +1 -0
- package/dist/shared/llm/cost-tracker.d.ts +133 -0
- package/dist/shared/llm/cost-tracker.d.ts.map +1 -0
- package/dist/shared/llm/cost-tracker.js +342 -0
- package/dist/shared/llm/cost-tracker.js.map +1 -0
- package/dist/shared/llm/index.d.ts +50 -0
- package/dist/shared/llm/index.d.ts.map +1 -0
- package/dist/shared/llm/index.js +56 -0
- package/dist/shared/llm/index.js.map +1 -0
- package/dist/shared/llm/interfaces.d.ts +503 -0
- package/dist/shared/llm/interfaces.d.ts.map +1 -0
- package/dist/shared/llm/interfaces.js +33 -0
- package/dist/shared/llm/interfaces.js.map +1 -0
- package/dist/shared/llm/provider-manager.d.ts +158 -0
- package/dist/shared/llm/provider-manager.d.ts.map +1 -0
- package/dist/shared/llm/provider-manager.js +527 -0
- package/dist/shared/llm/provider-manager.js.map +1 -0
- package/dist/shared/llm/providers/claude.d.ts +99 -0
- package/dist/shared/llm/providers/claude.d.ts.map +1 -0
- package/dist/shared/llm/providers/claude.js +394 -0
- package/dist/shared/llm/providers/claude.js.map +1 -0
- package/dist/shared/llm/providers/index.d.ts +8 -0
- package/dist/shared/llm/providers/index.d.ts.map +1 -0
- package/dist/shared/llm/providers/index.js +8 -0
- package/dist/shared/llm/providers/index.js.map +1 -0
- package/dist/shared/llm/providers/ollama.d.ts +91 -0
- package/dist/shared/llm/providers/ollama.d.ts.map +1 -0
- package/dist/shared/llm/providers/ollama.js +391 -0
- package/dist/shared/llm/providers/ollama.js.map +1 -0
- package/dist/shared/llm/providers/openai.d.ts +98 -0
- package/dist/shared/llm/providers/openai.d.ts.map +1 -0
- package/dist/shared/llm/providers/openai.js +440 -0
- package/dist/shared/llm/providers/openai.js.map +1 -0
- package/dist/shared/metrics/code-metrics.d.ts +75 -0
- package/dist/shared/metrics/code-metrics.d.ts.map +1 -0
- package/dist/shared/metrics/code-metrics.js +395 -0
- package/dist/shared/metrics/code-metrics.js.map +1 -0
- package/dist/shared/metrics/index.d.ts +9 -0
- package/dist/shared/metrics/index.d.ts.map +1 -0
- package/dist/shared/metrics/index.js +7 -0
- package/dist/shared/metrics/index.js.map +1 -0
- package/dist/shared/metrics/system-metrics.d.ts +109 -0
- package/dist/shared/metrics/system-metrics.d.ts.map +1 -0
- package/dist/shared/metrics/system-metrics.js +267 -0
- package/dist/shared/metrics/system-metrics.js.map +1 -0
- package/dist/shared/parsers/index.d.ts +6 -0
- package/dist/shared/parsers/index.d.ts.map +1 -0
- package/dist/shared/parsers/index.js +6 -0
- package/dist/shared/parsers/index.js.map +1 -0
- package/dist/shared/parsers/typescript-parser.d.ts +211 -0
- package/dist/shared/parsers/typescript-parser.d.ts.map +1 -0
- package/dist/shared/parsers/typescript-parser.js +561 -0
- package/dist/shared/parsers/typescript-parser.js.map +1 -0
- package/dist/shared/security/compliance-patterns.d.ts +78 -0
- package/dist/shared/security/compliance-patterns.d.ts.map +1 -0
- package/dist/shared/security/compliance-patterns.js +543 -0
- package/dist/shared/security/compliance-patterns.js.map +1 -0
- package/dist/shared/security/index.d.ts +8 -0
- package/dist/shared/security/index.d.ts.map +1 -0
- package/dist/shared/security/index.js +6 -0
- package/dist/shared/security/index.js.map +1 -0
- package/dist/shared/security/osv-client.d.ts +191 -0
- package/dist/shared/security/osv-client.d.ts.map +1 -0
- package/dist/shared/security/osv-client.js +256 -0
- package/dist/shared/security/osv-client.js.map +1 -0
- package/dist/shared/types/index.d.ts +66 -0
- package/dist/shared/types/index.d.ts.map +1 -0
- package/dist/shared/types/index.js +25 -0
- package/dist/shared/types/index.js.map +1 -0
- package/dist/shared/value-objects/index.d.ts +73 -0
- package/dist/shared/value-objects/index.d.ts.map +1 -0
- package/dist/shared/value-objects/index.js +229 -0
- package/dist/shared/value-objects/index.js.map +1 -0
- package/dist/strange-loop/healing-controller.d.ts +125 -0
- package/dist/strange-loop/healing-controller.d.ts.map +1 -0
- package/dist/strange-loop/healing-controller.js +648 -0
- package/dist/strange-loop/healing-controller.js.map +1 -0
- package/dist/strange-loop/index.d.ts +26 -0
- package/dist/strange-loop/index.d.ts.map +1 -0
- package/dist/strange-loop/index.js +30 -0
- package/dist/strange-loop/index.js.map +1 -0
- package/dist/strange-loop/self-model.d.ts +84 -0
- package/dist/strange-loop/self-model.d.ts.map +1 -0
- package/dist/strange-loop/self-model.js +378 -0
- package/dist/strange-loop/self-model.js.map +1 -0
- package/dist/strange-loop/strange-loop.d.ts +112 -0
- package/dist/strange-loop/strange-loop.d.ts.map +1 -0
- package/dist/strange-loop/strange-loop.js +354 -0
- package/dist/strange-loop/strange-loop.js.map +1 -0
- package/dist/strange-loop/swarm-observer.d.ts +89 -0
- package/dist/strange-loop/swarm-observer.d.ts.map +1 -0
- package/dist/strange-loop/swarm-observer.js +341 -0
- package/dist/strange-loop/swarm-observer.js.map +1 -0
- package/dist/strange-loop/topology-analyzer.d.ts +87 -0
- package/dist/strange-loop/topology-analyzer.d.ts.map +1 -0
- package/dist/strange-loop/topology-analyzer.js +441 -0
- package/dist/strange-loop/topology-analyzer.js.map +1 -0
- package/dist/strange-loop/types.d.ts +425 -0
- package/dist/strange-loop/types.d.ts.map +1 -0
- package/dist/strange-loop/types.js +22 -0
- package/dist/strange-loop/types.js.map +1 -0
- package/dist/time-crystal/default-phases.d.ts +95 -0
- package/dist/time-crystal/default-phases.d.ts.map +1 -0
- package/dist/time-crystal/default-phases.js +456 -0
- package/dist/time-crystal/default-phases.js.map +1 -0
- package/dist/time-crystal/index.d.ts +28 -0
- package/dist/time-crystal/index.d.ts.map +1 -0
- package/dist/time-crystal/index.js +55 -0
- package/dist/time-crystal/index.js.map +1 -0
- package/dist/time-crystal/oscillator.d.ts +195 -0
- package/dist/time-crystal/oscillator.d.ts.map +1 -0
- package/dist/time-crystal/oscillator.js +358 -0
- package/dist/time-crystal/oscillator.js.map +1 -0
- package/dist/time-crystal/phase-executor.d.ts +212 -0
- package/dist/time-crystal/phase-executor.d.ts.map +1 -0
- package/dist/time-crystal/phase-executor.js +327 -0
- package/dist/time-crystal/phase-executor.js.map +1 -0
- package/dist/time-crystal/scheduler.d.ts +239 -0
- package/dist/time-crystal/scheduler.d.ts.map +1 -0
- package/dist/time-crystal/scheduler.js +860 -0
- package/dist/time-crystal/scheduler.js.map +1 -0
- package/dist/time-crystal/test-runner.d.ts +141 -0
- package/dist/time-crystal/test-runner.d.ts.map +1 -0
- package/dist/time-crystal/test-runner.js +529 -0
- package/dist/time-crystal/test-runner.js.map +1 -0
- package/dist/time-crystal/types.d.ts +269 -0
- package/dist/time-crystal/types.d.ts.map +1 -0
- package/dist/time-crystal/types.js +51 -0
- package/dist/time-crystal/types.js.map +1 -0
- package/dist/workers/base-worker.d.ts +83 -0
- package/dist/workers/base-worker.d.ts.map +1 -0
- package/dist/workers/base-worker.js +235 -0
- package/dist/workers/base-worker.js.map +1 -0
- package/dist/workers/daemon.d.ts +73 -0
- package/dist/workers/daemon.d.ts.map +1 -0
- package/dist/workers/daemon.js +193 -0
- package/dist/workers/daemon.js.map +1 -0
- package/dist/workers/index.d.ts +91 -0
- package/dist/workers/index.d.ts.map +1 -0
- package/dist/workers/index.js +95 -0
- package/dist/workers/index.js.map +1 -0
- package/dist/workers/interfaces.d.ts +270 -0
- package/dist/workers/interfaces.d.ts.map +1 -0
- package/dist/workers/interfaces.js +9 -0
- package/dist/workers/interfaces.js.map +1 -0
- package/dist/workers/worker-manager.d.ts +87 -0
- package/dist/workers/worker-manager.d.ts.map +1 -0
- package/dist/workers/worker-manager.js +345 -0
- package/dist/workers/worker-manager.js.map +1 -0
- package/dist/workers/workers/compliance-checker.d.ts +28 -0
- package/dist/workers/workers/compliance-checker.d.ts.map +1 -0
- package/dist/workers/workers/compliance-checker.js +334 -0
- package/dist/workers/workers/compliance-checker.js.map +1 -0
- package/dist/workers/workers/coverage-tracker.d.ts +24 -0
- package/dist/workers/workers/coverage-tracker.d.ts.map +1 -0
- package/dist/workers/workers/coverage-tracker.js +265 -0
- package/dist/workers/workers/coverage-tracker.js.map +1 -0
- package/dist/workers/workers/defect-predictor.d.ts +22 -0
- package/dist/workers/workers/defect-predictor.d.ts.map +1 -0
- package/dist/workers/workers/defect-predictor.js +292 -0
- package/dist/workers/workers/defect-predictor.js.map +1 -0
- package/dist/workers/workers/flaky-detector.d.ts +25 -0
- package/dist/workers/workers/flaky-detector.d.ts.map +1 -0
- package/dist/workers/workers/flaky-detector.js +288 -0
- package/dist/workers/workers/flaky-detector.js.map +1 -0
- package/dist/workers/workers/index.d.ts +17 -0
- package/dist/workers/workers/index.d.ts.map +1 -0
- package/dist/workers/workers/index.js +17 -0
- package/dist/workers/workers/index.js.map +1 -0
- package/dist/workers/workers/learning-consolidation.d.ts +25 -0
- package/dist/workers/workers/learning-consolidation.d.ts.map +1 -0
- package/dist/workers/workers/learning-consolidation.js +324 -0
- package/dist/workers/workers/learning-consolidation.js.map +1 -0
- package/dist/workers/workers/performance-baseline.d.ts +25 -0
- package/dist/workers/workers/performance-baseline.d.ts.map +1 -0
- package/dist/workers/workers/performance-baseline.js +315 -0
- package/dist/workers/workers/performance-baseline.js.map +1 -0
- package/dist/workers/workers/quality-gate.d.ts +23 -0
- package/dist/workers/workers/quality-gate.d.ts.map +1 -0
- package/dist/workers/workers/quality-gate.js +348 -0
- package/dist/workers/workers/quality-gate.js.map +1 -0
- package/dist/workers/workers/regression-monitor.d.ts +24 -0
- package/dist/workers/workers/regression-monitor.d.ts.map +1 -0
- package/dist/workers/workers/regression-monitor.js +280 -0
- package/dist/workers/workers/regression-monitor.js.map +1 -0
- package/dist/workers/workers/security-scan.d.ts +22 -0
- package/dist/workers/workers/security-scan.d.ts.map +1 -0
- package/dist/workers/workers/security-scan.js +264 -0
- package/dist/workers/workers/security-scan.js.map +1 -0
- package/dist/workers/workers/test-health.d.ts +26 -0
- package/dist/workers/workers/test-health.d.ts.map +1 -0
- package/dist/workers/workers/test-health.js +258 -0
- package/dist/workers/workers/test-health.js.map +1 -0
- package/docs/analysis/V3-INIT-REQUIREMENTS-ANALYSIS.md +352 -0
- package/implementation/README.md +90 -0
- package/implementation/adrs/ADR-030-coherence-gated-quality-gates.md +312 -0
- package/implementation/adrs/ADR-031-strange-loop-self-awareness.md +484 -0
- package/implementation/adrs/ADR-032-time-crystal-scheduling.md +530 -0
- package/implementation/adrs/ADR-033-early-exit-testing.md +634 -0
- package/implementation/adrs/ADR-034-neural-topology-optimizer.md +589 -0
- package/implementation/adrs/ADR-035-causal-discovery.md +610 -0
- package/implementation/adrs/ADR-036-result-persistence.md +326 -0
- package/implementation/adrs/ADR-037-v3-qe-agent-naming.md +105 -0
- package/implementation/adrs/ADR-038-v3-qe-memory-unification.md +154 -0
- package/implementation/adrs/ADR-039-v3-qe-mcp-optimization.md +179 -0
- package/implementation/adrs/ADR-040-v3-qe-agentic-flow-integration.md +240 -0
- package/implementation/adrs/ADR-041-v3-qe-cli-enhancement.md +296 -0
- package/implementation/adrs/ADR-042-v3-qe-token-tracking-integration.md +517 -0
- package/implementation/adrs/v3-adrs.md +2783 -0
- package/implementation/planning/AQE-V3-MASTER-PLAN.md +815 -0
- package/package.json +88 -0
- package/security-scan-report-2026-01-11.md +410 -0
- package/security-verification-report-2026-01-11.md +278 -0
- package/src/benchmarks/performance-benchmarks.ts +646 -0
- package/src/benchmarks/run-benchmarks.ts +324 -0
- package/src/causal-discovery/causal-graph.ts +450 -0
- package/src/causal-discovery/discovery-engine.ts +438 -0
- package/src/causal-discovery/index.ts +117 -0
- package/src/causal-discovery/types.ts +456 -0
- package/src/causal-discovery/weight-matrix.ts +453 -0
- package/src/cli/commands/qe-tools.ts +634 -0
- package/src/cli/index.ts +1976 -0
- package/src/compatibility/agent-mapper.ts +291 -0
- package/src/compatibility/cli-adapter.ts +277 -0
- package/src/compatibility/config-migrator.ts +334 -0
- package/src/compatibility/index.ts +112 -0
- package/src/compatibility/mcp-adapter.ts +248 -0
- package/src/compatibility/types.ts +156 -0
- package/src/coordination/claims/claim-repository.ts +636 -0
- package/src/coordination/claims/claim-service.ts +675 -0
- package/src/coordination/claims/handoff-manager.ts +535 -0
- package/src/coordination/claims/index.ts +276 -0
- package/src/coordination/claims/interfaces.ts +687 -0
- package/src/coordination/claims/work-stealing.ts +436 -0
- package/src/coordination/cross-domain-router.ts +492 -0
- package/src/coordination/index.ts +127 -0
- package/src/coordination/interfaces.ts +691 -0
- package/src/coordination/protocol-executor.ts +760 -0
- package/src/coordination/protocols/code-intelligence-index.ts +855 -0
- package/src/coordination/protocols/defect-investigation.ts +1184 -0
- package/src/coordination/protocols/index.ts +11 -0
- package/src/coordination/protocols/learning-consolidation.ts +1181 -0
- package/src/coordination/protocols/morning-sync.ts +1055 -0
- package/src/coordination/protocols/quality-gate.ts +1566 -0
- package/src/coordination/protocols/security-audit.ts +1587 -0
- package/src/coordination/queen-coordinator.ts +1176 -0
- package/src/coordination/result-saver.ts +780 -0
- package/src/coordination/task-executor.ts +1146 -0
- package/src/coordination/workflow-orchestrator.ts +1917 -0
- package/src/domains/chaos-resilience/coordinator.ts +1032 -0
- package/src/domains/chaos-resilience/index.ts +143 -0
- package/src/domains/chaos-resilience/interfaces.ts +659 -0
- package/src/domains/chaos-resilience/plugin.ts +691 -0
- package/src/domains/chaos-resilience/services/chaos-engineer.ts +1097 -0
- package/src/domains/chaos-resilience/services/index.ts +19 -0
- package/src/domains/chaos-resilience/services/load-tester.ts +799 -0
- package/src/domains/chaos-resilience/services/performance-profiler.ts +792 -0
- package/src/domains/code-intelligence/coordinator.ts +631 -0
- package/src/domains/code-intelligence/index.ts +86 -0
- package/src/domains/code-intelligence/interfaces.ts +162 -0
- package/src/domains/code-intelligence/plugin.ts +451 -0
- package/src/domains/code-intelligence/services/impact-analyzer.ts +567 -0
- package/src/domains/code-intelligence/services/index.ts +26 -0
- package/src/domains/code-intelligence/services/knowledge-graph.ts +1067 -0
- package/src/domains/code-intelligence/services/semantic-analyzer.ts +901 -0
- package/src/domains/contract-testing/coordinator.ts +1038 -0
- package/src/domains/contract-testing/index.ts +122 -0
- package/src/domains/contract-testing/interfaces.ts +458 -0
- package/src/domains/contract-testing/plugin.ts +746 -0
- package/src/domains/contract-testing/services/api-compatibility.ts +748 -0
- package/src/domains/contract-testing/services/contract-validator.ts +1700 -0
- package/src/domains/contract-testing/services/index.ts +19 -0
- package/src/domains/contract-testing/services/schema-validator.ts +1102 -0
- package/src/domains/coverage-analysis/coordinator.ts +485 -0
- package/src/domains/coverage-analysis/index.ts +114 -0
- package/src/domains/coverage-analysis/interfaces.ts +142 -0
- package/src/domains/coverage-analysis/plugin.ts +172 -0
- package/src/domains/coverage-analysis/services/coverage-analyzer.ts +449 -0
- package/src/domains/coverage-analysis/services/coverage-embedder.ts +733 -0
- package/src/domains/coverage-analysis/services/coverage-parser.ts +753 -0
- package/src/domains/coverage-analysis/services/gap-detector.ts +592 -0
- package/src/domains/coverage-analysis/services/hnsw-index.ts +728 -0
- package/src/domains/coverage-analysis/services/index.ts +61 -0
- package/src/domains/coverage-analysis/services/risk-scorer.ts +540 -0
- package/src/domains/coverage-analysis/services/sublinear-analyzer.ts +747 -0
- package/src/domains/defect-intelligence/coordinator.ts +635 -0
- package/src/domains/defect-intelligence/index.ts +83 -0
- package/src/domains/defect-intelligence/interfaces.ts +152 -0
- package/src/domains/defect-intelligence/plugin.ts +483 -0
- package/src/domains/defect-intelligence/services/causal-root-cause-analyzer.ts +494 -0
- package/src/domains/defect-intelligence/services/defect-predictor.ts +852 -0
- package/src/domains/defect-intelligence/services/index.ts +37 -0
- package/src/domains/defect-intelligence/services/pattern-learner.ts +738 -0
- package/src/domains/defect-intelligence/services/root-cause-analyzer.ts +637 -0
- package/src/domains/domain-interface.ts +77 -0
- package/src/domains/index.ts +23 -0
- package/src/domains/learning-optimization/coordinator.ts +1215 -0
- package/src/domains/learning-optimization/index.ts +127 -0
- package/src/domains/learning-optimization/interfaces.ts +570 -0
- package/src/domains/learning-optimization/plugin.ts +851 -0
- package/src/domains/learning-optimization/services/index.ts +29 -0
- package/src/domains/learning-optimization/services/learning-coordinator.ts +972 -0
- package/src/domains/learning-optimization/services/metrics-optimizer.ts +915 -0
- package/src/domains/learning-optimization/services/production-intel.ts +971 -0
- package/src/domains/learning-optimization/services/transfer-specialist.ts +723 -0
- package/src/domains/quality-assessment/coherence/gate-controller.ts +549 -0
- package/src/domains/quality-assessment/coherence/index.ts +211 -0
- package/src/domains/quality-assessment/coherence/lambda-calculator.ts +384 -0
- package/src/domains/quality-assessment/coherence/partition-detector.ts +469 -0
- package/src/domains/quality-assessment/coherence/types.ts +384 -0
- package/src/domains/quality-assessment/coordinator.ts +605 -0
- package/src/domains/quality-assessment/index.ts +97 -0
- package/src/domains/quality-assessment/interfaces.ts +152 -0
- package/src/domains/quality-assessment/plugin.ts +496 -0
- package/src/domains/quality-assessment/services/coherence-gate.ts +358 -0
- package/src/domains/quality-assessment/services/deployment-advisor.ts +571 -0
- package/src/domains/quality-assessment/services/index.ts +34 -0
- package/src/domains/quality-assessment/services/quality-analyzer.ts +670 -0
- package/src/domains/quality-assessment/services/quality-gate.ts +384 -0
- package/src/domains/requirements-validation/coordinator.ts +812 -0
- package/src/domains/requirements-validation/index.ts +92 -0
- package/src/domains/requirements-validation/interfaces.ts +303 -0
- package/src/domains/requirements-validation/plugin.ts +576 -0
- package/src/domains/requirements-validation/services/bdd-scenario-writer.ts +676 -0
- package/src/domains/requirements-validation/services/index.ts +20 -0
- package/src/domains/requirements-validation/services/requirements-validator.ts +559 -0
- package/src/domains/requirements-validation/services/testability-scorer.ts +639 -0
- package/src/domains/security-compliance/coordinator.ts +757 -0
- package/src/domains/security-compliance/index.ts +120 -0
- package/src/domains/security-compliance/interfaces.ts +434 -0
- package/src/domains/security-compliance/plugin.ts +509 -0
- package/src/domains/security-compliance/services/compliance-validator.ts +1226 -0
- package/src/domains/security-compliance/services/index.ts +31 -0
- package/src/domains/security-compliance/services/security-auditor.ts +2227 -0
- package/src/domains/security-compliance/services/security-scanner.ts +2354 -0
- package/src/domains/security-compliance/services/semgrep-integration.ts +289 -0
- package/src/domains/test-execution/coordinator.ts +426 -0
- package/src/domains/test-execution/index.ts +76 -0
- package/src/domains/test-execution/interfaces.ts +119 -0
- package/src/domains/test-execution/plugin.ts +208 -0
- package/src/domains/test-execution/services/flaky-detector.ts +1240 -0
- package/src/domains/test-execution/services/index.ts +8 -0
- package/src/domains/test-execution/services/retry-handler.ts +820 -0
- package/src/domains/test-execution/services/test-executor.ts +885 -0
- package/src/domains/test-generation/coordinator.ts +656 -0
- package/src/domains/test-generation/index.ts +77 -0
- package/src/domains/test-generation/interfaces.ts +118 -0
- package/src/domains/test-generation/plugin.ts +397 -0
- package/src/domains/test-generation/services/index.ts +23 -0
- package/src/domains/test-generation/services/pattern-matcher.ts +1725 -0
- package/src/domains/test-generation/services/test-generator.ts +2750 -0
- package/src/domains/visual-accessibility/coordinator.ts +860 -0
- package/src/domains/visual-accessibility/index.ts +116 -0
- package/src/domains/visual-accessibility/interfaces.ts +435 -0
- package/src/domains/visual-accessibility/plugin.ts +568 -0
- package/src/domains/visual-accessibility/services/accessibility-tester.ts +982 -0
- package/src/domains/visual-accessibility/services/axe-core-audit.ts +630 -0
- package/src/domains/visual-accessibility/services/index.ts +28 -0
- package/src/domains/visual-accessibility/services/responsive-tester.ts +934 -0
- package/src/domains/visual-accessibility/services/visual-tester.ts +458 -0
- package/src/early-exit/early-exit-controller.ts +490 -0
- package/src/early-exit/early-exit-decision.ts +391 -0
- package/src/early-exit/index.ts +115 -0
- package/src/early-exit/quality-signal.ts +389 -0
- package/src/early-exit/speculative-executor.ts +505 -0
- package/src/early-exit/types.ts +407 -0
- package/src/feedback/coverage-learner.ts +456 -0
- package/src/feedback/feedback-loop.ts +426 -0
- package/src/feedback/index.ts +72 -0
- package/src/feedback/pattern-promotion.ts +373 -0
- package/src/feedback/quality-score-calculator.ts +334 -0
- package/src/feedback/test-outcome-tracker.ts +450 -0
- package/src/feedback/types.ts +497 -0
- package/src/index.ts +224 -0
- package/src/init/agents-installer.ts +536 -0
- package/src/init/index.ts +80 -0
- package/src/init/init-wizard.ts +1061 -0
- package/src/init/project-analyzer.ts +696 -0
- package/src/init/self-configurator.ts +488 -0
- package/src/init/skills-installer.ts +467 -0
- package/src/init/types.ts +432 -0
- package/src/integrations/ruvector/ast-complexity.ts +470 -0
- package/src/integrations/ruvector/coverage-router.ts +594 -0
- package/src/integrations/ruvector/diff-risk-classifier.ts +759 -0
- package/src/integrations/ruvector/fallback.ts +942 -0
- package/src/integrations/ruvector/graph-boundaries.ts +809 -0
- package/src/integrations/ruvector/index.ts +363 -0
- package/src/integrations/ruvector/interfaces.ts +609 -0
- package/src/integrations/ruvector/q-learning-router.ts +550 -0
- package/src/kernel/agent-coordinator.ts +165 -0
- package/src/kernel/agentdb-backend.ts +504 -0
- package/src/kernel/event-bus.ts +129 -0
- package/src/kernel/hybrid-backend.ts +538 -0
- package/src/kernel/index.ts +28 -0
- package/src/kernel/interfaces.ts +257 -0
- package/src/kernel/kernel.ts +285 -0
- package/src/kernel/memory-backend.ts +169 -0
- package/src/kernel/memory-factory.ts +293 -0
- package/src/kernel/plugin-loader.ts +179 -0
- package/src/learning/index.ts +219 -0
- package/src/learning/pattern-store.ts +990 -0
- package/src/learning/qe-guidance.ts +832 -0
- package/src/learning/qe-hooks.ts +644 -0
- package/src/learning/qe-patterns.ts +449 -0
- package/src/learning/qe-reasoning-bank.ts +951 -0
- package/src/learning/real-embeddings.ts +277 -0
- package/src/learning/real-qe-reasoning-bank.ts +833 -0
- package/src/learning/sqlite-persistence.ts +554 -0
- package/src/mcp/entry.ts +59 -0
- package/src/mcp/handlers/agent-handlers.ts +285 -0
- package/src/mcp/handlers/core-handlers.ts +317 -0
- package/src/mcp/handlers/domain-handlers.ts +1444 -0
- package/src/mcp/handlers/index.ts +57 -0
- package/src/mcp/handlers/memory-handlers.ts +338 -0
- package/src/mcp/handlers/task-handlers.ts +363 -0
- package/src/mcp/index.ts +30 -0
- package/src/mcp/metrics/index.ts +14 -0
- package/src/mcp/metrics/metrics-collector.ts +503 -0
- package/src/mcp/protocol-server.ts +752 -0
- package/src/mcp/security/cve-prevention.ts +742 -0
- package/src/mcp/security/index.ts +356 -0
- package/src/mcp/security/oauth21-provider.ts +821 -0
- package/src/mcp/security/rate-limiter.ts +615 -0
- package/src/mcp/security/sampling-server.ts +662 -0
- package/src/mcp/security/schema-validator.ts +855 -0
- package/src/mcp/server.ts +657 -0
- package/src/mcp/tool-registry.ts +391 -0
- package/src/mcp/tools/base.ts +399 -0
- package/src/mcp/tools/chaos-resilience/inject.ts +699 -0
- package/src/mcp/tools/code-intelligence/analyze.ts +745 -0
- package/src/mcp/tools/contract-testing/validate.ts +708 -0
- package/src/mcp/tools/coverage-analysis/index.ts +770 -0
- package/src/mcp/tools/defect-intelligence/predict.ts +466 -0
- package/src/mcp/tools/index.ts +214 -0
- package/src/mcp/tools/learning-optimization/optimize.ts +772 -0
- package/src/mcp/tools/quality-assessment/evaluate.ts +385 -0
- package/src/mcp/tools/registry.ts +248 -0
- package/src/mcp/tools/requirements-validation/validate.ts +394 -0
- package/src/mcp/tools/security-compliance/scan.ts +365 -0
- package/src/mcp/tools/test-execution/execute.ts +291 -0
- package/src/mcp/tools/test-generation/generate.ts +544 -0
- package/src/mcp/tools/visual-accessibility/index.ts +791 -0
- package/src/mcp/transport/index.ts +31 -0
- package/src/mcp/transport/stdio.ts +318 -0
- package/src/mcp/types.ts +543 -0
- package/src/neural-optimizer/index.ts +111 -0
- package/src/neural-optimizer/replay-buffer.ts +455 -0
- package/src/neural-optimizer/swarm-topology.ts +508 -0
- package/src/neural-optimizer/topology-optimizer.ts +828 -0
- package/src/neural-optimizer/types.ts +481 -0
- package/src/neural-optimizer/value-network.ts +351 -0
- package/src/optimization/auto-tuner.ts +817 -0
- package/src/optimization/index.ts +77 -0
- package/src/optimization/metric-collectors.ts +474 -0
- package/src/optimization/qe-workers.ts +704 -0
- package/src/optimization/tuning-algorithm.ts +401 -0
- package/src/optimization/types.ts +314 -0
- package/src/routing/index.ts +51 -0
- package/src/routing/qe-agent-registry.ts +963 -0
- package/src/routing/qe-task-router.ts +564 -0
- package/src/routing/routing-feedback.ts +365 -0
- package/src/routing/types.ts +406 -0
- package/src/shared/embeddings/embedding-cache.ts +157 -0
- package/src/shared/embeddings/index.ts +50 -0
- package/src/shared/embeddings/nomic-embedder.ts +404 -0
- package/src/shared/embeddings/ollama-client.ts +195 -0
- package/src/shared/embeddings/types.ts +147 -0
- package/src/shared/entities/agent.ts +141 -0
- package/src/shared/entities/base-entity.ts +79 -0
- package/src/shared/entities/index.ts +6 -0
- package/src/shared/events/domain-events.ts +259 -0
- package/src/shared/events/index.ts +5 -0
- package/src/shared/git/git-analyzer.ts +656 -0
- package/src/shared/git/index.ts +11 -0
- package/src/shared/http/http-client.ts +420 -0
- package/src/shared/http/index.ts +13 -0
- package/src/shared/index.ts +41 -0
- package/src/shared/io/file-reader.ts +525 -0
- package/src/shared/io/index.ts +25 -0
- package/src/shared/llm/cache.ts +473 -0
- package/src/shared/llm/circuit-breaker.ts +369 -0
- package/src/shared/llm/cost-tracker.ts +460 -0
- package/src/shared/llm/index.ts +140 -0
- package/src/shared/llm/interfaces.ts +629 -0
- package/src/shared/llm/provider-manager.ts +685 -0
- package/src/shared/llm/providers/claude.ts +524 -0
- package/src/shared/llm/providers/index.ts +8 -0
- package/src/shared/llm/providers/ollama.ts +575 -0
- package/src/shared/llm/providers/openai.ts +609 -0
- package/src/shared/metrics/code-metrics.ts +520 -0
- package/src/shared/metrics/index.ts +23 -0
- package/src/shared/metrics/system-metrics.ts +353 -0
- package/src/shared/parsers/index.ts +6 -0
- package/src/shared/parsers/typescript-parser.ts +841 -0
- package/src/shared/security/compliance-patterns.ts +666 -0
- package/src/shared/security/index.ts +30 -0
- package/src/shared/security/osv-client.ts +468 -0
- package/src/shared/types/index.ts +150 -0
- package/src/shared/value-objects/index.ts +273 -0
- package/src/strange-loop/healing-controller.ts +833 -0
- package/src/strange-loop/index.ts +104 -0
- package/src/strange-loop/self-model.ts +494 -0
- package/src/strange-loop/strange-loop.ts +446 -0
- package/src/strange-loop/swarm-observer.ts +448 -0
- package/src/strange-loop/topology-analyzer.ts +565 -0
- package/src/strange-loop/types.ts +640 -0
- package/src/time-crystal/default-phases.ts +520 -0
- package/src/time-crystal/index.ts +164 -0
- package/src/time-crystal/oscillator.ts +425 -0
- package/src/time-crystal/phase-executor.ts +521 -0
- package/src/time-crystal/scheduler.ts +1025 -0
- package/src/time-crystal/test-runner.ts +787 -0
- package/src/time-crystal/types.ts +421 -0
- package/src/workers/base-worker.ts +304 -0
- package/src/workers/daemon.ts +264 -0
- package/src/workers/index.ts +119 -0
- package/src/workers/interfaces.ts +393 -0
- package/src/workers/worker-manager.ts +424 -0
- package/src/workers/workers/compliance-checker.ts +445 -0
- package/src/workers/workers/coverage-tracker.ts +344 -0
- package/src/workers/workers/defect-predictor.ts +375 -0
- package/src/workers/workers/flaky-detector.ts +390 -0
- package/src/workers/workers/index.ts +17 -0
- package/src/workers/workers/learning-consolidation.ts +442 -0
- package/src/workers/workers/performance-baseline.ts +434 -0
- package/src/workers/workers/quality-gate.ts +419 -0
- package/src/workers/workers/regression-monitor.ts +357 -0
- package/src/workers/workers/security-scan.ts +349 -0
- package/src/workers/workers/test-health.ts +359 -0
- package/tests/integration/code-intelligence/knowledge-graph-real.test.ts +540 -0
- package/tests/integration/coordination/cross-domain-router.test.ts +403 -0
- package/tests/integration/coordination/protocol-executor.test.ts +454 -0
- package/tests/integration/coordination/workflow-orchestrator.test.ts +418 -0
- package/tests/integration/feedback/feedback-loop-integration.test.ts +560 -0
- package/tests/integration/migration/v2-to-v3-migration.test.ts +471 -0
- package/tests/integration/parsers/typescript-parser.test.ts +463 -0
- package/tests/integration/security/vulnerability-detection.test.ts +628 -0
- package/tests/integration/test-execution/coordinator.test.ts +410 -0
- package/tests/integration/test-generation/coordinator.test.ts +361 -0
- package/tests/mocks/index.ts +228 -0
- package/tests/time-crystal/default-phases.test.ts +476 -0
- package/tests/time-crystal/oscillator.test.ts +541 -0
- package/tests/time-crystal/phase-executor.test.ts +653 -0
- package/tests/time-crystal/scheduler.test.ts +626 -0
- package/tests/time-crystal/test-runner.test.ts +594 -0
- package/tests/unit/causal-discovery/causal-graph.test.ts +504 -0
- package/tests/unit/causal-discovery/causal-root-cause-analyzer.test.ts +347 -0
- package/tests/unit/causal-discovery/discovery-engine.test.ts +435 -0
- package/tests/unit/causal-discovery/weight-matrix.test.ts +328 -0
- package/tests/unit/cli/cli.test.ts +341 -0
- package/tests/unit/cli/commands.test.ts +414 -0
- package/tests/unit/cli/init-command.test.ts +274 -0
- package/tests/unit/cli/migrate-command.test.ts +396 -0
- package/tests/unit/coordination/claims/claim-service.test.ts +949 -0
- package/tests/unit/coordination/claims/handoff-manager.test.ts +773 -0
- package/tests/unit/coordination/claims/work-stealing.test.ts +492 -0
- package/tests/unit/coordination/queen-coordinator.test.ts +966 -0
- package/tests/unit/coordination/result-saver.test.ts +653 -0
- package/tests/unit/coordination/task-executor.test.ts +810 -0
- package/tests/unit/domains/chaos-resilience/chaos-engineer.test.ts +484 -0
- package/tests/unit/domains/chaos-resilience/load-tester.test.ts +559 -0
- package/tests/unit/domains/chaos-resilience/performance-profiler.test.ts +490 -0
- package/tests/unit/domains/code-intelligence/impact-analyzer.test.ts +560 -0
- package/tests/unit/domains/code-intelligence/knowledge-graph.test.ts +460 -0
- package/tests/unit/domains/code-intelligence/semantic-analyzer.test.ts +584 -0
- package/tests/unit/domains/contract-testing/api-compatibility.test.ts +483 -0
- package/tests/unit/domains/contract-testing/contract-validator.test.ts +370 -0
- package/tests/unit/domains/contract-testing/schema-validator.test.ts +610 -0
- package/tests/unit/domains/coverage-analysis/coverage-embedder.test.ts +298 -0
- package/tests/unit/domains/coverage-analysis/hnsw-index.test.ts +292 -0
- package/tests/unit/domains/coverage-analysis/sublinear-analyzer.test.ts +506 -0
- package/tests/unit/domains/defect-intelligence/defect-predictor.test.ts +370 -0
- package/tests/unit/domains/defect-intelligence/pattern-learner.test.ts +546 -0
- package/tests/unit/domains/defect-intelligence/root-cause-analyzer.test.ts +534 -0
- package/tests/unit/domains/learning-optimization/learning-coordinator.test.ts +541 -0
- package/tests/unit/domains/learning-optimization/metrics-optimizer.test.ts +552 -0
- package/tests/unit/domains/learning-optimization/production-intel.test.ts +589 -0
- package/tests/unit/domains/learning-optimization/transfer-specialist.test.ts +453 -0
- package/tests/unit/domains/quality-assessment/coherence-gate.test.ts +1006 -0
- package/tests/unit/domains/quality-assessment/deployment-advisor.test.ts +515 -0
- package/tests/unit/domains/quality-assessment/quality-analyzer.test.ts +401 -0
- package/tests/unit/domains/quality-assessment/quality-gate.test.ts +324 -0
- package/tests/unit/domains/requirements-validation/bdd-scenario-writer.test.ts +479 -0
- package/tests/unit/domains/requirements-validation/requirements-validator.test.ts +452 -0
- package/tests/unit/domains/requirements-validation/testability-scorer.test.ts +505 -0
- package/tests/unit/domains/security-compliance/compliance-validator.test.ts +500 -0
- package/tests/unit/domains/security-compliance/security-auditor.test.ts +498 -0
- package/tests/unit/domains/security-compliance/security-scanner.test.ts +412 -0
- package/tests/unit/domains/visual-accessibility/accessibility-tester.test.ts +432 -0
- package/tests/unit/domains/visual-accessibility/responsive-tester.test.ts +506 -0
- package/tests/unit/domains/visual-accessibility/visual-tester.test.ts +412 -0
- package/tests/unit/early-exit/early-exit-controller.test.ts +548 -0
- package/tests/unit/early-exit/early-exit-decision.test.ts +617 -0
- package/tests/unit/early-exit/index.test.ts +254 -0
- package/tests/unit/early-exit/quality-signal.test.ts +589 -0
- package/tests/unit/early-exit/speculative-executor.test.ts +453 -0
- package/tests/unit/feedback/coverage-learner.test.ts +288 -0
- package/tests/unit/feedback/feedback-loop.test.ts +458 -0
- package/tests/unit/feedback/pattern-promotion.test.ts +390 -0
- package/tests/unit/feedback/quality-score-calculator.test.ts +364 -0
- package/tests/unit/feedback/test-outcome-tracker.test.ts +243 -0
- package/tests/unit/init/init-wizard.test.ts +881 -0
- package/tests/unit/init/project-analyzer.test.ts +807 -0
- package/tests/unit/init/self-configurator.test.ts +493 -0
- package/tests/unit/integrations/ruvector/ast-complexity.test.ts +240 -0
- package/tests/unit/integrations/ruvector/coverage-router.test.ts +366 -0
- package/tests/unit/integrations/ruvector/diff-risk-classifier.test.ts +340 -0
- package/tests/unit/integrations/ruvector/graph-boundaries.test.ts +355 -0
- package/tests/unit/integrations/ruvector/q-learning-router.test.ts +314 -0
- package/tests/unit/kernel/agent-coordinator.test.ts +220 -0
- package/tests/unit/kernel/event-bus.test.ts +197 -0
- package/tests/unit/learning/qe-reasoning-bank.test.ts +666 -0
- package/tests/unit/learning/real-qe-reasoning-bank.benchmark.test.ts +415 -0
- package/tests/unit/mcp/mcp-server.test.ts +544 -0
- package/tests/unit/mcp/metrics/metrics-collector.test.ts +340 -0
- package/tests/unit/mcp/security/cve-prevention.test.ts +512 -0
- package/tests/unit/mcp/security/oauth21-provider.test.ts +624 -0
- package/tests/unit/mcp/security/rate-limiter.test.ts +410 -0
- package/tests/unit/mcp/security/sampling-server.test.ts +420 -0
- package/tests/unit/mcp/security/schema-validator.test.ts +494 -0
- package/tests/unit/mcp/tools/base.test.ts +336 -0
- package/tests/unit/mcp/tools/domain-tools.test.ts +759 -0
- package/tests/unit/mcp/tools/registry.test.ts +240 -0
- package/tests/unit/neural-optimizer/replay-buffer.test.ts +403 -0
- package/tests/unit/neural-optimizer/swarm-topology.test.ts +473 -0
- package/tests/unit/neural-optimizer/topology-optimizer.test.ts +595 -0
- package/tests/unit/neural-optimizer/value-network.test.ts +343 -0
- package/tests/unit/optimization/auto-tuner.test.ts +506 -0
- package/tests/unit/optimization/metric-collectors.test.ts +352 -0
- package/tests/unit/optimization/qe-workers.test.ts +407 -0
- package/tests/unit/optimization/tuning-algorithm.test.ts +467 -0
- package/tests/unit/routing/qe-agent-registry.test.ts +229 -0
- package/tests/unit/routing/qe-task-router.test.ts +390 -0
- package/tests/unit/routing/routing-feedback.test.ts +339 -0
- package/tests/unit/shared/embeddings/nomic-embedder.test.ts +419 -0
- package/tests/unit/shared/http/http-client.test.ts +719 -0
- package/tests/unit/shared/io/file-reader.test.ts +511 -0
- package/tests/unit/shared/llm/cache.test.ts +391 -0
- package/tests/unit/shared/llm/circuit-breaker.test.ts +293 -0
- package/tests/unit/shared/llm/cost-tracker.test.ts +431 -0
- package/tests/unit/shared/llm/provider-manager.test.ts +550 -0
- package/tests/unit/shared/llm/providers.test.ts +532 -0
- package/tests/unit/shared/parsers/typescript-parser.test.ts +693 -0
- package/tests/unit/shared/value-objects.test.ts +184 -0
- package/tests/unit/strange-loop/strange-loop.test.ts +1170 -0
- package/tests/unit/workers/base-worker.test.ts +341 -0
- package/tests/unit/workers/daemon.test.ts +291 -0
- package/tests/unit/workers/worker-manager.test.ts +284 -0
- package/tsconfig.json +32 -0
- package/vitest.config.ts +27 -0
|
@@ -0,0 +1,2750 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Test Generation Service
|
|
3
|
+
* Implements ITestGenerationService for AI-powered test generation
|
|
4
|
+
*
|
|
5
|
+
* Uses @faker-js/faker for realistic test data generation
|
|
6
|
+
* Uses TypeScript AST parser for code analysis
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
10
|
+
import * as fs from 'fs';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import * as ts from 'typescript';
|
|
13
|
+
import { faker } from '@faker-js/faker';
|
|
14
|
+
import { Result, ok, err } from '../../../shared/types';
|
|
15
|
+
import { MemoryBackend } from '../../../kernel/interfaces';
|
|
16
|
+
import {
|
|
17
|
+
GenerateTestsRequest,
|
|
18
|
+
GeneratedTests,
|
|
19
|
+
GeneratedTest,
|
|
20
|
+
TDDRequest,
|
|
21
|
+
TDDResult,
|
|
22
|
+
PropertyTestRequest,
|
|
23
|
+
PropertyTests,
|
|
24
|
+
TestDataRequest,
|
|
25
|
+
TestData,
|
|
26
|
+
Pattern,
|
|
27
|
+
} from '../interfaces';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Interface for the test generation service
|
|
31
|
+
*/
|
|
32
|
+
export interface ITestGenerationService {
|
|
33
|
+
generateTests(request: GenerateTestsRequest): Promise<Result<GeneratedTests, Error>>;
|
|
34
|
+
generateForCoverageGap(
|
|
35
|
+
file: string,
|
|
36
|
+
uncoveredLines: number[],
|
|
37
|
+
framework: string
|
|
38
|
+
): Promise<Result<GeneratedTest[], Error>>;
|
|
39
|
+
generateTDDTests(request: TDDRequest): Promise<Result<TDDResult, Error>>;
|
|
40
|
+
generatePropertyTests(request: PropertyTestRequest): Promise<Result<PropertyTests, Error>>;
|
|
41
|
+
generateTestData(request: TestDataRequest): Promise<Result<TestData, Error>>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Configuration for the test generator
|
|
46
|
+
*/
|
|
47
|
+
export interface TestGeneratorConfig {
|
|
48
|
+
defaultFramework: 'jest' | 'vitest' | 'mocha' | 'pytest';
|
|
49
|
+
maxTestsPerFile: number;
|
|
50
|
+
coverageTargetDefault: number;
|
|
51
|
+
enableAIGeneration: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const DEFAULT_CONFIG: TestGeneratorConfig = {
|
|
55
|
+
defaultFramework: 'jest',
|
|
56
|
+
maxTestsPerFile: 50,
|
|
57
|
+
coverageTargetDefault: 80,
|
|
58
|
+
enableAIGeneration: true,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Information about a function extracted from AST
|
|
63
|
+
*/
|
|
64
|
+
interface FunctionInfo {
|
|
65
|
+
name: string;
|
|
66
|
+
parameters: ParameterInfo[];
|
|
67
|
+
returnType: string | undefined;
|
|
68
|
+
isAsync: boolean;
|
|
69
|
+
isExported: boolean;
|
|
70
|
+
complexity: number;
|
|
71
|
+
startLine: number;
|
|
72
|
+
endLine: number;
|
|
73
|
+
body?: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Information about a class extracted from AST
|
|
78
|
+
*/
|
|
79
|
+
interface ClassInfo {
|
|
80
|
+
name: string;
|
|
81
|
+
methods: FunctionInfo[];
|
|
82
|
+
properties: PropertyInfo[];
|
|
83
|
+
isExported: boolean;
|
|
84
|
+
hasConstructor: boolean;
|
|
85
|
+
constructorParams?: ParameterInfo[];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Information about a parameter
|
|
90
|
+
*/
|
|
91
|
+
interface ParameterInfo {
|
|
92
|
+
name: string;
|
|
93
|
+
type: string | undefined;
|
|
94
|
+
optional: boolean;
|
|
95
|
+
defaultValue: string | undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Information about a class property
|
|
100
|
+
*/
|
|
101
|
+
interface PropertyInfo {
|
|
102
|
+
name: string;
|
|
103
|
+
type: string | undefined;
|
|
104
|
+
isPrivate: boolean;
|
|
105
|
+
isReadonly: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Test case definition
|
|
110
|
+
*/
|
|
111
|
+
interface TestCase {
|
|
112
|
+
description: string;
|
|
113
|
+
type: 'happy-path' | 'edge-case' | 'error-handling' | 'boundary';
|
|
114
|
+
setup?: string;
|
|
115
|
+
action: string;
|
|
116
|
+
assertion: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Data schema field definition
|
|
121
|
+
*/
|
|
122
|
+
interface SchemaField {
|
|
123
|
+
type: string;
|
|
124
|
+
faker?: string;
|
|
125
|
+
min?: number;
|
|
126
|
+
max?: number;
|
|
127
|
+
enum?: string[];
|
|
128
|
+
pattern?: string;
|
|
129
|
+
reference?: string;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Test Generation Service Implementation
|
|
134
|
+
* Uses heuristic analysis and AST parsing to generate test cases from source code
|
|
135
|
+
* Supports TDD workflow, property-based testing, and pattern-aware generation
|
|
136
|
+
*/
|
|
137
|
+
export class TestGeneratorService implements ITestGenerationService {
|
|
138
|
+
private readonly config: TestGeneratorConfig;
|
|
139
|
+
|
|
140
|
+
constructor(
|
|
141
|
+
private readonly memory: MemoryBackend,
|
|
142
|
+
config: Partial<TestGeneratorConfig> = {}
|
|
143
|
+
) {
|
|
144
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Generate tests for given source files
|
|
149
|
+
*/
|
|
150
|
+
async generateTests(request: GenerateTestsRequest): Promise<Result<GeneratedTests, Error>> {
|
|
151
|
+
try {
|
|
152
|
+
const {
|
|
153
|
+
sourceFiles,
|
|
154
|
+
testType,
|
|
155
|
+
framework,
|
|
156
|
+
coverageTarget = this.config.coverageTargetDefault,
|
|
157
|
+
patterns = [],
|
|
158
|
+
} = request;
|
|
159
|
+
|
|
160
|
+
if (sourceFiles.length === 0) {
|
|
161
|
+
return err(new Error('No source files provided'));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const tests: GeneratedTest[] = [];
|
|
165
|
+
const patternsUsed: string[] = [];
|
|
166
|
+
|
|
167
|
+
// Process each source file
|
|
168
|
+
for (const sourceFile of sourceFiles) {
|
|
169
|
+
const fileTests = await this.generateTestsForFile(
|
|
170
|
+
sourceFile,
|
|
171
|
+
testType,
|
|
172
|
+
framework,
|
|
173
|
+
patterns
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
if (fileTests.success) {
|
|
177
|
+
tests.push(...fileTests.value.tests);
|
|
178
|
+
patternsUsed.push(...fileTests.value.patternsUsed);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Calculate coverage estimate based on test count and complexity
|
|
183
|
+
const coverageEstimate = this.estimateCoverage(tests, coverageTarget);
|
|
184
|
+
|
|
185
|
+
// Store generation metadata in memory
|
|
186
|
+
await this.storeGenerationMetadata(tests, patternsUsed);
|
|
187
|
+
|
|
188
|
+
return ok({
|
|
189
|
+
tests,
|
|
190
|
+
coverageEstimate,
|
|
191
|
+
patternsUsed: [...new Set(patternsUsed)],
|
|
192
|
+
});
|
|
193
|
+
} catch (error) {
|
|
194
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Generate tests specifically targeting coverage gaps
|
|
200
|
+
*/
|
|
201
|
+
async generateForCoverageGap(
|
|
202
|
+
file: string,
|
|
203
|
+
uncoveredLines: number[],
|
|
204
|
+
framework: string
|
|
205
|
+
): Promise<Result<GeneratedTest[], Error>> {
|
|
206
|
+
try {
|
|
207
|
+
if (uncoveredLines.length === 0) {
|
|
208
|
+
return ok([]);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Analyze uncovered lines and generate targeted tests
|
|
212
|
+
// Groups consecutive lines and generates tests for each block
|
|
213
|
+
const tests: GeneratedTest[] = [];
|
|
214
|
+
|
|
215
|
+
// Group uncovered lines into logical blocks
|
|
216
|
+
const lineGroups = this.groupConsecutiveLines(uncoveredLines);
|
|
217
|
+
|
|
218
|
+
for (const group of lineGroups) {
|
|
219
|
+
const test = await this.generateTestForLines(file, group, framework);
|
|
220
|
+
if (test) {
|
|
221
|
+
tests.push(test);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return ok(tests);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Generate tests following TDD workflow
|
|
233
|
+
*/
|
|
234
|
+
async generateTDDTests(request: TDDRequest): Promise<Result<TDDResult, Error>> {
|
|
235
|
+
try {
|
|
236
|
+
const { feature, behavior, framework, phase } = request;
|
|
237
|
+
|
|
238
|
+
switch (phase) {
|
|
239
|
+
case 'red':
|
|
240
|
+
// Generate failing test first
|
|
241
|
+
return ok(await this.generateRedPhaseTest(feature, behavior, framework));
|
|
242
|
+
|
|
243
|
+
case 'green':
|
|
244
|
+
// Generate minimal implementation to make test pass
|
|
245
|
+
return ok(await this.generateGreenPhaseCode(feature, behavior, framework));
|
|
246
|
+
|
|
247
|
+
case 'refactor':
|
|
248
|
+
// Suggest refactoring improvements
|
|
249
|
+
return ok(await this.generateRefactoringSuggestions(feature, behavior));
|
|
250
|
+
|
|
251
|
+
default:
|
|
252
|
+
return err(new Error(`Unknown TDD phase: ${phase}`));
|
|
253
|
+
}
|
|
254
|
+
} catch (error) {
|
|
255
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Generate property-based tests
|
|
261
|
+
*/
|
|
262
|
+
async generatePropertyTests(
|
|
263
|
+
request: PropertyTestRequest
|
|
264
|
+
): Promise<Result<PropertyTests, Error>> {
|
|
265
|
+
try {
|
|
266
|
+
const { function: funcName, properties, constraints = {} } = request;
|
|
267
|
+
|
|
268
|
+
// Generate property-based tests using fast-check generators
|
|
269
|
+
const tests = properties.map((property) => ({
|
|
270
|
+
property,
|
|
271
|
+
testCode: this.generatePropertyTestCode(funcName, property, constraints),
|
|
272
|
+
generators: this.inferGenerators(property, constraints),
|
|
273
|
+
}));
|
|
274
|
+
|
|
275
|
+
return ok({
|
|
276
|
+
tests,
|
|
277
|
+
arbitraries: this.collectArbitraries(tests),
|
|
278
|
+
});
|
|
279
|
+
} catch (error) {
|
|
280
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Generate test data based on schema
|
|
286
|
+
*/
|
|
287
|
+
async generateTestData(request: TestDataRequest): Promise<Result<TestData, Error>> {
|
|
288
|
+
try {
|
|
289
|
+
const { schema, count, locale = 'en', preserveRelationships = false } = request;
|
|
290
|
+
|
|
291
|
+
// Generate test data using @faker-js/faker with seeded randomness
|
|
292
|
+
const seed = Date.now();
|
|
293
|
+
const records: unknown[] = [];
|
|
294
|
+
|
|
295
|
+
for (let i = 0; i < count; i++) {
|
|
296
|
+
const record = this.generateRecordFromSchema(schema, seed + i, locale);
|
|
297
|
+
records.push(record);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Handle relationships if needed
|
|
301
|
+
if (preserveRelationships) {
|
|
302
|
+
this.linkRelatedRecords(records, schema);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return ok({
|
|
306
|
+
records,
|
|
307
|
+
schema,
|
|
308
|
+
seed,
|
|
309
|
+
});
|
|
310
|
+
} catch (error) {
|
|
311
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// ============================================================================
|
|
316
|
+
// Private Helper Methods
|
|
317
|
+
// ============================================================================
|
|
318
|
+
|
|
319
|
+
private async generateTestsForFile(
|
|
320
|
+
sourceFile: string,
|
|
321
|
+
testType: 'unit' | 'integration' | 'e2e',
|
|
322
|
+
framework: string,
|
|
323
|
+
patterns: string[]
|
|
324
|
+
): Promise<Result<{ tests: GeneratedTest[]; patternsUsed: string[] }, Error>> {
|
|
325
|
+
const testFile = this.getTestFilePath(sourceFile, framework);
|
|
326
|
+
const patternsUsed: string[] = [];
|
|
327
|
+
|
|
328
|
+
// Look for applicable patterns from memory
|
|
329
|
+
const applicablePatterns = await this.findApplicablePatterns(sourceFile, patterns);
|
|
330
|
+
patternsUsed.push(...applicablePatterns.map((p) => p.name));
|
|
331
|
+
|
|
332
|
+
// Try to read and parse the source file for real AST analysis
|
|
333
|
+
let codeAnalysis: { functions: FunctionInfo[]; classes: ClassInfo[] } | null = null;
|
|
334
|
+
try {
|
|
335
|
+
const content = fs.readFileSync(sourceFile, 'utf-8');
|
|
336
|
+
codeAnalysis = this.analyzeSourceCode(content, sourceFile);
|
|
337
|
+
} catch {
|
|
338
|
+
// File doesn't exist or can't be read - use stub generation
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Generate test code based on analysis or fall back to stub
|
|
342
|
+
let testCode: string;
|
|
343
|
+
if (codeAnalysis && (codeAnalysis.functions.length > 0 || codeAnalysis.classes.length > 0)) {
|
|
344
|
+
testCode = this.generateRealTestCode(
|
|
345
|
+
sourceFile,
|
|
346
|
+
testType,
|
|
347
|
+
framework,
|
|
348
|
+
codeAnalysis,
|
|
349
|
+
applicablePatterns
|
|
350
|
+
);
|
|
351
|
+
} else {
|
|
352
|
+
testCode = this.generateStubTestCode(sourceFile, testType, framework, applicablePatterns);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const test: GeneratedTest = {
|
|
356
|
+
id: uuidv4(),
|
|
357
|
+
name: `${this.extractModuleName(sourceFile)} tests`,
|
|
358
|
+
sourceFile,
|
|
359
|
+
testFile,
|
|
360
|
+
testCode,
|
|
361
|
+
type: testType,
|
|
362
|
+
assertions: this.countAssertions(testCode),
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
return ok({ tests: [test], patternsUsed });
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Analyze source code using TypeScript AST
|
|
370
|
+
*/
|
|
371
|
+
private analyzeSourceCode(
|
|
372
|
+
content: string,
|
|
373
|
+
fileName: string
|
|
374
|
+
): { functions: FunctionInfo[]; classes: ClassInfo[] } {
|
|
375
|
+
const sourceFile = ts.createSourceFile(
|
|
376
|
+
path.basename(fileName),
|
|
377
|
+
content,
|
|
378
|
+
ts.ScriptTarget.Latest,
|
|
379
|
+
true,
|
|
380
|
+
ts.ScriptKind.TS
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
const functions: FunctionInfo[] = [];
|
|
384
|
+
const classes: ClassInfo[] = [];
|
|
385
|
+
|
|
386
|
+
const visit = (node: ts.Node): void => {
|
|
387
|
+
// Extract function declarations
|
|
388
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
389
|
+
functions.push(this.extractFunctionInfo(node, sourceFile));
|
|
390
|
+
}
|
|
391
|
+
// Extract arrow functions assigned to variables
|
|
392
|
+
else if (ts.isVariableStatement(node)) {
|
|
393
|
+
for (const declaration of node.declarationList.declarations) {
|
|
394
|
+
if (
|
|
395
|
+
ts.isVariableDeclaration(declaration) &&
|
|
396
|
+
declaration.initializer &&
|
|
397
|
+
(ts.isArrowFunction(declaration.initializer) ||
|
|
398
|
+
ts.isFunctionExpression(declaration.initializer))
|
|
399
|
+
) {
|
|
400
|
+
const name = declaration.name.getText(sourceFile);
|
|
401
|
+
functions.push(
|
|
402
|
+
this.extractArrowFunctionInfo(name, declaration.initializer, sourceFile, node)
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// Extract class declarations
|
|
408
|
+
else if (ts.isClassDeclaration(node) && node.name) {
|
|
409
|
+
classes.push(this.extractClassInfo(node, sourceFile));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
ts.forEachChild(node, visit);
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
ts.forEachChild(sourceFile, visit);
|
|
416
|
+
return { functions, classes };
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Extract function information from AST
|
|
421
|
+
*/
|
|
422
|
+
private extractFunctionInfo(
|
|
423
|
+
node: ts.FunctionDeclaration,
|
|
424
|
+
sourceFile: ts.SourceFile
|
|
425
|
+
): FunctionInfo {
|
|
426
|
+
const name = node.name?.getText(sourceFile) || 'anonymous';
|
|
427
|
+
const parameters = this.extractParameters(node.parameters, sourceFile);
|
|
428
|
+
const returnType = node.type?.getText(sourceFile);
|
|
429
|
+
const isAsync = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false;
|
|
430
|
+
const isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
|
|
431
|
+
|
|
432
|
+
const { line: startLine } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
433
|
+
const { line: endLine } = sourceFile.getLineAndCharacterOfPosition(node.getEnd());
|
|
434
|
+
|
|
435
|
+
return {
|
|
436
|
+
name,
|
|
437
|
+
parameters,
|
|
438
|
+
returnType,
|
|
439
|
+
isAsync,
|
|
440
|
+
isExported,
|
|
441
|
+
complexity: this.calculateComplexity(node),
|
|
442
|
+
startLine: startLine + 1,
|
|
443
|
+
endLine: endLine + 1,
|
|
444
|
+
body: node.body?.getText(sourceFile),
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Extract arrow function information from AST
|
|
450
|
+
*/
|
|
451
|
+
private extractArrowFunctionInfo(
|
|
452
|
+
name: string,
|
|
453
|
+
node: ts.ArrowFunction | ts.FunctionExpression,
|
|
454
|
+
sourceFile: ts.SourceFile,
|
|
455
|
+
parentNode: ts.Node
|
|
456
|
+
): FunctionInfo {
|
|
457
|
+
const parameters = this.extractParameters(node.parameters, sourceFile);
|
|
458
|
+
const returnType = node.type?.getText(sourceFile);
|
|
459
|
+
const isAsync = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false;
|
|
460
|
+
const isExported =
|
|
461
|
+
ts.isVariableStatement(parentNode) &&
|
|
462
|
+
(parentNode.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false);
|
|
463
|
+
|
|
464
|
+
const { line: startLine } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
465
|
+
const { line: endLine } = sourceFile.getLineAndCharacterOfPosition(node.getEnd());
|
|
466
|
+
|
|
467
|
+
return {
|
|
468
|
+
name,
|
|
469
|
+
parameters,
|
|
470
|
+
returnType,
|
|
471
|
+
isAsync,
|
|
472
|
+
isExported,
|
|
473
|
+
complexity: this.calculateComplexity(node),
|
|
474
|
+
startLine: startLine + 1,
|
|
475
|
+
endLine: endLine + 1,
|
|
476
|
+
body: node.body?.getText(sourceFile),
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Extract class information from AST
|
|
482
|
+
*/
|
|
483
|
+
private extractClassInfo(node: ts.ClassDeclaration, sourceFile: ts.SourceFile): ClassInfo {
|
|
484
|
+
const name = node.name?.getText(sourceFile) || 'AnonymousClass';
|
|
485
|
+
const methods: FunctionInfo[] = [];
|
|
486
|
+
const properties: PropertyInfo[] = [];
|
|
487
|
+
let hasConstructor = false;
|
|
488
|
+
let constructorParams: ParameterInfo[] | undefined;
|
|
489
|
+
|
|
490
|
+
const isExported =
|
|
491
|
+
node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
|
|
492
|
+
|
|
493
|
+
for (const member of node.members) {
|
|
494
|
+
if (ts.isMethodDeclaration(member)) {
|
|
495
|
+
const methodName = member.name.getText(sourceFile);
|
|
496
|
+
const parameters = this.extractParameters(member.parameters, sourceFile);
|
|
497
|
+
const returnType = member.type?.getText(sourceFile);
|
|
498
|
+
const isAsync =
|
|
499
|
+
member.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false;
|
|
500
|
+
|
|
501
|
+
const { line: startLine } = sourceFile.getLineAndCharacterOfPosition(
|
|
502
|
+
member.getStart(sourceFile)
|
|
503
|
+
);
|
|
504
|
+
const { line: endLine } = sourceFile.getLineAndCharacterOfPosition(member.getEnd());
|
|
505
|
+
|
|
506
|
+
methods.push({
|
|
507
|
+
name: methodName,
|
|
508
|
+
parameters,
|
|
509
|
+
returnType,
|
|
510
|
+
isAsync,
|
|
511
|
+
isExported: false,
|
|
512
|
+
complexity: this.calculateComplexity(member),
|
|
513
|
+
startLine: startLine + 1,
|
|
514
|
+
endLine: endLine + 1,
|
|
515
|
+
body: member.body?.getText(sourceFile),
|
|
516
|
+
});
|
|
517
|
+
} else if (ts.isConstructorDeclaration(member)) {
|
|
518
|
+
hasConstructor = true;
|
|
519
|
+
constructorParams = this.extractParameters(member.parameters, sourceFile);
|
|
520
|
+
} else if (ts.isPropertyDeclaration(member)) {
|
|
521
|
+
const propName = member.name.getText(sourceFile);
|
|
522
|
+
const propType = member.type?.getText(sourceFile);
|
|
523
|
+
const isPrivate =
|
|
524
|
+
member.modifiers?.some((m) => m.kind === ts.SyntaxKind.PrivateKeyword) ?? false;
|
|
525
|
+
const isReadonly =
|
|
526
|
+
member.modifiers?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ?? false;
|
|
527
|
+
|
|
528
|
+
properties.push({
|
|
529
|
+
name: propName,
|
|
530
|
+
type: propType,
|
|
531
|
+
isPrivate,
|
|
532
|
+
isReadonly,
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
return {
|
|
538
|
+
name,
|
|
539
|
+
methods,
|
|
540
|
+
properties,
|
|
541
|
+
isExported,
|
|
542
|
+
hasConstructor,
|
|
543
|
+
constructorParams,
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Extract parameters from a function
|
|
549
|
+
*/
|
|
550
|
+
private extractParameters(
|
|
551
|
+
params: ts.NodeArray<ts.ParameterDeclaration>,
|
|
552
|
+
sourceFile: ts.SourceFile
|
|
553
|
+
): ParameterInfo[] {
|
|
554
|
+
return params.map((param) => ({
|
|
555
|
+
name: param.name.getText(sourceFile),
|
|
556
|
+
type: param.type?.getText(sourceFile),
|
|
557
|
+
optional: param.questionToken !== undefined,
|
|
558
|
+
defaultValue: param.initializer?.getText(sourceFile),
|
|
559
|
+
}));
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Calculate cyclomatic complexity of a node
|
|
564
|
+
*/
|
|
565
|
+
private calculateComplexity(node: ts.Node): number {
|
|
566
|
+
let complexity = 1;
|
|
567
|
+
|
|
568
|
+
const visit = (n: ts.Node): void => {
|
|
569
|
+
switch (n.kind) {
|
|
570
|
+
case ts.SyntaxKind.IfStatement:
|
|
571
|
+
case ts.SyntaxKind.ForStatement:
|
|
572
|
+
case ts.SyntaxKind.ForInStatement:
|
|
573
|
+
case ts.SyntaxKind.ForOfStatement:
|
|
574
|
+
case ts.SyntaxKind.WhileStatement:
|
|
575
|
+
case ts.SyntaxKind.DoStatement:
|
|
576
|
+
case ts.SyntaxKind.CaseClause:
|
|
577
|
+
case ts.SyntaxKind.CatchClause:
|
|
578
|
+
case ts.SyntaxKind.ConditionalExpression:
|
|
579
|
+
complexity++;
|
|
580
|
+
break;
|
|
581
|
+
case ts.SyntaxKind.BinaryExpression: {
|
|
582
|
+
const binary = n as ts.BinaryExpression;
|
|
583
|
+
if (
|
|
584
|
+
binary.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken ||
|
|
585
|
+
binary.operatorToken.kind === ts.SyntaxKind.BarBarToken
|
|
586
|
+
) {
|
|
587
|
+
complexity++;
|
|
588
|
+
}
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
ts.forEachChild(n, visit);
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
ts.forEachChild(node, visit);
|
|
596
|
+
return complexity;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Generate real test code based on AST analysis
|
|
601
|
+
*/
|
|
602
|
+
private generateRealTestCode(
|
|
603
|
+
sourceFile: string,
|
|
604
|
+
testType: 'unit' | 'integration' | 'e2e',
|
|
605
|
+
framework: string,
|
|
606
|
+
analysis: { functions: FunctionInfo[]; classes: ClassInfo[] },
|
|
607
|
+
patterns: Pattern[]
|
|
608
|
+
): string {
|
|
609
|
+
const moduleName = this.extractModuleName(sourceFile);
|
|
610
|
+
const importPath = this.getImportPath(sourceFile);
|
|
611
|
+
|
|
612
|
+
switch (framework) {
|
|
613
|
+
case 'jest':
|
|
614
|
+
case 'vitest':
|
|
615
|
+
return this.generateRealJestVitestTest(
|
|
616
|
+
moduleName,
|
|
617
|
+
importPath,
|
|
618
|
+
testType,
|
|
619
|
+
analysis,
|
|
620
|
+
patterns,
|
|
621
|
+
framework
|
|
622
|
+
);
|
|
623
|
+
case 'mocha':
|
|
624
|
+
return this.generateRealMochaTest(moduleName, importPath, testType, analysis, patterns);
|
|
625
|
+
case 'pytest':
|
|
626
|
+
return this.generateRealPytestTest(moduleName, importPath, testType, analysis, patterns);
|
|
627
|
+
default:
|
|
628
|
+
return this.generateRealJestVitestTest(
|
|
629
|
+
moduleName,
|
|
630
|
+
importPath,
|
|
631
|
+
testType,
|
|
632
|
+
analysis,
|
|
633
|
+
patterns,
|
|
634
|
+
'vitest'
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Generate real Jest/Vitest test code
|
|
641
|
+
*/
|
|
642
|
+
private generateRealJestVitestTest(
|
|
643
|
+
moduleName: string,
|
|
644
|
+
importPath: string,
|
|
645
|
+
testType: string,
|
|
646
|
+
analysis: { functions: FunctionInfo[]; classes: ClassInfo[] },
|
|
647
|
+
patterns: Pattern[],
|
|
648
|
+
framework: string
|
|
649
|
+
): string {
|
|
650
|
+
const patternComment =
|
|
651
|
+
patterns.length > 0
|
|
652
|
+
? `// Applied patterns: ${patterns.map((p) => p.name).join(', ')}\n`
|
|
653
|
+
: '';
|
|
654
|
+
|
|
655
|
+
// Collect all exports to import
|
|
656
|
+
const exports: string[] = [];
|
|
657
|
+
for (const fn of analysis.functions) {
|
|
658
|
+
if (fn.isExported) exports.push(fn.name);
|
|
659
|
+
}
|
|
660
|
+
for (const cls of analysis.classes) {
|
|
661
|
+
if (cls.isExported) exports.push(cls.name);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
const importStatement =
|
|
665
|
+
exports.length > 0
|
|
666
|
+
? `import { ${exports.join(', ')} } from '${importPath}';`
|
|
667
|
+
: `import * as ${moduleName} from '${importPath}';`;
|
|
668
|
+
|
|
669
|
+
let testCode = `${patternComment}import { describe, it, expect, beforeEach${framework === 'vitest' ? ', vi' : ''} } from '${framework}';
|
|
670
|
+
${importStatement}
|
|
671
|
+
|
|
672
|
+
`;
|
|
673
|
+
|
|
674
|
+
// Generate tests for each function
|
|
675
|
+
for (const fn of analysis.functions) {
|
|
676
|
+
testCode += this.generateFunctionTests(fn, testType);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// Generate tests for each class
|
|
680
|
+
for (const cls of analysis.classes) {
|
|
681
|
+
testCode += this.generateClassTests(cls, testType);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
return testCode;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Generate tests for a function
|
|
689
|
+
*/
|
|
690
|
+
private generateFunctionTests(fn: FunctionInfo, _testType: string): string {
|
|
691
|
+
const testCases = this.generateTestCasesForFunction(fn);
|
|
692
|
+
|
|
693
|
+
let code = `describe('${fn.name}', () => {\n`;
|
|
694
|
+
|
|
695
|
+
for (const testCase of testCases) {
|
|
696
|
+
if (testCase.setup) {
|
|
697
|
+
code += ` ${testCase.setup}\n\n`;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
const asyncPrefix = fn.isAsync ? 'async ' : '';
|
|
701
|
+
code += ` it('${testCase.description}', ${asyncPrefix}() => {\n`;
|
|
702
|
+
code += ` ${testCase.action}\n`;
|
|
703
|
+
code += ` ${testCase.assertion}\n`;
|
|
704
|
+
code += ` });\n\n`;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
code += `});\n\n`;
|
|
708
|
+
return code;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Generate test cases for a function
|
|
713
|
+
*/
|
|
714
|
+
private generateTestCasesForFunction(fn: FunctionInfo): TestCase[] {
|
|
715
|
+
const testCases: TestCase[] = [];
|
|
716
|
+
|
|
717
|
+
// Generate valid input test
|
|
718
|
+
const validParams = fn.parameters.map((p) => this.generateTestValue(p)).join(', ');
|
|
719
|
+
const fnCall = fn.isAsync ? `await ${fn.name}(${validParams})` : `${fn.name}(${validParams})`;
|
|
720
|
+
|
|
721
|
+
testCases.push({
|
|
722
|
+
description: 'should handle valid input correctly',
|
|
723
|
+
type: 'happy-path',
|
|
724
|
+
action: `const result = ${fnCall};`,
|
|
725
|
+
assertion: 'expect(result).toBeDefined();',
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
// Generate tests for each parameter
|
|
729
|
+
for (const param of fn.parameters) {
|
|
730
|
+
if (!param.optional) {
|
|
731
|
+
// Test with undefined
|
|
732
|
+
const paramsWithUndefined = fn.parameters
|
|
733
|
+
.map((p) => (p.name === param.name ? 'undefined' : this.generateTestValue(p)))
|
|
734
|
+
.join(', ');
|
|
735
|
+
|
|
736
|
+
testCases.push({
|
|
737
|
+
description: `should handle undefined ${param.name}`,
|
|
738
|
+
type: 'error-handling',
|
|
739
|
+
action: fn.isAsync
|
|
740
|
+
? `const action = async () => await ${fn.name}(${paramsWithUndefined});`
|
|
741
|
+
: `const action = () => ${fn.name}(${paramsWithUndefined});`,
|
|
742
|
+
assertion: 'expect(action).toThrow();',
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// Type-specific boundary tests
|
|
747
|
+
if (param.type?.includes('string')) {
|
|
748
|
+
const paramsWithEmpty = fn.parameters
|
|
749
|
+
.map((p) => (p.name === param.name ? "''" : this.generateTestValue(p)))
|
|
750
|
+
.join(', ');
|
|
751
|
+
const emptyCall = fn.isAsync
|
|
752
|
+
? `await ${fn.name}(${paramsWithEmpty})`
|
|
753
|
+
: `${fn.name}(${paramsWithEmpty})`;
|
|
754
|
+
|
|
755
|
+
testCases.push({
|
|
756
|
+
description: `should handle empty string for ${param.name}`,
|
|
757
|
+
type: 'boundary',
|
|
758
|
+
action: `const result = ${emptyCall};`,
|
|
759
|
+
assertion: 'expect(result).toBeDefined();',
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
if (param.type?.includes('number')) {
|
|
764
|
+
const paramsWithZero = fn.parameters
|
|
765
|
+
.map((p) => (p.name === param.name ? '0' : this.generateTestValue(p)))
|
|
766
|
+
.join(', ');
|
|
767
|
+
const zeroCall = fn.isAsync
|
|
768
|
+
? `await ${fn.name}(${paramsWithZero})`
|
|
769
|
+
: `${fn.name}(${paramsWithZero})`;
|
|
770
|
+
|
|
771
|
+
testCases.push({
|
|
772
|
+
description: `should handle zero for ${param.name}`,
|
|
773
|
+
type: 'boundary',
|
|
774
|
+
action: `const result = ${zeroCall};`,
|
|
775
|
+
assertion: 'expect(result).toBeDefined();',
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
const paramsWithNegative = fn.parameters
|
|
779
|
+
.map((p) => (p.name === param.name ? '-1' : this.generateTestValue(p)))
|
|
780
|
+
.join(', ');
|
|
781
|
+
const negativeCall = fn.isAsync
|
|
782
|
+
? `await ${fn.name}(${paramsWithNegative})`
|
|
783
|
+
: `${fn.name}(${paramsWithNegative})`;
|
|
784
|
+
|
|
785
|
+
testCases.push({
|
|
786
|
+
description: `should handle negative value for ${param.name}`,
|
|
787
|
+
type: 'edge-case',
|
|
788
|
+
action: `const result = ${negativeCall};`,
|
|
789
|
+
assertion: 'expect(result).toBeDefined();',
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
if (param.type?.includes('[]') || param.type?.includes('Array')) {
|
|
794
|
+
const paramsWithEmpty = fn.parameters
|
|
795
|
+
.map((p) => (p.name === param.name ? '[]' : this.generateTestValue(p)))
|
|
796
|
+
.join(', ');
|
|
797
|
+
const emptyCall = fn.isAsync
|
|
798
|
+
? `await ${fn.name}(${paramsWithEmpty})`
|
|
799
|
+
: `${fn.name}(${paramsWithEmpty})`;
|
|
800
|
+
|
|
801
|
+
testCases.push({
|
|
802
|
+
description: `should handle empty array for ${param.name}`,
|
|
803
|
+
type: 'boundary',
|
|
804
|
+
action: `const result = ${emptyCall};`,
|
|
805
|
+
assertion: 'expect(result).toBeDefined();',
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// Async rejection test
|
|
811
|
+
if (fn.isAsync) {
|
|
812
|
+
testCases.push({
|
|
813
|
+
description: 'should handle async rejection gracefully',
|
|
814
|
+
type: 'error-handling',
|
|
815
|
+
action: `// Mock or setup to cause rejection`,
|
|
816
|
+
assertion: `// await expect(${fn.name}(invalidParams)).rejects.toThrow();`,
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
return testCases;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Generate tests for a class
|
|
825
|
+
*/
|
|
826
|
+
private generateClassTests(cls: ClassInfo, testType: string): string {
|
|
827
|
+
let code = `describe('${cls.name}', () => {\n`;
|
|
828
|
+
code += ` let instance: ${cls.name};\n\n`;
|
|
829
|
+
|
|
830
|
+
// Setup
|
|
831
|
+
if (cls.hasConstructor && cls.constructorParams) {
|
|
832
|
+
const constructorArgs = cls.constructorParams
|
|
833
|
+
.map((p) => this.generateTestValue(p))
|
|
834
|
+
.join(', ');
|
|
835
|
+
code += ` beforeEach(() => {\n`;
|
|
836
|
+
code += ` instance = new ${cls.name}(${constructorArgs});\n`;
|
|
837
|
+
code += ` });\n\n`;
|
|
838
|
+
} else {
|
|
839
|
+
code += ` beforeEach(() => {\n`;
|
|
840
|
+
code += ` instance = new ${cls.name}();\n`;
|
|
841
|
+
code += ` });\n\n`;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// Constructor test
|
|
845
|
+
code += ` it('should instantiate correctly', () => {\n`;
|
|
846
|
+
code += ` expect(instance).toBeInstanceOf(${cls.name});\n`;
|
|
847
|
+
code += ` });\n\n`;
|
|
848
|
+
|
|
849
|
+
// Generate tests for each public method
|
|
850
|
+
for (const method of cls.methods) {
|
|
851
|
+
if (!method.name.startsWith('_') && !method.name.startsWith('#')) {
|
|
852
|
+
code += this.generateMethodTests(method, cls.name, testType);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
code += `});\n\n`;
|
|
857
|
+
return code;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Generate tests for a class method
|
|
862
|
+
*/
|
|
863
|
+
private generateMethodTests(method: FunctionInfo, _className: string, _testType: string): string {
|
|
864
|
+
let code = ` describe('${method.name}', () => {\n`;
|
|
865
|
+
|
|
866
|
+
const validParams = method.parameters.map((p) => this.generateTestValue(p)).join(', ');
|
|
867
|
+
const methodCall = method.isAsync
|
|
868
|
+
? `await instance.${method.name}(${validParams})`
|
|
869
|
+
: `instance.${method.name}(${validParams})`;
|
|
870
|
+
|
|
871
|
+
// Happy path
|
|
872
|
+
const asyncPrefix = method.isAsync ? 'async ' : '';
|
|
873
|
+
code += ` it('should execute successfully', ${asyncPrefix}() => {\n`;
|
|
874
|
+
code += ` const result = ${methodCall};\n`;
|
|
875
|
+
code += ` expect(result).toBeDefined();\n`;
|
|
876
|
+
code += ` });\n`;
|
|
877
|
+
|
|
878
|
+
// Error handling for non-optional params
|
|
879
|
+
for (const param of method.parameters) {
|
|
880
|
+
if (!param.optional) {
|
|
881
|
+
const paramsWithUndefined = method.parameters
|
|
882
|
+
.map((p) => (p.name === param.name ? 'undefined as any' : this.generateTestValue(p)))
|
|
883
|
+
.join(', ');
|
|
884
|
+
|
|
885
|
+
code += `\n it('should handle invalid ${param.name}', () => {\n`;
|
|
886
|
+
code += ` expect(() => instance.${method.name}(${paramsWithUndefined})).toThrow();\n`;
|
|
887
|
+
code += ` });\n`;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
code += ` });\n\n`;
|
|
892
|
+
return code;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* Generate a test value for a parameter
|
|
897
|
+
*/
|
|
898
|
+
private generateTestValue(param: ParameterInfo): string {
|
|
899
|
+
if (param.defaultValue) {
|
|
900
|
+
return param.defaultValue;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
const type = param.type?.toLowerCase() || 'unknown';
|
|
904
|
+
const name = param.name.toLowerCase();
|
|
905
|
+
|
|
906
|
+
// Infer from param name first
|
|
907
|
+
if (name.includes('id')) return `'${faker.string.uuid()}'`;
|
|
908
|
+
if (name.includes('email')) return `'${faker.internet.email()}'`;
|
|
909
|
+
if (name.includes('name')) return `'${faker.person.fullName()}'`;
|
|
910
|
+
if (name.includes('url')) return `'${faker.internet.url()}'`;
|
|
911
|
+
if (name.includes('date')) return `new Date('${faker.date.recent().toISOString()}')`;
|
|
912
|
+
|
|
913
|
+
// Then by type
|
|
914
|
+
if (type.includes('string')) return `'${faker.lorem.word()}'`;
|
|
915
|
+
if (type.includes('number')) return String(faker.number.int({ min: 1, max: 100 }));
|
|
916
|
+
if (type.includes('boolean')) return 'true';
|
|
917
|
+
if (type.includes('[]') || type.includes('array')) return '[]';
|
|
918
|
+
if (type.includes('object') || type.includes('{')) return '{}';
|
|
919
|
+
if (type.includes('function')) return '() => {}';
|
|
920
|
+
if (type.includes('promise')) return 'Promise.resolve()';
|
|
921
|
+
if (type.includes('date')) return 'new Date()';
|
|
922
|
+
|
|
923
|
+
// Default
|
|
924
|
+
return `mock${param.name.charAt(0).toUpperCase() + param.name.slice(1)}`;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* Generate real Mocha test code
|
|
929
|
+
*/
|
|
930
|
+
private generateRealMochaTest(
|
|
931
|
+
moduleName: string,
|
|
932
|
+
importPath: string,
|
|
933
|
+
testType: string,
|
|
934
|
+
analysis: { functions: FunctionInfo[]; classes: ClassInfo[] },
|
|
935
|
+
patterns: Pattern[]
|
|
936
|
+
): string {
|
|
937
|
+
const patternComment =
|
|
938
|
+
patterns.length > 0
|
|
939
|
+
? `// Applied patterns: ${patterns.map((p) => p.name).join(', ')}\n`
|
|
940
|
+
: '';
|
|
941
|
+
|
|
942
|
+
const exports: string[] = [];
|
|
943
|
+
for (const fn of analysis.functions) {
|
|
944
|
+
if (fn.isExported) exports.push(fn.name);
|
|
945
|
+
}
|
|
946
|
+
for (const cls of analysis.classes) {
|
|
947
|
+
if (cls.isExported) exports.push(cls.name);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
const importStatement =
|
|
951
|
+
exports.length > 0
|
|
952
|
+
? `import { ${exports.join(', ')} } from '${importPath}';`
|
|
953
|
+
: `import * as ${moduleName} from '${importPath}';`;
|
|
954
|
+
|
|
955
|
+
let code = `${patternComment}import { expect } from 'chai';
|
|
956
|
+
${importStatement}
|
|
957
|
+
|
|
958
|
+
describe('${moduleName} - ${testType} tests', function() {
|
|
959
|
+
`;
|
|
960
|
+
|
|
961
|
+
for (const fn of analysis.functions) {
|
|
962
|
+
code += this.generateMochaFunctionTests(fn);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
for (const cls of analysis.classes) {
|
|
966
|
+
code += this.generateMochaClassTests(cls);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
code += `});\n`;
|
|
970
|
+
return code;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* Generate Mocha tests for a function
|
|
975
|
+
*/
|
|
976
|
+
private generateMochaFunctionTests(fn: FunctionInfo): string {
|
|
977
|
+
const validParams = fn.parameters.map((p) => this.generateTestValue(p)).join(', ');
|
|
978
|
+
const fnCall = fn.isAsync ? `await ${fn.name}(${validParams})` : `${fn.name}(${validParams})`;
|
|
979
|
+
|
|
980
|
+
let code = ` describe('${fn.name}', function() {\n`;
|
|
981
|
+
code += ` it('should handle valid input', ${fn.isAsync ? 'async ' : ''}function() {\n`;
|
|
982
|
+
code += ` const result = ${fnCall};\n`;
|
|
983
|
+
code += ` expect(result).to.not.be.undefined;\n`;
|
|
984
|
+
code += ` });\n`;
|
|
985
|
+
code += ` });\n\n`;
|
|
986
|
+
|
|
987
|
+
return code;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
/**
|
|
991
|
+
* Generate Mocha tests for a class
|
|
992
|
+
*/
|
|
993
|
+
private generateMochaClassTests(cls: ClassInfo): string {
|
|
994
|
+
const constructorArgs =
|
|
995
|
+
cls.constructorParams?.map((p) => this.generateTestValue(p)).join(', ') || '';
|
|
996
|
+
|
|
997
|
+
let code = ` describe('${cls.name}', function() {\n`;
|
|
998
|
+
code += ` let instance;\n\n`;
|
|
999
|
+
code += ` beforeEach(function() {\n`;
|
|
1000
|
+
code += ` instance = new ${cls.name}(${constructorArgs});\n`;
|
|
1001
|
+
code += ` });\n\n`;
|
|
1002
|
+
code += ` it('should instantiate correctly', function() {\n`;
|
|
1003
|
+
code += ` expect(instance).to.be.instanceOf(${cls.name});\n`;
|
|
1004
|
+
code += ` });\n`;
|
|
1005
|
+
|
|
1006
|
+
for (const method of cls.methods) {
|
|
1007
|
+
if (!method.name.startsWith('_')) {
|
|
1008
|
+
const methodParams = method.parameters.map((p) => this.generateTestValue(p)).join(', ');
|
|
1009
|
+
code += `\n it('${method.name} should work', ${method.isAsync ? 'async ' : ''}function() {\n`;
|
|
1010
|
+
code += ` const result = ${method.isAsync ? 'await ' : ''}instance.${method.name}(${methodParams});\n`;
|
|
1011
|
+
code += ` expect(result).to.not.be.undefined;\n`;
|
|
1012
|
+
code += ` });\n`;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
code += ` });\n\n`;
|
|
1017
|
+
return code;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Generate real Pytest test code
|
|
1022
|
+
*/
|
|
1023
|
+
private generateRealPytestTest(
|
|
1024
|
+
moduleName: string,
|
|
1025
|
+
importPath: string,
|
|
1026
|
+
testType: string,
|
|
1027
|
+
analysis: { functions: FunctionInfo[]; classes: ClassInfo[] },
|
|
1028
|
+
patterns: Pattern[]
|
|
1029
|
+
): string {
|
|
1030
|
+
const patternComment =
|
|
1031
|
+
patterns.length > 0
|
|
1032
|
+
? `# Applied patterns: ${patterns.map((p) => p.name).join(', ')}\n`
|
|
1033
|
+
: '';
|
|
1034
|
+
|
|
1035
|
+
const exports: string[] = [];
|
|
1036
|
+
for (const fn of analysis.functions) {
|
|
1037
|
+
if (fn.isExported) exports.push(fn.name);
|
|
1038
|
+
}
|
|
1039
|
+
for (const cls of analysis.classes) {
|
|
1040
|
+
if (cls.isExported) exports.push(cls.name);
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
const pythonImport = importPath.replace(/\//g, '.').replace(/\.(ts|js)$/, '');
|
|
1044
|
+
const importStatement =
|
|
1045
|
+
exports.length > 0
|
|
1046
|
+
? `from ${pythonImport} import ${exports.join(', ')}`
|
|
1047
|
+
: `import ${pythonImport} as ${moduleName}`;
|
|
1048
|
+
|
|
1049
|
+
let code = `${patternComment}import pytest
|
|
1050
|
+
${importStatement}
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
class Test${moduleName.charAt(0).toUpperCase() + moduleName.slice(1)}:
|
|
1054
|
+
"""${testType} tests for ${moduleName}"""
|
|
1055
|
+
|
|
1056
|
+
`;
|
|
1057
|
+
|
|
1058
|
+
for (const fn of analysis.functions) {
|
|
1059
|
+
code += this.generatePytestFunctionTests(fn);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
for (const cls of analysis.classes) {
|
|
1063
|
+
code += this.generatePytestClassTests(cls);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
return code;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* Generate Pytest tests for a function
|
|
1071
|
+
*/
|
|
1072
|
+
private generatePytestFunctionTests(fn: FunctionInfo): string {
|
|
1073
|
+
const validParams = fn.parameters.map((p) => this.generatePythonTestValue(p)).join(', ');
|
|
1074
|
+
|
|
1075
|
+
let code = ` def test_${fn.name}_valid_input(self):\n`;
|
|
1076
|
+
code += ` """Test ${fn.name} with valid input"""\n`;
|
|
1077
|
+
code += ` result = ${fn.name}(${validParams})\n`;
|
|
1078
|
+
code += ` assert result is not None\n\n`;
|
|
1079
|
+
|
|
1080
|
+
return code;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* Generate Pytest tests for a class
|
|
1085
|
+
*/
|
|
1086
|
+
private generatePytestClassTests(cls: ClassInfo): string {
|
|
1087
|
+
const constructorArgs =
|
|
1088
|
+
cls.constructorParams?.map((p) => this.generatePythonTestValue(p)).join(', ') || '';
|
|
1089
|
+
|
|
1090
|
+
let code = `\nclass Test${cls.name}:\n`;
|
|
1091
|
+
code += ` """Tests for ${cls.name}"""\n\n`;
|
|
1092
|
+
code += ` @pytest.fixture\n`;
|
|
1093
|
+
code += ` def instance(self):\n`;
|
|
1094
|
+
code += ` return ${cls.name}(${constructorArgs})\n\n`;
|
|
1095
|
+
code += ` def test_instantiation(self, instance):\n`;
|
|
1096
|
+
code += ` assert isinstance(instance, ${cls.name})\n\n`;
|
|
1097
|
+
|
|
1098
|
+
for (const method of cls.methods) {
|
|
1099
|
+
if (!method.name.startsWith('_')) {
|
|
1100
|
+
const methodParams = method.parameters.map((p) => this.generatePythonTestValue(p)).join(', ');
|
|
1101
|
+
code += ` def test_${method.name}(self, instance):\n`;
|
|
1102
|
+
code += ` result = instance.${method.name}(${methodParams})\n`;
|
|
1103
|
+
code += ` assert result is not None\n\n`;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
return code;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
/**
|
|
1111
|
+
* Generate a Python test value for a parameter
|
|
1112
|
+
*/
|
|
1113
|
+
private generatePythonTestValue(param: ParameterInfo): string {
|
|
1114
|
+
const type = param.type?.toLowerCase() || 'unknown';
|
|
1115
|
+
const name = param.name.toLowerCase();
|
|
1116
|
+
|
|
1117
|
+
if (name.includes('id')) return `"${faker.string.uuid()}"`;
|
|
1118
|
+
if (name.includes('name')) return `"${faker.person.fullName()}"`;
|
|
1119
|
+
if (name.includes('email')) return `"${faker.internet.email()}"`;
|
|
1120
|
+
|
|
1121
|
+
if (type.includes('str')) return `"${faker.lorem.word()}"`;
|
|
1122
|
+
if (type.includes('int') || type.includes('number')) {
|
|
1123
|
+
return String(faker.number.int({ min: 1, max: 100 }));
|
|
1124
|
+
}
|
|
1125
|
+
if (type.includes('bool')) return 'True';
|
|
1126
|
+
if (type.includes('list') || type.includes('[]')) return '[]';
|
|
1127
|
+
if (type.includes('dict') || type.includes('{}')) return '{}';
|
|
1128
|
+
|
|
1129
|
+
return 'None';
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
private async findApplicablePatterns(
|
|
1133
|
+
sourceFile: string,
|
|
1134
|
+
requestedPatterns: string[]
|
|
1135
|
+
): Promise<Pattern[]> {
|
|
1136
|
+
const patterns: Pattern[] = [];
|
|
1137
|
+
|
|
1138
|
+
// Check memory for stored patterns
|
|
1139
|
+
for (const patternName of requestedPatterns) {
|
|
1140
|
+
const stored = await this.memory.get<Pattern>(`pattern:${patternName}`);
|
|
1141
|
+
if (stored) {
|
|
1142
|
+
patterns.push(stored);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// Also search for patterns by file type
|
|
1147
|
+
const extension = sourceFile.split('.').pop() || '';
|
|
1148
|
+
const searchResults = await this.memory.search(`pattern:*:${extension}`, 5);
|
|
1149
|
+
for (const key of searchResults) {
|
|
1150
|
+
const pattern = await this.memory.get<Pattern>(key);
|
|
1151
|
+
if (pattern && !patterns.some((p) => p.id === pattern.id)) {
|
|
1152
|
+
patterns.push(pattern);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
return patterns;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
private generateStubTestCode(
|
|
1160
|
+
sourceFile: string,
|
|
1161
|
+
testType: 'unit' | 'integration' | 'e2e',
|
|
1162
|
+
framework: string,
|
|
1163
|
+
patterns: Pattern[]
|
|
1164
|
+
): string {
|
|
1165
|
+
const moduleName = this.extractModuleName(sourceFile);
|
|
1166
|
+
const importPath = this.getImportPath(sourceFile);
|
|
1167
|
+
|
|
1168
|
+
// Generate framework-specific test template
|
|
1169
|
+
switch (framework) {
|
|
1170
|
+
case 'jest':
|
|
1171
|
+
case 'vitest':
|
|
1172
|
+
return this.generateJestVitestTest(moduleName, importPath, testType, patterns);
|
|
1173
|
+
case 'mocha':
|
|
1174
|
+
return this.generateMochaTest(moduleName, importPath, testType, patterns);
|
|
1175
|
+
case 'pytest':
|
|
1176
|
+
return this.generatePytestTest(moduleName, importPath, testType, patterns);
|
|
1177
|
+
default:
|
|
1178
|
+
return this.generateJestVitestTest(moduleName, importPath, testType, patterns);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
private generateJestVitestTest(
|
|
1183
|
+
moduleName: string,
|
|
1184
|
+
importPath: string,
|
|
1185
|
+
testType: string,
|
|
1186
|
+
patterns: Pattern[]
|
|
1187
|
+
): string {
|
|
1188
|
+
const patternComment =
|
|
1189
|
+
patterns.length > 0
|
|
1190
|
+
? `// Applied patterns: ${patterns.map((p) => p.name).join(', ')}\n`
|
|
1191
|
+
: '';
|
|
1192
|
+
|
|
1193
|
+
// Generate pattern-aware test implementations
|
|
1194
|
+
const basicOpsTest = this.generateBasicOpsTest(moduleName, patterns);
|
|
1195
|
+
const edgeCaseTest = this.generateEdgeCaseTest(moduleName, patterns);
|
|
1196
|
+
const errorHandlingTest = this.generateErrorHandlingTest(moduleName, patterns);
|
|
1197
|
+
|
|
1198
|
+
return `${patternComment}import { ${moduleName} } from '${importPath}';
|
|
1199
|
+
|
|
1200
|
+
describe('${moduleName}', () => {
|
|
1201
|
+
describe('${testType} tests', () => {
|
|
1202
|
+
it('should be defined', () => {
|
|
1203
|
+
expect(${moduleName}).toBeDefined();
|
|
1204
|
+
});
|
|
1205
|
+
|
|
1206
|
+
${basicOpsTest}
|
|
1207
|
+
${edgeCaseTest}
|
|
1208
|
+
${errorHandlingTest}
|
|
1209
|
+
});
|
|
1210
|
+
});
|
|
1211
|
+
`;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Generate basic operations test based on patterns
|
|
1216
|
+
*/
|
|
1217
|
+
private generateBasicOpsTest(moduleName: string, patterns: Pattern[]): string {
|
|
1218
|
+
// Check for service pattern
|
|
1219
|
+
const isService = patterns.some((p) =>
|
|
1220
|
+
p.name.toLowerCase().includes('service') || p.name.toLowerCase().includes('repository')
|
|
1221
|
+
);
|
|
1222
|
+
|
|
1223
|
+
// Check for factory pattern
|
|
1224
|
+
const isFactory = patterns.some((p) => p.name.toLowerCase().includes('factory'));
|
|
1225
|
+
|
|
1226
|
+
// Check for async patterns
|
|
1227
|
+
const hasAsyncPattern = patterns.some((p) =>
|
|
1228
|
+
p.name.toLowerCase().includes('async') || p.name.toLowerCase().includes('promise')
|
|
1229
|
+
);
|
|
1230
|
+
|
|
1231
|
+
if (isService) {
|
|
1232
|
+
return ` it('should handle basic operations', async () => {
|
|
1233
|
+
// Service pattern: test core functionality
|
|
1234
|
+
const instance = new ${moduleName}();
|
|
1235
|
+
expect(instance).toBeInstanceOf(${moduleName});
|
|
1236
|
+
|
|
1237
|
+
// Verify service is properly initialized
|
|
1238
|
+
const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(instance))
|
|
1239
|
+
.filter(m => m !== 'constructor');
|
|
1240
|
+
expect(methods.length).toBeGreaterThan(0);
|
|
1241
|
+
});`;
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
if (isFactory) {
|
|
1245
|
+
return ` it('should handle basic operations', () => {
|
|
1246
|
+
// Factory pattern: test object creation
|
|
1247
|
+
const result = ${moduleName}.create ? ${moduleName}.create() : new ${moduleName}();
|
|
1248
|
+
expect(result).toBeDefined();
|
|
1249
|
+
expect(typeof result).not.toBe('undefined');
|
|
1250
|
+
});`;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
if (hasAsyncPattern) {
|
|
1254
|
+
return ` it('should handle basic operations', async () => {
|
|
1255
|
+
// Async pattern: test promise resolution
|
|
1256
|
+
const instance = typeof ${moduleName} === 'function'
|
|
1257
|
+
? new ${moduleName}()
|
|
1258
|
+
: ${moduleName};
|
|
1259
|
+
|
|
1260
|
+
// Verify async methods resolve properly
|
|
1261
|
+
if (typeof instance.execute === 'function') {
|
|
1262
|
+
await expect(instance.execute()).resolves.toBeDefined();
|
|
1263
|
+
}
|
|
1264
|
+
});`;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
// Default implementation
|
|
1268
|
+
return ` it('should handle basic operations', () => {
|
|
1269
|
+
// Verify module exports expected interface
|
|
1270
|
+
const moduleType = typeof ${moduleName};
|
|
1271
|
+
expect(['function', 'object']).toContain(moduleType);
|
|
1272
|
+
|
|
1273
|
+
if (moduleType === 'function') {
|
|
1274
|
+
// Class or function: verify instantiation
|
|
1275
|
+
const instance = new ${moduleName}();
|
|
1276
|
+
expect(instance).toBeDefined();
|
|
1277
|
+
} else {
|
|
1278
|
+
// Object module: verify properties exist
|
|
1279
|
+
expect(Object.keys(${moduleName}).length).toBeGreaterThan(0);
|
|
1280
|
+
}
|
|
1281
|
+
});`;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
/**
|
|
1285
|
+
* Generate edge case test based on patterns
|
|
1286
|
+
*/
|
|
1287
|
+
private generateEdgeCaseTest(moduleName: string, patterns: Pattern[]): string {
|
|
1288
|
+
const hasValidation = patterns.some((p) =>
|
|
1289
|
+
p.name.toLowerCase().includes('validation') || p.name.toLowerCase().includes('validator')
|
|
1290
|
+
);
|
|
1291
|
+
|
|
1292
|
+
const hasCollection = patterns.some((p) =>
|
|
1293
|
+
p.name.toLowerCase().includes('collection') || p.name.toLowerCase().includes('list')
|
|
1294
|
+
);
|
|
1295
|
+
|
|
1296
|
+
if (hasValidation) {
|
|
1297
|
+
return ` it('should handle edge cases', () => {
|
|
1298
|
+
// Validation pattern: test boundary conditions
|
|
1299
|
+
const instance = new ${moduleName}();
|
|
1300
|
+
|
|
1301
|
+
// Test with empty values
|
|
1302
|
+
if (typeof instance.validate === 'function') {
|
|
1303
|
+
expect(() => instance.validate('')).toBeDefined();
|
|
1304
|
+
expect(() => instance.validate(null)).toBeDefined();
|
|
1305
|
+
}
|
|
1306
|
+
});`;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
if (hasCollection) {
|
|
1310
|
+
return ` it('should handle edge cases', () => {
|
|
1311
|
+
// Collection pattern: test empty and large datasets
|
|
1312
|
+
const instance = new ${moduleName}();
|
|
1313
|
+
|
|
1314
|
+
// Empty collection should be handled gracefully
|
|
1315
|
+
if (typeof instance.add === 'function') {
|
|
1316
|
+
expect(() => instance.add(undefined)).toBeDefined();
|
|
1317
|
+
}
|
|
1318
|
+
if (typeof instance.get === 'function') {
|
|
1319
|
+
expect(instance.get('nonexistent')).toBeUndefined();
|
|
1320
|
+
}
|
|
1321
|
+
});`;
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
// Default edge case test
|
|
1325
|
+
return ` it('should handle edge cases', () => {
|
|
1326
|
+
// Test null/undefined handling
|
|
1327
|
+
const instance = typeof ${moduleName} === 'function'
|
|
1328
|
+
? new ${moduleName}()
|
|
1329
|
+
: ${moduleName};
|
|
1330
|
+
|
|
1331
|
+
// Module should handle edge case inputs gracefully
|
|
1332
|
+
expect(instance).toBeDefined();
|
|
1333
|
+
expect(() => JSON.stringify(instance)).not.toThrow();
|
|
1334
|
+
});`;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
/**
|
|
1338
|
+
* Generate error handling test based on patterns
|
|
1339
|
+
*/
|
|
1340
|
+
private generateErrorHandlingTest(moduleName: string, patterns: Pattern[]): string {
|
|
1341
|
+
const hasErrorPattern = patterns.some((p) =>
|
|
1342
|
+
p.name.toLowerCase().includes('error') || p.name.toLowerCase().includes('exception')
|
|
1343
|
+
);
|
|
1344
|
+
|
|
1345
|
+
const hasAsyncPattern = patterns.some((p) =>
|
|
1346
|
+
p.name.toLowerCase().includes('async') || p.name.toLowerCase().includes('promise')
|
|
1347
|
+
);
|
|
1348
|
+
|
|
1349
|
+
if (hasAsyncPattern) {
|
|
1350
|
+
return ` it('should handle error conditions', async () => {
|
|
1351
|
+
// Async error handling: verify rejections are caught
|
|
1352
|
+
const instance = typeof ${moduleName} === 'function'
|
|
1353
|
+
? new ${moduleName}()
|
|
1354
|
+
: ${moduleName};
|
|
1355
|
+
|
|
1356
|
+
// Async operations should reject gracefully on invalid input
|
|
1357
|
+
const asyncMethods = Object.getOwnPropertyNames(Object.getPrototypeOf(instance) || {})
|
|
1358
|
+
.filter(m => m !== 'constructor');
|
|
1359
|
+
|
|
1360
|
+
// At minimum, module should be stable
|
|
1361
|
+
expect(instance).toBeDefined();
|
|
1362
|
+
});`;
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
if (hasErrorPattern) {
|
|
1366
|
+
return ` it('should handle error conditions', () => {
|
|
1367
|
+
// Error pattern: verify custom error types
|
|
1368
|
+
try {
|
|
1369
|
+
const instance = new ${moduleName}();
|
|
1370
|
+
// Trigger error condition if possible
|
|
1371
|
+
if (typeof instance.throwError === 'function') {
|
|
1372
|
+
expect(() => instance.throwError()).toThrow();
|
|
1373
|
+
}
|
|
1374
|
+
} catch (error) {
|
|
1375
|
+
expect(error).toBeInstanceOf(Error);
|
|
1376
|
+
}
|
|
1377
|
+
});`;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
// Default error handling test
|
|
1381
|
+
return ` it('should handle error conditions', () => {
|
|
1382
|
+
// Verify error resilience
|
|
1383
|
+
expect(() => {
|
|
1384
|
+
const instance = typeof ${moduleName} === 'function'
|
|
1385
|
+
? new ${moduleName}()
|
|
1386
|
+
: ${moduleName};
|
|
1387
|
+
return instance;
|
|
1388
|
+
}).not.toThrow();
|
|
1389
|
+
|
|
1390
|
+
// Module should not throw on inspection
|
|
1391
|
+
expect(() => Object.keys(${moduleName})).not.toThrow();
|
|
1392
|
+
});`;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
private generateMochaTest(
|
|
1396
|
+
moduleName: string,
|
|
1397
|
+
importPath: string,
|
|
1398
|
+
testType: string,
|
|
1399
|
+
patterns: Pattern[]
|
|
1400
|
+
): string {
|
|
1401
|
+
const patternComment =
|
|
1402
|
+
patterns.length > 0
|
|
1403
|
+
? `// Applied patterns: ${patterns.map((p) => p.name).join(', ')}\n`
|
|
1404
|
+
: '';
|
|
1405
|
+
|
|
1406
|
+
// Determine if async tests needed based on patterns
|
|
1407
|
+
const isAsync = patterns.some((p) =>
|
|
1408
|
+
p.name.toLowerCase().includes('async') || p.name.toLowerCase().includes('promise')
|
|
1409
|
+
);
|
|
1410
|
+
const asyncSetup = isAsync ? 'async ' : '';
|
|
1411
|
+
|
|
1412
|
+
return `${patternComment}import { expect } from 'chai';
|
|
1413
|
+
import { ${moduleName} } from '${importPath}';
|
|
1414
|
+
|
|
1415
|
+
describe('${moduleName}', function() {
|
|
1416
|
+
describe('${testType} tests', function() {
|
|
1417
|
+
it('should be defined', function() {
|
|
1418
|
+
expect(${moduleName}).to.not.be.undefined;
|
|
1419
|
+
});
|
|
1420
|
+
|
|
1421
|
+
it('should handle basic operations', ${asyncSetup}function() {
|
|
1422
|
+
// Verify module exports expected interface
|
|
1423
|
+
const moduleType = typeof ${moduleName};
|
|
1424
|
+
expect(['function', 'object']).to.include(moduleType);
|
|
1425
|
+
|
|
1426
|
+
if (moduleType === 'function') {
|
|
1427
|
+
const instance = new ${moduleName}();
|
|
1428
|
+
expect(instance).to.exist;
|
|
1429
|
+
} else {
|
|
1430
|
+
expect(Object.keys(${moduleName})).to.have.length.greaterThan(0);
|
|
1431
|
+
}
|
|
1432
|
+
});
|
|
1433
|
+
|
|
1434
|
+
it('should handle edge cases', function() {
|
|
1435
|
+
// Verify resilience to edge inputs
|
|
1436
|
+
const instance = typeof ${moduleName} === 'function'
|
|
1437
|
+
? new ${moduleName}()
|
|
1438
|
+
: ${moduleName};
|
|
1439
|
+
expect(instance).to.exist;
|
|
1440
|
+
expect(() => JSON.stringify(instance)).to.not.throw();
|
|
1441
|
+
});
|
|
1442
|
+
|
|
1443
|
+
it('should handle error conditions', function() {
|
|
1444
|
+
// Verify error resilience
|
|
1445
|
+
expect(() => {
|
|
1446
|
+
const instance = typeof ${moduleName} === 'function'
|
|
1447
|
+
? new ${moduleName}()
|
|
1448
|
+
: ${moduleName};
|
|
1449
|
+
return instance;
|
|
1450
|
+
}).to.not.throw();
|
|
1451
|
+
});
|
|
1452
|
+
});
|
|
1453
|
+
});
|
|
1454
|
+
`;
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
private generatePytestTest(
|
|
1458
|
+
moduleName: string,
|
|
1459
|
+
importPath: string,
|
|
1460
|
+
testType: string,
|
|
1461
|
+
patterns: Pattern[]
|
|
1462
|
+
): string {
|
|
1463
|
+
const patternComment =
|
|
1464
|
+
patterns.length > 0
|
|
1465
|
+
? `# Applied patterns: ${patterns.map((p) => p.name).join(', ')}\n`
|
|
1466
|
+
: '';
|
|
1467
|
+
|
|
1468
|
+
// Determine if async tests needed based on patterns
|
|
1469
|
+
const isAsync = patterns.some((p) =>
|
|
1470
|
+
p.name.toLowerCase().includes('async') || p.name.toLowerCase().includes('promise')
|
|
1471
|
+
);
|
|
1472
|
+
const asyncDecorator = isAsync ? '@pytest.mark.asyncio\n ' : '';
|
|
1473
|
+
const asyncDef = isAsync ? 'async def' : 'def';
|
|
1474
|
+
|
|
1475
|
+
return `${patternComment}import pytest
|
|
1476
|
+
from ${importPath} import ${moduleName}
|
|
1477
|
+
|
|
1478
|
+
|
|
1479
|
+
class Test${moduleName}:
|
|
1480
|
+
"""${testType} tests for ${moduleName}"""
|
|
1481
|
+
|
|
1482
|
+
def test_is_defined(self):
|
|
1483
|
+
"""Verify the module is properly exported and defined."""
|
|
1484
|
+
assert ${moduleName} is not None
|
|
1485
|
+
|
|
1486
|
+
${asyncDecorator}${asyncDef} test_basic_operations(self):
|
|
1487
|
+
"""Test core functionality with valid inputs."""
|
|
1488
|
+
# Verify module can be instantiated or accessed
|
|
1489
|
+
if callable(${moduleName}):
|
|
1490
|
+
instance = ${moduleName}()
|
|
1491
|
+
assert instance is not None
|
|
1492
|
+
else:
|
|
1493
|
+
assert len(dir(${moduleName})) > 0
|
|
1494
|
+
|
|
1495
|
+
def test_edge_cases(self):
|
|
1496
|
+
"""Test handling of edge case inputs."""
|
|
1497
|
+
# Verify module handles edge cases gracefully
|
|
1498
|
+
instance = ${moduleName}() if callable(${moduleName}) else ${moduleName}
|
|
1499
|
+
assert instance is not None
|
|
1500
|
+
# Module should be serializable
|
|
1501
|
+
import json
|
|
1502
|
+
try:
|
|
1503
|
+
json.dumps(str(instance))
|
|
1504
|
+
except (TypeError, ValueError):
|
|
1505
|
+
pass # Complex objects may not serialize, but shouldn't crash
|
|
1506
|
+
|
|
1507
|
+
def test_error_conditions(self):
|
|
1508
|
+
"""Test error handling and recovery."""
|
|
1509
|
+
# Module instantiation should not raise unexpected errors
|
|
1510
|
+
try:
|
|
1511
|
+
instance = ${moduleName}() if callable(${moduleName}) else ${moduleName}
|
|
1512
|
+
assert instance is not None
|
|
1513
|
+
except TypeError:
|
|
1514
|
+
# Expected if constructor requires arguments
|
|
1515
|
+
pass
|
|
1516
|
+
`;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
private async generateRedPhaseTest(
|
|
1520
|
+
feature: string,
|
|
1521
|
+
behavior: string,
|
|
1522
|
+
_framework: string
|
|
1523
|
+
): Promise<TDDResult> {
|
|
1524
|
+
// Generate TDD RED phase: failing test that defines expected behavior
|
|
1525
|
+
const funcName = this.camelCase(feature);
|
|
1526
|
+
const assertions = this.generateAssertionsFromBehavior(behavior, funcName);
|
|
1527
|
+
|
|
1528
|
+
const testCode = `describe('${feature}', () => {
|
|
1529
|
+
it('${behavior}', () => {
|
|
1530
|
+
// Red phase: This test should fail initially
|
|
1531
|
+
${assertions}
|
|
1532
|
+
});
|
|
1533
|
+
});`;
|
|
1534
|
+
|
|
1535
|
+
return {
|
|
1536
|
+
phase: 'red',
|
|
1537
|
+
testCode,
|
|
1538
|
+
nextStep: 'Write the minimal implementation to make this test pass',
|
|
1539
|
+
};
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
/**
|
|
1543
|
+
* Generate specific assertions from behavior description
|
|
1544
|
+
* Uses NLP-style extraction to infer test values and assertions
|
|
1545
|
+
*/
|
|
1546
|
+
private generateAssertionsFromBehavior(behavior: string, funcName: string): string {
|
|
1547
|
+
const behaviorLower = behavior.toLowerCase();
|
|
1548
|
+
const assertions: string[] = [];
|
|
1549
|
+
|
|
1550
|
+
// Extract context from behavior description
|
|
1551
|
+
const context = this.extractBehaviorContext(behavior);
|
|
1552
|
+
|
|
1553
|
+
// Build function call with appropriate arguments
|
|
1554
|
+
const funcCall = this.buildFunctionCall(funcName, context, behaviorLower);
|
|
1555
|
+
|
|
1556
|
+
// Add setup if needed
|
|
1557
|
+
if (context.setupCode) {
|
|
1558
|
+
assertions.push(context.setupCode);
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
// Generate assertions based on expected outcome
|
|
1562
|
+
if (behaviorLower.includes('return') && behaviorLower.includes('true')) {
|
|
1563
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1564
|
+
assertions.push(` expect(result).toBe(true);`);
|
|
1565
|
+
} else if (behaviorLower.includes('return') && behaviorLower.includes('false')) {
|
|
1566
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1567
|
+
assertions.push(` expect(result).toBe(false);`);
|
|
1568
|
+
} else if (behaviorLower.includes('throw') || behaviorLower.includes('error')) {
|
|
1569
|
+
const errorMsg = context.extractedString || 'Error';
|
|
1570
|
+
assertions.push(` expect(() => ${funcCall}).toThrow(${context.extractedString ? `'${errorMsg}'` : ''});`);
|
|
1571
|
+
} else if (behaviorLower.includes('empty') || behaviorLower.includes('nothing')) {
|
|
1572
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1573
|
+
if (behaviorLower.includes('string')) {
|
|
1574
|
+
assertions.push(` expect(result).toBe('');`);
|
|
1575
|
+
} else if (behaviorLower.includes('object')) {
|
|
1576
|
+
assertions.push(` expect(result).toEqual({});`);
|
|
1577
|
+
} else {
|
|
1578
|
+
assertions.push(` expect(result).toEqual([]);`);
|
|
1579
|
+
}
|
|
1580
|
+
} else if (behaviorLower.includes('null')) {
|
|
1581
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1582
|
+
assertions.push(` expect(result).toBeNull();`);
|
|
1583
|
+
} else if (behaviorLower.includes('undefined')) {
|
|
1584
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1585
|
+
assertions.push(` expect(result).toBeUndefined();`);
|
|
1586
|
+
} else if (behaviorLower.includes('contain') || behaviorLower.includes('include')) {
|
|
1587
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1588
|
+
const expectedValue = context.extractedString || context.extractedNumber?.toString() || 'expectedItem';
|
|
1589
|
+
if (context.extractedString) {
|
|
1590
|
+
assertions.push(` expect(result).toContain('${expectedValue}');`);
|
|
1591
|
+
} else if (context.extractedNumber !== undefined) {
|
|
1592
|
+
assertions.push(` expect(result).toContain(${expectedValue});`);
|
|
1593
|
+
} else {
|
|
1594
|
+
assertions.push(` expect(result).toContain(testInput); // Contains the input`);
|
|
1595
|
+
}
|
|
1596
|
+
} else if (behaviorLower.includes('length') || behaviorLower.includes('count')) {
|
|
1597
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1598
|
+
const expectedLength = context.extractedNumber ?? 3;
|
|
1599
|
+
assertions.push(` expect(result).toHaveLength(${expectedLength});`);
|
|
1600
|
+
} else if (behaviorLower.includes('equal') || behaviorLower.includes('match')) {
|
|
1601
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1602
|
+
if (context.extractedString) {
|
|
1603
|
+
assertions.push(` expect(result).toEqual('${context.extractedString}');`);
|
|
1604
|
+
} else if (context.extractedNumber !== undefined) {
|
|
1605
|
+
assertions.push(` expect(result).toEqual(${context.extractedNumber});`);
|
|
1606
|
+
} else {
|
|
1607
|
+
assertions.push(` expect(result).toEqual(expectedOutput);`);
|
|
1608
|
+
}
|
|
1609
|
+
} else if (behaviorLower.includes('greater') || behaviorLower.includes('more than')) {
|
|
1610
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1611
|
+
const threshold = context.extractedNumber ?? 0;
|
|
1612
|
+
assertions.push(` expect(result).toBeGreaterThan(${threshold});`);
|
|
1613
|
+
} else if (behaviorLower.includes('less') || behaviorLower.includes('fewer')) {
|
|
1614
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1615
|
+
const threshold = context.extractedNumber ?? 100;
|
|
1616
|
+
assertions.push(` expect(result).toBeLessThan(${threshold});`);
|
|
1617
|
+
} else if (behaviorLower.includes('valid') || behaviorLower.includes('success')) {
|
|
1618
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1619
|
+
assertions.push(` expect(result).toBeDefined();`);
|
|
1620
|
+
if (behaviorLower.includes('object') || behaviorLower.includes('response')) {
|
|
1621
|
+
assertions.push(` expect(result.success ?? result.valid ?? result.ok).toBeTruthy();`);
|
|
1622
|
+
} else {
|
|
1623
|
+
assertions.push(` expect(result).toBeTruthy();`);
|
|
1624
|
+
}
|
|
1625
|
+
} else if (behaviorLower.includes('array') || behaviorLower.includes('list')) {
|
|
1626
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1627
|
+
assertions.push(` expect(Array.isArray(result)).toBe(true);`);
|
|
1628
|
+
if (context.extractedNumber !== undefined) {
|
|
1629
|
+
assertions.push(` expect(result.length).toBeGreaterThanOrEqual(${context.extractedNumber});`);
|
|
1630
|
+
}
|
|
1631
|
+
} else if (behaviorLower.includes('object')) {
|
|
1632
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1633
|
+
assertions.push(` expect(typeof result).toBe('object');`);
|
|
1634
|
+
assertions.push(` expect(result).not.toBeNull();`);
|
|
1635
|
+
} else if (behaviorLower.includes('string')) {
|
|
1636
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1637
|
+
assertions.push(` expect(typeof result).toBe('string');`);
|
|
1638
|
+
if (context.extractedString) {
|
|
1639
|
+
assertions.push(` expect(result).toContain('${context.extractedString}');`);
|
|
1640
|
+
}
|
|
1641
|
+
} else if (behaviorLower.includes('number')) {
|
|
1642
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1643
|
+
assertions.push(` expect(typeof result).toBe('number');`);
|
|
1644
|
+
assertions.push(` expect(Number.isNaN(result)).toBe(false);`);
|
|
1645
|
+
} else {
|
|
1646
|
+
// Default: check it's defined
|
|
1647
|
+
assertions.push(` const result = ${funcCall};`);
|
|
1648
|
+
assertions.push(` expect(result).toBeDefined();`);
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
return assertions.join('\n');
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
/**
|
|
1655
|
+
* Extract contextual information from behavior description
|
|
1656
|
+
*/
|
|
1657
|
+
private extractBehaviorContext(behavior: string): {
|
|
1658
|
+
extractedString?: string;
|
|
1659
|
+
extractedNumber?: number;
|
|
1660
|
+
inputType?: string;
|
|
1661
|
+
setupCode?: string;
|
|
1662
|
+
} {
|
|
1663
|
+
const context: {
|
|
1664
|
+
extractedString?: string;
|
|
1665
|
+
extractedNumber?: number;
|
|
1666
|
+
inputType?: string;
|
|
1667
|
+
setupCode?: string;
|
|
1668
|
+
} = {};
|
|
1669
|
+
|
|
1670
|
+
// Extract quoted strings from behavior
|
|
1671
|
+
const stringMatch = behavior.match(/["']([^"']+)["']/);
|
|
1672
|
+
if (stringMatch) {
|
|
1673
|
+
context.extractedString = stringMatch[1];
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
// Extract numbers from behavior
|
|
1677
|
+
const numberMatch = behavior.match(/\b(\d+)\b/);
|
|
1678
|
+
if (numberMatch) {
|
|
1679
|
+
context.extractedNumber = parseInt(numberMatch[1], 10);
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
// Detect input type
|
|
1683
|
+
if (/\b(email|e-mail)\b/i.test(behavior)) {
|
|
1684
|
+
context.inputType = 'email';
|
|
1685
|
+
context.setupCode = ` const testInput = 'test@example.com';`;
|
|
1686
|
+
} else if (/\b(url|link|href)\b/i.test(behavior)) {
|
|
1687
|
+
context.inputType = 'url';
|
|
1688
|
+
context.setupCode = ` const testInput = 'https://example.com';`;
|
|
1689
|
+
} else if (/\b(date|time|timestamp)\b/i.test(behavior)) {
|
|
1690
|
+
context.inputType = 'date';
|
|
1691
|
+
context.setupCode = ` const testInput = new Date('2024-01-15');`;
|
|
1692
|
+
} else if (/\b(id|uuid|identifier)\b/i.test(behavior)) {
|
|
1693
|
+
context.inputType = 'id';
|
|
1694
|
+
context.setupCode = ` const testInput = 'abc-123-def';`;
|
|
1695
|
+
} else if (/\b(user|person|customer)\b/i.test(behavior)) {
|
|
1696
|
+
context.inputType = 'user';
|
|
1697
|
+
context.setupCode = ` const testInput = { id: '1', name: 'Test User', email: 'test@example.com' };`;
|
|
1698
|
+
} else if (/\b(config|options|settings)\b/i.test(behavior)) {
|
|
1699
|
+
context.inputType = 'config';
|
|
1700
|
+
context.setupCode = ` const testInput = { enabled: true, timeout: 5000 };`;
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
return context;
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
/**
|
|
1707
|
+
* Build function call with appropriate arguments based on context
|
|
1708
|
+
*/
|
|
1709
|
+
private buildFunctionCall(
|
|
1710
|
+
funcName: string,
|
|
1711
|
+
context: { inputType?: string; extractedString?: string; extractedNumber?: number },
|
|
1712
|
+
behaviorLower: string
|
|
1713
|
+
): string {
|
|
1714
|
+
// If context has setup code, use testInput variable
|
|
1715
|
+
if (context.inputType) {
|
|
1716
|
+
return `${funcName}(testInput)`;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
// No input needed
|
|
1720
|
+
if (!behaviorLower.includes('with') && !behaviorLower.includes('given') && !behaviorLower.includes('for')) {
|
|
1721
|
+
return `${funcName}()`;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
// Infer input type from behavior
|
|
1725
|
+
if (behaviorLower.includes('string') || behaviorLower.includes('text') || behaviorLower.includes('name')) {
|
|
1726
|
+
const value = context.extractedString || 'test input';
|
|
1727
|
+
return `${funcName}('${value}')`;
|
|
1728
|
+
}
|
|
1729
|
+
if (behaviorLower.includes('number') || behaviorLower.includes('count') || behaviorLower.includes('amount')) {
|
|
1730
|
+
const value = context.extractedNumber ?? 42;
|
|
1731
|
+
return `${funcName}(${value})`;
|
|
1732
|
+
}
|
|
1733
|
+
if (behaviorLower.includes('array') || behaviorLower.includes('list') || behaviorLower.includes('items')) {
|
|
1734
|
+
return `${funcName}([1, 2, 3])`;
|
|
1735
|
+
}
|
|
1736
|
+
if (behaviorLower.includes('object') || behaviorLower.includes('data') || behaviorLower.includes('payload')) {
|
|
1737
|
+
return `${funcName}({ key: 'value' })`;
|
|
1738
|
+
}
|
|
1739
|
+
if (behaviorLower.includes('boolean') || behaviorLower.includes('flag')) {
|
|
1740
|
+
return `${funcName}(true)`;
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
// Default: use extracted value or generic input
|
|
1744
|
+
if (context.extractedString) {
|
|
1745
|
+
return `${funcName}('${context.extractedString}')`;
|
|
1746
|
+
}
|
|
1747
|
+
if (context.extractedNumber !== undefined) {
|
|
1748
|
+
return `${funcName}(${context.extractedNumber})`;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
return `${funcName}(input)`;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
private async generateGreenPhaseCode(
|
|
1755
|
+
feature: string,
|
|
1756
|
+
behavior: string,
|
|
1757
|
+
_framework: string
|
|
1758
|
+
): Promise<TDDResult> {
|
|
1759
|
+
// Generate TDD GREEN phase: minimal implementation to pass the test
|
|
1760
|
+
// Analyze the behavior description to generate appropriate implementation
|
|
1761
|
+
const behaviorLower = behavior.toLowerCase();
|
|
1762
|
+
const funcName = this.camelCase(feature);
|
|
1763
|
+
|
|
1764
|
+
// Infer return type and implementation from behavior
|
|
1765
|
+
const { returnType, implementation, params } = this.inferImplementationFromBehavior(behaviorLower);
|
|
1766
|
+
|
|
1767
|
+
const implementationCode = `/**
|
|
1768
|
+
* ${feature}
|
|
1769
|
+
* Behavior: ${behavior}
|
|
1770
|
+
*/
|
|
1771
|
+
export function ${funcName}(${params}): ${returnType} {
|
|
1772
|
+
${implementation}
|
|
1773
|
+
}`;
|
|
1774
|
+
|
|
1775
|
+
return {
|
|
1776
|
+
phase: 'green',
|
|
1777
|
+
implementationCode,
|
|
1778
|
+
nextStep: 'Refactor the code while keeping tests green',
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
/**
|
|
1783
|
+
* Infer implementation details from behavior description using heuristics
|
|
1784
|
+
* Analyzes the behavior text to determine return type, parameters, and minimal implementation
|
|
1785
|
+
*/
|
|
1786
|
+
private inferImplementationFromBehavior(behavior: string): {
|
|
1787
|
+
returnType: string;
|
|
1788
|
+
implementation: string;
|
|
1789
|
+
params: string;
|
|
1790
|
+
} {
|
|
1791
|
+
// Default values
|
|
1792
|
+
let returnType = 'unknown';
|
|
1793
|
+
let implementation = ' return undefined;';
|
|
1794
|
+
let params = '';
|
|
1795
|
+
|
|
1796
|
+
// Detect return type from behavior description
|
|
1797
|
+
if (behavior.includes('return') || behavior.includes('returns')) {
|
|
1798
|
+
if (behavior.includes('boolean') || behavior.includes('true') || behavior.includes('false') ||
|
|
1799
|
+
behavior.includes('valid') || behavior.includes('is ') || behavior.includes('has ') ||
|
|
1800
|
+
behavior.includes('can ') || behavior.includes('should ')) {
|
|
1801
|
+
returnType = 'boolean';
|
|
1802
|
+
implementation = ' // Validate and return boolean result\n return true;';
|
|
1803
|
+
} else if (behavior.includes('number') || behavior.includes('count') || behavior.includes('sum') ||
|
|
1804
|
+
behavior.includes('total') || behavior.includes('calculate') || behavior.includes('average')) {
|
|
1805
|
+
returnType = 'number';
|
|
1806
|
+
implementation = ' // Perform calculation and return result\n return 0;';
|
|
1807
|
+
} else if (behavior.includes('string') || behavior.includes('text') || behavior.includes('message') ||
|
|
1808
|
+
behavior.includes('name') || behavior.includes('format')) {
|
|
1809
|
+
returnType = 'string';
|
|
1810
|
+
implementation = " // Process and return string result\n return '';";
|
|
1811
|
+
} else if (behavior.includes('array') || behavior.includes('list') || behavior.includes('items') ||
|
|
1812
|
+
behavior.includes('collection') || behavior.includes('filter') || behavior.includes('map')) {
|
|
1813
|
+
returnType = 'unknown[]';
|
|
1814
|
+
implementation = ' // Process and return array\n return [];';
|
|
1815
|
+
} else if (behavior.includes('object') || behavior.includes('data') || behavior.includes('result') ||
|
|
1816
|
+
behavior.includes('response')) {
|
|
1817
|
+
returnType = 'Record<string, unknown>';
|
|
1818
|
+
implementation = ' // Build and return object\n return {};';
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
// Detect if async is needed
|
|
1823
|
+
if (behavior.includes('async') || behavior.includes('await') || behavior.includes('promise') ||
|
|
1824
|
+
behavior.includes('fetch') || behavior.includes('load') || behavior.includes('save') ||
|
|
1825
|
+
behavior.includes('api') || behavior.includes('request')) {
|
|
1826
|
+
returnType = `Promise<${returnType}>`;
|
|
1827
|
+
implementation = implementation.replace('return ', 'return await Promise.resolve(').replace(';', ');');
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
// Detect parameters from behavior
|
|
1831
|
+
const paramPatterns: Array<{ pattern: RegExp; param: string }> = [
|
|
1832
|
+
{ pattern: /(?:with|given|for|using)\s+(?:a\s+)?(?:string|text|name)/i, param: 'input: string' },
|
|
1833
|
+
{ pattern: /(?:with|given|for|using)\s+(?:a\s+)?(?:number|count|amount)/i, param: 'value: number' },
|
|
1834
|
+
{ pattern: /(?:with|given|for|using)\s+(?:an?\s+)?(?:array|list|items)/i, param: 'items: unknown[]' },
|
|
1835
|
+
{ pattern: /(?:with|given|for|using)\s+(?:an?\s+)?(?:object|data)/i, param: 'data: Record<string, unknown>' },
|
|
1836
|
+
{ pattern: /(?:with|given|for|using)\s+(?:an?\s+)?id/i, param: 'id: string' },
|
|
1837
|
+
{ pattern: /(?:with|given|for|using)\s+(?:valid|invalid)\s+input/i, param: 'input: unknown' },
|
|
1838
|
+
{ pattern: /(?:when|if)\s+(?:called\s+)?(?:with|without)/i, param: 'input?: unknown' },
|
|
1839
|
+
];
|
|
1840
|
+
|
|
1841
|
+
const detectedParams: string[] = [];
|
|
1842
|
+
for (const { pattern, param } of paramPatterns) {
|
|
1843
|
+
if (pattern.test(behavior) && !detectedParams.includes(param)) {
|
|
1844
|
+
detectedParams.push(param);
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
params = detectedParams.join(', ');
|
|
1848
|
+
|
|
1849
|
+
// Detect validation logic from behavior
|
|
1850
|
+
if (behavior.includes('validate') || behavior.includes('check') || behavior.includes('verify')) {
|
|
1851
|
+
if (params.includes('input')) {
|
|
1852
|
+
implementation = ` // Validate the input
|
|
1853
|
+
if (input === undefined || input === null) {
|
|
1854
|
+
throw new Error('Invalid input');
|
|
1855
|
+
}
|
|
1856
|
+
${implementation}`;
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
// Detect error throwing from behavior
|
|
1861
|
+
if (behavior.includes('throw') || behavior.includes('error') || behavior.includes('exception') ||
|
|
1862
|
+
behavior.includes('invalid') || behavior.includes('fail')) {
|
|
1863
|
+
if (behavior.includes('when') || behavior.includes('if')) {
|
|
1864
|
+
implementation = ` // Check for error conditions
|
|
1865
|
+
if (!input) {
|
|
1866
|
+
throw new Error('Validation failed');
|
|
1867
|
+
}
|
|
1868
|
+
${implementation}`;
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
return { returnType, implementation, params };
|
|
1873
|
+
}
|
|
1874
|
+
|
|
1875
|
+
private async generateRefactoringSuggestions(
|
|
1876
|
+
_feature: string,
|
|
1877
|
+
_behavior: string
|
|
1878
|
+
): Promise<TDDResult> {
|
|
1879
|
+
return {
|
|
1880
|
+
phase: 'refactor',
|
|
1881
|
+
refactoringChanges: [
|
|
1882
|
+
'Extract common logic into helper functions',
|
|
1883
|
+
'Apply single responsibility principle',
|
|
1884
|
+
'Consider adding type safety improvements',
|
|
1885
|
+
'Review naming conventions',
|
|
1886
|
+
'Optimize performance if needed',
|
|
1887
|
+
],
|
|
1888
|
+
nextStep: 'Apply refactoring changes and ensure all tests still pass',
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
private generatePropertyTestCode(
|
|
1893
|
+
funcName: string,
|
|
1894
|
+
property: string,
|
|
1895
|
+
constraints: Record<string, unknown>
|
|
1896
|
+
): string {
|
|
1897
|
+
// Analyze property description to generate appropriate generators and assertions
|
|
1898
|
+
const propertyLower = property.toLowerCase();
|
|
1899
|
+
const { generators, assertion, setupCode } = this.analyzePropertyForTestGeneration(
|
|
1900
|
+
propertyLower,
|
|
1901
|
+
funcName,
|
|
1902
|
+
constraints
|
|
1903
|
+
);
|
|
1904
|
+
|
|
1905
|
+
return `import * as fc from 'fast-check';
|
|
1906
|
+
|
|
1907
|
+
describe('${funcName} property tests', () => {
|
|
1908
|
+
it('${property}', () => {
|
|
1909
|
+
${setupCode}
|
|
1910
|
+
fc.assert(
|
|
1911
|
+
fc.property(${generators.join(', ')}, (${this.generatePropertyParams(generators)}) => {
|
|
1912
|
+
const result = ${funcName}(${this.generatePropertyArgs(generators)});
|
|
1913
|
+
${assertion}
|
|
1914
|
+
})
|
|
1915
|
+
);
|
|
1916
|
+
});
|
|
1917
|
+
});`;
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
/**
|
|
1921
|
+
* Analyze property description to determine generators and assertions
|
|
1922
|
+
*/
|
|
1923
|
+
private analyzePropertyForTestGeneration(
|
|
1924
|
+
propertyLower: string,
|
|
1925
|
+
funcName: string,
|
|
1926
|
+
constraints: Record<string, unknown>
|
|
1927
|
+
): { generators: string[]; assertion: string; setupCode: string } {
|
|
1928
|
+
const generators: string[] = [];
|
|
1929
|
+
let assertion = 'return result !== undefined;';
|
|
1930
|
+
let setupCode = '';
|
|
1931
|
+
|
|
1932
|
+
// Idempotent property: f(f(x)) === f(x)
|
|
1933
|
+
if (propertyLower.includes('idempotent') || propertyLower.includes('same result')) {
|
|
1934
|
+
generators.push(this.inferGeneratorFromConstraints(constraints, 'input'));
|
|
1935
|
+
assertion = `// Idempotent: applying twice gives same result
|
|
1936
|
+
const firstResult = ${funcName}(input);
|
|
1937
|
+
const secondResult = ${funcName}(firstResult);
|
|
1938
|
+
return JSON.stringify(firstResult) === JSON.stringify(secondResult);`;
|
|
1939
|
+
}
|
|
1940
|
+
// Commutative property: f(a, b) === f(b, a)
|
|
1941
|
+
else if (propertyLower.includes('commutative') || propertyLower.includes('order independent')) {
|
|
1942
|
+
const gen = this.inferGeneratorFromConstraints(constraints, 'value');
|
|
1943
|
+
generators.push(gen, gen);
|
|
1944
|
+
assertion = `// Commutative: order doesn't matter
|
|
1945
|
+
const result1 = ${funcName}(a, b);
|
|
1946
|
+
const result2 = ${funcName}(b, a);
|
|
1947
|
+
return JSON.stringify(result1) === JSON.stringify(result2);`;
|
|
1948
|
+
}
|
|
1949
|
+
// Associative property: f(f(a, b), c) === f(a, f(b, c))
|
|
1950
|
+
else if (propertyLower.includes('associative')) {
|
|
1951
|
+
const gen = this.inferGeneratorFromConstraints(constraints, 'value');
|
|
1952
|
+
generators.push(gen, gen, gen);
|
|
1953
|
+
assertion = `// Associative: grouping doesn't matter
|
|
1954
|
+
const left = ${funcName}(${funcName}(a, b), c);
|
|
1955
|
+
const right = ${funcName}(a, ${funcName}(b, c));
|
|
1956
|
+
return JSON.stringify(left) === JSON.stringify(right);`;
|
|
1957
|
+
}
|
|
1958
|
+
// Identity property: f(x, identity) === x
|
|
1959
|
+
else if (propertyLower.includes('identity') || propertyLower.includes('neutral element')) {
|
|
1960
|
+
generators.push(this.inferGeneratorFromConstraints(constraints, 'input'));
|
|
1961
|
+
const identity = constraints.identity !== undefined ? String(constraints.identity) : '0';
|
|
1962
|
+
setupCode = ` const identity = ${identity};`;
|
|
1963
|
+
assertion = `// Identity: operation with identity returns original
|
|
1964
|
+
const result = ${funcName}(input, identity);
|
|
1965
|
+
return JSON.stringify(result) === JSON.stringify(input);`;
|
|
1966
|
+
}
|
|
1967
|
+
// Inverse property: f(f(x)) === x (e.g., encode/decode)
|
|
1968
|
+
else if (propertyLower.includes('inverse') || propertyLower.includes('reversible') ||
|
|
1969
|
+
propertyLower.includes('round-trip') || propertyLower.includes('encode') ||
|
|
1970
|
+
propertyLower.includes('decode')) {
|
|
1971
|
+
generators.push(this.inferGeneratorFromConstraints(constraints, 'input'));
|
|
1972
|
+
const inverseFn = constraints.inverse as string || `${funcName}Inverse`;
|
|
1973
|
+
assertion = `// Inverse: applying function and its inverse returns original
|
|
1974
|
+
const encoded = ${funcName}(input);
|
|
1975
|
+
const decoded = ${inverseFn}(encoded);
|
|
1976
|
+
return JSON.stringify(decoded) === JSON.stringify(input);`;
|
|
1977
|
+
}
|
|
1978
|
+
// Distributive property: f(a, b + c) === f(a, b) + f(a, c)
|
|
1979
|
+
else if (propertyLower.includes('distributive')) {
|
|
1980
|
+
const gen = this.inferGeneratorFromConstraints(constraints, 'number');
|
|
1981
|
+
generators.push(gen, gen, gen);
|
|
1982
|
+
assertion = `// Distributive: f(a, b + c) === f(a, b) + f(a, c)
|
|
1983
|
+
const left = ${funcName}(a, b + c);
|
|
1984
|
+
const right = ${funcName}(a, b) + ${funcName}(a, c);
|
|
1985
|
+
return Math.abs(left - right) < 0.0001;`;
|
|
1986
|
+
}
|
|
1987
|
+
// Monotonic property: a <= b implies f(a) <= f(b)
|
|
1988
|
+
else if (propertyLower.includes('monotonic') || propertyLower.includes('preserves order') ||
|
|
1989
|
+
propertyLower.includes('non-decreasing') || propertyLower.includes('sorted')) {
|
|
1990
|
+
generators.push('fc.integer()', 'fc.integer()');
|
|
1991
|
+
assertion = `// Monotonic: preserves order
|
|
1992
|
+
const [small, large] = a <= b ? [a, b] : [b, a];
|
|
1993
|
+
const resultSmall = ${funcName}(small);
|
|
1994
|
+
const resultLarge = ${funcName}(large);
|
|
1995
|
+
return resultSmall <= resultLarge;`;
|
|
1996
|
+
}
|
|
1997
|
+
// Bounds/range property: output is within expected bounds
|
|
1998
|
+
else if (propertyLower.includes('bound') || propertyLower.includes('range') ||
|
|
1999
|
+
propertyLower.includes('between') || propertyLower.includes('clamp')) {
|
|
2000
|
+
generators.push(this.inferGeneratorFromConstraints(constraints, 'input'));
|
|
2001
|
+
const min = constraints.min !== undefined ? constraints.min : 0;
|
|
2002
|
+
const max = constraints.max !== undefined ? constraints.max : 100;
|
|
2003
|
+
assertion = `// Bounded: result is within expected range
|
|
2004
|
+
const result = ${funcName}(input);
|
|
2005
|
+
return result >= ${min} && result <= ${max};`;
|
|
2006
|
+
}
|
|
2007
|
+
// Length preservation
|
|
2008
|
+
else if (propertyLower.includes('length') || propertyLower.includes('size')) {
|
|
2009
|
+
generators.push('fc.array(fc.anything())');
|
|
2010
|
+
if (propertyLower.includes('preserve')) {
|
|
2011
|
+
assertion = `// Length preserved: output has same length as input
|
|
2012
|
+
const result = ${funcName}(input);
|
|
2013
|
+
return Array.isArray(result) && result.length === input.length;`;
|
|
2014
|
+
} else {
|
|
2015
|
+
assertion = `// Length invariant
|
|
2016
|
+
const result = ${funcName}(input);
|
|
2017
|
+
return typeof result.length === 'number' || typeof result.size === 'number';`;
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
// Type preservation
|
|
2021
|
+
else if (propertyLower.includes('type') && propertyLower.includes('preserve')) {
|
|
2022
|
+
generators.push('fc.anything()');
|
|
2023
|
+
assertion = `// Type preserved: output has same type as input
|
|
2024
|
+
const result = ${funcName}(input);
|
|
2025
|
+
return typeof result === typeof input;`;
|
|
2026
|
+
}
|
|
2027
|
+
// Non-null/defined output
|
|
2028
|
+
else if (propertyLower.includes('never null') || propertyLower.includes('always defined') ||
|
|
2029
|
+
propertyLower.includes('non-null')) {
|
|
2030
|
+
generators.push(this.inferGeneratorFromConstraints(constraints, 'input'));
|
|
2031
|
+
assertion = `// Never null: always returns defined value
|
|
2032
|
+
const result = ${funcName}(input);
|
|
2033
|
+
return result !== null && result !== undefined;`;
|
|
2034
|
+
}
|
|
2035
|
+
// Deterministic property: same input always produces same output
|
|
2036
|
+
else if (propertyLower.includes('deterministic') || propertyLower.includes('pure') ||
|
|
2037
|
+
propertyLower.includes('consistent')) {
|
|
2038
|
+
generators.push(this.inferGeneratorFromConstraints(constraints, 'input'));
|
|
2039
|
+
assertion = `// Deterministic: same input always gives same output
|
|
2040
|
+
const result1 = ${funcName}(input);
|
|
2041
|
+
const result2 = ${funcName}(input);
|
|
2042
|
+
return JSON.stringify(result1) === JSON.stringify(result2);`;
|
|
2043
|
+
}
|
|
2044
|
+
// Default case: basic existence check with type-appropriate generator
|
|
2045
|
+
else {
|
|
2046
|
+
generators.push(this.inferGeneratorFromConstraints(constraints, 'input'));
|
|
2047
|
+
assertion = `// Basic property: function returns a value
|
|
2048
|
+
return result !== undefined;`;
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
return { generators, assertion, setupCode };
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
/**
|
|
2055
|
+
* Infer the appropriate fast-check generator from constraints
|
|
2056
|
+
*/
|
|
2057
|
+
private inferGeneratorFromConstraints(
|
|
2058
|
+
constraints: Record<string, unknown>,
|
|
2059
|
+
hint: string
|
|
2060
|
+
): string {
|
|
2061
|
+
// Check explicit type constraint
|
|
2062
|
+
const type = (constraints.type as string)?.toLowerCase() || hint.toLowerCase();
|
|
2063
|
+
|
|
2064
|
+
if (type.includes('string') || type.includes('text')) {
|
|
2065
|
+
const minLength = constraints.minLength as number | undefined;
|
|
2066
|
+
const maxLength = constraints.maxLength as number | undefined;
|
|
2067
|
+
if (minLength !== undefined || maxLength !== undefined) {
|
|
2068
|
+
return `fc.string({ minLength: ${minLength ?? 0}, maxLength: ${maxLength ?? 100} })`;
|
|
2069
|
+
}
|
|
2070
|
+
return 'fc.string()';
|
|
2071
|
+
}
|
|
2072
|
+
|
|
2073
|
+
if (type.includes('number') || type.includes('int') || type.includes('value')) {
|
|
2074
|
+
const min = constraints.min as number | undefined;
|
|
2075
|
+
const max = constraints.max as number | undefined;
|
|
2076
|
+
if (min !== undefined || max !== undefined) {
|
|
2077
|
+
return `fc.integer({ min: ${min ?? Number.MIN_SAFE_INTEGER}, max: ${max ?? Number.MAX_SAFE_INTEGER} })`;
|
|
2078
|
+
}
|
|
2079
|
+
return 'fc.integer()';
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
if (type.includes('float') || type.includes('decimal')) {
|
|
2083
|
+
return 'fc.float()';
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
if (type.includes('boolean') || type.includes('bool')) {
|
|
2087
|
+
return 'fc.boolean()';
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
if (type.includes('array') || type.includes('list')) {
|
|
2091
|
+
const itemType = constraints.itemType as string || 'anything';
|
|
2092
|
+
const itemGen = this.getSimpleGenerator(itemType);
|
|
2093
|
+
return `fc.array(${itemGen})`;
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
if (type.includes('object') || type.includes('record')) {
|
|
2097
|
+
return 'fc.object()';
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
if (type.includes('date')) {
|
|
2101
|
+
return 'fc.date()';
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
if (type.includes('uuid') || type.includes('id')) {
|
|
2105
|
+
return 'fc.uuid()';
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
if (type.includes('email')) {
|
|
2109
|
+
return 'fc.emailAddress()';
|
|
2110
|
+
}
|
|
2111
|
+
|
|
2112
|
+
// Default to anything
|
|
2113
|
+
return 'fc.anything()';
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
/**
|
|
2117
|
+
* Get a simple generator for a type name
|
|
2118
|
+
*/
|
|
2119
|
+
private getSimpleGenerator(typeName: string): string {
|
|
2120
|
+
const typeMap: Record<string, string> = {
|
|
2121
|
+
string: 'fc.string()',
|
|
2122
|
+
number: 'fc.integer()',
|
|
2123
|
+
integer: 'fc.integer()',
|
|
2124
|
+
float: 'fc.float()',
|
|
2125
|
+
boolean: 'fc.boolean()',
|
|
2126
|
+
date: 'fc.date()',
|
|
2127
|
+
uuid: 'fc.uuid()',
|
|
2128
|
+
anything: 'fc.anything()',
|
|
2129
|
+
};
|
|
2130
|
+
return typeMap[typeName.toLowerCase()] || 'fc.anything()';
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
/**
|
|
2134
|
+
* Generate parameter names from generator list
|
|
2135
|
+
*/
|
|
2136
|
+
private generatePropertyParams(generators: string[]): string {
|
|
2137
|
+
if (generators.length === 1) {
|
|
2138
|
+
return 'input';
|
|
2139
|
+
}
|
|
2140
|
+
return generators.map((_, i) => String.fromCharCode(97 + i)).join(', '); // a, b, c...
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
/**
|
|
2144
|
+
* Generate argument list for function call
|
|
2145
|
+
*/
|
|
2146
|
+
private generatePropertyArgs(generators: string[]): string {
|
|
2147
|
+
if (generators.length === 1) {
|
|
2148
|
+
return 'input';
|
|
2149
|
+
}
|
|
2150
|
+
return generators.map((_, i) => String.fromCharCode(97 + i)).join(', ');
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
private inferGenerators(
|
|
2154
|
+
property: string,
|
|
2155
|
+
constraints: Record<string, unknown>
|
|
2156
|
+
): string[] {
|
|
2157
|
+
const generators: string[] = [];
|
|
2158
|
+
const propertyLower = property.toLowerCase();
|
|
2159
|
+
|
|
2160
|
+
// Analyze property description to infer appropriate generators
|
|
2161
|
+
// String-related properties
|
|
2162
|
+
if (
|
|
2163
|
+
propertyLower.includes('string') ||
|
|
2164
|
+
propertyLower.includes('text') ||
|
|
2165
|
+
propertyLower.includes('name') ||
|
|
2166
|
+
propertyLower.includes('email')
|
|
2167
|
+
) {
|
|
2168
|
+
if (constraints.minLength || constraints.maxLength) {
|
|
2169
|
+
const min = constraints.minLength ?? 0;
|
|
2170
|
+
const max = constraints.maxLength ?? 100;
|
|
2171
|
+
generators.push(`fc.string({ minLength: ${min}, maxLength: ${max} })`);
|
|
2172
|
+
} else {
|
|
2173
|
+
generators.push('fc.string()');
|
|
2174
|
+
}
|
|
2175
|
+
if (propertyLower.includes('email')) {
|
|
2176
|
+
generators.push('fc.emailAddress()');
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
// Number-related properties
|
|
2181
|
+
if (
|
|
2182
|
+
propertyLower.includes('number') ||
|
|
2183
|
+
propertyLower.includes('count') ||
|
|
2184
|
+
propertyLower.includes('amount') ||
|
|
2185
|
+
propertyLower.includes('integer') ||
|
|
2186
|
+
propertyLower.includes('positive') ||
|
|
2187
|
+
propertyLower.includes('negative')
|
|
2188
|
+
) {
|
|
2189
|
+
if (propertyLower.includes('positive')) {
|
|
2190
|
+
generators.push('fc.nat()');
|
|
2191
|
+
} else if (propertyLower.includes('negative')) {
|
|
2192
|
+
generators.push('fc.integer({ max: -1 })');
|
|
2193
|
+
} else if (constraints.min !== undefined || constraints.max !== undefined) {
|
|
2194
|
+
const min = constraints.min ?? Number.MIN_SAFE_INTEGER;
|
|
2195
|
+
const max = constraints.max ?? Number.MAX_SAFE_INTEGER;
|
|
2196
|
+
generators.push(`fc.integer({ min: ${min}, max: ${max} })`);
|
|
2197
|
+
} else {
|
|
2198
|
+
generators.push('fc.integer()');
|
|
2199
|
+
}
|
|
2200
|
+
if (propertyLower.includes('float') || propertyLower.includes('decimal')) {
|
|
2201
|
+
generators.push('fc.float()');
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
// Boolean properties
|
|
2206
|
+
if (propertyLower.includes('boolean') || propertyLower.includes('flag')) {
|
|
2207
|
+
generators.push('fc.boolean()');
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
// Array-related properties
|
|
2211
|
+
if (
|
|
2212
|
+
propertyLower.includes('array') ||
|
|
2213
|
+
propertyLower.includes('list') ||
|
|
2214
|
+
propertyLower.includes('collection')
|
|
2215
|
+
) {
|
|
2216
|
+
const itemType = constraints.itemType as string || 'anything';
|
|
2217
|
+
const itemGen = this.getGeneratorForType(itemType);
|
|
2218
|
+
if (constraints.minItems || constraints.maxItems) {
|
|
2219
|
+
const min = constraints.minItems ?? 0;
|
|
2220
|
+
const max = constraints.maxItems ?? 10;
|
|
2221
|
+
generators.push(`fc.array(${itemGen}, { minLength: ${min}, maxLength: ${max} })`);
|
|
2222
|
+
} else {
|
|
2223
|
+
generators.push(`fc.array(${itemGen})`);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
// Object-related properties
|
|
2228
|
+
if (propertyLower.includes('object') || propertyLower.includes('record')) {
|
|
2229
|
+
generators.push('fc.object()');
|
|
2230
|
+
generators.push('fc.dictionary(fc.string(), fc.anything())');
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
// Date-related properties
|
|
2234
|
+
if (propertyLower.includes('date') || propertyLower.includes('time')) {
|
|
2235
|
+
generators.push('fc.date()');
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
// UUID properties
|
|
2239
|
+
if (propertyLower.includes('uuid') || propertyLower.includes('id')) {
|
|
2240
|
+
generators.push('fc.uuid()');
|
|
2241
|
+
}
|
|
2242
|
+
|
|
2243
|
+
// Default fallback if no specific type detected
|
|
2244
|
+
if (generators.length === 0) {
|
|
2245
|
+
generators.push('fc.anything()');
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
return generators;
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
private getGeneratorForType(type: string): string {
|
|
2252
|
+
const typeGenerators: Record<string, string> = {
|
|
2253
|
+
string: 'fc.string()',
|
|
2254
|
+
number: 'fc.integer()',
|
|
2255
|
+
integer: 'fc.integer()',
|
|
2256
|
+
float: 'fc.float()',
|
|
2257
|
+
boolean: 'fc.boolean()',
|
|
2258
|
+
date: 'fc.date()',
|
|
2259
|
+
uuid: 'fc.uuid()',
|
|
2260
|
+
anything: 'fc.anything()',
|
|
2261
|
+
};
|
|
2262
|
+
return typeGenerators[type.toLowerCase()] || 'fc.anything()';
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
private collectArbitraries(tests: { generators: string[] }[]): string[] {
|
|
2266
|
+
const arbitraries = new Set<string>();
|
|
2267
|
+
for (const test of tests) {
|
|
2268
|
+
test.generators.forEach((g) => arbitraries.add(g));
|
|
2269
|
+
}
|
|
2270
|
+
return Array.from(arbitraries);
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
private generateRecordFromSchema(
|
|
2274
|
+
schema: Record<string, unknown>,
|
|
2275
|
+
seed: number,
|
|
2276
|
+
locale: string
|
|
2277
|
+
): Record<string, unknown> {
|
|
2278
|
+
// Set faker locale and seed for reproducibility
|
|
2279
|
+
faker.seed(seed);
|
|
2280
|
+
if (locale && locale !== 'en') {
|
|
2281
|
+
// Note: faker v8+ uses different locale handling
|
|
2282
|
+
// For now, we use the default locale
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
const record: Record<string, unknown> = {};
|
|
2286
|
+
|
|
2287
|
+
for (const [key, fieldDef] of Object.entries(schema)) {
|
|
2288
|
+
record[key] = this.generateValueForField(key, fieldDef, seed);
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
return record;
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2294
|
+
private generateValueForField(
|
|
2295
|
+
fieldName: string,
|
|
2296
|
+
fieldDef: unknown,
|
|
2297
|
+
_seed: number
|
|
2298
|
+
): unknown {
|
|
2299
|
+
// Handle simple type strings
|
|
2300
|
+
if (typeof fieldDef === 'string') {
|
|
2301
|
+
return this.generateValueForType(fieldDef, fieldName);
|
|
2302
|
+
}
|
|
2303
|
+
|
|
2304
|
+
// Handle complex field definitions
|
|
2305
|
+
if (typeof fieldDef === 'object' && fieldDef !== null) {
|
|
2306
|
+
const field = fieldDef as SchemaField;
|
|
2307
|
+
|
|
2308
|
+
// Use explicit faker method if specified
|
|
2309
|
+
if (field.faker) {
|
|
2310
|
+
return this.callFakerMethod(field.faker);
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
return this.generateValueForType(field.type, fieldName, field);
|
|
2314
|
+
}
|
|
2315
|
+
|
|
2316
|
+
return null;
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
private generateValueForType(
|
|
2320
|
+
type: string,
|
|
2321
|
+
fieldName: string,
|
|
2322
|
+
options?: SchemaField
|
|
2323
|
+
): unknown {
|
|
2324
|
+
const normalizedType = type.toLowerCase();
|
|
2325
|
+
|
|
2326
|
+
// Try to infer the best faker method based on field name and type
|
|
2327
|
+
switch (normalizedType) {
|
|
2328
|
+
case 'string':
|
|
2329
|
+
return this.generateStringValue(fieldName, options);
|
|
2330
|
+
case 'number':
|
|
2331
|
+
case 'int':
|
|
2332
|
+
case 'integer':
|
|
2333
|
+
return this.generateNumberValue(options);
|
|
2334
|
+
case 'float':
|
|
2335
|
+
case 'decimal':
|
|
2336
|
+
return faker.number.float({ min: options?.min ?? 0, max: options?.max ?? 1000, fractionDigits: 2 });
|
|
2337
|
+
case 'boolean':
|
|
2338
|
+
case 'bool':
|
|
2339
|
+
return faker.datatype.boolean();
|
|
2340
|
+
case 'date':
|
|
2341
|
+
case 'datetime':
|
|
2342
|
+
return faker.date.recent().toISOString();
|
|
2343
|
+
case 'email':
|
|
2344
|
+
return faker.internet.email();
|
|
2345
|
+
case 'uuid':
|
|
2346
|
+
case 'id':
|
|
2347
|
+
return faker.string.uuid();
|
|
2348
|
+
case 'url':
|
|
2349
|
+
return faker.internet.url();
|
|
2350
|
+
case 'phone':
|
|
2351
|
+
return faker.phone.number();
|
|
2352
|
+
case 'address':
|
|
2353
|
+
return this.generateAddress();
|
|
2354
|
+
case 'name':
|
|
2355
|
+
case 'fullname':
|
|
2356
|
+
return faker.person.fullName();
|
|
2357
|
+
case 'firstname':
|
|
2358
|
+
return faker.person.firstName();
|
|
2359
|
+
case 'lastname':
|
|
2360
|
+
return faker.person.lastName();
|
|
2361
|
+
case 'username':
|
|
2362
|
+
return faker.internet.username();
|
|
2363
|
+
case 'password':
|
|
2364
|
+
return faker.internet.password();
|
|
2365
|
+
case 'company':
|
|
2366
|
+
return faker.company.name();
|
|
2367
|
+
case 'jobtitle':
|
|
2368
|
+
return faker.person.jobTitle();
|
|
2369
|
+
case 'text':
|
|
2370
|
+
case 'paragraph':
|
|
2371
|
+
return faker.lorem.paragraph();
|
|
2372
|
+
case 'sentence':
|
|
2373
|
+
return faker.lorem.sentence();
|
|
2374
|
+
case 'word':
|
|
2375
|
+
case 'words':
|
|
2376
|
+
return faker.lorem.word();
|
|
2377
|
+
case 'avatar':
|
|
2378
|
+
case 'image':
|
|
2379
|
+
return faker.image.avatar();
|
|
2380
|
+
case 'color':
|
|
2381
|
+
return faker.color.rgb();
|
|
2382
|
+
case 'ipaddress':
|
|
2383
|
+
case 'ip':
|
|
2384
|
+
return faker.internet.ipv4();
|
|
2385
|
+
case 'mac':
|
|
2386
|
+
return faker.internet.mac();
|
|
2387
|
+
case 'latitude':
|
|
2388
|
+
return faker.location.latitude();
|
|
2389
|
+
case 'longitude':
|
|
2390
|
+
return faker.location.longitude();
|
|
2391
|
+
case 'country':
|
|
2392
|
+
return faker.location.country();
|
|
2393
|
+
case 'city':
|
|
2394
|
+
return faker.location.city();
|
|
2395
|
+
case 'zipcode':
|
|
2396
|
+
case 'postalcode':
|
|
2397
|
+
return faker.location.zipCode();
|
|
2398
|
+
case 'creditcard':
|
|
2399
|
+
return faker.finance.creditCardNumber();
|
|
2400
|
+
case 'currency':
|
|
2401
|
+
return faker.finance.currencyCode();
|
|
2402
|
+
case 'amount':
|
|
2403
|
+
case 'price':
|
|
2404
|
+
return faker.finance.amount();
|
|
2405
|
+
case 'json':
|
|
2406
|
+
case 'object':
|
|
2407
|
+
return { key: faker.lorem.word(), value: faker.lorem.sentence() };
|
|
2408
|
+
case 'array':
|
|
2409
|
+
return [faker.lorem.word(), faker.lorem.word(), faker.lorem.word()];
|
|
2410
|
+
case 'enum':
|
|
2411
|
+
if (options?.enum && options.enum.length > 0) {
|
|
2412
|
+
return faker.helpers.arrayElement(options.enum);
|
|
2413
|
+
}
|
|
2414
|
+
return faker.lorem.word();
|
|
2415
|
+
default:
|
|
2416
|
+
// Try to infer from field name
|
|
2417
|
+
return this.inferValueFromFieldName(fieldName);
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
private generateStringValue(fieldName: string, options?: SchemaField): string {
|
|
2422
|
+
const lowerName = fieldName.toLowerCase();
|
|
2423
|
+
|
|
2424
|
+
// Infer type from field name
|
|
2425
|
+
if (lowerName.includes('email')) return faker.internet.email();
|
|
2426
|
+
if (lowerName.includes('name') && lowerName.includes('first')) return faker.person.firstName();
|
|
2427
|
+
if (lowerName.includes('name') && lowerName.includes('last')) return faker.person.lastName();
|
|
2428
|
+
if (lowerName.includes('name')) return faker.person.fullName();
|
|
2429
|
+
if (lowerName.includes('phone')) return faker.phone.number();
|
|
2430
|
+
if (lowerName.includes('address')) return faker.location.streetAddress();
|
|
2431
|
+
if (lowerName.includes('city')) return faker.location.city();
|
|
2432
|
+
if (lowerName.includes('country')) return faker.location.country();
|
|
2433
|
+
if (lowerName.includes('zip') || lowerName.includes('postal')) return faker.location.zipCode();
|
|
2434
|
+
if (lowerName.includes('url') || lowerName.includes('website')) return faker.internet.url();
|
|
2435
|
+
if (lowerName.includes('username') || lowerName.includes('user')) return faker.internet.username();
|
|
2436
|
+
if (lowerName.includes('password')) return faker.internet.password();
|
|
2437
|
+
if (lowerName.includes('description') || lowerName.includes('bio')) return faker.lorem.paragraph();
|
|
2438
|
+
if (lowerName.includes('title')) return faker.lorem.sentence();
|
|
2439
|
+
if (lowerName.includes('company')) return faker.company.name();
|
|
2440
|
+
if (lowerName.includes('job')) return faker.person.jobTitle();
|
|
2441
|
+
if (lowerName.includes('avatar') || lowerName.includes('image')) return faker.image.avatar();
|
|
2442
|
+
|
|
2443
|
+
// Apply pattern if provided
|
|
2444
|
+
if (options?.pattern) {
|
|
2445
|
+
return faker.helpers.fromRegExp(options.pattern);
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
// Default string generation
|
|
2449
|
+
return faker.lorem.words(3);
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
private generateNumberValue(options?: SchemaField): number {
|
|
2453
|
+
const min = options?.min ?? 0;
|
|
2454
|
+
const max = options?.max ?? 10000;
|
|
2455
|
+
return faker.number.int({ min, max });
|
|
2456
|
+
}
|
|
2457
|
+
|
|
2458
|
+
private generateAddress(): Record<string, string> {
|
|
2459
|
+
return {
|
|
2460
|
+
street: faker.location.streetAddress(),
|
|
2461
|
+
city: faker.location.city(),
|
|
2462
|
+
state: faker.location.state(),
|
|
2463
|
+
zipCode: faker.location.zipCode(),
|
|
2464
|
+
country: faker.location.country(),
|
|
2465
|
+
};
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
private inferValueFromFieldName(fieldName: string): unknown {
|
|
2469
|
+
const lowerName = fieldName.toLowerCase();
|
|
2470
|
+
|
|
2471
|
+
if (lowerName.includes('id')) return faker.string.uuid();
|
|
2472
|
+
if (lowerName.includes('email')) return faker.internet.email();
|
|
2473
|
+
if (lowerName.includes('name')) return faker.person.fullName();
|
|
2474
|
+
if (lowerName.includes('phone')) return faker.phone.number();
|
|
2475
|
+
if (lowerName.includes('date') || lowerName.includes('time')) return faker.date.recent().toISOString();
|
|
2476
|
+
if (lowerName.includes('url')) return faker.internet.url();
|
|
2477
|
+
if (lowerName.includes('count') || lowerName.includes('amount')) return faker.number.int({ min: 0, max: 100 });
|
|
2478
|
+
if (lowerName.includes('price')) return faker.finance.amount();
|
|
2479
|
+
if (lowerName.includes('active') || lowerName.includes('enabled') || lowerName.includes('is')) {
|
|
2480
|
+
return faker.datatype.boolean();
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
// Default to a random string
|
|
2484
|
+
return faker.lorem.word();
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
private callFakerMethod(methodPath: string): unknown {
|
|
2488
|
+
try {
|
|
2489
|
+
const parts = methodPath.split('.');
|
|
2490
|
+
let result: unknown = faker;
|
|
2491
|
+
|
|
2492
|
+
for (const part of parts) {
|
|
2493
|
+
if (result && typeof result === 'object' && part in result) {
|
|
2494
|
+
const next = (result as Record<string, unknown>)[part];
|
|
2495
|
+
if (typeof next === 'function') {
|
|
2496
|
+
result = (next as () => unknown)();
|
|
2497
|
+
} else {
|
|
2498
|
+
result = next;
|
|
2499
|
+
}
|
|
2500
|
+
} else {
|
|
2501
|
+
return faker.lorem.word();
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
return result;
|
|
2506
|
+
} catch {
|
|
2507
|
+
return faker.lorem.word();
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
private linkRelatedRecords(
|
|
2512
|
+
records: unknown[],
|
|
2513
|
+
schema: Record<string, unknown>
|
|
2514
|
+
): void {
|
|
2515
|
+
// Find fields with references and link them
|
|
2516
|
+
const referenceFields: Array<{ field: string; reference: string }> = [];
|
|
2517
|
+
|
|
2518
|
+
for (const [key, fieldDef] of Object.entries(schema)) {
|
|
2519
|
+
if (typeof fieldDef === 'object' && fieldDef !== null) {
|
|
2520
|
+
const field = fieldDef as SchemaField;
|
|
2521
|
+
if (field.reference) {
|
|
2522
|
+
referenceFields.push({ field: key, reference: field.reference });
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
// If we have reference fields, link records
|
|
2528
|
+
if (referenceFields.length > 0) {
|
|
2529
|
+
for (let i = 0; i < records.length; i++) {
|
|
2530
|
+
const record = records[i] as Record<string, unknown>;
|
|
2531
|
+
for (const { field, reference } of referenceFields) {
|
|
2532
|
+
// Link to a random previous record's ID or create a new one
|
|
2533
|
+
if (i > 0 && reference === 'id') {
|
|
2534
|
+
const prevRecord = records[Math.floor(Math.random() * i)] as Record<string, unknown>;
|
|
2535
|
+
record[field] = prevRecord['id'] ?? faker.string.uuid();
|
|
2536
|
+
} else {
|
|
2537
|
+
record[field] = faker.string.uuid();
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
private async generateTestForLines(
|
|
2545
|
+
file: string,
|
|
2546
|
+
lines: number[],
|
|
2547
|
+
framework: string
|
|
2548
|
+
): Promise<GeneratedTest | null> {
|
|
2549
|
+
if (lines.length === 0) return null;
|
|
2550
|
+
|
|
2551
|
+
const testId = uuidv4();
|
|
2552
|
+
const testFile = this.getTestFilePath(file, framework);
|
|
2553
|
+
const moduleName = this.extractModuleName(file);
|
|
2554
|
+
const importPath = this.getImportPath(file);
|
|
2555
|
+
|
|
2556
|
+
// Generate meaningful coverage test code
|
|
2557
|
+
const testCode = this.generateCoverageTestCode(moduleName, importPath, lines, framework);
|
|
2558
|
+
|
|
2559
|
+
return {
|
|
2560
|
+
id: testId,
|
|
2561
|
+
name: `Coverage test for lines ${lines[0]}-${lines[lines.length - 1]}`,
|
|
2562
|
+
sourceFile: file,
|
|
2563
|
+
testFile,
|
|
2564
|
+
testCode,
|
|
2565
|
+
type: 'unit',
|
|
2566
|
+
assertions: this.countAssertions(testCode),
|
|
2567
|
+
};
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
/**
|
|
2571
|
+
* Generate actual coverage test code for specific lines
|
|
2572
|
+
*/
|
|
2573
|
+
private generateCoverageTestCode(
|
|
2574
|
+
moduleName: string,
|
|
2575
|
+
importPath: string,
|
|
2576
|
+
lines: number[],
|
|
2577
|
+
framework: string
|
|
2578
|
+
): string {
|
|
2579
|
+
const funcName = this.camelCase(moduleName);
|
|
2580
|
+
const lineRange = lines.length === 1
|
|
2581
|
+
? `line ${lines[0]}`
|
|
2582
|
+
: `lines ${lines[0]}-${lines[lines.length - 1]}`;
|
|
2583
|
+
|
|
2584
|
+
if (framework === 'pytest') {
|
|
2585
|
+
return `# Coverage test for ${lineRange} in ${moduleName}
|
|
2586
|
+
import pytest
|
|
2587
|
+
from ${importPath.replace(/\//g, '.')} import ${funcName}
|
|
2588
|
+
|
|
2589
|
+
class Test${this.pascalCase(moduleName)}Coverage:
|
|
2590
|
+
"""Tests to cover ${lineRange}"""
|
|
2591
|
+
|
|
2592
|
+
def test_cover_${lines[0]}_${lines[lines.length - 1]}(self):
|
|
2593
|
+
"""Exercise code path covering ${lineRange}"""
|
|
2594
|
+
# Arrange: Set up test inputs to reach uncovered lines
|
|
2595
|
+
test_input = None # Replace with appropriate input
|
|
2596
|
+
|
|
2597
|
+
# Act: Execute the code path
|
|
2598
|
+
try:
|
|
2599
|
+
result = ${funcName}(test_input)
|
|
2600
|
+
|
|
2601
|
+
# Assert: Verify expected behavior
|
|
2602
|
+
assert result is not None
|
|
2603
|
+
except Exception as e:
|
|
2604
|
+
# If exception is expected for this path, verify it
|
|
2605
|
+
pytest.fail(f"Unexpected exception: {e}")
|
|
2606
|
+
`;
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
// Default: Jest/Vitest format
|
|
2610
|
+
return `// Coverage test for ${lineRange} in ${moduleName}
|
|
2611
|
+
import { ${funcName} } from '${importPath}';
|
|
2612
|
+
|
|
2613
|
+
describe('${moduleName} coverage', () => {
|
|
2614
|
+
describe('${lineRange}', () => {
|
|
2615
|
+
it('should execute code path covering ${lineRange}', () => {
|
|
2616
|
+
// Arrange: Set up test inputs to reach uncovered lines
|
|
2617
|
+
const testInput = undefined; // Replace with appropriate input
|
|
2618
|
+
|
|
2619
|
+
// Act: Execute the code path
|
|
2620
|
+
const result = ${funcName}(testInput);
|
|
2621
|
+
|
|
2622
|
+
// Assert: Verify the code was reached and behaves correctly
|
|
2623
|
+
expect(result).toBeDefined();
|
|
2624
|
+
});
|
|
2625
|
+
|
|
2626
|
+
it('should handle edge case for ${lineRange}', () => {
|
|
2627
|
+
// Arrange: Set up edge case input
|
|
2628
|
+
const edgeCaseInput = null;
|
|
2629
|
+
|
|
2630
|
+
// Act & Assert: Verify edge case handling
|
|
2631
|
+
expect(() => ${funcName}(edgeCaseInput)).not.toThrow();
|
|
2632
|
+
});
|
|
2633
|
+
});
|
|
2634
|
+
});
|
|
2635
|
+
`;
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
private groupConsecutiveLines(lines: number[]): number[][] {
|
|
2639
|
+
if (lines.length === 0) return [];
|
|
2640
|
+
|
|
2641
|
+
const sorted = [...lines].sort((a, b) => a - b);
|
|
2642
|
+
const groups: number[][] = [[sorted[0]]];
|
|
2643
|
+
|
|
2644
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
2645
|
+
const currentGroup = groups[groups.length - 1];
|
|
2646
|
+
if (sorted[i] - currentGroup[currentGroup.length - 1] <= 3) {
|
|
2647
|
+
currentGroup.push(sorted[i]);
|
|
2648
|
+
} else {
|
|
2649
|
+
groups.push([sorted[i]]);
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2653
|
+
return groups;
|
|
2654
|
+
}
|
|
2655
|
+
|
|
2656
|
+
private getTestFilePath(sourceFile: string, framework: string): string {
|
|
2657
|
+
const ext = sourceFile.split('.').pop() || 'ts';
|
|
2658
|
+
const base = sourceFile.replace(`.${ext}`, '');
|
|
2659
|
+
|
|
2660
|
+
if (framework === 'pytest') {
|
|
2661
|
+
return `test_${base.split('/').pop()}.py`;
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
return `${base}.test.${ext}`;
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
private extractModuleName(sourceFile: string): string {
|
|
2668
|
+
const filename = sourceFile.split('/').pop() || sourceFile;
|
|
2669
|
+
return filename.replace(/\.(ts|js|tsx|jsx|py)$/, '');
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2672
|
+
private getImportPath(sourceFile: string): string {
|
|
2673
|
+
return sourceFile.replace(/\.(ts|js|tsx|jsx)$/, '');
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2676
|
+
private countAssertions(testCode: string): number {
|
|
2677
|
+
const assertPatterns = [
|
|
2678
|
+
/expect\(/g,
|
|
2679
|
+
/assert/g,
|
|
2680
|
+
/\.to\./g,
|
|
2681
|
+
/\.toBe/g,
|
|
2682
|
+
/\.toEqual/g,
|
|
2683
|
+
];
|
|
2684
|
+
|
|
2685
|
+
let count = 0;
|
|
2686
|
+
for (const pattern of assertPatterns) {
|
|
2687
|
+
const matches = testCode.match(pattern);
|
|
2688
|
+
count += matches ? matches.length : 0;
|
|
2689
|
+
}
|
|
2690
|
+
|
|
2691
|
+
return Math.max(1, count);
|
|
2692
|
+
}
|
|
2693
|
+
|
|
2694
|
+
private estimateCoverage(tests: GeneratedTest[], target: number): number {
|
|
2695
|
+
// Estimate coverage based on test characteristics
|
|
2696
|
+
const totalAssertions = tests.reduce((sum, t) => sum + t.assertions, 0);
|
|
2697
|
+
const totalTests = tests.length;
|
|
2698
|
+
|
|
2699
|
+
// Base coverage from test count (each test covers ~3-5% typically)
|
|
2700
|
+
const testBasedCoverage = totalTests * 4;
|
|
2701
|
+
|
|
2702
|
+
// Additional coverage from assertions (each assertion ~1-2%)
|
|
2703
|
+
const assertionCoverage = totalAssertions * 1.5;
|
|
2704
|
+
|
|
2705
|
+
// Test type multipliers (integration tests cover more)
|
|
2706
|
+
const typeMultiplier = tests.reduce((mult, t) => {
|
|
2707
|
+
if (t.type === 'integration') return mult + 0.1;
|
|
2708
|
+
if (t.type === 'e2e') return mult + 0.15;
|
|
2709
|
+
return mult;
|
|
2710
|
+
}, 1);
|
|
2711
|
+
|
|
2712
|
+
// Calculate estimated coverage with diminishing returns
|
|
2713
|
+
const rawEstimate = (testBasedCoverage + assertionCoverage) * typeMultiplier;
|
|
2714
|
+
const diminishedEstimate = rawEstimate * (1 - rawEstimate / 200); // Diminishing returns above 100%
|
|
2715
|
+
|
|
2716
|
+
// Cap at target and round
|
|
2717
|
+
const estimatedCoverage = Math.min(target, Math.max(0, diminishedEstimate));
|
|
2718
|
+
return Math.round(estimatedCoverage * 10) / 10;
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
private camelCase(str: string): string {
|
|
2722
|
+
return str
|
|
2723
|
+
.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase())
|
|
2724
|
+
.replace(/^./, (chr) => chr.toLowerCase());
|
|
2725
|
+
}
|
|
2726
|
+
|
|
2727
|
+
private pascalCase(str: string): string {
|
|
2728
|
+
return str
|
|
2729
|
+
.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase())
|
|
2730
|
+
.replace(/^./, (chr) => chr.toUpperCase());
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
private async storeGenerationMetadata(
|
|
2734
|
+
tests: GeneratedTest[],
|
|
2735
|
+
patterns: string[]
|
|
2736
|
+
): Promise<void> {
|
|
2737
|
+
const metadata = {
|
|
2738
|
+
generatedAt: new Date().toISOString(),
|
|
2739
|
+
testCount: tests.length,
|
|
2740
|
+
patterns,
|
|
2741
|
+
testIds: tests.map((t) => t.id),
|
|
2742
|
+
};
|
|
2743
|
+
|
|
2744
|
+
await this.memory.set(
|
|
2745
|
+
`test-generation:metadata:${Date.now()}`,
|
|
2746
|
+
metadata,
|
|
2747
|
+
{ namespace: 'test-generation', ttl: 86400 * 7 } // 7 days
|
|
2748
|
+
);
|
|
2749
|
+
}
|
|
2750
|
+
}
|