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