From fe6b753f5b2085bb6e972b3b312f759aae750d2e Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Tue, 11 Feb 2014 16:16:13 +0400 Subject: [PATCH] PY-10963 Pushing methods down should add needed imports (test only added) --- .../PyExtractSuperclassHelper.java | 6 +- .../PyMembersRefactoringBaseProcessor.java | 4 +- .../classes/pullUp/PyPullUpProcessor.java | 2 +- .../classes/pushDown/PyPushDownHandler.java | 28 ++++---- .../pushDown/PyPushDownPresenterImpl.java | 22 +++--- .../classes/pushDown/PyPushDownProcessor.java | 9 ++- .../importMultiFile/dest_module.after.py | 6 ++ .../importMultiFile/dest_module.py | 0 .../importMultiFile/source_module.after.py | 4 ++ .../importMultiFile/source_module.py | 6 ++ .../pullup/duplicateImport/Class.after.py | 7 ++ .../pullup/duplicateImport/Class.py | 3 + .../duplicateImport/SuperClass.after.py | 3 + .../pullup/multiFile/Class.after.py | 4 ++ .../multiFileImports/child_module.after.py | 6 ++ .../pushdown/multiFileImports/child_module.py | 4 ++ .../multiFileImports/parent_module.after.py | 4 ++ .../multiFileImports/parent_module.py | 6 ++ .../classes/PyClassRefactoringTest.java | 45 ++++++++++-- .../PyExtractSuperclassTest.java | 71 ++++++++++++------- .../classes/pullUp/PyPullUpTest.java | 18 +++-- .../classes/pushDown/PyPushDownTest.java | 43 +++++++---- 22 files changed, 223 insertions(+), 78 deletions(-) create mode 100644 python/testData/refactoring/extractsuperclass/importMultiFile/dest_module.after.py create mode 100644 python/testData/refactoring/extractsuperclass/importMultiFile/dest_module.py create mode 100644 python/testData/refactoring/extractsuperclass/importMultiFile/source_module.after.py create mode 100644 python/testData/refactoring/extractsuperclass/importMultiFile/source_module.py create mode 100644 python/testData/refactoring/pullup/duplicateImport/Class.after.py create mode 100644 python/testData/refactoring/pullup/multiFile/Class.after.py create mode 100644 python/testData/refactoring/pushdown/multiFileImports/child_module.after.py create mode 100644 python/testData/refactoring/pushdown/multiFileImports/child_module.py create mode 100644 python/testData/refactoring/pushdown/multiFileImports/parent_module.after.py create mode 100644 python/testData/refactoring/pushdown/multiFileImports/parent_module.py diff --git a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java index 3274b65364c7..f57d18cddb18 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java +++ b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java @@ -39,6 +39,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -56,10 +57,13 @@ public final class PyExtractSuperclassHelper { } static void extractSuperclass(final PyClass clazz, - final Collection selectedMemberInfos, + @NotNull Collection selectedMemberInfos, final String superBaseName, final String targetFile) { + //We will need to change it probably while param may be read-only + //noinspection AssignmentToMethodParameter + selectedMemberInfos = new ArrayList(selectedMemberInfos); // 'object' superclass is always pulled up, even if not selected explicitly if (MembersManager.findMember(selectedMemberInfos, ALLOW_OBJECT) == null) { final PyMemberInfo object = MembersManager.findMember(clazz, ALLOW_OBJECT); diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMembersRefactoringBaseProcessor.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMembersRefactoringBaseProcessor.java index 3aa195514db1..346990c2fd4e 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMembersRefactoringBaseProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMembersRefactoringBaseProcessor.java @@ -1,5 +1,6 @@ package com.jetbrains.python.refactoring.classes.membersManager; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.usageView.UsageInfo; @@ -32,10 +33,11 @@ public abstract class PyMembersRefactoringBaseProcessor extends BaseRefactoringP * @param to where to move */ protected PyMembersRefactoringBaseProcessor( + @NotNull final Project project, @NotNull final Collection membersToMove, @NotNull final PyClass from, @NotNull final PyClass... to) { - super(from.getProject()); + super(project); myFrom = from; myMembersToMove = new ArrayList(membersToMove); myTo = to.clone(); diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpProcessor.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpProcessor.java index d87195551ed1..673bd602a2fb 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpProcessor.java @@ -17,7 +17,7 @@ import java.util.Collection; class PyPullUpProcessor extends PyMembersRefactoringBaseProcessor { PyPullUpProcessor(@NotNull final PyClass from, @NotNull final PyClass to, @NotNull final Collection membersToMove) { - super(membersToMove, from, to); + super(from.getProject(), membersToMove, from, to); } diff --git a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownHandler.java b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownHandler.java index bd5c3088f6ca..08fda7107c47 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownHandler.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownHandler.java @@ -20,9 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.util.Query; -import com.jetbrains.python.PyBundle; import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyUtil; import com.jetbrains.python.psi.search.PyClassInheritorsSearch; import com.jetbrains.python.refactoring.classes.PyClassRefactoringHandler; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; @@ -50,19 +48,20 @@ public class PyPushDownHandler extends PyClassRefactoringHandler { return; } - ViewPresenterUtils.linkViewWithPresenterAndLaunch(PyPushDownPresenter.class, PyPushDownView.class, new Creator() { - @NotNull - @Override - public PyPushDownPresenter createPresenter(@NotNull PyPushDownView view) { - return new PyPushDownPresenterImpl(view, classUnderRefactoring, infoStorage); - } + ViewPresenterUtils + .linkViewWithPresenterAndLaunch(PyPushDownPresenter.class, PyPushDownView.class, new Creator() { + @NotNull + @Override + public PyPushDownPresenter createPresenter(@NotNull PyPushDownView view) { + return new PyPushDownPresenterImpl(project, view, classUnderRefactoring, infoStorage); + } - @NotNull - @Override - public PyPushDownView createView(@NotNull PyPushDownPresenter presenter) { - return new PyPushDownViewSwingImpl(classUnderRefactoring, project, presenter); - } - }); + @NotNull + @Override + public PyPushDownView createView(@NotNull PyPushDownPresenter presenter) { + return new PyPushDownViewSwingImpl(classUnderRefactoring, project, presenter); + } + }); } @Override @@ -74,5 +73,4 @@ public class PyPushDownHandler extends PyClassRefactoringHandler { protected String getHelpId() { return "members.push.down"; } - } diff --git a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownPresenterImpl.java b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownPresenterImpl.java index 3168638e45e9..439c5746686b 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownPresenterImpl.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownPresenterImpl.java @@ -1,5 +1,6 @@ package com.jetbrains.python.refactoring.classes.pushDown; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.classMembers.UsedByDependencyMemberInfoModel; @@ -7,29 +8,31 @@ import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyUtil; -import com.jetbrains.python.psi.search.PyClassInheritorsSearch; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.membersManager.vp.MembersBasedPresenterWithPreviewImpl; import com.jetbrains.python.refactoring.classes.membersManager.vp.MembersViewInitializationInfo; import org.jetbrains.annotations.NotNull; -import java.util.Collection; - /** - * Created by Ilya.Kazakevich on 10.02.14. + * @author Ilya.Kazakevich */ public class PyPushDownPresenterImpl extends MembersBasedPresenterWithPreviewImpl implements PyPushDownPresenter { - public PyPushDownPresenterImpl(@NotNull PyPushDownView view, - @NotNull PyClass classUnderRefactoring, - @NotNull PyMemberInfoStorage infoStorage) { + @NotNull + private final Project myProject; + + public PyPushDownPresenterImpl(@NotNull final Project project, + @NotNull final PyPushDownView view, + @NotNull final PyClass classUnderRefactoring, + @NotNull final PyMemberInfoStorage infoStorage) { super(view, classUnderRefactoring, infoStorage); + myProject = project; } @NotNull @Override public BaseRefactoringProcessor createProcessor() { - return new PyPushDownProcessor(myView.getSelectedMemberInfos(), myClassUnderRefactoring); + return new PyPushDownProcessor(myProject, myView.getSelectedMemberInfos(), myClassUnderRefactoring); } @NotNull @@ -42,7 +45,8 @@ public class PyPushDownPresenterImpl extends MembersBasedPresenterWithPreviewImp public void launch() { UsedByDependencyMemberInfoModel model = new UsedByDependencyMemberInfoModel(myClassUnderRefactoring); - myView.configure(new MembersViewInitializationInfo(model, PyUtil.filterOutObject(myStorage.getClassMemberInfos(myClassUnderRefactoring)))); + myView + .configure(new MembersViewInitializationInfo(model, PyUtil.filterOutObject(myStorage.getClassMemberInfos(myClassUnderRefactoring)))); myView.initAndShow(); } } diff --git a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java index 713da65c17c1..ae4aa33405fc 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java @@ -15,6 +15,7 @@ */ package com.jetbrains.python.refactoring.classes.pushDown; +import com.intellij.openapi.project.Project; import com.intellij.refactoring.RefactoringBundle; import com.intellij.usageView.UsageViewBundle; import com.jetbrains.python.psi.PyClass; @@ -33,9 +34,11 @@ public class PyPushDownProcessor extends PyMembersRefactoringBaseProcessor { private static final String HEADER = RefactoringBundle.message("push.down.members.elements.header"); - public PyPushDownProcessor(@NotNull Collection membersToMove, - @NotNull PyClass from) { - super(membersToMove, from, getChildren(from)); + public PyPushDownProcessor( + @NotNull final Project project, + @NotNull final Collection membersToMove, + @NotNull final PyClass from) { + super(project, membersToMove, from, getChildren(from)); } @NotNull diff --git a/python/testData/refactoring/extractsuperclass/importMultiFile/dest_module.after.py b/python/testData/refactoring/extractsuperclass/importMultiFile/dest_module.after.py new file mode 100644 index 000000000000..d1cfabf45123 --- /dev/null +++ b/python/testData/refactoring/extractsuperclass/importMultiFile/dest_module.after.py @@ -0,0 +1,6 @@ +import shutil + + +class NewParent(object): + def do_useful_stuff(self): + shutil.rmtree("/", ignore_errors=True) \ No newline at end of file diff --git a/python/testData/refactoring/extractsuperclass/importMultiFile/dest_module.py b/python/testData/refactoring/extractsuperclass/importMultiFile/dest_module.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/refactoring/extractsuperclass/importMultiFile/source_module.after.py b/python/testData/refactoring/extractsuperclass/importMultiFile/source_module.after.py new file mode 100644 index 000000000000..0b7e52858da6 --- /dev/null +++ b/python/testData/refactoring/extractsuperclass/importMultiFile/source_module.after.py @@ -0,0 +1,4 @@ +import dest_module + +class MyClass(dest_module.MyNewParent): + pass \ No newline at end of file diff --git a/python/testData/refactoring/extractsuperclass/importMultiFile/source_module.py b/python/testData/refactoring/extractsuperclass/importMultiFile/source_module.py new file mode 100644 index 000000000000..d9465cf28dae --- /dev/null +++ b/python/testData/refactoring/extractsuperclass/importMultiFile/source_module.py @@ -0,0 +1,6 @@ +import shutil + + +class MyClass(object): + def do_useful_stuff(self): + shutil.rmtree("/", ignore_errors=True) \ No newline at end of file diff --git a/python/testData/refactoring/pullup/duplicateImport/Class.after.py b/python/testData/refactoring/pullup/duplicateImport/Class.after.py new file mode 100644 index 000000000000..4aa1cb23e75b --- /dev/null +++ b/python/testData/refactoring/pullup/duplicateImport/Class.after.py @@ -0,0 +1,7 @@ +from SuperClass import SuperClass + + + + +class AnyClass(SuperClass): + pass diff --git a/python/testData/refactoring/pullup/duplicateImport/Class.py b/python/testData/refactoring/pullup/duplicateImport/Class.py index bd19d07b851d..5e5af1877c4d 100644 --- a/python/testData/refactoring/pullup/duplicateImport/Class.py +++ b/python/testData/refactoring/pullup/duplicateImport/Class.py @@ -1,4 +1,6 @@ from SuperClass import SuperClass +import os + from sys import argv @@ -7,3 +9,4 @@ class AnyClass(SuperClass): if not self.args: self.args = argv self.argument = some_argument + os.abort() diff --git a/python/testData/refactoring/pullup/duplicateImport/SuperClass.after.py b/python/testData/refactoring/pullup/duplicateImport/SuperClass.after.py index 19fa11b25860..a4cdf89ed9dd 100644 --- a/python/testData/refactoring/pullup/duplicateImport/SuperClass.after.py +++ b/python/testData/refactoring/pullup/duplicateImport/SuperClass.after.py @@ -1,4 +1,6 @@ from sys import argv +import os + class SuperClass(object): def __init__(self): @@ -8,3 +10,4 @@ class SuperClass(object): if not self.args: self.args = argv self.argument = some_argument + os.abort() diff --git a/python/testData/refactoring/pullup/multiFile/Class.after.py b/python/testData/refactoring/pullup/multiFile/Class.after.py new file mode 100644 index 000000000000..1def8e5229c1 --- /dev/null +++ b/python/testData/refactoring/pullup/multiFile/Class.after.py @@ -0,0 +1,4 @@ +from SuperClass import SuperClass + +class AnyClass(SuperClass): + pass diff --git a/python/testData/refactoring/pushdown/multiFileImports/child_module.after.py b/python/testData/refactoring/pushdown/multiFileImports/child_module.after.py new file mode 100644 index 000000000000..721b9dfbd8f2 --- /dev/null +++ b/python/testData/refactoring/pushdown/multiFileImports/child_module.after.py @@ -0,0 +1,6 @@ +from os import abort +from parent_module import Parent + +class Child(Parent): + def should_be_pushed(self): + abort() \ No newline at end of file diff --git a/python/testData/refactoring/pushdown/multiFileImports/child_module.py b/python/testData/refactoring/pushdown/multiFileImports/child_module.py new file mode 100644 index 000000000000..86716f1d649e --- /dev/null +++ b/python/testData/refactoring/pushdown/multiFileImports/child_module.py @@ -0,0 +1,4 @@ +from parent_module import Parent + +class Child(Parent): + pass \ No newline at end of file diff --git a/python/testData/refactoring/pushdown/multiFileImports/parent_module.after.py b/python/testData/refactoring/pushdown/multiFileImports/parent_module.after.py new file mode 100644 index 000000000000..8bc38a63f70c --- /dev/null +++ b/python/testData/refactoring/pushdown/multiFileImports/parent_module.after.py @@ -0,0 +1,4 @@ + + +class Parent(object): + pass \ No newline at end of file diff --git a/python/testData/refactoring/pushdown/multiFileImports/parent_module.py b/python/testData/refactoring/pushdown/multiFileImports/parent_module.py new file mode 100644 index 000000000000..97e05249929c --- /dev/null +++ b/python/testData/refactoring/pushdown/multiFileImports/parent_module.py @@ -0,0 +1,6 @@ +from os import abort + + +class Parent(object): + def should_be_pushed(self): + abort() \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/PyClassRefactoringTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/PyClassRefactoringTest.java index c232752b85d1..0a2827b25849 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/PyClassRefactoringTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/PyClassRefactoringTest.java @@ -26,19 +26,31 @@ import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.psi.PyTargetExpression; import com.jetbrains.python.psi.stubs.PyClassNameIndex; import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.hamcrest.Matchers; import org.jetbrains.annotations.NotNull; import org.junit.Assert; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.List; /** * @author Dennis.Ushakov */ public abstract class PyClassRefactoringTest extends PyTestCase { + @NotNull + private final String myRefactoringName; + + protected PyClassRefactoringTest(@NotNull final String refactoringName) { + myRefactoringName = refactoringName; + } + + //TODO: Doct + @NotNull + protected PyMemberInfo findMemberInfo(@NotNull final String clazzName, @NotNull final String memberName) { + final PyClass clazz = findClass(clazzName); + return MembersManager.findMember(clazz, findMember(clazzName, memberName)); + } + /** * @param className class where member should be found * @param memberName member that starts with dot (.) is treated as method. @@ -47,7 +59,7 @@ public abstract class PyClassRefactoringTest extends PyTestCase { * @return member or null if not found */ @NotNull - protected PyElement findMember(@NotNull String className, @NotNull String memberName) { + protected PyElement findMember(@NotNull final String className, @NotNull String memberName) { final PyElement result; //TODO: Get rid of this chain of copy pastes if (memberName.contains(".")) { @@ -98,4 +110,29 @@ public abstract class PyClassRefactoringTest extends PyTestCase { } }, null, null); } + + //TODO: Doc + protected void configureMultiFile(@NotNull final String... fileNamesNoExtensions) { + final String baseName = getMultiFileBaseName() + "/"; + + for (final String fileNameNoExtension : fileNamesNoExtensions) { + final String fileNameBefore = String.format("%s.py", fileNameNoExtension); + myFixture.copyFileToProject(baseName + fileNameBefore, fileNameBefore); + } + } + + //TODO: Doc + protected void checkMultiFile(@NotNull final String... fileNamesNoExtensions) { + for (final String fileNameNoExtension : fileNamesNoExtensions) { + final String fileNameAfter = String.format("%s.after.py", fileNameNoExtension); + final String fileNameBefore = String.format("%s.py", fileNameNoExtension); + myFixture.checkResultByFile(fileNameBefore, "/" + getMultiFileBaseName() + "/" + fileNameAfter, true); + } + } + + //TODO: Doc + @NotNull + protected String getMultiFileBaseName() { + return "refactoring/" + myRefactoringName + "/" + getTestName(true); + } } diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java index d872955a9b2b..bf9ef2ffc3be 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassTest.java @@ -15,8 +15,6 @@ */ package com.jetbrains.python.refactoring.classes.extractSuperclass; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -26,7 +24,6 @@ import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.refactoring.classes.PyClassRefactoringTest; -import com.jetbrains.python.refactoring.classes.extractSuperclass.PyExtractSuperclassHelper; import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; @@ -39,6 +36,28 @@ import java.util.List; * @author Dennis.Ushakov */ public class PyExtractSuperclassTest extends PyClassRefactoringTest { + + public PyExtractSuperclassTest() { + super("extractsuperclass"); + } + + //TODO: Doc + public void testImportMultiFile() throws Throwable { + final String[] modules = {"dest_module", "source_module"}; + configureMultiFile(modules); + myFixture.configureByFile("source_module.py"); + final String sourceClass = "MyClass"; + final PyMemberInfo member = findMemberInfo(sourceClass, ".do_useful_stuff"); + final String destUrl = myFixture.getFile().getVirtualFile().getParent().findChild("dest_module.py").getUrl(); + new WriteCommandAction.Simple(myFixture.getProject()) { + @Override + protected void run() throws Throwable { + PyExtractSuperclassHelper.extractSuperclass(findClass(sourceClass), Collections.singleton(member), "NewParent", destUrl); + } + }.execute(); + checkMultiFile(modules); + } + public void testSimple() throws Exception { doSimpleTest("Foo", "Suppa", null, true, ".foo"); } @@ -55,28 +74,33 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest { doSimpleTest("FromClass", "ToClass", null, true, "#instance_field", "#CLASS_FIELD"); } - private void doSimpleTest(final String className, final String superclassName, final String expectedError, final boolean sameFile, final String... membersName) throws Exception { + private void doSimpleTest(final String className, + final String superclassName, + final String expectedError, + final boolean sameFile, + final String... membersName) throws Exception { try { - String baseName = "/refactoring/extractsuperclass/" + getTestName(true); - myFixture.configureByFile(baseName + ".before.py"); - final PyClass clazz = findClass(className); - final List members = new ArrayList(); - for (String memberName : membersName) { - final PyElement member = findMember(className, memberName); - members.add(MembersManager.findMember(clazz, member)); - } - - new WriteCommandAction.Simple(myFixture.getProject()) { - @Override - protected void run() throws Throwable { - //noinspection ConstantConditions - final String url = sameFile ? myFixture.getFile().getVirtualFile().getUrl() : - myFixture.getFile().getVirtualFile().getParent().getUrl(); - PyExtractSuperclassHelper.extractSuperclass(clazz, members, superclassName, url); + String baseName = "/refactoring/extractsuperclass/" + getTestName(true); + myFixture.configureByFile(baseName + ".before.py"); + final PyClass clazz = findClass(className); + final List members = new ArrayList(); + for (String memberName : membersName) { + final PyElement member = findMember(className, memberName); + members.add(MembersManager.findMember(clazz, member)); } - }.execute(); - myFixture.checkResultByFile(baseName + ".after.py"); - } catch (Exception e) { + + new WriteCommandAction.Simple(myFixture.getProject()) { + @Override + protected void run() throws Throwable { + //noinspection ConstantConditions + final String url = sameFile ? myFixture.getFile().getVirtualFile().getUrl() : + myFixture.getFile().getVirtualFile().getParent().getUrl(); + PyExtractSuperclassHelper.extractSuperclass(clazz, members, superclassName, url); + } + }.execute(); + myFixture.checkResultByFile(baseName + ".after.py"); + } + catch (Exception e) { if (expectedError == null) throw e; assertEquals(expectedError, e.getMessage()); } @@ -164,5 +188,4 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest { String expected = psi_mgr.findFile(LocalFileSystem.getInstance().findFileByIoFile(expected_file)).getText().trim(); assertEquals(expected, result); } - } diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpTest.java index 4552c06e2b10..278f6eecf942 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpTest.java @@ -19,6 +19,7 @@ import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.refactoring.classes.PyClassRefactoringTest; import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; +import org.jetbrains.annotations.NotNull; import java.util.Collections; @@ -26,6 +27,11 @@ import java.util.Collections; * @author Dennis.Ushakov */ public class PyPullUpTest extends PyClassRefactoringTest { + + public PyPullUpTest() { + super("pullup"); + } + public void testSimple() { doHelperTest("Boo", ".boo", "Foo"); } @@ -79,18 +85,16 @@ public class PyPullUpTest extends PyClassRefactoringTest { } private void doMultiFileTest() { - String baseName = "refactoring/pullup/" + getTestName(true) + "/"; - myFixture.copyFileToProject(baseName + "Class.py", "Class.py"); - myFixture.copyFileToProject(baseName + "SuperClass.py", "SuperClass.py"); + final String[] modules = {"Class", "SuperClass"}; + configureMultiFile(modules); doPullUp("AnyClass", ".this_should_be_in_super", "SuperClass"); - myFixture.checkResultByFile("SuperClass.py", "/" + baseName + "/SuperClass.after.py", true); + checkMultiFile(modules); } private void doHelperTest(final String className, final String memberName, final String superClassName) { - String baseName = "/refactoring/pullup/" + getTestName(true); - myFixture.configureByFile(baseName + ".py"); + myFixture.configureByFile(getMultiFileBaseName() + ".py"); doPullUp(className, memberName, superClassName); - myFixture.checkResultByFile(baseName + ".after.py"); + myFixture.checkResultByFile(getMultiFileBaseName() + ".after.py"); } private void doPullUp(String className, String memberName, String superClassName) { diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownTest.java index dec76bc608bc..0bef72664180 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownTest.java @@ -15,13 +15,11 @@ */ package com.jetbrains.python.refactoring.classes.pushDown; -import com.intellij.openapi.command.WriteCommandAction; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.refactoring.classes.PyClassRefactoringTest; import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; -import com.jetbrains.python.refactoring.classes.pushDown.PyPushDownProcessor; import java.util.ArrayList; import java.util.Collections; @@ -31,6 +29,22 @@ import java.util.List; * @author Dennis.Ushakov */ public class PyPushDownTest extends PyClassRefactoringTest { + + public PyPushDownTest() { + super("pushdown"); + } + + //TODO: Doc + public void testMultiFileImports() { + final String[] modules = {"child_module", "parent_module"}; + configureMultiFile(modules); + final PyClass parentClass = findClass("Parent"); + final PyMemberInfo methodToMove = MembersManager.findMember(parentClass, findMember("Parent", ".should_be_pushed")); + + moveViaProcessor(myFixture.getProject(), new PyPushDownProcessor(myFixture.getProject(), Collections.singletonList(methodToMove), parentClass)); + checkMultiFile(modules); + } + public void testSimple() throws Exception { doProcessorTest("Foo", null, ".foo"); } @@ -52,24 +66,27 @@ public class PyPushDownTest extends PyClassRefactoringTest { } public void testExistingmethod() throws Exception { - doProcessorTest("Foo", "method foo is already overridden in class Boo. Method will not be pushed down to that class.", ".foo"); + doProcessorTest("Foo", + "method foo is already overridden in class Boo. Method will not be pushed down to that class.", + ".foo"); } private void doProcessorTest(final String className, final String expectedError, final String... memberNames) throws Exception { try { - String baseName = "/refactoring/pushdown/" + getTestName(true); - myFixture.configureByFile(baseName + ".before.py"); - final PyClass clazz = findClass(className); - final List members = new ArrayList(); - for (String memberName : memberNames) { - final PyElement member = findMember(className, memberName); - members.add(MembersManager.findMember(clazz, member)); - } + String baseName = "/refactoring/pushdown/" + getTestName(true); + myFixture.configureByFile(baseName + ".before.py"); + final PyClass clazz = findClass(className); + final List members = new ArrayList(); + for (String memberName : memberNames) { + final PyElement member = findMember(className, memberName); + members.add(MembersManager.findMember(clazz, member)); + } - final PyPushDownProcessor processor = new PyPushDownProcessor(members, clazz); + final PyPushDownProcessor processor = new PyPushDownProcessor(myFixture.getProject(), members, clazz); moveViaProcessor(myFixture.getProject(), processor); myFixture.checkResultByFile(baseName + ".after.py"); - } catch (Exception e) { + } + catch (Exception e) { if (expectedError == null) throw e; assertTrue(e.getMessage(), e.getMessage().contains(expectedError)); }