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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/METADATA +7 -6
  2. empathy_framework-4.7.0.dist-info/RECORD +354 -0
  3. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/top_level.txt +0 -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.py +173 -0
  130. empathy_os/workflows/__init__.py +212 -120
  131. empathy_os/workflows/batch_processing.py +8 -24
  132. empathy_os/workflows/bug_predict.py +1 -1
  133. empathy_os/workflows/code_review.py +20 -5
  134. empathy_os/workflows/code_review_pipeline.py +13 -8
  135. empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
  136. empathy_os/workflows/manage_documentation.py +1 -0
  137. empathy_os/workflows/orchestrated_health_check.py +6 -11
  138. empathy_os/workflows/orchestrated_release_prep.py +3 -3
  139. empathy_os/workflows/pr_review.py +18 -10
  140. empathy_os/workflows/progressive/__init__.py +2 -12
  141. empathy_os/workflows/progressive/cli.py +14 -37
  142. empathy_os/workflows/progressive/core.py +12 -12
  143. empathy_os/workflows/progressive/orchestrator.py +166 -144
  144. empathy_os/workflows/progressive/reports.py +22 -31
  145. empathy_os/workflows/progressive/telemetry.py +8 -14
  146. empathy_os/workflows/progressive/test_gen.py +29 -48
  147. empathy_os/workflows/progressive/workflow.py +31 -70
  148. empathy_os/workflows/release_prep.py +21 -6
  149. empathy_os/workflows/release_prep_crew.py +1 -0
  150. empathy_os/workflows/secure_release.py +13 -6
  151. empathy_os/workflows/security_audit.py +8 -3
  152. empathy_os/workflows/test_coverage_boost_crew.py +3 -2
  153. empathy_os/workflows/test_maintenance_crew.py +1 -0
  154. empathy_os/workflows/test_runner.py +16 -12
  155. empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
  156. empathy_software_plugin/cli.py +0 -122
  157. coach_wizards/__init__.py +0 -45
  158. coach_wizards/accessibility_wizard.py +0 -91
  159. coach_wizards/api_wizard.py +0 -91
  160. coach_wizards/base_wizard.py +0 -209
  161. coach_wizards/cicd_wizard.py +0 -91
  162. coach_wizards/code_reviewer_README.md +0 -60
  163. coach_wizards/code_reviewer_wizard.py +0 -180
  164. coach_wizards/compliance_wizard.py +0 -91
  165. coach_wizards/database_wizard.py +0 -91
  166. coach_wizards/debugging_wizard.py +0 -91
  167. coach_wizards/documentation_wizard.py +0 -91
  168. coach_wizards/generate_wizards.py +0 -347
  169. coach_wizards/localization_wizard.py +0 -173
  170. coach_wizards/migration_wizard.py +0 -91
  171. coach_wizards/monitoring_wizard.py +0 -91
  172. coach_wizards/observability_wizard.py +0 -91
  173. coach_wizards/performance_wizard.py +0 -91
  174. coach_wizards/prompt_engineering_wizard.py +0 -661
  175. coach_wizards/refactoring_wizard.py +0 -91
  176. coach_wizards/scaling_wizard.py +0 -90
  177. coach_wizards/security_wizard.py +0 -92
  178. coach_wizards/testing_wizard.py +0 -91
  179. empathy_framework-4.6.6.dist-info/RECORD +0 -410
  180. empathy_llm_toolkit/wizards/__init__.py +0 -43
  181. empathy_llm_toolkit/wizards/base_wizard.py +0 -364
  182. empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
  183. empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
  184. empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
  185. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
  186. empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
  187. empathy_os/wizard_factory_cli.py +0 -170
  188. empathy_software_plugin/wizards/__init__.py +0 -42
  189. empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
  190. empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
  191. empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
  192. empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
  193. empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
  194. empathy_software_plugin/wizards/base_wizard.py +0 -288
  195. empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
  196. empathy_software_plugin/wizards/code_review_wizard.py +0 -604
  197. empathy_software_plugin/wizards/debugging/__init__.py +0 -50
  198. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
  199. empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
  200. empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
  201. empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
  202. empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
  203. empathy_software_plugin/wizards/debugging/verification.py +0 -369
  204. empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
  205. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
  206. empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
  207. empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
  208. empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
  209. empathy_software_plugin/wizards/performance/__init__.py +0 -9
  210. empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
  211. empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
  212. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
  213. empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
  214. empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
  215. empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
  216. empathy_software_plugin/wizards/security/__init__.py +0 -32
  217. empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
  218. empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
  219. empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
  220. empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
  221. empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
  222. empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
  223. empathy_software_plugin/wizards/testing/__init__.py +0 -27
  224. empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
  225. empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
  226. empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
  227. empathy_software_plugin/wizards/testing_wizard.py +0 -274
  228. wizards/__init__.py +0 -82
  229. wizards/admission_assessment_wizard.py +0 -644
  230. wizards/care_plan.py +0 -321
  231. wizards/clinical_assessment.py +0 -769
  232. wizards/discharge_planning.py +0 -77
  233. wizards/discharge_summary_wizard.py +0 -468
  234. wizards/dosage_calculation.py +0 -497
  235. wizards/incident_report_wizard.py +0 -454
  236. wizards/medication_reconciliation.py +0 -85
  237. wizards/nursing_assessment.py +0 -171
  238. wizards/patient_education.py +0 -654
  239. wizards/quality_improvement.py +0 -705
  240. wizards/sbar_report.py +0 -324
  241. wizards/sbar_wizard.py +0 -608
  242. wizards/shift_handoff_wizard.py +0 -535
  243. wizards/soap_note_wizard.py +0 -679
  244. wizards/treatment_plan.py +0 -15
  245. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/WHEEL +0 -0
  246. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/entry_points.txt +0 -0
  247. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.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)