blob: 550c5a1e3144841297a6aabf460be87e421d757b [file] [log] [blame]
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.groovy.refactoring.introduceParameter
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiType
import com.intellij.psi.impl.source.PostprocessReformattingAspect
import com.intellij.refactoring.IntroduceParameterRefactoring
import gnu.trove.TIntArrayList
import gnu.trove.TObjectIntHashMap
import org.jetbrains.annotations.Nullable
import org.jetbrains.plugins.groovy.LightGroovyTestCase
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.*
import org.jetbrains.plugins.groovy.util.TestUtils
import org.junit.Assert
/**
* @author Maxim.Medvedev
*/
public class GrIntroduceParameterTest extends LightGroovyTestCase {
protected String getBasePath() {
return TestUtils.getTestDataPath() + "refactoring/introduceParameterGroovy/" + getTestName(true) + '/';
}
private void doDelegateTest() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, true);
}
private boolean doTest(int replaceFieldsWithGetters, boolean removeUnusedParameters, boolean declareFinal) {
return doTest(replaceFieldsWithGetters, removeUnusedParameters, declareFinal, null);
}
private boolean doTest(final int replaceFieldsWithGetters,
final boolean removeUnusedParameters,
final boolean declareFinal,
@Nullable final String conflicts) {
return doTest(replaceFieldsWithGetters, removeUnusedParameters, declareFinal, conflicts, false);
}
private boolean doTest(final int replaceFieldsWithGetters,
final boolean removeUnusedParameters,
final boolean declareFinal,
@Nullable final String conflicts,
final boolean generateDelegate) {
final String beforeGroovy = getTestName(false)+"Before.groovy";
final String afterGroovy = getTestName(false) + "After.groovy";
final String clazz = getTestName(false) + "MyClass.groovy";
final String afterClazz = getTestName(false) + "MyClass_after.groovy";
final boolean beforeExists = exists(beforeGroovy);
if (beforeExists) {
myFixture.copyFileToProject(beforeGroovy);
}
myFixture.configureByFile(clazz);
execute(replaceFieldsWithGetters, removeUnusedParameters, declareFinal, conflicts, generateDelegate, getProject(),
myFixture.getEditor(), myFixture.getFile());
PostprocessReformattingAspect.getInstance(getProject()).doPostponedFormatting();
myFixture.getEditor().getSelectionModel().removeSelection();
if (beforeExists) {
myFixture.checkResultByFile(beforeGroovy, afterGroovy, true);
}
if (exists(afterClazz)) {
myFixture.checkResultByFile(afterClazz);
}
return true;
}
private void doTest(final int replaceFieldsWithGetters,
final boolean removeUnusedParameters,
final boolean declareFinal,
@Nullable final String conflicts,
final boolean generateDelegate, String before, String after) {
myFixture.configureByText('before.groovy', before);
execute(replaceFieldsWithGetters, removeUnusedParameters, declareFinal, conflicts, generateDelegate, getProject(),
myFixture.getEditor(), myFixture.getFile());
PostprocessReformattingAspect.getInstance(getProject()).doPostponedFormatting();
myFixture.getEditor().getSelectionModel().removeSelection();
myFixture.checkResult(after);
}
private boolean exists(String sourceFilePath) {
File file = new File(getTestDataPath() + "/" + sourceFilePath);
return file.exists();
}
static void execute(final int replaceFieldsWithGetters,
final boolean removeUnusedParameters,
final boolean declareFinal,
final String conflicts,
final boolean generateDelegate,
final Project project,
final Editor editor,
final PsiFile file) {
CommandProcessor.instance.executeCommand(project, {
ApplicationManager.application.runWriteAction {
try {
final GrIntroduceParameterHandler hackedHandler = new GrIntroduceParameterHandler() {
@Override
protected void showDialog(IntroduceParameterInfo info) {
final GrIntroduceParameterSettings hackedSettings =
getSettings(info, removeUnusedParameters, replaceFieldsWithGetters, declareFinal, generateDelegate);
if (info.getToReplaceIn() instanceof GrMethod) {
new GrIntroduceParameterProcessor(hackedSettings).run();
}
else {
new GrIntroduceClosureParameterProcessor(hackedSettings).run();
}
}
};
hackedHandler.invoke(project, editor, file, null);
if (conflicts != null) fail("Conflicts were expected");
}
catch (Exception e) {
if (conflicts == null) {
e.printStackTrace();
fail("Conflicts were not expected");
}
Assert.assertEquals(conflicts, e.getMessage());
}
}
}, "introduce Parameter", null);
}
private static GrIntroduceParameterSettings getSettings(final IntroduceParameterInfo context,
final boolean removeUnusedParameters,
final int replaceFieldsWithGetters,
final boolean declareFinal,
final boolean generateDelegate) {
TIntArrayList toRemove = new TIntArrayList();
if (removeUnusedParameters) {
final TObjectIntHashMap<GrParameter> map = GroovyIntroduceParameterUtil.findParametersToRemove(context);
for (int i : map.getValues()) {
toRemove.add(i);
}
}
final GrStatement[] statements = context.getStatements()
GrExpression expr = statements.length == 1 ? GrIntroduceHandlerBase.findExpression(statements[0]) : null;
GrVariable var = context.var
final PsiType type = TypesUtil.unboxPrimitiveTypeWrapper(var != null ? var.getType() : expr != null ? expr.getType() : context.stringPartInfo.literal.type);
return new GrIntroduceExpressionSettingsImpl(context, "anObject", declareFinal, toRemove, generateDelegate, replaceFieldsWithGetters,
expr, var, type, var !=null, var != null, true);
}
public void testSimpleOverridedMethod() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testOverridedMethodWithRemoveUnusedParameters() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false);
}
public void testSimpleUsage() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testMethodWithoutParams() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testParameterSubstitution() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testThisSubstitution() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testThisSubstitutionInQualifier() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, "field <b><code>Test.i</code></b> is not accessible from method <b><code>XTest.n()</code></b>. Value for introduced parameter in that method call will be incorrect.");
}
public void testQualifiedThisSubstitution() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null);
}
public void testFieldAccess() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testMethodAccess() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testStaticFieldAccess() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testFieldWithGetterReplacement() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, false, false);
}
public void testFieldWithInaccessibleGetterReplacement() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false);
}
public void testWeirdQualifier() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false);
}
public void testSuperInExpression() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
}
public void testWeirdQualifierAndParameter() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false);
}
public void testImplicitSuperCall() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false);
}
public void testImplicitDefaultConstructor() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false);
}
public void testInternalSideEffect() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false);
}
/* public void testAnonymousClass() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, false);
}*/
public void testSuperWithSideEffect() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, "Parameter initializer contains <b><code>super</code></b>, but not all calls to method are in its class");
}
public void testConflictingField() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false);
}
/*public void testParameterJavaDoc1() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, true);
}
public void testParameterJavaDoc2() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, true);
}
public void testParameterJavaDoc3() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, true);
}
public void testParameterJavaDocBeforeVararg() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, false, false, true);
}*/
public void testRemoveParameterInHierarchy() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false);
}
/*public void testRemoveParameterWithJavadoc() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false, false);
}*/
public void testVarargs() { // IDEADEV-16828
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testMethodUsageInThisMethodInheritor() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testIncorrectArgumentList() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, true);
}
public void testClosure() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);
}
public void testDelegate1() {doDelegateTest();}
public void testDelegate2() {doDelegateTest();}
public void testDelegaterInSuper() {doDelegateTest();}
public void testClosureArg() {doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);}
public void testClosureArgWithEmptyArgList() {doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false);}
public void testScriptMethod() {doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, true, false);}
public void testAppStatement() {doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false);}
void testStringPart0() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, false, '''\
def foo() {
print 'a<selection>b</selection>c'
}
foo()
''', '''\
def foo(String anObject) {
print 'a' + anObject<caret> + 'c'
}
foo('b')
''')
}
void testIntroduceToConstructorUsedByAnonymousClass() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, false, '''\
class X {
def X() {
print <selection>2</selection>
}
}
print new X() {
}
''', '''\
class X {
def X(int anObject) {
print anObject
}
}
print new X(2) {
}
''')
}
void testNullType() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, false, '''\
def foo() {
def a = '4'
<selection>print a</selection>
}
foo()
''', '''\
def foo(anObject) {
def a = '4'
anObject
}
foo(print(a))
''')
}
void testIntroduceFromLocalVar() {
doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, false, '''\
def foo() {
def <selection>var = 5</selection>
print var + var
}
foo()
''', '''\
def foo(anObject) {
print anObject + anObject
}
foo(5)
''')
}
}