/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy
https://bitbucket.org/nbargnesi/idea · Groovy · 616 lines · 539 code · 74 blank · 3 comment · 2 complexity · a735a8bcfe77180df1928d3540b35ce6 MD5 · raw file
- package org.jetbrains.plugins.groovy.lang
-
- import com.intellij.codeInsight.generation.OverrideImplementUtil
- import com.intellij.codeInsight.lookup.LookupManager
- import com.intellij.codeInsight.navigation.GotoImplementationHandler
- import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection
- import com.intellij.openapi.module.Module
- import com.intellij.openapi.roots.ContentEntry
- import com.intellij.openapi.roots.ModifiableRootModel
- import com.intellij.openapi.roots.OrderRootType
- import com.intellij.openapi.roots.libraries.Library
- import com.intellij.openapi.vfs.JarFileSystem
- import com.intellij.psi.search.GlobalSearchScope
- import com.intellij.testFramework.LightProjectDescriptor
- import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor
- import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
- import junit.framework.ComparisonFailure
- import org.jetbrains.annotations.NotNull
- import org.jetbrains.plugins.groovy.codeInspection.GroovyUnusedDeclarationInspection
- import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection
- import org.jetbrains.plugins.groovy.codeInspection.unassignedVariable.UnassignedVariableAccessInspection
- import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition
- import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
- import org.jetbrains.plugins.groovy.util.TestUtils
- import com.intellij.psi.*
-
- /**
- * @author peter
- */
- class GppFunctionalTest extends LightCodeInsightFixtureTestCase {
-
- @NotNull
- @Override
- protected LightProjectDescriptor getProjectDescriptor() {
- return GppProjectDescriptor.instance;
- }
-
- protected void setUp() {
- super.setUp()
- }
-
- public void testCastListToIterable() throws Exception {
- myFixture.addClass("class X extends java.util.ArrayList<Integer> {}")
- testAssignability """
- X ints = [239, 4.2d]
- """
- }
-
- public void testCastListToAnything() throws Exception {
- testAssignability """
- File f1 = ['path']
- File f2 = <warning descr="Constructor 'File' in 'java.io.File' cannot be applied to '(java.lang.String, java.lang.Integer, java.lang.Boolean, java.lang.Integer)'">['path', 2, true, 42]</warning>
- """
- }
-
- public void testCastMapToAnotherMap() throws Exception {
- myFixture.addClass """
- public class Y extends java.util.HashMap<String, String> {
- public Y(int initialCapacity) {
- super(initialCapacity);
- }
- }
- """
-
- testAssignability """
- HashMap<String, File> m1 = ['a':['b']]
- Y y = <warning descr="Constructor 'Y' in 'Y' cannot be applied to '(['a':java.lang.String])'">[a:'b']</warning>
- """
- }
-
- public void testAnonymousClass() throws Exception {
- myFixture.enableInspections new GroovyAssignabilityCheckInspection()
- testAssignability """
- def x = new Object() {
- def foo() {
- HashMap<String, File> m1 = ['a':['b']]
- HashMap<String, File> m2 = <warning descr="Cannot assign 'File' to 'HashMap<String, File>'">new File('aaa')</warning>
- }
- }
- """
- }
-
- public void testCastMapToObject() throws Exception {
- myFixture.addClass("class Foo { String name; void foo() {} }")
- testAssignability """
- Foo f = [name: 'aaa', foo: { println 'hi' }, anotherProperty: 42 ]
- """
- }
-
- void testAssignability(String text) {
- myFixture.enableInspections new GroovyAssignabilityCheckInspection()
- PsiFile file = configureGppScript(text)
- myFixture.testHighlighting(true, false, false, file.virtualFile)
- }
-
- private PsiFile configureScript(String text) {
- return myFixture.configureByText("a.groovy", text)
- }
- private PsiFile configureGppScript(String text) {
- return myFixture.configureByText("a.gpp", text)
- }
-
- public void testDeclaredVariableTypeIsMoreImportantThanTheInitializerOne() throws Exception {
- configureScript("""
- File f = ['path']
- f.mk<caret>
- """)
- myFixture.completeBasic()
- assertSameElements myFixture.lookupElementStrings, "mkdir", "mkdirs"
- }
-
- public void testDeclaredVariableTypeIsMoreImportantThanTheInitializerOne2() throws Exception {
- myFixture.addClass """
- public class Some {
- public int prop
-
- public void f_foo() {}
- public void f_bar() {}
- }
- """
-
- configureScript("""
- Some s = [prop: 239]
- s.f_<caret>
- """)
- myFixture.completeBasic()
- assertSameElements myFixture.lookupElementStrings, "f_foo", "f_bar"
- }
-
- public void testResolveMethod() throws Exception {
- myFixture.configureByText("a.groovy", """
- def foo(File f) {}
- @Typed def bar() {
- fo<caret>o(['path'])
- }
- """)
- def reference = findReference()
- def target = reference.resolve()
- assertEquals "foo", ((GrMethod)target).name
- }
-
- private PsiReference findReference() {
- return myFixture.file.findReferenceAt(myFixture.editor.caretModel.offset)
- }
-
- public void testOverloadingWithConversion() throws Exception {
- myFixture.configureByText("a.groovy", """
- def foo(List l) {}
- def foo(File f) {}
- @Typed def bar() {
- fo<caret>o(['path'])
- }
- """)
- def reference = findReference()
- def target = reference.resolve()
- assertNotNull target
- assert target.text.contains("List l")
- }
-
- public void testWrongProperty() throws Exception {
- myFixture.configureByText 'a.gpp', '''
- class ClassA {
- def prop = 2
- def bar() {
- def t = new Object()
- t.pr<caret>op
- }
- }'''
- assert !findReference().resolve()
- }
-
- public void testCastClosureToOneMethodClass() throws Exception {
- myFixture.addClass """
- public abstract class Foo {
- public abstract void foo(String s);
- public abstract void bar(String s);
- }
- public interface Action {
- void act();
- }
- """
-
- testAssignability """
- Foo f = <warning descr="Cannot assign 'Closure' to 'Foo'">{ println it }</warning>
- Function1<String, Object> f1 = { println it }
- Function1<String, Object> f2 = { x=42 -> println x }
- Function1<String, Object> f3 = <warning descr="Cannot assign 'Closure' to 'Function1<String, Object>'">{ int x -> println x }</warning>
- Runnable r = { println it }
- Action a = { println it }
- Action a1 = { a2 = 2 -> println a2 }
- """
- }
-
- public void testClosureParameterTypesInAssignment() throws Exception {
- configureScript "Function1<String, Object> f = { it.subs<caret> }"
- myFixture.completeBasic()
- assertSameElements myFixture.lookupElementStrings, "subSequence", "substring", "substring"
- }
-
- public void testClosureParameterTypesInMethodInvocation() throws Exception {
- myFixture.configureByText "a.groovy", """
- def foo(int a = 1, Function1<String, Object> f) {}
- def foo(String s) {}
- def foo(Function2<Integer, String, Object> f) {}
-
- @Typed def bar() {
- foo { it.subsREF }
- foo(1, { it.subsREF })
- foo 1, { it.subsREF }
- foo(1) { it.subsREF }
- foo { a -> a.subsREF }
- foo { a, int b=2 -> a.subsREF }
- foo { a, b -> b.subsREF }
- }
- """
- def text = myFixture.file.text
- def pos = 0
- while (true) {
- pos = text.indexOf("REF", pos+1)
- if (pos < 0) {
- break
- }
- myFixture.editor.caretModel.moveToOffset pos
- myFixture.completeBasic()
- try {
- assertSameElements myFixture.lookupElementStrings, "subSequence", "substring", "substring"
- }
- catch (ComparisonFailure ex) {
- println "at: " + text[0..<pos] + "<caret>" + text[pos..<text.size()]
- throw ex
- }
- LookupManager.getInstance(project).hideActiveLookup()
- }
- }
-
- public void testReturnTypeOneMethodInterface() throws Exception {
- myFixture.configureByText "a.groovy", """
- @Typed Function1<String, Integer> bar() {
- { it.subs<caret> }
- }
- """
- myFixture.completeBasic()
- assertSameElements myFixture.lookupElementStrings, "subSequence", "substring", "substring"
- }
-
- public void testClosureInMapInstantiation() throws Exception {
- myFixture.configureByText "a.groovy", """
- class Foo<T> {
- int foo(T a) {}
- }
-
- @Typed Foo<String> bar() {
- return [foo: { it.subs<caret> }]
- }
- """
- myFixture.completeBasic()
- assertSameElements myFixture.lookupElementStrings, "subSequence", "substring", "substring"
- }
-
- public void testClosureInMapInstantiationBoxPrimitives() throws Exception {
- myFixture.configureByText "a.groovy", """
- class Foo {
- int foo(int a) {}
- }
-
- @Typed Foo bar() {
- return [foo: { it.intV<caret>V }]
- }
- """
- myFixture.completeBasic()
- assertSameElements myFixture.lookupElementStrings, "intValue"
- }
-
- public void testClosureInListInstantiation() throws Exception {
- myFixture.configureByText "a.groovy", """
- class Foo {
- def Foo(int a, Function1<String, Integer> f) {}
- }
-
- @Typed Foo foo() {
- [239, { s -> s.subs<caret> }]
- }
- """
- myFixture.completeBasic()
- assertSameElements myFixture.lookupElementStrings, "subSequence", "substring", "substring"
- }
-
- public void testTraitHighlighting() throws Exception {
- myFixture.configureByText "a.groovy", """
- @Trait
- abstract class Intf {
- abstract void foo()
- void bar() {}
- }
- <error descr="Method 'foo' is not implemented">class Foo implements Intf</error> {}
- <error descr="Method 'foo' is not implemented">class Wrong extends Foo</error> {}
- class Bar implements Intf {
- void foo() {}
- }
- """
- myFixture.testHighlighting(true, false, false, myFixture.file.virtualFile)
- }
-
- public void testTraitImplementingAndNavigation() throws Exception {
- myFixture.configureByText "a.groovy", """
- @Trait
- abstract class <caret>Intf {
- abstract void foo()
- void bar() {}
- }
- class Foo implements Intf {}
- class Bar implements Intf {
- void foo() {}
- }
- class BarImpl extends Bar {}
- """
- def facade = JavaPsiFacade.getInstance(getProject())
- def allScope = GlobalSearchScope.allScope(project)
- assertOneElement(OverrideImplementUtil.getMethodsToOverrideImplement(facade.findClass("Foo", allScope), true))
-
- GrTypeDefinition barClass = facade.findClass("Bar", allScope) as GrTypeDefinition
- assertEmpty(OverrideImplementUtil.getMethodsToOverrideImplement(barClass, true))
- assertTrue "bar" in OverrideImplementUtil.getMethodsToOverrideImplement(barClass, false).collect { ((PsiMethod) it.element).name }
-
- assertEmpty(OverrideImplementUtil.getMethodsToOverrideImplement(facade.findClass("BarImpl", allScope), true))
-
- def implementations = new GotoImplementationHandler().getSourceAndTargetElements(myFixture.editor, myFixture.file).targets
- assertEquals Arrays.toString(implementations), 3, implementations.size()
- }
-
- public void testResolveToStdLib() throws Exception {
- configureScript """
- @Typed def foo(List<String> l) {
- l.ea<caret>ch { it.substring(1) }
- }
- """
- PsiMethod method = resolveReference().navigationElement as PsiMethod
- assertEquals "each", method.name
- assertEquals "groovypp.util.Iterations", method.containingClass.qualifiedName
- }
-
- public void testResolveToStdLibWithArrayQualifier() throws Exception {
- configureGppScript """
- Integer[] a = []
- a.fol<caret>dLeft(2, { a, b -> a+b })
- """
- PsiMethod method = resolveReference().navigationElement as PsiMethod
- assertEquals "foldLeft", method.name
- assertEquals "groovypp.util.Iterations", method.containingClass.qualifiedName
- }
-
- private PsiElement resolveReference() {
- return findReference().resolve()
- }
-
- public void testResolveToSuperMethodClosureSyntax() {
- configureScript """
- abstract class Super implements Runnable {
- def method(int bar) {}
- }
-
- Super s = { <caret>method(2) } as Super
- """
- assert resolveReference() instanceof GrMethod
- }
-
- public void testMethodTypeParameterInference() throws Exception {
- configureScript """
- @Typed package aaa
-
- java.util.concurrent.atomic.AtomicReference<Integer> r = [2]
- r.apply { it.intV<caret>i }
- """
- myFixture.completeBasic()
- assertSameElements myFixture.getLookupElementStrings(), "intValue"
- }
-
- public void testMethodTypeParameterInference2() throws Exception {
- configureScript """
- @Typed package aaa
-
- java.util.concurrent.atomic.AtomicReference<Integer> r = [2]
- r.apply { it.intV<caret>i } {}
- """
- myFixture.completeBasic()
- assertSameElements myFixture.getLookupElementStrings(), "intValue"
- }
-
- public void testGotoSuperMethodFromMapLiterals() throws Exception {
- PsiClass point = myFixture.addClass("""
- class Point {
- Point() {}
- Point(int y) {}
- int y;
- void setX(int x) {}
- void move(int x, int y) {}
- void move(int y) {}
- }""")
-
- configureScript "Point p = [<caret>y:2]"
- assertEquals point.findFieldByName("y", false), resolveReference()
-
- configureScript "Point p = [<caret>x:2]"
- assertEquals point.findMethodsByName("setX", false)[0], resolveReference()
-
- configureScript "Point p = [mo<caret>ve: { x, y -> z }]"
- assertEquals point.findMethodsByName("move", false)[0], resolveReference()
-
- configureScript "Point p = [mo<caret>ve: ]"
- def resolveResults = multiResolveReference()
- assertSameElements resolveResults.collect { it.element }, point.findMethodsByName("move", false)
- }
-
- ResolveResult[] multiResolveReference() {
- return ((PsiPolyVariantReference) myFixture.file.findReferenceAt(myFixture.editor.caretModel.offset)).multiResolve(true)
- }
-
- public void testGotoSuperConstructorFromMapLiterals() throws Exception {
- PsiClass point = myFixture.addClass("""
- class Point {
- Point() {}
- Point(int y) {}
- }""")
-
- configureGppScript "Point p = [su<caret>per: 2]"
- assertEquals point.constructors[1], resolveReference()
-
- configureGppScript "Point p = [su<caret>per: [2]]"
- assertEquals point.constructors[1], resolveReference()
-
- configureGppScript "Point p = ['su<caret>per': []]"
- assertEquals point.constructors[0], resolveReference()
-
- configureGppScript "Point p = ['su<caret>per': 'a']"
- assertEquals 1, multiResolveReference().size()
- }
-
- public void testGotoSuperConstructorFromLiteralOnsets() throws Exception {
- PsiClass point = myFixture.addClass("""
- class Point {
- Point() {}
- Point(int y) {}
- }""")
-
- configureGppScript "Point p = <caret>[super: 2]"
- assertEquals point.constructors[1], resolveReference()
-
- configureGppScript "Point p = <caret>[2]"
- assertEquals point.constructors[1], resolveReference()
-
- configureGppScript "Point p = <caret>[]"
- assertEquals point.constructors[0], resolveReference()
-
- configureGppScript "Point p = <caret>[:]"
- assertEquals point.constructors[0], resolveReference()
-
- configureGppScript "Point p = <caret>[239, 42]"
- assertEquals 2, multiResolveReference().size()
-
- configureGppScript """
- def foo(Point p) {}
- foo(<caret>[2, 3])
- """
- assertEquals 2, multiResolveReference().size()
-
- configureGppScript """
- def foo(Point... p) {}
- foo(<caret>['super':[2, 3]])
- """
- assertEquals 2, multiResolveReference().size()
- }
-
- public void testGotoClassFromLiteralOnsetsWhenNoConstructorsPresent() throws Exception {
- PsiClass point = myFixture.addClass(""" class Point { }""")
- configureGppScript "Point p = <caret>[super: 2]"
- assertEquals point, resolveReference()
-
- configureGppScript "Point p = <caret>[]"
- assertEquals point, resolveReference()
- }
-
- public void testNoGotoObjectFromLiteral() throws Exception {
- myFixture.addClass(""" class Point { }""")
-
- configureGppScript "def p = <caret>[]"
- assertNull findReference()
- }
-
- public void testHighlightInapplicableLiteralConstructor() throws Exception {
- myFixture.addClass("""
- class Point {
- Point() {}
- }""")
-
- configureGppScript """
- def foo(Point p) {}
- Point p = [:]
- Point p2 = [super:warning descr="Cannot find constructor of 'Point'">[4, 2]</warning>]
- foo(<warning descr="Cannot find constructor of 'Point'">[4, 2]</warning>)
- """
- }
-
- public void testResolveTraitMethod() throws Exception {
- configureScript """
- @Trait
- class Some {
- public void doSmth() { println "hello" }
- }
- Some s
- s.do<caret>Smth()
- """
- assertEquals "doSmth", ((PsiMethod) findReference().resolve()).name
- }
-
- public void testBaseConstructorCallInMapLiteras() throws Exception {
- configureScript """
- @Typed File foo() { <warning descr="Constructor 'File' in 'java.io.File' cannot be applied to '(['super':[java.lang.String]])'">['super':['a']]</warning> }
- @Typed File goo() { <warning descr="Constructor 'File' in 'java.io.File' cannot be applied to '([:])'">[:]</warning> }
- File bar() { <warning descr="Constructor 'File' in 'java.io.File' cannot be applied to '([:])'">[:]</warning> }
- """
- myFixture.enableInspections new GroovyAssignabilityCheckInspection()
- myFixture.checkHighlighting(true, false, false)
- }
-
- public void testNestedLiteralConstructors() throws Exception {
- configureGppScript """
- class Foo {
- def Foo(Bar b) { }
- }
-
- class Bar {
- def Bar(int i) { }
- }
-
- Foo x = <warning descr="Constructor 'Foo' in 'Foo' cannot be applied to '([java.lang.Integer])'">[[2]]</warning>
- println x
- """
- myFixture.enableInspections new GroovyAssignabilityCheckInspection()
- myFixture.checkHighlighting(true, false, false)
- }
-
- public void testNoReturnTypeInferenceInTypedContext() throws Exception {
- configureGppScript """
- class Foo {
- def foo() { "aaa" }
- }
- new Foo().foo().substr<caret>a
- """
- assertEmpty myFixture.completeBasic()
- }
-
- public void testDeclaredReturnTypeInTypedContext() throws Exception {
- configureGppScript """
- class Foo {
- String getFoo() { "aaa" }
- }
- new Foo().foo.substr<caret>a
- """
- myFixture.completeBasic()
- assertOrderedEquals myFixture.lookupElementStrings, "substring", "substring"
- }
-
- public void testNonInitializedVariable() throws Exception {
- configureScript """
-
- @Typed
- def foo() {
- int a
- return a
- }
-
- def bar() {
- int a
- return <warning descr="Variable 'a' might not be assigned">a</warning>
- }"""
- myFixture.enableInspections new UnassignedVariableAccessInspection()
- myFixture.checkHighlighting(true, false, false)
- }
-
- public void testExternalizable() throws Exception {
- configureScript '''
- @Typed class Foo implements Externalizable {}
- <error descr="Method 'writeExternal' is not implemented">class Bar implements Externalizable</error> {}
- '''
- myFixture.checkHighlighting(true, false, false)
- }
-
- public void testUsedInterceptors() {
- configureGppScript '''
- class Bar {
- Object getUnresolvedProperty(String <warning descr="Parameter name is unused">name</warning>) {}
- Object <warning descr="Method getUnresolvedProperty is unused">getUnresolvedProperty</warning>(int <warning descr="Parameter name is unused">name</warning>) {}
- void setUnresolvedProperty(String <warning descr="Parameter name is unused">name</warning>, String <warning descr="Parameter value is unused">value</warning>) {}
- int invokeUnresolvedMethod(String <warning descr="Parameter name is unused">name</warning>, String <warning descr="Parameter arg1 is unused">arg1</warning>, boolean <warning descr="Parameter arg2 is unused">arg2</warning>, Object... <warning descr="Parameter args is unused">args</warning>) {}
- int invokeUnresolvedMethod(String <warning descr="Parameter name is unused">name</warning>, Object... <warning descr="Parameter args is unused">args</warning>) {}
- int <warning descr="Method invokeUnresolvedMethod is unused">invokeUnresolvedMethod</warning>(Object... <warning descr="Parameter args is unused">args</warning>) {}
- }
- println new Bar().zzz
- '''
- myFixture.enableInspections(new GroovyUnusedDeclarationInspection(), new UnusedDeclarationInspection())
- myFixture.checkHighlighting(true, false, false)
- }
-
- }
-
- class GppProjectDescriptor extends DefaultLightProjectDescriptor {
- public static final instance = new GppProjectDescriptor()
-
- @Override
- public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
- final Library.ModifiableModel modifiableModel = model.moduleLibraryTable.createLibrary("GROOVY++").modifiableModel;
- modifiableModel.addRoot(JarFileSystem.instance.refreshAndFindFileByPath(TestUtils.absoluteTestDataPath + "mockGroovypp/groovypp-0.9.0_1.8.2.jar!/"), OrderRootType.CLASSES)
- modifiableModel.addRoot(JarFileSystem.instance.refreshAndFindFileByPath(TestUtils.mockGroovy1_7LibraryName + "!/"), OrderRootType.CLASSES);
- modifiableModel.commit();
- }
- }