package com.intellij.flex.refactoring;
import com.intellij.flex.util.FlexTestUtils;
import com.intellij.javascript.flex.css.FlexStylesIndexableSetContributor;
import com.intellij.javascript.flex.mxml.schema.FlexSchemaHandler;
import com.intellij.lang.javascript.JSChangeSignatureTestBase;
import com.intellij.lang.javascript.JSTestOption;
import com.intellij.lang.javascript.JSTestOptions;
import com.intellij.lang.javascript.flex.FlexModuleType;
import com.intellij.lang.javascript.psi.ecmal4.JSAttributeList;
import com.intellij.lang.javascript.refactoring.changeSignature.JSParameterInfo;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import static com.intellij.openapi.vfs.VfsUtilCore.convertFromUrl;
import static com.intellij.openapi.vfs.VfsUtilCore.urlToPath;
public class FlexChangeSignatureTest extends JSChangeSignatureTestBase {
@Override
public void setUp() throws Exception {
VfsRootAccess.allowRootAccess(getTestRootDisposable(),
urlToPath(convertFromUrl(FlexSchemaHandler.class.getResource("z.xsd"))),
urlToPath(convertFromUrl(FlexStylesIndexableSetContributor.class.getResource("FlexStyles.as"))));
super.setUp();
}
protected String[] getActiveFileNames() {
return new String[]{"From.as", "From.mxml"};
}
@NotNull
@Override
protected String getTestRoot() {
return "/flexChangeSignature/";
}
@Override
protected String getTestDataPath() {
return FlexTestUtils.getTestDataPath("");
}
@Override
protected ModuleType getModuleType() {
return FlexModuleType.getInstance();
}
@Override
protected void setUpJdk() {
FlexTestUtils.setupFlexSdk(myModule, getTestName(false), getClass());
}
public void testAddParam1() throws Exception {
doTest("bar", JSAttributeList.AccessType.PUBLIC, "int", new String[]{"zzz"},
new JSParameterInfo("stringParam", "String", "", "\"def\"", -1));
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testAddParam2() throws Exception {
doTest("blablabala__12", JSAttributeList.AccessType.PACKAGE_LOCAL, "", new String[]{"zzz"},
new JSParameterInfo("p", "mx.messaging.AbstractConsumer", "", "CONS", -1),
new JSParameterInfo("p2", "flash.events.EventDispatcher", "null", "DISP", -1));
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testAddParam3() throws Exception {
doTest("bar", JSAttributeList.AccessType.PACKAGE_LOCAL, "", new String[]{"zzz"},
new JSParameterInfo("p1", "int", "", "100", -1),
new JSParameterInfo("p2", "String", "abc", "\"def\"", -1),
new JSParameterInfo("p3", "Boolean", "false", "", -1),
new JSParameterInfo("p4", "...", "", "", -1));
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testRemoveParam1() throws Exception {
doTest("foo", JSAttributeList.AccessType.PRIVATE, "flash.events.EventDispatcher", new String[]{"zzz"});
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testChangeParam1() throws Exception {
doTest("renamed", JSAttributeList.AccessType.PACKAGE_LOCAL, "Boolean", new String[]{"bar"},
new JSParameterInfo("i2", "Number", "", "", 1),
new JSParameterInfo("sss", "String", "\"abc\"", "", 0),
new JSParameterInfo("o", "flash.events.EventDispatcher", "FOO", "", 2),
new JSParameterInfo("rest2", "...", "", "", 3));
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testProp1() throws Exception {
doTest("v2", JSAttributeList.AccessType.PROTECTED, "Number", ArrayUtil.EMPTY_STRING_ARRAY);
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testProp2() throws Exception {
doTest("v2", JSAttributeList.AccessType.PROTECTED, "void", ArrayUtil.EMPTY_STRING_ARRAY,
new JSParameterInfo("value", "Number", "", "", 0));
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testPropagate1() throws Exception {
doTest("foo", JSAttributeList.AccessType.PACKAGE_LOCAL, "",
new String[]{"bar", "zzz", "abc", "nopropagate"},
new JSParameterInfo("s", "String", "", "", 0),
new JSParameterInfo("added1", "Number", "", "added1def", -1),
new JSParameterInfo("added2", "Object", "", "added2def", -1));
}
public void testConflicts1() throws Exception {
String[] conflicts = new String[]{
"There is already a parameter p1 in method From.foo(String, String). It will conflict with the new parameter.",
"There is already a parameter p1 in the method From.foo(String, String). It will conflict with the renamed parameter.",
"There is already a variable p2 in method From.foo(String, String). It will conflict with the new parameter.",
"There is already a variable p3 in method FromEx.foo(String, String). It will conflict with the new parameter.",
"There is already a variable p1 in method From.pp(). It will conflict with the new parameter.",
"There is already a variable p2 in method From.pp(). It will conflict with the new parameter.",
"There is already a variable p3 in method From.pp(). It will conflict with the new parameter.",
"There is already a variable p1 in function pp2(). It will conflict with the new parameter.",
"Class From already contains a method bar()",
"Method FromEx.foo(String, String) with internal visibility won't be accessible from function zz()",
"Method From.foo(String, String) with internal visibility won't be able to participate in hierarchy"
};
doTestConflicts("bar", JSAttributeList.AccessType.PACKAGE_LOCAL, "String", conflicts, new String[]{"pp", "zz"},
new JSParameterInfo("p1", "String", "", "", 0), // p1
new JSParameterInfo("p1", "String", "", "", 1), // p2->p1
new JSParameterInfo("p1", "String", "", "a", -1),
new JSParameterInfo("p2", "String", "", "b", -1),
new JSParameterInfo("p3", "String", "", "c", -1));
}
public void testConflicts2() throws Exception {
String[] conflicts = new String[]{
"There is already a variable value2 in the property From.prop. It will conflict with the renamed parameter.",
"Property From.prop with private visibility won't be accessible from function ttt()",
"Class From already contains a field _prop2"
};
doTestConflicts("prop2", JSAttributeList.AccessType.PRIVATE, "*", conflicts, ArrayUtil.EMPTY_STRING_ARRAY,
new JSParameterInfo("value2", "", "", "foo", 0));
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testMxml() throws Exception {
doTest("abc2", JSAttributeList.AccessType.PACKAGE_LOCAL, "",
new String[]{"ref", "aaa"},
new JSParameterInfo("s", "String", "", "\"def\"", -1),
new JSParameterInfo("p", "int", "", "0", -1),
new JSParameterInfo("z", "Object", "", "this", -1));
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testExistingSignature() throws Exception {
doTest("foo", JSAttributeList.AccessType.PACKAGE_LOCAL, "",
new String[]{"bar"},
new JSParameterInfo("p", "int", "15", "2000", -1),
new JSParameterInfo("s", "String", "null", "\"abcde\"", -1));
}
public void testAddParam4() throws Exception {
doTest("foo", JSAttributeList.AccessType.PACKAGE_LOCAL, "void",
new String[]{"zzz"},
new JSParameterInfo("i", "int", "", "777", -1),
new JSParameterInfo("p", "String", "\"default\"", "", 0),
new JSParameterInfo("z", "Test", "null", "", -1));
}
public void testAddParam5() throws Exception {
doTest("foo", JSAttributeList.AccessType.PACKAGE_LOCAL, "void",
new String[]{"zzz"},
new JSParameterInfo("p", "String", "", "\"abc\"", -1),
new JSParameterInfo("args", "...", "", "", 0));
}
public void testNested() throws Exception {
doTest("nested2", JSAttributeList.AccessType.PACKAGE_LOCAL, "int",
new String[]{"test"},
new JSParameterInfo("p", "String", "", "\"abc\"", -1));
}
public void testSuperConstructorCall() throws Exception {
doTest("From", JSAttributeList.AccessType.PACKAGE_LOCAL, "",
new String[]{"FromEx"},
new JSParameterInfo("p", "String", "", "", 0),
new JSParameterInfo("b", "Boolean", "", "true", -1));
}
public void testSuperConstructorCall2() throws Exception {
doTest("A", JSAttributeList.AccessType.PUBLIC, "",
new String[]{"B"},
new JSParameterInfo("p", "String", "", "", 0),
new JSParameterInfo("b", "Boolean", "", "true", -1));
}
public void testNamespace() throws Exception {
doTest("foo2", JSAttributeList.AccessType.PUBLIC, "", new String[]{"bar", "barZ"}, new JSParameterInfo("p", "", "", "", 0));
}
public void testNamespace2() throws Exception {
doTest("foo2", JSAttributeList.AccessType.PRIVATE, "", new String[]{"bar"}, new JSParameterInfo("p", "", "", "", 0));
}
public void testAddParam6() throws Exception {
doTest("doSmth", JSAttributeList.AccessType.PACKAGE_LOCAL, "",
new String[]{"A", "B"},
new JSParameterInfo("s", "String", "", "\"abc\"", -1),
new JSParameterInfo("args", "...", "", "", 0));
}
public void testAddParam7() throws Exception {
doTest("doSmth", JSAttributeList.AccessType.PACKAGE_LOCAL, "",
new String[]{"zz"},
new JSParameterInfo("s", "String", "", "", 1),
new JSParameterInfo("i", "int", "", "", 0),
new JSParameterInfo("b", "Type", "", "def", -1),
new JSParameterInfo("i2", "int", "0", "", 2),
new JSParameterInfo("p", "From", "null", "", 3));
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testNoPropagateToSdkInheritor() throws Exception {
myAfterCommitRunnable =
() -> FlexTestUtils.addLibrary(myModule, "Lib", getTestDataPath() + getTestRoot() + getTestName(false), "Flex_small.swc", null, null);
doTest("abc", JSAttributeList.AccessType.PACKAGE_LOCAL, "", new String[]{"bar", "listener"});
}
private void doTestInaccessible() throws Exception {
try {
doTest("", JSAttributeList.AccessType.PACKAGE_LOCAL, "", null);
fail("Refactoring should be inaccessible");
}
catch (CommonRefactoringUtil.RefactoringErrorHintException e) {
// expected
}
}
public void testAnonymousFunction1() throws Exception {
doTestInaccessible();
}
public void testAnonymousFunction2() throws Exception {
doTestInaccessible();
}
public void testAnonymousFunction3() throws Exception {
doTestInaccessible();
}
public void testAnonymousFunction4() throws Exception {
doTest("v2", JSAttributeList.AccessType.PACKAGE_LOCAL, "String", new String[]{"foo"}, new JSParameterInfo("b2", "String", "", "", 1),
new JSParameterInfo("a2", "int", "", "", 0), new JSParameterInfo("c", "Boolean", "", "false", -1));
}
public void testAnonymousFunction5() throws Exception {
doTest("sayLoud", JSAttributeList.AccessType.PUBLIC, "void", new String[]{"usage1", "usage2"},
new JSParameterInfo("message", "String", "", "", 0),
new JSParameterInfo("loud", "Boolean", "true", "false", -1));
}
@JSTestOptions(JSTestOption.WithFlexSdk)
public void testEventHandlerCall() throws Exception {
doTest("", JSAttributeList.AccessType.PACKAGE_LOCAL, "void", ArrayUtil.EMPTY_STRING_ARRAY,
new JSParameterInfo("i", "int", "", "1000", -1));
}
public void testAnonymousFunction6() throws Exception {
myAfterCommitRunnable = () -> WriteAction.run(() -> {
String root = getTestRoot() + getTestName(false) + "/module2";
Module module2 = ModuleManager.getInstance(myProject).newModule(getTestDataPath() + root, getModuleType().getId());
myModulesToDispose.add(module2);
PsiTestUtil.addSourceRoot(module2, getVirtualFile(root));
FlexTestUtils.addFlexModuleDependency(module2, myModule);
});
doTestInaccessible();
}
public void testPropagateToFunctionExpression() throws Exception {
doTest("", JSAttributeList.AccessType.PACKAGE_LOCAL, "", new String[]{"f1"},
new JSParameterInfo("i", "int", "", "100", -1));
}
public void testImportsForAgrumentsAndInitializers() throws Exception {
doTest("foo", JSAttributeList.AccessType.PACKAGE_LOCAL, "", null,
new JSParameterInfo("p1", "com.Foo", "aaa.A.SIZE", "new com.Foo()", -1),
new JSParameterInfo("p2", "com.Bar", "bbb.B.ourLength", "com.Bar.SIZE", -1),
new JSParameterInfo("p3", "String", "", "com.Foo.MESSAGE", -1),
new JSParameterInfo("p4", "bar.Zzz", "", "bar.Zzz.func(new bar.Yyy(), uuu.glob(com.Const))", -1),
new JSParameterInfo("p5", "bar.Yyy", "", "unresolved", -1));
}
public void testIncompatibleOverrideConflict() throws Exception {
String[] conflicts = new String[]{
"Overriding method B.foo() has different number of parameters than refactored method A.foo(int). Method B.foo() will be ignored during refactoring."
};
doTestConflicts("foo2", JSAttributeList.AccessType.PUBLIC, "", conflicts, null, new JSParameterInfo("j", "int", "", "", 0));
}
public void testIncompatibleImplementationConflict() throws Exception {
String[] conflicts = new String[]{
"Implementing method B.foo() has different number of parameters than refactored method A.foo(int). Method B.foo() will be ignored during refactoring."
};
doTestConflicts("foo", JSAttributeList.AccessType.PUBLIC, "", conflicts, null, new JSParameterInfo("j", "int", "", "", 0));
}
public void testIncompatibleImplementation() throws Exception {
myIgnoreConflicts = true;
doTest("foo2", JSAttributeList.AccessType.PUBLIC, "", null, new JSParameterInfo("j", "int", "", "", 0));
}
}