moai-adk 0.34.0__py3-none-any.whl → 1.1.0__py3-none-any.whl
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.
- moai_adk/__main__.py +136 -5
- moai_adk/astgrep/__init__.py +37 -0
- moai_adk/astgrep/analyzer.py +522 -0
- moai_adk/astgrep/models.py +124 -0
- moai_adk/astgrep/rules.py +179 -0
- moai_adk/cli/commands/analyze.py +11 -2
- moai_adk/cli/commands/doctor.py +7 -1
- moai_adk/cli/commands/init.py +321 -11
- moai_adk/cli/commands/language.py +7 -1
- moai_adk/cli/commands/rank.py +449 -0
- moai_adk/cli/commands/status.py +7 -1
- moai_adk/cli/commands/switch.py +325 -0
- moai_adk/cli/commands/update.py +296 -23
- moai_adk/cli/prompts/init_prompts.py +362 -66
- moai_adk/cli/prompts/translations/__init__.py +573 -0
- moai_adk/cli/ui/prompts.py +61 -2
- moai_adk/cli/worktree/cli.py +106 -1
- moai_adk/cli/worktree/manager.py +155 -0
- moai_adk/core/config/unified.py +244 -63
- moai_adk/core/credentials.py +264 -0
- moai_adk/core/error_recovery_system.py +22 -4
- moai_adk/core/git/conflict_detector.py +10 -1
- moai_adk/core/git/event_detector.py +16 -5
- moai_adk/core/integration/engine.py +2 -2
- moai_adk/core/integration/integration_tester.py +5 -5
- moai_adk/core/language_config_resolver.py +9 -3
- moai_adk/core/merge/analyzer.py +509 -324
- moai_adk/core/migration/alfred_to_moai_migrator.py +7 -1
- moai_adk/core/migration/backup_manager.py +54 -4
- moai_adk/core/migration/file_migrator.py +174 -2
- moai_adk/core/migration/interactive_checkbox_ui.py +42 -31
- moai_adk/core/migration/version_detector.py +123 -19
- moai_adk/core/migration/version_migrator.py +44 -9
- moai_adk/core/model_allocator.py +241 -0
- moai_adk/core/project/backup_utils.py +12 -2
- moai_adk/core/project/initializer.py +44 -87
- moai_adk/core/project/phase_executor.py +95 -33
- moai_adk/core/project/validator.py +16 -1
- moai_adk/core/quality/trust_checker.py +30 -10
- moai_adk/core/rollback_manager.py +60 -25
- moai_adk/core/template/backup.py +88 -6
- moai_adk/core/template/config.py +33 -9
- moai_adk/core/template/merger.py +34 -8
- moai_adk/core/template/processor.py +334 -11
- moai_adk/core/template_engine.py +10 -1
- moai_adk/core/template_variable_synchronizer.py +16 -2
- moai_adk/core/version_sync.py +54 -6
- moai_adk/foundation/__init__.py +1 -20
- moai_adk/foundation/testing.py +1 -1
- moai_adk/loop/__init__.py +54 -0
- moai_adk/loop/controller.py +305 -0
- moai_adk/loop/feedback.py +230 -0
- moai_adk/loop/state.py +209 -0
- moai_adk/loop/storage.py +220 -0
- moai_adk/lsp/__init__.py +70 -0
- moai_adk/lsp/client.py +320 -0
- moai_adk/lsp/models.py +261 -0
- moai_adk/lsp/protocol.py +404 -0
- moai_adk/lsp/server_manager.py +248 -0
- moai_adk/project/configuration.py +8 -1
- moai_adk/py.typed +0 -0
- moai_adk/ralph/__init__.py +37 -0
- moai_adk/ralph/engine.py +307 -0
- moai_adk/rank/__init__.py +21 -0
- moai_adk/rank/auth.py +425 -0
- moai_adk/rank/client.py +557 -0
- moai_adk/rank/config.py +147 -0
- moai_adk/rank/hook.py +1503 -0
- moai_adk/rank/py.typed +0 -0
- moai_adk/statusline/__init__.py +3 -0
- moai_adk/statusline/enhanced_output_style_detector.py +5 -5
- moai_adk/statusline/main.py +20 -1
- moai_adk/statusline/memory_collector.py +268 -0
- moai_adk/statusline/renderer.py +54 -38
- moai_adk/tag_system/__init__.py +48 -0
- moai_adk/tag_system/atomic_ops.py +117 -0
- moai_adk/tag_system/linkage.py +335 -0
- moai_adk/tag_system/parser.py +176 -0
- moai_adk/tag_system/validator.py +200 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +19 -3
- moai_adk/templates/.claude/agents/moai/builder-command.md +62 -16
- moai_adk/templates/.claude/agents/moai/builder-plugin.md +763 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +21 -5
- moai_adk/templates/.claude/agents/moai/expert-backend.md +103 -39
- moai_adk/templates/.claude/agents/moai/expert-debug.md +9 -3
- moai_adk/templates/.claude/agents/moai/expert-devops.md +16 -14
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +45 -31
- moai_adk/templates/.claude/agents/moai/expert-performance.md +13 -9
- moai_adk/templates/.claude/agents/moai/expert-refactoring.md +228 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +19 -3
- moai_adk/templates/.claude/agents/moai/expert-testing.md +13 -9
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +8 -2
- moai_adk/templates/.claude/agents/moai/manager-docs.md +10 -5
- moai_adk/templates/.claude/agents/moai/manager-git.md +99 -27
- moai_adk/templates/.claude/agents/moai/manager-project.md +87 -7
- moai_adk/templates/.claude/agents/moai/manager-quality.md +22 -5
- moai_adk/templates/.claude/agents/moai/manager-spec.md +8 -2
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +45 -14
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +16 -3
- moai_adk/templates/.claude/commands/moai/0-project.md +239 -1185
- moai_adk/templates/.claude/commands/moai/1-plan.md +383 -363
- moai_adk/templates/.claude/commands/moai/2-run.md +254 -347
- moai_adk/templates/.claude/commands/moai/3-sync.md +174 -100
- moai_adk/templates/.claude/commands/moai/9-feedback.md +49 -33
- moai_adk/templates/.claude/commands/moai/alfred.md +339 -0
- moai_adk/templates/.claude/commands/moai/cancel-loop.md +163 -0
- moai_adk/templates/.claude/commands/moai/fix.md +264 -0
- moai_adk/templates/.claude/commands/moai/loop.md +363 -0
- moai_adk/templates/.claude/hooks/moai/lib/README.md +143 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +37 -81
- moai_adk/templates/.claude/hooks/moai/lib/alfred_detector.py +105 -0
- moai_adk/templates/.claude/hooks/moai/lib/atomic_write.py +122 -0
- moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +4 -1
- moai_adk/templates/.claude/hooks/moai/lib/common.py +35 -5
- moai_adk/templates/.claude/hooks/moai/lib/config.py +376 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +24 -28
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +14 -14
- moai_adk/templates/.claude/hooks/moai/lib/enhanced_output_style_detector.py +372 -0
- moai_adk/templates/.claude/hooks/moai/lib/exceptions.py +171 -0
- moai_adk/templates/.claude/hooks/moai/lib/file_utils.py +95 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_collector.py +190 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +15 -13
- moai_adk/templates/.claude/hooks/moai/lib/language_detector.py +298 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +125 -25
- moai_adk/templates/.claude/hooks/moai/lib/main.py +341 -0
- moai_adk/templates/.claude/hooks/moai/lib/memory_collector.py +268 -0
- moai_adk/templates/.claude/hooks/moai/lib/metrics_tracker.py +78 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +9 -7
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +204 -13
- moai_adk/templates/.claude/hooks/moai/lib/project.py +23 -14
- moai_adk/templates/.claude/hooks/moai/lib/renderer.py +359 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_linkage.py +333 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_parser.py +176 -0
- moai_adk/templates/.claude/hooks/moai/lib/tag_validator.py +200 -0
- moai_adk/templates/.claude/hooks/moai/lib/timeout.py +5 -5
- moai_adk/templates/.claude/hooks/moai/lib/tool_registry.py +896 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +30 -18
- moai_adk/templates/.claude/hooks/moai/lib/update_checker.py +129 -0
- moai_adk/templates/.claude/hooks/moai/lib/version_reader.py +741 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__ast_grep_scan.py +276 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__code_formatter.py +255 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__coverage_guard.py +325 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__linter.py +315 -0
- moai_adk/templates/.claude/hooks/moai/post_tool__lsp_diagnostic.py +508 -0
- moai_adk/templates/.claude/hooks/moai/pre_commit__tag_validator.py +287 -0
- moai_adk/templates/.claude/hooks/moai/pre_tool__security_guard.py +268 -0
- moai_adk/templates/.claude/hooks/moai/pre_tool__tdd_enforcer.py +208 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +93 -61
- moai_adk/templates/.claude/hooks/moai/session_end__rank_submit.py +69 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +165 -70
- moai_adk/templates/.claude/hooks/moai/shared/utils/announcement_translator.py +206 -0
- moai_adk/templates/.claude/hooks/moai/stop__loop_controller.py +621 -0
- moai_adk/templates/.claude/output-styles/moai/alfred.md +758 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +86 -3
- moai_adk/templates/.claude/output-styles/moai/yoda.md +2 -2
- moai_adk/templates/.claude/settings.json +154 -77
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +252 -198
- moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +169 -323
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +39 -27
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +115 -125
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +150 -150
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +182 -175
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +198 -138
- moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +226 -320
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +43 -222
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +75 -219
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +103 -463
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/component-architecture.md +723 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/nextjs16-patterns.md +713 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/performance-optimization.md +694 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/react19-patterns.md +591 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/state-management.md +680 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/modules/vue35-patterns.md +802 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +118 -339
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +74 -377
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +299 -70
- moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +205 -182
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/advanced-agent-patterns.md +370 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-cli-reference-official.md +420 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +32 -22
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-devcontainers-official.md +381 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-discover-plugins-official.md +379 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-headless-official.md +378 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +110 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-plugin-marketplaces-official.md +308 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-plugins-official.md +640 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sandboxing-official.md +282 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +425 -71
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-statusline-official.md +293 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +325 -143
- moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +96 -316
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +116 -294
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-advanced.md +279 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-implementation.md +267 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +121 -650
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/patterns.md +22 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-ears-format.md +200 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +37 -730
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-tdd-implementation.md +275 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +77 -819
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-implementation.md +244 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-validation.md +219 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +14 -18
- moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +86 -270
- moai_adk/templates/.claude/skills/moai-framework-electron/SKILL.md +288 -0
- moai_adk/templates/.claude/skills/moai-framework-electron/examples.md +2082 -0
- moai_adk/templates/.claude/skills/moai-framework-electron/reference.md +1649 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +76 -582
- moai_adk/templates/.claude/skills/moai-lang-cpp/examples.md +1239 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/modules/advanced-patterns.md +401 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/reference.md +1136 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +82 -436
- moai_adk/templates/.claude/skills/moai-lang-csharp/examples.md +585 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/aspnet-core.md +627 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/blazor-components.md +767 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/cqrs-validation.md +626 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/csharp12-features.md +580 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/modules/efcore-patterns.md +622 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/reference.md +403 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +65 -542
- moai_adk/templates/.claude/skills/moai-lang-elixir/examples.md +1171 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/modules/advanced-patterns.md +531 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/reference.md +889 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +32 -405
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +114 -293
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +83 -307
- moai_adk/templates/.claude/skills/moai-lang-javascript/SKILL.md +179 -0
- moai_adk/templates/.claude/skills/moai-lang-javascript/examples.md +973 -0
- moai_adk/templates/.claude/skills/moai-lang-javascript/reference.md +1543 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +42 -279
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +94 -556
- moai_adk/templates/.claude/skills/moai-lang-php/examples.md +1608 -0
- moai_adk/templates/.claude/skills/moai-lang-php/modules/advanced-patterns.md +538 -0
- moai_adk/templates/.claude/skills/moai-lang-php/reference.md +1323 -0
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +108 -358
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +84 -482
- moai_adk/templates/.claude/skills/moai-lang-r/examples.md +1154 -0
- moai_adk/templates/.claude/skills/moai-lang-r/modules/advanced-patterns.md +489 -0
- moai_adk/templates/.claude/skills/moai-lang-r/reference.md +1087 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +106 -610
- moai_adk/templates/.claude/skills/moai-lang-ruby/examples.md +1106 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/modules/advanced-patterns.md +309 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/modules/testing-patterns.md +306 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/reference.md +1024 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +51 -265
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +106 -442
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/akka-actors.md +479 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/cats-effect.md +489 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/functional-programming.md +460 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/spark-data.md +498 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/modules/zio-patterns.md +541 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +88 -457
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/combine-reactive.md +256 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/concurrency.md +270 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/swift6-features.md +265 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/modules/swiftui-patterns.md +314 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +75 -283
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +97 -252
- moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +64 -240
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +331 -12
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +330 -37
- moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +90 -287
- moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +200 -206
- moai_adk/templates/.claude/skills/moai-platform-auth0/examples.md +2446 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/adaptive-mfa.md +233 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/akamai-integration.md +214 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/application-credentials.md +280 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-log-events.md +224 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/attack-protection-overview.md +140 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/bot-detection.md +144 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/breached-password-detection.md +187 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/brute-force-protection.md +189 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/certifications.md +282 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/compliance-overview.md +263 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/continuous-session-protection.md +307 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/customize-mfa.md +177 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/dpop-implementation.md +283 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/fapi-implementation.md +259 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/gdpr-compliance.md +313 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/guardian-configuration.md +269 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/highly-regulated-identity.md +272 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/jwt-fundamentals.md +248 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mdl-verification.md +210 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-api-management.md +278 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-factors.md +226 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mfa-overview.md +174 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/mtls-sender-constraining.md +316 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/ropg-flow-mfa.md +216 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-center.md +325 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/security-guidance.md +277 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/state-parameters.md +177 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/step-up-authentication.md +251 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/suspicious-ip-throttling.md +240 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/tenant-access-control.md +179 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/modules/webauthn-fido.md +235 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/reference.md +224 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +75 -330
- moai_adk/templates/.claude/skills/moai-platform-clerk/examples.md +1426 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/modules/advanced-patterns.md +417 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/reference.md +273 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +100 -340
- moai_adk/templates/.claude/skills/moai-platform-convex/examples.md +506 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/auth-integration.md +421 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/file-storage.md +474 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/reactive-queries.md +302 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/modules/server-functions.md +452 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/reference.md +385 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +113 -326
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/examples.md +514 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/custom-claims.md +374 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/phone-auth.md +372 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/modules/social-auth.md +339 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/reference.md +382 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +71 -302
- moai_adk/templates/.claude/skills/moai-platform-firestore/examples.md +445 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/offline-cache.md +392 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/realtime-listeners.md +441 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/security-rules.md +352 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/modules/transactions.md +452 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/reference.md +322 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +101 -412
- moai_adk/templates/.claude/skills/moai-platform-neon/examples.md +470 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/auto-scaling.md +349 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/branching-workflows.md +354 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/connection-pooling.md +412 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/modules/pitr-backups.md +458 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/reference.md +272 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +96 -327
- moai_adk/templates/.claude/skills/moai-platform-railway/examples.md +539 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/docker-deployment.md +261 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/multi-service.md +291 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/networking-domains.md +338 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/modules/volumes-storage.md +353 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/reference.md +374 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +103 -428
- moai_adk/templates/.claude/skills/moai-platform-supabase/examples.md +502 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/auth-integration.md +384 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/edge-functions.md +371 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/postgresql-pgvector.md +231 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/realtime-presence.md +354 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/row-level-security.md +286 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/storage-cdn.md +319 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/modules/typescript-patterns.md +453 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/reference.md +284 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +96 -446
- moai_adk/templates/.claude/skills/moai-platform-vercel/examples.md +502 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/analytics-speed.md +348 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/deployment-config.md +344 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/edge-functions.md +222 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/isr-caching.md +306 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/modules/kv-storage.md +399 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/reference.md +360 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/SKILL.md +193 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/examples.md +1099 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/language-specific.md +307 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/pattern-syntax.md +237 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/refactoring-patterns.md +260 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/modules/security-rules.md +239 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/reference.md +288 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/go.yml +90 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/python.yml +101 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/languages/typescript.yml +83 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/complexity-check.yml +94 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/quality/deprecated-apis.yml +84 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/secrets-detection.yml +89 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/sql-injection.yml +45 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/security/xss-prevention.yml +50 -0
- moai_adk/templates/.claude/skills/moai-tool-ast-grep/rules/sgconfig.yml +54 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +225 -423
- moai_adk/templates/.claude/skills/moai-workflow-loop/SKILL.md +197 -0
- moai_adk/templates/.claude/skills/moai-workflow-loop/examples.md +1063 -0
- moai_adk/templates/.claude/skills/moai-workflow-loop/reference.md +1414 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +211 -314
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +15 -43
- moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +119 -316
- moai_adk/templates/.claude/skills/moai-workflow-spec/modules/advanced-patterns.md +237 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +96 -203
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +201 -388
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +52 -3
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +263 -806
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/context7-integration.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/review-workflows.md +500 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/relevance-analysis.md +154 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/safety-analysis.md +148 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/scoring-algorithms.md +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/timeliness-analysis.md +168 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/truthfulness-analysis.md +136 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework/usability-analysis.md +153 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review/trust5-framework.md +257 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +191 -1344
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/analysis-patterns.md +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/core-classes.md +299 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/code-review/tool-integration.md +380 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/debugging-workflows.md +451 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/debugging/error-analysis.md +442 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/optimization-patterns.md +473 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance/profiling-techniques.md +481 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/ai-optimization.md +241 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/bottleneck-detection.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/optimization-plan.md +315 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/profiler-core.md +277 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization/real-time-monitoring.md +187 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +287 -1194
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/quality-metrics.md +415 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/ai-workflows.md +620 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/refactoring/patterns.md +692 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/security-analysis.md +429 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +262 -1192
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/static-analysis.md +438 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd/core-classes.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/advanced-features.md +494 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/red-green-refactor.md +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-generation.md +471 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7/test-patterns.md +371 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +227 -1222
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/trust5-validation.md +428 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/SKILL.md +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/integration-patterns.md +149 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/moai-adk-integration.md +245 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-advanced.md +310 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-development.md +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/parallel-workflows.md +302 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/registry-architecture.md +271 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/resource-optimization.md +300 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/tools-integration.md +280 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/troubleshooting.md +397 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-commands.md +296 -0
- moai_adk/templates/.claude/skills/moai-workflow-worktree/modules/worktree-management.md +217 -0
- moai_adk/templates/.git-hooks/pre-push +162 -59
- moai_adk/templates/.github/workflows/ci-universal.yml +934 -133
- moai_adk/templates/.gitignore +65 -107
- moai_adk/templates/.lsp.json +152 -0
- moai_adk/templates/.mcp.json +2 -20
- moai_adk/templates/.moai/announcements/en.json +18 -0
- moai_adk/templates/.moai/announcements/ja.json +18 -0
- moai_adk/templates/.moai/announcements/ko.json +18 -0
- moai_adk/templates/.moai/announcements/zh.json +18 -0
- moai_adk/templates/.moai/config/config.yaml +8 -2
- moai_adk/templates/.moai/config/multilingual-triggers.yaml +213 -0
- moai_adk/templates/.moai/config/sections/language.yaml +2 -2
- moai_adk/templates/.moai/config/sections/llm.yaml +41 -0
- moai_adk/templates/.moai/config/sections/pricing.yaml +30 -0
- moai_adk/templates/.moai/config/sections/project.yaml +2 -2
- moai_adk/templates/.moai/config/sections/quality.yaml +43 -5
- moai_adk/templates/.moai/config/sections/ralph.yaml +55 -0
- moai_adk/templates/.moai/config/sections/system.yaml +46 -1
- moai_adk/templates/.moai/config/sections/user.yaml +1 -1
- moai_adk/templates/.moai/config/statusline-config.yaml +2 -2
- moai_adk/templates/.moai/llm-configs/glm.json +22 -0
- moai_adk/templates/CLAUDE.ja.md +343 -0
- moai_adk/templates/CLAUDE.ko.md +343 -0
- moai_adk/templates/CLAUDE.md +200 -499
- moai_adk/templates/CLAUDE.zh.md +343 -0
- moai_adk/utils/common.py +37 -0
- moai_adk/version.py +1 -1
- moai_adk-1.1.0.dist-info/METADATA +2443 -0
- moai_adk-1.1.0.dist-info/RECORD +701 -0
- {moai_adk-0.34.0.dist-info → moai_adk-1.1.0.dist-info}/entry_points.txt +2 -0
- moai_adk-1.1.0.dist-info/licenses/LICENSE +99 -0
- moai_adk/core/config/auto_spec_config.py +0 -340
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +0 -901
- moai_adk/core/spec/confidence_scoring.py +0 -680
- moai_adk/core/spec/ears_template_engine.py +0 -1247
- moai_adk/core/spec/quality_validator.py +0 -687
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +0 -670
- moai_adk/templates/.claude/agents/moai/expert-database.md +0 -777
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +0 -1041
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +0 -458
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +0 -1607
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +0 -789
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +0 -469
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +0 -1032
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +0 -438
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +0 -431
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/design-system-tokens.md +0 -405
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +0 -336
- moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +0 -402
- moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +0 -607
- moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +0 -300
- moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +0 -537
- moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +0 -520
- moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +0 -574
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +0 -317
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +0 -663
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +0 -190
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +0 -175
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +0 -196
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +0 -17
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +0 -158
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +0 -340
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +0 -713
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +0 -538
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +0 -1336
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +0 -730
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +0 -608
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +0 -1005
- moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +0 -436
- moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +0 -411
- moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +0 -982
- moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +0 -778
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +0 -646
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +0 -782
- moai_adk/templates/.moai/config/questions/_schema.yaml +0 -151
- moai_adk/templates/.moai/config/questions/tab0-init.yaml +0 -251
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +0 -108
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +0 -81
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +0 -634
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +0 -170
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +0 -87
- moai_adk/templates/.moai/scripts/setup-glm.py +0 -136
- moai_adk-0.34.0.dist-info/METADATA +0 -2999
- moai_adk-0.34.0.dist-info/RECORD +0 -463
- moai_adk-0.34.0.dist-info/licenses/LICENSE +0 -21
- /moai_adk/foundation/{git.py → git/__init__.py} +0 -0
- /moai_adk/templates/.claude/skills/moai-library-mermaid/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-library-mermaid/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-library-nextra/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-jit-docs/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-jit-docs/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-testing/{advanced-patterns.md → modules/advanced-patterns.md} +0 -0
- /moai_adk/templates/.claude/skills/moai-workflow-testing/{optimization.md → modules/optimization.md} +0 -0
- /moai_adk/templates/.claude/skills/{moai-worktree → moai-workflow-worktree}/examples.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-worktree → moai-workflow-worktree}/reference.md +0 -0
- {moai_adk-0.34.0.dist-info → moai_adk-1.1.0.dist-info}/WHEEL +0 -0
|
@@ -5,1109 +5,29 @@
|
|
|
5
5
|
> Time: 25+ minutes
|
|
6
6
|
> Dependencies: Python 3.8+, pytest, Context7 MCP, unittest, asyncio
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Overview
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
TDD Context7 integration provides a comprehensive test-driven development workflow with AI-powered test generation, Context7-enhanced testing patterns, and automated best practices enforcement.
|
|
11
|
+
|
|
12
|
+
### Key Features
|
|
13
|
+
|
|
14
|
+
- AI-Powered Test Generation: Generate comprehensive test suites from specifications
|
|
15
|
+
- Context7 Integration: Access latest testing patterns and best practices
|
|
16
|
+
- RED-GREEN-REFACTOR Cycle: Complete TDD workflow implementation
|
|
17
|
+
- Advanced Testing: Property-based testing, mutation testing, continuous testing
|
|
18
|
+
- Test Patterns: Comprehensive library of testing patterns and fixtures
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Basic TDD Cycle
|
|
11
23
|
|
|
12
24
|
```python
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
import asyncio
|
|
16
|
-
import subprocess
|
|
17
|
-
import os
|
|
18
|
-
import sys
|
|
19
|
-
import time
|
|
20
|
-
from typing import Dict, List, Optional, Any, Union, Callable
|
|
21
|
-
from dataclasses import dataclass, field
|
|
22
|
-
from enum import Enum
|
|
23
|
-
import ast
|
|
24
|
-
import inspect
|
|
25
|
-
import json
|
|
26
|
-
from pathlib import Path
|
|
27
|
-
|
|
28
|
-
class TDDPhase(Enum):
|
|
29
|
-
"""TDD cycle phases."""
|
|
30
|
-
RED = "red" # Write failing test
|
|
31
|
-
GREEN = "green" # Make test pass
|
|
32
|
-
REFACTOR = "refactor" # Improve code while keeping tests green
|
|
33
|
-
REVIEW = "review" # Review and commit changes
|
|
34
|
-
|
|
35
|
-
class TestType(Enum):
|
|
36
|
-
"""Types of tests in TDD."""
|
|
37
|
-
UNIT = "unit"
|
|
38
|
-
INTEGRATION = "integration"
|
|
39
|
-
ACCEPTANCE = "acceptance"
|
|
40
|
-
PERFORMANCE = "performance"
|
|
41
|
-
SECURITY = "security"
|
|
42
|
-
REGRESSION = "regression"
|
|
43
|
-
|
|
44
|
-
class TestStatus(Enum):
|
|
45
|
-
"""Test execution status."""
|
|
46
|
-
PENDING = "pending"
|
|
47
|
-
RUNNING = "running"
|
|
48
|
-
PASSED = "passed"
|
|
49
|
-
FAILED = "failed"
|
|
50
|
-
SKIPPED = "skipped"
|
|
51
|
-
ERROR = "error"
|
|
52
|
-
|
|
53
|
-
@dataclass
|
|
54
|
-
class TestSpecification:
|
|
55
|
-
"""Specification for a TDD test."""
|
|
56
|
-
name: str
|
|
57
|
-
description: str
|
|
58
|
-
test_type: TestType
|
|
59
|
-
requirements: List[str]
|
|
60
|
-
acceptance_criteria: List[str]
|
|
61
|
-
edge_cases: List[str]
|
|
62
|
-
preconditions: List[str] = field(default_factory=list)
|
|
63
|
-
postconditions: List[str] = field(default_factory=list)
|
|
64
|
-
dependencies: List[str] = field(default_factory=list)
|
|
65
|
-
mock_requirements: Dict[str, Any] = field(default_factory=dict)
|
|
66
|
-
|
|
67
|
-
@dataclass
|
|
68
|
-
class TestCase:
|
|
69
|
-
"""Individual test case with metadata."""
|
|
70
|
-
id: str
|
|
71
|
-
name: str
|
|
72
|
-
file_path: str
|
|
73
|
-
line_number: int
|
|
74
|
-
specification: TestSpecification
|
|
75
|
-
status: TestStatus
|
|
76
|
-
execution_time: float
|
|
77
|
-
error_message: Optional[str] = None
|
|
78
|
-
coverage_data: Dict[str, Any] = field(default_factory=dict)
|
|
79
|
-
|
|
80
|
-
@dataclass
|
|
81
|
-
class TDDSession:
|
|
82
|
-
"""TDD development session with cycle tracking."""
|
|
83
|
-
id: str
|
|
84
|
-
project_path: str
|
|
85
|
-
current_phase: TDDPhase
|
|
86
|
-
test_cases: List[TestCase]
|
|
87
|
-
start_time: float
|
|
88
|
-
context7_patterns: Dict[str, Any] = field(default_factory=dict)
|
|
89
|
-
metrics: Dict[str, Any] = field(default_factory=dict)
|
|
90
|
-
|
|
91
|
-
class Context7TDDIntegration:
|
|
92
|
-
"""Integration with Context7 for TDD patterns and best practices."""
|
|
93
|
-
|
|
94
|
-
def __init__(self, context7_client=None):
|
|
95
|
-
self.context7 = context7_client
|
|
96
|
-
self.pattern_cache = {}
|
|
97
|
-
self.test_generators = {}
|
|
98
|
-
|
|
99
|
-
async def load_tdd_patterns(self, language: str = "python") -> Dict[str, Any]:
|
|
100
|
-
"""Load TDD patterns and best practices from Context7."""
|
|
101
|
-
|
|
102
|
-
cache_key = f"tdd_patterns_{language}"
|
|
103
|
-
if cache_key in self.pattern_cache:
|
|
104
|
-
return self.pattern_cache[cache_key]
|
|
105
|
-
|
|
106
|
-
patterns = {}
|
|
107
|
-
|
|
108
|
-
if self.context7:
|
|
109
|
-
try:
|
|
110
|
-
# Load TDD best practices
|
|
111
|
-
tdd_patterns = await self.context7.get_library_docs(
|
|
112
|
-
context7_library_id="/testing/pytest",
|
|
113
|
-
topic="TDD RED-GREEN-REFACTOR patterns best practices 2025",
|
|
114
|
-
tokens=4000
|
|
115
|
-
)
|
|
116
|
-
patterns['tdd_best_practices'] = tdd_patterns
|
|
117
|
-
|
|
118
|
-
# Load test patterns for specific language
|
|
119
|
-
if language == "python":
|
|
120
|
-
python_patterns = await self.context7.get_library_docs(
|
|
121
|
-
context7_library_id="/python/pytest",
|
|
122
|
-
topic="advanced testing patterns mocking fixtures 2025",
|
|
123
|
-
tokens=3000
|
|
124
|
-
)
|
|
125
|
-
patterns['python_testing'] = python_patterns
|
|
126
|
-
|
|
127
|
-
# Load assertion patterns
|
|
128
|
-
assertion_patterns = await self.context7.get_library_docs(
|
|
129
|
-
context7_library_id="/testing/assertions",
|
|
130
|
-
topic="assertion patterns error messages test design 2025",
|
|
131
|
-
tokens=2000
|
|
132
|
-
)
|
|
133
|
-
patterns['assertions'] = assertion_patterns
|
|
134
|
-
|
|
135
|
-
# Load mocking patterns
|
|
136
|
-
mocking_patterns = await self.context7.get_library_docs(
|
|
137
|
-
context7_library_id="/python/unittest-mock",
|
|
138
|
-
topic="mocking strategies test doubles isolation patterns 2025",
|
|
139
|
-
tokens=3000
|
|
140
|
-
)
|
|
141
|
-
patterns['mocking'] = mocking_patterns
|
|
142
|
-
|
|
143
|
-
except Exception as e:
|
|
144
|
-
print(f"Failed to load Context7 patterns: {e}")
|
|
145
|
-
patterns = self._get_default_patterns()
|
|
146
|
-
else:
|
|
147
|
-
patterns = self._get_default_patterns()
|
|
148
|
-
|
|
149
|
-
self.pattern_cache[cache_key] = patterns
|
|
150
|
-
return patterns
|
|
151
|
-
|
|
152
|
-
def _get_default_patterns(self) -> Dict[str, Any]:
|
|
153
|
-
"""Get default TDD patterns when Context7 is unavailable."""
|
|
154
|
-
return {
|
|
155
|
-
'tdd_best_practices': {
|
|
156
|
-
'red_phase': [
|
|
157
|
-
"Write the simplest possible failing test",
|
|
158
|
-
"Test one specific behavior or requirement",
|
|
159
|
-
"Ensure test clearly expresses intent",
|
|
160
|
-
"Make test fail for the right reason"
|
|
161
|
-
],
|
|
162
|
-
'green_phase': [
|
|
163
|
-
"Write the simplest code to make test pass",
|
|
164
|
-
"Don't worry about code quality yet",
|
|
165
|
-
"Focus on making the test green quickly",
|
|
166
|
-
"Avoid premature optimization"
|
|
167
|
-
],
|
|
168
|
-
'refactor_phase': [
|
|
169
|
-
"Improve code design while keeping tests green",
|
|
170
|
-
"Remove duplication and improve readability",
|
|
171
|
-
"Apply design patterns appropriately",
|
|
172
|
-
"Ensure all tests still pass"
|
|
173
|
-
]
|
|
174
|
-
},
|
|
175
|
-
'python_testing': {
|
|
176
|
-
'pytest_features': [
|
|
177
|
-
"Parametrized tests for multiple scenarios",
|
|
178
|
-
"Fixtures for test setup and teardown",
|
|
179
|
-
"Markers for categorizing tests",
|
|
180
|
-
"Plugins for enhanced functionality"
|
|
181
|
-
],
|
|
182
|
-
'assertions': [
|
|
183
|
-
"Use pytest's assert statements",
|
|
184
|
-
"Provide clear error messages",
|
|
185
|
-
"Test expected exceptions with pytest.raises",
|
|
186
|
-
"Use pytest.approx for floating point comparisons"
|
|
187
|
-
]
|
|
188
|
-
},
|
|
189
|
-
'assertions': {
|
|
190
|
-
'best_practices': [
|
|
191
|
-
"One assertion per test when possible",
|
|
192
|
-
"Clear and descriptive assertion messages",
|
|
193
|
-
"Test both positive and negative cases",
|
|
194
|
-
"Use appropriate assertion methods"
|
|
195
|
-
]
|
|
196
|
-
},
|
|
197
|
-
'mocking': {
|
|
198
|
-
'strategies': [
|
|
199
|
-
"Mock external dependencies",
|
|
200
|
-
"Use dependency injection for testability",
|
|
201
|
-
"Create test doubles for complex objects",
|
|
202
|
-
"Verify interactions with mocks"
|
|
203
|
-
]
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
class TestGenerator:
|
|
208
|
-
"""AI-powered test case generation based on specifications."""
|
|
209
|
-
|
|
210
|
-
def __init__(self, context7_client=None):
|
|
211
|
-
self.context7 = context7_client
|
|
212
|
-
self.templates = self._load_test_templates()
|
|
213
|
-
|
|
214
|
-
def _load_test_templates(self) -> Dict[str, str]:
|
|
215
|
-
"""Load test templates for different scenarios."""
|
|
216
|
-
return {
|
|
217
|
-
'unit_function': '''
|
|
218
|
-
def test_{function_name}_{scenario}():
|
|
219
|
-
"""
|
|
220
|
-
Test {description}
|
|
221
|
-
|
|
222
|
-
Given: {preconditions}
|
|
223
|
-
When: {action}
|
|
224
|
-
Then: {expected_outcome}
|
|
225
|
-
"""
|
|
226
|
-
# Arrange
|
|
227
|
-
{setup_code}
|
|
228
|
-
|
|
229
|
-
# Act
|
|
230
|
-
result = {function_call}
|
|
231
|
-
|
|
232
|
-
# Assert
|
|
233
|
-
assert result == {expected_value}, f"Expected {expected_value}, got {result}"
|
|
234
|
-
''',
|
|
235
|
-
'unit_method': '''
|
|
236
|
-
class Test{ClassName}:
|
|
237
|
-
def test_{method_name}_{scenario}(self):
|
|
238
|
-
"""
|
|
239
|
-
Test {description}
|
|
240
|
-
"""
|
|
241
|
-
# Arrange
|
|
242
|
-
{setup_code}
|
|
243
|
-
instance = {ClassName}({constructor_args})
|
|
244
|
-
|
|
245
|
-
# Act
|
|
246
|
-
result = instance.{method_name}({method_args})
|
|
247
|
-
|
|
248
|
-
# Assert
|
|
249
|
-
{assertions}
|
|
250
|
-
''',
|
|
251
|
-
'integration_test': '''
|
|
252
|
-
def test_{feature_name}_{scenario}():
|
|
253
|
-
"""
|
|
254
|
-
Test integration: {description}
|
|
255
|
-
"""
|
|
256
|
-
# Arrange
|
|
257
|
-
{setup_code}
|
|
258
|
-
|
|
259
|
-
# Act
|
|
260
|
-
result = {action}
|
|
261
|
-
|
|
262
|
-
# Assert
|
|
263
|
-
{assertions}
|
|
264
|
-
|
|
265
|
-
# Cleanup
|
|
266
|
-
{cleanup_code}
|
|
267
|
-
''',
|
|
268
|
-
'exception_test': '''
|
|
269
|
-
def test_{function_name}_raises_{exception}_{scenario}():
|
|
270
|
-
"""
|
|
271
|
-
Test that {function_name} raises {exception} when {condition}
|
|
272
|
-
"""
|
|
273
|
-
# Arrange
|
|
274
|
-
{setup_code}
|
|
275
|
-
|
|
276
|
-
# Act & Assert
|
|
277
|
-
with pytest.raises({exception}) as exc_info:
|
|
278
|
-
{function_call}
|
|
279
|
-
|
|
280
|
-
assert "{expected_message}" in str(exc_info.value)
|
|
281
|
-
''',
|
|
282
|
-
'parameterized_test': '''
|
|
283
|
-
@pytest.mark.parametrize("{param_names}", {test_values})
|
|
284
|
-
def test_{function_name}_{scenario}({param_names}):
|
|
285
|
-
"""
|
|
286
|
-
Test {function_name} with different inputs: {description}
|
|
287
|
-
"""
|
|
288
|
-
# Arrange
|
|
289
|
-
{setup_code}
|
|
290
|
-
|
|
291
|
-
# Act
|
|
292
|
-
result = {function_call}
|
|
293
|
-
|
|
294
|
-
# Assert
|
|
295
|
-
assert result == {expected_value}, f"For {param_names}={{param_names}}, expected {expected_value}, got {{result}}"
|
|
296
|
-
'''
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
async def generate_test_case(
|
|
300
|
-
self, specification: TestSpecification,
|
|
301
|
-
context7_patterns: Dict[str, Any] = None
|
|
302
|
-
) -> str:
|
|
303
|
-
"""Generate test code based on specification."""
|
|
304
|
-
|
|
305
|
-
if self.context7 and context7_patterns:
|
|
306
|
-
try:
|
|
307
|
-
# Use Context7 to enhance test generation
|
|
308
|
-
enhanced_spec = await self._enhance_specification_with_context7(
|
|
309
|
-
specification, context7_patterns
|
|
310
|
-
)
|
|
311
|
-
return self._generate_test_from_enhanced_spec(enhanced_spec)
|
|
312
|
-
except Exception as e:
|
|
313
|
-
print(f"Context7 test generation failed: {e}")
|
|
314
|
-
|
|
315
|
-
return self._generate_test_from_specification(specification)
|
|
316
|
-
|
|
317
|
-
async def _enhance_specification_with_context7(
|
|
318
|
-
self, specification: TestSpecification,
|
|
319
|
-
context7_patterns: Dict[str, Any]
|
|
320
|
-
) -> TestSpecification:
|
|
321
|
-
"""Enhance test specification using Context7 patterns."""
|
|
322
|
-
|
|
323
|
-
# Add additional edge cases based on Context7 patterns
|
|
324
|
-
additional_edge_cases = []
|
|
325
|
-
|
|
326
|
-
testing_patterns = context7_patterns.get('python_testing', {})
|
|
327
|
-
if testing_patterns:
|
|
328
|
-
# Add common edge cases for different data types
|
|
329
|
-
if any('number' in str(req).lower() for req in specification.requirements):
|
|
330
|
-
additional_edge_cases.extend([
|
|
331
|
-
"Test with zero value",
|
|
332
|
-
"Test with negative value",
|
|
333
|
-
"Test with maximum/minimum values",
|
|
334
|
-
"Test with floating point edge cases"
|
|
335
|
-
])
|
|
336
|
-
|
|
337
|
-
if any('string' in str(req).lower() for req in specification.requirements):
|
|
338
|
-
additional_edge_cases.extend([
|
|
339
|
-
"Test with empty string",
|
|
340
|
-
"Test with very long string",
|
|
341
|
-
"Test with special characters",
|
|
342
|
-
"Test with unicode characters"
|
|
343
|
-
])
|
|
344
|
-
|
|
345
|
-
if any('list' in str(req).lower() or 'array' in str(req).lower() for req in specification.requirements):
|
|
346
|
-
additional_edge_cases.extend([
|
|
347
|
-
"Test with empty list",
|
|
348
|
-
"Test with single element",
|
|
349
|
-
"Test with large list",
|
|
350
|
-
"Test with duplicate elements"
|
|
351
|
-
])
|
|
352
|
-
|
|
353
|
-
# Combine original and additional edge cases
|
|
354
|
-
combined_edge_cases = list(set(specification.edge_cases + additional_edge_cases))
|
|
355
|
-
|
|
356
|
-
return TestSpecification(
|
|
357
|
-
name=specification.name,
|
|
358
|
-
description=specification.description,
|
|
359
|
-
test_type=specification.test_type,
|
|
360
|
-
requirements=specification.requirements,
|
|
361
|
-
acceptance_criteria=specification.acceptance_criteria,
|
|
362
|
-
edge_cases=combined_edge_cases,
|
|
363
|
-
preconditions=specification.preconditions,
|
|
364
|
-
postconditions=specification.postconditions,
|
|
365
|
-
dependencies=specification.dependencies,
|
|
366
|
-
mock_requirements=specification.mock_requirements
|
|
367
|
-
)
|
|
368
|
-
|
|
369
|
-
def _generate_test_from_enhanced_spec(self, spec: TestSpecification) -> str:
|
|
370
|
-
"""Generate test code from enhanced specification."""
|
|
371
|
-
return self._generate_test_from_specification(spec)
|
|
372
|
-
|
|
373
|
-
def _generate_test_from_specification(self, spec: TestSpecification) -> str:
|
|
374
|
-
"""Generate test code from specification."""
|
|
375
|
-
|
|
376
|
-
# Determine appropriate template based on test type and requirements
|
|
377
|
-
if spec.test_type == TestType.UNIT:
|
|
378
|
-
return self._generate_unit_test(spec)
|
|
379
|
-
elif spec.test_type == TestType.INTEGRATION:
|
|
380
|
-
return self._generate_integration_test(spec)
|
|
381
|
-
else:
|
|
382
|
-
return self._generate_generic_test(spec)
|
|
383
|
-
|
|
384
|
-
def _generate_unit_test(self, spec: TestSpecification) -> str:
|
|
385
|
-
"""Generate unit test code."""
|
|
386
|
-
|
|
387
|
-
# Extract function/class information from specification name
|
|
388
|
-
function_name = spec.name.lower().replace('test_', '').replace('_test', '')
|
|
389
|
-
|
|
390
|
-
# Check if this is an exception test
|
|
391
|
-
if any('error' in criterion.lower() or 'exception' in criterion.lower()
|
|
392
|
-
for criterion in spec.acceptance_criteria):
|
|
393
|
-
return self._generate_exception_test(spec, function_name)
|
|
394
|
-
|
|
395
|
-
# Check if this requires parameterization
|
|
396
|
-
if len(spec.acceptance_criteria) > 1 or len(spec.edge_cases) > 2:
|
|
397
|
-
return self._generate_parameterized_test(spec, function_name)
|
|
398
|
-
|
|
399
|
-
# Generate standard unit test
|
|
400
|
-
return self._generate_standard_unit_test(spec, function_name)
|
|
401
|
-
|
|
402
|
-
def _generate_standard_unit_test(self, spec: TestSpecification, function_name: str) -> str:
|
|
403
|
-
"""Generate standard unit test."""
|
|
404
|
-
|
|
405
|
-
template = self.templates['unit_function']
|
|
406
|
-
|
|
407
|
-
# Fill template with specification details
|
|
408
|
-
setup_code = self._generate_setup_code(spec)
|
|
409
|
-
function_call = self._generate_function_call(function_name, spec)
|
|
410
|
-
assertions = self._generate_assertions(spec)
|
|
411
|
-
|
|
412
|
-
return template.format(
|
|
413
|
-
function_name=function_name,
|
|
414
|
-
scenario=self._extract_scenario(spec),
|
|
415
|
-
description=spec.description,
|
|
416
|
-
preconditions=', '.join(spec.preconditions),
|
|
417
|
-
action=self._describe_action(spec),
|
|
418
|
-
expected_outcome=spec.acceptance_criteria[0] if spec.acceptance_criteria else "expected behavior",
|
|
419
|
-
setup_code=setup_code,
|
|
420
|
-
function_call=function_call,
|
|
421
|
-
expected_value=self._extract_expected_value(spec),
|
|
422
|
-
assertions=assertions
|
|
423
|
-
)
|
|
424
|
-
|
|
425
|
-
def _generate_exception_test(self, spec: TestSpecification, function_name: str) -> str:
|
|
426
|
-
"""Generate exception test."""
|
|
427
|
-
|
|
428
|
-
template = self.templates['exception_test']
|
|
429
|
-
|
|
430
|
-
# Extract expected exception and message
|
|
431
|
-
exception_type = "Exception" # Default
|
|
432
|
-
expected_message = "Error occurred"
|
|
433
|
-
|
|
434
|
-
for criterion in spec.acceptance_criteria:
|
|
435
|
-
if 'raise' in criterion.lower() or 'exception' in criterion.lower():
|
|
436
|
-
# Try to extract exception type
|
|
437
|
-
if 'valueerror' in criterion.lower():
|
|
438
|
-
exception_type = "ValueError"
|
|
439
|
-
elif 'typeerror' in criterion.lower():
|
|
440
|
-
exception_type = "TypeError"
|
|
441
|
-
elif 'attributeerror' in criterion.lower():
|
|
442
|
-
exception_type = "AttributeError"
|
|
443
|
-
elif 'keyerror' in criterion.lower():
|
|
444
|
-
exception_type = "KeyError"
|
|
445
|
-
|
|
446
|
-
# Try to extract expected message
|
|
447
|
-
if 'message:' in criterion.lower():
|
|
448
|
-
parts = criterion.split('message:')
|
|
449
|
-
if len(parts) > 1:
|
|
450
|
-
expected_message = parts[1].strip().strip('"\'')
|
|
451
|
-
|
|
452
|
-
return template.format(
|
|
453
|
-
function_name=function_name,
|
|
454
|
-
exception=exception_type,
|
|
455
|
-
scenario=self._extract_scenario(spec),
|
|
456
|
-
condition=self._describe_condition(spec),
|
|
457
|
-
setup_code=self._generate_setup_code(spec),
|
|
458
|
-
function_call=self._generate_function_call(function_name, spec),
|
|
459
|
-
expected_message=expected_message
|
|
460
|
-
)
|
|
461
|
-
|
|
462
|
-
def _generate_parameterized_test(self, spec: TestSpecification, function_name: str) -> str:
|
|
463
|
-
"""Generate parameterized test."""
|
|
464
|
-
|
|
465
|
-
template = self.templates['parameterized_test']
|
|
466
|
-
|
|
467
|
-
# Generate test parameters and values
|
|
468
|
-
param_names, test_values = self._generate_test_parameters(spec)
|
|
469
|
-
|
|
470
|
-
return template.format(
|
|
471
|
-
function_name=function_name,
|
|
472
|
-
scenario=self._extract_scenario(spec),
|
|
473
|
-
description=spec.description,
|
|
474
|
-
param_names=', '.join(param_names),
|
|
475
|
-
test_values=test_values,
|
|
476
|
-
setup_code=self._generate_setup_code(spec),
|
|
477
|
-
function_call=self._generate_function_call(function_name, spec),
|
|
478
|
-
expected_value=self._extract_expected_value(spec)
|
|
479
|
-
)
|
|
480
|
-
|
|
481
|
-
def _generate_integration_test(self, spec: TestSpecification) -> str:
|
|
482
|
-
"""Generate integration test."""
|
|
483
|
-
|
|
484
|
-
template = self.templates['integration_test']
|
|
485
|
-
|
|
486
|
-
feature_name = spec.name.lower().replace('test_', '').replace('_test', '')
|
|
487
|
-
|
|
488
|
-
return template.format(
|
|
489
|
-
feature_name=feature_name,
|
|
490
|
-
scenario=self._extract_scenario(spec),
|
|
491
|
-
description=spec.description,
|
|
492
|
-
setup_code=self._generate_setup_code(spec),
|
|
493
|
-
action=self._describe_action(spec),
|
|
494
|
-
assertions=self._generate_assertions(spec),
|
|
495
|
-
cleanup_code=self._generate_cleanup_code(spec)
|
|
496
|
-
)
|
|
497
|
-
|
|
498
|
-
def _generate_generic_test(self, spec: TestSpecification) -> str:
|
|
499
|
-
"""Generate generic test code."""
|
|
500
|
-
|
|
501
|
-
test_code = f'''
|
|
502
|
-
def test_{spec.name.replace(' ', '_').lower()}():
|
|
503
|
-
"""
|
|
504
|
-
Test: {spec.description}
|
|
505
|
-
|
|
506
|
-
Requirements:
|
|
507
|
-
{chr(10).join(f" - {req}" for req in spec.requirements)}
|
|
508
|
-
|
|
509
|
-
Acceptance Criteria:
|
|
510
|
-
{chr(10).join(f" - {crit}" for crit in spec.acceptance_criteria)}
|
|
511
|
-
"""
|
|
512
|
-
# TODO: Implement test based on specification
|
|
513
|
-
# This is a generated template - fill in with actual test logic
|
|
514
|
-
|
|
515
|
-
# Arrange
|
|
516
|
-
# {chr(10).join(f" # {req}" for req in spec.preconditions)}
|
|
517
|
-
|
|
518
|
-
# Act
|
|
519
|
-
# result = function_to_test()
|
|
520
|
-
|
|
521
|
-
# Assert
|
|
522
|
-
# assert result is not None
|
|
523
|
-
# Add specific assertions based on acceptance criteria
|
|
524
|
-
'''
|
|
525
|
-
|
|
526
|
-
return test_code
|
|
527
|
-
|
|
528
|
-
def _extract_scenario(self, spec: TestSpecification) -> str:
|
|
529
|
-
"""Extract scenario name from specification."""
|
|
530
|
-
if '_' in spec.name:
|
|
531
|
-
parts = spec.name.split('_')
|
|
532
|
-
if len(parts) > 1:
|
|
533
|
-
return '_'.join(parts[1:])
|
|
534
|
-
return 'default'
|
|
535
|
-
|
|
536
|
-
def _describe_action(self, spec: TestSpecification) -> str:
|
|
537
|
-
"""Describe the action being tested."""
|
|
538
|
-
return f"Call {spec.name}"
|
|
539
|
-
|
|
540
|
-
def _describe_condition(self, spec: TestSpecification) -> str:
|
|
541
|
-
"""Describe condition for exception test."""
|
|
542
|
-
return spec.requirements[0] if spec.requirements else "invalid input"
|
|
543
|
-
|
|
544
|
-
def _generate_setup_code(self, spec: TestSpecification) -> str:
|
|
545
|
-
"""Generate setup code based on specification."""
|
|
546
|
-
setup_lines = []
|
|
547
|
-
|
|
548
|
-
# Add mock requirements
|
|
549
|
-
for mock_name, mock_config in spec.mock_requirements.items():
|
|
550
|
-
if isinstance(mock_config, dict) and 'return_value' in mock_config:
|
|
551
|
-
setup_lines.append(f"{mock_name} = Mock(return_value={mock_config['return_value']})")
|
|
552
|
-
else:
|
|
553
|
-
setup_lines.append(f"{mock_name} = Mock()")
|
|
554
|
-
|
|
555
|
-
# Add preconditions as setup
|
|
556
|
-
for condition in spec.preconditions:
|
|
557
|
-
setup_lines.append(f"# {condition}")
|
|
558
|
-
|
|
559
|
-
return '\n '.join(setup_lines) if setup_lines else "pass"
|
|
560
|
-
|
|
561
|
-
def _generate_function_call(self, function_name: str, spec: TestSpecification) -> str:
|
|
562
|
-
"""Generate function call with arguments."""
|
|
563
|
-
|
|
564
|
-
# Extract arguments from mock requirements or requirements
|
|
565
|
-
args = []
|
|
566
|
-
|
|
567
|
-
if spec.mock_requirements:
|
|
568
|
-
args.extend(spec.mock_requirements.keys())
|
|
569
|
-
|
|
570
|
-
if not args:
|
|
571
|
-
# Add placeholder arguments based on requirements
|
|
572
|
-
for req in spec.requirements[:3]: # Limit to first 3 requirements
|
|
573
|
-
if 'input' in req.lower() or 'parameter' in req.lower():
|
|
574
|
-
args.append("test_input")
|
|
575
|
-
break
|
|
576
|
-
|
|
577
|
-
return f"{function_name}({', '.join(args)})" if args else f"{function_name}()"
|
|
578
|
-
|
|
579
|
-
def _generate_assertions(self, spec: TestSpecification) -> str:
|
|
580
|
-
"""Generate assertions based on acceptance criteria."""
|
|
581
|
-
assertions = []
|
|
582
|
-
|
|
583
|
-
for criterion in spec.acceptance_criteria[:3]: # Limit to first 3 criteria
|
|
584
|
-
if 'returns' in criterion.lower() or 'result' in criterion.lower():
|
|
585
|
-
assertions.append("assert result is not None")
|
|
586
|
-
elif 'equals' in criterion.lower() or 'equal' in criterion.lower():
|
|
587
|
-
assertions.append("assert result == expected_value")
|
|
588
|
-
elif 'length' in criterion.lower():
|
|
589
|
-
assertions.append("assert len(result) > 0")
|
|
590
|
-
else:
|
|
591
|
-
assertions.append(f"# {criterion}")
|
|
592
|
-
|
|
593
|
-
return '\n '.join(assertions) if assertions else "assert True # Add specific assertions"
|
|
594
|
-
|
|
595
|
-
def _generate_cleanup_code(self, spec: TestSpecification) -> str:
|
|
596
|
-
"""Generate cleanup code for integration tests."""
|
|
597
|
-
cleanup_lines = []
|
|
598
|
-
|
|
599
|
-
# Add cleanup for any resources mentioned in postconditions
|
|
600
|
-
for condition in spec.postconditions:
|
|
601
|
-
if 'close' in condition.lower():
|
|
602
|
-
cleanup_lines.append("# Close connections")
|
|
603
|
-
elif 'delete' in condition.lower():
|
|
604
|
-
cleanup_lines.append("# Delete temporary resources")
|
|
605
|
-
else:
|
|
606
|
-
cleanup_lines.append(f"# {condition}")
|
|
607
|
-
|
|
608
|
-
return '\n '.join(cleanup_lines) if cleanup_lines else "pass"
|
|
609
|
-
|
|
610
|
-
def _extract_expected_value(self, spec: TestSpecification) -> str:
|
|
611
|
-
"""Extract expected value from acceptance criteria."""
|
|
612
|
-
for criterion in spec.acceptance_criteria:
|
|
613
|
-
if 'returns' in criterion.lower():
|
|
614
|
-
# Try to extract expected value
|
|
615
|
-
if 'true' in criterion.lower():
|
|
616
|
-
return "True"
|
|
617
|
-
elif 'false' in criterion.lower():
|
|
618
|
-
return "False"
|
|
619
|
-
elif 'none' in criterion.lower():
|
|
620
|
-
return "None"
|
|
621
|
-
elif 'empty' in criterion.lower():
|
|
622
|
-
return "[]"
|
|
623
|
-
else:
|
|
624
|
-
return "expected_result"
|
|
625
|
-
return "expected_result"
|
|
626
|
-
|
|
627
|
-
def _generate_test_parameters(self, spec: TestSpecification) -> tuple:
|
|
628
|
-
"""Generate parameters and values for parameterized tests."""
|
|
629
|
-
|
|
630
|
-
# Create test cases from acceptance criteria and edge cases
|
|
631
|
-
test_cases = []
|
|
632
|
-
|
|
633
|
-
# Add acceptance criteria as test cases
|
|
634
|
-
for criterion in spec.acceptance_criteria:
|
|
635
|
-
if 'input' in criterion.lower():
|
|
636
|
-
# Extract input values
|
|
637
|
-
if 'valid' in criterion.lower():
|
|
638
|
-
test_cases.append(('valid_input', 'expected_output'))
|
|
639
|
-
elif 'invalid' in criterion.lower():
|
|
640
|
-
test_cases.append(('invalid_input', 'exception'))
|
|
641
|
-
|
|
642
|
-
# Add edge cases
|
|
643
|
-
for edge_case in spec.edge_cases:
|
|
644
|
-
if 'zero' in edge_case.lower():
|
|
645
|
-
test_cases.append((0, 'zero_result'))
|
|
646
|
-
elif 'empty' in edge_case.lower():
|
|
647
|
-
test_cases.append(('', 'empty_result'))
|
|
648
|
-
elif 'null' in edge_case.lower() or 'none' in edge_case.lower():
|
|
649
|
-
test_cases.append((None, 'none_result'))
|
|
650
|
-
|
|
651
|
-
# Convert to pytest format
|
|
652
|
-
if test_cases:
|
|
653
|
-
param_names = ['test_input', 'expected_output']
|
|
654
|
-
test_values = str(test_cases).replace("'", '"')
|
|
655
|
-
return param_names, test_values
|
|
656
|
-
|
|
657
|
-
# Fallback
|
|
658
|
-
return ['test_input', 'expected_output'], '[("test", "expected")]'
|
|
659
|
-
|
|
660
|
-
class TDDManager:
|
|
661
|
-
"""Main TDD workflow manager with Context7 integration."""
|
|
662
|
-
|
|
663
|
-
def __init__(self, project_path: str, context7_client=None):
|
|
664
|
-
self.project_path = Path(project_path)
|
|
665
|
-
self.context7 = context7_client
|
|
666
|
-
self.context7_integration = Context7TDDIntegration(context7_client)
|
|
667
|
-
self.test_generator = TestGenerator(context7_client)
|
|
668
|
-
self.current_session = None
|
|
669
|
-
self.test_history = []
|
|
670
|
-
|
|
671
|
-
async def start_tdd_session(
|
|
672
|
-
self, feature_name: str,
|
|
673
|
-
test_types: List[TestType] = None
|
|
674
|
-
) -> TDDSession:
|
|
675
|
-
"""Start a new TDD development session."""
|
|
676
|
-
|
|
677
|
-
if test_types is None:
|
|
678
|
-
test_types = [TestType.UNIT, TestType.INTEGRATION]
|
|
679
|
-
|
|
680
|
-
# Load Context7 patterns
|
|
681
|
-
context7_patterns = await self.context7_integration.load_tdd_patterns()
|
|
682
|
-
|
|
683
|
-
# Create session
|
|
684
|
-
session = TDDSession(
|
|
685
|
-
id=f"tdd_{feature_name}_{int(time.time())}",
|
|
686
|
-
project_path=str(self.project_path),
|
|
687
|
-
current_phase=TDDPhase.RED,
|
|
688
|
-
test_cases=[],
|
|
689
|
-
start_time=time.time(),
|
|
690
|
-
context7_patterns=context7_patterns,
|
|
691
|
-
metrics={
|
|
692
|
-
'tests_written': 0,
|
|
693
|
-
'tests_passing': 0,
|
|
694
|
-
'tests_failing': 0,
|
|
695
|
-
'coverage_percentage': 0.0
|
|
696
|
-
}
|
|
697
|
-
)
|
|
698
|
-
|
|
699
|
-
self.current_session = session
|
|
700
|
-
return session
|
|
701
|
-
|
|
702
|
-
async def write_failing_test(
|
|
703
|
-
self, specification: TestSpecification,
|
|
704
|
-
file_path: str = None
|
|
705
|
-
) -> str:
|
|
706
|
-
"""RED phase: Write a failing test based on specification."""
|
|
707
|
-
|
|
708
|
-
if not self.current_session:
|
|
709
|
-
raise ValueError("No active TDD session")
|
|
710
|
-
|
|
711
|
-
# Generate test code
|
|
712
|
-
test_code = await self.test_generator.generate_test_case(
|
|
713
|
-
specification, self.current_session.context7_patterns
|
|
714
|
-
)
|
|
715
|
-
|
|
716
|
-
# Determine file path
|
|
717
|
-
if file_path is None:
|
|
718
|
-
file_path = self._determine_test_file_path(specification)
|
|
719
|
-
|
|
720
|
-
# Write test file
|
|
721
|
-
full_path = self.project_path / file_path
|
|
722
|
-
full_path.parent.mkdir(parents=True, exist_ok=True)
|
|
723
|
-
|
|
724
|
-
with open(full_path, 'a', encoding='utf-8') as f:
|
|
725
|
-
f.write('\n\n' + test_code)
|
|
726
|
-
|
|
727
|
-
# Create test case object
|
|
728
|
-
test_case = TestCase(
|
|
729
|
-
id=f"test_{int(time.time())}",
|
|
730
|
-
name=specification.name,
|
|
731
|
-
file_path=str(full_path),
|
|
732
|
-
line_number=self._count_lines_in_file(str(full_path)),
|
|
733
|
-
specification=specification,
|
|
734
|
-
status=TestStatus.PENDING,
|
|
735
|
-
execution_time=0.0
|
|
736
|
-
)
|
|
737
|
-
|
|
738
|
-
self.current_session.test_cases.append(test_case)
|
|
739
|
-
self.current_session.metrics['tests_written'] += 1
|
|
740
|
-
|
|
741
|
-
return str(full_path)
|
|
742
|
-
|
|
743
|
-
async def run_tests_and_verify_failure(self) -> Dict[str, Any]:
|
|
744
|
-
"""RED phase: Run tests and verify they fail as expected."""
|
|
745
|
-
|
|
746
|
-
if not self.current_session:
|
|
747
|
-
raise ValueError("No active TDD session")
|
|
748
|
-
|
|
749
|
-
# Run tests using pytest
|
|
750
|
-
test_results = await self._run_pytest()
|
|
751
|
-
|
|
752
|
-
# Update session metrics
|
|
753
|
-
failing_tests = test_results.get('failures', 0)
|
|
754
|
-
self.current_session.metrics['tests_failing'] = failing_tests
|
|
755
|
-
|
|
756
|
-
# Verify at least one test is failing (RED phase requirement)
|
|
757
|
-
if failing_tests == 0:
|
|
758
|
-
raise ValueError("RED phase violation: No tests are failing. Write a proper failing test first.")
|
|
759
|
-
|
|
760
|
-
return test_results
|
|
761
|
-
|
|
762
|
-
async def implement_minimum_code_to_pass(self, target_function: str) -> Dict[str, Any]:
|
|
763
|
-
"""GREEN phase: Implement minimum code to make tests pass."""
|
|
764
|
-
|
|
765
|
-
if not self.current_session:
|
|
766
|
-
raise ValueError("No active TDD session")
|
|
767
|
-
|
|
768
|
-
# Generate minimum implementation
|
|
769
|
-
implementation = await self._generate_minimum_implementation(target_function)
|
|
770
|
-
|
|
771
|
-
# Write implementation
|
|
772
|
-
impl_path = self._determine_implementation_file_path(target_function)
|
|
773
|
-
full_path = self.project_path / impl_path
|
|
774
|
-
full_path.parent.mkdir(parents=True, exist_ok=True)
|
|
775
|
-
|
|
776
|
-
with open(full_path, 'w', encoding='utf-8') as f:
|
|
777
|
-
f.write(implementation)
|
|
778
|
-
|
|
779
|
-
# Run tests to verify they pass
|
|
780
|
-
test_results = await self._run_pytest()
|
|
781
|
-
|
|
782
|
-
# Update session metrics
|
|
783
|
-
passing_tests = test_results.get('passed', 0)
|
|
784
|
-
self.current_session.metrics['tests_passing'] = passing_tests
|
|
785
|
-
|
|
786
|
-
if test_results.get('failures', 0) > 0:
|
|
787
|
-
raise ValueError("GREEN phase violation: Tests are still failing. Implementation needs adjustment.")
|
|
788
|
-
|
|
789
|
-
self.current_session.current_phase = TDDPhase.GREEN
|
|
790
|
-
return test_results
|
|
791
|
-
|
|
792
|
-
async def refactor_while_maintaining_tests(self) -> Dict[str, Any]:
|
|
793
|
-
"""REFACTOR phase: Improve code while keeping tests green."""
|
|
794
|
-
|
|
795
|
-
if not self.current_session:
|
|
796
|
-
raise ValueError("No active TDD session")
|
|
797
|
-
|
|
798
|
-
if self.current_session.current_phase != TDDPhase.GREEN:
|
|
799
|
-
raise ValueError("Must complete GREEN phase before REFACTOR")
|
|
800
|
-
|
|
801
|
-
# Get Context7 refactoring patterns
|
|
802
|
-
refactoring_patterns = await self._get_refactoring_patterns()
|
|
803
|
-
|
|
804
|
-
# Generate refactoring suggestions
|
|
805
|
-
suggestions = await self._generate_refactoring_suggestions(refactoring_patterns)
|
|
806
|
-
|
|
807
|
-
# Apply refactoring suggestions
|
|
808
|
-
for suggestion in suggestions:
|
|
809
|
-
await self._apply_refactoring_suggestion(suggestion)
|
|
810
|
-
|
|
811
|
-
# Verify tests still pass after each refactoring
|
|
812
|
-
test_results = await self._run_pytest()
|
|
813
|
-
if test_results.get('failures', 0) > 0:
|
|
814
|
-
raise ValueError(f"REFACTOR phase violation: Tests failed after applying suggestion: {suggestion['description']}")
|
|
815
|
-
|
|
816
|
-
self.current_session.current_phase = TDDPhase.REFACTOR
|
|
817
|
-
return suggestions
|
|
818
|
-
|
|
819
|
-
async def run_full_tdd_cycle(
|
|
820
|
-
self, specification: TestSpecification,
|
|
821
|
-
target_function: str = None
|
|
822
|
-
) -> Dict[str, Any]:
|
|
823
|
-
"""Run complete RED-GREEN-REFACTOR TDD cycle."""
|
|
824
|
-
|
|
825
|
-
cycle_results = {}
|
|
826
|
-
|
|
827
|
-
# RED phase
|
|
828
|
-
print(" RED Phase: Writing failing test...")
|
|
829
|
-
test_file = await self.write_failing_test(specification)
|
|
830
|
-
red_results = await self.run_tests_and_verify_failure()
|
|
831
|
-
cycle_results['red'] = {'test_file': test_file, 'results': red_results}
|
|
832
|
-
|
|
833
|
-
# GREEN phase
|
|
834
|
-
print("🟢 GREEN Phase: Implementing minimum code...")
|
|
835
|
-
if target_function is None:
|
|
836
|
-
target_function = specification.name.replace('test_', '').replace('_test', '')
|
|
837
|
-
green_results = await self.implement_minimum_code_to_pass(target_function)
|
|
838
|
-
cycle_results['green'] = {'results': green_results}
|
|
839
|
-
|
|
840
|
-
# REFACTOR phase
|
|
841
|
-
print(" REFACTOR Phase: Improving code quality...")
|
|
842
|
-
refactor_results = await self.refactor_while_maintaining_tests()
|
|
843
|
-
cycle_results['refactor'] = {'suggestions': refactor_results}
|
|
844
|
-
|
|
845
|
-
# REVIEW phase
|
|
846
|
-
print("🟣 REVIEW Phase: Final verification...")
|
|
847
|
-
coverage_results = await self._run_coverage_analysis()
|
|
848
|
-
cycle_results['review'] = {'coverage': coverage_results}
|
|
849
|
-
|
|
850
|
-
self.current_session.current_phase = TDDPhase.REVIEW
|
|
851
|
-
return cycle_results
|
|
852
|
-
|
|
853
|
-
async def _run_pytest(self) -> Dict[str, Any]:
|
|
854
|
-
"""Run pytest and return results."""
|
|
855
|
-
|
|
856
|
-
try:
|
|
857
|
-
# Run pytest with JSON output for parsing
|
|
858
|
-
result = subprocess.run(
|
|
859
|
-
[
|
|
860
|
-
sys.executable, '-m', 'pytest',
|
|
861
|
-
str(self.project_path),
|
|
862
|
-
'--tb=short',
|
|
863
|
-
'--json-report',
|
|
864
|
-
'--json-report-file=/tmp/pytest_results.json'
|
|
865
|
-
],
|
|
866
|
-
capture_output=True,
|
|
867
|
-
text=True,
|
|
868
|
-
cwd=str(self.project_path)
|
|
869
|
-
)
|
|
870
|
-
|
|
871
|
-
# Parse results
|
|
872
|
-
try:
|
|
873
|
-
with open('/tmp/pytest_results.json', 'r') as f:
|
|
874
|
-
results_data = json.load(f)
|
|
875
|
-
|
|
876
|
-
return {
|
|
877
|
-
'summary': results_data.get('summary', {}),
|
|
878
|
-
'tests': results_data.get('tests', []),
|
|
879
|
-
'passed': results_data.get('summary', {}).get('passed', 0),
|
|
880
|
-
'failed': results_data.get('summary', {}).get('failed', 0),
|
|
881
|
-
'skipped': results_data.get('summary', {}).get('skipped', 0),
|
|
882
|
-
'total': results_data.get('summary', {}).get('total', 0),
|
|
883
|
-
'duration': results_data.get('summary', {}).get('duration', 0)
|
|
884
|
-
}
|
|
885
|
-
except (FileNotFoundError, json.JSONDecodeError):
|
|
886
|
-
# Fallback to parsing stdout
|
|
887
|
-
return self._parse_pytest_output(result.stdout)
|
|
888
|
-
|
|
889
|
-
except Exception as e:
|
|
890
|
-
print(f"Error running pytest: {e}")
|
|
891
|
-
return {'error': str(e), 'passed': 0, 'failed': 0, 'skipped': 0, 'total': 0}
|
|
892
|
-
|
|
893
|
-
def _parse_pytest_output(self, output: str) -> Dict[str, Any]:
|
|
894
|
-
"""Parse pytest output when JSON is not available."""
|
|
895
|
-
|
|
896
|
-
lines = output.split('\n')
|
|
897
|
-
results = {'passed': 0, 'failed': 0, 'skipped': 0, 'total': 0, 'duration': 0}
|
|
898
|
-
|
|
899
|
-
for line in lines:
|
|
900
|
-
if ' passed in ' in line:
|
|
901
|
-
parts = line.split()
|
|
902
|
-
if parts and parts[0].isdigit():
|
|
903
|
-
results['passed'] = int(parts[0])
|
|
904
|
-
results['total'] = int(parts[0])
|
|
905
|
-
elif ' passed' in line and ' failed' in line:
|
|
906
|
-
# Parse format like "2 passed, 1 failed"
|
|
907
|
-
passed_part = line.split(' passed')[0]
|
|
908
|
-
if passed_part.strip().isdigit():
|
|
909
|
-
results['passed'] = int(passed_part.strip())
|
|
910
|
-
|
|
911
|
-
if ' failed' in line:
|
|
912
|
-
failed_part = line.split(' failed')[0].split(', ')[-1]
|
|
913
|
-
if failed_part.strip().isdigit():
|
|
914
|
-
results['failed'] = int(failed_part.strip())
|
|
915
|
-
|
|
916
|
-
results['total'] = results['passed'] + results['failed']
|
|
917
|
-
|
|
918
|
-
return results
|
|
919
|
-
|
|
920
|
-
def _determine_test_file_path(self, specification: TestSpecification) -> str:
|
|
921
|
-
"""Determine appropriate test file path based on specification."""
|
|
922
|
-
|
|
923
|
-
# Create tests directory structure
|
|
924
|
-
test_dir = "tests"
|
|
925
|
-
|
|
926
|
-
# Determine subdirectory based on test type
|
|
927
|
-
if specification.test_type == TestType.INTEGRATION:
|
|
928
|
-
test_dir += "/integration"
|
|
929
|
-
elif specification.test_type == TestType.ACCEPTANCE:
|
|
930
|
-
test_dir += "/acceptance"
|
|
931
|
-
elif specification.test_type == TestType.PERFORMANCE:
|
|
932
|
-
test_dir += "/performance"
|
|
933
|
-
|
|
934
|
-
# Generate filename
|
|
935
|
-
feature_name = specification.name.replace('test_', '').replace('_test', '')
|
|
936
|
-
filename = f"test_{feature_name}.py"
|
|
937
|
-
|
|
938
|
-
return f"{test_dir}/{filename}"
|
|
939
|
-
|
|
940
|
-
def _determine_implementation_file_path(self, function_name: str) -> str:
|
|
941
|
-
"""Determine implementation file path for target function."""
|
|
942
|
-
|
|
943
|
-
# Simple heuristic - place in src directory
|
|
944
|
-
# In real implementation, this would be more sophisticated
|
|
945
|
-
return f"src/{function_name}.py"
|
|
946
|
-
|
|
947
|
-
def _count_lines_in_file(self, file_path: str) -> int:
|
|
948
|
-
"""Count lines in a file."""
|
|
949
|
-
try:
|
|
950
|
-
with open(file_path, 'r', encoding='utf-8') as f:
|
|
951
|
-
return len(f.readlines())
|
|
952
|
-
except FileNotFoundError:
|
|
953
|
-
return 0
|
|
954
|
-
|
|
955
|
-
async def _generate_minimum_implementation(self, target_function: str) -> str:
|
|
956
|
-
"""Generate minimum implementation to make tests pass."""
|
|
957
|
-
|
|
958
|
-
# Get Context7 patterns for implementation
|
|
959
|
-
patterns = self.current_session.context7_patterns
|
|
960
|
-
|
|
961
|
-
# Simple implementation template
|
|
962
|
-
implementation = f'''
|
|
963
|
-
def {target_function}(*args, kwargs):
|
|
964
|
-
"""
|
|
965
|
-
Minimum implementation for {target_function}.
|
|
966
|
-
|
|
967
|
-
This is a TDD-generated implementation that will be
|
|
968
|
-
refined during the REFACTOR phase.
|
|
969
|
-
"""
|
|
970
|
-
# TODO: Implement proper logic based on test requirements
|
|
971
|
-
# This is a placeholder to make tests pass initially
|
|
972
|
-
|
|
973
|
-
if args:
|
|
974
|
-
return args[0] # Return first argument as default
|
|
975
|
-
|
|
976
|
-
return None # Default return value
|
|
977
|
-
'''
|
|
978
|
-
|
|
979
|
-
return implementation
|
|
980
|
-
|
|
981
|
-
async def _get_refactoring_patterns(self) -> Dict[str, Any]:
|
|
982
|
-
"""Get refactoring patterns from Context7."""
|
|
983
|
-
|
|
984
|
-
if self.context7:
|
|
985
|
-
try:
|
|
986
|
-
patterns = await self.context7.get_library_docs(
|
|
987
|
-
context7_library_id="/refactoring/guru",
|
|
988
|
-
topic="code refactoring patterns clean code 2025",
|
|
989
|
-
tokens=3000
|
|
990
|
-
)
|
|
991
|
-
return patterns
|
|
992
|
-
except Exception as e:
|
|
993
|
-
print(f"Failed to get refactoring patterns: {e}")
|
|
994
|
-
|
|
995
|
-
return {}
|
|
996
|
-
|
|
997
|
-
async def _generate_refactoring_suggestions(self, patterns: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
998
|
-
"""Generate refactoring suggestions based on current implementation."""
|
|
999
|
-
|
|
1000
|
-
suggestions = []
|
|
1001
|
-
|
|
1002
|
-
# Add general refactoring suggestions
|
|
1003
|
-
suggestions.extend([
|
|
1004
|
-
{
|
|
1005
|
-
'type': 'extract_method',
|
|
1006
|
-
'description': 'Extract complex logic into separate methods',
|
|
1007
|
-
'priority': 'medium',
|
|
1008
|
-
'applicable_to': ['large_functions']
|
|
1009
|
-
},
|
|
1010
|
-
{
|
|
1011
|
-
'type': 'improve_naming',
|
|
1012
|
-
'description': 'Improve variable and function naming for clarity',
|
|
1013
|
-
'priority': 'high',
|
|
1014
|
-
'applicable_to': ['all_functions']
|
|
1015
|
-
},
|
|
1016
|
-
{
|
|
1017
|
-
'type': 'add_documentation',
|
|
1018
|
-
'description': 'Add comprehensive docstrings and comments',
|
|
1019
|
-
'priority': 'medium',
|
|
1020
|
-
'applicable_to': ['all_functions']
|
|
1021
|
-
},
|
|
1022
|
-
{
|
|
1023
|
-
'type': 'handle_edge_cases',
|
|
1024
|
-
'description': 'Add proper error handling and edge case management',
|
|
1025
|
-
'priority': 'high',
|
|
1026
|
-
'applicable_to': ['public_functions']
|
|
1027
|
-
}
|
|
1028
|
-
])
|
|
1029
|
-
|
|
1030
|
-
return suggestions
|
|
1031
|
-
|
|
1032
|
-
async def _apply_refactoring_suggestion(self, suggestion: Dict[str, Any]) -> bool:
|
|
1033
|
-
"""Apply a refactoring suggestion to the codebase."""
|
|
1034
|
-
|
|
1035
|
-
# In a real implementation, this would analyze the code
|
|
1036
|
-
# and apply automated refactoring using tools like Rope
|
|
1037
|
-
|
|
1038
|
-
print(f"Applying refactoring: {suggestion['description']}")
|
|
1039
|
-
|
|
1040
|
-
# Simulate refactoring application
|
|
1041
|
-
await asyncio.sleep(0.1) # Simulate work
|
|
1042
|
-
|
|
1043
|
-
return True
|
|
1044
|
-
|
|
1045
|
-
async def _run_coverage_analysis(self) -> Dict[str, Any]:
|
|
1046
|
-
"""Run test coverage analysis."""
|
|
1047
|
-
|
|
1048
|
-
try:
|
|
1049
|
-
# Run coverage analysis
|
|
1050
|
-
result = subprocess.run(
|
|
1051
|
-
[
|
|
1052
|
-
sys.executable, '-m', 'pytest',
|
|
1053
|
-
str(self.project_path),
|
|
1054
|
-
'--cov=src',
|
|
1055
|
-
'--cov-report=json',
|
|
1056
|
-
'--cov-report=term-missing'
|
|
1057
|
-
],
|
|
1058
|
-
capture_output=True,
|
|
1059
|
-
text=True,
|
|
1060
|
-
cwd=str(self.project_path)
|
|
1061
|
-
)
|
|
1062
|
-
|
|
1063
|
-
# Parse coverage results
|
|
1064
|
-
try:
|
|
1065
|
-
# Look for coverage file
|
|
1066
|
-
import glob
|
|
1067
|
-
coverage_files = glob.glob(str(self.project_path) + '/coverage.json')
|
|
1068
|
-
if coverage_files:
|
|
1069
|
-
with open(coverage_files[0], 'r') as f:
|
|
1070
|
-
coverage_data = json.load(f)
|
|
1071
|
-
|
|
1072
|
-
total_coverage = coverage_data.get('totals', {}).get('percent_covered', 0)
|
|
1073
|
-
self.current_session.metrics['coverage_percentage'] = total_coverage
|
|
1074
|
-
|
|
1075
|
-
return {
|
|
1076
|
-
'total_coverage': total_coverage,
|
|
1077
|
-
'files': coverage_data.get('files', {}),
|
|
1078
|
-
'totals': coverage_data.get('totals', {})
|
|
1079
|
-
}
|
|
1080
|
-
except Exception:
|
|
1081
|
-
pass
|
|
1082
|
-
|
|
1083
|
-
return {'total_coverage': 0, 'message': 'Coverage analysis failed'}
|
|
1084
|
-
|
|
1085
|
-
except Exception as e:
|
|
1086
|
-
return {'error': str(e), 'total_coverage': 0}
|
|
1087
|
-
|
|
1088
|
-
def get_session_summary(self) -> Dict[str, Any]:
|
|
1089
|
-
"""Get summary of current TDD session."""
|
|
1090
|
-
|
|
1091
|
-
if not self.current_session:
|
|
1092
|
-
return {}
|
|
1093
|
-
|
|
1094
|
-
duration = time.time() - self.current_session.start_time
|
|
1095
|
-
|
|
1096
|
-
return {
|
|
1097
|
-
'session_id': self.current_session.id,
|
|
1098
|
-
'phase': self.current_session.current_phase.value,
|
|
1099
|
-
'duration_seconds': duration,
|
|
1100
|
-
'duration_formatted': f"{duration:.1f} seconds",
|
|
1101
|
-
'metrics': self.current_session.metrics,
|
|
1102
|
-
'test_cases_count': len(self.current_session.test_cases)
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
# Usage Examples
|
|
1106
|
-
"""
|
|
25
|
+
from moai_workflow_testing import TDDManager, TestSpecification, TestType
|
|
26
|
+
|
|
1107
27
|
# Initialize TDD Manager
|
|
1108
28
|
tdd_manager = TDDManager(
|
|
1109
|
-
|
|
1110
|
-
|
|
29
|
+
project_path="/path/to/project",
|
|
30
|
+
context7_client=context7
|
|
1111
31
|
)
|
|
1112
32
|
|
|
1113
33
|
# Start TDD session
|
|
@@ -1115,146 +35,231 @@ session = await tdd_manager.start_tdd_session("user_authentication")
|
|
|
1115
35
|
|
|
1116
36
|
# Create test specification
|
|
1117
37
|
test_spec = TestSpecification(
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
"Test with empty password",
|
|
1134
|
-
"Test with malformed email",
|
|
1135
|
-
"Test with very long password"
|
|
1136
|
-
],
|
|
1137
|
-
mock_requirements={
|
|
1138
|
-
"user_database": {"return_value": "mock_user"},
|
|
1139
|
-
"token_generator": {"return_value": "mock_token"}
|
|
1140
|
-
}
|
|
38
|
+
name="test_user_login_valid_credentials",
|
|
39
|
+
description="Test that user can login with valid credentials",
|
|
40
|
+
test_type=TestType.UNIT,
|
|
41
|
+
requirements=[
|
|
42
|
+
"User must provide valid email and password",
|
|
43
|
+
"System should authenticate user credentials"
|
|
44
|
+
],
|
|
45
|
+
acceptance_criteria=[
|
|
46
|
+
"Valid credentials return user token",
|
|
47
|
+
"Invalid credentials raise AuthenticationError"
|
|
48
|
+
],
|
|
49
|
+
edge_cases=[
|
|
50
|
+
"Test with empty email",
|
|
51
|
+
"Test with empty password"
|
|
52
|
+
]
|
|
1141
53
|
)
|
|
1142
54
|
|
|
1143
55
|
# Run complete TDD cycle
|
|
1144
56
|
cycle_results = await tdd_manager.run_full_tdd_cycle(
|
|
1145
|
-
|
|
1146
|
-
|
|
57
|
+
specification=test_spec,
|
|
58
|
+
target_function="authenticate_user"
|
|
1147
59
|
)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Core Components
|
|
63
|
+
|
|
64
|
+
### TDD Cycle Phases
|
|
65
|
+
|
|
66
|
+
1. RED Phase: Write failing test
|
|
67
|
+
- Create test specification
|
|
68
|
+
- Generate test code
|
|
69
|
+
- Verify test fails for right reason
|
|
70
|
+
|
|
71
|
+
2. GREEN Phase: Implement minimum code
|
|
72
|
+
- Write simplest implementation
|
|
73
|
+
- Make tests pass
|
|
74
|
+
- Focus on functionality, not quality
|
|
75
|
+
|
|
76
|
+
3. REFACTOR Phase: Improve code quality
|
|
77
|
+
- Refactor while tests pass
|
|
78
|
+
- Apply design patterns
|
|
79
|
+
- Remove duplication
|
|
80
|
+
|
|
81
|
+
4. REVIEW Phase: Verify and commit
|
|
82
|
+
- Check test coverage
|
|
83
|
+
- Review code quality
|
|
84
|
+
- Commit changes
|
|
85
|
+
|
|
86
|
+
### Context7 Integration
|
|
87
|
+
|
|
88
|
+
The TDD Context7 integration provides:
|
|
89
|
+
|
|
90
|
+
- Pattern Loading: Access latest testing patterns from Context7
|
|
91
|
+
- AI Test Generation: Enhanced test generation with Context7 patterns
|
|
92
|
+
- Best Practices: Industry-standard testing practices
|
|
93
|
+
- Edge Case Detection: Automatic edge case identification
|
|
94
|
+
- Test Suggestions: AI-powered test improvement suggestions
|
|
95
|
+
|
|
96
|
+
## Module Structure
|
|
1148
97
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
98
|
+
### Core Modules
|
|
99
|
+
|
|
100
|
+
**RED-GREEN-REFACTOR Implementation** (`tdd-context7/red-green-refactor.md`)
|
|
101
|
+
- TDD cycle implementation
|
|
102
|
+
- Test execution and validation
|
|
103
|
+
- Coverage analysis
|
|
104
|
+
- Session management
|
|
105
|
+
|
|
106
|
+
**Test Generation** (`tdd-context7/test-generation.md`)
|
|
107
|
+
- AI-powered test generation
|
|
108
|
+
- Specification-based generation
|
|
109
|
+
- Context7-enhanced generation
|
|
110
|
+
- Template-based generation
|
|
111
|
+
|
|
112
|
+
**Test Patterns** (`tdd-context7/test-patterns.md`)
|
|
113
|
+
- Testing patterns and best practices
|
|
114
|
+
- Pytest fixtures and organization
|
|
115
|
+
- Test discovery structure
|
|
116
|
+
- Coverage configuration
|
|
117
|
+
|
|
118
|
+
**Advanced Features** (`tdd-context7/advanced-features.md`)
|
|
119
|
+
- Comprehensive test suite generation
|
|
120
|
+
- Property-based testing
|
|
121
|
+
- Mutation testing
|
|
122
|
+
- Continuous testing
|
|
123
|
+
|
|
124
|
+
## Common Use Cases
|
|
125
|
+
|
|
126
|
+
### Unit Testing
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
# Generate unit test from specification
|
|
130
|
+
test_spec = TestSpecification(
|
|
131
|
+
name="test_calculate_sum",
|
|
132
|
+
description="Test sum calculation",
|
|
133
|
+
test_type=TestType.UNIT,
|
|
134
|
+
requirements=["Function should sum two numbers"],
|
|
135
|
+
acceptance_criteria=["Returns correct sum"],
|
|
136
|
+
edge_cases=["Zero values", "Negative numbers", "Large numbers"]
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
test_code = await test_generator.generate_test_case(test_spec)
|
|
1160
140
|
```
|
|
1161
141
|
|
|
1162
|
-
|
|
142
|
+
### Integration Testing
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
# Integration test specification
|
|
146
|
+
integration_spec = TestSpecification(
|
|
147
|
+
name="test_database_integration",
|
|
148
|
+
description="Test database connection and query",
|
|
149
|
+
test_type=TestType.INTEGRATION,
|
|
150
|
+
requirements=["Database connection", "Query execution"],
|
|
151
|
+
acceptance_criteria=["Connection succeeds", "Query returns data"],
|
|
152
|
+
edge_cases=["Connection failure", "Empty results", "Large datasets"]
|
|
153
|
+
)
|
|
154
|
+
```
|
|
1163
155
|
|
|
1164
|
-
###
|
|
156
|
+
### Exception Testing
|
|
1165
157
|
|
|
1166
|
-
AI-Powered Test Case Generation:
|
|
1167
158
|
```python
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
# Analyze function using AST
|
|
1178
|
-
function_analysis = self._analyze_function_code(function_code)
|
|
1179
|
-
|
|
1180
|
-
# Generate tests for different scenarios
|
|
1181
|
-
test_cases = []
|
|
1182
|
-
|
|
1183
|
-
# Happy path tests
|
|
1184
|
-
happy_path_tests = await self._generate_happy_path_tests(
|
|
1185
|
-
function_analysis, context7_patterns
|
|
1186
|
-
)
|
|
1187
|
-
test_cases.extend(happy_path_tests)
|
|
1188
|
-
|
|
1189
|
-
# Edge case tests
|
|
1190
|
-
edge_case_tests = await self._generate_edge_case_tests(
|
|
1191
|
-
function_analysis, context7_patterns
|
|
1192
|
-
)
|
|
1193
|
-
test_cases.extend(edge_case_tests)
|
|
1194
|
-
|
|
1195
|
-
# Error handling tests
|
|
1196
|
-
error_tests = await self._generate_error_handling_tests(
|
|
1197
|
-
function_analysis, context7_patterns
|
|
1198
|
-
)
|
|
1199
|
-
test_cases.extend(error_tests)
|
|
1200
|
-
|
|
1201
|
-
# Performance tests for critical functions
|
|
1202
|
-
if self._is_performance_critical(function_analysis):
|
|
1203
|
-
perf_tests = await self._generate_performance_tests(function_analysis)
|
|
1204
|
-
test_cases.extend(perf_tests)
|
|
1205
|
-
|
|
1206
|
-
return test_cases
|
|
1207
|
-
|
|
1208
|
-
def _analyze_function_code(self, code: str) -> Dict[str, Any]:
|
|
1209
|
-
"""Analyze function code to extract test requirements."""
|
|
1210
|
-
|
|
1211
|
-
try:
|
|
1212
|
-
tree = ast.parse(code)
|
|
1213
|
-
|
|
1214
|
-
analysis = {
|
|
1215
|
-
'functions': [],
|
|
1216
|
-
'parameters': [],
|
|
1217
|
-
'return_statements': [],
|
|
1218
|
-
'exceptions': [],
|
|
1219
|
-
'external_calls': []
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
|
-
for node in ast.walk(tree):
|
|
1223
|
-
if isinstance(node, ast.FunctionDef):
|
|
1224
|
-
analysis['functions'].append({
|
|
1225
|
-
'name': node.name,
|
|
1226
|
-
'args': [arg.arg for arg in node.args.args],
|
|
1227
|
-
'decorators': [d.id if isinstance(d, ast.Name) else str(d) for d in node.decorator_list]
|
|
1228
|
-
})
|
|
1229
|
-
|
|
1230
|
-
elif isinstance(node, ast.Raise):
|
|
1231
|
-
analysis['exceptions'].append({
|
|
1232
|
-
'type': node.exc.func.id if node.exc and hasattr(node.exc, 'func') else 'Exception',
|
|
1233
|
-
'message': node.exc.msg if node.exc and hasattr(node.exc, 'msg') else None
|
|
1234
|
-
})
|
|
1235
|
-
|
|
1236
|
-
elif isinstance(node, ast.Call):
|
|
1237
|
-
if isinstance(node.func, ast.Attribute):
|
|
1238
|
-
analysis['external_calls'].append(f"{node.func.value.id}.{node.func.attr}")
|
|
1239
|
-
elif isinstance(node.func, ast.Name):
|
|
1240
|
-
analysis['external_calls'].append(node.func.id)
|
|
1241
|
-
|
|
1242
|
-
return analysis
|
|
1243
|
-
|
|
1244
|
-
except Exception as e:
|
|
1245
|
-
print(f"Error analyzing function code: {e}")
|
|
1246
|
-
return {}
|
|
159
|
+
# Exception test specification
|
|
160
|
+
exception_spec = TestSpecification(
|
|
161
|
+
name="test_divide_by_zero",
|
|
162
|
+
description="Test division by zero exception",
|
|
163
|
+
test_type=TestType.UNIT,
|
|
164
|
+
requirements=["Division function", "Error handling"],
|
|
165
|
+
acceptance_criteria=["Raises ZeroDivisionError"],
|
|
166
|
+
edge_cases=["Divisor is zero", "Dividend is zero"]
|
|
167
|
+
)
|
|
1247
168
|
```
|
|
1248
169
|
|
|
1249
170
|
## Best Practices
|
|
1250
171
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
172
|
+
### Test Design
|
|
173
|
+
|
|
174
|
+
1. One Test One Behavior: Each test should verify one specific behavior
|
|
175
|
+
2. Descriptive Names: Test names should clearly describe what is being tested
|
|
176
|
+
3. Arrange-Act-Assert: Structure tests with this pattern for clarity
|
|
177
|
+
4. Independent Tests: Tests should not depend on each other
|
|
178
|
+
5. Fast Execution: Keep tests fast for quick feedback
|
|
179
|
+
|
|
180
|
+
### Context7 Integration
|
|
181
|
+
|
|
182
|
+
1. Pattern Loading: Load Context7 patterns for latest best practices
|
|
183
|
+
2. Edge Case Detection: Use Context7 to identify missing edge cases
|
|
184
|
+
3. Test Suggestions: Leverage AI suggestions for test improvements
|
|
185
|
+
4. Quality Analysis: Use Context7 for test quality analysis
|
|
186
|
+
|
|
187
|
+
### TDD Workflow
|
|
188
|
+
|
|
189
|
+
1. Write Failing Test First: Always start with a failing test
|
|
190
|
+
2. Keep Tests Green: Never commit failing tests
|
|
191
|
+
3. Refactor Confidently: Use tests as safety net for refactoring
|
|
192
|
+
4. High Coverage: Aim for 80%+ test coverage
|
|
193
|
+
5. Continuous Testing: Run tests automatically with every change
|
|
194
|
+
|
|
195
|
+
## Advanced Features
|
|
196
|
+
|
|
197
|
+
### Property-Based Testing
|
|
198
|
+
|
|
199
|
+
Use Hypothesis for property-based testing to verify code properties across many random inputs.
|
|
200
|
+
|
|
201
|
+
### Mutation Testing
|
|
202
|
+
|
|
203
|
+
Use mutation testing to verify test suite quality by introducing code mutations and checking if tests catch them.
|
|
204
|
+
|
|
205
|
+
### Continuous Testing
|
|
206
|
+
|
|
207
|
+
Implement watch mode for automatic test execution on file changes.
|
|
208
|
+
|
|
209
|
+
### AI-Powered Generation
|
|
210
|
+
|
|
211
|
+
Leverage Context7 for intelligent test generation and suggestions.
|
|
212
|
+
|
|
213
|
+
## Performance Considerations
|
|
214
|
+
|
|
215
|
+
- Test Execution: Use parallel test execution for faster feedback
|
|
216
|
+
- Test Isolation: Ensure tests are isolated to prevent interference
|
|
217
|
+
- Mock External Dependencies: Mock external services for fast, reliable tests
|
|
218
|
+
- Optimize Setup: Use fixtures and test factories for efficient test setup
|
|
219
|
+
|
|
220
|
+
## Troubleshooting
|
|
221
|
+
|
|
222
|
+
### Common Issues
|
|
223
|
+
|
|
224
|
+
1. Tests Failing Intermittently
|
|
225
|
+
- Check for shared state between tests
|
|
226
|
+
- Verify test isolation
|
|
227
|
+
- Add proper cleanup in fixtures
|
|
228
|
+
|
|
229
|
+
2. Slow Test Execution
|
|
230
|
+
- Use parallel test execution
|
|
231
|
+
- Mock external dependencies
|
|
232
|
+
- Optimize test setup
|
|
233
|
+
|
|
234
|
+
3. Context7 Integration Issues
|
|
235
|
+
- Verify Context7 client configuration
|
|
236
|
+
- Check network connectivity
|
|
237
|
+
- Use default patterns as fallback
|
|
238
|
+
|
|
239
|
+
## Resources
|
|
240
|
+
|
|
241
|
+
### Detailed Modules
|
|
242
|
+
|
|
243
|
+
- [RED-GREEN-REFACTOR Implementation](./tdd-context7/red-green-refactor.md) - Core TDD cycle
|
|
244
|
+
- [Test Generation](./tdd-context7/test-generation.md) - AI-powered generation
|
|
245
|
+
- [Test Patterns](./tdd-context7/test-patterns.md) - Patterns and best practices
|
|
246
|
+
- [Advanced Features](./tdd-context7/advanced-features.md) - Advanced testing techniques
|
|
247
|
+
|
|
248
|
+
### Related Modules
|
|
249
|
+
|
|
250
|
+
- [AI Debugging](./ai-debugging.md) - Debugging techniques
|
|
251
|
+
- [Performance Optimization](./performance-optimization.md) - Performance testing
|
|
252
|
+
- [Smart Refactoring](./smart-refactoring.md) - Refactoring with tests
|
|
253
|
+
|
|
254
|
+
### External Resources
|
|
255
|
+
|
|
256
|
+
- [Pytest Documentation](https://docs.pytest.org/)
|
|
257
|
+
- [Python Testing Best Practices](https://docs.python-guide.org/writing/tests/)
|
|
258
|
+
- [Hypothesis Property-Based Testing](https://hypothesis.works/)
|
|
259
|
+
- [Context7 MCP Documentation](https://context7.io/docs)
|
|
1256
260
|
|
|
1257
261
|
---
|
|
1258
262
|
|
|
1259
263
|
Module: `modules/tdd-context7.md`
|
|
1260
|
-
|
|
264
|
+
Version: 2.0.0 (Modular Structure)
|
|
265
|
+
Last Updated: 2026-01-06
|