blob: fbf568807e40e4b9fef3aad743a451ca8a4ead47 [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.refactoring.classes.pullUp;
import com.intellij.util.ArrayUtil;
import com.jetbrains.python.psi.LanguageLevel;
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 org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author Dennis.Ushakov
*/
public class PyPullUpTest extends PyClassRefactoringTest {
public PyPullUpTest() {
super("pullup");
}
public void testSimple() {
doHelperTest("Boo", ".boo", "Foo");
}
public void testSuperclass() {
doHelperTest("Boo", "Foo", "Zope");
}
public void testExistingsuperclass() {
doHelperTest("Boo", "Foo", "Zope");
}
public void testWithComments() {
doHelperTest("Boo", ".boo", "Foo");
}
public void testWithMultilineComments() {
doHelperTest("Boo", ".boo", "Foo");
}
public void testSeveralParents() {
doHelperTest("Child", "Spam", "Parent_1");
}
public void testMoveClassAttributesSimple() {
doHelperTest("Child", "#CLASS_VAR", "Parent");
}
public void testInstanceNotDeclaredInInit() {
doHelperTest("Child", "#foo", "Parent");
}
public void testMoveClassAttributesNoPass() {
doHelperTest("Child2", "#CLASS_VAR", "Parent2");
}
public void testMoveInstanceAttributesSimple() {
doHelperTest("Child", "#instance_field", "Parent");
}
public void testMoveInstanceAttributesNoInit() {
doHelperTest("Child", "#instance_field", "Parent");
}
public void testMoveInstanceAttributesLeaveEmptyInit() {
doHelperTest("Child", "#foo", "Parent");
}
// Ensures than all fields are moved in correct order
public void testDependenciesOrder() {
doHelperTestSeveralMembers("Child", "Parent", "#CLASS_FIELD", "#ANOTHER_CLASS_FIELD", "#FIELD", ".foo", "#SOME_VAR", "#b", "#d", "#A_FIELD");
}
public void testMultiFile() { // PY-2810
doMultiFileTest();
}
public void testDuplicateImport() { // PY-2810
doMultiFileTest();
}
public void testProperties() {
final String[] modules = {"Class", "SuperClass"};
configureMultiFile(modules);
doPullUp("AnyClass", "SuperClass", ".new_property");
checkMultiFile(modules);
}
public void testFieldMove() {
final String[] modules = {"Class", "SuperClass"};
configureMultiFile(modules);
doPullUp("AnyClass", "SuperClass", "#COPYRIGHT");
doPullUp("AnyClass", "SuperClass", "#version");
checkMultiFile(modules);
}
private void doMultiFileTest() {
final String[] modules = {"Class", "SuperClass"};
configureMultiFile(modules);
doPullUp("AnyClass", "SuperClass", ".this_should_be_in_super");
checkMultiFile(modules);
}
/**
* Ensures that pulling abstract method up to class that already uses ABCMeta works correctly
*/
public void testAbstractMethodHasMeta() {
checkAbstract(".my_method");
}
/**
* Ensures that pulling abstract method up to class that has NO ABCMeta works correctly for py2 (__metaclass__ is added)
*/
public void testAbstractMethodPy2AddMeta() {
checkAbstract(".my_method", ".my_method_2");
}
/**
* Ensures that pulling abstract method up to class that has NO ABCMeta works correctly for py3k (metaclass is added)
*/
public void testAbstractMethodPy3AddMeta() {
setLanguageLevel(LanguageLevel.PYTHON34);
checkAbstract(".my_method", ".my_class_method");
}
/**
* Moves methods fromn Child to Parent and make them abstract
* @param methodNames methods to check
*/
private void checkAbstract(@NotNull final String... methodNames) {
final String[] modules = {"Class", "SuperClass"};
configureMultiFile(ArrayUtil.mergeArrays(modules, "abc"));
doPullUp("Child", "Parent", true, methodNames);
checkMultiFile(modules);
}
private void doHelperTest(final String className, final String memberName, final String superClassName) {
doHelperTestSeveralMembers(className, superClassName, memberName);
}
private void doHelperTestSeveralMembers(@NotNull final String className, @NotNull final String superClassName, @NotNull final String... memberNames) {
myFixture.configureByFile(getMultiFileBaseName() + ".py");
doPullUp(className, superClassName, false, memberNames);
myFixture.checkResultByFile(getMultiFileBaseName() + ".after.py");
}
private void doPullUp(final String className, final String superClassName, final String memberName) {
doPullUp(className, superClassName, false, memberName);
}
private void doPullUp(final String className, final String superClassName, final boolean toAbstract, final String... memberNames ) {
final PyClass clazz = findClass(className);
final PyClass superClass = findClass(superClassName);
final Collection<PyMemberInfo<PyElement>> membersToMove = new ArrayList<PyMemberInfo<PyElement>>(memberNames.length);
for (final String memberName : memberNames) {
final PyElement member = findMember(className, memberName);
final PyMemberInfo<PyElement> memberInfo = MembersManager.findMember(clazz, member);
memberInfo.setToAbstract(toAbstract);
membersToMove.add(memberInfo);
}
moveViaProcessor(clazz.getProject(),
new PyPullUpProcessor(clazz, superClass, membersToMove));
}
}