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

import org.apache.commons.beanutils2.ConversionException;

import junit.framework.TestCase;

/**
 */
public class BooleanConverterTestCase extends TestCase {

    public static final String[] STANDARD_TRUES = new String[] {
            "yes", "y", "true", "on", "1"
        };

    public static final String[] STANDARD_FALSES = new String[] {
            "no", "n", "false", "off", "0"
        };


    public BooleanConverterTestCase(final String name) {
        super(name);
    }

    public void testAdditionalStrings() {
        final String[] trueStrings = {"sure"};
        final String[] falseStrings = {"nope"};
        final BooleanConverter converter = new BooleanConverter(
            trueStrings, falseStrings);
        testConversionValues(
            converter,
            new String[] {"sure", "Sure"},
            new String[] {"nope", "nOpE"});

        try {
            converter.convert(Boolean.class, "true");
            fail("Converting obsolete true value should have generated an exception");
        } catch (final ConversionException expected) {
            // Exception is successful test
        }
        try {
            converter.convert(Boolean.class, "bogus");
            fail("Converting invalid string should have generated an exception");
        } catch (final ConversionException expected) {
            // Exception is successful test
        }
    }

    public void testCaseInsensitivity() {
        final BooleanConverter converter = new BooleanConverter();
        testConversionValues(
            converter,
            new String[] {"Yes", "TRUE"},
            new String[] {"NO", "fAlSe"});
    }


    /**
     * Tests a conversion to another target type. This should not be possible.
     */
    public void testConversionToOtherType() {
        final BooleanConverter converter = new BooleanConverter();
        try {
            converter.convert(Integer.class, STANDARD_TRUES[0]);
            fail("Could convert to unsupported type!");
        } catch (final ConversionException cex) {
            // Expected result
        }
    }

    protected void testConversionValues(final BooleanConverter converter,
            final String[] trueValues, final String[] falseValues) {

        for (final String trueValue : trueValues) {
            assertEquals(Boolean.TRUE, converter.convert(Boolean.class, trueValue));
        }
        for (final String falseValue : falseValues) {
            assertEquals(Boolean.FALSE, converter.convert(Boolean.class, falseValue));
        }
    }

    public void testDefaultValue() {
        final Object defaultValue = Boolean.TRUE;
        final BooleanConverter converter = new BooleanConverter(defaultValue);

        assertSame(defaultValue, converter.convert(Boolean.class, "bogus"));
        testConversionValues(converter, STANDARD_TRUES, STANDARD_FALSES);
    }

    public void testInvalidString() {
        final BooleanConverter converter = new BooleanConverter();
        try {
            converter.convert(Boolean.class, "bogus");
            fail("Converting invalid string should have generated an exception");
        } catch (final ConversionException expected) {
            // Exception is successful test
        }
    }

    /**
     * Tests whether a conversion to a primitive boolean is possible.
     */
    public void testPrimitiveTargetClass() {
        final BooleanConverter converter = new BooleanConverter();
        assertTrue("Wrong result", converter.convert(Boolean.TYPE, STANDARD_TRUES[0]));
    }

    public void testStandardValues() {
        final BooleanConverter converter = new BooleanConverter();
        testConversionValues(converter, STANDARD_TRUES, STANDARD_FALSES);
    }

}
