<commit_before>/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.codehaus.groovy.transform

import groovy.test.GroovyShellTestCase
import org.codehaus.groovy.control.MultipleCompilationErrorsException
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestName
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

import static groovy.test.GroovyAssert.isAtLeastJdk
import static org.junit.Assume.assumeTrue

/**
 * Tests for the @Immutable transform.
 */
@RunWith(JUnit4)
class ImmutableTransformTest extends GroovyShellTestCase {

    @Rule public TestName nameRule = new TestName()

    @Before
    void setUp() {
        super.setUp()
        // check java version requirements
        assumeTrue(nameRule.methodName.endsWith('_vm8').implies(isAtLeastJdk('1.8')))
    }

    @After
    void tearDown() {
        super.tearDown()
    }

    @Test
    void testImmutable() {
        def objects = evaluate('''
            import groovy.transform.Immutable
            enum Coin { HEAD, TAIL }
            @Immutable class Bar {
                String x, y
                Coin c
                Collection nums
            }
            [new Bar(x:'x', y:'y', c:Coin.HEAD, nums:[1,2]),
             new Bar('x', 'y', Coin.HEAD, [1,2])]
        ''')

        assert objects[0].hashCode() == objects[1].hashCode()
        assert objects[0] == objects[1]
        assert objects[0].nums.class.name.contains("Unmodifiable")
    }

    @Test
    void testImmutableClonesListAndCollectionFields() {
        def objects = evaluate("""
            import groovy.transform.Immutable
            def myNums = [1, 2]
            @Immutable class Bar {
                List nums
                Collection otherNums
            }
            def myBar = new Bar(nums:myNums, otherNums:myNums)
            myNums << 3
            [myNums, myBar]
        """)

        assertNotSame(objects[0], objects[1].nums)
        assertNotSame(objects[0], objects[1].otherNums)
        assertNotSame(objects[1].nums, objects[1].otherNums)
        assertEquals 3, objects[0].size()
        assertEquals 2, objects[1].nums.size()
        assertEquals 2, objects[1].otherNums.size()
        assertTrue objects[1].nums.class.name.contains("Unmodifiable")
        assertTrue objects[1].otherNums.class.name.contains("Unmodifiable")
    }

    @Test
    void testImmutableField() {
        def person = evaluate("""
            import groovy.transform.Immutable
            @Immutable class Person {
                boolean married
            }
            new Person(married:false)
        """)
        shouldFail(ReadOnlyPropertyException) {
            person.married = true
        }
    }

    @Test
    void testCloneableField() {
        def (originalDolly, lab) = evaluate("""
            import groovy.transform.Immutable

            class Dolly implements Cloneable {
                String name
            }

            @Immutable class Lab {
                String name
                Cloneable clone
            }

            def dolly = new Dolly(name: "The Sheep")
            [dolly, new Lab(name: "Area 51", clone: dolly)]
        """)

        def clonedDolly = lab.clone
        def clonedDolly2 = lab.clone

        assert lab.name == 'Area 51'
        assert !originalDolly.is(clonedDolly)
        assert originalDolly.name == clonedDolly.name
        assert !clonedDolly2.is(clonedDolly)
        assert clonedDolly2.name == clonedDolly.name
    }

    @Test
    void testCloneableFieldNotCloneableObject() {
        def cls = shouldFail(CloneNotSupportedException) {<commit_msg>minor test refactor<commit_after>/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.codehaus.groovy.transform

import groovy.test.GroovyShellTestCase
import org.codehaus.groovy.control.MultipleCompilationErrorsException
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestName
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

import static groovy.test.GroovyAssert.isAtLeastJdk
import static org.junit.Assume.assumeTrue

/**
 * Tests for the @Immutable transform.
 */
@RunWith(JUnit4)
class ImmutableTransformTest extends GroovyShellTestCase {

    @Rule public TestName nameRule = new TestName()

    @Before
    void setUp() {
        super.setUp()
        // check java version requirements
        assumeTrue(nameRule.methodName.endsWith('_vm8').implies(isAtLeastJdk('1.8')))
    }

    @After
    void tearDown() {
        super.tearDown()
    }

    @Test
    void testImmutable() {
        def objects = evaluate('''
            import groovy.transform.Immutable
            enum Coin { HEAD, TAIL }
            @Immutable class Bar {
                String x, y
                Coin c
                Collection nums
            }
            [new Bar(x:'x', y:'y', c:Coin.HEAD, nums:[1,2]),
             new Bar('x', 'y', Coin.HEAD, [1,2])]
        ''')

        assert objects[0].hashCode() == objects[1].hashCode()
        assert objects[0] == objects[1]
        assert objects[0].nums.class.name.contains("Unmodifiable")
    }

    @Test
    void testImmutableClonesListAndCollectionFields() {
        def objects = evaluate("""
            import groovy.transform.Immutable
            def myNums = [1, 2]
            @Immutable class Bar {
                List nums
                Collection otherNums
            }
            def myBar = new Bar(nums:myNums, otherNums:myNums)
            myNums << 3
            [myNums, myBar]
        """)

        assertNotSame(objects[0], objects[1].nums)
        assertNotSame(objects[0], objects[1].otherNums)
        assertNotSame(objects[1].nums, objects[1].otherNums)
        assertEquals 3, objects[0].size()
        assertEquals 2, objects[1].nums.size()
        assertEquals 2, objects[1].otherNums.size()
        assertTrue objects[1].nums.class.name.contains("Unmodifiable")
        assertTrue objects[1].otherNums.class.name.contains("Unmodifiable")
    }

    @Test
    void testImmutableField() {
        def person = evaluate("""
            import groovy.transform.Immutable
            @Immutable class Person {
                boolean married
            }
            new Person(married:false)
        """)
        shouldFail(ReadOnlyPropertyException) {
            person.married = true
        }
    }

    @Test
    void testCloneableField() {
        def (originalDolly, lab) = evaluate('''
            import groovy.transform.*

            @AutoClone
            class Dolly implements Cloneable {
                String name
            }

            @Immutable class Lab {
                String name
                Cloneable clone
            }

            def dolly = new Dolly(name: "The Sheep")
            [dolly, new Lab(name: "Area 51", clone: dolly)]
        ''')

        def clonedDolly = lab.clone
        def clonedDolly2 = lab.clone

        assert lab.name == 'Area 51'
        assert !originalDolly.is(clonedDolly)
        assert originalDolly.name == clonedDolly.name
        assert !clonedDolly2.is(clonedDolly)
        assert clonedDolly2.name == clonedDolly.name
    }

    @Test
    void testCloneableFieldNotCloneableObject() {
        def cls = shouldFail(CloneNotSupportedException) {
{'fraction_non_alphanumeric': 0.0940065219835826, 'fraction_numerical': 0.009445631395479591, 'mean_word_length': 2.257875457875458, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3835893', 'n_tokens_mistral': 2572, 'n_tokens_neox': 2477, 'n_words': 671}