moai-adk 0.35.1__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.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/__init__.py +10 -0
- moai_adk/__main__.py +199 -0
- moai_adk/cli/__init__.py +6 -0
- moai_adk/cli/commands/__init__.py +17 -0
- moai_adk/cli/commands/analyze.py +116 -0
- moai_adk/cli/commands/doctor.py +272 -0
- moai_adk/cli/commands/init.py +372 -0
- moai_adk/cli/commands/language.py +248 -0
- moai_adk/cli/commands/status.py +104 -0
- moai_adk/cli/commands/update.py +2686 -0
- moai_adk/cli/main.py +13 -0
- moai_adk/cli/prompts/__init__.py +5 -0
- moai_adk/cli/prompts/init_prompts.py +219 -0
- moai_adk/cli/spec_status.py +263 -0
- moai_adk/cli/ui/__init__.py +44 -0
- moai_adk/cli/ui/progress.py +422 -0
- moai_adk/cli/ui/prompts.py +389 -0
- moai_adk/cli/ui/theme.py +129 -0
- moai_adk/cli/worktree/__init__.py +27 -0
- moai_adk/cli/worktree/__main__.py +31 -0
- moai_adk/cli/worktree/cli.py +683 -0
- moai_adk/cli/worktree/exceptions.py +89 -0
- moai_adk/cli/worktree/manager.py +493 -0
- moai_adk/cli/worktree/models.py +65 -0
- moai_adk/cli/worktree/registry.py +422 -0
- moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
- moai_adk/core/__init__.py +1 -0
- moai_adk/core/analysis/__init__.py +9 -0
- moai_adk/core/analysis/session_analyzer.py +400 -0
- moai_adk/core/claude_integration.py +393 -0
- moai_adk/core/command_helpers.py +270 -0
- moai_adk/core/comprehensive_monitoring_system.py +1183 -0
- moai_adk/core/config/__init__.py +19 -0
- moai_adk/core/config/auto_spec_config.py +340 -0
- moai_adk/core/config/migration.py +244 -0
- moai_adk/core/config/unified.py +436 -0
- moai_adk/core/context_manager.py +273 -0
- moai_adk/core/diagnostics/__init__.py +19 -0
- moai_adk/core/diagnostics/slash_commands.py +159 -0
- moai_adk/core/enterprise_features.py +1404 -0
- moai_adk/core/error_recovery_system.py +1902 -0
- moai_adk/core/event_driven_hook_system.py +1371 -0
- moai_adk/core/git/__init__.py +31 -0
- moai_adk/core/git/branch.py +25 -0
- moai_adk/core/git/branch_manager.py +129 -0
- moai_adk/core/git/checkpoint.py +134 -0
- moai_adk/core/git/commit.py +67 -0
- moai_adk/core/git/conflict_detector.py +413 -0
- moai_adk/core/git/event_detector.py +79 -0
- moai_adk/core/git/manager.py +216 -0
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +901 -0
- moai_adk/core/input_validation_middleware.py +1006 -0
- moai_adk/core/integration/__init__.py +22 -0
- moai_adk/core/integration/engine.py +157 -0
- moai_adk/core/integration/integration_tester.py +226 -0
- moai_adk/core/integration/models.py +88 -0
- moai_adk/core/integration/utils.py +211 -0
- moai_adk/core/issue_creator.py +305 -0
- moai_adk/core/jit_context_loader.py +956 -0
- moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
- moai_adk/core/language_config.py +202 -0
- moai_adk/core/language_config_resolver.py +572 -0
- moai_adk/core/language_validator.py +543 -0
- moai_adk/core/mcp/setup.py +116 -0
- moai_adk/core/merge/__init__.py +9 -0
- moai_adk/core/merge/analyzer.py +605 -0
- moai_adk/core/migration/__init__.py +18 -0
- moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
- moai_adk/core/migration/backup_manager.py +277 -0
- moai_adk/core/migration/custom_element_scanner.py +358 -0
- moai_adk/core/migration/file_migrator.py +209 -0
- moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
- moai_adk/core/migration/selective_restorer.py +470 -0
- moai_adk/core/migration/template_utils.py +74 -0
- moai_adk/core/migration/user_selection_ui.py +338 -0
- moai_adk/core/migration/version_detector.py +139 -0
- moai_adk/core/migration/version_migrator.py +228 -0
- moai_adk/core/performance/__init__.py +6 -0
- moai_adk/core/performance/cache_system.py +316 -0
- moai_adk/core/performance/parallel_processor.py +116 -0
- moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
- moai_adk/core/project/__init__.py +1 -0
- moai_adk/core/project/backup_utils.py +70 -0
- moai_adk/core/project/checker.py +300 -0
- moai_adk/core/project/detector.py +293 -0
- moai_adk/core/project/initializer.py +387 -0
- moai_adk/core/project/phase_executor.py +716 -0
- moai_adk/core/project/validator.py +139 -0
- moai_adk/core/quality/__init__.py +6 -0
- moai_adk/core/quality/trust_checker.py +377 -0
- moai_adk/core/quality/validators/__init__.py +6 -0
- moai_adk/core/quality/validators/base_validator.py +19 -0
- moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
- moai_adk/core/robust_json_parser.py +611 -0
- moai_adk/core/rollback_manager.py +918 -0
- moai_adk/core/session_manager.py +651 -0
- moai_adk/core/skill_loading_system.py +579 -0
- moai_adk/core/spec/confidence_scoring.py +680 -0
- moai_adk/core/spec/ears_template_engine.py +1247 -0
- moai_adk/core/spec/quality_validator.py +687 -0
- moai_adk/core/spec_status_manager.py +478 -0
- moai_adk/core/template/__init__.py +7 -0
- moai_adk/core/template/backup.py +174 -0
- moai_adk/core/template/config.py +191 -0
- moai_adk/core/template/languages.py +43 -0
- moai_adk/core/template/merger.py +233 -0
- moai_adk/core/template/processor.py +1200 -0
- moai_adk/core/template_engine.py +310 -0
- moai_adk/core/template_variable_synchronizer.py +417 -0
- moai_adk/core/unified_permission_manager.py +745 -0
- moai_adk/core/user_behavior_analytics.py +851 -0
- moai_adk/core/version_sync.py +429 -0
- moai_adk/foundation/__init__.py +56 -0
- moai_adk/foundation/backend.py +1027 -0
- moai_adk/foundation/database.py +1115 -0
- moai_adk/foundation/devops.py +1585 -0
- moai_adk/foundation/ears.py +431 -0
- moai_adk/foundation/frontend.py +870 -0
- moai_adk/foundation/git/commit_templates.py +557 -0
- moai_adk/foundation/git.py +376 -0
- moai_adk/foundation/langs.py +484 -0
- moai_adk/foundation/ml_ops.py +1162 -0
- moai_adk/foundation/testing.py +1524 -0
- moai_adk/foundation/trust/trust_principles.py +676 -0
- moai_adk/foundation/trust/validation_checklist.py +1573 -0
- moai_adk/project/__init__.py +0 -0
- moai_adk/project/configuration.py +1084 -0
- moai_adk/project/documentation.py +566 -0
- moai_adk/project/schema.py +447 -0
- moai_adk/statusline/__init__.py +38 -0
- moai_adk/statusline/alfred_detector.py +105 -0
- moai_adk/statusline/config.py +376 -0
- moai_adk/statusline/enhanced_output_style_detector.py +372 -0
- moai_adk/statusline/git_collector.py +190 -0
- moai_adk/statusline/main.py +322 -0
- moai_adk/statusline/metrics_tracker.py +78 -0
- moai_adk/statusline/renderer.py +343 -0
- moai_adk/statusline/update_checker.py +129 -0
- moai_adk/statusline/version_reader.py +741 -0
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +714 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +474 -0
- moai_adk/templates/.claude/agents/moai/builder-command.md +1172 -0
- moai_adk/templates/.claude/agents/moai/builder-plugin.md +637 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +666 -0
- moai_adk/templates/.claude/agents/moai/expert-backend.md +899 -0
- moai_adk/templates/.claude/agents/moai/expert-database.md +777 -0
- moai_adk/templates/.claude/agents/moai/expert-debug.md +401 -0
- moai_adk/templates/.claude/agents/moai/expert-devops.md +720 -0
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +734 -0
- moai_adk/templates/.claude/agents/moai/expert-performance.md +657 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +513 -0
- moai_adk/templates/.claude/agents/moai/expert-testing.md +733 -0
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +1041 -0
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +432 -0
- moai_adk/templates/.claude/agents/moai/manager-docs.md +573 -0
- moai_adk/templates/.claude/agents/moai/manager-git.md +1060 -0
- moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
- moai_adk/templates/.claude/agents/moai/manager-quality.md +624 -0
- moai_adk/templates/.claude/agents/moai/manager-spec.md +809 -0
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +780 -0
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +784 -0
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +458 -0
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +1607 -0
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +789 -0
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +469 -0
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +1032 -0
- moai_adk/templates/.claude/commands/moai/0-project.md +1386 -0
- moai_adk/templates/.claude/commands/moai/1-plan.md +1427 -0
- moai_adk/templates/.claude/commands/moai/2-run.md +943 -0
- moai_adk/templates/.claude/commands/moai/3-sync.md +1324 -0
- moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
- moai_adk/templates/.claude/hooks/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
- moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
- moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
- moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
- moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
- moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
- moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +1083 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +560 -0
- moai_adk/templates/.claude/output-styles/moai/yoda.md +359 -0
- moai_adk/templates/.claude/settings.json +172 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/SKILL.md +307 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/examples.md +431 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/batch_generate.py +560 -0
- moai_adk/templates/.claude/skills/moai-ai-nano-banana/scripts/generate_image.py +362 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +249 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/examples.md +406 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/reference.md +328 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +320 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/examples.md +718 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/reference.md +464 -0
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +323 -0
- moai_adk/templates/.claude/skills/moai-domain-database/examples.md +830 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
- moai_adk/templates/.claude/skills/moai-domain-database/reference.md +545 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/examples.md +968 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/reference.md +664 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +455 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +492 -0
- moai_adk/templates/.claude/skills/moai-formats-data/examples.md +804 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
- moai_adk/templates/.claude/skills/moai-formats-data/reference.md +585 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +202 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/examples.md +732 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference.md +209 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +441 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/examples.md +1048 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/reference.md +246 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +420 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/examples.md +358 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +359 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/reference.md +478 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/SKILL.md +315 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/examples.md +228 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/assumption-matrix.md +80 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/cognitive-bias.md +199 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/first-principles.md +140 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/modules/trade-off-analysis.md +154 -0
- moai_adk/templates/.claude/skills/moai-foundation-philosopher/reference.md +157 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +364 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
- moai_adk/templates/.claude/skills/moai-lang-cpp/SKILL.md +649 -0
- moai_adk/templates/.claude/skills/moai-lang-csharp/SKILL.md +478 -0
- moai_adk/templates/.claude/skills/moai-lang-elixir/SKILL.md +612 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/SKILL.md +477 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/examples.md +1090 -0
- moai_adk/templates/.claude/skills/moai-lang-flutter/reference.md +686 -0
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +376 -0
- moai_adk/templates/.claude/skills/moai-lang-go/examples.md +919 -0
- moai_adk/templates/.claude/skills/moai-lang-go/reference.md +737 -0
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +385 -0
- moai_adk/templates/.claude/skills/moai-lang-java/examples.md +864 -0
- moai_adk/templates/.claude/skills/moai-lang-java/reference.md +291 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/SKILL.md +382 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/examples.md +1006 -0
- moai_adk/templates/.claude/skills/moai-lang-kotlin/reference.md +562 -0
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +644 -0
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +481 -0
- moai_adk/templates/.claude/skills/moai-lang-python/examples.md +977 -0
- moai_adk/templates/.claude/skills/moai-lang-python/reference.md +804 -0
- moai_adk/templates/.claude/skills/moai-lang-r/SKILL.md +579 -0
- moai_adk/templates/.claude/skills/moai-lang-ruby/SKILL.md +687 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +372 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/examples.md +659 -0
- moai_adk/templates/.claude/skills/moai-lang-rust/reference.md +504 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/examples.md +633 -0
- moai_adk/templates/.claude/skills/moai-lang-scala/reference.md +423 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/SKILL.md +497 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/examples.md +918 -0
- moai_adk/templates/.claude/skills/moai-lang-swift/reference.md +672 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +368 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/examples.md +1089 -0
- moai_adk/templates/.claude/skills/moai-lang-typescript/reference.md +731 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +300 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +319 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/examples.md +592 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/reference.md +379 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +372 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
- moai_adk/templates/.claude/skills/moai-mcp-figma/SKILL.md +402 -0
- moai_adk/templates/.claude/skills/moai-mcp-figma/advanced-patterns.md +607 -0
- moai_adk/templates/.claude/skills/moai-mcp-notion/SKILL.md +300 -0
- moai_adk/templates/.claude/skills/moai-mcp-notion/advanced-patterns.md +537 -0
- moai_adk/templates/.claude/skills/moai-platform-auth0/SKILL.md +291 -0
- moai_adk/templates/.claude/skills/moai-platform-clerk/SKILL.md +390 -0
- moai_adk/templates/.claude/skills/moai-platform-convex/SKILL.md +398 -0
- moai_adk/templates/.claude/skills/moai-platform-firebase-auth/SKILL.md +379 -0
- moai_adk/templates/.claude/skills/moai-platform-firestore/SKILL.md +358 -0
- moai_adk/templates/.claude/skills/moai-platform-neon/SKILL.md +467 -0
- moai_adk/templates/.claude/skills/moai-platform-railway/SKILL.md +377 -0
- moai_adk/templates/.claude/skills/moai-platform-supabase/SKILL.md +466 -0
- moai_adk/templates/.claude/skills/moai-platform-vercel/SKILL.md +482 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/SKILL.md +474 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/examples.md +621 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/migration.md +341 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/reference.md +463 -0
- moai_adk/templates/.claude/skills/moai-plugin-builder/validation.md +373 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/SKILL.md +275 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/adaptive-mfa.md +233 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/akamai-integration.md +215 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/application-credentials.md +280 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-log-events.md +225 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/attack-protection-overview.md +140 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/bot-detection.md +144 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/breached-password-detection.md +187 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/brute-force-protection.md +189 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/certifications.md +282 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/compliance-overview.md +263 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/continuous-session-protection.md +307 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/customize-mfa.md +178 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/dpop-implementation.md +283 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/fapi-implementation.md +259 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/gdpr-compliance.md +313 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/guardian-configuration.md +269 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/highly-regulated-identity.md +272 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/jwt-fundamentals.md +248 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mdl-verification.md +211 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-api-management.md +278 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-factors.md +226 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mfa-overview.md +174 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/mtls-sender-constraining.md +316 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/ropg-flow-mfa.md +217 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-center.md +325 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/security-guidance.md +277 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/state-parameters.md +178 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/step-up-authentication.md +251 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/suspicious-ip-throttling.md +240 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/tenant-access-control.md +180 -0
- moai_adk/templates/.claude/skills/moai-security-auth0/modules/webauthn-fido.md +235 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +449 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/examples.md +544 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/reference.md +307 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +390 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +175 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples.md +547 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/reference.md +275 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1434 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +92 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/SKILL.md +534 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/examples.md +900 -0
- moai_adk/templates/.claude/skills/moai-workflow-spec/reference.md +704 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +377 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/examples.md +552 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/reference.md +346 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +456 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples.md +672 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference.md +440 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
- moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +411 -0
- moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
- moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
- moai_adk/templates/.git-hooks/pre-commit +128 -0
- moai_adk/templates/.git-hooks/pre-push +365 -0
- moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
- moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +337 -0
- moai_adk/templates/.gitignore +222 -0
- moai_adk/templates/.mcp.json +13 -0
- moai_adk/templates/.moai/config/config.yaml +58 -0
- moai_adk/templates/.moai/config/questions/_schema.yaml +174 -0
- moai_adk/templates/.moai/config/questions/tab0-init.yaml +251 -0
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +107 -0
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +79 -0
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +632 -0
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +182 -0
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +96 -0
- moai_adk/templates/.moai/config/sections/git-strategy.yaml +116 -0
- moai_adk/templates/.moai/config/sections/language.yaml +11 -0
- moai_adk/templates/.moai/config/sections/project.yaml +13 -0
- moai_adk/templates/.moai/config/sections/quality.yaml +17 -0
- moai_adk/templates/.moai/config/sections/system.yaml +24 -0
- moai_adk/templates/.moai/config/sections/user.yaml +5 -0
- moai_adk/templates/.moai/config/statusline-config.yaml +92 -0
- moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
- moai_adk/templates/CLAUDE.md +642 -0
- moai_adk/utils/__init__.py +30 -0
- moai_adk/utils/banner.py +38 -0
- moai_adk/utils/common.py +294 -0
- moai_adk/utils/link_validator.py +241 -0
- moai_adk/utils/logger.py +147 -0
- moai_adk/utils/safe_file_reader.py +206 -0
- moai_adk/utils/timeout.py +160 -0
- moai_adk/utils/toon_utils.py +256 -0
- moai_adk/version.py +22 -0
- moai_adk-0.35.1.dist-info/METADATA +3018 -0
- moai_adk-0.35.1.dist-info/RECORD +502 -0
- moai_adk-0.35.1.dist-info/WHEEL +4 -0
- moai_adk-0.35.1.dist-info/entry_points.txt +3 -0
- moai_adk-0.35.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Integration Testing Framework
|
|
3
|
+
|
|
4
|
+
Provides comprehensive integration testing capabilities for MoAI-ADK components.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .engine import TestEngine
|
|
8
|
+
from .integration_tester import IntegrationTester
|
|
9
|
+
from .models import IntegrationTestResult, TestComponent, TestStatus, TestSuite
|
|
10
|
+
from .utils import ComponentDiscovery, TestEnvironment, TestResultAnalyzer
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"IntegrationTester",
|
|
14
|
+
"IntegrationTestResult",
|
|
15
|
+
"TestComponent",
|
|
16
|
+
"TestSuite",
|
|
17
|
+
"TestStatus",
|
|
18
|
+
"TestEngine",
|
|
19
|
+
"ComponentDiscovery",
|
|
20
|
+
"TestResultAnalyzer",
|
|
21
|
+
"TestEnvironment",
|
|
22
|
+
]
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Integration testing execution engine.
|
|
3
|
+
|
|
4
|
+
This module contains the core test execution logic for running
|
|
5
|
+
integration tests with timeout handling and concurrent execution.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import time
|
|
10
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
11
|
+
from typing import Callable, List, Optional
|
|
12
|
+
|
|
13
|
+
from .models import IntegrationTestResult, TestStatus
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestEngine:
|
|
17
|
+
"""
|
|
18
|
+
Core test execution engine for integration testing.
|
|
19
|
+
|
|
20
|
+
Handles test execution, timeout management, and concurrent execution.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, test_timeout: float = 30.0, max_workers: int = 4):
|
|
24
|
+
"""
|
|
25
|
+
Initialize the test engine.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
test_timeout: Maximum time (in seconds) for each test
|
|
29
|
+
max_workers: Maximum number of concurrent workers
|
|
30
|
+
"""
|
|
31
|
+
if test_timeout <= 0:
|
|
32
|
+
raise ValueError("Test timeout must be positive")
|
|
33
|
+
if max_workers <= 0:
|
|
34
|
+
raise ValueError("Max workers must be positive")
|
|
35
|
+
|
|
36
|
+
self.test_timeout = test_timeout
|
|
37
|
+
self.max_workers = max_workers
|
|
38
|
+
self._test_counter = 0
|
|
39
|
+
|
|
40
|
+
def _generate_test_id(self) -> str:
|
|
41
|
+
"""Generate a unique test ID."""
|
|
42
|
+
self._test_counter += 1
|
|
43
|
+
return f"test_{self._test_counter:04d}"
|
|
44
|
+
|
|
45
|
+
def execute_test(
|
|
46
|
+
self, test_func: Callable, test_name: str = None, components: List[str] = None
|
|
47
|
+
) -> IntegrationTestResult:
|
|
48
|
+
"""
|
|
49
|
+
Execute a single integration test.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
test_func: Test function to execute
|
|
53
|
+
test_name: Optional test name
|
|
54
|
+
components: List of components being tested
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
IntegrationTestResult: Test execution result
|
|
58
|
+
"""
|
|
59
|
+
if test_name is None:
|
|
60
|
+
test_name = self._generate_test_id()
|
|
61
|
+
|
|
62
|
+
if components is None:
|
|
63
|
+
components = []
|
|
64
|
+
|
|
65
|
+
start_time = time.time()
|
|
66
|
+
result = IntegrationTestResult(test_name=test_name, passed=False, components_tested=components)
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
# Execute test with timeout
|
|
70
|
+
with ThreadPoolExecutor(max_workers=1) as executor:
|
|
71
|
+
future = executor.submit(test_func)
|
|
72
|
+
try:
|
|
73
|
+
test_result = future.result(timeout=self.test_timeout)
|
|
74
|
+
result.passed = bool(test_result)
|
|
75
|
+
result.status = TestStatus.PASSED if result.passed else TestStatus.FAILED
|
|
76
|
+
|
|
77
|
+
except TimeoutError:
|
|
78
|
+
result.error_message = f"Test timed out after {self.test_timeout}s"
|
|
79
|
+
result.status = TestStatus.FAILED
|
|
80
|
+
|
|
81
|
+
except Exception as e:
|
|
82
|
+
result.error_message = str(e)
|
|
83
|
+
result.status = TestStatus.FAILED
|
|
84
|
+
|
|
85
|
+
finally:
|
|
86
|
+
result.execution_time = time.time() - start_time
|
|
87
|
+
|
|
88
|
+
return result
|
|
89
|
+
|
|
90
|
+
async def execute_test_async(
|
|
91
|
+
self, test_func: Callable, test_name: str = None, components: List[str] = None
|
|
92
|
+
) -> IntegrationTestResult:
|
|
93
|
+
"""
|
|
94
|
+
Execute a single integration test asynchronously.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
test_func: Test function to execute
|
|
98
|
+
test_name: Optional test name
|
|
99
|
+
components: List of components being tested
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
IntegrationTestResult: Test execution result
|
|
103
|
+
"""
|
|
104
|
+
loop = asyncio.get_event_loop()
|
|
105
|
+
return await loop.run_in_executor(None, self.execute_test, test_func, test_name, components)
|
|
106
|
+
|
|
107
|
+
def run_concurrent_tests(self, tests: List[tuple], timeout: Optional[float] = None) -> List[IntegrationTestResult]:
|
|
108
|
+
"""
|
|
109
|
+
Run multiple tests concurrently.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
tests: List of (test_func, test_name, components) tuples
|
|
113
|
+
timeout: Optional timeout for entire batch
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
List of test results
|
|
117
|
+
"""
|
|
118
|
+
if timeout is None:
|
|
119
|
+
timeout = self.test_timeout * 2
|
|
120
|
+
|
|
121
|
+
results = []
|
|
122
|
+
|
|
123
|
+
with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
|
|
124
|
+
# Submit all tests
|
|
125
|
+
future_to_test = {executor.submit(self.execute_test, *test): test for test in tests}
|
|
126
|
+
|
|
127
|
+
# Collect results as they complete
|
|
128
|
+
for future in as_completed(future_to_test, timeout=timeout):
|
|
129
|
+
try:
|
|
130
|
+
result = future.result()
|
|
131
|
+
results.append(result)
|
|
132
|
+
except Exception as e:
|
|
133
|
+
test_info = future_to_test[future]
|
|
134
|
+
error_result = IntegrationTestResult(
|
|
135
|
+
test_name=test_info[1] if len(test_info) > 1 else "unknown",
|
|
136
|
+
passed=False,
|
|
137
|
+
error_message=f"Execution error: {str(e)}",
|
|
138
|
+
)
|
|
139
|
+
results.append(error_result)
|
|
140
|
+
|
|
141
|
+
return results
|
|
142
|
+
|
|
143
|
+
async def run_concurrent_tests_async(
|
|
144
|
+
self, tests: List[tuple], timeout: Optional[float] = None
|
|
145
|
+
) -> List[IntegrationTestResult]:
|
|
146
|
+
"""
|
|
147
|
+
Run multiple tests concurrently asynchronously.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
tests: List of (test_func, test_name, components) tuples
|
|
151
|
+
timeout: Optional timeout for entire batch
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
List of test results
|
|
155
|
+
"""
|
|
156
|
+
loop = asyncio.get_event_loop()
|
|
157
|
+
return await loop.run_in_executor(None, self.run_concurrent_tests, tests, timeout)
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Integration Tester - Main Interface
|
|
3
|
+
|
|
4
|
+
Provides a high-level interface for comprehensive integration testing
|
|
5
|
+
of MoAI-ADK components. This module serves as the main entry point
|
|
6
|
+
for integration testing functionality.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Any, Callable, Dict, List, Optional, Union
|
|
10
|
+
|
|
11
|
+
from .engine import TestEngine
|
|
12
|
+
from .models import IntegrationTestResult, TestComponent, TestSuite
|
|
13
|
+
from .utils import ComponentDiscovery, TestEnvironment, TestResultAnalyzer
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class IntegrationTester:
|
|
17
|
+
"""
|
|
18
|
+
Comprehensive integration tester for MoAI-ADK components.
|
|
19
|
+
|
|
20
|
+
This class provides a high-level interface for testing multiple components
|
|
21
|
+
together to ensure they work correctly in integration scenarios.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, test_timeout: float = 30.0, max_workers: int = 4):
|
|
25
|
+
"""
|
|
26
|
+
Initialize the integration tester.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
test_timeout: Maximum time (in seconds) for each test
|
|
30
|
+
max_workers: Maximum number of concurrent workers
|
|
31
|
+
"""
|
|
32
|
+
self.engine = TestEngine(test_timeout, max_workers)
|
|
33
|
+
self.test_results: List[IntegrationTestResult] = []
|
|
34
|
+
self.discovery = ComponentDiscovery()
|
|
35
|
+
self.analyzer = TestResultAnalyzer()
|
|
36
|
+
|
|
37
|
+
def add_test_result(self, result: IntegrationTestResult):
|
|
38
|
+
"""
|
|
39
|
+
Add a test result to the results list.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
result: Test result to add
|
|
43
|
+
"""
|
|
44
|
+
self.test_results.append(result)
|
|
45
|
+
|
|
46
|
+
def clear_results(self):
|
|
47
|
+
"""Clear all test results."""
|
|
48
|
+
self.test_results.clear()
|
|
49
|
+
|
|
50
|
+
def get_success_rate(self) -> float:
|
|
51
|
+
"""
|
|
52
|
+
Get the success rate of all tests.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
Success rate as percentage (0-100)
|
|
56
|
+
"""
|
|
57
|
+
return self.analyzer.calculate_success_rate(self.test_results)
|
|
58
|
+
|
|
59
|
+
def get_test_stats(self) -> Dict[str, Any]:
|
|
60
|
+
"""
|
|
61
|
+
Get comprehensive test statistics.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
Dictionary with test statistics
|
|
65
|
+
"""
|
|
66
|
+
return self.analyzer.get_execution_stats(self.test_results)
|
|
67
|
+
|
|
68
|
+
def run_test(
|
|
69
|
+
self, test_func: Callable, test_name: str = None, components: List[str] = None
|
|
70
|
+
) -> IntegrationTestResult:
|
|
71
|
+
"""
|
|
72
|
+
Run a single integration test.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
test_func: Test function to execute
|
|
76
|
+
test_name: Optional test name
|
|
77
|
+
components: List of components being tested
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
IntegrationTestResult: Test execution result
|
|
81
|
+
"""
|
|
82
|
+
result = self.engine.execute_test(test_func, test_name, components)
|
|
83
|
+
self.add_test_result(result)
|
|
84
|
+
return result
|
|
85
|
+
|
|
86
|
+
async def run_test_async(
|
|
87
|
+
self, test_func: Callable, test_name: str = None, components: List[str] = None
|
|
88
|
+
) -> IntegrationTestResult:
|
|
89
|
+
"""
|
|
90
|
+
Run a single integration test asynchronously.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
test_func: Test function to execute
|
|
94
|
+
test_name: Optional test name
|
|
95
|
+
components: List of components being tested
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
IntegrationTestResult: Test execution result
|
|
99
|
+
"""
|
|
100
|
+
result = await self.engine.execute_test_async(test_func, test_name, components)
|
|
101
|
+
self.add_test_result(result)
|
|
102
|
+
return result
|
|
103
|
+
|
|
104
|
+
def run_test_suite(self, test_suite: TestSuite) -> List[IntegrationTestResult]:
|
|
105
|
+
"""
|
|
106
|
+
Run a complete test suite.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
test_suite: Test suite to run
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
List of test results
|
|
113
|
+
"""
|
|
114
|
+
results = []
|
|
115
|
+
|
|
116
|
+
def placeholder_test():
|
|
117
|
+
"""Placeholder test function"""
|
|
118
|
+
return True
|
|
119
|
+
|
|
120
|
+
for test_case_name in test_suite.test_cases:
|
|
121
|
+
# This is a simplified implementation
|
|
122
|
+
# In practice, you would map test case names to actual test functions
|
|
123
|
+
result = self.run_test(
|
|
124
|
+
placeholder_test,
|
|
125
|
+
test_case_name,
|
|
126
|
+
[c.name for c in test_suite.components],
|
|
127
|
+
)
|
|
128
|
+
results.append(result)
|
|
129
|
+
|
|
130
|
+
return results
|
|
131
|
+
|
|
132
|
+
def run_concurrent_tests(self, tests: List[tuple], timeout: Optional[float] = None) -> List[IntegrationTestResult]:
|
|
133
|
+
"""
|
|
134
|
+
Run multiple tests concurrently.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
tests: List of (test_func, test_name, components) tuples
|
|
138
|
+
timeout: Optional timeout for entire batch
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
List of test results
|
|
142
|
+
"""
|
|
143
|
+
results = self.engine.run_concurrent_tests(tests, timeout)
|
|
144
|
+
self.test_results.extend(results)
|
|
145
|
+
return results
|
|
146
|
+
|
|
147
|
+
async def run_concurrent_tests_async(
|
|
148
|
+
self, tests: List[tuple], timeout: Optional[float] = None
|
|
149
|
+
) -> List[IntegrationTestResult]:
|
|
150
|
+
"""
|
|
151
|
+
Run multiple tests concurrently asynchronously.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
tests: List of (test_func, test_name, components) tuples
|
|
155
|
+
timeout: Optional timeout for entire batch
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
List of test results
|
|
159
|
+
"""
|
|
160
|
+
results = await self.engine.run_concurrent_tests_async(tests, timeout)
|
|
161
|
+
self.test_results.extend(results)
|
|
162
|
+
return results
|
|
163
|
+
|
|
164
|
+
def discover_components(self, base_path: str) -> List[TestComponent]:
|
|
165
|
+
"""
|
|
166
|
+
Discover testable components in the given path.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
base_path: Base path to search for components
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
List of discovered components
|
|
173
|
+
"""
|
|
174
|
+
return self.discovery.discover_components(base_path)
|
|
175
|
+
|
|
176
|
+
def create_test_environment(self, temp_dir: Optional[str] = None) -> TestEnvironment:
|
|
177
|
+
"""
|
|
178
|
+
Create a test environment for integration testing.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
temp_dir: Optional temporary directory path
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
TestEnvironment instance
|
|
185
|
+
"""
|
|
186
|
+
return TestEnvironment(temp_dir)
|
|
187
|
+
|
|
188
|
+
def export_results(self, format: str = "dict") -> Union[Dict, str]:
|
|
189
|
+
"""
|
|
190
|
+
Export test results in specified format.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
format: Export format ("dict", "json", "summary")
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
Exported results
|
|
197
|
+
"""
|
|
198
|
+
if format == "dict":
|
|
199
|
+
return [vars(result) for result in self.test_results] # type: ignore[return-value]
|
|
200
|
+
elif format == "summary":
|
|
201
|
+
return {
|
|
202
|
+
"stats": self.get_test_stats(),
|
|
203
|
+
"failed_tests": self.analyzer.get_failed_tests(self.test_results),
|
|
204
|
+
}
|
|
205
|
+
else:
|
|
206
|
+
raise ValueError(f"Unsupported format: {format}")
|
|
207
|
+
|
|
208
|
+
def validate_test_environment(self) -> List[str]:
|
|
209
|
+
"""
|
|
210
|
+
Validate the test environment.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
List of validation warnings
|
|
214
|
+
"""
|
|
215
|
+
warnings = []
|
|
216
|
+
|
|
217
|
+
# Check if we have any test results
|
|
218
|
+
if not self.test_results:
|
|
219
|
+
warnings.append("No test results found")
|
|
220
|
+
|
|
221
|
+
# Check success rate
|
|
222
|
+
success_rate = self.get_success_rate()
|
|
223
|
+
if success_rate < 80.0:
|
|
224
|
+
warnings.append(f"Low success rate: {success_rate:.1f}%")
|
|
225
|
+
|
|
226
|
+
return warnings
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Integration testing data structures and utilities.
|
|
3
|
+
|
|
4
|
+
This module contains common data structures and utility functions
|
|
5
|
+
for integration testing across the MoAI-ADK system.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from enum import Enum
|
|
10
|
+
from typing import List, Optional
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TestStatus(Enum):
|
|
14
|
+
"""Test status enumeration"""
|
|
15
|
+
|
|
16
|
+
PENDING = "pending"
|
|
17
|
+
RUNNING = "running"
|
|
18
|
+
PASSED = "passed"
|
|
19
|
+
FAILED = "failed"
|
|
20
|
+
SKIPPED = "skipped"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class IntegrationTestResult:
|
|
25
|
+
"""Test result data structure"""
|
|
26
|
+
|
|
27
|
+
test_name: str
|
|
28
|
+
passed: bool
|
|
29
|
+
error_message: Optional[str] = None
|
|
30
|
+
execution_time: float = 0.0
|
|
31
|
+
components_tested: Optional[List[str]] = None
|
|
32
|
+
status: Optional[TestStatus] = None
|
|
33
|
+
|
|
34
|
+
def __post_init__(self):
|
|
35
|
+
if self.components_tested is None:
|
|
36
|
+
self.components_tested = []
|
|
37
|
+
if self.passed:
|
|
38
|
+
self.status = TestStatus.PASSED
|
|
39
|
+
elif self.error_message:
|
|
40
|
+
self.status = TestStatus.FAILED
|
|
41
|
+
else:
|
|
42
|
+
self.status = TestStatus.PENDING
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class TestComponent:
|
|
47
|
+
"""Test component definition"""
|
|
48
|
+
|
|
49
|
+
name: str
|
|
50
|
+
component_type: str
|
|
51
|
+
version: str
|
|
52
|
+
dependencies: Optional[List[str]] = None
|
|
53
|
+
|
|
54
|
+
def __post_init__(self):
|
|
55
|
+
if self.dependencies is None:
|
|
56
|
+
self.dependencies = []
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@dataclass
|
|
60
|
+
class TestSuite:
|
|
61
|
+
"""Test suite definition"""
|
|
62
|
+
|
|
63
|
+
name: str
|
|
64
|
+
description: str
|
|
65
|
+
components: List[TestComponent]
|
|
66
|
+
test_cases: Optional[List[str]] = None
|
|
67
|
+
|
|
68
|
+
def __post_init__(self):
|
|
69
|
+
if self.test_cases is None:
|
|
70
|
+
self.test_cases = []
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class IntegrationTestError(Exception):
|
|
74
|
+
"""Base exception for integration testing"""
|
|
75
|
+
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class TestTimeoutError(IntegrationTestError):
|
|
80
|
+
"""Test timeout exception"""
|
|
81
|
+
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class ComponentNotFoundError(IntegrationTestError):
|
|
86
|
+
"""Component not found exception"""
|
|
87
|
+
|
|
88
|
+
pass
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Integration testing utilities and helper functions.
|
|
3
|
+
|
|
4
|
+
This module contains utility functions for component discovery,
|
|
5
|
+
dependency resolution, and test result analysis.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import shutil
|
|
9
|
+
import tempfile
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
12
|
+
|
|
13
|
+
from .models import IntegrationTestResult, TestComponent
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ComponentDiscovery:
|
|
17
|
+
"""
|
|
18
|
+
Component discovery utilities for integration testing.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def discover_components(base_path: str) -> List[TestComponent]:
|
|
23
|
+
"""
|
|
24
|
+
Discover testable components in the given path.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
base_path: Base path to search for components
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
List of discovered components
|
|
31
|
+
"""
|
|
32
|
+
components: List[TestComponent] = []
|
|
33
|
+
base_dir = Path(base_path)
|
|
34
|
+
|
|
35
|
+
if not base_dir.exists():
|
|
36
|
+
return components
|
|
37
|
+
|
|
38
|
+
# Look for Python modules
|
|
39
|
+
for py_file in base_dir.rglob("*.py"):
|
|
40
|
+
if py_file.name.startswith("__"):
|
|
41
|
+
continue
|
|
42
|
+
|
|
43
|
+
relative_path = py_file.relative_to(base_dir)
|
|
44
|
+
module_name = str(relative_path.with_suffix("")).replace("/", ".")
|
|
45
|
+
|
|
46
|
+
component = TestComponent(
|
|
47
|
+
name=module_name,
|
|
48
|
+
component_type="python_module",
|
|
49
|
+
version="1.0.0", # Default version
|
|
50
|
+
)
|
|
51
|
+
components.append(component)
|
|
52
|
+
|
|
53
|
+
return components
|
|
54
|
+
|
|
55
|
+
@staticmethod
|
|
56
|
+
def resolve_dependencies(components: List[TestComponent]) -> Dict[str, List[str]]:
|
|
57
|
+
"""
|
|
58
|
+
Resolve dependencies between components.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
components: List of components to analyze
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
Dictionary mapping component names to their dependencies
|
|
65
|
+
"""
|
|
66
|
+
dependency_map = {}
|
|
67
|
+
|
|
68
|
+
for component in components:
|
|
69
|
+
try:
|
|
70
|
+
# Try to import and analyze dependencies
|
|
71
|
+
dependencies = ComponentDiscovery._analyze_imports(component)
|
|
72
|
+
dependency_map[component.name] = dependencies
|
|
73
|
+
except Exception:
|
|
74
|
+
dependency_map[component.name] = component.dependencies
|
|
75
|
+
|
|
76
|
+
return dependency_map
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def _analyze_imports(component: TestComponent) -> List[str]:
|
|
80
|
+
"""
|
|
81
|
+
Analyze imports for a component to determine dependencies.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
component: Component to analyze
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
List of dependency names
|
|
88
|
+
"""
|
|
89
|
+
# This is a simplified implementation
|
|
90
|
+
# In a real scenario, you would parse the source code
|
|
91
|
+
return component.dependencies
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class TestResultAnalyzer:
|
|
95
|
+
"""
|
|
96
|
+
Test result analysis utilities.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def calculate_success_rate(results: List[IntegrationTestResult]) -> float:
|
|
101
|
+
"""
|
|
102
|
+
Calculate the success rate of test results.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
results: List of test results
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Success rate as percentage (0-100)
|
|
109
|
+
"""
|
|
110
|
+
if not results:
|
|
111
|
+
return 0.0
|
|
112
|
+
|
|
113
|
+
passed = sum(1 for result in results if result.passed)
|
|
114
|
+
return (passed / len(results)) * 100
|
|
115
|
+
|
|
116
|
+
@staticmethod
|
|
117
|
+
def get_failed_tests(
|
|
118
|
+
results: List[IntegrationTestResult],
|
|
119
|
+
) -> List[IntegrationTestResult]:
|
|
120
|
+
"""
|
|
121
|
+
Get list of failed tests.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
results: List of test results
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
List of failed test results
|
|
128
|
+
"""
|
|
129
|
+
return [result for result in results if not result.passed]
|
|
130
|
+
|
|
131
|
+
@staticmethod
|
|
132
|
+
def get_execution_stats(results: List[IntegrationTestResult]) -> Dict[str, Any]:
|
|
133
|
+
"""
|
|
134
|
+
Get execution statistics for test results.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
results: List of test results
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
Dictionary with execution statistics
|
|
141
|
+
"""
|
|
142
|
+
if not results:
|
|
143
|
+
return {
|
|
144
|
+
"total": 0,
|
|
145
|
+
"passed": 0,
|
|
146
|
+
"failed": 0,
|
|
147
|
+
"success_rate": 0.0,
|
|
148
|
+
"total_time": 0.0,
|
|
149
|
+
"avg_time": 0.0,
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
passed = sum(1 for result in results if result.passed)
|
|
153
|
+
failed = len(results) - passed
|
|
154
|
+
total_time = sum(result.execution_time for result in results)
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
"total": len(results),
|
|
158
|
+
"passed": passed,
|
|
159
|
+
"failed": failed,
|
|
160
|
+
"success_rate": TestResultAnalyzer.calculate_success_rate(results),
|
|
161
|
+
"total_time": total_time,
|
|
162
|
+
"avg_time": total_time / len(results),
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class TestEnvironment:
|
|
167
|
+
"""
|
|
168
|
+
Test environment management utilities.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
def __init__(self, temp_dir: Optional[str] = None):
|
|
172
|
+
"""
|
|
173
|
+
Initialize test environment.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
temp_dir: Optional temporary directory path
|
|
177
|
+
"""
|
|
178
|
+
self.temp_dir = temp_dir
|
|
179
|
+
self.created_temp = False
|
|
180
|
+
|
|
181
|
+
if self.temp_dir is None:
|
|
182
|
+
self.temp_dir = tempfile.mkdtemp(prefix="moai_integration_test_")
|
|
183
|
+
self.created_temp = True
|
|
184
|
+
|
|
185
|
+
def cleanup(self):
|
|
186
|
+
"""Clean up test environment."""
|
|
187
|
+
if self.created_temp and self.temp_dir:
|
|
188
|
+
try:
|
|
189
|
+
shutil.rmtree(self.temp_dir)
|
|
190
|
+
except Exception:
|
|
191
|
+
pass # Ignore cleanup errors
|
|
192
|
+
|
|
193
|
+
def get_temp_path(self, name: str) -> str:
|
|
194
|
+
"""
|
|
195
|
+
Get a temporary file path.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
name: File name
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
Full path to temporary file
|
|
202
|
+
"""
|
|
203
|
+
return str(Path(self.temp_dir) / name)
|
|
204
|
+
|
|
205
|
+
def __enter__(self):
|
|
206
|
+
"""Context manager entry."""
|
|
207
|
+
return self
|
|
208
|
+
|
|
209
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
210
|
+
"""Context manager exit."""
|
|
211
|
+
self.cleanup()
|