aios-core 2.1.5 → 2.2.0
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/.aios-core/core/README.md +229 -229
- package/.aios-core/core/data/agent-config-requirements.yaml +368 -368
- package/.aios-core/core/data/aios-kb.md +923 -923
- package/.aios-core/core/data/workflow-patterns.yaml +267 -267
- package/.aios-core/core/docs/SHARD-TRANSLATION-GUIDE.md +335 -335
- package/.aios-core/core/docs/component-creation-guide.md +457 -457
- package/.aios-core/core/docs/session-update-pattern.md +307 -307
- package/.aios-core/core/docs/template-syntax.md +266 -266
- package/.aios-core/core/docs/troubleshooting-guide.md +624 -624
- package/.aios-core/core/elicitation/elicitation-engine.js +1 -1
- package/.aios-core/core/index.esm.js +42 -42
- package/.aios-core/core/index.js +1 -1
- package/.aios-core/core/migration/migration-config.yaml +83 -83
- package/.aios-core/core/migration/module-mapping.yaml +89 -89
- package/.aios-core/core/quality-gates/layer2-pr-automation.js +1 -1
- package/.aios-core/core/quality-gates/quality-gate-config.yaml +86 -86
- package/.aios-core/core/registry/README.md +179 -179
- package/.aios-core/core/utils/security-utils.js +1 -1
- package/.aios-core/core-config.yaml +391 -382
- package/.aios-core/data/agent-config-requirements.yaml +368 -368
- package/.aios-core/data/aios-kb.md +923 -923
- package/.aios-core/data/technical-preferences.md +3 -3
- package/.aios-core/data/workflow-patterns.yaml +267 -267
- package/.aios-core/development/README.md +142 -142
- package/.aios-core/development/agent-teams/team-all.yaml +15 -15
- package/.aios-core/development/agent-teams/team-fullstack.yaml +18 -18
- package/.aios-core/development/agent-teams/team-ide-minimal.yaml +10 -10
- package/.aios-core/development/agent-teams/team-no-ui.yaml +13 -13
- package/.aios-core/development/agent-teams/team-qa-focused.yaml +155 -155
- package/.aios-core/development/agents/aios-master.md +339 -339
- package/.aios-core/development/agents/analyst.md +195 -195
- package/.aios-core/development/agents/architect.md +359 -359
- package/.aios-core/development/agents/data-engineer.md +468 -468
- package/.aios-core/development/agents/dev.md +390 -390
- package/.aios-core/development/agents/devops.md +398 -398
- package/.aios-core/development/agents/pm.md +198 -198
- package/.aios-core/development/agents/po.md +256 -256
- package/.aios-core/development/agents/qa.md +312 -312
- package/.aios-core/development/agents/sm.md +220 -220
- package/.aios-core/development/agents/ux-design-expert.md +451 -451
- package/.aios-core/development/scripts/greeting-config-cli.js +85 -85
- package/.aios-core/development/tasks/add-mcp.md +319 -319
- package/.aios-core/development/tasks/advanced-elicitation.md +318 -318
- package/.aios-core/development/tasks/analyst-facilitate-brainstorming.md +341 -341
- package/.aios-core/development/tasks/analyze-brownfield.md +456 -0
- package/.aios-core/development/tasks/analyze-framework.md +696 -696
- package/.aios-core/development/tasks/analyze-performance.md +637 -637
- package/.aios-core/development/tasks/apply-qa-fixes.md +340 -340
- package/.aios-core/development/tasks/architect-analyze-impact.md +826 -826
- package/.aios-core/development/tasks/audit-codebase.md +429 -429
- package/.aios-core/development/tasks/audit-tailwind-config.md +270 -270
- package/.aios-core/development/tasks/audit-utilities.md +358 -358
- package/.aios-core/development/tasks/bootstrap-shadcn-library.md +286 -286
- package/.aios-core/development/tasks/brownfield-create-epic.md +485 -485
- package/.aios-core/development/tasks/brownfield-create-story.md +356 -356
- package/.aios-core/development/tasks/build-component.md +478 -478
- package/.aios-core/development/tasks/calculate-roi.md +455 -455
- package/.aios-core/development/tasks/ci-cd-configuration.md +764 -764
- package/.aios-core/development/tasks/cleanup-utilities.md +670 -670
- package/.aios-core/development/tasks/collaborative-edit.md +1108 -1108
- package/.aios-core/development/tasks/compose-molecule.md +284 -284
- package/.aios-core/development/tasks/consolidate-patterns.md +414 -414
- package/.aios-core/development/tasks/correct-course.md +279 -279
- package/.aios-core/development/tasks/create-agent.md +321 -321
- package/.aios-core/development/tasks/create-brownfield-story.md +726 -726
- package/.aios-core/development/tasks/create-deep-research-prompt.md +498 -498
- package/.aios-core/development/tasks/create-doc.md +316 -316
- package/.aios-core/development/tasks/create-next-story.md +774 -774
- package/.aios-core/development/tasks/create-suite.md +283 -283
- package/.aios-core/development/tasks/create-task.md +371 -371
- package/.aios-core/development/tasks/create-workflow.md +370 -370
- package/.aios-core/development/tasks/db-analyze-hotpaths.md +572 -572
- package/.aios-core/development/tasks/db-apply-migration.md +381 -381
- package/.aios-core/development/tasks/db-bootstrap.md +642 -642
- package/.aios-core/development/tasks/db-domain-modeling.md +693 -693
- package/.aios-core/development/tasks/db-dry-run.md +293 -293
- package/.aios-core/development/tasks/db-env-check.md +260 -260
- package/.aios-core/development/tasks/db-expansion-pack-integration.md +663 -663
- package/.aios-core/development/tasks/db-explain.md +631 -631
- package/.aios-core/development/tasks/db-impersonate.md +495 -495
- package/.aios-core/development/tasks/db-load-csv.md +593 -593
- package/.aios-core/development/tasks/db-policy-apply.md +653 -653
- package/.aios-core/development/tasks/db-rls-audit.md +411 -411
- package/.aios-core/development/tasks/db-rollback.md +739 -739
- package/.aios-core/development/tasks/db-run-sql.md +613 -613
- package/.aios-core/development/tasks/db-schema-audit.md +1011 -1011
- package/.aios-core/development/tasks/db-seed.md +390 -390
- package/.aios-core/development/tasks/db-smoke-test.md +351 -351
- package/.aios-core/development/tasks/db-snapshot.md +569 -569
- package/.aios-core/development/tasks/db-supabase-setup.md +712 -712
- package/.aios-core/development/tasks/db-verify-order.md +515 -515
- package/.aios-core/development/tasks/deprecate-component.md +956 -956
- package/.aios-core/development/tasks/dev-apply-qa-fixes.md +318 -318
- package/.aios-core/development/tasks/dev-backlog-debt.md +469 -469
- package/.aios-core/development/tasks/dev-develop-story.md +846 -846
- package/.aios-core/development/tasks/dev-improve-code-quality.md +872 -872
- package/.aios-core/development/tasks/dev-optimize-performance.md +1033 -1033
- package/.aios-core/development/tasks/dev-suggest-refactoring.md +870 -870
- package/.aios-core/development/tasks/dev-validate-next-story.md +348 -348
- package/.aios-core/development/tasks/document-project.md +552 -552
- package/.aios-core/development/tasks/environment-bootstrap.md +1311 -1311
- package/.aios-core/development/tasks/execute-checklist.md +301 -301
- package/.aios-core/development/tasks/export-design-tokens-dtcg.md +274 -274
- package/.aios-core/development/tasks/extend-pattern.md +269 -269
- package/.aios-core/development/tasks/extract-tokens.md +467 -467
- package/.aios-core/development/tasks/facilitate-brainstorming-session.md +518 -518
- package/.aios-core/development/tasks/generate-ai-frontend-prompt.md +260 -260
- package/.aios-core/development/tasks/generate-documentation.md +284 -284
- package/.aios-core/development/tasks/generate-migration-strategy.md +522 -522
- package/.aios-core/development/tasks/generate-shock-report.md +501 -501
- package/.aios-core/development/tasks/github-devops-github-pr-automation.md +427 -427
- package/.aios-core/development/tasks/github-devops-pre-push-quality-gate.md +733 -733
- package/.aios-core/development/tasks/github-devops-repository-cleanup.md +374 -374
- package/.aios-core/development/tasks/github-devops-version-management.md +483 -483
- package/.aios-core/development/tasks/improve-self.md +822 -822
- package/.aios-core/development/tasks/index-docs.md +387 -387
- package/.aios-core/development/tasks/init-project-status.md +506 -506
- package/.aios-core/development/tasks/integrate-expansion-pack.md +314 -314
- package/.aios-core/development/tasks/kb-mode-interaction.md +283 -283
- package/.aios-core/development/tasks/learn-patterns.md +900 -900
- package/.aios-core/development/tasks/mcp-workflow.md +437 -437
- package/.aios-core/development/tasks/modify-agent.md +381 -381
- package/.aios-core/development/tasks/modify-task.md +424 -424
- package/.aios-core/development/tasks/modify-workflow.md +465 -465
- package/.aios-core/development/tasks/po-backlog-add.md +370 -370
- package/.aios-core/development/tasks/po-manage-story-backlog.md +523 -523
- package/.aios-core/development/tasks/po-pull-story-from-clickup.md +540 -540
- package/.aios-core/development/tasks/po-pull-story.md +316 -316
- package/.aios-core/development/tasks/po-stories-index.md +351 -351
- package/.aios-core/development/tasks/po-sync-story-to-clickup.md +457 -457
- package/.aios-core/development/tasks/po-sync-story.md +303 -303
- package/.aios-core/development/tasks/pr-automation.md +701 -701
- package/.aios-core/development/tasks/propose-modification.md +842 -842
- package/.aios-core/development/tasks/qa-backlog-add-followup.md +425 -425
- package/.aios-core/development/tasks/qa-gate.md +373 -373
- package/.aios-core/development/tasks/qa-generate-tests.md +1174 -1174
- package/.aios-core/development/tasks/qa-nfr-assess.md +557 -557
- package/.aios-core/development/tasks/qa-review-proposal.md +1157 -1157
- package/.aios-core/development/tasks/qa-review-story.md +682 -682
- package/.aios-core/development/tasks/qa-risk-profile.md +566 -566
- package/.aios-core/development/tasks/qa-run-tests.md +277 -277
- package/.aios-core/development/tasks/qa-test-design.md +387 -387
- package/.aios-core/development/tasks/qa-trace-requirements.md +476 -476
- package/.aios-core/development/tasks/release-management.md +723 -723
- package/.aios-core/development/tasks/security-audit.md +554 -554
- package/.aios-core/development/tasks/security-scan.md +790 -790
- package/.aios-core/development/tasks/setup-database.md +741 -741
- package/.aios-core/development/tasks/setup-design-system.md +462 -462
- package/.aios-core/development/tasks/setup-github.md +874 -874
- package/.aios-core/development/tasks/setup-llm-routing.md +1 -1
- package/.aios-core/development/tasks/setup-mcp-docker.md +584 -584
- package/.aios-core/development/tasks/setup-project-docs.md +440 -0
- package/.aios-core/development/tasks/shard-doc.md +537 -537
- package/.aios-core/development/tasks/sm-create-next-story.md +480 -480
- package/.aios-core/development/tasks/sync-documentation.md +864 -864
- package/.aios-core/development/tasks/tailwind-upgrade.md +294 -294
- package/.aios-core/development/tasks/test-as-user.md +621 -621
- package/.aios-core/development/tasks/test-validation-task.md +171 -171
- package/.aios-core/development/tasks/undo-last.md +346 -346
- package/.aios-core/development/tasks/update-manifest.md +409 -409
- package/.aios-core/development/tasks/ux-create-wireframe.md +617 -617
- package/.aios-core/development/tasks/ux-ds-scan-artifact.md +672 -672
- package/.aios-core/development/tasks/ux-user-research.md +559 -559
- package/.aios-core/development/tasks/validate-next-story.md +422 -422
- package/.aios-core/development/workflows/README.md +83 -83
- package/.aios-core/development/workflows/brownfield-fullstack.yaml +297 -297
- package/.aios-core/development/workflows/brownfield-service.yaml +187 -187
- package/.aios-core/development/workflows/brownfield-ui.yaml +197 -197
- package/.aios-core/development/workflows/greenfield-fullstack.yaml +333 -333
- package/.aios-core/development/workflows/greenfield-service.yaml +206 -206
- package/.aios-core/development/workflows/greenfield-ui.yaml +235 -235
- package/.aios-core/docs/SHARD-TRANSLATION-GUIDE.md +335 -335
- package/.aios-core/docs/component-creation-guide.md +457 -457
- package/.aios-core/docs/session-update-pattern.md +307 -307
- package/.aios-core/docs/standards/AGENT-PERSONALIZATION-STANDARD-V1.md +572 -572
- package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-QUICK-REFERENCE.md +185 -185
- package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-V2.1.md +354 -354
- package/.aios-core/docs/standards/AIOS-FRAMEWORK-MASTER.md +1963 -1963
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +821 -821
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-SUMMARY.md +1190 -1190
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1.md +439 -439
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.2-SUMMARY.md +1339 -1339
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO.md +5398 -5398
- package/.aios-core/docs/standards/EXECUTOR-DECISION-TREE.md +697 -697
- package/.aios-core/docs/standards/OPEN-SOURCE-VS-SERVICE-DIFFERENCES.md +511 -511
- package/.aios-core/docs/standards/QUALITY-GATES-SPECIFICATION.md +556 -556
- package/.aios-core/docs/standards/STANDARDS-INDEX.md +210 -210
- package/.aios-core/docs/standards/STORY-TEMPLATE-V2-SPECIFICATION.md +550 -550
- package/.aios-core/docs/standards/TASK-FORMAT-SPECIFICATION-V1.md +1414 -1414
- package/.aios-core/docs/standards/V3-ARCHITECTURAL-DECISIONS.md +523 -523
- package/.aios-core/docs/template-syntax.md +266 -266
- package/.aios-core/docs/troubleshooting-guide.md +624 -624
- package/.aios-core/index.esm.js +15 -15
- package/.aios-core/index.js +1 -1
- package/.aios-core/infrastructure/README.md +126 -126
- package/.aios-core/infrastructure/integrations/pm-adapters/README.md +59 -59
- package/.aios-core/infrastructure/scripts/approval-workflow.js +1 -1
- package/.aios-core/infrastructure/scripts/batch-creator.js +1 -1
- package/.aios-core/infrastructure/scripts/component-generator.js +3 -3
- package/.aios-core/infrastructure/scripts/component-metadata.js +1 -1
- package/.aios-core/infrastructure/scripts/component-search.js +1 -1
- package/.aios-core/infrastructure/scripts/coverage-analyzer.js +1 -1
- package/.aios-core/infrastructure/scripts/dependency-analyzer.js +1 -1
- package/.aios-core/infrastructure/scripts/dependency-impact-analyzer.js +1 -1
- package/.aios-core/infrastructure/scripts/documentation-integrity/brownfield-analyzer.js +501 -0
- package/.aios-core/infrastructure/scripts/documentation-integrity/config-generator.js +368 -0
- package/.aios-core/infrastructure/scripts/documentation-integrity/deployment-config-loader.js +308 -0
- package/.aios-core/infrastructure/scripts/documentation-integrity/doc-generator.js +331 -0
- package/.aios-core/infrastructure/scripts/documentation-integrity/gitignore-generator.js +312 -0
- package/.aios-core/infrastructure/scripts/documentation-integrity/index.js +74 -0
- package/.aios-core/infrastructure/scripts/documentation-integrity/mode-detector.js +389 -0
- package/.aios-core/infrastructure/scripts/framework-analyzer.js +1 -1
- package/.aios-core/infrastructure/scripts/improvement-engine.js +1 -1
- package/.aios-core/infrastructure/scripts/llm-routing/install-llm-routing.js +26 -13
- package/.aios-core/infrastructure/scripts/llm-routing/templates/claude-free-tracked.cmd +127 -0
- package/.aios-core/infrastructure/scripts/llm-routing/templates/claude-free-tracked.sh +108 -0
- package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-proxy.cmd +71 -0
- package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-proxy.sh +65 -0
- package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-usage.cmd +51 -0
- package/.aios-core/infrastructure/scripts/llm-routing/templates/deepseek-usage.sh +16 -0
- package/.aios-core/infrastructure/scripts/llm-routing/usage-tracker/index.js +549 -0
- package/.aios-core/infrastructure/scripts/modification-risk-assessment.js +1 -1
- package/.aios-core/infrastructure/scripts/performance-analyzer.js +1 -1
- package/.aios-core/infrastructure/scripts/pm-adapter.js +134 -134
- package/.aios-core/infrastructure/scripts/repository-detector.js +3 -3
- package/.aios-core/infrastructure/scripts/template-engine.js +1 -1
- package/.aios-core/infrastructure/scripts/template-validator.js +1 -1
- package/.aios-core/infrastructure/scripts/test-generator.js +1 -1
- package/.aios-core/infrastructure/scripts/test-quality-assessment.js +1 -1
- package/.aios-core/infrastructure/scripts/transaction-manager.js +1 -1
- package/.aios-core/infrastructure/scripts/usage-analytics.js +1 -1
- package/.aios-core/infrastructure/scripts/visual-impact-generator.js +2 -2
- package/.aios-core/infrastructure/templates/core-config/core-config-brownfield.tmpl.yaml +176 -0
- package/.aios-core/infrastructure/templates/core-config/core-config-greenfield.tmpl.yaml +127 -0
- package/.aios-core/infrastructure/templates/github-workflows/README.md +109 -109
- package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -0
- package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -0
- package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -0
- package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -0
- package/.aios-core/infrastructure/templates/project-docs/coding-standards-tmpl.md +346 -0
- package/.aios-core/infrastructure/templates/project-docs/source-tree-tmpl.md +177 -0
- package/.aios-core/infrastructure/templates/project-docs/tech-stack-tmpl.md +267 -0
- package/.aios-core/infrastructure/tests/regression-suite-v2.md +621 -621
- package/.aios-core/infrastructure/tools/README.md +222 -222
- package/.aios-core/infrastructure/tools/cli/github-cli.yaml +200 -200
- package/.aios-core/infrastructure/tools/cli/railway-cli.yaml +260 -260
- package/.aios-core/infrastructure/tools/cli/supabase-cli.yaml +224 -224
- package/.aios-core/infrastructure/tools/local/ffmpeg.yaml +261 -261
- package/.aios-core/infrastructure/tools/mcp/21st-dev-magic.yaml +127 -127
- package/.aios-core/infrastructure/tools/mcp/browser.yaml +103 -103
- package/.aios-core/infrastructure/tools/mcp/clickup.yaml +534 -534
- package/.aios-core/infrastructure/tools/mcp/context7.yaml +78 -78
- package/.aios-core/infrastructure/tools/mcp/desktop-commander.yaml +180 -180
- package/.aios-core/infrastructure/tools/mcp/exa.yaml +103 -103
- package/.aios-core/infrastructure/tools/mcp/google-workspace.yaml +930 -930
- package/.aios-core/infrastructure/tools/mcp/n8n.yaml +551 -551
- package/.aios-core/infrastructure/tools/mcp/supabase.yaml +808 -808
- package/.aios-core/install-manifest.yaml +347 -347
- package/.aios-core/product/README.md +56 -56
- package/.aios-core/product/checklists/accessibility-wcag-checklist.md +80 -0
- package/.aios-core/product/checklists/architect-checklist.md +443 -443
- package/.aios-core/product/checklists/change-checklist.md +182 -182
- package/.aios-core/product/checklists/component-quality-checklist.md +74 -0
- package/.aios-core/product/checklists/database-design-checklist.md +119 -119
- package/.aios-core/product/checklists/dba-predeploy-checklist.md +97 -97
- package/.aios-core/product/checklists/dba-rollback-checklist.md +99 -99
- package/.aios-core/product/checklists/migration-readiness-checklist.md +75 -0
- package/.aios-core/product/checklists/pattern-audit-checklist.md +88 -0
- package/.aios-core/product/checklists/pm-checklist.md +375 -375
- package/.aios-core/product/checklists/po-master-checklist.md +441 -441
- package/.aios-core/product/checklists/pre-push-checklist.md +108 -108
- package/.aios-core/product/checklists/release-checklist.md +122 -122
- package/.aios-core/product/checklists/story-dod-checklist.md +101 -101
- package/.aios-core/product/checklists/story-draft-checklist.md +215 -215
- package/.aios-core/product/data/atomic-design-principles.md +108 -0
- package/.aios-core/product/data/brainstorming-techniques.md +36 -36
- package/.aios-core/product/data/consolidation-algorithms.md +142 -0
- package/.aios-core/product/data/database-best-practices.md +182 -0
- package/.aios-core/product/data/design-token-best-practices.md +107 -0
- package/.aios-core/product/data/elicitation-methods.md +134 -134
- package/.aios-core/product/data/integration-patterns.md +207 -0
- package/.aios-core/product/data/migration-safety-guide.md +329 -0
- package/.aios-core/product/data/mode-selection-best-practices.md +471 -471
- package/.aios-core/product/data/postgres-tuning-guide.md +300 -0
- package/.aios-core/product/data/rls-security-patterns.md +333 -0
- package/.aios-core/product/data/roi-calculation-guide.md +142 -0
- package/.aios-core/product/data/supabase-patterns.md +330 -0
- package/.aios-core/product/data/test-levels-framework.md +148 -148
- package/.aios-core/product/data/test-priorities-matrix.md +174 -174
- package/.aios-core/product/data/wcag-compliance-guide.md +267 -0
- package/.aios-core/product/templates/1mcp-config.yaml +225 -225
- package/.aios-core/product/templates/activation-instructions-inline-greeting.yaml +63 -63
- package/.aios-core/product/templates/activation-instructions-template.md +258 -258
- package/.aios-core/product/templates/agent-template.yaml +120 -120
- package/.aios-core/product/templates/architecture-tmpl.yaml +650 -650
- package/.aios-core/product/templates/brainstorming-output-tmpl.yaml +155 -155
- package/.aios-core/product/templates/brownfield-architecture-tmpl.yaml +475 -475
- package/.aios-core/product/templates/brownfield-prd-tmpl.yaml +279 -279
- package/.aios-core/product/templates/changelog-template.md +134 -134
- package/.aios-core/product/templates/command-rationalization-matrix.md +152 -152
- package/.aios-core/product/templates/competitor-analysis-tmpl.yaml +292 -292
- package/.aios-core/product/templates/design-story-tmpl.yaml +587 -587
- package/.aios-core/product/templates/ds-artifact-analysis.md +70 -70
- package/.aios-core/product/templates/front-end-architecture-tmpl.yaml +205 -205
- package/.aios-core/product/templates/front-end-spec-tmpl.yaml +348 -348
- package/.aios-core/product/templates/fullstack-architecture-tmpl.yaml +804 -804
- package/.aios-core/product/templates/github-pr-template.md +67 -67
- package/.aios-core/product/templates/gordon-mcp.yaml +140 -140
- package/.aios-core/product/templates/ide-rules/antigravity-rules.md +115 -115
- package/.aios-core/product/templates/ide-rules/claude-rules.md +221 -221
- package/.aios-core/product/templates/ide-rules/cline-rules.md +84 -84
- package/.aios-core/product/templates/ide-rules/copilot-rules.md +92 -92
- package/.aios-core/product/templates/ide-rules/cursor-rules.md +115 -115
- package/.aios-core/product/templates/ide-rules/gemini-rules.md +85 -85
- package/.aios-core/product/templates/ide-rules/roo-rules.md +86 -86
- package/.aios-core/product/templates/ide-rules/trae-rules.md +104 -104
- package/.aios-core/product/templates/ide-rules/windsurf-rules.md +80 -80
- package/.aios-core/product/templates/index-strategy-tmpl.yaml +53 -53
- package/.aios-core/product/templates/market-research-tmpl.yaml +251 -251
- package/.aios-core/product/templates/mcp-workflow.js +271 -271
- package/.aios-core/product/templates/migration-plan-tmpl.yaml +1022 -1022
- package/.aios-core/product/templates/migration-strategy-tmpl.md +524 -524
- package/.aios-core/product/templates/personalized-agent-template.md +258 -258
- package/.aios-core/product/templates/personalized-checklist-template.md +340 -340
- package/.aios-core/product/templates/personalized-task-template-v2.md +905 -905
- package/.aios-core/product/templates/personalized-task-template.md +344 -344
- package/.aios-core/product/templates/personalized-template-file.yaml +322 -322
- package/.aios-core/product/templates/personalized-workflow-template.yaml +460 -460
- package/.aios-core/product/templates/prd-tmpl.yaml +201 -201
- package/.aios-core/product/templates/project-brief-tmpl.yaml +220 -220
- package/.aios-core/product/templates/qa-gate-tmpl.yaml +240 -240
- package/.aios-core/product/templates/rls-policies-tmpl.yaml +1203 -1203
- package/.aios-core/product/templates/schema-design-tmpl.yaml +428 -428
- package/.aios-core/product/templates/state-persistence-tmpl.yaml +219 -219
- package/.aios-core/product/templates/story-tmpl.yaml +331 -331
- package/.aios-core/product/templates/task-execution-report.md +495 -495
- package/.aios-core/product/templates/task-template.md +122 -122
- package/.aios-core/product/templates/token-exports-tailwind-tmpl.js +395 -395
- package/.aios-core/product/templates/tokens-schema-tmpl.yaml +305 -305
- package/.aios-core/product/templates/workflow-template.yaml +133 -133
- package/.aios-core/scripts/README.md +354 -354
- package/.aios-core/scripts/aios-doc-template.md +325 -325
- package/.aios-core/scripts/elicitation-engine.js +1 -1
- package/.aios-core/scripts/test-template-system.js +1 -1
- package/.aios-core/scripts/workflow-management.md +69 -69
- package/.aios-core/user-guide.md +1413 -1413
- package/.aios-core/working-in-the-brownfield.md +361 -361
- package/LICENSE +1 -1
- package/README.md +702 -703
- package/bin/aios-init-old.js +3 -3
- package/bin/aios-init-v4.js +1 -1
- package/bin/aios-init.backup-v1.1.4.js +1 -1
- package/bin/aios-init.js +3 -3
- package/bin/aios.js +279 -279
- package/bin/utils/install-errors.js +339 -339
- package/bin/utils/install-transaction.js +445 -445
- package/index.d.ts +18 -18
- package/index.esm.js +20 -20
- package/index.js +6 -6
- package/package.json +8 -10
- package/packages/installer/src/config/templates/env-template.js +27 -4
- package/packages/installer/src/detection/detect-project-type.js +81 -81
- package/packages/installer/src/wizard/wizard.js +185 -34
- package/packages/installer/tests/integration/environment-configuration.test.js +2 -1
- package/packages/installer/tests/integration/wizard-detection.test.js +8 -6
- package/packages/installer/tests/unit/env-template.test.js +11 -10
- package/src/config/ide-configs.js +1 -1
- package/src/wizard/feedback.js +2 -2
- package/src/wizard/index.js +1 -1
- package/src/wizard/validation/report-generator.js +1 -1
- package/src/wizard/validation/troubleshooting-system.js +13 -13
- package/.aios-core/development/tasks/validate-structure.md +0 -243
- package/.aios-core/infrastructure/scripts/_archived/final-todo-count.js +0 -122
- package/.aios-core/infrastructure/scripts/_archived/fix-yaml-formatting.js +0 -89
- package/.aios-core/infrastructure/scripts/_archived/migration-generator.js +0 -780
- package/.aios-core/infrastructure/scripts/_archived/migration-path-generator.js +0 -950
- package/.aios-core/infrastructure/scripts/_archived/phase2-entrada-saida-errors.js +0 -425
- package/.aios-core/infrastructure/scripts/_archived/phase2-spot-check.js +0 -132
- package/.aios-core/infrastructure/scripts/_archived/phase3-tools-scripts-validation.js +0 -381
- package/.aios-core/infrastructure/scripts/_archived/phase4-metadata-performance.js +0 -203
- package/.aios-core/infrastructure/scripts/_archived/test-yaml-parsing.js +0 -24
- package/.aios-core/infrastructure/scripts/_archived/verify-yaml-fix.js +0 -51
- package/.aios-core/infrastructure/scripts/source-tree-guardian/index.js +0 -375
- package/.aios-core/infrastructure/scripts/source-tree-guardian/manifest-generator.js +0 -410
- package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/naming-rules.yaml +0 -285
- package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/placement-rules.yaml +0 -262
- package/.aios-core/infrastructure/scripts/source-tree-guardian/validator.js +0 -468
- package/.aios-core/tasks/find-component.md.legacy +0 -391
- package/.aios-core/tasks/generate-commit-message.md.legacy +0 -426
- package/.aios-core/tasks/generate-migration.md.legacy +0 -382
- package/.aios-core/tasks/rollback-modification.md.legacy +0 -307
- package/.aios-core/tasks/update-tests.md.legacy +0 -283
|
@@ -1,1175 +1,1175 @@
|
|
|
1
|
-
---
|
|
2
|
-
|
|
3
|
-
## Execution Modes
|
|
4
|
-
|
|
5
|
-
**Choose your execution mode:**
|
|
6
|
-
|
|
7
|
-
### 1. YOLO Mode - Fast, Autonomous (0-1 prompts)
|
|
8
|
-
- Autonomous decision making with logging
|
|
9
|
-
- Minimal user interaction
|
|
10
|
-
- **Best for:** Simple, deterministic tasks
|
|
11
|
-
|
|
12
|
-
### 2. Interactive Mode - Balanced, Educational (5-10 prompts) **[DEFAULT]**
|
|
13
|
-
- Explicit decision checkpoints
|
|
14
|
-
- Educational explanations
|
|
15
|
-
- **Best for:** Learning, complex decisions
|
|
16
|
-
|
|
17
|
-
### 3. Pre-Flight Planning - Comprehensive Upfront Planning
|
|
18
|
-
- Task analysis phase (identify all ambiguities)
|
|
19
|
-
- Zero ambiguity execution
|
|
20
|
-
- **Best for:** Ambiguous requirements, critical work
|
|
21
|
-
|
|
22
|
-
**Parameter:** `mode` (optional, default: `interactive`)
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Task Definition (AIOS Task Format V1.0)
|
|
27
|
-
|
|
28
|
-
```yaml
|
|
29
|
-
task: qaGenerateTests()
|
|
30
|
-
responsável: Quinn (Guardian)
|
|
31
|
-
responsavel_type: Agente
|
|
32
|
-
atomic_layer: Config
|
|
33
|
-
|
|
34
|
-
**Entrada:**
|
|
35
|
-
- campo: target
|
|
36
|
-
tipo: string
|
|
37
|
-
origem: User Input
|
|
38
|
-
obrigatório: true
|
|
39
|
-
validação: Must exist
|
|
40
|
-
|
|
41
|
-
- campo: criteria
|
|
42
|
-
tipo: array
|
|
43
|
-
origem: config
|
|
44
|
-
obrigatório: true
|
|
45
|
-
validação: Non-empty validation criteria
|
|
46
|
-
|
|
47
|
-
- campo: strict
|
|
48
|
-
tipo: boolean
|
|
49
|
-
origem: User Input
|
|
50
|
-
obrigatório: false
|
|
51
|
-
validação: Default: true
|
|
52
|
-
|
|
53
|
-
**Saída:**
|
|
54
|
-
- campo: validation_result
|
|
55
|
-
tipo: boolean
|
|
56
|
-
destino: Return value
|
|
57
|
-
persistido: false
|
|
58
|
-
|
|
59
|
-
- campo: errors
|
|
60
|
-
tipo: array
|
|
61
|
-
destino: Memory
|
|
62
|
-
persistido: false
|
|
63
|
-
|
|
64
|
-
- campo: report
|
|
65
|
-
tipo: object
|
|
66
|
-
destino: File (.ai/*.json)
|
|
67
|
-
persistido: true
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
---
|
|
71
|
-
|
|
72
|
-
## Pre-Conditions
|
|
73
|
-
|
|
74
|
-
**Purpose:** Validate prerequisites BEFORE task execution (blocking)
|
|
75
|
-
|
|
76
|
-
**Checklist:**
|
|
77
|
-
|
|
78
|
-
```yaml
|
|
79
|
-
pre-conditions:
|
|
80
|
-
- [ ] Validation rules loaded; target available for validation
|
|
81
|
-
tipo: pre-condition
|
|
82
|
-
blocker: true
|
|
83
|
-
validação: |
|
|
84
|
-
Check validation rules loaded; target available for validation
|
|
85
|
-
error_message: "Pre-condition failed: Validation rules loaded; target available for validation"
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Post-Conditions
|
|
91
|
-
|
|
92
|
-
**Purpose:** Validate execution success AFTER task completes
|
|
93
|
-
|
|
94
|
-
**Checklist:**
|
|
95
|
-
|
|
96
|
-
```yaml
|
|
97
|
-
post-conditions:
|
|
98
|
-
- [ ] Validation executed; results accurate; report generated
|
|
99
|
-
tipo: post-condition
|
|
100
|
-
blocker: true
|
|
101
|
-
validação: |
|
|
102
|
-
Verify validation executed; results accurate; report generated
|
|
103
|
-
error_message: "Post-condition failed: Validation executed; results accurate; report generated"
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## Acceptance Criteria
|
|
109
|
-
|
|
110
|
-
**Purpose:** Definitive pass/fail criteria for task completion
|
|
111
|
-
|
|
112
|
-
**Checklist:**
|
|
113
|
-
|
|
114
|
-
```yaml
|
|
115
|
-
acceptance-criteria:
|
|
116
|
-
- [ ] Validation rules applied; pass/fail accurate; actionable feedback
|
|
117
|
-
tipo: acceptance-criterion
|
|
118
|
-
blocker: true
|
|
119
|
-
validação: |
|
|
120
|
-
Assert validation rules applied; pass/fail accurate; actionable feedback
|
|
121
|
-
error_message: "Acceptance criterion not met: Validation rules applied; pass/fail accurate; actionable feedback"
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## Tools
|
|
127
|
-
|
|
128
|
-
**External/shared resources used by this task:**
|
|
129
|
-
|
|
130
|
-
- **Tool:** validation-engine
|
|
131
|
-
- **Purpose:** Rule-based validation and reporting
|
|
132
|
-
- **Source:** .aios-core/utils/validation-engine.js
|
|
133
|
-
|
|
134
|
-
- **Tool:** schema-validator
|
|
135
|
-
- **Purpose:** JSON/YAML schema validation
|
|
136
|
-
- **Source:** ajv or similar
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
## Scripts
|
|
141
|
-
|
|
142
|
-
**Agent-specific code for this task:**
|
|
143
|
-
|
|
144
|
-
- **Script:** run-validation.js
|
|
145
|
-
- **Purpose:** Execute validation rules and generate report
|
|
146
|
-
- **Language:** JavaScript
|
|
147
|
-
- **Location:** .aios-core/scripts/run-validation.js
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Error Handling
|
|
152
|
-
|
|
153
|
-
**Strategy:** retry
|
|
154
|
-
|
|
155
|
-
**Common Errors:**
|
|
156
|
-
|
|
157
|
-
1. **Error:** Validation Criteria Missing
|
|
158
|
-
- **Cause:** Required validation rules not defined
|
|
159
|
-
- **Resolution:** Ensure validation criteria loaded from config
|
|
160
|
-
- **Recovery:** Use default validation rules, log warning
|
|
161
|
-
|
|
162
|
-
2. **Error:** Invalid Schema
|
|
163
|
-
- **Cause:** Target does not match expected schema
|
|
164
|
-
- **Resolution:** Update schema or fix target structure
|
|
165
|
-
- **Recovery:** Detailed validation error report
|
|
166
|
-
|
|
167
|
-
3. **Error:** Dependency Missing
|
|
168
|
-
- **Cause:** Required dependency for validation not found
|
|
169
|
-
- **Resolution:** Install missing dependencies
|
|
170
|
-
- **Recovery:** Abort with clear dependency list
|
|
171
|
-
|
|
172
|
-
---
|
|
173
|
-
|
|
174
|
-
## Performance
|
|
175
|
-
|
|
176
|
-
**Expected Metrics:**
|
|
177
|
-
|
|
178
|
-
```yaml
|
|
179
|
-
duration_expected: 2-10 min (estimated)
|
|
180
|
-
cost_estimated: $0.001-0.008
|
|
181
|
-
token_usage: ~800-2,500 tokens
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
**Optimization Notes:**
|
|
185
|
-
- Validate configuration early; use atomic writes; implement rollback checkpoints
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## Metadata
|
|
190
|
-
|
|
191
|
-
```yaml
|
|
192
|
-
story: N/A
|
|
193
|
-
version: 1.0.0
|
|
194
|
-
dependencies:
|
|
195
|
-
- N/A
|
|
196
|
-
tags:
|
|
197
|
-
- quality-assurance
|
|
198
|
-
- testing
|
|
199
|
-
updated_at: 2025-11-17
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
tools:
|
|
205
|
-
- github-cli
|
|
206
|
-
# TODO: Create test-generation-checklist.md for validation (follow-up story needed)
|
|
207
|
-
# checklists:
|
|
208
|
-
# - test-generation-checklist.md
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
# Generate Tests - AIOS Developer Task
|
|
212
|
-
|
|
213
|
-
## Purpose
|
|
214
|
-
Automatically generate comprehensive test suites for framework components using AI analysis and template systems.
|
|
215
|
-
|
|
216
|
-
## Command Pattern
|
|
217
|
-
```
|
|
218
|
-
*generate-tests <component-type> <component-name> [options]
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
## Parameters
|
|
222
|
-
- `component-type`: Type of component (agent, task, workflow, util)
|
|
223
|
-
- `component-name`: Name/ID of the component to generate tests for
|
|
224
|
-
- `options`: Test generation configuration
|
|
225
|
-
|
|
226
|
-
### Options
|
|
227
|
-
- `--test-type <type>`: Type of tests to generate (unit, integration, e2e, all)
|
|
228
|
-
- `--coverage-target <percentage>`: Target code coverage percentage (default: 80)
|
|
229
|
-
- `--framework <name>`: Test framework to use (jest, mocha, vitest)
|
|
230
|
-
- `--mock-level <level>`: Mocking level (minimal, moderate, extensive)
|
|
231
|
-
- `--update-existing`: Update existing test files instead of creating new ones
|
|
232
|
-
- `--quality-level <level>`: Test quality level (basic, standard, comprehensive)
|
|
233
|
-
- `--output-dir <path>`: Custom output directory for generated tests
|
|
234
|
-
|
|
235
|
-
## Examples
|
|
236
|
-
```bash
|
|
237
|
-
# Generate unit tests for an agent
|
|
238
|
-
*generate-tests agent weather-fetcher --test-type unit --coverage-target 90
|
|
239
|
-
|
|
240
|
-
# Generate comprehensive test suite for a utility
|
|
241
|
-
*generate-tests util logger --test-type all --quality-level comprehensive
|
|
242
|
-
|
|
243
|
-
# Update existing tests for a task
|
|
244
|
-
*generate-tests task data-processor --update-existing --coverage-target 85
|
|
245
|
-
|
|
246
|
-
# Generate integration tests with extensive mocking
|
|
247
|
-
*generate-tests workflow user-onboarding --test-type integration --mock-level extensive
|
|
248
|
-
|
|
249
|
-
# Generate tests for all component types
|
|
250
|
-
*generate-tests all components --framework vitest --output-dir tests/auto-generated
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
## Implementation
|
|
254
|
-
|
|
255
|
-
```javascript
|
|
256
|
-
const fs = require('fs').promises;
|
|
257
|
-
const path = require('path');
|
|
258
|
-
const chalk = require('chalk');
|
|
259
|
-
const inquirer = require('inquirer');
|
|
260
|
-
|
|
261
|
-
class GenerateTestsTask {
|
|
262
|
-
constructor() {
|
|
263
|
-
this.taskName = 'generate-tests';
|
|
264
|
-
this.description = 'Generate comprehensive test suites for framework components';
|
|
265
|
-
this.rootPath = process.cwd();
|
|
266
|
-
this.testTemplateSystem = null;
|
|
267
|
-
this.testGenerator = null;
|
|
268
|
-
this.coverageAnalyzer = null;
|
|
269
|
-
this.qualityAssessment = null;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
async execute(params) {
|
|
273
|
-
try {
|
|
274
|
-
console.log(chalk.blue('🧪 AIOS Test Generation'));
|
|
275
|
-
console.log(chalk.gray('Generating comprehensive test suites for components\n'));
|
|
276
|
-
|
|
277
|
-
// Parse and validate parameters
|
|
278
|
-
const config = await this.parseParameters(params);
|
|
279
|
-
|
|
280
|
-
// Initialize dependencies
|
|
281
|
-
await this.initializeDependencies();
|
|
282
|
-
|
|
283
|
-
// Analyze target components
|
|
284
|
-
const components = await this.identifyTargetComponents(config);
|
|
285
|
-
if (components.length === 0) {
|
|
286
|
-
throw new Error('No components found matching the criteria');
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
console.log(chalk.gray(`Found ${components.length} component(s) for test generation`));
|
|
290
|
-
|
|
291
|
-
// Generate test plan
|
|
292
|
-
const testPlan = await this.generateTestPlan(components, config);
|
|
293
|
-
|
|
294
|
-
// Display test generation summary
|
|
295
|
-
await this.displayTestGenerationSummary(testPlan);
|
|
296
|
-
|
|
297
|
-
// Request confirmation
|
|
298
|
-
const confirmed = await this.requestConfirmation(testPlan);
|
|
299
|
-
if (!confirmed) {
|
|
300
|
-
console.log(chalk.gray('Test generation cancelled'));
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Execute test generation
|
|
305
|
-
const generationResults = await this.executeTestGeneration(testPlan);
|
|
306
|
-
|
|
307
|
-
// Analyze generated tests
|
|
308
|
-
const analysisResults = await this.analyzeGeneratedTests(generationResults);
|
|
309
|
-
|
|
310
|
-
// Update existing test documentation
|
|
311
|
-
await this.updateTestDocumentation(generationResults);
|
|
312
|
-
|
|
313
|
-
// Display success summary
|
|
314
|
-
console.log(chalk.green('\n✅ Test generation completed successfully'));
|
|
315
|
-
console.log(chalk.gray(` Components tested: ${components.length}`));
|
|
316
|
-
console.log(chalk.gray(` Test files generated: ${generationResults.testFilesGenerated}`));
|
|
317
|
-
console.log(chalk.gray(` Expected coverage: ${analysisResults.expectedCoverage}%`));
|
|
318
|
-
console.log(chalk.gray(` Quality score: ${analysisResults.qualityScore}/10`));
|
|
319
|
-
|
|
320
|
-
return {
|
|
321
|
-
success: true,
|
|
322
|
-
components: components.length,
|
|
323
|
-
testFilesGenerated: generationResults.testFilesGenerated,
|
|
324
|
-
expectedCoverage: analysisResults.expectedCoverage,
|
|
325
|
-
qualityScore: analysisResults.qualityScore
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
} catch (error) {
|
|
329
|
-
console.error(chalk.red(`\n❌ Test generation failed: ${error.message}`));
|
|
330
|
-
throw error;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
async parseParameters(params) {
|
|
335
|
-
if (params.length < 2 && params[0] !== 'all') {
|
|
336
|
-
throw new Error('Usage: *generate-tests <component-type> <component-name> [options]');
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
const config = {
|
|
340
|
-
componentType: params[0],
|
|
341
|
-
componentName: params[1] || null,
|
|
342
|
-
testType: 'unit',
|
|
343
|
-
coverageTarget: 80,
|
|
344
|
-
framework: 'jest',
|
|
345
|
-
mockLevel: 'moderate',
|
|
346
|
-
updateExisting: false,
|
|
347
|
-
qualityLevel: 'standard',
|
|
348
|
-
outputDir: null,
|
|
349
|
-
generateAll: params[0] === 'all'
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
// Parse options
|
|
353
|
-
for (let i = 2; i < params.length; i++) {
|
|
354
|
-
const param = params[i];
|
|
355
|
-
|
|
356
|
-
if (param === '--update-existing') {
|
|
357
|
-
config.updateExisting = true;
|
|
358
|
-
} else if (param.startsWith('--test-type') && params[i + 1]) {
|
|
359
|
-
config.testType = params[++i];
|
|
360
|
-
} else if (param.startsWith('--coverage-target') && params[i + 1]) {
|
|
361
|
-
config.coverageTarget = parseInt(params[++i]) || 80;
|
|
362
|
-
} else if (param.startsWith('--framework') && params[i + 1]) {
|
|
363
|
-
config.framework = params[++i];
|
|
364
|
-
} else if (param.startsWith('--mock-level') && params[i + 1]) {
|
|
365
|
-
config.mockLevel = params[++i];
|
|
366
|
-
} else if (param.startsWith('--quality-level') && params[i + 1]) {
|
|
367
|
-
config.qualityLevel = params[++i];
|
|
368
|
-
} else if (param.startsWith('--output-dir') && params[i + 1]) {
|
|
369
|
-
config.outputDir = params[++i];
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// Validation
|
|
374
|
-
if (!config.generateAll) {
|
|
375
|
-
const validTypes = ['agent', 'task', 'workflow', 'util'];
|
|
376
|
-
if (!validTypes.includes(config.componentType)) {
|
|
377
|
-
throw new Error(`Invalid component type: ${config.componentType}. Must be one of: ${validTypes.join(', ')}`);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
const validTestTypes = ['unit', 'integration', 'e2e', 'all'];
|
|
382
|
-
if (!validTestTypes.includes(config.testType)) {
|
|
383
|
-
throw new Error(`Invalid test type: ${config.testType}. Must be one of: ${validTestTypes.join(', ')}`);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
const validFrameworks = ['jest', 'mocha', 'vitest'];
|
|
387
|
-
if (!validFrameworks.includes(config.framework)) {
|
|
388
|
-
throw new Error(`Invalid framework: ${config.framework}. Must be one of: ${validFrameworks.join(', ')}`);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
const validMockLevels = ['minimal', 'moderate', 'extensive'];
|
|
392
|
-
if (!validMockLevels.includes(config.mockLevel)) {
|
|
393
|
-
throw new Error(`Invalid mock level: ${config.mockLevel}. Must be one of: ${validMockLevels.join(', ')}`);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
const validQualityLevels = ['basic', 'standard', 'comprehensive'];
|
|
397
|
-
if (!validQualityLevels.includes(config.qualityLevel)) {
|
|
398
|
-
throw new Error(`Invalid quality level: ${config.qualityLevel}. Must be one of: ${validQualityLevels.join(', ')}`);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
if (config.coverageTarget < 0 || config.coverageTarget > 100) {
|
|
402
|
-
throw new Error('Coverage target must be between 0 and 100');
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
return config;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
async initializeDependencies() {
|
|
409
|
-
try {
|
|
410
|
-
// Initialize test template system
|
|
411
|
-
const TestTemplateSystem = require('../scripts/test-template-system');
|
|
412
|
-
this.testTemplateSystem = new TestTemplateSystem({ rootPath: this.rootPath });
|
|
413
|
-
await this.testTemplateSystem.initialize();
|
|
414
|
-
|
|
415
|
-
// Initialize test generator
|
|
416
|
-
const TestGenerator = require('../scripts/test-generator');
|
|
417
|
-
this.testGenerator = new TestGenerator({
|
|
418
|
-
rootPath: this.rootPath,
|
|
419
|
-
templateSystem: this.testTemplateSystem
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
// Initialize coverage analyzer
|
|
423
|
-
const CoverageAnalyzer = require('../scripts/coverage-analyzer');
|
|
424
|
-
this.coverageAnalyzer = new CoverageAnalyzer({ rootPath: this.rootPath });
|
|
425
|
-
|
|
426
|
-
// Initialize quality assessment
|
|
427
|
-
const TestQualityAssessment = require('../scripts/test-quality-assessment');
|
|
428
|
-
this.qualityAssessment = new TestQualityAssessment({ rootPath: this.rootPath });
|
|
429
|
-
|
|
430
|
-
} catch (error) {
|
|
431
|
-
throw new Error(`Failed to initialize dependencies: ${error.message}`);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
async identifyTargetComponents(config) {
|
|
436
|
-
const components = [];
|
|
437
|
-
|
|
438
|
-
if (config.generateAll) {
|
|
439
|
-
// Find all components in the framework
|
|
440
|
-
const allComponents = await this.discoverAllComponents();
|
|
441
|
-
components.push(...allComponents);
|
|
442
|
-
} else {
|
|
443
|
-
// Find specific component
|
|
444
|
-
const ComponentSearch = require('../scripts/component-search');
|
|
445
|
-
const componentSearch = new ComponentSearch({ rootPath: this.rootPath });
|
|
446
|
-
|
|
447
|
-
const component = await componentSearch.findComponent(config.componentType, config.componentName);
|
|
448
|
-
if (!component) {
|
|
449
|
-
// Suggest similar components
|
|
450
|
-
const suggestions = await componentSearch.findSimilarComponents(config.componentType, config.componentName);
|
|
451
|
-
if (suggestions.length > 0) {
|
|
452
|
-
console.log(chalk.yellow('\nDid you mean one of these?'));
|
|
453
|
-
suggestions.forEach(suggestion => {
|
|
454
|
-
console.log(chalk.gray(` - ${suggestion.type}/${suggestion.name}`));
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
throw new Error(`Component not found: ${config.componentType}/${config.componentName}`);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
components.push(component);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
return components;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
async discoverAllComponents() {
|
|
467
|
-
const components = [];
|
|
468
|
-
const componentTypes = ['agents', 'tasks', 'workflows', 'utils'];
|
|
469
|
-
|
|
470
|
-
for (const type of componentTypes) {
|
|
471
|
-
const typeDir = path.join(this.rootPath, 'aios-core', type);
|
|
472
|
-
|
|
473
|
-
try {
|
|
474
|
-
const files = await fs.readdir(typeDir);
|
|
475
|
-
|
|
476
|
-
for (const file of files) {
|
|
477
|
-
const filePath = path.join(typeDir, file);
|
|
478
|
-
const stats = await fs.stat(filePath);
|
|
479
|
-
|
|
480
|
-
if (stats.isFile()) {
|
|
481
|
-
const componentType = type.slice(0, -1); // Remove 's' from plural
|
|
482
|
-
const componentName = path.basename(file, path.extname(file));
|
|
483
|
-
|
|
484
|
-
components.push({
|
|
485
|
-
id: `${componentType}/${componentName}`,
|
|
486
|
-
type: componentType,
|
|
487
|
-
name: componentName,
|
|
488
|
-
filePath: filePath
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
} catch (error) {
|
|
493
|
-
// Directory doesn't exist, skip
|
|
494
|
-
continue;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
return components;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
async generateTestPlan(components, config) {
|
|
502
|
-
const testPlan = {
|
|
503
|
-
generation_id: `test-gen-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`,
|
|
504
|
-
components: components,
|
|
505
|
-
config: config,
|
|
506
|
-
test_suites: [],
|
|
507
|
-
estimated_duration: 0,
|
|
508
|
-
expected_files: 0,
|
|
509
|
-
quality_targets: {}
|
|
510
|
-
};
|
|
511
|
-
|
|
512
|
-
console.log(chalk.gray('Analyzing components and generating test plan...'));
|
|
513
|
-
|
|
514
|
-
for (const component of components) {
|
|
515
|
-
const componentAnalysis = await this.analyzeComponentForTesting(component, config);
|
|
516
|
-
const testSuite = await this.planTestSuite(component, componentAnalysis, config);
|
|
517
|
-
|
|
518
|
-
testPlan.test_suites.push(testSuite);
|
|
519
|
-
testPlan.estimated_duration += testSuite.estimated_duration;
|
|
520
|
-
testPlan.expected_files += testSuite.test_files.length;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// Set quality targets
|
|
524
|
-
testPlan.quality_targets = {
|
|
525
|
-
coverage_target: config.coverageTarget,
|
|
526
|
-
quality_level: config.qualityLevel,
|
|
527
|
-
mock_coverage: this.calculateMockCoverage(config.mockLevel),
|
|
528
|
-
assertion_density: this.calculateAssertionDensity(config.qualityLevel)
|
|
529
|
-
};
|
|
530
|
-
|
|
531
|
-
return testPlan;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
async analyzeComponentForTesting(component, config) {
|
|
535
|
-
const analysis = {
|
|
536
|
-
component_id: component.id,
|
|
537
|
-
complexity: 'medium',
|
|
538
|
-
dependencies: [],
|
|
539
|
-
external_dependencies: [],
|
|
540
|
-
testable_functions: [],
|
|
541
|
-
edge_cases: [],
|
|
542
|
-
mock_requirements: [],
|
|
543
|
-
existing_tests: null
|
|
544
|
-
};
|
|
545
|
-
|
|
546
|
-
try {
|
|
547
|
-
// Read component file
|
|
548
|
-
const content = await fs.readFile(component.filePath, 'utf-8');
|
|
549
|
-
|
|
550
|
-
// Analyze component complexity
|
|
551
|
-
analysis.complexity = this.assessComplexity(content, component.type);
|
|
552
|
-
|
|
553
|
-
// Identify dependencies
|
|
554
|
-
analysis.dependencies = this.extractDependencies(content, component.type);
|
|
555
|
-
analysis.external_dependencies = this.extractExternalDependencies(content);
|
|
556
|
-
|
|
557
|
-
// Identify testable functions/methods
|
|
558
|
-
analysis.testable_functions = this.extractTestableFunctions(content, component.type);
|
|
559
|
-
|
|
560
|
-
// Identify edge cases
|
|
561
|
-
analysis.edge_cases = this.identifyEdgeCases(content, component.type);
|
|
562
|
-
|
|
563
|
-
// Determine mock requirements
|
|
564
|
-
analysis.mock_requirements = this.determineMockRequirements(analysis, config.mockLevel);
|
|
565
|
-
|
|
566
|
-
// Check for existing tests
|
|
567
|
-
analysis.existing_tests = await this.findExistingTests(component);
|
|
568
|
-
|
|
569
|
-
} catch (error) {
|
|
570
|
-
console.warn(chalk.yellow(`Failed to analyze ${component.id}: ${error.message}`));
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
return analysis;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
async planTestSuite(component, analysis, config) {
|
|
577
|
-
const testSuite = {
|
|
578
|
-
component_id: component.id,
|
|
579
|
-
component_type: component.type,
|
|
580
|
-
test_files: [],
|
|
581
|
-
total_tests: 0,
|
|
582
|
-
estimated_duration: 0,
|
|
583
|
-
coverage_plan: {},
|
|
584
|
-
quality_metrics: {}
|
|
585
|
-
};
|
|
586
|
-
|
|
587
|
-
// Plan different types of tests based on config
|
|
588
|
-
if (config.testType === 'unit' || config.testType === 'all') {
|
|
589
|
-
const unitTestFile = await this.planUnitTests(component, analysis, config);
|
|
590
|
-
testSuite.test_files.push(unitTestFile);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
if (config.testType === 'integration' || config.testType === 'all') {
|
|
594
|
-
const integrationTestFile = await this.planIntegrationTests(component, analysis, config);
|
|
595
|
-
if (integrationTestFile) {
|
|
596
|
-
testSuite.test_files.push(integrationTestFile);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
if (config.testType === 'e2e' || config.testType === 'all') {
|
|
601
|
-
const e2eTestFile = await this.planE2ETests(component, analysis, config);
|
|
602
|
-
if (e2eTestFile) {
|
|
603
|
-
testSuite.test_files.push(e2eTestFile);
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// Calculate totals
|
|
608
|
-
testSuite.total_tests = testSuite.test_files.reduce((sum, file) => sum + file.test_count, 0);
|
|
609
|
-
testSuite.estimated_duration = testSuite.test_files.reduce((sum, file) => sum + file.estimated_duration, 0);
|
|
610
|
-
|
|
611
|
-
// Plan coverage
|
|
612
|
-
testSuite.coverage_plan = {
|
|
613
|
-
target_percentage: config.coverageTarget,
|
|
614
|
-
lines_to_cover: analysis.testable_functions.length * 5, // Estimate
|
|
615
|
-
assertions_planned: testSuite.total_tests * this.calculateAssertionDensity(config.qualityLevel)
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
return testSuite;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
async planUnitTests(component, analysis, config) {
|
|
622
|
-
const testFile = {
|
|
623
|
-
file_path: this.generateTestFilePath(component, 'unit', config),
|
|
624
|
-
test_type: 'unit',
|
|
625
|
-
test_count: 0,
|
|
626
|
-
estimated_duration: 0,
|
|
627
|
-
test_cases: [],
|
|
628
|
-
mocks_required: [],
|
|
629
|
-
setup_requirements: []
|
|
630
|
-
};
|
|
631
|
-
|
|
632
|
-
// Generate test cases for each testable function
|
|
633
|
-
for (const func of analysis.testable_functions) {
|
|
634
|
-
const testCases = await this.generateFunctionTestCases(func, analysis, config);
|
|
635
|
-
testFile.test_cases.push(...testCases);
|
|
636
|
-
testFile.test_count += testCases.length;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// Add edge case tests
|
|
640
|
-
for (const edgeCase of analysis.edge_cases) {
|
|
641
|
-
const edgeCaseTest = await this.generateEdgeCaseTest(edgeCase, analysis, config);
|
|
642
|
-
testFile.test_cases.push(edgeCaseTest);
|
|
643
|
-
testFile.test_count++;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
// Determine mocks required
|
|
647
|
-
testFile.mocks_required = analysis.mock_requirements.filter(mock => mock.level !== 'none');
|
|
648
|
-
|
|
649
|
-
// Calculate estimated duration
|
|
650
|
-
testFile.estimated_duration = testFile.test_count * 2; // 2 minutes per test case
|
|
651
|
-
|
|
652
|
-
return testFile;
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
async planIntegrationTests(component, analysis, config) {
|
|
656
|
-
// Skip integration tests for simple components
|
|
657
|
-
if (analysis.complexity === 'low' && analysis.dependencies.length === 0) {
|
|
658
|
-
return null;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
const testFile = {
|
|
662
|
-
file_path: this.generateTestFilePath(component, 'integration', config),
|
|
663
|
-
test_type: 'integration',
|
|
664
|
-
test_count: 0,
|
|
665
|
-
estimated_duration: 0,
|
|
666
|
-
test_cases: [],
|
|
667
|
-
integration_scenarios: [],
|
|
668
|
-
setup_requirements: ['test database', 'mock services']
|
|
669
|
-
};
|
|
670
|
-
|
|
671
|
-
// Generate integration scenarios
|
|
672
|
-
testFile.integration_scenarios = await this.generateIntegrationScenarios(component, analysis);
|
|
673
|
-
testFile.test_count = testFile.integration_scenarios.length;
|
|
674
|
-
testFile.estimated_duration = testFile.test_count * 5; // 5 minutes per integration test
|
|
675
|
-
|
|
676
|
-
return testFile;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
async planE2ETests(component, analysis, config) {
|
|
680
|
-
// Only generate E2E tests for workflows and certain tasks
|
|
681
|
-
if (component.type !== 'workflow' && component.type !== 'task') {
|
|
682
|
-
return null;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
const testFile = {
|
|
686
|
-
file_path: this.generateTestFilePath(component, 'e2e', config),
|
|
687
|
-
test_type: 'e2e',
|
|
688
|
-
test_count: 0,
|
|
689
|
-
estimated_duration: 0,
|
|
690
|
-
test_scenarios: [],
|
|
691
|
-
setup_requirements: ['full system', 'test data']
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
// Generate E2E scenarios
|
|
695
|
-
testFile.test_scenarios = await this.generateE2EScenarios(component, analysis);
|
|
696
|
-
testFile.test_count = testFile.test_scenarios.length;
|
|
697
|
-
testFile.estimated_duration = testFile.test_count * 10; // 10 minutes per E2E test
|
|
698
|
-
|
|
699
|
-
return testFile;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
generateTestFilePath(component, testType, config) {
|
|
703
|
-
const baseDir = config.outputDir || path.join(this.rootPath, 'tests');
|
|
704
|
-
const typeDir = testType === 'unit' ? 'unit' : testType === 'integration' ? 'integration' : 'e2e';
|
|
705
|
-
const componentDir = component.type === 'util' ? 'utils' : component.type;
|
|
706
|
-
|
|
707
|
-
const fileName = `${component.name}.${testType}.test.js`;
|
|
708
|
-
return path.join(baseDir, typeDir, componentDir, fileName);
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
async displayTestGenerationSummary(testPlan) {
|
|
712
|
-
console.log(chalk.blue('\n📋 Test Generation Plan'));
|
|
713
|
-
console.log(chalk.gray('━'.repeat(50)));
|
|
714
|
-
|
|
715
|
-
console.log(`Components: ${chalk.white(testPlan.components.length)}`);
|
|
716
|
-
console.log(`Test suites: ${chalk.white(testPlan.test_suites.length)}`);
|
|
717
|
-
console.log(`Expected test files: ${chalk.white(testPlan.expected_files)}`);
|
|
718
|
-
console.log(`Total tests planned: ${chalk.white(testPlan.test_suites.reduce((sum, suite) => sum + suite.total_tests, 0))}`);
|
|
719
|
-
console.log(`Coverage target: ${chalk.white(testPlan.config.coverageTarget)}%`);
|
|
720
|
-
console.log(`Quality level: ${chalk.white(testPlan.config.qualityLevel)}`);
|
|
721
|
-
console.log(`Estimated duration: ${chalk.white(Math.round(testPlan.estimated_duration / 60))} hours`);
|
|
722
|
-
|
|
723
|
-
console.log(chalk.blue('\nTest Suites:'));
|
|
724
|
-
testPlan.test_suites.forEach((suite, index) => {
|
|
725
|
-
console.log(` ${index + 1}. ${suite.component_id} (${suite.total_tests} tests)`);
|
|
726
|
-
});
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
async requestConfirmation(testPlan) {
|
|
730
|
-
const { confirmed } = await inquirer.prompt([{
|
|
731
|
-
type: 'confirm',
|
|
732
|
-
name: 'confirmed',
|
|
733
|
-
message: `Generate ${testPlan.expected_files} test files for ${testPlan.components.length} components?`,
|
|
734
|
-
default: true
|
|
735
|
-
}]);
|
|
736
|
-
|
|
737
|
-
return confirmed;
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
async executeTestGeneration(testPlan) {
|
|
741
|
-
const results = {
|
|
742
|
-
testFilesGenerated: 0,
|
|
743
|
-
testsGenerated: 0,
|
|
744
|
-
errors: [],
|
|
745
|
-
generated_files: []
|
|
746
|
-
};
|
|
747
|
-
|
|
748
|
-
console.log(chalk.gray('\nGenerating test files...'));
|
|
749
|
-
|
|
750
|
-
for (const testSuite of testPlan.test_suites) {
|
|
751
|
-
try {
|
|
752
|
-
const component = testPlan.components.find(c => c.id === testSuite.component_id);
|
|
753
|
-
|
|
754
|
-
for (const testFile of testSuite.test_files) {
|
|
755
|
-
console.log(chalk.gray(` Generating ${testFile.test_type} tests for ${component.name}...`));
|
|
756
|
-
|
|
757
|
-
const generatedContent = await this.testGenerator.generateTestFile(
|
|
758
|
-
component,
|
|
759
|
-
testFile,
|
|
760
|
-
testPlan.config
|
|
761
|
-
);
|
|
762
|
-
|
|
763
|
-
// Ensure directory exists
|
|
764
|
-
await fs.mkdir(path.dirname(testFile.file_path), { recursive: true });
|
|
765
|
-
|
|
766
|
-
// Write test file
|
|
767
|
-
if (testPlan.config.updateExisting || !(await this.fileExists(testFile.file_path))) {
|
|
768
|
-
await fs.writeFile(testFile.file_path, generatedContent);
|
|
769
|
-
results.testFilesGenerated++;
|
|
770
|
-
results.testsGenerated += testFile.test_count;
|
|
771
|
-
results.generated_files.push(testFile.file_path);
|
|
772
|
-
|
|
773
|
-
console.log(chalk.green(` ✓ Generated ${testFile.file_path}`));
|
|
774
|
-
} else {
|
|
775
|
-
console.log(chalk.yellow(` ⚠ Skipped ${testFile.file_path} (already exists)`));
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
} catch (error) {
|
|
780
|
-
results.errors.push({
|
|
781
|
-
component_id: testSuite.component_id,
|
|
782
|
-
error: error.message
|
|
783
|
-
});
|
|
784
|
-
console.error(chalk.red(` ✗ Failed to generate tests for ${testSuite.component_id}: ${error.message}`));
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
return results;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
async analyzeGeneratedTests(generationResults) {
|
|
792
|
-
const analysis = {
|
|
793
|
-
expectedCoverage: 0,
|
|
794
|
-
qualityScore: 0,
|
|
795
|
-
testDistribution: {},
|
|
796
|
-
recommendations: []
|
|
797
|
-
};
|
|
798
|
-
|
|
799
|
-
if (generationResults.testFilesGenerated > 0) {
|
|
800
|
-
// Analyze each generated test file
|
|
801
|
-
for (const filePath of generationResults.generated_files) {
|
|
802
|
-
try {
|
|
803
|
-
const testAnalysis = await this.qualityAssessment.analyzeSingleTestFile(filePath);
|
|
804
|
-
analysis.expectedCoverage += testAnalysis.estimatedCoverage || 0;
|
|
805
|
-
analysis.qualityScore += testAnalysis.qualityScore || 0;
|
|
806
|
-
} catch (error) {
|
|
807
|
-
console.warn(chalk.yellow(`Failed to analyze ${filePath}: ${error.message}`));
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
// Calculate averages
|
|
812
|
-
analysis.expectedCoverage = Math.round(analysis.expectedCoverage / generationResults.testFilesGenerated);
|
|
813
|
-
analysis.qualityScore = Math.round((analysis.qualityScore / generationResults.testFilesGenerated) * 10) / 10;
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
return analysis;
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
async updateTestDocumentation(generationResults) {
|
|
820
|
-
// Update test documentation with newly generated tests
|
|
821
|
-
const testDocs = {
|
|
822
|
-
generated_at: new Date().toISOString(),
|
|
823
|
-
test_files: generationResults.generated_files,
|
|
824
|
-
total_tests: generationResults.testsGenerated,
|
|
825
|
-
generation_notes: 'Auto-generated by AIOS test generation system'
|
|
826
|
-
};
|
|
827
|
-
|
|
828
|
-
const docsPath = path.join(this.rootPath, 'docs', 'testing', 'auto-generated-tests.json');
|
|
829
|
-
|
|
830
|
-
try {
|
|
831
|
-
await fs.mkdir(path.dirname(docsPath), { recursive: true });
|
|
832
|
-
await fs.writeFile(docsPath, JSON.stringify(testDocs, null, 2));
|
|
833
|
-
} catch (error) {
|
|
834
|
-
console.warn(chalk.yellow(`Failed to update test documentation: ${error.message}`));
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
// Helper methods
|
|
839
|
-
|
|
840
|
-
async fileExists(filePath) {
|
|
841
|
-
try {
|
|
842
|
-
await fs.access(filePath);
|
|
843
|
-
return true;
|
|
844
|
-
} catch {
|
|
845
|
-
return false;
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
assessComplexity(content, componentType) {
|
|
850
|
-
// Simple heuristic for complexity assessment
|
|
851
|
-
const lines = content.split('\n').length;
|
|
852
|
-
const functions = (content.match(/function|=>/g) || []).length;
|
|
853
|
-
const conditions = (content.match(/if|switch|for|while/g) || []).length;
|
|
854
|
-
|
|
855
|
-
const complexityScore = (lines / 10) + (functions * 2) + (conditions * 3);
|
|
856
|
-
|
|
857
|
-
if (complexityScore > 50) return 'high';
|
|
858
|
-
if (complexityScore > 20) return 'medium';
|
|
859
|
-
return 'low';
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
extractDependencies(content, componentType) {
|
|
863
|
-
const dependencies = [];
|
|
864
|
-
|
|
865
|
-
// Extract require/import statements
|
|
866
|
-
const requireMatches = content.match(/require\(['"]([^'"]+)['"]\)/g) || [];
|
|
867
|
-
const importMatches = content.match(/import .+ from ['"]([^'"]+)['"]/g) || [];
|
|
868
|
-
|
|
869
|
-
requireMatches.forEach(match => {
|
|
870
|
-
const dep = match.match(/require\(['"]([^'"]+)['"]\)/)[1];
|
|
871
|
-
if (dep.startsWith('./') || dep.startsWith('../')) {
|
|
872
|
-
dependencies.push(dep);
|
|
873
|
-
}
|
|
874
|
-
});
|
|
875
|
-
|
|
876
|
-
importMatches.forEach(match => {
|
|
877
|
-
const dep = match.match(/from ['"]([^'"]+)['"]/)[1];
|
|
878
|
-
if (dep.startsWith('./') || dep.startsWith('../')) {
|
|
879
|
-
dependencies.push(dep);
|
|
880
|
-
}
|
|
881
|
-
});
|
|
882
|
-
|
|
883
|
-
return dependencies;
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
extractExternalDependencies(content) {
|
|
887
|
-
const externalDeps = [];
|
|
888
|
-
|
|
889
|
-
const requireMatches = content.match(/require\(['"]([^'"]+)['"]\)/g) || [];
|
|
890
|
-
const importMatches = content.match(/import .+ from ['"]([^'"]+)['"]/g) || [];
|
|
891
|
-
|
|
892
|
-
requireMatches.forEach(match => {
|
|
893
|
-
const dep = match.match(/require\(['"]([^'"]+)['"]\)/)[1];
|
|
894
|
-
if (!dep.startsWith('./') && !dep.startsWith('../') && !dep.startsWith('node:')) {
|
|
895
|
-
externalDeps.push(dep);
|
|
896
|
-
}
|
|
897
|
-
});
|
|
898
|
-
|
|
899
|
-
importMatches.forEach(match => {
|
|
900
|
-
const dep = match.match(/from ['"]([^'"]+)['"]/)[1];
|
|
901
|
-
if (!dep.startsWith('./') && !dep.startsWith('../') && !dep.startsWith('node:')) {
|
|
902
|
-
externalDeps.push(dep);
|
|
903
|
-
}
|
|
904
|
-
});
|
|
905
|
-
|
|
906
|
-
return [...new Set(externalDeps)]; // Remove duplicates
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
extractTestableFunctions(content, componentType) {
|
|
910
|
-
const functions = [];
|
|
911
|
-
|
|
912
|
-
// Extract function declarations and expressions
|
|
913
|
-
const functionMatches = content.match(/(?:function\s+(\w+)|(\w+)\s*[:=]\s*(?:async\s+)?function|(\w+)\s*[:=]\s*(?:async\s+)?\([^)]*\)\s*=>)/g) || [];
|
|
914
|
-
|
|
915
|
-
functionMatches.forEach(match => {
|
|
916
|
-
let functionName = null;
|
|
917
|
-
|
|
918
|
-
if (match.includes('function ')) {
|
|
919
|
-
functionName = match.match(/function\s+(\w+)/)?.[1];
|
|
920
|
-
} else {
|
|
921
|
-
functionName = match.match(/(\w+)\s*[:=]/)?.[1];
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
if (functionName && !functionName.startsWith('_')) {
|
|
925
|
-
functions.push({
|
|
926
|
-
name: functionName,
|
|
927
|
-
type: 'function',
|
|
928
|
-
visibility: 'public'
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
});
|
|
932
|
-
|
|
933
|
-
return functions;
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
identifyEdgeCases(content, componentType) {
|
|
937
|
-
const edgeCases = [];
|
|
938
|
-
|
|
939
|
-
// Look for common edge case patterns
|
|
940
|
-
if (content.includes('null') || content.includes('undefined')) {
|
|
941
|
-
edgeCases.push({ type: 'null_undefined', description: 'Handle null/undefined values' });
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
if (content.includes('length') || content.includes('size')) {
|
|
945
|
-
edgeCases.push({ type: 'empty_collections', description: 'Handle empty arrays/objects' });
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
if (content.includes('catch') || content.includes('throw')) {
|
|
949
|
-
edgeCases.push({ type: 'error_handling', description: 'Test error conditions' });
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
if (content.includes('async') || content.includes('await')) {
|
|
953
|
-
edgeCases.push({ type: 'async_operations', description: 'Test async operation failures' });
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
return edgeCases;
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
determineMockRequirements(analysis, mockLevel) {
|
|
960
|
-
const mocks = [];
|
|
961
|
-
|
|
962
|
-
if (mockLevel === 'minimal') {
|
|
963
|
-
// Only mock external dependencies
|
|
964
|
-
analysis.external_dependencies.forEach(dep => {
|
|
965
|
-
mocks.push({ type: 'external', target: dep, level: 'full' });
|
|
966
|
-
});
|
|
967
|
-
} else if (mockLevel === 'moderate') {
|
|
968
|
-
// Mock external dependencies and some internal ones
|
|
969
|
-
analysis.external_dependencies.forEach(dep => {
|
|
970
|
-
mocks.push({ type: 'external', target: dep, level: 'full' });
|
|
971
|
-
});
|
|
972
|
-
analysis.dependencies.slice(0, 3).forEach(dep => {
|
|
973
|
-
mocks.push({ type: 'internal', target: dep, level: 'partial' });
|
|
974
|
-
});
|
|
975
|
-
} else if (mockLevel === 'extensive') {
|
|
976
|
-
// Mock everything possible
|
|
977
|
-
analysis.external_dependencies.forEach(dep => {
|
|
978
|
-
mocks.push({ type: 'external', target: dep, level: 'full' });
|
|
979
|
-
});
|
|
980
|
-
analysis.dependencies.forEach(dep => {
|
|
981
|
-
mocks.push({ type: 'internal', target: dep, level: 'full' });
|
|
982
|
-
});
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
return mocks;
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
async findExistingTests(component) {
|
|
989
|
-
const possibleTestPaths = [
|
|
990
|
-
path.join(this.rootPath, 'tests', 'unit', component.type, `${component.name}.test.js`),
|
|
991
|
-
path.join(this.rootPath, 'tests', 'unit', component.type, `${component.name}.spec.js`),
|
|
992
|
-
path.join(this.rootPath, 'test', `${component.name}.test.js`),
|
|
993
|
-
path.join(this.rootPath, '__tests__', `${component.name}.test.js`)
|
|
994
|
-
];
|
|
995
|
-
|
|
996
|
-
for (const testPath of possibleTestPaths) {
|
|
997
|
-
if (await this.fileExists(testPath)) {
|
|
998
|
-
return {
|
|
999
|
-
path: testPath,
|
|
1000
|
-
exists: true
|
|
1001
|
-
};
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
return { exists: false };
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
calculateMockCoverage(mockLevel) {
|
|
1009
|
-
const coverage = {
|
|
1010
|
-
minimal: 30,
|
|
1011
|
-
moderate: 60,
|
|
1012
|
-
extensive: 90
|
|
1013
|
-
};
|
|
1014
|
-
return coverage[mockLevel] || 60;
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
calculateAssertionDensity(qualityLevel) {
|
|
1018
|
-
const density = {
|
|
1019
|
-
basic: 2,
|
|
1020
|
-
standard: 4,
|
|
1021
|
-
comprehensive: 6
|
|
1022
|
-
};
|
|
1023
|
-
return density[qualityLevel] || 4;
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
async generateFunctionTestCases(func, analysis, config) {
|
|
1027
|
-
// This would generate test cases based on function analysis
|
|
1028
|
-
// For now, return basic test case structure
|
|
1029
|
-
return [
|
|
1030
|
-
{
|
|
1031
|
-
name: `should ${func.name} successfully`,
|
|
1032
|
-
type: 'success_case',
|
|
1033
|
-
description: `Test successful execution of ${func.name}`,
|
|
1034
|
-
assertions: config.qualityLevel === 'comprehensive' ? 3 : 2
|
|
1035
|
-
},
|
|
1036
|
-
{
|
|
1037
|
-
name: `should handle ${func.name} errors`,
|
|
1038
|
-
type: 'error_case',
|
|
1039
|
-
description: `Test error handling in ${func.name}`,
|
|
1040
|
-
assertions: 2
|
|
1041
|
-
}
|
|
1042
|
-
];
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
async generateEdgeCaseTest(edgeCase, analysis, config) {
|
|
1046
|
-
return {
|
|
1047
|
-
name: `should handle ${edgeCase.type}`,
|
|
1048
|
-
type: 'edge_case',
|
|
1049
|
-
description: edgeCase.description,
|
|
1050
|
-
assertions: 1
|
|
1051
|
-
};
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
async generateIntegrationScenarios(component, analysis) {
|
|
1055
|
-
// Generate integration test scenarios based on component dependencies
|
|
1056
|
-
const scenarios = [];
|
|
1057
|
-
|
|
1058
|
-
if (analysis.dependencies.length > 0) {
|
|
1059
|
-
scenarios.push({
|
|
1060
|
-
name: 'should integrate with dependencies',
|
|
1061
|
-
description: 'Test integration with internal dependencies',
|
|
1062
|
-
dependencies: analysis.dependencies.slice(0, 3)
|
|
1063
|
-
});
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
if (analysis.external_dependencies.length > 0) {
|
|
1067
|
-
scenarios.push({
|
|
1068
|
-
name: 'should integrate with external services',
|
|
1069
|
-
description: 'Test integration with external dependencies',
|
|
1070
|
-
dependencies: analysis.external_dependencies.slice(0, 2)
|
|
1071
|
-
});
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
return scenarios;
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
async generateE2EScenarios(component, analysis) {
|
|
1078
|
-
const scenarios = [];
|
|
1079
|
-
|
|
1080
|
-
if (component.type === 'workflow') {
|
|
1081
|
-
scenarios.push({
|
|
1082
|
-
name: 'should complete full workflow',
|
|
1083
|
-
description: 'Test complete workflow execution end-to-end',
|
|
1084
|
-
steps: ['initialize', 'execute', 'validate', 'cleanup']
|
|
1085
|
-
});
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
if (component.type === 'task') {
|
|
1089
|
-
scenarios.push({
|
|
1090
|
-
name: 'should execute task end-to-end',
|
|
1091
|
-
description: 'Test complete task execution with real dependencies',
|
|
1092
|
-
steps: ['setup', 'execute', 'verify_output']
|
|
1093
|
-
});
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
return scenarios;
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
module.exports = GenerateTestsTask;
|
|
1101
|
-
```
|
|
1102
|
-
|
|
1103
|
-
## Validation Rules
|
|
1104
|
-
|
|
1105
|
-
### Input Validation
|
|
1106
|
-
- Component type must be valid or 'all' for bulk generation
|
|
1107
|
-
- Coverage target must be 0-100%
|
|
1108
|
-
- Test framework must be supported
|
|
1109
|
-
- Quality level must be recognized
|
|
1110
|
-
|
|
1111
|
-
### Safety Checks
|
|
1112
|
-
- Don't overwrite existing tests without confirmation
|
|
1113
|
-
- Validate component exists before test generation
|
|
1114
|
-
- Ensure output directory is writable
|
|
1115
|
-
- Check for conflicting test frameworks
|
|
1116
|
-
|
|
1117
|
-
### Generation Requirements
|
|
1118
|
-
- Must generate syntactically valid test code
|
|
1119
|
-
- Should include appropriate setup/teardown
|
|
1120
|
-
- Must include meaningful test descriptions
|
|
1121
|
-
- Should follow testing best practices
|
|
1122
|
-
|
|
1123
|
-
## Integration Points
|
|
1124
|
-
|
|
1125
|
-
### Test Template System
|
|
1126
|
-
- Provides reusable test templates
|
|
1127
|
-
- Manages test code generation patterns
|
|
1128
|
-
- Handles framework-specific syntax
|
|
1129
|
-
- Supports custom test structures
|
|
1130
|
-
|
|
1131
|
-
### Test Generator
|
|
1132
|
-
- Orchestrates test file creation
|
|
1133
|
-
- Analyzes components for testable elements
|
|
1134
|
-
- Generates comprehensive test suites
|
|
1135
|
-
- Handles different test types (unit, integration, e2e)
|
|
1136
|
-
|
|
1137
|
-
### Coverage Analyzer
|
|
1138
|
-
- Analyzes existing test coverage
|
|
1139
|
-
- Identifies coverage gaps
|
|
1140
|
-
- Provides coverage metrics
|
|
1141
|
-
- Suggests coverage improvements
|
|
1142
|
-
|
|
1143
|
-
### Quality Assessment
|
|
1144
|
-
- Evaluates generated test quality
|
|
1145
|
-
- Provides quality metrics and scores
|
|
1146
|
-
- Identifies test improvement opportunities
|
|
1147
|
-
- Validates test effectiveness
|
|
1148
|
-
|
|
1149
|
-
## Output Structure
|
|
1150
|
-
|
|
1151
|
-
### Success Response
|
|
1152
|
-
```json
|
|
1153
|
-
{
|
|
1154
|
-
"success": true,
|
|
1155
|
-
"components": 5,
|
|
1156
|
-
"testFilesGenerated": 12,
|
|
1157
|
-
"expectedCoverage": 85,
|
|
1158
|
-
"qualityScore": 8.5
|
|
1159
|
-
}
|
|
1160
|
-
```
|
|
1161
|
-
|
|
1162
|
-
### Error Response
|
|
1163
|
-
```json
|
|
1164
|
-
{
|
|
1165
|
-
"success": false,
|
|
1166
|
-
"error": "Component not found: agent/invalid-name",
|
|
1167
|
-
"suggestions": ["weather-agent", "data-agent"]
|
|
1168
|
-
}
|
|
1169
|
-
```
|
|
1170
|
-
|
|
1171
|
-
## Security Considerations
|
|
1172
|
-
- Validate all file paths to prevent directory traversal
|
|
1173
|
-
- Sanitize component names and test descriptions
|
|
1174
|
-
- Ensure generated code doesn't include sensitive information
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
## Execution Modes
|
|
4
|
+
|
|
5
|
+
**Choose your execution mode:**
|
|
6
|
+
|
|
7
|
+
### 1. YOLO Mode - Fast, Autonomous (0-1 prompts)
|
|
8
|
+
- Autonomous decision making with logging
|
|
9
|
+
- Minimal user interaction
|
|
10
|
+
- **Best for:** Simple, deterministic tasks
|
|
11
|
+
|
|
12
|
+
### 2. Interactive Mode - Balanced, Educational (5-10 prompts) **[DEFAULT]**
|
|
13
|
+
- Explicit decision checkpoints
|
|
14
|
+
- Educational explanations
|
|
15
|
+
- **Best for:** Learning, complex decisions
|
|
16
|
+
|
|
17
|
+
### 3. Pre-Flight Planning - Comprehensive Upfront Planning
|
|
18
|
+
- Task analysis phase (identify all ambiguities)
|
|
19
|
+
- Zero ambiguity execution
|
|
20
|
+
- **Best for:** Ambiguous requirements, critical work
|
|
21
|
+
|
|
22
|
+
**Parameter:** `mode` (optional, default: `interactive`)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Task Definition (AIOS Task Format V1.0)
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
task: qaGenerateTests()
|
|
30
|
+
responsável: Quinn (Guardian)
|
|
31
|
+
responsavel_type: Agente
|
|
32
|
+
atomic_layer: Config
|
|
33
|
+
|
|
34
|
+
**Entrada:**
|
|
35
|
+
- campo: target
|
|
36
|
+
tipo: string
|
|
37
|
+
origem: User Input
|
|
38
|
+
obrigatório: true
|
|
39
|
+
validação: Must exist
|
|
40
|
+
|
|
41
|
+
- campo: criteria
|
|
42
|
+
tipo: array
|
|
43
|
+
origem: config
|
|
44
|
+
obrigatório: true
|
|
45
|
+
validação: Non-empty validation criteria
|
|
46
|
+
|
|
47
|
+
- campo: strict
|
|
48
|
+
tipo: boolean
|
|
49
|
+
origem: User Input
|
|
50
|
+
obrigatório: false
|
|
51
|
+
validação: Default: true
|
|
52
|
+
|
|
53
|
+
**Saída:**
|
|
54
|
+
- campo: validation_result
|
|
55
|
+
tipo: boolean
|
|
56
|
+
destino: Return value
|
|
57
|
+
persistido: false
|
|
58
|
+
|
|
59
|
+
- campo: errors
|
|
60
|
+
tipo: array
|
|
61
|
+
destino: Memory
|
|
62
|
+
persistido: false
|
|
63
|
+
|
|
64
|
+
- campo: report
|
|
65
|
+
tipo: object
|
|
66
|
+
destino: File (.ai/*.json)
|
|
67
|
+
persistido: true
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Pre-Conditions
|
|
73
|
+
|
|
74
|
+
**Purpose:** Validate prerequisites BEFORE task execution (blocking)
|
|
75
|
+
|
|
76
|
+
**Checklist:**
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
pre-conditions:
|
|
80
|
+
- [ ] Validation rules loaded; target available for validation
|
|
81
|
+
tipo: pre-condition
|
|
82
|
+
blocker: true
|
|
83
|
+
validação: |
|
|
84
|
+
Check validation rules loaded; target available for validation
|
|
85
|
+
error_message: "Pre-condition failed: Validation rules loaded; target available for validation"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Post-Conditions
|
|
91
|
+
|
|
92
|
+
**Purpose:** Validate execution success AFTER task completes
|
|
93
|
+
|
|
94
|
+
**Checklist:**
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
post-conditions:
|
|
98
|
+
- [ ] Validation executed; results accurate; report generated
|
|
99
|
+
tipo: post-condition
|
|
100
|
+
blocker: true
|
|
101
|
+
validação: |
|
|
102
|
+
Verify validation executed; results accurate; report generated
|
|
103
|
+
error_message: "Post-condition failed: Validation executed; results accurate; report generated"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Acceptance Criteria
|
|
109
|
+
|
|
110
|
+
**Purpose:** Definitive pass/fail criteria for task completion
|
|
111
|
+
|
|
112
|
+
**Checklist:**
|
|
113
|
+
|
|
114
|
+
```yaml
|
|
115
|
+
acceptance-criteria:
|
|
116
|
+
- [ ] Validation rules applied; pass/fail accurate; actionable feedback
|
|
117
|
+
tipo: acceptance-criterion
|
|
118
|
+
blocker: true
|
|
119
|
+
validação: |
|
|
120
|
+
Assert validation rules applied; pass/fail accurate; actionable feedback
|
|
121
|
+
error_message: "Acceptance criterion not met: Validation rules applied; pass/fail accurate; actionable feedback"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Tools
|
|
127
|
+
|
|
128
|
+
**External/shared resources used by this task:**
|
|
129
|
+
|
|
130
|
+
- **Tool:** validation-engine
|
|
131
|
+
- **Purpose:** Rule-based validation and reporting
|
|
132
|
+
- **Source:** .aios-core/utils/validation-engine.js
|
|
133
|
+
|
|
134
|
+
- **Tool:** schema-validator
|
|
135
|
+
- **Purpose:** JSON/YAML schema validation
|
|
136
|
+
- **Source:** ajv or similar
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Scripts
|
|
141
|
+
|
|
142
|
+
**Agent-specific code for this task:**
|
|
143
|
+
|
|
144
|
+
- **Script:** run-validation.js
|
|
145
|
+
- **Purpose:** Execute validation rules and generate report
|
|
146
|
+
- **Language:** JavaScript
|
|
147
|
+
- **Location:** .aios-core/scripts/run-validation.js
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Error Handling
|
|
152
|
+
|
|
153
|
+
**Strategy:** retry
|
|
154
|
+
|
|
155
|
+
**Common Errors:**
|
|
156
|
+
|
|
157
|
+
1. **Error:** Validation Criteria Missing
|
|
158
|
+
- **Cause:** Required validation rules not defined
|
|
159
|
+
- **Resolution:** Ensure validation criteria loaded from config
|
|
160
|
+
- **Recovery:** Use default validation rules, log warning
|
|
161
|
+
|
|
162
|
+
2. **Error:** Invalid Schema
|
|
163
|
+
- **Cause:** Target does not match expected schema
|
|
164
|
+
- **Resolution:** Update schema or fix target structure
|
|
165
|
+
- **Recovery:** Detailed validation error report
|
|
166
|
+
|
|
167
|
+
3. **Error:** Dependency Missing
|
|
168
|
+
- **Cause:** Required dependency for validation not found
|
|
169
|
+
- **Resolution:** Install missing dependencies
|
|
170
|
+
- **Recovery:** Abort with clear dependency list
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Performance
|
|
175
|
+
|
|
176
|
+
**Expected Metrics:**
|
|
177
|
+
|
|
178
|
+
```yaml
|
|
179
|
+
duration_expected: 2-10 min (estimated)
|
|
180
|
+
cost_estimated: $0.001-0.008
|
|
181
|
+
token_usage: ~800-2,500 tokens
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Optimization Notes:**
|
|
185
|
+
- Validate configuration early; use atomic writes; implement rollback checkpoints
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Metadata
|
|
190
|
+
|
|
191
|
+
```yaml
|
|
192
|
+
story: N/A
|
|
193
|
+
version: 1.0.0
|
|
194
|
+
dependencies:
|
|
195
|
+
- N/A
|
|
196
|
+
tags:
|
|
197
|
+
- quality-assurance
|
|
198
|
+
- testing
|
|
199
|
+
updated_at: 2025-11-17
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
tools:
|
|
205
|
+
- github-cli
|
|
206
|
+
# TODO: Create test-generation-checklist.md for validation (follow-up story needed)
|
|
207
|
+
# checklists:
|
|
208
|
+
# - test-generation-checklist.md
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
# Generate Tests - AIOS Developer Task
|
|
212
|
+
|
|
213
|
+
## Purpose
|
|
214
|
+
Automatically generate comprehensive test suites for framework components using AI analysis and template systems.
|
|
215
|
+
|
|
216
|
+
## Command Pattern
|
|
217
|
+
```
|
|
218
|
+
*generate-tests <component-type> <component-name> [options]
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Parameters
|
|
222
|
+
- `component-type`: Type of component (agent, task, workflow, util)
|
|
223
|
+
- `component-name`: Name/ID of the component to generate tests for
|
|
224
|
+
- `options`: Test generation configuration
|
|
225
|
+
|
|
226
|
+
### Options
|
|
227
|
+
- `--test-type <type>`: Type of tests to generate (unit, integration, e2e, all)
|
|
228
|
+
- `--coverage-target <percentage>`: Target code coverage percentage (default: 80)
|
|
229
|
+
- `--framework <name>`: Test framework to use (jest, mocha, vitest)
|
|
230
|
+
- `--mock-level <level>`: Mocking level (minimal, moderate, extensive)
|
|
231
|
+
- `--update-existing`: Update existing test files instead of creating new ones
|
|
232
|
+
- `--quality-level <level>`: Test quality level (basic, standard, comprehensive)
|
|
233
|
+
- `--output-dir <path>`: Custom output directory for generated tests
|
|
234
|
+
|
|
235
|
+
## Examples
|
|
236
|
+
```bash
|
|
237
|
+
# Generate unit tests for an agent
|
|
238
|
+
*generate-tests agent weather-fetcher --test-type unit --coverage-target 90
|
|
239
|
+
|
|
240
|
+
# Generate comprehensive test suite for a utility
|
|
241
|
+
*generate-tests util logger --test-type all --quality-level comprehensive
|
|
242
|
+
|
|
243
|
+
# Update existing tests for a task
|
|
244
|
+
*generate-tests task data-processor --update-existing --coverage-target 85
|
|
245
|
+
|
|
246
|
+
# Generate integration tests with extensive mocking
|
|
247
|
+
*generate-tests workflow user-onboarding --test-type integration --mock-level extensive
|
|
248
|
+
|
|
249
|
+
# Generate tests for all component types
|
|
250
|
+
*generate-tests all components --framework vitest --output-dir tests/auto-generated
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Implementation
|
|
254
|
+
|
|
255
|
+
```javascript
|
|
256
|
+
const fs = require('fs').promises;
|
|
257
|
+
const path = require('path');
|
|
258
|
+
const chalk = require('chalk');
|
|
259
|
+
const inquirer = require('inquirer');
|
|
260
|
+
|
|
261
|
+
class GenerateTestsTask {
|
|
262
|
+
constructor() {
|
|
263
|
+
this.taskName = 'generate-tests';
|
|
264
|
+
this.description = 'Generate comprehensive test suites for framework components';
|
|
265
|
+
this.rootPath = process.cwd();
|
|
266
|
+
this.testTemplateSystem = null;
|
|
267
|
+
this.testGenerator = null;
|
|
268
|
+
this.coverageAnalyzer = null;
|
|
269
|
+
this.qualityAssessment = null;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async execute(params) {
|
|
273
|
+
try {
|
|
274
|
+
console.log(chalk.blue('🧪 AIOS Test Generation'));
|
|
275
|
+
console.log(chalk.gray('Generating comprehensive test suites for components\n'));
|
|
276
|
+
|
|
277
|
+
// Parse and validate parameters
|
|
278
|
+
const config = await this.parseParameters(params);
|
|
279
|
+
|
|
280
|
+
// Initialize dependencies
|
|
281
|
+
await this.initializeDependencies();
|
|
282
|
+
|
|
283
|
+
// Analyze target components
|
|
284
|
+
const components = await this.identifyTargetComponents(config);
|
|
285
|
+
if (components.length === 0) {
|
|
286
|
+
throw new Error('No components found matching the criteria');
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
console.log(chalk.gray(`Found ${components.length} component(s) for test generation`));
|
|
290
|
+
|
|
291
|
+
// Generate test plan
|
|
292
|
+
const testPlan = await this.generateTestPlan(components, config);
|
|
293
|
+
|
|
294
|
+
// Display test generation summary
|
|
295
|
+
await this.displayTestGenerationSummary(testPlan);
|
|
296
|
+
|
|
297
|
+
// Request confirmation
|
|
298
|
+
const confirmed = await this.requestConfirmation(testPlan);
|
|
299
|
+
if (!confirmed) {
|
|
300
|
+
console.log(chalk.gray('Test generation cancelled'));
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Execute test generation
|
|
305
|
+
const generationResults = await this.executeTestGeneration(testPlan);
|
|
306
|
+
|
|
307
|
+
// Analyze generated tests
|
|
308
|
+
const analysisResults = await this.analyzeGeneratedTests(generationResults);
|
|
309
|
+
|
|
310
|
+
// Update existing test documentation
|
|
311
|
+
await this.updateTestDocumentation(generationResults);
|
|
312
|
+
|
|
313
|
+
// Display success summary
|
|
314
|
+
console.log(chalk.green('\n✅ Test generation completed successfully'));
|
|
315
|
+
console.log(chalk.gray(` Components tested: ${components.length}`));
|
|
316
|
+
console.log(chalk.gray(` Test files generated: ${generationResults.testFilesGenerated}`));
|
|
317
|
+
console.log(chalk.gray(` Expected coverage: ${analysisResults.expectedCoverage}%`));
|
|
318
|
+
console.log(chalk.gray(` Quality score: ${analysisResults.qualityScore}/10`));
|
|
319
|
+
|
|
320
|
+
return {
|
|
321
|
+
success: true,
|
|
322
|
+
components: components.length,
|
|
323
|
+
testFilesGenerated: generationResults.testFilesGenerated,
|
|
324
|
+
expectedCoverage: analysisResults.expectedCoverage,
|
|
325
|
+
qualityScore: analysisResults.qualityScore
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
} catch (error) {
|
|
329
|
+
console.error(chalk.red(`\n❌ Test generation failed: ${error.message}`));
|
|
330
|
+
throw error;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async parseParameters(params) {
|
|
335
|
+
if (params.length < 2 && params[0] !== 'all') {
|
|
336
|
+
throw new Error('Usage: *generate-tests <component-type> <component-name> [options]');
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const config = {
|
|
340
|
+
componentType: params[0],
|
|
341
|
+
componentName: params[1] || null,
|
|
342
|
+
testType: 'unit',
|
|
343
|
+
coverageTarget: 80,
|
|
344
|
+
framework: 'jest',
|
|
345
|
+
mockLevel: 'moderate',
|
|
346
|
+
updateExisting: false,
|
|
347
|
+
qualityLevel: 'standard',
|
|
348
|
+
outputDir: null,
|
|
349
|
+
generateAll: params[0] === 'all'
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// Parse options
|
|
353
|
+
for (let i = 2; i < params.length; i++) {
|
|
354
|
+
const param = params[i];
|
|
355
|
+
|
|
356
|
+
if (param === '--update-existing') {
|
|
357
|
+
config.updateExisting = true;
|
|
358
|
+
} else if (param.startsWith('--test-type') && params[i + 1]) {
|
|
359
|
+
config.testType = params[++i];
|
|
360
|
+
} else if (param.startsWith('--coverage-target') && params[i + 1]) {
|
|
361
|
+
config.coverageTarget = parseInt(params[++i]) || 80;
|
|
362
|
+
} else if (param.startsWith('--framework') && params[i + 1]) {
|
|
363
|
+
config.framework = params[++i];
|
|
364
|
+
} else if (param.startsWith('--mock-level') && params[i + 1]) {
|
|
365
|
+
config.mockLevel = params[++i];
|
|
366
|
+
} else if (param.startsWith('--quality-level') && params[i + 1]) {
|
|
367
|
+
config.qualityLevel = params[++i];
|
|
368
|
+
} else if (param.startsWith('--output-dir') && params[i + 1]) {
|
|
369
|
+
config.outputDir = params[++i];
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Validation
|
|
374
|
+
if (!config.generateAll) {
|
|
375
|
+
const validTypes = ['agent', 'task', 'workflow', 'util'];
|
|
376
|
+
if (!validTypes.includes(config.componentType)) {
|
|
377
|
+
throw new Error(`Invalid component type: ${config.componentType}. Must be one of: ${validTypes.join(', ')}`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const validTestTypes = ['unit', 'integration', 'e2e', 'all'];
|
|
382
|
+
if (!validTestTypes.includes(config.testType)) {
|
|
383
|
+
throw new Error(`Invalid test type: ${config.testType}. Must be one of: ${validTestTypes.join(', ')}`);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const validFrameworks = ['jest', 'mocha', 'vitest'];
|
|
387
|
+
if (!validFrameworks.includes(config.framework)) {
|
|
388
|
+
throw new Error(`Invalid framework: ${config.framework}. Must be one of: ${validFrameworks.join(', ')}`);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const validMockLevels = ['minimal', 'moderate', 'extensive'];
|
|
392
|
+
if (!validMockLevels.includes(config.mockLevel)) {
|
|
393
|
+
throw new Error(`Invalid mock level: ${config.mockLevel}. Must be one of: ${validMockLevels.join(', ')}`);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const validQualityLevels = ['basic', 'standard', 'comprehensive'];
|
|
397
|
+
if (!validQualityLevels.includes(config.qualityLevel)) {
|
|
398
|
+
throw new Error(`Invalid quality level: ${config.qualityLevel}. Must be one of: ${validQualityLevels.join(', ')}`);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (config.coverageTarget < 0 || config.coverageTarget > 100) {
|
|
402
|
+
throw new Error('Coverage target must be between 0 and 100');
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
return config;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
async initializeDependencies() {
|
|
409
|
+
try {
|
|
410
|
+
// Initialize test template system
|
|
411
|
+
const TestTemplateSystem = require('../scripts/test-template-system');
|
|
412
|
+
this.testTemplateSystem = new TestTemplateSystem({ rootPath: this.rootPath });
|
|
413
|
+
await this.testTemplateSystem.initialize();
|
|
414
|
+
|
|
415
|
+
// Initialize test generator
|
|
416
|
+
const TestGenerator = require('../scripts/test-generator');
|
|
417
|
+
this.testGenerator = new TestGenerator({
|
|
418
|
+
rootPath: this.rootPath,
|
|
419
|
+
templateSystem: this.testTemplateSystem
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
// Initialize coverage analyzer
|
|
423
|
+
const CoverageAnalyzer = require('../scripts/coverage-analyzer');
|
|
424
|
+
this.coverageAnalyzer = new CoverageAnalyzer({ rootPath: this.rootPath });
|
|
425
|
+
|
|
426
|
+
// Initialize quality assessment
|
|
427
|
+
const TestQualityAssessment = require('../scripts/test-quality-assessment');
|
|
428
|
+
this.qualityAssessment = new TestQualityAssessment({ rootPath: this.rootPath });
|
|
429
|
+
|
|
430
|
+
} catch (error) {
|
|
431
|
+
throw new Error(`Failed to initialize dependencies: ${error.message}`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
async identifyTargetComponents(config) {
|
|
436
|
+
const components = [];
|
|
437
|
+
|
|
438
|
+
if (config.generateAll) {
|
|
439
|
+
// Find all components in the framework
|
|
440
|
+
const allComponents = await this.discoverAllComponents();
|
|
441
|
+
components.push(...allComponents);
|
|
442
|
+
} else {
|
|
443
|
+
// Find specific component
|
|
444
|
+
const ComponentSearch = require('../scripts/component-search');
|
|
445
|
+
const componentSearch = new ComponentSearch({ rootPath: this.rootPath });
|
|
446
|
+
|
|
447
|
+
const component = await componentSearch.findComponent(config.componentType, config.componentName);
|
|
448
|
+
if (!component) {
|
|
449
|
+
// Suggest similar components
|
|
450
|
+
const suggestions = await componentSearch.findSimilarComponents(config.componentType, config.componentName);
|
|
451
|
+
if (suggestions.length > 0) {
|
|
452
|
+
console.log(chalk.yellow('\nDid you mean one of these?'));
|
|
453
|
+
suggestions.forEach(suggestion => {
|
|
454
|
+
console.log(chalk.gray(` - ${suggestion.type}/${suggestion.name}`));
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
throw new Error(`Component not found: ${config.componentType}/${config.componentName}`);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
components.push(component);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return components;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
async discoverAllComponents() {
|
|
467
|
+
const components = [];
|
|
468
|
+
const componentTypes = ['agents', 'tasks', 'workflows', 'utils'];
|
|
469
|
+
|
|
470
|
+
for (const type of componentTypes) {
|
|
471
|
+
const typeDir = path.join(this.rootPath, 'aios-core', type);
|
|
472
|
+
|
|
473
|
+
try {
|
|
474
|
+
const files = await fs.readdir(typeDir);
|
|
475
|
+
|
|
476
|
+
for (const file of files) {
|
|
477
|
+
const filePath = path.join(typeDir, file);
|
|
478
|
+
const stats = await fs.stat(filePath);
|
|
479
|
+
|
|
480
|
+
if (stats.isFile()) {
|
|
481
|
+
const componentType = type.slice(0, -1); // Remove 's' from plural
|
|
482
|
+
const componentName = path.basename(file, path.extname(file));
|
|
483
|
+
|
|
484
|
+
components.push({
|
|
485
|
+
id: `${componentType}/${componentName}`,
|
|
486
|
+
type: componentType,
|
|
487
|
+
name: componentName,
|
|
488
|
+
filePath: filePath
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
} catch (error) {
|
|
493
|
+
// Directory doesn't exist, skip
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return components;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
async generateTestPlan(components, config) {
|
|
502
|
+
const testPlan = {
|
|
503
|
+
generation_id: `test-gen-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`,
|
|
504
|
+
components: components,
|
|
505
|
+
config: config,
|
|
506
|
+
test_suites: [],
|
|
507
|
+
estimated_duration: 0,
|
|
508
|
+
expected_files: 0,
|
|
509
|
+
quality_targets: {}
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
console.log(chalk.gray('Analyzing components and generating test plan...'));
|
|
513
|
+
|
|
514
|
+
for (const component of components) {
|
|
515
|
+
const componentAnalysis = await this.analyzeComponentForTesting(component, config);
|
|
516
|
+
const testSuite = await this.planTestSuite(component, componentAnalysis, config);
|
|
517
|
+
|
|
518
|
+
testPlan.test_suites.push(testSuite);
|
|
519
|
+
testPlan.estimated_duration += testSuite.estimated_duration;
|
|
520
|
+
testPlan.expected_files += testSuite.test_files.length;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Set quality targets
|
|
524
|
+
testPlan.quality_targets = {
|
|
525
|
+
coverage_target: config.coverageTarget,
|
|
526
|
+
quality_level: config.qualityLevel,
|
|
527
|
+
mock_coverage: this.calculateMockCoverage(config.mockLevel),
|
|
528
|
+
assertion_density: this.calculateAssertionDensity(config.qualityLevel)
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
return testPlan;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
async analyzeComponentForTesting(component, config) {
|
|
535
|
+
const analysis = {
|
|
536
|
+
component_id: component.id,
|
|
537
|
+
complexity: 'medium',
|
|
538
|
+
dependencies: [],
|
|
539
|
+
external_dependencies: [],
|
|
540
|
+
testable_functions: [],
|
|
541
|
+
edge_cases: [],
|
|
542
|
+
mock_requirements: [],
|
|
543
|
+
existing_tests: null
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
try {
|
|
547
|
+
// Read component file
|
|
548
|
+
const content = await fs.readFile(component.filePath, 'utf-8');
|
|
549
|
+
|
|
550
|
+
// Analyze component complexity
|
|
551
|
+
analysis.complexity = this.assessComplexity(content, component.type);
|
|
552
|
+
|
|
553
|
+
// Identify dependencies
|
|
554
|
+
analysis.dependencies = this.extractDependencies(content, component.type);
|
|
555
|
+
analysis.external_dependencies = this.extractExternalDependencies(content);
|
|
556
|
+
|
|
557
|
+
// Identify testable functions/methods
|
|
558
|
+
analysis.testable_functions = this.extractTestableFunctions(content, component.type);
|
|
559
|
+
|
|
560
|
+
// Identify edge cases
|
|
561
|
+
analysis.edge_cases = this.identifyEdgeCases(content, component.type);
|
|
562
|
+
|
|
563
|
+
// Determine mock requirements
|
|
564
|
+
analysis.mock_requirements = this.determineMockRequirements(analysis, config.mockLevel);
|
|
565
|
+
|
|
566
|
+
// Check for existing tests
|
|
567
|
+
analysis.existing_tests = await this.findExistingTests(component);
|
|
568
|
+
|
|
569
|
+
} catch (error) {
|
|
570
|
+
console.warn(chalk.yellow(`Failed to analyze ${component.id}: ${error.message}`));
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
return analysis;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
async planTestSuite(component, analysis, config) {
|
|
577
|
+
const testSuite = {
|
|
578
|
+
component_id: component.id,
|
|
579
|
+
component_type: component.type,
|
|
580
|
+
test_files: [],
|
|
581
|
+
total_tests: 0,
|
|
582
|
+
estimated_duration: 0,
|
|
583
|
+
coverage_plan: {},
|
|
584
|
+
quality_metrics: {}
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
// Plan different types of tests based on config
|
|
588
|
+
if (config.testType === 'unit' || config.testType === 'all') {
|
|
589
|
+
const unitTestFile = await this.planUnitTests(component, analysis, config);
|
|
590
|
+
testSuite.test_files.push(unitTestFile);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (config.testType === 'integration' || config.testType === 'all') {
|
|
594
|
+
const integrationTestFile = await this.planIntegrationTests(component, analysis, config);
|
|
595
|
+
if (integrationTestFile) {
|
|
596
|
+
testSuite.test_files.push(integrationTestFile);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if (config.testType === 'e2e' || config.testType === 'all') {
|
|
601
|
+
const e2eTestFile = await this.planE2ETests(component, analysis, config);
|
|
602
|
+
if (e2eTestFile) {
|
|
603
|
+
testSuite.test_files.push(e2eTestFile);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// Calculate totals
|
|
608
|
+
testSuite.total_tests = testSuite.test_files.reduce((sum, file) => sum + file.test_count, 0);
|
|
609
|
+
testSuite.estimated_duration = testSuite.test_files.reduce((sum, file) => sum + file.estimated_duration, 0);
|
|
610
|
+
|
|
611
|
+
// Plan coverage
|
|
612
|
+
testSuite.coverage_plan = {
|
|
613
|
+
target_percentage: config.coverageTarget,
|
|
614
|
+
lines_to_cover: analysis.testable_functions.length * 5, // Estimate
|
|
615
|
+
assertions_planned: testSuite.total_tests * this.calculateAssertionDensity(config.qualityLevel)
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
return testSuite;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
async planUnitTests(component, analysis, config) {
|
|
622
|
+
const testFile = {
|
|
623
|
+
file_path: this.generateTestFilePath(component, 'unit', config),
|
|
624
|
+
test_type: 'unit',
|
|
625
|
+
test_count: 0,
|
|
626
|
+
estimated_duration: 0,
|
|
627
|
+
test_cases: [],
|
|
628
|
+
mocks_required: [],
|
|
629
|
+
setup_requirements: []
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
// Generate test cases for each testable function
|
|
633
|
+
for (const func of analysis.testable_functions) {
|
|
634
|
+
const testCases = await this.generateFunctionTestCases(func, analysis, config);
|
|
635
|
+
testFile.test_cases.push(...testCases);
|
|
636
|
+
testFile.test_count += testCases.length;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// Add edge case tests
|
|
640
|
+
for (const edgeCase of analysis.edge_cases) {
|
|
641
|
+
const edgeCaseTest = await this.generateEdgeCaseTest(edgeCase, analysis, config);
|
|
642
|
+
testFile.test_cases.push(edgeCaseTest);
|
|
643
|
+
testFile.test_count++;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// Determine mocks required
|
|
647
|
+
testFile.mocks_required = analysis.mock_requirements.filter(mock => mock.level !== 'none');
|
|
648
|
+
|
|
649
|
+
// Calculate estimated duration
|
|
650
|
+
testFile.estimated_duration = testFile.test_count * 2; // 2 minutes per test case
|
|
651
|
+
|
|
652
|
+
return testFile;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
async planIntegrationTests(component, analysis, config) {
|
|
656
|
+
// Skip integration tests for simple components
|
|
657
|
+
if (analysis.complexity === 'low' && analysis.dependencies.length === 0) {
|
|
658
|
+
return null;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
const testFile = {
|
|
662
|
+
file_path: this.generateTestFilePath(component, 'integration', config),
|
|
663
|
+
test_type: 'integration',
|
|
664
|
+
test_count: 0,
|
|
665
|
+
estimated_duration: 0,
|
|
666
|
+
test_cases: [],
|
|
667
|
+
integration_scenarios: [],
|
|
668
|
+
setup_requirements: ['test database', 'mock services']
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
// Generate integration scenarios
|
|
672
|
+
testFile.integration_scenarios = await this.generateIntegrationScenarios(component, analysis);
|
|
673
|
+
testFile.test_count = testFile.integration_scenarios.length;
|
|
674
|
+
testFile.estimated_duration = testFile.test_count * 5; // 5 minutes per integration test
|
|
675
|
+
|
|
676
|
+
return testFile;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
async planE2ETests(component, analysis, config) {
|
|
680
|
+
// Only generate E2E tests for workflows and certain tasks
|
|
681
|
+
if (component.type !== 'workflow' && component.type !== 'task') {
|
|
682
|
+
return null;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
const testFile = {
|
|
686
|
+
file_path: this.generateTestFilePath(component, 'e2e', config),
|
|
687
|
+
test_type: 'e2e',
|
|
688
|
+
test_count: 0,
|
|
689
|
+
estimated_duration: 0,
|
|
690
|
+
test_scenarios: [],
|
|
691
|
+
setup_requirements: ['full system', 'test data']
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
// Generate E2E scenarios
|
|
695
|
+
testFile.test_scenarios = await this.generateE2EScenarios(component, analysis);
|
|
696
|
+
testFile.test_count = testFile.test_scenarios.length;
|
|
697
|
+
testFile.estimated_duration = testFile.test_count * 10; // 10 minutes per E2E test
|
|
698
|
+
|
|
699
|
+
return testFile;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
generateTestFilePath(component, testType, config) {
|
|
703
|
+
const baseDir = config.outputDir || path.join(this.rootPath, 'tests');
|
|
704
|
+
const typeDir = testType === 'unit' ? 'unit' : testType === 'integration' ? 'integration' : 'e2e';
|
|
705
|
+
const componentDir = component.type === 'util' ? 'utils' : component.type;
|
|
706
|
+
|
|
707
|
+
const fileName = `${component.name}.${testType}.test.js`;
|
|
708
|
+
return path.join(baseDir, typeDir, componentDir, fileName);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
async displayTestGenerationSummary(testPlan) {
|
|
712
|
+
console.log(chalk.blue('\n📋 Test Generation Plan'));
|
|
713
|
+
console.log(chalk.gray('━'.repeat(50)));
|
|
714
|
+
|
|
715
|
+
console.log(`Components: ${chalk.white(testPlan.components.length)}`);
|
|
716
|
+
console.log(`Test suites: ${chalk.white(testPlan.test_suites.length)}`);
|
|
717
|
+
console.log(`Expected test files: ${chalk.white(testPlan.expected_files)}`);
|
|
718
|
+
console.log(`Total tests planned: ${chalk.white(testPlan.test_suites.reduce((sum, suite) => sum + suite.total_tests, 0))}`);
|
|
719
|
+
console.log(`Coverage target: ${chalk.white(testPlan.config.coverageTarget)}%`);
|
|
720
|
+
console.log(`Quality level: ${chalk.white(testPlan.config.qualityLevel)}`);
|
|
721
|
+
console.log(`Estimated duration: ${chalk.white(Math.round(testPlan.estimated_duration / 60))} hours`);
|
|
722
|
+
|
|
723
|
+
console.log(chalk.blue('\nTest Suites:'));
|
|
724
|
+
testPlan.test_suites.forEach((suite, index) => {
|
|
725
|
+
console.log(` ${index + 1}. ${suite.component_id} (${suite.total_tests} tests)`);
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
async requestConfirmation(testPlan) {
|
|
730
|
+
const { confirmed } = await inquirer.prompt([{
|
|
731
|
+
type: 'confirm',
|
|
732
|
+
name: 'confirmed',
|
|
733
|
+
message: `Generate ${testPlan.expected_files} test files for ${testPlan.components.length} components?`,
|
|
734
|
+
default: true
|
|
735
|
+
}]);
|
|
736
|
+
|
|
737
|
+
return confirmed;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
async executeTestGeneration(testPlan) {
|
|
741
|
+
const results = {
|
|
742
|
+
testFilesGenerated: 0,
|
|
743
|
+
testsGenerated: 0,
|
|
744
|
+
errors: [],
|
|
745
|
+
generated_files: []
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
console.log(chalk.gray('\nGenerating test files...'));
|
|
749
|
+
|
|
750
|
+
for (const testSuite of testPlan.test_suites) {
|
|
751
|
+
try {
|
|
752
|
+
const component = testPlan.components.find(c => c.id === testSuite.component_id);
|
|
753
|
+
|
|
754
|
+
for (const testFile of testSuite.test_files) {
|
|
755
|
+
console.log(chalk.gray(` Generating ${testFile.test_type} tests for ${component.name}...`));
|
|
756
|
+
|
|
757
|
+
const generatedContent = await this.testGenerator.generateTestFile(
|
|
758
|
+
component,
|
|
759
|
+
testFile,
|
|
760
|
+
testPlan.config
|
|
761
|
+
);
|
|
762
|
+
|
|
763
|
+
// Ensure directory exists
|
|
764
|
+
await fs.mkdir(path.dirname(testFile.file_path), { recursive: true });
|
|
765
|
+
|
|
766
|
+
// Write test file
|
|
767
|
+
if (testPlan.config.updateExisting || !(await this.fileExists(testFile.file_path))) {
|
|
768
|
+
await fs.writeFile(testFile.file_path, generatedContent);
|
|
769
|
+
results.testFilesGenerated++;
|
|
770
|
+
results.testsGenerated += testFile.test_count;
|
|
771
|
+
results.generated_files.push(testFile.file_path);
|
|
772
|
+
|
|
773
|
+
console.log(chalk.green(` ✓ Generated ${testFile.file_path}`));
|
|
774
|
+
} else {
|
|
775
|
+
console.log(chalk.yellow(` ⚠ Skipped ${testFile.file_path} (already exists)`));
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
} catch (error) {
|
|
780
|
+
results.errors.push({
|
|
781
|
+
component_id: testSuite.component_id,
|
|
782
|
+
error: error.message
|
|
783
|
+
});
|
|
784
|
+
console.error(chalk.red(` ✗ Failed to generate tests for ${testSuite.component_id}: ${error.message}`));
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
return results;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
async analyzeGeneratedTests(generationResults) {
|
|
792
|
+
const analysis = {
|
|
793
|
+
expectedCoverage: 0,
|
|
794
|
+
qualityScore: 0,
|
|
795
|
+
testDistribution: {},
|
|
796
|
+
recommendations: []
|
|
797
|
+
};
|
|
798
|
+
|
|
799
|
+
if (generationResults.testFilesGenerated > 0) {
|
|
800
|
+
// Analyze each generated test file
|
|
801
|
+
for (const filePath of generationResults.generated_files) {
|
|
802
|
+
try {
|
|
803
|
+
const testAnalysis = await this.qualityAssessment.analyzeSingleTestFile(filePath);
|
|
804
|
+
analysis.expectedCoverage += testAnalysis.estimatedCoverage || 0;
|
|
805
|
+
analysis.qualityScore += testAnalysis.qualityScore || 0;
|
|
806
|
+
} catch (error) {
|
|
807
|
+
console.warn(chalk.yellow(`Failed to analyze ${filePath}: ${error.message}`));
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// Calculate averages
|
|
812
|
+
analysis.expectedCoverage = Math.round(analysis.expectedCoverage / generationResults.testFilesGenerated);
|
|
813
|
+
analysis.qualityScore = Math.round((analysis.qualityScore / generationResults.testFilesGenerated) * 10) / 10;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
return analysis;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
async updateTestDocumentation(generationResults) {
|
|
820
|
+
// Update test documentation with newly generated tests
|
|
821
|
+
const testDocs = {
|
|
822
|
+
generated_at: new Date().toISOString(),
|
|
823
|
+
test_files: generationResults.generated_files,
|
|
824
|
+
total_tests: generationResults.testsGenerated,
|
|
825
|
+
generation_notes: 'Auto-generated by AIOS test generation system'
|
|
826
|
+
};
|
|
827
|
+
|
|
828
|
+
const docsPath = path.join(this.rootPath, 'docs', 'testing', 'auto-generated-tests.json');
|
|
829
|
+
|
|
830
|
+
try {
|
|
831
|
+
await fs.mkdir(path.dirname(docsPath), { recursive: true });
|
|
832
|
+
await fs.writeFile(docsPath, JSON.stringify(testDocs, null, 2));
|
|
833
|
+
} catch (error) {
|
|
834
|
+
console.warn(chalk.yellow(`Failed to update test documentation: ${error.message}`));
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// Helper methods
|
|
839
|
+
|
|
840
|
+
async fileExists(filePath) {
|
|
841
|
+
try {
|
|
842
|
+
await fs.access(filePath);
|
|
843
|
+
return true;
|
|
844
|
+
} catch {
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
assessComplexity(content, componentType) {
|
|
850
|
+
// Simple heuristic for complexity assessment
|
|
851
|
+
const lines = content.split('\n').length;
|
|
852
|
+
const functions = (content.match(/function|=>/g) || []).length;
|
|
853
|
+
const conditions = (content.match(/if|switch|for|while/g) || []).length;
|
|
854
|
+
|
|
855
|
+
const complexityScore = (lines / 10) + (functions * 2) + (conditions * 3);
|
|
856
|
+
|
|
857
|
+
if (complexityScore > 50) return 'high';
|
|
858
|
+
if (complexityScore > 20) return 'medium';
|
|
859
|
+
return 'low';
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
extractDependencies(content, componentType) {
|
|
863
|
+
const dependencies = [];
|
|
864
|
+
|
|
865
|
+
// Extract require/import statements
|
|
866
|
+
const requireMatches = content.match(/require\(['"]([^'"]+)['"]\)/g) || [];
|
|
867
|
+
const importMatches = content.match(/import .+ from ['"]([^'"]+)['"]/g) || [];
|
|
868
|
+
|
|
869
|
+
requireMatches.forEach(match => {
|
|
870
|
+
const dep = match.match(/require\(['"]([^'"]+)['"]\)/)[1];
|
|
871
|
+
if (dep.startsWith('./') || dep.startsWith('../')) {
|
|
872
|
+
dependencies.push(dep);
|
|
873
|
+
}
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
importMatches.forEach(match => {
|
|
877
|
+
const dep = match.match(/from ['"]([^'"]+)['"]/)[1];
|
|
878
|
+
if (dep.startsWith('./') || dep.startsWith('../')) {
|
|
879
|
+
dependencies.push(dep);
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
return dependencies;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
extractExternalDependencies(content) {
|
|
887
|
+
const externalDeps = [];
|
|
888
|
+
|
|
889
|
+
const requireMatches = content.match(/require\(['"]([^'"]+)['"]\)/g) || [];
|
|
890
|
+
const importMatches = content.match(/import .+ from ['"]([^'"]+)['"]/g) || [];
|
|
891
|
+
|
|
892
|
+
requireMatches.forEach(match => {
|
|
893
|
+
const dep = match.match(/require\(['"]([^'"]+)['"]\)/)[1];
|
|
894
|
+
if (!dep.startsWith('./') && !dep.startsWith('../') && !dep.startsWith('node:')) {
|
|
895
|
+
externalDeps.push(dep);
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
importMatches.forEach(match => {
|
|
900
|
+
const dep = match.match(/from ['"]([^'"]+)['"]/)[1];
|
|
901
|
+
if (!dep.startsWith('./') && !dep.startsWith('../') && !dep.startsWith('node:')) {
|
|
902
|
+
externalDeps.push(dep);
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
return [...new Set(externalDeps)]; // Remove duplicates
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
extractTestableFunctions(content, componentType) {
|
|
910
|
+
const functions = [];
|
|
911
|
+
|
|
912
|
+
// Extract function declarations and expressions
|
|
913
|
+
const functionMatches = content.match(/(?:function\s+(\w+)|(\w+)\s*[:=]\s*(?:async\s+)?function|(\w+)\s*[:=]\s*(?:async\s+)?\([^)]*\)\s*=>)/g) || [];
|
|
914
|
+
|
|
915
|
+
functionMatches.forEach(match => {
|
|
916
|
+
let functionName = null;
|
|
917
|
+
|
|
918
|
+
if (match.includes('function ')) {
|
|
919
|
+
functionName = match.match(/function\s+(\w+)/)?.[1];
|
|
920
|
+
} else {
|
|
921
|
+
functionName = match.match(/(\w+)\s*[:=]/)?.[1];
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
if (functionName && !functionName.startsWith('_')) {
|
|
925
|
+
functions.push({
|
|
926
|
+
name: functionName,
|
|
927
|
+
type: 'function',
|
|
928
|
+
visibility: 'public'
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
return functions;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
identifyEdgeCases(content, componentType) {
|
|
937
|
+
const edgeCases = [];
|
|
938
|
+
|
|
939
|
+
// Look for common edge case patterns
|
|
940
|
+
if (content.includes('null') || content.includes('undefined')) {
|
|
941
|
+
edgeCases.push({ type: 'null_undefined', description: 'Handle null/undefined values' });
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
if (content.includes('length') || content.includes('size')) {
|
|
945
|
+
edgeCases.push({ type: 'empty_collections', description: 'Handle empty arrays/objects' });
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
if (content.includes('catch') || content.includes('throw')) {
|
|
949
|
+
edgeCases.push({ type: 'error_handling', description: 'Test error conditions' });
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
if (content.includes('async') || content.includes('await')) {
|
|
953
|
+
edgeCases.push({ type: 'async_operations', description: 'Test async operation failures' });
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
return edgeCases;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
determineMockRequirements(analysis, mockLevel) {
|
|
960
|
+
const mocks = [];
|
|
961
|
+
|
|
962
|
+
if (mockLevel === 'minimal') {
|
|
963
|
+
// Only mock external dependencies
|
|
964
|
+
analysis.external_dependencies.forEach(dep => {
|
|
965
|
+
mocks.push({ type: 'external', target: dep, level: 'full' });
|
|
966
|
+
});
|
|
967
|
+
} else if (mockLevel === 'moderate') {
|
|
968
|
+
// Mock external dependencies and some internal ones
|
|
969
|
+
analysis.external_dependencies.forEach(dep => {
|
|
970
|
+
mocks.push({ type: 'external', target: dep, level: 'full' });
|
|
971
|
+
});
|
|
972
|
+
analysis.dependencies.slice(0, 3).forEach(dep => {
|
|
973
|
+
mocks.push({ type: 'internal', target: dep, level: 'partial' });
|
|
974
|
+
});
|
|
975
|
+
} else if (mockLevel === 'extensive') {
|
|
976
|
+
// Mock everything possible
|
|
977
|
+
analysis.external_dependencies.forEach(dep => {
|
|
978
|
+
mocks.push({ type: 'external', target: dep, level: 'full' });
|
|
979
|
+
});
|
|
980
|
+
analysis.dependencies.forEach(dep => {
|
|
981
|
+
mocks.push({ type: 'internal', target: dep, level: 'full' });
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
return mocks;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
async findExistingTests(component) {
|
|
989
|
+
const possibleTestPaths = [
|
|
990
|
+
path.join(this.rootPath, 'tests', 'unit', component.type, `${component.name}.test.js`),
|
|
991
|
+
path.join(this.rootPath, 'tests', 'unit', component.type, `${component.name}.spec.js`),
|
|
992
|
+
path.join(this.rootPath, 'test', `${component.name}.test.js`),
|
|
993
|
+
path.join(this.rootPath, '__tests__', `${component.name}.test.js`)
|
|
994
|
+
];
|
|
995
|
+
|
|
996
|
+
for (const testPath of possibleTestPaths) {
|
|
997
|
+
if (await this.fileExists(testPath)) {
|
|
998
|
+
return {
|
|
999
|
+
path: testPath,
|
|
1000
|
+
exists: true
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
return { exists: false };
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
calculateMockCoverage(mockLevel) {
|
|
1009
|
+
const coverage = {
|
|
1010
|
+
minimal: 30,
|
|
1011
|
+
moderate: 60,
|
|
1012
|
+
extensive: 90
|
|
1013
|
+
};
|
|
1014
|
+
return coverage[mockLevel] || 60;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
calculateAssertionDensity(qualityLevel) {
|
|
1018
|
+
const density = {
|
|
1019
|
+
basic: 2,
|
|
1020
|
+
standard: 4,
|
|
1021
|
+
comprehensive: 6
|
|
1022
|
+
};
|
|
1023
|
+
return density[qualityLevel] || 4;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
async generateFunctionTestCases(func, analysis, config) {
|
|
1027
|
+
// This would generate test cases based on function analysis
|
|
1028
|
+
// For now, return basic test case structure
|
|
1029
|
+
return [
|
|
1030
|
+
{
|
|
1031
|
+
name: `should ${func.name} successfully`,
|
|
1032
|
+
type: 'success_case',
|
|
1033
|
+
description: `Test successful execution of ${func.name}`,
|
|
1034
|
+
assertions: config.qualityLevel === 'comprehensive' ? 3 : 2
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
name: `should handle ${func.name} errors`,
|
|
1038
|
+
type: 'error_case',
|
|
1039
|
+
description: `Test error handling in ${func.name}`,
|
|
1040
|
+
assertions: 2
|
|
1041
|
+
}
|
|
1042
|
+
];
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
async generateEdgeCaseTest(edgeCase, analysis, config) {
|
|
1046
|
+
return {
|
|
1047
|
+
name: `should handle ${edgeCase.type}`,
|
|
1048
|
+
type: 'edge_case',
|
|
1049
|
+
description: edgeCase.description,
|
|
1050
|
+
assertions: 1
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
async generateIntegrationScenarios(component, analysis) {
|
|
1055
|
+
// Generate integration test scenarios based on component dependencies
|
|
1056
|
+
const scenarios = [];
|
|
1057
|
+
|
|
1058
|
+
if (analysis.dependencies.length > 0) {
|
|
1059
|
+
scenarios.push({
|
|
1060
|
+
name: 'should integrate with dependencies',
|
|
1061
|
+
description: 'Test integration with internal dependencies',
|
|
1062
|
+
dependencies: analysis.dependencies.slice(0, 3)
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
if (analysis.external_dependencies.length > 0) {
|
|
1067
|
+
scenarios.push({
|
|
1068
|
+
name: 'should integrate with external services',
|
|
1069
|
+
description: 'Test integration with external dependencies',
|
|
1070
|
+
dependencies: analysis.external_dependencies.slice(0, 2)
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
return scenarios;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
async generateE2EScenarios(component, analysis) {
|
|
1078
|
+
const scenarios = [];
|
|
1079
|
+
|
|
1080
|
+
if (component.type === 'workflow') {
|
|
1081
|
+
scenarios.push({
|
|
1082
|
+
name: 'should complete full workflow',
|
|
1083
|
+
description: 'Test complete workflow execution end-to-end',
|
|
1084
|
+
steps: ['initialize', 'execute', 'validate', 'cleanup']
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
if (component.type === 'task') {
|
|
1089
|
+
scenarios.push({
|
|
1090
|
+
name: 'should execute task end-to-end',
|
|
1091
|
+
description: 'Test complete task execution with real dependencies',
|
|
1092
|
+
steps: ['setup', 'execute', 'verify_output']
|
|
1093
|
+
});
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
return scenarios;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
module.exports = GenerateTestsTask;
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
## Validation Rules
|
|
1104
|
+
|
|
1105
|
+
### Input Validation
|
|
1106
|
+
- Component type must be valid or 'all' for bulk generation
|
|
1107
|
+
- Coverage target must be 0-100%
|
|
1108
|
+
- Test framework must be supported
|
|
1109
|
+
- Quality level must be recognized
|
|
1110
|
+
|
|
1111
|
+
### Safety Checks
|
|
1112
|
+
- Don't overwrite existing tests without confirmation
|
|
1113
|
+
- Validate component exists before test generation
|
|
1114
|
+
- Ensure output directory is writable
|
|
1115
|
+
- Check for conflicting test frameworks
|
|
1116
|
+
|
|
1117
|
+
### Generation Requirements
|
|
1118
|
+
- Must generate syntactically valid test code
|
|
1119
|
+
- Should include appropriate setup/teardown
|
|
1120
|
+
- Must include meaningful test descriptions
|
|
1121
|
+
- Should follow testing best practices
|
|
1122
|
+
|
|
1123
|
+
## Integration Points
|
|
1124
|
+
|
|
1125
|
+
### Test Template System
|
|
1126
|
+
- Provides reusable test templates
|
|
1127
|
+
- Manages test code generation patterns
|
|
1128
|
+
- Handles framework-specific syntax
|
|
1129
|
+
- Supports custom test structures
|
|
1130
|
+
|
|
1131
|
+
### Test Generator
|
|
1132
|
+
- Orchestrates test file creation
|
|
1133
|
+
- Analyzes components for testable elements
|
|
1134
|
+
- Generates comprehensive test suites
|
|
1135
|
+
- Handles different test types (unit, integration, e2e)
|
|
1136
|
+
|
|
1137
|
+
### Coverage Analyzer
|
|
1138
|
+
- Analyzes existing test coverage
|
|
1139
|
+
- Identifies coverage gaps
|
|
1140
|
+
- Provides coverage metrics
|
|
1141
|
+
- Suggests coverage improvements
|
|
1142
|
+
|
|
1143
|
+
### Quality Assessment
|
|
1144
|
+
- Evaluates generated test quality
|
|
1145
|
+
- Provides quality metrics and scores
|
|
1146
|
+
- Identifies test improvement opportunities
|
|
1147
|
+
- Validates test effectiveness
|
|
1148
|
+
|
|
1149
|
+
## Output Structure
|
|
1150
|
+
|
|
1151
|
+
### Success Response
|
|
1152
|
+
```json
|
|
1153
|
+
{
|
|
1154
|
+
"success": true,
|
|
1155
|
+
"components": 5,
|
|
1156
|
+
"testFilesGenerated": 12,
|
|
1157
|
+
"expectedCoverage": 85,
|
|
1158
|
+
"qualityScore": 8.5
|
|
1159
|
+
}
|
|
1160
|
+
```
|
|
1161
|
+
|
|
1162
|
+
### Error Response
|
|
1163
|
+
```json
|
|
1164
|
+
{
|
|
1165
|
+
"success": false,
|
|
1166
|
+
"error": "Component not found: agent/invalid-name",
|
|
1167
|
+
"suggestions": ["weather-agent", "data-agent"]
|
|
1168
|
+
}
|
|
1169
|
+
```
|
|
1170
|
+
|
|
1171
|
+
## Security Considerations
|
|
1172
|
+
- Validate all file paths to prevent directory traversal
|
|
1173
|
+
- Sanitize component names and test descriptions
|
|
1174
|
+
- Ensure generated code doesn't include sensitive information
|
|
1175
1175
|
- Validate test framework dependencies for security vulnerabilities
|