mirror of
https://github.com/python/cpython.git
synced 2025-07-23 03:05:38 +00:00

svn+ssh://pythondev@svn.python.org/python/trunk ........ r78351 | r.david.murray | 2010-02-22 19:24:49 -0500 (Mon, 22 Feb 2010) | 5 lines Issue 6292: for the moment at least, the test suite passes if run with -OO. Tests requiring docstrings are skipped. Patch by Brian Curtin, thanks to Matias Torchinsky for helping review and improve the patch. ........
275 lines
9.5 KiB
Python
275 lines
9.5 KiB
Python
"""
|
|
Unit tests for refactor.py.
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
import codecs
|
|
import operator
|
|
import io
|
|
import tempfile
|
|
import shutil
|
|
import unittest
|
|
import warnings
|
|
|
|
from lib2to3 import refactor, pygram, fixer_base
|
|
from lib2to3.pgen2 import token
|
|
|
|
from . import support
|
|
|
|
|
|
TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
|
|
FIXER_DIR = os.path.join(TEST_DATA_DIR, "fixers")
|
|
|
|
sys.path.append(FIXER_DIR)
|
|
try:
|
|
_DEFAULT_FIXERS = refactor.get_fixers_from_package("myfixes")
|
|
finally:
|
|
sys.path.pop()
|
|
|
|
_2TO3_FIXERS = refactor.get_fixers_from_package("lib2to3.fixes")
|
|
|
|
class TestRefactoringTool(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
sys.path.append(FIXER_DIR)
|
|
|
|
def tearDown(self):
|
|
sys.path.pop()
|
|
|
|
def check_instances(self, instances, classes):
|
|
for inst, cls in zip(instances, classes):
|
|
if not isinstance(inst, cls):
|
|
self.fail("%s are not instances of %s" % instances, classes)
|
|
|
|
def rt(self, options=None, fixers=_DEFAULT_FIXERS, explicit=None):
|
|
return refactor.RefactoringTool(fixers, options, explicit)
|
|
|
|
def test_print_function_option(self):
|
|
rt = self.rt({"print_function" : True})
|
|
self.assertTrue(rt.grammar is pygram.python_grammar_no_print_statement)
|
|
self.assertTrue(rt.driver.grammar is
|
|
pygram.python_grammar_no_print_statement)
|
|
|
|
def test_fixer_loading_helpers(self):
|
|
contents = ["explicit", "first", "last", "parrot", "preorder"]
|
|
non_prefixed = refactor.get_all_fix_names("myfixes")
|
|
prefixed = refactor.get_all_fix_names("myfixes", False)
|
|
full_names = refactor.get_fixers_from_package("myfixes")
|
|
self.assertEqual(prefixed, ["fix_" + name for name in contents])
|
|
self.assertEqual(non_prefixed, contents)
|
|
self.assertEqual(full_names,
|
|
["myfixes.fix_" + name for name in contents])
|
|
|
|
def test_detect_future_print(self):
|
|
run = refactor._detect_future_print
|
|
self.assertFalse(run(""))
|
|
self.assertTrue(run("from __future__ import print_function"))
|
|
self.assertFalse(run("from __future__ import generators"))
|
|
self.assertFalse(run("from __future__ import generators, feature"))
|
|
input = "from __future__ import generators, print_function"
|
|
self.assertTrue(run(input))
|
|
input ="from __future__ import print_function, generators"
|
|
self.assertTrue(run(input))
|
|
input = "from __future__ import (print_function,)"
|
|
self.assertTrue(run(input))
|
|
input = "from __future__ import (generators, print_function)"
|
|
self.assertTrue(run(input))
|
|
input = "from __future__ import (generators, nested_scopes)"
|
|
self.assertFalse(run(input))
|
|
input = """from __future__ import generators
|
|
from __future__ import print_function"""
|
|
self.assertTrue(run(input))
|
|
self.assertFalse(run("from"))
|
|
self.assertFalse(run("from 4"))
|
|
self.assertFalse(run("from x"))
|
|
self.assertFalse(run("from x 5"))
|
|
self.assertFalse(run("from x im"))
|
|
self.assertFalse(run("from x import"))
|
|
self.assertFalse(run("from x import 4"))
|
|
input = "'docstring'\nfrom __future__ import print_function"
|
|
self.assertTrue(run(input))
|
|
input = "'docstring'\n'somng'\nfrom __future__ import print_function"
|
|
self.assertFalse(run(input))
|
|
input = "# comment\nfrom __future__ import print_function"
|
|
self.assertTrue(run(input))
|
|
input = "# comment\n'doc'\nfrom __future__ import print_function"
|
|
self.assertTrue(run(input))
|
|
input = "class x: pass\nfrom __future__ import print_function"
|
|
self.assertFalse(run(input))
|
|
|
|
def test_get_headnode_dict(self):
|
|
class NoneFix(fixer_base.BaseFix):
|
|
pass
|
|
|
|
class FileInputFix(fixer_base.BaseFix):
|
|
PATTERN = "file_input< any * >"
|
|
|
|
class SimpleFix(fixer_base.BaseFix):
|
|
PATTERN = "'name'"
|
|
|
|
no_head = NoneFix({}, [])
|
|
with_head = FileInputFix({}, [])
|
|
simple = SimpleFix({}, [])
|
|
d = refactor._get_headnode_dict([no_head, with_head, simple])
|
|
top_fixes = d.pop(pygram.python_symbols.file_input)
|
|
self.assertEqual(top_fixes, [with_head, no_head])
|
|
name_fixes = d.pop(token.NAME)
|
|
self.assertEqual(name_fixes, [simple, no_head])
|
|
for fixes in d.values():
|
|
self.assertEqual(fixes, [no_head])
|
|
|
|
def test_fixer_loading(self):
|
|
from myfixes.fix_first import FixFirst
|
|
from myfixes.fix_last import FixLast
|
|
from myfixes.fix_parrot import FixParrot
|
|
from myfixes.fix_preorder import FixPreorder
|
|
|
|
rt = self.rt()
|
|
pre, post = rt.get_fixers()
|
|
|
|
self.check_instances(pre, [FixPreorder])
|
|
self.check_instances(post, [FixFirst, FixParrot, FixLast])
|
|
|
|
def test_naughty_fixers(self):
|
|
self.assertRaises(ImportError, self.rt, fixers=["not_here"])
|
|
self.assertRaises(refactor.FixerError, self.rt, fixers=["no_fixer_cls"])
|
|
self.assertRaises(refactor.FixerError, self.rt, fixers=["bad_order"])
|
|
|
|
def test_refactor_string(self):
|
|
rt = self.rt()
|
|
input = "def parrot(): pass\n\n"
|
|
tree = rt.refactor_string(input, "<test>")
|
|
self.assertNotEqual(str(tree), input)
|
|
|
|
input = "def f(): pass\n\n"
|
|
tree = rt.refactor_string(input, "<test>")
|
|
self.assertEqual(str(tree), input)
|
|
|
|
def test_refactor_stdin(self):
|
|
|
|
class MyRT(refactor.RefactoringTool):
|
|
|
|
def print_output(self, old_text, new_text, filename, equal):
|
|
results.extend([old_text, new_text, filename, equal])
|
|
|
|
results = []
|
|
rt = MyRT(_DEFAULT_FIXERS)
|
|
save = sys.stdin
|
|
sys.stdin = io.StringIO("def parrot(): pass\n\n")
|
|
try:
|
|
rt.refactor_stdin()
|
|
finally:
|
|
sys.stdin = save
|
|
expected = ["def parrot(): pass\n\n",
|
|
"def cheese(): pass\n\n",
|
|
"<stdin>", False]
|
|
self.assertEqual(results, expected)
|
|
|
|
def check_file_refactoring(self, test_file, fixers=_2TO3_FIXERS):
|
|
def read_file():
|
|
with open(test_file, "rb") as fp:
|
|
return fp.read()
|
|
old_contents = read_file()
|
|
rt = self.rt(fixers=fixers)
|
|
|
|
rt.refactor_file(test_file)
|
|
self.assertEqual(old_contents, read_file())
|
|
|
|
try:
|
|
rt.refactor_file(test_file, True)
|
|
new_contents = read_file()
|
|
self.assertNotEqual(old_contents, new_contents)
|
|
finally:
|
|
with open(test_file, "wb") as fp:
|
|
fp.write(old_contents)
|
|
return new_contents
|
|
|
|
def test_refactor_file(self):
|
|
test_file = os.path.join(FIXER_DIR, "parrot_example.py")
|
|
self.check_file_refactoring(test_file, _DEFAULT_FIXERS)
|
|
|
|
def test_refactor_dir(self):
|
|
def check(structure, expected):
|
|
def mock_refactor_file(self, f, *args):
|
|
got.append(f)
|
|
save_func = refactor.RefactoringTool.refactor_file
|
|
refactor.RefactoringTool.refactor_file = mock_refactor_file
|
|
rt = self.rt()
|
|
got = []
|
|
dir = tempfile.mkdtemp(prefix="2to3-test_refactor")
|
|
try:
|
|
os.mkdir(os.path.join(dir, "a_dir"))
|
|
for fn in structure:
|
|
open(os.path.join(dir, fn), "wb").close()
|
|
rt.refactor_dir(dir)
|
|
finally:
|
|
refactor.RefactoringTool.refactor_file = save_func
|
|
shutil.rmtree(dir)
|
|
self.assertEqual(got,
|
|
[os.path.join(dir, path) for path in expected])
|
|
check([], [])
|
|
tree = ["nothing",
|
|
"hi.py",
|
|
".dumb",
|
|
".after.py",
|
|
"sappy"]
|
|
expected = ["hi.py"]
|
|
check(tree, expected)
|
|
tree = ["hi.py",
|
|
os.path.join("a_dir", "stuff.py")]
|
|
check(tree, tree)
|
|
|
|
def test_file_encoding(self):
|
|
fn = os.path.join(TEST_DATA_DIR, "different_encoding.py")
|
|
self.check_file_refactoring(fn)
|
|
|
|
def test_bom(self):
|
|
fn = os.path.join(TEST_DATA_DIR, "bom.py")
|
|
data = self.check_file_refactoring(fn)
|
|
self.assertTrue(data.startswith(codecs.BOM_UTF8))
|
|
|
|
def test_crlf_newlines(self):
|
|
old_sep = os.linesep
|
|
os.linesep = "\r\n"
|
|
try:
|
|
fn = os.path.join(TEST_DATA_DIR, "crlf.py")
|
|
fixes = refactor.get_fixers_from_package("lib2to3.fixes")
|
|
self.check_file_refactoring(fn, fixes)
|
|
finally:
|
|
os.linesep = old_sep
|
|
|
|
|
|
@unittest.skipIf(sys.flags.optimize >= 2,
|
|
"Docstrings are omitted with -O2 and above")
|
|
def test_refactor_docstring(self):
|
|
rt = self.rt()
|
|
|
|
def example():
|
|
"""
|
|
>>> example()
|
|
42
|
|
"""
|
|
out = rt.refactor_docstring(example.__doc__, "<test>")
|
|
self.assertEqual(out, example.__doc__)
|
|
|
|
def parrot():
|
|
"""
|
|
>>> def parrot():
|
|
... return 43
|
|
"""
|
|
out = rt.refactor_docstring(parrot.__doc__, "<test>")
|
|
self.assertNotEqual(out, parrot.__doc__)
|
|
|
|
def test_explicit(self):
|
|
from myfixes.fix_explicit import FixExplicit
|
|
|
|
rt = self.rt(fixers=["myfixes.fix_explicit"])
|
|
self.assertEqual(len(rt.post_order), 0)
|
|
|
|
rt = self.rt(explicit=["myfixes.fix_explicit"])
|
|
for fix in rt.post_order:
|
|
if isinstance(fix, FixExplicit):
|
|
break
|
|
else:
|
|
self.fail("explicit fixer not loaded")
|