/*
 * 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 junit.framework.Test;
import junit.framework.TestSuite;

/**
 * Test Case for the {@link BeanUtilsBean2}.
 *
 */
public class BeanUtils2TestCase extends BeanUtilsTestCase {



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



    /**
     * Set up instance variables required by this test case.
     */
    @Override
    public void setUp() {
        ConvertUtils.deregister();
        BeanUtilsBean.setInstance(new BeanUtilsBean2());
        setUpShared();
    }

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

    /**
     * Tear down instance variables required by this test case.
     */
    @Override
    public void tearDown() {
        bean = null;
    }

    /**
     * Test {@code copyProperty()} converting to a String.
     */
    @Override
    public void testCopyPropertyConvertToString() {
        try {
            BeanUtils.copyProperty(bean, "stringProperty", testUtilDate);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }
        assertEquals("java.util.Date --> String", testStringDate, bean.getStringProperty());
    }

    /**
     * Test {@code copyProperty()} converting to a String.
     */
    @Override
    public void testCopyPropertyConvertToStringArray() {
        try {
            bean.setStringArray(null);
            BeanUtils.copyProperty(bean, "stringArray", new java.util.Date[] {testUtilDate});
        } catch (final Throwable t) {
            fail("Threw " + t);
        }
        assertEquals("java.util.Date[] --> String[] length", 1, bean.getStringArray().length);
        assertEquals("java.util.Date[] --> String[] value ", testStringDate, bean.getStringArray()[0]);
    }

    /**
     * Test {@code copyProperty()} converting to a String on indexed property
     */
    @Override
    public void testCopyPropertyConvertToStringIndexed() {
        try {
            bean.setStringArray(new String[1]);
            BeanUtils.copyProperty(bean, "stringArray[0]", testUtilDate);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }
        assertEquals("java.util.Date[] --> String[] length", 1, bean.getStringArray().length);
        assertEquals("java.util.Date[] --> String[] value ", testStringDate, bean.getStringArray()[0]);
    }

    /**
     * Test {@code getArrayProperty()} converting to a String.
     */
    @Override
    public void testGetArrayPropertyDate() {
        String[] value = null;
        try {
            bean.setDateArrayProperty(new java.util.Date[] {testUtilDate});
            value = BeanUtils.getArrayProperty(bean, "dateArrayProperty");
        } catch (final Throwable t) {
            fail("Threw " + t);
        }
        assertEquals("java.util.Date[] --> String[] length", 1, value.length);
        assertEquals("java.util.Date[] --> String[] value ", testStringDate, value[0]);
    }

    /**
     * Test {@code getArrayProperty()} converting to a String.
     */
    @Override
    public void testGetIndexedPropertyDate() {
        String value = null;
        try {
            bean.setDateArrayProperty(new java.util.Date[] {testUtilDate});
            value = BeanUtils.getIndexedProperty(bean, "dateArrayProperty[0]");
        } catch (final Throwable t) {
            fail("Threw " + t);
        }
        assertEquals("java.util.Date[0] --> String", testStringDate, value);
    }

    /**
     * Test {@code getSimpleProperty()} converting to a String.
     */
    @Override
    public void testGetSimplePropertyDate() {
        String value = null;
        try {
            bean.setDateProperty(testUtilDate);
            value = BeanUtils.getSimpleProperty(bean, "dateProperty");
        } catch (final Throwable t) {
            fail("Threw " + t);
        }
        assertEquals("java.util.Date --> String", testStringDate, value);
    }

    /**
     * Test {@code setProperty()} converting to a String.
     */
    @Override
    public void testSetPropertyConvertToString() {
        try {
            BeanUtils.setProperty(bean, "stringProperty", testUtilDate);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }
        assertEquals("java.util.Date --> String", testStringDate, bean.getStringProperty());
    }

    /**
     * Test {@code setProperty()} converting to a String array.
     */
    @Override
    public void testSetPropertyConvertToStringArray() {
        try {
            bean.setStringArray(null);
            BeanUtils.setProperty(bean, "stringArray", new java.util.Date[] {testUtilDate});
        } catch (final Throwable t) {
            fail("Threw " + t);
        }
        assertEquals("java.util.Date[] --> String[] length", 1, bean.getStringArray().length);
        assertEquals("java.util.Date[] --> String[] value ", testStringDate, bean.getStringArray()[0]);
    }

    /**
     * Test {@code setProperty()} converting to a String on indexed property
     */
    @Override
    public void testSetPropertyConvertToStringIndexed() {
        try {
            bean.setStringArray(new String[1]);
            BeanUtils.setProperty(bean, "stringArray[0]", testUtilDate);
        } catch (final Throwable t) {
            fail("Threw " + t);
        }
        assertEquals("java.util.Date --> String[]", testStringDate, bean.getStringArray()[0]);
    }

}
