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 and
6 * others. All Rights Reserved.
7 ********************************************************************/
8
9
10 #include "unicode/utypes.h"
11
12 /**
13 * IntlTest is a base class for tests.
14 */
15
16 #include <assert.h>
17 #include <stdarg.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <cmath>
22 #include <math.h>
23 #include <iostream>
24
25 #include "unicode/ctest.h" // for str_timeDelta
26 #include "unicode/curramt.h"
27 #include "unicode/locid.h"
28 #include "unicode/putil.h"
29 #include "unicode/smpdtfmt.h"
30 #include "unicode/timezone.h"
31 #include "unicode/uclean.h"
32 #include "unicode/ucnv.h"
33 #include "unicode/unistr.h"
34 #include "unicode/ures.h"
35 #include "unicode/utf16.h"
36
37 #include "intltest.h"
38
39 #include "caltztst.h"
40 #include "cmemory.h"
41 #include "cstring.h"
42 #include "itmajor.h"
43 #include "mutex.h"
44 #include "putilimp.h" // for uprv_getRawUTCtime()
45 #include "uassert.h"
46 #include "udbgutil.h"
47 #include "umutex.h"
48 #include "uoptions.h"
49 #include "number_decnum.h"
50
51 #ifdef XP_MAC_CONSOLE
52 #include <console.h>
53 #include "Files.h"
54 #endif
55
56
57 // Static list of errors found
58 static UnicodeString errorList;
59 static void *knownList = NULL; // known issues
60 static UBool noKnownIssues = FALSE; // if TRUE, don't emit known issues
61
62 //-----------------------------------------------------------------------------
63 //convenience classes to ease porting code that uses the Java
64 //string-concatenation operator (moved from findword test by rtg)
65
66 // [LIU] Just to get things working
67 UnicodeString
UCharToUnicodeString(UChar c)68 UCharToUnicodeString(UChar c)
69 { return UnicodeString(c); }
70
71 // [rtg] Just to get things working
72 UnicodeString
operator +(const UnicodeString & left,long num)73 operator+(const UnicodeString& left,
74 long num)
75 {
76 char buffer[64]; // nos changed from 10 to 64
77 char danger = 'p'; // guard against overrunning the buffer (rtg)
78
79 sprintf(buffer, "%ld", num);
80 assert(danger == 'p');
81
82 return left + buffer;
83 }
84
85 UnicodeString
operator +(const UnicodeString & left,unsigned long num)86 operator+(const UnicodeString& left,
87 unsigned long num)
88 {
89 char buffer[64]; // nos changed from 10 to 64
90 char danger = 'p'; // guard against overrunning the buffer (rtg)
91
92 sprintf(buffer, "%lu", num);
93 assert(danger == 'p');
94
95 return left + buffer;
96 }
97
98 UnicodeString
Int64ToUnicodeString(int64_t num)99 Int64ToUnicodeString(int64_t num)
100 {
101 char buffer[64]; // nos changed from 10 to 64
102 char danger = 'p'; // guard against overrunning the buffer (rtg)
103
104 #if defined(_MSC_VER)
105 sprintf(buffer, "%I64d", num);
106 #else
107 sprintf(buffer, "%lld", (long long)num);
108 #endif
109 assert(danger == 'p');
110
111 return buffer;
112 }
113
114 UnicodeString
DoubleToUnicodeString(double num)115 DoubleToUnicodeString(double num)
116 {
117 char buffer[64]; // nos changed from 10 to 64
118 char danger = 'p'; // guard against overrunning the buffer (rtg)
119
120 sprintf(buffer, "%1.14e", num);
121 assert(danger == 'p');
122
123 return buffer;
124 }
125
126 // [LIU] Just to get things working
127 UnicodeString
operator +(const UnicodeString & left,double num)128 operator+(const UnicodeString& left,
129 double num)
130 {
131 char buffer[64]; // was 32, made it arbitrarily bigger (rtg)
132 char danger = 'p'; // guard against overrunning the buffer (rtg)
133
134 // IEEE floating point has 52 bits of mantissa, plus one assumed bit
135 // 53*log(2)/log(10) = 15.95
136 // so there is no need to show more than 16 digits. [alan]
137
138 sprintf(buffer, "%.17g", num);
139 assert(danger == 'p');
140
141 return left + buffer;
142 }
143
144 #if 0
145 UnicodeString
146 operator+(const UnicodeString& left,
147 int64_t num) {
148 return left + Int64ToUnicodeString(num);
149 }
150 #endif
151
152 #if !UCONFIG_NO_FORMATTING
153
154 /**
155 * Return a string display for this, without surrounding braces.
156 */
_toString(const Formattable & f)157 UnicodeString _toString(const Formattable& f) {
158 UnicodeString s;
159 switch (f.getType()) {
160 case Formattable::kDate:
161 {
162 UErrorCode status = U_ZERO_ERROR;
163 SimpleDateFormat fmt(status);
164 if (U_SUCCESS(status)) {
165 FieldPosition pos;
166 fmt.format(f.getDate(), s, pos);
167 s.insert(0, "Date:");
168 } else {
169 s = UnicodeString("Error creating date format]");
170 }
171 }
172 break;
173 case Formattable::kDouble:
174 s = UnicodeString("double:") + f.getDouble();
175 break;
176 case Formattable::kLong:
177 s = UnicodeString("long:") + f.getLong();
178 break;
179
180 case Formattable::kInt64:
181 s = UnicodeString("int64:") + Int64ToUnicodeString(f.getInt64());
182 break;
183
184 case Formattable::kString:
185 f.getString(s);
186 s.insert(0, "String:");
187 break;
188 case Formattable::kArray:
189 {
190 int32_t i, n;
191 const Formattable* array = f.getArray(n);
192 s.insert(0, UnicodeString("Array:"));
193 UnicodeString delim(", ");
194 for (i=0; i<n; ++i) {
195 if (i > 0) {
196 s.append(delim);
197 }
198 s = s + _toString(array[i]);
199 }
200 }
201 break;
202 case Formattable::kObject: {
203 const CurrencyAmount* c = dynamic_cast<const CurrencyAmount*>(f.getObject());
204 if (c != NULL) {
205 s = _toString(c->getNumber()) + " " + UnicodeString(c->getISOCurrency());
206 } else {
207 s = UnicodeString("Unknown UObject");
208 }
209 break;
210 }
211 default:
212 s = UnicodeString("Unknown Formattable type=") + (int32_t)f.getType();
213 break;
214 }
215 return s;
216 }
217
218 /**
219 * Originally coded this as operator+, but that makes the expression
220 * + char* ambiguous. - liu
221 */
toString(const Formattable & f)222 UnicodeString toString(const Formattable& f) {
223 UnicodeString s((UChar)91/*[*/);
224 s.append(_toString(f));
225 s.append((UChar)0x5d/*]*/);
226 return s;
227 }
228
229 #endif
230
231 // useful when operator+ won't cooperate
toString(int32_t n)232 UnicodeString toString(int32_t n) {
233 return UnicodeString() + (long)n;
234 }
235
236
237
toString(UBool b)238 UnicodeString toString(UBool b) {
239 return b ? UnicodeString("TRUE"):UnicodeString("FALSE");
240 }
241
toString(const UnicodeSet & uniset,UErrorCode & status)242 UnicodeString toString(const UnicodeSet& uniset, UErrorCode& status) {
243 UnicodeString result;
244 uniset.toPattern(result, status);
245 return result;
246 }
247
248 // stephen - cleaned up 05/05/99
operator +(const UnicodeString & left,char num)249 UnicodeString operator+(const UnicodeString& left, char num)
250 { return left + (long)num; }
operator +(const UnicodeString & left,short num)251 UnicodeString operator+(const UnicodeString& left, short num)
252 { return left + (long)num; }
operator +(const UnicodeString & left,int num)253 UnicodeString operator+(const UnicodeString& left, int num)
254 { return left + (long)num; }
operator +(const UnicodeString & left,unsigned char num)255 UnicodeString operator+(const UnicodeString& left, unsigned char num)
256 { return left + (unsigned long)num; }
operator +(const UnicodeString & left,unsigned short num)257 UnicodeString operator+(const UnicodeString& left, unsigned short num)
258 { return left + (unsigned long)num; }
operator +(const UnicodeString & left,unsigned int num)259 UnicodeString operator+(const UnicodeString& left, unsigned int num)
260 { return left + (unsigned long)num; }
operator +(const UnicodeString & left,float num)261 UnicodeString operator+(const UnicodeString& left, float num)
262 { return left + (double)num; }
263
264 //------------------
265
266 // Append a hex string to the target
267 UnicodeString&
appendHex(uint32_t number,int32_t digits,UnicodeString & target)268 IntlTest::appendHex(uint32_t number,
269 int32_t digits,
270 UnicodeString& target)
271 {
272 static const UChar digitString[] = {
273 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
274 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0
275 }; /* "0123456789ABCDEF" */
276
277 if (digits < 0) { // auto-digits
278 digits = 2;
279 uint32_t max = 0xff;
280 while (number > max) {
281 digits += 2;
282 max = (max << 8) | 0xff;
283 }
284 }
285 switch (digits)
286 {
287 case 8:
288 target += digitString[(number >> 28) & 0xF];
289 U_FALLTHROUGH;
290 case 7:
291 target += digitString[(number >> 24) & 0xF];
292 U_FALLTHROUGH;
293 case 6:
294 target += digitString[(number >> 20) & 0xF];
295 U_FALLTHROUGH;
296 case 5:
297 target += digitString[(number >> 16) & 0xF];
298 U_FALLTHROUGH;
299 case 4:
300 target += digitString[(number >> 12) & 0xF];
301 U_FALLTHROUGH;
302 case 3:
303 target += digitString[(number >> 8) & 0xF];
304 U_FALLTHROUGH;
305 case 2:
306 target += digitString[(number >> 4) & 0xF];
307 U_FALLTHROUGH;
308 case 1:
309 target += digitString[(number >> 0) & 0xF];
310 break;
311 default:
312 target += "**";
313 }
314 return target;
315 }
316
317 UnicodeString
toHex(uint32_t number,int32_t digits)318 IntlTest::toHex(uint32_t number, int32_t digits) {
319 UnicodeString result;
320 appendHex(number, digits, result);
321 return result;
322 }
323
isPrintable(UChar32 c)324 static inline UBool isPrintable(UChar32 c) {
325 return c <= 0x7E && (c >= 0x20 || c == 9 || c == 0xA || c == 0xD);
326 }
327
328 // Replace nonprintable characters with unicode escapes
329 UnicodeString&
prettify(const UnicodeString & source,UnicodeString & target)330 IntlTest::prettify(const UnicodeString &source,
331 UnicodeString &target)
332 {
333 int32_t i;
334
335 target.remove();
336 target += "\"";
337
338 for (i = 0; i < source.length(); )
339 {
340 UChar32 ch = source.char32At(i);
341 i += U16_LENGTH(ch);
342
343 if (!isPrintable(ch))
344 {
345 if (ch <= 0xFFFF) {
346 target += "\\u";
347 appendHex(ch, 4, target);
348 } else {
349 target += "\\U";
350 appendHex(ch, 8, target);
351 }
352 }
353 else
354 {
355 target += ch;
356 }
357 }
358
359 target += "\"";
360
361 return target;
362 }
363
364 // Replace nonprintable characters with unicode escapes
365 UnicodeString
prettify(const UnicodeString & source,UBool parseBackslash)366 IntlTest::prettify(const UnicodeString &source, UBool parseBackslash)
367 {
368 int32_t i;
369 UnicodeString target;
370 target.remove();
371 target += "\"";
372
373 for (i = 0; i < source.length();)
374 {
375 UChar32 ch = source.char32At(i);
376 i += U16_LENGTH(ch);
377
378 if (!isPrintable(ch))
379 {
380 if (parseBackslash) {
381 // If we are preceded by an odd number of backslashes,
382 // then this character has already been backslash escaped.
383 // Delete a backslash.
384 int32_t backslashCount = 0;
385 for (int32_t j=target.length()-1; j>=0; --j) {
386 if (target.charAt(j) == (UChar)92) {
387 ++backslashCount;
388 } else {
389 break;
390 }
391 }
392 if ((backslashCount % 2) == 1) {
393 target.truncate(target.length() - 1);
394 }
395 }
396 if (ch <= 0xFFFF) {
397 target += "\\u";
398 appendHex(ch, 4, target);
399 } else {
400 target += "\\U";
401 appendHex(ch, 8, target);
402 }
403 }
404 else
405 {
406 target += ch;
407 }
408 }
409
410 target += "\"";
411
412 return target;
413 }
414
415 /* IntlTest::setICU_DATA - if the ICU_DATA environment variable is not already
416 * set, try to deduce the directory in which ICU was built,
417 * and set ICU_DATA to "icu/source/data" in that location.
418 * The intent is to allow the tests to have a good chance
419 * of running without requiring that the user manually set
420 * ICU_DATA. Common data isn't a problem, since it is
421 * picked up via a static (build time) reference, but the
422 * tests dynamically load some data.
423 */
setICU_DATA()424 void IntlTest::setICU_DATA() {
425 // Android-changed: Do not u_setDataDirectory because libicuuc.so initializes itself.
426 #if !defined(ANDROID_USE_ICU_REG)
427 u_setDataDirectory(ctest_dataOutDir());
428 #endif
429 }
430
431
432 //--------------------------------------------------------------------------------------
433
434 static const int32_t indentLevel_offset = 3;
435 static const char delim = '/';
436
437 IntlTest* IntlTest::gTest = NULL;
438
439 static int32_t execCount = 0;
440
it_log(UnicodeString message)441 void it_log( UnicodeString message )
442 {
443 if (IntlTest::gTest)
444 IntlTest::gTest->log( message );
445 }
446
it_logln(UnicodeString message)447 void it_logln( UnicodeString message )
448 {
449 if (IntlTest::gTest)
450 IntlTest::gTest->logln( message );
451 }
452
it_logln(void)453 void it_logln( void )
454 {
455 if (IntlTest::gTest)
456 IntlTest::gTest->logln();
457 }
458
it_info(UnicodeString message)459 void it_info( UnicodeString message )
460 {
461 if (IntlTest::gTest)
462 IntlTest::gTest->info( message );
463 }
464
it_infoln(UnicodeString message)465 void it_infoln( UnicodeString message )
466 {
467 if (IntlTest::gTest)
468 IntlTest::gTest->infoln( message );
469 }
470
it_infoln(void)471 void it_infoln( void )
472 {
473 if (IntlTest::gTest)
474 IntlTest::gTest->infoln();
475 }
476
it_err()477 void it_err()
478 {
479 if (IntlTest::gTest)
480 IntlTest::gTest->err();
481 }
482
it_err(UnicodeString message)483 void it_err( UnicodeString message )
484 {
485 if (IntlTest::gTest)
486 IntlTest::gTest->err( message );
487 }
488
it_errln(UnicodeString message)489 void it_errln( UnicodeString message )
490 {
491 if (IntlTest::gTest)
492 IntlTest::gTest->errln( message );
493 }
494
it_dataerr(UnicodeString message)495 void it_dataerr( UnicodeString message )
496 {
497 if (IntlTest::gTest)
498 IntlTest::gTest->dataerr( message );
499 }
500
it_dataerrln(UnicodeString message)501 void it_dataerrln( UnicodeString message )
502 {
503 if (IntlTest::gTest)
504 IntlTest::gTest->dataerrln( message );
505 }
506
IntlTest()507 IntlTest::IntlTest()
508 {
509 caller = NULL;
510 testPath = NULL;
511 LL_linestart = TRUE;
512 errorCount = 0;
513 dataErrorCount = 0;
514 verbose = FALSE;
515 no_time = FALSE;
516 no_err_msg = FALSE;
517 warn_on_missing_data = FALSE;
518 quick = FALSE;
519 leaks = FALSE;
520 threadCount = 12;
521 testoutfp = stdout;
522 LL_indentlevel = indentLevel_offset;
523 numProps = 0;
524 strcpy(basePath, "/");
525 currName[0]=0;
526 }
527
setCaller(IntlTest * callingTest)528 void IntlTest::setCaller( IntlTest* callingTest )
529 {
530 caller = callingTest;
531 if (caller) {
532 warn_on_missing_data = caller->warn_on_missing_data;
533 verbose = caller->verbose;
534 no_err_msg = caller->no_err_msg;
535 quick = caller->quick;
536 threadCount = caller->threadCount;
537 testoutfp = caller->testoutfp;
538 write_golden_data = caller->write_golden_data;
539 LL_indentlevel = caller->LL_indentlevel + indentLevel_offset;
540 numProps = caller->numProps;
541 for (int32_t i = 0; i < numProps; i++) {
542 proplines[i] = caller->proplines[i];
543 }
544 }
545 }
546
callTest(IntlTest & testToBeCalled,char * par,const char * basename)547 UBool IntlTest::callTest( IntlTest& testToBeCalled, char* par, const char* basename)
548 {
549 execCount--; // correct a previously assumed test-exec, as this only calls a subtest
550 testToBeCalled.setCaller( this );
551 strcpy(testToBeCalled.basePath, basename);
552 strcat(testToBeCalled.basePath, this->basePath);
553 UBool result = testToBeCalled.runTest( testPath, par, testToBeCalled.basePath);
554 strcpy(testToBeCalled.basePath, basename); // reset it.
555 strcat(testToBeCalled.basePath, this->basePath);
556 return result;
557 }
558
setPath(char * pathVal)559 void IntlTest::setPath( char* pathVal )
560 {
561 this->testPath = pathVal;
562 }
563
setVerbose(UBool verboseVal)564 UBool IntlTest::setVerbose( UBool verboseVal )
565 {
566 UBool rval = this->verbose;
567 this->verbose = verboseVal;
568 return rval;
569 }
570
setNotime(UBool no_time)571 UBool IntlTest::setNotime( UBool no_time )
572 {
573 UBool rval = this->no_time;
574 this->no_time = no_time;
575 return rval;
576 }
577
setWarnOnMissingData(UBool warn_on_missing_dataVal)578 UBool IntlTest::setWarnOnMissingData( UBool warn_on_missing_dataVal )
579 {
580 UBool rval = this->warn_on_missing_data;
581 this->warn_on_missing_data = warn_on_missing_dataVal;
582 return rval;
583 }
584
setWriteGoldenData(UBool write_golden_data)585 UBool IntlTest::setWriteGoldenData( UBool write_golden_data )
586 {
587 UBool rval = this->write_golden_data;
588 this->write_golden_data = write_golden_data;
589 return rval;
590 }
591
setNoErrMsg(UBool no_err_msgVal)592 UBool IntlTest::setNoErrMsg( UBool no_err_msgVal )
593 {
594 UBool rval = this->no_err_msg;
595 this->no_err_msg = no_err_msgVal;
596 return rval;
597 }
598
setQuick(UBool quickVal)599 UBool IntlTest::setQuick( UBool quickVal )
600 {
601 UBool rval = this->quick;
602 this->quick = quickVal;
603 return rval;
604 }
605
setLeaks(UBool leaksVal)606 UBool IntlTest::setLeaks( UBool leaksVal )
607 {
608 UBool rval = this->leaks;
609 this->leaks = leaksVal;
610 return rval;
611 }
612
setThreadCount(int32_t count)613 int32_t IntlTest::setThreadCount( int32_t count )
614 {
615 int32_t rval = this->threadCount;
616 this->threadCount = count;
617 return rval;
618 }
619
getErrors(void)620 int32_t IntlTest::getErrors( void )
621 {
622 return errorCount;
623 }
624
getDataErrors(void)625 int32_t IntlTest::getDataErrors( void )
626 {
627 return dataErrorCount;
628 }
629
runTest(char * name,char * par,char * baseName)630 UBool IntlTest::runTest( char* name, char* par, char *baseName )
631 {
632 UBool rval;
633 char* pos = NULL;
634
635 char* baseNameBuffer = NULL;
636
637 if(baseName == NULL) {
638 baseNameBuffer = (char*)malloc(1024);
639 baseName=baseNameBuffer;
640 strcpy(baseName, "/");
641 }
642
643 if (name)
644 pos = strchr( name, delim ); // check if name contains path (by looking for '/')
645 if (pos) {
646 testPath = pos+1; // store subpath for calling subtest
647 *pos = 0; // split into two strings
648 }else{
649 testPath = NULL;
650 }
651
652 if (!name || (name[0] == 0) || (strcmp(name, "*") == 0)) {
653 rval = runTestLoop( NULL, par, baseName );
654
655 }else if (strcmp( name, "LIST" ) == 0) {
656 this->usage();
657 rval = TRUE;
658
659 }else{
660 rval = runTestLoop( name, par, baseName );
661 }
662
663 if (pos)
664 *pos = delim; // restore original value at pos
665 if(baseNameBuffer!=NULL) {
666 free(baseNameBuffer);
667 }
668 return rval;
669 }
670
671 // call individual tests, to be overridden to call implementations
runIndexedTest(int32_t,UBool,const char * &,char *)672 void IntlTest::runIndexedTest( int32_t /*index*/, UBool /*exec*/, const char* & /*name*/, char* /*par*/ )
673 {
674 // to be overridden by a method like:
675 /*
676 switch (index) {
677 case 0: name = "First Test"; if (exec) FirstTest( par ); break;
678 case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
679 default: name = ""; break;
680 }
681 */
682 this->errln("*** runIndexedTest needs to be overridden! ***");
683 }
684
685
string_replace_all(std::string str,const std::string & from,const std::string & to)686 static std::string string_replace_all(std::string str, const std::string& from, const std::string& to) {
687 size_t start = 0;
688 while((start = str.find(from, start)) != std::string::npos) {
689 str.replace(start, from.length(), to);
690 start += to.length();
691 }
692 return str;
693 }
694
695 /**
696 * Escape some known characters, but the list is not perfect.
697 */
escape_xml_attribute(std::string str)698 static std::string escape_xml_attribute(std::string str) {
699 str = string_replace_all(str, "&", "&");
700 str = string_replace_all(str, "\"", """);
701 str = string_replace_all(str, "'", "'");
702 str = string_replace_all(str, "<", "<");
703 str = string_replace_all(str, ">", ">");
704 return str;
705 }
706
runTestLoop(char * testname,char * par,char * baseName)707 UBool IntlTest::runTestLoop( char* testname, char* par, char *baseName )
708 {
709 int32_t index = 0;
710 const char* name;
711 UBool run_this_test;
712 int32_t lastErrorCount;
713 UBool rval = FALSE;
714 UBool lastTestFailed;
715
716 if(baseName == NULL) {
717 printf("ERROR: baseName can't be null.\n");
718 return FALSE;
719 } else {
720 if ((char *)this->basePath != baseName) {
721 strcpy(this->basePath, baseName);
722 }
723 }
724
725 char * saveBaseLoc = baseName+strlen(baseName);
726
727 IntlTest* saveTest = gTest;
728 gTest = this;
729 do {
730 this->runIndexedTest( index, FALSE, name, par );
731 if (strcmp(name,"skip") == 0) {
732 run_this_test = FALSE;
733 } else {
734 if (!name || (name[0] == 0))
735 break;
736 if (!testname) {
737 run_this_test = TRUE;
738 }else{
739 run_this_test = (UBool) (strcmp( name, testname ) == 0);
740 }
741 }
742 if (run_this_test) {
743 lastErrorCount = errorCount;
744 execCount++;
745 char msg[256];
746 sprintf(msg, "%s {", name);
747 LL_message(msg, TRUE);
748 UDate timeStart = uprv_getRawUTCtime();
749 strcpy(saveBaseLoc,name);
750 strcat(saveBaseLoc,"/");
751
752 currErr = ""; // Reset the current error message
753 strcpy(currName, name); // set
754 this->runIndexedTest( index, TRUE, name, par );
755 currName[0]=0; // reset
756
757 UDate timeStop = uprv_getRawUTCtime();
758 rval = TRUE; // at least one test has been called
759 char secs[256];
760 if(!no_time) {
761 sprintf(secs, "%f", (timeStop-timeStart)/1000.0);
762 } else {
763 secs[0]=0;
764 }
765
766
767 strcpy(saveBaseLoc,name);
768
769
770 std::string err = currErr;
771 err = escape_xml_attribute(err);
772 ctest_xml_testcase(name, baseName, secs, (lastErrorCount!=errorCount)?err.c_str():NULL);
773
774
775 saveBaseLoc[0]=0; /* reset path */
776
777 if (lastErrorCount == errorCount) {
778 sprintf( msg, " } OK: %s ", name );
779 if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
780 lastTestFailed = FALSE;
781 }else{
782 sprintf(msg, " } ERRORS (%li) in %s", (long)(errorCount-lastErrorCount), name);
783 if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
784
785 for(int i=0;i<LL_indentlevel;i++) {
786 errorList += " ";
787 }
788 errorList += name;
789 errorList += "\n";
790 lastTestFailed = TRUE;
791 }
792 LL_indentlevel -= 3;
793 if (lastTestFailed) {
794 LL_message( "", TRUE);
795 }
796 LL_message( msg, TRUE);
797 if (lastTestFailed) {
798 LL_message( "", TRUE);
799 }
800 LL_indentlevel += 3;
801 }
802 index++;
803 }while(name);
804
805 *saveBaseLoc = 0;
806
807 gTest = saveTest;
808 return rval;
809 }
810
811
812 /**
813 * Adds given string to the log if we are in verbose mode.
814 */
log(const UnicodeString & message)815 void IntlTest::log( const UnicodeString &message )
816 {
817 if( verbose ) {
818 LL_message( message, FALSE );
819 }
820 }
821
822 /**
823 * Adds given string to the log if we are in verbose mode. Adds a new line to
824 * the given message.
825 */
logln(const UnicodeString & message)826 void IntlTest::logln( const UnicodeString &message )
827 {
828 if( verbose ) {
829 LL_message( message, TRUE );
830 }
831 }
832
logln(void)833 void IntlTest::logln( void )
834 {
835 if( verbose ) {
836 LL_message( "", TRUE );
837 }
838 }
839
840 /**
841 * Unconditionally adds given string to the log.
842 */
info(const UnicodeString & message)843 void IntlTest::info( const UnicodeString &message )
844 {
845 LL_message( message, FALSE );
846 }
847
848 /**
849 * Unconditionally adds given string to the log. Adds a new line to
850 * the given message.
851 */
infoln(const UnicodeString & message)852 void IntlTest::infoln( const UnicodeString &message )
853 {
854 LL_message( message, TRUE );
855 }
856
infoln(void)857 void IntlTest::infoln( void )
858 {
859 LL_message( "", TRUE );
860 }
861
IncErrorCount(void)862 int32_t IntlTest::IncErrorCount( void )
863 {
864 errorCount++;
865 if (caller) caller->IncErrorCount();
866 return errorCount;
867 }
868
IncDataErrorCount(void)869 int32_t IntlTest::IncDataErrorCount( void )
870 {
871 dataErrorCount++;
872 if (caller) caller->IncDataErrorCount();
873 return dataErrorCount;
874 }
875
err()876 void IntlTest::err()
877 {
878 IncErrorCount();
879 }
880
err(const UnicodeString & message)881 void IntlTest::err( const UnicodeString &message )
882 {
883 IncErrorCount();
884 if (!no_err_msg) LL_err_message( message, FALSE );
885 }
886
errln(const UnicodeString & message)887 void IntlTest::errln( const UnicodeString &message )
888 {
889 IncErrorCount();
890 if (!no_err_msg) LL_err_message( message, TRUE );
891 }
892
dataerr(const UnicodeString & message)893 void IntlTest::dataerr( const UnicodeString &message )
894 {
895 IncDataErrorCount();
896
897 if (!warn_on_missing_data) {
898 IncErrorCount();
899 }
900
901 if (!no_err_msg) LL_err_message( message, FALSE );
902 }
903
dataerrln(const UnicodeString & message)904 void IntlTest::dataerrln( const UnicodeString &message )
905 {
906 int32_t errCount = IncDataErrorCount();
907 UnicodeString msg;
908 if (!warn_on_missing_data) {
909 IncErrorCount();
910 msg = message;
911 } else {
912 msg = UnicodeString("[DATA] " + message);
913 }
914
915 if (!no_err_msg) {
916 if ( errCount == 1) {
917 LL_err_message( msg + " - (Are you missing data?)", TRUE ); // only show this message the first time
918 } else {
919 LL_err_message( msg , TRUE );
920 }
921 }
922 }
923
errcheckln(UErrorCode status,const UnicodeString & message)924 void IntlTest::errcheckln(UErrorCode status, const UnicodeString &message ) {
925 if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
926 dataerrln(message);
927 } else {
928 errln(message);
929 }
930 }
931
932 /* convenience functions that include sprintf formatting */
log(const char * fmt,...)933 void IntlTest::log(const char *fmt, ...)
934 {
935 char buffer[4000];
936 va_list ap;
937
938 va_start(ap, fmt);
939 /* sprintf it just to make sure that the information is valid */
940 vsprintf(buffer, fmt, ap);
941 va_end(ap);
942 if( verbose ) {
943 log(UnicodeString(buffer, (const char *)NULL));
944 }
945 }
946
logln(const char * fmt,...)947 void IntlTest::logln(const char *fmt, ...)
948 {
949 char buffer[4000];
950 va_list ap;
951
952 va_start(ap, fmt);
953 /* sprintf it just to make sure that the information is valid */
954 vsprintf(buffer, fmt, ap);
955 va_end(ap);
956 if( verbose ) {
957 logln(UnicodeString(buffer, (const char *)NULL));
958 }
959 }
960
logKnownIssue(const char * ticket,const char * fmt,...)961 UBool IntlTest::logKnownIssue(const char *ticket, const char *fmt, ...)
962 {
963 char buffer[4000];
964 va_list ap;
965
966 va_start(ap, fmt);
967 /* sprintf it just to make sure that the information is valid */
968 vsprintf(buffer, fmt, ap);
969 va_end(ap);
970 return logKnownIssue(ticket, UnicodeString(buffer, (const char *)NULL));
971 }
972
logKnownIssue(const char * ticket)973 UBool IntlTest::logKnownIssue(const char *ticket) {
974 return logKnownIssue(ticket, UnicodeString());
975 }
976
logKnownIssue(const char * ticket,const UnicodeString & msg)977 UBool IntlTest::logKnownIssue(const char *ticket, const UnicodeString &msg) {
978 if(noKnownIssues) return FALSE;
979
980 char fullpath[2048];
981 strcpy(fullpath, basePath);
982 strcat(fullpath, currName);
983 UnicodeString msg2 = msg;
984 UBool firstForTicket = TRUE, firstForWhere = TRUE;
985 knownList = udbg_knownIssue_openU(knownList, ticket, fullpath, msg2.getTerminatedBuffer(), &firstForTicket, &firstForWhere);
986
987 msg2 = UNICODE_STRING_SIMPLE("(Known issue ") +
988 UnicodeString(ticket, -1, US_INV) + UNICODE_STRING_SIMPLE(") ") + msg;
989 if(firstForTicket || firstForWhere) {
990 infoln(msg2);
991 } else {
992 logln(msg2);
993 }
994
995 return TRUE;
996 }
997
998 /* convenience functions that include sprintf formatting */
info(const char * fmt,...)999 void IntlTest::info(const char *fmt, ...)
1000 {
1001 char buffer[4000];
1002 va_list ap;
1003
1004 va_start(ap, fmt);
1005 /* sprintf it just to make sure that the information is valid */
1006 vsprintf(buffer, fmt, ap);
1007 va_end(ap);
1008 info(UnicodeString(buffer, (const char *)NULL));
1009 }
1010
infoln(const char * fmt,...)1011 void IntlTest::infoln(const char *fmt, ...)
1012 {
1013 char buffer[4000];
1014 va_list ap;
1015
1016 va_start(ap, fmt);
1017 /* sprintf it just to make sure that the information is valid */
1018 vsprintf(buffer, fmt, ap);
1019 va_end(ap);
1020 infoln(UnicodeString(buffer, (const char *)NULL));
1021 }
1022
err(const char * fmt,...)1023 void IntlTest::err(const char *fmt, ...)
1024 {
1025 char buffer[4000];
1026 va_list ap;
1027
1028 va_start(ap, fmt);
1029 vsprintf(buffer, fmt, ap);
1030 va_end(ap);
1031 err(UnicodeString(buffer, (const char *)NULL));
1032 }
1033
errln(const char * fmt,...)1034 void IntlTest::errln(const char *fmt, ...)
1035 {
1036 char buffer[4000];
1037 va_list ap;
1038
1039 va_start(ap, fmt);
1040 vsprintf(buffer, fmt, ap);
1041 va_end(ap);
1042 errln(UnicodeString(buffer, (const char *)NULL));
1043 }
1044
dataerrln(const char * fmt,...)1045 void IntlTest::dataerrln(const char *fmt, ...)
1046 {
1047 char buffer[4000];
1048 va_list ap;
1049
1050 va_start(ap, fmt);
1051 vsprintf(buffer, fmt, ap);
1052 va_end(ap);
1053 dataerrln(UnicodeString(buffer, (const char *)NULL));
1054 }
1055
errcheckln(UErrorCode status,const char * fmt,...)1056 void IntlTest::errcheckln(UErrorCode status, const char *fmt, ...)
1057 {
1058 char buffer[4000];
1059 va_list ap;
1060
1061 va_start(ap, fmt);
1062 vsprintf(buffer, fmt, ap);
1063 va_end(ap);
1064
1065 if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
1066 dataerrln(UnicodeString(buffer, (const char *)NULL));
1067 } else {
1068 errln(UnicodeString(buffer, (const char *)NULL));
1069 }
1070 }
1071
printErrors()1072 void IntlTest::printErrors()
1073 {
1074 IntlTest::LL_err_message(errorList, TRUE);
1075 }
1076
printKnownIssues()1077 UBool IntlTest::printKnownIssues()
1078 {
1079 if(knownList != NULL) {
1080 udbg_knownIssue_print(knownList);
1081 udbg_knownIssue_close(knownList);
1082 return TRUE;
1083 } else {
1084 return FALSE;
1085 }
1086 }
1087
LL_err_message(const UnicodeString & message,UBool newline)1088 void IntlTest::LL_err_message( const UnicodeString& message, UBool newline ) {
1089 this->LL_message(message, newline, true);
1090 }
1091
1092
LL_message(UnicodeString message,UBool newline,UBool isErr)1093 void IntlTest::LL_message( UnicodeString message, UBool newline, UBool isErr )
1094 {
1095 // Synchronize this function.
1096 // All error messages generated by tests funnel through here.
1097 // Multithreaded tests can concurrently generate errors, requiring synchronization
1098 // to keep each message together.
1099 static UMutex messageMutex;
1100 Mutex lock(&messageMutex);
1101
1102 // string that starts with a LineFeed character and continues
1103 // with spaces according to the current indentation
1104 static const UChar indentUChars[] = {
1105 '\n',
1106 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1107 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1108 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1109 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1110 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1111 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1112 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1113 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1114 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1115 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
1116 };
1117 U_ASSERT(1 + LL_indentlevel <= UPRV_LENGTHOF(indentUChars));
1118 UnicodeString indent(FALSE, indentUChars, 1 + LL_indentlevel);
1119
1120 char buffer[30000];
1121 int32_t length;
1122
1123 // stream out the indentation string first if necessary
1124 length = indent.extract(1, indent.length(), buffer, sizeof(buffer));
1125 if (length > 0) {
1126 fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp);
1127 if (isErr) currErr.append(buffer, length);
1128 }
1129
1130 // replace each LineFeed by the indentation string
1131 message.findAndReplace(UnicodeString((UChar)'\n'), indent);
1132
1133 // stream out the message
1134 length = message.extract(0, message.length(), buffer, sizeof(buffer));
1135 if (length > 0) {
1136 length = length > 30000 ? 30000 : length;
1137 fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp);
1138 if (isErr) currErr.append(buffer, length);
1139 }
1140
1141 if (newline) {
1142 char newLine = '\n';
1143 fwrite(&newLine, sizeof(newLine), 1, (FILE *)testoutfp);
1144 if (isErr) currErr += newLine;
1145 }
1146
1147 // A newline usually flushes the buffer, but
1148 // flush the message just in case of a core dump.
1149 fflush((FILE *)testoutfp);
1150 }
1151
1152 /**
1153 * Print a usage message for this test class.
1154 */
usage(void)1155 void IntlTest::usage( void )
1156 {
1157 UBool save_verbose = setVerbose( TRUE );
1158 logln("Test names:");
1159 logln("-----------");
1160
1161 int32_t index = 0;
1162 const char* name = NULL;
1163 do{
1164 this->runIndexedTest( index, FALSE, name );
1165 if (!name) break;
1166 logln(name);
1167 index++;
1168 }while (name && (name[0] != 0));
1169 setVerbose( save_verbose );
1170 }
1171
1172
1173 // memory leak reporting software will be able to take advantage of the testsuite
1174 // being run a second time local to a specific method in order to report only actual leaks
1175 UBool
run_phase2(char * name,char * par)1176 IntlTest::run_phase2( char* name, char* par ) // supports reporting memory leaks
1177 {
1178 UnicodeString* strLeak = new UnicodeString("forced leak"); // for verifying purify filter
1179 strLeak->append(" for verifying purify filter");
1180 return this->runTest( name, par );
1181 }
1182
1183
1184 #if UCONFIG_NO_LEGACY_CONVERSION
1185 # define TRY_CNV_1 "iso-8859-1"
1186 # define TRY_CNV_2 "ibm-1208"
1187 #else
1188 # define TRY_CNV_1 "iso-8859-7"
1189 # define TRY_CNV_2 "sjis"
1190 #endif
1191
1192 #ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
1193 U_CAPI void unistr_printLengths();
1194 #endif
1195
1196 int
main(int argc,char * argv[])1197 main(int argc, char* argv[])
1198 {
1199 UBool syntax = FALSE;
1200 UBool all = FALSE;
1201 UBool verbose = FALSE;
1202 UBool no_err_msg = FALSE;
1203 UBool no_time = FALSE;
1204 UBool quick = TRUE;
1205 UBool name = FALSE;
1206 UBool leaks = FALSE;
1207 UBool utf8 = FALSE;
1208 const char *summary_file = NULL;
1209 UBool warnOnMissingData = FALSE;
1210 UBool writeGoldenData = FALSE;
1211 UBool defaultDataFound = FALSE;
1212 int32_t threadCount = 12;
1213 UErrorCode errorCode = U_ZERO_ERROR;
1214 UConverter *cnv = NULL;
1215 const char *warnOrErr = "Failure";
1216 UDate startTime, endTime;
1217 int32_t diffTime;
1218 const char *props[IntlTest::kMaxProps];
1219 int32_t nProps = 0;
1220
1221 U_MAIN_INIT_ARGS(argc, argv);
1222
1223 startTime = uprv_getRawUTCtime();
1224
1225 for (int i = 1; i < argc; ++i) {
1226 if (argv[i][0] == '-') {
1227 const char* str = argv[i] + 1;
1228 if (strcmp("verbose", str) == 0 ||
1229 strcmp("v", str) == 0)
1230 verbose = TRUE;
1231 else if (strcmp("noerrormsg", str) == 0 ||
1232 strcmp("n", str) == 0)
1233 no_err_msg = TRUE;
1234 else if (strcmp("exhaustive", str) == 0 ||
1235 strcmp("e", str) == 0)
1236 quick = FALSE;
1237 else if (strcmp("all", str) == 0 ||
1238 strcmp("a", str) == 0)
1239 all = TRUE;
1240 else if (strcmp("utf-8", str) == 0 ||
1241 strcmp("u", str) == 0)
1242 utf8 = TRUE;
1243 else if (strcmp("noknownissues", str) == 0 ||
1244 strcmp("K", str) == 0)
1245 noKnownIssues = TRUE;
1246 else if (strcmp("leaks", str) == 0 ||
1247 strcmp("l", str) == 0)
1248 leaks = TRUE;
1249 else if (strcmp("notime", str) == 0 ||
1250 strcmp("T", str) == 0)
1251 no_time = TRUE;
1252 else if (strcmp("goldens", str) == 0 ||
1253 strcmp("G", str) == 0)
1254 writeGoldenData = TRUE;
1255 else if (strncmp("E", str, 1) == 0)
1256 summary_file = str+1;
1257 else if (strcmp("x", str)==0) {
1258 if(++i>=argc) {
1259 printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n");
1260 syntax = TRUE;
1261 }
1262 if(ctest_xml_setFileName(argv[i])) { /* set the name */
1263 return 1; /* error */
1264 }
1265 } else if (strcmp("w", str) == 0) {
1266 warnOnMissingData = TRUE;
1267 warnOrErr = "WARNING";
1268 }
1269 else if (strncmp("threads:", str, 8) == 0) {
1270 threadCount = atoi(str + 8);
1271 }
1272 else if (strncmp("prop:", str, 5) == 0) {
1273 if (nProps < IntlTest::kMaxProps) {
1274 props[nProps] = str + 5;
1275 }
1276 nProps++;
1277 }
1278 else {
1279 syntax = TRUE;
1280 }
1281 }else{
1282 name = TRUE;
1283 }
1284 }
1285
1286 if (!all && !name) {
1287 all = TRUE;
1288 } else if (all && name) {
1289 syntax = TRUE;
1290 }
1291
1292 if (syntax) {
1293 fprintf(stdout,
1294 "### Syntax:\n"
1295 "### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n"
1296 "### \n"
1297 "### Options are: verbose (v), all (a), noerrormsg (n), \n"
1298 "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:<propery>=<value>, \n"
1299 "### notime (T), \n"
1300 "### threads:<threadCount>\n"
1301 "### (The default thread count is 12.),\n"
1302 "### (Specify either -all (shortcut -a) or a test name). \n"
1303 "### -all will run all of the tests.\n"
1304 "### \n"
1305 "### To get a list of the test names type: intltest LIST \n"
1306 "### To run just the utility tests type: intltest utility \n"
1307 "### \n"
1308 "### Test names can be nested using slashes (\"testA/subtest1\") \n"
1309 "### For example to list the utility tests type: intltest utility/LIST \n"
1310 "### To run just the Locale test type: intltest utility/LocaleTest \n"
1311 "### \n"
1312 "### A parameter can be specified for a test by appending '@' and the value \n"
1313 "### to the testname. \n\n");
1314 return 1;
1315 }
1316
1317 if (nProps > IntlTest::kMaxProps) {
1318 fprintf(stdout, "### Too many properties. Exiting.\n");
1319 }
1320
1321 MajorTestLevel major;
1322 major.setVerbose( verbose );
1323 major.setNoErrMsg( no_err_msg );
1324 major.setQuick( quick );
1325 major.setLeaks( leaks );
1326 major.setThreadCount( threadCount );
1327 major.setWarnOnMissingData( warnOnMissingData );
1328 major.setWriteGoldenData( writeGoldenData );
1329 major.setNotime (no_time);
1330 for (int32_t i = 0; i < nProps; i++) {
1331 major.setProperty(props[i]);
1332 }
1333
1334
1335 fprintf(stdout, "-----------------------------------------------\n");
1336 fprintf(stdout, " IntlTest (C++) Test Suite for \n");
1337 fprintf(stdout, " International Components for Unicode %s\n", U_ICU_VERSION);
1338
1339
1340 {
1341 const char *charsetFamily = "Unknown";
1342 int32_t voidSize = (int32_t)sizeof(void*);
1343 int32_t bits = voidSize * 8;
1344 if(U_CHARSET_FAMILY==U_ASCII_FAMILY) {
1345 charsetFamily="ASCII";
1346 } else if(U_CHARSET_FAMILY==U_EBCDIC_FAMILY) {
1347 charsetFamily="EBCDIC";
1348 }
1349 fprintf(stdout,
1350 " Bits: %d, Byte order: %s, Chars: %s\n",
1351 bits, U_IS_BIG_ENDIAN?"Big endian":"Little endian",
1352 charsetFamily);
1353 }
1354 fprintf(stdout, "-----------------------------------------------\n");
1355 fprintf(stdout, " Options: \n");
1356 fprintf(stdout, " all (a) : %s\n", (all? "On" : "Off"));
1357 fprintf(stdout, " Verbose (v) : %s\n", (verbose? "On" : "Off"));
1358 fprintf(stdout, " No error messages (n) : %s\n", (no_err_msg? "On" : "Off"));
1359 fprintf(stdout, " Exhaustive (e) : %s\n", (!quick? "On" : "Off"));
1360 fprintf(stdout, " Leaks (l) : %s\n", (leaks? "On" : "Off"));
1361 fprintf(stdout, " utf-8 (u) : %s\n", (utf8? "On" : "Off"));
1362 fprintf(stdout, " notime (T) : %s\n", (no_time? "On" : "Off"));
1363 fprintf(stdout, " noknownissues (K) : %s\n", (noKnownIssues? "On" : "Off"));
1364 fprintf(stdout, " Warn on missing data (w) : %s\n", (warnOnMissingData? "On" : "Off"));
1365 fprintf(stdout, " Write golden data (G) : %s\n", (writeGoldenData? "On" : "Off"));
1366 fprintf(stdout, " Threads : %d\n", threadCount);
1367 for (int32_t i = 0; i < nProps; i++) {
1368 fprintf(stdout, " Custom property (prop:) : %s\n", props[i]);
1369 }
1370 fprintf(stdout, "-----------------------------------------------\n");
1371
1372 if(utf8) {
1373 ucnv_setDefaultName("utf-8");
1374 }
1375 /* Check whether ICU will initialize without forcing the build data directory into
1376 * the ICU_DATA path. Success here means either the data dll contains data, or that
1377 * this test program was run with ICU_DATA set externally. Failure of this check
1378 * is normal when ICU data is not packaged into a shared library.
1379 *
1380 * Whether or not this test succeeds, we want to cleanup and reinitialize
1381 * with a data path so that data loading from individual files can be tested.
1382 */
1383 u_init(&errorCode);
1384 if (U_FAILURE(errorCode)) {
1385 fprintf(stderr,
1386 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
1387 defaultDataFound = FALSE;
1388 }
1389 else {
1390 defaultDataFound = TRUE;
1391 }
1392 u_cleanup();
1393 if(utf8) {
1394 ucnv_setDefaultName("utf-8");
1395 }
1396 errorCode = U_ZERO_ERROR;
1397
1398 /* Initialize ICU */
1399 if (!defaultDataFound) {
1400 IntlTest::setICU_DATA(); // Must set data directory before u_init() is called.
1401 }
1402 u_init(&errorCode);
1403 if (U_FAILURE(errorCode)) {
1404 fprintf(stderr,
1405 "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
1406 "*** Check the ICU_DATA environment variable and \n"
1407 "*** check that the data files are present.\n", argv[0], u_errorName(errorCode));
1408 if(warnOnMissingData == 0) {
1409 fprintf(stderr, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1410 u_cleanup();
1411 return 1;
1412 }
1413 }
1414
1415 // initial check for the default converter
1416 errorCode = U_ZERO_ERROR;
1417 cnv = ucnv_open(0, &errorCode);
1418 if(cnv != 0) {
1419 // ok
1420 ucnv_close(cnv);
1421 } else {
1422 fprintf(stdout,
1423 "*** %s! The default converter [%s] cannot be opened.\n"
1424 "*** Check the ICU_DATA environment variable and\n"
1425 "*** check that the data files are present.\n",
1426 warnOrErr, ucnv_getDefaultName());
1427 if(!warnOnMissingData) {
1428 fprintf(stdout, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1429 return 1;
1430 }
1431 }
1432
1433 // try more data
1434 cnv = ucnv_open(TRY_CNV_2, &errorCode);
1435 if(cnv != 0) {
1436 // ok
1437 ucnv_close(cnv);
1438 } else {
1439 fprintf(stdout,
1440 "*** %s! The converter for " TRY_CNV_2 " cannot be opened.\n"
1441 "*** Check the ICU_DATA environment variable and \n"
1442 "*** check that the data files are present.\n", warnOrErr);
1443 if(!warnOnMissingData) {
1444 fprintf(stdout, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1445 return 1;
1446 }
1447 }
1448
1449 UResourceBundle *rb = ures_open(0, "en", &errorCode);
1450 ures_close(rb);
1451 if(U_FAILURE(errorCode)) {
1452 fprintf(stdout,
1453 "*** %s! The \"en\" locale resource bundle cannot be opened.\n"
1454 "*** Check the ICU_DATA environment variable and \n"
1455 "*** check that the data files are present.\n", warnOrErr);
1456 if(!warnOnMissingData) {
1457 fprintf(stdout, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1458 return 1;
1459 }
1460 }
1461
1462 Locale originalLocale; // Save the default locale for comparison later on.
1463
1464 if(ctest_xml_init("intltest"))
1465 return 1;
1466
1467
1468 /* TODO: Add option to call u_cleanup and rerun tests. */
1469 if (all) {
1470 major.runTest();
1471 if (leaks) {
1472 major.run_phase2( NULL, NULL );
1473 }
1474 }else{
1475 for (int i = 1; i < argc; ++i) {
1476 if (argv[i][0] != '-') {
1477 char* name = argv[i];
1478 fprintf(stdout, "\n=== Handling test: %s: ===\n", name);
1479
1480 char baseName[1024] = "/";
1481
1482 char* parameter = strchr( name, '@' );
1483 if (parameter) {
1484 *parameter = 0;
1485 parameter += 1;
1486 }
1487 execCount = 0;
1488 UBool res = major.runTest( name, parameter, baseName );
1489 if (leaks && res) {
1490 major.run_phase2( name, parameter );
1491 }
1492 if (!res || (execCount <= 0)) {
1493 fprintf(stdout, "\n---ERROR: Test doesn't exist: %s!\n", name);
1494 }
1495 } else if(!strcmp(argv[i],"-x")) {
1496 i++;
1497 }
1498 }
1499 }
1500
1501
1502 #if !UCONFIG_NO_FORMATTING
1503 CalendarTimeZoneTest::cleanup();
1504 #endif
1505
1506 Locale lastDefaultLocale;
1507 if (originalLocale != lastDefaultLocale) {
1508 major.errln("FAILURE: A test changed the default locale without resetting it.");
1509 }
1510
1511 fprintf(stdout, "\n--------------------------------------\n");
1512 if( major.printKnownIssues() ) {
1513 fprintf(stdout, " To run suppressed tests, use the -K option. \n");
1514 }
1515 if (major.getErrors() == 0) {
1516 /* Call it twice to make sure that the defaults were reset. */
1517 /* Call it before the OK message to verify proper cleanup. */
1518 u_cleanup();
1519 u_cleanup();
1520
1521 fprintf(stdout, "OK: All tests passed without error.\n");
1522
1523 if (major.getDataErrors() != 0) {
1524 fprintf(stdout, "\t*WARNING* some data-loading errors were ignored by the -w option.\n");
1525 }
1526 }else{
1527 fprintf(stdout, "Errors in total: %ld.\n", (long)major.getErrors());
1528 major.printErrors();
1529
1530 if(summary_file != NULL) {
1531 FILE *summf = fopen(summary_file, "w");
1532 if( summf != NULL) {
1533 char buf[10000];
1534 int32_t length = errorList.extract(0, errorList.length(), buf, sizeof(buf));
1535 fwrite(buf, sizeof(*buf), length, (FILE*)summf);
1536 fclose(summf);
1537 }
1538 }
1539
1540
1541 if (major.getDataErrors() != 0) {
1542 fprintf(stdout, "\t*Note* some errors are data-loading related. If the data used is not the \n"
1543 "\tstock ICU data (i.e some have been added or removed), consider using\n"
1544 "\tthe '-w' option to turn these errors into warnings.\n");
1545 }
1546
1547 /* Call afterwards to display errors. */
1548 u_cleanup();
1549 }
1550
1551 #ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
1552 unistr_printLengths();
1553 #endif
1554
1555 fprintf(stdout, "--------------------------------------\n");
1556
1557 if (execCount <= 0) {
1558 fprintf(stdout, "***** Not all called tests actually exist! *****\n");
1559 }
1560 if(!no_time) {
1561 endTime = uprv_getRawUTCtime();
1562 diffTime = (int32_t)(endTime - startTime);
1563 printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
1564 (int)((diffTime%U_MILLIS_PER_DAY)/U_MILLIS_PER_HOUR),
1565 (int)((diffTime%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE),
1566 (int)((diffTime%U_MILLIS_PER_MINUTE)/U_MILLIS_PER_SECOND),
1567 (int)(diffTime%U_MILLIS_PER_SECOND));
1568 }
1569
1570 if(ctest_xml_fini())
1571 return 1;
1572
1573 #ifdef ZERO_EXIT_CODE_FOR_FAILURES
1574 // Exit code 0 to indicate the test completed.
1575 return 0;
1576 #else
1577 return major.getErrors();
1578 #endif
1579 }
1580
loadTestData(UErrorCode & err)1581 const char* IntlTest::loadTestData(UErrorCode& err){
1582 return ctest_loadTestData(&err);
1583 }
1584
getTestDataPath(UErrorCode & err)1585 const char* IntlTest::getTestDataPath(UErrorCode& err) {
1586 return loadTestData(err);
1587 }
1588
1589 /* Returns the path to icu/source/test/testdata/ */
getSourceTestData(UErrorCode &)1590 const char *IntlTest::getSourceTestData(UErrorCode& /*err*/) {
1591 return ctest_testDataDir();
1592 }
1593
getUnidataPath(char path[])1594 char *IntlTest::getUnidataPath(char path[]) {
1595 const int kUnicodeDataTxtLength = 15; // strlen("UnicodeData.txt")
1596
1597 // Look inside ICU_DATA first.
1598 strcpy(path, pathToDataDirectory());
1599 strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
1600 FILE *f = fopen(path, "r");
1601 if(f != NULL) {
1602 fclose(f);
1603 *(strchr(path, 0) - kUnicodeDataTxtLength) = 0; // Remove the basename.
1604 return path;
1605 }
1606
1607 // As a fallback, try to guess where the source data was located
1608 // at the time ICU was built, and look there.
1609 # ifdef U_TOPSRCDIR
1610 strcpy(path, U_TOPSRCDIR U_FILE_SEP_STRING "data");
1611 # else
1612 UErrorCode errorCode = U_ZERO_ERROR;
1613 const char *testDataPath = loadTestData(errorCode);
1614 if(U_FAILURE(errorCode)) {
1615 it_errln(UnicodeString(
1616 "unable to find path to source/data/unidata/ and loadTestData() failed: ") +
1617 u_errorName(errorCode));
1618 return NULL;
1619 }
1620 strcpy(path, testDataPath);
1621 strcat(path, U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
1622 U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
1623 U_FILE_SEP_STRING "data");
1624 # endif
1625 strcat(path, U_FILE_SEP_STRING);
1626 strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
1627 f = fopen(path, "r");
1628 if(f != NULL) {
1629 fclose(f);
1630 *(strchr(path, 0) - kUnicodeDataTxtLength) = 0; // Remove the basename.
1631 return path;
1632 }
1633 return NULL;
1634 }
1635
1636 /* returns the path to icu/source/data */
pathToDataDirectory()1637 const char * IntlTest::pathToDataDirectory()
1638 {
1639 return ctest_dataSrcDir();
1640 }
1641
1642 /*
1643 * This is a variant of cintltst/ccolltst.c:CharsToUChars().
1644 * It converts an invariant-character string into a UnicodeString, with
1645 * unescaping \u sequences.
1646 */
CharsToUnicodeString(const char * chars)1647 UnicodeString CharsToUnicodeString(const char* chars){
1648 return UnicodeString(chars, -1, US_INV).unescape();
1649 }
1650
ctou(const char * chars)1651 UnicodeString ctou(const char* chars) {
1652 return CharsToUnicodeString(chars);
1653 }
1654
1655 #define RAND_M (714025)
1656 #define RAND_IA (1366)
1657 #define RAND_IC (150889)
1658
1659 static int32_t RAND_SEED;
1660
1661 /**
1662 * Returns a uniform random value x, with 0.0 <= x < 1.0. Use
1663 * with care: Does not return all possible values; returns one of
1664 * 714,025 values, uniformly spaced. However, the period is
1665 * effectively infinite. See: Numerical Recipes, section 7.1.
1666 *
1667 * @param seedp pointer to seed. Set *seedp to any negative value
1668 * to restart the sequence.
1669 */
random(int32_t * seedp)1670 float IntlTest::random(int32_t* seedp) {
1671 static int32_t iy, ir[98];
1672 static UBool first=TRUE;
1673 int32_t j;
1674 if (*seedp < 0 || first) {
1675 first = FALSE;
1676 if ((*seedp=(RAND_IC-(*seedp)) % RAND_M) < 0) *seedp = -(*seedp);
1677 for (j=1;j<=97;++j) {
1678 *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
1679 ir[j]=(*seedp);
1680 }
1681 *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
1682 iy=(*seedp);
1683 }
1684 j=(int32_t)(1 + 97.0*iy/RAND_M);
1685 U_ASSERT(j>=1 && j<=97);
1686 iy=ir[j];
1687 *seedp=(RAND_IA*(*seedp)+RAND_IC) % RAND_M;
1688 ir[j]=(*seedp);
1689 return (float) iy/RAND_M;
1690 }
1691
1692 /**
1693 * Convenience method using a global seed.
1694 */
random()1695 float IntlTest::random() {
1696 return random(&RAND_SEED);
1697 }
1698
1699
1700 /*
1701 * Integer random number class implementation.
1702 * Similar to C++ std::minstd_rand, with the same algorithm & constants.
1703 */
icu_rand(uint32_t seed)1704 IntlTest::icu_rand::icu_rand(uint32_t seed) {
1705 seed = seed % 2147483647UL;
1706 if (seed == 0) {
1707 seed = 1;
1708 }
1709 fLast = seed;
1710 }
1711
~icu_rand()1712 IntlTest::icu_rand::~icu_rand() {}
1713
seed(uint32_t seed)1714 void IntlTest::icu_rand::seed(uint32_t seed) {
1715 if (seed == 0) {
1716 seed = 1;
1717 }
1718 fLast = seed;
1719 }
1720
operator ()()1721 uint32_t IntlTest::icu_rand::operator() () {
1722 fLast = ((uint64_t)fLast * 48271UL) % 2147483647UL;
1723 return fLast;
1724 }
1725
getSeed()1726 uint32_t IntlTest::icu_rand::getSeed() {
1727 return (uint32_t) fLast;
1728 }
1729
1730
1731
toHex(int32_t i)1732 static inline UChar toHex(int32_t i) {
1733 return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10)));
1734 }
1735
escape(const UnicodeString & s,UnicodeString & result)1736 static UnicodeString& escape(const UnicodeString& s, UnicodeString& result) {
1737 for (int32_t i=0; i<s.length(); ++i) {
1738 UChar c = s[i];
1739 if (c <= (UChar)0x7F) {
1740 result += c;
1741 } else {
1742 result += (UChar)0x5c;
1743 result += (UChar)0x75;
1744 result += toHex((c >> 12) & 0xF);
1745 result += toHex((c >> 8) & 0xF);
1746 result += toHex((c >> 4) & 0xF);
1747 result += toHex( c & 0xF);
1748 }
1749 }
1750 return result;
1751 }
1752
1753 #define VERBOSE_ASSERTIONS
1754
assertTrue(const char * message,UBool condition,UBool quiet,UBool possibleDataError,const char * file,int line)1755 UBool IntlTest::assertTrue(const char* message, UBool condition, UBool quiet, UBool possibleDataError, const char *file, int line) {
1756 if (file != NULL) {
1757 if (!condition) {
1758 if (possibleDataError) {
1759 dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
1760 } else {
1761 errln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
1762 }
1763 } else if (!quiet) {
1764 logln("%s:%d: Ok: %s", file, line, message);
1765 }
1766 } else {
1767 if (!condition) {
1768 if (possibleDataError) {
1769 dataerrln("FAIL: assertTrue() failed: %s", message);
1770 } else {
1771 errln("FAIL: assertTrue() failed: %s", message);
1772 }
1773 } else if (!quiet) {
1774 logln("Ok: %s", message);
1775 }
1776
1777 }
1778 return condition;
1779 }
1780
assertFalse(const char * message,UBool condition,UBool quiet,UBool possibleDataError)1781 UBool IntlTest::assertFalse(const char* message, UBool condition, UBool quiet, UBool possibleDataError) {
1782 if (condition) {
1783 if (possibleDataError) {
1784 dataerrln("FAIL: assertTrue() failed: %s", message);
1785 } else {
1786 errln("FAIL: assertTrue() failed: %s", message);
1787 }
1788 } else if (!quiet) {
1789 logln("Ok: %s", message);
1790 }
1791 return !condition;
1792 }
1793
assertSuccess(const char * message,UErrorCode ec,UBool possibleDataError,const char * file,int line)1794 UBool IntlTest::assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError, const char *file, int line) {
1795 if( file==NULL ) {
1796 file = ""; // prevent failure if no file given
1797 }
1798 if (U_FAILURE(ec)) {
1799 if (possibleDataError) {
1800 dataerrln("FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
1801 } else {
1802 errcheckln(ec, "FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
1803 }
1804 return FALSE;
1805 } else {
1806 logln("OK: %s:%d: %s - (%s)", file, line, message, u_errorName(ec));
1807 }
1808 return TRUE;
1809 }
1810
assertEquals(const char * message,const UnicodeString & expected,const UnicodeString & actual,UBool possibleDataError)1811 UBool IntlTest::assertEquals(const char* message,
1812 const UnicodeString& expected,
1813 const UnicodeString& actual,
1814 UBool possibleDataError) {
1815 if (expected != actual) {
1816 if (possibleDataError) {
1817 dataerrln((UnicodeString)"FAIL: " + message + "; got " +
1818 prettify(actual) +
1819 "; expected " + prettify(expected));
1820 } else {
1821 errln((UnicodeString)"FAIL: " + message + "; got " +
1822 prettify(actual) +
1823 "; expected " + prettify(expected));
1824 }
1825 return FALSE;
1826 }
1827 #ifdef VERBOSE_ASSERTIONS
1828 else {
1829 logln((UnicodeString)"Ok: " + message + "; got " + prettify(actual));
1830 }
1831 #endif
1832 return TRUE;
1833 }
1834
assertEquals(const char * message,const char * expected,const char * actual)1835 UBool IntlTest::assertEquals(const char* message,
1836 const char* expected,
1837 const char* actual) {
1838 if (uprv_strcmp(expected, actual) != 0) {
1839 errln((UnicodeString)"FAIL: " + message + "; got \"" +
1840 actual +
1841 "\"; expected \"" + expected + "\"");
1842 return FALSE;
1843 }
1844 #ifdef VERBOSE_ASSERTIONS
1845 else {
1846 logln((UnicodeString)"Ok: " + message + "; got \"" + actual + "\"");
1847 }
1848 #endif
1849 return TRUE;
1850 }
1851
assertEquals(const char * message,int32_t expected,int32_t actual)1852 UBool IntlTest::assertEquals(const char* message,
1853 int32_t expected,
1854 int32_t actual) {
1855 if (expected != actual) {
1856 errln((UnicodeString)"FAIL: " + message + "; got " +
1857 actual + "=0x" + toHex(actual) +
1858 "; expected " + expected + "=0x" + toHex(expected));
1859 return FALSE;
1860 }
1861 #ifdef VERBOSE_ASSERTIONS
1862 else {
1863 logln((UnicodeString)"Ok: " + message + "; got " + actual + "=0x" + toHex(actual));
1864 }
1865 #endif
1866 return TRUE;
1867 }
1868
assertEquals(const char * message,int64_t expected,int64_t actual)1869 UBool IntlTest::assertEquals(const char* message,
1870 int64_t expected,
1871 int64_t actual) {
1872 if (expected != actual) {
1873 errln((UnicodeString)"FAIL: " + message + "; got int64 " +
1874 Int64ToUnicodeString(actual) +
1875 "; expected " + Int64ToUnicodeString(expected) );
1876 return FALSE;
1877 }
1878 #ifdef VERBOSE_ASSERTIONS
1879 else {
1880 logln((UnicodeString)"Ok: " + message + "; got int64 " + Int64ToUnicodeString(actual));
1881 }
1882 #endif
1883 return TRUE;
1884 }
1885
assertEquals(const char * message,double expected,double actual)1886 UBool IntlTest::assertEquals(const char* message,
1887 double expected,
1888 double actual) {
1889 bool bothNaN = std::isnan(expected) && std::isnan(actual);
1890 if (expected != actual && !bothNaN) {
1891 errln((UnicodeString)"FAIL: " + message + "; got " +
1892 actual +
1893 "; expected " + expected);
1894 return FALSE;
1895 }
1896 #ifdef VERBOSE_ASSERTIONS
1897 else {
1898 logln((UnicodeString)"Ok: " + message + "; got " + actual);
1899 }
1900 #endif
1901 return TRUE;
1902 }
1903
assertEquals(const char * message,UBool expected,UBool actual)1904 UBool IntlTest::assertEquals(const char* message,
1905 UBool expected,
1906 UBool actual) {
1907 if (expected != actual) {
1908 errln((UnicodeString)"FAIL: " + message + "; got " +
1909 toString(actual) +
1910 "; expected " + toString(expected));
1911 return FALSE;
1912 }
1913 #ifdef VERBOSE_ASSERTIONS
1914 else {
1915 logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
1916 }
1917 #endif
1918 return TRUE;
1919 }
1920
1921
assertEquals(const char * message,UErrorCode expected,UErrorCode actual)1922 UBool IntlTest::assertEquals(const char* message,
1923 UErrorCode expected,
1924 UErrorCode actual) {
1925 if (expected != actual) {
1926 errln((UnicodeString)"FAIL: " + message + "; got " +
1927 u_errorName(actual) +
1928 "; expected " + u_errorName(expected));
1929 return FALSE;
1930 }
1931 #ifdef VERBOSE_ASSERTIONS
1932 else {
1933 logln((UnicodeString)"Ok: " + message + "; got " + u_errorName(actual));
1934 }
1935 #endif
1936 return TRUE;
1937 }
1938
assertEquals(const char * message,const UnicodeSet & expected,const UnicodeSet & actual)1939 UBool IntlTest::assertEquals(const char* message,
1940 const UnicodeSet& expected,
1941 const UnicodeSet& actual) {
1942 IcuTestErrorCode status(*this, "assertEqualsUniSet");
1943 if (expected != actual) {
1944 errln((UnicodeString)"FAIL: " + message + "; got " +
1945 toString(actual, status) +
1946 "; expected " + toString(expected, status));
1947 return FALSE;
1948 }
1949 #ifdef VERBOSE_ASSERTIONS
1950 else {
1951 logln((UnicodeString)"Ok: " + message + "; got " + toString(actual, status));
1952 }
1953 #endif
1954 return TRUE;
1955 }
1956
1957
1958 #if !UCONFIG_NO_FORMATTING
assertEquals(const char * message,const Formattable & expected,const Formattable & actual,UBool possibleDataError)1959 UBool IntlTest::assertEquals(const char* message,
1960 const Formattable& expected,
1961 const Formattable& actual,
1962 UBool possibleDataError) {
1963 if (expected != actual) {
1964 if (possibleDataError) {
1965 dataerrln((UnicodeString)"FAIL: " + message + "; got " +
1966 toString(actual) +
1967 "; expected " + toString(expected));
1968 } else {
1969 errln((UnicodeString)"FAIL: " + message + "; got " +
1970 toString(actual) +
1971 "; expected " + toString(expected));
1972 }
1973 return FALSE;
1974 }
1975 #ifdef VERBOSE_ASSERTIONS
1976 else {
1977 logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
1978 }
1979 #endif
1980 return TRUE;
1981 }
1982 #endif
1983
vectorToString(const std::vector<std::string> & strings)1984 std::string vectorToString(const std::vector<std::string>& strings) {
1985 std::string result = "{";
1986 bool first = true;
1987 for (auto element : strings) {
1988 if (first) {
1989 first = false;
1990 } else {
1991 result += ", ";
1992 }
1993 result += "\"";
1994 result += element;
1995 result += "\"";
1996 }
1997 result += "}";
1998 return result;
1999 }
2000
assertEquals(const char * message,const std::vector<std::string> & expected,const std::vector<std::string> & actual)2001 UBool IntlTest::assertEquals(const char* message,
2002 const std::vector<std::string>& expected,
2003 const std::vector<std::string>& actual) {
2004 if (expected != actual) {
2005 std::string expectedAsString = vectorToString(expected);
2006 std::string actualAsString = vectorToString(actual);
2007 errln((UnicodeString)"FAIL: " + message +
2008 "; got " + actualAsString.c_str() +
2009 "; expected " + expectedAsString.c_str());
2010 return FALSE;
2011 }
2012 #ifdef VERBOSE_ASSERTIONS
2013 else {
2014 logln((UnicodeString)"Ok: " + message + "; got " + vectorToString(actual).c_str());
2015 }
2016 #endif
2017 return TRUE;
2018 }
2019
assertNotEquals(const char * message,int32_t expectedNot,int32_t actual)2020 UBool IntlTest::assertNotEquals(const char* message,
2021 int32_t expectedNot,
2022 int32_t actual) {
2023 if (expectedNot == actual) {
2024 errln((UnicodeString)("FAIL: ") + message + "; got " + actual + "=0x" + toHex(actual) +
2025 "; expected != " + expectedNot);
2026 return FALSE;
2027 }
2028 #ifdef VERBOSE_ASSERTIONS
2029 else {
2030 logln((UnicodeString)("Ok: ") + message + "; got " + actual + "=0x" + toHex(actual) +
2031 " != " + expectedNot);
2032 }
2033 #endif
2034 return TRUE;
2035 }
2036
assertEqualsNear(const char * message,double expected,double actual,double delta)2037 UBool IntlTest::assertEqualsNear(const char* message,
2038 double expected,
2039 double actual,
2040 double delta) {
2041 if (std::isnan(delta) || std::isinf(delta)) {
2042 errln((UnicodeString)("FAIL: ") + message + "; nonsensical delta " + delta +
2043 " - delta may not be NaN or Inf");
2044 return FALSE;
2045 }
2046 bool bothNaN = std::isnan(expected) && std::isnan(actual);
2047 double difference = std::abs(expected - actual);
2048 if (expected != actual && (difference > delta || std::isnan(difference)) && !bothNaN) {
2049 errln((UnicodeString)("FAIL: ") + message + "; got " + actual + "; expected " + expected +
2050 "; acceptable delta " + delta);
2051 return FALSE;
2052 }
2053 #ifdef VERBOSE_ASSERTIONS
2054 else {
2055 logln((UnicodeString)("Ok: ") + message + "; got " + actual);
2056 }
2057 #endif
2058 return TRUE;
2059 }
2060
2061 static char ASSERT_BUF[256];
2062
extractToAssertBuf(const UnicodeString & message)2063 static const char* extractToAssertBuf(const UnicodeString& message) {
2064 UnicodeString buf;
2065 escape(message, buf);
2066 buf.extract(0, 0x7FFFFFFF, ASSERT_BUF, sizeof(ASSERT_BUF)-1, 0);
2067 ASSERT_BUF[sizeof(ASSERT_BUF)-1] = 0;
2068 return ASSERT_BUF;
2069 }
2070
assertTrue(const UnicodeString & message,UBool condition,UBool quiet,UBool possibleDataError)2071 UBool IntlTest::assertTrue(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) {
2072 return assertTrue(extractToAssertBuf(message), condition, quiet, possibleDataError);
2073 }
2074
assertFalse(const UnicodeString & message,UBool condition,UBool quiet,UBool possibleDataError)2075 UBool IntlTest::assertFalse(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) {
2076 return assertFalse(extractToAssertBuf(message), condition, quiet, possibleDataError);
2077 }
2078
assertSuccess(const UnicodeString & message,UErrorCode ec)2079 UBool IntlTest::assertSuccess(const UnicodeString& message, UErrorCode ec) {
2080 return assertSuccess(extractToAssertBuf(message), ec);
2081 }
2082
assertEquals(const UnicodeString & message,const UnicodeString & expected,const UnicodeString & actual,UBool possibleDataError)2083 UBool IntlTest::assertEquals(const UnicodeString& message,
2084 const UnicodeString& expected,
2085 const UnicodeString& actual,
2086 UBool possibleDataError) {
2087 return assertEquals(extractToAssertBuf(message), expected, actual, possibleDataError);
2088 }
2089
assertEquals(const UnicodeString & message,const char * expected,const char * actual)2090 UBool IntlTest::assertEquals(const UnicodeString& message,
2091 const char* expected,
2092 const char* actual) {
2093 return assertEquals(extractToAssertBuf(message), expected, actual);
2094 }
assertEquals(const UnicodeString & message,UBool expected,UBool actual)2095 UBool IntlTest::assertEquals(const UnicodeString& message,
2096 UBool expected,
2097 UBool actual) {
2098 return assertEquals(extractToAssertBuf(message), expected, actual);
2099 }
assertEquals(const UnicodeString & message,int32_t expected,int32_t actual)2100 UBool IntlTest::assertEquals(const UnicodeString& message,
2101 int32_t expected,
2102 int32_t actual) {
2103 return assertEquals(extractToAssertBuf(message), expected, actual);
2104 }
assertEquals(const UnicodeString & message,int64_t expected,int64_t actual)2105 UBool IntlTest::assertEquals(const UnicodeString& message,
2106 int64_t expected,
2107 int64_t actual) {
2108 return assertEquals(extractToAssertBuf(message), expected, actual);
2109 }
assertEquals(const UnicodeString & message,double expected,double actual)2110 UBool IntlTest::assertEquals(const UnicodeString& message,
2111 double expected,
2112 double actual) {
2113 return assertEquals(extractToAssertBuf(message), expected, actual);
2114 }
assertEquals(const UnicodeString & message,UErrorCode expected,UErrorCode actual)2115 UBool IntlTest::assertEquals(const UnicodeString& message,
2116 UErrorCode expected,
2117 UErrorCode actual) {
2118 return assertEquals(extractToAssertBuf(message), expected, actual);
2119 }
assertEquals(const UnicodeString & message,const UnicodeSet & expected,const UnicodeSet & actual)2120 UBool IntlTest::assertEquals(const UnicodeString& message,
2121 const UnicodeSet& expected,
2122 const UnicodeSet& actual) {
2123 return assertEquals(extractToAssertBuf(message), expected, actual);
2124 }
assertEquals(const UnicodeString & message,const std::vector<std::string> & expected,const std::vector<std::string> & actual)2125 UBool IntlTest::assertEquals(const UnicodeString& message,
2126 const std::vector<std::string>& expected,
2127 const std::vector<std::string>& actual) {
2128 return assertEquals(extractToAssertBuf(message), expected, actual);
2129 }
assertNotEquals(const UnicodeString & message,int32_t expectedNot,int32_t actual)2130 UBool IntlTest::assertNotEquals(const UnicodeString &message,
2131 int32_t expectedNot,
2132 int32_t actual) {
2133 return assertNotEquals(extractToAssertBuf(message), expectedNot, actual);
2134 }
assertEqualsNear(const UnicodeString & message,double expected,double actual,double delta)2135 UBool IntlTest::assertEqualsNear(const UnicodeString& message,
2136 double expected,
2137 double actual,
2138 double delta) {
2139 return assertEqualsNear(extractToAssertBuf(message), expected, actual, delta);
2140 }
2141
2142 #if !UCONFIG_NO_FORMATTING
assertEquals(const UnicodeString & message,const Formattable & expected,const Formattable & actual)2143 UBool IntlTest::assertEquals(const UnicodeString& message,
2144 const Formattable& expected,
2145 const Formattable& actual) {
2146 return assertEquals(extractToAssertBuf(message), expected, actual);
2147 }
2148 #endif
2149
setProperty(const char * propline)2150 void IntlTest::setProperty(const char* propline) {
2151 if (numProps < kMaxProps) {
2152 proplines[numProps] = propline;
2153 }
2154 numProps++;
2155 }
2156
getProperty(const char * prop)2157 const char* IntlTest::getProperty(const char* prop) {
2158 const char* val = NULL;
2159 for (int32_t i = 0; i < numProps; i++) {
2160 int32_t plen = static_cast<int32_t>(uprv_strlen(prop));
2161 if ((int32_t)uprv_strlen(proplines[i]) > plen + 1
2162 && proplines[i][plen] == '='
2163 && uprv_strncmp(proplines[i], prop, plen) == 0) {
2164 val = &(proplines[i][plen+1]);
2165 break;
2166 }
2167 }
2168 return val;
2169 }
2170
2171 /*
2172 * Hey, Emacs, please set the following:
2173 *
2174 * Local Variables:
2175 * indent-tabs-mode: nil
2176 * End:
2177 *
2178 */
2179