crca 1.4.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.
- .github/ISSUE_TEMPLATE/bug_report.md +65 -0
- .github/ISSUE_TEMPLATE/feature_request.md +41 -0
- .github/PULL_REQUEST_TEMPLATE.md +20 -0
- .github/workflows/publish-manual.yml +61 -0
- .github/workflows/publish.yml +64 -0
- .gitignore +214 -0
- CRCA.py +4156 -0
- LICENSE +201 -0
- MANIFEST.in +43 -0
- PKG-INFO +5035 -0
- README.md +4959 -0
- __init__.py +17 -0
- branches/CRCA-Q.py +2728 -0
- branches/crca_cg/corposwarm.py +9065 -0
- branches/crca_cg/fix_rancher_docker_creds.ps1 +155 -0
- branches/crca_cg/package.json +5 -0
- branches/crca_cg/test_bolt_integration.py +446 -0
- branches/crca_cg/test_corposwarm_comprehensive.py +773 -0
- branches/crca_cg/test_new_features.py +163 -0
- branches/crca_sd/__init__.py +149 -0
- branches/crca_sd/crca_sd_core.py +770 -0
- branches/crca_sd/crca_sd_governance.py +1325 -0
- branches/crca_sd/crca_sd_mpc.py +1130 -0
- branches/crca_sd/crca_sd_realtime.py +1844 -0
- branches/crca_sd/crca_sd_tui.py +1133 -0
- crca-1.4.0.dist-info/METADATA +5035 -0
- crca-1.4.0.dist-info/RECORD +501 -0
- crca-1.4.0.dist-info/WHEEL +4 -0
- crca-1.4.0.dist-info/licenses/LICENSE +201 -0
- docs/CRCA-Q.md +2333 -0
- examples/config.yaml.example +25 -0
- examples/crca_sd_example.py +513 -0
- examples/data_broker_example.py +294 -0
- examples/logistics_corporation.py +861 -0
- examples/palantir_example.py +299 -0
- examples/policy_bench.py +934 -0
- examples/pridnestrovia-sd.py +705 -0
- examples/pridnestrovia_realtime.py +1902 -0
- prompts/__init__.py +10 -0
- prompts/default_crca.py +101 -0
- pyproject.toml +151 -0
- requirements.txt +76 -0
- schemas/__init__.py +43 -0
- schemas/mcpSchemas.py +51 -0
- schemas/policy.py +458 -0
- templates/__init__.py +38 -0
- templates/base_specialized_agent.py +195 -0
- templates/drift_detection.py +325 -0
- templates/examples/causal_agent_template.py +309 -0
- templates/examples/drag_drop_example.py +213 -0
- templates/examples/logistics_agent_template.py +207 -0
- templates/examples/trading_agent_template.py +206 -0
- templates/feature_mixins.py +253 -0
- templates/graph_management.py +442 -0
- templates/llm_integration.py +194 -0
- templates/module_registry.py +276 -0
- templates/mpc_planner.py +280 -0
- templates/policy_loop.py +1168 -0
- templates/prediction_framework.py +448 -0
- templates/statistical_methods.py +778 -0
- tests/sanity.yml +31 -0
- tests/sanity_check +406 -0
- tests/test_core.py +47 -0
- tests/test_crca_excel.py +166 -0
- tests/test_crca_sd.py +780 -0
- tests/test_data_broker.py +424 -0
- tests/test_palantir.py +349 -0
- tools/__init__.py +38 -0
- tools/actuators.py +437 -0
- tools/bolt.diy/Dockerfile +103 -0
- tools/bolt.diy/app/components/@settings/core/AvatarDropdown.tsx +175 -0
- tools/bolt.diy/app/components/@settings/core/ControlPanel.tsx +345 -0
- tools/bolt.diy/app/components/@settings/core/constants.tsx +108 -0
- tools/bolt.diy/app/components/@settings/core/types.ts +114 -0
- tools/bolt.diy/app/components/@settings/index.ts +12 -0
- tools/bolt.diy/app/components/@settings/shared/components/TabTile.tsx +151 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionForm.tsx +193 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ConnectionTestIndicator.tsx +60 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ErrorState.tsx +102 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/LoadingState.tsx +94 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/ServiceHeader.tsx +72 -0
- tools/bolt.diy/app/components/@settings/shared/service-integration/index.ts +6 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataTab.tsx +721 -0
- tools/bolt.diy/app/components/@settings/tabs/data/DataVisualization.tsx +384 -0
- tools/bolt.diy/app/components/@settings/tabs/event-logs/EventLogsTab.tsx +1013 -0
- tools/bolt.diy/app/components/@settings/tabs/features/FeaturesTab.tsx +295 -0
- tools/bolt.diy/app/components/@settings/tabs/github/GitHubTab.tsx +281 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubAuthDialog.tsx +173 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubCacheManager.tsx +367 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubConnection.tsx +233 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubErrorBoundary.tsx +105 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubProgressiveLoader.tsx +266 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositoryCard.tsx +121 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubRepositorySelector.tsx +312 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubStats.tsx +291 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/GitHubUserProfile.tsx +46 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/GitHubStateIndicators.tsx +264 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/RepositoryCard.tsx +361 -0
- tools/bolt.diy/app/components/@settings/tabs/github/components/shared/index.ts +11 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/GitLabTab.tsx +305 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabAuthDialog.tsx +186 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabConnection.tsx +253 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/GitLabRepositorySelector.tsx +358 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryCard.tsx +79 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/RepositoryList.tsx +142 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/StatsDisplay.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/gitlab/components/index.ts +4 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerList.tsx +99 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpServerListItem.tsx +70 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpStatusBadge.tsx +37 -0
- tools/bolt.diy/app/components/@settings/tabs/mcp/McpTab.tsx +239 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/NetlifyTab.tsx +1393 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/NetlifyConnection.tsx +990 -0
- tools/bolt.diy/app/components/@settings/tabs/netlify/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/tabs/notifications/NotificationsTab.tsx +300 -0
- tools/bolt.diy/app/components/@settings/tabs/profile/ProfileTab.tsx +181 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/cloud/CloudProvidersTab.tsx +308 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ErrorBoundary.tsx +68 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/HealthStatusBadge.tsx +64 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LoadingSkeleton.tsx +107 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/LocalProvidersTab.tsx +556 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ModelCard.tsx +106 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/ProviderCard.tsx +120 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/SetupGuide.tsx +671 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/StatusDashboard.tsx +91 -0
- tools/bolt.diy/app/components/@settings/tabs/providers/local/types.ts +44 -0
- tools/bolt.diy/app/components/@settings/tabs/settings/SettingsTab.tsx +215 -0
- tools/bolt.diy/app/components/@settings/tabs/supabase/SupabaseTab.tsx +1089 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/VercelTab.tsx +909 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/VercelConnection.tsx +368 -0
- tools/bolt.diy/app/components/@settings/tabs/vercel/components/index.ts +1 -0
- tools/bolt.diy/app/components/@settings/utils/tab-helpers.ts +54 -0
- tools/bolt.diy/app/components/chat/APIKeyManager.tsx +169 -0
- tools/bolt.diy/app/components/chat/Artifact.tsx +296 -0
- tools/bolt.diy/app/components/chat/AssistantMessage.tsx +192 -0
- tools/bolt.diy/app/components/chat/BaseChat.module.scss +47 -0
- tools/bolt.diy/app/components/chat/BaseChat.tsx +522 -0
- tools/bolt.diy/app/components/chat/Chat.client.tsx +670 -0
- tools/bolt.diy/app/components/chat/ChatAlert.tsx +108 -0
- tools/bolt.diy/app/components/chat/ChatBox.tsx +334 -0
- tools/bolt.diy/app/components/chat/CodeBlock.module.scss +10 -0
- tools/bolt.diy/app/components/chat/CodeBlock.tsx +85 -0
- tools/bolt.diy/app/components/chat/DicussMode.tsx +17 -0
- tools/bolt.diy/app/components/chat/ExamplePrompts.tsx +37 -0
- tools/bolt.diy/app/components/chat/FilePreview.tsx +38 -0
- tools/bolt.diy/app/components/chat/GitCloneButton.tsx +327 -0
- tools/bolt.diy/app/components/chat/ImportFolderButton.tsx +141 -0
- tools/bolt.diy/app/components/chat/LLMApiAlert.tsx +109 -0
- tools/bolt.diy/app/components/chat/MCPTools.tsx +129 -0
- tools/bolt.diy/app/components/chat/Markdown.module.scss +171 -0
- tools/bolt.diy/app/components/chat/Markdown.spec.ts +48 -0
- tools/bolt.diy/app/components/chat/Markdown.tsx +252 -0
- tools/bolt.diy/app/components/chat/Messages.client.tsx +102 -0
- tools/bolt.diy/app/components/chat/ModelSelector.tsx +797 -0
- tools/bolt.diy/app/components/chat/NetlifyDeploymentLink.client.tsx +51 -0
- tools/bolt.diy/app/components/chat/ProgressCompilation.tsx +110 -0
- tools/bolt.diy/app/components/chat/ScreenshotStateManager.tsx +33 -0
- tools/bolt.diy/app/components/chat/SendButton.client.tsx +39 -0
- tools/bolt.diy/app/components/chat/SpeechRecognition.tsx +28 -0
- tools/bolt.diy/app/components/chat/StarterTemplates.tsx +38 -0
- tools/bolt.diy/app/components/chat/SupabaseAlert.tsx +199 -0
- tools/bolt.diy/app/components/chat/SupabaseConnection.tsx +339 -0
- tools/bolt.diy/app/components/chat/ThoughtBox.tsx +43 -0
- tools/bolt.diy/app/components/chat/ToolInvocations.tsx +409 -0
- tools/bolt.diy/app/components/chat/UserMessage.tsx +101 -0
- tools/bolt.diy/app/components/chat/VercelDeploymentLink.client.tsx +158 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ExportChatButton.tsx +49 -0
- tools/bolt.diy/app/components/chat/chatExportAndImport/ImportButtons.tsx +96 -0
- tools/bolt.diy/app/components/deploy/DeployAlert.tsx +197 -0
- tools/bolt.diy/app/components/deploy/DeployButton.tsx +277 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitHubDeploymentDialog.tsx +1041 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploy.client.tsx +171 -0
- tools/bolt.diy/app/components/deploy/GitLabDeploymentDialog.tsx +764 -0
- tools/bolt.diy/app/components/deploy/NetlifyDeploy.client.tsx +246 -0
- tools/bolt.diy/app/components/deploy/VercelDeploy.client.tsx +235 -0
- tools/bolt.diy/app/components/editor/codemirror/BinaryContent.tsx +7 -0
- tools/bolt.diy/app/components/editor/codemirror/CodeMirrorEditor.tsx +555 -0
- tools/bolt.diy/app/components/editor/codemirror/EnvMasking.ts +80 -0
- tools/bolt.diy/app/components/editor/codemirror/cm-theme.ts +192 -0
- tools/bolt.diy/app/components/editor/codemirror/indent.ts +68 -0
- tools/bolt.diy/app/components/editor/codemirror/languages.ts +112 -0
- tools/bolt.diy/app/components/git/GitUrlImport.client.tsx +147 -0
- tools/bolt.diy/app/components/header/Header.tsx +42 -0
- tools/bolt.diy/app/components/header/HeaderActionButtons.client.tsx +54 -0
- tools/bolt.diy/app/components/mandate/MandateSubmission.tsx +167 -0
- tools/bolt.diy/app/components/observability/DeploymentStatus.tsx +168 -0
- tools/bolt.diy/app/components/observability/EventTimeline.tsx +119 -0
- tools/bolt.diy/app/components/observability/FileDiffViewer.tsx +121 -0
- tools/bolt.diy/app/components/observability/GovernanceStatus.tsx +197 -0
- tools/bolt.diy/app/components/observability/GovernorMetrics.tsx +246 -0
- tools/bolt.diy/app/components/observability/LogStream.tsx +244 -0
- tools/bolt.diy/app/components/observability/MandateDetails.tsx +201 -0
- tools/bolt.diy/app/components/observability/ObservabilityDashboard.tsx +200 -0
- tools/bolt.diy/app/components/sidebar/HistoryItem.tsx +187 -0
- tools/bolt.diy/app/components/sidebar/Menu.client.tsx +536 -0
- tools/bolt.diy/app/components/sidebar/date-binning.ts +59 -0
- tools/bolt.diy/app/components/txt +1 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/index.tsx +18 -0
- tools/bolt.diy/app/components/ui/BackgroundRays/styles.module.scss +246 -0
- tools/bolt.diy/app/components/ui/Badge.tsx +53 -0
- tools/bolt.diy/app/components/ui/BranchSelector.tsx +270 -0
- tools/bolt.diy/app/components/ui/Breadcrumbs.tsx +101 -0
- tools/bolt.diy/app/components/ui/Button.tsx +46 -0
- tools/bolt.diy/app/components/ui/Card.tsx +55 -0
- tools/bolt.diy/app/components/ui/Checkbox.tsx +32 -0
- tools/bolt.diy/app/components/ui/CloseButton.tsx +49 -0
- tools/bolt.diy/app/components/ui/CodeBlock.tsx +103 -0
- tools/bolt.diy/app/components/ui/Collapsible.tsx +9 -0
- tools/bolt.diy/app/components/ui/ColorSchemeDialog.tsx +378 -0
- tools/bolt.diy/app/components/ui/Dialog.tsx +449 -0
- tools/bolt.diy/app/components/ui/Dropdown.tsx +63 -0
- tools/bolt.diy/app/components/ui/EmptyState.tsx +154 -0
- tools/bolt.diy/app/components/ui/FileIcon.tsx +346 -0
- tools/bolt.diy/app/components/ui/FilterChip.tsx +92 -0
- tools/bolt.diy/app/components/ui/GlowingEffect.tsx +192 -0
- tools/bolt.diy/app/components/ui/GradientCard.tsx +100 -0
- tools/bolt.diy/app/components/ui/IconButton.tsx +84 -0
- tools/bolt.diy/app/components/ui/Input.tsx +22 -0
- tools/bolt.diy/app/components/ui/Label.tsx +20 -0
- tools/bolt.diy/app/components/ui/LoadingDots.tsx +27 -0
- tools/bolt.diy/app/components/ui/LoadingOverlay.tsx +32 -0
- tools/bolt.diy/app/components/ui/PanelHeader.tsx +20 -0
- tools/bolt.diy/app/components/ui/PanelHeaderButton.tsx +36 -0
- tools/bolt.diy/app/components/ui/Popover.tsx +29 -0
- tools/bolt.diy/app/components/ui/Progress.tsx +22 -0
- tools/bolt.diy/app/components/ui/RepositoryStats.tsx +87 -0
- tools/bolt.diy/app/components/ui/ScrollArea.tsx +41 -0
- tools/bolt.diy/app/components/ui/SearchInput.tsx +80 -0
- tools/bolt.diy/app/components/ui/SearchResultItem.tsx +134 -0
- tools/bolt.diy/app/components/ui/Separator.tsx +22 -0
- tools/bolt.diy/app/components/ui/SettingsButton.tsx +35 -0
- tools/bolt.diy/app/components/ui/Slider.tsx +73 -0
- tools/bolt.diy/app/components/ui/StatusIndicator.tsx +90 -0
- tools/bolt.diy/app/components/ui/Switch.tsx +37 -0
- tools/bolt.diy/app/components/ui/Tabs.tsx +52 -0
- tools/bolt.diy/app/components/ui/TabsWithSlider.tsx +112 -0
- tools/bolt.diy/app/components/ui/ThemeSwitch.tsx +29 -0
- tools/bolt.diy/app/components/ui/Tooltip.tsx +122 -0
- tools/bolt.diy/app/components/ui/index.ts +38 -0
- tools/bolt.diy/app/components/ui/use-toast.ts +66 -0
- tools/bolt.diy/app/components/workbench/DiffView.tsx +796 -0
- tools/bolt.diy/app/components/workbench/EditorPanel.tsx +174 -0
- tools/bolt.diy/app/components/workbench/ExpoQrModal.tsx +55 -0
- tools/bolt.diy/app/components/workbench/FileBreadcrumb.tsx +150 -0
- tools/bolt.diy/app/components/workbench/FileTree.tsx +565 -0
- tools/bolt.diy/app/components/workbench/Inspector.tsx +126 -0
- tools/bolt.diy/app/components/workbench/InspectorPanel.tsx +146 -0
- tools/bolt.diy/app/components/workbench/LockManager.tsx +262 -0
- tools/bolt.diy/app/components/workbench/PortDropdown.tsx +91 -0
- tools/bolt.diy/app/components/workbench/Preview.tsx +1049 -0
- tools/bolt.diy/app/components/workbench/ScreenshotSelector.tsx +293 -0
- tools/bolt.diy/app/components/workbench/Search.tsx +257 -0
- tools/bolt.diy/app/components/workbench/Workbench.client.tsx +506 -0
- tools/bolt.diy/app/components/workbench/terminal/Terminal.tsx +131 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalManager.tsx +68 -0
- tools/bolt.diy/app/components/workbench/terminal/TerminalTabs.tsx +277 -0
- tools/bolt.diy/app/components/workbench/terminal/theme.ts +36 -0
- tools/bolt.diy/app/components/workflow/WorkflowPhase.tsx +109 -0
- tools/bolt.diy/app/components/workflow/WorkflowStatus.tsx +60 -0
- tools/bolt.diy/app/components/workflow/WorkflowTimeline.tsx +150 -0
- tools/bolt.diy/app/entry.client.tsx +7 -0
- tools/bolt.diy/app/entry.server.tsx +80 -0
- tools/bolt.diy/app/root.tsx +156 -0
- tools/bolt.diy/app/routes/_index.tsx +175 -0
- tools/bolt.diy/app/routes/api.bug-report.ts +254 -0
- tools/bolt.diy/app/routes/api.chat.ts +463 -0
- tools/bolt.diy/app/routes/api.check-env-key.ts +41 -0
- tools/bolt.diy/app/routes/api.configured-providers.ts +110 -0
- tools/bolt.diy/app/routes/api.corporate-swarm-status.ts +55 -0
- tools/bolt.diy/app/routes/api.enhancer.ts +137 -0
- tools/bolt.diy/app/routes/api.export-api-keys.ts +44 -0
- tools/bolt.diy/app/routes/api.git-info.ts +69 -0
- tools/bolt.diy/app/routes/api.git-proxy.$.ts +178 -0
- tools/bolt.diy/app/routes/api.github-branches.ts +166 -0
- tools/bolt.diy/app/routes/api.github-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.github-stats.ts +198 -0
- tools/bolt.diy/app/routes/api.github-template.ts +242 -0
- tools/bolt.diy/app/routes/api.github-user.ts +287 -0
- tools/bolt.diy/app/routes/api.gitlab-branches.ts +143 -0
- tools/bolt.diy/app/routes/api.gitlab-deploy.ts +67 -0
- tools/bolt.diy/app/routes/api.gitlab-projects.ts +105 -0
- tools/bolt.diy/app/routes/api.health.ts +8 -0
- tools/bolt.diy/app/routes/api.llmcall.ts +298 -0
- tools/bolt.diy/app/routes/api.mandate.ts +351 -0
- tools/bolt.diy/app/routes/api.mcp-check.ts +16 -0
- tools/bolt.diy/app/routes/api.mcp-update-config.ts +23 -0
- tools/bolt.diy/app/routes/api.models.$provider.ts +2 -0
- tools/bolt.diy/app/routes/api.models.ts +90 -0
- tools/bolt.diy/app/routes/api.netlify-deploy.ts +240 -0
- tools/bolt.diy/app/routes/api.netlify-user.ts +142 -0
- tools/bolt.diy/app/routes/api.supabase-user.ts +199 -0
- tools/bolt.diy/app/routes/api.supabase.query.ts +92 -0
- tools/bolt.diy/app/routes/api.supabase.ts +56 -0
- tools/bolt.diy/app/routes/api.supabase.variables.ts +32 -0
- tools/bolt.diy/app/routes/api.system.diagnostics.ts +142 -0
- tools/bolt.diy/app/routes/api.system.disk-info.ts +311 -0
- tools/bolt.diy/app/routes/api.system.git-info.ts +332 -0
- tools/bolt.diy/app/routes/api.update.ts +21 -0
- tools/bolt.diy/app/routes/api.vercel-deploy.ts +497 -0
- tools/bolt.diy/app/routes/api.vercel-user.ts +161 -0
- tools/bolt.diy/app/routes/api.workflow-status.$proposalId.ts +309 -0
- tools/bolt.diy/app/routes/chat.$id.tsx +8 -0
- tools/bolt.diy/app/routes/execute.$mandateId.tsx +432 -0
- tools/bolt.diy/app/routes/git.tsx +25 -0
- tools/bolt.diy/app/routes/observability.$mandateId.tsx +50 -0
- tools/bolt.diy/app/routes/webcontainer.connect.$id.tsx +32 -0
- tools/bolt.diy/app/routes/webcontainer.preview.$id.tsx +97 -0
- tools/bolt.diy/app/routes/workflow.$proposalId.tsx +170 -0
- tools/bolt.diy/app/styles/animations.scss +49 -0
- tools/bolt.diy/app/styles/components/code.scss +9 -0
- tools/bolt.diy/app/styles/components/editor.scss +135 -0
- tools/bolt.diy/app/styles/components/resize-handle.scss +30 -0
- tools/bolt.diy/app/styles/components/terminal.scss +3 -0
- tools/bolt.diy/app/styles/components/toast.scss +23 -0
- tools/bolt.diy/app/styles/diff-view.css +72 -0
- tools/bolt.diy/app/styles/index.scss +73 -0
- tools/bolt.diy/app/styles/variables.scss +255 -0
- tools/bolt.diy/app/styles/z-index.scss +37 -0
- tools/bolt.diy/app/types/GitHub.ts +182 -0
- tools/bolt.diy/app/types/GitLab.ts +103 -0
- tools/bolt.diy/app/types/actions.ts +85 -0
- tools/bolt.diy/app/types/artifact.ts +5 -0
- tools/bolt.diy/app/types/context.ts +26 -0
- tools/bolt.diy/app/types/design-scheme.ts +93 -0
- tools/bolt.diy/app/types/global.d.ts +13 -0
- tools/bolt.diy/app/types/mandate.ts +333 -0
- tools/bolt.diy/app/types/model.ts +25 -0
- tools/bolt.diy/app/types/netlify.ts +94 -0
- tools/bolt.diy/app/types/supabase.ts +54 -0
- tools/bolt.diy/app/types/template.ts +8 -0
- tools/bolt.diy/app/types/terminal.ts +9 -0
- tools/bolt.diy/app/types/theme.ts +1 -0
- tools/bolt.diy/app/types/vercel.ts +67 -0
- tools/bolt.diy/app/utils/buffer.ts +29 -0
- tools/bolt.diy/app/utils/classNames.ts +65 -0
- tools/bolt.diy/app/utils/constants.ts +147 -0
- tools/bolt.diy/app/utils/debounce.ts +13 -0
- tools/bolt.diy/app/utils/debugLogger.ts +1284 -0
- tools/bolt.diy/app/utils/diff.spec.ts +11 -0
- tools/bolt.diy/app/utils/diff.ts +117 -0
- tools/bolt.diy/app/utils/easings.ts +3 -0
- tools/bolt.diy/app/utils/fileLocks.ts +96 -0
- tools/bolt.diy/app/utils/fileUtils.ts +121 -0
- tools/bolt.diy/app/utils/folderImport.ts +73 -0
- tools/bolt.diy/app/utils/formatSize.ts +12 -0
- tools/bolt.diy/app/utils/getLanguageFromExtension.ts +24 -0
- tools/bolt.diy/app/utils/githubStats.ts +9 -0
- tools/bolt.diy/app/utils/gitlabStats.ts +54 -0
- tools/bolt.diy/app/utils/logger.ts +162 -0
- tools/bolt.diy/app/utils/markdown.ts +155 -0
- tools/bolt.diy/app/utils/mobile.ts +4 -0
- tools/bolt.diy/app/utils/os.ts +4 -0
- tools/bolt.diy/app/utils/path.ts +19 -0
- tools/bolt.diy/app/utils/projectCommands.ts +197 -0
- tools/bolt.diy/app/utils/promises.ts +19 -0
- tools/bolt.diy/app/utils/react.ts +6 -0
- tools/bolt.diy/app/utils/sampler.ts +49 -0
- tools/bolt.diy/app/utils/selectStarterTemplate.ts +255 -0
- tools/bolt.diy/app/utils/shell.ts +384 -0
- tools/bolt.diy/app/utils/stacktrace.ts +27 -0
- tools/bolt.diy/app/utils/stripIndent.ts +23 -0
- tools/bolt.diy/app/utils/terminal.ts +11 -0
- tools/bolt.diy/app/utils/unreachable.ts +3 -0
- tools/bolt.diy/app/vite-env.d.ts +2 -0
- tools/bolt.diy/assets/entitlements.mac.plist +25 -0
- tools/bolt.diy/assets/icons/icon.icns +0 -0
- tools/bolt.diy/assets/icons/icon.ico +0 -0
- tools/bolt.diy/assets/icons/icon.png +0 -0
- tools/bolt.diy/bindings.js +78 -0
- tools/bolt.diy/bindings.sh +33 -0
- tools/bolt.diy/docker-compose.yaml +145 -0
- tools/bolt.diy/electron/main/index.ts +201 -0
- tools/bolt.diy/electron/main/tsconfig.json +30 -0
- tools/bolt.diy/electron/main/ui/menu.ts +29 -0
- tools/bolt.diy/electron/main/ui/window.ts +54 -0
- tools/bolt.diy/electron/main/utils/auto-update.ts +110 -0
- tools/bolt.diy/electron/main/utils/constants.ts +4 -0
- tools/bolt.diy/electron/main/utils/cookie.ts +40 -0
- tools/bolt.diy/electron/main/utils/reload.ts +35 -0
- tools/bolt.diy/electron/main/utils/serve.ts +71 -0
- tools/bolt.diy/electron/main/utils/store.ts +3 -0
- tools/bolt.diy/electron/main/utils/vite-server.ts +44 -0
- tools/bolt.diy/electron/main/vite.config.ts +44 -0
- tools/bolt.diy/electron/preload/index.ts +22 -0
- tools/bolt.diy/electron/preload/tsconfig.json +7 -0
- tools/bolt.diy/electron/preload/vite.config.ts +31 -0
- tools/bolt.diy/electron-builder.yml +64 -0
- tools/bolt.diy/electron-update.yml +4 -0
- tools/bolt.diy/eslint.config.mjs +57 -0
- tools/bolt.diy/functions/[[path]].ts +12 -0
- tools/bolt.diy/icons/angular.svg +1 -0
- tools/bolt.diy/icons/astro.svg +8 -0
- tools/bolt.diy/icons/chat.svg +1 -0
- tools/bolt.diy/icons/expo-brand.svg +1 -0
- tools/bolt.diy/icons/expo.svg +4 -0
- tools/bolt.diy/icons/logo-text.svg +1 -0
- tools/bolt.diy/icons/logo.svg +4 -0
- tools/bolt.diy/icons/mcp.svg +1 -0
- tools/bolt.diy/icons/nativescript.svg +1 -0
- tools/bolt.diy/icons/netlify.svg +10 -0
- tools/bolt.diy/icons/nextjs.svg +1 -0
- tools/bolt.diy/icons/nuxt.svg +1 -0
- tools/bolt.diy/icons/qwik.svg +1 -0
- tools/bolt.diy/icons/react.svg +1 -0
- tools/bolt.diy/icons/remix.svg +24 -0
- tools/bolt.diy/icons/remotion.svg +1 -0
- tools/bolt.diy/icons/shadcn.svg +21 -0
- tools/bolt.diy/icons/slidev.svg +60 -0
- tools/bolt.diy/icons/solidjs.svg +1 -0
- tools/bolt.diy/icons/stars.svg +1 -0
- tools/bolt.diy/icons/svelte.svg +1 -0
- tools/bolt.diy/icons/typescript.svg +1 -0
- tools/bolt.diy/icons/vite.svg +1 -0
- tools/bolt.diy/icons/vue.svg +1 -0
- tools/bolt.diy/load-context.ts +9 -0
- tools/bolt.diy/notarize.cjs +31 -0
- tools/bolt.diy/package.json +218 -0
- tools/bolt.diy/playwright.config.preview.ts +35 -0
- tools/bolt.diy/pre-start.cjs +26 -0
- tools/bolt.diy/public/apple-touch-icon-precomposed.png +0 -0
- tools/bolt.diy/public/apple-touch-icon.png +0 -0
- tools/bolt.diy/public/favicon.ico +0 -0
- tools/bolt.diy/public/favicon.svg +4 -0
- tools/bolt.diy/public/icons/AmazonBedrock.svg +1 -0
- tools/bolt.diy/public/icons/Anthropic.svg +4 -0
- tools/bolt.diy/public/icons/Cohere.svg +4 -0
- tools/bolt.diy/public/icons/Deepseek.svg +5 -0
- tools/bolt.diy/public/icons/Default.svg +4 -0
- tools/bolt.diy/public/icons/Google.svg +4 -0
- tools/bolt.diy/public/icons/Groq.svg +4 -0
- tools/bolt.diy/public/icons/HuggingFace.svg +4 -0
- tools/bolt.diy/public/icons/Hyperbolic.svg +3 -0
- tools/bolt.diy/public/icons/LMStudio.svg +5 -0
- tools/bolt.diy/public/icons/Mistral.svg +4 -0
- tools/bolt.diy/public/icons/Ollama.svg +4 -0
- tools/bolt.diy/public/icons/OpenAI.svg +4 -0
- tools/bolt.diy/public/icons/OpenAILike.svg +4 -0
- tools/bolt.diy/public/icons/OpenRouter.svg +4 -0
- tools/bolt.diy/public/icons/Perplexity.svg +4 -0
- tools/bolt.diy/public/icons/Together.svg +4 -0
- tools/bolt.diy/public/icons/xAI.svg +5 -0
- tools/bolt.diy/public/inspector-script.js +292 -0
- tools/bolt.diy/public/logo-dark-styled.png +0 -0
- tools/bolt.diy/public/logo-dark.png +0 -0
- tools/bolt.diy/public/logo-light-styled.png +0 -0
- tools/bolt.diy/public/logo-light.png +0 -0
- tools/bolt.diy/public/logo.svg +15 -0
- tools/bolt.diy/public/social_preview_index.jpg +0 -0
- tools/bolt.diy/scripts/clean.js +45 -0
- tools/bolt.diy/scripts/electron-dev.mjs +181 -0
- tools/bolt.diy/scripts/setup-env.sh +41 -0
- tools/bolt.diy/scripts/update-imports.sh +7 -0
- tools/bolt.diy/scripts/update.sh +52 -0
- tools/bolt.diy/services/execution-governor/Dockerfile +41 -0
- tools/bolt.diy/services/execution-governor/config.ts +42 -0
- tools/bolt.diy/services/execution-governor/index.ts +683 -0
- tools/bolt.diy/services/execution-governor/metrics.ts +141 -0
- tools/bolt.diy/services/execution-governor/package.json +31 -0
- tools/bolt.diy/services/execution-governor/priority-queue.ts +139 -0
- tools/bolt.diy/services/execution-governor/tsconfig.json +21 -0
- tools/bolt.diy/services/execution-governor/types.ts +145 -0
- tools/bolt.diy/services/headless-executor/Dockerfile +43 -0
- tools/bolt.diy/services/headless-executor/executor.ts +210 -0
- tools/bolt.diy/services/headless-executor/index.ts +323 -0
- tools/bolt.diy/services/headless-executor/package.json +27 -0
- tools/bolt.diy/services/headless-executor/tsconfig.json +21 -0
- tools/bolt.diy/services/headless-executor/types.ts +38 -0
- tools/bolt.diy/test-workflows.sh +240 -0
- tools/bolt.diy/tests/integration/corporate-swarm.test.ts +208 -0
- tools/bolt.diy/tests/mandates/budget-limited.json +34 -0
- tools/bolt.diy/tests/mandates/complex.json +53 -0
- tools/bolt.diy/tests/mandates/constraint-enforced.json +36 -0
- tools/bolt.diy/tests/mandates/simple.json +35 -0
- tools/bolt.diy/tsconfig.json +37 -0
- tools/bolt.diy/types/istextorbinary.d.ts +15 -0
- tools/bolt.diy/uno.config.ts +279 -0
- tools/bolt.diy/vite-electron.config.ts +76 -0
- tools/bolt.diy/vite.config.ts +112 -0
- tools/bolt.diy/worker-configuration.d.ts +22 -0
- tools/bolt.diy/wrangler.toml +6 -0
- tools/code_generator.py +461 -0
- tools/file_operations.py +465 -0
- tools/mandate_generator.py +337 -0
- tools/mcpClientUtils.py +1216 -0
- tools/sensors.py +285 -0
- utils/Agent_types.py +15 -0
- utils/AnyToStr.py +0 -0
- utils/HHCS.py +277 -0
- utils/__init__.py +30 -0
- utils/agent.py +3627 -0
- utils/aop.py +2948 -0
- utils/canonical.py +143 -0
- utils/conversation.py +1195 -0
- utils/doctrine_versioning +230 -0
- utils/formatter.py +474 -0
- utils/ledger.py +311 -0
- utils/out_types.py +16 -0
- utils/rollback.py +339 -0
- utils/router.py +929 -0
- utils/tui.py +1908 -0
|
@@ -0,0 +1,773 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Comprehensive test suite for CorporateSwarm system.
|
|
4
|
+
|
|
5
|
+
Tests all major features including:
|
|
6
|
+
- Corporation creation and initialization
|
|
7
|
+
- Member management
|
|
8
|
+
- Proposal creation and voting
|
|
9
|
+
- Task generation and evaluation
|
|
10
|
+
- Mandate execution (with forced mandate submission)
|
|
11
|
+
- Deployment features
|
|
12
|
+
- Testing features
|
|
13
|
+
- I/O operations
|
|
14
|
+
- Governance and compliance
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import sys
|
|
18
|
+
import os
|
|
19
|
+
import time
|
|
20
|
+
import requests
|
|
21
|
+
from typing import Dict, Any, List, Optional
|
|
22
|
+
|
|
23
|
+
# Add current directory to path
|
|
24
|
+
sys.path.insert(0, os.path.dirname(__file__))
|
|
25
|
+
|
|
26
|
+
from corposwarm import (
|
|
27
|
+
create_corporation,
|
|
28
|
+
CorporateSwarm,
|
|
29
|
+
CorporateRole,
|
|
30
|
+
DepartmentType,
|
|
31
|
+
ProposalType,
|
|
32
|
+
VoteResult
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def check_bolt_diy_health(url: str = "http://localhost:5173", timeout: int = 5) -> bool:
|
|
37
|
+
"""
|
|
38
|
+
Check if bolt.diy is running and reachable.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
url: bolt.diy API URL
|
|
42
|
+
timeout: Request timeout in seconds
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
bool: True if bolt.diy is reachable, False otherwise
|
|
46
|
+
"""
|
|
47
|
+
try:
|
|
48
|
+
health_url = url.rstrip('/') + "/api/health"
|
|
49
|
+
response = requests.get(health_url, timeout=timeout)
|
|
50
|
+
if response.status_code == 200:
|
|
51
|
+
try:
|
|
52
|
+
data = response.json()
|
|
53
|
+
if data.get("status") == "healthy":
|
|
54
|
+
return True
|
|
55
|
+
except (ValueError, KeyError):
|
|
56
|
+
# Response is not JSON or missing status field, but 200 OK - still ready
|
|
57
|
+
pass
|
|
58
|
+
return True # Any 200 response means the server is ready
|
|
59
|
+
return False
|
|
60
|
+
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
|
|
61
|
+
return False
|
|
62
|
+
except Exception:
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def ensure_bolt_diy_ready(url: str = "http://localhost:5173", max_wait: int = 60) -> bool:
|
|
67
|
+
"""
|
|
68
|
+
Ensure bolt.diy is ready, waiting up to max_wait seconds.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
url: bolt.diy API URL
|
|
72
|
+
max_wait: Maximum time to wait in seconds
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
bool: True if bolt.diy is ready, False otherwise
|
|
76
|
+
"""
|
|
77
|
+
start_time = time.time()
|
|
78
|
+
check_interval = 2 # Check every 2 seconds
|
|
79
|
+
|
|
80
|
+
while time.time() - start_time < max_wait:
|
|
81
|
+
if check_bolt_diy_health(url):
|
|
82
|
+
return True
|
|
83
|
+
time.sleep(check_interval)
|
|
84
|
+
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class TestCorporationCreation:
|
|
89
|
+
"""Test corporation creation and initialization."""
|
|
90
|
+
|
|
91
|
+
def test_create_simple_corporation(self):
|
|
92
|
+
"""Test creating a simple corporation."""
|
|
93
|
+
corp = create_corporation(
|
|
94
|
+
name="TestCorp",
|
|
95
|
+
verbose=False,
|
|
96
|
+
budget_limit=100.0
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
assert corp is not None
|
|
100
|
+
assert corp.name == "TestCorp"
|
|
101
|
+
assert len(corp.board_members) > 0
|
|
102
|
+
assert len(corp.executive_team) > 0
|
|
103
|
+
assert len(corp.members) > 0
|
|
104
|
+
assert corp.cost_tracker.budget_limit == 100.0
|
|
105
|
+
|
|
106
|
+
print("[PASS] Corporation creation test passed")
|
|
107
|
+
|
|
108
|
+
def test_corporation_with_custom_config(self):
|
|
109
|
+
"""Test creating corporation with custom configuration."""
|
|
110
|
+
corp = create_corporation(
|
|
111
|
+
name="CustomCorp",
|
|
112
|
+
model_name="gpt-4o-mini",
|
|
113
|
+
budget_limit=200.0,
|
|
114
|
+
enable_causal_reasoning=True,
|
|
115
|
+
enable_quant_analysis=True,
|
|
116
|
+
verbose=False
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
assert corp.corporate_model_name == "gpt-4o-mini"
|
|
120
|
+
assert corp.config.enable_causal_reasoning is True
|
|
121
|
+
assert corp.config.enable_quant_analysis is True
|
|
122
|
+
|
|
123
|
+
print("[PASS] Custom configuration test passed")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class TestMemberManagement:
|
|
127
|
+
"""Test member management features."""
|
|
128
|
+
|
|
129
|
+
def test_add_member(self):
|
|
130
|
+
"""Test adding a new member."""
|
|
131
|
+
corp = create_corporation(
|
|
132
|
+
name="MemberTestCorp",
|
|
133
|
+
verbose=False,
|
|
134
|
+
budget_limit=100.0
|
|
135
|
+
)
|
|
136
|
+
"""Test adding a new member."""
|
|
137
|
+
initial_count = len(corp.members)
|
|
138
|
+
|
|
139
|
+
member_id = corp.add_member(
|
|
140
|
+
name="Test Member",
|
|
141
|
+
role=CorporateRole.EMPLOYEE,
|
|
142
|
+
department=DepartmentType.TECHNOLOGY,
|
|
143
|
+
expertise_areas=["Python", "Testing"],
|
|
144
|
+
voting_weight=1.0
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
assert member_id is not None
|
|
148
|
+
assert len(corp.members) == initial_count + 1
|
|
149
|
+
assert member_id in corp.members
|
|
150
|
+
assert corp.members[member_id].name == "Test Member"
|
|
151
|
+
|
|
152
|
+
print("[PASS] Add member test passed")
|
|
153
|
+
|
|
154
|
+
def test_add_executive(self):
|
|
155
|
+
"""Test adding an executive team member."""
|
|
156
|
+
corp = create_corporation(
|
|
157
|
+
name="MemberTestCorp",
|
|
158
|
+
verbose=False,
|
|
159
|
+
budget_limit=100.0
|
|
160
|
+
)
|
|
161
|
+
member_id = corp.add_member(
|
|
162
|
+
name="Test CEO",
|
|
163
|
+
role=CorporateRole.CEO,
|
|
164
|
+
department=DepartmentType.OPERATIONS,
|
|
165
|
+
expertise_areas=["Strategy", "Leadership"],
|
|
166
|
+
voting_weight=2.0
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
assert member_id in corp.executive_team
|
|
170
|
+
assert corp.members[member_id].voting_weight == 2.0
|
|
171
|
+
|
|
172
|
+
print("[PASS] Add executive test passed")
|
|
173
|
+
|
|
174
|
+
def test_add_board_member(self):
|
|
175
|
+
"""Test adding a board member."""
|
|
176
|
+
corp = create_corporation(
|
|
177
|
+
name="MemberTestCorp",
|
|
178
|
+
verbose=False,
|
|
179
|
+
budget_limit=100.0
|
|
180
|
+
)
|
|
181
|
+
member_id = corp.add_member(
|
|
182
|
+
name="Test Board Member",
|
|
183
|
+
role=CorporateRole.BOARD_MEMBER,
|
|
184
|
+
department=DepartmentType.OPERATIONS,
|
|
185
|
+
expertise_areas=["Governance"],
|
|
186
|
+
voting_weight=1.5
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
assert member_id in corp.board_members
|
|
190
|
+
assert corp.members[member_id].role == CorporateRole.BOARD_MEMBER
|
|
191
|
+
|
|
192
|
+
print("[PASS] Add board member test passed")
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class TestProposalAndVoting:
|
|
196
|
+
"""Test proposal creation and voting."""
|
|
197
|
+
|
|
198
|
+
def test_create_proposal(self):
|
|
199
|
+
"""Test creating a proposal."""
|
|
200
|
+
corp = create_corporation(
|
|
201
|
+
name="VoteTestCorp",
|
|
202
|
+
verbose=False,
|
|
203
|
+
budget_limit=100.0
|
|
204
|
+
)
|
|
205
|
+
"""Test creating a proposal."""
|
|
206
|
+
sponsor_id = corp.executive_team[0] if corp.executive_team else corp.board_members[0]
|
|
207
|
+
|
|
208
|
+
proposal_id = corp.create_proposal(
|
|
209
|
+
title="Test Proposal",
|
|
210
|
+
description="This is a test proposal for revenue generation",
|
|
211
|
+
proposal_type=ProposalType.STRATEGIC_INITIATIVE,
|
|
212
|
+
sponsor_id=sponsor_id,
|
|
213
|
+
department=DepartmentType.OPERATIONS,
|
|
214
|
+
budget_impact=10.0,
|
|
215
|
+
timeline="1 week"
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
assert proposal_id is not None
|
|
219
|
+
proposal = corp._find_proposal(proposal_id)
|
|
220
|
+
assert proposal.title == "Test Proposal"
|
|
221
|
+
assert proposal.budget_impact == 10.0
|
|
222
|
+
|
|
223
|
+
print("[PASS] Create proposal test passed")
|
|
224
|
+
|
|
225
|
+
def test_conduct_vote(self):
|
|
226
|
+
"""Test conducting a vote on a proposal."""
|
|
227
|
+
corp = create_corporation(
|
|
228
|
+
name="VoteTestCorp",
|
|
229
|
+
verbose=False,
|
|
230
|
+
budget_limit=100.0
|
|
231
|
+
)
|
|
232
|
+
sponsor_id = corp.executive_team[0] if corp.executive_team else corp.board_members[0]
|
|
233
|
+
|
|
234
|
+
proposal_id = corp.create_proposal(
|
|
235
|
+
title="Revenue Proposal",
|
|
236
|
+
description="Generate revenue through aggressive marketing campaign",
|
|
237
|
+
proposal_type=ProposalType.STRATEGIC_INITIATIVE,
|
|
238
|
+
sponsor_id=sponsor_id,
|
|
239
|
+
department=DepartmentType.OPERATIONS,
|
|
240
|
+
budget_impact=5.0
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
vote = corp.conduct_corporate_vote(proposal_id)
|
|
244
|
+
|
|
245
|
+
assert vote is not None
|
|
246
|
+
assert vote.proposal.proposal_id == proposal_id
|
|
247
|
+
assert vote.result in [VoteResult.APPROVED, VoteResult.REJECTED, VoteResult.TABLED, VoteResult.FAILED]
|
|
248
|
+
assert len(vote.participants) > 0
|
|
249
|
+
|
|
250
|
+
print(f"[PASS] Conduct vote test passed (Result: {vote.result.value})")
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class TestTaskGeneration:
|
|
254
|
+
"""Test automatic task generation."""
|
|
255
|
+
|
|
256
|
+
def test_generate_tasks(self):
|
|
257
|
+
"""Test automatic task generation."""
|
|
258
|
+
corp = create_corporation(
|
|
259
|
+
name="TaskGenCorp",
|
|
260
|
+
verbose=False,
|
|
261
|
+
budget_limit=100.0
|
|
262
|
+
)
|
|
263
|
+
"""Test automatic task generation."""
|
|
264
|
+
tasks = corp.generate_tasks_automatically(max_tasks=5)
|
|
265
|
+
|
|
266
|
+
assert isinstance(tasks, list)
|
|
267
|
+
assert len(tasks) > 0
|
|
268
|
+
assert all(isinstance(task, str) for task in tasks)
|
|
269
|
+
|
|
270
|
+
print(f"[PASS] Generated {len(tasks)} tasks:")
|
|
271
|
+
for i, task in enumerate(tasks[:3], 1):
|
|
272
|
+
print(f" {i}. {task[:60]}...")
|
|
273
|
+
|
|
274
|
+
def test_evaluate_task(self):
|
|
275
|
+
"""Test task evaluation with CRCA."""
|
|
276
|
+
corp = create_corporation(
|
|
277
|
+
name="TaskGenCorp",
|
|
278
|
+
verbose=False,
|
|
279
|
+
budget_limit=100.0
|
|
280
|
+
)
|
|
281
|
+
task = "Launch aggressive marketing campaign to increase revenue by 50%"
|
|
282
|
+
|
|
283
|
+
evaluation = corp.evaluate_task_with_crca(task)
|
|
284
|
+
|
|
285
|
+
assert evaluation is not None
|
|
286
|
+
assert "overall_score" in evaluation
|
|
287
|
+
assert "positive_outcomes" in evaluation
|
|
288
|
+
assert "negative_outcomes" in evaluation
|
|
289
|
+
assert isinstance(evaluation["overall_score"], (int, float))
|
|
290
|
+
|
|
291
|
+
print(f"[PASS] Task evaluation test passed (Score: {evaluation['overall_score']:.2f})")
|
|
292
|
+
|
|
293
|
+
def test_refine_task(self):
|
|
294
|
+
"""Test task refinement."""
|
|
295
|
+
corp = create_corporation(
|
|
296
|
+
name="TaskGenCorp",
|
|
297
|
+
verbose=False,
|
|
298
|
+
budget_limit=100.0
|
|
299
|
+
)
|
|
300
|
+
task = "Increase revenue through marketing"
|
|
301
|
+
issues = ["Budget concerns", "Timeline risks"]
|
|
302
|
+
|
|
303
|
+
refined = corp.refine_task_with_llm(task, issues)
|
|
304
|
+
|
|
305
|
+
assert isinstance(refined, str)
|
|
306
|
+
assert len(refined) > 0
|
|
307
|
+
|
|
308
|
+
print("[PASS] Task refinement test passed")
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
class TestMandateExecution:
|
|
312
|
+
"""Test mandate execution feature - FORCED MANDATE SUBMISSION."""
|
|
313
|
+
|
|
314
|
+
def test_create_mandate_proposal(self):
|
|
315
|
+
"""Test creating a proposal that will become a mandate."""
|
|
316
|
+
corp = create_corporation(
|
|
317
|
+
name="MandateTestCorp",
|
|
318
|
+
verbose=False,
|
|
319
|
+
budget_limit=200.0,
|
|
320
|
+
auto_deploy_enabled=False, # Disable auto-deploy for testing
|
|
321
|
+
auto_test_enabled=True
|
|
322
|
+
)
|
|
323
|
+
"""Test creating a proposal that will become a mandate."""
|
|
324
|
+
sponsor_id = corp.executive_team[0] if corp.executive_team else corp.board_members[0]
|
|
325
|
+
|
|
326
|
+
# Create a code-related proposal (will trigger mandate execution)
|
|
327
|
+
proposal_id = corp.create_proposal(
|
|
328
|
+
title="Build Simple Todo App",
|
|
329
|
+
description="Create a simple React todo application with add, delete, and complete functionality. This is a revenue-generating project.",
|
|
330
|
+
proposal_type=ProposalType.STRATEGIC_INITIATIVE,
|
|
331
|
+
sponsor_id=sponsor_id,
|
|
332
|
+
department=DepartmentType.TECHNOLOGY,
|
|
333
|
+
budget_impact=20.0,
|
|
334
|
+
timeline="2 days"
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
assert proposal_id is not None
|
|
338
|
+
print(f"[PASS] Created proposal: {proposal_id}")
|
|
339
|
+
|
|
340
|
+
return proposal_id
|
|
341
|
+
|
|
342
|
+
def test_force_mandate_execution(self):
|
|
343
|
+
"""FORCE mandate execution by creating and approving a code-related proposal."""
|
|
344
|
+
# Check bolt.diy health before mandate execution
|
|
345
|
+
bolt_diy_url = os.getenv("BOLT_DIY_API_URL", "http://localhost:5173")
|
|
346
|
+
print(f"Checking bolt.diy health at {bolt_diy_url}...")
|
|
347
|
+
|
|
348
|
+
if not check_bolt_diy_health(bolt_diy_url):
|
|
349
|
+
print(f"[WARN] bolt.diy not ready at {bolt_diy_url}, attempting to wait...")
|
|
350
|
+
if not ensure_bolt_diy_ready(bolt_diy_url, max_wait=30):
|
|
351
|
+
print(f"[SKIP] bolt.diy not available, skipping mandate execution test")
|
|
352
|
+
return
|
|
353
|
+
|
|
354
|
+
print(f"[INFO] bolt.diy is ready at {bolt_diy_url}")
|
|
355
|
+
|
|
356
|
+
corp = create_corporation(
|
|
357
|
+
name="MandateTestCorp",
|
|
358
|
+
verbose=False,
|
|
359
|
+
budget_limit=200.0,
|
|
360
|
+
auto_deploy_enabled=False,
|
|
361
|
+
auto_test_enabled=True
|
|
362
|
+
)
|
|
363
|
+
sponsor_id = corp.executive_team[0] if corp.executive_team else corp.board_members[0]
|
|
364
|
+
|
|
365
|
+
# Create a profit-focused code proposal
|
|
366
|
+
proposal_id = corp.create_proposal(
|
|
367
|
+
title="Build Revenue-Generating Landing Page",
|
|
368
|
+
description="Create a simple HTML/CSS/JS landing page for a SaaS product. Include pricing section, CTA buttons, and contact form. This will generate revenue through lead generation.",
|
|
369
|
+
proposal_type=ProposalType.STRATEGIC_INITIATIVE,
|
|
370
|
+
sponsor_id=sponsor_id,
|
|
371
|
+
department=DepartmentType.TECHNOLOGY,
|
|
372
|
+
budget_impact=15.0,
|
|
373
|
+
timeline="1 day"
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
proposal = corp._find_proposal(proposal_id)
|
|
377
|
+
assert proposal is not None
|
|
378
|
+
|
|
379
|
+
# Process proposal (this will make real HTTP calls to bolt.diy and open real browser windows)
|
|
380
|
+
result = corp._process_proposal_task(
|
|
381
|
+
f"Execute proposal {proposal_id}: Build Revenue-Generating Landing Page"
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
assert result is not None
|
|
385
|
+
assert "status" in result
|
|
386
|
+
assert "proposal_id" in result
|
|
387
|
+
|
|
388
|
+
print(f"[PASS] Mandate execution test passed (Status: {result.get('status')})")
|
|
389
|
+
print(f" Note: Browser windows should have opened automatically for mandate visibility")
|
|
390
|
+
|
|
391
|
+
def test_execute_code_mandate_direct(self):
|
|
392
|
+
"""Test direct mandate execution with a simple project."""
|
|
393
|
+
# Check bolt.diy health before mandate execution
|
|
394
|
+
bolt_diy_url = os.getenv("BOLT_DIY_API_URL", "http://localhost:5173")
|
|
395
|
+
print(f"Checking bolt.diy health at {bolt_diy_url}...")
|
|
396
|
+
|
|
397
|
+
if not check_bolt_diy_health(bolt_diy_url):
|
|
398
|
+
print(f"[WARN] bolt.diy not ready at {bolt_diy_url}, attempting to wait...")
|
|
399
|
+
if not ensure_bolt_diy_ready(bolt_diy_url, max_wait=30):
|
|
400
|
+
print(f"[SKIP] bolt.diy not available, skipping direct mandate execution test")
|
|
401
|
+
return
|
|
402
|
+
|
|
403
|
+
print(f"[INFO] bolt.diy is ready at {bolt_diy_url}")
|
|
404
|
+
|
|
405
|
+
corp = create_corporation(
|
|
406
|
+
name="MandateTestCorp",
|
|
407
|
+
verbose=False,
|
|
408
|
+
budget_limit=200.0
|
|
409
|
+
)
|
|
410
|
+
# Create a simple mandate for a todo app
|
|
411
|
+
mandate = {
|
|
412
|
+
"mandate_id": f"test-mandate-{int(time.time())}",
|
|
413
|
+
"objectives": [
|
|
414
|
+
"Create a simple HTML todo application",
|
|
415
|
+
"Add functionality to add, delete, and mark todos as complete",
|
|
416
|
+
"Style with basic CSS"
|
|
417
|
+
],
|
|
418
|
+
"constraints": {
|
|
419
|
+
"language": "html",
|
|
420
|
+
"maxDependencies": 0,
|
|
421
|
+
"no_frameworks": True
|
|
422
|
+
},
|
|
423
|
+
"budget": {
|
|
424
|
+
"token": 50000,
|
|
425
|
+
"time": 300,
|
|
426
|
+
"cost": 2.0
|
|
427
|
+
},
|
|
428
|
+
"deliverables": [
|
|
429
|
+
"index.html",
|
|
430
|
+
"style.css",
|
|
431
|
+
"script.js"
|
|
432
|
+
],
|
|
433
|
+
"governance": {
|
|
434
|
+
"proposal_id": "test-proposal-123"
|
|
435
|
+
},
|
|
436
|
+
"iteration_config": {
|
|
437
|
+
"max_iterations": 2,
|
|
438
|
+
"test_required": False
|
|
439
|
+
},
|
|
440
|
+
"deployment": {
|
|
441
|
+
"enabled": False,
|
|
442
|
+
"provider": "netlify",
|
|
443
|
+
"auto_deploy": False
|
|
444
|
+
},
|
|
445
|
+
"testing": {
|
|
446
|
+
"enabled": False,
|
|
447
|
+
"generate_tests": False,
|
|
448
|
+
"run_tests": False
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
# Execute mandate (this will make real HTTP calls to bolt.diy and open real browser windows)
|
|
453
|
+
result = corp.execute_code_mandate(mandate, proposal_id="test-proposal-123")
|
|
454
|
+
|
|
455
|
+
assert result is not None
|
|
456
|
+
assert "status" in result
|
|
457
|
+
assert result.get("status") in ["accepted", "completed", "failed"]
|
|
458
|
+
|
|
459
|
+
print(f"[PASS] Direct mandate execution test passed")
|
|
460
|
+
print(f" Mandate ID: {mandate['mandate_id']}")
|
|
461
|
+
print(f" Status: {result.get('status')}")
|
|
462
|
+
print(f" Note: Browser windows should have opened automatically for mandate visibility")
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
class TestDeploymentFeatures:
|
|
466
|
+
"""Test deployment features."""
|
|
467
|
+
|
|
468
|
+
def test_deploy_to_netlify(self):
|
|
469
|
+
"""Test Netlify deployment."""
|
|
470
|
+
corp = create_corporation(
|
|
471
|
+
name="DeployTestCorp",
|
|
472
|
+
verbose=False,
|
|
473
|
+
budget_limit=100.0
|
|
474
|
+
)
|
|
475
|
+
"""Test Netlify deployment."""
|
|
476
|
+
mandate_id = "test-mandate-123"
|
|
477
|
+
files = {
|
|
478
|
+
"index.html": "<html><body>Test</body></html>",
|
|
479
|
+
"style.css": "body { margin: 0; }"
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
# This will make real HTTP calls to Netlify (if configured)
|
|
483
|
+
result = corp._deploy_to_netlify(mandate_id, files, "http://localhost:5173")
|
|
484
|
+
|
|
485
|
+
assert result is not None
|
|
486
|
+
assert "status" in result
|
|
487
|
+
|
|
488
|
+
print("[PASS] Netlify deployment test passed")
|
|
489
|
+
|
|
490
|
+
def test_deploy_to_vercel(self):
|
|
491
|
+
"""Test Vercel deployment."""
|
|
492
|
+
corp = create_corporation(
|
|
493
|
+
name="DeployTestCorp",
|
|
494
|
+
verbose=False,
|
|
495
|
+
budget_limit=100.0
|
|
496
|
+
)
|
|
497
|
+
mandate_id = "test-mandate-456"
|
|
498
|
+
files = {
|
|
499
|
+
"index.html": "<html><body>Test</body></html>"
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
# This will make real HTTP calls to Vercel (if configured)
|
|
503
|
+
result = corp._deploy_to_vercel(mandate_id, files, "http://localhost:5173")
|
|
504
|
+
|
|
505
|
+
assert result is not None
|
|
506
|
+
print("[PASS] Vercel deployment test passed")
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
class TestIOOperations:
|
|
510
|
+
"""Test I/O operations."""
|
|
511
|
+
|
|
512
|
+
def test_file_operations(self):
|
|
513
|
+
"""Test file operations."""
|
|
514
|
+
corp = create_corporation(
|
|
515
|
+
name="IOTestCorp",
|
|
516
|
+
verbose=False,
|
|
517
|
+
budget_limit=100.0
|
|
518
|
+
)
|
|
519
|
+
"""Test file operations."""
|
|
520
|
+
mandate_id = "test-mandate-io"
|
|
521
|
+
operations = [
|
|
522
|
+
{
|
|
523
|
+
"type": "write",
|
|
524
|
+
"path": "test.txt",
|
|
525
|
+
"content": "Hello, World!"
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
"type": "read",
|
|
529
|
+
"path": "test.txt"
|
|
530
|
+
}
|
|
531
|
+
]
|
|
532
|
+
|
|
533
|
+
# This will make real HTTP calls to bolt.diy for file operations
|
|
534
|
+
result = corp.perform_file_operations(mandate_id, operations)
|
|
535
|
+
|
|
536
|
+
assert result is not None
|
|
537
|
+
assert "status" in result
|
|
538
|
+
|
|
539
|
+
print("[PASS] File operations test passed")
|
|
540
|
+
|
|
541
|
+
def test_database_operations(self):
|
|
542
|
+
"""Test database operations."""
|
|
543
|
+
corp = create_corporation(
|
|
544
|
+
name="IOTestCorp",
|
|
545
|
+
verbose=False,
|
|
546
|
+
budget_limit=100.0
|
|
547
|
+
)
|
|
548
|
+
mandate_id = "test-mandate-db"
|
|
549
|
+
operations = [
|
|
550
|
+
{
|
|
551
|
+
"type": "query",
|
|
552
|
+
"database": "sqlite",
|
|
553
|
+
"query": "SELECT * FROM users LIMIT 10"
|
|
554
|
+
}
|
|
555
|
+
]
|
|
556
|
+
|
|
557
|
+
# This will make real HTTP calls to bolt.diy for database operations
|
|
558
|
+
result = corp.perform_database_operations(mandate_id, operations)
|
|
559
|
+
|
|
560
|
+
assert result is not None
|
|
561
|
+
print("[PASS] Database operations test passed")
|
|
562
|
+
|
|
563
|
+
def test_api_calls(self):
|
|
564
|
+
"""Test API calls."""
|
|
565
|
+
corp = create_corporation(
|
|
566
|
+
name="IOTestCorp",
|
|
567
|
+
verbose=False,
|
|
568
|
+
budget_limit=100.0
|
|
569
|
+
)
|
|
570
|
+
mandate_id = "test-mandate-api"
|
|
571
|
+
requests_list = [
|
|
572
|
+
{
|
|
573
|
+
"method": "GET",
|
|
574
|
+
"url": "https://api.example.com/data",
|
|
575
|
+
"headers": {"Authorization": "Bearer token"}
|
|
576
|
+
}
|
|
577
|
+
]
|
|
578
|
+
|
|
579
|
+
# This will make real HTTP calls via bolt.diy
|
|
580
|
+
result = corp.perform_api_calls(mandate_id, requests_list)
|
|
581
|
+
|
|
582
|
+
assert result is not None
|
|
583
|
+
print("[PASS] API calls test passed")
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
class TestGovernance:
|
|
587
|
+
"""Test governance features."""
|
|
588
|
+
|
|
589
|
+
def test_esg_score(self):
|
|
590
|
+
"""Test ESG score calculation."""
|
|
591
|
+
corp = create_corporation(
|
|
592
|
+
name="GovTestCorp",
|
|
593
|
+
verbose=False,
|
|
594
|
+
budget_limit=100.0
|
|
595
|
+
)
|
|
596
|
+
"""Test ESG score calculation."""
|
|
597
|
+
esg_score = corp.calculate_esg_score()
|
|
598
|
+
|
|
599
|
+
assert esg_score is not None
|
|
600
|
+
assert hasattr(esg_score, "environmental_score")
|
|
601
|
+
assert hasattr(esg_score, "social_score")
|
|
602
|
+
assert hasattr(esg_score, "governance_score")
|
|
603
|
+
assert hasattr(esg_score, "overall_score")
|
|
604
|
+
|
|
605
|
+
print(f"[PASS] ESG score test passed (Overall: {esg_score.overall_score:.1f})")
|
|
606
|
+
|
|
607
|
+
def test_risk_assessment(self):
|
|
608
|
+
"""Test risk assessment."""
|
|
609
|
+
corp = create_corporation(
|
|
610
|
+
name="GovTestCorp",
|
|
611
|
+
verbose=False,
|
|
612
|
+
budget_limit=100.0
|
|
613
|
+
)
|
|
614
|
+
risks = corp.conduct_risk_assessment("comprehensive")
|
|
615
|
+
|
|
616
|
+
assert risks is not None
|
|
617
|
+
assert isinstance(risks, dict)
|
|
618
|
+
|
|
619
|
+
print(f"[PASS] Risk assessment test passed ({len(risks)} risks identified)")
|
|
620
|
+
|
|
621
|
+
def test_compliance_framework(self):
|
|
622
|
+
"""Test compliance framework."""
|
|
623
|
+
corp = create_corporation(
|
|
624
|
+
name="GovTestCorp",
|
|
625
|
+
verbose=False,
|
|
626
|
+
budget_limit=100.0
|
|
627
|
+
)
|
|
628
|
+
frameworks = corp.establish_compliance_framework("comprehensive")
|
|
629
|
+
|
|
630
|
+
assert frameworks is not None
|
|
631
|
+
assert isinstance(frameworks, dict)
|
|
632
|
+
|
|
633
|
+
print("[PASS] Compliance framework test passed")
|
|
634
|
+
|
|
635
|
+
def test_corporate_status(self):
|
|
636
|
+
"""Test getting corporate status."""
|
|
637
|
+
corp = create_corporation(
|
|
638
|
+
name="GovTestCorp",
|
|
639
|
+
verbose=False,
|
|
640
|
+
budget_limit=100.0
|
|
641
|
+
)
|
|
642
|
+
status = corp.get_corporate_status()
|
|
643
|
+
|
|
644
|
+
assert status is not None
|
|
645
|
+
assert "members" in status
|
|
646
|
+
assert "departments" in status
|
|
647
|
+
assert "proposals" in status
|
|
648
|
+
|
|
649
|
+
print("[PASS] Corporate status test passed")
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
class TestTaskDecomposition:
|
|
653
|
+
"""Test task decomposition features."""
|
|
654
|
+
|
|
655
|
+
def test_decompose_task(self):
|
|
656
|
+
"""Test task decomposition."""
|
|
657
|
+
corp = create_corporation(
|
|
658
|
+
name="DecompTestCorp",
|
|
659
|
+
verbose=False,
|
|
660
|
+
budget_limit=100.0
|
|
661
|
+
)
|
|
662
|
+
"""Test task decomposition."""
|
|
663
|
+
task = "Build a revenue-generating SaaS landing page with pricing, features, and contact form"
|
|
664
|
+
|
|
665
|
+
subtasks = corp.decompose_task(task)
|
|
666
|
+
|
|
667
|
+
assert isinstance(subtasks, list)
|
|
668
|
+
assert len(subtasks) > 0
|
|
669
|
+
|
|
670
|
+
for subtask in subtasks:
|
|
671
|
+
assert "task" in subtask
|
|
672
|
+
assert "priority" in subtask
|
|
673
|
+
|
|
674
|
+
print(f"[PASS] Task decomposition test passed ({len(subtasks)} subtasks)")
|
|
675
|
+
|
|
676
|
+
def test_re_sort_subtasks(self):
|
|
677
|
+
"""Test sub-task re-sorting."""
|
|
678
|
+
corp = create_corporation(
|
|
679
|
+
name="DecompTestCorp",
|
|
680
|
+
verbose=False,
|
|
681
|
+
budget_limit=100.0
|
|
682
|
+
)
|
|
683
|
+
task = "Create a profit-maximizing e-commerce website"
|
|
684
|
+
subtasks = corp.decompose_task(task)
|
|
685
|
+
|
|
686
|
+
if len(subtasks) > 1:
|
|
687
|
+
sorted_subtasks = corp.re_sort_subtasks(subtasks)
|
|
688
|
+
|
|
689
|
+
assert len(sorted_subtasks) == len(subtasks)
|
|
690
|
+
assert isinstance(sorted_subtasks, list)
|
|
691
|
+
|
|
692
|
+
print("[PASS] Sub-task re-sorting test passed")
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
def run_all_tests():
|
|
696
|
+
"""Run all test classes."""
|
|
697
|
+
print("\n" + "="*80)
|
|
698
|
+
print("CorporateSwarm Comprehensive Test Suite")
|
|
699
|
+
print("="*80 + "\n")
|
|
700
|
+
|
|
701
|
+
test_classes = [
|
|
702
|
+
TestCorporationCreation,
|
|
703
|
+
TestMemberManagement,
|
|
704
|
+
TestProposalAndVoting,
|
|
705
|
+
TestTaskGeneration,
|
|
706
|
+
TestMandateExecution,
|
|
707
|
+
TestDeploymentFeatures,
|
|
708
|
+
TestIOOperations,
|
|
709
|
+
TestGovernance,
|
|
710
|
+
TestTaskDecomposition
|
|
711
|
+
]
|
|
712
|
+
|
|
713
|
+
total_tests = 0
|
|
714
|
+
passed_tests = 0
|
|
715
|
+
failed_tests = []
|
|
716
|
+
|
|
717
|
+
for test_class in test_classes:
|
|
718
|
+
class_name = test_class.__name__
|
|
719
|
+
print(f"\n{'='*80}")
|
|
720
|
+
print(f"Running {class_name}")
|
|
721
|
+
print(f"{'='*80}")
|
|
722
|
+
|
|
723
|
+
# Create instance
|
|
724
|
+
instance = test_class()
|
|
725
|
+
|
|
726
|
+
# Get all test methods
|
|
727
|
+
test_methods = [method for method in dir(instance) if method.startswith('test_')]
|
|
728
|
+
|
|
729
|
+
# Create fixtures if needed
|
|
730
|
+
if hasattr(instance, 'corp'):
|
|
731
|
+
try:
|
|
732
|
+
instance.corp = instance.corp()
|
|
733
|
+
except:
|
|
734
|
+
pass
|
|
735
|
+
|
|
736
|
+
for test_method_name in test_methods:
|
|
737
|
+
total_tests += 1
|
|
738
|
+
test_method = getattr(instance, test_method_name)
|
|
739
|
+
|
|
740
|
+
try:
|
|
741
|
+
# Run test method (bound method, so call without arguments)
|
|
742
|
+
test_method()
|
|
743
|
+
|
|
744
|
+
passed_tests += 1
|
|
745
|
+
print(f"[PASS] {test_method_name} PASSED")
|
|
746
|
+
except Exception as e:
|
|
747
|
+
failed_tests.append((class_name, test_method_name, str(e)))
|
|
748
|
+
print(f"[FAIL] {test_method_name} FAILED: {e}")
|
|
749
|
+
import traceback
|
|
750
|
+
traceback.print_exc()
|
|
751
|
+
|
|
752
|
+
# Print summary
|
|
753
|
+
print("\n" + "="*80)
|
|
754
|
+
print("TEST SUMMARY")
|
|
755
|
+
print("="*80)
|
|
756
|
+
print(f"Total Tests: {total_tests}")
|
|
757
|
+
print(f"Passed: {passed_tests}")
|
|
758
|
+
print(f"Failed: {len(failed_tests)}")
|
|
759
|
+
|
|
760
|
+
if failed_tests:
|
|
761
|
+
print("\nFailed Tests:")
|
|
762
|
+
for class_name, method_name, error in failed_tests:
|
|
763
|
+
print(f" - {class_name}.{method_name}: {error}")
|
|
764
|
+
|
|
765
|
+
print("="*80 + "\n")
|
|
766
|
+
|
|
767
|
+
return len(failed_tests) == 0
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
if __name__ == "__main__":
|
|
771
|
+
success = run_all_tests()
|
|
772
|
+
sys.exit(0 if success else 1)
|
|
773
|
+
|