1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2011, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 * Copyright (C) 2010 , Yahoo! Inc.
6 ********************************************************************/
7
8#include "unicode/utypes.h"
9
10#if !UCONFIG_NO_FORMATTING
11
12#include "selfmts.h"
13#include "cmemory.h"
14#include "unicode/selfmt.h"
15
16#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
17
18#define SIMPLE_PATTERN_STRING                                                    "feminine {feminineVerbValue} other{otherVerbValue}"
19
20
21#define SELECT_PATTERN_DATA 4
22#define SELECT_SYNTAX_DATA 10
23#define EXP_FORMAT_RESULT_DATA 12
24#define NUM_OF_FORMAT_ARGS 3
25
26#define VERBOSE_INT(x) {logln("%s:%d:  int %s=%d\n", __FILE__, __LINE__, #x, (x));}
27#define VERBOSE_USTRING(text) {logln("%s:%d: UnicodeString %s(%d) = ", __FILE__, __LINE__, #text, text.length()); logln(UnicodeString(" \"")+text+UnicodeString("\";"));}
28
29
30void SelectFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
31{
32    if (exec) logln("TestSuite SelectFormat");
33    switch (index) {
34        TESTCASE(0, selectFormatAPITest);
35        TESTCASE(1, selectFormatUnitTest);
36        default: name = "";
37            break;
38    }
39}
40
41/**
42 * Unit tests of SelectFormat class.
43 */
44void SelectFormatTest::selectFormatUnitTest(/*char *par*/)
45{
46  const UnicodeString SIMPLE_PATTERN(SIMPLE_PATTERN_STRING); /* Don't static init this! */
47
48    UnicodeString patternTestData[SELECT_PATTERN_DATA] = {
49        UNICODE_STRING_SIMPLE("fem {femValue} other{even}"),
50        UNICODE_STRING_SIMPLE("other{odd or even}"),
51        UNICODE_STRING_SIMPLE("odd{The number {0, number, integer} is odd.}other{The number {0, number, integer} is even.}"),
52        UNICODE_STRING_SIMPLE("odd{The number {1} is odd}other{The number {1} is even}"),
53    };
54
55    UnicodeString formatArgs[NUM_OF_FORMAT_ARGS] = {
56        UNICODE_STRING_SIMPLE("fem"),
57        UNICODE_STRING_SIMPLE("other"),
58        UNICODE_STRING_SIMPLE("odd")
59    };
60
61    UnicodeString expFormatResult[][NUM_OF_FORMAT_ARGS] = {
62        {
63            UNICODE_STRING_SIMPLE("femValue"),
64            UNICODE_STRING_SIMPLE("even"),
65            UNICODE_STRING_SIMPLE("even")
66        },
67        {
68            UNICODE_STRING_SIMPLE("odd or even"),
69            UNICODE_STRING_SIMPLE("odd or even"),
70            UNICODE_STRING_SIMPLE("odd or even"),
71        },
72        {
73            UNICODE_STRING_SIMPLE("The number {0, number, integer} is even."),
74            UNICODE_STRING_SIMPLE("The number {0, number, integer} is even."),
75            UNICODE_STRING_SIMPLE("The number {0, number, integer} is odd."),
76        },
77        {
78            UNICODE_STRING_SIMPLE("The number {1} is even"),
79            UNICODE_STRING_SIMPLE("The number {1} is even"),
80            UNICODE_STRING_SIMPLE("The number {1} is odd"),
81        }
82    };
83
84    UnicodeString checkSyntaxData[SELECT_SYNTAX_DATA] = {
85        UNICODE_STRING_SIMPLE("odd{foo}"),
86        UNICODE_STRING_SIMPLE("*odd{foo} other{bar}"),
87        UNICODE_STRING_SIMPLE("odd{foo},other{bar}"),
88        UNICODE_STRING_SIMPLE("od d{foo} other{bar}"),
89        UNICODE_STRING_SIMPLE("odd{foo}{foobar}other{foo}"),
90        UNICODE_STRING_SIMPLE("odd{foo1}other{foo2}}"),
91        UNICODE_STRING_SIMPLE("odd{foo1}other{{foo2}"),
92        UNICODE_STRING_SIMPLE("odd{fo{o1}other{foo2}}")
93    };
94
95    UErrorCode status = U_ZERO_ERROR;
96    VERBOSE_USTRING(SIMPLE_PATTERN);
97    SelectFormat* selFmt = new SelectFormat( SIMPLE_PATTERN , status);
98    if (U_FAILURE(status)) {
99        dataerrln("ERROR: SelectFormat Unit Test constructor failed in unit tests.- exitting");
100        return;
101    }
102
103    // ======= Test SelectFormat pattern syntax.
104    logln("SelectFormat Unit Test : Testing SelectFormat pattern syntax.");
105    for (int32_t i=0; i<SELECT_SYNTAX_DATA; ++i) {
106        status = U_ZERO_ERROR;
107        VERBOSE_INT(i);
108        VERBOSE_USTRING(checkSyntaxData[i]);
109        selFmt->applyPattern(checkSyntaxData[i], status);
110        if (U_SUCCESS(status)){
111            errln("\nERROR: Unexpected result - SelectFormat Unit Test failed to detect syntax error with pattern: "+checkSyntaxData[i]);
112        }
113    }
114
115    // ICU 4.8 does not check for duplicate keywords any more.
116    status = U_ZERO_ERROR;
117    selFmt->applyPattern("odd{foo} odd{bar} other{foobar}", status);
118    FieldPosition format_ignore(FieldPosition::DONT_CARE);
119    UnicodeString format_result;
120    selFmt->format(UnicodeString("odd"), format_result, format_ignore, status);
121    assertEquals("should use first occurrence of the 'odd' keyword", "foo", format_result);
122    format_result.remove();
123    selFmt->applyPattern("odd{foo} other{bar} other{foobar}", status);
124    selFmt->format(UnicodeString("other"), format_result, format_ignore, status);
125    assertEquals("should use first occurrence of the 'other' keyword", "bar", format_result);
126
127    delete selFmt;
128    selFmt = NULL;
129
130    logln("SelectFormat Unit Test : Creating format object for Testing applying various patterns");
131    status = U_ZERO_ERROR;
132    selFmt = new SelectFormat( SIMPLE_PATTERN , status);
133    //SelectFormat* selFmt1 = new SelectFormat( SIMPLE_PATTERN , status);
134    if (U_FAILURE(status)) {
135        errln("ERROR: SelectFormat Unit Test constructor failed in unit tests.- exitting");
136        return;
137    }
138
139    // ======= Test applying and formatting with various pattern
140    logln("SelectFormat Unit test: Testing  applyPattern() and format() ...");
141    UnicodeString result;
142    FieldPosition ignore(FieldPosition::DONT_CARE);
143
144    for(int32_t i=0; i<SELECT_PATTERN_DATA; ++i) {
145        status = U_ZERO_ERROR;
146        selFmt->applyPattern(patternTestData[i], status);
147        if (U_FAILURE(status)) {
148            errln("ERROR: SelectFormat Unit Test failed to apply pattern- "+patternTestData[i] );
149            continue;
150        }
151
152        //Format with the keyword array
153        for(int32_t j=0; j<3; j++) {
154            result.remove();
155            selFmt->format( formatArgs[j], result , ignore , status);
156            if (U_FAILURE(status)) {
157                errln("ERROR: SelectFormat Unit test failed in format() with argument: "+ formatArgs[j] + " and error is " + u_errorName(status) );
158            }else{
159                if( result != expFormatResult[i][j] ){
160                    errln("ERROR: SelectFormat Unit test failed in format() with unexpected result\n  with argument: "+ formatArgs[j] + "\n result obtained: " + result + "\n and expected is: " + expFormatResult[i][j] );
161                }
162            }
163        }
164    }
165
166    //Test with an invalid keyword
167    // one which contains Pattern_Syntax or Pattern_White_Space.
168    logln("SelectFormat Unit test: Testing  format() with keyword method and with invalid keywords...");
169    status = U_ZERO_ERROR;
170    result.remove();
171    UnicodeString keywords[] = {
172        "9Keyword-_",
173        "-Keyword-_",
174        "_Keyword-_",
175        "\\u00E9Keyword-_",
176        "Key word-_",
177        " Keyword-_",
178        "Key*word-_",
179        "*Keyword-_"
180    };
181
182    delete selFmt;
183    selFmt = NULL;
184
185    selFmt = new SelectFormat( SIMPLE_PATTERN , status);
186    for (int32_t i = 0; i < LENGTHOF(keywords); i++ ){
187        status = U_ZERO_ERROR;
188        selFmt->format( keywords[i], result , ignore , status);
189        if (!U_FAILURE(status)) {
190            errln("ERROR: SelectFormat Unit test failed in format() with keyWord and with an invalid keyword as : "+
191                  keywords[i]+" ("+u_errorName(status)+")");
192        }
193    }
194
195    delete selFmt;
196}
197
198/**
199 * Test various generic API methods of SelectFormat for Basic API usage.
200 * This is to make sure the API test coverage is 100% .
201 */
202void SelectFormatTest::selectFormatAPITest(/*char *par*/)
203{
204  const UnicodeString SIMPLE_PATTERN(SIMPLE_PATTERN_STRING); /* Don't static init this! */
205    int numOfConstructors =3;
206    UErrorCode status[3];
207    SelectFormat* selFmt[3] = { NULL, NULL, NULL };
208
209    // ========= Test constructors
210    logln("SelectFormat API test: Testing SelectFormat constructors ...");
211    for (int32_t i=0; i< numOfConstructors; ++i) {
212        status[i] = U_ZERO_ERROR;
213    }
214
215    selFmt[0]= new SelectFormat(SIMPLE_PATTERN, status[0]);
216    if ( U_FAILURE(status[0]) ) {
217      errln("ERROR: SelectFormat API test constructor with pattern and status failed! with %s\n", u_errorName(status[0]));
218        return;
219    }
220
221    // =========== Test copy constructor
222    logln("SelectFormat API test: Testing copy constructor and == operator ...");
223    SelectFormat fmt = *selFmt[0];
224    SelectFormat* dupPFmt = new SelectFormat(fmt);
225    if ((*selFmt[0]) != (*dupPFmt)) {
226        errln("ERROR: SelectFormat API test Failed in copy constructor or == operator!");
227    }
228    delete dupPFmt;
229
230    // ======= Test clone && == operator.
231    logln("SelectFormat API test: Testing clone and == operator ...");
232    if ( U_SUCCESS(status[0])  ) {
233        selFmt[1] = (SelectFormat*)selFmt[0]->clone();
234        if (selFmt[1]!=NULL) {
235            if ( *selFmt[1] != *selFmt[0] ) {
236                errln("ERROR: SelectFormat API test clone test failed!");
237            }
238        } else {
239          errln("ERROR: SelectFormat API test clone test failed with NULL!");
240          return;
241        }
242    } else {
243      errln("ERROR: could not create [0]: %s\n", u_errorName(status[0]));
244      return;
245    }
246
247    // ======= Test assignment operator && == operator.
248    logln("SelectFormat API test: Testing assignment operator and == operator ...");
249    selFmt[2]= new SelectFormat(SIMPLE_PATTERN, status[2]);
250    if ( U_SUCCESS(status[2]) ) {
251        *selFmt[1] = *selFmt[2];
252        if (selFmt[1]!=NULL) {
253            if ( (*selFmt[1] != *selFmt[2]) ) {
254                errln("ERROR: SelectFormat API test assignment operator test failed!");
255            }
256        }
257        delete selFmt[1];
258    }
259    else {
260         errln("ERROR: SelectFormat constructor failed in assignment operator!");
261    }
262    delete selFmt[0];
263    delete selFmt[2];
264
265    // ======= Test getStaticClassID() and getStaticClassID()
266    logln("SelectFormat API test: Testing getStaticClassID() and getStaticClassID() ...");
267    UErrorCode status1 = U_ZERO_ERROR;
268    SelectFormat* selFmt1 = new SelectFormat( SIMPLE_PATTERN , status1);
269    if( U_FAILURE(status1)) {
270        errln("ERROR: SelectFormat constructor failed in staticClassID test! Exitting");
271        return;
272    }
273
274    logln("Testing getStaticClassID()");
275    if(selFmt1->getDynamicClassID() !=SelectFormat::getStaticClassID()) {
276        errln("ERROR: SelectFormat API test getDynamicClassID() didn't return the expected value");
277    }
278
279    // ======= Test applyPattern() and toPattern()
280    logln("SelectFormat API test: Testing applyPattern() and toPattern() ...");
281    UnicodeString pattern = UnicodeString("masculine{masculineVerbValue} other{otherVerbValue}");
282    status1 = U_ZERO_ERROR;
283    selFmt1->applyPattern( pattern, status1);
284    if (U_FAILURE(status1)) {
285        errln("ERROR: SelectFormat API test failed in applyPattern() with pattern: "+ pattern);
286    }else{
287        UnicodeString checkPattern;
288        selFmt1->toPattern( checkPattern);
289        if( checkPattern != pattern ){
290            errln("ERROR: SelectFormat API test failed in toPattern() with unexpected result with pattern: "+ pattern);
291        }
292    }
293
294    // ======= Test different format() methods
295    logln("SelectFormat API test: Testing  format() with keyword method ...");
296    status1 = U_ZERO_ERROR;
297    UnicodeString result;
298    FieldPosition ignore(FieldPosition::DONT_CARE);
299    UnicodeString keyWord = UnicodeString("masculine");
300
301    selFmt1->format( keyWord, result , ignore , status1);
302    if (U_FAILURE(status1)) {
303        errln("ERROR: SelectFormat API test failed in format() with keyWord: "+ keyWord);
304    }else{
305        UnicodeString expected=UnicodeString("masculineVerbValue");
306        if( result != expected ){
307            errln("ERROR: SelectFormat API test failed in format() with unexpected result with keyWord: "+ keyWord);
308        }
309    }
310
311    logln("SelectFormat API test: Testing  format() with Formattable obj method ...");
312    status1 = U_ZERO_ERROR;
313    result.remove();
314    UnicodeString result1;
315    Formattable testArgs = Formattable("other");
316    selFmt1->format( testArgs, result1 , ignore , status1);
317    if (U_FAILURE(status1)) {
318        errln("ERROR: SelectFormat API test failed in format() with Formattable");
319    }else{
320        UnicodeString expected=UnicodeString("otherVerbValue");
321        if( result1 != expected ){
322            errln("ERROR: SelectFormat API test failed in format() with unexpected result with Formattable");
323        }
324    }
325
326
327    delete selFmt1;
328}
329#endif /* #if !UCONFIG_NO_FORMATTING */
330