empathy-framework 4.6.6__py3-none-any.whl → 4.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. empathy_framework-4.7.1.dist-info/METADATA +690 -0
  2. empathy_framework-4.7.1.dist-info/RECORD +379 -0
  3. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/top_level.txt +1 -2
  4. empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
  5. empathy_llm_toolkit/agent_factory/__init__.py +6 -6
  6. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
  7. empathy_llm_toolkit/agents_md/__init__.py +22 -0
  8. empathy_llm_toolkit/agents_md/loader.py +218 -0
  9. empathy_llm_toolkit/agents_md/parser.py +271 -0
  10. empathy_llm_toolkit/agents_md/registry.py +307 -0
  11. empathy_llm_toolkit/commands/__init__.py +51 -0
  12. empathy_llm_toolkit/commands/context.py +375 -0
  13. empathy_llm_toolkit/commands/loader.py +301 -0
  14. empathy_llm_toolkit/commands/models.py +231 -0
  15. empathy_llm_toolkit/commands/parser.py +371 -0
  16. empathy_llm_toolkit/commands/registry.py +429 -0
  17. empathy_llm_toolkit/config/__init__.py +8 -8
  18. empathy_llm_toolkit/config/unified.py +3 -7
  19. empathy_llm_toolkit/context/__init__.py +22 -0
  20. empathy_llm_toolkit/context/compaction.py +455 -0
  21. empathy_llm_toolkit/context/manager.py +434 -0
  22. empathy_llm_toolkit/hooks/__init__.py +24 -0
  23. empathy_llm_toolkit/hooks/config.py +306 -0
  24. empathy_llm_toolkit/hooks/executor.py +289 -0
  25. empathy_llm_toolkit/hooks/registry.py +302 -0
  26. empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
  27. empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
  28. empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
  29. empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
  30. empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
  31. empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
  32. empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
  33. empathy_llm_toolkit/learning/__init__.py +30 -0
  34. empathy_llm_toolkit/learning/evaluator.py +438 -0
  35. empathy_llm_toolkit/learning/extractor.py +514 -0
  36. empathy_llm_toolkit/learning/storage.py +560 -0
  37. empathy_llm_toolkit/providers.py +4 -11
  38. empathy_llm_toolkit/security/__init__.py +17 -17
  39. empathy_llm_toolkit/utils/tokens.py +2 -5
  40. empathy_os/__init__.py +202 -70
  41. empathy_os/cache_monitor.py +5 -3
  42. empathy_os/cli/__init__.py +11 -55
  43. empathy_os/cli/__main__.py +29 -15
  44. empathy_os/cli/commands/inspection.py +21 -12
  45. empathy_os/cli/commands/memory.py +4 -12
  46. empathy_os/cli/commands/profiling.py +198 -0
  47. empathy_os/cli/commands/utilities.py +27 -7
  48. empathy_os/cli.py +28 -57
  49. empathy_os/cli_unified.py +525 -1164
  50. empathy_os/cost_tracker.py +9 -3
  51. empathy_os/dashboard/server.py +200 -2
  52. empathy_os/hot_reload/__init__.py +7 -7
  53. empathy_os/hot_reload/config.py +6 -7
  54. empathy_os/hot_reload/integration.py +35 -35
  55. empathy_os/hot_reload/reloader.py +57 -57
  56. empathy_os/hot_reload/watcher.py +28 -28
  57. empathy_os/hot_reload/websocket.py +2 -2
  58. empathy_os/memory/__init__.py +11 -4
  59. empathy_os/memory/claude_memory.py +1 -1
  60. empathy_os/memory/cross_session.py +8 -12
  61. empathy_os/memory/edges.py +6 -6
  62. empathy_os/memory/file_session.py +770 -0
  63. empathy_os/memory/graph.py +30 -30
  64. empathy_os/memory/nodes.py +6 -6
  65. empathy_os/memory/short_term.py +15 -9
  66. empathy_os/memory/unified.py +606 -140
  67. empathy_os/meta_workflows/agent_creator.py +3 -9
  68. empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
  69. empathy_os/meta_workflows/form_engine.py +6 -18
  70. empathy_os/meta_workflows/intent_detector.py +64 -24
  71. empathy_os/meta_workflows/models.py +3 -1
  72. empathy_os/meta_workflows/pattern_learner.py +13 -31
  73. empathy_os/meta_workflows/plan_generator.py +55 -47
  74. empathy_os/meta_workflows/session_context.py +2 -3
  75. empathy_os/meta_workflows/workflow.py +20 -51
  76. empathy_os/models/cli.py +2 -2
  77. empathy_os/models/tasks.py +1 -2
  78. empathy_os/models/telemetry.py +4 -1
  79. empathy_os/models/token_estimator.py +3 -1
  80. empathy_os/monitoring/alerts.py +938 -9
  81. empathy_os/monitoring/alerts_cli.py +346 -183
  82. empathy_os/orchestration/execution_strategies.py +12 -29
  83. empathy_os/orchestration/pattern_learner.py +20 -26
  84. empathy_os/orchestration/real_tools.py +6 -15
  85. empathy_os/platform_utils.py +2 -1
  86. empathy_os/plugins/__init__.py +2 -2
  87. empathy_os/plugins/base.py +64 -64
  88. empathy_os/plugins/registry.py +32 -32
  89. empathy_os/project_index/index.py +49 -15
  90. empathy_os/project_index/models.py +1 -2
  91. empathy_os/project_index/reports.py +1 -1
  92. empathy_os/project_index/scanner.py +1 -0
  93. empathy_os/redis_memory.py +10 -7
  94. empathy_os/resilience/__init__.py +1 -1
  95. empathy_os/resilience/health.py +10 -10
  96. empathy_os/routing/__init__.py +7 -7
  97. empathy_os/routing/chain_executor.py +37 -37
  98. empathy_os/routing/classifier.py +36 -36
  99. empathy_os/routing/smart_router.py +40 -40
  100. empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
  101. empathy_os/scaffolding/__init__.py +8 -8
  102. empathy_os/scaffolding/__main__.py +1 -1
  103. empathy_os/scaffolding/cli.py +28 -28
  104. empathy_os/socratic/__init__.py +3 -19
  105. empathy_os/socratic/ab_testing.py +25 -36
  106. empathy_os/socratic/blueprint.py +38 -38
  107. empathy_os/socratic/cli.py +34 -20
  108. empathy_os/socratic/collaboration.py +30 -28
  109. empathy_os/socratic/domain_templates.py +9 -1
  110. empathy_os/socratic/embeddings.py +17 -13
  111. empathy_os/socratic/engine.py +135 -70
  112. empathy_os/socratic/explainer.py +70 -60
  113. empathy_os/socratic/feedback.py +24 -19
  114. empathy_os/socratic/forms.py +15 -10
  115. empathy_os/socratic/generator.py +51 -35
  116. empathy_os/socratic/llm_analyzer.py +25 -23
  117. empathy_os/socratic/mcp_server.py +99 -159
  118. empathy_os/socratic/session.py +19 -13
  119. empathy_os/socratic/storage.py +98 -67
  120. empathy_os/socratic/success.py +38 -27
  121. empathy_os/socratic/visual_editor.py +51 -39
  122. empathy_os/socratic/web_ui.py +99 -66
  123. empathy_os/telemetry/cli.py +3 -1
  124. empathy_os/telemetry/usage_tracker.py +1 -3
  125. empathy_os/test_generator/__init__.py +3 -3
  126. empathy_os/test_generator/cli.py +28 -28
  127. empathy_os/test_generator/generator.py +64 -66
  128. empathy_os/test_generator/risk_analyzer.py +11 -11
  129. empathy_os/vscode_bridge 2.py +173 -0
  130. empathy_os/vscode_bridge.py +173 -0
  131. empathy_os/workflows/__init__.py +212 -120
  132. empathy_os/workflows/batch_processing.py +8 -24
  133. empathy_os/workflows/bug_predict.py +1 -1
  134. empathy_os/workflows/code_review.py +20 -5
  135. empathy_os/workflows/code_review_pipeline.py +13 -8
  136. empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
  137. empathy_os/workflows/manage_documentation.py +1 -0
  138. empathy_os/workflows/orchestrated_health_check.py +6 -11
  139. empathy_os/workflows/orchestrated_release_prep.py +3 -3
  140. empathy_os/workflows/pr_review.py +18 -10
  141. empathy_os/workflows/progressive/README 2.md +454 -0
  142. empathy_os/workflows/progressive/__init__ 2.py +92 -0
  143. empathy_os/workflows/progressive/__init__.py +2 -12
  144. empathy_os/workflows/progressive/cli 2.py +242 -0
  145. empathy_os/workflows/progressive/cli.py +14 -37
  146. empathy_os/workflows/progressive/core 2.py +488 -0
  147. empathy_os/workflows/progressive/core.py +12 -12
  148. empathy_os/workflows/progressive/orchestrator 2.py +701 -0
  149. empathy_os/workflows/progressive/orchestrator.py +166 -144
  150. empathy_os/workflows/progressive/reports 2.py +528 -0
  151. empathy_os/workflows/progressive/reports.py +22 -31
  152. empathy_os/workflows/progressive/telemetry 2.py +280 -0
  153. empathy_os/workflows/progressive/telemetry.py +8 -14
  154. empathy_os/workflows/progressive/test_gen 2.py +514 -0
  155. empathy_os/workflows/progressive/test_gen.py +29 -48
  156. empathy_os/workflows/progressive/workflow 2.py +628 -0
  157. empathy_os/workflows/progressive/workflow.py +31 -70
  158. empathy_os/workflows/release_prep.py +21 -6
  159. empathy_os/workflows/release_prep_crew.py +1 -0
  160. empathy_os/workflows/secure_release.py +13 -6
  161. empathy_os/workflows/security_audit.py +8 -3
  162. empathy_os/workflows/test_coverage_boost_crew.py +3 -2
  163. empathy_os/workflows/test_maintenance_crew.py +1 -0
  164. empathy_os/workflows/test_runner.py +16 -12
  165. empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
  166. empathy_software_plugin/cli.py +0 -122
  167. patterns/README.md +119 -0
  168. patterns/__init__.py +95 -0
  169. patterns/behavior.py +298 -0
  170. patterns/code_review_memory.json +441 -0
  171. patterns/core.py +97 -0
  172. patterns/debugging.json +3763 -0
  173. patterns/empathy.py +268 -0
  174. patterns/health_check_memory.json +505 -0
  175. patterns/input.py +161 -0
  176. patterns/memory_graph.json +8 -0
  177. patterns/refactoring_memory.json +1113 -0
  178. patterns/registry.py +663 -0
  179. patterns/security_memory.json +8 -0
  180. patterns/structural.py +415 -0
  181. patterns/validation.py +194 -0
  182. coach_wizards/__init__.py +0 -45
  183. coach_wizards/accessibility_wizard.py +0 -91
  184. coach_wizards/api_wizard.py +0 -91
  185. coach_wizards/base_wizard.py +0 -209
  186. coach_wizards/cicd_wizard.py +0 -91
  187. coach_wizards/code_reviewer_README.md +0 -60
  188. coach_wizards/code_reviewer_wizard.py +0 -180
  189. coach_wizards/compliance_wizard.py +0 -91
  190. coach_wizards/database_wizard.py +0 -91
  191. coach_wizards/debugging_wizard.py +0 -91
  192. coach_wizards/documentation_wizard.py +0 -91
  193. coach_wizards/generate_wizards.py +0 -347
  194. coach_wizards/localization_wizard.py +0 -173
  195. coach_wizards/migration_wizard.py +0 -91
  196. coach_wizards/monitoring_wizard.py +0 -91
  197. coach_wizards/observability_wizard.py +0 -91
  198. coach_wizards/performance_wizard.py +0 -91
  199. coach_wizards/prompt_engineering_wizard.py +0 -661
  200. coach_wizards/refactoring_wizard.py +0 -91
  201. coach_wizards/scaling_wizard.py +0 -90
  202. coach_wizards/security_wizard.py +0 -92
  203. coach_wizards/testing_wizard.py +0 -91
  204. empathy_framework-4.6.6.dist-info/METADATA +0 -1597
  205. empathy_framework-4.6.6.dist-info/RECORD +0 -410
  206. empathy_llm_toolkit/wizards/__init__.py +0 -43
  207. empathy_llm_toolkit/wizards/base_wizard.py +0 -364
  208. empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
  209. empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
  210. empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
  211. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
  212. empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
  213. empathy_os/wizard_factory_cli.py +0 -170
  214. empathy_software_plugin/wizards/__init__.py +0 -42
  215. empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
  216. empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
  217. empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
  218. empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
  219. empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
  220. empathy_software_plugin/wizards/base_wizard.py +0 -288
  221. empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
  222. empathy_software_plugin/wizards/code_review_wizard.py +0 -604
  223. empathy_software_plugin/wizards/debugging/__init__.py +0 -50
  224. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
  225. empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
  226. empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
  227. empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
  228. empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
  229. empathy_software_plugin/wizards/debugging/verification.py +0 -369
  230. empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
  231. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
  232. empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
  233. empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
  234. empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
  235. empathy_software_plugin/wizards/performance/__init__.py +0 -9
  236. empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
  237. empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
  238. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
  239. empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
  240. empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
  241. empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
  242. empathy_software_plugin/wizards/security/__init__.py +0 -32
  243. empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
  244. empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
  245. empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
  246. empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
  247. empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
  248. empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
  249. empathy_software_plugin/wizards/testing/__init__.py +0 -27
  250. empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
  251. empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
  252. empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
  253. empathy_software_plugin/wizards/testing_wizard.py +0 -274
  254. wizards/__init__.py +0 -82
  255. wizards/admission_assessment_wizard.py +0 -644
  256. wizards/care_plan.py +0 -321
  257. wizards/clinical_assessment.py +0 -769
  258. wizards/discharge_planning.py +0 -77
  259. wizards/discharge_summary_wizard.py +0 -468
  260. wizards/dosage_calculation.py +0 -497
  261. wizards/incident_report_wizard.py +0 -454
  262. wizards/medication_reconciliation.py +0 -85
  263. wizards/nursing_assessment.py +0 -171
  264. wizards/patient_education.py +0 -654
  265. wizards/quality_improvement.py +0 -705
  266. wizards/sbar_report.py +0 -324
  267. wizards/sbar_wizard.py +0 -608
  268. wizards/shift_handoff_wizard.py +0 -535
  269. wizards/soap_note_wizard.py +0 -679
  270. wizards/treatment_plan.py +0 -15
  271. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/WHEEL +0 -0
  272. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/entry_points.txt +0 -0
  273. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,533 +0,0 @@
1
- """Test Suggester for Enhanced Testing Wizard
2
-
3
- Generates smart test suggestions based on code analysis and coverage gaps.
4
- Uses pattern recognition to suggest high-value tests.
5
-
6
- Copyright 2025 Smart-AI-Memory
7
- Licensed under Fair Source License 0.9
8
- """
9
-
10
- import ast
11
- from dataclasses import dataclass
12
- from enum import Enum
13
- from pathlib import Path
14
-
15
-
16
- class TestPriority(Enum):
17
- """Priority levels for test suggestions"""
18
-
19
- CRITICAL = "critical" # Untested critical paths
20
- HIGH = "high" # Important functionality
21
- MEDIUM = "medium" # Standard coverage
22
- LOW = "low" # Nice to have
23
-
24
-
25
- @dataclass
26
- class TestSuggestion:
27
- """A suggested test to write"""
28
-
29
- target_file: str
30
- target_function: str
31
- target_line: int
32
- test_type: str # "unit", "integration", "edge_case", "error_handling"
33
- priority: TestPriority
34
- suggestion: str # Human-readable description
35
- template: str # Code template
36
- reasoning: str # Why this test is important
37
- estimated_impact: float # Impact on coverage (0-100)
38
-
39
-
40
- @dataclass
41
- class CodeElement:
42
- """Represents a code element that needs testing"""
43
-
44
- name: str
45
- type: str # "function", "class", "method"
46
- file_path: str
47
- line_number: int
48
- is_public: bool
49
- complexity: int # Cyclomatic complexity estimate
50
- has_error_handling: bool
51
- parameters: list[str]
52
- return_type: str | None
53
-
54
-
55
- class TestSuggester:
56
- """Analyzes code to suggest high-value tests.
57
-
58
- Uses static analysis to:
59
- - Identify untested functions
60
- - Detect edge cases
61
- - Find error handling paths
62
- - Suggest integration tests
63
- """
64
-
65
- def __init__(self):
66
- self.critical_patterns = [
67
- "parse",
68
- "validate",
69
- "authenticate",
70
- "authorize",
71
- "save",
72
- "delete",
73
- "update",
74
- "create",
75
- "execute",
76
- "run",
77
- "process",
78
- ]
79
-
80
- def analyze_file(self, file_path: Path) -> list[CodeElement]:
81
- """Analyze a Python file to extract testable elements
82
-
83
- Args:
84
- file_path: Path to Python file
85
-
86
- Returns:
87
- List of CodeElement objects
88
-
89
- Raises:
90
- FileNotFoundError: If file doesn't exist
91
- SyntaxError: If file has syntax errors
92
-
93
- """
94
- if not file_path.exists():
95
- raise FileNotFoundError(f"File not found: {file_path}")
96
-
97
- with open(file_path, encoding="utf-8") as f:
98
- content = f.read()
99
-
100
- try:
101
- tree = ast.parse(content)
102
- except SyntaxError as e:
103
- raise SyntaxError(f"Syntax error in {file_path}: {e}") from e
104
-
105
- return self._extract_code_elements(tree, str(file_path))
106
-
107
- def _extract_code_elements(self, tree: ast.AST, file_path: str) -> list[CodeElement]:
108
- """Extract testable code elements from AST"""
109
- elements = []
110
-
111
- for node in ast.walk(tree):
112
- # Extract functions
113
- if isinstance(node, ast.FunctionDef):
114
- element = self._analyze_function(node, file_path)
115
- elements.append(element)
116
-
117
- # Extract class methods
118
- elif isinstance(node, ast.ClassDef):
119
- for item in node.body:
120
- if isinstance(item, ast.FunctionDef):
121
- element = self._analyze_method(item, node.name, file_path)
122
- elements.append(element)
123
-
124
- return elements
125
-
126
- def _analyze_function(self, node: ast.FunctionDef, file_path: str) -> CodeElement:
127
- """Analyze a function node"""
128
- # Check if public (not starting with _)
129
- is_public = not node.name.startswith("_")
130
-
131
- # Extract parameters
132
- parameters = [arg.arg for arg in node.args.args]
133
-
134
- # Estimate complexity (simple heuristic)
135
- complexity = self._estimate_complexity(node)
136
-
137
- # Check for error handling
138
- has_error_handling = self._has_error_handling(node)
139
-
140
- # Extract return type
141
- return_type = None
142
- if node.returns:
143
- return_type = ast.unparse(node.returns)
144
-
145
- return CodeElement(
146
- name=node.name,
147
- type="function",
148
- file_path=file_path,
149
- line_number=node.lineno,
150
- is_public=is_public,
151
- complexity=complexity,
152
- has_error_handling=has_error_handling,
153
- parameters=parameters,
154
- return_type=return_type,
155
- )
156
-
157
- def _analyze_method(
158
- self,
159
- node: ast.FunctionDef,
160
- class_name: str,
161
- file_path: str,
162
- ) -> CodeElement:
163
- """Analyze a class method"""
164
- element = self._analyze_function(node, file_path)
165
- element.name = f"{class_name}.{node.name}"
166
- element.type = "method"
167
- return element
168
-
169
- def _estimate_complexity(self, node: ast.FunctionDef) -> int:
170
- """Estimate cyclomatic complexity
171
-
172
- Counts decision points: if, for, while, and, or, except
173
- """
174
- complexity = 1 # Base complexity
175
-
176
- for child in ast.walk(node):
177
- if isinstance(child, ast.If | ast.For | ast.While | ast.ExceptHandler):
178
- complexity += 1
179
- elif isinstance(child, ast.BoolOp):
180
- # Count 'and'/'or' operations
181
- complexity += len(child.values) - 1
182
-
183
- return complexity
184
-
185
- def _has_error_handling(self, node: ast.FunctionDef) -> bool:
186
- """Check if function has try/except blocks"""
187
- for child in ast.walk(node):
188
- if isinstance(child, ast.Try):
189
- return True
190
- return False
191
-
192
- def suggest_tests(
193
- self,
194
- code_elements: list[CodeElement],
195
- covered_lines: set[int],
196
- ) -> list[TestSuggestion]:
197
- """Generate test suggestions for code elements
198
-
199
- Args:
200
- code_elements: List of code elements from analysis
201
- covered_lines: Set of line numbers already covered by tests
202
-
203
- Returns:
204
- List of TestSuggestion objects, sorted by priority
205
-
206
- """
207
- suggestions = []
208
-
209
- for element in code_elements:
210
- # Skip private elements unless they're complex
211
- if not element.is_public and element.complexity < 3:
212
- continue
213
-
214
- # Check if already tested
215
- is_covered = element.line_number in covered_lines
216
-
217
- # Generate suggestions based on element characteristics
218
- element_suggestions = self._generate_element_suggestions(element, is_covered)
219
-
220
- suggestions.extend(element_suggestions)
221
-
222
- # Sort by priority and impact
223
- suggestions.sort(key=lambda s: (s.priority.value, -s.estimated_impact))
224
-
225
- return suggestions
226
-
227
- def _generate_element_suggestions(
228
- self,
229
- element: CodeElement,
230
- is_covered: bool,
231
- ) -> list[TestSuggestion]:
232
- """Generate suggestions for a single code element"""
233
- suggestions = []
234
-
235
- # Determine base priority
236
- base_priority = self._determine_priority(element, is_covered)
237
-
238
- # 1. Basic functionality test
239
- if not is_covered:
240
- suggestions.append(self._suggest_basic_test(element, base_priority))
241
-
242
- # 2. Edge case tests
243
- if element.complexity > 2:
244
- suggestions.append(self._suggest_edge_case_tests(element, base_priority))
245
-
246
- # 3. Error handling tests
247
- if element.has_error_handling or self._should_have_error_handling(element):
248
- suggestions.append(self._suggest_error_test(element, base_priority))
249
-
250
- # 4. Parameter validation tests
251
- if len(element.parameters) > 0:
252
- suggestions.append(self._suggest_parameter_tests(element, base_priority))
253
-
254
- return suggestions
255
-
256
- def _determine_priority(self, element: CodeElement, is_covered: bool) -> TestPriority:
257
- """Determine test priority based on element characteristics"""
258
- # Critical if untested and matches critical patterns
259
- if not is_covered:
260
- for pattern in self.critical_patterns:
261
- if pattern in element.name.lower():
262
- return TestPriority.CRITICAL
263
-
264
- # High priority if complex or has error handling
265
- if element.complexity > 5 or element.has_error_handling:
266
- return TestPriority.HIGH if not is_covered else TestPriority.MEDIUM
267
-
268
- # Medium priority if public
269
- if element.is_public:
270
- return TestPriority.MEDIUM if not is_covered else TestPriority.LOW
271
-
272
- return TestPriority.LOW
273
-
274
- def _should_have_error_handling(self, element: CodeElement) -> bool:
275
- """Determine if element should have error handling"""
276
- # Functions that interact with external systems
277
- error_prone_patterns = [
278
- "parse",
279
- "load",
280
- "save",
281
- "fetch",
282
- "request",
283
- "connect",
284
- "execute",
285
- "validate",
286
- "convert",
287
- ]
288
-
289
- return any(pattern in element.name.lower() for pattern in error_prone_patterns)
290
-
291
- def _suggest_basic_test(self, element: CodeElement, priority: TestPriority) -> TestSuggestion:
292
- """Generate basic functionality test suggestion"""
293
- # Generate test template
294
- template = self._generate_basic_template(element)
295
-
296
- # Calculate impact (uncovered function = high impact)
297
- impact = 50.0 if element.is_public else 30.0
298
-
299
- return TestSuggestion(
300
- target_file=element.file_path,
301
- target_function=element.name,
302
- target_line=element.line_number,
303
- test_type="unit",
304
- priority=priority,
305
- suggestion=f"Test basic functionality of {element.name}",
306
- template=template,
307
- reasoning=f"Function {element.name} is currently untested",
308
- estimated_impact=impact,
309
- )
310
-
311
- def _suggest_edge_case_tests(
312
- self,
313
- element: CodeElement,
314
- priority: TestPriority,
315
- ) -> TestSuggestion:
316
- """Generate edge case test suggestions"""
317
- edge_cases = self._identify_edge_cases(element)
318
-
319
- template = self._generate_edge_case_template(element, edge_cases)
320
-
321
- return TestSuggestion(
322
- target_file=element.file_path,
323
- target_function=element.name,
324
- target_line=element.line_number,
325
- test_type="edge_case",
326
- priority=priority,
327
- suggestion=f"Test edge cases: {', '.join(edge_cases)}",
328
- template=template,
329
- reasoning=f"Complex function (complexity {element.complexity}) needs edge case coverage",
330
- estimated_impact=25.0,
331
- )
332
-
333
- def _suggest_error_test(self, element: CodeElement, priority: TestPriority) -> TestSuggestion:
334
- """Generate error handling test suggestion"""
335
- template = self._generate_error_template(element)
336
-
337
- return TestSuggestion(
338
- target_file=element.file_path,
339
- target_function=element.name,
340
- target_line=element.line_number,
341
- test_type="error_handling",
342
- priority=priority,
343
- suggestion=f"Test error handling for {element.name}",
344
- template=template,
345
- reasoning="Function should handle errors gracefully",
346
- estimated_impact=20.0,
347
- )
348
-
349
- def _suggest_parameter_tests(
350
- self,
351
- element: CodeElement,
352
- priority: TestPriority,
353
- ) -> TestSuggestion:
354
- """Generate parameter validation test suggestion"""
355
- template = self._generate_parameter_template(element)
356
-
357
- return TestSuggestion(
358
- target_file=element.file_path,
359
- target_function=element.name,
360
- target_line=element.line_number,
361
- test_type="unit",
362
- priority=priority,
363
- suggestion="Test with various parameter combinations",
364
- template=template,
365
- reasoning=f"Function takes {len(element.parameters)} parameters - test combinations",
366
- estimated_impact=15.0,
367
- )
368
-
369
- def _identify_edge_cases(self, element: CodeElement) -> list[str]:
370
- """Identify likely edge cases based on function name and parameters"""
371
- edge_cases = []
372
-
373
- name_lower = element.name.lower()
374
-
375
- # List/collection operations
376
- if any(word in name_lower for word in ["list", "array", "collection"]):
377
- edge_cases.extend(["empty list", "single item", "large list"])
378
-
379
- # String operations
380
- if any(word in name_lower for word in ["string", "text", "name"]):
381
- edge_cases.extend(["empty string", "unicode", "very long string"])
382
-
383
- # Numeric operations
384
- if any(word in name_lower for word in ["count", "size", "number", "calculate"]):
385
- edge_cases.extend(["zero", "negative", "very large number"])
386
-
387
- # File/path operations
388
- if any(word in name_lower for word in ["file", "path", "directory"]):
389
- edge_cases.extend(["nonexistent path", "invalid path", "permissions"])
390
-
391
- # Default edge cases
392
- if not edge_cases:
393
- edge_cases = ["None input", "invalid type", "boundary values"]
394
-
395
- return edge_cases[:3] # Limit to top 3
396
-
397
- def _generate_basic_template(self, element: CodeElement) -> str:
398
- """Generate basic test template"""
399
- func_name = element.name.split(".")[-1] # Get last part for methods
400
- test_name = f"test_{func_name}_basic"
401
-
402
- # Generate parameter examples
403
- params = []
404
- for param in element.parameters:
405
- if param in ["self", "cls"]:
406
- continue
407
- params.append(f"{param}=...") # Placeholder
408
-
409
- param_str = ", ".join(params) if params else ""
410
-
411
- template = f"""
412
- def {test_name}():
413
- '''Test basic functionality of {element.name}'''
414
- # Arrange
415
- {param_str}
416
-
417
- # Act
418
- result = {element.name}({param_str})
419
-
420
- # Assert
421
- assert result is not None
422
- # TODO: Add specific assertions
423
- """
424
- return template.strip()
425
-
426
- def _generate_edge_case_template(self, element: CodeElement, edge_cases: list[str]) -> str:
427
- """Generate edge case test template"""
428
- func_name = element.name.split(".")[-1]
429
- test_name = f"test_{func_name}_edge_cases"
430
-
431
- cases_str = "\n # - ".join(edge_cases)
432
-
433
- template = f"""
434
- def {test_name}():
435
- '''Test edge cases for {element.name}'''
436
- # Edge cases to test:
437
- # - {cases_str}
438
-
439
- # Test case 1: {edge_cases[0]}
440
- # TODO: Implement test
441
-
442
- # Test case 2: {edge_cases[1] if len(edge_cases) > 1 else "Add more"}
443
- # TODO: Implement test
444
- """
445
- return template.strip()
446
-
447
- def _generate_error_template(self, element: CodeElement) -> str:
448
- """Generate error handling test template"""
449
- func_name = element.name.split(".")[-1]
450
- test_name = f"test_{func_name}_error_handling"
451
-
452
- template = f"""
453
- def {test_name}():
454
- '''Test error handling for {element.name}'''
455
- # Test invalid input
456
- with pytest.raises(ValueError):
457
- {element.name}(invalid_input)
458
-
459
- # Test None input
460
- with pytest.raises(TypeError):
461
- {element.name}(None)
462
-
463
- # TODO: Add more error cases
464
- """
465
- return template.strip()
466
-
467
- def _generate_parameter_template(self, element: CodeElement) -> str:
468
- """Generate parameter validation test template"""
469
- func_name = element.name.split(".")[-1]
470
- test_name = f"test_{func_name}_parameters"
471
-
472
- params_str = ", ".join(p for p in element.parameters if p not in ["self", "cls"])
473
-
474
- template = f"""
475
- @pytest.mark.parametrize("{params_str}", [
476
- # Add test cases here
477
- # Example: (value1, value2, expected_result)
478
- ])
479
- def {test_name}({params_str}):
480
- '''Test {element.name} with various parameter combinations'''
481
- result = {element.name}({params_str})
482
- # TODO: Add assertions
483
- """
484
- return template.strip()
485
-
486
- def generate_summary(self, suggestions: list[TestSuggestion]) -> str:
487
- """Generate human-readable suggestions summary"""
488
- if not suggestions:
489
- return "No test suggestions - coverage looks good!"
490
-
491
- summary = []
492
- summary.append("=" * 60)
493
- summary.append("TEST SUGGESTIONS")
494
- summary.append("=" * 60)
495
-
496
- # Group by priority
497
- by_priority: dict[TestPriority, list[TestSuggestion]] = {
498
- TestPriority.CRITICAL: [],
499
- TestPriority.HIGH: [],
500
- TestPriority.MEDIUM: [],
501
- TestPriority.LOW: [],
502
- }
503
-
504
- for suggestion in suggestions:
505
- by_priority[suggestion.priority].append(suggestion)
506
-
507
- # Display by priority
508
- for priority in [TestPriority.CRITICAL, TestPriority.HIGH, TestPriority.MEDIUM]:
509
- suggestions_list = by_priority[priority]
510
- if not suggestions_list:
511
- continue
512
-
513
- icon = {"critical": "🔴", "high": "🟡", "medium": "🔵"}
514
- summary.append(f"\n{icon[priority.value]} {priority.value.upper()} Priority:")
515
-
516
- for i, sug in enumerate(suggestions_list[:5], 1):
517
- summary.append(f"\n{i}. {sug.suggestion}")
518
- summary.append(f" File: {sug.target_file}:{sug.target_line}")
519
- summary.append(f" Type: {sug.test_type}")
520
- summary.append(f" Impact: +{sug.estimated_impact:.1f}% coverage")
521
- summary.append(f" Reason: {sug.reasoning}")
522
-
523
- if len(suggestions_list) > 5:
524
- summary.append(f"\n ... and {len(suggestions_list) - 5} more")
525
-
526
- summary.append("\n" + "=" * 60)
527
- summary.append(f"Total Suggestions: {len(suggestions)}")
528
- summary.append(f" Critical: {len(by_priority[TestPriority.CRITICAL])}")
529
- summary.append(f" High: {len(by_priority[TestPriority.HIGH])}")
530
- summary.append(f" Medium: {len(by_priority[TestPriority.MEDIUM])}")
531
- summary.append("=" * 60)
532
-
533
- return "\n".join(summary)