fishertools 0.2.1__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fishertools/__init__.py +16 -5
- fishertools/errors/__init__.py +11 -3
- fishertools/errors/exception_types.py +282 -0
- fishertools/errors/explainer.py +87 -1
- fishertools/errors/models.py +73 -1
- fishertools/errors/patterns.py +40 -0
- fishertools/examples/cli_example.py +156 -0
- fishertools/examples/learn_example.py +65 -0
- fishertools/examples/logger_example.py +176 -0
- fishertools/examples/menu_example.py +101 -0
- fishertools/examples/storage_example.py +175 -0
- fishertools/input_utils.py +185 -0
- fishertools/learn/__init__.py +19 -2
- fishertools/learn/examples.py +88 -1
- fishertools/learn/knowledge_engine.py +321 -0
- fishertools/learn/repl/__init__.py +19 -0
- fishertools/learn/repl/cli.py +31 -0
- fishertools/learn/repl/code_sandbox.py +229 -0
- fishertools/learn/repl/command_handler.py +544 -0
- fishertools/learn/repl/command_parser.py +165 -0
- fishertools/learn/repl/engine.py +479 -0
- fishertools/learn/repl/models.py +121 -0
- fishertools/learn/repl/session_manager.py +284 -0
- fishertools/learn/repl/test_code_sandbox.py +261 -0
- fishertools/learn/repl/test_code_sandbox_pbt.py +148 -0
- fishertools/learn/repl/test_command_handler.py +224 -0
- fishertools/learn/repl/test_command_handler_pbt.py +189 -0
- fishertools/learn/repl/test_command_parser.py +160 -0
- fishertools/learn/repl/test_command_parser_pbt.py +100 -0
- fishertools/learn/repl/test_engine.py +190 -0
- fishertools/learn/repl/test_session_manager.py +310 -0
- fishertools/learn/repl/test_session_manager_pbt.py +182 -0
- fishertools/learn/test_knowledge_engine.py +241 -0
- fishertools/learn/test_knowledge_engine_pbt.py +180 -0
- fishertools/patterns/__init__.py +46 -0
- fishertools/patterns/cli.py +175 -0
- fishertools/patterns/logger.py +140 -0
- fishertools/patterns/menu.py +99 -0
- fishertools/patterns/storage.py +127 -0
- fishertools/readme_transformer.py +631 -0
- fishertools/safe/__init__.py +6 -1
- fishertools/safe/files.py +329 -1
- fishertools/transform_readme.py +105 -0
- fishertools-0.4.0.dist-info/METADATA +104 -0
- fishertools-0.4.0.dist-info/RECORD +131 -0
- {fishertools-0.2.1.dist-info → fishertools-0.4.0.dist-info}/WHEEL +1 -1
- tests/test_documentation_properties.py +329 -0
- tests/test_documentation_structure.py +349 -0
- tests/test_errors/test_exception_types.py +446 -0
- tests/test_errors/test_exception_types_pbt.py +333 -0
- tests/test_errors/test_patterns.py +52 -0
- tests/test_input_utils/__init__.py +1 -0
- tests/test_input_utils/test_input_utils.py +65 -0
- tests/test_learn/test_examples.py +179 -1
- tests/test_learn/test_explain_properties.py +307 -0
- tests/test_patterns_cli.py +611 -0
- tests/test_patterns_docstrings.py +473 -0
- tests/test_patterns_logger.py +465 -0
- tests/test_patterns_menu.py +440 -0
- tests/test_patterns_storage.py +447 -0
- tests/test_readme_enhancements_v0_3_1.py +2036 -0
- tests/test_readme_transformer/__init__.py +1 -0
- tests/test_readme_transformer/test_readme_infrastructure.py +1023 -0
- tests/test_readme_transformer/test_transform_readme_integration.py +431 -0
- tests/test_safe/test_files.py +726 -1
- fishertools-0.2.1.dist-info/METADATA +0 -256
- fishertools-0.2.1.dist-info/RECORD +0 -81
- {fishertools-0.2.1.dist-info → fishertools-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {fishertools-0.2.1.dist-info → fishertools-0.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for exception type identification module.
|
|
3
|
+
|
|
4
|
+
Tests the exception type identification functionality including:
|
|
5
|
+
- Identifying exception types from exception objects
|
|
6
|
+
- Getting exception type information
|
|
7
|
+
- Checking if exception types are supported
|
|
8
|
+
- Retrieving exception type mappings
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
from fishertools.errors.exception_types import (
|
|
13
|
+
identify_exception_type,
|
|
14
|
+
get_exception_type_info,
|
|
15
|
+
is_supported_exception_type,
|
|
16
|
+
get_exception_type_mapping,
|
|
17
|
+
get_supported_exception_types,
|
|
18
|
+
ExceptionTypeInfo,
|
|
19
|
+
EXCEPTION_TYPE_MAPPING
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TestIdentifyExceptionType:
|
|
24
|
+
"""Tests for identify_exception_type function."""
|
|
25
|
+
|
|
26
|
+
def test_identify_type_error(self):
|
|
27
|
+
"""Test identifying TypeError."""
|
|
28
|
+
exc = TypeError("unsupported operand type")
|
|
29
|
+
assert identify_exception_type(exc) == "TypeError"
|
|
30
|
+
|
|
31
|
+
def test_identify_value_error(self):
|
|
32
|
+
"""Test identifying ValueError."""
|
|
33
|
+
exc = ValueError("invalid literal for int()")
|
|
34
|
+
assert identify_exception_type(exc) == "ValueError"
|
|
35
|
+
|
|
36
|
+
def test_identify_index_error(self):
|
|
37
|
+
"""Test identifying IndexError."""
|
|
38
|
+
exc = IndexError("list index out of range")
|
|
39
|
+
assert identify_exception_type(exc) == "IndexError"
|
|
40
|
+
|
|
41
|
+
def test_identify_key_error(self):
|
|
42
|
+
"""Test identifying KeyError."""
|
|
43
|
+
exc = KeyError("missing_key")
|
|
44
|
+
assert identify_exception_type(exc) == "KeyError"
|
|
45
|
+
|
|
46
|
+
def test_identify_attribute_error(self):
|
|
47
|
+
"""Test identifying AttributeError."""
|
|
48
|
+
exc = AttributeError("'str' object has no attribute 'append'")
|
|
49
|
+
assert identify_exception_type(exc) == "AttributeError"
|
|
50
|
+
|
|
51
|
+
def test_identify_file_not_found_error(self):
|
|
52
|
+
"""Test identifying FileNotFoundError."""
|
|
53
|
+
exc = FileNotFoundError("No such file or directory")
|
|
54
|
+
assert identify_exception_type(exc) == "FileNotFoundError"
|
|
55
|
+
|
|
56
|
+
def test_identify_permission_error(self):
|
|
57
|
+
"""Test identifying PermissionError."""
|
|
58
|
+
exc = PermissionError("Permission denied")
|
|
59
|
+
assert identify_exception_type(exc) == "PermissionError"
|
|
60
|
+
|
|
61
|
+
def test_identify_zero_division_error(self):
|
|
62
|
+
"""Test identifying ZeroDivisionError."""
|
|
63
|
+
exc = ZeroDivisionError("division by zero")
|
|
64
|
+
assert identify_exception_type(exc) == "ZeroDivisionError"
|
|
65
|
+
|
|
66
|
+
def test_identify_name_error(self):
|
|
67
|
+
"""Test identifying NameError."""
|
|
68
|
+
exc = NameError("name 'undefined_var' is not defined")
|
|
69
|
+
assert identify_exception_type(exc) == "NameError"
|
|
70
|
+
|
|
71
|
+
def test_identify_unknown_exception(self):
|
|
72
|
+
"""Test identifying unknown exception type."""
|
|
73
|
+
class CustomException(Exception):
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
exc = CustomException("custom error")
|
|
77
|
+
assert identify_exception_type(exc) == "CustomException"
|
|
78
|
+
|
|
79
|
+
def test_identify_with_non_exception_raises_type_error(self):
|
|
80
|
+
"""Test that non-Exception objects raise TypeError."""
|
|
81
|
+
with pytest.raises(TypeError):
|
|
82
|
+
identify_exception_type("not an exception")
|
|
83
|
+
|
|
84
|
+
with pytest.raises(TypeError):
|
|
85
|
+
identify_exception_type(42)
|
|
86
|
+
|
|
87
|
+
with pytest.raises(TypeError):
|
|
88
|
+
identify_exception_type(None)
|
|
89
|
+
|
|
90
|
+
def test_identify_with_exception_subclass(self):
|
|
91
|
+
"""Test identifying exception subclasses."""
|
|
92
|
+
# FileNotFoundError is a subclass of OSError
|
|
93
|
+
exc = FileNotFoundError("file not found")
|
|
94
|
+
assert identify_exception_type(exc) == "FileNotFoundError"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TestGetExceptionTypeInfo:
|
|
98
|
+
"""Tests for get_exception_type_info function."""
|
|
99
|
+
|
|
100
|
+
def test_get_info_type_error(self):
|
|
101
|
+
"""Test getting info for TypeError."""
|
|
102
|
+
exc = TypeError("unsupported operand type")
|
|
103
|
+
info = get_exception_type_info(exc)
|
|
104
|
+
|
|
105
|
+
assert isinstance(info, ExceptionTypeInfo)
|
|
106
|
+
assert info.name == "TypeError"
|
|
107
|
+
assert info.exception_class == TypeError
|
|
108
|
+
assert "Type mismatch" in info.description
|
|
109
|
+
assert len(info.common_causes) > 0
|
|
110
|
+
|
|
111
|
+
def test_get_info_value_error(self):
|
|
112
|
+
"""Test getting info for ValueError."""
|
|
113
|
+
exc = ValueError("invalid literal")
|
|
114
|
+
info = get_exception_type_info(exc)
|
|
115
|
+
|
|
116
|
+
assert info.name == "ValueError"
|
|
117
|
+
assert info.exception_class == ValueError
|
|
118
|
+
assert "Invalid value" in info.description
|
|
119
|
+
|
|
120
|
+
def test_get_info_index_error(self):
|
|
121
|
+
"""Test getting info for IndexError."""
|
|
122
|
+
exc = IndexError("list index out of range")
|
|
123
|
+
info = get_exception_type_info(exc)
|
|
124
|
+
|
|
125
|
+
assert info.name == "IndexError"
|
|
126
|
+
assert "Sequence index" in info.description
|
|
127
|
+
|
|
128
|
+
def test_get_info_key_error(self):
|
|
129
|
+
"""Test getting info for KeyError."""
|
|
130
|
+
exc = KeyError("missing_key")
|
|
131
|
+
info = get_exception_type_info(exc)
|
|
132
|
+
|
|
133
|
+
assert info.name == "KeyError"
|
|
134
|
+
assert "Dictionary key" in info.description
|
|
135
|
+
|
|
136
|
+
def test_get_info_attribute_error(self):
|
|
137
|
+
"""Test getting info for AttributeError."""
|
|
138
|
+
exc = AttributeError("'str' object has no attribute 'append'")
|
|
139
|
+
info = get_exception_type_info(exc)
|
|
140
|
+
|
|
141
|
+
assert info.name == "AttributeError"
|
|
142
|
+
assert "Attribute or method" in info.description
|
|
143
|
+
|
|
144
|
+
def test_get_info_file_not_found_error(self):
|
|
145
|
+
"""Test getting info for FileNotFoundError."""
|
|
146
|
+
exc = FileNotFoundError("No such file")
|
|
147
|
+
info = get_exception_type_info(exc)
|
|
148
|
+
|
|
149
|
+
assert info.name == "FileNotFoundError"
|
|
150
|
+
assert "File or directory" in info.description
|
|
151
|
+
|
|
152
|
+
def test_get_info_permission_error(self):
|
|
153
|
+
"""Test getting info for PermissionError."""
|
|
154
|
+
exc = PermissionError("Permission denied")
|
|
155
|
+
info = get_exception_type_info(exc)
|
|
156
|
+
|
|
157
|
+
assert info.name == "PermissionError"
|
|
158
|
+
assert "Permission denied" in info.description
|
|
159
|
+
|
|
160
|
+
def test_get_info_zero_division_error(self):
|
|
161
|
+
"""Test getting info for ZeroDivisionError."""
|
|
162
|
+
exc = ZeroDivisionError("division by zero")
|
|
163
|
+
info = get_exception_type_info(exc)
|
|
164
|
+
|
|
165
|
+
assert info.name == "ZeroDivisionError"
|
|
166
|
+
assert "Division by zero" in info.description
|
|
167
|
+
|
|
168
|
+
def test_get_info_name_error(self):
|
|
169
|
+
"""Test getting info for NameError."""
|
|
170
|
+
exc = NameError("name 'x' is not defined")
|
|
171
|
+
info = get_exception_type_info(exc)
|
|
172
|
+
|
|
173
|
+
assert info.name == "NameError"
|
|
174
|
+
assert "Name not defined" in info.description
|
|
175
|
+
|
|
176
|
+
def test_get_info_unknown_exception(self):
|
|
177
|
+
"""Test getting info for unknown exception type."""
|
|
178
|
+
class CustomException(Exception):
|
|
179
|
+
pass
|
|
180
|
+
|
|
181
|
+
exc = CustomException("custom error")
|
|
182
|
+
info = get_exception_type_info(exc)
|
|
183
|
+
|
|
184
|
+
assert info.name == "CustomException"
|
|
185
|
+
assert info.exception_class == CustomException
|
|
186
|
+
assert "unexpected error" in info.description.lower()
|
|
187
|
+
|
|
188
|
+
def test_get_info_with_non_exception_raises_type_error(self):
|
|
189
|
+
"""Test that non-Exception objects raise TypeError."""
|
|
190
|
+
with pytest.raises(TypeError):
|
|
191
|
+
get_exception_type_info("not an exception")
|
|
192
|
+
|
|
193
|
+
with pytest.raises(TypeError):
|
|
194
|
+
get_exception_type_info(42)
|
|
195
|
+
|
|
196
|
+
def test_info_has_common_causes(self):
|
|
197
|
+
"""Test that exception info includes common causes."""
|
|
198
|
+
exc = TypeError("unsupported operand type")
|
|
199
|
+
info = get_exception_type_info(exc)
|
|
200
|
+
|
|
201
|
+
assert isinstance(info.common_causes, list)
|
|
202
|
+
assert len(info.common_causes) > 0
|
|
203
|
+
assert all(isinstance(cause, str) for cause in info.common_causes)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class TestIsSupportedExceptionType:
|
|
207
|
+
"""Tests for is_supported_exception_type function."""
|
|
208
|
+
|
|
209
|
+
def test_supported_type_error(self):
|
|
210
|
+
"""Test that TypeError is supported."""
|
|
211
|
+
exc = TypeError("unsupported operand type")
|
|
212
|
+
assert is_supported_exception_type(exc) is True
|
|
213
|
+
|
|
214
|
+
def test_supported_value_error(self):
|
|
215
|
+
"""Test that ValueError is supported."""
|
|
216
|
+
exc = ValueError("invalid literal")
|
|
217
|
+
assert is_supported_exception_type(exc) is True
|
|
218
|
+
|
|
219
|
+
def test_supported_index_error(self):
|
|
220
|
+
"""Test that IndexError is supported."""
|
|
221
|
+
exc = IndexError("list index out of range")
|
|
222
|
+
assert is_supported_exception_type(exc) is True
|
|
223
|
+
|
|
224
|
+
def test_supported_key_error(self):
|
|
225
|
+
"""Test that KeyError is supported."""
|
|
226
|
+
exc = KeyError("missing_key")
|
|
227
|
+
assert is_supported_exception_type(exc) is True
|
|
228
|
+
|
|
229
|
+
def test_supported_attribute_error(self):
|
|
230
|
+
"""Test that AttributeError is supported."""
|
|
231
|
+
exc = AttributeError("'str' object has no attribute 'append'")
|
|
232
|
+
assert is_supported_exception_type(exc) is True
|
|
233
|
+
|
|
234
|
+
def test_supported_file_not_found_error(self):
|
|
235
|
+
"""Test that FileNotFoundError is supported."""
|
|
236
|
+
exc = FileNotFoundError("No such file")
|
|
237
|
+
assert is_supported_exception_type(exc) is True
|
|
238
|
+
|
|
239
|
+
def test_supported_permission_error(self):
|
|
240
|
+
"""Test that PermissionError is supported."""
|
|
241
|
+
exc = PermissionError("Permission denied")
|
|
242
|
+
assert is_supported_exception_type(exc) is True
|
|
243
|
+
|
|
244
|
+
def test_supported_zero_division_error(self):
|
|
245
|
+
"""Test that ZeroDivisionError is supported."""
|
|
246
|
+
exc = ZeroDivisionError("division by zero")
|
|
247
|
+
assert is_supported_exception_type(exc) is True
|
|
248
|
+
|
|
249
|
+
def test_supported_name_error(self):
|
|
250
|
+
"""Test that NameError is supported."""
|
|
251
|
+
exc = NameError("name 'x' is not defined")
|
|
252
|
+
assert is_supported_exception_type(exc) is True
|
|
253
|
+
|
|
254
|
+
def test_unsupported_custom_exception(self):
|
|
255
|
+
"""Test that custom exceptions are not supported."""
|
|
256
|
+
class CustomException(Exception):
|
|
257
|
+
pass
|
|
258
|
+
|
|
259
|
+
exc = CustomException("custom error")
|
|
260
|
+
assert is_supported_exception_type(exc) is False
|
|
261
|
+
|
|
262
|
+
def test_unsupported_runtime_error(self):
|
|
263
|
+
"""Test that RuntimeError is not in supported list."""
|
|
264
|
+
exc = RuntimeError("runtime error")
|
|
265
|
+
assert is_supported_exception_type(exc) is False
|
|
266
|
+
|
|
267
|
+
def test_is_supported_with_non_exception_raises_type_error(self):
|
|
268
|
+
"""Test that non-Exception objects raise TypeError."""
|
|
269
|
+
with pytest.raises(TypeError):
|
|
270
|
+
is_supported_exception_type("not an exception")
|
|
271
|
+
|
|
272
|
+
with pytest.raises(TypeError):
|
|
273
|
+
is_supported_exception_type(42)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
class TestGetExceptionTypeMapping:
|
|
277
|
+
"""Tests for get_exception_type_mapping function."""
|
|
278
|
+
|
|
279
|
+
def test_mapping_is_dict(self):
|
|
280
|
+
"""Test that mapping returns a dictionary."""
|
|
281
|
+
mapping = get_exception_type_mapping()
|
|
282
|
+
assert isinstance(mapping, dict)
|
|
283
|
+
|
|
284
|
+
def test_mapping_contains_all_supported_types(self):
|
|
285
|
+
"""Test that mapping contains all supported exception types."""
|
|
286
|
+
mapping = get_exception_type_mapping()
|
|
287
|
+
|
|
288
|
+
expected_types = [
|
|
289
|
+
TypeError, ValueError, IndexError, KeyError, AttributeError,
|
|
290
|
+
FileNotFoundError, PermissionError, ZeroDivisionError, NameError
|
|
291
|
+
]
|
|
292
|
+
|
|
293
|
+
for exc_type in expected_types:
|
|
294
|
+
assert exc_type in mapping
|
|
295
|
+
|
|
296
|
+
def test_mapping_values_are_exception_type_info(self):
|
|
297
|
+
"""Test that all mapping values are ExceptionTypeInfo instances."""
|
|
298
|
+
mapping = get_exception_type_mapping()
|
|
299
|
+
|
|
300
|
+
for exc_type, info in mapping.items():
|
|
301
|
+
assert isinstance(info, ExceptionTypeInfo)
|
|
302
|
+
assert info.exception_class == exc_type
|
|
303
|
+
|
|
304
|
+
def test_mapping_is_copy(self):
|
|
305
|
+
"""Test that returned mapping is a copy, not the original."""
|
|
306
|
+
mapping1 = get_exception_type_mapping()
|
|
307
|
+
mapping2 = get_exception_type_mapping()
|
|
308
|
+
|
|
309
|
+
# Should be equal but not the same object
|
|
310
|
+
assert mapping1 == mapping2
|
|
311
|
+
assert mapping1 is not mapping2
|
|
312
|
+
|
|
313
|
+
def test_mapping_has_correct_structure(self):
|
|
314
|
+
"""Test that mapping entries have correct structure."""
|
|
315
|
+
mapping = get_exception_type_mapping()
|
|
316
|
+
|
|
317
|
+
for exc_type, info in mapping.items():
|
|
318
|
+
assert hasattr(info, 'exception_class')
|
|
319
|
+
assert hasattr(info, 'name')
|
|
320
|
+
assert hasattr(info, 'description')
|
|
321
|
+
assert hasattr(info, 'common_causes')
|
|
322
|
+
|
|
323
|
+
assert isinstance(info.name, str)
|
|
324
|
+
assert isinstance(info.description, str)
|
|
325
|
+
assert isinstance(info.common_causes, list)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
class TestGetSupportedExceptionTypes:
|
|
329
|
+
"""Tests for get_supported_exception_types function."""
|
|
330
|
+
|
|
331
|
+
def test_returns_list(self):
|
|
332
|
+
"""Test that function returns a list."""
|
|
333
|
+
types = get_supported_exception_types()
|
|
334
|
+
assert isinstance(types, list)
|
|
335
|
+
|
|
336
|
+
def test_contains_all_supported_types(self):
|
|
337
|
+
"""Test that list contains all supported exception type names."""
|
|
338
|
+
types = get_supported_exception_types()
|
|
339
|
+
|
|
340
|
+
expected_names = [
|
|
341
|
+
"TypeError", "ValueError", "IndexError", "KeyError", "AttributeError",
|
|
342
|
+
"FileNotFoundError", "PermissionError", "ZeroDivisionError", "NameError"
|
|
343
|
+
]
|
|
344
|
+
|
|
345
|
+
for name in expected_names:
|
|
346
|
+
assert name in types
|
|
347
|
+
|
|
348
|
+
def test_all_items_are_strings(self):
|
|
349
|
+
"""Test that all items in the list are strings."""
|
|
350
|
+
types = get_supported_exception_types()
|
|
351
|
+
assert all(isinstance(t, str) for t in types)
|
|
352
|
+
|
|
353
|
+
def test_no_duplicates(self):
|
|
354
|
+
"""Test that there are no duplicate exception type names."""
|
|
355
|
+
types = get_supported_exception_types()
|
|
356
|
+
assert len(types) == len(set(types))
|
|
357
|
+
|
|
358
|
+
def test_correct_count(self):
|
|
359
|
+
"""Test that the list has the correct number of supported types."""
|
|
360
|
+
types = get_supported_exception_types()
|
|
361
|
+
# Should have 9 supported exception types
|
|
362
|
+
assert len(types) == 9
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class TestExceptionTypeMapping:
|
|
366
|
+
"""Tests for the EXCEPTION_TYPE_MAPPING constant."""
|
|
367
|
+
|
|
368
|
+
def test_mapping_exists(self):
|
|
369
|
+
"""Test that EXCEPTION_TYPE_MAPPING is defined."""
|
|
370
|
+
assert EXCEPTION_TYPE_MAPPING is not None
|
|
371
|
+
assert isinstance(EXCEPTION_TYPE_MAPPING, dict)
|
|
372
|
+
|
|
373
|
+
def test_mapping_has_all_types(self):
|
|
374
|
+
"""Test that mapping has all expected exception types."""
|
|
375
|
+
expected_types = [
|
|
376
|
+
TypeError, ValueError, IndexError, KeyError, AttributeError,
|
|
377
|
+
FileNotFoundError, PermissionError, ZeroDivisionError, NameError
|
|
378
|
+
]
|
|
379
|
+
|
|
380
|
+
for exc_type in expected_types:
|
|
381
|
+
assert exc_type in EXCEPTION_TYPE_MAPPING
|
|
382
|
+
|
|
383
|
+
def test_mapping_values_are_info_objects(self):
|
|
384
|
+
"""Test that all values are ExceptionTypeInfo objects."""
|
|
385
|
+
for exc_type, info in EXCEPTION_TYPE_MAPPING.items():
|
|
386
|
+
assert isinstance(info, ExceptionTypeInfo)
|
|
387
|
+
assert info.exception_class == exc_type
|
|
388
|
+
assert isinstance(info.name, str)
|
|
389
|
+
assert isinstance(info.description, str)
|
|
390
|
+
assert isinstance(info.common_causes, list)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
class TestExceptionTypeIdentificationIntegration:
|
|
394
|
+
"""Integration tests for exception type identification."""
|
|
395
|
+
|
|
396
|
+
def test_identify_and_get_info_consistency(self):
|
|
397
|
+
"""Test that identify_exception_type and get_exception_type_info are consistent."""
|
|
398
|
+
exceptions = [
|
|
399
|
+
TypeError("test"),
|
|
400
|
+
ValueError("test"),
|
|
401
|
+
IndexError("test"),
|
|
402
|
+
KeyError("test"),
|
|
403
|
+
AttributeError("test"),
|
|
404
|
+
FileNotFoundError("test"),
|
|
405
|
+
PermissionError("test"),
|
|
406
|
+
ZeroDivisionError("test"),
|
|
407
|
+
NameError("test"),
|
|
408
|
+
]
|
|
409
|
+
|
|
410
|
+
for exc in exceptions:
|
|
411
|
+
exc_type_name = identify_exception_type(exc)
|
|
412
|
+
info = get_exception_type_info(exc)
|
|
413
|
+
|
|
414
|
+
assert exc_type_name == info.name
|
|
415
|
+
|
|
416
|
+
def test_supported_check_consistency(self):
|
|
417
|
+
"""Test that is_supported_exception_type is consistent with mapping."""
|
|
418
|
+
mapping = get_exception_type_mapping()
|
|
419
|
+
|
|
420
|
+
for exc_type in mapping.keys():
|
|
421
|
+
exc = exc_type("test")
|
|
422
|
+
assert is_supported_exception_type(exc) is True
|
|
423
|
+
|
|
424
|
+
def test_all_supported_types_in_list(self):
|
|
425
|
+
"""Test that all supported types are in the supported types list."""
|
|
426
|
+
supported_list = get_supported_exception_types()
|
|
427
|
+
mapping = get_exception_type_mapping()
|
|
428
|
+
|
|
429
|
+
for info in mapping.values():
|
|
430
|
+
assert info.name in supported_list
|
|
431
|
+
|
|
432
|
+
def test_exception_type_info_completeness(self):
|
|
433
|
+
"""Test that all exception type info objects are complete."""
|
|
434
|
+
mapping = get_exception_type_mapping()
|
|
435
|
+
|
|
436
|
+
for exc_type, info in mapping.items():
|
|
437
|
+
# Check all required fields are present and non-empty
|
|
438
|
+
assert info.exception_class is not None
|
|
439
|
+
assert info.name and len(info.name) > 0
|
|
440
|
+
assert info.description and len(info.description) > 0
|
|
441
|
+
assert info.common_causes and len(info.common_causes) > 0
|
|
442
|
+
|
|
443
|
+
# Check all common causes are non-empty strings
|
|
444
|
+
for cause in info.common_causes:
|
|
445
|
+
assert isinstance(cause, str)
|
|
446
|
+
assert len(cause) > 0
|