You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/07/14 13:12:09 UTC

[groovy] branch master updated: Update tests for GROOVY-9043, GROOVY-9093, GROOVY-9106, et al.(closes #938)

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 6f49f5a  Update tests for GROOVY-9043, GROOVY-9093, GROOVY-9106, et al.(closes #938)
6f49f5a is described below

commit 6f49f5a47267dfcc549e9172fd952d48d5e1fd2a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Jul 14 21:11:03 2019 +0800

    Update tests for GROOVY-9043, GROOVY-9093, GROOVY-9106, et al.(closes #938)
---
 .../packageScope/DifferentPackageTest.groovy       | 247 +++++++++++++++++----
 .../packageScope/PackageScopeTransformTest.groovy  | 244 +++++++++++++-------
 .../groovy/transform/packageScope/p/One.groovy     |  24 --
 3 files changed, 365 insertions(+), 150 deletions(-)

diff --git a/src/test/org/codehaus/groovy/transform/packageScope/DifferentPackageTest.groovy b/src/test/org/codehaus/groovy/transform/packageScope/DifferentPackageTest.groovy
index b41b9c6..a041e6a 100644
--- a/src/test/org/codehaus/groovy/transform/packageScope/DifferentPackageTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/packageScope/DifferentPackageTest.groovy
@@ -18,72 +18,227 @@
  */
 package org.codehaus.groovy.transform.packageScope
 
-import org.codehaus.groovy.control.MultipleCompilationErrorsException
+import org.codehaus.groovy.control.*
+import org.codehaus.groovy.tools.GroovyClass
 
-class DifferentPackageTest extends GroovyTestCase {
-    void _FIXME_testSamePackageShouldSeeInstanceProps() {
-        assertScript '''
-            package org.codehaus.groovy.transform.packageScope.p
+final class DifferentPackageTest extends GroovyTestCase {
 
-            @groovy.transform.CompileStatic
-            class Two extends One {
-                void valSize() {
-                    value.size()
-                }
+    /** Class in package {@code p} with package-private fields {@code value} and {@code CONST}. */
+    private static final String P_DOT_ONE = '''
+        package p
+
+        @groovy.transform.CompileStatic
+        class One {
+            @groovy.transform.PackageScope
+            String value = 'value'
+            @groovy.transform.PackageScope
+            static final int CONST = 42
+        }
+    '''
+
+    private ClassLoader addSources(Map<String, String> sources) {
+        new CompilationUnit().with {
+            sources.each { name, text -> addSource(name + '.groovy', text) }
+            compile(Phases.CLASS_GENERATION)
+
+            classes.each { GroovyClass groovyClass ->
+                classLoader.defineClass(groovyClass.name, groovyClass.bytes)
             }
+            return classLoader
+        }
+    }
+
+    //--------------------------------------------------------------------------
 
-            assert new Two().valSize() == 3
-        '''
+    void testSamePackageShouldSeeInstanceProps1() {
+        def loader = addSources(
+            One: P_DOT_ONE,
+            Two: '''
+                package p
+
+                @groovy.transform.CompileStatic
+                class Two extends One {
+                    int valueSize() {
+                        value.size()
+                    }
+                }
+            ''')
+
+        assert loader.loadClass('p.Two').newInstance().valueSize() == 5
     }
 
-    void _FIXME_testSamePackageShouldSeeStaticProps() {
-        assertScript '''
-            package org.codehaus.groovy.transform.packageScope.p
+    void testSamePackageShouldSeeInstanceProps2() {
+        def loader = addSources(
+            One: P_DOT_ONE,
+            Peer: '''
+                package p
 
-            @groovy.transform.CompileStatic
-            class Three {
-                static void halfNum() {
-                    One.NUM / 2
+                @groovy.transform.CompileStatic
+                class Peer {
+                    int valueSize() {
+                        new One().value.size()
+                    }
                 }
-            }
+            ''')
 
-            assert Three.halfNum() == 21
-        '''
+        assert loader.loadClass('p.Peer').newInstance().valueSize() == 5
     }
 
-    void _FIXME_testDifferentPackageShouldNotSeeInstanceProps() {
-        def message = shouldFail(MultipleCompilationErrorsException, '''
-            package org.codehaus.groovy.transform.packageScope.q
+    void testSamePackageShouldSeeStaticProps1() {
+        def loader = addSources(
+            One: P_DOT_ONE,
+            Two: '''
+                package p
 
-            import org.codehaus.groovy.transform.packageScope.p.One
+                @groovy.transform.CompileStatic
+                class Two extends One {
+                    static def half() {
+                        CONST / 2
+                    }
+                }
+            ''')
+
+        assert loader.loadClass('p.Two').half() == 21
+    }
 
-            @groovy.transform.CompileStatic
-            class Two extends One {
-                void valSize() {
-                    value.size()
+    void testSamePackageShouldSeeStaticProps2() {
+        def loader = addSources(
+            One: P_DOT_ONE,
+            Two: '''
+                package p
+
+                @groovy.transform.CompileStatic
+                class Two extends One {
+                    def half() {
+                        CONST / 2
+                    }
                 }
-            }
+            ''')
 
-            assert new Two().valSize() == 3
-        ''')
-        assert message.matches('(?s).*Access to .*value is forbidden.*')
+        assert loader.loadClass('p.Two').newInstance().half() == 21
     }
 
-    void testDifferentPackageShouldNotSeeStaticProps() {
-        def message = shouldFail(MultipleCompilationErrorsException, '''
-            package org.codehaus.groovy.transform.packageScope.q
+    void testSamePackageShouldSeeStaticProps3() {
+        def loader = addSources(
+            One: P_DOT_ONE,
+            Peer: '''
+                package p
 
-            import org.codehaus.groovy.transform.packageScope.p.One
+                @groovy.transform.CompileStatic
+                class Peer {
+                    static def half() {
+                        One.CONST / 2
+                    }
+                }
+            ''')
+
+        assert loader.loadClass('p.Peer').half() == 21
+    }
 
-            @groovy.transform.CompileStatic
-            class Three {
-                static void halfNum() {
-                    One.NUM / 2
+    void testSamePackageShouldSeeStaticProps4() {
+        def loader = addSources(
+            One: P_DOT_ONE,
+            Peer: '''
+                package p
+
+                @groovy.transform.CompileStatic
+                class Peer {
+                    def half() {
+                        One.CONST / 2
+                    }
                 }
-            }
+            ''')
+
+        assert loader.loadClass('p.Peer').newInstance().half() == 21
+    }
+
+    // GROOVY-9106
+    void _FIXME_testSamePackageShouldSeeStaticProps5() {
+        def loader = addSources(
+            One: P_DOT_ONE,
+            Two: '''
+                package q
+
+                @groovy.transform.CompileStatic
+                class Two extends p.One {
+                }
+            ''',
+            Peer: '''\
+                package p
+
+                @groovy.transform.CompileStatic
+                class Peer {
+                    static def half() {
+                        (q.Two.CONST / 2) // indirect access
+                    }
+                }
+            ''')
+
+        assert loader.loadClass('p.Peer').half() == 21
+    }
+
+    // GROOVY-9093
+    void _FIXME_testDifferentPackageShouldNotSeeInstanceProps() {
+        def err = shouldFail CompilationFailedException, {
+            def loader = addSources(
+                One: P_DOT_ONE,
+                Two: '''
+                    package q
+
+                    @groovy.transform.CompileStatic
+                    class Two extends p.One {
+                        int valueSize() {
+                            value.size() // not visible
+                        }
+                    }
+                ''')
+            // TODO: Don't need this once compiler errors
+            assert loader.loadClass('q.Two').newInstance().valueSize() == 5
+        }
+
+        assert err =~ / Access to ... value is forbidden /
+    }
+
+    // GROOVY-9093
+    void _FIXME_testDifferentPackageShouldNotSeeStaticProps1() {
+        def err = shouldFail CompilationFailedException, {
+            def loader = addSources(
+                One: P_DOT_ONE,
+                Two: '''
+                    package q
+
+                    @groovy.transform.CompileStatic
+                    class Two extends p.One {
+                        static def half() {
+                            (CONST / 2) // not visible
+                        }
+                    }
+                ''')
+            // TODO: Don't need this once compiler errors
+            assert loader.loadClass('q.Two').half() == 21
+        }
+
+        assert err =~ / Access to p.One#CONST is forbidden /
+    }
+
+    void testDifferentPackageShouldNotSeeStaticProps2() {
+        def err = shouldFail CompilationFailedException, {
+            addSources(
+                One: P_DOT_ONE,
+                Other: '''
+                    package q
+
+                    import p.One
+
+                    @groovy.transform.CompileStatic
+                    class Other {
+                        static def half() {
+                            (One.CONST / 2) // not visible
+                        }
+                    }
+                ''')
+        }
 
-            assert Three.halfNum() == 21
-        ''')
-        assert message.matches('(?s).*Access to .*One#NUM is forbidden.*')
+        assert err =~ / Access to p.One#CONST is forbidden /
     }
 }
diff --git a/src/test/org/codehaus/groovy/transform/packageScope/PackageScopeTransformTest.groovy b/src/test/org/codehaus/groovy/transform/packageScope/PackageScopeTransformTest.groovy
index 83f8048..12f3a5e 100644
--- a/src/test/org/codehaus/groovy/transform/packageScope/PackageScopeTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/packageScope/PackageScopeTransformTest.groovy
@@ -18,107 +18,191 @@
  */
 package org.codehaus.groovy.transform.packageScope
 
-import java.lang.reflect.Modifier
+import groovy.transform.CompileStatic
+import org.junit.Test
 
-class PackageScopeTransformTest extends GroovyShellTestCase {
-    // GROOVY-9043
-    void testPackagePrivateAccessFromInnerClassCS() {
+import static groovy.test.GroovyAssert.assertScript
+
+@CompileStatic
+final class PackageScopeTransformTest {
+
+    @Test
+    void testPackageScope1() {
         assertScript '''
-            import groovy.transform.CompileStatic
             import groovy.transform.PackageScope
-            @CompileStatic
-            class Test {
-                @PackageScope
-                static final String S = 'S'
-                static private final String T = 'T'
-                static protected final String U = 'U'
-                static class Inner {
-                    String method() {
-                        S + T + U
-                    }
-                }
+            import static java.lang.reflect.Modifier.*
+
+            class A {
+                String x
+            }
+            @PackageScope class B {
+                String x
             }
 
-            assert new Test.Inner().method() == 'STU'
+            assert isPublic(A.modifiers)
+            assert !isPublic(B.modifiers) && !isPrivate(B.modifiers) && !isProtected(B.modifiers)
+
+            assert isPublic(A.getDeclaredConstructor().modifiers)
+            assert isPublic(B.getDeclaredConstructor().modifiers)
+
+            assert isPrivate(A.getDeclaredField('x').modifiers)
+            assert isPrivate(A.getDeclaredField('x').modifiers)
+
+            assert isPublic(A.getDeclaredMethod('getX').modifiers)
+            assert isPublic(B.getDeclaredMethod('getX').modifiers)
+
+            assert isPublic(A.getDeclaredMethod('setX', String).modifiers)
+            assert isPublic(B.getDeclaredMethod('setX', String).modifiers)
         '''
     }
 
-    void testImmutable() {
-        def objects = evaluate("""
+    @Test
+    void testPackageScope2() {
+        assertScript '''
             import groovy.transform.PackageScope
-            import static groovy.transform.PackageScopeTarget.FIELDS
-            class Control {
-                String x
-                def method() {}
+            import static java.lang.reflect.Modifier.*
+            import static groovy.test.GroovyAssert.shouldFail
+
+            class C {
+                @PackageScope C() {}
+                @PackageScope String x
+                @PackageScope def method() {}
+            }
+
+            boolean isPackagePrivate(modifiers) {
+                !isPublic(modifiers) && !isPrivate(modifiers) && !isProtected(modifiers)
             }
-            @PackageScope(FIELDS) class Foo {
+
+            assert isPublic(C.modifiers)
+
+            assert isPackagePrivate(C.getDeclaredConstructor().modifiers)
+
+            assert isPackagePrivate(C.getDeclaredField('x').modifiers)
+
+            assert isPackagePrivate(C.getDeclaredMethod('method').modifiers)
+
+            shouldFail(NoSuchMethodException) {
+                C.getDeclaredMethod('getX')
+                C.getDeclaredMethod('setX', String)
+            }
+        '''
+    }
+
+    @Test
+    void testPackageScope3() {
+        assertScript '''
+            import groovy.transform.PackageScope
+            import static java.lang.reflect.Modifier.*
+            import static groovy.test.GroovyAssert.shouldFail
+            import static groovy.transform.PackageScopeTarget.*
+
+            @PackageScope(FIELDS) class C {
+                C() {}
                 String x
                 def method() {}
             }
-            class Bar {
-                Bar() {}
-                @PackageScope Bar(String x) { this.x = x }
-                @PackageScope String x
-                @PackageScope def method() {}
+
+            boolean isPackagePrivate(modifiers) {
+                !isPublic(modifiers) && !isPrivate(modifiers) && !isProtected(modifiers)
+            }
+
+            assert isPublic(C.modifiers)
+
+            assert isPublic(C.getDeclaredConstructor().modifiers)
+
+            assert isPackagePrivate(C.getDeclaredField('x').modifiers)
+
+            assert isPublic(C.getDeclaredMethod('method').modifiers)
+
+            shouldFail(NoSuchMethodException) {
+                C.getDeclaredMethod('getX')
+                C.getDeclaredMethod('setX', String)
             }
-            @PackageScope class Baz {
+        '''
+    }
+
+    @Test
+    void testPackageScope4() {
+        assertScript '''
+            import groovy.transform.PackageScope
+            import static java.lang.reflect.Modifier.*
+            import static groovy.test.GroovyAssert.shouldFail
+            import static groovy.transform.PackageScopeTarget.*
+
+            @PackageScope(METHODS) class C {
+                C() {}
                 String x
                 def method() {}
             }
-            [new Control(), new Foo(), new Bar(), new Baz()]
-        """)
-        objects*.class.each { c ->
-            def methodNames = c.methods.name
-            if (c.name == 'Control' || c.name == 'Baz') {
-                assert methodNames.contains('getX')
-                assert methodNames.contains('setX')
-            } else {
-                assert !methodNames.contains('getX')
-                assert !methodNames.contains('setX')
-            }
-            def xField = c.declaredFields.find{ it.name == 'x' }
-            assert xField
-            if (c.name == 'Control' || c.name == 'Baz') {
-                assert Modifier.isPrivate(xField.modifiers)
-            } else {
-                assert !Modifier.isPrivate(xField.modifiers)
-                assert !Modifier.isPublic(xField.modifiers)
-                assert !Modifier.isProtected(xField.modifiers)
+
+            boolean isPackagePrivate(modifiers) {
+                !isPublic(modifiers) && !isPrivate(modifiers) && !isProtected(modifiers)
             }
-            def method = c.declaredMethods.find{ it.name == 'method' }
-            assert method
-            if (c.name == 'Bar') {
-                assert !Modifier.isPrivate(method.modifiers)
-                assert !Modifier.isPublic(method.modifiers)
-                assert !Modifier.isProtected(method.modifiers)
-            } else {
-                assert Modifier.isPublic(method.modifiers)
+
+            assert isPublic(C.modifiers)
+
+            assert isPublic(C.getDeclaredConstructor().modifiers)
+
+            assert isPrivate(C.getDeclaredField('x').modifiers)
+            assert isPublic(C.getDeclaredMethod('getX').modifiers)
+            assert isPublic(C.getDeclaredMethod('setX', String).modifiers)
+
+            assert isPackagePrivate(C.getDeclaredMethod('method').modifiers)
+        '''
+    }
+
+    @Test
+    void testPackageScope5() {
+        assertScript '''
+            import groovy.transform.PackageScope
+            import static java.lang.reflect.Modifier.*
+            import static groovy.test.GroovyAssert.shouldFail
+            import static groovy.transform.PackageScopeTarget.*
+
+            @PackageScope([CLASS, CONSTRUCTORS, METHODS]) class C {
+                C() {}
+                String x
+                def method() {}
+                static class D {}
             }
-            if (c.name == 'Baz') {
-                assert !Modifier.isPrivate(c.modifiers)
-                assert !Modifier.isPublic(c.modifiers)
-                assert !Modifier.isProtected(c.modifiers)
-            } else {
-                assert Modifier.isPublic(c.modifiers)
+
+            boolean isPackagePrivate(modifiers) {
+                !isPublic(modifiers) && !isPrivate(modifiers) && !isProtected(modifiers)
             }
-            def cons = c.declaredConstructors
-            if (c.name == 'Bar') {
-                assert cons.size() == 2
-                cons.each { con ->
-                    if (con.parameterTypes*.name == []) {
-                        assert Modifier.isPublic(con.modifiers)
-                    } else {
-                        assert con.parameterTypes*.name == ['java.lang.String']
-                        assert !Modifier.isPrivate(con.modifiers)
-                        assert !Modifier.isPublic(con.modifiers)
-                        assert !Modifier.isProtected(con.modifiers)
-                    }
 
+            assert isPackagePrivate(C.modifiers)
+
+            assert isPackagePrivate(C.getDeclaredConstructor().modifiers)
+
+            assert isPrivate(C.getDeclaredField('x').modifiers)
+            assert isPublic(C.getDeclaredMethod('getX').modifiers)
+            assert isPublic(C.getDeclaredMethod('setX', String).modifiers)
+
+            assert isPackagePrivate(C.getDeclaredMethod('method').modifiers)
+
+            assert isPublic(C.getDeclaredClasses()[0].modifiers) // not transitive
+        '''
+    }
+
+    @Test // GROOVY-9043
+    void testStaticFieldAccessFromInnerClassCS() {
+        assertScript '''
+            import groovy.transform.CompileStatic
+            import groovy.transform.PackageScope
+
+            @CompileStatic
+            class Test {
+                @PackageScope static final String S = 'S'
+                protected static final String T = 'T'
+                private static final String U = 'U'
+                static class Inner {
+                    String method() {
+                        S + T + U
+                    }
                 }
-            } else {
-                assert cons.size() == 1
-                assert Modifier.isPublic(cons[0].modifiers)
             }
-        }
+
+            assert new Test.Inner().method() == 'STU'
+        '''
     }
-}
\ No newline at end of file
+}
diff --git a/src/test/org/codehaus/groovy/transform/packageScope/p/One.groovy b/src/test/org/codehaus/groovy/transform/packageScope/p/One.groovy
deleted file mode 100644
index f4fc0e6..0000000
--- a/src/test/org/codehaus/groovy/transform/packageScope/p/One.groovy
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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 org.codehaus.groovy.transform.packageScope.p
-
-class One {
-    @groovy.transform.PackageScope final String value = 'val'
-    @groovy.transform.PackageScope final static Integer NUM = 42
-}