code-abyss 1.5.1
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.
- package/LICENSE +21 -0
- package/README.md +197 -0
- package/bin/install.js +193 -0
- package/bin/uninstall.js +42 -0
- package/config/AGENTS.md +247 -0
- package/config/CLAUDE.md +207 -0
- package/config/settings.example.json +27 -0
- package/output-styles/abyss-cultivator.md +399 -0
- package/package.json +41 -0
- package/skills/SKILL.md +115 -0
- package/skills/ai/SKILL.md +29 -0
- package/skills/ai/agent-dev.md +242 -0
- package/skills/ai/llm-security.md +288 -0
- package/skills/architecture/SKILL.md +41 -0
- package/skills/architecture/api-design.md +225 -0
- package/skills/architecture/caching.md +299 -0
- package/skills/architecture/cloud-native.md +285 -0
- package/skills/architecture/compliance.md +299 -0
- package/skills/architecture/data-security.md +184 -0
- package/skills/architecture/message-queue.md +329 -0
- package/skills/architecture/security-arch.md +210 -0
- package/skills/development/SKILL.md +43 -0
- package/skills/development/cpp.md +246 -0
- package/skills/development/go.md +323 -0
- package/skills/development/java.md +277 -0
- package/skills/development/python.md +288 -0
- package/skills/development/rust.md +313 -0
- package/skills/development/shell.md +313 -0
- package/skills/development/typescript.md +277 -0
- package/skills/devops/SKILL.md +36 -0
- package/skills/devops/cost-optimization.md +272 -0
- package/skills/devops/database.md +217 -0
- package/skills/devops/devsecops.md +198 -0
- package/skills/devops/git-workflow.md +181 -0
- package/skills/devops/observability.md +280 -0
- package/skills/devops/performance.md +273 -0
- package/skills/devops/testing.md +186 -0
- package/skills/gen-docs/SKILL.md +114 -0
- package/skills/gen-docs/scripts/doc_generator.py +491 -0
- package/skills/multi-agent/SKILL.md +268 -0
- package/skills/run_skill.py +88 -0
- package/skills/security/SKILL.md +51 -0
- package/skills/security/blue-team.md +379 -0
- package/skills/security/code-audit.md +265 -0
- package/skills/security/pentest.md +226 -0
- package/skills/security/red-team.md +321 -0
- package/skills/security/threat-intel.md +322 -0
- package/skills/security/vuln-research.md +369 -0
- package/skills/tests/README.md +225 -0
- package/skills/tests/SUMMARY.md +362 -0
- package/skills/tests/__init__.py +3 -0
- package/skills/tests/test_change_analyzer.py +558 -0
- package/skills/tests/test_doc_generator.py +538 -0
- package/skills/tests/test_module_scanner.py +376 -0
- package/skills/tests/test_quality_checker.py +516 -0
- package/skills/tests/test_security_scanner.py +426 -0
- package/skills/verify-change/SKILL.md +138 -0
- package/skills/verify-change/scripts/change_analyzer.py +529 -0
- package/skills/verify-module/SKILL.md +125 -0
- package/skills/verify-module/scripts/module_scanner.py +321 -0
- package/skills/verify-quality/SKILL.md +158 -0
- package/skills/verify-quality/scripts/quality_checker.py +481 -0
- package/skills/verify-security/SKILL.md +141 -0
- package/skills/verify-security/scripts/security_scanner.py +368 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
verify-module 单元测试
|
|
4
|
+
测试模块结构扫描器功能
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import unittest
|
|
8
|
+
import tempfile
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
# 添加 skills 目录到 Python 路径
|
|
13
|
+
sys.path.insert(0, str(Path(__file__).parent.parent / "verify-module" / "scripts"))
|
|
14
|
+
|
|
15
|
+
from module_scanner import (
|
|
16
|
+
Severity, Issue, ScanResult, scan_module, scan_structure,
|
|
17
|
+
check_required_files, check_source_dirs, check_test_dirs,
|
|
18
|
+
check_doc_quality, format_report
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TestModuleScanner(unittest.TestCase):
|
|
23
|
+
"""模块扫描器测试"""
|
|
24
|
+
|
|
25
|
+
def setUp(self):
|
|
26
|
+
"""测试前准备"""
|
|
27
|
+
self.temp_dir = tempfile.TemporaryDirectory()
|
|
28
|
+
self.temp_path = Path(self.temp_dir.name)
|
|
29
|
+
|
|
30
|
+
def tearDown(self):
|
|
31
|
+
"""测试后清理"""
|
|
32
|
+
self.temp_dir.cleanup()
|
|
33
|
+
|
|
34
|
+
def test_scan_module_nonexistent_path(self):
|
|
35
|
+
"""测试不存在的路径"""
|
|
36
|
+
nonexistent = self.temp_path / "nonexistent"
|
|
37
|
+
|
|
38
|
+
result = scan_module(str(nonexistent))
|
|
39
|
+
|
|
40
|
+
self.assertFalse(result.passed)
|
|
41
|
+
self.assertTrue(any(i.severity == Severity.ERROR for i in result.issues))
|
|
42
|
+
|
|
43
|
+
def test_scan_module_file_not_directory(self):
|
|
44
|
+
"""测试文件而非目录"""
|
|
45
|
+
test_file = self.temp_path / "test.txt"
|
|
46
|
+
test_file.write_text("test")
|
|
47
|
+
|
|
48
|
+
result = scan_module(str(test_file))
|
|
49
|
+
|
|
50
|
+
self.assertFalse(result.passed)
|
|
51
|
+
self.assertTrue(any(i.severity == Severity.ERROR for i in result.issues))
|
|
52
|
+
|
|
53
|
+
def test_scan_module_missing_readme(self):
|
|
54
|
+
"""测试缺少 README.md"""
|
|
55
|
+
result = scan_module(str(self.temp_path))
|
|
56
|
+
|
|
57
|
+
self.assertFalse(result.passed)
|
|
58
|
+
self.assertTrue(any("README.md" in i.message for i in result.issues))
|
|
59
|
+
|
|
60
|
+
def test_scan_module_missing_design(self):
|
|
61
|
+
"""测试缺少 DESIGN.md"""
|
|
62
|
+
(self.temp_path / "README.md").write_text("# Test Module\n\nThis is a test module.")
|
|
63
|
+
|
|
64
|
+
result = scan_module(str(self.temp_path))
|
|
65
|
+
|
|
66
|
+
self.assertFalse(result.passed)
|
|
67
|
+
self.assertTrue(any("DESIGN.md" in i.message for i in result.issues))
|
|
68
|
+
|
|
69
|
+
def test_scan_module_with_required_files(self):
|
|
70
|
+
"""测试包含必需文件"""
|
|
71
|
+
(self.temp_path / "README.md").write_text("# Test Module\n\nThis is a test module.")
|
|
72
|
+
(self.temp_path / "DESIGN.md").write_text("# Design\n\nDesign decisions.")
|
|
73
|
+
|
|
74
|
+
result = scan_module(str(self.temp_path))
|
|
75
|
+
|
|
76
|
+
# 应该没有关于缺少文档的错误
|
|
77
|
+
self.assertTrue(not any("缺少必需文档" in i.message for i in result.issues))
|
|
78
|
+
|
|
79
|
+
def test_scan_module_with_src_directory(self):
|
|
80
|
+
"""测试包含 src 目录"""
|
|
81
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
82
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
83
|
+
(self.temp_path / "src").mkdir()
|
|
84
|
+
(self.temp_path / "src" / "main.py").write_text("print('hello')")
|
|
85
|
+
|
|
86
|
+
result = scan_module(str(self.temp_path))
|
|
87
|
+
|
|
88
|
+
# 应该没有关于缺少源码目录的警告
|
|
89
|
+
self.assertTrue(not any("未找到源码目录" in i.message for i in result.issues))
|
|
90
|
+
|
|
91
|
+
def test_scan_module_with_tests_directory(self):
|
|
92
|
+
"""测试包含 tests 目录"""
|
|
93
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
94
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
95
|
+
(self.temp_path / "tests").mkdir()
|
|
96
|
+
(self.temp_path / "tests" / "test_main.py").write_text("import unittest")
|
|
97
|
+
|
|
98
|
+
result = scan_module(str(self.temp_path))
|
|
99
|
+
|
|
100
|
+
# 应该没有关于缺少测试目录的警告
|
|
101
|
+
self.assertTrue(not any("未找到测试目录" in i.message for i in result.issues))
|
|
102
|
+
|
|
103
|
+
def test_scan_module_with_alternative_src_dirs(self):
|
|
104
|
+
"""测试替代源码目录名称"""
|
|
105
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
106
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
107
|
+
|
|
108
|
+
# 测试 lib 目录
|
|
109
|
+
(self.temp_path / "lib").mkdir()
|
|
110
|
+
(self.temp_path / "lib" / "main.py").write_text("print('hello')")
|
|
111
|
+
|
|
112
|
+
result = scan_module(str(self.temp_path))
|
|
113
|
+
|
|
114
|
+
self.assertTrue(not any("未找到源码目录" in i.message for i in result.issues))
|
|
115
|
+
|
|
116
|
+
def test_scan_module_with_alternative_test_dirs(self):
|
|
117
|
+
"""测试替代测试目录名称"""
|
|
118
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
119
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
120
|
+
|
|
121
|
+
# 测试 __tests__ 目录
|
|
122
|
+
(self.temp_path / "__tests__").mkdir()
|
|
123
|
+
(self.temp_path / "__tests__" / "test.py").write_text("import unittest")
|
|
124
|
+
|
|
125
|
+
result = scan_module(str(self.temp_path))
|
|
126
|
+
|
|
127
|
+
self.assertTrue(not any("未找到测试目录" in i.message for i in result.issues))
|
|
128
|
+
|
|
129
|
+
def test_scan_module_with_root_code_files(self):
|
|
130
|
+
"""测试根目录代码文件"""
|
|
131
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
132
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
133
|
+
(self.temp_path / "main.py").write_text("print('hello')")
|
|
134
|
+
|
|
135
|
+
result = scan_module(str(self.temp_path))
|
|
136
|
+
|
|
137
|
+
# 应该没有关于缺少源码的警告
|
|
138
|
+
self.assertTrue(not any("未找到源码目录" in i.message for i in result.issues))
|
|
139
|
+
|
|
140
|
+
def test_scan_module_with_root_shell_script_files(self):
|
|
141
|
+
"""测试根目录 shell 脚本识别为源码"""
|
|
142
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
143
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
144
|
+
(self.temp_path / "install.sh").write_text("#!/usr/bin/env bash\necho ok")
|
|
145
|
+
|
|
146
|
+
result = scan_module(str(self.temp_path))
|
|
147
|
+
|
|
148
|
+
self.assertTrue(not any("未找到源码目录" in i.message for i in result.issues))
|
|
149
|
+
|
|
150
|
+
def test_scan_module_with_root_powershell_script_files(self):
|
|
151
|
+
"""测试根目录 PowerShell 脚本识别为源码"""
|
|
152
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
153
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
154
|
+
(self.temp_path / "install.ps1").write_text("Write-Host 'ok'")
|
|
155
|
+
|
|
156
|
+
result = scan_module(str(self.temp_path))
|
|
157
|
+
|
|
158
|
+
self.assertTrue(not any("未找到源码目录" in i.message for i in result.issues))
|
|
159
|
+
|
|
160
|
+
def test_scan_module_too_many_root_files(self):
|
|
161
|
+
"""测试根目录文件过多"""
|
|
162
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
163
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
164
|
+
|
|
165
|
+
# 创建多个根目录代码文件
|
|
166
|
+
for i in range(10):
|
|
167
|
+
(self.temp_path / f"file{i}.py").write_text("print('hello')")
|
|
168
|
+
|
|
169
|
+
result = scan_module(str(self.temp_path))
|
|
170
|
+
|
|
171
|
+
self.assertTrue(any("根目录代码文件过多" in i.message for i in result.issues))
|
|
172
|
+
|
|
173
|
+
def test_scan_module_small_readme(self):
|
|
174
|
+
"""测试内容过少的 README"""
|
|
175
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
176
|
+
(self.temp_path / "DESIGN.md").write_text("# Design\n\nDesign content here.")
|
|
177
|
+
|
|
178
|
+
result = scan_module(str(self.temp_path))
|
|
179
|
+
|
|
180
|
+
self.assertTrue(any("文档内容过少" in i.message for i in result.issues))
|
|
181
|
+
|
|
182
|
+
def test_scan_module_readme_without_title(self):
|
|
183
|
+
"""测试 README 缺少标题"""
|
|
184
|
+
(self.temp_path / "README.md").write_text("This is content without title.")
|
|
185
|
+
(self.temp_path / "DESIGN.md").write_text("# Design\n\nDesign content here.")
|
|
186
|
+
|
|
187
|
+
result = scan_module(str(self.temp_path))
|
|
188
|
+
|
|
189
|
+
self.assertTrue(any("缺少标题" in i.message for i in result.issues))
|
|
190
|
+
|
|
191
|
+
def test_scan_module_readme_without_usage(self):
|
|
192
|
+
"""测试 README 缺少使用说明"""
|
|
193
|
+
(self.temp_path / "README.md").write_text("# Test Module\n\nThis is a test module.")
|
|
194
|
+
(self.temp_path / "DESIGN.md").write_text("# Design\n\nDesign content here.")
|
|
195
|
+
|
|
196
|
+
result = scan_module(str(self.temp_path))
|
|
197
|
+
|
|
198
|
+
self.assertTrue(any("建议添加使用说明" in i.message for i in result.issues))
|
|
199
|
+
|
|
200
|
+
def test_scan_module_design_without_decisions(self):
|
|
201
|
+
"""测试 DESIGN 缺少设计决策"""
|
|
202
|
+
(self.temp_path / "README.md").write_text("# Test\n\nUsage: test")
|
|
203
|
+
(self.temp_path / "DESIGN.md").write_text("# Design\n\nSome content.")
|
|
204
|
+
|
|
205
|
+
result = scan_module(str(self.temp_path))
|
|
206
|
+
|
|
207
|
+
self.assertTrue(any("建议记录设计决策" in i.message for i in result.issues))
|
|
208
|
+
|
|
209
|
+
def test_scan_structure_basic(self):
|
|
210
|
+
"""测试目录结构扫描"""
|
|
211
|
+
(self.temp_path / "file1.py").write_text("x = 1")
|
|
212
|
+
(self.temp_path / "subdir").mkdir()
|
|
213
|
+
(self.temp_path / "subdir" / "file2.py").write_text("y = 2")
|
|
214
|
+
|
|
215
|
+
structure = scan_structure(self.temp_path)
|
|
216
|
+
|
|
217
|
+
self.assertEqual(structure["type"], "dir")
|
|
218
|
+
self.assertTrue(len(structure["children"]) > 0)
|
|
219
|
+
|
|
220
|
+
def test_scan_structure_ignores_hidden_files(self):
|
|
221
|
+
"""测试忽略隐藏文件"""
|
|
222
|
+
(self.temp_path / ".hidden").write_text("hidden")
|
|
223
|
+
(self.temp_path / "visible.py").write_text("visible")
|
|
224
|
+
|
|
225
|
+
structure = scan_structure(self.temp_path)
|
|
226
|
+
|
|
227
|
+
# 隐藏文件应该被忽略
|
|
228
|
+
names = [c["name"] for c in structure["children"]]
|
|
229
|
+
self.assertNotIn(".hidden", names)
|
|
230
|
+
self.assertIn("visible.py", names)
|
|
231
|
+
|
|
232
|
+
def test_scan_result_passed_property(self):
|
|
233
|
+
"""测试 ScanResult.passed 属性"""
|
|
234
|
+
result = ScanResult(module_path="/test")
|
|
235
|
+
|
|
236
|
+
# 没有错误时应该通过
|
|
237
|
+
self.assertTrue(result.passed)
|
|
238
|
+
|
|
239
|
+
# 添加警告
|
|
240
|
+
result.issues.append(Issue(
|
|
241
|
+
severity=Severity.WARNING,
|
|
242
|
+
message="test warning"
|
|
243
|
+
))
|
|
244
|
+
self.assertTrue(result.passed)
|
|
245
|
+
|
|
246
|
+
# 添加错误
|
|
247
|
+
result.issues.append(Issue(
|
|
248
|
+
severity=Severity.ERROR,
|
|
249
|
+
message="test error"
|
|
250
|
+
))
|
|
251
|
+
self.assertFalse(result.passed)
|
|
252
|
+
|
|
253
|
+
def test_scan_result_error_count(self):
|
|
254
|
+
"""测试错误计数"""
|
|
255
|
+
result = ScanResult(module_path="/test")
|
|
256
|
+
|
|
257
|
+
result.issues.append(Issue(severity=Severity.ERROR, message="error1"))
|
|
258
|
+
result.issues.append(Issue(severity=Severity.ERROR, message="error2"))
|
|
259
|
+
result.issues.append(Issue(severity=Severity.WARNING, message="warning"))
|
|
260
|
+
|
|
261
|
+
self.assertEqual(result.error_count, 2)
|
|
262
|
+
self.assertEqual(result.warning_count, 1)
|
|
263
|
+
|
|
264
|
+
def test_format_report_basic(self):
|
|
265
|
+
"""测试报告格式化"""
|
|
266
|
+
result = ScanResult(module_path="/test/module")
|
|
267
|
+
|
|
268
|
+
report = format_report(result)
|
|
269
|
+
|
|
270
|
+
self.assertIn("模块完整性扫描报告", report)
|
|
271
|
+
self.assertIn("/test/module", report)
|
|
272
|
+
|
|
273
|
+
def test_format_report_with_issues(self):
|
|
274
|
+
"""测试包含问题的报告"""
|
|
275
|
+
result = ScanResult(module_path="/test/module")
|
|
276
|
+
result.issues.append(Issue(
|
|
277
|
+
severity=Severity.ERROR,
|
|
278
|
+
message="缺少必需文档: README.md",
|
|
279
|
+
path="/test/module/README.md"
|
|
280
|
+
))
|
|
281
|
+
|
|
282
|
+
report = format_report(result, verbose=True)
|
|
283
|
+
|
|
284
|
+
self.assertIn("缺少必需文档", report)
|
|
285
|
+
self.assertIn("README.md", report)
|
|
286
|
+
|
|
287
|
+
def test_issue_dataclass(self):
|
|
288
|
+
"""测试 Issue 数据类"""
|
|
289
|
+
issue = Issue(
|
|
290
|
+
severity=Severity.WARNING,
|
|
291
|
+
message="test message",
|
|
292
|
+
path="/test/path"
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
self.assertEqual(issue.severity, Severity.WARNING)
|
|
296
|
+
self.assertEqual(issue.message, "test message")
|
|
297
|
+
self.assertEqual(issue.path, "/test/path")
|
|
298
|
+
|
|
299
|
+
def test_severity_enum(self):
|
|
300
|
+
"""测试 Severity 枚举"""
|
|
301
|
+
self.assertEqual(Severity.ERROR.value, "error")
|
|
302
|
+
self.assertEqual(Severity.WARNING.value, "warning")
|
|
303
|
+
self.assertEqual(Severity.INFO.value, "info")
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
class TestModuleScannerEdgeCases(unittest.TestCase):
|
|
307
|
+
"""模块扫描器边界条件测试"""
|
|
308
|
+
|
|
309
|
+
def setUp(self):
|
|
310
|
+
"""测试前准备"""
|
|
311
|
+
self.temp_dir = tempfile.TemporaryDirectory()
|
|
312
|
+
self.temp_path = Path(self.temp_dir.name)
|
|
313
|
+
|
|
314
|
+
def tearDown(self):
|
|
315
|
+
"""测试后清理"""
|
|
316
|
+
self.temp_dir.cleanup()
|
|
317
|
+
|
|
318
|
+
def test_scan_module_deeply_nested(self):
|
|
319
|
+
"""测试深层嵌套结构"""
|
|
320
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
321
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
322
|
+
|
|
323
|
+
deep_path = self.temp_path / "a" / "b" / "c" / "d"
|
|
324
|
+
deep_path.mkdir(parents=True)
|
|
325
|
+
(deep_path / "file.py").write_text("x = 1")
|
|
326
|
+
|
|
327
|
+
result = scan_module(str(self.temp_path))
|
|
328
|
+
|
|
329
|
+
self.assertIsInstance(result, ScanResult)
|
|
330
|
+
|
|
331
|
+
def test_scan_module_with_special_characters(self):
|
|
332
|
+
"""测试包含特殊字符的文件名"""
|
|
333
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
334
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
335
|
+
(self.temp_path / "文件.py").write_text("x = 1")
|
|
336
|
+
|
|
337
|
+
result = scan_module(str(self.temp_path))
|
|
338
|
+
|
|
339
|
+
self.assertIsInstance(result, ScanResult)
|
|
340
|
+
|
|
341
|
+
def test_scan_module_with_symlinks(self):
|
|
342
|
+
"""测试包含符号链接"""
|
|
343
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
344
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
345
|
+
(self.temp_path / "src").mkdir()
|
|
346
|
+
(self.temp_path / "src" / "main.py").write_text("x = 1")
|
|
347
|
+
|
|
348
|
+
result = scan_module(str(self.temp_path))
|
|
349
|
+
|
|
350
|
+
self.assertIsInstance(result, ScanResult)
|
|
351
|
+
|
|
352
|
+
def test_scan_module_with_large_files(self):
|
|
353
|
+
"""测试包含大文件"""
|
|
354
|
+
(self.temp_path / "README.md").write_text("# Test\n" + "x" * 10000)
|
|
355
|
+
(self.temp_path / "DESIGN.md").write_text("# Design\n" + "y" * 10000)
|
|
356
|
+
|
|
357
|
+
result = scan_module(str(self.temp_path))
|
|
358
|
+
|
|
359
|
+
self.assertIsInstance(result, ScanResult)
|
|
360
|
+
|
|
361
|
+
def test_scan_module_with_multiple_languages(self):
|
|
362
|
+
"""测试多语言代码"""
|
|
363
|
+
(self.temp_path / "README.md").write_text("# Test")
|
|
364
|
+
(self.temp_path / "DESIGN.md").write_text("# Design")
|
|
365
|
+
(self.temp_path / "src").mkdir()
|
|
366
|
+
(self.temp_path / "src" / "main.py").write_text("x = 1")
|
|
367
|
+
(self.temp_path / "src" / "main.go").write_text("package main")
|
|
368
|
+
(self.temp_path / "src" / "main.rs").write_text("fn main() {}")
|
|
369
|
+
|
|
370
|
+
result = scan_module(str(self.temp_path))
|
|
371
|
+
|
|
372
|
+
self.assertIsInstance(result, ScanResult)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
if __name__ == '__main__':
|
|
376
|
+
unittest.main()
|