-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.test.py
More file actions
119 lines (85 loc) · 4.06 KB
/
Copy patherrors.test.py
File metadata and controls
119 lines (85 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from __future__ import annotations
import ast
import sys
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
from mapper import errors # noqa: E402
def reaching_back(source: str) -> list[str]:
"""Every import in that source that comes from this package rather than outside it.
Written against text rather than against the one file it guards, so it can be
handed something that should fail it. A reader nobody has seen report a fault
reports a clean run whether or not there is one.
A relative import counts however deep it goes, and an absolute one counts
when it is the package or a module under it. The dot is required, because a
package whose name merely begins the same way is somebody else's.
"""
def inside(name: str) -> bool:
return name.startswith(".") or name == "mapper" or name.startswith("mapper.")
borrowed = []
for node in ast.walk(ast.parse(source)):
if isinstance(node, ast.Import):
borrowed += [alias.name for alias in node.names if inside(alias.name)]
elif isinstance(node, ast.ImportFrom):
name = "." * node.level + (node.module or "")
if inside(name):
borrowed.append(name)
return borrowed
class OneHomeTest(unittest.TestCase):
"""That every refusal this package makes is defined here and nowhere else.
Two classes under one name both work, both get tested, and `except` catches
half the cases it names. Keeping them in one module is what makes that
impossible rather than unlikely.
"""
def named(self) -> list[str]:
return [
name
for name, held in vars(errors).items()
if isinstance(held, type) and issubclass(held, Exception)
]
def test_the_module_defines_the_refusals_this_package_makes(self) -> None:
self.assertEqual(
sorted(self.named()),
["NeedsBankCount", "NoHeader", "NotWholeBanks", "UnknownModelError"],
)
def test_every_one_of_them_derives_from_exception(self) -> None:
stray = [name for name in self.named() if not issubclass(getattr(errors, name), Exception)]
self.assertEqual(stray, [])
def test_and_every_one_says_what_it_means(self) -> None:
"""A refusal a caller meets and cannot look up is a refusal they guess at."""
silent = [
name for name in self.named() if not (getattr(errors, name).__doc__ or "").strip()
]
self.assertEqual(silent, [])
def test_none_of_them_is_a_subclass_of_another(self) -> None:
"""Or catching one would silently catch the other."""
held = [getattr(errors, name) for name in self.named()]
overlapping = [
(one.__name__, other.__name__)
for one in held
for other in held
if one is not other and issubclass(one, other)
]
self.assertEqual(overlapping, [])
class NoCycleTest(unittest.TestCase):
"""That this module imports nothing from the package it belongs to.
Everything here raises, so everything here imports this. An import running
the other way closes the cycle and makes the order modules happen to load in
decide whether the package works.
"""
def test_it_imports_nothing_from_this_package(self) -> None:
held = (ROOT / "mapper" / "errors.py").read_text()
self.assertEqual(reaching_back(held), [])
def test_the_reader_of_that_names_an_absolute_import_back(self) -> None:
found = reaching_back("import mapper.layout\n")
self.assertEqual(found, ["mapper.layout"])
def test_and_a_relative_one(self) -> None:
found = reaching_back("from . import layout\n")
self.assertEqual(found, ["."])
def test_and_steps_over_one_from_outside(self) -> None:
"""The standard library and a package whose name merely starts the same."""
found = reaching_back("from __future__ import annotations\nimport mappertools\n")
self.assertEqual(found, [])
if __name__ == "__main__":
unittest.main()