• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /********************************************************************
3  * COPYRIGHT:
4  * Copyright (c) 1997-2005, International Business Machines Corporation and
5  * others. All Rights Reserved.
6  ********************************************************************/
7 
8 #include "unicode/utypes.h"
9 
10 #if !UCONFIG_NO_FORMATTING
11 
12 #include "intltest.h"
13 #include "tchcfmt.h"
14 #include "cmemory.h"
15 #include "unicode/msgfmt.h"
16 #include "unicode/choicfmt.h"
17 
18 #include <float.h>
19 
20 // tests have obvious memory leaks!
21 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)22 void TestChoiceFormat::runIndexedTest(int32_t index, UBool exec,
23                                       const char* &name, char* /*par*/) {
24     switch (index) {
25         TESTCASE(0,TestSimpleExample);
26         TESTCASE(1,TestComplexExample);
27         TESTCASE(2,TestClosures);
28         TESTCASE(3,TestPatterns);
29         default: name = ""; break;
30     }
31 }
32 
chkstatus(UErrorCode & status,const char * msg=NULL)33 static UBool chkstatus( UErrorCode &status, const char* msg = NULL )
34 {
35     UBool ok = U_SUCCESS(status);
36     if (!ok) it_errln( msg );
37     return ok;
38 }
39 
40 void
TestSimpleExample(void)41 TestChoiceFormat::TestSimpleExample( void )
42 {
43     double limits[] = {1,2,3,4,5,6,7};
44     UnicodeString monthNames[] = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"};
45     ChoiceFormat* form = new ChoiceFormat(limits, monthNames, 7);
46     ParsePosition parse_pos;
47     // TODO Fix this ParsePosition stuff...
48     UnicodeString str;
49     UnicodeString res1, res2;
50     UErrorCode status;
51     FieldPosition fpos(0);
52     Formattable f;
53     int32_t ix;
54     //for (double i = 0.0; i <= 8.0; ++i) {
55     for (ix = 0; ix <= 8; ++ix) {
56         double i = ix; //nos
57         status = U_ZERO_ERROR;
58         fpos = 0;
59         str = "";
60         res1 = form->format(i, str, fpos, status );
61         if (!chkstatus( status, "***  test_simple_example format" )) {
62             delete form;
63             return;
64         }
65         //form->parse(res1, f, parse_pos);
66         res2 = " ??? ";
67         it_logln(UnicodeString("") + ix + UnicodeString(" -> ") + res1 + UnicodeString(" -> ") + res2);
68     }
69     //Testing ==operator
70     const double filelimits[] = {0,1,2};
71     const UnicodeString filepart[] = {"are no files","is one file","are {2} files"};
72     ChoiceFormat* formnew=new ChoiceFormat(filelimits, filepart, 3);
73     ChoiceFormat* formequal=new ChoiceFormat(limits, monthNames, 7);
74     if(*formnew == *form){
75         errln("ERROR: ==operator failed\n");
76     }
77     if(!(*form == *formequal)){
78         errln("ERROR: ==operator failed\n");
79     }
80     delete formequal;
81 
82 #ifdef U_USE_CHOICE_FORMAT_DEPRECATES
83     //Testing adoptChoices()
84     double *limitsToAdopt = (double *)uprv_malloc(7 * sizeof(double));
85     UnicodeString *monthNamesToAdopt = new UnicodeString[7];
86 
87     uprv_arrayCopy(monthNames, monthNamesToAdopt, 7);
88     uprv_memcpy(limitsToAdopt, limits, (size_t)(7 * sizeof(limits[0])));
89 
90     formnew->adoptChoices(limitsToAdopt, monthNamesToAdopt, 7);
91     if(!(*formnew == *form)){
92         errln("ERROR: ==Operator or adoptChoices failed\n");
93     }
94 #endif
95 
96     delete formnew;
97 
98     //Testing getLimits()
99     double *gotLimits=0;
100     int32_t count=0;
101     gotLimits=(double*)form->getLimits(count);
102     if(count != 7){
103         errln("getLimits didn't update the count correctly\n");
104     }
105     for(ix=0; ix<count; ix++){
106         if(gotLimits[ix] != limits[ix]){
107             errln((UnicodeString)"getLimits didn't get the limits correctly.  Expected " + limits[ix] + " Got " + gotLimits[ix]);
108         }
109     }
110     //Testing getFormat()
111     count=0;
112     UnicodeString *gotFormats=0;
113     gotFormats=(UnicodeString*)form->getFormats(count);
114     if(count != 7){
115         errln("getFormats didn't update the count correctly\n");
116     }
117     for(ix=0; ix<count; ix++){
118         if(gotFormats[ix] != monthNames[ix]){
119             errln((UnicodeString)"getFormats didn't get the Formats correctly.  Expected " + monthNames[ix] + " Got " + gotFormats[ix]);
120         }
121     }
122 
123 
124     delete form;
125 
126 }
127 
128 void
TestComplexExample(void)129 TestChoiceFormat::TestComplexExample( void )
130 {
131     UErrorCode status = U_ZERO_ERROR;
132     const double filelimits[] = {-1, 0,1,2};
133     const UnicodeString filepart[] = {"are corrupted files", "are no files","is one file","are {2} files"};
134 
135     ChoiceFormat* fileform = new ChoiceFormat( filelimits, filepart, 4);
136 
137     if (!fileform) {
138         it_errln("***  test_complex_example fileform");
139         return;
140     }
141 
142     Format* filenumform = NumberFormat::createInstance( status );
143     if (!filenumform) {
144         it_errln("***  test_complex_example filenumform");
145         delete fileform;
146         return;
147     }
148     if (!chkstatus( status, "***  test_simple_example filenumform" )) {
149         delete fileform;
150         delete filenumform;
151         return;
152     }
153 
154     //const Format* testFormats[] = { fileform, NULL, filenumform };
155     //pattform->setFormats( testFormats, 3 );
156 
157     MessageFormat* pattform = new MessageFormat("There {0} on {1}", status );
158     if (!pattform) {
159         it_errln("***  test_complex_example pattform");
160         delete fileform;
161         delete filenumform;
162         return;
163     }
164     if (!chkstatus( status, "***  test_complex_example pattform" )) {
165         delete fileform;
166         delete filenumform;
167         delete pattform;
168         return;
169     }
170 
171     pattform->setFormat( 0, *fileform );
172     pattform->setFormat( 2, *filenumform );
173 
174 
175     Formattable testArgs[] = {(int32_t)0, "Disk_A", (int32_t)0};
176     UnicodeString str;
177     UnicodeString res1, res2;
178     pattform->toPattern( res1 );
179     it_logln("MessageFormat toPattern: " + res1);
180     fileform->toPattern( res1 );
181     it_logln("ChoiceFormat toPattern: " + res1);
182     if (res1 == "-1.0#are corrupted files|0.0#are no files|1.0#is one file|2.0#are {2} files") {
183         it_logln("toPattern tested!");
184     }else{
185         it_errln("***  ChoiceFormat to Pattern result!");
186     }
187 
188     FieldPosition fpos(0);
189 
190     UnicodeString checkstr[] = {
191         "There are corrupted files on Disk_A",
192         "There are no files on Disk_A",
193         "There is one file on Disk_A",
194         "There are 2 files on Disk_A",
195         "There are 3 files on Disk_A"
196     };
197 
198     // if (status != U_ZERO_ERROR) return; // TODO: analyze why we have such a bad bail out here!
199 
200     if (U_FAILURE(status)) {
201         delete fileform;
202         delete filenumform;
203         delete pattform;
204         return;
205     }
206 
207 
208     int32_t i;
209     int32_t start = -1;
210     for (i = start; i < 4; ++i) {
211         str = "";
212         status = U_ZERO_ERROR;
213         testArgs[0] = Formattable((int32_t)i);
214         testArgs[2] = testArgs[0];
215         res2 = pattform->format(testArgs, 3, str, fpos, status );
216         if (!chkstatus( status, "***  test_complex_example format" )) {
217             delete fileform;
218             delete filenumform;
219             delete pattform;
220             return;
221         }
222         it_logln(i + UnicodeString(" -> ") + res2);
223         if (res2 != checkstr[i - start]) {
224             it_errln("***  test_complex_example res string");
225             it_errln(UnicodeString("*** ") + i + UnicodeString(" -> '") + res2 + UnicodeString("' unlike '") + checkstr[i] + UnicodeString("' ! "));
226         }
227     }
228     it_logln();
229 
230     it_logln("------ additional testing in complex test ------");
231     it_logln();
232     //
233     int32_t retCount;
234     const double* retLimits = fileform->getLimits( retCount );
235     if ((retCount == 4) && (retLimits)
236     && (retLimits[0] == -1.0)
237     && (retLimits[1] == 0.0)
238     && (retLimits[2] == 1.0)
239     && (retLimits[3] == 2.0)) {
240         it_logln("getLimits tested!");
241     }else{
242         it_errln("***  getLimits unexpected result!");
243     }
244 
245     const UnicodeString* retFormats = fileform->getFormats( retCount );
246     if ((retCount == 4) && (retFormats)
247     && (retFormats[0] == "are corrupted files")
248     && (retFormats[1] == "are no files")
249     && (retFormats[2] == "is one file")
250     && (retFormats[3] == "are {2} files")) {
251         it_logln("getFormats tested!");
252     }else{
253         it_errln("***  getFormats unexpected result!");
254     }
255 
256     UnicodeString checkstr2[] = {
257         "There is no folder on Disk_A",
258         "There is one folder on Disk_A",
259         "There are many folders on Disk_A",
260         "There are many folders on Disk_A"
261     };
262 
263     fileform->applyPattern("0#is no folder|1#is one folder|2#are many folders", status );
264     if (status == U_ZERO_ERROR)
265         it_logln("status applyPattern OK!");
266     if (!chkstatus( status, "***  test_complex_example pattform" )) {
267         delete fileform;
268         delete filenumform;
269         delete pattform;
270         return;
271     }
272     pattform->setFormat( 0, *fileform );
273     fpos = 0;
274     for (i = 0; i < 4; ++i) {
275         str = "";
276         status = U_ZERO_ERROR;
277         testArgs[0] = Formattable((int32_t)i);
278         testArgs[2] = testArgs[0];
279         res2 = pattform->format(testArgs, 3, str, fpos, status );
280         if (!chkstatus( status, "***  test_complex_example format 2" )) {
281             delete fileform;
282             delete filenumform;
283             delete pattform;
284             return;
285         }
286         it_logln(UnicodeString() + i + UnicodeString(" -> ") + res2);
287         if (res2 != checkstr2[i]) {
288             it_errln("***  test_complex_example res string");
289             it_errln(UnicodeString("*** ") + i + UnicodeString(" -> '") + res2 + UnicodeString("' unlike '") + checkstr2[i] + UnicodeString("' ! "));
290         }
291     }
292 
293     const double limits_A[] = {1,2,3,4,5,6,7};
294     const UnicodeString monthNames_A[] = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"};
295     ChoiceFormat* form_A = new ChoiceFormat(limits_A, monthNames_A, 7);
296     ChoiceFormat* form_A2 = new ChoiceFormat(limits_A, monthNames_A, 7);
297     const double limits_B[] = {1,2,3,4,5,6,7};
298     const UnicodeString monthNames_B[] = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat_BBB"};
299     ChoiceFormat* form_B = new ChoiceFormat(limits_B, monthNames_B, 7);
300     if (!form_A || !form_B || !form_A2) {
301         it_errln("***  test-choiceFormat not allocatable!");
302     }else{
303         if (*form_A == *form_A2) {
304             it_logln("operator== tested.");
305         }else{
306             it_errln("***  operator==");
307         }
308 
309         if (*form_A != *form_B) {
310             it_logln("operator!= tested.");
311         }else{
312             it_errln("***  operator!=");
313         }
314 
315         ChoiceFormat* form_A3 = (ChoiceFormat*) form_A->clone();
316         if (!form_A3) {
317             it_errln("***  ChoiceFormat->clone is nil.");
318         }else{
319             if ((*form_A3 == *form_A) && (*form_A3 != *form_B)) {
320                 it_logln("method clone tested.");
321             }else{
322                 it_errln("***  ChoiceFormat clone or operator==, or operator!= .");
323             }
324         }
325 
326         ChoiceFormat form_Assigned( *form_A );
327         UBool ok = (form_Assigned == *form_A) && (form_Assigned != *form_B);
328         form_Assigned = *form_B;
329         ok = ok && (form_Assigned != *form_A) && (form_Assigned == *form_B);
330         if (ok) {
331             it_logln("copy constructor and operator= tested.");
332         }else{
333             it_errln("***  copy constructor or operator= or operator == or operator != .");
334         }
335         delete form_A3;
336     }
337 
338 
339     delete form_A; delete form_A2; delete form_B;
340 
341     const char* testPattern = "0#none|1#one|2#many";
342     ChoiceFormat form_pat( testPattern, status );
343     if (!chkstatus( status, "***  ChoiceFormat contructor( newPattern, status)" )) {
344         delete fileform;
345         delete filenumform;
346         delete pattform;
347         return;
348     }
349 
350     form_pat.toPattern( res1 );
351     if (res1 == "0.0#none|1.0#one|2.0#many") {
352         it_logln("ChoiceFormat contructor( newPattern, status) tested");
353     }else{
354         it_errln("***  ChoiceFormat contructor( newPattern, status) or toPattern result!");
355     }
356 
357 #ifdef U_USE_CHOICE_FORMAT_DEPRECATES
358     double* d_a = (double *)uprv_malloc(2 * sizeof(double));
359     if (!d_a) { it_errln("*** allocation error."); return; }
360     d_a[0] = 1.0; d_a[1] = 2.0;
361 
362     UnicodeString* s_a = new UnicodeString[2];
363     if (!s_a) { it_errln("*** allocation error."); return; }
364     s_a[0] = "first"; s_a[1] = "second";
365 
366     form_pat.adoptChoices( d_a, s_a, 2 );
367     form_pat.toPattern( res1 );
368     it_out << "ChoiceFormat adoptChoices toPattern: " << res1 << endl;
369     if (res1 == "1.0#first|2.0#second") {
370         it_logln("ChoiceFormat adoptChoices tested");
371     }else{
372         it_errln("***  ChoiceFormat adoptChoices result!");
373     }
374 #endif
375 
376     double d_a2[] = { 3.0, 4.0 };
377     UnicodeString s_a2[] = { "third", "forth" };
378 
379     form_pat.setChoices( d_a2, s_a2, 2 );
380     form_pat.toPattern( res1 );
381     it_logln(UnicodeString("ChoiceFormat adoptChoices toPattern: ") + res1);
382     if (res1 == "3.0#third|4.0#forth") {
383         it_logln("ChoiceFormat adoptChoices tested");
384     }else{
385         it_errln("***  ChoiceFormat adoptChoices result!");
386     }
387 
388     str = "";
389     fpos = 0;
390     status = U_ZERO_ERROR;
391     double arg_double = 3.0;
392     res1 = form_pat.format( arg_double, str, fpos );
393     it_logln(UnicodeString("ChoiceFormat format:") + res1);
394     if (res1 != "third") it_errln("***  ChoiceFormat format (double, ...) result!");
395 
396     str = "";
397     fpos = 0;
398     status = U_ZERO_ERROR;
399     int64_t arg_64 = 3;
400     res1 = form_pat.format( arg_64, str, fpos );
401     it_logln(UnicodeString("ChoiceFormat format:") + res1);
402     if (res1 != "third") it_errln("***  ChoiceFormat format (int64_t, ...) result!");
403 
404     str = "";
405     fpos = 0;
406     status = U_ZERO_ERROR;
407     int32_t arg_long = 3;
408     res1 = form_pat.format( arg_long, str, fpos );
409     it_logln(UnicodeString("ChoiceFormat format:") + res1);
410     if (res1 != "third") it_errln("***  ChoiceFormat format (int32_t, ...) result!");
411 
412     Formattable ft( (int32_t)3 );
413     str = "";
414     fpos = 0;
415     status = U_ZERO_ERROR;
416     res1 = form_pat.format( ft, str, fpos, status );
417     if (!chkstatus( status, "***  test_complex_example format (int32_t, ...)" )) {
418         delete fileform;
419         delete filenumform;
420         delete pattform;
421         return;
422     }
423     it_logln(UnicodeString("ChoiceFormat format:") + res1);
424     if (res1 != "third") it_errln("***  ChoiceFormat format (Formattable, ...) result!");
425 
426     Formattable fta[] = { (int32_t)3 };
427     str = "";
428     fpos = 0;
429     status = U_ZERO_ERROR;
430     res1 = form_pat.format( fta, 1, str, fpos, status );
431     if (!chkstatus( status, "***  test_complex_example format (int32_t, ...)" )) {
432         delete fileform;
433         delete filenumform;
434         delete pattform;
435         return;
436     }
437     it_logln(UnicodeString("ChoiceFormat format:") + res1);
438     if (res1 != "third") it_errln("***  ChoiceFormat format (Formattable[], cnt, ...) result!");
439 
440     ParsePosition parse_pos = 0;
441     Formattable result;
442     UnicodeString parsetext("third");
443     form_pat.parse( parsetext, result, parse_pos );
444     double rd = (result.getType() == Formattable::kLong) ? result.getLong() : result.getDouble();
445     if (rd == 3.0) {
446         it_logln("parse( ..., ParsePos ) tested.");
447     }else{
448         it_errln("*** ChoiceFormat parse( ..., ParsePos )!");
449     }
450 
451     form_pat.parse( parsetext, result, status );
452     rd = (result.getType() == Formattable::kLong) ? result.getLong() : result.getDouble();
453     if (rd == 3.0) {
454         it_logln("parse( ..., UErrorCode ) tested.");
455     }else{
456         it_errln("*** ChoiceFormat parse( ..., UErrorCode )!");
457     }
458 
459     /*
460     UClassID classID = ChoiceFormat::getStaticClassID();
461     if (classID == form_pat.getDynamicClassID()) {
462         it_out << "getStaticClassID and getDynamicClassID tested." << endl;
463     }else{
464         it_errln("*** getStaticClassID and getDynamicClassID!");
465     }
466     */
467 
468     it_logln();
469 
470     delete fileform;
471     delete filenumform;
472     delete pattform;
473 }
474 
475 
476 /**
477  * Test new closure API
478  */
TestClosures(void)479 void TestChoiceFormat::TestClosures(void) {
480     // Construct open, half-open, half-open (the other way), and closed
481     // intervals.  Do this both using arrays and using a pattern.
482 
483     // 'fmt1' is created using arrays
484     UBool T = TRUE, F = FALSE;
485     // 0:   ,1)
486     // 1: [1,2]
487     // 2: (2,3]
488     // 3: (3,4)
489     // 4: [4,5)
490     // 5: [5,
491     double limits[]  = { 0, 1, 2, 3, 4, 5 };
492     UBool closures[] = { F, F, T, T, F, F };
493     UnicodeString fmts[] = {
494         ",1)", "[1,2]", "(2,3]", "(3,4)", "[4,5)", "[5,"
495     };
496     ChoiceFormat fmt1(limits, closures, fmts, 6);
497 
498     // 'fmt2' is created using a pattern; it should be equivalent
499     UErrorCode status = U_ZERO_ERROR;
500     const char* PAT = "0.0#,1)|1.0#[1,2]|2.0<(2,3]|3.0<(3,4)|4.0#[4,5)|5.0#[5,";
501     ChoiceFormat fmt2(PAT, status);
502     if (U_FAILURE(status)) {
503         errln("FAIL: ChoiceFormat constructor failed");
504         return;
505     }
506 
507     // Check the patterns
508     UnicodeString str;
509     fmt1.toPattern(str);
510     if (str == PAT) {
511         logln("Ok: " + str);
512     } else {
513         errln("FAIL: " + str + ", expected " + PAT);
514     }
515     str.truncate(0);
516 
517     // Check equality
518     if (fmt1 != fmt2) {
519         errln("FAIL: fmt1 != fmt2");
520     }
521 
522     int32_t i;
523     int32_t count2 = 0;
524     const double *limits2 = fmt2.getLimits(count2);
525     const UBool *closures2 = fmt2.getClosures(count2);
526 
527     if((count2 != 6) || !limits2 || !closures2) {
528         errln("FAIL: couldn't get limits or closures");
529     } else {
530         for(i=0;i<count2;i++) {
531           logln("#%d/%d: limit %g closed %s\n",
532                 i, count2,
533                 limits2[i],
534                 closures2[i] ?"T":"F");
535           if(limits2[i] != limits[i]) {
536             errln("FAIL: limit #%d = %g, should be %g\n", i, limits2[i], limits[i]);
537           }
538           if((closures2[i]!=0) != (closures[i]!=0)) {
539             errln("FAIL: closure #%d = %s, should be %s\n", i, closures2[i]?"T":"F", closures[i]?"T":"F");
540           }
541         }
542     }
543 
544     // Now test both format objects
545     UnicodeString exp[] = {
546         /*-0.5 => */ ",1)",
547         /* 0.0 => */ ",1)",
548         /* 0.5 => */ ",1)",
549         /* 1.0 => */ "[1,2]",
550         /* 1.5 => */ "[1,2]",
551         /* 2.0 => */ "[1,2]",
552         /* 2.5 => */ "(2,3]",
553         /* 3.0 => */ "(2,3]",
554         /* 3.5 => */ "(3,4)",
555         /* 4.0 => */ "[4,5)",
556         /* 4.5 => */ "[4,5)",
557         /* 5.0 => */ "[5,",
558         /* 5.5 => */ "[5,"
559     };
560 
561     // Each format object should behave exactly the same
562     ChoiceFormat* FMT[] = { &fmt1, &fmt2 };
563     for (int32_t pass=0; pass<2; ++pass) {
564         int32_t j=0;
565         for (int32_t ix=-5; ix<=55; ix+=5) {
566             double x = ix / 10.0; // -0.5 to 5.5 step +0.5
567             FMT[pass]->format(x, str);
568             if (str == exp[j]) {
569                 logln((UnicodeString)"Ok: " + x + " => " + str);
570             } else {
571                 errln((UnicodeString)"FAIL: " + x + " => " + str +
572                       ", expected " + exp[j]);
573             }
574             str.truncate(0);
575             ++j;
576         }
577     }
578 }
579 
580 /**
581  * Helper for TestPatterns()
582  */
_testPattern(const char * pattern,UBool isValid,double v1,const char * str1,double v2,const char * str2,double v3,const char * str3)583 void TestChoiceFormat::_testPattern(const char* pattern,
584                                     UBool isValid,
585                                     double v1, const char* str1,
586                                     double v2, const char* str2,
587                                     double v3, const char* str3) {
588     UErrorCode ec = U_ZERO_ERROR;
589     ChoiceFormat fmt(pattern, ec);
590     if (!isValid) {
591         if (U_FAILURE(ec)) {
592             logln((UnicodeString)"Ok: " + pattern + " failed");
593         } else {
594             logln((UnicodeString)"FAIL: " + pattern + " accepted");
595         }
596         return;
597     }
598     if (U_FAILURE(ec)) {
599         errln((UnicodeString)"FAIL: ChoiceFormat(" + pattern + ") failed");
600         return;
601     } else {
602         logln((UnicodeString)"Ok: Pattern: " + pattern);
603     }
604     UnicodeString out;
605     logln((UnicodeString)"  toPattern: " + fmt.toPattern(out));
606 
607     double v[] = {v1, v2, v3};
608     const char* str[] = {str1, str2, str3};
609     for (int32_t i=0; i<3; ++i) {
610         out.truncate(0);
611         fmt.format(v[i], out);
612         if (out == str[i]) {
613             logln((UnicodeString)"Ok: " + v[i] + " => " + out);
614         } else {
615             errln((UnicodeString)"FAIL: " + v[i] + " => " + out +
616                   ", expected " + str[i]);
617         }
618     }
619 }
620 
621 /**
622  * Test applyPattern
623  */
TestPatterns(void)624 void TestChoiceFormat::TestPatterns(void) {
625     // Try a pattern that isolates a single value.  Create
626     // three ranges: [-Inf,1.0) [1.0,1.0] (1.0,+Inf]
627     _testPattern("0.0#a|1.0#b|1.0<c", TRUE,
628                  1.0 - 1e-9, "a",
629                  1.0, "b",
630                  1.0 + 1e-9, "c");
631 
632     // Try an invalid pattern that isolates a single value.
633     // [-Inf,1.0) [1.0,1.0) [1.0,+Inf]
634     _testPattern("0.0#a|1.0#b|1.0#c", FALSE,
635                  0, 0, 0, 0, 0, 0);
636 
637     // Another
638     // [-Inf,1.0] (1.0,1.0) [1.0,+Inf]
639     _testPattern("0.0#a|1.0<b|1.0#c", FALSE,
640                  0, 0, 0, 0, 0, 0);
641     // Another
642     // [-Inf,1.0] (1.0,1.0] (1.0,+Inf]
643     _testPattern("0.0#a|1.0<b|1.0<c", FALSE,
644                  0, 0, 0, 0, 0, 0);
645 
646     // Try a grossly invalid pattern.
647     // [-Inf,2.0) [2.0,1.0) [1.0,+Inf]
648     _testPattern("0.0#a|2.0#b|1.0#c", FALSE,
649                  0, 0, 0, 0, 0, 0);
650 }
651 
652 #endif /* #if !UCONFIG_NO_FORMATTING */
653