blob: c5fc320f64501c6a11c3ce17b87656344d5db71d [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
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200199
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000200def open_file(path):
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000201 dirname = os.path.dirname(path)
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200202 try:
203 os.makedirs(dirname)
204 except OSError as e:
205 if e.errno != errno.EEXIST:
206 raise
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000207 return open(path, "w")
208
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200209
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000210def create_package(source):
211 ofi = None
Antoine Pitrou92f60ed2010-10-14 22:11:44 +0000212 try:
213 for line in source.splitlines():
214 if line.startswith(" ") or line.startswith("\t"):
215 ofi.write(line.strip() + "\n")
216 else:
217 if ofi:
218 ofi.close()
219 ofi = open_file(os.path.join(TEST_DIR, line.strip()))
220 finally:
221 if ofi:
222 ofi.close()
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000223
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200224
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000225class ModuleFinderTest(unittest.TestCase):
226 def _do_test(self, info, report=False):
227 import_this, modules, missing, maybe_missing, source = info
228 create_package(source)
229 try:
230 mf = modulefinder.ModuleFinder(path=TEST_PATH)
231 mf.import_hook(import_this)
232 if report:
233 mf.report()
234## # This wouldn't work in general when executed several times:
235## opath = sys.path[:]
236## sys.path = TEST_PATH
237## try:
238## __import__(import_this)
239## except:
240## import traceback; traceback.print_exc()
241## sys.path = opath
242## return
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200243 modules = sorted(set(modules))
244 found = sorted(mf.modules)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000245 # check if we found what we expected, not more, not less
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200246 self.assertEqual(found, modules)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000247
248 # check for missing and maybe missing modules
249 bad, maybe = mf.any_missing_maybe()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000250 self.assertEqual(bad, missing)
251 self.assertEqual(maybe, maybe_missing)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000252 finally:
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200253 shutil.rmtree(TEST_DIR)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000254
255 def test_package(self):
256 self._do_test(package_test)
257
258 def test_maybe(self):
259 self._do_test(maybe_test)
260
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200261 def test_maybe_new(self):
262 self._do_test(maybe_test_new)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000263
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200264 def test_absolute_imports(self):
265 self._do_test(absolute_import_test)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000266
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200267 def test_relative_imports(self):
268 self._do_test(relative_import_test)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000269
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200270 def test_relative_imports_2(self):
271 self._do_test(relative_import_test_2)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000272
Éric Araujo1e3a68d2011-07-28 23:35:29 +0200273 def test_relative_imports_3(self):
274 self._do_test(relative_import_test_3)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000275
Benjamin Petersonc0747cf2008-11-03 20:31:38 +0000276
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000277def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000278 support.run_unittest(ModuleFinderTest)
Guido van Rossumfc2a0a82006-10-27 23:06:01 +0000279
280if __name__ == "__main__":
281 unittest.main()