| /* |
| * Copyright 2003-2012 the original author or authors. |
| * |
| * 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 groovy |
| |
| import gls.CompilableTestSupport |
| import static java.lang.Boolean.FALSE as F |
| import static java.text.DateFormat.MEDIUM as M |
| import static java.util.regex.Pattern.* |
| import static java.text.DateFormat.MEDIUM |
| import static junit.framework.Assert.format |
| import static junit.framework.Assert.assertEquals |
| import static groovy.StaticImportTarget.x |
| import static groovy.StaticImportTarget.z // do not remove |
| import static groovy.StaticImportTarget.cl |
| import static java.lang.Math.* |
| import static java.util.Calendar.getInstance as now |
| import static groovy.API.* |
| import static groovy.StaticImportChild.* |
| import static groovy.bugs.Groovy4145.foo4145 |
| import static groovy.Outer1.* |
| import static groovy.Outer2.Inner2 |
| import static groovy.Outer2.Inner2 as InnerAlias2 |
| import static java.util.jar.Attributes.* |
| import static java.util.jar.Attributes.Name as AttrName |
| // TODO GROOVY-4287: reinstate next two imports |
| //import static Outer3.* |
| //import static Outer4.Inner4 |
| import static groovy.Container5087.* |
| import org.codehaus.groovy.runtime.DefaultGroovyMethods as DGM |
| |
| class StaticImportTest extends CompilableTestSupport { |
| void testFieldWithAliasInExpression() { |
| assert !F |
| } |
| |
| void testMethodAndField() { |
| assert cos(2 * PI) == 1.0 |
| } |
| |
| static myStaticMethod() { |
| cos(2 * PI) |
| } |
| |
| void testMethodAndFieldInStaticContext() { |
| assert myStaticMethod() == 1.0 |
| } |
| |
| void testMethodAndFieldInClosure() { |
| def closure = { cos(2 * PI) } |
| assert closure() == 1.0 |
| } |
| |
| void testFieldAsObjectExpression() { |
| assert PI.equals(Math.PI) |
| } |
| |
| void testFieldAsArgumentList() { |
| assert ("" + PI.toString()).contains('3.14') |
| } |
| |
| void testFieldAliasing() { |
| assert MEDIUM == M |
| } |
| |
| void testMethodAliasing() { |
| // GROOVY-1809 making this not possible on one line? |
| def now = now().time |
| assert now.class == Date |
| } |
| |
| void testWildCardAliasing() { |
| assert MULTILINE == java.util.regex.Pattern.MULTILINE |
| } |
| |
| private format(a, b, c, ignored) { format(a, b, c) } |
| |
| void testMethodDefCanUseStaticallyImportedMethodWithSameNameButDiffArgs() { |
| assert format("different", "abc", "aBc", 3) == 'different expected:<abc> but was:<aBc>' |
| } |
| |
| void testAssertEqualsFromJUnit() { |
| double[] values = [3.9999, 4.0001, 0.00021, 0.00019] |
| assertEquals(values[0], values[1], values[2]) |
| shouldFail(junit.framework.AssertionFailedError) { |
| assertEquals(values[0], values[1], values[3]) |
| } |
| } |
| |
| void testStaticImportFromGroovy() { |
| def nonstaticval = new StaticImportTarget().y("he", 3) |
| def staticval = x("he", 3) |
| assert nonstaticval == staticval |
| } |
| |
| void testStaticImportWithVarArgs() { |
| assert noArrayMethod("one", 1) == 'noArrayMethod(one, 1)' |
| assert API.arrayMethod("two", 1, 2, 3) == 'arrayMethod(two, 1, 2, 3)' |
| assert arrayMethod("three", 1, 2, 3) == 'arrayMethod(three, 1, 2, 3)' |
| } |
| |
| void testStaticImportFromParentClass() { |
| assert cmethod() == 'hello from child' |
| assert pmethod() == 'hello from parent' |
| assert cfield == 21 |
| assert pfield == 42 |
| } |
| |
| void testStaticImportAndDefaultValue() { |
| assertScript """ |
| import static Foo.* |
| import static Bar.* |
| |
| class Bar { |
| static void bar() { |
| assert foo(10,1000) == 1010 |
| assert foo(10) == 110 |
| } |
| } |
| |
| class Foo { |
| static int foo(int x, int y = 100) {x+y} |
| } |
| |
| Bar.bar() |
| """ |
| } |
| |
| void testStaticImportProperty() { |
| def sources = [ |
| "class Foo { static x = 'foo'" + " }", |
| "class Foo { static x = 'foo'" + "; static getX() { x + '_get' } }", |
| "class Foo { static x = 'foo'" + "; static void setX(newx) { x = newx + '_set' } }", |
| "class Foo { static x = 'foo'" + "; static getX() { x + '_get' }; static void setX(newx) { x = newx + '_set' } }" |
| ] |
| def imports = [ |
| "import static Foo.*", |
| "import static Foo.getX; import static Foo.setX" |
| ] |
| def results = [ |
| "assert x == 'foo'; x = 'bar'; assert getX() == 'bar'; setX('baz'); assert 'baz' == x", |
| "assert x == 'foo_get'; x = 'bar'; assert getX() == 'bar_get'; setX('baz'); assert 'baz_get' == x", |
| "assert x == 'foo'; x = 'bar'; assert getX() == 'bar_set'; setX('baz'); assert 'baz_set' == x", |
| "assert x == 'foo_get'; x = 'bar'; assert getX() == 'bar_set_get'; setX('baz'); assert 'baz_set_get' == x" |
| ] |
| [0..<sources.size(), 0..<imports.size()].combinations().each { i, j -> |
| assertScript sources[i] + "\n" + imports[j] + "\n" + results[i] |
| } |
| } |
| |
| void testStaticImportPropertyBooleanAlternative() { |
| def sources = [ |
| "class Foo { static x = null" + "; static boolean isX() { x } }", |
| "class Foo { static x = null" + "; static boolean isX() { x }; static void setX(newx) { x = newx } }" |
| ] |
| def imports = [ |
| "import static Foo.*", |
| "import static Foo.x", |
| "import static Foo.isX; import static Foo.setX" |
| ] |
| def results = [ |
| "assert !x; x = true ; assert isX(); setX(false); assert !x", |
| "assert !x; x = false; assert !isX(); setX(true); assert x" |
| ] |
| [0..<sources.size(), 0..<imports.size()].combinations().each { i, j -> |
| assertScript sources[i] + "\n" + imports[j] + "\n" + results[i] |
| } |
| } |
| |
| void testStaticImportPropertyWithPublicField() { |
| def sources = [ |
| "class Foo { public static x = 'foo'" + " }", |
| "class Foo { public static x = 'foo'" + "; static getX() { x + '_get' } }", |
| "class Foo { public static x = 'foo'" + "; static void setX(newx) { x = newx + '_set' } }", |
| "class Foo { public static x = 'foo'" + "; static getX() { x + '_get' }; static void setX(newx) { x = newx + '_set' } }" |
| ] |
| def imports = [ |
| "import static Foo.*", |
| "import static Foo.x" |
| ] |
| def results = [ |
| "assert x == 'foo'; x = 'bar'; assert x == 'bar'; x = 'baz' ; assert 'baz' == x", |
| "assert x == 'foo_get'; x = 'bar'; assert getX() == 'bar_get'; x = 'baz' ; assert 'baz_get' == x", |
| "assert x == 'foo'; x = 'bar'; assert x == 'bar_set'; setX('baz'); assert 'baz_set' == x", |
| "assert x == 'foo_get'; x = 'bar'; assert getX() == 'bar_set_get'; setX('baz'); assert 'baz_set_get' == x" |
| ] |
| [0..<sources.size(), 0..<imports.size()].combinations().each { i, j -> |
| assertScript sources[i] + "\n" + imports[j] + "\n" + results[i] |
| } |
| assertScript sources[3] + """ |
| import static Foo.getX; import static Foo.setX |
| assert getX() == 'foo_get'; setX('bar'); assert getX() == 'bar_set_get'; setX('baz'); assert 'baz_set_get' == getX() |
| """ |
| } |
| |
| void testStaticImportPropertyWithAliases() { |
| def sources = [ |
| "class Foo { static x = 'foo'" + " }", |
| "class Foo { static x = 'foo'" + "; static getX() { x + '_get' } }", |
| "class Foo { static x = 'foo'" + "; static void setX(newx) { x = newx + '_set' } }", |
| "class Foo { static x = 'foo'" + "; static getX() { x + '_get' }; static void setX(newx) { x = newx + '_set' } }" |
| ] |
| def imports = [ |
| "import static Foo.x as z", |
| "import static Foo.getX as getZ; import static Foo.setX as setZ" |
| ] |
| def results = [ |
| "assert z == 'foo'; z = 'bar'; assert getZ() == 'bar'; setZ('baz'); assert 'baz' == z", |
| "assert z == 'foo_get'; z = 'bar'; assert getZ() == 'bar_get'; setZ('baz'); assert 'baz_get' == z", |
| "assert z == 'foo'; z = 'bar'; assert getZ() == 'bar_set'; setZ('baz'); assert 'baz_set' == z", |
| "assert z == 'foo_get'; z = 'bar'; assert getZ() == 'bar_set_get'; setZ('baz'); assert 'baz_set_get' == z" |
| ] |
| [0..<sources.size(), 0..<imports.size()].combinations().each { i, j -> |
| assertScript sources[i] + "\n" + imports[j] + "\n" + results[i] |
| } |
| } |
| |
| void testConstructorArgsAliasing() { |
| // not recommended style to use statics in constructors but supported |
| assertScript """ |
| class Foo { |
| static x |
| } |
| import static Foo.x as z |
| new Foo(z:'hi') |
| assert z == 'hi' |
| """ |
| } |
| |
| void testMethodCallWithThisTargetIsNotResolvedToStaticallyImportedMethod() { |
| // not using shouldFail() to avoid closure scope |
| try { |
| this.z() |
| fail() |
| } catch (MissingMethodException expected) {} |
| } |
| |
| void testMethodCallWithSuperTargetIsNotResolvedToStaticallyImportedMethod() { |
| // not using shouldFail() to avoid closure scope |
| try { |
| super.z() |
| fail() |
| } catch (MissingMethodException expected) {} |
| } |
| |
| void testStaticImportOfAClosureField() { //GROOVY-3945 |
| assert cl() == 'StaticImportTarget#static closure called' |
| } |
| |
| void testStaticPropertyImportedImplementedAsGetter() { //GROOVY-4145 |
| assert foo4145 == 3 |
| } |
| |
| void testMethodCallExpressionInStaticContextWithInstanceVariableShouldFail() { //GROOVY-4228 |
| shouldNotCompile ''' |
| class B { |
| def c = new Object() |
| static main(args) { |
| c.foo() |
| } |
| } |
| ''' |
| } |
| |
| void testStaticStarImportOfStaticInnerClass() { |
| assert Inner1.class.name == 'groovy.Outer1$Inner1' |
| } |
| |
| void testStaticImportOfStaticInnerClass() { |
| assert Inner2.class.name == 'groovy.Outer2$Inner2' |
| } |
| |
| void testStaticImportOfStaticInnerClassWithAlias() { |
| assert InnerAlias2.class.name == 'groovy.Outer2$Inner2' |
| } |
| |
| void testStaticImportOfStaticInnerClassExistingExternalJar() { |
| assert Name.class.name == 'java.util.jar.Attributes$Name' |
| } |
| |
| void testStaticImportOfStaticInnerClassExistingExternalJarWithAlias() { |
| assert AttrName.class.name == 'java.util.jar.Attributes$Name' |
| } |
| |
| void testExplicitStaticMethodCallHasPrecedenceOverStaticImport() { |
| Bar4964.run() |
| } |
| |
| // TODO GROOVY-4287: reinstate next two tests |
| // void testStaticStarImportOfStaticInnerClassExternalClass() { |
| // assert Inner3.class.name == 'Outer3$Inner3' |
| // } |
| // |
| // void testStaticImportOfStaticInnerClassExternalClass() { |
| // assert Inner4.class.name == 'Outer4$Inner4' |
| // } |
| |
| void testMapIndexInLeftExpressionOfEquals() { |
| holder = 'foo' |
| def map = [:] |
| map[holder] = 'bar' |
| assert map.containsKey('foo') |
| assert map.foo == 'bar' |
| } |
| |
| void testConstructorParamInLeftExpressionOfEquals() { |
| holder = [:] |
| new HolderWrapper(holder).foo = 'baz' |
| assert holder.foo == 'baz' |
| } |
| |
| void testMethodParamInLeftExpressionOfEquals() { |
| holder = [[a:1, b:2], [c:3]] |
| DGM.find(holder) { it.size() == 2 }.a = 4 |
| assert holder[0].a == 4 |
| dgmFind(holder) { it.size() == 1 }.c = 7 |
| assert holder[1].c == 7 |
| } |
| |
| private <T> T dgmFind(Collection<T> col, Closure clos) { |
| DGM.find(col, clos) |
| } |
| } |
| |
| class API { |
| static noArrayMethod(String s, int value) { |
| "noArrayMethod(${s}, ${value})" |
| } |
| |
| static arrayMethod(String s, int[] values) { |
| "arrayMethod(${s}, " + values.toList().join(", ") + ")" |
| } |
| } |
| |
| class StaticImportParent { |
| static pfield = 42 |
| static pmethod() { 'hello from parent' } |
| } |
| |
| class StaticImportChild extends StaticImportParent { |
| static cfield = 21 |
| static cmethod() { 'hello from child' } |
| } |
| |
| class Outer1 { |
| static class Inner1 {} |
| } |
| |
| class Outer2 { |
| static class Inner2 {} |
| } |
| |
| class Foo4964 { |
| static doIt() { [k: 'foo'] } |
| } |
| |
| import static Foo4964.* |
| class Bar4964 { |
| static doIt() { [k: 'bar'] } |
| static run() { |
| assert doIt().k == 'foo' |
| assert doIt() == [k: 'foo'] |
| assert Bar4964.doIt() == [k: 'bar'] |
| assert Bar4964.doIt().k == 'bar' |
| } |
| } |
| |
| class Container5087 { |
| static holder |
| } |
| |
| class HolderWrapper { |
| def holder |
| |
| HolderWrapper(holder) { |
| this.holder = holder |
| } |
| |
| void setProperty(String name, Object value) { |
| holder[name] = value |
| } |
| } |