
/*
 *  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.
 */

import org.junit.jupiter.api.Test

import static groovy.test.GroovyAssert.assertScript
import static groovy.test.GroovyAssert.shouldFail

class DifferencesFromJavaTest {
    @Test
    void testMultiMethods() {
        assertScript '''import static org.junit.jupiter.api.Assertions.*
// tag::multimethods[]
int method(String arg) {
    return 1;
}
int method(Object arg) {
    return 2;
}
Object o = "Object";
int result = method(o);
// end::multimethods[]
/*
// With Java:
// tag::multimethods_java[]
assertEquals(2, result);
// end::multimethods_java[]
*/
// With Groovy:
// tag::multimethods_groovy[]
assertEquals(1, result);
// end::multimethods_groovy[]
'''
    }

    @Test
    void testArrayCreation() {
        shouldFail {
            assertScript '''
                // tag::arraycreate_fail[]
                int[] array = {1, 2, 3};             // Java array initializer shorthand syntax
                int[] array2 = new int[] {4, 5, 6};  // Java array initializer long syntax
                // end::arraycreate_fail[]
            '''
        }
        assertScript '''
            // tag::arraycreate_success[]
            int[] array = [1, 2, 3]
            // end::arraycreate_success[]
            assert array instanceof int[]
            // tag::arraycreate3_success[]
            def array2 = new int[] {1, 2, 3} // Groovy 3.0+ supports the Java-style array initialization long syntax
            // end::arraycreate3_success[]
            assert array2 instanceof int[]
        '''
    }

    @Test
    void testPackagePrivate() {
        assertScript '''
            import groovy.transform.ASTTest
            import java.lang.reflect.Modifier

            @ASTTest(phase = CLASS_GENERATION, value = {
                def field = node.getField('name')
                assert field.modifiers == Modifier.PRIVATE
            })
            // tag::packageprivate_property[]
            class Person {
                String name
            }
            // end::packageprivate_property[]
            new Person()
        '''

        assertScript '''
            import groovy.transform.ASTTest
            import groovy.transform.PackageScope

            @ASTTest(phase = CLASS_GENERATION, value = {
                def field = node.getField('name')
                assert field.modifiers == 0
            })
            // tag::packageprivate_field[]
            class Person {
                @PackageScope String name
            }
            // end::packageprivate_field[]
            new Person()
        '''
    }

    @Test
    void testAnonymousAndNestedClasses() {
        assertScript '''
// tag::innerclass_1[]
class A {
    static class B {}
}

new A.B()
// end::innerclass_1[]
'''
        assertScript '''
// tag::innerclass_2[]
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

CountDownLatch called = new CountDownLatch(1)

Timer timer = new Timer()
timer.schedule(new TimerTask() {
    void run() {
        called.countDown()
    }
}, 0)

assert called.await(10, TimeUnit.SECONDS)
// end::innerclass_2[]
'''
        assertScript '''
/*
// tag::innerclass_3_java[]
public class Y {
    public class X {}
    public X foo() {
        return new X();
    }
    public static X createX(Y y) {
        return y.new X();
    }
}
// end::innerclass_3_java[]
*/
// tag::innerclass_3[]
public class Y {
    public class X {}
    public X foo() {
        return new X()
    }
    public static X createX(Y y) {
        return new X(y)
    }
}
// end::innerclass_3[]
def y = new Y()
def x = Y.createX(y)
assert (x.'this$0').is(y)
'''
    }

    @Test
    void testStringsAndCharsGotchas() {
        assertScript '''
import org.codehaus.groovy.runtime.typehandling.GroovyCastException;

// tag::type_depends_on_quoting_AND_whether_we_actually_interpolate[]
assert 'c'.class == String
assert "c".class == String
assert "c${1}".class in GString
// end::type_depends_on_quoting_AND_whether_we_actually_interpolate[]
// tag::single_char_strings_are_autocasted[]
char a = 'a'
assert Character.digit(a, 16) == 10: 'But Groovy does boxing'
assert Character.digit((char) 'a', 16) == 10

try {
  assert Character.digit('a', 16) == 10
  assert false: 'Need explicit cast'
} catch(MissingMethodException e) {
}
// end::single_char_strings_are_autocasted[]
// tag::chars_c_vs_groovy_cast[]
// for single char strings, both are the same
assert ((char) "c").class == Character
assert ("c" as char).class == Character

// for multi char strings they are not
try {
  ((char) 'cx') == 'c'
  assert false: 'will fail - not castable'
} catch(GroovyCastException e) {
}
assert ('cx' as char) == 'c'
assert 'cx'.asType(char) == 'c'
// end::chars_c_vs_groovy_cast[]
        '''

    }
}
