Home | History | Annotate | Download | only in test
      1 import __future__
      2 import os
      3 import unittest
      4 import distutils.dir_util
      5 import tempfile
      6 
      7 from test import test_support
      8 
      9 try: set
     10 except NameError: from sets import Set as set
     11 
     12 import 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 
     18 TEST_DIR = tempfile.mkdtemp()
     19 TEST_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 
     36 maybe_test = [
     37     "a.module",
     38     ["a", "a.module", "sys",
     39      "b"],
     40     ["c"], ["b.something"],
     41     """\
     42 a/__init__.py
     43 a/module.py
     44                                 from b import something
     45                                 from c import something
     46 b/__init__.py
     47                                 from sys import *
     48 """]
     49 
     50 maybe_test_new = [
     51     "a.module",
     52     ["a", "a.module", "sys",
     53      "b", "__future__"],
     54     ["c"], ["b.something"],
     55     """\
     56 a/__init__.py
     57 a/module.py
     58                                 from b import something
     59                                 from c import something
     60 b/__init__.py
     61                                 from __future__ import absolute_import
     62                                 from sys import *
     63 """]
     64 
     65 package_test = [
     66     "a.module",
     67     ["a", "a.b", "a.c", "a.module", "mymodule", "sys"],
     68     ["blahblah"], [],
     69     """\
     70 mymodule.py
     71 a/__init__.py
     72                                 import blahblah
     73                                 from a import b
     74                                 import c
     75 a/module.py
     76                                 import sys
     77                                 from a import b as x
     78                                 from a.c import sillyname
     79 a/b.py
     80 a/c.py
     81                                 from a.module import x
     82                                 import mymodule as sillyname
     83                                 from sys import version_info
     84 """]
     85 
     86 absolute_import_test = [
     87     "a.module",
     88     ["a", "a.module",
     89      "b", "b.x", "b.y", "b.z",
     90      "__future__", "sys", "exceptions"],
     91     ["blahblah"], [],
     92     """\
     93 mymodule.py
     94 a/__init__.py
     95 a/module.py
     96                                 from __future__ import absolute_import
     97                                 import sys # sys
     98                                 import blahblah # fails
     99                                 import exceptions # exceptions
    100                                 import b.x # b.x
    101                                 from b import y # b.y
    102                                 from b.z import * # b.z.*
    103 a/exceptions.py
    104 a/sys.py
    105                                 import mymodule
    106 a/b/__init__.py
    107 a/b/x.py
    108 a/b/y.py
    109 a/b/z.py
    110 b/__init__.py
    111                                 import z
    112 b/unused.py
    113 b/x.py
    114 b/y.py
    115 b/z.py
    116 """]
    117 
    118 relative_import_test = [
    119     "a.module",
    120     ["__future__",
    121      "a", "a.module",
    122      "a.b", "a.b.y", "a.b.z",
    123      "a.b.c", "a.b.c.moduleC",
    124      "a.b.c.d", "a.b.c.e",
    125      "a.b.x",
    126      "exceptions"],
    127     [], [],
    128     """\
    129 mymodule.py
    130 a/__init__.py
    131                                 from .b import y, z # a.b.y, a.b.z
    132 a/module.py
    133                                 from __future__ import absolute_import # __future__
    134                                 import exceptions # exceptions
    135 a/exceptions.py
    136 a/sys.py
    137 a/b/__init__.py
    138                                 from ..b import x # a.b.x
    139                                 #from a.b.c import moduleC
    140                                 from .c import moduleC # a.b.moduleC
    141 a/b/x.py
    142 a/b/y.py
    143 a/b/z.py
    144 a/b/g.py
    145 a/b/c/__init__.py
    146                                 from ..c import e # a.b.c.e
    147 a/b/c/moduleC.py
    148                                 from ..c import d # a.b.c.d
    149 a/b/c/d.py
    150 a/b/c/e.py
    151 a/b/c/x.py
    152 """]
    153 
    154 relative_import_test_2 = [
    155     "a.module",
    156     ["a", "a.module",
    157      "a.sys",
    158      "a.b", "a.b.y", "a.b.z",
    159      "a.b.c", "a.b.c.d",
    160      "a.b.c.e",
    161      "a.b.c.moduleC",
    162      "a.b.c.f",
    163      "a.b.x",
    164      "a.another"],
    165     [], [],
    166     """\
    167 mymodule.py
    168 a/__init__.py
    169                                 from . import sys # a.sys
    170 a/another.py
    171 a/module.py
    172                                 from .b import y, z # a.b.y, a.b.z
    173 a/exceptions.py
    174 a/sys.py
    175 a/b/__init__.py
    176                                 from .c import moduleC # a.b.c.moduleC
    177                                 from .c import d # a.b.c.d
    178 a/b/x.py
    179 a/b/y.py
    180 a/b/z.py
    181 a/b/c/__init__.py
    182                                 from . import e # a.b.c.e
    183 a/b/c/moduleC.py
    184                                 #
    185                                 from . import f   # a.b.c.f
    186                                 from .. import x  # a.b.x
    187                                 from ... import another # a.another
    188 a/b/c/d.py
    189 a/b/c/e.py
    190 a/b/c/f.py
    191 """]
    192 
    193 relative_import_test_3 = [
    194     "a.module",
    195     ["a", "a.module"],
    196     ["a.bar"],
    197     [],
    198     """\
    199 a/__init__.py
    200                                 def foo(): pass
    201 a/module.py
    202                                 from . import foo
    203                                 from . import bar
    204 """]
    205 
    206 def open_file(path):
    207     ##print "#", os.path.abspath(path)
    208     dirname = os.path.dirname(path)
    209     distutils.dir_util.mkpath(dirname)
    210     return open(path, "w")
    211 
    212 def create_package(source):
    213     ofi = None
    214     try:
    215         for line in source.splitlines():
    216             if line.startswith(" ") or line.startswith("\t"):
    217                 ofi.write(line.strip() + "\n")
    218             else:
    219                 if ofi:
    220                     ofi.close()
    221                 ofi = open_file(os.path.join(TEST_DIR, line.strip()))
    222     finally:
    223         if ofi:
    224             ofi.close()
    225 
    226 class ModuleFinderTest(unittest.TestCase):
    227     def _do_test(self, info, report=False):
    228         import_this, modules, missing, maybe_missing, source = info
    229         create_package(source)
    230         try:
    231             mf = modulefinder.ModuleFinder(path=TEST_PATH)
    232             mf.import_hook(import_this)
    233             if report:
    234                 mf.report()
    235 ##                # This wouldn't work in general when executed several times:
    236 ##                opath = sys.path[:]
    237 ##                sys.path = TEST_PATH
    238 ##                try:
    239 ##                    __import__(import_this)
    240 ##                except:
    241 ##                    import traceback; traceback.print_exc()
    242 ##                sys.path = opath
    243 ##                return
    244             modules = set(modules)
    245             found = set(mf.modules.keys())
    246             more = list(found - modules)
    247             less = list(modules - found)
    248             # check if we found what we expected, not more, not less
    249             self.assertEqual((more, less), ([], []))
    250 
    251             # check for missing and maybe missing modules
    252             bad, maybe = mf.any_missing_maybe()
    253             self.assertEqual(bad, missing)
    254             self.assertEqual(maybe, maybe_missing)
    255         finally:
    256             distutils.dir_util.remove_tree(TEST_DIR)
    257 
    258     def test_package(self):
    259         self._do_test(package_test)
    260 
    261     def test_maybe(self):
    262         self._do_test(maybe_test)
    263 
    264     if getattr(__future__, "absolute_import", None):
    265 
    266         def test_maybe_new(self):
    267             self._do_test(maybe_test_new)
    268 
    269         def test_absolute_imports(self):
    270             self._do_test(absolute_import_test)
    271 
    272         def test_relative_imports(self):
    273             self._do_test(relative_import_test)
    274 
    275         def test_relative_imports_2(self):
    276             self._do_test(relative_import_test_2)
    277 
    278         def test_relative_imports_3(self):
    279             self._do_test(relative_import_test_3)
    280 
    281 def test_main():
    282     distutils.log.set_threshold(distutils.log.WARN)
    283     test_support.run_unittest(ModuleFinderTest)
    284 
    285 if __name__ == "__main__":
    286     unittest.main()
    287