1 /********************************************************************
3 * Copyright (c) 1997-2014, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
8 #include "unicode/utypes.h"
11 * IntlTest is a base class for tests.
20 #include "unicode/unistr.h"
21 #include "unicode/ures.h"
22 #include "unicode/smpdtfmt.h"
23 #include "unicode/ucnv.h"
24 #include "unicode/uclean.h"
25 #include "unicode/timezone.h"
26 #include "unicode/curramt.h"
27 #include "unicode/putil.h"
38 #include "putilimp.h" // for uprv_getRawUTCtime()
39 #include "unicode/locid.h"
40 #include "unicode/ctest.h" // for str_timeDelta
49 static char* _testDataPath
=NULL
;
51 // Static list of errors found
52 static UnicodeString errorList
;
53 static void *knownList
= NULL
; // known issues
54 static UBool noKnownIssues
= FALSE
; // if TRUE, don't emit known issues
56 //-----------------------------------------------------------------------------
57 //convenience classes to ease porting code that uses the Java
58 //string-concatenation operator (moved from findword test by rtg)
60 // [LIU] Just to get things working
62 UCharToUnicodeString(UChar c
)
63 { return UnicodeString(c
); }
65 // [rtg] Just to get things working
67 operator+(const UnicodeString
& left
,
70 char buffer
[64]; // nos changed from 10 to 64
71 char danger
= 'p'; // guard against overrunning the buffer (rtg)
73 sprintf(buffer
, "%ld", num
);
74 assert(danger
== 'p');
80 operator+(const UnicodeString
& left
,
83 char buffer
[64]; // nos changed from 10 to 64
84 char danger
= 'p'; // guard against overrunning the buffer (rtg)
86 sprintf(buffer
, "%lu", num
);
87 assert(danger
== 'p');
93 Int64ToUnicodeString(int64_t num
)
95 char buffer
[64]; // nos changed from 10 to 64
96 char danger
= 'p'; // guard against overrunning the buffer (rtg)
99 sprintf(buffer
, "%I64d", num
);
101 sprintf(buffer
, "%lld", (long long)num
);
103 assert(danger
== 'p');
108 // [LIU] Just to get things working
110 operator+(const UnicodeString
& left
,
113 char buffer
[64]; // was 32, made it arbitrarily bigger (rtg)
114 char danger
= 'p'; // guard against overrunning the buffer (rtg)
116 // IEEE floating point has 52 bits of mantissa, plus one assumed bit
117 // 53*log(2)/log(10) = 15.95
118 // so there is no need to show more than 16 digits. [alan]
120 sprintf(buffer
, "%.17g", num
);
121 assert(danger
== 'p');
123 return left
+ buffer
;
128 operator+(const UnicodeString
& left
,
130 return left
+ Int64ToUnicodeString(num
);
134 #if !UCONFIG_NO_FORMATTING
137 * Return a string display for this, without surrounding braces.
139 UnicodeString
_toString(const Formattable
& f
) {
141 switch (f
.getType()) {
142 case Formattable::kDate
:
144 UErrorCode status
= U_ZERO_ERROR
;
145 SimpleDateFormat
fmt(status
);
146 if (U_SUCCESS(status
)) {
148 fmt
.format(f
.getDate(), s
, pos
);
149 s
.insert(0, "Date:");
151 s
= UnicodeString("Error creating date format]");
155 case Formattable::kDouble
:
156 s
= UnicodeString("double:") + f
.getDouble();
158 case Formattable::kLong
:
159 s
= UnicodeString("long:") + f
.getLong();
162 case Formattable::kInt64
:
163 s
= UnicodeString("int64:") + Int64ToUnicodeString(f
.getInt64());
166 case Formattable::kString
:
168 s
.insert(0, "String:");
170 case Formattable::kArray
:
173 const Formattable
* array
= f
.getArray(n
);
174 s
.insert(0, UnicodeString("Array:"));
175 UnicodeString
delim(", ");
176 for (i
=0; i
<n
; ++i
) {
180 s
= s
+ _toString(array
[i
]);
184 case Formattable::kObject
: {
185 const CurrencyAmount
* c
= dynamic_cast<const CurrencyAmount
*>(f
.getObject());
187 s
= _toString(c
->getNumber()) + " " + UnicodeString(c
->getISOCurrency());
189 s
= UnicodeString("Unknown UObject");
194 s
= UnicodeString("Unknown Formattable type=") + (int32_t)f
.getType();
201 * Originally coded this as operator+, but that makes the expression
202 * + char* ambiguous. - liu
204 UnicodeString
toString(const Formattable
& f
) {
205 UnicodeString
s((UChar
)91/*[*/);
206 s
.append(_toString(f
));
207 s
.append((UChar
)0x5d/*]*/);
213 // useful when operator+ won't cooperate
214 UnicodeString
toString(int32_t n
) {
215 return UnicodeString() + (long)n
;
220 UnicodeString
toString(UBool b
) {
221 return b
? UnicodeString("TRUE"):UnicodeString("FALSE");
224 // stephen - cleaned up 05/05/99
225 UnicodeString
operator+(const UnicodeString
& left
, char num
)
226 { return left
+ (long)num
; }
227 UnicodeString
operator+(const UnicodeString
& left
, short num
)
228 { return left
+ (long)num
; }
229 UnicodeString
operator+(const UnicodeString
& left
, int num
)
230 { return left
+ (long)num
; }
231 UnicodeString
operator+(const UnicodeString
& left
, unsigned char num
)
232 { return left
+ (unsigned long)num
; }
233 UnicodeString
operator+(const UnicodeString
& left
, unsigned short num
)
234 { return left
+ (unsigned long)num
; }
235 UnicodeString
operator+(const UnicodeString
& left
, unsigned int num
)
236 { return left
+ (unsigned long)num
; }
237 UnicodeString
operator+(const UnicodeString
& left
, float num
)
238 { return left
+ (double)num
; }
242 // Append a hex string to the target
244 IntlTest::appendHex(uint32_t number
,
246 UnicodeString
& target
)
248 static const UChar digitString
[] = {
249 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
250 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0
251 }; /* "0123456789ABCDEF" */
253 if (digits
< 0) { // auto-digits
256 while (number
> max
) {
258 max
= (max
<< 8) | 0xff;
264 target
+= digitString
[(number
>> 28) & 0xF];
266 target
+= digitString
[(number
>> 24) & 0xF];
268 target
+= digitString
[(number
>> 20) & 0xF];
270 target
+= digitString
[(number
>> 16) & 0xF];
272 target
+= digitString
[(number
>> 12) & 0xF];
274 target
+= digitString
[(number
>> 8) & 0xF];
276 target
+= digitString
[(number
>> 4) & 0xF];
278 target
+= digitString
[(number
>> 0) & 0xF];
287 IntlTest::toHex(uint32_t number
, int32_t digits
) {
288 UnicodeString result
;
289 appendHex(number
, digits
, result
);
293 static inline UBool
isPrintable(UChar32 c
) {
294 return c
<= 0x7E && (c
>= 0x20 || c
== 9 || c
== 0xA || c
== 0xD);
297 // Replace nonprintable characters with unicode escapes
299 IntlTest::prettify(const UnicodeString
&source
,
300 UnicodeString
&target
)
307 for (i
= 0; i
< source
.length(); )
309 UChar32 ch
= source
.char32At(i
);
312 if (!isPrintable(ch
))
316 appendHex(ch
, 4, target
);
319 appendHex(ch
, 8, target
);
333 // Replace nonprintable characters with unicode escapes
335 IntlTest::prettify(const UnicodeString
&source
, UBool parseBackslash
)
338 UnicodeString target
;
342 for (i
= 0; i
< source
.length();)
344 UChar32 ch
= source
.char32At(i
);
347 if (!isPrintable(ch
))
349 if (parseBackslash
) {
350 // If we are preceded by an odd number of backslashes,
351 // then this character has already been backslash escaped.
352 // Delete a backslash.
353 int32_t backslashCount
= 0;
354 for (int32_t j
=target
.length()-1; j
>=0; --j
) {
355 if (target
.charAt(j
) == (UChar
)92) {
361 if ((backslashCount
% 2) == 1) {
362 target
.truncate(target
.length() - 1);
367 appendHex(ch
, 4, target
);
370 appendHex(ch
, 8, target
);
384 /* IntlTest::setICU_DATA - if the ICU_DATA environment variable is not already
385 * set, try to deduce the directory in which ICU was built,
386 * and set ICU_DATA to "icu/source/data" in that location.
387 * The intent is to allow the tests to have a good chance
388 * of running without requiring that the user manually set
389 * ICU_DATA. Common data isn't a problem, since it is
390 * picked up via a static (build time) reference, but the
391 * tests dynamically load some data.
393 void IntlTest::setICU_DATA() {
394 const char *original_ICU_DATA
= getenv("ICU_DATA");
396 if (original_ICU_DATA
!= NULL
&& *original_ICU_DATA
!= 0) {
397 /* If the user set ICU_DATA, don't second-guess the person. */
401 // U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
402 // to point to the top of the build hierarchy, which may or
403 // may not be the same as the source directory, depending on
404 // the configure options used. At any rate,
405 // set the data path to the built data from this directory.
406 // The value is complete with quotes, so it can be used
407 // as-is as a string constant.
409 #if defined (U_TOPBUILDDIR)
411 static char env_string
[] = U_TOPBUILDDIR
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
412 u_setDataDirectory(env_string
);
417 // Use #else so we don't get compiler warnings due to the return above.
419 /* On Windows, the file name obtained from __FILE__ includes a full path.
420 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
421 * Change to "wherever\icu\source\data"
424 char p
[sizeof(__FILE__
) + 10];
429 /* We want to back over three '\' chars. */
430 /* Only Windows should end up here, so looking for '\' is safe. */
431 for (i
=1; i
<=3; i
++) {
432 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
433 if (pBackSlash
!= NULL
) {
434 *pBackSlash
= 0; /* Truncate the string at the '\' */
438 if (pBackSlash
!= NULL
) {
439 /* We found and truncated three names from the path.
440 * Now append "source\data" and set the environment
442 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
443 u_setDataDirectory(p
); /* p is "ICU_DATA=wherever\icu\source\data" */
447 /* __FILE__ on MSVC7 does not contain the directory */
448 u_setDataDirectory(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
454 /* No location for the data dir was identifiable.
455 * Add other fallbacks for the test data location here if the need arises
460 //--------------------------------------------------------------------------------------
462 static const int32_t indentLevel_offset
= 3;
463 static const char delim
= '/';
465 IntlTest
* IntlTest::gTest
= NULL
;
467 static int32_t execCount
= 0;
469 void it_log( UnicodeString message
)
472 IntlTest::gTest
->log( message
);
475 void it_logln( UnicodeString message
)
478 IntlTest::gTest
->logln( message
);
481 void it_logln( void )
484 IntlTest::gTest
->logln();
487 void it_info( UnicodeString message
)
490 IntlTest::gTest
->info( message
);
493 void it_infoln( UnicodeString message
)
496 IntlTest::gTest
->infoln( message
);
499 void it_infoln( void )
502 IntlTest::gTest
->infoln();
508 IntlTest::gTest
->err();
511 void it_err( UnicodeString message
)
514 IntlTest::gTest
->err( message
);
517 void it_errln( UnicodeString message
)
520 IntlTest::gTest
->errln( message
);
523 void it_dataerr( UnicodeString message
)
526 IntlTest::gTest
->dataerr( message
);
529 void it_dataerrln( UnicodeString message
)
532 IntlTest::gTest
->dataerrln( message
);
545 warn_on_missing_data
= FALSE
;
550 LL_indentlevel
= indentLevel_offset
;
552 strcpy(basePath
, "/");
556 void IntlTest::setCaller( IntlTest
* callingTest
)
558 caller
= callingTest
;
560 warn_on_missing_data
= caller
->warn_on_missing_data
;
561 verbose
= caller
->verbose
;
562 no_err_msg
= caller
->no_err_msg
;
563 quick
= caller
->quick
;
564 testoutfp
= caller
->testoutfp
;
565 LL_indentlevel
= caller
->LL_indentlevel
+ indentLevel_offset
;
566 numProps
= caller
->numProps
;
567 for (int32_t i
= 0; i
< numProps
; i
++) {
568 proplines
[i
] = caller
->proplines
[i
];
573 UBool
IntlTest::callTest( IntlTest
& testToBeCalled
, char* par
)
575 execCount
--; // correct a previously assumed test-exec, as this only calls a subtest
576 testToBeCalled
.setCaller( this );
577 strcpy(testToBeCalled
.basePath
, this->basePath
);
578 UBool result
= testToBeCalled
.runTest( testPath
, par
, testToBeCalled
.basePath
);
579 strcpy(testToBeCalled
.basePath
, this->basePath
); // reset it.
583 void IntlTest::setPath( char* pathVal
)
585 this->testPath
= pathVal
;
588 UBool
IntlTest::setVerbose( UBool verboseVal
)
590 UBool rval
= this->verbose
;
591 this->verbose
= verboseVal
;
595 UBool
IntlTest::setNotime( UBool no_time
)
597 UBool rval
= this->no_time
;
598 this->no_time
= no_time
;
602 UBool
IntlTest::setWarnOnMissingData( UBool warn_on_missing_dataVal
)
604 UBool rval
= this->warn_on_missing_data
;
605 this->warn_on_missing_data
= warn_on_missing_dataVal
;
609 UBool
IntlTest::setNoErrMsg( UBool no_err_msgVal
)
611 UBool rval
= this->no_err_msg
;
612 this->no_err_msg
= no_err_msgVal
;
616 UBool
IntlTest::setQuick( UBool quickVal
)
618 UBool rval
= this->quick
;
619 this->quick
= quickVal
;
623 UBool
IntlTest::setLeaks( UBool leaksVal
)
625 UBool rval
= this->leaks
;
626 this->leaks
= leaksVal
;
630 int32_t IntlTest::setThreadCount( int32_t count
)
632 int32_t rval
= this->threadCount
;
633 this->threadCount
= count
;
637 int32_t IntlTest::getErrors( void )
642 int32_t IntlTest::getDataErrors( void )
644 return dataErrorCount
;
647 UBool
IntlTest::runTest( char* name
, char* par
, char *baseName
)
652 char* baseNameBuffer
= NULL
;
654 if(baseName
== NULL
) {
655 baseNameBuffer
= (char*)malloc(1024);
656 baseName
=baseNameBuffer
;
657 strcpy(baseName
, "/");
661 pos
= strchr( name
, delim
); // check if name contains path (by looking for '/')
663 testPath
= pos
+1; // store subpath for calling subtest
664 *pos
= 0; // split into two strings
669 if (!name
|| (name
[0] == 0) || (strcmp(name
, "*") == 0)) {
670 rval
= runTestLoop( NULL
, par
, baseName
);
672 }else if (strcmp( name
, "LIST" ) == 0) {
677 rval
= runTestLoop( name
, par
, baseName
);
681 *pos
= delim
; // restore original value at pos
682 if(baseNameBuffer
!=NULL
) {
683 free(baseNameBuffer
);
688 // call individual tests, to be overriden to call implementations
689 void IntlTest::runIndexedTest( int32_t /*index*/, UBool
/*exec*/, const char* & /*name*/, char* /*par*/ )
691 // to be overriden by a method like:
694 case 0: name = "First Test"; if (exec) FirstTest( par ); break;
695 case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
696 default: name = ""; break;
699 this->errln("*** runIndexedTest needs to be overriden! ***");
703 UBool
IntlTest::runTestLoop( char* testname
, char* par
, char *baseName
)
708 int32_t lastErrorCount
;
710 UBool lastTestFailed
;
712 if(baseName
== NULL
) {
713 printf("ERROR: baseName can't be null.\n");
716 if ((char *)this->basePath
!= baseName
) {
717 strcpy(this->basePath
, baseName
);
721 char * saveBaseLoc
= baseName
+strlen(baseName
);
723 IntlTest
* saveTest
= gTest
;
726 this->runIndexedTest( index
, FALSE
, name
, par
);
727 if (strcmp(name
,"skip") == 0) {
728 run_this_test
= FALSE
;
730 if (!name
|| (name
[0] == 0))
733 run_this_test
= TRUE
;
735 run_this_test
= (UBool
) (strcmp( name
, testname
) == 0);
739 lastErrorCount
= errorCount
;
742 sprintf(msg
, "%s {", name
);
743 LL_message(msg
, TRUE
);
744 UDate timeStart
= uprv_getRawUTCtime();
745 strcpy(saveBaseLoc
,name
);
746 strcat(saveBaseLoc
,"/");
748 strcpy(currName
, name
); // set
749 this->runIndexedTest( index
, TRUE
, name
, par
);
750 currName
[0]=0; // reset
752 UDate timeStop
= uprv_getRawUTCtime();
753 rval
= TRUE
; // at least one test has been called
756 sprintf(secs
, "%f", (timeStop
-timeStart
)/1000.0);
762 strcpy(saveBaseLoc
,name
);
765 ctest_xml_testcase(baseName
, name
, secs
, (lastErrorCount
!=errorCount
)?"err":NULL
);
768 saveBaseLoc
[0]=0; /* reset path */
770 if (lastErrorCount
== errorCount
) {
771 sprintf( msg
, " } OK: %s ", name
);
772 if(!no_time
) str_timeDelta(msg
+strlen(msg
),timeStop
-timeStart
);
773 lastTestFailed
= FALSE
;
775 sprintf(msg
, " } ERRORS (%li) in %s", (long)(errorCount
-lastErrorCount
), name
);
776 if(!no_time
) str_timeDelta(msg
+strlen(msg
),timeStop
-timeStart
);
778 for(int i
=0;i
<LL_indentlevel
;i
++) {
783 lastTestFailed
= TRUE
;
786 if (lastTestFailed
) {
787 LL_message( "", TRUE
);
789 LL_message( msg
, TRUE
);
790 if (lastTestFailed
) {
791 LL_message( "", TRUE
);
806 * Adds given string to the log if we are in verbose mode.
808 void IntlTest::log( const UnicodeString
&message
)
811 LL_message( message
, FALSE
);
816 * Adds given string to the log if we are in verbose mode. Adds a new line to
819 void IntlTest::logln( const UnicodeString
&message
)
822 LL_message( message
, TRUE
);
826 void IntlTest::logln( void )
829 LL_message( "", TRUE
);
834 * Unconditionally adds given string to the log.
836 void IntlTest::info( const UnicodeString
&message
)
838 LL_message( message
, FALSE
);
842 * Unconditionally adds given string to the log. Adds a new line to
845 void IntlTest::infoln( const UnicodeString
&message
)
847 LL_message( message
, TRUE
);
850 void IntlTest::infoln( void )
852 LL_message( "", TRUE
);
855 int32_t IntlTest::IncErrorCount( void )
858 if (caller
) caller
->IncErrorCount();
862 int32_t IntlTest::IncDataErrorCount( void )
865 if (caller
) caller
->IncDataErrorCount();
866 return dataErrorCount
;
874 void IntlTest::err( const UnicodeString
&message
)
877 if (!no_err_msg
) LL_message( message
, FALSE
);
880 void IntlTest::errln( const UnicodeString
&message
)
883 if (!no_err_msg
) LL_message( message
, TRUE
);
886 void IntlTest::dataerr( const UnicodeString
&message
)
890 if (!warn_on_missing_data
) {
894 if (!no_err_msg
) LL_message( message
, FALSE
);
897 void IntlTest::dataerrln( const UnicodeString
&message
)
899 int32_t errCount
= IncDataErrorCount();
901 if (!warn_on_missing_data
) {
905 msg
= UnicodeString("[DATA] " + message
);
909 if ( errCount
== 1) {
910 LL_message( msg
+ " - (Are you missing data?)", TRUE
); // only show this message the first time
912 LL_message( msg
, TRUE
);
917 void IntlTest::errcheckln(UErrorCode status
, const UnicodeString
&message
) {
918 if (status
== U_FILE_ACCESS_ERROR
|| status
== U_MISSING_RESOURCE_ERROR
) {
925 /* convenience functions that include sprintf formatting */
926 void IntlTest::log(const char *fmt
, ...)
932 /* sprintf it just to make sure that the information is valid */
933 vsprintf(buffer
, fmt
, ap
);
936 log(UnicodeString(buffer
, ""));
940 void IntlTest::logln(const char *fmt
, ...)
946 /* sprintf it just to make sure that the information is valid */
947 vsprintf(buffer
, fmt
, ap
);
950 logln(UnicodeString(buffer
, ""));
954 UBool
IntlTest::logKnownIssue(const char *ticket
, const char *fmt
, ...)
960 /* sprintf it just to make sure that the information is valid */
961 vsprintf(buffer
, fmt
, ap
);
963 return logKnownIssue(ticket
, UnicodeString(buffer
, ""));
966 UBool
IntlTest::logKnownIssue(const char *ticket
) {
967 return logKnownIssue(ticket
, UnicodeString());
970 UBool
IntlTest::logKnownIssue(const char *ticket
, const UnicodeString
&msg
) {
971 if(noKnownIssues
) return FALSE
;
974 strcpy(fullpath
, basePath
);
975 strcat(fullpath
, currName
);
976 UnicodeString msg2
=msg
;
977 UBool firstForTicket
, firstForWhere
;
978 knownList
= udbg_knownIssue_openU(knownList
, ticket
, fullpath
, msg2
.getTerminatedBuffer(), &firstForTicket
, &firstForWhere
);
980 msg2
= UNICODE_STRING_SIMPLE("(Known issue #") +
981 UnicodeString(ticket
, -1, US_INV
) + UNICODE_STRING_SIMPLE(") ") + msg
;
982 if(firstForTicket
|| firstForWhere
) {
991 /* convenience functions that include sprintf formatting */
992 void IntlTest::info(const char *fmt
, ...)
998 /* sprintf it just to make sure that the information is valid */
999 vsprintf(buffer
, fmt
, ap
);
1001 info(UnicodeString(buffer
, ""));
1004 void IntlTest::infoln(const char *fmt
, ...)
1010 /* sprintf it just to make sure that the information is valid */
1011 vsprintf(buffer
, fmt
, ap
);
1013 infoln(UnicodeString(buffer
, ""));
1016 void IntlTest::err(const char *fmt
, ...)
1022 vsprintf(buffer
, fmt
, ap
);
1024 err(UnicodeString(buffer
, ""));
1027 void IntlTest::errln(const char *fmt
, ...)
1033 vsprintf(buffer
, fmt
, ap
);
1035 errln(UnicodeString(buffer
, ""));
1038 void IntlTest::dataerrln(const char *fmt
, ...)
1044 vsprintf(buffer
, fmt
, ap
);
1046 dataerrln(UnicodeString(buffer
, ""));
1049 void IntlTest::errcheckln(UErrorCode status
, const char *fmt
, ...)
1055 vsprintf(buffer
, fmt
, ap
);
1058 if (status
== U_FILE_ACCESS_ERROR
|| status
== U_MISSING_RESOURCE_ERROR
) {
1059 dataerrln(UnicodeString(buffer
, ""));
1061 errln(UnicodeString(buffer
, ""));
1065 void IntlTest::printErrors()
1067 IntlTest::LL_message(errorList
, TRUE
);
1070 UBool
IntlTest::printKnownIssues()
1072 if(knownList
!= NULL
) {
1073 udbg_knownIssue_print(knownList
);
1074 udbg_knownIssue_close(knownList
);
1081 void IntlTest::LL_message( UnicodeString message
, UBool newline
)
1083 // string that starts with a LineFeed character and continues
1084 // with spaces according to the current indentation
1085 static const UChar indentUChars
[] = {
1087 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1088 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1089 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1090 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1091 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1092 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1093 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1094 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1095 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1096 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
1098 UnicodeString
indent(FALSE
, indentUChars
, 1 + LL_indentlevel
);
1103 // stream out the indentation string first if necessary
1104 length
= indent
.extract(1, indent
.length(), buffer
, sizeof(buffer
));
1106 fwrite(buffer
, sizeof(*buffer
), length
, (FILE *)testoutfp
);
1109 // replace each LineFeed by the indentation string
1110 message
.findAndReplace(UnicodeString((UChar
)'\n'), indent
);
1112 // stream out the message
1113 length
= message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
1115 length
= length
> 30000 ? 30000 : length
;
1116 fwrite(buffer
, sizeof(*buffer
), length
, (FILE *)testoutfp
);
1120 char newLine
= '\n';
1121 fwrite(&newLine
, sizeof(newLine
), 1, (FILE *)testoutfp
);
1124 // A newline usually flushes the buffer, but
1125 // flush the message just in case of a core dump.
1126 fflush((FILE *)testoutfp
);
1130 * Print a usage message for this test class.
1132 void IntlTest::usage( void )
1134 UBool save_verbose
= setVerbose( TRUE
);
1135 logln("Test names:");
1136 logln("-----------");
1139 const char* name
= NULL
;
1141 this->runIndexedTest( index
, FALSE
, name
);
1145 }while (name
&& (name
[0] != 0));
1146 setVerbose( save_verbose
);
1150 // memory leak reporting software will be able to take advantage of the testsuite
1151 // being run a second time local to a specific method in order to report only actual leaks
1153 IntlTest::run_phase2( char* name
, char* par
) // supports reporting memory leaks
1155 UnicodeString
* strLeak
= new UnicodeString("forced leak"); // for verifying purify filter
1156 strLeak
->append(" for verifying purify filter");
1157 return this->runTest( name
, par
);
1161 #if UCONFIG_NO_LEGACY_CONVERSION
1162 # define TRY_CNV_1 "iso-8859-1"
1163 # define TRY_CNV_2 "ibm-1208"
1165 # define TRY_CNV_1 "iso-8859-7"
1166 # define TRY_CNV_2 "sjis"
1170 main(int argc
, char* argv
[])
1172 UBool syntax
= FALSE
;
1174 UBool verbose
= FALSE
;
1175 UBool no_err_msg
= FALSE
;
1176 UBool no_time
= FALSE
;
1179 UBool leaks
= FALSE
;
1181 const char *summary_file
= NULL
;
1182 UBool warnOnMissingData
= FALSE
;
1183 UBool defaultDataFound
= FALSE
;
1184 int32_t threadCount
= 1;
1185 UErrorCode errorCode
= U_ZERO_ERROR
;
1186 UConverter
*cnv
= NULL
;
1187 const char *warnOrErr
= "Failure";
1188 UDate startTime
, endTime
;
1190 const char *props
[IntlTest::kMaxProps
];
1193 U_MAIN_INIT_ARGS(argc
, argv
);
1195 startTime
= uprv_getRawUTCtime();
1197 for (int i
= 1; i
< argc
; ++i
) {
1198 if (argv
[i
][0] == '-') {
1199 const char* str
= argv
[i
] + 1;
1200 if (strcmp("verbose", str
) == 0 ||
1201 strcmp("v", str
) == 0)
1203 else if (strcmp("noerrormsg", str
) == 0 ||
1204 strcmp("n", str
) == 0)
1206 else if (strcmp("exhaustive", str
) == 0 ||
1207 strcmp("e", str
) == 0)
1209 else if (strcmp("all", str
) == 0 ||
1210 strcmp("a", str
) == 0)
1212 else if (strcmp("utf-8", str
) == 0 ||
1213 strcmp("u", str
) == 0)
1215 else if (strcmp("noknownissues", str
) == 0 ||
1216 strcmp("K", str
) == 0)
1217 noKnownIssues
= TRUE
;
1218 else if (strcmp("leaks", str
) == 0 ||
1219 strcmp("l", str
) == 0)
1221 else if (strcmp("notime", str
) == 0 ||
1222 strcmp("T", str
) == 0)
1224 else if (strncmp("E", str
, 1) == 0)
1225 summary_file
= str
+1;
1226 else if (strcmp("x", str
)==0) {
1228 printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n");
1231 if(ctest_xml_setFileName(argv
[i
])) { /* set the name */
1232 return 1; /* error */
1234 } else if (strcmp("w", str
) == 0) {
1235 warnOnMissingData
= TRUE
;
1236 warnOrErr
= "WARNING";
1238 else if (strncmp("threads:", str
, 8) == 0) {
1239 threadCount
= atoi(str
+ 8);
1241 else if (strncmp("prop:", str
, 5) == 0) {
1242 if (nProps
< IntlTest::kMaxProps
) {
1243 props
[nProps
] = str
+ 5;
1255 if (!all
&& !name
) {
1257 } else if (all
&& name
) {
1264 "### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n"
1266 "### Options are: verbose (v), all (a), noerrormsg (n), \n"
1267 "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:<propery>=<value>, \n"
1268 "### notime (T), \n"
1269 "### threads:<threadCount> (Mulithreading must first be \n"
1270 "### enabled otherwise this will be ignored. \n"
1271 "### The default thread count is 1.),\n"
1272 "### (Specify either -all (shortcut -a) or a test name). \n"
1273 "### -all will run all of the tests.\n"
1275 "### To get a list of the test names type: intltest LIST \n"
1276 "### To run just the utility tests type: intltest utility \n"
1278 "### Test names can be nested using slashes (\"testA/subtest1\") \n"
1279 "### For example to list the utility tests type: intltest utility/LIST \n"
1280 "### To run just the Locale test type: intltest utility/LocaleTest \n"
1282 "### A parameter can be specified for a test by appending '@' and the value \n"
1283 "### to the testname. \n\n");
1287 if (nProps
> IntlTest::kMaxProps
) {
1288 fprintf(stdout
, "### Too many properties. Exiting.\n");
1291 MajorTestLevel major
;
1292 major
.setVerbose( verbose
);
1293 major
.setNoErrMsg( no_err_msg
);
1294 major
.setQuick( quick
);
1295 major
.setLeaks( leaks
);
1296 major
.setThreadCount( threadCount
);
1297 major
.setWarnOnMissingData( warnOnMissingData
);
1298 major
.setNotime (no_time
);
1299 for (int32_t i
= 0; i
< nProps
; i
++) {
1300 major
.setProperty(props
[i
]);
1304 fprintf(stdout
, "-----------------------------------------------\n");
1305 fprintf(stdout
, " IntlTest (C++) Test Suite for \n");
1306 fprintf(stdout
, " International Components for Unicode %s\n", U_ICU_VERSION
);
1310 const char *charsetFamily
= "Unknown";
1311 int32_t voidSize
= (int32_t)sizeof(void*);
1312 int32_t bits
= voidSize
* 8;
1313 if(U_CHARSET_FAMILY
==U_ASCII_FAMILY
) {
1314 charsetFamily
="ASCII";
1315 } else if(U_CHARSET_FAMILY
==U_EBCDIC_FAMILY
) {
1316 charsetFamily
="EBCDIC";
1319 " Bits: %d, Byte order: %s, Chars: %s\n",
1320 bits
, U_IS_BIG_ENDIAN
?"Big endian":"Little endian",
1323 fprintf(stdout
, "-----------------------------------------------\n");
1324 fprintf(stdout
, " Options: \n");
1325 fprintf(stdout
, " all (a) : %s\n", (all
? "On" : "Off"));
1326 fprintf(stdout
, " Verbose (v) : %s\n", (verbose
? "On" : "Off"));
1327 fprintf(stdout
, " No error messages (n) : %s\n", (no_err_msg
? "On" : "Off"));
1328 fprintf(stdout
, " Exhaustive (e) : %s\n", (!quick
? "On" : "Off"));
1329 fprintf(stdout
, " Leaks (l) : %s\n", (leaks
? "On" : "Off"));
1330 fprintf(stdout
, " utf-8 (u) : %s\n", (utf8
? "On" : "Off"));
1331 fprintf(stdout
, " notime (T) : %s\n", (no_time
? "On" : "Off"));
1332 fprintf(stdout
, " noknownissues (K) : %s\n", (noKnownIssues
? "On" : "Off"));
1333 fprintf(stdout
, " Warn on missing data (w) : %s\n", (warnOnMissingData
? "On" : "Off"));
1334 #if (ICU_USE_THREADS==0)
1335 fprintf(stdout
, " Threads : Disabled\n");
1337 fprintf(stdout
, " Threads : %d\n", threadCount
);
1339 for (int32_t i
= 0; i
< nProps
; i
++) {
1340 fprintf(stdout
, " Custom property (prop:) : %s\n", props
[i
]);
1342 fprintf(stdout
, "-----------------------------------------------\n");
1345 ucnv_setDefaultName("utf-8");
1347 /* Check whether ICU will initialize without forcing the build data directory into
1348 * the ICU_DATA path. Success here means either the data dll contains data, or that
1349 * this test program was run with ICU_DATA set externally. Failure of this check
1350 * is normal when ICU data is not packaged into a shared library.
1352 * Whether or not this test succeeds, we want to cleanup and reinitialize
1353 * with a data path so that data loading from individual files can be tested.
1356 if (U_FAILURE(errorCode
)) {
1358 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
1359 defaultDataFound
= FALSE
;
1362 defaultDataFound
= TRUE
;
1366 ucnv_setDefaultName("utf-8");
1368 errorCode
= U_ZERO_ERROR
;
1370 /* Initialize ICU */
1371 if (!defaultDataFound
) {
1372 IntlTest::setICU_DATA(); // Must set data directory before u_init() is called.
1375 if (U_FAILURE(errorCode
)) {
1377 "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
1378 "*** Check the ICU_DATA environment variable and \n"
1379 "*** check that the data files are present.\n", argv
[0], u_errorName(errorCode
));
1380 if(warnOnMissingData
== 0) {
1381 fprintf(stderr
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1387 // initial check for the default converter
1388 errorCode
= U_ZERO_ERROR
;
1389 cnv
= ucnv_open(0, &errorCode
);
1395 "*** %s! The default converter [%s] cannot be opened.\n"
1396 "*** Check the ICU_DATA environment variable and\n"
1397 "*** check that the data files are present.\n",
1398 warnOrErr
, ucnv_getDefaultName());
1399 if(!warnOnMissingData
) {
1400 fprintf(stdout
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1406 cnv
= ucnv_open(TRY_CNV_2
, &errorCode
);
1412 "*** %s! The converter for " TRY_CNV_2
" cannot be opened.\n"
1413 "*** Check the ICU_DATA environment variable and \n"
1414 "*** check that the data files are present.\n", warnOrErr
);
1415 if(!warnOnMissingData
) {
1416 fprintf(stdout
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1421 UResourceBundle
*rb
= ures_open(0, "en", &errorCode
);
1423 if(U_FAILURE(errorCode
)) {
1425 "*** %s! The \"en\" locale resource bundle cannot be opened.\n"
1426 "*** Check the ICU_DATA environment variable and \n"
1427 "*** check that the data files are present.\n", warnOrErr
);
1428 if(!warnOnMissingData
) {
1429 fprintf(stdout
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1434 Locale originalLocale
; // Save the default locale for comparison later on.
1436 if(ctest_xml_init("intltest"))
1440 /* TODO: Add option to call u_cleanup and rerun tests. */
1444 major
.run_phase2( NULL
, NULL
);
1447 for (int i
= 1; i
< argc
; ++i
) {
1448 if (argv
[i
][0] != '-') {
1449 char* name
= argv
[i
];
1450 fprintf(stdout
, "\n=== Handling test: %s: ===\n", name
);
1452 char baseName
[1024];
1453 sprintf(baseName
, "/%s/", name
);
1455 char* parameter
= strchr( name
, '@' );
1461 UBool res
= major
.runTest( name
, parameter
, baseName
);
1463 major
.run_phase2( name
, parameter
);
1465 if (!res
|| (execCount
<= 0)) {
1466 fprintf(stdout
, "\n---ERROR: Test doesn't exist: %s!\n", name
);
1468 } else if(!strcmp(argv
[i
],"-x")) {
1475 #if !UCONFIG_NO_FORMATTING
1476 CalendarTimeZoneTest::cleanup();
1479 free(_testDataPath
);
1482 Locale lastDefaultLocale
;
1483 if (originalLocale
!= lastDefaultLocale
) {
1484 major
.errln("FAILURE: A test changed the default locale without resetting it.");
1487 fprintf(stdout
, "\n--------------------------------------\n");
1488 if( major
.printKnownIssues() ) {
1489 fprintf(stdout
, " To run suppressed tests, use the -K option. \n");
1491 if (major
.getErrors() == 0) {
1492 /* Call it twice to make sure that the defaults were reset. */
1493 /* Call it before the OK message to verify proper cleanup. */
1497 fprintf(stdout
, "OK: All tests passed without error.\n");
1499 if (major
.getDataErrors() != 0) {
1500 fprintf(stdout
, "\t*WARNING* some data-loading errors were ignored by the -w option.\n");
1503 fprintf(stdout
, "Errors in total: %ld.\n", (long)major
.getErrors());
1504 major
.printErrors();
1506 if(summary_file
!= NULL
) {
1507 FILE *summf
= fopen(summary_file
, "w");
1508 if( summf
!= NULL
) {
1510 int32_t length
= errorList
.extract(0, errorList
.length(), buf
, sizeof(buf
));
1511 fwrite(buf
, sizeof(*buf
), length
, (FILE*)summf
);
1517 if (major
.getDataErrors() != 0) {
1518 fprintf(stdout
, "\t*Note* some errors are data-loading related. If the data used is not the \n"
1519 "\tstock ICU data (i.e some have been added or removed), consider using\n"
1520 "\tthe '-w' option to turn these errors into warnings.\n");
1523 /* Call afterwards to display errors. */
1527 fprintf(stdout
, "--------------------------------------\n");
1529 if (execCount
<= 0) {
1530 fprintf(stdout
, "***** Not all called tests actually exist! *****\n");
1533 endTime
= uprv_getRawUTCtime();
1534 diffTime
= (int32_t)(endTime
- startTime
);
1535 printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
1536 (int)((diffTime%U_MILLIS_PER_DAY
)/U_MILLIS_PER_HOUR
),
1537 (int)((diffTime%U_MILLIS_PER_HOUR
)/U_MILLIS_PER_MINUTE
),
1538 (int)((diffTime%U_MILLIS_PER_MINUTE
)/U_MILLIS_PER_SECOND
),
1539 (int)(diffTime%U_MILLIS_PER_SECOND
));
1542 if(ctest_xml_fini())
1545 return major
.getErrors();
1548 const char* IntlTest::loadTestData(UErrorCode
& err
){
1549 if( _testDataPath
== NULL
){
1550 const char* directory
=NULL
;
1551 UResourceBundle
* test
=NULL
;
1553 const char* tdrelativepath
;
1555 #if defined (U_TOPBUILDDIR)
1556 tdrelativepath
= "test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
1557 directory
= U_TOPBUILDDIR
;
1559 tdrelativepath
= ".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
1560 directory
= pathToDataDirectory();
1563 tdpath
= (char*) malloc(sizeof(char) *(( strlen(directory
) * strlen(tdrelativepath
)) + 100));
1566 /* u_getDataDirectory shoul return \source\data ... set the
1567 * directory to ..\source\data\..\test\testdata\out\testdata
1569 strcpy(tdpath
, directory
);
1570 strcat(tdpath
, tdrelativepath
);
1571 strcat(tdpath
,"testdata");
1573 test
=ures_open(tdpath
, "testtypes", &err
);
1576 err
= U_FILE_ACCESS_ERROR
;
1577 it_dataerrln((UnicodeString
)"Could not load testtypes.res in testdata bundle with path " + tdpath
+ (UnicodeString
)" - " + u_errorName(err
));
1581 _testDataPath
= tdpath
;
1582 return _testDataPath
;
1584 return _testDataPath
;
1587 const char* IntlTest::getTestDataPath(UErrorCode
& err
) {
1588 return loadTestData(err
);
1591 /* Returns the path to icu/source/test/testdata/ */
1592 const char *IntlTest::getSourceTestData(UErrorCode
& /*err*/) {
1593 const char *srcDataDir
= NULL
;
1595 srcDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
;
1597 srcDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
;
1598 FILE *f
= fopen(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"rbbitst.txt", "r");
1600 /* We're in icu/source/test/intltest/ */
1604 /* We're in icu/source/test/intltest/Platform/(Debug|Release) */
1605 srcDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
1606 "test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
;
1612 char *IntlTest::getUnidataPath(char path
[]) {
1613 const int kUnicodeDataTxtLength
= 15; // strlen("UnicodeData.txt")
1615 // Look inside ICU_DATA first.
1616 strcpy(path
, pathToDataDirectory());
1617 strcat(path
, "unidata" U_FILE_SEP_STRING
"UnicodeData.txt");
1618 FILE *f
= fopen(path
, "r");
1621 *(strchr(path
, 0) - kUnicodeDataTxtLength
) = 0; // Remove the basename.
1625 // As a fallback, try to guess where the source data was located
1626 // at the time ICU was built, and look there.
1628 strcpy(path
, U_TOPSRCDIR U_FILE_SEP_STRING
"data");
1630 UErrorCode errorCode
= U_ZERO_ERROR
;
1631 const char *testDataPath
= loadTestData(errorCode
);
1632 if(U_FAILURE(errorCode
)) {
1633 it_errln(UnicodeString(
1634 "unable to find path to source/data/unidata/ and loadTestData() failed: ") +
1635 u_errorName(errorCode
));
1638 strcpy(path
, testDataPath
);
1639 strcat(path
, U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".."
1640 U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".."
1641 U_FILE_SEP_STRING
"data");
1643 strcat(path
, U_FILE_SEP_STRING
);
1644 strcat(path
, "unidata" U_FILE_SEP_STRING
"UnicodeData.txt");
1645 f
= fopen(path
, "r");
1648 *(strchr(path
, 0) - kUnicodeDataTxtLength
) = 0; // Remove the basename.
1654 const char* IntlTest::fgDataDir
= NULL
;
1656 /* returns the path to icu/source/data */
1657 const char * IntlTest::pathToDataDirectory()
1660 if(fgDataDir
!= NULL
) {
1664 /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
1665 // to point to the top of the build hierarchy, which may or
1666 // may not be the same as the source directory, depending on
1667 // the configure options used. At any rate,
1668 // set the data path to the built data from this directory.
1669 // The value is complete with quotes, so it can be used
1670 // as-is as a string constant.
1672 #if defined (U_TOPSRCDIR)
1674 fgDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
1678 /* On Windows, the file name obtained from __FILE__ includes a full path.
1679 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
1680 * Change to "wherever\icu\source\data"
1683 static char p
[sizeof(__FILE__
) + 10];
1687 strcpy(p
, __FILE__
);
1688 /* We want to back over three '\' chars. */
1689 /* Only Windows should end up here, so looking for '\' is safe. */
1690 for (i
=1; i
<=3; i
++) {
1691 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
1692 if (pBackSlash
!= NULL
) {
1693 *pBackSlash
= 0; /* Truncate the string at the '\' */
1697 if (pBackSlash
!= NULL
) {
1698 /* We found and truncated three names from the path.
1699 * Now append "source\data" and set the environment
1701 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
);
1705 /* __FILE__ on MSVC7 does not contain the directory */
1706 FILE *file
= fopen(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
1709 fgDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
1712 fgDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
1723 * This is a variant of cintltst/ccolltst.c:CharsToUChars().
1724 * It converts an invariant-character string into a UnicodeString, with
1725 * unescaping \u sequences.
1727 UnicodeString
CharsToUnicodeString(const char* chars
){
1728 return UnicodeString(chars
, -1, US_INV
).unescape();
1731 UnicodeString
ctou(const char* chars
) {
1732 return CharsToUnicodeString(chars
);
1735 #define RAND_M (714025)
1736 #define RAND_IA (1366)
1737 #define RAND_IC (150889)
1739 static int32_t RAND_SEED
;
1742 * Returns a uniform random value x, with 0.0 <= x < 1.0. Use
1743 * with care: Does not return all possible values; returns one of
1744 * 714,025 values, uniformly spaced. However, the period is
1745 * effectively infinite. See: Numerical Recipes, section 7.1.
1747 * @param seedp pointer to seed. Set *seedp to any negative value
1748 * to restart the sequence.
1750 float IntlTest::random(int32_t* seedp
) {
1751 static int32_t iy
, ir
[98];
1752 static UBool first
=TRUE
;
1754 if (*seedp
< 0 || first
) {
1756 if ((*seedp
=(RAND_IC
-(*seedp
)) % RAND_M
) < 0) *seedp
= -(*seedp
);
1757 for (j
=1;j
<=97;++j
) {
1758 *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
;
1761 *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
;
1764 j
=(int32_t)(1 + 97.0*iy
/RAND_M
);
1765 U_ASSERT(j
>=1 && j
<=97);
1767 *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
;
1769 return (float) iy
/RAND_M
;
1773 * Convenience method using a global seed.
1775 float IntlTest::random() {
1776 return random(&RAND_SEED
);
1779 static inline UChar
toHex(int32_t i
) {
1780 return (UChar
)(i
+ (i
< 10 ? 0x30 : (0x41 - 10)));
1783 static UnicodeString
& escape(const UnicodeString
& s
, UnicodeString
& result
) {
1784 for (int32_t i
=0; i
<s
.length(); ++i
) {
1786 if (c
<= (UChar
)0x7F) {
1789 result
+= (UChar
)0x5c;
1790 result
+= (UChar
)0x75;
1791 result
+= toHex((c
>> 12) & 0xF);
1792 result
+= toHex((c
>> 8) & 0xF);
1793 result
+= toHex((c
>> 4) & 0xF);
1794 result
+= toHex( c
& 0xF);
1800 #define VERBOSE_ASSERTIONS
1802 UBool
IntlTest::assertTrue(const char* message
, UBool condition
, UBool quiet
, UBool possibleDataError
, const char *file
, int line
) {
1805 if (possibleDataError
) {
1806 dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file
, line
, message
);
1808 errln("%s:%d: FAIL: assertTrue() failed: %s", file
, line
, message
);
1810 } else if (!quiet
) {
1811 logln("%s:%d: Ok: %s", file
, line
, message
);
1815 if (possibleDataError
) {
1816 dataerrln("FAIL: assertTrue() failed: %s", message
);
1818 errln("FAIL: assertTrue() failed: %s", message
);
1820 } else if (!quiet
) {
1821 logln("Ok: %s", message
);
1828 UBool
IntlTest::assertFalse(const char* message
, UBool condition
, UBool quiet
) {
1830 errln("FAIL: assertFalse() failed: %s", message
);
1831 } else if (!quiet
) {
1832 logln("Ok: %s", message
);
1837 UBool
IntlTest::assertSuccess(const char* message
, UErrorCode ec
, UBool possibleDataError
, const char *file
, int line
) {
1839 file
= ""; // prevent failure if no file given
1841 if (U_FAILURE(ec
)) {
1842 if (possibleDataError
) {
1843 dataerrln("FAIL: %s:%d: %s (%s)", file
, line
, message
, u_errorName(ec
));
1845 errcheckln(ec
, "FAIL: %s:%d: %s (%s)", file
, line
, message
, u_errorName(ec
));
1849 logln("OK: %s:%d: %s - (%s)", file
, line
, message
, u_errorName(ec
));
1854 UBool
IntlTest::assertEquals(const char* message
,
1855 const UnicodeString
& expected
,
1856 const UnicodeString
& actual
,
1857 UBool possibleDataError
) {
1858 if (expected
!= actual
) {
1859 if (possibleDataError
) {
1860 dataerrln((UnicodeString
)"FAIL: " + message
+ "; got " +
1862 "; expected " + prettify(expected
));
1864 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
1866 "; expected " + prettify(expected
));
1870 #ifdef VERBOSE_ASSERTIONS
1872 logln((UnicodeString
)"Ok: " + message
+ "; got " + prettify(actual
));
1878 UBool
IntlTest::assertEquals(const char* message
,
1879 const char* expected
,
1880 const char* actual
) {
1881 if (uprv_strcmp(expected
, actual
) != 0) {
1882 errln((UnicodeString
)"FAIL: " + message
+ "; got \"" +
1884 "\"; expected \"" + expected
+ "\"");
1887 #ifdef VERBOSE_ASSERTIONS
1889 logln((UnicodeString
)"Ok: " + message
+ "; got \"" + actual
+ "\"");
1895 UBool
IntlTest::assertEquals(const char* message
,
1898 if (expected
!= actual
) {
1899 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
1900 actual
+ "=0x" + toHex(actual
) +
1901 "; expected " + expected
+ "=0x" + toHex(expected
));
1904 #ifdef VERBOSE_ASSERTIONS
1906 logln((UnicodeString
)"Ok: " + message
+ "; got " + actual
+ "=0x" + toHex(actual
));
1912 UBool
IntlTest::assertEquals(const char* message
,
1915 if (expected
!= actual
) {
1916 errln((UnicodeString
)"FAIL: " + message
+ "; got int64 " +
1917 Int64ToUnicodeString(actual
) +
1918 "; expected " + Int64ToUnicodeString(expected
) );
1921 #ifdef VERBOSE_ASSERTIONS
1923 logln((UnicodeString
)"Ok: " + message
+ "; got int64 " + Int64ToUnicodeString(actual
));
1929 UBool
IntlTest::assertEquals(const char* message
,
1932 if (expected
!= actual
) {
1933 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
1935 "; expected " + toString(expected
));
1938 #ifdef VERBOSE_ASSERTIONS
1940 logln((UnicodeString
)"Ok: " + message
+ "; got " + toString(actual
));
1946 #if !UCONFIG_NO_FORMATTING
1947 UBool
IntlTest::assertEquals(const char* message
,
1948 const Formattable
& expected
,
1949 const Formattable
& actual
,
1950 UBool possibleDataError
) {
1951 if (expected
!= actual
) {
1952 if (possibleDataError
) {
1953 dataerrln((UnicodeString
)"FAIL: " + message
+ "; got " +
1955 "; expected " + toString(expected
));
1957 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
1959 "; expected " + toString(expected
));
1963 #ifdef VERBOSE_ASSERTIONS
1965 logln((UnicodeString
)"Ok: " + message
+ "; got " + toString(actual
));
1972 static char ASSERT_BUF
[256];
1974 static const char* extractToAssertBuf(const UnicodeString
& message
) {
1976 escape(message
, buf
);
1977 buf
.extract(0, 0x7FFFFFFF, ASSERT_BUF
, sizeof(ASSERT_BUF
)-1, 0);
1978 ASSERT_BUF
[sizeof(ASSERT_BUF
)-1] = 0;
1982 UBool
IntlTest::assertTrue(const UnicodeString
& message
, UBool condition
, UBool quiet
) {
1983 return assertTrue(extractToAssertBuf(message
), condition
, quiet
);
1986 UBool
IntlTest::assertFalse(const UnicodeString
& message
, UBool condition
, UBool quiet
) {
1987 return assertFalse(extractToAssertBuf(message
), condition
, quiet
);
1990 UBool
IntlTest::assertSuccess(const UnicodeString
& message
, UErrorCode ec
) {
1991 return assertSuccess(extractToAssertBuf(message
), ec
);
1994 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
1995 const UnicodeString
& expected
,
1996 const UnicodeString
& actual
,
1997 UBool possibleDataError
) {
1998 return assertEquals(extractToAssertBuf(message
), expected
, actual
, possibleDataError
);
2001 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2002 const char* expected
,
2003 const char* actual
) {
2004 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2006 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2009 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2011 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2014 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2016 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2019 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2022 #if !UCONFIG_NO_FORMATTING
2023 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
2024 const Formattable
& expected
,
2025 const Formattable
& actual
) {
2026 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
2030 void IntlTest::setProperty(const char* propline
) {
2031 if (numProps
< kMaxProps
) {
2032 proplines
[numProps
] = propline
;
2037 const char* IntlTest::getProperty(const char* prop
) {
2038 const char* val
= NULL
;
2039 for (int32_t i
= 0; i
< numProps
; i
++) {
2040 int32_t plen
= uprv_strlen(prop
);
2041 if ((int32_t)uprv_strlen(proplines
[i
]) > plen
+ 1
2042 && proplines
[i
][plen
] == '='
2043 && uprv_strncmp(proplines
[i
], prop
, plen
) == 0) {
2044 val
= &(proplines
[i
][plen
+1]);
2052 * Hey, Emacs, please set the following:
2055 * indent-tabs-mode: nil