/Lib/lib2to3/tests/test_refactor.py

http://unladen-swallow.googlecode.com/ · Python · 170 lines · 123 code · 35 blank · 12 comment · 16 complexity · 1733c3da5e35a7ae29ad4096941426a0 MD5 · raw file

  1. """
  2. Unit tests for refactor.py.
  3. """
  4. import sys
  5. import os
  6. import operator
  7. import StringIO
  8. import tempfile
  9. import unittest
  10. from lib2to3 import refactor, pygram, fixer_base
  11. from . import support
  12. FIXER_DIR = os.path.join(os.path.dirname(__file__), "data/fixers")
  13. sys.path.append(FIXER_DIR)
  14. try:
  15. _DEFAULT_FIXERS = refactor.get_fixers_from_package("myfixes")
  16. finally:
  17. sys.path.pop()
  18. class TestRefactoringTool(unittest.TestCase):
  19. def setUp(self):
  20. sys.path.append(FIXER_DIR)
  21. def tearDown(self):
  22. sys.path.pop()
  23. def check_instances(self, instances, classes):
  24. for inst, cls in zip(instances, classes):
  25. if not isinstance(inst, cls):
  26. self.fail("%s are not instances of %s" % instances, classes)
  27. def rt(self, options=None, fixers=_DEFAULT_FIXERS, explicit=None):
  28. return refactor.RefactoringTool(fixers, options, explicit)
  29. def test_print_function_option(self):
  30. gram = pygram.python_grammar
  31. save = gram.keywords["print"]
  32. try:
  33. rt = self.rt({"print_function" : True})
  34. self.assertRaises(KeyError, operator.itemgetter("print"),
  35. gram.keywords)
  36. finally:
  37. gram.keywords["print"] = save
  38. def test_fixer_loading_helpers(self):
  39. contents = ["explicit", "first", "last", "parrot", "preorder"]
  40. non_prefixed = refactor.get_all_fix_names("myfixes")
  41. prefixed = refactor.get_all_fix_names("myfixes", False)
  42. full_names = refactor.get_fixers_from_package("myfixes")
  43. self.assertEqual(prefixed, ["fix_" + name for name in contents])
  44. self.assertEqual(non_prefixed, contents)
  45. self.assertEqual(full_names,
  46. ["myfixes.fix_" + name for name in contents])
  47. def test_get_headnode_dict(self):
  48. class NoneFix(fixer_base.BaseFix):
  49. PATTERN = None
  50. class FileInputFix(fixer_base.BaseFix):
  51. PATTERN = "file_input< any * >"
  52. no_head = NoneFix({}, [])
  53. with_head = FileInputFix({}, [])
  54. d = refactor.get_headnode_dict([no_head, with_head])
  55. expected = {None: [no_head],
  56. pygram.python_symbols.file_input : [with_head]}
  57. self.assertEqual(d, expected)
  58. def test_fixer_loading(self):
  59. from myfixes.fix_first import FixFirst
  60. from myfixes.fix_last import FixLast
  61. from myfixes.fix_parrot import FixParrot
  62. from myfixes.fix_preorder import FixPreorder
  63. rt = self.rt()
  64. pre, post = rt.get_fixers()
  65. self.check_instances(pre, [FixPreorder])
  66. self.check_instances(post, [FixFirst, FixParrot, FixLast])
  67. def test_naughty_fixers(self):
  68. self.assertRaises(ImportError, self.rt, fixers=["not_here"])
  69. self.assertRaises(refactor.FixerError, self.rt, fixers=["no_fixer_cls"])
  70. self.assertRaises(refactor.FixerError, self.rt, fixers=["bad_order"])
  71. def test_refactor_string(self):
  72. rt = self.rt()
  73. input = "def parrot(): pass\n\n"
  74. tree = rt.refactor_string(input, "<test>")
  75. self.assertNotEqual(str(tree), input)
  76. input = "def f(): pass\n\n"
  77. tree = rt.refactor_string(input, "<test>")
  78. self.assertEqual(str(tree), input)
  79. def test_refactor_stdin(self):
  80. class MyRT(refactor.RefactoringTool):
  81. def print_output(self, lines):
  82. diff_lines.extend(lines)
  83. diff_lines = []
  84. rt = MyRT(_DEFAULT_FIXERS)
  85. save = sys.stdin
  86. sys.stdin = StringIO.StringIO("def parrot(): pass\n\n")
  87. try:
  88. rt.refactor_stdin()
  89. finally:
  90. sys.stdin = save
  91. expected = """--- <stdin> (original)
  92. +++ <stdin> (refactored)
  93. @@ -1,2 +1,2 @@
  94. -def parrot(): pass
  95. +def cheese(): pass""".splitlines()
  96. self.assertEqual(diff_lines[:-1], expected)
  97. def test_refactor_file(self):
  98. test_file = os.path.join(FIXER_DIR, "parrot_example.py")
  99. old_contents = open(test_file, "r").read()
  100. rt = self.rt()
  101. rt.refactor_file(test_file)
  102. self.assertEqual(old_contents, open(test_file, "r").read())
  103. rt.refactor_file(test_file, True)
  104. try:
  105. self.assertNotEqual(old_contents, open(test_file, "r").read())
  106. finally:
  107. open(test_file, "w").write(old_contents)
  108. # Docstrings are omitted when Python is passed -OO, so skip this test.
  109. if sys.flags.optimize <= 1:
  110. def test_refactor_docstring(self):
  111. rt = self.rt()
  112. def example():
  113. """
  114. >>> example()
  115. 42
  116. """
  117. out = rt.refactor_docstring(example.__doc__, "<test>")
  118. self.assertEqual(out, example.__doc__)
  119. def parrot():
  120. """
  121. >>> def parrot():
  122. ... return 43
  123. """
  124. out = rt.refactor_docstring(parrot.__doc__, "<test>")
  125. self.assertNotEqual(out, parrot.__doc__)
  126. def test_explicit(self):
  127. from myfixes.fix_explicit import FixExplicit
  128. rt = self.rt(fixers=["myfixes.fix_explicit"])
  129. self.assertEqual(len(rt.post_order), 0)
  130. rt = self.rt(explicit=["myfixes.fix_explicit"])
  131. for fix in rt.post_order:
  132. if isinstance(fix, FixExplicit):
  133. break
  134. else:
  135. self.fail("explicit fixer not loaded")