1 /********************************************************************
3 * Copyright (c) 1997-2013, 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
48 static char* _testDataPath
=NULL
;
50 // Static list of errors found
51 static UnicodeString errorList
;
53 //-----------------------------------------------------------------------------
54 //convenience classes to ease porting code that uses the Java
55 //string-concatenation operator (moved from findword test by rtg)
57 // [LIU] Just to get things working
59 UCharToUnicodeString(UChar c
)
60 { return UnicodeString(c
); }
62 // [rtg] Just to get things working
64 operator+(const UnicodeString
& left
,
67 char buffer
[64]; // nos changed from 10 to 64
68 char danger
= 'p'; // guard against overrunning the buffer (rtg)
70 sprintf(buffer
, "%ld", num
);
71 assert(danger
== 'p');
77 operator+(const UnicodeString
& left
,
80 char buffer
[64]; // nos changed from 10 to 64
81 char danger
= 'p'; // guard against overrunning the buffer (rtg)
83 sprintf(buffer
, "%lu", num
);
84 assert(danger
== 'p');
90 Int64ToUnicodeString(int64_t num
)
92 char buffer
[64]; // nos changed from 10 to 64
93 char danger
= 'p'; // guard against overrunning the buffer (rtg)
96 sprintf(buffer
, "%I64d", num
);
98 sprintf(buffer
, "%lld", (long long)num
);
100 assert(danger
== 'p');
105 // [LIU] Just to get things working
107 operator+(const UnicodeString
& left
,
110 char buffer
[64]; // was 32, made it arbitrarily bigger (rtg)
111 char danger
= 'p'; // guard against overrunning the buffer (rtg)
113 // IEEE floating point has 52 bits of mantissa, plus one assumed bit
114 // 53*log(2)/log(10) = 15.95
115 // so there is no need to show more than 16 digits. [alan]
117 sprintf(buffer
, "%.17g", num
);
118 assert(danger
== 'p');
120 return left
+ buffer
;
123 #if !UCONFIG_NO_FORMATTING
126 * Return a string display for this, without surrounding braces.
128 UnicodeString
_toString(const Formattable
& f
) {
130 switch (f
.getType()) {
131 case Formattable::kDate
:
133 UErrorCode status
= U_ZERO_ERROR
;
134 SimpleDateFormat
fmt(status
);
135 if (U_SUCCESS(status
)) {
137 fmt
.format(f
.getDate(), s
, pos
);
138 s
.insert(0, "Date:");
140 s
= UnicodeString("Error creating date format]");
144 case Formattable::kDouble
:
145 s
= UnicodeString("double:") + f
.getDouble();
147 case Formattable::kLong
:
148 s
= UnicodeString("long:") + f
.getLong();
151 case Formattable::kInt64
:
152 s
= UnicodeString("int64:") + Int64ToUnicodeString(f
.getInt64());
155 case Formattable::kString
:
157 s
.insert(0, "String:");
159 case Formattable::kArray
:
162 const Formattable
* array
= f
.getArray(n
);
163 s
.insert(0, UnicodeString("Array:"));
164 UnicodeString
delim(", ");
165 for (i
=0; i
<n
; ++i
) {
169 s
= s
+ _toString(array
[i
]);
173 case Formattable::kObject
: {
174 const CurrencyAmount
* c
= dynamic_cast<const CurrencyAmount
*>(f
.getObject());
176 s
= _toString(c
->getNumber()) + " " + UnicodeString(c
->getISOCurrency());
178 s
= UnicodeString("Unknown UObject");
183 s
= UnicodeString("Unknown Formattable type=") + (int32_t)f
.getType();
190 * Originally coded this as operator+, but that makes the expression
191 * + char* ambiguous. - liu
193 UnicodeString
toString(const Formattable
& f
) {
194 UnicodeString
s((UChar
)91/*[*/);
195 s
.append(_toString(f
));
196 s
.append((UChar
)0x5d/*]*/);
202 // useful when operator+ won't cooperate
203 UnicodeString
toString(int32_t n
) {
204 return UnicodeString() + (long)n
;
207 // stephen - cleaned up 05/05/99
208 UnicodeString
operator+(const UnicodeString
& left
, char num
)
209 { return left
+ (long)num
; }
210 UnicodeString
operator+(const UnicodeString
& left
, short num
)
211 { return left
+ (long)num
; }
212 UnicodeString
operator+(const UnicodeString
& left
, int num
)
213 { return left
+ (long)num
; }
214 UnicodeString
operator+(const UnicodeString
& left
, unsigned char num
)
215 { return left
+ (unsigned long)num
; }
216 UnicodeString
operator+(const UnicodeString
& left
, unsigned short num
)
217 { return left
+ (unsigned long)num
; }
218 UnicodeString
operator+(const UnicodeString
& left
, unsigned int num
)
219 { return left
+ (unsigned long)num
; }
220 UnicodeString
operator+(const UnicodeString
& left
, float num
)
221 { return left
+ (double)num
; }
225 // Append a hex string to the target
227 IntlTest::appendHex(uint32_t number
,
229 UnicodeString
& target
)
231 static const UChar digitString
[] = {
232 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
233 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0
234 }; /* "0123456789ABCDEF" */
236 if (digits
< 0) { // auto-digits
239 while (number
> max
) {
241 max
= (max
<< 8) | 0xff;
247 target
+= digitString
[(number
>> 28) & 0xF];
249 target
+= digitString
[(number
>> 24) & 0xF];
251 target
+= digitString
[(number
>> 20) & 0xF];
253 target
+= digitString
[(number
>> 16) & 0xF];
255 target
+= digitString
[(number
>> 12) & 0xF];
257 target
+= digitString
[(number
>> 8) & 0xF];
259 target
+= digitString
[(number
>> 4) & 0xF];
261 target
+= digitString
[(number
>> 0) & 0xF];
270 IntlTest::toHex(uint32_t number
, int32_t digits
) {
271 UnicodeString result
;
272 appendHex(number
, digits
, result
);
276 static inline UBool
isPrintable(UChar32 c
) {
277 return c
<= 0x7E && (c
>= 0x20 || c
== 9 || c
== 0xA || c
== 0xD);
280 // Replace nonprintable characters with unicode escapes
282 IntlTest::prettify(const UnicodeString
&source
,
283 UnicodeString
&target
)
290 for (i
= 0; i
< source
.length(); )
292 UChar32 ch
= source
.char32At(i
);
295 if (!isPrintable(ch
))
299 appendHex(ch
, 4, target
);
302 appendHex(ch
, 8, target
);
316 // Replace nonprintable characters with unicode escapes
318 IntlTest::prettify(const UnicodeString
&source
, UBool parseBackslash
)
321 UnicodeString target
;
325 for (i
= 0; i
< source
.length();)
327 UChar32 ch
= source
.char32At(i
);
330 if (!isPrintable(ch
))
332 if (parseBackslash
) {
333 // If we are preceded by an odd number of backslashes,
334 // then this character has already been backslash escaped.
335 // Delete a backslash.
336 int32_t backslashCount
= 0;
337 for (int32_t j
=target
.length()-1; j
>=0; --j
) {
338 if (target
.charAt(j
) == (UChar
)92) {
344 if ((backslashCount
% 2) == 1) {
345 target
.truncate(target
.length() - 1);
350 appendHex(ch
, 4, target
);
353 appendHex(ch
, 8, target
);
367 /* IntlTest::setICU_DATA - if the ICU_DATA environment variable is not already
368 * set, try to deduce the directory in which ICU was built,
369 * and set ICU_DATA to "icu/source/data" in that location.
370 * The intent is to allow the tests to have a good chance
371 * of running without requiring that the user manually set
372 * ICU_DATA. Common data isn't a problem, since it is
373 * picked up via a static (build time) reference, but the
374 * tests dynamically load some data.
376 void IntlTest::setICU_DATA() {
377 const char *original_ICU_DATA
= getenv("ICU_DATA");
379 if (original_ICU_DATA
!= NULL
&& *original_ICU_DATA
!= 0) {
380 /* If the user set ICU_DATA, don't second-guess the person. */
384 // U_TOPBUILDDIR is set by the makefiles on UNIXes when building cintltst and intltst
385 // to point to the top of the build hierarchy, which may or
386 // may not be the same as the source directory, depending on
387 // the configure options used. At any rate,
388 // set the data path to the built data from this directory.
389 // The value is complete with quotes, so it can be used
390 // as-is as a string constant.
392 #if defined (U_TOPBUILDDIR)
394 static char env_string
[] = U_TOPBUILDDIR
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
395 u_setDataDirectory(env_string
);
400 // Use #else so we don't get compiler warnings due to the return above.
402 /* On Windows, the file name obtained from __FILE__ includes a full path.
403 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
404 * Change to "wherever\icu\source\data"
407 char p
[sizeof(__FILE__
) + 10];
412 /* We want to back over three '\' chars. */
413 /* Only Windows should end up here, so looking for '\' is safe. */
414 for (i
=1; i
<=3; i
++) {
415 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
416 if (pBackSlash
!= NULL
) {
417 *pBackSlash
= 0; /* Truncate the string at the '\' */
421 if (pBackSlash
!= NULL
) {
422 /* We found and truncated three names from the path.
423 * Now append "source\data" and set the environment
425 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
426 u_setDataDirectory(p
); /* p is "ICU_DATA=wherever\icu\source\data" */
430 /* __FILE__ on MSVC7 does not contain the directory */
431 u_setDataDirectory(".."U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
);
437 /* No location for the data dir was identifiable.
438 * Add other fallbacks for the test data location here if the need arises
443 //--------------------------------------------------------------------------------------
445 static const int32_t indentLevel_offset
= 3;
446 static const char delim
= '/';
448 IntlTest
* IntlTest::gTest
= NULL
;
450 static int32_t execCount
= 0;
452 void it_log( UnicodeString message
)
455 IntlTest::gTest
->log( message
);
458 void it_logln( UnicodeString message
)
461 IntlTest::gTest
->logln( message
);
464 void it_logln( void )
467 IntlTest::gTest
->logln();
470 void it_info( UnicodeString message
)
473 IntlTest::gTest
->info( message
);
476 void it_infoln( UnicodeString message
)
479 IntlTest::gTest
->infoln( message
);
482 void it_infoln( void )
485 IntlTest::gTest
->infoln();
491 IntlTest::gTest
->err();
494 void it_err( UnicodeString message
)
497 IntlTest::gTest
->err( message
);
500 void it_errln( UnicodeString message
)
503 IntlTest::gTest
->errln( message
);
506 void it_dataerr( UnicodeString message
)
509 IntlTest::gTest
->dataerr( message
);
512 void it_dataerrln( UnicodeString message
)
515 IntlTest::gTest
->dataerrln( message
);
528 warn_on_missing_data
= FALSE
;
533 LL_indentlevel
= indentLevel_offset
;
535 strcpy(basePath
, "/");
538 void IntlTest::setCaller( IntlTest
* callingTest
)
540 caller
= callingTest
;
542 warn_on_missing_data
= caller
->warn_on_missing_data
;
543 verbose
= caller
->verbose
;
544 no_err_msg
= caller
->no_err_msg
;
545 quick
= caller
->quick
;
546 testoutfp
= caller
->testoutfp
;
547 LL_indentlevel
= caller
->LL_indentlevel
+ indentLevel_offset
;
548 numProps
= caller
->numProps
;
549 for (int32_t i
= 0; i
< numProps
; i
++) {
550 proplines
[i
] = caller
->proplines
[i
];
555 UBool
IntlTest::callTest( IntlTest
& testToBeCalled
, char* par
)
557 execCount
--; // correct a previously assumed test-exec, as this only calls a subtest
558 testToBeCalled
.setCaller( this );
559 strcpy(testToBeCalled
.basePath
, this->basePath
);
560 UBool result
= testToBeCalled
.runTest( testPath
, par
, testToBeCalled
.basePath
);
561 strcpy(testToBeCalled
.basePath
, this->basePath
); // reset it.
565 void IntlTest::setPath( char* pathVal
)
567 this->testPath
= pathVal
;
570 UBool
IntlTest::setVerbose( UBool verboseVal
)
572 UBool rval
= this->verbose
;
573 this->verbose
= verboseVal
;
577 UBool
IntlTest::setNotime( UBool no_time
)
579 UBool rval
= this->no_time
;
580 this->no_time
= no_time
;
584 UBool
IntlTest::setWarnOnMissingData( UBool warn_on_missing_dataVal
)
586 UBool rval
= this->warn_on_missing_data
;
587 this->warn_on_missing_data
= warn_on_missing_dataVal
;
591 UBool
IntlTest::setNoErrMsg( UBool no_err_msgVal
)
593 UBool rval
= this->no_err_msg
;
594 this->no_err_msg
= no_err_msgVal
;
598 UBool
IntlTest::setQuick( UBool quickVal
)
600 UBool rval
= this->quick
;
601 this->quick
= quickVal
;
605 UBool
IntlTest::setLeaks( UBool leaksVal
)
607 UBool rval
= this->leaks
;
608 this->leaks
= leaksVal
;
612 int32_t IntlTest::setThreadCount( int32_t count
)
614 int32_t rval
= this->threadCount
;
615 this->threadCount
= count
;
619 int32_t IntlTest::getErrors( void )
624 int32_t IntlTest::getDataErrors( void )
626 return dataErrorCount
;
629 UBool
IntlTest::runTest( char* name
, char* par
, char *baseName
)
634 char* baseNameBuffer
= NULL
;
636 if(baseName
== NULL
) {
637 baseNameBuffer
= (char*)malloc(1024);
638 baseName
=baseNameBuffer
;
639 strcpy(baseName
, "/");
643 pos
= strchr( name
, delim
); // check if name contains path (by looking for '/')
645 testPath
= pos
+1; // store subpath for calling subtest
646 *pos
= 0; // split into two strings
651 if (!name
|| (name
[0] == 0) || (strcmp(name
, "*") == 0)) {
652 rval
= runTestLoop( NULL
, par
, baseName
);
654 }else if (strcmp( name
, "LIST" ) == 0) {
659 rval
= runTestLoop( name
, par
, baseName
);
663 *pos
= delim
; // restore original value at pos
664 if(baseNameBuffer
!=NULL
) {
665 free(baseNameBuffer
);
670 // call individual tests, to be overriden to call implementations
671 void IntlTest::runIndexedTest( int32_t /*index*/, UBool
/*exec*/, const char* & /*name*/, char* /*par*/ )
673 // to be overriden by a method like:
676 case 0: name = "First Test"; if (exec) FirstTest( par ); break;
677 case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
678 default: name = ""; break;
681 this->errln("*** runIndexedTest needs to be overriden! ***");
685 UBool
IntlTest::runTestLoop( char* testname
, char* par
, char *baseName
)
690 int32_t lastErrorCount
;
692 UBool lastTestFailed
;
694 if(baseName
== NULL
) {
695 printf("ERROR: baseName can't be null.\n");
698 if ((char *)this->basePath
!= baseName
) {
699 strcpy(this->basePath
, baseName
);
703 char * saveBaseLoc
= baseName
+strlen(baseName
);
705 IntlTest
* saveTest
= gTest
;
708 this->runIndexedTest( index
, FALSE
, name
, par
);
709 if (strcmp(name
,"skip") == 0) {
710 run_this_test
= FALSE
;
712 if (!name
|| (name
[0] == 0))
715 run_this_test
= TRUE
;
717 run_this_test
= (UBool
) (strcmp( name
, testname
) == 0);
721 lastErrorCount
= errorCount
;
724 sprintf(msg
, "%s {", name
);
725 LL_message(msg
, TRUE
);
726 UDate timeStart
= uprv_getRawUTCtime();
727 strcpy(saveBaseLoc
,name
);
728 strcat(saveBaseLoc
,"/");
730 this->runIndexedTest( index
, TRUE
, name
, par
);
732 UDate timeStop
= uprv_getRawUTCtime();
733 rval
= TRUE
; // at least one test has been called
736 sprintf(secs
, "%f", (timeStop
-timeStart
)/1000.0);
742 strcpy(saveBaseLoc
,name
);
745 ctest_xml_testcase(baseName
, name
, secs
, (lastErrorCount
!=errorCount
)?"err":NULL
);
748 saveBaseLoc
[0]=0; /* reset path */
750 if (lastErrorCount
== errorCount
) {
751 sprintf( msg
, " } OK: %s ", name
);
752 if(!no_time
) str_timeDelta(msg
+strlen(msg
),timeStop
-timeStart
);
753 lastTestFailed
= FALSE
;
755 sprintf(msg
, " } ERRORS (%li) in %s", (long)(errorCount
-lastErrorCount
), name
);
756 if(!no_time
) str_timeDelta(msg
+strlen(msg
),timeStop
-timeStart
);
758 for(int i
=0;i
<LL_indentlevel
;i
++) {
763 lastTestFailed
= TRUE
;
766 if (lastTestFailed
) {
767 LL_message( "", TRUE
);
769 LL_message( msg
, TRUE
);
770 if (lastTestFailed
) {
771 LL_message( "", TRUE
);
786 * Adds given string to the log if we are in verbose mode.
788 void IntlTest::log( const UnicodeString
&message
)
791 LL_message( message
, FALSE
);
796 * Adds given string to the log if we are in verbose mode. Adds a new line to
799 void IntlTest::logln( const UnicodeString
&message
)
802 LL_message( message
, TRUE
);
806 void IntlTest::logln( void )
809 LL_message( "", TRUE
);
814 * Unconditionally adds given string to the log.
816 void IntlTest::info( const UnicodeString
&message
)
818 LL_message( message
, FALSE
);
822 * Unconditionally adds given string to the log. Adds a new line to
825 void IntlTest::infoln( const UnicodeString
&message
)
827 LL_message( message
, TRUE
);
830 void IntlTest::infoln( void )
832 LL_message( "", TRUE
);
835 int32_t IntlTest::IncErrorCount( void )
838 if (caller
) caller
->IncErrorCount();
842 int32_t IntlTest::IncDataErrorCount( void )
845 if (caller
) caller
->IncDataErrorCount();
846 return dataErrorCount
;
854 void IntlTest::err( const UnicodeString
&message
)
857 if (!no_err_msg
) LL_message( message
, FALSE
);
860 void IntlTest::errln( const UnicodeString
&message
)
863 if (!no_err_msg
) LL_message( message
, TRUE
);
866 void IntlTest::dataerr( const UnicodeString
&message
)
870 if (!warn_on_missing_data
) {
874 if (!no_err_msg
) LL_message( message
, FALSE
);
877 void IntlTest::dataerrln( const UnicodeString
&message
)
881 if (!warn_on_missing_data
) {
885 msg
= UnicodeString("[DATA] " + message
);
888 if (!no_err_msg
) LL_message( msg
+ " - (Are you missing data?)", TRUE
);
891 void IntlTest::errcheckln(UErrorCode status
, const UnicodeString
&message
) {
892 if (status
== U_FILE_ACCESS_ERROR
|| status
== U_MISSING_RESOURCE_ERROR
) {
899 /* convenience functions that include sprintf formatting */
900 void IntlTest::log(const char *fmt
, ...)
906 /* sprintf it just to make sure that the information is valid */
907 vsprintf(buffer
, fmt
, ap
);
910 log(UnicodeString(buffer
, ""));
914 void IntlTest::logln(const char *fmt
, ...)
920 /* sprintf it just to make sure that the information is valid */
921 vsprintf(buffer
, fmt
, ap
);
924 logln(UnicodeString(buffer
, ""));
928 /* convenience functions that include sprintf formatting */
929 void IntlTest::info(const char *fmt
, ...)
935 /* sprintf it just to make sure that the information is valid */
936 vsprintf(buffer
, fmt
, ap
);
938 info(UnicodeString(buffer
, ""));
941 void IntlTest::infoln(const char *fmt
, ...)
947 /* sprintf it just to make sure that the information is valid */
948 vsprintf(buffer
, fmt
, ap
);
950 infoln(UnicodeString(buffer
, ""));
953 void IntlTest::err(const char *fmt
, ...)
959 vsprintf(buffer
, fmt
, ap
);
961 err(UnicodeString(buffer
, ""));
964 void IntlTest::errln(const char *fmt
, ...)
970 vsprintf(buffer
, fmt
, ap
);
972 errln(UnicodeString(buffer
, ""));
975 void IntlTest::dataerrln(const char *fmt
, ...)
981 vsprintf(buffer
, fmt
, ap
);
983 dataerrln(UnicodeString(buffer
, ""));
986 void IntlTest::errcheckln(UErrorCode status
, const char *fmt
, ...)
992 vsprintf(buffer
, fmt
, ap
);
995 if (status
== U_FILE_ACCESS_ERROR
|| status
== U_MISSING_RESOURCE_ERROR
) {
996 dataerrln(UnicodeString(buffer
, ""));
998 errln(UnicodeString(buffer
, ""));
1002 void IntlTest::printErrors()
1004 IntlTest::LL_message(errorList
, TRUE
);
1007 void IntlTest::LL_message( UnicodeString message
, UBool newline
)
1009 // string that starts with a LineFeed character and continues
1010 // with spaces according to the current indentation
1011 static const UChar indentUChars
[] = {
1013 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1014 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1015 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1016 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1017 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1018 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1019 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1020 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1021 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1022 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
1024 UnicodeString
indent(FALSE
, indentUChars
, 1 + LL_indentlevel
);
1029 // stream out the indentation string first if necessary
1030 length
= indent
.extract(1, indent
.length(), buffer
, sizeof(buffer
));
1032 fwrite(buffer
, sizeof(*buffer
), length
, (FILE *)testoutfp
);
1035 // replace each LineFeed by the indentation string
1036 message
.findAndReplace(UnicodeString((UChar
)'\n'), indent
);
1038 // stream out the message
1039 length
= message
.extract(0, message
.length(), buffer
, sizeof(buffer
));
1041 length
= length
> 10000 ? 10000 : length
;
1042 fwrite(buffer
, sizeof(*buffer
), length
, (FILE *)testoutfp
);
1046 char newLine
= '\n';
1047 fwrite(&newLine
, sizeof(newLine
), 1, (FILE *)testoutfp
);
1050 // A newline usually flushes the buffer, but
1051 // flush the message just in case of a core dump.
1052 fflush((FILE *)testoutfp
);
1056 * Print a usage message for this test class.
1058 void IntlTest::usage( void )
1060 UBool save_verbose
= setVerbose( TRUE
);
1061 logln("Test names:");
1062 logln("-----------");
1065 const char* name
= NULL
;
1067 this->runIndexedTest( index
, FALSE
, name
);
1071 }while (name
&& (name
[0] != 0));
1072 setVerbose( save_verbose
);
1076 // memory leak reporting software will be able to take advantage of the testsuite
1077 // being run a second time local to a specific method in order to report only actual leaks
1079 IntlTest::run_phase2( char* name
, char* par
) // supports reporting memory leaks
1081 UnicodeString
* strLeak
= new UnicodeString("forced leak"); // for verifying purify filter
1082 strLeak
->append(" for verifying purify filter");
1083 return this->runTest( name
, par
);
1087 #if UCONFIG_NO_LEGACY_CONVERSION
1088 # define TRY_CNV_1 "iso-8859-1"
1089 # define TRY_CNV_2 "ibm-1208"
1091 # define TRY_CNV_1 "iso-8859-7"
1092 # define TRY_CNV_2 "sjis"
1096 main(int argc
, char* argv
[])
1098 UBool syntax
= FALSE
;
1100 UBool verbose
= FALSE
;
1101 UBool no_err_msg
= FALSE
;
1102 UBool no_time
= FALSE
;
1105 UBool leaks
= FALSE
;
1106 UBool warnOnMissingData
= FALSE
;
1107 UBool defaultDataFound
= FALSE
;
1108 int32_t threadCount
= 1;
1109 UErrorCode errorCode
= U_ZERO_ERROR
;
1110 UConverter
*cnv
= NULL
;
1111 const char *warnOrErr
= "Failure";
1112 UDate startTime
, endTime
;
1114 const char *props
[IntlTest::kMaxProps
];
1117 U_MAIN_INIT_ARGS(argc
, argv
);
1119 startTime
= uprv_getRawUTCtime();
1121 for (int i
= 1; i
< argc
; ++i
) {
1122 if (argv
[i
][0] == '-') {
1123 const char* str
= argv
[i
] + 1;
1124 if (strcmp("verbose", str
) == 0 ||
1125 strcmp("v", str
) == 0)
1127 else if (strcmp("noerrormsg", str
) == 0 ||
1128 strcmp("n", str
) == 0)
1130 else if (strcmp("exhaustive", str
) == 0 ||
1131 strcmp("e", str
) == 0)
1133 else if (strcmp("all", str
) == 0 ||
1134 strcmp("a", str
) == 0)
1136 else if (strcmp("leaks", str
) == 0 ||
1137 strcmp("l", str
) == 0)
1139 else if (strcmp("notime", str
) == 0 ||
1140 strcmp("T", str
) == 0)
1142 else if (strcmp("x", str
)==0) {
1144 printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n");
1147 if(ctest_xml_setFileName(argv
[i
])) { /* set the name */
1148 return 1; /* error */
1150 } else if (strcmp("w", str
) == 0) {
1151 warnOnMissingData
= TRUE
;
1152 warnOrErr
= "WARNING";
1154 else if (strncmp("threads:", str
, 8) == 0) {
1155 threadCount
= atoi(str
+ 8);
1157 else if (strncmp("prop:", str
, 5) == 0) {
1158 if (nProps
< IntlTest::kMaxProps
) {
1159 props
[nProps
] = str
+ 5;
1171 if (!all
&& !name
) {
1173 } else if (all
&& name
) {
1180 "### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n"
1182 "### Options are: verbose (v), all (a), noerrormsg (n), \n"
1183 "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:<propery>=<value>, \n"
1184 "### notime (T), \n"
1185 "### threads:<threadCount> (Mulithreading must first be \n"
1186 "### enabled otherwise this will be ignored. \n"
1187 "### The default thread count is 1.),\n"
1188 "### (Specify either -all (shortcut -a) or a test name). \n"
1189 "### -all will run all of the tests.\n"
1191 "### To get a list of the test names type: intltest LIST \n"
1192 "### To run just the utility tests type: intltest utility \n"
1194 "### Test names can be nested using slashes (\"testA/subtest1\") \n"
1195 "### For example to list the utility tests type: intltest utility/LIST \n"
1196 "### To run just the Locale test type: intltest utility/LocaleTest \n"
1198 "### A parameter can be specified for a test by appending '@' and the value \n"
1199 "### to the testname. \n\n");
1203 if (nProps
> IntlTest::kMaxProps
) {
1204 fprintf(stdout
, "### Too many properties. Exiting.\n");
1207 UBool all_tests_exist
= TRUE
;
1208 MajorTestLevel major
;
1209 major
.setVerbose( verbose
);
1210 major
.setNoErrMsg( no_err_msg
);
1211 major
.setQuick( quick
);
1212 major
.setLeaks( leaks
);
1213 major
.setThreadCount( threadCount
);
1214 major
.setWarnOnMissingData( warnOnMissingData
);
1215 major
.setNotime (no_time
);
1216 for (int32_t i
= 0; i
< nProps
; i
++) {
1217 major
.setProperty(props
[i
]);
1221 fprintf(stdout
, "-----------------------------------------------\n");
1222 fprintf(stdout
, " IntlTest (C++) Test Suite for \n");
1223 fprintf(stdout
, " International Components for Unicode %s\n", U_ICU_VERSION
);
1227 const char *charsetFamily
= "Unknown";
1228 int32_t voidSize
= (int32_t)sizeof(void*);
1229 int32_t bits
= voidSize
* 8;
1230 if(U_CHARSET_FAMILY
==U_ASCII_FAMILY
) {
1231 charsetFamily
="ASCII";
1232 } else if(U_CHARSET_FAMILY
==U_EBCDIC_FAMILY
) {
1233 charsetFamily
="EBCDIC";
1236 " Bits: %d, Byte order: %s, Chars: %s\n",
1237 bits
, U_IS_BIG_ENDIAN
?"Big endian":"Little endian",
1240 fprintf(stdout
, "-----------------------------------------------\n");
1241 fprintf(stdout
, " Options: \n");
1242 fprintf(stdout
, " all (a) : %s\n", (all
? "On" : "Off"));
1243 fprintf(stdout
, " Verbose (v) : %s\n", (verbose
? "On" : "Off"));
1244 fprintf(stdout
, " No error messages (n) : %s\n", (no_err_msg
? "On" : "Off"));
1245 fprintf(stdout
, " Exhaustive (e) : %s\n", (!quick
? "On" : "Off"));
1246 fprintf(stdout
, " Leaks (l) : %s\n", (leaks
? "On" : "Off"));
1247 fprintf(stdout
, " notime (T) : %s\n", (no_time
? "On" : "Off"));
1248 fprintf(stdout
, " Warn on missing data (w) : %s\n", (warnOnMissingData
? "On" : "Off"));
1249 #if (ICU_USE_THREADS==0)
1250 fprintf(stdout
, " Threads : Disabled\n");
1252 fprintf(stdout
, " Threads : %d\n", threadCount
);
1254 for (int32_t i
= 0; i
< nProps
; i
++) {
1255 fprintf(stdout
, " Custom property (prop:) : %s\n", props
[i
]);
1257 fprintf(stdout
, "-----------------------------------------------\n");
1259 /* Check whether ICU will initialize without forcing the build data directory into
1260 * the ICU_DATA path. Success here means either the data dll contains data, or that
1261 * this test program was run with ICU_DATA set externally. Failure of this check
1262 * is normal when ICU data is not packaged into a shared library.
1264 * Whether or not this test succeeds, we want to cleanup and reinitialize
1265 * with a data path so that data loading from individual files can be tested.
1268 if (U_FAILURE(errorCode
)) {
1270 "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
1271 defaultDataFound
= FALSE
;
1274 defaultDataFound
= TRUE
;
1277 errorCode
= U_ZERO_ERROR
;
1279 /* Initialize ICU */
1280 if (!defaultDataFound
) {
1281 IntlTest::setICU_DATA(); // Must set data directory before u_init() is called.
1284 if (U_FAILURE(errorCode
)) {
1286 "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
1287 "*** Check the ICU_DATA environment variable and \n"
1288 "*** check that the data files are present.\n", argv
[0], u_errorName(errorCode
));
1289 if(warnOnMissingData
== 0) {
1290 fprintf(stderr
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1297 // initial check for the default converter
1298 errorCode
= U_ZERO_ERROR
;
1299 cnv
= ucnv_open(0, &errorCode
);
1305 "*** %s! The default converter [%s] cannot be opened.\n"
1306 "*** Check the ICU_DATA environment variable and\n"
1307 "*** check that the data files are present.\n",
1308 warnOrErr
, ucnv_getDefaultName());
1309 if(!warnOnMissingData
) {
1310 fprintf(stdout
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1316 cnv
= ucnv_open(TRY_CNV_2
, &errorCode
);
1322 "*** %s! The converter for " TRY_CNV_2
" cannot be opened.\n"
1323 "*** Check the ICU_DATA environment variable and \n"
1324 "*** check that the data files are present.\n", warnOrErr
);
1325 if(!warnOnMissingData
) {
1326 fprintf(stdout
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1331 UResourceBundle
*rb
= ures_open(0, "en", &errorCode
);
1333 if(U_FAILURE(errorCode
)) {
1335 "*** %s! The \"en\" locale resource bundle cannot be opened.\n"
1336 "*** Check the ICU_DATA environment variable and \n"
1337 "*** check that the data files are present.\n", warnOrErr
);
1338 if(!warnOnMissingData
) {
1339 fprintf(stdout
, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
1344 Locale originalLocale
; // Save the default locale for comparison later on.
1346 if(ctest_xml_init("intltest"))
1350 /* TODO: Add option to call u_cleanup and rerun tests. */
1354 major
.run_phase2( NULL
, NULL
);
1357 for (int i
= 1; i
< argc
; ++i
) {
1358 if (argv
[i
][0] != '-') {
1359 char* name
= argv
[i
];
1360 fprintf(stdout
, "\n=== Handling test: %s: ===\n", name
);
1362 char baseName
[1024];
1363 sprintf(baseName
, "/%s/", name
);
1365 char* parameter
= strchr( name
, '@' );
1371 UBool res
= major
.runTest( name
, parameter
, baseName
);
1373 major
.run_phase2( name
, parameter
);
1375 if (!res
|| (execCount
<= 0)) {
1376 fprintf(stdout
, "\n---ERROR: Test doesn't exist: %s!\n", name
);
1377 all_tests_exist
= FALSE
;
1379 } else if(!strcmp(argv
[i
],"-x")) {
1386 #if !UCONFIG_NO_FORMATTING
1387 CalendarTimeZoneTest::cleanup();
1390 free(_testDataPath
);
1393 Locale lastDefaultLocale
;
1394 if (originalLocale
!= lastDefaultLocale
) {
1395 major
.errln("FAILURE: A test changed the default locale without resetting it.");
1398 fprintf(stdout
, "\n--------------------------------------\n");
1399 if (major
.getErrors() == 0) {
1400 /* Call it twice to make sure that the defaults were reset. */
1401 /* Call it before the OK message to verify proper cleanup. */
1405 fprintf(stdout
, "OK: All tests passed without error.\n");
1407 if (major
.getDataErrors() != 0) {
1408 fprintf(stdout
, "\t*WARNING* some data-loading errors were ignored by the -w option.\n");
1411 fprintf(stdout
, "Errors in total: %ld.\n", (long)major
.getErrors());
1412 major
.printErrors();
1415 if (major
.getDataErrors() != 0) {
1416 fprintf(stdout
, "\t*Note* some errors are data-loading related. If the data used is not the \n"
1417 "\tstock ICU data (i.e some have been added or removed), consider using\n"
1418 "\tthe '-w' option to turn these errors into warnings.\n");
1421 /* Call afterwards to display errors. */
1425 fprintf(stdout
, "--------------------------------------\n");
1427 if (execCount
<= 0) {
1428 fprintf(stdout
, "***** Not all called tests actually exist! *****\n");
1431 endTime
= uprv_getRawUTCtime();
1432 diffTime
= (int32_t)(endTime
- startTime
);
1433 printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
1434 (int)((diffTime%U_MILLIS_PER_DAY
)/U_MILLIS_PER_HOUR
),
1435 (int)((diffTime%U_MILLIS_PER_HOUR
)/U_MILLIS_PER_MINUTE
),
1436 (int)((diffTime%U_MILLIS_PER_MINUTE
)/U_MILLIS_PER_SECOND
),
1437 (int)(diffTime%U_MILLIS_PER_SECOND
));
1440 if(ctest_xml_fini())
1443 return major
.getErrors();
1446 const char* IntlTest::loadTestData(UErrorCode
& err
){
1447 if( _testDataPath
== NULL
){
1448 const char* directory
=NULL
;
1449 UResourceBundle
* test
=NULL
;
1451 const char* tdrelativepath
;
1453 #if defined (U_TOPBUILDDIR)
1454 tdrelativepath
= "test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
1455 directory
= U_TOPBUILDDIR
;
1457 tdrelativepath
= ".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"out" U_FILE_SEP_STRING
;
1458 directory
= pathToDataDirectory();
1461 tdpath
= (char*) malloc(sizeof(char) *(( strlen(directory
) * strlen(tdrelativepath
)) + 100));
1464 /* u_getDataDirectory shoul return \source\data ... set the
1465 * directory to ..\source\data\..\test\testdata\out\testdata
1467 strcpy(tdpath
, directory
);
1468 strcat(tdpath
, tdrelativepath
);
1469 strcat(tdpath
,"testdata");
1471 test
=ures_open(tdpath
, "testtypes", &err
);
1474 err
= U_FILE_ACCESS_ERROR
;
1475 it_dataerrln((UnicodeString
)"Could not load testtypes.res in testdata bundle with path " + tdpath
+ (UnicodeString
)" - " + u_errorName(err
));
1479 _testDataPath
= tdpath
;
1480 return _testDataPath
;
1482 return _testDataPath
;
1485 const char* IntlTest::getTestDataPath(UErrorCode
& err
) {
1486 return loadTestData(err
);
1489 /* Returns the path to icu/source/test/testdata/ */
1490 const char *IntlTest::getSourceTestData(UErrorCode
& /*err*/) {
1491 const char *srcDataDir
= NULL
;
1493 srcDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
;
1495 srcDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
;
1496 FILE *f
= fopen(".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata" U_FILE_SEP_STRING
"rbbitst.txt", "r");
1498 /* We're in icu/source/test/intltest/ */
1502 /* We're in icu/source/test/intltest/Platform/(Debug|Release) */
1503 srcDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
"test" U_FILE_SEP_STRING
"testdata"U_FILE_SEP_STRING
;
1509 const char* IntlTest::fgDataDir
= NULL
;
1511 /* returns the path to icu/source/data */
1512 const char * IntlTest::pathToDataDirectory()
1515 if(fgDataDir
!= NULL
) {
1519 /* U_TOPSRCDIR is set by the makefiles on UNIXes when building cintltst and intltst
1520 // to point to the top of the build hierarchy, which may or
1521 // may not be the same as the source directory, depending on
1522 // the configure options used. At any rate,
1523 // set the data path to the built data from this directory.
1524 // The value is complete with quotes, so it can be used
1525 // as-is as a string constant.
1527 #if defined (U_TOPSRCDIR)
1529 fgDataDir
= U_TOPSRCDIR U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
1533 /* On Windows, the file name obtained from __FILE__ includes a full path.
1534 * This file is "wherever\icu\source\test\cintltst\cintltst.c"
1535 * Change to "wherever\icu\source\data"
1538 static char p
[sizeof(__FILE__
) + 10];
1542 strcpy(p
, __FILE__
);
1543 /* We want to back over three '\' chars. */
1544 /* Only Windows should end up here, so looking for '\' is safe. */
1545 for (i
=1; i
<=3; i
++) {
1546 pBackSlash
= strrchr(p
, U_FILE_SEP_CHAR
);
1547 if (pBackSlash
!= NULL
) {
1548 *pBackSlash
= 0; /* Truncate the string at the '\' */
1552 if (pBackSlash
!= NULL
) {
1553 /* We found and truncated three names from the path.
1554 * Now append "source\data" and set the environment
1556 strcpy(pBackSlash
, U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
);
1560 /* __FILE__ on MSVC7 does not contain the directory */
1561 FILE *file
= fopen(".." U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
"Makefile.in", "r");
1564 fgDataDir
= ".." U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
1567 fgDataDir
= ".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".." U_FILE_SEP_STRING
".."U_FILE_SEP_STRING
"data" U_FILE_SEP_STRING
;
1578 * This is a variant of cintltst/ccolltst.c:CharsToUChars().
1579 * It converts an invariant-character string into a UnicodeString, with
1580 * unescaping \u sequences.
1582 UnicodeString
CharsToUnicodeString(const char* chars
){
1583 return UnicodeString(chars
, -1, US_INV
).unescape();
1586 UnicodeString
ctou(const char* chars
) {
1587 return CharsToUnicodeString(chars
);
1590 #define RAND_M (714025)
1591 #define RAND_IA (1366)
1592 #define RAND_IC (150889)
1594 static int32_t RAND_SEED
;
1597 * Returns a uniform random value x, with 0.0 <= x < 1.0. Use
1598 * with care: Does not return all possible values; returns one of
1599 * 714,025 values, uniformly spaced. However, the period is
1600 * effectively infinite. See: Numerical Recipes, section 7.1.
1602 * @param seedp pointer to seed. Set *seedp to any negative value
1603 * to restart the sequence.
1605 float IntlTest::random(int32_t* seedp
) {
1606 static int32_t iy
, ir
[98];
1607 static UBool first
=TRUE
;
1609 if (*seedp
< 0 || first
) {
1611 if ((*seedp
=(RAND_IC
-(*seedp
)) % RAND_M
) < 0) *seedp
= -(*seedp
);
1612 for (j
=1;j
<=97;++j
) {
1613 *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
;
1616 *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
;
1619 j
=(int32_t)(1 + 97.0*iy
/RAND_M
);
1620 U_ASSERT(j
>=1 && j
<=97);
1622 *seedp
=(RAND_IA
*(*seedp
)+RAND_IC
) % RAND_M
;
1624 return (float) iy
/RAND_M
;
1628 * Convenience method using a global seed.
1630 float IntlTest::random() {
1631 return random(&RAND_SEED
);
1634 static inline UChar
toHex(int32_t i
) {
1635 return (UChar
)(i
+ (i
< 10 ? 0x30 : (0x41 - 10)));
1638 static UnicodeString
& escape(const UnicodeString
& s
, UnicodeString
& result
) {
1639 for (int32_t i
=0; i
<s
.length(); ++i
) {
1641 if (c
<= (UChar
)0x7F) {
1644 result
+= (UChar
)0x5c;
1645 result
+= (UChar
)0x75;
1646 result
+= toHex((c
>> 12) & 0xF);
1647 result
+= toHex((c
>> 8) & 0xF);
1648 result
+= toHex((c
>> 4) & 0xF);
1649 result
+= toHex( c
& 0xF);
1655 #define VERBOSE_ASSERTIONS
1657 UBool
IntlTest::assertTrue(const char* message
, UBool condition
, UBool quiet
, UBool possibleDataError
, const char *file
, int line
) {
1660 if (possibleDataError
) {
1661 dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file
, line
, message
);
1663 errln("%s:%d: FAIL: assertTrue() failed: %s", file
, line
, message
);
1665 } else if (!quiet
) {
1666 logln("%s:%d: Ok: %s", file
, line
, message
);
1670 if (possibleDataError
) {
1671 dataerrln("FAIL: assertTrue() failed: %s", message
);
1673 errln("FAIL: assertTrue() failed: %s", message
);
1675 } else if (!quiet
) {
1676 logln("Ok: %s", message
);
1683 UBool
IntlTest::assertFalse(const char* message
, UBool condition
, UBool quiet
) {
1685 errln("FAIL: assertFalse() failed: %s", message
);
1686 } else if (!quiet
) {
1687 logln("Ok: %s", message
);
1692 UBool
IntlTest::assertSuccess(const char* message
, UErrorCode ec
, UBool possibleDataError
) {
1693 if (U_FAILURE(ec
)) {
1694 if (possibleDataError
) {
1695 dataerrln("FAIL: %s (%s)", message
, u_errorName(ec
));
1697 errcheckln(ec
, "FAIL: %s (%s)", message
, u_errorName(ec
));
1705 UBool
IntlTest::assertEquals(const char* message
,
1706 const UnicodeString
& expected
,
1707 const UnicodeString
& actual
,
1708 UBool possibleDataError
) {
1709 if (expected
!= actual
) {
1710 if (possibleDataError
) {
1711 dataerrln((UnicodeString
)"FAIL: " + message
+ "; got " +
1713 "; expected " + prettify(expected
));
1715 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
1717 "; expected " + prettify(expected
));
1721 #ifdef VERBOSE_ASSERTIONS
1723 logln((UnicodeString
)"Ok: " + message
+ "; got " + prettify(actual
));
1729 UBool
IntlTest::assertEquals(const char* message
,
1730 const char* expected
,
1731 const char* actual
) {
1732 if (uprv_strcmp(expected
, actual
) != 0) {
1733 errln((UnicodeString
)"FAIL: " + message
+ "; got \"" +
1735 "\"; expected \"" + expected
+ "\"");
1738 #ifdef VERBOSE_ASSERTIONS
1740 logln((UnicodeString
)"Ok: " + message
+ "; got \"" + actual
+ "\"");
1746 UBool
IntlTest::assertEquals(const char* message
,
1749 if (expected
!= actual
) {
1750 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
1751 actual
+ "=0x" + toHex(actual
) +
1752 "; expected " + expected
+ "=0x" + toHex(expected
));
1755 #ifdef VERBOSE_ASSERTIONS
1757 logln((UnicodeString
)"Ok: " + message
+ "; got " + actual
+ "=0x" + toHex(actual
));
1763 #if !UCONFIG_NO_FORMATTING
1764 UBool
IntlTest::assertEquals(const char* message
,
1765 const Formattable
& expected
,
1766 const Formattable
& actual
) {
1767 if (expected
!= actual
) {
1768 errln((UnicodeString
)"FAIL: " + message
+ "; got " +
1770 "; expected " + toString(expected
));
1773 #ifdef VERBOSE_ASSERTIONS
1775 logln((UnicodeString
)"Ok: " + message
+ "; got " + toString(actual
));
1782 static char ASSERT_BUF
[256];
1784 static const char* extractToAssertBuf(const UnicodeString
& message
) {
1786 escape(message
, buf
);
1787 buf
.extract(0, 0x7FFFFFFF, ASSERT_BUF
, sizeof(ASSERT_BUF
)-1, 0);
1788 ASSERT_BUF
[sizeof(ASSERT_BUF
)-1] = 0;
1792 UBool
IntlTest::assertTrue(const UnicodeString
& message
, UBool condition
, UBool quiet
) {
1793 return assertTrue(extractToAssertBuf(message
), condition
, quiet
);
1796 UBool
IntlTest::assertFalse(const UnicodeString
& message
, UBool condition
, UBool quiet
) {
1797 return assertFalse(extractToAssertBuf(message
), condition
, quiet
);
1800 UBool
IntlTest::assertSuccess(const UnicodeString
& message
, UErrorCode ec
) {
1801 return assertSuccess(extractToAssertBuf(message
), ec
);
1804 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
1805 const UnicodeString
& expected
,
1806 const UnicodeString
& actual
) {
1807 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
1810 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
1811 const char* expected
,
1812 const char* actual
) {
1813 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
1815 //--------------------------------------------------------------------
1816 // Time bomb - allows temporary behavior that expires at a given
1818 //--------------------------------------------------------------------
1820 UBool
IntlTest::isICUVersionBefore(int major
, int minor
, int milli
) {
1822 UVersionInfo ov
= { (uint8_t)major
, (uint8_t)minor
, (uint8_t)milli
, 0 };
1824 return uprv_memcmp(iv
, ov
, U_MAX_VERSION_LENGTH
) < 0;
1827 #if !UCONFIG_NO_FORMATTING
1828 UBool
IntlTest::assertEquals(const UnicodeString
& message
,
1829 const Formattable
& expected
,
1830 const Formattable
& actual
) {
1831 return assertEquals(extractToAssertBuf(message
), expected
, actual
);
1835 void IntlTest::setProperty(const char* propline
) {
1836 if (numProps
< kMaxProps
) {
1837 proplines
[numProps
] = propline
;
1842 const char* IntlTest::getProperty(const char* prop
) {
1843 const char* val
= NULL
;
1844 for (int32_t i
= 0; i
< numProps
; i
++) {
1845 int32_t plen
= uprv_strlen(prop
);
1846 if ((int32_t)uprv_strlen(proplines
[i
]) > plen
+ 1
1847 && proplines
[i
][plen
] == '='
1848 && uprv_strncmp(proplines
[i
], prop
, plen
) == 0) {
1849 val
= &(proplines
[i
][plen
+1]);
1857 * Hey, Emacs, please set the following:
1860 * indent-tabs-mode: nil