/*
 * 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.apache.commons.beanutils2;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * <p>
 * Test case for {@code ConstructorUtils}
 * </p>
 */
public class ConstructorUtilsTestCase extends TestCase {

    /**
     * Creates the tests included in this test suite.
     */
    public static Test suite() {
        return new TestSuite(ConstructorUtilsTestCase.class);
    }

    /**
     * Constructs a new instance of this test case.
     *
     * @param name Name of the test case
     */
    public ConstructorUtilsTestCase(final String name) {
        super(name);
    }

    /**
     * Sets up instance variables required by this test case.
     */
    @Override
    public void setUp() throws Exception {
        super.setUp();
    }

    /**
     * Tear down instance variables required by this test case.
     */
    @Override
    public void tearDown() throws Exception {
        super.tearDown();
    }

    public void testGetAccessibleConstructor() throws Exception {
        {
            final Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(TestBean.class, String.class);
            assertNotNull(ctor);
            assertTrue(Modifier.isPublic(ctor.getModifiers()));
        }
        {
            final Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(TestBean.class, Integer.class);
            assertNotNull(ctor);
            assertTrue(Modifier.isPublic(ctor.getModifiers()));
        }
        {
            final Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(TestBean.class, Integer.TYPE);
            assertNull(ctor);
        }
    }

    public void testGetAccessibleConstructorWithConstructorArg() throws Exception {
        {
            final Class<?>[] types = { Integer.class };
            final Constructor<?> c1 = TestBean.class.getConstructor(types);
            final Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(c1);
            assertNotNull(ctor);
            assertTrue(Modifier.isPublic(ctor.getModifiers()));
        }
        {
            final Class<?>[] types = { Integer.class };
            final Constructor<?> c1 = TestBean.class.getDeclaredConstructor(types);
            final Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(c1);
            assertNotNull(ctor);
            assertTrue(Modifier.isPublic(ctor.getModifiers()));
        }
        {
            final Class<?>[] types = { Integer.TYPE };
            final Constructor<?> c1 = TestBean.class.getDeclaredConstructor(types);
            final Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(c1);
            assertNull(ctor);
        }
    }

    public void testGetAccessibleConstructorWithTypeArray() throws Exception {
        {
            final Class<?>[] types = { Boolean.TYPE, String.class };
            final Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(TestBean.class, types);
            assertNotNull(ctor);
            assertTrue(Modifier.isPublic(ctor.getModifiers()));
        }
        {
            final Class<?>[] types = { Boolean.TYPE, Boolean.TYPE, String.class };
            final Constructor<?> ctor = ConstructorUtils.getAccessibleConstructor(TestBean.class, types);
            assertNull(ctor);
        }
    }

    public void testInvokeConstructor() throws Exception {
        {
            final Object obj = ConstructorUtils.invokeConstructor(TestBean.class, "TEST");
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertEquals("TEST", ((TestBean) obj).getStringProperty());
        }
        {
            final Object obj = ConstructorUtils.invokeConstructor(TestBean.class, Float.valueOf(17.3f));
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertEquals(17.3f, ((TestBean) obj).getFloatProperty(), 0.0f);
        }
    }

    public void testInvokeConstructorNull() throws Exception {
        final Object obj = ConstructorUtils.invokeConstructor(TestBean.class, (Object) null);
        assertNotNull(obj);
        assertTrue(obj instanceof TestBean);
    }

    public void testInvokeConstructorWithArgArray() throws Exception {
        final Object[] args = { Float.valueOf(17.3f), "TEST" };
        final Object obj = ConstructorUtils.invokeConstructor(TestBean.class, args);
        assertNotNull(obj);
        assertTrue(obj instanceof TestBean);
        assertEquals(17.3f, ((TestBean) obj).getFloatProperty(), 0.0f);
        assertEquals("TEST", ((TestBean) obj).getStringProperty());
    }

    public void testInvokeConstructorWithTypeArray() throws Exception {
        {
            final Object[] args = { Boolean.TRUE, "TEST" };
            final Class<?>[] types = { Boolean.TYPE, String.class };
            final Object obj = ConstructorUtils.invokeConstructor(TestBean.class, args, types);
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertTrue( ((TestBean) obj).getBooleanProperty());
            assertEquals("TEST", ((TestBean) obj).getStringProperty());
        }
        {
            final Object[] args = { Boolean.TRUE, "TEST" };
            final Class<?>[] types = { Boolean.class, String.class };
            final Object obj = ConstructorUtils.invokeConstructor(TestBean.class, args, types);
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertTrue( ((TestBean) obj).isBooleanSecond());
            assertEquals("TEST", ((TestBean) obj).getStringProperty());
        }
    }

    public void testInvokeExactConstructor() throws Exception {
        {
            final Object obj = ConstructorUtils.invokeExactConstructor(TestBean.class, "TEST");
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertEquals("TEST", ((TestBean) obj).getStringProperty());
        }
        {
            try {
                ConstructorUtils.invokeExactConstructor(TestBean.class, Float.valueOf(17.3f));
                fail("Expected NoSuchMethodException");
            } catch (final NoSuchMethodException e) {
                // expected
            }
        }
        {
            final Object obj = ConstructorUtils.invokeExactConstructor(TestBean.class, Boolean.TRUE);
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertTrue( ((TestBean) obj).isBooleanSecond());
        }
    }

    public void testInvokeExactConstructorWithArgArray() throws Exception {
        {
            final Object[] args = { Float.valueOf(17.3f), "TEST" };
            try {
                ConstructorUtils.invokeExactConstructor(TestBean.class, args);
                fail("Expected NoSuchMethodException");
            } catch (final NoSuchMethodException e) {
                // expected
            }
        }
        {
            final Object[] args = { Boolean.TRUE, "TEST" };
            final Object obj = ConstructorUtils.invokeExactConstructor(TestBean.class, args);
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertTrue( ((TestBean) obj).isBooleanSecond());
            assertEquals("TEST", ((TestBean) obj).getStringProperty());
        }
    }

    public void testInvokeExactConstructorWithNull() throws Exception {
        final Object obj = ConstructorUtils.invokeExactConstructor(TestBean.class, (Object) null);
        assertNotNull(obj);
        assertTrue(obj instanceof TestBean);
    }

    public void testInvokeExactConstructorWithTypeArray() throws Exception {
        {
            final Object[] args = { Boolean.TRUE, "TEST" };
            final Class<?>[] types = { Boolean.TYPE, String.class };
            final Object obj = ConstructorUtils.invokeExactConstructor(TestBean.class, args, types);
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertTrue( ((TestBean) obj).getBooleanProperty());
            assertEquals("TEST", ((TestBean) obj).getStringProperty());
        }
        {
            final Object[] args = { Boolean.TRUE, "TEST" };
            final Class<?>[] types = { Boolean.class, String.class };
            final Object obj = ConstructorUtils.invokeExactConstructor(TestBean.class, args, types);
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertTrue( ((TestBean) obj).isBooleanSecond());
            assertEquals("TEST", ((TestBean) obj).getStringProperty());
        }
        {
            final Object[] args = { Float.valueOf(17.3f), "TEST" };
            final Class<?>[] types = { Float.TYPE, String.class };
            final Object obj = ConstructorUtils.invokeExactConstructor(TestBean.class, args, types);
            assertNotNull(obj);
            assertTrue(obj instanceof TestBean);
            assertEquals(17.3f, ((TestBean) obj).getFloatProperty(), 0.0f);
            assertEquals("TEST", ((TestBean) obj).getStringProperty());
        }
        {
            final Object[] args = { Float.valueOf(17.3f), "TEST" };
            final Class<?>[] types = { Float.class, String.class };
            try {
                ConstructorUtils.invokeExactConstructor(TestBean.class, args, types);
                fail("Expected NoSuchMethodException");
            } catch (final NoSuchMethodException e) {
                // expected
            }
        }
    }

}
