1 /*
2 **********************************************************************
3 * Copyright (c) 2011-2014,International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
6 */
7 #include <stdio.h>
8 #include <string.h>
9
10 #include "sieve.h"
11 #include "unicode/utimer.h"
12 #include "udbgutil.h"
13 #include "unicode/ustring.h"
14 #include "unicode/decimfmt.h"
15 #include "unicode/udat.h"
16 U_NAMESPACE_USE
17
18 #if U_PLATFORM_IMPLEMENTS_POSIX
19 #include <unistd.h>
20
usage(const char * prog)21 static void usage(const char *prog) {
22 fprintf(stderr, "Usage: %s [ -f outfile.xml ] [ -t 'TestName' ]\n", prog);
23 }
24 #endif
25
26 void runTests(void);
27
28 #ifndef ITERATIONS
29 #define ITERATIONS 5
30 #endif
31
32 #ifndef TEST_LOCALE
33 #define TEST_LOCALE "en_US"
34 #endif
35
36 FILE *out = NULL;
37 UErrorCode setupStatus = U_ZERO_ERROR;
38 const char *outName = NULL;
39 int listmode = 0;
40 const char *testName = NULL;
41 const char *progname = NULL;
42 int errflg = 0;
43 int testhit = 0;
44
testMatch(const char * aName)45 int testMatch(const char *aName) {
46 if(testName==NULL) return 1;
47 int len = strlen(testName);
48 if(testName[len-1]=='*') {
49 return strncmp(testName,aName,len-1);
50 } else {
51 return strcmp(testName,aName);
52 }
53 }
54
main(int argc,char * const * argv)55 int main(int argc, char * const * argv){
56 #if U_DEBUG
57 fprintf(stderr,"%s: warning: U_DEBUG is on.\n", argv[0]);
58 #endif
59 #if U_DEBUG
60 {
61 double m;
62 double s = uprv_getSieveTime(&m);
63 fprintf(stderr, "** Standard sieve time: %.9fs +/- %.9fs (%d iterations)\n", s,m, (int)U_LOTS_OF_TIMES);
64 }
65 #endif
66
67 #if U_PLATFORM_IMPLEMENTS_POSIX
68 int c;
69 //extern int optind;
70 extern char *optarg;
71 while((c=getopt(argc,argv,"lf:t:")) != EOF) {
72 switch(c) {
73 case 'f':
74 outName = optarg;
75 break;
76 case 'l':
77 listmode++;
78 break;
79 case 't':
80 testName = optarg;
81 break;
82 case '?':
83 errflg++;
84 }
85 if(errflg) {
86 usage(progname);
87 return 0;
88 }
89 }
90 /* for ( ; optind < argc; optind++) { ... argv[optind] } */
91 #else
92 if(argc==2) {
93 outName = argv[1];
94 } else if(argc>2) {
95 fprintf(stderr, "Err: usage: %s [ output-file.xml ]\n", argv[0]);
96 }
97 #endif
98
99 if(listmode && outName != NULL ) {
100 fprintf(stderr, "Warning: no output when list mode\n");
101 outName=NULL;
102 }
103
104 if(outName != NULL) {
105
106
107 out=fopen(outName,"w");
108 if(out==NULL) {
109 fprintf(stderr,"Err: can't open %s for writing.\n", outName);
110 return 1;
111 } else {
112 fprintf(stderr, "# writing results to %s\n", outName);
113 }
114 fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
115 fprintf(out, "<tests icu=\"%s\">\n", U_ICU_VERSION);
116 fprintf(out, "<!-- %s -->\n", U_COPYRIGHT_STRING);
117 } else {
118 fprintf(stderr, "# (no output)\n");
119 }
120
121 if(listmode && testName!=NULL) {
122 fprintf(stderr, "ERR: no -l mode when specific test with -t\n");
123 usage(progname);
124 return 1;
125 }
126
127
128 runTests();
129
130
131 if(out!=NULL) {
132 #ifndef SKIP_INFO
133 udbg_writeIcuInfo(out);
134 #endif
135 fprintf(out, "</tests>\n");
136 fclose(out);
137 }
138
139 if(U_FAILURE(setupStatus)) {
140 fprintf(stderr, "Error in tests: %s\n", u_errorName(setupStatus));
141 return 1;
142 }
143
144 return 0;
145 }
146
147 class HowExpensiveTest {
148 public:
~HowExpensiveTest()149 virtual ~HowExpensiveTest(){}
150 protected:
HowExpensiveTest(const char * name,const char * file,int32_t line)151 HowExpensiveTest(const char *name, const char *file, int32_t line) : fName(name), fFile(file), fLine(line) {}
152 protected:
153 /**
154 * @return number of iterations
155 */
156 virtual int32_t run() = 0;
warmup()157 virtual void warmup() { run(); }
158 public:
getName()159 virtual const char *getName() { return fName; }
160 public:
runTest(double * subTime)161 virtual int32_t runTest(double *subTime) {
162 UTimer a,b;
163 utimer_getTime(&a);
164 int32_t iter = run();
165 utimer_getTime(&b);
166 *subTime = utimer_getDeltaSeconds(&a,&b);
167 return iter;
168 }
169
runTests(double * subTime,double * marginOfError)170 virtual int32_t runTests(double *subTime, double *marginOfError) {
171 warmup(); /* warmup */
172 double times[ITERATIONS];
173 int subIterations = 0;
174 for(int i=0;i<ITERATIONS;i++) {
175 subIterations = runTest(×[i]);
176 #if U_DEBUG
177 fprintf(stderr, "trial: %d/%d = %.9fs\n", i, ITERATIONS,times[i]);
178 fflush(stderr);
179 #endif
180 }
181 uint32_t iterations = ITERATIONS;
182 *subTime = uprv_getMeanTime(times,&iterations,marginOfError);
183 return subIterations;
184 }
185 public:
186 const char *fName;
187 const char *fFile;
188 int32_t fLine;
189 int32_t fIterations;
190 };
191
runTestOn(HowExpensiveTest & t)192 void runTestOn(HowExpensiveTest &t) {
193 if(U_FAILURE(setupStatus)) return; // silently
194 const char *tn = t.getName();
195 if(testName!=NULL && testMatch(tn)) return; // skipped.
196 if(listmode) {
197 fprintf(stderr, "%s:%d:\t%s\n", t.fFile, t.fLine, t.getName());
198 testhit++;
199 return;
200 } else {
201 fprintf(stderr, "%s:%d: Running: %s\n", t.fFile, t.fLine, t.getName());
202 testhit++;
203 }
204 double sieveTime = uprv_getSieveTime(NULL);
205 double st;
206 double me;
207
208 fflush(stdout);
209 fflush(stderr);
210 int32_t iter = t.runTests(&st,&me);
211 if(U_FAILURE(setupStatus)) {
212 fprintf(stderr, "Error in tests: %s\n", u_errorName(setupStatus));
213 return;
214 }
215 fflush(stdout);
216 fflush(stderr);
217
218 double stn = st/sieveTime;
219
220 printf("%s\t%.9f\t%.9f +/- %.9f, @ %d iter\n", t.getName(),stn,st,me,iter);
221
222 if(out!=NULL) {
223 fprintf(out, " <test name=\"%s\" standardizedTime=\"%f\" realDuration=\"%f\" marginOfError=\"%f\" iterations=\"%d\" />\n",
224 tn,stn,st,me,iter);
225 fflush(out);
226 }
227 }
228
229 /* ------------------- test code here --------------------- */
230
231 class SieveTest : public HowExpensiveTest {
232 public:
~SieveTest()233 virtual ~SieveTest(){}
SieveTest()234 SieveTest():HowExpensiveTest("SieveTest",__FILE__,__LINE__){}
run()235 virtual int32_t run(){return 0;} // dummy
runTest(double * subTime)236 int32_t runTest(double *subTime) {
237 *subTime = uprv_getSieveTime(NULL);
238 return U_LOTS_OF_TIMES;
239 }
runTests(double * subTime,double * marginOfError)240 virtual int32_t runTests(double *subTime, double *marginOfError) {
241 *subTime = uprv_getSieveTime(marginOfError);
242 return U_LOTS_OF_TIMES;
243 }
244 };
245
246
247 /* ------- NumParseTest ------------- */
248 #include "unicode/unum.h"
249 /* open and close tests */
250 #define OCName(svc,ub,testn,suffix,n) testn ## svc ## ub ## suffix ## n
251 #define OCStr(svc,ub,suffix,n) "Test_" # svc # ub # suffix # n
252 #define OCRun(svc,ub,suffix) svc ## ub ## suffix
253 // TODO: run away screaming
254 #define OpenCloseTest(n, svc,suffix,c,a,d) class OCName(svc,_,Test_,suffix,n) : public HowExpensiveTest { public: OCName(svc,_,Test_,suffix,n)():HowExpensiveTest(OCStr(svc,_,suffix,n),__FILE__,__LINE__) c int32_t run() { int32_t i; for(i=0;i<U_LOTS_OF_TIMES;i++){ OCRun(svc,_,close) ( OCRun(svc,_,suffix) a ); } return i; } void warmup() { OCRun(svc,_,close) ( OCRun(svc,_,suffix) a); } virtual ~ OCName(svc,_,Test_,suffix,n) () d };
255 #define QuickTest(n,c,r,d) class n : public HowExpensiveTest { public: n():HowExpensiveTest(#n,__FILE__,__LINE__) c int32_t run() r virtual ~n () d };
256
257 class NumTest : public HowExpensiveTest {
258 private:
259 double fExpect;
260 UNumberFormat *fFmt;
261 UnicodeString fPat;
262 UnicodeString fString;
263 const UChar *fStr;
264 int32_t fLen;
265 const char *fFile;
266 int fLine;
267 const char *fCPat;
268 const char *fCStr;
269 char name[100];
270 public:
getName()271 virtual const char *getName() {
272 if(name[0]==0) {
273 sprintf(name,"%s:p=|%s|,str=|%s|",getClassName(),fCPat,fCStr);
274 }
275 return name;
276 }
277 protected:
initFmt()278 virtual UNumberFormat* initFmt() {
279 return unum_open(UNUM_PATTERN_DECIMAL, fPat.getTerminatedBuffer(), -1, TEST_LOCALE, 0, &setupStatus);
280 }
getClassName()281 virtual const char *getClassName() {
282 return "NumTest";
283 }
284 public:
NumTest(const char * pat,const char * num,double expect,const char * FILE,int LINE)285 NumTest(const char *pat, const char *num, double expect, const char *FILE, int LINE)
286 : HowExpensiveTest("(n/a)",FILE, LINE),
287 fExpect(expect),
288 fFmt(0),
289 fPat(pat, -1, US_INV),
290 fString(num,-1,US_INV),
291 fStr(fString.getTerminatedBuffer()),
292 fLen(u_strlen(fStr)),
293 fFile(FILE),
294 fLine(LINE),
295 fCPat(pat),
296 fCStr(num)
297 {
298 name[0]=0;
299 }
warmup()300 void warmup() {
301 fFmt = initFmt();
302 if(U_SUCCESS(setupStatus)) {
303 double trial = unum_parseDouble(fFmt,fStr,fLen, NULL, &setupStatus);
304 if(U_SUCCESS(setupStatus) && trial!=fExpect) {
305 setupStatus = U_INTERNAL_PROGRAM_ERROR;
306 printf("%s:%d: warmup() %s got %.8f expected %.8f\n",
307 fFile,fLine,getName(),trial,fExpect);
308 }
309 }
310 }
run()311 int32_t run() {
312 double trial=0.0;
313 int i;
314 for(i=0;i<U_LOTS_OF_TIMES;i++){
315 trial = unum_parse(fFmt,fStr,fLen, NULL, &setupStatus);
316 }
317 return i;
318 }
~NumTest()319 virtual ~NumTest(){}
320 };
321
322 #define DO_NumTest(p,n,x) { NumTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); }
323
324
325 class AttrNumTest : public NumTest
326 {
327 private:
328 UNumberFormatAttribute fAttr;
329 int32_t fAttrValue;
330 char name2[100];
331 protected:
getClassName()332 virtual const char *getClassName() {
333 sprintf(name2,"AttrNumTest:%d=%d", fAttr,fAttrValue);
334 return name2;
335 }
336 public:
AttrNumTest(const char * pat,const char * num,double expect,const char * FILE,int LINE,UNumberFormatAttribute attr,int32_t newValue)337 AttrNumTest(const char *pat, const char *num, double expect, const char *FILE, int LINE, UNumberFormatAttribute attr, int32_t newValue)
338 : NumTest(pat,num,expect,FILE,LINE),
339 fAttr(attr),
340 fAttrValue(newValue)
341 {
342 }
initFmt()343 virtual UNumberFormat* initFmt() {
344 UNumberFormat *fmt = NumTest::initFmt();
345 unum_setAttribute(fmt, fAttr,fAttrValue);
346 return fmt;
347 }
348 };
349
350 #define DO_AttrNumTest(p,n,x,a,v) { AttrNumTest t(p,n,x,__FILE__,__LINE__,a,v); runTestOn(t); }
351
352
353 class NOXNumTest : public NumTest
354 {
355 private:
356 UNumberFormatAttribute fAttr;
357 int32_t fAttrValue;
358 char name2[100];
359 protected:
getClassName()360 virtual const char *getClassName() {
361 sprintf(name2,"NOXNumTest:%d=%d", fAttr,fAttrValue);
362 return name2;
363 }
364 public:
NOXNumTest(const char * pat,const char * num,double expect,const char * FILE,int LINE)365 NOXNumTest(const char *pat, const char *num, double expect, const char *FILE, int LINE /*, UNumberFormatAttribute attr, int32_t newValue */)
366 : NumTest(pat,num,expect,FILE,LINE) /* ,
367 fAttr(attr),
368 fAttrValue(newValue) */
369 {
370 }
initFmt()371 virtual UNumberFormat* initFmt() {
372 UNumberFormat *fmt = NumTest::initFmt();
373 //unum_setAttribute(fmt, fAttr,fAttrValue);
374 return fmt;
375 }
376 };
377
378 #define DO_NOXNumTest(p,n,x) { NOXNumTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); }
379
380 #define DO_TripleNumTest(p,n,x) DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_YES) \
381 DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_NO) \
382 DO_AttrNumTest(p,n,x,UNUM_PARSE_ALL_INPUT,UNUM_MAYBE)
383
384
385 class NumFmtTest : public HowExpensiveTest {
386 private:
387 double fExpect;
388 UNumberFormat *fFmt;
389 UnicodeString fPat;
390 UnicodeString fString;
391 const UChar *fStr;
392 int32_t fLen;
393 const char *fFile;
394 int fLine;
395 const char *fCPat;
396 const char *fCStr;
397 char name[100];
398 public:
getName()399 virtual const char *getName() {
400 if(name[0]==0) {
401 sprintf(name,"%s:p=|%s|,str=|%s|",getClassName(),fCPat,fCStr);
402 }
403 return name;
404 }
405 protected:
initFmt()406 virtual UNumberFormat* initFmt() {
407 return unum_open(UNUM_PATTERN_DECIMAL, fPat.getTerminatedBuffer(), -1, TEST_LOCALE, 0, &setupStatus);
408 }
getClassName()409 virtual const char *getClassName() {
410 return "NumFmtTest";
411 }
412 public:
NumFmtTest(const char * pat,const char * num,double expect,const char * FILE,int LINE)413 NumFmtTest(const char *pat, const char *num, double expect, const char *FILE, int LINE)
414 : HowExpensiveTest("(n/a)",FILE, LINE),
415 fExpect(expect),
416 fFmt(0),
417 fPat(pat, -1, US_INV),
418 fString(num,-1,US_INV),
419 fStr(fString.getTerminatedBuffer()),
420 fLen(u_strlen(fStr)),
421 fFile(FILE),
422 fLine(LINE),
423 fCPat(pat),
424 fCStr(num)
425 {
426 name[0]=0;
427 }
warmup()428 void warmup() {
429 fFmt = initFmt();
430 UChar buf[100];
431 if(U_SUCCESS(setupStatus)) {
432 int32_t trial = unum_formatDouble(fFmt,fExpect, buf, 100, NULL, &setupStatus);
433 if(!U_SUCCESS(setupStatus)
434 || trial!=fLen
435 ||trial<=0
436 || u_strncmp(fStr,buf,trial) ) {
437 char strBuf[200];
438 u_strToUTF8(strBuf,200,NULL,buf,trial+1,&setupStatus);
439 printf("%s:%d: warmup() %s got %s expected %s, err %s\n",
440 fFile,fLine,getName(),strBuf,fCStr, u_errorName(setupStatus));
441 setupStatus = U_INTERNAL_PROGRAM_ERROR;
442 }
443 }
444 }
run()445 int32_t run() {
446 int32_t trial;
447 int i;
448 UChar buf[100];
449 if(U_SUCCESS(setupStatus)) {
450 for(i=0;i<U_LOTS_OF_TIMES;i++){
451 trial = unum_formatDouble(fFmt,fExpect, buf, 100, NULL, &setupStatus);
452 }
453 }
454 return i;
455 }
~NumFmtTest()456 virtual ~NumFmtTest(){}
457 };
458
459 #define DO_NumFmtTest(p,n,x) { NumFmtTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); }
460
461 class NumFmtInt64Test : public HowExpensiveTest {
462 public:
463 enum EMode {
464 kDefault,
465 kPattern,
466 kApplyPattern,
467 kGroupOff,
468 kApplyGroupOff
469 };
470 private:
471 EMode fMode;
472 int64_t fExpect;
473 UNumberFormat *fFmt;
474 UnicodeString fPat;
475 UnicodeString fString;
476 const UChar *fStr;
477 int32_t fLen;
478 const char *fFile;
479 int fLine;
480 const char *fCPat;
481 const char *fCStr;
482 char name[100];
483 public:
getName()484 virtual const char *getName() {
485 if(name[0]==0) {
486 sprintf(name,"%s:p=|%s|,str=|%s|",getClassName(),fCPat,fCStr);
487 }
488 return name;
489 }
490 protected:
initFmt()491 virtual UNumberFormat* initFmt() {
492 switch(fMode) {
493 case kPattern:
494 return unum_open(UNUM_PATTERN_DECIMAL, fPat.getTerminatedBuffer(), -1, TEST_LOCALE, 0, &setupStatus);
495 case kApplyPattern:
496 {
497 UNumberFormat *fmt = unum_open(UNUM_DECIMAL, NULL, -1, TEST_LOCALE, 0, &setupStatus);
498 unum_applyPattern(fmt, FALSE, fPat.getTerminatedBuffer(), -1, NULL, &setupStatus);
499 return fmt;
500 }
501 case kGroupOff:
502 {
503 UNumberFormat *fmt = unum_open(UNUM_PATTERN_DECIMAL, fPat.getTerminatedBuffer(), -1, TEST_LOCALE, 0, &setupStatus);
504 unum_setAttribute(fmt, UNUM_GROUPING_USED, UNUM_NO);
505 return fmt;
506 }
507 case kApplyGroupOff:
508 {
509 UNumberFormat *fmt = unum_open(UNUM_DECIMAL, NULL, -1, TEST_LOCALE, 0, &setupStatus);
510 unum_applyPattern(fmt, FALSE, fPat.getTerminatedBuffer(), -1, NULL, &setupStatus);
511 unum_setAttribute(fmt, UNUM_GROUPING_USED, UNUM_NO);
512 return fmt;
513 }
514 default:
515 case kDefault:
516 return unum_open(UNUM_DEFAULT, NULL, -1, TEST_LOCALE, 0, &setupStatus);
517 }
518 }
getClassName()519 virtual const char *getClassName() {
520 switch(fMode) {
521 case EMode::kDefault:
522 return "NumFmtInt64Test (default)";
523 case EMode::kPattern:
524 return "NumFmtInt64Test (pattern)";
525 case EMode::kApplyPattern:
526 return "NumFmtInt64Test (applypattern)";
527 case EMode::kGroupOff:
528 return "NumFmtInt64Test (pattern, group=off)";
529 case EMode::kApplyGroupOff:
530 return "NumFmtInt64Test (applypattern, group=off)";
531 default:
532 return "NumFmtInt64Test (? ? ?)";
533 }
534 }
535 public:
NumFmtInt64Test(const char * pat,const char * num,int64_t expect,const char * FILE,int LINE,EMode mode)536 NumFmtInt64Test(const char *pat, const char *num, int64_t expect, const char *FILE, int LINE, EMode mode)
537 : HowExpensiveTest("(n/a)",FILE, LINE),
538 fMode(mode),
539 fExpect(expect),
540 fFmt(0),
541 fPat(pat, -1, US_INV),
542 fString(num,-1,US_INV),
543 fStr(fString.getTerminatedBuffer()),
544 fLen(u_strlen(fStr)),
545 fFile(FILE),
546 fLine(LINE),
547 fCPat(pat),
548 fCStr(num)
549 {
550 name[0]=0;
551 }
warmup()552 void warmup() {
553 fFmt = initFmt();
554 UChar buf[100];
555 if(U_SUCCESS(setupStatus)) {
556 int32_t trial = unum_formatInt64(fFmt,fExpect, buf, 100, NULL, &setupStatus);
557 if(!U_SUCCESS(setupStatus)
558 || trial!=fLen
559 ||trial<=0
560 || u_strncmp(fStr,buf,trial) ) {
561 char strBuf[200];
562 u_strToUTF8(strBuf,200,NULL,buf,trial+1,&setupStatus);
563 printf("%s:%d: warmup() %s got %s (len %d) expected %s (len %d), err %s\n",
564 fFile,fLine,getName(),strBuf,trial,fCStr,fLen, u_errorName(setupStatus));
565 setupStatus = U_INTERNAL_PROGRAM_ERROR;
566 }
567 }
568 }
run()569 int32_t run() {
570 int32_t trial;
571 int i;
572 UChar buf[100];
573 if(U_SUCCESS(setupStatus)) {
574 for(i=0;i<U_LOTS_OF_TIMES;i++){
575 trial = unum_formatInt64(fFmt,fExpect, buf, 100, NULL, &setupStatus);
576 }
577 }
578 return i;
579 }
~NumFmtInt64Test()580 virtual ~NumFmtInt64Test(){}
581 };
582
583 /**
584 * unum_open .. with pattern, == new DecimalFormat(pattern)
585 */
586 #define DO_NumFmtInt64Test(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kPattern); runTestOn(t); }
587 /**
588 * unum_open(UNUM_DECIMAL), then
589 */
590 #define DO_NumFmtInt64Test_apply(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kApplyPattern); runTestOn(t); }
591
592 #define DO_NumFmtInt64Test_default(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kDefault); runTestOn(t); }
593 #define DO_NumFmtInt64Test_gr0(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kGroupOff); runTestOn(t); }
594 #define DO_NumFmtInt64Test_applygr0(p,n,x) { NumFmtInt64Test t(p,n,x,__FILE__,__LINE__,NumFmtInt64Test::EMode::kApplyGroupOff); runTestOn(t); }
595
596
597 class NumFmtStringPieceTest : public HowExpensiveTest {
598 private:
599 const StringPiece &fExpect;
600 UNumberFormat *fFmt;
601 UnicodeString fPat;
602 UnicodeString fString;
603 const UChar *fStr;
604 int32_t fLen;
605 const char *fFile;
606 int fLine;
607 const char *fCPat;
608 const char *fCStr;
609 char name[100];
610 public:
getName()611 virtual const char *getName() {
612 if(name[0]==0) {
613 sprintf(name,"%s:p=|%s|,str=|%s|,sp=|%s|",getClassName(),fCPat,fCStr, fExpect.data());
614 }
615 return name;
616 }
617 protected:
initFmt()618 virtual UNumberFormat* initFmt() {
619 DecimalFormat *d = new DecimalFormat(setupStatus);
620 UParseError pe;
621 d->applyPattern(fPat, pe, setupStatus);
622 return (UNumberFormat*) d;
623 }
getClassName()624 virtual const char *getClassName() {
625 return "NumFmtStringPieceTest";
626 }
627 public:
NumFmtStringPieceTest(const char * pat,const char * num,const StringPiece & expect,const char * FILE,int LINE)628 NumFmtStringPieceTest(const char *pat, const char *num, const StringPiece& expect, const char *FILE, int LINE)
629 : HowExpensiveTest("(n/a)",FILE, LINE),
630 fExpect(expect),
631 fFmt(0),
632 fPat(pat, -1, US_INV),
633 fString(num,-1,US_INV),
634 fStr(fString.getTerminatedBuffer()),
635 fLen(u_strlen(fStr)),
636 fFile(FILE),
637 fLine(LINE),
638 fCPat(pat),
639 fCStr(num)
640 {
641 name[0]=0;
642 }
warmup()643 void warmup() {
644 fFmt = initFmt();
645 UnicodeString buf;
646 if(U_SUCCESS(setupStatus)) {
647 buf.remove();
648 ((const DecimalFormat*)fFmt)->format(fExpect, buf, NULL, setupStatus);
649 if(!U_SUCCESS(setupStatus)
650 || fString!=buf
651 ) {
652 char strBuf[200];
653 u_strToUTF8(strBuf,200,NULL,buf.getTerminatedBuffer(),buf.length()+1,&setupStatus);
654 printf("%s:%d: warmup() %s got %s (len %d) expected %s (len %d), err %s\n",
655 fFile,fLine,getName(),strBuf,buf.length(),fCStr,fLen, u_errorName(setupStatus));
656 setupStatus = U_INTERNAL_PROGRAM_ERROR;
657 }
658 }
659 }
660
run()661 int32_t run() {
662 #if U_DEBUG
663 int32_t trial;
664 #endif
665 int i=0;
666 UnicodeString buf;
667 if(U_SUCCESS(setupStatus)) {
668 for(i=0;i<U_LOTS_OF_TIMES;i++){
669 buf.remove();
670 ((const DecimalFormat*)fFmt)->format(fExpect, buf, NULL, setupStatus);
671 }
672 }
673 return i;
674 }
~NumFmtStringPieceTest()675 virtual ~NumFmtStringPieceTest(){}
676 };
677
678 #define DO_NumFmtStringPieceTest(p,n,x) { NumFmtStringPieceTest t(p,n,x,__FILE__,__LINE__); runTestOn(t); }
679
680 // TODO: move, scope.
681 static UChar pattern[] = { 0x23 }; // '#'
682 static UChar strdot[] = { '2', '.', '0', 0 };
683 static UChar strspc[] = { '2', ' ', 0 };
684 static UChar strgrp[] = {'2',',','2','2','2', 0 };
685 static UChar strbeng[] = {0x09E8,0x09E8,0x09E8,0x09E8, 0 };
686
687 UNumberFormat *NumParseTest_fmt;
688
689 // TODO: de-uglify.
690 QuickTest(NumParseTest,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; static UChar str[] = { 0x31 };double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,str,1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
691
692 QuickTest(NumParseTestdot,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strdot,1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
693 QuickTest(NumParseTestspc,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strspc,1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
694 QuickTest(NumParseTestgrp,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strgrp,-1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
695
696 QuickTest(NumParseTestbeng,{ static UChar pattern[] = { 0x23 }; NumParseTest_fmt = unum_open(UNUM_PATTERN_DECIMAL, pattern, 1, TEST_LOCALE, 0, &setupStatus); },{ int32_t i; double val; for(i=0;i<U_LOTS_OF_TIMES;i++) { val=unum_parse(NumParseTest_fmt,strbeng,-1,NULL,&setupStatus); } return i; },{unum_close(NumParseTest_fmt);})
697
698 UDateFormat *DateFormatTest_fmt = NULL;
699 UDate sometime = 100000000.0;
700 UChar onekbuf[1024];
701 const int32_t onekbuf_len = sizeof(onekbuf)/sizeof(onekbuf[0]);
702
703
704 QuickTest(DateFormatTestBasic, \
705 { \
706 DateFormatTest_fmt = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &setupStatus); \
707 }, \
708 { \
709 int i; \
710 for(i=0;i<U_LOTS_OF_TIMES;i++) \
711 { \
712 udat_format(DateFormatTest_fmt, sometime, onekbuf, onekbuf_len, NULL, &setupStatus); \
713 } \
714 return i; \
715 }, \
716 { \
717 udat_close(DateFormatTest_fmt); \
718 } \
719 )
720
721
722 QuickTest(NullTest,{},{int j=U_LOTS_OF_TIMES;while(--j);return U_LOTS_OF_TIMES;},{})
723
724 #if 0
725 #include <time.h>
726
727 QuickTest(RandomTest,{},{timespec ts; ts.tv_sec=rand()%4; int j=U_LOTS_OF_TIMES;while(--j) { ts.tv_nsec=100000+(rand()%10000)*1000000; nanosleep(&ts,NULL); return j;} return U_LOTS_OF_TIMES;},{})
728 #endif
729
730 OpenCloseTest(pattern,unum,open,{},(UNUM_PATTERN_DECIMAL,pattern,1,TEST_LOCALE,0,&setupStatus),{})
731 OpenCloseTest(default,unum,open,{},(UNUM_DEFAULT,NULL,-1,TEST_LOCALE,0,&setupStatus),{})
732 #if !UCONFIG_NO_CONVERSION
733 #include "unicode/ucnv.h"
734 OpenCloseTest(gb18030,ucnv,open,{},("gb18030",&setupStatus),{})
735 #endif
736 #include "unicode/ures.h"
737 OpenCloseTest(root,ures,open,{},(NULL,"root",&setupStatus),{})
738
runTests()739 void runTests() {
740 {
741 SieveTest t;
742 runTestOn(t);
743 }
744 #if 0
745 {
746 RandomTest t;
747 runTestOn(t);
748 }
749 #endif
750 {
751 NullTest t;
752 runTestOn(t);
753 }
754
755 #ifndef SKIP_DATEFMT_TESTS
756 {
757 DateFormatTestBasic t;
758 runTestOn(t);
759 }
760 #endif
761
762 #ifndef SKIP_NUMPARSE_TESTS
763 {
764 // parse tests
765
766 DO_NumTest("#","0",0.0);
767 DO_NumTest("#","2.0",2.0);
768 DO_NumTest("#","2 ",2);
769 DO_NumTest("#","-2 ",-2);
770 DO_NumTest("+#","+2",2);
771 DO_NumTest("#,###.0","2222.0",2222.0);
772 DO_NumTest("#.0","1.000000000000000000000000000000000000000000000000000000000000000000000000000000",1.0);
773 DO_NumTest("#","123456",123456);
774
775 // attr
776 #ifdef HAVE_UNUM_MAYBE
777 DO_AttrNumTest("#","0",0.0,UNUM_PARSE_ALL_INPUT,UNUM_YES);
778 DO_AttrNumTest("#","0",0.0,UNUM_PARSE_ALL_INPUT,UNUM_NO);
779 DO_AttrNumTest("#","0",0.0,UNUM_PARSE_ALL_INPUT,UNUM_MAYBE);
780 DO_TripleNumTest("#","2.0",2.0);
781 DO_AttrNumTest("#.0","1.000000000000000000000000000000000000000000000000000000000000000000000000000000",1.0,UNUM_PARSE_ALL_INPUT,UNUM_NO);
782 #endif
783
784
785 // { NumParseTestgrp t; runTestOn(t); }
786 { NumParseTestbeng t; runTestOn(t); }
787
788 }
789 #endif
790
791 #ifndef SKIP_NUMFORMAT_TESTS
792 // format tests
793 {
794
795 DO_NumFmtInt64Test("0000","0001",1);
796 DO_NumFmtInt64Test("0000","0000",0);
797 StringPiece sp3456("3456");
798 DO_NumFmtStringPieceTest("0000","3456",sp3456);
799 DO_NumFmtStringPieceTest("#","3456",sp3456);
800 StringPiece sp3("3");
801 DO_NumFmtStringPieceTest("0000","0003",sp3);
802 DO_NumFmtStringPieceTest("#","3",sp3);
803 StringPiece spn3("-3");
804 DO_NumFmtStringPieceTest("0000","-0003",spn3);
805 DO_NumFmtStringPieceTest("#","-3",spn3);
806 StringPiece spPI("123.456");
807 DO_NumFmtStringPieceTest("#.0000","123.4560",spPI);
808 DO_NumFmtStringPieceTest("#.00","123.46",spPI);
809
810 DO_NumFmtTest("#","0",0.0);
811 DO_NumFmtTest("#","12345",12345);
812 DO_NumFmtTest("#","-2",-2);
813 DO_NumFmtTest("+#","+2",2);
814
815 DO_NumFmtInt64Test("#","-682",-682);
816 DO_NumFmtInt64Test("#","0",0);
817 DO_NumFmtInt64Test("#","12345",12345);
818 DO_NumFmtInt64Test("#,###","12,345",12345);
819 DO_NumFmtInt64Test("#","1234",1234);
820 DO_NumFmtInt64Test("#","123",123);
821 DO_NumFmtInt64Test("#,###","123",123);
822 DO_NumFmtInt64Test_apply("#","123",123);
823 DO_NumFmtInt64Test_apply("#","12345",12345);
824 DO_NumFmtInt64Test_apply("#,###","123",123);
825 DO_NumFmtInt64Test_apply("#,###","12,345",12345);
826 DO_NumFmtInt64Test_default("","123",123);
827 DO_NumFmtInt64Test_default("","12,345",12345);
828 DO_NumFmtInt64Test_applygr0("#","123",123);
829 DO_NumFmtInt64Test_applygr0("#","12345",12345);
830 DO_NumFmtInt64Test_applygr0("#,###","123",123);
831 DO_NumFmtInt64Test_applygr0("#,###","12345",12345);
832 DO_NumFmtInt64Test_gr0("#","123",123);
833 DO_NumFmtInt64Test_gr0("#","12345",12345);
834 DO_NumFmtInt64Test_gr0("#,###","123",123);
835 DO_NumFmtInt64Test_gr0("#,###","12345",12345);
836 DO_NumFmtInt64Test("#","-2",-2);
837 DO_NumFmtInt64Test("+#","+2",2);
838 }
839
840 #ifndef SKIP_NUM_OPEN_TEST
841 {
842 Test_unum_opendefault t;
843 runTestOn(t);
844 }
845 {
846 Test_unum_openpattern t;
847 runTestOn(t);
848 }
849 #endif
850
851 #endif /* skip numformat tests */
852 #if !UCONFIG_NO_CONVERSION
853 {
854 Test_ucnv_opengb18030 t;
855 runTestOn(t);
856 }
857 #endif
858 {
859 Test_ures_openroot t;
860 runTestOn(t);
861 }
862
863 if(testhit==0) {
864 fprintf(stderr, "ERROR: no tests matched.\n");
865 }
866 }
867