home | career | drupal | java | mac | mysql | perl | scala | uml | unix

Groovy example source code file (CanonicalTransformTest.groovy)

This example Groovy source code file (CanonicalTransformTest.groovy) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Groovy tags/keywords

bar, baz, canonical, canonical, foo, foo, haslist, haslistandmap, rectangle, rectangle, string, string, this, tostring

The Groovy CanonicalTransformTest.groovy source code

/*
 * Copyright 2008-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.codehaus.groovy.transform

/**
 * @author Paulo Poiati
 * @author Paul King
 */
class CanonicalTransformTest extends GroovyShellTestCase {

    void testCanonical() {
        def objects = evaluate("""
            import groovy.transform.Canonical
            @Canonical class Foo {
                String x, y
            }
            [new Foo(x:'x', y:'y'),
             new Foo('x', 'y')]
        """)

        assertEquals objects[0].hashCode(), objects[1].hashCode()
        assertEquals objects[0], objects[1]
    }

    void testCanonicalCantAlsoBeImmutable() {
        def msg = shouldFail(RuntimeException) {
            assertScript """
                import groovy.transform.*
                @Canonical
                @Immutable
                class Foo {
                    String bar
                }
            """
        }
        assert msg.contains("@Canonical class 'Foo' can't also be @Immutable")
    }

    void testCanonicalWithDeclaredConstructor() {
        def msg = shouldFail(GroovyRuntimeException) {
            assertScript """
                @groovy.transform.Canonical class Foo {
                    def foo, bar, baz
                
                    Foo() {}
                
                    Foo(foo, bar) {
                        this.foo = foo
                        this.bar = bar
                    }
                }
            
                def foo = new Foo('a', 'b')
                def foo1 = new Foo()
                foo1.foo = 'a'
                foo1.bar = 'b'
                assert foo == foo1
            
                // Fail here
                new Foo('a', 'b', 'c')
            """
        }
        assert msg.contains('Could not find matching constructor')
    }

    void testCanonicalNotCopyOrCloneProperty() {
        assertScript """
            def date = new Date()
            def array = [1, 2, 3] as Integer[]
            def map = [foo: 'bar']
            def collection = [4, 5, 6]
            
            @groovy.transform.Canonical class Foo {
                Date date
                Integer[] array
                Map map
                Collection collection
            }
            
            def foo = new Foo(date, array, map, collection)
            
            assert date.is(foo.date)
            assert array.is(foo.array)
            assert map.is(foo.map)
            assert collection.is(foo.collection)
        """
    }

    void testCanonicalChange() {
        def objects = evaluate("""
              @groovy.transform.Canonical class Foo {
                  String x, y
              }
              [new Foo(x:'x', y:'y'),
               new Foo('x', 'y')]
        """)
        objects[0].x = 'z'
        assertFalse objects[0] == objects[1]
        assertFalse objects[0].hashCode() == objects[1].hashCode()
    }

    void testUntyped() {
        def object = evaluate("""
              @groovy.transform.Canonical class Foo {
                  def x
                  def y = 10
              }
              new Foo()
        """)

        assert null == object.x
        assert 10 == object.y

        object.x = 20
        assert 20 == object.x
        object.x = [1, 2, 3]
        assert [1, 2, 3] == object.x
    }

    void testCanonicalRectangleFieldsNamesTupleToString() {
        assert 'Rectangle(w:10, h:20, x:5, y:7)' == evaluate("""
            import groovy.transform.*
            @Canonical
            @ToString(includeNames=true, includeFields=true)
            @TupleConstructor(includeFields=true)
            class Rectangle {
                int w, h
                private int x, y
            }
            new Rectangle(10, 20, 5, 7).toString()
        """)
    }

    void testCanonicalRectangleFieldsToString() {
        assert 'Rectangle(10, 20, 0, 0)' == evaluate("""
            import groovy.transform.*
            @Canonical
            @ToString(includeFields=true)
            class Rectangle {
                int w, h
                private int x, y
            }
            new Rectangle(10, 20).toString()
        """)
    }

    void testCanonicalDefaultToString() {
        assert 'Rectangle(10, 20)' == evaluate("""
            import groovy.transform.*
            @Canonical
            class Rectangle {
                int w, h
                private int x, y
            }
            new Rectangle(10, 20).toString()
        """)
    }

    void testCanonicalRectangleTupleNamesToString() {
        assert 'Rectangle(w:10, h:20)' == evaluate("""
            import groovy.transform.*
            @Canonical
            @ToString(includeNames=true)
            @TupleConstructor(includeFields=true)
            class Rectangle {
                int w, h
                private int x, y
            }
            new Rectangle(10, 20, 5, 7).toString()
        """)
    }

    void testCanonicalRectangleFieldsTupleToString() {
        assert 'Rectangle(10, 20, 5, 7)' == evaluate("""
            import groovy.transform.*
            @Canonical
            @ToString(includeFields=true)
            @TupleConstructor(includeFields=true)
            class Rectangle {
                int w, h
                private int x, y
            }
            new Rectangle(10, 20, 5, 7).toString()
        """)
    }

    void testCanonicalRectangleFieldsNamesToString() {
        assert 'Rectangle(w:10, h:20, x:0, y:0)' == evaluate("""
            import groovy.transform.*
            @Canonical
            @ToString(includeNames=true, includeFields=true)
            class Rectangle {
                int w, h
                private int x, y
            }
            new Rectangle(10, 20).toString()
        """)
    }

    void testMapConstructorOptional() {
        assertScript """
            @groovy.transform.Canonical class Foo {
                String bar
                String baz = 'a'
            }
            
            def foo = new Foo(bar: 'c')
            def foo1 = new Foo(baz: 'd')
            assert 'a' == foo.baz
            assert 'c' == foo.bar
            assert 'd' == foo1.baz
            assert null == foo1.bar
        """
    }

    void testMapConstructorOptionalPrimitive() {
        assertScript """
            @groovy.transform.Canonical class Foo {
                String a
                int b
                char c
                short d
                long e
                byte f
                double h
                float i
                boolean j
            }
            
            new Foo("foo")
            new Foo("foo", 10)
            new Foo("foo", 10, (char) 20)
            new Foo("foo", 10, (char) 20, (short) 30)
            new Foo("foo", 10, (char) 20, (short) 30, 40L)
            new Foo("foo", 10, (char) 20, (short) 30, 40L, (byte) 50)
            new Foo("foo", 10, (char) 20, (short) 30, 40L, (byte) 50, 0.0)
            new Foo("foo", 10, (char) 20, (short) 30, 40L, (byte) 50, 0.0, 0.0F)
        """
    }

    void testOrderedConstructorOptional() {
        assertScript """
            @groovy.transform.Canonical class Foo {
                String bar
                String baz = 'a'
            }
            
            def foo = new Foo()
            def foo0 = new Foo('c')
            def foo1 = new Foo('c', 'd')
            assert null == foo.bar
            assert 'a' == foo.baz
            assert 'c' == foo0.bar
            assert 'a' == foo0.baz
            assert 'c' == foo1.bar
            assert 'd' == foo1.baz
        """
    }

    void testCanonicalListProp() {
        def objects = evaluate("""
              @groovy.transform.Canonical class HasList {
                  String[] letters
                  List nums
              }
              def letters = 'A,B,C'.split(',')
              def nums = [1, 2]
              [new HasList(letters:letters, nums:nums),
               new HasList(letters, nums)]
        """)

        assertEquals objects[0].hashCode(), objects[1].hashCode()
        assertEquals objects[0], objects[1]
        assert objects[0].letters.size() == 3
        assert objects[0].nums.size() == 2

        objects[0].nums = [1, 2, 3]
        objects[1].letters = 'D,E'.split(',')

        assert objects[0].nums.size() == 3
        assert objects[1].letters.size() == 2
        assertFalse objects[0] == objects[1]
        assert !(objects[0].hashCode() == objects[1].hashCode())
    }

    void testCanonicalChangeArray() {
        assertScript """
              @groovy.transform.Canonical class HasListAndMap {
                  Object[] foo
              }
              def object = new HasListAndMap()
              def object2 = new HasListAndMap(['bar'] as Object[])
              
              assert object != object2
              
              object.foo = new Object[1]
              object.foo[0] = 'bar'
              
              assert object == object2
        """
    }

    void testCanonicalChangeCollection() {
        def object = evaluate("""
              @groovy.transform.Canonical class HasListAndMap {
                  List nums
                  Map map
              }
              new HasListAndMap(nums:[], map:[:])
        """)

        object.nums << 1
        object.nums.add 2
        object.map.foo = "bat"
        assertEquals 2, object.nums.size()
        assertEquals 1, object.map.size()
        object.nums.remove 0
        assertEquals 1, object.nums.size()
    }

    void testCanonicalAsMapKey() {
        assertScript """
            @groovy.transform.Canonical final class HasString {
                String s
            }
            def k1 = new HasString('xyz')
            def k2 = new HasString('xyz')
            def map = [(k1):42]
            assert map[k2] == 42
        """
    }

    void testCanonicalWithOnlyMap() {
        assertScript """
            @groovy.transform.Canonical final class HasMap {
                Map map
            }
            def m = new HasMap([:])
            new HashMap()
        """
    }

    void testCanonicalWithInvalidPropertyName() {
        def msg = shouldFail(MissingPropertyException) {
            assertScript """
                @groovy.transform.Canonical class Simple { }
                new Simple(missing:'Name')
            """
        }
        assert msg.contains('No such property: missing for class: Simple')
    }

    void testCanonicalWithHashMap() {
        assertScript """
            @groovy.transform.Canonical final class HasHashMap {
                HashMap map = [d:4]
            }
            assert new HasHashMap([a:1]).map == [a:1]
            assert new HasHashMap(c:3).map == [c:3]
            assert new HasHashMap(null).map == null
            assert new HasHashMap().map == [d:4]
            assert new HasHashMap([:]).map == [:]
            assert new HasHashMap(map:5, c:3).map == [map:5, c:3]
            assert new HasHashMap(map:[:]).map == [map:[:]]
        """
    }

    void testCanonicalEquals() {
        assertScript """
            @groovy.transform.Canonical class This { String value }
            @groovy.transform.Canonical class That { String value }
            class Other { }

            assert new This('foo') == new This("foo")
            assert new This('f${"o"}o') == new This("foo")

            assert new This('foo') != new This("bar")
            assert new This('foo') != new That("foo")
            assert new This('foo') != new Other()
            assert new Other() != new This("foo")
        """
    }

    void testExistingToString() {
        assertScript """
            import groovy.transform.Canonical
            @Canonical class Foo {
                String value
            }
            @Canonical class Bar {
                String value
                String toString() { 'zzz' + _toString() }
            }
            @Canonical class Baz {
                String value
                String toString() { 'zzz' + _toString() }
                def _toString() { 'xxx' }
            }
            def foo = new Foo('abc')
            def foo0 = new Foo('abc')
            def foo1 = new Foo(value:'abc')
            def bar = new Bar('abc')
            def baz = new Baz('abc')
            assert bar.toString() == 'zzz' + foo.toString().replaceAll('Foo', 'Bar')
            assert baz.toString() == 'zzzxxx'

            assert 'Foo(abc)' == foo0.toString()
            foo0.value = 'cde'
            assert 'Foo(cde)' == foo0.toString()
            assert 'Foo(abc)' == foo1.toString()
            foo1.value = 'cde'
            assert 'Foo(cde)' == foo1.toString()
        """
    }

    void testExistingEquals() {
        assertScript """
            import groovy.transform.Canonical
            @Canonical class Foo {
                String value
            }
            @Canonical class Bar {
                String value
                // doesn't follow normal conventions - for testing only
                boolean equals(other) { value == 'abc' || _equals(other) }
            }
            @Canonical class Baz {
                String value
                // doesn't follow normal conventions - for testing only
                boolean equals(Baz other) { value == 'abc' || _equals(other) }
                def _equals(other) { false }
            }
            def foo1 = new Foo('abc')
            def foo2 = new Foo('abc')
            def foo3 = new Foo('def')
            assert foo1 == foo2
            assert foo1 != foo3

            def bar1 = new Bar('abc')
            def bar2 = new Bar('abc')
            def bar3 = new Bar('def')
            def bar4 = new Bar('def')
            assert bar1 == bar2
            assert bar1 == bar3
            assert bar3 != bar1

            def baz1 = new Baz('abc')
            def baz2 = new Baz('abc')
            def baz3 = new Baz('def')
            def baz4 = new Baz('def')
            assert baz1 == baz2
            assert baz1 == baz3
            assert baz3 != baz1
            assert baz3 != baz4
        """
    }

    void testExistingHashCode() {
        assertScript """
            import groovy.transform.Canonical
            @Canonical class Foo {
                String value
            }
            @Canonical class Bar {
                String value
                // doesn't follow normal conventions - for testing only
                int hashCode() { value == 'abc' ? -1 : _hashCode() }
            }
            @Canonical class Baz {
                String value
                // doesn't follow normal conventions - for testing only
                int hashCode() { value == 'abc' ? -1 : _hashCode() }
                def _hashCode() { -100 }
            }
            def foo1 = new Foo('abc')
            def foo2 = new Foo('abc')
            assert foo1.hashCode() == foo2.hashCode()

            def bar1 = new Bar('abc')
            def bar2 = new Bar('def')
            def bar3 = new Bar('def')
            assert bar1.hashCode() == -1
            assert bar2.hashCode() == bar3.hashCode()

            def baz1 = new Baz('abc')
            def baz2 = new Baz('def')
            assert baz1.hashCode() == -1
            assert baz2.hashCode() == -100
        """
    }
}

Other Groovy examples (source code examples)

Here is a short list of links related to this Groovy CanonicalTransformTest.groovy source code file:

new blog posts

 

Copyright 1998-2013 Alvin Alexander, alvinalexander.com
All Rights Reserved.