/*
 * Copyright (C) 2009 The Android Open Source Project
 * 
 * Licensed 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 java.util;

import java.math.BigDecimal;
import junit.framework.Test;
import junit.framework.TestSuite;

public class FormatterTest extends junit.framework.TestCase {
    // http://b/2301938
    public void test_uppercaseConversions() throws Exception {
        // In most locales, the upper-case equivalent of "i" is "I".
        assertEquals("JAKOB ARJOUNI", String.format(Locale.US, "%S", "jakob arjouni"));
        // In Turkish-language locales, there's a dotted capital "i".
        assertEquals("JAKOB ARJOUN\u0130", String.format(new Locale("tr", "TR"), "%S", "jakob arjouni"));
    }

    // Creating a NumberFormat is expensive, so we like to reuse them, but we need to be careful
    // because they're mutable.
    public void test_NumberFormat_reuse() throws Exception {
        assertEquals("7.000000 7", String.format("%.6f %d", 7.0, 7));
    }

    public void test_formatNull() throws Exception {
        // We fast-path %s and %d (with no configuration) but need to make sure we handle the
        // special case of the null argument...
        assertEquals("null", String.format(Locale.US, "%s", (String) null));
        assertEquals("null", String.format(Locale.US, "%d", (Integer) null));
        // ...without screwing up conversions that don't take an argument.
        assertEquals("%", String.format(Locale.US, "%%"));
    }
    
    // Alleged regression tests for historical bugs. (It's unclear whether the bugs were in
    // BigDecimal or Formatter.)
    public void test_BigDecimalFormatting() throws Exception {
        BigDecimal[] input = new BigDecimal[] {
            new BigDecimal("20.00000"),
            new BigDecimal("20.000000"),
            new BigDecimal(".2"),
            new BigDecimal("2"),
            new BigDecimal("-2"),
            new BigDecimal("200000000000000000000000"),
            new BigDecimal("20000000000000000000000000000000000000000000000000")
        };
        String[] output = new String[] {
            "20.00",
            "20.00",
            "0.20",
            "2.00",
            "-2.00",
            "200000000000000000000000.00",
            "20000000000000000000000000000000000000000000000000.00"
        };
        for (int i = 0; i < input.length; ++i) {
            String result = String.format("%.2f", input[i]);
            assertEquals("input=\"" + input[i] + "\", " + ",expected=" + output[i] + ",actual=" + result,
                    output[i], result);
        }
    }
}
