// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (c) 2004-2011, International Business Machines
 * Corporation and others.  All Rights Reserved.
 * Copyright (C) 2010 , Yahoo! Inc.
 *******************************************************************************
 */
package com.ibm.icu.dev.test.format;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.text.SelectFormat;

/**
 * @author kirtig
 * This class does the unit testing for the SelectFormat
 */
@RunWith(JUnit4.class)
public class SelectFormatUnitTest extends TestFmwk {

    static final String SIMPLE_PATTERN = "feminine {feminineVerbValue} other{otherVerbValue}";

    /**
     * Unit tests for pattern syntax
     */
    @Test
    public void TestPatternSyntax() {
        String checkSyntaxData[] = {
            "odd{foo}",
            "*odd{foo} other{bar}",
            "odd{foo},other{bar}",
            "od d{foo} other{bar}",
            "odd{foo}{foobar}other{foo}",
            "odd{foo1}other{foo2}}",
            "odd{foo1}other{{foo2}",
            "odd{fo{o1}other{foo2}}"
        };

        //Test SelectFormat pattern syntax
        SelectFormat selFmt = new SelectFormat(SIMPLE_PATTERN);
        for (int i=0; i<checkSyntaxData.length; ++i) {
            try {
                selFmt.applyPattern(checkSyntaxData[i]);
                errln("\nERROR: Unexpected result - SelectFormat Unit Test failed "
                      + "to detect syntax error with pattern: "+checkSyntaxData[i]);
            } catch (IllegalArgumentException e){
                // ok
                continue;
            }
        }

        // ICU 4.8 does not check for duplicate keywords any more.
        selFmt.applyPattern("odd{foo} odd{bar} other{foobar}");
        assertEquals("should use first occurrence of the 'odd' keyword", "foo", selFmt.format("odd"));
        selFmt.applyPattern("odd{foo} other{bar} other{foobar}");
        assertEquals("should use first occurrence of the 'other' keyword", "bar", selFmt.format("other"));
    }

    /**
     * Unit tests for invalid keywords
     */
    @Test
    public void TestInvalidKeyword() {
        // Test formatting with invalid keyword:
        // one which contains Pattern_Syntax or Pattern_White_Space.
        String keywords[] = {
            "9Keyword-_",
            "-Keyword-_",
            "_Keyword-_",
            "\\u00E9Keyword-_",
            "Key word",
            " Keyword",
            "Keyword ",
            "Key*word-_",
            "*Keyword-_"
        };

        String expected = "Invalid formatting argument.";
        SelectFormat selFmt = new SelectFormat(SIMPLE_PATTERN);
        for (int i = 0; i< 6; i++ ){
            try {
                selFmt.format( keywords[i]);
                fail("Error:TestInvalidKeyword failed to detect invalid keyword "
                     + "for keyword: " + keywords[i]  );
            } catch (IllegalArgumentException e){
                assertEquals("Error:TestInvalidKeyword failed with unexpected "
                            +"error message for keyword: " + keywords[i]
                            , expected , e.getMessage() );
                continue;
            }
        }

    }

    /**
     * API tests for  applyPattern and format
     */
    @Test
    public void TestApplyFormat() {
        //Test applying and formatting with various pattern
        String patternTestData[] = {
            "fem {femValue} other{even}",
            "other{odd or even}",
            "odd{The number {0, number, integer} is odd.}other{The number {0, number, integer} is even.}",
            "odd{The number {1} is odd}other{The number {1} is even}"
        };

        String formatArgs[] = {
            "fem",
            "other",
            "odd"
        };

        String expFormatResult[][] = {
            {
                "femValue",
                "even",
                "even",
            },
            {
                "odd or even",
            "odd or even",
            "odd or even",
            },
            {
                "The number {0, number, integer} is even.",
                "The number {0, number, integer} is even.",
                "The number {0, number, integer} is odd.",
            },
            {
                "The number {1} is even",
                "The number {1} is even",
                "The number {1} is odd",
            }
        };

        log("SelectFormat Unit test: Testing  applyPattern() and format() ...");
        SelectFormat selFmt = new SelectFormat(SIMPLE_PATTERN);

        for (int i=0; i<patternTestData.length; ++i) {
            try {
                selFmt.applyPattern(patternTestData[i]);
            } catch (IllegalArgumentException e){
                errln("ERROR: SelectFormat Unit Test failed to apply pattern- "
                     + patternTestData[i] );
                continue;
            }

            //Format with the keyword array
            for (int j=0; j<3; j++) {
                assertEquals("ERROR: SelectFormat Unit test failed in format() with unexpected result", selFmt.format(formatArgs[j]) ,expFormatResult[i][j] );
            }
        }
    }

}

