1 /********************************************************************
2  * COPYRIGHT:
3  * Copyright (c) 1997-2014, 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 SIMPLE_PATTERN_STRING                                                    "feminine {feminineVerbValue} other{otherVerbValue}"
17 
18 
19 #define SELECT_PATTERN_DATA 4
20 #define SELECT_SYNTAX_DATA 10
21 #define EXP_FORMAT_RESULT_DATA 12
22 #define NUM_OF_FORMAT_ARGS 3
23 
24 #define VERBOSE_INT(x) {logln("%s:%d:  int %s=%d\n", __FILE__, __LINE__, #x, (x));}
25 #define VERBOSE_USTRING(text) {logln("%s:%d: UnicodeString %s(%d) = ", __FILE__, __LINE__, #text, text.length()); logln(UnicodeString(" \"")+text+UnicodeString("\";"));}
26 
27 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)28 void SelectFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
29 {
30     if (exec) logln("TestSuite SelectFormat");
31     switch (index) {
32         TESTCASE(0, selectFormatAPITest);
33         TESTCASE(1, selectFormatUnitTest);
34         default: name = "";
35             break;
36     }
37 }
38 
39 /**
40  * Unit tests of SelectFormat class.
41  */
selectFormatUnitTest()42 void SelectFormatTest::selectFormatUnitTest(/*char *par*/)
43 {
44   const UnicodeString SIMPLE_PATTERN(SIMPLE_PATTERN_STRING); /* Don't static init this! */
45 
46     UnicodeString patternTestData[SELECT_PATTERN_DATA] = {
47         UNICODE_STRING_SIMPLE("fem {femValue} other{even}"),
48         UNICODE_STRING_SIMPLE("other{odd or even}"),
49         UNICODE_STRING_SIMPLE("odd{The number {0, number, integer} is odd.}other{The number {0, number, integer} is even.}"),
50         UNICODE_STRING_SIMPLE("odd{The number {1} is odd}other{The number {1} is even}"),
51     };
52 
53     UnicodeString formatArgs[NUM_OF_FORMAT_ARGS] = {
54         UNICODE_STRING_SIMPLE("fem"),
55         UNICODE_STRING_SIMPLE("other"),
56         UNICODE_STRING_SIMPLE("odd")
57     };
58 
59     UnicodeString expFormatResult[][NUM_OF_FORMAT_ARGS] = {
60         {
61             UNICODE_STRING_SIMPLE("femValue"),
62             UNICODE_STRING_SIMPLE("even"),
63             UNICODE_STRING_SIMPLE("even")
64         },
65         {
66             UNICODE_STRING_SIMPLE("odd or even"),
67             UNICODE_STRING_SIMPLE("odd or even"),
68             UNICODE_STRING_SIMPLE("odd or even"),
69         },
70         {
71             UNICODE_STRING_SIMPLE("The number {0, number, integer} is even."),
72             UNICODE_STRING_SIMPLE("The number {0, number, integer} is even."),
73             UNICODE_STRING_SIMPLE("The number {0, number, integer} is odd."),
74         },
75         {
76             UNICODE_STRING_SIMPLE("The number {1} is even"),
77             UNICODE_STRING_SIMPLE("The number {1} is even"),
78             UNICODE_STRING_SIMPLE("The number {1} is odd"),
79         }
80     };
81 
82     UnicodeString checkSyntaxData[SELECT_SYNTAX_DATA] = {
83         UNICODE_STRING_SIMPLE("odd{foo}"),
84         UNICODE_STRING_SIMPLE("*odd{foo} other{bar}"),
85         UNICODE_STRING_SIMPLE("odd{foo},other{bar}"),
86         UNICODE_STRING_SIMPLE("od d{foo} other{bar}"),
87         UNICODE_STRING_SIMPLE("odd{foo}{foobar}other{foo}"),
88         UNICODE_STRING_SIMPLE("odd{foo1}other{foo2}}"),
89         UNICODE_STRING_SIMPLE("odd{foo1}other{{foo2}"),
90         UNICODE_STRING_SIMPLE("odd{fo{o1}other{foo2}}")
91     };
92 
93     UErrorCode status = U_ZERO_ERROR;
94     VERBOSE_USTRING(SIMPLE_PATTERN);
95     SelectFormat* selFmt = new SelectFormat( SIMPLE_PATTERN , status);
96     if (U_FAILURE(status)) {
97         dataerrln("ERROR: SelectFormat Unit Test constructor failed in unit tests.- exitting");
98         return;
99     }
100 
101     // ======= Test SelectFormat pattern syntax.
102     logln("SelectFormat Unit Test : Testing SelectFormat pattern syntax.");
103     for (int32_t i=0; i<SELECT_SYNTAX_DATA; ++i) {
104         status = U_ZERO_ERROR;
105         VERBOSE_INT(i);
106         VERBOSE_USTRING(checkSyntaxData[i]);
107         selFmt->applyPattern(checkSyntaxData[i], status);
108         if (U_SUCCESS(status)){
109             errln("\nERROR: Unexpected result - SelectFormat Unit Test failed to detect syntax error with pattern: "+checkSyntaxData[i]);
110         }
111     }
112 
113     // ICU 4.8 does not check for duplicate keywords any more.
114     status = U_ZERO_ERROR;
115     selFmt->applyPattern("odd{foo} odd{bar} other{foobar}", status);
116     FieldPosition format_ignore(FieldPosition::DONT_CARE);
117     UnicodeString format_result;
118     selFmt->format(UnicodeString("odd"), format_result, format_ignore, status);
119     assertEquals("should use first occurrence of the 'odd' keyword", "foo", format_result);
120     format_result.remove();
121     selFmt->applyPattern("odd{foo} other{bar} other{foobar}", status);
122     selFmt->format(UnicodeString("other"), format_result, format_ignore, status);
123     assertEquals("should use first occurrence of the 'other' keyword", "bar", format_result);
124 
125     delete selFmt;
126     selFmt = NULL;
127 
128     logln("SelectFormat Unit Test : Creating format object for Testing applying various patterns");
129     status = U_ZERO_ERROR;
130     selFmt = new SelectFormat( SIMPLE_PATTERN , status);
131     //SelectFormat* selFmt1 = new SelectFormat( SIMPLE_PATTERN , status);
132     if (U_FAILURE(status)) {
133         errln("ERROR: SelectFormat Unit Test constructor failed in unit tests.- exitting");
134         return;
135     }
136 
137     // ======= Test applying and formatting with various pattern
138     logln("SelectFormat Unit test: Testing  applyPattern() and format() ...");
139     UnicodeString result;
140     FieldPosition ignore(FieldPosition::DONT_CARE);
141 
142     for(int32_t i=0; i<SELECT_PATTERN_DATA; ++i) {
143         status = U_ZERO_ERROR;
144         selFmt->applyPattern(patternTestData[i], status);
145         if (U_FAILURE(status)) {
146             errln("ERROR: SelectFormat Unit Test failed to apply pattern- "+patternTestData[i] );
147             continue;
148         }
149 
150         //Format with the keyword array
151         for(int32_t j=0; j<3; j++) {
152             result.remove();
153             selFmt->format( formatArgs[j], result , ignore , status);
154             if (U_FAILURE(status)) {
155                 errln("ERROR: SelectFormat Unit test failed in format() with argument: "+ formatArgs[j] + " and error is " + u_errorName(status) );
156             }else{
157                 if( result != expFormatResult[i][j] ){
158                     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] );
159                 }
160             }
161         }
162     }
163 
164     //Test with an invalid keyword
165     // one which contains Pattern_Syntax or Pattern_White_Space.
166     logln("SelectFormat Unit test: Testing  format() with keyword method and with invalid keywords...");
167     status = U_ZERO_ERROR;
168     result.remove();
169     UnicodeString keywords[] = {
170         "9Keyword-_",
171         "-Keyword-_",
172         "_Keyword-_",
173         "\\u00E9Keyword-_",
174         "Key word-_",
175         " Keyword-_",
176         "Key*word-_",
177         "*Keyword-_"
178     };
179 
180     delete selFmt;
181     selFmt = NULL;
182 
183     selFmt = new SelectFormat( SIMPLE_PATTERN , status);
184     for (int32_t i = 0; i < UPRV_LENGTHOF(keywords); i++ ){
185         status = U_ZERO_ERROR;
186         selFmt->format( keywords[i], result , ignore , status);
187         if (!U_FAILURE(status)) {
188             errln("ERROR: SelectFormat Unit test failed in format() with keyWord and with an invalid keyword as : "+
189                   keywords[i]+" ("+u_errorName(status)+")");
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  */
selectFormatAPITest()200 void 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