From 8a3a0b1d0bc1a25baec780ba010fa2954a85ea5e Mon Sep 17 00:00:00 2001 From: Alexandr Suhinin Date: Mon, 30 Jan 2023 17:02:32 +0200 Subject: [PATCH] [extract method with object] add tests GitOrigin-RevId: 0e2d72f613e0b8d1f396bd3a28ca32dd834893c7 --- .../IntroduceNullableObject.java | 12 ++ .../IntroduceNullableObject_after.java | 25 +++ .../IntroduceObjectWithAssignments.java | 11 ++ .../IntroduceObjectWithAssignments_after.java | 24 +++ .../IntroduceObjectWithRename.java | 14 ++ .../IntroduceObjectWithRename_after.java | 26 +++ .../IntroduceObjectWithTypeParameters.java | 14 ++ ...troduceObjectWithTypeParameters_after.java | 26 +++ .../IntroduceObjectWithWrongClassname1.java | 10 ++ .../IntroduceObjectWithWrongClassname2.java | 12 ++ ...IntroduceObjectWithWrongVariableName1.java | 10 ++ ...IntroduceObjectWithWrongVariableName2.java | 11 ++ .../IntroduceSimpleObject.java | 10 ++ .../IntroduceSimpleObject_after.java | 29 ++++ .../IntroduceSimpleRecord.java | 10 ++ .../IntroduceSimpleRecord_after.java | 22 +++ .../ExtractMethodAndDuplicatesInplaceTest.kt | 149 +++++++++++++++--- 17 files changed, 389 insertions(+), 26 deletions(-) create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceNullableObject.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceNullableObject_after.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithAssignments.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithAssignments_after.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithRename.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithRename_after.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithTypeParameters.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithTypeParameters_after.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongClassname1.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongClassname2.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongVariableName1.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongVariableName2.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleObject.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleObject_after.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleRecord.java create mode 100644 java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleRecord_after.java diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceNullableObject.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceNullableObject.java new file mode 100644 index 000000000000..9d6960bdbdda --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceNullableObject.java @@ -0,0 +1,12 @@ +public class Test { + public static int main(boolean param) { + int x = 0; + int y = 0; + if (param) return -1; + if (Math.random() > 0.5) return -1; + System.out.println(); + + System.out.println("Point(" + x + ", " + y+ ")"); + return 0; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceNullableObject_after.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceNullableObject_after.java new file mode 100644 index 000000000000..4264d9077e90 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceNullableObject_after.java @@ -0,0 +1,25 @@ +import org.jetbrains.annotations.Nullable; + +public class Test { + public static int main(boolean param) { + Result result = getResult(param); + if (result == null) return -1; + + System.out.println("Point(" + result.x() + ", " + result.y() + ")"); + return 0; + } + + @Nullable + private static Result getResult(boolean param) { + int x = 0; + int y = 0; + if (param) return null; + if (Math.random() > 0.5) return null; + System.out.println(); + Result result = new Result(x, y); + return result; + } + + private record Result(int x, int y) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithAssignments.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithAssignments.java new file mode 100644 index 000000000000..4b617781b73c --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithAssignments.java @@ -0,0 +1,11 @@ +public class Test { + public static void main(String[] args) { + int x = 42; + int y = 0; + System.out.println(); + System.out.println(); + x = (x + y)/2; + + System.out.println("Point(" + x + ", " + y + ")"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithAssignments_after.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithAssignments_after.java new file mode 100644 index 000000000000..43d38c9e1341 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithAssignments_after.java @@ -0,0 +1,24 @@ +import org.jetbrains.annotations.NotNull; + +public class Test { + public static void main(String[] args) { + Result result = getResult(); + int x; + x = (result.x() + result.y())/2; + + System.out.println("Point(" + x + ", " + result.y() + ")"); + } + + @NotNull + private static Result getResult() { + int x = 42; + int y = 0; + System.out.println(); + System.out.println(); + Result result = new Result(x, y); + return result; + } + + private record Result(int x, int y) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithRename.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithRename.java new file mode 100644 index 000000000000..f2dec5f7d7b5 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithRename.java @@ -0,0 +1,14 @@ +public class Test { + + private R getR() { + return null; + } + + public void main(String[] args, T param) { + T t = param; + R r = getR(); + System.out.println(); + + System.out.println("Custom(" + t + ", " + r + ")"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithRename_after.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithRename_after.java new file mode 100644 index 000000000000..fca3fc8cfed1 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithRename_after.java @@ -0,0 +1,26 @@ +import org.jetbrains.annotations.NotNull; + +public class Test { + + private R getR() { + return null; + } + + public void main(String[] args, T param) { + MyResult myVariable = getTrMyResult(param); + + System.out.println("Custom(" + myVariable.t() + ", " + myVariable.r() + ")"); + } + + @NotNull + private MyResult getTrMyResult(T param) { + T t = param; + R r = getR(); + System.out.println(); + MyResult myVariable = new MyResult<>(t, r); + return myVariable; + } + + private record MyResult(T t, R r) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithTypeParameters.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithTypeParameters.java new file mode 100644 index 000000000000..f2dec5f7d7b5 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithTypeParameters.java @@ -0,0 +1,14 @@ +public class Test { + + private R getR() { + return null; + } + + public void main(String[] args, T param) { + T t = param; + R r = getR(); + System.out.println(); + + System.out.println("Custom(" + t + ", " + r + ")"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithTypeParameters_after.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithTypeParameters_after.java new file mode 100644 index 000000000000..d2ca27ac94db --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithTypeParameters_after.java @@ -0,0 +1,26 @@ +import org.jetbrains.annotations.NotNull; + +public class Test { + + private R getR() { + return null; + } + + public void main(String[] args, T param) { + Result result = getTrResult(param); + + System.out.println("Custom(" + result.t() + ", " + result.r() + ")"); + } + + @NotNull + private Result getTrResult(T param) { + T t = param; + R r = getR(); + System.out.println(); + Result result = new Result<>(t, r); + return result; + } + + private record Result(T t, R r) { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongClassname1.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongClassname1.java new file mode 100644 index 000000000000..811a5952ffc6 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongClassname1.java @@ -0,0 +1,10 @@ +public class Test { + + void test() { + int x = 0; + int y = 0; + System.out.println(); + + System.out.println("Point(" + x + ", " + y + ")"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongClassname2.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongClassname2.java new file mode 100644 index 000000000000..14ec2debd4a0 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongClassname2.java @@ -0,0 +1,12 @@ +public class Test { + + void test() { + int x = 0; + int y = 0; + System.out.println(); + + System.out.println("Point(" + x + ", " + y + ")"); + } + + record Conflict(int x) {} +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongVariableName1.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongVariableName1.java new file mode 100644 index 000000000000..811a5952ffc6 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongVariableName1.java @@ -0,0 +1,10 @@ +public class Test { + + void test() { + int x = 0; + int y = 0; + System.out.println(); + + System.out.println("Point(" + x + ", " + y + ")"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongVariableName2.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongVariableName2.java new file mode 100644 index 000000000000..0ef645874a87 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceObjectWithWrongVariableName2.java @@ -0,0 +1,11 @@ +public class Test { + + void test() { + int conflict = 42; + int x = 0; + int y = 0; + System.out.println(); + + System.out.println("Point(" + x + ", " + y + ")"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleObject.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleObject.java new file mode 100644 index 000000000000..811a5952ffc6 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleObject.java @@ -0,0 +1,10 @@ +public class Test { + + void test() { + int x = 0; + int y = 0; + System.out.println(); + + System.out.println("Point(" + x + ", " + y + ")"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleObject_after.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleObject_after.java new file mode 100644 index 000000000000..4bfca930ab08 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleObject_after.java @@ -0,0 +1,29 @@ +import org.jetbrains.annotations.NotNull; + +public class Test { + + void test() { + Result result = getResult(); + + System.out.println("Point(" + result.x + ", " + result.y + ")"); + } + + @NotNull + private static Result getResult() { + int x = 0; + int y = 0; + System.out.println(); + Result result = new Result(x, y); + return result; + } + + private static class Result { + public final int x; + public final int y; + + public Result(int x, int y) { + this.x = x; + this.y = y; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleRecord.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleRecord.java new file mode 100644 index 000000000000..811a5952ffc6 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleRecord.java @@ -0,0 +1,10 @@ +public class Test { + + void test() { + int x = 0; + int y = 0; + System.out.println(); + + System.out.println("Point(" + x + ", " + y + ")"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleRecord_after.java b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleRecord_after.java new file mode 100644 index 000000000000..96aefae0f753 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodAndDuplicatesInplace/IntroduceSimpleRecord_after.java @@ -0,0 +1,22 @@ +import org.jetbrains.annotations.NotNull; + +public class Test { + + void test() { + Result result = getResult(); + + System.out.println("Point(" + result.x() + ", " + result.y() + ")"); + } + + @NotNull + private static Result getResult() { + int x = 0; + int y = 0; + System.out.println(); + Result result = new Result(x, y); + return result; + } + + private record Result(int x, int y) { + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt index 4884aee96656..c54db246d81d 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodAndDuplicatesInplaceTest.kt @@ -44,18 +44,26 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() { } fun testInvalidRename(){ - doTest(changedName = "invalid! name", checkResults = false) + doTest { + renameTemplate("invalid! name") + nextTemplateVariable() + } require(getActiveTemplate() != null) } fun testConflictRename(){ - doTest(changedName = "conflict", checkResults = false) + doTest { + renameTemplate("conflict") + nextTemplateVariable() + } require(getActiveTemplate() != null) } fun testValidRename(){ - doTest(changedName = "valid") - require(getActiveTemplate() == null) + doTest { + renameTemplate("valid") + nextTemplateVariable() + } } fun testGeneratedDefault(){ @@ -63,11 +71,17 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() { } fun testRenamedExactDuplicate(){ - doTest(changedName = "renamed") + doTest { + renameTemplate("renamed") + nextTemplateVariable() + } } fun testRenamedParametrizedDuplicate(){ - doTest(changedName = "averageWithOffset") + doTest { + renameTemplate("averageWithOffset") + nextTemplateVariable() + } } fun testStaticMustBePlaced(){ @@ -81,7 +95,10 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() { } fun testThreeDuplicates(){ - doTest(changedName = "sayHello") + doTest { + renameTemplate("sayHello") + nextTemplateVariable() + } } fun testParameterGrouping(){ @@ -217,7 +234,10 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() { } fun testTemplateRenamesInsertedCallOnly(){ - doTest(changedName = "renamed") + doTest { + renameTemplate("renamed") + nextTemplateVariable() + } } fun testSignatureChangeIsNotAvoided() { @@ -271,6 +291,78 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() { } } + fun testIntroduceSimpleObject(){ + IdeaTestUtil.withLevel(module, LanguageLevel.JDK_1_8) { + doTest() + } + } + + fun testIntroduceSimpleRecord(){ + doTest() + } + + fun testIntroduceNullableObject(){ + doTest() + } + + fun testIntroduceObjectWithAssignments(){ + doTest() + } + + fun testIntroduceObjectWithTypeParameters(){ + doTest() + } + + fun testIntroduceObjectWithRename(){ + doTest { + renameTemplate("MyResult") + nextTemplateVariable() + renameTemplate("myVariable") + nextTemplateVariable() + nextTemplateVariable() + } + } + + fun testIntroduceObjectWithWrongClassname1(){ + doTest { + renameTemplate("Wrong !") + nextTemplateVariable() + nextTemplateVariable() + nextTemplateVariable() + } + require(getActiveTemplate() != null) + } + + fun testIntroduceObjectWithWrongClassname2(){ + doTest { + renameTemplate("Conflict") + nextTemplateVariable() + nextTemplateVariable() + nextTemplateVariable() + } + require(getActiveTemplate() != null) + } + + fun testIntroduceObjectWithWrongVariableName1(){ + doTest { + nextTemplateVariable() + renameTemplate("wrong !") + nextTemplateVariable() + nextTemplateVariable() + } + require(getActiveTemplate() != null) + } + + fun testIntroduceObjectWithWrongVariableName2(){ + doTest { + nextTemplateVariable() + renameTemplate("conflict") + nextTemplateVariable() + nextTemplateVariable() + } + require(getActiveTemplate() != null) + } + fun testRefactoringListener(){ templateTest { configureByFile("$BASE_PATH/${getTestName(false)}.java") @@ -288,27 +380,30 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() { override fun conflictsDetected(refactoringId: String, conflictsData: RefactoringEventData) = Unit override fun undoRefactoring(refactoringId: String) = Unit }) - val template = startRefactoring(editor) + startRefactoring(editor) require(startReceived) - finishTemplate(template) + nextTemplateVariable() require(doneReceived) } } - private fun doTest(checkResults: Boolean = true, changedName: String? = null){ + private fun doTest(runnable: (TemplateState) -> Unit = { finishTemplate() }){ templateTest { configureByFile("$BASE_PATH/${getTestName(false)}.java") val template = startRefactoring(editor) - if (changedName != null) { - renameTemplate(template, changedName) - } - finishTemplate(template) - if (checkResults) { + runnable.invoke(template) + if (getActiveTemplate() == null) { checkResultByFile("$BASE_PATH/${getTestName(false)}_after.java") } } } + private fun finishTemplate(){ + do { + val isVariableSwitched = nextTemplateVariable() + } while (isVariableSwitched) + } + private inline fun runAndRevertSettings(action: () -> Unit) { val settings = JavaRefactoringSettings.getInstance() val defaultStatic = settings.EXTRACT_STATIC_METHOD @@ -329,6 +424,7 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() { private fun startRefactoring(editor: Editor): TemplateState { val selection = with(editor.selectionModel) { TextRange(selectionStart, selectionEnd) } MethodExtractor().doExtract(file, selection) + UIUtil.dispatchAllInvocationEvents() val templateState = getActiveTemplate() require(templateState != null) { "Failed to start refactoring" } return templateState @@ -336,18 +432,19 @@ class ExtractMethodAndDuplicatesInplaceTest: LightJavaCodeInsightTestCase() { private fun getActiveTemplate() = TemplateManagerImpl.getTemplateState(editor) - private fun finishTemplate(templateState: TemplateState){ - try { - LookupManager.getActiveLookup(templateState.editor)?.hideLookup(true) - val dataContext = DataManager.getInstance().getDataContext(editor.component) - val event = AnActionEvent.createFromDataContext(ActionPlaces.UNKNOWN, Presentation(), dataContext) - ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_NEXT_TEMPLATE_VARIABLE).actionPerformed(event) - UIUtil.dispatchAllInvocationEvents() - } catch (ignore: RefactoringErrorHintException) { - } + private fun nextTemplateVariable(): Boolean { + val templateState = getActiveTemplate() ?: return false + val previousRange = templateState.currentVariableRange + LookupManager.getActiveLookup(templateState.editor)?.hideLookup(true) + val dataContext = DataManager.getInstance().getDataContext(editor.component) + val event = AnActionEvent.createFromDataContext(ActionPlaces.UNKNOWN, Presentation(), dataContext) + ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_NEXT_TEMPLATE_VARIABLE).actionPerformed(event) + UIUtil.dispatchAllInvocationEvents() + return templateState.isFinished || templateState.currentVariableRange != previousRange } - private fun renameTemplate(templateState: TemplateState, name: String) { + private fun renameTemplate(name: String) { + val templateState = getActiveTemplate() ?: return WriteCommandAction.runWriteCommandAction(project) { val range = templateState.currentVariableRange!! editor.document.replaceString(range.startOffset, range.endOffset, name)