|
|
@ -1,545 +0,0 @@ |
|
|
import unittest |
|
|
|
|
|
import tempfile |
|
|
|
|
|
import shutil |
|
|
|
|
|
import os |
|
|
|
|
|
import mock |
|
|
|
|
|
import sys |
|
|
|
|
|
|
|
|
|
|
|
from elpy import refactor |
|
|
|
|
|
from textwrap import dedent |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RefactorTestCase(unittest.TestCase): |
|
|
|
|
|
def setUp(self): |
|
|
|
|
|
self.project_root = tempfile.mkdtemp(prefix="test-refactor-root") |
|
|
|
|
|
self.addCleanup(shutil.rmtree, self.project_root, |
|
|
|
|
|
ignore_errors=True) |
|
|
|
|
|
|
|
|
|
|
|
def create_file(self, name, contents=""): |
|
|
|
|
|
filename = os.path.join(self.project_root, name) |
|
|
|
|
|
contents = dedent(contents) |
|
|
|
|
|
offset = contents.find("_|_") |
|
|
|
|
|
if offset > -1: |
|
|
|
|
|
contents = contents[:offset] + contents[offset + 3:] |
|
|
|
|
|
with open(filename, "w") as f: |
|
|
|
|
|
f.write(contents) |
|
|
|
|
|
return filename, offset |
|
|
|
|
|
|
|
|
|
|
|
def assertSourceEqual(self, first, second, msg=None): |
|
|
|
|
|
"""Fail if the two objects are unequal, ignoring indentation.""" |
|
|
|
|
|
self.assertEqual(dedent(first), dedent(second), msg=msg) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestGetRefactorOptions(RefactorTestCase): |
|
|
|
|
|
def test_should_only_return_importsmodule_if_not_on_symbol(self): |
|
|
|
|
|
filename, offset = self.create_file("foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
import foo |
|
|
|
|
|
_|_""") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
options = ref.get_refactor_options(offset) |
|
|
|
|
|
self.assertTrue(all(opt['category'] in ('Imports', |
|
|
|
|
|
'Module') |
|
|
|
|
|
for opt in options)) |
|
|
|
|
|
filename, offset = self.create_file("foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
_|_ |
|
|
|
|
|
import foo""") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
options = ref.get_refactor_options(offset) |
|
|
|
|
|
self.assertTrue(all(opt['category'] in ('Imports', |
|
|
|
|
|
'Module') |
|
|
|
|
|
for opt in options)) |
|
|
|
|
|
|
|
|
|
|
|
def test_should_return_all_if_on_symbol(self): |
|
|
|
|
|
filename, offset = self.create_file("foo.py", |
|
|
|
|
|
"import _|_foo") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
options = ref.get_refactor_options(offset) |
|
|
|
|
|
self.assertTrue(all(opt['category'] in ('Imports', |
|
|
|
|
|
'Method', |
|
|
|
|
|
'Module', |
|
|
|
|
|
'Symbol') |
|
|
|
|
|
for opt in options)) |
|
|
|
|
|
|
|
|
|
|
|
def test_should_return_only_region_if_endoffset(self): |
|
|
|
|
|
filename, offset = self.create_file("foo.py", |
|
|
|
|
|
"import foo") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
options = ref.get_refactor_options(offset, 5) |
|
|
|
|
|
self.assertTrue(all(opt['category'] == 'Region' |
|
|
|
|
|
for opt in options)) |
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
def test_should_treat_from_import_special(self): |
|
|
|
|
|
filename, offset = self.create_file("foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
import foo |
|
|
|
|
|
_|_""") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
options = ref.get_refactor_options(offset) |
|
|
|
|
|
self.assertFalse(any(opt['name'] == "refactor_froms_to_imports" |
|
|
|
|
|
for opt in options)) |
|
|
|
|
|
filename, offset = self.create_file("foo.py", |
|
|
|
|
|
"imp_|_ort foo") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
options = ref.get_refactor_options(offset) |
|
|
|
|
|
self.assertTrue(any(opt['name'] == "refactor_froms_to_imports" |
|
|
|
|
|
for opt in options)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestGetChanges(RefactorTestCase): |
|
|
|
|
|
def test_should_fail_if_method_is_not_refactoring(self): |
|
|
|
|
|
filename, offset = self.create_file("foo.py") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
self.assertRaises(ValueError, ref.get_changes, "bad_name") |
|
|
|
|
|
|
|
|
|
|
|
def test_should_return_method_results(self): |
|
|
|
|
|
filename, offset = self.create_file("foo.py") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
with mock.patch.object(ref, 'refactor_extract_method') as test: |
|
|
|
|
|
test.return_value = "Meep!" |
|
|
|
|
|
self.assertEqual(ref.get_changes("refactor_extract_method", |
|
|
|
|
|
1, 2), |
|
|
|
|
|
"Meep!") |
|
|
|
|
|
test.assert_called_with(1, 2) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestIsOnSymbol(RefactorTestCase): |
|
|
|
|
|
def test_should_find_symbol(self): |
|
|
|
|
|
filename, offset = self.create_file("test.py", "__B_|_AR = 100") |
|
|
|
|
|
r = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
self.assertTrue(r._is_on_symbol(offset)) |
|
|
|
|
|
|
|
|
|
|
|
# Issue #111 |
|
|
|
|
|
def test_should_find_symbol_with_underscores(self): |
|
|
|
|
|
filename, offset = self.create_file("test.py", "_|___BAR = 100") |
|
|
|
|
|
r = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
self.assertTrue(r._is_on_symbol(offset)) |
|
|
|
|
|
|
|
|
|
|
|
def test_should_not_find_weird_places(self): |
|
|
|
|
|
filename, offset = self.create_file("test.py", "hello = _|_ 1 + 1") |
|
|
|
|
|
r = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
self.assertFalse(r._is_on_symbol(offset)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestFromsToImports(RefactorTestCase): |
|
|
|
|
|
def test_should_refactor(self): |
|
|
|
|
|
filename, offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
_|_from datetime import datetime |
|
|
|
|
|
|
|
|
|
|
|
d = datetime(2013, 4, 7) |
|
|
|
|
|
""") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
(change,) = ref.get_changes("refactor_froms_to_imports", offset) |
|
|
|
|
|
self.assertEqual(change['action'], 'change') |
|
|
|
|
|
self.assertEqual(change['file'], filename) |
|
|
|
|
|
self.assertSourceEqual(change['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
import datetime |
|
|
|
|
|
|
|
|
|
|
|
d = datetime.datetime(2013, 4, 7) |
|
|
|
|
|
""") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestOrganizeImports(RefactorTestCase): |
|
|
|
|
|
def test_should_refactor(self): |
|
|
|
|
|
filename, offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
import unittest, base64 |
|
|
|
|
|
import datetime, json |
|
|
|
|
|
|
|
|
|
|
|
obj = json.dumps(23) |
|
|
|
|
|
unittest.TestCase() |
|
|
|
|
|
""") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
(change,) = ref.get_changes("refactor_organize_imports") |
|
|
|
|
|
self.assertEqual(change['action'], 'change') |
|
|
|
|
|
self.assertEqual(change['file'], filename) |
|
|
|
|
|
self.assertSourceEqual(change['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
import json |
|
|
|
|
|
import unittest |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
obj = json.dumps(23) |
|
|
|
|
|
unittest.TestCase() |
|
|
|
|
|
""") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestModuleToPackage(RefactorTestCase): |
|
|
|
|
|
def test_should_refactor(self): |
|
|
|
|
|
filename, offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"_|_import os\n") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
changes = ref.refactor_module_to_package() |
|
|
|
|
|
a, b, c = changes |
|
|
|
|
|
# Not sure why the a change is there. It's a CHANGE that |
|
|
|
|
|
# changes nothing... |
|
|
|
|
|
self.assertEqual(a['diff'], '') |
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(b['action'], 'create') |
|
|
|
|
|
self.assertEqual(b['type'], 'directory') |
|
|
|
|
|
self.assertEqual(b['path'], os.path.join(self.project_root, "foo")) |
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(c['action'], 'move') |
|
|
|
|
|
self.assertEqual(c['type'], 'file') |
|
|
|
|
|
self.assertEqual(c['source'], os.path.join(self.project_root, |
|
|
|
|
|
"foo.py")) |
|
|
|
|
|
self.assertEqual(c['destination'], os.path.join(self.project_root, |
|
|
|
|
|
"foo/__init__.py")) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestRenameAtPoint(RefactorTestCase): |
|
|
|
|
|
def test_should_refactor(self): |
|
|
|
|
|
filename, offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
class Foo(object): |
|
|
|
|
|
def _|_foo(self): |
|
|
|
|
|
return 5 |
|
|
|
|
|
|
|
|
|
|
|
def bar(self): |
|
|
|
|
|
return self.foo() |
|
|
|
|
|
""") |
|
|
|
|
|
file2, offset2 = self.create_file( |
|
|
|
|
|
"bar.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
import foo |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x = foo.Foo() |
|
|
|
|
|
x.foo()""") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
first, second = ref.refactor_rename_at_point(offset, "frob", |
|
|
|
|
|
in_hierarchy=False, |
|
|
|
|
|
docs=False) |
|
|
|
|
|
if first['file'] == filename: |
|
|
|
|
|
a, b = first, second |
|
|
|
|
|
else: |
|
|
|
|
|
a, b = second, first |
|
|
|
|
|
self.assertEqual(a['action'], 'change') |
|
|
|
|
|
self.assertEqual(a['file'], filename) |
|
|
|
|
|
self.assertSourceEqual(a['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
class Foo(object): |
|
|
|
|
|
def frob(self): |
|
|
|
|
|
return 5 |
|
|
|
|
|
|
|
|
|
|
|
def bar(self): |
|
|
|
|
|
return self.frob() |
|
|
|
|
|
""") |
|
|
|
|
|
self.assertEqual(b['action'], 'change') |
|
|
|
|
|
self.assertEqual(b['file'], file2) |
|
|
|
|
|
self.assertSourceEqual(b['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
import foo |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x = foo.Foo() |
|
|
|
|
|
x.frob()""") |
|
|
|
|
|
|
|
|
|
|
|
def test_should_refactor_in_hierarchy(self): |
|
|
|
|
|
filename, offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
class Foo(object): |
|
|
|
|
|
def _|_foo(self): |
|
|
|
|
|
return 5 |
|
|
|
|
|
|
|
|
|
|
|
def bar(self): |
|
|
|
|
|
return self.foo() |
|
|
|
|
|
|
|
|
|
|
|
class Bar(Foo): |
|
|
|
|
|
def foo(self): |
|
|
|
|
|
return 42 |
|
|
|
|
|
|
|
|
|
|
|
class Baz(object): |
|
|
|
|
|
def foo(self): |
|
|
|
|
|
return 42 |
|
|
|
|
|
""") |
|
|
|
|
|
file2, offset2 = self.create_file( |
|
|
|
|
|
"bar.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
import foo |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x, y, z = foo.Foo(), foo.Bar(), foo.Baz() |
|
|
|
|
|
x.foo() |
|
|
|
|
|
y.foo() |
|
|
|
|
|
z.foo()""") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
first, second = ref.refactor_rename_at_point(offset, "frob", |
|
|
|
|
|
in_hierarchy=True, |
|
|
|
|
|
docs=False) |
|
|
|
|
|
if first['file'] == filename: |
|
|
|
|
|
a, b = first, second |
|
|
|
|
|
else: |
|
|
|
|
|
a, b = second, first |
|
|
|
|
|
self.assertEqual(a['action'], 'change') |
|
|
|
|
|
self.assertEqual(a['file'], filename) |
|
|
|
|
|
self.assertSourceEqual(a['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
class Foo(object): |
|
|
|
|
|
def frob(self): |
|
|
|
|
|
return 5 |
|
|
|
|
|
|
|
|
|
|
|
def bar(self): |
|
|
|
|
|
return self.frob() |
|
|
|
|
|
|
|
|
|
|
|
class Bar(Foo): |
|
|
|
|
|
def frob(self): |
|
|
|
|
|
return 42 |
|
|
|
|
|
|
|
|
|
|
|
class Baz(object): |
|
|
|
|
|
def foo(self): |
|
|
|
|
|
return 42 |
|
|
|
|
|
""") |
|
|
|
|
|
self.assertEqual(b['action'], 'change') |
|
|
|
|
|
self.assertEqual(b['file'], file2) |
|
|
|
|
|
self.assertSourceEqual(b['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
import foo |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
x, y, z = foo.Foo(), foo.Bar(), foo.Baz() |
|
|
|
|
|
x.frob() |
|
|
|
|
|
y.frob() |
|
|
|
|
|
z.foo()""") |
|
|
|
|
|
|
|
|
|
|
|
def test_should_refactor_in_docstrings(self): |
|
|
|
|
|
filename, offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
class Foo(object): |
|
|
|
|
|
"Frobnicate the foo" |
|
|
|
|
|
def _|_foo(self): |
|
|
|
|
|
return 5 |
|
|
|
|
|
|
|
|
|
|
|
print("I'm an unrelated foo") |
|
|
|
|
|
""") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
(change,) = ref.refactor_rename_at_point(offset, "frob", |
|
|
|
|
|
in_hierarchy=False, |
|
|
|
|
|
docs=True) |
|
|
|
|
|
self.assertEqual(change['action'], 'change') |
|
|
|
|
|
self.assertEqual(change['file'], filename) |
|
|
|
|
|
self.assertSourceEqual(change['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
class Foo(object): |
|
|
|
|
|
"Frobnicate the frob" |
|
|
|
|
|
def frob(self): |
|
|
|
|
|
return 5 |
|
|
|
|
|
|
|
|
|
|
|
print("I'm an unrelated foo") |
|
|
|
|
|
""") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestRenameCurrentModule(RefactorTestCase): |
|
|
|
|
|
def test_should_refactor(self): |
|
|
|
|
|
filename, offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"_|_import os\n") |
|
|
|
|
|
file2, offset = self.create_file( |
|
|
|
|
|
"bar.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
_|_import foo |
|
|
|
|
|
foo.os |
|
|
|
|
|
""") |
|
|
|
|
|
dest = os.path.join(self.project_root, "frob.py") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
a, b = ref.refactor_rename_current_module("frob") |
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(a['action'], 'change') |
|
|
|
|
|
self.assertEqual(a['file'], file2) |
|
|
|
|
|
self.assertEqual(a['contents'], |
|
|
|
|
|
"import frob\n" |
|
|
|
|
|
"frob.os\n") |
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(b['action'], 'move') |
|
|
|
|
|
self.assertEqual(b['type'], 'file') |
|
|
|
|
|
self.assertEqual(b['source'], filename) |
|
|
|
|
|
self.assertEqual(b['destination'], dest) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestMoveModule(RefactorTestCase): |
|
|
|
|
|
def test_should_refactor(self): |
|
|
|
|
|
filename, offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"_|_import os\n") |
|
|
|
|
|
file2, offset = self.create_file( |
|
|
|
|
|
"bar.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
_|_import foo |
|
|
|
|
|
foo.os |
|
|
|
|
|
""") |
|
|
|
|
|
dest = os.path.join(self.project_root, "frob") |
|
|
|
|
|
os.mkdir(dest) |
|
|
|
|
|
with open(os.path.join(dest, "__init__.py"), "w") as f: |
|
|
|
|
|
f.write("") |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
a, b = ref.refactor_move_module(dest) |
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(a['action'], 'change') |
|
|
|
|
|
self.assertEqual(a['file'], file2) |
|
|
|
|
|
self.assertSourceEqual(a['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
import frob.foo |
|
|
|
|
|
frob.foo.os |
|
|
|
|
|
""") |
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(b['action'], 'move') |
|
|
|
|
|
self.assertEqual(b['type'], 'file') |
|
|
|
|
|
self.assertEqual(b['source'], filename) |
|
|
|
|
|
self.assertEqual(b['destination'], |
|
|
|
|
|
os.path.join(dest, "foo.py")) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestCreateInline(RefactorTestCase): |
|
|
|
|
|
def setUp(self): |
|
|
|
|
|
super(TestCreateInline, self).setUp() |
|
|
|
|
|
self.filename, self.offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
def add(a, b): |
|
|
|
|
|
return a + b |
|
|
|
|
|
|
|
|
|
|
|
x = _|_add(2, 3) |
|
|
|
|
|
y = add(17, 4) |
|
|
|
|
|
""") |
|
|
|
|
|
|
|
|
|
|
|
def test_should_refactor_single_occurrenc(self): |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, self.filename) |
|
|
|
|
|
(change,) = ref.refactor_create_inline(self.offset, True) |
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(change['action'], 'change') |
|
|
|
|
|
self.assertEqual(change['file'], self.filename) |
|
|
|
|
|
self.assertSourceEqual(change['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
def add(a, b): |
|
|
|
|
|
return a + b |
|
|
|
|
|
|
|
|
|
|
|
x = 2 + 3 |
|
|
|
|
|
y = add(17, 4) |
|
|
|
|
|
""") |
|
|
|
|
|
|
|
|
|
|
|
def test_should_refactor_all_occurrencs(self): |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, self.filename) |
|
|
|
|
|
(change,) = ref.refactor_create_inline(self.offset, False) |
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(change['action'], 'change') |
|
|
|
|
|
self.assertEqual(change['file'], self.filename) |
|
|
|
|
|
self.assertSourceEqual(change['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
x = 2 + 3 |
|
|
|
|
|
y = 17 + 4 |
|
|
|
|
|
""") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestExtractMethod(RefactorTestCase): |
|
|
|
|
|
def setUp(self): |
|
|
|
|
|
super(TestExtractMethod, self).setUp() |
|
|
|
|
|
self.filename, self.offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
class Foo(object): |
|
|
|
|
|
def spaghetti(self, a, b): |
|
|
|
|
|
_|_x = a + 5 |
|
|
|
|
|
y = b + 23 |
|
|
|
|
|
return y |
|
|
|
|
|
""") |
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(sys.version_info >= (3, 5), "Python 3.5 not supported") |
|
|
|
|
|
def test_should_refactor_local(self): |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, self.filename) |
|
|
|
|
|
(change,) = ref.refactor_extract_method(self.offset, 104, |
|
|
|
|
|
"calc", False) |
|
|
|
|
|
self.assertEqual(change['action'], 'change') |
|
|
|
|
|
self.assertEqual(change['file'], self.filename) |
|
|
|
|
|
expected = """\ |
|
|
|
|
|
class Foo(object): |
|
|
|
|
|
def spaghetti(self, a, b): |
|
|
|
|
|
return self.calc(a, b) |
|
|
|
|
|
|
|
|
|
|
|
def calc(self, a, b): |
|
|
|
|
|
x = a + 5 |
|
|
|
|
|
y = b + 23 |
|
|
|
|
|
return y |
|
|
|
|
|
""" |
|
|
|
|
|
expected2 = expected.replace("return self.calc(a, b)", |
|
|
|
|
|
"return self.calc(b, a)") |
|
|
|
|
|
expected2 = expected2.replace("def calc(self, a, b)", |
|
|
|
|
|
"def calc(self, b, a)") |
|
|
|
|
|
# This is silly, but it's what we got. |
|
|
|
|
|
if change['contents'] == dedent(expected2): |
|
|
|
|
|
self.assertSourceEqual(change['contents'], expected2) |
|
|
|
|
|
else: |
|
|
|
|
|
self.assertSourceEqual(change['contents'], expected) |
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(sys.version_info >= (3, 5), "Python 3.5 not supported") |
|
|
|
|
|
def test_should_refactor_global(self): |
|
|
|
|
|
ref = refactor.Refactor(self.project_root, self.filename) |
|
|
|
|
|
(change,) = ref.refactor_extract_method(self.offset, 104, |
|
|
|
|
|
"calc", True) |
|
|
|
|
|
self.assertEqual(change['action'], 'change') |
|
|
|
|
|
self.assertEqual(change['file'], self.filename) |
|
|
|
|
|
expected = """\ |
|
|
|
|
|
class Foo(object): |
|
|
|
|
|
def spaghetti(self, a, b): |
|
|
|
|
|
return calc(a, b) |
|
|
|
|
|
|
|
|
|
|
|
def calc(a, b): |
|
|
|
|
|
x = a + 5 |
|
|
|
|
|
y = b + 23 |
|
|
|
|
|
return y |
|
|
|
|
|
""" |
|
|
|
|
|
expected2 = expected.replace("return calc(a, b)", |
|
|
|
|
|
"return calc(b, a)") |
|
|
|
|
|
expected2 = expected2.replace("def calc(a, b)", |
|
|
|
|
|
"def calc(b, a)") |
|
|
|
|
|
if change['contents'] == dedent(expected2): |
|
|
|
|
|
self.assertSourceEqual(change['contents'], expected2) |
|
|
|
|
|
else: |
|
|
|
|
|
self.assertSourceEqual(change['contents'], expected) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@unittest.skipIf(not refactor.ROPE_AVAILABLE, "Requires Rope") |
|
|
|
|
|
class TestUseFunction(RefactorTestCase): |
|
|
|
|
|
def test_should_refactor(self): |
|
|
|
|
|
filename, offset = self.create_file( |
|
|
|
|
|
"foo.py", |
|
|
|
|
|
"""\ |
|
|
|
|
|
def _|_add_and_multiply(a, b, c): |
|
|
|
|
|
temp = a + b |
|
|
|
|
|
return temp * c |
|
|
|
|
|
|
|
|
|
|
|
f = 1 + 2 |
|
|
|
|
|
g = f * 3 |
|
|
|
|
|
""") |
|
|
|
|
|
|
|
|
|
|
|
ref = refactor.Refactor(self.project_root, filename) |
|
|
|
|
|
(change,) = ref.refactor_use_function(offset) |
|
|
|
|
|
|
|
|
|
|
|
self.assertEqual(change['action'], 'change') |
|
|
|
|
|
self.assertEqual(change['file'], filename) |
|
|
|
|
|
self.assertSourceEqual(change['contents'], |
|
|
|
|
|
"""\ |
|
|
|
|
|
def add_and_multiply(a, b, c): |
|
|
|
|
|
temp = a + b |
|
|
|
|
|
return temp * c |
|
|
|
|
|
|
|
|
|
|
|
g = add_and_multiply(1, 2, 3) |
|
|
|
|
|
""") |
|
|
|