1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /***********************************************************************
4  * COPYRIGHT:
5  * Copyright (c) 1997-2016, International Business Machines Corporation
6  * and others. All Rights Reserved.
7  ***********************************************************************/
8 
9 #include "unicode/utypes.h"
10 
11 #if !UCONFIG_NO_FORMATTING
12 
13 #include "intltest.h"
14 #include "tfsmalls.h"
15 #include "cmemory.h"
16 
17 #include "unicode/msgfmt.h"
18 #include "unicode/choicfmt.h"
19 
20 #include "unicode/parsepos.h"
21 #include "unicode/fieldpos.h"
22 #include "unicode/fmtable.h"
23 
24 /*static UBool chkstatus( UErrorCode &status, char* msg = NULL )
25 {
26     UBool ok = (status == U_ZERO_ERROR);
27     if (!ok) it_errln( msg );
28     return ok;
29 }*/
30 
test_ParsePosition(void)31 void test_ParsePosition( void )
32 {
33     ParsePosition* pp1 = new ParsePosition();
34     if (pp1 && (pp1->getIndex() == 0)) {
35         it_logln("PP constructor() tested.");
36     }else{
37         it_errln("*** PP getIndex or constructor() result");
38     }
39     delete pp1;
40 
41 
42     {
43         int32_t to = 5;
44         ParsePosition pp2( to );
45         if (pp2.getIndex() == 5) {
46             it_logln("PP getIndex and constructor(int32_t) tested.");
47         }else{
48             it_errln("*** PP getIndex or constructor(int32_t) result");
49         }
50         pp2.setIndex( 3 );
51         if (pp2.getIndex() == 3) {
52             it_logln("PP setIndex tested.");
53         }else{
54             it_errln("*** PP getIndex or setIndex result");
55         }
56     }
57 
58     ParsePosition pp2, pp3;
59     pp2 = 3;
60     pp3 = 5;
61     ParsePosition pp4( pp3 );
62     if ((pp2 != pp3) && (pp3 == pp4)) {
63         it_logln("PP copy constructor, operator== and operator != tested.");
64     }else{
65         it_errln("*** PP operator== or operator != result");
66     }
67 
68     ParsePosition pp5;
69     pp5 = pp4;
70     if ((pp4 == pp5) && (!(pp4 != pp5))) {
71         it_logln("PP operator= tested.");
72     }else{
73         it_errln("*** PP operator= operator== or operator != result");
74     }
75 
76 
77 }
78 
79 #include "unicode/decimfmt.h"
80 
test_FieldPosition_example(void)81 void test_FieldPosition_example( void )
82 {
83     //***** no error detection yet !!!!!!!
84     //***** this test is for compiler checks and visual verification only.
85     double doubleNum[] = { 123456789.0, -12345678.9, 1234567.89, -123456.789,
86         12345.6789, -1234.56789, 123.456789, -12.3456789, 1.23456789};
87     int32_t dNumSize = UPRV_LENGTHOF(doubleNum);
88 
89     UErrorCode status = U_ZERO_ERROR;
90     DecimalFormat* fmt = (DecimalFormat*) NumberFormat::createInstance(status);
91     if (U_FAILURE(status)) {
92         it_dataerrln("NumberFormat::createInstance() error");
93         return;
94     }
95     fmt->setDecimalSeparatorAlwaysShown(TRUE);
96 
97     const int32_t tempLen = 20;
98     char temp[tempLen];
99 
100     for (int32_t i=0; i<dNumSize; i++) {
101         FieldPosition pos(NumberFormat::INTEGER_FIELD);
102         UnicodeString buf;
103         //char fmtText[tempLen];
104         //ToCharString(fmt->format(doubleNum[i], buf, pos), fmtText);
105         UnicodeString res = fmt->format(doubleNum[i], buf, pos);
106         for (int32_t j=0; j<tempLen; j++) temp[j] = '='; // clear with spaces
107         int32_t tempOffset = (tempLen <= (tempLen - pos.getEndIndex())) ?
108             tempLen : (tempLen - pos.getEndIndex());
109         temp[tempOffset] = '\0';
110         it_logln(UnicodeString("FP ") + UnicodeString(temp) + res);
111     }
112     delete fmt;
113 
114     it_logln("");
115 
116 }
117 
test_FieldPosition(void)118 void test_FieldPosition( void )
119 {
120 
121     FieldPosition fp( 7 );
122 
123     if (fp.getField() == 7) {
124         it_logln("FP constructor(int32_t) and getField tested.");
125     }else{
126         it_errln("*** FP constructor(int32_t) or getField");
127     }
128 
129     FieldPosition* fph = new FieldPosition( 3 );
130     if ( fph->getField() != 3) it_errln("*** FP getField or heap constr.");
131     delete fph;
132 
133     UBool err1 = FALSE;
134     UBool err2 = FALSE;
135     UBool err3 = FALSE;
136     for (int32_t i = -50; i < 50; i++ ) {
137         fp.setField( i+8 );
138         fp.setBeginIndex( i+6 );
139         fp.setEndIndex( i+7 );
140         if (fp.getField() != i+8)  err1 = TRUE;
141         if (fp.getBeginIndex() != i+6) err2 = TRUE;
142         if (fp.getEndIndex() != i+7) err3 = TRUE;
143     }
144     if (!err1) {
145         it_logln("FP setField and getField tested.");
146     }else{
147         it_errln("*** FP setField or getField");
148     }
149     if (!err2) {
150         it_logln("FP setBeginIndex and getBeginIndex tested.");
151     }else{
152         it_errln("*** FP setBeginIndex or getBeginIndex");
153     }
154     if (!err3) {
155         it_logln("FP setEndIndex and getEndIndex tested.");
156     }else{
157         it_errln("*** FP setEndIndex or getEndIndex");
158     }
159 
160     it_logln("");
161 
162 }
163 
test_Formattable(void)164 void test_Formattable( void )
165 {
166     UErrorCode status = U_ZERO_ERROR;
167     Formattable* ftp = new Formattable();
168     if (!ftp || !(ftp->getType() == Formattable::kLong) || !(ftp->getLong() == 0)) {
169         it_errln("*** Formattable constructor or getType or getLong");
170     }
171     delete ftp;
172 
173     Formattable fta, ftb;
174     fta.setLong(1); ftb.setLong(2);
175     if ((fta != ftb) || !(fta == ftb)) {
176         it_logln("FT setLong, operator== and operator!= tested.");
177         status = U_ZERO_ERROR;
178         fta.getLong(&status);
179         if ( status == U_INVALID_FORMAT_ERROR){
180             it_errln("*** FT getLong(UErrorCode* status) failed on real Long");
181         } else {
182             it_logln("FT getLong(UErrorCode* status) tested.");
183         }
184     }else{
185         it_errln("*** Formattable setLong or operator== or !=");
186     }
187     fta = ftb;
188     if ((fta == ftb) || !(fta != ftb)) {
189         it_logln("FT operator= tested.");
190     }else{
191         it_errln("*** FT operator= or operator== or operator!=");
192     }
193 
194     fta.setDouble( 3.0 );
195     if ((fta.getType() == Formattable::kDouble) && (fta.getDouble() == 3.0)) {
196         it_logln("FT set- and getDouble tested.");
197     }else{
198         it_errln("*** FT set- or getDouble");
199     }
200 
201     fta.getDate(status = U_ZERO_ERROR);
202     if (status != U_INVALID_FORMAT_ERROR){
203         it_errln("*** FT getDate with status should fail on non-Date");
204     }
205     fta.setDate( 4.0 );
206     if ((fta.getType() == Formattable::kDate) && (fta.getDate() == 4.0)) {
207         it_logln("FT set- and getDate tested.");
208         status = U_ZERO_ERROR;
209         fta.getDate(status);
210         if ( status == U_INVALID_FORMAT_ERROR){
211             it_errln("*** FT getDate with status failed on real Date");
212         } else {
213             it_logln("FT getDate with status tested.");
214         }
215     }else{
216         it_errln("*** FT set- or getDate");
217     }
218 
219     status = U_ZERO_ERROR;
220     fta.getLong(&status);
221     if (status != U_INVALID_FORMAT_ERROR){
222         it_errln("*** FT getLong(UErrorCode* status) should fail on non-Long");
223     }
224 
225     fta.setString("abc");
226     const Formattable ftc(fta);
227     UnicodeString res;
228 
229     {
230         UBool t;
231         t = (fta.getType() == Formattable::kString)
232             && (fta.getString(res) == "abc")
233             && (fta.getString() == "abc");
234         res = fta.getString(status = U_ZERO_ERROR);
235         t = t && (status != U_INVALID_FORMAT_ERROR && res == "abc");
236         res = ftc.getString(status = U_ZERO_ERROR);
237         t = t && (status != U_INVALID_FORMAT_ERROR && res == "abc");
238         ftc.getString(res,status = U_ZERO_ERROR);
239         t = t && (status != U_INVALID_FORMAT_ERROR && res == "abc");
240         if (t) {
241             it_logln("FT set- and getString tested.");
242         }else{
243             it_errln("*** FT set- or getString");
244         }
245     }
246 
247     UnicodeString ucs = "unicode-string";
248     UnicodeString* ucs_ptr = new UnicodeString("pointed-to-unicode-string");
249 
250     const Formattable ftarray[] =
251     {
252         Formattable( 1.0, Formattable::kIsDate ),
253         2.0,
254         (int32_t)3,
255         ucs,
256         ucs_ptr
257     };
258     const int32_t ft_cnt = UPRV_LENGTHOF(ftarray);
259     Formattable ft_arr( ftarray, ft_cnt );
260     UnicodeString temp;
261     if ((ft_arr[0].getType() == Formattable::kDate)   && (ft_arr[0].getDate()   == 1.0)
262      && (ft_arr[1].getType() == Formattable::kDouble) && (ft_arr[1].getDouble() == 2.0)
263      && (ft_arr[2].getType() == Formattable::kLong)   && (ft_arr[2].getLong()   == (int32_t)3)
264      && (ft_arr[3].getType() == Formattable::kString) && (ft_arr[3].getString(temp) == ucs)
265      && (ft_arr[4].getType() == Formattable::kString) && (ft_arr[4].getString(temp) == *ucs_ptr) ) {
266         it_logln("FT constr. for date, double, long, ustring, ustring* and array tested");
267     }else{
268         it_errln("*** FT constr. for date, double, long, ustring, ustring* or array");
269     }
270 
271     int32_t i, res_cnt;
272     const Formattable* res_array = ft_arr.getArray( res_cnt );
273     if (res_cnt == ft_cnt) {
274         UBool same  = TRUE;
275         for (i = 0; i < res_cnt; i++ ) {
276             if (res_array[i] != ftarray[i]) {
277                 same = FALSE;
278             }
279         }
280         if (same) {
281             it_logln("FT getArray tested");
282             res_array = ft_arr.getArray( res_cnt, status = U_ZERO_ERROR);
283             if (status == U_INVALID_FORMAT_ERROR){
284                 it_errln("*** FT getArray with status failed on real array");
285             } else {
286                 it_logln("FT getArray with status tested on real array");
287             }
288         }else{
289             it_errln("*** FT getArray comparison");
290         }
291     }else{
292         it_errln(UnicodeString("*** FT getArray count res_cnt=") + res_cnt + UnicodeString("ft_cnt=") + ft_cnt);
293     }
294 
295     res_array = fta.getArray(res_cnt, status = U_ZERO_ERROR);
296     if (status == U_INVALID_FORMAT_ERROR){
297         if (res_cnt == 0 && res_array == NULL){
298             it_logln("FT getArray with status tested on non array");
299         } else {
300             it_errln("*** FT getArray with status return values are not consistent");
301         }
302     } else {
303         it_errln("*** FT getArray with status should fail on non-array");
304     }
305 
306 
307     Formattable *pf;
308     for(i = 0; i < ft_cnt; ++i) {
309         pf = ftarray[i].clone();
310         if(pf == (ftarray + i) || *pf != ftarray[i]) {
311             it_errln(UnicodeString("Formattable.clone() failed for item ") + i);
312         }
313         delete pf;
314     }
315 
316     const Formattable ftarr1[] = { Formattable( (int32_t)1 ), Formattable( (int32_t)2 ) };
317     const Formattable ftarr2[] = { Formattable( (int32_t)3 ), Formattable( (int32_t)4 ) };
318 
319     const int32_t ftarr1_cnt = UPRV_LENGTHOF(ftarr1);
320     const int32_t ftarr2_cnt = UPRV_LENGTHOF(ftarr2);
321 
322     ft_arr.setArray( ftarr1, ftarr1_cnt );
323     if ((ft_arr[0].getType() == Formattable::kLong) && (ft_arr[0].getLong() == (int32_t)1)) {
324         it_logln("FT setArray tested");
325     }else{
326         it_errln("*** FT setArray");
327     }
328 
329     Formattable* ft_dynarr = new Formattable[ftarr2_cnt];
330     for (i = 0; i < ftarr2_cnt; i++ ) {
331         ft_dynarr[i] = ftarr2[i];
332     }
333     if ((ft_dynarr[0].getType() == Formattable::kLong) && (ft_dynarr[0].getLong() == (int32_t)3)
334      && (ft_dynarr[1].getType() == Formattable::kLong) && (ft_dynarr[1].getLong() == (int32_t)4)) {
335         it_logln("FT operator= and array operations tested");
336     }else{
337         it_errln("*** FT operator= or array operations");
338     }
339 
340     ft_arr.adoptArray( ft_dynarr, ftarr2_cnt );
341     if ((ft_arr[0].getType() == Formattable::kLong) && (ft_arr[0].getLong() == (int32_t)3)
342      && (ft_arr[1].getType() == Formattable::kLong) && (ft_arr[1].getLong() == (int32_t)4)) {
343         it_logln("FT adoptArray tested");
344     }else{
345         it_errln("*** FT adoptArray or operator[]");
346     }
347 
348     ft_arr.setLong(0);   // calls 'dispose' and deletes adopted array !
349 
350     UnicodeString* ucs_dyn = new UnicodeString("ttt");
351     UnicodeString tmp2;
352 
353     fta.adoptString( ucs_dyn );
354     if ((fta.getType() == Formattable::kString) && (fta.getString(tmp2) == "ttt")) {
355         it_logln("FT adoptString tested");
356     }else{
357         it_errln("*** FT adoptString or getString");
358     }
359     fta.setLong(0);   // calls 'dispose' and deletes adopted string !
360 
361     it_logln();
362 }
363 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)364 void TestFormatSmallClasses::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
365 {
366     switch (index) {
367         case 0: name = "pp";
368                 if (exec) logln("TestSuite Format/SmallClasses/ParsePosition (f/chc/sma/pp): ");
369                 if (exec) test_ParsePosition();
370                 break;
371         case 1: name = "fp";
372                 if (exec) logln("TestSuite Format/SmallClasses/FieldPosition (f/chc/sma/fp): ");
373                 if (exec) test_FieldPosition();
374                 break;
375         case 2: name = "fpe";
376                 if (exec) logln("TestSuite Format/SmallClasses/FieldPositionExample (f/chc/sma/fpe): ");
377                 if (exec) test_FieldPosition_example();
378                 break;
379         case 3: name = "ft";
380                 if (exec) logln("TestSuite Format/SmallClasses/Formattable (f/chc/sma/ft): ");
381                 if (exec) test_Formattable();
382                 break;
383         default: name = ""; break; //needed to end loop
384     }
385 }
386 
387 #endif /* #if !UCONFIG_NO_FORMATTING */
388