#
# Unit Tests for util/misc/import_file
#
#

import os
import sys
from os.path import abspath, dirname
pkgdir = dirname(abspath(__file__))+os.sep+".."+os.sep+".."
currdir = dirname(abspath(__file__))+os.sep

import pyutilib.misc
try:
    import unittest2 as unittest
except:
    import unittest
import pyutilib.misc.comparison

try:
    import runpy
    _runpy=True
except:
    _runpy=False

class TestRunFile(unittest.TestCase):

    def test_run_file1(self):
        pyutilib.misc.run_file(currdir+"import1.py", logfile=currdir+"import1.log")
        if not os.path.exists(currdir+"import1.log"):
            self.fail("test_run_file - failed to create logfile")
        self.assertFalse(pyutilib.misc.comparison.compare_file(currdir+"import1.log",currdir+"import1.txt")[0])
        os.remove(currdir+"import1.log")

    def test_run_file2(self):
        pyutilib.misc.run_file("import1.py", logfile=currdir+"import1.log", execdir=currdir)
        if not os.path.exists(currdir+"import1.log"):
            self.fail("test_run_file - failed to create logfile")
        self.assertFalse(pyutilib.misc.comparison.compare_file(currdir+"import1.log",currdir+"import1.txt")[0])
        os.remove(currdir+"import1.log")

    def test_run_file3(self):
        try:
            pyutilib.misc.run_file("import2.py", logfile=currdir+"import2.log", execdir=currdir)
            self.fail("test_run_file - expected type error in import2.py")
        except TypeError:
            pass
        self.assertFalse(pyutilib.misc.comparison.compare_file(currdir+"import2.log",currdir+"import2.txt")[0])
        os.remove(currdir+"import2.log")

class TestImportFile(unittest.TestCase):

    def setUp(self):
        self._mods = list(sys.modules.keys())

    def tearDown(self):
        to_del = [ m for m in sys.modules.keys() if m not in
                   self._mods ]
        for mod in to_del:
            del sys.modules[mod]

    def test_import_file_context1(self):
        pyutilib.misc.import_file(currdir+"import1.py")
        if "import1" in globals():
            self.fail("test_import_file - globals() should not be affected by import")

    def test_import_file_context2(self):
        import1 = pyutilib.misc.import_file(currdir+"import1.py")
        try:
            c = import1.a
        except:
            self.fail("test_import_file - could not access data in import.py")

    def test_import_file_context3(self):
        pyutilib.misc.import_file(currdir+"import1.py", context=globals())
        if not "import1" in globals():
            self.fail("test_import_file - failed to import the import1.py file")

    def test1(self):
        try:
            pyutilib.misc.import_file('tfile.py')
        except IOError:
            pass
        else:
            self.fail('File does not exist. Expected IOError.')

    def test2(self):
        try:
            pyutilib.misc.import_file('tfile')
        except ImportError:
            pass
        else:
            self.fail('Module does not exist. Expected ImportError.')

    def test3(self):
        dirname = currdir+'import_data'+os.sep+'a'
        sys.path.insert(0,dirname)
        context = {}
        m = pyutilib.misc.import_file('tfile', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')
        sys.path.remove(dirname)


    def test4(self):
        dirname = currdir+'import_data'+os.sep+'a'
        sys.path.insert(0,dirname)
        context = {}
        m = pyutilib.misc.import_file('tfile', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')
        sys.path.remove(dirname)
        dirname = currdir+'import_data'+os.sep+'b'
        sys.path.insert(0,dirname)
        m = pyutilib.misc.import_file('tfile', context=context, name='junk')
        self.assertEqual(id(m),id(context['junk']))
        self.assertEqual(m.f(),'b')
        sys.path.remove(dirname)

    def test4a(self):
        dirname = currdir+'import_data'+os.sep+'a'
        sys.path.insert(0,dirname)
        context = {}
        m = pyutilib.misc.import_file('tfile', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')
        sys.path.remove(dirname)
        dirname = currdir+'import_data'+os.sep+'b'
        sys.path.insert(0,dirname)
        m = pyutilib.misc.import_file('tfile', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')
        sys.path.remove(dirname)

    def test5(self):
        dirname = currdir+'import_data'+os.sep+'a'+os.sep
        context = {}
        m = pyutilib.misc.import_file(dirname+'tfile', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')

    def test6(self):
        dirname = currdir+'import_data'+os.sep+'a'+os.sep
        context = {}
        m = pyutilib.misc.import_file(dirname+'tfile', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')
        dirname = currdir+'import_data'+os.sep+'b'+os.sep
        m = pyutilib.misc.import_file(dirname+'tfile', context=context, name='junk')
        self.assertEqual(id(m),id(context['junk']))
        self.assertEqual(m.f(),'b')

    def test6a(self):
        dirname = currdir+'import_data'+os.sep+'a'+os.sep
        context = {}
        m = pyutilib.misc.import_file(dirname+'tfile', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')
        dirname = currdir+'import_data'+os.sep+'b'+os.sep
        m = pyutilib.misc.import_file(dirname+'tfile', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')

    def test7(self):
        dirname = currdir+'import_data'+os.sep+'a'+os.sep
        context = {}
        m = pyutilib.misc.import_file(dirname+'tfile.py', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')

    def test8(self):
        dirname = currdir+'import_data'+os.sep+'a'+os.sep
        context = {}
        m = pyutilib.misc.import_file(dirname+'tfile.py', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')
        dirname = currdir+'import_data'+os.sep+'b'+os.sep
        m = pyutilib.misc.import_file(dirname+'tfile.py', context=context, name='junk')
        self.assertEqual(id(m),id(context['junk']))
        self.assertEqual(m.f(),'b')

    def test8a(self):
        dirname = currdir+'import_data'+os.sep+'a'+os.sep
        context = {}
        m = pyutilib.misc.import_file(dirname+'tfile.py', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')
        dirname = currdir+'import_data'+os.sep+'b'+os.sep
        m = pyutilib.misc.import_file(dirname+'tfile.py', context=context)
        self.assertEqual(id(m),id(context['tfile']))
        self.assertEqual(m.f(),'a')

    def test9(self):
        try:
            pyutilib.misc.import_file('foo/bar')
        except ImportError:
            pass
        else:
            self.fail('Module does not exist. Expected ImportError.')

    def test9a(self):
        try:
            pyutilib.misc.import_file('foo/bar', name='junk')
        except ImportError:
            pass
        else:
            self.fail('Module does not exist. Expected ImportError.')

    def test10(self):
        try:
            pyutilib.misc.import_file('foo.bar')
        except ImportError:
            pass
        else:
            self.fail('Module does not exist. Expected ImportError.')

    def test10a(self):
        try:
            pyutilib.misc.import_file('foo.bar', name='junk')
        except ImportError:
            pass
        else:
            self.fail('Module does not exist. Expected ImportError.')

    def test11(self):
        try:
            pyutilib.misc.import_file('baz/foo.bar')
        except ImportError:
            pass
        else:
            self.fail('Module does not exist. Expected ImportError.')

    def test11a(self):
        try:
            pyutilib.misc.import_file('baz/foo.bar', name='junk')
        except ImportError:
            pass
        else:
            self.fail('Module does not exist. Expected ImportError.')

    def test12(self):
        dirname = currdir+'import_data'
        sys.path.insert(0,dirname)
        context = {}
        m = pyutilib.misc.import_file('tfile1.0', context=context)
        self.assertEqual(id(m),id(context['tfile1.0']))
        self.assertEqual(m.f(),'tfile1.0')
        sys.path.remove(dirname)

    def test12a(self):
        dirname = currdir+'import_data'
        sys.path.insert(0,dirname)
        context = {}
        m = pyutilib.misc.import_file('tfile1.0', context=context, name='junk')
        self.assertEqual(id(m),id(context['junk']))
        self.assertEqual(m.f(),'tfile1.0')
        sys.path.remove(dirname)

    def test13(self):
        dirname = currdir+'import_data'+os.sep
        context = {}
        m = pyutilib.misc.import_file(dirname+'tfile1.0', context=context)
        self.assertEqual(id(m),id(context['tfile1.0']))
        self.assertEqual(m.f(),'tfile1.0')

    def test13a(self):
        dirname = currdir+'import_data'+os.sep
        context = {}
        m = pyutilib.misc.import_file(dirname+'tfile1.0', context=context, name='junk')
        self.assertEqual(id(m),id(context['junk']))
        self.assertEqual(m.f(),'tfile1.0')

    def test14(self):
        context = {}
        m = pyutilib.misc.import_file('pyutilib.misc.tests.import_data.a.tfile', context=context)
        self.assertEqual(id(m),id(context['pyutilib.misc.tests.import_data.a.tfile']))
        self.assertEqual(m.f(),'a')

# Apply decorator explicitly
TestRunFile = unittest.skipIf(not _runpy, "Cannot import 'runpy'")(TestRunFile)

if __name__ == "__main__":
    unittest.main()
