blob: 53ea232174912cb0593b29a71f7881aec4293a07 [file] [log] [blame]
Christian Heimes05e8be12008-02-23 18:30:17 +00001import os
Éric Araujo1e3a68d2011-07-28 23:35:29 +02002import errno
3import shutil
Guido van Rossumfc2a0a82006-10-27 23:06:01 +00004import unittest
Guido van Rossumfc2a0a82006-10-27 23:06:01 +00005import tempfile
6
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Guido van Rossumfc2a0a82006-10-27 23:06:01 +00008
Guido van Rossumfc2a0a82006-10-27 23:06:01 +00009import modulefinder
10
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000011TEST_DIR = tempfile.mkdtemp()
Éric Araujo1e3a68d2011-07-28 23:35:29 +020012TEST_PATH = [TEST_DIR, os.path.dirname(tempfile.__file__)]
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000013
14# Each test description is a list of 5 items:
15#
16# 1. a module name that will be imported by modulefinder
17# 2. a list of module names that modulefinder is required to find
18# 3. a list of module names that modulefinder should complain
19# about because they are not found
20# 4. a list of module names that modulefinder should complain
21# about because they MAY be not found
22# 5. a string specifying packages to create; the format is obvious imo.
23#
24# Each package will be created in TEST_DIR, and TEST_DIR will be
25# removed after the tests again.
26# Modulefinder searches in a path that contains TEST_DIR, plus
27# the standard Lib directory.
28
29maybe_test = [
30 "a.module",
31 ["a", "a.module", "sys",
32 "b"],
33 ["c"], ["b.something"],
34 """\
35a/__init__.py
36a/module.py
37 from b import something
38 from c import something
39b/__init__.py
40 from sys import *
41"""]
42
43maybe_test_new = [
44 "a.module",
45 ["a", "a.module", "sys",
Thomas Wouters89f507f2006-12-13 04:49:30 +000046 "b", "__future__"],
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000047 ["c"], ["b.something"],
48 """\
49a/__init__.py
50a/module.py
51 from b import something
52 from c import something
53b/__init__.py
Thomas Wouters89f507f2006-12-13 04:49:30 +000054 from __future__ import absolute_import
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000055 from sys import *
56"""]
57
58package_test = [
59 "a.module",
60 ["a", "a.b", "a.c", "a.module", "mymodule", "sys"],
61 ["blahblah", "c"], [],
62 """\
63mymodule.py
64a/__init__.py
65 import blahblah
66 from a import b
67 import c
68a/module.py
69 import sys
70 from a import b as x
71 from a.c import sillyname
72a/b.py
73a/c.py
74 from a.module import x
75 import mymodule as sillyname
76 from sys import version_info
77"""]
78
79absolute_import_test = [
80 "a.module",
81 ["a", "a.module",
82 "b", "b.x", "b.y", "b.z",
Neal Norwitz2633c692007-02-26 22:22:47 +000083 "__future__", "sys", "gc"],
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000084 ["blahblah", "z"], [],
85 """\
86mymodule.py
87a/__init__.py
88a/module.py
Thomas Wouters89f507f2006-12-13 04:49:30 +000089 from __future__ import absolute_import
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000090 import sys # sys
91 import blahblah # fails
Neal Norwitz2633c692007-02-26 22:22:47 +000092 import gc # gc
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000093 import b.x # b.x
94 from b import y # b.y
95 from b.z import * # b.z.*
Neal Norwitz2633c692007-02-26 22:22:47 +000096a/gc.py
Guido van Rossumfc2a0a82006-10-27 23:06:01 +000097a/sys.py
98 import mymodule
99a/b/__init__.py
100a/b/x.py
101a/b/y.py
102a/b/z.py
103b/__init__.py
104 import z
105b/unused.py
106b/x.py
107b/y.py
108b/z.py
109"""]
110
111relative_import_test = [
112 "a.module",
Thomas Wouters89f507f2006-12-13 04:49:30 +0000113 ["__future__",
114 "a", "a.module",
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000115 "a.b", "a.b.y", "a.b.z",
116 "a.b.c", "a.b.c.moduleC",
117 "a.b.c.d", "a.b.c.e",
118 "a.b.x",
Neal Norwitz2633c692007-02-26 22:22:47 +0000119 "gc"],
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000120 [], [],
121 """\
122mymodule.py
123a/__init__.py
124 from .b import y, z # a.b.y, a.b.z
125a/module.py
Thomas Wouters89f507f2006-12-13 04:49:30 +0000126 from __future__ import absolute_import # __future__
Neal Norwitz2633c692007-02-26 22:22:47 +0000127 import gc # gc
128a/gc.py
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000129a/sys.py
130a/b/__init__.py
131 from ..b import x # a.b.x
132 #from a.b.c import moduleC
133 from .c import moduleC # a.b.moduleC
134a/b/x.py
135a/b/y.py
136a/b/z.py
137a/b/g.py
138a/b/c/__init__.py
139 from ..c import e # a.b.c.e
140a/b/c/moduleC.py
141 from ..c import d # a.b.c.d
142a/b/c/d.py
143a/b/c/e.py
144a/b/c/x.py
145"""]
146
147relative_import_test_2 = [
148 "a.module",
149 ["a", "a.module",
150 "a.sys",
151 "a.b", "a.b.y", "a.b.z",
152 "a.b.c", "a.b.c.d",
153 "a.b.c.e",
154 "a.b.c.moduleC",
155 "a.b.c.f",
156 "a.b.x",
157 "a.another"],
158 [], [],
159 """\
160mymodule.py
161a/__init__.py
162 from . import sys # a.sys
163a/another.py
164a/module.py
165 from .b import y, z # a.b.y, a.b.z
Neal Norwitz2633c692007-02-26 22:22:47 +0000166a/gc.py
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000167a/sys.py
168a/b/__init__.py
169 from .c import moduleC # a.b.c.moduleC
170 from .c import d # a.b.c.d
171a/b/x.py
172a/b/y.py
173a/b/z.py
174a/b/c/__init__.py
175 from . import e # a.b.c.e
176a/b/c/moduleC.py
177 #
178 from . import f # a.b.c.f
179 from .. import x # a.b.x
180 from ... import another # a.another
181a/b/c/d.py
182a/b/c/e.py
183a/b/c/f.py
184"""]
185
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000186relative_import_test_3 = [
187 "a.module",
188 ["a", "a.module"],
189 ["a.bar"],
190 [],
191 """\
192a/__init__.py
193 def foo(): pass
194a/module.py
195 from . import foo
196 from . import bar
197"""]
198
Brett Cannon73b969e2012-12-22 19:34:21 -0500199relative_import_test_4 = [
200 "a.module",
201 ["a", "a.module"],
202 [],
203 [],
204 """\
205a/__init__.py
206 def foo(): pass
207a/module.py
208 from . import *
209"""]
210
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200211
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000212def open_file(path):
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000213 dirname = os.path.dirname(path)
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200214 try:
215 os.makedirs(dirname)
216 except OSError as e:
217 if e.errno != errno.EEXIST:
218 raise
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000219 return open(path, "w")
220
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200221
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000222def create_package(source):
223 ofi = None
Antoine Pitrou92f60ed2010-10-14 22:11:44 +0000224 try:
225 for line in source.splitlines():
226 if line.startswith(" ") or line.startswith("\t"):
227 ofi.write(line.strip() + "\n")
228 else:
229 if ofi:
230 ofi.close()
231 ofi = open_file(os.path.join(TEST_DIR, line.strip()))
232 finally:
233 if ofi:
234 ofi.close()
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000235
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200236
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000237class ModuleFinderTest(unittest.TestCase):
238 def _do_test(self, info, report=False):
239 import_this, modules, missing, maybe_missing, source = info
240 create_package(source)
241 try:
242 mf = modulefinder.ModuleFinder(path=TEST_PATH)
243 mf.import_hook(import_this)
244 if report:
245 mf.report()
246## # This wouldn't work in general when executed several times:
247## opath = sys.path[:]
248## sys.path = TEST_PATH
249## try:
250## __import__(import_this)
251## except:
252## import traceback; traceback.print_exc()
253## sys.path = opath
254## return
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200255 modules = sorted(set(modules))
256 found = sorted(mf.modules)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000257 # check if we found what we expected, not more, not less
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200258 self.assertEqual(found, modules)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000259
260 # check for missing and maybe missing modules
261 bad, maybe = mf.any_missing_maybe()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000262 self.assertEqual(bad, missing)
263 self.assertEqual(maybe, maybe_missing)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000264 finally:
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200265 shutil.rmtree(TEST_DIR)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000266
267 def test_package(self):
268 self._do_test(package_test)
269
270 def test_maybe(self):
271 self._do_test(maybe_test)
272
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200273 def test_maybe_new(self):
274 self._do_test(maybe_test_new)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000275
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200276 def test_absolute_imports(self):
277 self._do_test(absolute_import_test)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000278
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200279 def test_relative_imports(self):
280 self._do_test(relative_import_test)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000281
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200282 def test_relative_imports_2(self):
283 self._do_test(relative_import_test_2)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000284
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200285 def test_relative_imports_3(self):
286 self._do_test(relative_import_test_3)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000287
Brett Cannon73b969e2012-12-22 19:34:21 -0500288 def test_relative_imports_4(self):
289 self._do_test(relative_import_test_4)
290
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000291
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000292def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000293 support.run_unittest(ModuleFinderTest)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000294
295if __name__ == "__main__":
296 unittest.main()