blob: 0b8e45144ad3017bb42d4166ac2737baa292268c [file] [log] [blame]
Guido van Rossumfc2a0a82006-10-27 23:06:01 +00001import __future__
2import sys, os
3import unittest
4import distutils.dir_util
5import tempfile
6
7from test import test_support
8
9try: set
10except NameError: from sets import Set as set
11
12import modulefinder
13
14# Note: To test modulefinder with Python 2.2, sets.py and
15# modulefinder.py must be available - they are not in the standard
16# library.
17
18TEST_DIR = tempfile.mkdtemp()
19TEST_PATH = [TEST_DIR, os.path.dirname(__future__.__file__)]
20
21# Each test description is a list of 5 items:
22#
23# 1. a module name that will be imported by modulefinder
24# 2. a list of module names that modulefinder is required to find
25# 3. a list of module names that modulefinder should complain
26# about because they are not found
27# 4. a list of module names that modulefinder should complain
28# about because they MAY be not found
29# 5. a string specifying packages to create; the format is obvious imo.
30#
31# Each package will be created in TEST_DIR, and TEST_DIR will be
32# removed after the tests again.
33# Modulefinder searches in a path that contains TEST_DIR, plus
34# the standard Lib directory.
35
36maybe_test = [
37 "a.module",
38 ["a", "a.module", "sys",
39 "b"],
40 ["c"], ["b.something"],
41 """\
42a/__init__.py
43a/module.py
44 from b import something
45 from c import something
46b/__init__.py
47 from sys import *
48"""]
49
50maybe_test_new = [
51 "a.module",
52 ["a", "a.module", "sys",
53 "b"],
54 ["c"], ["b.something"],
55 """\
56a/__init__.py
57a/module.py
58 from b import something
59 from c import something
60b/__init__.py
61 from sys import *
62"""]
63
64package_test = [
65 "a.module",
66 ["a", "a.b", "a.c", "a.module", "mymodule", "sys"],
67 ["blahblah", "c"], [],
68 """\
69mymodule.py
70a/__init__.py
71 import blahblah
72 from a import b
73 import c
74a/module.py
75 import sys
76 from a import b as x
77 from a.c import sillyname
78a/b.py
79a/c.py
80 from a.module import x
81 import mymodule as sillyname
82 from sys import version_info
83"""]
84
85absolute_import_test = [
86 "a.module",
87 ["a", "a.module",
88 "b", "b.x", "b.y", "b.z",
89 "sys", "exceptions"],
90 ["blahblah", "z"], [],
91 """\
92mymodule.py
93a/__init__.py
94a/module.py
95 import sys # sys
96 import blahblah # fails
97 import exceptions # exceptions
98 import b.x # b.x
99 from b import y # b.y
100 from b.z import * # b.z.*
101a/exceptions.py
102a/sys.py
103 import mymodule
104a/b/__init__.py
105a/b/x.py
106a/b/y.py
107a/b/z.py
108b/__init__.py
109 import z
110b/unused.py
111b/x.py
112b/y.py
113b/z.py
114"""]
115
116relative_import_test = [
117 "a.module",
118 ["a", "a.module",
119 "a.b", "a.b.y", "a.b.z",
120 "a.b.c", "a.b.c.moduleC",
121 "a.b.c.d", "a.b.c.e",
122 "a.b.x",
123 "exceptions"],
124 [], [],
125 """\
126mymodule.py
127a/__init__.py
128 from .b import y, z # a.b.y, a.b.z
129a/module.py
130 import exceptions # exceptions
131a/exceptions.py
132a/sys.py
133a/b/__init__.py
134 from ..b import x # a.b.x
135 #from a.b.c import moduleC
136 from .c import moduleC # a.b.moduleC
137a/b/x.py
138a/b/y.py
139a/b/z.py
140a/b/g.py
141a/b/c/__init__.py
142 from ..c import e # a.b.c.e
143a/b/c/moduleC.py
144 from ..c import d # a.b.c.d
145a/b/c/d.py
146a/b/c/e.py
147a/b/c/x.py
148"""]
149
150relative_import_test_2 = [
151 "a.module",
152 ["a", "a.module",
153 "a.sys",
154 "a.b", "a.b.y", "a.b.z",
155 "a.b.c", "a.b.c.d",
156 "a.b.c.e",
157 "a.b.c.moduleC",
158 "a.b.c.f",
159 "a.b.x",
160 "a.another"],
161 [], [],
162 """\
163mymodule.py
164a/__init__.py
165 from . import sys # a.sys
166a/another.py
167a/module.py
168 from .b import y, z # a.b.y, a.b.z
169a/exceptions.py
170a/sys.py
171a/b/__init__.py
172 from .c import moduleC # a.b.c.moduleC
173 from .c import d # a.b.c.d
174a/b/x.py
175a/b/y.py
176a/b/z.py
177a/b/c/__init__.py
178 from . import e # a.b.c.e
179a/b/c/moduleC.py
180 #
181 from . import f # a.b.c.f
182 from .. import x # a.b.x
183 from ... import another # a.another
184a/b/c/d.py
185a/b/c/e.py
186a/b/c/f.py
187"""]
188
189def open_file(path):
190 ##print "#", os.path.abspath(path)
191 dirname = os.path.dirname(path)
192 distutils.dir_util.mkpath(dirname)
193 return open(path, "w")
194
195def create_package(source):
196 ofi = None
197 for line in source.splitlines():
198 if line.startswith(" ") or line.startswith("\t"):
199 ofi.write(line.strip() + "\n")
200 else:
201 ofi = open_file(os.path.join(TEST_DIR, line.strip()))
202
203class ModuleFinderTest(unittest.TestCase):
204 def _do_test(self, info, report=False):
205 import_this, modules, missing, maybe_missing, source = info
206 create_package(source)
207 try:
208 mf = modulefinder.ModuleFinder(path=TEST_PATH)
209 mf.import_hook(import_this)
210 if report:
211 mf.report()
212## # This wouldn't work in general when executed several times:
213## opath = sys.path[:]
214## sys.path = TEST_PATH
215## try:
216## __import__(import_this)
217## except:
218## import traceback; traceback.print_exc()
219## sys.path = opath
220## return
221 modules = set(modules)
222 found = set(mf.modules.keys())
223 more = list(found - modules)
224 less = list(modules - found)
225 # check if we found what we expected, not more, not less
226 self.failUnlessEqual((more, less), ([], []))
227
228 # check for missing and maybe missing modules
229 bad, maybe = mf.any_missing_maybe()
230 self.failUnlessEqual(bad, missing)
231 self.failUnlessEqual(maybe, maybe_missing)
232 finally:
233 distutils.dir_util.remove_tree(TEST_DIR)
234
235 def test_package(self):
236 self._do_test(package_test)
237
238 def test_maybe(self):
239 self._do_test(maybe_test)
240
241 if getattr(__future__, "absolute_import", None):
242
243 def test_maybe_new(self):
244 self._do_test(maybe_test_new)
245
246 def test_absolute_imports(self):
247 self._do_test(absolute_import_test)
248
249 def test_relative_imports(self):
250 self._do_test(relative_import_test)
251
252 def test_relative_imports_2(self):
253 self._do_test(relative_import_test_2)
254
255def test_main():
256 test_support.run_unittest(ModuleFinderTest)
257
258if __name__ == "__main__":
259 unittest.main()