Home | History | Annotate | Download | only in tests
      1 # -*- coding: utf-8 -*-
      2 import sys
      3 import codecs
      4 import logging
      5 import os
      6 import re
      7 import shutil
      8 import StringIO
      9 import sys
     10 import tempfile
     11 import unittest
     12 
     13 from lib2to3 import main
     14 
     15 
     16 TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
     17 PY2_TEST_MODULE = os.path.join(TEST_DATA_DIR, "py2_test_grammar.py")
     18 
     19 
     20 class TestMain(unittest.TestCase):
     21 
     22     if not hasattr(unittest.TestCase, 'assertNotRegex'):
     23         # This method was only introduced in 3.2.
     24         def assertNotRegex(self, text, regexp, msg=None):
     25             import re
     26             if not hasattr(regexp, 'search'):
     27                 regexp = re.compile(regexp)
     28             if regexp.search(text):
     29                 self.fail("regexp %s MATCHED text %r" % (regexp.pattern, text))
     30 
     31     def setUp(self):
     32         self.temp_dir = None  # tearDown() will rmtree this directory if set.
     33 
     34     def tearDown(self):
     35         # Clean up logging configuration down by main.
     36         del logging.root.handlers[:]
     37         if self.temp_dir:
     38             shutil.rmtree(self.temp_dir)
     39 
     40     def run_2to3_capture(self, args, in_capture, out_capture, err_capture):
     41         save_stdin = sys.stdin
     42         save_stdout = sys.stdout
     43         save_stderr = sys.stderr
     44         sys.stdin = in_capture
     45         sys.stdout = out_capture
     46         sys.stderr = err_capture
     47         try:
     48             return main.main("lib2to3.fixes", args)
     49         finally:
     50             sys.stdin = save_stdin
     51             sys.stdout = save_stdout
     52             sys.stderr = save_stderr
     53 
     54     def test_unencodable_diff(self):
     55         input_stream = StringIO.StringIO(u"print 'nothing'\nprint u'ber'\n")
     56         out = StringIO.StringIO()
     57         out_enc = codecs.getwriter("ascii")(out)
     58         err = StringIO.StringIO()
     59         ret = self.run_2to3_capture(["-"], input_stream, out_enc, err)
     60         self.assertEqual(ret, 0)
     61         output = out.getvalue()
     62         self.assertTrue("-print 'nothing'" in output)
     63         self.assertTrue("WARNING: couldn't encode <stdin>'s diff for "
     64                         "your terminal" in err.getvalue())
     65 
     66     def setup_test_source_trees(self):
     67         """Setup a test source tree and output destination tree."""
     68         self.temp_dir = tempfile.mkdtemp()  # tearDown() cleans this up.
     69         self.py2_src_dir = os.path.join(self.temp_dir, "python2_project")
     70         self.py3_dest_dir = os.path.join(self.temp_dir, "python3_project")
     71         os.mkdir(self.py2_src_dir)
     72         os.mkdir(self.py3_dest_dir)
     73         # Turn it into a package with a few files.
     74         self.setup_files = []
     75         open(os.path.join(self.py2_src_dir, "__init__.py"), "w").close()
     76         self.setup_files.append("__init__.py")
     77         shutil.copy(PY2_TEST_MODULE, self.py2_src_dir)
     78         self.setup_files.append(os.path.basename(PY2_TEST_MODULE))
     79         self.trivial_py2_file = os.path.join(self.py2_src_dir, "trivial.py")
     80         self.init_py2_file = os.path.join(self.py2_src_dir, "__init__.py")
     81         with open(self.trivial_py2_file, "w") as trivial:
     82             trivial.write("print 'I need a simple conversion.'")
     83         self.setup_files.append("trivial.py")
     84 
     85     def test_filename_changing_on_output_single_dir(self):
     86         """2to3 a single directory with a new output dir and suffix."""
     87         self.setup_test_source_trees()
     88         out = StringIO.StringIO()
     89         err = StringIO.StringIO()
     90         suffix = "TEST"
     91         ret = self.run_2to3_capture(
     92                 ["-n", "--add-suffix", suffix, "--write-unchanged-files",
     93                  "--no-diffs", "--output-dir",
     94                  self.py3_dest_dir, self.py2_src_dir],
     95                 StringIO.StringIO(""), out, err)
     96         self.assertEqual(ret, 0)
     97         stderr = err.getvalue()
     98         self.assertIn(" implies -w.", stderr)
     99         self.assertIn(
    100                 "Output in %r will mirror the input directory %r layout" % (
    101                         self.py3_dest_dir, self.py2_src_dir), stderr)
    102         self.assertEqual(set(name+suffix for name in self.setup_files),
    103                          set(os.listdir(self.py3_dest_dir)))
    104         for name in self.setup_files:
    105             self.assertIn("Writing converted %s to %s" % (
    106                     os.path.join(self.py2_src_dir, name),
    107                     os.path.join(self.py3_dest_dir, name+suffix)), stderr)
    108         sep = re.escape(os.sep)
    109         self.assertRegexpMatches(
    110                 stderr, r"No changes to .*/__init__\.py".replace("/", sep))
    111         self.assertNotRegex(
    112                 stderr, r"No changes to .*/trivial\.py".replace("/", sep))
    113 
    114     def test_filename_changing_on_output_two_files(self):
    115         """2to3 two files in one directory with a new output dir."""
    116         self.setup_test_source_trees()
    117         err = StringIO.StringIO()
    118         py2_files = [self.trivial_py2_file, self.init_py2_file]
    119         expected_files = set(os.path.basename(name) for name in py2_files)
    120         ret = self.run_2to3_capture(
    121                 ["-n", "-w", "--write-unchanged-files",
    122                  "--no-diffs", "--output-dir", self.py3_dest_dir] + py2_files,
    123                 StringIO.StringIO(""), StringIO.StringIO(), err)
    124         self.assertEqual(ret, 0)
    125         stderr = err.getvalue()
    126         self.assertIn(
    127                 "Output in %r will mirror the input directory %r layout" % (
    128                         self.py3_dest_dir, self.py2_src_dir), stderr)
    129         self.assertEqual(expected_files, set(os.listdir(self.py3_dest_dir)))
    130 
    131     def test_filename_changing_on_output_single_file(self):
    132         """2to3 a single file with a new output dir."""
    133         self.setup_test_source_trees()
    134         err = StringIO.StringIO()
    135         ret = self.run_2to3_capture(
    136                 ["-n", "-w", "--no-diffs", "--output-dir", self.py3_dest_dir,
    137                  self.trivial_py2_file],
    138                 StringIO.StringIO(""), StringIO.StringIO(), err)
    139         self.assertEqual(ret, 0)
    140         stderr = err.getvalue()
    141         self.assertIn(
    142                 "Output in %r will mirror the input directory %r layout" % (
    143                         self.py3_dest_dir, self.py2_src_dir), stderr)
    144         self.assertEqual(set([os.path.basename(self.trivial_py2_file)]),
    145                          set(os.listdir(self.py3_dest_dir)))
    146 
    147 
    148 if __name__ == '__main__':
    149     unittest.main()
    150