From de907c6cd360351e1df68c1be51af1d2b30436c3 Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Mon, 26 Mar 2018 15:21:36 +0300 Subject: [PATCH] IDEA-172425 Add tests to check that generated code is correct --- .../WithReflectionAccess.java | 28 +++++++ .../outs/accessConstructor.out | 38 ++++++++++ .../outs/accessField.out | 44 +++++++++++ .../outs/accessMethod.out | 38 ++++++++++ .../outs/accessMethodReference.out | 38 ++++++++++ .../outs/methodWithParameter.out | 44 +++++++++++ .../outs/methodWithPrimitiveParameter.out | 44 +++++++++++ .../outs/twiceAccessToTheSameField.out | 75 +++++++++++++++++++ .../outs/updateField.out | 44 +++++++++++ ...ctMethodObject4DebuggerReflectionTest.java | 72 ++++++++++++++++++ 10 files changed, 465 insertions(+) create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/WithReflectionAccess.java create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessConstructor.out create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessField.out create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessMethod.out create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessMethodReference.out create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/methodWithParameter.out create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/methodWithPrimitiveParameter.out create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/twiceAccessToTheSameField.out create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/updateField.out create mode 100644 java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerReflectionTest.java diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/WithReflectionAccess.java b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/WithReflectionAccess.java new file mode 100644 index 000000000000..71201b5fbf44 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/WithReflectionAccess.java @@ -0,0 +1,28 @@ +public class WithReflectionAccess { + private int field = 10; + + private WithReflectionAccess(int value) { + field = value; + } + + public static void main(String[] args) { + WithReflectionAccess instance = new WithReflectionAccess(2000); + int a = 42; + } + + private static void method() { + + } + + private int method(int arg) { + return 0; + } + + private Object method(WithReflectionAccess arg) { + return arg; + } + + public static void apply(Runnable runnable) { + runnable.run(); + } +} diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessConstructor.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessConstructor.out new file mode 100644 index 000000000000..b53ecb639332 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessConstructor.out @@ -0,0 +1,38 @@ +call text: WithReflectionAccess result = Test.invoke(); +class: +static class Test { + static WithReflectionAccess invoke() { + return newWithReflectionAccess1(50); + } + + public static WithReflectionAccess newWithReflectionAccess1(int value) { + try { + Class klass = Class.forName("WithReflectionAccess"); + java.lang.reflect.Constructor member = null; + int interfaceNumber = -1; + Class[] interfaces = null; + while (member == null) { + try { + member = klass.getDeclaredConstructor(int.class); + } catch (ReflectiveOperationException e) { + if (interfaceNumber == -1) { + interfaces = klass.getInterfaces(); + interfaceNumber = 0; + } + if (interfaceNumber < interfaces.length) { + klass = interfaces[interfaceNumber]; + interfaceNumber += 1; + } else { + klass = klass.getSuperclass(); + if (klass == null) throw e; + interfaceNumber = -1; + } + } + } + member.setAccessible(true); + return (WithReflectionAccess) member.newInstance(value); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessField.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessField.out new file mode 100644 index 000000000000..881eac0da6be --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessField.out @@ -0,0 +1,44 @@ +call text: new Test(instance).invoke(); +class: +static class Test { + private WithReflectionAccess instance; + + public Test(WithReflectionAccess instance) { + this.instance = instance; + } + + public static int accessToFieldField1(Object object, Object value) { + try { + Class klass = Class.forName("WithReflectionAccess"); + java.lang.reflect.Field member = null; + int interfaceNumber = -1; + Class[] interfaces = null; + while (member == null) { + try { + member = klass.getDeclaredField("field"); + } catch (ReflectiveOperationException e) { + if (interfaceNumber == -1) { + interfaces = klass.getInterfaces(); + interfaceNumber = 0; + } + if (interfaceNumber < interfaces.length) { + klass = interfaces[interfaceNumber]; + interfaceNumber += 1; + } else { + klass = klass.getSuperclass(); + if (klass == null) throw e; + interfaceNumber = -1; + } + } + } + member.setAccessible(true); + return (int) member.get(object); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public void invoke() { + System.out.println(accessToFieldField1(instance, null)); + } + } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessMethod.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessMethod.out new file mode 100644 index 000000000000..60332405a0d5 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessMethod.out @@ -0,0 +1,38 @@ +call text: Test.invoke(); +class: +static class Test { + static void invoke() { + callMethod1(null); + } + + public static void callMethod1(Object object) { + try { + Class klass = Class.forName("WithReflectionAccess"); + java.lang.reflect.Method member = null; + int interfaceNumber = -1; + Class[] interfaces = null; + while (member == null) { + try { + member = klass.getDeclaredMethod("method"); + } catch (ReflectiveOperationException e) { + if (interfaceNumber == -1) { + interfaces = klass.getInterfaces(); + interfaceNumber = 0; + } + if (interfaceNumber < interfaces.length) { + klass = interfaces[interfaceNumber]; + interfaceNumber += 1; + } else { + klass = klass.getSuperclass(); + if (klass == null) throw e; + interfaceNumber = -1; + } + } + } + member.setAccessible(true); + member.invoke(object); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessMethodReference.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessMethodReference.out new file mode 100644 index 000000000000..74409b14c26b --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/accessMethodReference.out @@ -0,0 +1,38 @@ +call text: Test.invoke(); +class: +static class Test { + static void invoke() { + apply(() -> callMethod1(null)); + } + + public static void callMethod1(Object object) { + try { + Class klass = Class.forName("WithReflectionAccess"); + java.lang.reflect.Method member = null; + int interfaceNumber = -1; + Class[] interfaces = null; + while (member == null) { + try { + member = klass.getDeclaredMethod("method"); + } catch (ReflectiveOperationException e) { + if (interfaceNumber == -1) { + interfaces = klass.getInterfaces(); + interfaceNumber = 0; + } + if (interfaceNumber < interfaces.length) { + klass = interfaces[interfaceNumber]; + interfaceNumber += 1; + } else { + klass = klass.getSuperclass(); + if (klass == null) throw e; + interfaceNumber = -1; + } + } + } + member.setAccessible(true); + member.invoke(object); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/methodWithParameter.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/methodWithParameter.out new file mode 100644 index 000000000000..316f3dfbe03f --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/methodWithParameter.out @@ -0,0 +1,44 @@ +call text: Object result = new Test(instance).invoke(); +class: +static class Test { + private WithReflectionAccess instance; + + public Test(WithReflectionAccess instance) { + this.instance = instance; + } + + public static Object callMethod1(Object object, WithReflectionAccess arg) { + try { + Class klass = Class.forName("WithReflectionAccess"); + java.lang.reflect.Method member = null; + int interfaceNumber = -1; + Class[] interfaces = null; + while (member == null) { + try { + member = klass.getDeclaredMethod("method", Class.forName("WithReflectionAccess")); + } catch (ReflectiveOperationException e) { + if (interfaceNumber == -1) { + interfaces = klass.getInterfaces(); + interfaceNumber = 0; + } + if (interfaceNumber < interfaces.length) { + klass = interfaces[interfaceNumber]; + interfaceNumber += 1; + } else { + klass = klass.getSuperclass(); + if (klass == null) throw e; + interfaceNumber = -1; + } + } + } + member.setAccessible(true); + return (Object) member.invoke(object, arg); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public Object invoke() { + return callMethod1(instance, instance); + } + } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/methodWithPrimitiveParameter.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/methodWithPrimitiveParameter.out new file mode 100644 index 000000000000..d1deecf6f3db --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/methodWithPrimitiveParameter.out @@ -0,0 +1,44 @@ +call text: int result = new Test(instance).invoke(); +class: +static class Test { + private WithReflectionAccess instance; + + public Test(WithReflectionAccess instance) { + this.instance = instance; + } + + public static int callMethod1(Object object, int arg) { + try { + Class klass = Class.forName("WithReflectionAccess"); + java.lang.reflect.Method member = null; + int interfaceNumber = -1; + Class[] interfaces = null; + while (member == null) { + try { + member = klass.getDeclaredMethod("method", int.class); + } catch (ReflectiveOperationException e) { + if (interfaceNumber == -1) { + interfaces = klass.getInterfaces(); + interfaceNumber = 0; + } + if (interfaceNumber < interfaces.length) { + klass = interfaces[interfaceNumber]; + interfaceNumber += 1; + } else { + klass = klass.getSuperclass(); + if (klass == null) throw e; + interfaceNumber = -1; + } + } + } + member.setAccessible(true); + return (int) member.invoke(object, arg); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public int invoke() { + return callMethod1(instance, 42); + } + } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/twiceAccessToTheSameField.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/twiceAccessToTheSameField.out new file mode 100644 index 000000000000..305d3304ffd0 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/twiceAccessToTheSameField.out @@ -0,0 +1,75 @@ +call text: int result = new Test(instance).invoke(); +class: +static class Test { + private WithReflectionAccess instance; + + public Test(WithReflectionAccess instance) { + this.instance = instance; + } + + public static int accessToFieldField1(Object object, Object value) { + try { + Class klass = Class.forName("WithReflectionAccess"); + java.lang.reflect.Field member = null; + int interfaceNumber = -1; + Class[] interfaces = null; + while (member == null) { + try { + member = klass.getDeclaredField("field"); + } catch (ReflectiveOperationException e) { + if (interfaceNumber == -1) { + interfaces = klass.getInterfaces(); + interfaceNumber = 0; + } + if (interfaceNumber < interfaces.length) { + klass = interfaces[interfaceNumber]; + interfaceNumber += 1; + } else { + klass = klass.getSuperclass(); + if (klass == null) throw e; + interfaceNumber = -1; + } + } + } + member.setAccessible(true); + return (int) member.get(object); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public static int accessToFieldField2(Object object, Object value) { + try { + Class klass = Class.forName("WithReflectionAccess"); + java.lang.reflect.Field member = null; + int interfaceNumber = -1; + Class[] interfaces = null; + while (member == null) { + try { + member = klass.getDeclaredField("field"); + } catch (ReflectiveOperationException e) { + if (interfaceNumber == -1) { + interfaces = klass.getInterfaces(); + interfaceNumber = 0; + } + if (interfaceNumber < interfaces.length) { + klass = interfaces[interfaceNumber]; + interfaceNumber += 1; + } else { + klass = klass.getSuperclass(); + if (klass == null) throw e; + interfaceNumber = -1; + } + } + } + member.setAccessible(true); + return (int) member.get(object); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public int invoke() { + return accessToFieldField1(instance, null) + accessToFieldField2(instance, null); + } + } \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/updateField.out b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/updateField.out new file mode 100644 index 000000000000..c2544589be89 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/outs/updateField.out @@ -0,0 +1,44 @@ +call text: new Test(instance).invoke(); +class: +static class Test { + private WithReflectionAccess instance; + + public Test(WithReflectionAccess instance) { + this.instance = instance; + } + + public static void accessToFieldField1(Object object, Object value) { + try { + Class klass = Class.forName("WithReflectionAccess"); + java.lang.reflect.Field member = null; + int interfaceNumber = -1; + Class[] interfaces = null; + while (member == null) { + try { + member = klass.getDeclaredField("field"); + } catch (ReflectiveOperationException e) { + if (interfaceNumber == -1) { + interfaces = klass.getInterfaces(); + interfaceNumber = 0; + } + if (interfaceNumber < interfaces.length) { + klass = interfaces[interfaceNumber]; + interfaceNumber += 1; + } else { + klass = klass.getSuperclass(); + if (klass == null) throw e; + interfaceNumber = -1; + } + } + } + member.setAccessible(true); + member.set(object, value); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + public void invoke() { + accessToFieldField1(instance, 50); + } + } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerReflectionTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerReflectionTest.java new file mode 100644 index 000000000000..ebc1c22cc171 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerReflectionTest.java @@ -0,0 +1,72 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.java.refactoring; + +import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.psi.JavaCodeFragment; +import com.intellij.psi.JavaCodeFragmentFactory; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.extractMethod.PrepareFailedException; +import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler; +import com.intellij.testFramework.UsefulTestCase; +import org.jetbrains.annotations.NotNull; + +/** + * @author Vitaliy.Bibaev + */ +public class ExtractMethodObject4DebuggerReflectionTest extends LightRefactoringTestCase { + public void testAccessField() throws PrepareFailedException { + doTest("System.out.println(instance.field)"); + } + + public void testUpdateField() throws PrepareFailedException { + doTest("instance.field = 50"); + } + + public void testAccessConstructor() throws PrepareFailedException { + doTest("new WithReflectionAccess(50)"); + } + + public void testAccessMethod() throws PrepareFailedException { + doTest("method()"); + } + + public void testAccessMethodReference() throws PrepareFailedException { + doTest("apply(WithReflectionAccess::method)"); + } + + public void testTwiceAccessToTheSameField() throws PrepareFailedException { + doTest("instance.field + instance.field"); + } + + public void testMethodWithParameter() throws PrepareFailedException { + doTest("instance.method(instance)"); + } + + public void testMethodWithPrimitiveParameter() throws PrepareFailedException { + doTest("instance.method(42)"); + } + + @NotNull + @Override + protected String getTestDataPath() { + return super.getTestDataPath() + "/refactoring/extractMethodObject4Debugger"; + } + + private void doTest(String evaluatedText) throws PrepareFailedException { + String testName = getTestName(true); + configureByFile("/WithReflectionAccess.java"); + final int offset = getEditor().getCaretModel().getOffset(); + final PsiElement context = getFile().findElementAt(offset); + final JavaCodeFragmentFactory fragmentFactory = JavaCodeFragmentFactory.getInstance(getProject()); + final JavaCodeFragment fragment = fragmentFactory.createExpressionCodeFragment(evaluatedText, context, null, false); + final ExtractLightMethodObjectHandler.ExtractedData extractedData = + ExtractLightMethodObjectHandler.extractLightMethodObject(getProject(), context, fragment, "test", JavaSdkVersion.JDK_1_9); + assertNotNull(extractedData); + assertFalse(extractedData.useMagicAccessor()); + String actualText = "call text: " + extractedData.getGeneratedCallText() + "\n" + + "class: " + "\n" + + extractedData.getGeneratedInnerClass().getText(); + UsefulTestCase + .assertSameLinesWithFile(getTestDataPath() + "/outs/" + testName + ".out", actualText, true); + } +}