1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
10 #include "unicode/utypes.h"
13 * IntlTest is a base class for tests.
23 #include "unicode/ctest.h" // for str_timeDelta
24 #include "unicode/curramt.h"
25 #include "unicode/locid.h"
26 #include "unicode/putil.h"
27 #include "unicode/smpdtfmt.h"
28 #include "unicode/timezone.h"
29 #include "unicode/uclean.h"
30 #include "unicode/ucnv.h"
31 #include "unicode/unistr.h"
32 #include "unicode/ures.h"
33 #include "unicode/utf16.h"
42 #include "putilimp.h" // for uprv_getRawUTCtime()
54 static char* _testDataPath
=NULL
;
56 // Static list of errors found
57 static UnicodeString errorList
;
58 static void *knownList
= NULL
; // known issues
59 static UBool noKnownIssues
= FALSE
; // if TRUE, don't emit known issues
61 //-----------------------------------------------------------------------------
62 //convenience classes to ease porting code that uses the Java
63 //string-concatenation operator (moved from findword test by rtg)
65 // [LIU] Just to get things working
67 UCharToUnicodeString(UChar c
)
68 { return UnicodeString(c
); }
70 // [rtg] Just to get things working
72 operator+(const UnicodeString
& left
,
75 char buffer
[64]; // nos changed from 10 to 64
76 char danger
= 'p'; // guard against overrunning the buffer (rtg)
78 sprintf(buffer
, "%ld", num
);
79 assert(danger
== 'p');
85 operator+(const UnicodeString
& left
,
88 char buffer
[64]; // nos changed from 10 to 64
89 char danger
= 'p'; // guard against overrunning the buffer (rtg)
91 sprintf(buffer
, "%lu", num
);
92 assert(danger
== 'p');
98 Int64ToUnicodeString(int64_t num
)
100 char buffer
[64]; // nos changed from 10 to 64
101 char danger
= 'p'; // guard against overrunning the buffer (rtg)
103 #if defined(_MSC_VER)
104 sprintf(buffer
, "%I64d", num
);
106 sprintf(buffer
, "%lld", (long long)num
);
108 assert(danger
== 'p');
114 DoubleToUnicodeString(double num
)
116 char buffer
[64]; // nos changed from 10 to 64
117 char danger
= 'p'; // guard against overrunning the buffer (rtg)
119 sprintf(buffer
, "%1.14e", num
);
120 assert(danger
== 'p');
125 // [LIU] Just to get things working
127 operator+(const UnicodeString
& left
,
130 char buffer
[64]; // was 32, made it arbitrarily bigger (rtg)
131 char danger
= 'p'; // guard against overrunning the buffer (rtg)
133 // IEEE floating point has 52 bits of mantissa, plus one assumed bit
134 // 53*log(2)/log(10) = 15.95
135 // so there is no need to show more than 16 digits. [alan]
137 sprintf(buffer
, "%.17g", num
);
138 assert(danger
== 'p');
140 return left
+ buffer
;
145 operator+(const UnicodeString
& left
,
147 return left
+ Int64ToUnicodeString(num
);
151 #if !UCONFIG_NO_FORMATTING
154 * Return a string display for this, without surrounding braces.
156 UnicodeString
_toString(const Formattable
& f
) {
158 switch (f
.getType()) {
159 case Formattable::kDate
:
161 UErrorCode status
= U_ZERO_ERROR
;
162 SimpleDateFormat
fmt(status
);
163 if (U_SUCCESS(status
)) {
165 fmt
.format(f
.getDate(), s
, pos
);
166 s
.insert(0, "Date:");
168 s
= UnicodeString("Error creating date format]");
172 case Formattable::kDouble
:
173 s
= UnicodeString("double:") + f
.getDouble();
175 case Formattable::kLong
:
176 s
= UnicodeString("long:") + f
.getLong();
179 case Formattable::kInt64
:
180 s
= UnicodeString("int64:") + Int64ToUnicodeString(f
.getInt64());
183 case Formattable::kString
:
185 s
.insert(0, "String:");
187 case Formattable::kArray
:
190 const Formattable
* array
= f
.getArray(n
);
191 s
.insert(0, UnicodeString("Array:"));
192 UnicodeString
delim(", ");
193 for (i
=0; i
<n
; ++i
) {
197 s
= s
+ _toString(array
[i
]);
201 case Formattable::kObject
: {
202 const CurrencyAmount
* c
= dynamic_cast<const CurrencyAmount
*>(f
.getObject());
204 s
= _toString(c
->getNumber()) + " " + UnicodeString(c
->getISOCurrency());
206 s
= UnicodeString("Unknown UObject");
211 s
= UnicodeString("Unknown Formattable type=") + (int32_t)f
.getType();
218 * Originally coded this as operator+, but that makes the expression
219 * + char* ambiguous. - liu
221 UnicodeString
toString(const Formattable
& f
) {
222 UnicodeString
s((UChar
)91/*[*/);
223 s
.append(_toString(f
));
224 s
.append((UChar
)0x5d/*]*/);
230 // useful when operator+ won't cooperate
231 UnicodeString
toString(int32_t n
) {
232 return UnicodeString() + (long)n
;
237 UnicodeString
toString(UBool b
) {
238 return b
? UnicodeString("TRUE"):UnicodeString("FALSE");
241 UnicodeString
toString(const UnicodeSet
& uniset
, UErrorCode
& status
) {
242 UnicodeString result
;
243 uniset
.toPattern(result
, status
);
247 // stephen - cleaned up 05/05/99
248 UnicodeString
operator+(const UnicodeString
& left
, char num
)
249 { return left
+ (long)num
; }
250 UnicodeString
operator+(const UnicodeString
& left
, short num
)
251 { return left
+ (long)num
; }
252 UnicodeString
operator+(const UnicodeString
& left
, int num
)
253 { return left
+ (long)num
; }
254 UnicodeString
operator+(const UnicodeString
& left
, unsigned char num
)
255 { return left
+ (unsigned long)num
; }
256 UnicodeString
operator+(const UnicodeString
& left
, unsigned short num
)
257 { return left
+ (unsigned long)num
; }
258 UnicodeString
operator+(const UnicodeString
& left
, unsigned int num
)
259 { return left
+ (unsigned long)num
; }
260 UnicodeString
operator+(const UnicodeString
& left
, float num
)
261 { return left
+ (double)num
; }
265 // Append a hex string to the target
267 IntlTest::appendHex(uint32_t number
,
269 UnicodeString
& target
)
271 static const UChar digitString
[] = {
272 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
273 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0
274 }; /* "0123456789ABCDEF" */
276 if (digits
< 0) { // auto-digits
279 while (number
> max
) {
281 max
= (max
<< 8) | 0xff;
287 target
+= digitString
[(number
>> 28) & 0xF];
290 target
+= digitString
[(number
>> 24) & 0xF];
293 target
+= digitString
[(number
>> 20) & 0xF];
296 target
+= digitString
[(number
>> 16) & 0xF];
299 target
+= digitString
[(number
>> 12) & 0xF];
302 target
+= digitString
[(number
>> 8) & 0xF];
305 target
+= digitString
[(number
>> 4) & 0xF];
308 target
+= digitString
[(number
>> 0) & 0xF];
317 IntlTest::toHex(uint32_t number
, int32_t digits
) {
318 UnicodeString result
;
319 appendHex(number
, digits
, result
);
323 static inline UBool
isPrintable(UChar32 c
) {
324 return c
<= 0x7E && (c
>= 0x20 || c
== 9 || c
== 0xA || c
== 0xD);
327 // Replace nonprintable characters with unicode escapes
329 IntlTest::prettify(const UnicodeString
&source
,
330 UnicodeString
&target
)
337 for (i
= 0; i
< source
.length(); )
339 UChar32 ch
= source
.char32At(i
);
342 if (!isPrintable(ch
))
346 appendHex(ch
, 4, target
);
349 appendHex(ch
, 8, target
);
363 // Replace nonprintable characters with unicode escapes
365 IntlTest::prettify(const UnicodeString
&source
, UBool parseBackslash
)
368 UnicodeString target
;
372 for (i
= 0; i
< source
.length();)
374 UChar32 ch
= source
.char32At(i
);
377 if (!isPrintable(ch
))
379 if (parseBackslash
) {
380 // If we are preceded by an odd number of backslashes,
381 // then this character has already been backslash escaped.
382 // Delete a backslash.
383 int32_t backslashCount
= 0;
384 for (int32_t j
=target
.length()-1; j
>=0; --j
) {
385 if (target
.charAt(j
) == (UChar
)92) {
391 if ((backslashCount
% 2) == 1) {
392 target
.truncate(target
.length() - 1);
397 appendHex(ch
, 4, target
);
400 appendHex(ch
, 8, target
);
414 /* IntlTest::setICU_DATA - if the ICU_DATA environment variable is not already
415 * set, try to deduce the directory in which ICU was built,
416 * and set ICU_DATA to "icu/source/data" in that location.
417 * The intent is to allow the tests to have a good chance
418 * of running without requiring that the user manually set
419 * ICU_DATA. Common data isn't a problem, since it is
420 * picked up via a static (build time) reference, but the
421 * tests dynamically load some data.
423 void IntlTest::setICU_DATA() {
424 const char *original_ICU_DATA
= getenv("ICU_DATA");
426 if (original_ICU_DATA
!= NULL
&& *original_ICU_DATA
!= 0) {
427 /* If the user set ICU_DATA, don't second-guess the person. */
431 // U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
432 // to point to the top of the build hierarchy, which may or
433 // may not be the same as the source directory, depending on
434 // the configure options used. At any rate,
435 // set the data path to the built data from this directory.
436 // The value is complete with quotes, so it can be used
437 // as-is as a string constant.
439 #if defined (U_TOPBUILDDIR)
441 static char env_string
[] = U_TOPBUILDDIR
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
442 u_setDataDirectory(env_string
);
447 // Use #else so we don't get compiler warnings due to the return above.
449 /* On Windows, the file name obtained from __FILE__ includes a full path.
450 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
451 * Change to "wherever\icu\source\data"
454 char p
[sizeof(__FILE__
) + 10];
459 /* We want to back over three '\' chars. */
460 /* Only Windows should end up here, so looking for '\' is safe. */
461 for (i
=1; i
<=3; i
++) {
462 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
463 if (pBackSlash
!= NULL
) {
464 *pBackSlash
= 0; /* Truncate the string at the '\' */
468 if (pBackSlash
!= NULL
) {
469 /* We found and truncated three names from the path.
470 * Now append "source\data" and set the environment
472 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
473 u_setDataDirectory(p
); /* p is "ICU_DATA=wherever\icu\source\data" */
477 /* __FILE__ on MSVC7 does not contain the directory */
478 u_setDataDirectory(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
484 /* No location for the data dir was identifiable.
485 * Add other fallbacks for the test data location here if the need arises
490 //--------------------------------------------------------------------------------------
492 static const int32_t indentLevel_offset
= 3;
493 static const char delim
= '/';
495 IntlTest
* IntlTest::gTest
= NULL
;
497 static int32_t execCount
= 0;
499 void it_log( UnicodeString message
)
502 IntlTest::gTest
->log( message
);
505 void it_logln( UnicodeString message
)
508 IntlTest::gTest
->logln( message
);
511 void it_logln( void )
514 IntlTest::gTest
->logln();
517 void it_info( UnicodeString message
)
520 IntlTest::gTest
->info( message
);
523 void it_infoln( UnicodeString message
)
526 IntlTest::gTest
->infoln( message
);
529 void it_infoln( void )
532 IntlTest::gTest
->infoln();
538 IntlTest::gTest
->err();
541 void it_err( UnicodeString message
)
544 IntlTest::gTest
->err( message
);
547 void it_errln( UnicodeString message
)
550 IntlTest::gTest
->errln( message
);
553 void it_dataerr( UnicodeString message
)
556 IntlTest::gTest
->dataerr( message
);
559 void it_dataerrln( UnicodeString message
)
562 IntlTest::gTest
->dataerrln( message
);
575 warn_on_missing_data
= FALSE
;
580 LL_indentlevel
= indentLevel_offset
;
582 strcpy(basePath
, "/");
586 void IntlTest::setCaller( IntlTest
* callingTest
)
588 caller
= callingTest
;
590 warn_on_missing_data
= caller
->warn_on_missing_data
;
591 verbose
= caller
->verbose
;
592 no_err_msg
= caller
->no_err_msg
;
593 quick
= caller
->quick
;
594 threadCount
= caller
->threadCount
;
595 testoutfp
= caller
->testoutfp
;
596 write_golden_data
= caller
->write_golden_data
;
597 LL_indentlevel
= caller
->LL_indentlevel
+ indentLevel_offset
;
598 numProps
= caller
->numProps
;
599 for (int32_t i
= 0; i
< numProps
; i
++) {
600 proplines
[i
] = caller
->proplines
[i
];
605 UBool
IntlTest::callTest( IntlTest
& testToBeCalled
, char* par
)
607 execCount
--; // correct a previously assumed test-exec, as this only calls a subtest
608 testToBeCalled
.setCaller( this );
609 strcpy(testToBeCalled
.basePath
, this->basePath
);
610 UBool result
= testToBeCalled
.runTest( testPath
, par
, testToBeCalled
.basePath
);
611 strcpy(testToBeCalled
.basePath
, this->basePath
); // reset it.
615 void IntlTest::setPath( char* pathVal
)
617 this->testPath
= pathVal
;
620 UBool
IntlTest::setVerbose( UBool verboseVal
)
622 UBool rval
= this->verbose
;
623 this->verbose
= verboseVal
;
627 UBool
IntlTest::setNotime( UBool no_time
)
629 UBool rval
= this->no_time
;
630 this->no_time
= no_time
;
634 UBool
IntlTest::setWarnOnMissingData( UBool warn_on_missing_dataVal
)
636 UBool rval
= this->warn_on_missing_data
;
637 this->warn_on_missing_data
= warn_on_missing_dataVal
;
641 UBool
IntlTest::setWriteGoldenData( UBool write_golden_data
)
643 UBool rval
= this->write_golden_data
;
644 this->write_golden_data
= write_golden_data
;
648 UBool
IntlTest::setNoErrMsg( UBool no_err_msgVal
)
650 UBool rval
= this->no_err_msg
;
651 this->no_err_msg
= no_err_msgVal
;
655 UBool
IntlTest::setQuick( UBool quickVal
)
657 UBool rval
= this->quick
;
658 this->quick
= quickVal
;
662 UBool
IntlTest::setLeaks( UBool leaksVal
)
664 UBool rval
= this->leaks
;
665 this->leaks
= leaksVal
;
669 int32_t IntlTest::setThreadCount( int32_t count
)
671 int32_t rval
= this->threadCount
;
672 this->threadCount
= count
;
676 int32_t IntlTest::getErrors( void )
681 int32_t IntlTest::getDataErrors( void )
683 return dataErrorCount
;
686 UBool
IntlTest::runTest( char* name
, char* par
, char *baseName
)
691 char* baseNameBuffer
= NULL
;
693 if(baseName
== NULL
) {
694 baseNameBuffer
= (char*)malloc(1024);
695 baseName
=baseNameBuffer
;
696 strcpy(baseName
, "/");
700 pos
= strchr( name
, delim
); // check if name contains path (by looking for '/')
702 testPath
= pos
+1; // store subpath for calling subtest
703 *pos
= 0; // split into two strings
708 if (!name
|| (name
[0] == 0) || (strcmp(name
, "*") == 0)) {
709 rval
= runTestLoop( NULL
, par
, baseName
);
711 }else if (strcmp( name
, "LIST" ) == 0) {
716 rval
= runTestLoop( name
, par
, baseName
);
720 *pos
= delim
; // restore original value at pos
721 if(baseNameBuffer
!=NULL
) {
722 free(baseNameBuffer
);
727 // call individual tests, to be overridden to call implementations
728 void IntlTest::runIndexedTest( int32_t /*index*/, UBool
/*exec*/, const char* & /*name*/, char* /*par*/ )
730 // to be overridden by a method like:
733 case 0: name = "First Test"; if (exec) FirstTest( par ); break;
734 case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
735 default: name = ""; break;
738 this->errln("*** runIndexedTest needs to be overridden! ***");
742 UBool
IntlTest::runTestLoop( char* testname
, char* par
, char *baseName
)
747 int32_t lastErrorCount
;
749 UBool lastTestFailed
;
751 if(baseName
== NULL
) {
752 printf("ERROR: baseName can't be null.\n");
755 if ((char *)this->basePath
!= baseName
) {
756 strcpy(this->basePath
, baseName
);
760 char * saveBaseLoc
= baseName
+strlen(baseName
);
762 IntlTest
* saveTest
= gTest
;
765 this->runIndexedTest( index
, FALSE
, name
, par
);
766 if (strcmp(name
,"skip") == 0) {
767 run_this_test
= FALSE
;
769 if (!name
|| (name
[0] == 0))
772 run_this_test
= TRUE
;
774 run_this_test
= (UBool
) (strcmp( name
, testname
) == 0);
778 lastErrorCount
= errorCount
;
781 sprintf(msg
, "%s {", name
);
782 LL_message(msg
, TRUE
);
783 UDate timeStart
= uprv_getRawUTCtime();
784 strcpy(saveBaseLoc
,name
);
785 strcat(saveBaseLoc
,"/");
787 strcpy(currName
, name
); // set
788 this->runIndexedTest( index
, TRUE
, name
, par
);
789 currName
[0]=0; // reset
791 UDate timeStop
= uprv_getRawUTCtime();
792 rval
= TRUE
; // at least one test has been called
795 sprintf(secs
, "%f", (timeStop
-timeStart
)/1000.0);
801 strcpy(saveBaseLoc
,name
);
804 ctest_xml_testcase(baseName
, name
, secs
, (lastErrorCount
!=errorCount
)?"err":NULL
);
807 saveBaseLoc
[0]=0; /* reset path */
809 if (lastErrorCount
== errorCount
) {
810 sprintf( msg
, " } OK: %s ", name
);
811 if(!no_time
) str_timeDelta(msg
+strlen(msg
),timeStop
-timeStart
);
812 lastTestFailed
= FALSE
;
814 sprintf(msg
, " } ERRORS (%li) in %s", (long)(errorCount
-lastErrorCount
), name
);
815 if(!no_time
) str_timeDelta(msg
+strlen(msg
),timeStop
-timeStart
);
817 for(int i
=0;i
<LL_indentlevel
;i
++) {
822 lastTestFailed
= TRUE
;
825 if (lastTestFailed
) {
826 LL_message( "", TRUE
);
828 LL_message( msg
, TRUE
);
829 if (lastTestFailed
) {
830 LL_message( "", TRUE
);
845 * Adds given string to the log if we are in verbose mode.
847 void IntlTest::log( const UnicodeString
&message
)
850 LL_message( message
, FALSE
);
855 * Adds given string to the log if we are in verbose mode. Adds a new line to
858 void IntlTest::logln( const UnicodeString
&message
)
861 LL_message( message
, TRUE
);
865 void IntlTest::logln( void )
868 LL_message( "", TRUE
);
873 * Unconditionally adds given string to the log.
875 void IntlTest::info( const UnicodeString
&message
)
877 LL_message( message
, FALSE
);
881 * Unconditionally adds given string to the log. Adds a new line to
884 void IntlTest::infoln( const UnicodeString
&message
)
886 LL_message( message
, TRUE
);
889 void IntlTest::infoln( void )
891 LL_message( "", TRUE
);
894 int32_t IntlTest::IncErrorCount( void )
897 if (caller
) caller
->IncErrorCount();
901 int32_t IntlTest::IncDataErrorCount( void )
904 if (caller
) caller
->IncDataErrorCount();
905 return dataErrorCount
;
913 void IntlTest::err( const UnicodeString
&message
)
916 if (!no_err_msg
) LL_message( message
, FALSE
);
919 void IntlTest::errln( const UnicodeString
&message
)
922 if (!no_err_msg
) LL_message( message
, TRUE
);
925 void IntlTest::dataerr( const UnicodeString
&message
)
929 if (!warn_on_missing_data
) {
933 if (!no_err_msg
) LL_message( message
, FALSE
);
936 void IntlTest::dataerrln( const UnicodeString
&message
)
938 int32_t errCount
= IncDataErrorCount();
940 if (!warn_on_missing_data
) {
944 msg
= UnicodeString("[DATA] " + message
);
948 if ( errCount
== 1) {
949 LL_message( msg
+ " - (Are you missing data?)", TRUE
); // only show this message the first time
951 LL_message( msg
, TRUE
);
956 void IntlTest::errcheckln(UErrorCode status
, const UnicodeString
&message
) {
957 if (status
== U_FILE_ACCESS_ERROR
|| status
== U_MISSING_RESOURCE_ERROR
) {
964 /* convenience functions that include sprintf formatting */
965 void IntlTest::log(const char *fmt
, ...)
971 /* sprintf it just to make sure that the information is valid */
972 vsprintf(buffer
, fmt
, ap
);
975 log(UnicodeString(buffer
, (const char *)NULL
));
979 void IntlTest::logln(const char *fmt
, ...)
985 /* sprintf it just to make sure that the information is valid */
986 vsprintf(buffer
, fmt
, ap
);
989 logln(UnicodeString(buffer
, (const char *)NULL
));
993 UBool
IntlTest::logKnownIssue(const char *ticket
, const char *fmt
, ...)
999 /* sprintf it just to make sure that the information is valid */
1000 vsprintf(buffer
, fmt
, ap
);
1002 return logKnownIssue(ticket
, UnicodeString(buffer
, (const char *)NULL
));
1005 UBool
IntlTest::logKnownIssue(const char *ticket
) {
1006 return logKnownIssue(ticket
, UnicodeString());
1009 UBool
IntlTest::logKnownIssue(const char *ticket
, const UnicodeString
&msg
) {
1010 if(noKnownIssues
) return FALSE
;
1012 char fullpath
[2048];
1013 strcpy(fullpath
, basePath
);
1014 strcat(fullpath
, currName
);
1015 UnicodeString msg2
= msg
;
1016 UBool firstForTicket
= TRUE
, firstForWhere
= TRUE
;
1017 knownList
= udbg_knownIssue_openU(knownList
, ticket
, fullpath
, msg2
.getTerminatedBuffer(), &firstForTicket
, &firstForWhere
);
1019 msg2
= UNICODE_STRING_SIMPLE("(Known issue #") +
1020 UnicodeString(ticket
, -1, US_INV
) + UNICODE_STRING_SIMPLE(") ") + msg
;
1021 if(firstForTicket
|| firstForWhere
) {
1030 /* convenience functions that include sprintf formatting */
1031 void IntlTest::info(const char *fmt
, ...)
1037 /* sprintf it just to make sure that the information is valid */
1038 vsprintf(buffer
, fmt
, ap
);
1040 info(UnicodeString(buffer
, (const char *)NULL
));
1043 void IntlTest::infoln(const char *fmt
, ...)
1049 /* sprintf it just to make sure that the information is valid */
1050 vsprintf(buffer
, fmt
, ap
);
1052 infoln(UnicodeString(buffer
, (const char *)NULL
));
1055 void IntlTest::err(const char *fmt
, ...)
1061 vsprintf(buffer
, fmt
, ap
);
1063 err(UnicodeString(buffer
, (const char *)NULL
));
1066 void IntlTest::errln(const char *fmt
, ...)
1072 vsprintf(buffer
, fmt
, ap
);
1074 errln(UnicodeString(buffer
, (const char *)NULL
));
1077 void IntlTest::dataerrln(const char *fmt
, ...)
1083 vsprintf(buffer
, fmt
, ap
);
1085 dataerrln(UnicodeString(buffer
, (const char *)NULL
));
1088 void IntlTest::errcheckln(UErrorCode status
, const char *fmt
, ...)
1094 vsprintf(buffer
, fmt
, ap
);
1097 if (status
== U_FILE_ACCESS_ERROR
|| status
== U_MISSING_RESOURCE_ERROR
) {
1098 dataerrln(UnicodeString(buffer
, (const char *)NULL
));
1100 errln(UnicodeString(buffer
, (const char *)NULL
));
1104 void IntlTest::printErrors()
1106 IntlTest::LL_message(errorList
, TRUE
);
1109 UBool
IntlTest::printKnownIssues()
1111 if(knownList
!= NULL
) {
1112 udbg_knownIssue_print(knownList
);
1113 udbg_knownIssue_close(knownList
);
1121 void IntlTest::LL_message( UnicodeString message
, UBool newline
)
1123 // Synchronize this function.
1124 // All error messages generated by tests funnel through here.
1125 // Multithreaded tests can concurrently generate errors, requiring synchronization
1126 // to keep each message together.
1127 static UMutex messageMutex
;
1128 Mutex
lock(&messageMutex
);
1130 // string that starts with a LineFeed character and continues
1131 // with spaces according to the current indentation
1132 static const UChar indentUChars
[] = {
1134 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1135 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1136 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1137 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1138 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1139 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1140 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1141 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1142 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1143 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
1145 U_ASSERT(1 + LL_indentlevel
<= UPRV_LENGTHOF(indentUChars
));
1146 UnicodeString
indent(FALSE
, indentUChars
, 1 + LL_indentlevel
);
1151 // stream out the indentation string first if necessary
1152 length
= indent
.extract(1, indent
.length(), buffer
, sizeof(buffer
));
1154 fwrite(buffer
, sizeof(*buffer
), length
, (FILE *)testoutfp
);
1157 // replace each LineFeed by the indentation string
1158 message
.findAndReplace(UnicodeString((UChar
)'\n'), indent
);
1160 // stream out the message
1161 length
= message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
1163 length
= length
> 30000 ? 30000 : length
;
1164 fwrite(buffer
, sizeof(*buffer
), length
, (FILE *)testoutfp
);
1168 char newLine
= '\n';
1169 fwrite(&newLine
, sizeof(newLine
), 1, (FILE *)testoutfp
);
1172 // A newline usually flushes the buffer, but
1173 // flush the message just in case of a core dump.
1174 fflush((FILE *)testoutfp
);
1178 * Print a usage message for this test class.
1180 void IntlTest::usage( void )
1182 UBool save_verbose
= setVerbose( TRUE
);
1183 logln("Test names:");
1184 logln("-----------");
1187 const char* name
= NULL
;
1189 this->runIndexedTest( index
, FALSE
, name
);
1193 }while (name
&& (name
[0] != 0));
1194 setVerbose( save_verbose
);
1198 // memory leak reporting software will be able to take advantage of the testsuite
1199 // being run a second time local to a specific method in order to report only actual leaks
1201 IntlTest::run_phase2( char* name
, char* par
) // supports reporting memory leaks
1203 UnicodeString
* strLeak
= new UnicodeString("forced leak"); // for verifying purify filter
1204 strLeak
->append(" for verifying purify filter");
1205 return this->runTest( name
, par
);
1209 #if UCONFIG_NO_LEGACY_CONVERSION
1210 # define TRY_CNV_1 "iso-8859-1"
1211 # define TRY_CNV_2 "ibm-1208"
1213 # define TRY_CNV_1 "iso-8859-7"
1214 # define TRY_CNV_2 "sjis"
1217 #ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
1218 U_CAPI
void unistr_printLengths();
1222 main(int argc
, char* argv
[])
1224 UBool syntax
= FALSE
;
1226 UBool verbose
= FALSE
;
1227 UBool no_err_msg
= FALSE
;
1228 UBool no_time
= FALSE
;
1231 UBool leaks
= FALSE
;
1233 const char *summary_file
= NULL
;
1234 UBool warnOnMissingData
= FALSE
;
1235 UBool writeGoldenData
= FALSE
;
1236 UBool defaultDataFound
= FALSE
;
1237 int32_t threadCount
= 12;
1238 UErrorCode errorCode
= U_ZERO_ERROR
;
1239 UConverter
*cnv
= NULL
;
1240 const char *warnOrErr
= "Failure";
1241 UDate startTime
, endTime
;
1243 const char *props
[IntlTest::kMaxProps
];
1246 U_MAIN_INIT_ARGS(argc
, argv
);
1248 startTime
= uprv_getRawUTCtime();
1250 for (int i
= 1; i
< argc
; ++i
) {
1251 if (argv
[i
][0] == '-') {
1252 const char* str
= argv
[i
] + 1;
1253 if (strcmp("verbose", str
) == 0 ||
1254 strcmp("v", str
) == 0)
1256 else if (strcmp("noerrormsg", str
) == 0 ||
1257 strcmp("n", str
) == 0)
1259 else if (strcmp("exhaustive", str
) == 0 ||
1260 strcmp("e", str
) == 0)
1262 else if (strcmp("all", str
) == 0 ||
1263 strcmp("a", str
) == 0)
1265 else if (strcmp("utf-8", str
) == 0 ||
1266 strcmp("u", str
) == 0)
1268 else if (strcmp("noknownissues", str
) == 0 ||
1269 strcmp("K", str
) == 0)
1270 noKnownIssues
= TRUE
;
1271 else if (strcmp("leaks", str
) == 0 ||
1272 strcmp("l", str
) == 0)
1274 else if (strcmp("notime", str
) == 0 ||
1275 strcmp("T", str
) == 0)
1277 else if (strcmp("goldens", str
) == 0 ||
1278 strcmp("G", str
) == 0)
1279 writeGoldenData
= TRUE
;
1280 else if (strncmp("E", str
, 1) == 0)
1281 summary_file
= str
+1;
1282 else if (strcmp("x", str
)==0) {
1284 printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n");
1287 if(ctest_xml_setFileName(argv
[i
])) { /* set the name */
1288 return 1; /* error */
1290 } else if (strcmp("w", str
) == 0) {
1291 warnOnMissingData
= TRUE
;
1292 warnOrErr
= "WARNING";
1294 else if (strncmp("threads:", str
, 8) == 0) {
1295 threadCount
= atoi(str
+ 8);
1297 else if (strncmp("prop:", str
, 5) == 0) {
1298 if (nProps
< IntlTest::kMaxProps
) {
1299 props
[nProps
] = str
+ 5;
1311 if (!all
&& !name
) {
1313 } else if (all
&& name
) {
1320 "### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n"
1322 "### Options are: verbose (v), all (a), noerrormsg (n), \n"
1323 "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:<propery>=<value>, \n"
1324 "### notime (T), \n"
1325 "### threads:<threadCount>\n"
1326 "### (The default thread count is 12.),\n"
1327 "### (Specify either -all (shortcut -a) or a test name). \n"
1328 "### -all will run all of the tests.\n"
1330 "### To get a list of the test names type: intltest LIST \n"
1331 "### To run just the utility tests type: intltest utility \n"
1333 "### Test names can be nested using slashes (\"testA/subtest1\") \n"
1334 "### For example to list the utility tests type: intltest utility/LIST \n"
1335 "### To run just the Locale test type: intltest utility/LocaleTest \n"
1337 "### A parameter can be specified for a test by appending '@' and the value \n"
1338 "### to the testname. \n\n");
1342 if (nProps
> IntlTest::kMaxProps
) {
1343 fprintf(stdout
, "### Too many properties. Exiting.\n");
1346 MajorTestLevel major
;
1347 major
.setVerbose( verbose
);
1348 major
.setNoErrMsg( no_err_msg
);
1349 major
.setQuick( quick
);
1350 major
.setLeaks( leaks
);
1351 major
.setThreadCount( threadCount
);
1352 major
.setWarnOnMissingData( warnOnMissingData
);
1353 major
.setWriteGoldenData( writeGoldenData
);
1354 major
.setNotime (no_time
);
1355 for (int32_t i
= 0; i
< nProps
; i
++) {
1356 major
.setProperty(props
[i
]);
1360 fprintf(stdout
, "-----------------------------------------------\n");
1361 fprintf(stdout
, " IntlTest (C++) Test Suite for \n");
1362 fprintf(stdout
, " International Components for Unicode %s\n", U_ICU_VERSION
);
1366 const char *charsetFamily
= "Unknown";
1367 int32_t voidSize
= (int32_t)sizeof(void*);
1368 int32_t bits
= voidSize
* 8;
1369 if(U_CHARSET_FAMILY
==U_ASCII_FAMILY
) {
1370 charsetFamily
="ASCII";
1371 } else if(U_CHARSET_FAMILY
==U_EBCDIC_FAMILY
) {
1372 charsetFamily
="EBCDIC";
1375 " Bits: %d, Byte order: %s, Chars: %s\n",
1376 bits
, U_IS_BIG_ENDIAN
?"Big endian":"Little endian",
1379 fprintf(stdout
, "-----------------------------------------------\n");
1380 fprintf(stdout
, " Options: \n");
1381 fprintf(stdout
, " all (a) : %s\n", (all
? "On" : "Off"));
1382 fprintf(stdout
, " Verbose (v) : %s\n", (verbose
? "On" : "Off"));
1383 fprintf(stdout
, " No error messages (n) : %s\n", (no_err_msg
? "On" : "Off"));
1384 fprintf(stdout
, " Exhaustive (e) : %s\n", (!quick
? "On" : "Off"));
1385 fprintf(stdout
, " Leaks (l) : %s\n", (leaks
? "On" : "Off"));
1386 fprintf(stdout
, " utf-8 (u) : %s\n", (utf8
? "On" : "Off"));
1387 fprintf(stdout
, " notime (T) : %s\n", (no_time
? "On" : "Off"));
1388 fprintf(stdout
, " noknownissues (K) : %s\n", (noKnownIssues
? "On" : "Off"));
1389 fprintf(stdout
, " Warn on missing data (w) : %s\n", (warnOnMissingData
? "On" : "Off"));
1390 fprintf(stdout
, " Write golden data (G) : %s\n", (writeGoldenData
? "On" : "Off"));
1391 fprintf(stdout
, " Threads : %d\n", threadCount
);
1392 for (int32_t i
= 0; i
< nProps
; i
++) {
1393 fprintf(stdout
, " Custom property (prop:) : %s\n", props
[i
]);
1395 fprintf(stdout
, "-----------------------------------------------\n");
1398 ucnv_setDefaultName("utf-8");
1400 /* Check whether ICU will initialize without forcing the build data directory into
1401 * the ICU_DATA path. Success here means either the data dll contains data, or that
1402 * this test program was run with ICU_DATA set externally. Failure of this check
1403 * is normal when ICU data is not packaged into a shared library.
1405 * Whether or not this test succeeds, we want to cleanup and reinitialize
1406 * with a data path so that data loading from individual files can be tested.
1409 if (U_FAILURE(errorCode
)) {
1411 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
1412 defaultDataFound
= FALSE
;
1415 defaultDataFound
= TRUE
;
1419 ucnv_setDefaultName("utf-8");
1421 errorCode
= U_ZERO_ERROR
;
1423 /* Initialize ICU */
1424 if (!defaultDataFound
) {
1425 IntlTest::setICU_DATA(); // Must set data directory before u_init() is called.
1428 if (U_FAILURE(errorCode
)) {
1430 "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
1431 "*** Check the ICU_DATA environment variable and \n"
1432 "*** check that the data files are present.\n", argv
[0], u_errorName(errorCode
));
1433 if(warnOnMissingData
== 0) {
1434 fprintf(stderr
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1440 // initial check for the default converter
1441 errorCode
= U_ZERO_ERROR
;
1442 cnv
= ucnv_open(0, &errorCode
);
1448 "*** %s! The default converter [%s] cannot be opened.\n"
1449 "*** Check the ICU_DATA environment variable and\n"
1450 "*** check that the data files are present.\n",
1451 warnOrErr
, ucnv_getDefaultName());
1452 if(!warnOnMissingData
) {
1453 fprintf(stdout
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1459 cnv
= ucnv_open(TRY_CNV_2
, &errorCode
);
1465 "*** %s! The converter for " TRY_CNV_2
" cannot be opened.\n"
1466 "*** Check the ICU_DATA environment variable and \n"
1467 "*** check that the data files are present.\n", warnOrErr
);
1468 if(!warnOnMissingData
) {
1469 fprintf(stdout
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1474 UResourceBundle
*rb
= ures_open(0, "en", &errorCode
);
1476 if(U_FAILURE(errorCode
)) {
1478 "*** %s! The \"en\" locale resource bundle cannot be opened.\n"
1479 "*** Check the ICU_DATA environment variable and \n"
1480 "*** check that the data files are present.\n", warnOrErr
);
1481 if(!warnOnMissingData
) {
1482 fprintf(stdout
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1487 Locale originalLocale
; // Save the default locale for comparison later on.
1489 if(ctest_xml_init("intltest"))
1493 /* TODO: Add option to call u_cleanup and rerun tests. */
1497 major
.run_phase2( NULL
, NULL
);
1500 for (int i
= 1; i
< argc
; ++i
) {
1501 if (argv
[i
][0] != '-') {
1502 char* name
= argv
[i
];
1503 fprintf(stdout
, "\n=== Handling test: %s: ===\n", name
);
1505 char baseName
[1024];
1506 sprintf(baseName
, "/%s/", name
);
1508 char* parameter
= strchr( name
, '@' );
1514 UBool res
= major
.runTest( name
, parameter
, baseName
);
1516 major
.run_phase2( name
, parameter
);
1518 if (!res
|| (execCount
<= 0)) {
1519 fprintf(stdout
, "\n---ERROR: Test doesn't exist: %s!\n", name
);
1521 } else if(!strcmp(argv
[i
],"-x")) {
1528 #if !UCONFIG_NO_FORMATTING
1529 CalendarTimeZoneTest::cleanup();
1532 free(_testDataPath
);
1535 Locale lastDefaultLocale
;
1536 if (originalLocale
!= lastDefaultLocale
) {
1537 major
.errln("FAILURE: A test changed the default locale without resetting it.");
1540 fprintf(stdout
, "\n--------------------------------------\n");
1541 if( major
.printKnownIssues() ) {
1542 fprintf(stdout
, " To run suppressed tests, use the -K option. \n");
1544 if (major
.getErrors() == 0) {
1545 /* Call it twice to make sure that the defaults were reset. */
1546 /* Call it before the OK message to verify proper cleanup. */
1550 fprintf(stdout
, "OK: All tests passed without error.\n");
1552 if (major
.getDataErrors() != 0) {
1553 fprintf(stdout
, "\t*WARNING* some data-loading errors were ignored by the -w option.\n");
1556 fprintf(stdout
, "Errors in total: %ld.\n", (long)major
.getErrors());
1557 major
.printErrors();
1559 if(summary_file
!= NULL
) {
1560 FILE *summf
= fopen(summary_file
, "w");
1561 if( summf
!= NULL
) {
1563 int32_t length
= errorList
.extract(0, errorList
.length(), buf
, sizeof(buf
));
1564 fwrite(buf
, sizeof(*buf
), length
, (FILE*)summf
);
1570 if (major
.getDataErrors() != 0) {
1571 fprintf(stdout
, "\t*Note* some errors are data-loading related. If the data used is not the \n"
1572 "\tstock ICU data (i.e some have been added or removed), consider using\n"
1573 "\tthe '-w' option to turn these errors into warnings.\n");
1576 /* Call afterwards to display errors. */
1580 #ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
1581 unistr_printLengths();
1584 fprintf(stdout
, "--------------------------------------\n");
1586 if (execCount
<= 0) {
1587 fprintf(stdout
, "***** Not all called tests actually exist! *****\n");
1590 endTime
= uprv_getRawUTCtime();
1591 diffTime
= (int32_t)(endTime
- startTime
);
1592 printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
1593 (int)((diffTime%U_MILLIS_PER_DAY
)/U_MILLIS_PER_HOUR
),
1594 (int)((diffTime%U_MILLIS_PER_HOUR
)/U_MILLIS_PER_MINUTE
),
1595 (int)((diffTime%U_MILLIS_PER_MINUTE
)/U_MILLIS_PER_SECOND
),
1596 (int)(diffTime%U_MILLIS_PER_SECOND
));
1599 if(ctest_xml_fini())
1602 return major
.getErrors();
1605 const char* IntlTest::loadTestData(UErrorCode
& err
){
1606 if( _testDataPath
== NULL
){
1607 const char* directory
=NULL
;
1608 UResourceBundle
* test
=NULL
;
1610 const char* tdrelativepath
;
1612 #if defined (U_TOPBUILDDIR)
1613 tdrelativepath
= "test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
1614 directory
= U_TOPBUILDDIR
;
1616 tdrelativepath
= ".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
1617 directory
= pathToDataDirectory();
1620 tdpath
= (char*) malloc(sizeof(char) *(( strlen(directory
) * strlen(tdrelativepath
)) + 100));
1623 /* u_getDataDirectory shoul return \source\data ... set the
1624 * directory to ..\source\data\..\test\testdata\out\testdata
1626 strcpy(tdpath
, directory
);
1627 strcat(tdpath
, tdrelativepath
);
1628 strcat(tdpath
,"testdata");
1630 test
=ures_open(tdpath
, "testtypes", &err
);
1633 err
= U_FILE_ACCESS_ERROR
;
1634 it_dataerrln((UnicodeString
)"Could not load testtypes.res in testdata bundle with path " + tdpath
+ (UnicodeString
)" - " + u_errorName(err
));
1638 _testDataPath
= tdpath
;
1639 return _testDataPath
;
1641 return _testDataPath
;
1644 const char* IntlTest::getTestDataPath(UErrorCode
& err
) {
1645 return loadTestData(err
);
1648 /* Returns the path to icu/source/test/testdata/ */
1649 const char *IntlTest::getSourceTestData(UErrorCode
& /*err*/) {
1650 const char *srcDataDir
= NULL
;
1652 srcDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
;
1654 srcDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
;
1655 FILE *f
= fopen(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"rbbitst.txt", "r");
1657 /* We're in icu/source/test/intltest/ */
1661 /* We're in icu/source/test/intltest/Platform/(Debug|Release) */
1662 srcDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
1663 "test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
;
1669 char *IntlTest::getUnidataPath(char path
[]) {
1670 const int kUnicodeDataTxtLength
= 15; // strlen("UnicodeData.txt")
1672 // Look inside ICU_DATA first.
1673 strcpy(path
, pathToDataDirectory());
1674 strcat(path
, "unidata" U_FILE_SEP_STRING
"UnicodeData.txt");
1675 FILE *f
= fopen(path
, "r");
1678 *(strchr(path
, 0) - kUnicodeDataTxtLength
) = 0; // Remove the basename.
1682 // As a fallback, try to guess where the source data was located
1683 // at the time ICU was built, and look there.
1685 strcpy(path
, U_TOPSRCDIR U_FILE_SEP_STRING
"data");
1687 UErrorCode errorCode
= U_ZERO_ERROR
;
1688 const char *testDataPath
= loadTestData(errorCode
);
1689 if(U_FAILURE(errorCode
)) {
1690 it_errln(UnicodeString(
1691 "unable to find path to source/data/unidata/ and loadTestData() failed: ") +
1692 u_errorName(errorCode
));
1695 strcpy(path
, testDataPath
);
1696 strcat(path
, U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".."
1697 U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".."
1698 U_FILE_SEP_STRING
"data");
1700 strcat(path
, U_FILE_SEP_STRING
);
1701 strcat(path
, "unidata" U_FILE_SEP_STRING
"UnicodeData.txt");
1702 f
= fopen(path
, "r");
1705 *(strchr(path
, 0) - kUnicodeDataTxtLength
) = 0; // Remove the basename.
1711 const char* IntlTest::fgDataDir
= NULL
;
1713 /* returns the path to icu/source/data */
1714 const char * IntlTest::pathToDataDirectory()
1717 if(fgDataDir
!= NULL
) {
1721 /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
1722 // to point to the top of the build hierarchy, which may or
1723 // may not be the same as the source directory, depending on
1724 // the configure options used. At any rate,
1725 // set the data path to the built data from this directory.
1726 // The value is complete with quotes, so it can be used
1727 // as-is as a string constant.
1729 #if defined (U_TOPSRCDIR)
1731 fgDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
1735 /* On Windows, the file name obtained from __FILE__ includes a full path.
1736 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
1737 * Change to "wherever\icu\source\data"
1740 static char p
[sizeof(__FILE__
) + 10];
1744 strcpy(p
, __FILE__
);
1745 /* We want to back over three '\' chars. */
1746 /* Only Windows should end up here, so looking for '\' is safe. */
1747 for (i
=1; i
<=3; i
++) {
1748 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
1749 if (pBackSlash
!= NULL
) {
1750 *pBackSlash
= 0; /* Truncate the string at the '\' */
1754 if (pBackSlash
!= NULL
) {
1755 /* We found and truncated three names from the path.
1756 * Now append "source\data" and set the environment
1758 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
);
1762 /* __FILE__ on MSVC7 does not contain the directory */
1763 FILE *file
= fopen(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
1766 fgDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
1769 fgDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
1780 * This is a variant of cintltst/ccolltst.c:CharsToUChars().
1781 * It converts an invariant-character string into a UnicodeString, with
1782 * unescaping \u sequences.
1784 UnicodeString
CharsToUnicodeString(const char* chars
){
1785 return UnicodeString(chars
, -1, US_INV
).unescape();
1788 UnicodeString
ctou(const char* chars
) {
1789 return CharsToUnicodeString(chars
);
1792 #define RAND_M (714025)
1793 #define RAND_IA (1366)
1794 #define RAND_IC (150889)
1796 static int32_t RAND_SEED
;
1799 * Returns a uniform random value x, with 0.0 <= x < 1.0. Use
1800 * with care: Does not return all possible values; returns one of
1801 * 714,025 values, uniformly spaced. However, the period is
1802 * effectively infinite. See: Numerical Recipes, section 7.1.
1804 * @param seedp pointer to seed. Set *seedp to any negative value
1805 * to restart the sequence.
1807 float IntlTest::random(int32_t* seedp
) {
1808 static int32_t iy
, ir
[98];
1809 static UBool first
=TRUE
;
1811 if (*seedp
< 0 || first
) {
1813 if ((*seedp
=(RAND_IC
-(*seedp
)) % RAND_M
) < 0) *seedp
= -(*seedp
);
1814 for (j
=1;j
<=97;++j
) {
1815 *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
;
1818 *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
;
1821 j
=(int32_t)(1 + 97.0*iy
/RAND_M
);
1822 U_ASSERT(j
>=1 && j
<=97);
1824 *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
;
1826 return (float) iy
/RAND_M
;
1830 * Convenience method using a global seed.
1832 float IntlTest::random() {
1833 return random(&RAND_SEED
);
1838 * Integer random number class implementation.
1839 * Similar to C++ std::minstd_rand, with the same algorithm & constants.
1841 IntlTest::icu_rand::icu_rand(uint32_t seed
) {
1842 seed
= seed
% 2147483647UL;
1849 IntlTest::icu_rand::~icu_rand() {}
1851 void IntlTest::icu_rand::seed(uint32_t seed
) {
1858 uint32_t IntlTest::icu_rand::operator() () {
1859 fLast
= ((uint64_t)fLast
* 48271UL) % 2147483647UL;
1863 uint32_t IntlTest::icu_rand::getSeed() {
1864 return (uint32_t) fLast
;
1869 static inline UChar
toHex(int32_t i
) {
1870 return (UChar
)(i
+ (i
< 10 ? 0x30 : (0x41 - 10)));
1873 static UnicodeString
& escape(const UnicodeString
& s
, UnicodeString
& result
) {
1874 for (int32_t i
=0; i
<s
.length(); ++i
) {
1876 if (c
<= (UChar
)0x7F) {
1879 result
+= (UChar
)0x5c;
1880 result
+= (UChar
)0x75;
1881 result
+= toHex((c
>> 12) & 0xF);
1882 result
+= toHex((c
>> 8) & 0xF);
1883 result
+= toHex((c
>> 4) & 0xF);
1884 result
+= toHex( c
& 0xF);
1890 #define VERBOSE_ASSERTIONS
1892 UBool
IntlTest::assertTrue(const char* message
, UBool condition
, UBool quiet
, UBool possibleDataError
, const char *file
, int line
) {
1895 if (possibleDataError
) {
1896 dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file
, line
, message
);
1898 errln("%s:%d: FAIL: assertTrue() failed: %s", file
, line
, message
);
1900 } else if (!quiet
) {
1901 logln("%s:%d: Ok: %s", file
, line
, message
);
1905 if (possibleDataError
) {
1906 dataerrln("FAIL: assertTrue() failed: %s", message
);
1908 errln("FAIL: assertTrue() failed: %s", message
);
1910 } else if (!quiet
) {
1911 logln("Ok: %s", message
);
1918 UBool
IntlTest::assertFalse(const char* message
, UBool condition
, UBool quiet
, UBool possibleDataError
) {
1920 if (possibleDataError
) {
1921 dataerrln("FAIL: assertTrue() failed: %s", message
);
1923 errln("FAIL: assertTrue() failed: %s", message
);
1925 } else if (!quiet
) {
1926 logln("Ok: %s", message
);
1931 UBool
IntlTest::assertSuccess(const char* message
, UErrorCode ec
, UBool possibleDataError
, const char *file
, int line
) {
1933 file
= ""; // prevent failure if no file given
1935 if (U_FAILURE(ec
)) {
1936 if (possibleDataError
) {
1937 dataerrln("FAIL: %s:%d: %s (%s)", file
, line
, message
, u_errorName(ec
));
1939 errcheckln(ec
, "FAIL: %s:%d: %s (%s)", file
, line
, message
, u_errorName(ec
));
1943 logln("OK: %s:%d: %s - (%s)", file
, line
, message
, u_errorName(ec
));
1948 UBool
IntlTest::assertEquals(const char* message
,
1949 const UnicodeString
& expected
,
1950 const UnicodeString
& actual
,
1951 UBool possibleDataError
) {
1952 if (expected
!= actual
) {
1953 if (possibleDataError
) {
1954 dataerrln((UnicodeString
)"FAIL: " + message
+ "; got " +
1956 "; expected " + prettify(expected
));
1958 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
1960 "; expected " + prettify(expected
));
1964 #ifdef VERBOSE_ASSERTIONS
1966 logln((UnicodeString
)"Ok: " + message
+ "; got " + prettify(actual
));
1972 UBool
IntlTest::assertEquals(const char* message
,
1973 const char* expected
,
1974 const char* actual
) {
1975 if (uprv_strcmp(expected
, actual
) != 0) {
1976 errln((UnicodeString
)"FAIL: " + message
+ "; got \"" +
1978 "\"; expected \"" + expected
+ "\"");
1981 #ifdef VERBOSE_ASSERTIONS
1983 logln((UnicodeString
)"Ok: " + message
+ "; got \"" + actual
+ "\"");
1989 UBool
IntlTest::assertEquals(const char* message
,
1992 if (expected
!= actual
) {
1993 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
1994 actual
+ "=0x" + toHex(actual
) +
1995 "; expected " + expected
+ "=0x" + toHex(expected
));
1998 #ifdef VERBOSE_ASSERTIONS
2000 logln((UnicodeString
)"Ok: " + message
+ "; got " + actual
+ "=0x" + toHex(actual
));
2006 UBool
IntlTest::assertEquals(const char* message
,
2009 if (expected
!= actual
) {
2010 errln((UnicodeString
)"FAIL: " + message
+ "; got int64 " +
2011 Int64ToUnicodeString(actual
) +
2012 "; expected " + Int64ToUnicodeString(expected
) );
2015 #ifdef VERBOSE_ASSERTIONS
2017 logln((UnicodeString
)"Ok: " + message
+ "; got int64 " + Int64ToUnicodeString(actual
));
2023 UBool
IntlTest::assertEquals(const char* message
,
2026 bool bothNaN
= std::isnan(expected
) && std::isnan(actual
);
2027 if (expected
!= actual
&& !bothNaN
) {
2028 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
2030 "; expected " + expected
);
2033 #ifdef VERBOSE_ASSERTIONS
2035 logln((UnicodeString
)"Ok: " + message
+ "; got " + actual
);
2042 UBool
IntlTest::assertEquals(const char* message
,
2045 if (expected
!= actual
) {
2046 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
2048 "; expected " + toString(expected
));
2051 #ifdef VERBOSE_ASSERTIONS
2053 logln((UnicodeString
)"Ok: " + message
+ "; got " + toString(actual
));
2060 UBool
IntlTest::assertEquals(const char* message
,
2061 UErrorCode expected
,
2062 UErrorCode actual
) {
2063 if (expected
!= actual
) {
2064 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
2065 u_errorName(actual
) +
2066 "; expected " + u_errorName(expected
));
2069 #ifdef VERBOSE_ASSERTIONS
2071 logln((UnicodeString
)"Ok: " + message
+ "; got " + u_errorName(actual
));
2077 UBool
IntlTest::assertEquals(const char* message
,
2078 const UnicodeSet
& expected
,
2079 const UnicodeSet
& actual
) {
2080 IcuTestErrorCode
status(*this, "assertEqualsUniSet");
2081 if (expected
!= actual
) {
2082 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
2083 toString(actual
, status
) +
2084 "; expected " + toString(expected
, status
));
2087 #ifdef VERBOSE_ASSERTIONS
2089 logln((UnicodeString
)"Ok: " + message
+ "; got " + toString(actual
, status
));
2096 #if !UCONFIG_NO_FORMATTING
2097 UBool
IntlTest::assertEquals(const char* message
,
2098 const Formattable
& expected
,
2099 const Formattable
& actual
,
2100 UBool possibleDataError
) {
2101 if (expected
!= actual
) {
2102 if (possibleDataError
) {
2103 dataerrln((UnicodeString
)"FAIL: " + message
+ "; got " +
2105 "; expected " + toString(expected
));
2107 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
2109 "; expected " + toString(expected
));
2113 #ifdef VERBOSE_ASSERTIONS
2115 logln((UnicodeString
)"Ok: " + message
+ "; got " + toString(actual
));
2122 std::string
vectorToString(const std::vector
<std::string
>& strings
) {
2123 std::string result
= "{";
2125 for (auto element
: strings
) {
2139 UBool
IntlTest::assertEquals(const char* message
,
2140 const std::vector
<std::string
>& expected
,
2141 const std::vector
<std::string
>& actual
) {
2142 if (expected
!= actual
) {
2143 std::string expectedAsString
= vectorToString(expected
);
2144 std::string actualAsString
= vectorToString(actual
);
2145 errln((UnicodeString
)"FAIL: " + message
+
2146 "; got " + actualAsString
.c_str() +
2147 "; expected " + expectedAsString
.c_str());
2150 #ifdef VERBOSE_ASSERTIONS
2152 logln((UnicodeString
)"Ok: " + message
+ "; got " + vectorToString(actual
).c_str());
2158 static char ASSERT_BUF
[256];
2160 static const char* extractToAssertBuf(const UnicodeString
& message
) {
2162 escape(message
, buf
);
2163 buf
.extract(0, 0x7FFFFFFF, ASSERT_BUF
, sizeof(ASSERT_BUF
)-1, 0);
2164 ASSERT_BUF
[sizeof(ASSERT_BUF
)-1] = 0;
2168 UBool
IntlTest::assertTrue(const UnicodeString
& message
, UBool condition
, UBool quiet
, UBool possibleDataError
) {
2169 return assertTrue(extractToAssertBuf(message
), condition
, quiet
, possibleDataError
);
2172 UBool
IntlTest::assertFalse(const UnicodeString
& message
, UBool condition
, UBool quiet
, UBool possibleDataError
) {
2173 return assertFalse(extractToAssertBuf(message
), condition
, quiet
, possibleDataError
);
2176 UBool
IntlTest::assertSuccess(const UnicodeString
& message
, UErrorCode ec
) {
2177 return assertSuccess(extractToAssertBuf(message
), ec
);
2180 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2181 const UnicodeString
& expected
,
2182 const UnicodeString
& actual
,
2183 UBool possibleDataError
) {
2184 return assertEquals(extractToAssertBuf(message
), expected
, actual
, possibleDataError
);
2187 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2188 const char* expected
,
2189 const char* actual
) {
2190 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2192 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2195 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2197 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2200 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2202 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2205 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2207 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2210 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2212 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2213 UErrorCode expected
,
2214 UErrorCode actual
) {
2215 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2217 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2218 const UnicodeSet
& expected
,
2219 const UnicodeSet
& actual
) {
2220 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2222 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2223 const std::vector
<std::string
>& expected
,
2224 const std::vector
<std::string
>& actual
) {
2225 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2228 #if !UCONFIG_NO_FORMATTING
2229 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2230 const Formattable
& expected
,
2231 const Formattable
& actual
) {
2232 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2236 void IntlTest::setProperty(const char* propline
) {
2237 if (numProps
< kMaxProps
) {
2238 proplines
[numProps
] = propline
;
2243 const char* IntlTest::getProperty(const char* prop
) {
2244 const char* val
= NULL
;
2245 for (int32_t i
= 0; i
< numProps
; i
++) {
2246 int32_t plen
= static_cast<int32_t>(uprv_strlen(prop
));
2247 if ((int32_t)uprv_strlen(proplines
[i
]) > plen
+ 1
2248 && proplines
[i
][plen
] == '='
2249 && uprv_strncmp(proplines
[i
], prop
, plen
) == 0) {
2250 val
= &(proplines
[i
][plen
+1]);
2258 * Hey, Emacs, please set the following:
2261 * indent-tabs-mode: nil