crackerjack 0.18.2__py3-none-any.whl → 0.45.2__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.
Files changed (533) hide show
  1. crackerjack/README.md +19 -0
  2. crackerjack/__init__.py +96 -2
  3. crackerjack/__main__.py +637 -138
  4. crackerjack/adapters/README.md +18 -0
  5. crackerjack/adapters/__init__.py +39 -0
  6. crackerjack/adapters/_output_paths.py +167 -0
  7. crackerjack/adapters/_qa_adapter_base.py +309 -0
  8. crackerjack/adapters/_tool_adapter_base.py +706 -0
  9. crackerjack/adapters/ai/README.md +65 -0
  10. crackerjack/adapters/ai/__init__.py +5 -0
  11. crackerjack/adapters/ai/claude.py +853 -0
  12. crackerjack/adapters/complexity/README.md +53 -0
  13. crackerjack/adapters/complexity/__init__.py +10 -0
  14. crackerjack/adapters/complexity/complexipy.py +641 -0
  15. crackerjack/adapters/dependency/__init__.py +22 -0
  16. crackerjack/adapters/dependency/pip_audit.py +418 -0
  17. crackerjack/adapters/format/README.md +72 -0
  18. crackerjack/adapters/format/__init__.py +11 -0
  19. crackerjack/adapters/format/mdformat.py +313 -0
  20. crackerjack/adapters/format/ruff.py +516 -0
  21. crackerjack/adapters/lint/README.md +47 -0
  22. crackerjack/adapters/lint/__init__.py +11 -0
  23. crackerjack/adapters/lint/codespell.py +273 -0
  24. crackerjack/adapters/lsp/README.md +49 -0
  25. crackerjack/adapters/lsp/__init__.py +27 -0
  26. crackerjack/adapters/lsp/_base.py +194 -0
  27. crackerjack/adapters/lsp/_client.py +358 -0
  28. crackerjack/adapters/lsp/_manager.py +193 -0
  29. crackerjack/adapters/lsp/skylos.py +283 -0
  30. crackerjack/adapters/lsp/zuban.py +557 -0
  31. crackerjack/adapters/refactor/README.md +59 -0
  32. crackerjack/adapters/refactor/__init__.py +12 -0
  33. crackerjack/adapters/refactor/creosote.py +318 -0
  34. crackerjack/adapters/refactor/refurb.py +406 -0
  35. crackerjack/adapters/refactor/skylos.py +494 -0
  36. crackerjack/adapters/sast/README.md +132 -0
  37. crackerjack/adapters/sast/__init__.py +32 -0
  38. crackerjack/adapters/sast/_base.py +201 -0
  39. crackerjack/adapters/sast/bandit.py +423 -0
  40. crackerjack/adapters/sast/pyscn.py +405 -0
  41. crackerjack/adapters/sast/semgrep.py +241 -0
  42. crackerjack/adapters/security/README.md +111 -0
  43. crackerjack/adapters/security/__init__.py +17 -0
  44. crackerjack/adapters/security/gitleaks.py +339 -0
  45. crackerjack/adapters/type/README.md +52 -0
  46. crackerjack/adapters/type/__init__.py +12 -0
  47. crackerjack/adapters/type/pyrefly.py +402 -0
  48. crackerjack/adapters/type/ty.py +402 -0
  49. crackerjack/adapters/type/zuban.py +522 -0
  50. crackerjack/adapters/utility/README.md +51 -0
  51. crackerjack/adapters/utility/__init__.py +10 -0
  52. crackerjack/adapters/utility/checks.py +884 -0
  53. crackerjack/agents/README.md +264 -0
  54. crackerjack/agents/__init__.py +66 -0
  55. crackerjack/agents/architect_agent.py +238 -0
  56. crackerjack/agents/base.py +167 -0
  57. crackerjack/agents/claude_code_bridge.py +641 -0
  58. crackerjack/agents/coordinator.py +600 -0
  59. crackerjack/agents/documentation_agent.py +520 -0
  60. crackerjack/agents/dry_agent.py +585 -0
  61. crackerjack/agents/enhanced_coordinator.py +279 -0
  62. crackerjack/agents/enhanced_proactive_agent.py +185 -0
  63. crackerjack/agents/error_middleware.py +53 -0
  64. crackerjack/agents/formatting_agent.py +230 -0
  65. crackerjack/agents/helpers/__init__.py +9 -0
  66. crackerjack/agents/helpers/performance/__init__.py +22 -0
  67. crackerjack/agents/helpers/performance/performance_ast_analyzer.py +357 -0
  68. crackerjack/agents/helpers/performance/performance_pattern_detector.py +909 -0
  69. crackerjack/agents/helpers/performance/performance_recommender.py +572 -0
  70. crackerjack/agents/helpers/refactoring/__init__.py +22 -0
  71. crackerjack/agents/helpers/refactoring/code_transformer.py +536 -0
  72. crackerjack/agents/helpers/refactoring/complexity_analyzer.py +344 -0
  73. crackerjack/agents/helpers/refactoring/dead_code_detector.py +437 -0
  74. crackerjack/agents/helpers/test_creation/__init__.py +19 -0
  75. crackerjack/agents/helpers/test_creation/test_ast_analyzer.py +216 -0
  76. crackerjack/agents/helpers/test_creation/test_coverage_analyzer.py +643 -0
  77. crackerjack/agents/helpers/test_creation/test_template_generator.py +1031 -0
  78. crackerjack/agents/import_optimization_agent.py +1181 -0
  79. crackerjack/agents/performance_agent.py +325 -0
  80. crackerjack/agents/performance_helpers.py +205 -0
  81. crackerjack/agents/proactive_agent.py +55 -0
  82. crackerjack/agents/refactoring_agent.py +511 -0
  83. crackerjack/agents/refactoring_helpers.py +247 -0
  84. crackerjack/agents/security_agent.py +793 -0
  85. crackerjack/agents/semantic_agent.py +479 -0
  86. crackerjack/agents/semantic_helpers.py +356 -0
  87. crackerjack/agents/test_creation_agent.py +570 -0
  88. crackerjack/agents/test_specialist_agent.py +526 -0
  89. crackerjack/agents/tracker.py +110 -0
  90. crackerjack/api.py +647 -0
  91. crackerjack/cli/README.md +394 -0
  92. crackerjack/cli/__init__.py +24 -0
  93. crackerjack/cli/cache_handlers.py +209 -0
  94. crackerjack/cli/cache_handlers_enhanced.py +680 -0
  95. crackerjack/cli/facade.py +162 -0
  96. crackerjack/cli/formatting.py +13 -0
  97. crackerjack/cli/handlers/__init__.py +85 -0
  98. crackerjack/cli/handlers/advanced.py +103 -0
  99. crackerjack/cli/handlers/ai_features.py +62 -0
  100. crackerjack/cli/handlers/analytics.py +479 -0
  101. crackerjack/cli/handlers/changelog.py +271 -0
  102. crackerjack/cli/handlers/config_handlers.py +16 -0
  103. crackerjack/cli/handlers/coverage.py +84 -0
  104. crackerjack/cli/handlers/documentation.py +280 -0
  105. crackerjack/cli/handlers/main_handlers.py +497 -0
  106. crackerjack/cli/handlers/monitoring.py +371 -0
  107. crackerjack/cli/handlers.py +700 -0
  108. crackerjack/cli/interactive.py +488 -0
  109. crackerjack/cli/options.py +1216 -0
  110. crackerjack/cli/semantic_handlers.py +292 -0
  111. crackerjack/cli/utils.py +19 -0
  112. crackerjack/cli/version.py +19 -0
  113. crackerjack/code_cleaner.py +1307 -0
  114. crackerjack/config/README.md +472 -0
  115. crackerjack/config/__init__.py +275 -0
  116. crackerjack/config/global_lock_config.py +207 -0
  117. crackerjack/config/hooks.py +390 -0
  118. crackerjack/config/loader.py +239 -0
  119. crackerjack/config/settings.py +141 -0
  120. crackerjack/config/tool_commands.py +331 -0
  121. crackerjack/core/README.md +393 -0
  122. crackerjack/core/__init__.py +0 -0
  123. crackerjack/core/async_workflow_orchestrator.py +738 -0
  124. crackerjack/core/autofix_coordinator.py +282 -0
  125. crackerjack/core/container.py +105 -0
  126. crackerjack/core/enhanced_container.py +583 -0
  127. crackerjack/core/file_lifecycle.py +472 -0
  128. crackerjack/core/performance.py +244 -0
  129. crackerjack/core/performance_monitor.py +357 -0
  130. crackerjack/core/phase_coordinator.py +1227 -0
  131. crackerjack/core/proactive_workflow.py +267 -0
  132. crackerjack/core/resource_manager.py +425 -0
  133. crackerjack/core/retry.py +275 -0
  134. crackerjack/core/service_watchdog.py +601 -0
  135. crackerjack/core/session_coordinator.py +239 -0
  136. crackerjack/core/timeout_manager.py +563 -0
  137. crackerjack/core/websocket_lifecycle.py +410 -0
  138. crackerjack/core/workflow/__init__.py +21 -0
  139. crackerjack/core/workflow/workflow_ai_coordinator.py +863 -0
  140. crackerjack/core/workflow/workflow_event_orchestrator.py +1107 -0
  141. crackerjack/core/workflow/workflow_issue_parser.py +714 -0
  142. crackerjack/core/workflow/workflow_phase_executor.py +1158 -0
  143. crackerjack/core/workflow/workflow_security_gates.py +400 -0
  144. crackerjack/core/workflow_orchestrator.py +2243 -0
  145. crackerjack/data/README.md +11 -0
  146. crackerjack/data/__init__.py +8 -0
  147. crackerjack/data/models.py +79 -0
  148. crackerjack/data/repository.py +210 -0
  149. crackerjack/decorators/README.md +180 -0
  150. crackerjack/decorators/__init__.py +35 -0
  151. crackerjack/decorators/error_handling.py +649 -0
  152. crackerjack/decorators/error_handling_decorators.py +334 -0
  153. crackerjack/decorators/helpers.py +58 -0
  154. crackerjack/decorators/patterns.py +281 -0
  155. crackerjack/decorators/utils.py +58 -0
  156. crackerjack/docs/INDEX.md +11 -0
  157. crackerjack/docs/README.md +11 -0
  158. crackerjack/docs/generated/api/API_REFERENCE.md +10895 -0
  159. crackerjack/docs/generated/api/CLI_REFERENCE.md +109 -0
  160. crackerjack/docs/generated/api/CROSS_REFERENCES.md +1755 -0
  161. crackerjack/docs/generated/api/PROTOCOLS.md +3 -0
  162. crackerjack/docs/generated/api/SERVICES.md +1252 -0
  163. crackerjack/documentation/README.md +11 -0
  164. crackerjack/documentation/__init__.py +31 -0
  165. crackerjack/documentation/ai_templates.py +756 -0
  166. crackerjack/documentation/dual_output_generator.py +767 -0
  167. crackerjack/documentation/mkdocs_integration.py +518 -0
  168. crackerjack/documentation/reference_generator.py +1065 -0
  169. crackerjack/dynamic_config.py +678 -0
  170. crackerjack/errors.py +378 -0
  171. crackerjack/events/README.md +11 -0
  172. crackerjack/events/__init__.py +16 -0
  173. crackerjack/events/telemetry.py +175 -0
  174. crackerjack/events/workflow_bus.py +346 -0
  175. crackerjack/exceptions/README.md +301 -0
  176. crackerjack/exceptions/__init__.py +5 -0
  177. crackerjack/exceptions/config.py +4 -0
  178. crackerjack/exceptions/tool_execution_error.py +245 -0
  179. crackerjack/executors/README.md +591 -0
  180. crackerjack/executors/__init__.py +13 -0
  181. crackerjack/executors/async_hook_executor.py +938 -0
  182. crackerjack/executors/cached_hook_executor.py +316 -0
  183. crackerjack/executors/hook_executor.py +1295 -0
  184. crackerjack/executors/hook_lock_manager.py +708 -0
  185. crackerjack/executors/individual_hook_executor.py +739 -0
  186. crackerjack/executors/lsp_aware_hook_executor.py +349 -0
  187. crackerjack/executors/progress_hook_executor.py +282 -0
  188. crackerjack/executors/tool_proxy.py +433 -0
  189. crackerjack/hooks/README.md +485 -0
  190. crackerjack/hooks/lsp_hook.py +93 -0
  191. crackerjack/intelligence/README.md +557 -0
  192. crackerjack/intelligence/__init__.py +37 -0
  193. crackerjack/intelligence/adaptive_learning.py +693 -0
  194. crackerjack/intelligence/agent_orchestrator.py +485 -0
  195. crackerjack/intelligence/agent_registry.py +377 -0
  196. crackerjack/intelligence/agent_selector.py +439 -0
  197. crackerjack/intelligence/integration.py +250 -0
  198. crackerjack/interactive.py +719 -0
  199. crackerjack/managers/README.md +369 -0
  200. crackerjack/managers/__init__.py +11 -0
  201. crackerjack/managers/async_hook_manager.py +135 -0
  202. crackerjack/managers/hook_manager.py +585 -0
  203. crackerjack/managers/publish_manager.py +631 -0
  204. crackerjack/managers/test_command_builder.py +391 -0
  205. crackerjack/managers/test_executor.py +474 -0
  206. crackerjack/managers/test_manager.py +1357 -0
  207. crackerjack/managers/test_progress.py +187 -0
  208. crackerjack/mcp/README.md +374 -0
  209. crackerjack/mcp/__init__.py +0 -0
  210. crackerjack/mcp/cache.py +352 -0
  211. crackerjack/mcp/client_runner.py +121 -0
  212. crackerjack/mcp/context.py +802 -0
  213. crackerjack/mcp/dashboard.py +657 -0
  214. crackerjack/mcp/enhanced_progress_monitor.py +493 -0
  215. crackerjack/mcp/file_monitor.py +394 -0
  216. crackerjack/mcp/progress_components.py +607 -0
  217. crackerjack/mcp/progress_monitor.py +1016 -0
  218. crackerjack/mcp/rate_limiter.py +336 -0
  219. crackerjack/mcp/server.py +24 -0
  220. crackerjack/mcp/server_core.py +526 -0
  221. crackerjack/mcp/service_watchdog.py +505 -0
  222. crackerjack/mcp/state.py +407 -0
  223. crackerjack/mcp/task_manager.py +259 -0
  224. crackerjack/mcp/tools/README.md +27 -0
  225. crackerjack/mcp/tools/__init__.py +19 -0
  226. crackerjack/mcp/tools/core_tools.py +469 -0
  227. crackerjack/mcp/tools/error_analyzer.py +283 -0
  228. crackerjack/mcp/tools/execution_tools.py +384 -0
  229. crackerjack/mcp/tools/intelligence_tool_registry.py +46 -0
  230. crackerjack/mcp/tools/intelligence_tools.py +264 -0
  231. crackerjack/mcp/tools/monitoring_tools.py +628 -0
  232. crackerjack/mcp/tools/proactive_tools.py +367 -0
  233. crackerjack/mcp/tools/progress_tools.py +222 -0
  234. crackerjack/mcp/tools/semantic_tools.py +584 -0
  235. crackerjack/mcp/tools/utility_tools.py +358 -0
  236. crackerjack/mcp/tools/workflow_executor.py +699 -0
  237. crackerjack/mcp/websocket/README.md +31 -0
  238. crackerjack/mcp/websocket/__init__.py +14 -0
  239. crackerjack/mcp/websocket/app.py +54 -0
  240. crackerjack/mcp/websocket/endpoints.py +492 -0
  241. crackerjack/mcp/websocket/event_bridge.py +188 -0
  242. crackerjack/mcp/websocket/jobs.py +406 -0
  243. crackerjack/mcp/websocket/monitoring/__init__.py +25 -0
  244. crackerjack/mcp/websocket/monitoring/api/__init__.py +19 -0
  245. crackerjack/mcp/websocket/monitoring/api/dependencies.py +141 -0
  246. crackerjack/mcp/websocket/monitoring/api/heatmap.py +154 -0
  247. crackerjack/mcp/websocket/monitoring/api/intelligence.py +199 -0
  248. crackerjack/mcp/websocket/monitoring/api/metrics.py +203 -0
  249. crackerjack/mcp/websocket/monitoring/api/telemetry.py +101 -0
  250. crackerjack/mcp/websocket/monitoring/dashboard.py +18 -0
  251. crackerjack/mcp/websocket/monitoring/factory.py +109 -0
  252. crackerjack/mcp/websocket/monitoring/filters.py +10 -0
  253. crackerjack/mcp/websocket/monitoring/metrics.py +64 -0
  254. crackerjack/mcp/websocket/monitoring/models.py +90 -0
  255. crackerjack/mcp/websocket/monitoring/utils.py +171 -0
  256. crackerjack/mcp/websocket/monitoring/websocket_manager.py +78 -0
  257. crackerjack/mcp/websocket/monitoring/websockets/__init__.py +17 -0
  258. crackerjack/mcp/websocket/monitoring/websockets/dependencies.py +126 -0
  259. crackerjack/mcp/websocket/monitoring/websockets/heatmap.py +176 -0
  260. crackerjack/mcp/websocket/monitoring/websockets/intelligence.py +291 -0
  261. crackerjack/mcp/websocket/monitoring/websockets/metrics.py +291 -0
  262. crackerjack/mcp/websocket/monitoring_endpoints.py +21 -0
  263. crackerjack/mcp/websocket/server.py +174 -0
  264. crackerjack/mcp/websocket/websocket_handler.py +276 -0
  265. crackerjack/mcp/websocket_server.py +10 -0
  266. crackerjack/models/README.md +308 -0
  267. crackerjack/models/__init__.py +40 -0
  268. crackerjack/models/config.py +730 -0
  269. crackerjack/models/config_adapter.py +265 -0
  270. crackerjack/models/protocols.py +1535 -0
  271. crackerjack/models/pydantic_models.py +320 -0
  272. crackerjack/models/qa_config.py +145 -0
  273. crackerjack/models/qa_results.py +134 -0
  274. crackerjack/models/resource_protocols.py +299 -0
  275. crackerjack/models/results.py +35 -0
  276. crackerjack/models/semantic_models.py +258 -0
  277. crackerjack/models/task.py +173 -0
  278. crackerjack/models/test_models.py +60 -0
  279. crackerjack/monitoring/README.md +11 -0
  280. crackerjack/monitoring/__init__.py +0 -0
  281. crackerjack/monitoring/ai_agent_watchdog.py +405 -0
  282. crackerjack/monitoring/metrics_collector.py +427 -0
  283. crackerjack/monitoring/regression_prevention.py +580 -0
  284. crackerjack/monitoring/websocket_server.py +406 -0
  285. crackerjack/orchestration/README.md +340 -0
  286. crackerjack/orchestration/__init__.py +43 -0
  287. crackerjack/orchestration/advanced_orchestrator.py +894 -0
  288. crackerjack/orchestration/cache/README.md +312 -0
  289. crackerjack/orchestration/cache/__init__.py +37 -0
  290. crackerjack/orchestration/cache/memory_cache.py +338 -0
  291. crackerjack/orchestration/cache/tool_proxy_cache.py +340 -0
  292. crackerjack/orchestration/config.py +297 -0
  293. crackerjack/orchestration/coverage_improvement.py +180 -0
  294. crackerjack/orchestration/execution_strategies.py +361 -0
  295. crackerjack/orchestration/hook_orchestrator.py +1398 -0
  296. crackerjack/orchestration/strategies/README.md +401 -0
  297. crackerjack/orchestration/strategies/__init__.py +39 -0
  298. crackerjack/orchestration/strategies/adaptive_strategy.py +630 -0
  299. crackerjack/orchestration/strategies/parallel_strategy.py +237 -0
  300. crackerjack/orchestration/strategies/sequential_strategy.py +299 -0
  301. crackerjack/orchestration/test_progress_streamer.py +647 -0
  302. crackerjack/plugins/README.md +11 -0
  303. crackerjack/plugins/__init__.py +15 -0
  304. crackerjack/plugins/base.py +200 -0
  305. crackerjack/plugins/hooks.py +254 -0
  306. crackerjack/plugins/loader.py +335 -0
  307. crackerjack/plugins/managers.py +264 -0
  308. crackerjack/py313.py +191 -0
  309. crackerjack/security/README.md +11 -0
  310. crackerjack/security/__init__.py +0 -0
  311. crackerjack/security/audit.py +197 -0
  312. crackerjack/services/README.md +374 -0
  313. crackerjack/services/__init__.py +9 -0
  314. crackerjack/services/ai/README.md +295 -0
  315. crackerjack/services/ai/__init__.py +7 -0
  316. crackerjack/services/ai/advanced_optimizer.py +878 -0
  317. crackerjack/services/ai/contextual_ai_assistant.py +542 -0
  318. crackerjack/services/ai/embeddings.py +444 -0
  319. crackerjack/services/ai/intelligent_commit.py +328 -0
  320. crackerjack/services/ai/predictive_analytics.py +510 -0
  321. crackerjack/services/anomaly_detector.py +392 -0
  322. crackerjack/services/api_extractor.py +617 -0
  323. crackerjack/services/backup_service.py +467 -0
  324. crackerjack/services/bounded_status_operations.py +530 -0
  325. crackerjack/services/cache.py +369 -0
  326. crackerjack/services/changelog_automation.py +399 -0
  327. crackerjack/services/command_execution_service.py +305 -0
  328. crackerjack/services/config_integrity.py +132 -0
  329. crackerjack/services/config_merge.py +546 -0
  330. crackerjack/services/config_service.py +198 -0
  331. crackerjack/services/config_template.py +493 -0
  332. crackerjack/services/coverage_badge_service.py +173 -0
  333. crackerjack/services/coverage_ratchet.py +381 -0
  334. crackerjack/services/debug.py +733 -0
  335. crackerjack/services/dependency_analyzer.py +460 -0
  336. crackerjack/services/dependency_monitor.py +622 -0
  337. crackerjack/services/documentation_generator.py +493 -0
  338. crackerjack/services/documentation_service.py +704 -0
  339. crackerjack/services/enhanced_filesystem.py +497 -0
  340. crackerjack/services/enterprise_optimizer.py +865 -0
  341. crackerjack/services/error_pattern_analyzer.py +676 -0
  342. crackerjack/services/file_filter.py +221 -0
  343. crackerjack/services/file_hasher.py +149 -0
  344. crackerjack/services/file_io_service.py +361 -0
  345. crackerjack/services/file_modifier.py +615 -0
  346. crackerjack/services/filesystem.py +381 -0
  347. crackerjack/services/git.py +422 -0
  348. crackerjack/services/health_metrics.py +615 -0
  349. crackerjack/services/heatmap_generator.py +744 -0
  350. crackerjack/services/incremental_executor.py +380 -0
  351. crackerjack/services/initialization.py +823 -0
  352. crackerjack/services/input_validator.py +668 -0
  353. crackerjack/services/intelligent_commit.py +327 -0
  354. crackerjack/services/log_manager.py +289 -0
  355. crackerjack/services/logging.py +228 -0
  356. crackerjack/services/lsp_client.py +628 -0
  357. crackerjack/services/memory_optimizer.py +414 -0
  358. crackerjack/services/metrics.py +587 -0
  359. crackerjack/services/monitoring/README.md +30 -0
  360. crackerjack/services/monitoring/__init__.py +9 -0
  361. crackerjack/services/monitoring/dependency_monitor.py +678 -0
  362. crackerjack/services/monitoring/error_pattern_analyzer.py +676 -0
  363. crackerjack/services/monitoring/health_metrics.py +716 -0
  364. crackerjack/services/monitoring/metrics.py +587 -0
  365. crackerjack/services/monitoring/performance_benchmarks.py +410 -0
  366. crackerjack/services/monitoring/performance_cache.py +388 -0
  367. crackerjack/services/monitoring/performance_monitor.py +569 -0
  368. crackerjack/services/parallel_executor.py +527 -0
  369. crackerjack/services/pattern_cache.py +333 -0
  370. crackerjack/services/pattern_detector.py +478 -0
  371. crackerjack/services/patterns/__init__.py +142 -0
  372. crackerjack/services/patterns/agents.py +107 -0
  373. crackerjack/services/patterns/code/__init__.py +15 -0
  374. crackerjack/services/patterns/code/detection.py +118 -0
  375. crackerjack/services/patterns/code/imports.py +107 -0
  376. crackerjack/services/patterns/code/paths.py +159 -0
  377. crackerjack/services/patterns/code/performance.py +119 -0
  378. crackerjack/services/patterns/code/replacement.py +36 -0
  379. crackerjack/services/patterns/core.py +212 -0
  380. crackerjack/services/patterns/documentation/__init__.py +14 -0
  381. crackerjack/services/patterns/documentation/badges_markdown.py +96 -0
  382. crackerjack/services/patterns/documentation/comments_blocks.py +83 -0
  383. crackerjack/services/patterns/documentation/docstrings.py +89 -0
  384. crackerjack/services/patterns/formatting.py +226 -0
  385. crackerjack/services/patterns/operations.py +339 -0
  386. crackerjack/services/patterns/security/__init__.py +23 -0
  387. crackerjack/services/patterns/security/code_injection.py +122 -0
  388. crackerjack/services/patterns/security/credentials.py +190 -0
  389. crackerjack/services/patterns/security/path_traversal.py +221 -0
  390. crackerjack/services/patterns/security/unsafe_operations.py +216 -0
  391. crackerjack/services/patterns/templates.py +62 -0
  392. crackerjack/services/patterns/testing/__init__.py +18 -0
  393. crackerjack/services/patterns/testing/error_patterns.py +107 -0
  394. crackerjack/services/patterns/testing/pytest_output.py +126 -0
  395. crackerjack/services/patterns/tool_output/__init__.py +16 -0
  396. crackerjack/services/patterns/tool_output/bandit.py +72 -0
  397. crackerjack/services/patterns/tool_output/other.py +97 -0
  398. crackerjack/services/patterns/tool_output/pyright.py +67 -0
  399. crackerjack/services/patterns/tool_output/ruff.py +44 -0
  400. crackerjack/services/patterns/url_sanitization.py +114 -0
  401. crackerjack/services/patterns/utilities.py +42 -0
  402. crackerjack/services/patterns/utils.py +339 -0
  403. crackerjack/services/patterns/validation.py +46 -0
  404. crackerjack/services/patterns/versioning.py +62 -0
  405. crackerjack/services/predictive_analytics.py +523 -0
  406. crackerjack/services/profiler.py +280 -0
  407. crackerjack/services/quality/README.md +415 -0
  408. crackerjack/services/quality/__init__.py +11 -0
  409. crackerjack/services/quality/anomaly_detector.py +392 -0
  410. crackerjack/services/quality/pattern_cache.py +333 -0
  411. crackerjack/services/quality/pattern_detector.py +479 -0
  412. crackerjack/services/quality/qa_orchestrator.py +491 -0
  413. crackerjack/services/quality/quality_baseline.py +395 -0
  414. crackerjack/services/quality/quality_baseline_enhanced.py +649 -0
  415. crackerjack/services/quality/quality_intelligence.py +949 -0
  416. crackerjack/services/regex_patterns.py +58 -0
  417. crackerjack/services/regex_utils.py +483 -0
  418. crackerjack/services/secure_path_utils.py +524 -0
  419. crackerjack/services/secure_status_formatter.py +450 -0
  420. crackerjack/services/secure_subprocess.py +635 -0
  421. crackerjack/services/security.py +239 -0
  422. crackerjack/services/security_logger.py +495 -0
  423. crackerjack/services/server_manager.py +411 -0
  424. crackerjack/services/smart_scheduling.py +167 -0
  425. crackerjack/services/status_authentication.py +460 -0
  426. crackerjack/services/status_security_manager.py +315 -0
  427. crackerjack/services/terminal_utils.py +0 -0
  428. crackerjack/services/thread_safe_status_collector.py +441 -0
  429. crackerjack/services/tool_filter.py +368 -0
  430. crackerjack/services/tool_version_service.py +43 -0
  431. crackerjack/services/unified_config.py +115 -0
  432. crackerjack/services/validation_rate_limiter.py +220 -0
  433. crackerjack/services/vector_store.py +689 -0
  434. crackerjack/services/version_analyzer.py +461 -0
  435. crackerjack/services/version_checker.py +223 -0
  436. crackerjack/services/websocket_resource_limiter.py +438 -0
  437. crackerjack/services/zuban_lsp_service.py +391 -0
  438. crackerjack/slash_commands/README.md +11 -0
  439. crackerjack/slash_commands/__init__.py +59 -0
  440. crackerjack/slash_commands/init.md +112 -0
  441. crackerjack/slash_commands/run.md +197 -0
  442. crackerjack/slash_commands/status.md +127 -0
  443. crackerjack/tools/README.md +11 -0
  444. crackerjack/tools/__init__.py +30 -0
  445. crackerjack/tools/_git_utils.py +105 -0
  446. crackerjack/tools/check_added_large_files.py +139 -0
  447. crackerjack/tools/check_ast.py +105 -0
  448. crackerjack/tools/check_json.py +103 -0
  449. crackerjack/tools/check_jsonschema.py +297 -0
  450. crackerjack/tools/check_toml.py +103 -0
  451. crackerjack/tools/check_yaml.py +110 -0
  452. crackerjack/tools/codespell_wrapper.py +72 -0
  453. crackerjack/tools/end_of_file_fixer.py +202 -0
  454. crackerjack/tools/format_json.py +128 -0
  455. crackerjack/tools/mdformat_wrapper.py +114 -0
  456. crackerjack/tools/trailing_whitespace.py +198 -0
  457. crackerjack/tools/validate_input_validator_patterns.py +236 -0
  458. crackerjack/tools/validate_regex_patterns.py +188 -0
  459. crackerjack/ui/README.md +11 -0
  460. crackerjack/ui/__init__.py +1 -0
  461. crackerjack/ui/dashboard_renderer.py +28 -0
  462. crackerjack/ui/templates/README.md +11 -0
  463. crackerjack/utils/console_utils.py +13 -0
  464. crackerjack/utils/dependency_guard.py +230 -0
  465. crackerjack/utils/retry_utils.py +275 -0
  466. crackerjack/workflows/README.md +590 -0
  467. crackerjack/workflows/__init__.py +46 -0
  468. crackerjack/workflows/actions.py +811 -0
  469. crackerjack/workflows/auto_fix.py +444 -0
  470. crackerjack/workflows/container_builder.py +499 -0
  471. crackerjack/workflows/definitions.py +443 -0
  472. crackerjack/workflows/engine.py +177 -0
  473. crackerjack/workflows/event_bridge.py +242 -0
  474. crackerjack-0.45.2.dist-info/METADATA +1678 -0
  475. crackerjack-0.45.2.dist-info/RECORD +478 -0
  476. {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/WHEEL +1 -1
  477. crackerjack-0.45.2.dist-info/entry_points.txt +2 -0
  478. crackerjack/.gitignore +0 -14
  479. crackerjack/.libcst.codemod.yaml +0 -18
  480. crackerjack/.pdm.toml +0 -1
  481. crackerjack/.pre-commit-config.yaml +0 -91
  482. crackerjack/.pytest_cache/.gitignore +0 -2
  483. crackerjack/.pytest_cache/CACHEDIR.TAG +0 -4
  484. crackerjack/.pytest_cache/README.md +0 -8
  485. crackerjack/.pytest_cache/v/cache/nodeids +0 -1
  486. crackerjack/.pytest_cache/v/cache/stepwise +0 -1
  487. crackerjack/.ruff_cache/.gitignore +0 -1
  488. crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
  489. crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
  490. crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
  491. crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
  492. crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
  493. crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
  494. crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
  495. crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
  496. crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
  497. crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
  498. crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
  499. crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
  500. crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
  501. crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
  502. crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
  503. crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
  504. crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
  505. crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
  506. crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
  507. crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
  508. crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
  509. crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
  510. crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
  511. crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
  512. crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
  513. crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
  514. crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
  515. crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
  516. crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
  517. crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
  518. crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
  519. crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
  520. crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
  521. crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
  522. crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
  523. crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
  524. crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
  525. crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
  526. crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
  527. crackerjack/.ruff_cache/CACHEDIR.TAG +0 -1
  528. crackerjack/crackerjack.py +0 -855
  529. crackerjack/pyproject.toml +0 -214
  530. crackerjack-0.18.2.dist-info/METADATA +0 -420
  531. crackerjack-0.18.2.dist-info/RECORD +0 -59
  532. crackerjack-0.18.2.dist-info/entry_points.txt +0 -4
  533. {crackerjack-0.18.2.dist-info → crackerjack-0.45.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,1031 @@
1
+ """Test template generator for test creation.
2
+
3
+ This module provides comprehensive test template generation for various
4
+ Python code patterns. Uses AgentContext pattern (legacy, intentional).
5
+ """
6
+
7
+ import ast
8
+ from collections.abc import Callable
9
+ from pathlib import Path
10
+ from typing import Any
11
+
12
+ from crackerjack.agents.base import AgentContext
13
+
14
+
15
+ class TestTemplateGenerator:
16
+ """Test template generator for test creation.
17
+
18
+ Uses AgentContext pattern (legacy, intentional).
19
+ """
20
+
21
+ def __init__(self, context: AgentContext) -> None:
22
+ self.context = context
23
+
24
+ async def generate_test_content(
25
+ self,
26
+ module_file: Path,
27
+ functions: list[dict[str, Any]],
28
+ classes: list[dict[str, Any]],
29
+ ) -> str:
30
+ """Generate complete test file content."""
31
+ test_params = self._prepare_test_generation_params(module_file)
32
+ return await self._generate_all_test_types(test_params, functions, classes)
33
+
34
+ async def generate_comprehensive_test_content(
35
+ self,
36
+ test_params: dict[str, Any],
37
+ functions: list[dict[str, Any]],
38
+ classes: list[dict[str, Any]],
39
+ ) -> str:
40
+ """Generate comprehensive test content with all test types."""
41
+ return await self._generate_all_test_types(test_params, functions, classes)
42
+
43
+ def _prepare_test_generation_params(self, module_file: Path) -> dict[str, Any]:
44
+ """Prepare parameters for test generation."""
45
+ module_name = self._get_module_import_path(module_file)
46
+ module_category = self._categorize_module(
47
+ str(module_file.relative_to(self.context.project_path))
48
+ )
49
+ return {
50
+ "module_name": module_name,
51
+ "module_file": module_file,
52
+ "module_category": module_category,
53
+ }
54
+
55
+ async def _generate_all_test_types(
56
+ self,
57
+ test_params: dict[str, Any],
58
+ functions: list[dict[str, Any]],
59
+ classes: list[dict[str, Any]],
60
+ ) -> str:
61
+ """Generate all test types (functions, classes, integration)."""
62
+ base_content = self._generate_enhanced_test_file_header(
63
+ test_params["module_name"],
64
+ test_params["module_file"],
65
+ test_params["module_category"],
66
+ )
67
+
68
+ function_tests = await self._generate_function_tests_content(
69
+ functions, test_params["module_category"]
70
+ )
71
+ class_tests = await self._generate_class_tests_content(
72
+ classes, test_params["module_category"]
73
+ )
74
+ integration_tests = await self._generate_integration_tests_content(
75
+ test_params["module_file"],
76
+ functions,
77
+ classes,
78
+ test_params["module_category"],
79
+ )
80
+
81
+ return base_content + function_tests + class_tests + integration_tests
82
+
83
+ async def _generate_function_tests_content(
84
+ self, functions: list[dict[str, Any]], module_category: str
85
+ ) -> str:
86
+ """Generate test content for all functions."""
87
+ return await self._generate_enhanced_function_tests(functions, module_category)
88
+
89
+ async def _generate_class_tests_content(
90
+ self, classes: list[dict[str, Any]], module_category: str
91
+ ) -> str:
92
+ """Generate test content for all classes."""
93
+ return await self._generate_enhanced_class_tests(classes, module_category)
94
+
95
+ async def _generate_integration_tests_content(
96
+ self,
97
+ module_file: Path,
98
+ functions: list[dict[str, Any]],
99
+ classes: list[dict[str, Any]],
100
+ module_category: str,
101
+ ) -> str:
102
+ """Generate integration test content."""
103
+ return await self._generate_integration_tests(
104
+ module_file, functions, classes, module_category
105
+ )
106
+
107
+ def _generate_enhanced_test_file_header(
108
+ self, module_name: str, module_file: Path, module_category: str
109
+ ) -> str:
110
+ """Generate test file header with imports and class definition."""
111
+ imports = [
112
+ "import pytest",
113
+ "from pathlib import Path",
114
+ "from unittest.mock import Mock, patch, AsyncMock",
115
+ ]
116
+
117
+ if module_category in ("service", "manager", "core"):
118
+ imports.append("import asyncio")
119
+
120
+ if module_category == "agent":
121
+ imports.extend(
122
+ [
123
+ "from crackerjack.agents.base import AgentContext, FixResult, "
124
+ "Issue, IssueType",
125
+ ]
126
+ )
127
+
128
+ imports_str = "\n".join(imports)
129
+
130
+ try:
131
+ content = self.context.get_file_content(module_file) or ""
132
+ tree = ast.parse(content)
133
+
134
+ importable_items = []
135
+ for node in ast.walk(tree):
136
+ if isinstance(node, ast.ClassDef) and not node.name.startswith("_"):
137
+ importable_items.append(node.name)
138
+ elif isinstance(
139
+ node, ast.FunctionDef | ast.AsyncFunctionDef
140
+ ) and not node.name.startswith("_"):
141
+ importable_items.append(node.name)
142
+
143
+ if importable_items:
144
+ specific_imports = (
145
+ f"from {module_name} import {', '.join(importable_items[:10])}"
146
+ )
147
+ else:
148
+ specific_imports = f"import {module_name}"
149
+
150
+ except Exception:
151
+ specific_imports = f"import {module_name}"
152
+
153
+ class_name = f"Test{module_file.stem.replace('_', '').title()}"
154
+
155
+ return (
156
+ f'"""{imports_str}\n'
157
+ f"{specific_imports}\n"
158
+ "\n"
159
+ "\n"
160
+ f"class {class_name}:\n"
161
+ f' """Tests for {module_name}.\n'
162
+ "\n"
163
+ f" This module contains comprehensive tests for {module_name}\n"
164
+ " including:\n"
165
+ " - Basic functionality tests\n"
166
+ " - Edge case validation\n"
167
+ " - Error handling verification\n"
168
+ " - Integration testing\n"
169
+ " - Performance validation (where applicable)\n"
170
+ ' """\n'
171
+ "\n"
172
+ " def test_module_imports_successfully(self):\n"
173
+ ' """Test that the module can be imported without errors."""\n'
174
+ f" import {module_name}\n"
175
+ f" assert {module_name} is not None\n"
176
+ )
177
+
178
+ def _get_module_import_path(self, file_path: Path) -> str:
179
+ """Get module import path from file path."""
180
+ try:
181
+ relative_path = file_path.relative_to(self.context.project_path)
182
+ parts = (*relative_path.parts[:-1], relative_path.stem)
183
+ return ".".join(parts)
184
+ except ValueError:
185
+ return file_path.stem
186
+
187
+ async def generate_function_test(self, func_info: dict[str, Any]) -> str:
188
+ """Generate single function test."""
189
+ func_name = func_info["name"]
190
+ args = func_info.get("args", [])
191
+
192
+ test_template = f"""def test_{func_name}_basic(self):
193
+ \"\"\"Test basic functionality of {func_name}.\"\"\"
194
+ try:
195
+ result = {func_name}({self._generate_default_args(args)})
196
+ assert result is not None or result is None
197
+ except TypeError:
198
+ pytest.skip(
199
+ "Function requires specific arguments - manual implementation needed"
200
+ )
201
+ except Exception as e:
202
+ pytest.fail(f"Unexpected error in {func_name}: {{e}}")"""
203
+
204
+ return test_template
205
+
206
+ async def _generate_enhanced_function_tests(
207
+ self, functions: list[dict[str, Any]], module_category: str
208
+ ) -> str:
209
+ """Generate enhanced function tests with multiple test types."""
210
+ if not functions:
211
+ return ""
212
+
213
+ test_methods = []
214
+ for func in functions:
215
+ func_tests = await self._generate_all_tests_for_function(
216
+ func, module_category
217
+ )
218
+ test_methods.extend(func_tests)
219
+
220
+ return "\n".join(test_methods)
221
+
222
+ async def _generate_all_tests_for_function(
223
+ self, func: dict[str, Any], module_category: str
224
+ ) -> list[str]:
225
+ """Generate all test types for a function."""
226
+ func_tests = []
227
+
228
+ basic_test = await self._generate_basic_function_test(func, module_category)
229
+ func_tests.append(basic_test)
230
+
231
+ additional_tests = await self._generate_conditional_tests_for_function(
232
+ func, module_category
233
+ )
234
+ func_tests.extend(additional_tests)
235
+
236
+ return func_tests
237
+
238
+ async def _generate_conditional_tests_for_function(
239
+ self, func: dict[str, Any], module_category: str
240
+ ) -> list[str]:
241
+ """Generate conditional tests based on function characteristics."""
242
+ tests = []
243
+ args = func.get("args", [])
244
+ func_name = func["name"]
245
+
246
+ if self._should_generate_parametrized_test(args):
247
+ parametrized_test = await self._generate_parametrized_test(
248
+ func, module_category
249
+ )
250
+ tests.append(parametrized_test)
251
+
252
+ error_test = await self._generate_error_handling_test(func, module_category)
253
+ tests.append(error_test)
254
+
255
+ if self._should_generate_edge_case_test(args, func_name):
256
+ edge_test = await self._generate_edge_case_test(func, module_category)
257
+ tests.append(edge_test)
258
+
259
+ return tests
260
+
261
+ def _should_generate_parametrized_test(self, args: list[str]) -> bool:
262
+ """Check if parametrized test should be generated."""
263
+ return len(args) > 1
264
+
265
+ def _should_generate_edge_case_test(self, args: list[str], func_name: str) -> bool:
266
+ """Check if edge case test should be generated."""
267
+ has_multiple_args = len(args) > 2
268
+ is_complex_function = any(
269
+ hint in func_name.lower()
270
+ for hint in ("process", "validate", "parse", "convert")
271
+ )
272
+ return has_multiple_args or is_complex_function
273
+
274
+ async def _generate_basic_function_test(
275
+ self, func: dict[str, Any], module_category: str
276
+ ) -> str:
277
+ """Generate basic function test."""
278
+ func_name = func["name"]
279
+ args = func.get("args", [])
280
+
281
+ template_generator = self._get_test_template_generator(module_category)
282
+ return template_generator(func_name, args)
283
+
284
+ def _get_test_template_generator(
285
+ self, module_category: str
286
+ ) -> Callable[[str, list[str]], str]:
287
+ """Get test template generator based on module category."""
288
+ return {
289
+ "agent": self._generate_agent_test_template,
290
+ "service": self._generate_async_test_template,
291
+ "manager": self._generate_async_test_template,
292
+ }.get(module_category, self._generate_default_test_template)
293
+
294
+ def _generate_agent_test_template(self, func_name: str, args: list[str]) -> str:
295
+ """Generate test template for agent functions."""
296
+ template = (
297
+ " def test_FUNC_NAME_basic_functionality(self):\n"
298
+ ' """Test basic functionality of FUNC_NAME."""\n'
299
+ "\n"
300
+ "\n"
301
+ " try:\n"
302
+ " result = FUNC_NAME(ARGS)\n"
303
+ " assert result is not None or result is None\n"
304
+ " except (TypeError, NotImplementedError) as e:\n"
305
+ + (
306
+ " pytest.skip('Function FUNC_NAME requires manual "
307
+ "implementation: ' + str(e))\n"
308
+ )
309
+ + " except Exception as e:\n"
310
+ " pytest.fail('Unexpected error in FUNC_NAME: ' + str(e))"
311
+ )
312
+
313
+ return template.replace("FUNC_NAME", func_name).replace(
314
+ "ARGS", self._generate_smart_default_args(args)
315
+ )
316
+
317
+ def _generate_async_test_template(self, func_name: str, args: list[str]) -> str:
318
+ """Generate test template for async functions."""
319
+ template = (
320
+ " @pytest.mark.asyncio\n"
321
+ " async def test_FUNC_NAME_basic_functionality(self):\n"
322
+ ' """Test basic functionality of FUNC_NAME."""\n'
323
+ "\n"
324
+ "\n"
325
+ " try:\n"
326
+ " if asyncio.iscoroutinefunction(FUNC_NAME):\n"
327
+ " result = await FUNC_NAME(ARGS)\n"
328
+ " else:\n"
329
+ " result = FUNC_NAME(ARGS)\n"
330
+ " assert result is not None or result is None\n"
331
+ " except (TypeError, NotImplementedError) as e:\n"
332
+ + (
333
+ " pytest.skip('Function FUNC_NAME requires manual "
334
+ "implementation: ' + str(e))\n"
335
+ )
336
+ + " except Exception as e:\n"
337
+ " pytest.fail('Unexpected error in FUNC_NAME: ' + str(e))"
338
+ )
339
+
340
+ return template.replace("FUNC_NAME", func_name).replace(
341
+ "ARGS", self._generate_smart_default_args(args)
342
+ )
343
+
344
+ def _generate_default_test_template(self, func_name: str, args: list[str]) -> str:
345
+ """Generate default test template."""
346
+ template = (
347
+ " def test_FUNC_NAME_basic_functionality(self):\n"
348
+ ' """Test basic functionality of FUNC_NAME."""\n'
349
+ " try:\n"
350
+ " result = FUNC_NAME(ARGS)\n"
351
+ " assert result is not None or result is None\n"
352
+ " except (TypeError, NotImplementedError) as e:\n"
353
+ + (
354
+ " pytest.skip('Function FUNC_NAME requires manual "
355
+ "implementation: ' + str(e))\n"
356
+ )
357
+ + " except Exception as e:\n"
358
+ " pytest.fail('Unexpected error in FUNC_NAME: ' + str(e))"
359
+ )
360
+
361
+ return template.replace("FUNC_NAME", func_name).replace(
362
+ "ARGS", self._generate_smart_default_args(args)
363
+ )
364
+
365
+ async def _generate_parametrized_test(
366
+ self, func: dict[str, Any], module_category: str
367
+ ) -> str:
368
+ """Generate parametrized test."""
369
+ func_name = func["name"]
370
+ args = func.get("args", [])
371
+
372
+ test_cases = self._generate_test_parameters(args)
373
+
374
+ if not test_cases:
375
+ return ""
376
+
377
+ parametrize_decorator = f"@pytest.mark.parametrize({test_cases})"
378
+
379
+ test_template = (
380
+ f" {parametrize_decorator}\n"
381
+ f" def test_{func_name}_with_parameters(self, "
382
+ f"{', '.join(args) if len(args) <= 5 else 'test_input'}):\n"
383
+ f' """Test {func_name} with various parameter combinations."""\n'
384
+ " try:\n"
385
+ f" if len({args}) <= 5:\n"
386
+ f" result = {func_name}({', '.join(args)})\n"
387
+ " else:\n"
388
+ f" result = {func_name}(**test_input)\n"
389
+ "\n"
390
+ " assert result is not None or result is None\n"
391
+ " except (TypeError, ValueError) as expected_error:\n"
392
+ "\n"
393
+ " pass\n"
394
+ " except Exception as e:\n"
395
+ ' pytest.fail(f"Unexpected error with parameters: {e}")'
396
+ )
397
+
398
+ return test_template
399
+
400
+ async def _generate_error_handling_test(
401
+ self, func: dict[str, Any], module_category: str
402
+ ) -> str:
403
+ """Generate error handling test."""
404
+ func_name = func["name"]
405
+ args = func.get("args", [])
406
+
407
+ test_template = (
408
+ f" def test_{func_name}_error_handling(self):\n"
409
+ f' """Test {func_name} error handling with invalid inputs."""\n'
410
+ "\n"
411
+ " with pytest.raises((TypeError, ValueError, AttributeError)):\n"
412
+ f" {func_name}({self._generate_invalid_args(args)})\n"
413
+ "\n"
414
+ "\n"
415
+ f" if len({args}) > 0:\n"
416
+ " with pytest.raises((TypeError, ValueError)):\n"
417
+ f" {func_name}("
418
+ f"{self._generate_edge_case_args(args, 'empty')})"
419
+ )
420
+
421
+ return test_template
422
+
423
+ async def _generate_edge_case_test(
424
+ self, func: dict[str, Any], module_category: str
425
+ ) -> str:
426
+ """Generate edge case test."""
427
+ func_name = func["name"]
428
+ args = func.get("args", [])
429
+
430
+ test_template = (
431
+ f" def test_{func_name}_edge_cases(self):\n"
432
+ f' """Test {func_name} with edge case scenarios."""\n'
433
+ "\n"
434
+ " edge_cases = [\n"
435
+ f" {self._generate_edge_case_args(args, 'boundary')},\n"
436
+ f" {self._generate_edge_case_args(args, 'extreme')},\n"
437
+ " ]\n"
438
+ "\n"
439
+ " for edge_case in edge_cases:\n"
440
+ " try:\n"
441
+ f" result = {func_name}(*edge_case)\n"
442
+ "\n"
443
+ " assert result is not None or result is None\n"
444
+ " except (ValueError, TypeError):\n"
445
+ "\n"
446
+ " pass\n"
447
+ " except Exception as e:\n"
448
+ ' pytest.fail(f"Unexpected error with edge case {edge_case}: '
449
+ '{e}")'
450
+ )
451
+
452
+ return test_template
453
+
454
+ def _generate_test_parameters(self, args: list[str]) -> str:
455
+ """Generate test parameters for parametrized tests."""
456
+ if not args or len(args) > 5:
457
+ return ""
458
+
459
+ param_names = ", ".join(f'"{arg}"' for arg in args)
460
+ param_values = []
461
+
462
+ for i in range(min(3, len(args))):
463
+ test_case = []
464
+ for arg in args:
465
+ if "path" in arg.lower():
466
+ test_case.append(f'Path("test_{i}")')
467
+ elif "str" in arg.lower() or "name" in arg.lower():
468
+ test_case.append(f'"test_{i}"')
469
+ elif "int" in arg.lower() or "count" in arg.lower():
470
+ test_case.append(str(i))
471
+ elif "bool" in arg.lower():
472
+ test_case.append("True" if i % 2 == 0 else "False")
473
+ else:
474
+ test_case.append("None")
475
+ param_values.append(f"({', '.join(test_case)})")
476
+
477
+ return f"[{param_names}], [{', '.join(param_values)}]"
478
+
479
+ def _generate_smart_default_args(self, args: list[str]) -> str:
480
+ """Generate smart default arguments based on arg names."""
481
+ if not args or args == ["self"]:
482
+ return ""
483
+
484
+ filtered_args = self._filter_args(args)
485
+ if not filtered_args:
486
+ return ""
487
+
488
+ placeholders = [
489
+ self._generate_placeholder_for_arg(arg) for arg in filtered_args
490
+ ]
491
+ return ", ".join(placeholders)
492
+
493
+ def _filter_args(self, args: list[str]) -> list[str]:
494
+ """Filter out 'self' from arguments."""
495
+ return [arg for arg in args if arg != "self"]
496
+
497
+ def _generate_placeholder_for_arg(self, arg: str) -> str:
498
+ """Generate placeholder value for argument."""
499
+ arg_lower = arg.lower()
500
+
501
+ if self._is_path_arg(arg_lower):
502
+ return 'Path("test_file.txt")'
503
+ elif self._is_url_arg(arg_lower):
504
+ return '"https: //example.com"'
505
+ elif self._is_email_arg(arg_lower):
506
+ return '"test@example.com"'
507
+ elif self._is_id_arg(arg_lower):
508
+ return '"test-id-123"'
509
+ elif self._is_name_arg(arg_lower):
510
+ return '"test_name"'
511
+ elif self._is_numeric_arg(arg_lower):
512
+ return "10"
513
+ elif self._is_boolean_arg(arg_lower):
514
+ return "True"
515
+ elif self._is_text_arg(arg_lower):
516
+ return '"test data"'
517
+ elif self._is_list_arg(arg_lower):
518
+ return '["test1", "test2"]'
519
+ elif self._is_dict_arg(arg_lower):
520
+ return '{"key": "value"}'
521
+ return '"test"'
522
+
523
+ def _is_path_arg(self, arg_lower: str) -> bool:
524
+ """Check if arg is path-like."""
525
+ return any(term in arg_lower for term in ("path", "file"))
526
+
527
+ def _is_url_arg(self, arg_lower: str) -> bool:
528
+ """Check if arg is URL-like."""
529
+ return any(term in arg_lower for term in ("url", "uri"))
530
+
531
+ def _is_email_arg(self, arg_lower: str) -> bool:
532
+ """Check if arg is email-like."""
533
+ return any(term in arg_lower for term in ("email", "mail"))
534
+
535
+ def _is_id_arg(self, arg_lower: str) -> bool:
536
+ """Check if arg is ID-like."""
537
+ return any(term in arg_lower for term in ("id", "uuid"))
538
+
539
+ def _is_name_arg(self, arg_lower: str) -> bool:
540
+ """Check if arg is name-like."""
541
+ return any(term in arg_lower for term in ("name", "title"))
542
+
543
+ def _is_numeric_arg(self, arg_lower: str) -> bool:
544
+ """Check if arg is numeric."""
545
+ return any(term in arg_lower for term in ("count", "size", "number", "num"))
546
+
547
+ def _is_boolean_arg(self, arg_lower: str) -> bool:
548
+ """Check if arg is boolean."""
549
+ return any(term in arg_lower for term in ("enable", "flag", "is_", "has_"))
550
+
551
+ def _is_text_arg(self, arg_lower: str) -> bool:
552
+ """Check if arg is text-like."""
553
+ return any(term in arg_lower for term in ("data", "content", "text"))
554
+
555
+ def _is_list_arg(self, arg_lower: str) -> bool:
556
+ """Check if arg is list-like."""
557
+ return any(term in arg_lower for term in ("list[t.Any]", "items"))
558
+
559
+ def _is_dict_arg(self, arg_lower: str) -> bool:
560
+ """Check if arg is dict-like."""
561
+ return any(
562
+ term in arg_lower for term in ("dict[str, t.Any]", "config", "options")
563
+ )
564
+
565
+ def _generate_invalid_args(self, args: list[str]) -> str:
566
+ """Generate invalid arguments for error testing."""
567
+ filtered_args = [arg for arg in args if arg != "self"]
568
+ if not filtered_args:
569
+ return ""
570
+ return ", ".join(["None"] * len(filtered_args))
571
+
572
+ def _generate_edge_case_args(self, args: list[str], case_type: str) -> str:
573
+ """Generate edge case arguments."""
574
+ filtered_args = self._filter_args(args)
575
+ if not filtered_args:
576
+ return ""
577
+
578
+ placeholders = self._generate_placeholders_by_case_type(
579
+ filtered_args, case_type
580
+ )
581
+ return ", ".join(placeholders)
582
+
583
+ def _generate_placeholders_by_case_type(
584
+ self, filtered_args: list[str], case_type: str
585
+ ) -> list[str]:
586
+ """Generate placeholders based on case type."""
587
+ if case_type == "empty":
588
+ return self._generate_empty_case_placeholders(filtered_args)
589
+ elif case_type == "boundary":
590
+ return self._generate_boundary_case_placeholders(filtered_args)
591
+
592
+ return self._generate_extreme_case_placeholders(filtered_args)
593
+
594
+ def _generate_empty_case_placeholders(self, filtered_args: list[str]) -> list[str]:
595
+ """Generate empty case placeholders."""
596
+ placeholders = []
597
+ for arg in filtered_args:
598
+ arg_lower = arg.lower()
599
+ if any(term in arg_lower for term in ("str", "name", "text")):
600
+ placeholders.append('""')
601
+ elif any(term in arg_lower for term in ("list[t.Any]", "items")):
602
+ placeholders.append("[]")
603
+ elif any(term in arg_lower for term in ("dict[str, t.Any]", "config")):
604
+ placeholders.append("{}")
605
+ else:
606
+ placeholders.append("None")
607
+ return placeholders
608
+
609
+ def _generate_boundary_case_placeholders(
610
+ self, filtered_args: list[str]
611
+ ) -> list[str]:
612
+ """Generate boundary case placeholders."""
613
+ placeholders = []
614
+ for arg in filtered_args:
615
+ arg_lower = arg.lower()
616
+ if any(term in arg_lower for term in ("count", "size", "number")):
617
+ placeholders.append("0")
618
+ elif any(term in arg_lower for term in ("str", "name")):
619
+ placeholders.append('"x" * 1000')
620
+ else:
621
+ placeholders.append("None")
622
+ return placeholders
623
+
624
+ def _generate_extreme_case_placeholders(
625
+ self, filtered_args: list[str]
626
+ ) -> list[str]:
627
+ """Generate extreme case placeholders."""
628
+ placeholders = []
629
+ for arg in filtered_args:
630
+ arg_lower = arg.lower()
631
+ if any(term in arg_lower for term in ("count", "size", "number")):
632
+ placeholders.append("-1")
633
+ else:
634
+ placeholders.append("None")
635
+ return placeholders
636
+
637
+ async def _generate_enhanced_class_tests(
638
+ self, classes: list[dict[str, Any]], module_category: str
639
+ ) -> str:
640
+ """Generate enhanced class tests."""
641
+ if not classes:
642
+ return ""
643
+
644
+ test_components = await self._generate_all_class_test_components(
645
+ classes, module_category
646
+ )
647
+ return self._combine_class_test_elements(
648
+ test_components["fixtures"], test_components["test_methods"]
649
+ )
650
+
651
+ async def _generate_all_class_test_components(
652
+ self, classes: list[dict[str, Any]], module_category: str
653
+ ) -> dict[str, list[str]]:
654
+ """Generate all class test components."""
655
+ fixtures = []
656
+ test_methods = []
657
+
658
+ for cls in classes:
659
+ class_components = await self._generate_single_class_test_components(
660
+ cls, module_category
661
+ )
662
+ fixtures.extend(class_components["fixtures"])
663
+ test_methods.extend(class_components["test_methods"])
664
+
665
+ return {"fixtures": fixtures, "test_methods": test_methods}
666
+
667
+ async def _generate_single_class_test_components(
668
+ self, cls: dict[str, Any], module_category: str
669
+ ) -> dict[str, list[str]]:
670
+ """Generate test components for single class."""
671
+ fixtures = []
672
+ test_methods = []
673
+ methods = cls.get("methods", [])
674
+
675
+ fixture = await self._generate_class_fixture(cls, module_category)
676
+ if fixture:
677
+ fixtures.append(fixture)
678
+
679
+ core_tests = await self._generate_core_class_tests(
680
+ cls, methods, module_category
681
+ )
682
+ test_methods.extend(core_tests)
683
+
684
+ return {"fixtures": fixtures, "test_methods": test_methods}
685
+
686
+ async def _generate_core_class_tests(
687
+ self, cls: dict[str, Any], methods: list[str], module_category: str
688
+ ) -> list[str]:
689
+ """Generate core class tests."""
690
+ test_methods = []
691
+
692
+ instantiation_test = await self._generate_class_instantiation_test(
693
+ cls, module_category
694
+ )
695
+ test_methods.append(instantiation_test)
696
+
697
+ method_tests = await self._generate_method_tests(
698
+ cls, methods[:5], module_category
699
+ )
700
+ test_methods.extend(method_tests)
701
+
702
+ property_test = await self._generate_class_property_test(cls, module_category)
703
+ if property_test:
704
+ test_methods.append(property_test)
705
+
706
+ return test_methods
707
+
708
+ async def _generate_method_tests(
709
+ self, cls: dict[str, Any], methods: list[str], module_category: str
710
+ ) -> list[str]:
711
+ """Generate tests for class methods."""
712
+ method_tests = []
713
+ for method in methods:
714
+ method_test = await self._generate_class_method_test(
715
+ cls, method, module_category
716
+ )
717
+ method_tests.append(method_test)
718
+ return method_tests
719
+
720
+ def _combine_class_test_elements(
721
+ self, fixtures: list[str], test_methods: list[str]
722
+ ) -> str:
723
+ """Combine class test fixtures and methods."""
724
+ fixture_section = "\n".join(fixtures) if fixtures else ""
725
+ test_section = "\n".join(test_methods)
726
+ return fixture_section + test_section
727
+
728
+ async def _generate_class_fixture(
729
+ self, cls: dict[str, Any], module_category: str
730
+ ) -> str:
731
+ """Generate class fixture."""
732
+ class_name = cls["name"]
733
+
734
+ if module_category in ("service", "manager", "core"):
735
+ fixture_template = (
736
+ " @pytest.fixture\n"
737
+ f" def {class_name.lower()}_instance(self):\n"
738
+ f' """Fixture to create {class_name} instance for testing."""\n'
739
+ "\n"
740
+ " try:\n"
741
+ f" return {class_name}()\n"
742
+ " except TypeError:\n"
743
+ "\n"
744
+ f" with patch.object({class_name}, '__init__', return_value=None):\n"
745
+ f" instance = {class_name}.__new__({class_name})\n"
746
+ " return instance"
747
+ )
748
+
749
+ elif module_category == "agent":
750
+ fixture_template = (
751
+ " @pytest.fixture\n"
752
+ f" def {class_name.lower()}_instance(self):\n"
753
+ f' """Fixture to create {class_name} instance for testing."""\n'
754
+ "\n"
755
+ " mock_context = Mock(spec=AgentContext)\n"
756
+ ' mock_context.project_path = Path("/test/project")\n'
757
+ ' mock_context.get_file_content = Mock(return_value="# test content")\n'
758
+ " mock_context.write_file_content = Mock(return_value=True)\n"
759
+ "\n"
760
+ " try:\n"
761
+ f" return {class_name}(mock_context)\n"
762
+ " except Exception:\n"
763
+ ' pytest.skip("Agent requires specific context configuration")'
764
+ )
765
+
766
+ else:
767
+ fixture_template = (
768
+ " @pytest.fixture\n"
769
+ f" def {class_name.lower()}_instance(self):\n"
770
+ f' """Fixture to create {class_name} instance for testing."""\n'
771
+ " try:\n"
772
+ f" return {class_name}()\n"
773
+ " except TypeError:\n"
774
+ ' pytest.skip("Class requires specific constructor arguments")'
775
+ )
776
+
777
+ return fixture_template
778
+
779
+ @staticmethod
780
+ async def _generate_class_instantiation_test(
781
+ class_info: dict[str, Any], module_category: str
782
+ ) -> str:
783
+ """Generate class instantiation test."""
784
+ class_name = class_info["name"]
785
+
786
+ test_template = (
787
+ f" def test_{class_name.lower()}_instantiation(self, {class_name.lower()}_instance):\n"
788
+ f' """Test successful instantiation of {class_name}."""\n'
789
+ f" assert {class_name.lower()}_instance is not None\n"
790
+ f" assert isinstance({class_name.lower()}_instance, {class_name})\n"
791
+ "\n"
792
+ f" assert hasattr({class_name.lower()}_instance, '__class__')\n"
793
+ f' assert {class_name.lower()}_instance.__class__.__name__ == "{class_name}"'
794
+ )
795
+
796
+ return test_template
797
+
798
+ async def _generate_class_method_test(
799
+ self, cls: dict[str, Any], method_name: str, module_category: str
800
+ ) -> str:
801
+ """Generate test for class method."""
802
+ class_name = cls["name"]
803
+
804
+ if self._is_special_agent_method(module_category, method_name):
805
+ return self._generate_agent_method_test(class_name, method_name)
806
+ if module_category in ("service", "manager"):
807
+ return self._generate_async_method_test(class_name, method_name)
808
+ return self._generate_default_method_test(class_name, method_name)
809
+
810
+ def _is_special_agent_method(self, module_category: str, method_name: str) -> bool:
811
+ """Check if method is special agent method."""
812
+ return module_category == "agent" and method_name in (
813
+ "can_handle",
814
+ "analyze_and_fix",
815
+ )
816
+
817
+ def _generate_agent_method_test(self, class_name: str, method_name: str) -> str:
818
+ """Generate test for agent method."""
819
+ if method_name == "can_handle":
820
+ return self._generate_can_handle_test(class_name)
821
+ elif method_name == "analyze_and_fix":
822
+ return self._generate_analyze_and_fix_test(class_name)
823
+ return self._generate_generic_agent_method_test(class_name, method_name)
824
+
825
+ def _generate_can_handle_test(self, class_name: str) -> str:
826
+ """Generate can_handle test for agent."""
827
+ return (
828
+ " @pytest.mark.asyncio\n"
829
+ f" async def test_{class_name.lower()}_can_handle(self, {class_name.lower()}_instance):\n"
830
+ f' """Test {class_name}.can_handle method."""\n'
831
+ "\n"
832
+ " mock_issue = Mock(spec=Issue)\n"
833
+ " mock_issue.type = IssueType.COVERAGE_IMPROVEMENT\n"
834
+ ' mock_issue.message = "test coverage issue"\n'
835
+ ' mock_issue.file_path = "/test/path.py"\n'
836
+ "\n"
837
+ f" result = await {class_name.lower()}_instance.can_handle(mock_issue)\n"
838
+ " assert isinstance(result, (int, float))\n"
839
+ " assert 0.0 <= result <= 1.0"
840
+ )
841
+
842
+ def _generate_analyze_and_fix_test(self, class_name: str) -> str:
843
+ """Generate analyze_and_fix test for agent."""
844
+ return (
845
+ " @pytest.mark.asyncio\n"
846
+ f" async def test_{class_name.lower()}_analyze_and_fix(self, {class_name.lower()}_instance):\n"
847
+ f' """Test {class_name}.analyze_and_fix method."""\n'
848
+ "\n"
849
+ " mock_issue = Mock(spec=Issue)\n"
850
+ " mock_issue.type = IssueType.COVERAGE_IMPROVEMENT\n"
851
+ ' mock_issue.message = "test coverage issue"\n'
852
+ ' mock_issue.file_path = "/test/path.py"\n'
853
+ "\n"
854
+ f" result = await {class_name.lower()}_instance.analyze_and_fix(mock_issue)\n"
855
+ " assert isinstance(result, FixResult)\n"
856
+ " assert hasattr(result, 'success')\n"
857
+ " assert hasattr(result, 'confidence')"
858
+ )
859
+
860
+ def _generate_generic_agent_method_test(
861
+ self, class_name: str, method_name: str
862
+ ) -> str:
863
+ """Generate generic agent method test."""
864
+ return (
865
+ " @pytest.mark.asyncio\n"
866
+ f" async def test_{class_name.lower()}_{method_name}(self, {class_name.lower()}_instance):\n"
867
+ f' """Test {class_name}.{method_name} method."""\n'
868
+ " try:\n"
869
+ f" method = getattr({class_name.lower()}_instance, "
870
+ f'"{method_name}", None)\n'
871
+ f" assert method is not None, "
872
+ f'f"Method {method_name} should exist"\n'
873
+ "\n"
874
+ " if asyncio.iscoroutinefunction(method):\n"
875
+ " result = await method()\n"
876
+ " else:\n"
877
+ " result = method()\n"
878
+ "\n"
879
+ " assert result is not None or result is None\n"
880
+ " except (TypeError, NotImplementedError):\n"
881
+ f' pytest.skip(f"Method {method_name} requires specific arguments")\n'
882
+ " except Exception as e:\n"
883
+ f' pytest.fail(f"Unexpected error in {method_name}: {{e}}")'
884
+ )
885
+
886
+ def _generate_async_method_test(self, class_name: str, method_name: str) -> str:
887
+ """Generate async method test."""
888
+ return (
889
+ " @pytest.mark.asyncio\n"
890
+ f" async def test_{class_name.lower()}_{method_name}(self, {class_name.lower()}_instance):\n"
891
+ f' """Test {class_name}.{method_name} method."""\n'
892
+ " try:\n"
893
+ f" method = getattr({class_name.lower()}_instance, "
894
+ f'"{method_name}", None)\n'
895
+ f" assert method is not None, "
896
+ f'f"Method {method_name} should exist"\n'
897
+ "\n"
898
+ " if asyncio.iscoroutinefunction(method):\n"
899
+ " result = await method()\n"
900
+ " else:\n"
901
+ " result = method()\n"
902
+ "\n"
903
+ " assert result is not None or result is None\n"
904
+ "\n"
905
+ " except (TypeError, NotImplementedError):\n"
906
+ f' pytest.skip(f"Method {method_name} requires specific arguments or implementation")\n'
907
+ " except Exception as e:\n"
908
+ f' pytest.fail(f"Unexpected error in {method_name}: {{e}}")'
909
+ )
910
+
911
+ def _generate_default_method_test(self, class_name: str, method_name: str) -> str:
912
+ """Generate default method test."""
913
+ return (
914
+ f" def test_{class_name.lower()}_{method_name}(self, {class_name.lower()}_instance):\n"
915
+ f' """Test {class_name}.{method_name} method."""\n'
916
+ " try:\n"
917
+ f" method = getattr({class_name.lower()}_instance, "
918
+ f'"{method_name}", None)\n'
919
+ f" assert method is not None, "
920
+ f'f"Method {method_name} should exist"\n'
921
+ "\n"
922
+ " result = method()\n"
923
+ " assert result is not None or result is None\n"
924
+ "\n"
925
+ " except (TypeError, NotImplementedError):\n"
926
+ f' pytest.skip(f"Method {method_name} requires specific arguments or implementation")\n'
927
+ " except Exception as e:\n"
928
+ f' pytest.fail(f"Unexpected error in {method_name}: {{e}}")'
929
+ )
930
+
931
+ async def _generate_class_property_test(
932
+ self, cls: dict[str, Any], module_category: str
933
+ ) -> str:
934
+ """Generate class property test."""
935
+ class_name = cls["name"]
936
+
937
+ if module_category not in ("service", "manager", "agent"):
938
+ return ""
939
+
940
+ test_template = (
941
+ f" def test_{class_name.lower()}_properties(self, {class_name.lower()}_instance):\n"
942
+ f' """Test {class_name} properties and attributes."""\n'
943
+ "\n"
944
+ f" assert hasattr({class_name.lower()}_instance, '__dict__') or \\\n"
945
+ f" hasattr({class_name.lower()}_instance, '__slots__')\n"
946
+ "\n"
947
+ f" str_repr = str({class_name.lower()}_instance)\n"
948
+ " assert len(str_repr) > 0\n"
949
+ f' assert "{class_name}" in str_repr or "{class_name.lower()}" in \\\n'
950
+ " str_repr.lower()"
951
+ )
952
+
953
+ return test_template
954
+
955
+ async def _generate_integration_tests(
956
+ self,
957
+ module_file: Path,
958
+ functions: list[dict[str, Any]],
959
+ classes: list[dict[str, Any]],
960
+ module_category: str,
961
+ ) -> str:
962
+ """Generate integration tests."""
963
+ if module_category not in ("service", "manager", "core"):
964
+ return ""
965
+
966
+ if len(functions) < 3 and len(classes) < 2:
967
+ return ""
968
+
969
+ integration_tests = (
970
+ "\n\n"
971
+ " @pytest.mark.integration\n"
972
+ f" def test_{module_file.stem}_integration(self):\n"
973
+ f' """Integration test for {module_file.stem} module functionality."""\n'
974
+ "\n"
975
+ ' pytest.skip("Integration test needs manual implementation")\n'
976
+ "\n"
977
+ " @pytest.mark.integration\n"
978
+ " @pytest.mark.asyncio\n"
979
+ f" async def test_{module_file.stem}_async_integration(self):\n"
980
+ f' """Async integration test for {module_file.stem} module."""\n'
981
+ "\n"
982
+ ' pytest.skip("Async integration test needs manual implementation")\n'
983
+ "\n"
984
+ " @pytest.mark.performance\n"
985
+ f" def test_{module_file.stem}_performance(self):\n"
986
+ f' """Basic performance test for {module_file.stem} module."""\n'
987
+ "\n"
988
+ ' pytest.skip("Performance test needs manual implementation")'
989
+ )
990
+
991
+ return integration_tests
992
+
993
+ def _generate_default_args(self, args: list[str]) -> str:
994
+ """Generate default arguments."""
995
+ if not args or args == ["self"]:
996
+ return ""
997
+
998
+ filtered_args = [arg for arg in args if arg != "self"]
999
+ if not filtered_args:
1000
+ return ""
1001
+
1002
+ placeholders = []
1003
+ for arg in filtered_args:
1004
+ if "path" in arg.lower():
1005
+ placeholders.append('Path("test")')
1006
+ elif "str" in arg.lower() or "name" in arg.lower():
1007
+ placeholders.append('"test"')
1008
+ elif "int" in arg.lower() or "count" in arg.lower():
1009
+ placeholders.append("1")
1010
+ elif "bool" in arg.lower():
1011
+ placeholders.append("True")
1012
+ else:
1013
+ placeholders.append("None")
1014
+
1015
+ return ", ".join(placeholders)
1016
+
1017
+ def _categorize_module(self, relative_path: str) -> str:
1018
+ """Categorize module by path."""
1019
+ if "managers/" in relative_path:
1020
+ return "manager"
1021
+ elif "services/" in relative_path:
1022
+ return "service"
1023
+ elif "core/" in relative_path:
1024
+ return "core"
1025
+ elif "agents/" in relative_path:
1026
+ return "agent"
1027
+ elif "models/" in relative_path:
1028
+ return "model"
1029
+ elif "executors/" in relative_path:
1030
+ return "executor"
1031
+ return "utility"