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