groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From emil...@apache.org
Subject [groovy] 01/01: GROOVY-9195: SC: uniform treatment for "foo.bar" and "foo.with { bar }"
Date Wed, 30 Oct 2019 03:48:00 GMT
This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY-9195
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 76baa957c9aaae245f9a2096521eeffb8e3d7cbb
Author: Eric Milles <eric.milles@thomsonreuters.com>
AuthorDate: Tue Oct 29 20:21:39 2019 -0500

    GROOVY-9195: SC: uniform treatment for "foo.bar" and "foo.with { bar }"
    
    refactor GROOVY-9288, GROOVY-9292, GROOVY-9293, et al. dynamic property
---
 .../groovy/classgen/AsmClassGenerator.java         |   16 +-
 .../transform/stc/StaticTypeCheckingVisitor.java   |   21 -
 src/test/groovy/bugs/Groovy9136.groovy             |   14 +-
 src/test/groovy/bugs/Groovy9288.groovy             |  111 ++-
 src/test/groovy/bugs/Groovy9292.groovy             |  359 +++++++
 src/test/groovy/bugs/Groovy9292Bug.groovy          | 1008 --------------------
 src/test/groovy/bugs/Groovy9293.groovy             |   11 +-
 .../stc/FieldsAndPropertiesSTCTest.groovy          |   42 +-
 .../groovy/text/MarkupTemplateEngineTest.groovy    |  700 +++++++-------
 9 files changed, 831 insertions(+), 1451 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index d7c30f4..31719f5 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -1158,9 +1158,17 @@ public class AsmClassGenerator extends ClassGenerator {
         return classNode.getSuperClass().getGetterMethod(getterMethodName);
     }
 
+    private boolean isGroovyObject(Expression objectExpression) {
+        if (isThisExpression(objectExpression)) return true;
+        if (objectExpression instanceof ClassExpression) return false;
+
+        ClassNode objectExpressionType = controller.getTypeChooser().resolveType(objectExpression, controller.getClassNode());
+        if (objectExpressionType.equals(ClassHelper.OBJECT_TYPE)) objectExpressionType = objectExpression.getType();
+        return objectExpressionType.isDerivedFromGroovyObject();
+    }
+
     private boolean isThisOrSuperInStaticContext(Expression objectExpression) {
-        if (controller.isInClosure()) return false;
-        return controller.isStaticContext() && isThisOrSuper(objectExpression);
+        return !controller.isInClosure() && controller.isStaticContext() && isThisOrSuper(objectExpression);
     }
 
     @Override
@@ -1241,10 +1249,6 @@ public class AsmClassGenerator extends ClassGenerator {
         return false;
     }
 
-    private static boolean isGroovyObject(Expression objectExpression) {
-        return isThisExpression(objectExpression) || objectExpression.getType().isDerivedFromGroovyObject() && !(objectExpression instanceof ClassExpression);
-    }
-
     public void visitFieldExpression(FieldExpression expression) {
         FieldNode field = expression.getField();
 
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 633d7fa..22bc46c 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1583,23 +1583,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 FieldNode field = current.getDeclaredField(propertyName);
                 field = allowStaticAccessToMember(field, staticOnly);
 
-                if (null != field && objectExpression instanceof VariableExpression) {
-                    int fieldModifiers = field.getModifiers();
-                    if (Modifier.isProtected(fieldModifiers) || isPackagePrivate(fieldModifiers)) {
-                        TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
-                        if (null != enclosingClosure) {
-                            switch (objectExpression.getText()) {
-                                case "it":
-                                    if (!enclosingClosure.getClosureExpression().hasItParameter()) break;
-                                case "owner":
-                                case "delegate":
-                                case "thisObject":
-                                    pexp.putNodeMetaData(DYNAMIC_RESOLUTION, Boolean.TRUE);
-                            }
-                        }
-                    }
-                }
-
                 // skip property/accessor checks for "x.@field"
                 if (field != null && pexp instanceof AttributeExpression) {
                     if (storeField(field, pexp, current, visitor, receiver.getData(), !readMode)) {
@@ -1739,10 +1722,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         return foundGetterOrSetter;
     }
 
-    private static boolean isPackagePrivate(int modifiers) {
-        return !(Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers) || Modifier.isPrivate(modifiers));
-    }
-
     private static boolean hasAccessToField(ClassNode accessor, FieldNode field) {
         if (field.isPublic() || accessor.equals(field.getDeclaringClass())) {
             return true;
diff --git a/src/test/groovy/bugs/Groovy9136.groovy b/src/test/groovy/bugs/Groovy9136.groovy
index ea31af5..eac1274 100644
--- a/src/test/groovy/bugs/Groovy9136.groovy
+++ b/src/test/groovy/bugs/Groovy9136.groovy
@@ -18,11 +18,9 @@
  */
 package groovy.bugs
 
-import groovy.test.NotYetImplemented
 import org.junit.Test
 
 import static groovy.test.GroovyAssert.assertScript
-import static groovy.test.GroovyAssert.shouldFail
 
 final class Groovy9136 {
 
@@ -47,9 +45,9 @@ final class Groovy9136 {
         '''
     }
 
-    @Test @NotYetImplemented // GROOVY-9195
+    @Test // GROOVY-9195
     void testMethodParameterFieldAccessFromClosure2() {
-        def err = shouldFail '''
+        assertScript '''
             class Foo {
                 private String field = 'foo'
             }
@@ -64,14 +62,13 @@ final class Groovy9136 {
 
             def bar = new Bar()
             def out = bar.test(new Foo())
+            assert out == 'foo'
         '''
-
-        assert err =~ /Access to Foo#field is forbidden/
     }
 
     @Test
     void testMethodParameterFieldAccessFromClosure3() {
-        def err = shouldFail '''
+        assertScript '''
             class Foo {
                 private String field = 'foo'
             }
@@ -86,8 +83,7 @@ final class Groovy9136 {
 
             def bar = new Bar()
             def out = bar.test(new Foo())
+            assert out == 'foo'
         '''
-
-        assert err =~ /Access to Foo#field is forbidden/
     }
 }
diff --git a/src/test/groovy/bugs/Groovy9288.groovy b/src/test/groovy/bugs/Groovy9288.groovy
index e898b93..c6b73dc 100644
--- a/src/test/groovy/bugs/Groovy9288.groovy
+++ b/src/test/groovy/bugs/Groovy9288.groovy
@@ -18,20 +18,33 @@
  */
 package groovy.bugs
 
-
+import groovy.transform.CompileStatic
 import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import org.junit.runners.Parameterized.Parameter
+import org.junit.runners.Parameterized.Parameters
 
+@CompileStatic @RunWith(Parameterized)
 final class Groovy9288 {
 
+    @Parameters
+    static modifiers() {
+        ['public', 'protected']
+    }
+
+    @Parameter
+    public String modifier
+
     private final GroovyShell shell = new GroovyShell()
 
     @Test
-    void 'test accessing a protected super class field inside a closure - same package'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - same package'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             class B extends A {
@@ -45,20 +58,20 @@ final class Groovy9288 {
 
             def obj = new B()
             assert obj.test() == "works"
-        '''
+        """
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - diff package'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - diff package'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             assert true
-        '''
+        """
 
         shell.evaluate '''
             package b
@@ -78,12 +91,12 @@ final class Groovy9288 {
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - same package, it qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - same package, it qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             class B extends A {
@@ -97,20 +110,20 @@ final class Groovy9288 {
 
             def obj = new B()
             assert obj.test() == "works"
-        '''
+        """
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - diff package, it qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - diff package, it qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             assert true
-        '''
+        """
 
         shell.evaluate '''
             package b
@@ -130,12 +143,12 @@ final class Groovy9288 {
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - same package, this qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - same package, this qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             class B extends A {
@@ -149,20 +162,20 @@ final class Groovy9288 {
 
             def obj = new B()
             assert obj.test() == "works"
-        '''
+        """
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - diff package, this qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - diff package, this qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             assert true
-        '''
+        """
 
         shell.evaluate '''
             package b
@@ -182,12 +195,12 @@ final class Groovy9288 {
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - same package, owner qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - same package, owner qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             class B extends A {
@@ -201,20 +214,20 @@ final class Groovy9288 {
 
             def obj = new B()
             assert obj.test() == "works"
-        '''
+        """
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - diff package, owner qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - diff package, owner qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             assert true
-        '''
+        """
 
         shell.evaluate '''
             package b
@@ -234,12 +247,12 @@ final class Groovy9288 {
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - same package, delegate qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - same package, delegate qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             class B extends A {
@@ -253,20 +266,20 @@ final class Groovy9288 {
 
             def obj = new B()
             assert obj.test() == "works"
-        '''
+        """
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - diff package, delegate qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - diff package, delegate qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             assert true
-        '''
+        """
 
         shell.evaluate '''
             package b
@@ -286,12 +299,12 @@ final class Groovy9288 {
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - same package, thisObject qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - same package, thisObject qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             class B extends A {
@@ -305,20 +318,20 @@ final class Groovy9288 {
 
             def obj = new B()
             assert obj.test() == "works"
-        '''
+        """
     }
 
     @Test
-    void 'test accessing a protected super class field inside a closure - diff package, thisObject qualifier'() {
-        shell.evaluate '''
+    void 'test accessing a super class field inside a closure - diff package, thisObject qualifier'() {
+        shell.evaluate """
             package a
 
             class A {
-                protected String superField = 'works'
+                $modifier String superField = 'works'
             }
 
             assert true
-        '''
+        """
 
         shell.evaluate '''
             package b
diff --git a/src/test/groovy/bugs/Groovy9292.groovy b/src/test/groovy/bugs/Groovy9292.groovy
new file mode 100644
index 0000000..b2a0a93
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9292.groovy
@@ -0,0 +1,359 @@
+/*
+ *  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 groovy.bugs
+
+import groovy.test.NotYetImplemented
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.shouldFail
+
+final class Groovy9292 {
+
+    private final GroovyShell shell = new GroovyShell()
+
+    @Test @NotYetImplemented
+    void 'test accessing a private super class field inside a closure - same package'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                class B extends A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        'something'.with {
+                            return superField // ClassCastException: a.B$_test_closure1 cannot be cast to a.A
+                        }
+                    }
+                }
+
+                def obj = new B()
+                assert obj.test() == "works"
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - diff package'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                assert true
+            '''
+
+            shell.evaluate '''
+                package b
+
+                class B extends a.A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        'something'.with {
+                            return superField
+                        }
+                    }
+                }
+
+                new B().test()
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - same package, it qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                class B extends A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        with {
+                            return it.superField
+                        }
+                    }
+                }
+
+                def obj = new B()
+                assert obj.test() == "works"
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - diff package, it qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                assert true
+            '''
+
+            shell.evaluate '''
+                package b
+
+                class B extends a.A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        with {
+                            return it.superField
+                        }
+                    }
+                }
+
+                new B().test()
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - same package, this qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                class B extends A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        'something'.with {
+                            return this.superField
+                        }
+                    }
+                }
+
+                def obj = new B()
+                assert obj.test() == "works"
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - diff package, this qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                assert true
+            '''
+
+            shell.evaluate '''
+                package b
+
+                class B extends a.A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        'something'.with {
+                            return this.superField
+                        }
+                    }
+                }
+
+                new B().test()
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - same package, owner qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                class B extends A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        'something'.with {
+                            return owner.superField
+                        }
+                    }
+                }
+
+                def obj = new B()
+                assert obj.test() == "works"
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - diff package, owner qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                assert true
+            '''
+
+            shell.evaluate '''
+                package b
+
+                class B extends a.A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        'something'.with {
+                            return owner.superField
+                        }
+                    }
+                }
+
+                new B().test()
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - same package, delegate qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                class B extends A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        with {
+                            return delegate.superField
+                        }
+                    }
+                }
+
+                def obj = new B()
+                assert obj.test() == "works"
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - diff package, delegate qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                assert true
+            '''
+
+            shell.evaluate '''
+                package b
+
+                class B extends a.A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        with {
+                            return delegate.superField
+                        }
+                    }
+                }
+
+                new B().test()
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - same package, thisObject qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                class B extends A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        'something'.with {
+                            return thisObject.superField
+                        }
+                    }
+                }
+
+                def obj = new B()
+                assert obj.test() == "works"
+            '''
+        }
+    }
+
+    @Test
+    void 'test accessing a private super class field inside a closure - diff package, thisObject qualifier'() {
+        shouldFail(MissingPropertyException) {
+            shell.evaluate '''
+                package a
+
+                class A {
+                    private String superField = 'works'
+                }
+
+                assert true
+            '''
+
+            shell.evaluate '''
+                package b
+
+                class B extends a.A {
+                    @groovy.transform.CompileStatic
+                    def test() {
+                        'something'.with {
+                            return thisObject.superField
+                        }
+                    }
+                }
+
+                new B().test()
+            '''
+        }
+    }
+}
diff --git a/src/test/groovy/bugs/Groovy9292Bug.groovy b/src/test/groovy/bugs/Groovy9292Bug.groovy
deleted file mode 100644
index 6b11a4c..0000000
--- a/src/test/groovy/bugs/Groovy9292Bug.groovy
+++ /dev/null
@@ -1,1008 +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 groovy.bugs
-
-import groovy.test.NotYetImplemented
-import org.junit.Test
-
-final class Groovy9292Bug {
-
-    @Test
-    void "test accessing a protected super class field from inside a closure - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                protected String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    'something'.with {
-                        return superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a protected super class field from inside a closure - same package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                protected String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package a
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    'something'.with {
-                        return superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
-    }
-
-
-    @Test
-    void "test accessing a protected super class field from inside a closure - using it - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                protected String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return it.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a protected super class field from inside a closure - using this - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                protected String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    'something'.with {
-                        return this.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-
-    @Test
-    void "test accessing a protected super class field from inside a closure - using thisObject - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                protected String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    'something'.with {
-                        return thisObject.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a protected super class field from inside a closure - using owner - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                protected String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    'something'.with {
-                        return owner.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a protected super class field from inside a closure - using delegate - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                protected String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return delegate.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a package-private super class field from inside a closure - same package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                @groovy.transform.PackageScope String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package a
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return delegate.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a package-private super class field from inside a closure - using delegate - same package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                @groovy.transform.PackageScope String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package a
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return delegate.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a package-private super class field from inside a closure - using it - same package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                @groovy.transform.PackageScope String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package a
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return it.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
-    }
-
-    @NotYetImplemented // java.lang.IllegalAccessError: class a.ConcreteClass$_doThing_closure1 tried to access field a.Abstract_Class.superField (a.ConcreteClass$_doThing_closure1 is in unnamed module of loader groovy.lang.GroovyClassLoader$InnerLoader @5fa47fea; a.Abstract_Class is in unnamed module of loader groovy.lang.GroovyClassLoader$InnerLoader @28cda624)
-    @Test
-    void "test accessing a package-private super class field from inside a closure - using this - same package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                @groovy.transform.PackageScope String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package a
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return this.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a package-private super class field from inside a closure - using thisObject - same package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                @groovy.transform.PackageScope String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package a
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return thisObject.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a package-private super class field from inside a closure - using owner - same package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                @groovy.transform.PackageScope String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package a
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return owner.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new a.ConcreteClass().doThing() == 'field'")
-    }
-
-
-    @Test
-    void "test accessing a public super class field from inside a closure - different package -- regression"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                public String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a public super class field from inside a closure - using delegate - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                public String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return delegate.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-
-    @Test
-    void "test accessing a public super class field from inside a closure - using it - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                public String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return it.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a public super class field from inside a closure - using this - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                public String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return this.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a public super class field from inside a closure - using thisObject - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                public String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return thisObject.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a public super class field from inside a closure - using owner - different package"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                public String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return owner.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-
-    @Test
-    void "test accessing a private super class field from inside a closure via getter - different package -- regression"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-
-    @Test
-    void "test accessing a private super class field from inside a closure via getter - using delegate - different package -- regression"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return delegate.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a private super class field from inside a closure via getter - using it - different package -- regression"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return it.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-
-    @Test
-    void "test accessing a private super class field from inside a closure via getter - using this - different package -- regression"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return this.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a private super class field from inside a closure via getter - using thisObject - different package -- regression"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return thisObject.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-
-    @Test
-    void "test accessing a private super class field from inside a closure via getter - using owner - different package -- regression"() {
-        GroovyShell shell = new GroovyShell()
-        shell.evaluate('''
-            package a
-            
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            abstract class Abstract_Class {
-                String superField = 'field'
-                
-                abstract String doThing()
-            }
-            assert true
-        ''')
-
-        shell.evaluate('''
-            package b
-            
-            import a.Abstract_Class
-            import groovy.transform.CompileStatic
-            
-            @CompileStatic
-            class ConcreteClass extends Abstract_Class {
-               
-                @Override
-                String doThing() {
-                    this.with {
-                        return owner.superField
-                    }
-                }
-            }
-            assert true
-        ''')
-
-        shell.evaluate("assert new b.ConcreteClass().doThing() == 'field'")
-    }
-}
diff --git a/src/test/groovy/bugs/Groovy9293.groovy b/src/test/groovy/bugs/Groovy9293.groovy
index 282bf50..2d98906 100644
--- a/src/test/groovy/bugs/Groovy9293.groovy
+++ b/src/test/groovy/bugs/Groovy9293.groovy
@@ -18,11 +18,12 @@
  */
 package groovy.bugs
 
-
+import groovy.transform.CompileStatic
 import org.junit.Test
 
 import static groovy.test.GroovyAssert.shouldFail
 
+@CompileStatic
 final class Groovy9293 {
 
     private final GroovyShell shell = new GroovyShell()
@@ -106,7 +107,7 @@ final class Groovy9293 {
         '''
     }
 
-    @Test
+    @Test // GROOVY-9293
     void 'test accessing a package-private super class field inside a closure - diff package, it qualifier'() {
         shouldFail(MissingPropertyException) {
             shell.evaluate '''
@@ -216,7 +217,7 @@ final class Groovy9293 {
         '''
     }
 
-    @Test
+    @Test // GROOVY-9293
     void 'test accessing a package-private super class field inside a closure - diff package, owner qualifier'() {
         shouldFail(MissingPropertyException) {
             shell.evaluate '''
@@ -271,7 +272,7 @@ final class Groovy9293 {
         '''
     }
 
-    @Test
+    @Test // GROOVY-9293
     void 'test accessing a package-private super class field inside a closure - diff package, delegate qualifier'() {
         shouldFail(MissingPropertyException) {
             shell.evaluate '''
@@ -326,7 +327,7 @@ final class Groovy9293 {
         '''
     }
 
-    @Test
+    @Test // GROOVY-9293
     void 'test accessing a package-private super class field inside a closure - diff package, thisObject qualifier'() {
         shouldFail(MissingPropertyException) {
             shell.evaluate '''
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index 2cf90b3..a873576 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -542,29 +542,30 @@ new FooWorker().doSomething()'''
     }
 
     void testShouldFailWithIncompatibleGenericTypes() {
-        shouldFailWithMessages '''public class Foo {
+        shouldFailWithMessages '''\
+            public class Foo {
+                private List<String> names;
 
-    private List<String> names;
-
-    public List<String> getNames() {
-        return names;
-    }
-
-    public void setNames(List<String> names) {
-        this.names = names;
-    }
-}
+                public List<String> getNames() {
+                    return names;
+                }
 
-class FooWorker {
+                public void setNames(List<String> names) {
+                    this.names = names;
+                }
+            }
 
-    public void doSomething() {
-        new Foo().with {
-            names = new ArrayList<Integer>()
-        }
-    }
-}
+            class FooWorker {
+                public void doSomething() {
+                    new Foo().with {
+                        names = new ArrayList<Integer>()
+                    }
+                }
+            }
 
-new FooWorker().doSomething()''', 'Cannot assign value of type java.util.ArrayList <Integer> to variable of type java.util.List <String>'
+            new FooWorker().doSomething()
+        ''',
+        'Cannot assign value of type java.util.ArrayList <Integer> to variable of type java.util.List <String>'
     }
 
     void testAICAsStaticProperty() {
@@ -730,7 +731,7 @@ import org.codehaus.groovy.ast.stmt.AssertStatement
     void testImplicitPropertyOfDelegateShouldNotPreferField() {
         assertScript '''
             Calendar.instance.with {
-                Date d1 = time
+                Date d1 = time // Date getTime() vs. long time
             }
         '''
     }
@@ -820,4 +821,3 @@ import org.codehaus.groovy.ast.stmt.AssertStatement
     static class BaseClass2 extends BaseClass {
     }
 }
-
diff --git a/subprojects/groovy-templates/src/test/groovy/groovy/text/MarkupTemplateEngineTest.groovy b/subprojects/groovy-templates/src/test/groovy/groovy/text/MarkupTemplateEngineTest.groovy
index 3596319..31ccf10 100644
--- a/subprojects/groovy-templates/src/test/groovy/groovy/text/MarkupTemplateEngineTest.groovy
+++ b/subprojects/groovy-templates/src/test/groovy/groovy/text/MarkupTemplateEngineTest.groovy
@@ -18,441 +18,454 @@
  */
 package groovy.text
 
-import groovy.test.GroovyTestCase
+import groovy.test.NotYetImplemented
 import groovy.text.markup.BaseTemplate
 import groovy.text.markup.MarkupTemplateEngine
 import groovy.text.markup.TagLibAdapter
 import groovy.text.markup.TemplateConfiguration
-import groovy.test.NotYetImplemented
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.shouldFail
+
+final class MarkupTemplateEngineTest {
 
-class MarkupTemplateEngineTest extends GroovyTestCase {
     private Locale locale
 
-    @Override
+    @Before
     void setUp() {
         locale = Locale.default
-        super.setUp();
         Locale.default = Locale.US
     }
 
-    @Override
+    @After
     void tearDown() {
-        super.tearDown();
         Locale.default = locale
     }
 
+    @Test
     void testSimpleTemplate() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-html {
-    body {
-        yield 'It works!'
-    }
-}
-'''
+            html {
+                body {
+                    yield 'It works!'
+                }
+            }
+            '''
         String rendered = template.make()
         assert rendered == '<html><body>It works!</body></html>'
     }
 
+    @Test
     void testSimpleTemplateWithModel() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-html {
-    body {
-        yield message
-    }
-}
-'''
+            html {
+                body {
+                    yield message
+                }
+            }
+            '''
         def model = [message: 'It works!']
         StringWriter rendered = new StringWriter()
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><body>It works!</body></html>'
     }
 
+    @Test
     void testSimpleTemplateWithIncludeTemplate() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-html {
-    body {
-        include template:'includes/hello.tpl'
-    }
-}
-'''
+            html {
+                body {
+                    include template:'includes/hello.tpl'
+                }
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html><body>Hello from include!</body></html>'
     }
 
+    @Test
     void testSimpleTemplateWithIncludeTemplateWithLocale() {
         def tplConfig = new TemplateConfiguration()
         tplConfig.locale = Locale.FRANCE
         MarkupTemplateEngine engine = new MarkupTemplateEngine(this.class.classLoader, tplConfig)
         def template = engine.createTemplate '''
-html {
-    body {
-        include template:'includes/hello.tpl'
-    }
-}
-'''
+            html {
+                body {
+                    include template:'includes/hello.tpl'
+                }
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html><body>Bonjour!</body></html>'
     }
 
+    @Test
     void testSimpleTemplateWithIncludeTemplateWithLocalePriority() {
         def tplConfig = new TemplateConfiguration()
         tplConfig.locale = Locale.FRANCE // set default locale
         MarkupTemplateEngine engine = new MarkupTemplateEngine(this.class.classLoader, tplConfig)
         def template = engine.createTemplate '''
-html {
-    body {
-        include template:'includes/hello_en_US.tpl' // if not found, will fall back to the default locale
-    }
-}
-'''
+            html {
+                body {
+                    include template:'includes/hello_en_US.tpl' // if not found, will fall back to the default locale
+                }
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html><body>Bonjour!</body></html>'
     }
 
+    @Test
     void testSimpleTemplateWithIncludeRaw() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-html {
-    body {
-        include unescaped:'includes/hello.html'
-    }
-}
-'''
+            html {
+                body {
+                    include unescaped:'includes/hello.html'
+                }
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html><body>Hello unescaped!</body></html>'
     }
 
+    @Test
     void testSimpleTemplateWithIncludeEscaped() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-html {
-    body {
-        include escaped:'includes/hello-escaped.txt'
-    }
-}
-'''
+            html {
+                body {
+                    include escaped:'includes/hello-escaped.txt'
+                }
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html><body>Hello &lt;escaped&gt;!</body></html>'
     }
 
-    void testCollectionInModel() {
-        MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
-        def template = engine.createTemplate '''
-html {
-    body {
-        ul {
-            persons.each { p ->
-                li(p.name)
-            }
-        }
-    }
-}
-'''
-        StringWriter rendered = new StringWriter()
-        def model = [persons: [[name: 'Cedric'], [name: 'Jochen']]]
-        template.make(model).writeTo(rendered)
-        assert rendered.toString() == '<html><body><ul><li>Cedric</li><li>Jochen</li></ul></body></html>'
-
-    }
-
+    @Test
     void testHTMLHeader() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-yieldUnescaped '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
-html {
-    body('Hello, XHTML!')
-}
-'''
+            yieldUnescaped '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
+            html {
+                body('Hello, XHTML!')
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><body>Hello, XHTML!</body></html>'
     }
 
+    @Test
     void testTemplateWithHelperMethod() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-def foo = {
-    body('Hello from foo!')
-}
+            def foo = {
+                body('Hello from foo!')
+            }
 
-html {
-    foo()
-}
-'''
+            html {
+                foo()
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html><body>Hello from foo!</body></html>'
     }
 
+    @Test
     void testCallPi() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-pi("xml-stylesheet":[href:"mystyle.css", type:"text/css"])
-html {
-    body('Hello, PI!')
-}
-'''
+            pi("xml-stylesheet":[href:"mystyle.css", type:"text/css"])
+            html {
+                body('Hello, PI!')
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString().normalize() == '<?xml-stylesheet href=\'mystyle.css\' type=\'text/css\'?>\n<html><body>Hello, PI!</body></html>'
     }
 
+    @Test
     void testXmlDeclaration() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-xmlDeclaration()
-html {
-    body('Hello, PI!')
-}
-'''
+            xmlDeclaration()
+            html {
+                body('Hello, PI!')
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString().normalize() == '<?xml version=\'1.0\'?>\n<html><body>Hello, PI!</body></html>'
     }
 
+    @Test
     void testXmlDeclarationWithEncoding() {
         def configuration = new TemplateConfiguration()
         configuration.declarationEncoding = 'UTF-8'
         MarkupTemplateEngine engine = new MarkupTemplateEngine(configuration)
         def template = engine.createTemplate '''
-xmlDeclaration()
-html {
-    body('Hello, PI!')
-}
-'''
+            xmlDeclaration()
+            html {
+                body('Hello, PI!')
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString().normalize() == '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<html><body>Hello, PI!</body></html>'
     }
 
+    @Test
     void testNewLine() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         engine.templateConfiguration.newLineString = '||'
         def template = engine.createTemplate '''
-html {
-    newLine()
-    body('Hello, PI!')
-}
-'''
+            html {
+                newLine()
+                body('Hello, PI!')
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html>||<body>Hello, PI!</body></html>'
     }
 
+    @Test
     void testXMLWithYieldTag() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-':yield'()
-'''
+            ':yield'()
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<yield/>'
     }
 
+    @Test
     void testTagsWithAttributes() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-html {
-    a(href:'foo.html', 'Link text')
-    tagWithQuote(attr:"fo'o")
-}
-'''
+            html {
+                a(href:'foo.html', 'Link text')
+                tagWithQuote(attr:"fo'o")
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html><a href=\'foo.html\'>Link text</a><tagWithQuote attr=\'fo&apos;o\'/></html>'
     }
 
+    @Test
     void testTagsWithAttributesAndDoubleQuotes() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         engine.templateConfiguration.useDoubleQuotes = true
         def template = engine.createTemplate '''
-html {
-    a(href:'foo.html', 'Link text')
-    tagWithQuote(attr:"fo'o")
-}
-'''
+            html {
+                a(href:'foo.html', 'Link text')
+                tagWithQuote(attr:"fo'o")
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html><a href="foo.html">Link text</a><tagWithQuote attr="fo\'o"/></html>'
     }
 
+    @Test
     void testLoopInTemplate() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def model = [text: 'Hello', persons: ['Bob', 'Alice']]
         def template = engine.createTemplate '''
-html {
-    body {
-        ul {
-            persons.each {
-                li("$text $it")
+            html {
+                body {
+                    ul {
+                        persons.each {
+                            li("$text $it")
+                        }
+                    }
+                }
             }
-        }
-    }
-}
-'''
+            '''
         StringWriter rendered = new StringWriter()
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><body><ul><li>Hello Bob</li><li>Hello Alice</li></ul></body></html>'
     }
 
+    @Test
     void testHelperFunctionInBinding() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def model = [text: { it.toUpperCase() }]
         def template = engine.createTemplate '''
-html {
-    body {
-        text('hello')
-    }
-}
-'''
+            html {
+                body {
+                    text('hello')
+                }
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><body>HELLO</body></html>'
     }
 
+    @Test
     void testShouldNotEscapeUserInputAutomatically() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def model = [text: '<xml>']
         def template = engine.createTemplate '''
-html {
-    body(text)
-}
-'''
+            html {
+                body(text)
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><body><xml></body></html>'
     }
 
+    @Test
     void testShouldEscapeUserInputAutomatically() {
         TemplateConfiguration config = new TemplateConfiguration()
         config.autoEscape = true
         MarkupTemplateEngine engine = new MarkupTemplateEngine(this.class.classLoader, config)
         def model = [text: '<xml>']
         def template = engine.createTemplate '''
-html {
-    body(text)
-}
-'''
+            html {
+                body(text)
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><body>&lt;xml&gt;</body></html>'
     }
 
+    @Test
     void testShouldNotEscapeUserInputAutomaticallyEvenIfFlagSet() {
         TemplateConfiguration config = new TemplateConfiguration()
         config.autoEscape = true
         MarkupTemplateEngine engine = new MarkupTemplateEngine(this.class.classLoader, config)
         def model = [text: '<xml>']
         def template = engine.createTemplate '''
-html {
-    body(unescaped.text)
-}
-'''
+            html {
+                body(unescaped.text)
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><body><xml></body></html>'
     }
 
-
+    @Test
     void testTypeCheckedModel() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTypeCheckedModelTemplate '''
-html {
-    body(text.toUpperCase())
-}
-''', [text: 'String']
+            html {
+                body(text.toUpperCase())
+            }
+            ''', [text: 'String']
         def model = [text: 'Type checked!']
         StringWriter rendered = new StringWriter()
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><body>TYPE CHECKED!</body></html>'
-
     }
 
+    @Test
     void testTypeCheckedModelShouldFail() {
-        assert shouldFail {
+        def err = shouldFail {
             MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
             def template = engine.createTypeCheckedModelTemplate '''
-    html {
-        body(text.toUpperCase())
-    }
-    ''', [text: 'Integer']
+                html {
+                    body(text.toUpperCase())
+                }
+                ''', [text: 'Integer']
             def model = [text: 'Type checked!']
             StringWriter rendered = new StringWriter()
             template.make(model).writeTo(rendered)
             assert rendered.toString() == '<html><body>TYPE CHECKED!</body></html>'
-        } =~ 'Cannot find matching method java.lang.Integer#toUpperCase()'
+        }
 
+        assert err =~ /Cannot find matching method java.lang.Integer#toUpperCase\(\)/
     }
 
+    @Test
     void testTypeCheckedModelShouldFailWithoutModelDescription() {
-        assert shouldFail {
+        def err = shouldFail {
             MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
             def template = engine.createTypeCheckedModelTemplate '''
-    html {
-        body(p.name.toUpperCase())
-    }
-    ''', [:]
+                html {
+                    body(p.name.toUpperCase())
+                }
+                ''', [:]
             def model = [p: new Person(name: 'C├ędric')]
             StringWriter rendered = new StringWriter()
             template.make(model).writeTo(rendered)
-        } =~ 'No such property: name'
+        }
 
+        assert err =~ /No such property: name/
     }
 
+    @Test
     void testTypeCheckedModelShouldSucceedWithModelDescription() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTypeCheckedModelTemplate '''
-    html {
-        body(p.name.toUpperCase())
-    }
-    ''', [p: 'groovy.text.MarkupTemplateEngineTest.Person']
+            html {
+                body(p.name.toUpperCase())
+            }
+            ''', [p: 'groovy.text.MarkupTemplateEngineTest.Person']
         def model = [p: new Person(name: 'Cedric')]
         StringWriter rendered = new StringWriter()
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><body>CEDRIC</body></html>'
     }
 
+    @Test
     void testTypeCheckedModelShouldSucceedWithModelDescriptionUsingGenerics() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTypeCheckedModelTemplate '''
-    html {
-        ul {
-            persons.each { p ->
-                li(p.name.toUpperCase())
+            html {
+                ul {
+                    persons.each { p ->
+                        li(p.name.toUpperCase())
+                    }
+                }
             }
-        }
-    }
-    ''', [persons: 'List<groovy.text.MarkupTemplateEngineTest.Person>']
+            ''', [persons: 'List<groovy.text.MarkupTemplateEngineTest.Person>']
         def model = [persons: [new Person(name: 'Cedric')]]
         StringWriter rendered = new StringWriter()
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><ul><li>CEDRIC</li></ul></html>'
     }
 
+    @Test
     void testTypeCheckedTemplateShouldFailInInclude() {
-        assert shouldFail {
+        def err = shouldFail {
             MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
             def template = engine.createTypeCheckedModelTemplate '''
-    html {
-        body {
-            include template:'includes/typecheckedinclude.tpl'
-        }
-    }
-    ''', [text: 'Integer']
+                html {
+                    body {
+                        include template:'includes/typecheckedinclude.tpl'
+                    }
+                }
+                ''', [text: 'Integer']
             def model = [text: 'Type checked!']
             StringWriter rendered = new StringWriter()
             template.make(model).writeTo(rendered)
-        } =~ 'Cannot find matching method java.lang.Integer#toUpperCase()'
+        }
+
+        assert err =~ /Cannot find matching method java.lang.Integer#toUpperCase\(\)/
     }
 
+    @Test
     void testSimpleAutoIndent() {
         TemplateConfiguration config = new TemplateConfiguration()
         config.autoIndent = true
@@ -471,14 +484,16 @@ html {
 '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
-        assert rendered.toString() == '''<html>
+        assert rendered.toString() == '''\
+<html>
     <body>
         <p>Test</p>
     </body>
 </html>'''
     }
 
-   void testSimpleAutoIndentShouldAddNewLineInLoop() {
+    @Test
+    void testSimpleAutoIndentShouldAddNewLineInLoop() {
         TemplateConfiguration config = new TemplateConfiguration()
         config.autoIndent = true
         config.newLineString = '\n'
@@ -504,7 +519,8 @@ html {
         StringWriter rendered = new StringWriter()
         def model = [persons:['Cedric','Jochen']]
         template.make(model).writeTo(rendered)
-        assert rendered.toString() == '''<html>
+        assert rendered.toString() == '''\
+<html>
     <body>
         <ul>
             <li>Cedric</li>
@@ -514,6 +530,7 @@ html {
 </html>'''
     }
 
+    @Test
     void testSimpleAutoIndentShouldAutoAddNewLineInLoop() {
         TemplateConfiguration config = new TemplateConfiguration()
         config.autoIndent = true
@@ -535,17 +552,19 @@ html {
         StringWriter rendered = new StringWriter()
         def model = [persons:['Cedric','Jochen']]
         template.make(model).writeTo(rendered)
-        assert rendered.toString() == '''<html>
+        assert rendered.toString() == '''\
+<html>
     <body>
         <ul>
             <li>Cedric</li>
             <li>Jochen</li>
-            
+            |
         </ul>
     </body>
-</html>'''
+</html>'''.replace('|', '')
     }
 
+    @Test
     void testSimpleAutoIndentWithAutoNewLine() {
         TemplateConfiguration config = new TemplateConfiguration()
         config.autoIndent = true
@@ -561,13 +580,15 @@ html {
 '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
-        assert rendered.toString() == '''<html>
+        assert rendered.toString() == '''\
+<html>
     <body>
         <p>Test</p>
     </body>
 </html>'''
     }
 
+    @Test
     void testCustomTemplateClass() {
         TemplateConfiguration config = new TemplateConfiguration()
         config.baseTemplateClass = CustomBaseTemplate
@@ -578,15 +599,15 @@ html {
         tpl.version = 'Template v1'
         tpl.writeTo(rendered)
         assert rendered.toString() == "<p>Template v1</p>"
-
     }
 
+    @Test
     void testShouldNotThrowTypeCheckingError() {
         TemplateConfiguration config = new TemplateConfiguration()
         MarkupTemplateEngine engine = new MarkupTemplateEngine(this.class.classLoader, config)
         def template = engine.createTemplate '''int x = name.length()
-yield "$name: $x"
-'''
+            yield "$name: $x"
+            '''
         StringWriter rendered = new StringWriter()
         def model = [name: 'Michel']
         def tpl = template.make(model)
@@ -594,11 +615,11 @@ yield "$name: $x"
         assert rendered.toString() == "Michel: 6"
     }
 
+    @Test
     void testComment() {
         TemplateConfiguration config = new TemplateConfiguration()
         MarkupTemplateEngine engine = new MarkupTemplateEngine(this.class.classLoader, config)
-        def template = engine.createTemplate '''comment " This is a $comment "
-'''
+        def template = engine.createTemplate '''comment " This is a $comment "'''
         StringWriter rendered = new StringWriter()
         def model = [comment: 'comment']
         def tpl = template.make(model)
@@ -606,11 +627,11 @@ yield "$name: $x"
         assert rendered.toString() == "<!-- This is a comment -->"
     }
 
+    @Test
     void testYieldUnescaped() {
         TemplateConfiguration config = new TemplateConfiguration()
         MarkupTemplateEngine engine = new MarkupTemplateEngine(this.class.classLoader, config)
-        def template = engine.createTemplate '''yieldUnescaped html
-'''
+        def template = engine.createTemplate '''yieldUnescaped html'''
         StringWriter rendered = new StringWriter()
         def model = [html: '<html></html>']
         def tpl = template.make(model)
@@ -618,11 +639,11 @@ yield "$name: $x"
         assert rendered.toString() == "<html></html>"
     }
 
+    @Test
     void testGrailsTagLibCompatibility() {
         TemplateConfiguration config = new TemplateConfiguration()
         MarkupTemplateEngine engine = new MarkupTemplateEngine(this.class.classLoader, config)
-        def template = engine.createTemplate '''g.emoticon(happy:'true') { 'Hi John' }
-'''
+        def template = engine.createTemplate '''g.emoticon(happy:'true') { 'Hi John' }'''
         StringWriter rendered = new StringWriter()
         def model = [:]
         def tpl = template.make(model)
@@ -632,6 +653,7 @@ yield "$name: $x"
         assert rendered.toString() == "Hi John :-)"
     }
 
+    @Test
     void testLoadTemplateFromDirectory() {
         def tplDir = File.createTempDir("templates", "")
         try {
@@ -642,12 +664,12 @@ yield "$name: $x"
             assert templateFile.text
             MarkupTemplateEngine engine = new MarkupTemplateEngine(loader, tplDir, new TemplateConfiguration())
             def template = engine.createTemplate '''
-html {
-    body {
-        include template:'hello-from-dir.tpl'
-    }
-}
-'''
+                html {
+                    body {
+                        include template:'hello-from-dir.tpl'
+                    }
+                }
+                '''
             StringWriter rendered = new StringWriter()
             template.make().writeTo(rendered)
             assert rendered.toString() == '<html><body>Hello from include!</body></html>'
@@ -656,6 +678,7 @@ html {
         }
     }
 
+    @Test
     void testLoadTemplateByName() {
         TemplateConfiguration config = new TemplateConfiguration()
         MarkupTemplateEngine engine = new MarkupTemplateEngine(this.class.classLoader, config)
@@ -667,6 +690,7 @@ html {
         assert rendered.toString() == "Hello from include!"
     }
 
+    @Test
     void testLoadTemplateByNameWithLocale() {
         TemplateConfiguration config = new TemplateConfiguration()
         config.locale = Locale.FRANCE
@@ -679,38 +703,37 @@ html {
         assert rendered.toString() == "Bonjour!"
     }
 
+    @Test
     void testTypeCheckedModelShouldNotConflictWithAutoEscape() {
-
         def model = [title: "This is my glorious title ${1 + 1}".toString()]
-
         def template = new MarkupTemplateEngine(
                 getClass().getClassLoader(),
                 new TemplateConfiguration(autoNewLine: true, autoEscape: true, newLineString: 'NL')).createTypeCheckedModelTemplate('''
-body {
-  div(class: 'text')  {
-    yield title.toUpperCase()
-  }
-}
-
-''', [title: 'String'])
+                    body {
+                      div(class: 'text')  {
+                        yield title.toUpperCase()
+                      }
+                    }
 
+                    ''', [title: 'String'])
         def stringWriter = new StringWriter()
         template.make(model).writeTo(stringWriter)
         assert stringWriter.toString() == '<body>NL<div class=\'text\'>NLTHIS IS MY GLORIOUS TITLE 2NL</div>NL</body>'
     }
 
+    @Test
     void testCopyConstructorForTemplateConfiguration() {
         TemplateConfiguration cfg = new TemplateConfiguration(
-                declarationEncoding : 'iso-8859-1',
-                expandEmptyElements : true,
-                useDoubleQuotes     : false,
-                newLineString       : 'NL',
-                autoEscape          : true,
-                autoIndent          : true,
-                autoIndentString    : true,
-                autoNewLine         : true,
-                baseTemplateClass   : BaseTemplate,
-                locale              : Locale.CHINA
+            declarationEncoding : 'iso-8859-1',
+            expandEmptyElements : true,
+            useDoubleQuotes     : false,
+            newLineString       : 'NL',
+            autoEscape          : true,
+            autoIndent          : true,
+            autoIndentString    : true,
+            autoNewLine         : true,
+            baseTemplateClass   : BaseTemplate,
+            locale              : Locale.CHINA
         )
         def copy = new TemplateConfiguration(cfg)
         cfg.properties.each {
@@ -719,133 +742,156 @@ body {
         }
     }
 
+    @Test
+    void testCollectionInModel() {
+        MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
+        def template = engine.createTemplate '''
+            html {
+                body {
+                    ul {
+                        persons.each { p ->
+                            li(p.name)
+                        }
+                    }
+                }
+            }
+            '''
+        StringWriter rendered = new StringWriter()
+        def model = [persons: [[name: 'Cedric'], [name: 'Jochen']]]
+        template.make(model).writeTo(rendered)
+        assert rendered.toString() == '<html><body><ul><li>Cedric</li><li>Jochen</li></ul></body></html>'
+    }
+
+    @Test @NotYetImplemented // ClassCastException: java.util.LinkedHashMap cannot be cast to groovy.lang.GroovyObject
     void testInlinedModelTypeDeclaration() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-modelTypes = {
-    List<groovy.text.MarkupTemplateEngineTest.Person> persons
-}
+            modelTypes = {
+                List<groovy.text.MarkupTemplateEngineTest.Person> persons
+            }
 
-html {
-    body {
-        ul {
-            persons.each { p ->
-                li(p.name)
+            html {
+                body {
+                    ul {
+                        persons.each { p ->
+                            li(p.name)
+                        }
+                    }
+                }
             }
-        }
-    }
-}
-'''
+            '''
         StringWriter rendered = new StringWriter()
         def model = [persons: [[name: 'Cedric'], [name: 'Jochen']]]
         template.make(model).writeTo(rendered)
         assert rendered.toString() == '<html><body><ul><li>Cedric</li><li>Jochen</li></ul></body></html>'
-
     }
 
+    @Test
     void testInlinedModelTypeDeclarationShouldFailBecauseIncorrectType() {
-        assert shouldFail {
+        def err = shouldFail {
             MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
             def template = engine.createTemplate '''
-modelTypes = {
-    List<String> persons
-}
+                modelTypes = {
+                    List<String> persons
+                }
 
-html {
-    body {
-        ul {
-            persons.each { p ->
-                li(p.name)
-            }
-        }
-    }
-}
-'''
+                html {
+                    body {
+                        ul {
+                            persons.each { p ->
+                                li(p.name)
+                            }
+                        }
+                    }
+                }
+                '''
             StringWriter rendered = new StringWriter()
             def model = [persons: [[name: 'Cedric'], [name: 'Jochen']]]
             template.make(model).writeTo(rendered)
             assert rendered.toString() == '<html><body><ul><li>Cedric</li><li>Jochen</li></ul></body></html>'
-        } =~ 'No such property: name for class: java.lang.String'
+        }
 
+        assert err =~ /No such property: name for class: java.lang.String/
     }
 
+    @Test
     void testFragment() {
         def config = new TemplateConfiguration()
         MarkupTemplateEngine engine = new MarkupTemplateEngine(config)
         def template = engine.createTemplate '''
-html {
-    body {
-        [Index: 'index.html',
-        Page1: 'page.html',
-        Page2: 'page2.html'].each { k,v ->
-            fragment(page:v,title:k, 'a(href:page, title)')
-        }
-    }
-}
-'''
+            html {
+                body {
+                    [Index: 'index.html',
+                    Page1: 'page.html',
+                    Page2: 'page2.html'].each { k,v ->
+                        fragment(page:v,title:k, 'a(href:page, title)')
+                    }
+                }
+            }
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == "<html><body><a href='index.html'>Index</a><a href='page.html'>Page1</a><a href='page2.html'>Page2</a></body></html>"
     }
 
+    @Test
     void testLayout() {
         def config = new TemplateConfiguration()
         MarkupTemplateEngine engine = new MarkupTemplateEngine(config)
         def template = engine.createTemplate '''
-layout 'includes/body.tpl', bodyContents: contents {
-    div {
-        p('This is the body')
-    }
-}, title: 'This is the title'
-'''
-
+            layout 'includes/body.tpl', bodyContents: contents {
+                div {
+                    p('This is the body')
+                }
+            }, title: 'This is the title'
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == "<html><head><title>This is the title</title></head><body><div><p>This is the body</p></div></body></html>"
     }
 
-    // GROOVY-6915
+    @Test // GROOVY-6915
     void testLayoutWithModelInheritance() {
         def config = new TemplateConfiguration()
         MarkupTemplateEngine engine = new MarkupTemplateEngine(config)
         def template = engine.createTemplate '''
-        layout 'includes/body.tpl', bodyContents: contents {
-            div {
-                p('This is the body')
+            layout 'includes/body.tpl', bodyContents: contents {
+                div {
+                    p('This is the body')
+                }
             }
-        }
-        '''
-
+            '''
         StringWriter rendered = new StringWriter()
         template.make([title:'This is the title']).writeTo(rendered)
         assert rendered.toString() == "<html><head><title/></head><body><div><p>This is the body</p></div></body></html>"
 
         template = engine.createTemplate '''
-        layout 'includes/body.tpl', true, bodyContents: contents {
-            div {
-                p('This is the body')
+            layout 'includes/body.tpl', true, bodyContents: contents {
+                div {
+                    p('This is the body')
+                }
             }
-        }
-        '''
+            '''
         rendered = new StringWriter()
         template.make([title:'This is the title']).writeTo(rendered)
         assert rendered.toString() == "<html><head><title>This is the title</title></head><body><div><p>This is the body</p></div></body></html>"
 
         template = engine.createTemplate '''
-        layout 'includes/body.tpl', true, bodyContents: contents {
-            div {
-                p('This is the body')
-            }
-        }, title: 'This is another title'
-        '''
+            layout 'includes/body.tpl', true, bodyContents: contents {
+                div {
+                    p('This is the body')
+                }
+            }, title: 'This is another title'
+            '''
         rendered = new StringWriter()
         template.make([title:'This is the title']).writeTo(rendered)
         assert rendered.toString() == "<html><head><title>This is another title</title></head><body><div><p>This is the body</p></div></body></html>"
     }
 
+    @Test
     void testSimplePIRenderedProperly() {
         def config = new TemplateConfiguration()
-        config.newLineString=''
+        config.newLineString = ''
         MarkupTemplateEngine engine = new MarkupTemplateEngine(config)
         def template = engine.createTemplate '''pi(FOO: 'bar')'''
         StringWriter rendered = new StringWriter()
@@ -853,21 +899,21 @@ layout 'includes/body.tpl', bodyContents: contents {
         assert rendered.toString() == '<?FOO bar?>'
     }
 
-    // GROOVY-6794
+    @Test // GROOVY-6794
     void testShouldNotThrowForbiddenPropertyAccess() {
         def config = new TemplateConfiguration()
         MarkupTemplateEngine engine = new MarkupTemplateEngine(config)
         def template = engine.createTemplate '''messages.each { message ->
-    yield message.summary
-}'''
+                yield message.summary
+            }
+            '''
         StringWriter rendered = new StringWriter()
         def model = [messages: [new Message(summary: 'summary')]]
         template.make(model).writeTo(rendered)
         assert rendered.toString() == 'summary'
-
     }
 
-    // GROOVY-6914
+    @Test // GROOVY-6914
     void testCachingOfTemplateResolver() {
         int hit = 0
         int miss = 0
@@ -893,7 +939,7 @@ layout 'includes/body.tpl', bodyContents: contents {
                     include template:'includes/hello.tpl'
                 }
             }
-        '''
+            '''
         StringWriter rendered = new StringWriter()
         template.make().writeTo(rendered)
         assert rendered.toString() == '<html><body>Hello from include!Hello from include!Hello from include!</body></html>'
@@ -901,57 +947,53 @@ layout 'includes/body.tpl', bodyContents: contents {
         assert hit==2
     }
 
+    @Test
     void testMarkupInGString() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
-
         def template = engine.createTemplate '''
-        html {
-            body {
-                def test = { p('hg') }
-                def x = "directly ${$test()}"
-                p("This is a p with ${true?$a(href:'link.html','link'):x}")
-                p("This is a p with ${false?$a(href:'link.html','link'):x}")
+            html {
+                body {
+                    def test = { p('hg') }
+                    def x = "directly ${$test()}"
+                    p("This is a p with ${true?$a(href:'link.html','link'):x}")
+                    p("This is a p with ${false?$a(href:'link.html','link'):x}")
+                }
             }
-        }
-        '''
-
+            '''
         String rendered = template.make()
         assert rendered == '<html><body><p>This is a p with <a href=\'link.html\'>link</a></p><p>This is a p with directly <p>hg</p></p></body></html>'
     }
 
+    @Test
     void testMarkupInGStringUsingStringOf() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
-
         def template = engine.createTemplate '''
-        html {
-            body {
-                def test = { p('hg') }
-                def x = "directly ${stringOf { test()} }"
-                p("This is a p with ${stringOf { true?a(href:'link.html','link'):x} }")
-                p("This is a p with ${stringOf { false?a(href:'link.html','link'):x} }")
+            html {
+                body {
+                    def test = { p('hg') }
+                    def x = "directly ${stringOf { test()} }"
+                    p("This is a p with ${stringOf { true?a(href:'link.html','link'):x} }")
+                    p("This is a p with ${stringOf { false?a(href:'link.html','link'):x} }")
+                }
             }
-        }
-        '''
-
+            '''
         String rendered = template.make()
         assert rendered == '<html><body><p>This is a p with <a href=\'link.html\'>link</a></p><p>This is a p with directly <p>hg</p></p></body></html>'
     }
 
+    @Test
     void testShouldNotThrowStackOverflow() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
-
         def template = engine.createTemplate '''
             p("This is an ${strong('error')}")
-        '''
+            '''
         String rendered = template.make().writeTo(new StringWriter())
         assert rendered == '<strong>error</strong><p>This is an </p>'
-
     }
 
-    // GROOVY-6935
+    @Test // GROOVY-6935
     void testShouldNotThrowVerifyErrorBecauseOfEqualsInsteadOfSemiColumn() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
-
         def template = engine.createTemplate '''
             a(href='foo.html', 'link')
         '''
@@ -967,26 +1009,23 @@ layout 'includes/body.tpl', bodyContents: contents {
         assert rendered == '<a>link</a>'
     }
 
-    // GROOVY-6939
-    @NotYetImplemented
+    @Test @NotYetImplemented // GROOVY-6939
     void testShouldNotFailWithDoCallMethod() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
-
         def template = engine.createTemplate '''
             groups.each { k, v -> li(k) }
-        '''
+            '''
         def model = [groups:[a:'Group a',b:'Group b']]
         String rendered = template.make(model)
         assert rendered == '<li>a</li><li>b</li>'
     }
 
-    // GROOVY-6940
+    @Test // GROOVY-6940
     void testSubscriptOperatorOnModel() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
-
         def template = engine.createTemplate '''
             yield list[0]
-        '''
+            '''
         def model = [list:['Item 1']]
         String rendered = template.make(model)
         assert rendered == 'Item 1'
@@ -994,7 +1033,7 @@ layout 'includes/body.tpl', bodyContents: contents {
         template = engine.createTemplate '''
             list[0] = 'Item 2'
             yield list[0]
-        '''
+            '''
         model = [list:['Item 1']]
         rendered = template.make(model)
         assert model.list[0] == 'Item 2'
@@ -1004,35 +1043,33 @@ layout 'includes/body.tpl', bodyContents: contents {
             def indirect = list
             indirect[0] = 'Item 4'
             yield list[0]
-        '''
+            '''
         model = [list:['Item 3']]
         rendered = template.make(model)
         assert model.list[0] == 'Item 4'
         assert rendered == 'Item 4'
-
     }
 
-    // GROOVY-6941
+    @Test // GROOVY-6941
     void testDynamicPropertyInsideBlock() {
         MarkupTemplateEngine engine = new MarkupTemplateEngine(new TemplateConfiguration())
         def template = engine.createTemplate '''
-        div {
-            yield xml.file.name
-        }
-        '''
+            div {
+                yield xml.file.name
+            }
+            '''
         def model = [xml: [file:[name:'test']]]
         String rendered = template.make(model)
         assert rendered == '<div>test</div>'
-
     }
 
-    class SimpleTagLib {
+    static class SimpleTagLib {
         def emoticon = { attrs, body ->
             out << body() << (attrs.happy == 'true' ? " :-)" : " :-(")
         }
     }
 
-    public static class Person {
+    static class Person {
         String name
     }
 
@@ -1047,5 +1084,4 @@ layout 'includes/body.tpl', bodyContents: contents {
             this.summary = summary
         }
     }
-
 }


Mime
View raw message