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

/**
 * <p>Test Case for the {@code MappedPropertyDescriptor}.</p>
 *
 */
public class MappedPropertyTestCase extends TestCase {

    

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

    

    /**
     * Run this Test
     */
    public static void main(final String[] args) {
      junit.textui.TestRunner.run(suite());
    }

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

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

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

    

    /**
     * Test valid method name
     */
    public void testFound() {
        final String property = "mapproperty";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNotNull("Getter is missing", desc.getMappedReadMethod());
            assertNotNull("Setter is missing", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test boolean "is" method name
     */
    public void testBooleanMapped() {
        final String property = "mappedBoolean";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNotNull("Getter is missing", desc.getMappedReadMethod());
            assertNotNull("Setter is missing", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test invalid method name
     */
    public void testNotFound() {
        final String property = "xxxxxxx";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            new MappedPropertyDescriptor(property, clazz);
            fail("Property '" + property + "' found in " + clazz.getName());
        } catch (final Exception ex) {
            // expected result
        }
    }

    /**
     * Test Mapped Property - Getter only
     */
    public void testMappedGetterOnly() {
        final String property = "mappedGetterOnly";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNotNull("Getter is missing", desc.getMappedReadMethod());
            assertNull("Setter is found", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test Mapped Property - Setter Only
     */
    public void testMappedSetterOnly() {
        final String property = "mappedSetterOnly";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNull("Getter is found", desc.getMappedReadMethod());
            assertNotNull("Setter is missing", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test Mapped Property - Invalid Setter
     */
    public void testInvalidSetter() {
        final String property = "invalidSetter";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNotNull("Getter is missing", desc.getMappedReadMethod());
            assertNull("Setter is found", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test Mapped Property - Invalid Getter
     */
    public void testInvalidGetter() {
        final String property = "invalidGetter";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNull("Getter is found", desc.getMappedReadMethod());
            assertNotNull("Setter is missing", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test Mapped Property - Different Types
     *
     * Expect to find the getDifferentTypes() method, but not
     * the setDifferentTypes() method because setDifferentTypes()
     * sets and Integer, while getDifferentTypes() returns a Long.
     */
    public void testDifferentTypes() {
        final String property = "differentTypes";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNotNull("Getter is missing", desc.getMappedReadMethod());
            assertNull("Setter is found", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test Map getter
     */
    public void testMapGetter() {
        final MappedPropertyTestBean bean = new MappedPropertyTestBean();
        try {
            final String testValue = "test value";
            final String testKey   = "testKey";
            BeanUtils.setProperty(bean, "myMap("+testKey+")", "test value");
            assertEquals("Map getter", testValue, bean.getMyMap().get(testKey));
        } catch (final Exception ex) {
            fail("Test set mapped property failed: " + ex);
        }
    }


    /**
     * Test property with any two args
     */
    public void testAnyArgsProperty() {
        final String property = "anyMapped";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNull("Getter is found", desc.getMappedReadMethod());
            assertNotNull("Setter is missing", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test property with two primitive args
     */
    public void testPrimitiveArgsProperty() {
        final String property = "mappedPrimitive";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNull("Getter is found", desc.getMappedReadMethod());
            assertNotNull("Setter is missing", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test 'protected' mapped property
     */
    public void testProtected() {
        final String property = "protectedProperty";
        final Class<?> clazz = MappedPropertyTestBean.class;
        try {
            new MappedPropertyDescriptor(property, clazz);
            fail("Property '" + property + "' found in " + clazz.getName());
        } catch (final Exception ex) {
            // expected result
        }
    }


    /**
     * Test 'public' method in parent
     */
    public void testPublicParentMethod() {
        final String property = "mapproperty";
        final Class<?> clazz = MappedPropertyChildBean.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNotNull("Getter is missing", desc.getMappedReadMethod());
            assertNotNull("Setter is missing", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test 'protected' method in parent
     */
    public void testProtectedParentMethod() {
        final String property = "protectedMapped";
        final Class<?> clazz = MappedPropertyChildBean.class;
        try {
            new MappedPropertyDescriptor(property, clazz);
            fail("Property '" + property + "' found in " + clazz.getName());
        } catch (final Exception ex) {
        }
    }


    /**
     * Test Interface with mapped property
     */
    public void testInterfaceMapped() {
        final String property = "mapproperty";
        final Class<?> clazz = MappedPropertyTestInterface.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNotNull("Getter is missing", desc.getMappedReadMethod());
            assertNotNull("Setter is missing", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }

    /**
     * Test property not found in interface
     */
    public void testInterfaceNotFound() {
        final String property = "XXXXXX";
        final Class<?> clazz = MappedPropertyTestInterface.class;
        try {
            new MappedPropertyDescriptor(property, clazz);
            fail("Property '" + property + "' found in " + clazz.getName());
        } catch (final Exception ex) {
        }
    }

    /**
     * Test Interface Inherited mapped property
     */
    public void testChildInterfaceMapped() {
        final String property = "mapproperty";
        final Class<?> clazz = MappedPropertyChildInterface.class;
        try {
            final MappedPropertyDescriptor desc
                = new MappedPropertyDescriptor(property, clazz);
            assertNotNull("Getter is missing", desc.getMappedReadMethod());
            assertNotNull("Setter is missing", desc.getMappedWriteMethod());
        } catch (final Exception ex) {
            fail("Property '" + property + "' Not Found in " + clazz.getName() + ": " + ex);
        }
    }
}