Skip to content

Commit d387230

Browse files
committed
Create test suite
1 parent 510679d commit d387230

File tree

6 files changed

+282
-3
lines changed

6 files changed

+282
-3
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ install:
1414
- python setup.py sdist && version=$(python setup.py --version) && pushd dist && pip install stdlib-list-${version}.tar.gz && popd
1515

1616
script:
17-
# FIXME: add some real test.
18-
- python -c "import stdlib_list; print(stdlib_list.stdlib_list('$TRAVIS_PYTHON_VERSION'))"
17+
- python -m tests
1918

2019
deploy:
2120
skip_cleanup: true

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ def read(*parts):
2424
long_description="{}".format(read("README.md")),
2525
long_description_content_type="text/markdown",
2626
include_package_data=True,
27-
packages=find_packages(),
27+
packages=find_packages(exclude=["tests", "tests.*"]),
2828
cmdclass=versioneer.get_cmdclass(),
2929
)

tests/__init__.py

Whitespace-only changes.

tests/__main__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import unittest
2+
3+
from tests.test_basic import *
4+
from tests.test_platform import *
5+
6+
if __name__ == "__main__":
7+
unittest.main()

tests/test_basic.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import sys
2+
import unittest
3+
4+
import stdlib_list
5+
6+
PY2 = sys.version_info[0] == 2
7+
8+
9+
class CurrentVersionBase(unittest.TestCase):
10+
def setUp(self):
11+
self.list = stdlib_list.stdlib_list(sys.version[:3])
12+
13+
14+
class TestCurrentVersion(CurrentVersionBase):
15+
def test_string(self):
16+
self.assertIn("string", self.list)
17+
18+
def test_list_is_sorted(self):
19+
self.assertEqual(sorted(self.list), self.list)
20+
21+
def test_builtin_modules(self):
22+
"""Check all top level stdlib packages are recognised."""
23+
unknown_builtins = set()
24+
for module_name in sys.builtin_module_names:
25+
if module_name not in self.list:
26+
unknown_builtins.add(module_name)
27+
28+
self.assertFalse(sorted(unknown_builtins))
29+
30+
31+
class TestSysModules(CurrentVersionBase):
32+
33+
# This relies on invocation in a clean python environment using unittest
34+
# not using pytest.
35+
36+
ignore_list = ["stdlib_list", "functools32", "tests", "_virtualenv_distutils"]
37+
38+
def setUp(self):
39+
super(TestSysModules, self).setUp()
40+
self.maxDiff = None
41+
42+
def test_preloaded_packages(self):
43+
"""Check all top level stdlib packages are recognised."""
44+
not_stdlib = set()
45+
for module_name in sys.modules:
46+
pkg, _, module = module_name.partition(".")
47+
48+
# https://github.com/jackmaney/python-stdlib-list/issues/29
49+
if pkg.startswith("_sysconfigdata_"):
50+
continue
51+
52+
if pkg in self.ignore_list:
53+
continue
54+
55+
# Avoid duplicating errors covered by other tests
56+
if pkg in sys.builtin_module_names:
57+
continue
58+
59+
if pkg not in self.list:
60+
not_stdlib.add(pkg)
61+
62+
self.assertFalse(sorted(not_stdlib))
63+
64+
def test_preloaded_modules(self):
65+
"""Check all stdlib modules are recognised."""
66+
not_stdlib = set()
67+
for module_name in sys.modules:
68+
pkg, _, module = module_name.partition(".")
69+
70+
# https://github.com/jackmaney/python-stdlib-list/issues/29
71+
if pkg.startswith("_sysconfigdata_"):
72+
continue
73+
74+
if pkg in self.ignore_list:
75+
continue
76+
77+
# Avoid duplicating errors covered by other tests
78+
if module_name in sys.builtin_module_names:
79+
continue
80+
81+
if PY2:
82+
# Python 2.7 creates sub-modules for imports
83+
if pkg in self.list and module in self.list:
84+
continue
85+
86+
# Python 2.7 deprecation solution for old names
87+
if pkg == "email":
88+
mod = sys.modules[module_name]
89+
if mod.__class__.__name__ == "LazyImporter":
90+
continue
91+
92+
if module_name not in self.list:
93+
not_stdlib.add(module_name)
94+
95+
self.assertFalse(sorted(not_stdlib))
96+
97+
98+
if __name__ == "__main__":
99+
unittest.main()

tests/test_platform.py

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import difflib
2+
import os
3+
import os.path
4+
import sys
5+
import unittest
6+
from distutils.sysconfig import get_python_lib
7+
from sysconfig import get_config_var
8+
9+
import stdlib_list
10+
11+
try:
12+
sys.base_prefix
13+
has_base_prefix = sys.base_prefix != sys.prefix
14+
except AttributeError:
15+
has_base_prefix = False
16+
17+
shlib_ext = get_config_var("SHLIB_SUFFIX") or get_config_var("SO")
18+
19+
tk_libs = get_config_var("TKPATH")
20+
21+
22+
class UnifiedDiffAssertionError(AssertionError):
23+
def __init__(self, expected, got, msg="Differences"):
24+
super(UnifiedDiffAssertionError, self).__init__(self)
25+
filename = "stdlib_list/lists/{}.txt".format(sys.version[:3])
26+
diff = difflib.unified_diff(
27+
expected, got, lineterm="", fromfile="a/" + filename, tofile="b/" + filename
28+
)
29+
self.description = "{name}\n{diff}".format(name=msg, diff="\n".join(diff))
30+
31+
def __str__(self):
32+
return self.description
33+
34+
35+
class CurrentPlatformBase(object):
36+
37+
dir = None
38+
ignore_test = False
39+
40+
def setUp(self):
41+
self.list = stdlib_list.stdlib_list(sys.version[:3])
42+
if self.dir:
43+
self.assertTrue(os.path.isdir(self.dir))
44+
45+
def _collect_shared(self, name):
46+
# stdlib extensions are not in subdirectories
47+
if "/" in name:
48+
return None
49+
50+
return name.split(".", 1)[0]
51+
52+
def _collect_file(self, name):
53+
if name.endswith(shlib_ext):
54+
return self._collect_shared(name)
55+
56+
if not name.endswith(".py"):
57+
return None
58+
59+
# This excludes `_sysconfigdata_m_linux_x86_64-linux-gnu`
60+
# https://github.com/jackmaney/python-stdlib-list/issues/29
61+
if "-" in name:
62+
return None
63+
64+
# Ignore this oddball stdlib test.test_frozen helper
65+
if name == "__phello__.foo.py":
66+
return None
67+
68+
if name.endswith("/__init__.py"):
69+
return name[:-12].replace("/", ".")
70+
71+
# Strip .py and replace '/'
72+
return name[:-3].replace("/", ".")
73+
74+
def _collect_all(self, base):
75+
base = base + "/" if not base.endswith("/") else base
76+
base_len = len(base)
77+
modules = []
78+
79+
for root, dirs, files in os.walk(base):
80+
for filename in files:
81+
relative_base = root[base_len:]
82+
relative_path = os.path.join(relative_base, filename)
83+
module_name = self._collect_file(relative_path)
84+
if module_name:
85+
modules.append(module_name)
86+
87+
# In-place filtering of traversal, removing invalid module names
88+
# and cache directories
89+
for dir in dirs:
90+
if "-" in dir:
91+
dirs.remove(dir)
92+
if "__pycache__" in dirs:
93+
dirs.remove("__pycache__")
94+
95+
if self.ignore_test and "test" in dirs:
96+
dirs.remove("test")
97+
98+
# openSUSE custom module added to stdlib directory
99+
if "_import_failed" in dirs:
100+
dirs.remove("_import_failed")
101+
102+
return modules
103+
104+
def assertNoDiff(self, base, new):
105+
if base == new:
106+
self.assertEqual(base, new)
107+
else:
108+
raise UnifiedDiffAssertionError(got=sorted(new), expected=sorted(base))
109+
110+
def test_dir(self):
111+
needed = set(self.list)
112+
items = self._collect_all(self.dir)
113+
for item in items:
114+
if item not in self.list:
115+
needed.add(item)
116+
117+
self.assertNoDiff(set(self.list), needed)
118+
119+
120+
class TestPureLibDir(CurrentPlatformBase, unittest.TestCase):
121+
def setUp(self):
122+
self.dir = get_python_lib(standard_lib=True, plat_specific=False)
123+
super(TestPureLibDir, self).setUp()
124+
125+
126+
class TestPlatLibDir(CurrentPlatformBase, unittest.TestCase):
127+
def setUp(self):
128+
self.dir = get_python_lib(standard_lib=True, plat_specific=True)
129+
super(TestPlatLibDir, self).setUp()
130+
131+
132+
class TestSharedDir(CurrentPlatformBase, unittest.TestCase):
133+
def setUp(self):
134+
self.dir = get_config_var("DESTSHARED")
135+
super(TestSharedDir, self).setUp()
136+
137+
138+
if has_base_prefix:
139+
140+
class TestBasePureLibDir(CurrentPlatformBase, unittest.TestCase):
141+
def setUp(self):
142+
base = sys.base_prefix
143+
self.dir = get_python_lib(
144+
standard_lib=True, plat_specific=False, prefix=base
145+
)
146+
super(TestBasePureLibDir, self).setUp()
147+
148+
class TestBasePlatLibDir(CurrentPlatformBase, unittest.TestCase):
149+
def setUp(self):
150+
base = sys.base_prefix
151+
self.dir = get_python_lib(
152+
standard_lib=True, plat_specific=True, prefix=base
153+
)
154+
super(TestBasePlatLibDir, self).setUp()
155+
156+
157+
if tk_libs:
158+
tk_libs = tk_libs.strip(os.pathsep)
159+
160+
class TestTkDir(CurrentPlatformBase, unittest.TestCase):
161+
162+
# Python 2.7 tk-libs includes a `test` package, however it is
163+
# added to sys.path by test.test_tk as a top level directory
164+
# so test.widget_tests becomes module name `widget_tests`
165+
ignore_test = True
166+
167+
def setUp(self):
168+
base = get_python_lib(standard_lib=True, plat_specific=False)
169+
self.dir = os.path.join(base, tk_libs)
170+
super(TestTkDir, self).setUp()
171+
172+
173+
if __name__ == "__main__":
174+
unittest.main()

0 commit comments

Comments
 (0)