+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
* COPYRIGHT:
- * Copyright (c) 1997-2004, International Business Machines Corporation and
+ * Copyright (c) 1997-2016, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
* IntlTest is a base class for tests.
*/
-#include <stdio.h>
-#include <string.h>
#include <assert.h>
#include <stdarg.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <cmath>
-#include "unicode/unistr.h"
-#include "unicode/ures.h"
-#include "unicode/smpdtfmt.h"
-#include "unicode/ucnv.h"
-#include "unicode/uclean.h"
-#include "unicode/timezone.h"
+#include "unicode/ctest.h" // for str_timeDelta
#include "unicode/curramt.h"
+#include "unicode/locid.h"
#include "unicode/putil.h"
+#include "unicode/smpdtfmt.h"
+#include "unicode/timezone.h"
+#include "unicode/uclean.h"
+#include "unicode/ucnv.h"
+#include "unicode/unistr.h"
+#include "unicode/ures.h"
+#include "unicode/utf16.h"
#include "intltest.h"
+
#include "caltztst.h"
-#include "itmajor.h"
+#include "cmemory.h"
#include "cstring.h"
-#include "umutex.h"
+#include "itmajor.h"
+#include "mutex.h"
+#include "putilimp.h" // for uprv_getRawUTCtime()
#include "uassert.h"
-#include "cmemory.h"
+#include "udbgutil.h"
+#include "umutex.h"
+#include "uoptions.h"
#ifdef XP_MAC_CONSOLE
#include <console.h>
// Static list of errors found
static UnicodeString errorList;
+static void *knownList = NULL; // known issues
+static UBool noKnownIssues = FALSE; // if TRUE, don't emit known issues
//-----------------------------------------------------------------------------
//convenience classes to ease porting code that uses the Java
char buffer[64]; // nos changed from 10 to 64
char danger = 'p'; // guard against overrunning the buffer (rtg)
-#ifdef WIN32
+#if defined(_MSC_VER)
sprintf(buffer, "%I64d", num);
#else
- sprintf(buffer, "%lld", num);
+ sprintf(buffer, "%lld", (long long)num);
#endif
assert(danger == 'p');
return buffer;
}
+UnicodeString
+DoubleToUnicodeString(double num)
+{
+ char buffer[64]; // nos changed from 10 to 64
+ char danger = 'p'; // guard against overrunning the buffer (rtg)
+
+ sprintf(buffer, "%1.14e", num);
+ assert(danger == 'p');
+
+ return buffer;
+}
+
// [LIU] Just to get things working
UnicodeString
operator+(const UnicodeString& left,
// 53*log(2)/log(10) = 15.95
// so there is no need to show more than 16 digits. [alan]
- sprintf(buffer, "%.16g", num);
+ sprintf(buffer, "%.17g", num);
assert(danger == 'p');
return left + buffer;
}
+#if 0
+UnicodeString
+operator+(const UnicodeString& left,
+ int64_t num) {
+ return left + Int64ToUnicodeString(num);
+}
+#endif
+
#if !UCONFIG_NO_FORMATTING
/**
- * Return a string display for for this, without surrounding braces.
+ * Return a string display for this, without surrounding braces.
*/
UnicodeString _toString(const Formattable& f) {
UnicodeString s;
}
}
break;
- case Formattable::kObject:
- if (f.getObject()->getDynamicClassID() ==
- CurrencyAmount::getStaticClassID()) {
- const CurrencyAmount& c = (const CurrencyAmount&) *f.getObject();
- s = _toString(c.getNumber()) + " " + UnicodeString(c.getISOCurrency());
+ case Formattable::kObject: {
+ const CurrencyAmount* c = dynamic_cast<const CurrencyAmount*>(f.getObject());
+ if (c != NULL) {
+ s = _toString(c->getNumber()) + " " + UnicodeString(c->getISOCurrency());
} else {
s = UnicodeString("Unknown UObject");
}
break;
+ }
default:
s = UnicodeString("Unknown Formattable type=") + (int32_t)f.getType();
break;
return UnicodeString() + (long)n;
}
+
+
+UnicodeString toString(UBool b) {
+ return b ? UnicodeString("TRUE"):UnicodeString("FALSE");
+}
+
+UnicodeString toString(const UnicodeSet& uniset, UErrorCode& status) {
+ UnicodeString result;
+ uniset.toPattern(result, status);
+ return result;
+}
+
// stephen - cleaned up 05/05/99
UnicodeString operator+(const UnicodeString& left, char num)
{ return left + (long)num; }
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0
}; /* "0123456789ABCDEF" */
+ if (digits < 0) { // auto-digits
+ digits = 2;
+ uint32_t max = 0xff;
+ while (number > max) {
+ digits += 2;
+ max = (max << 8) | 0xff;
+ }
+ }
switch (digits)
{
case 8:
target += digitString[(number >> 28) & 0xF];
+ U_FALLTHROUGH;
case 7:
target += digitString[(number >> 24) & 0xF];
+ U_FALLTHROUGH;
case 6:
target += digitString[(number >> 20) & 0xF];
+ U_FALLTHROUGH;
case 5:
target += digitString[(number >> 16) & 0xF];
+ U_FALLTHROUGH;
case 4:
target += digitString[(number >> 12) & 0xF];
+ U_FALLTHROUGH;
case 3:
target += digitString[(number >> 8) & 0xF];
+ U_FALLTHROUGH;
case 2:
target += digitString[(number >> 4) & 0xF];
+ U_FALLTHROUGH;
case 1:
target += digitString[(number >> 0) & 0xF];
break;
return target;
}
+UnicodeString
+IntlTest::toHex(uint32_t number, int32_t digits) {
+ UnicodeString result;
+ appendHex(number, digits, result);
+ return result;
+}
+
+static inline UBool isPrintable(UChar32 c) {
+ return c <= 0x7E && (c >= 0x20 || c == 9 || c == 0xA || c == 0xD);
+}
+
// Replace nonprintable characters with unicode escapes
UnicodeString&
IntlTest::prettify(const UnicodeString &source,
for (i = 0; i < source.length(); )
{
UChar32 ch = source.char32At(i);
- i += UTF_CHAR_LENGTH(ch);
+ i += U16_LENGTH(ch);
- if (ch < 0x09 || (ch > 0x0A && ch < 0x20)|| ch > 0x7E)
+ if (!isPrintable(ch))
{
if (ch <= 0xFFFF) {
target += "\\u";
for (i = 0; i < source.length();)
{
UChar32 ch = source.char32At(i);
- i += UTF_CHAR_LENGTH(ch);
+ i += U16_LENGTH(ch);
- if (ch < 0x09 || (ch > 0x0A && ch < 0x20)|| ch > 0x7E)
+ if (!isPrintable(ch))
{
if (parseBackslash) {
// If we are preceded by an odd number of backslashes,
return target;
}
-#if defined(_WIN32) || defined(WIN32) || defined(__OS2__) || defined(OS2)
-#define PREV_DIR ".."
-#else
-#define PREV_DIR "/../"
-#endif
-
-void
-IntlTest::pathnameInContext( char* fullname, int32_t maxsize, const char* relPath ) //nosmac
-{
- const char* mainDir;
- char sepChar;
- const char inpSepChar = '|';
-
- // So what's going on is that ICU_DATA during tests points to:
- // ICU | source | data
- //and we want ICU | source |
- //
- // We'll add | test | testdata
- //
- // So, just add a .. here - back up one level
-
- mainDir = u_getDataDirectory();
- sepChar = U_FILE_SEP_CHAR;
- char sepString[] = U_FILE_SEP_STRING;
-
-#if defined(XP_MAC)
- Str255 volName;
- int16_t volNum;
- OSErr err = GetVol( volName, &volNum );
- if (err != noErr)
- volName[0] = 0;
- mainDir = (char*) &(volName[1]);
- mainDir[volName[0]] = 0;
-#else
- char mainDirBuffer[255];
- if(mainDir!=NULL) {
- strcpy(mainDirBuffer, mainDir);
- strcat(mainDirBuffer, PREV_DIR);
- } else {
- mainDirBuffer[0]='\0';
- }
- mainDir=mainDirBuffer;
-#endif
-
- if (relPath[0] == '|')
- relPath++;
- int32_t lenMainDir = strlen(mainDir);
- int32_t lenRelPath = strlen(relPath);
- if (maxsize < lenMainDir + lenRelPath + 2) {
- fullname[0] = 0;
- return;
- }
- strcpy(fullname, mainDir);
- strcat(fullname, sepString);
- strcat(fullname, relPath);
- char* tmp = strchr(fullname, inpSepChar);
- while (tmp) {
- *tmp = sepChar;
- tmp = strchr(tmp+1, inpSepChar);
- }
-}
-
/* IntlTest::setICU_DATA - if the ICU_DATA environment variable is not already
* set, try to deduce the directory in which ICU was built,
* and set ICU_DATA to "icu/source/data" in that location.
}
else {
/* __FILE__ on MSVC7 does not contain the directory */
- u_setDataDirectory(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING);
+ u_setDataDirectory(".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING);
return;
}
}
IntlTest::gTest->errln( message );
}
+void it_dataerr( UnicodeString message )
+{
+ if (IntlTest::gTest)
+ IntlTest::gTest->dataerr( message );
+}
+
+void it_dataerrln( UnicodeString message )
+{
+ if (IntlTest::gTest)
+ IntlTest::gTest->dataerrln( message );
+}
IntlTest::IntlTest()
{
caller = NULL;
- path = NULL;
+ testPath = NULL;
LL_linestart = TRUE;
errorCount = 0;
+ dataErrorCount = 0;
verbose = FALSE;
+ no_time = FALSE;
no_err_msg = FALSE;
+ warn_on_missing_data = FALSE;
quick = FALSE;
leaks = FALSE;
+ threadCount = 12;
testoutfp = stdout;
LL_indentlevel = indentLevel_offset;
+ numProps = 0;
+ strcpy(basePath, "/");
+ currName[0]=0;
}
void IntlTest::setCaller( IntlTest* callingTest )
{
caller = callingTest;
if (caller) {
+ warn_on_missing_data = caller->warn_on_missing_data;
verbose = caller->verbose;
no_err_msg = caller->no_err_msg;
quick = caller->quick;
+ threadCount = caller->threadCount;
testoutfp = caller->testoutfp;
LL_indentlevel = caller->LL_indentlevel + indentLevel_offset;
+ numProps = caller->numProps;
+ for (int32_t i = 0; i < numProps; i++) {
+ proplines[i] = caller->proplines[i];
+ }
}
}
{
execCount--; // correct a previously assumed test-exec, as this only calls a subtest
testToBeCalled.setCaller( this );
- return testToBeCalled.runTest( path, par );
+ strcpy(testToBeCalled.basePath, this->basePath );
+ UBool result = testToBeCalled.runTest( testPath, par, testToBeCalled.basePath );
+ strcpy(testToBeCalled.basePath, this->basePath ); // reset it.
+ return result;
}
void IntlTest::setPath( char* pathVal )
{
- this->path = pathVal;
+ this->testPath = pathVal;
}
UBool IntlTest::setVerbose( UBool verboseVal )
return rval;
}
+UBool IntlTest::setNotime( UBool no_time )
+{
+ UBool rval = this->no_time;
+ this->no_time = no_time;
+ return rval;
+}
+
+UBool IntlTest::setWarnOnMissingData( UBool warn_on_missing_dataVal )
+{
+ UBool rval = this->warn_on_missing_data;
+ this->warn_on_missing_data = warn_on_missing_dataVal;
+ return rval;
+}
+
UBool IntlTest::setNoErrMsg( UBool no_err_msgVal )
{
UBool rval = this->no_err_msg;
return rval;
}
+int32_t IntlTest::setThreadCount( int32_t count )
+{
+ int32_t rval = this->threadCount;
+ this->threadCount = count;
+ return rval;
+}
+
int32_t IntlTest::getErrors( void )
{
return errorCount;
}
-UBool IntlTest::runTest( char* name, char* par )
+int32_t IntlTest::getDataErrors( void )
+{
+ return dataErrorCount;
+}
+
+UBool IntlTest::runTest( char* name, char* par, char *baseName )
{
UBool rval;
char* pos = NULL;
+ char* baseNameBuffer = NULL;
+
+ if(baseName == NULL) {
+ baseNameBuffer = (char*)malloc(1024);
+ baseName=baseNameBuffer;
+ strcpy(baseName, "/");
+ }
+
if (name)
pos = strchr( name, delim ); // check if name contains path (by looking for '/')
if (pos) {
- path = pos+1; // store subpath for calling subtest
+ testPath = pos+1; // store subpath for calling subtest
*pos = 0; // split into two strings
}else{
- path = NULL;
+ testPath = NULL;
}
if (!name || (name[0] == 0) || (strcmp(name, "*") == 0)) {
- rval = runTestLoop( NULL, par );
+ rval = runTestLoop( NULL, par, baseName );
}else if (strcmp( name, "LIST" ) == 0) {
this->usage();
rval = TRUE;
}else{
- rval = runTestLoop( name, par );
+ rval = runTestLoop( name, par, baseName );
}
if (pos)
*pos = delim; // restore original value at pos
+ if(baseNameBuffer!=NULL) {
+ free(baseNameBuffer);
+ }
return rval;
}
-// call individual tests, to be overriden to call implementations
-void IntlTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* par )
+// call individual tests, to be overridden to call implementations
+void IntlTest::runIndexedTest( int32_t /*index*/, UBool /*exec*/, const char* & /*name*/, char* /*par*/ )
{
- // to be overriden by a method like:
+ // to be overridden by a method like:
/*
switch (index) {
case 0: name = "First Test"; if (exec) FirstTest( par ); break;
default: name = ""; break;
}
*/
- this->errln("*** runIndexedTest needs to be overriden! ***");
- name = ""; exec = exec; index = index; par = par;
+ this->errln("*** runIndexedTest needs to be overridden! ***");
}
-UBool IntlTest::runTestLoop( char* testname, char* par )
+UBool IntlTest::runTestLoop( char* testname, char* par, char *baseName )
{
int32_t index = 0;
const char* name;
UBool rval = FALSE;
UBool lastTestFailed;
+ if(baseName == NULL) {
+ printf("ERROR: baseName can't be null.\n");
+ return FALSE;
+ } else {
+ if ((char *)this->basePath != baseName) {
+ strcpy(this->basePath, baseName);
+ }
+ }
+
+ char * saveBaseLoc = baseName+strlen(baseName);
+
IntlTest* saveTest = gTest;
gTest = this;
do {
this->runIndexedTest( index, FALSE, name, par );
- if (!name || (name[0] == 0))
- break;
- if (!testname) {
- run_this_test = TRUE;
- }else{
- run_this_test = (UBool) (strcmp( name, testname ) == 0);
+ if (strcmp(name,"skip") == 0) {
+ run_this_test = FALSE;
+ } else {
+ if (!name || (name[0] == 0))
+ break;
+ if (!testname) {
+ run_this_test = TRUE;
+ }else{
+ run_this_test = (UBool) (strcmp( name, testname ) == 0);
+ }
}
if (run_this_test) {
lastErrorCount = errorCount;
execCount++;
+ char msg[256];
+ sprintf(msg, "%s {", name);
+ LL_message(msg, TRUE);
+ UDate timeStart = uprv_getRawUTCtime();
+ strcpy(saveBaseLoc,name);
+ strcat(saveBaseLoc,"/");
+
+ strcpy(currName, name); // set
this->runIndexedTest( index, TRUE, name, par );
+ currName[0]=0; // reset
+
+ UDate timeStop = uprv_getRawUTCtime();
rval = TRUE; // at least one test has been called
- char msg[256];
+ char secs[256];
+ if(!no_time) {
+ sprintf(secs, "%f", (timeStop-timeStart)/1000.0);
+ } else {
+ secs[0]=0;
+ }
+
+
+ strcpy(saveBaseLoc,name);
+
+
+ ctest_xml_testcase(baseName, name, secs, (lastErrorCount!=errorCount)?"err":NULL);
+
+
+ saveBaseLoc[0]=0; /* reset path */
+
if (lastErrorCount == errorCount) {
- sprintf( msg, "---OK: %s", name );
+ sprintf( msg, " } OK: %s ", name );
+ if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
lastTestFailed = FALSE;
}else{
- sprintf(msg, "---ERRORS (%li) in %s", (long)(errorCount-lastErrorCount), name);
+ sprintf(msg, " } ERRORS (%li) in %s", (long)(errorCount-lastErrorCount), name);
+ if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart);
for(int i=0;i<LL_indentlevel;i++) {
errorList += " ";
index++;
}while(name);
+ *saveBaseLoc = 0;
+
gTest = saveTest;
return rval;
}
return errorCount;
}
-void IntlTest::err() {
+int32_t IntlTest::IncDataErrorCount( void )
+{
+ dataErrorCount++;
+ if (caller) caller->IncDataErrorCount();
+ return dataErrorCount;
+}
+
+void IntlTest::err()
+{
IncErrorCount();
}
if (!no_err_msg) LL_message( message, TRUE );
}
+void IntlTest::dataerr( const UnicodeString &message )
+{
+ IncDataErrorCount();
+
+ if (!warn_on_missing_data) {
+ IncErrorCount();
+ }
+
+ if (!no_err_msg) LL_message( message, FALSE );
+}
+
+void IntlTest::dataerrln( const UnicodeString &message )
+{
+ int32_t errCount = IncDataErrorCount();
+ UnicodeString msg;
+ if (!warn_on_missing_data) {
+ IncErrorCount();
+ msg = message;
+ } else {
+ msg = UnicodeString("[DATA] " + message);
+ }
+
+ if (!no_err_msg) {
+ if ( errCount == 1) {
+ LL_message( msg + " - (Are you missing data?)", TRUE ); // only show this message the first time
+ } else {
+ LL_message( msg , TRUE );
+ }
+ }
+}
+
+void IntlTest::errcheckln(UErrorCode status, const UnicodeString &message ) {
+ if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
+ dataerrln(message);
+ } else {
+ errln(message);
+ }
+}
+
/* convenience functions that include sprintf formatting */
void IntlTest::log(const char *fmt, ...)
{
vsprintf(buffer, fmt, ap);
va_end(ap);
if( verbose ) {
- log(UnicodeString(buffer, ""));
+ log(UnicodeString(buffer, (const char *)NULL));
}
}
vsprintf(buffer, fmt, ap);
va_end(ap);
if( verbose ) {
- logln(UnicodeString(buffer, ""));
+ logln(UnicodeString(buffer, (const char *)NULL));
}
}
+UBool IntlTest::logKnownIssue(const char *ticket, const char *fmt, ...)
+{
+ char buffer[4000];
+ va_list ap;
+
+ va_start(ap, fmt);
+ /* sprintf it just to make sure that the information is valid */
+ vsprintf(buffer, fmt, ap);
+ va_end(ap);
+ return logKnownIssue(ticket, UnicodeString(buffer, (const char *)NULL));
+}
+
+UBool IntlTest::logKnownIssue(const char *ticket) {
+ return logKnownIssue(ticket, UnicodeString());
+}
+
+UBool IntlTest::logKnownIssue(const char *ticket, const UnicodeString &msg) {
+ if(noKnownIssues) return FALSE;
+
+ char fullpath[2048];
+ strcpy(fullpath, basePath);
+ strcat(fullpath, currName);
+ UnicodeString msg2 = msg;
+ UBool firstForTicket = TRUE, firstForWhere = TRUE;
+ knownList = udbg_knownIssue_openU(knownList, ticket, fullpath, msg2.getTerminatedBuffer(), &firstForTicket, &firstForWhere);
+
+ msg2 = UNICODE_STRING_SIMPLE("(Known issue #") +
+ UnicodeString(ticket, -1, US_INV) + UNICODE_STRING_SIMPLE(") ") + msg;
+ if(firstForTicket || firstForWhere) {
+ infoln(msg2);
+ } else {
+ logln(msg2);
+ }
+
+ return TRUE;
+}
+
/* convenience functions that include sprintf formatting */
void IntlTest::info(const char *fmt, ...)
{
/* sprintf it just to make sure that the information is valid */
vsprintf(buffer, fmt, ap);
va_end(ap);
- info(UnicodeString(buffer, ""));
+ info(UnicodeString(buffer, (const char *)NULL));
}
void IntlTest::infoln(const char *fmt, ...)
/* sprintf it just to make sure that the information is valid */
vsprintf(buffer, fmt, ap);
va_end(ap);
- infoln(UnicodeString(buffer, ""));
+ infoln(UnicodeString(buffer, (const char *)NULL));
}
void IntlTest::err(const char *fmt, ...)
va_start(ap, fmt);
vsprintf(buffer, fmt, ap);
va_end(ap);
- err(UnicodeString(buffer, ""));
+ err(UnicodeString(buffer, (const char *)NULL));
}
void IntlTest::errln(const char *fmt, ...)
va_start(ap, fmt);
vsprintf(buffer, fmt, ap);
va_end(ap);
- errln(UnicodeString(buffer, ""));
+ errln(UnicodeString(buffer, (const char *)NULL));
+}
+
+void IntlTest::dataerrln(const char *fmt, ...)
+{
+ char buffer[4000];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsprintf(buffer, fmt, ap);
+ va_end(ap);
+ dataerrln(UnicodeString(buffer, (const char *)NULL));
+}
+
+void IntlTest::errcheckln(UErrorCode status, const char *fmt, ...)
+{
+ char buffer[4000];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsprintf(buffer, fmt, ap);
+ va_end(ap);
+
+ if (status == U_FILE_ACCESS_ERROR || status == U_MISSING_RESOURCE_ERROR) {
+ dataerrln(UnicodeString(buffer, (const char *)NULL));
+ } else {
+ errln(UnicodeString(buffer, (const char *)NULL));
+ }
}
void IntlTest::printErrors()
IntlTest::LL_message(errorList, TRUE);
}
+UBool IntlTest::printKnownIssues()
+{
+ if(knownList != NULL) {
+ udbg_knownIssue_print(knownList);
+ udbg_knownIssue_close(knownList);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
void IntlTest::LL_message( UnicodeString message, UBool newline )
{
+ // Synchronize this function.
+ // All error messages generated by tests funnel through here.
+ // Multithreaded tests can concurrently generate errors, requiring synchronization
+ // to keep each message together.
+ static UMutex *messageMutex = STATIC_NEW(UMutex);
+ Mutex lock(messageMutex);
+
// string that starts with a LineFeed character and continues
// with spaces according to the current indentation
static const UChar indentUChars[] = {
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
};
+ U_ASSERT(1 + LL_indentlevel <= UPRV_LENGTHOF(indentUChars));
UnicodeString indent(FALSE, indentUChars, 1 + LL_indentlevel);
- char buffer[10000];
+ char buffer[30000];
int32_t length;
// stream out the indentation string first if necessary
// stream out the message
length = message.extract(0, message.length(), buffer, sizeof(buffer));
if (length > 0) {
+ length = length > 30000 ? 30000 : length;
fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp);
}
# define TRY_CNV_2 "sjis"
#endif
+#ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
+U_CAPI void unistr_printLengths();
+#endif
+
int
main(int argc, char* argv[])
{
UBool all = FALSE;
UBool verbose = FALSE;
UBool no_err_msg = FALSE;
+ UBool no_time = FALSE;
UBool quick = TRUE;
UBool name = FALSE;
UBool leaks = FALSE;
+ UBool utf8 = FALSE;
+ const char *summary_file = NULL;
UBool warnOnMissingData = FALSE;
+ UBool defaultDataFound = FALSE;
+ int32_t threadCount = 12;
UErrorCode errorCode = U_ZERO_ERROR;
UConverter *cnv = NULL;
const char *warnOrErr = "Failure";
+ UDate startTime, endTime;
+ int32_t diffTime;
+ const char *props[IntlTest::kMaxProps];
+ int32_t nProps = 0;
-#ifdef XP_MAC_CONSOLE
- argc = ccommand( &argv );
-#endif
-
- /* Initialize ICU */
- IntlTest::setICU_DATA(); // Must set data directory before u_init() is called.
- u_init(&errorCode);
- if (U_FAILURE(errorCode)) {
- fprintf(stderr,
- "#### %s: u_init() failed, error is \"%s\".\n"
- "#### Most commonly indicates that the ICU data is not accesible.\n"
- "#### Check setting of ICU_DATA, or check that ICU data library is available\n"
- "#### ICU_DATA is currently set to \"%s\"\n", argv[0], u_errorName(errorCode), u_getDataDirectory());
- u_cleanup();
- return 1;
- }
+ U_MAIN_INIT_ARGS(argc, argv);
+ startTime = uprv_getRawUTCtime();
for (int i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
else if (strcmp("all", str) == 0 ||
strcmp("a", str) == 0)
all = TRUE;
+ else if (strcmp("utf-8", str) == 0 ||
+ strcmp("u", str) == 0)
+ utf8 = TRUE;
+ else if (strcmp("noknownissues", str) == 0 ||
+ strcmp("K", str) == 0)
+ noKnownIssues = TRUE;
else if (strcmp("leaks", str) == 0 ||
strcmp("l", str) == 0)
leaks = TRUE;
- else if (strcmp("w", str) == 0) {
+ else if (strcmp("notime", str) == 0 ||
+ strcmp("T", str) == 0)
+ no_time = TRUE;
+ else if (strncmp("E", str, 1) == 0)
+ summary_file = str+1;
+ else if (strcmp("x", str)==0) {
+ if(++i>=argc) {
+ printf("* Error: '-x' option requires an argument. usage: '-x outfile.xml'.\n");
+ syntax = TRUE;
+ }
+ if(ctest_xml_setFileName(argv[i])) { /* set the name */
+ return 1; /* error */
+ }
+ } else if (strcmp("w", str) == 0) {
warnOnMissingData = TRUE;
warnOrErr = "WARNING";
}
+ else if (strncmp("threads:", str, 8) == 0) {
+ threadCount = atoi(str + 8);
+ }
+ else if (strncmp("prop:", str, 5) == 0) {
+ if (nProps < IntlTest::kMaxProps) {
+ props[nProps] = str + 5;
+ }
+ nProps++;
+ }
else {
syntax = TRUE;
}
fprintf(stdout,
"### Syntax:\n"
"### IntlTest [-option1 -option2 ...] [testname1 testname2 ...] \n"
- "### where options are: verbose (v), all (a), noerrormsg (n), \n"
- "### exhaustive (e), leaks (l)"
+ "### \n"
+ "### Options are: verbose (v), all (a), noerrormsg (n), \n"
+ "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:<propery>=<value>, \n"
+ "### notime (T), \n"
+ "### threads:<threadCount>\n"
+ "### (The default thread count is 12.),\n"
"### (Specify either -all (shortcut -a) or a test name). \n"
"### -all will run all of the tests.\n"
"### \n"
return 1;
}
- UBool all_tests_exist = TRUE;
+ if (nProps > IntlTest::kMaxProps) {
+ fprintf(stdout, "### Too many properties. Exiting.\n");
+ }
+
MajorTestLevel major;
major.setVerbose( verbose );
major.setNoErrMsg( no_err_msg );
major.setQuick( quick );
major.setLeaks( leaks );
+ major.setThreadCount( threadCount );
+ major.setWarnOnMissingData( warnOnMissingData );
+ major.setNotime (no_time);
+ for (int32_t i = 0; i < nProps; i++) {
+ major.setProperty(props[i]);
+ }
+
+
fprintf(stdout, "-----------------------------------------------\n");
fprintf(stdout, " IntlTest (C++) Test Suite for \n");
fprintf(stdout, " International Components for Unicode %s\n", U_ICU_VERSION);
+
+
+ {
+ const char *charsetFamily = "Unknown";
+ int32_t voidSize = (int32_t)sizeof(void*);
+ int32_t bits = voidSize * 8;
+ if(U_CHARSET_FAMILY==U_ASCII_FAMILY) {
+ charsetFamily="ASCII";
+ } else if(U_CHARSET_FAMILY==U_EBCDIC_FAMILY) {
+ charsetFamily="EBCDIC";
+ }
+ fprintf(stdout,
+ " Bits: %d, Byte order: %s, Chars: %s\n",
+ bits, U_IS_BIG_ENDIAN?"Big endian":"Little endian",
+ charsetFamily);
+ }
fprintf(stdout, "-----------------------------------------------\n");
fprintf(stdout, " Options: \n");
- fprintf(stdout, " all (a) : %s\n", (all? "On" : "Off"));
- fprintf(stdout, " Verbose (v) : %s\n", (verbose? "On" : "Off"));
- fprintf(stdout, " No error messages (n) : %s\n", (no_err_msg? "On" : "Off"));
- fprintf(stdout, " Exhaustive (e) : %s\n", (!quick? "On" : "Off"));
- fprintf(stdout, " Leaks (l) : %s\n", (leaks? "On" : "Off"));
+ fprintf(stdout, " all (a) : %s\n", (all? "On" : "Off"));
+ fprintf(stdout, " Verbose (v) : %s\n", (verbose? "On" : "Off"));
+ fprintf(stdout, " No error messages (n) : %s\n", (no_err_msg? "On" : "Off"));
+ fprintf(stdout, " Exhaustive (e) : %s\n", (!quick? "On" : "Off"));
+ fprintf(stdout, " Leaks (l) : %s\n", (leaks? "On" : "Off"));
+ fprintf(stdout, " utf-8 (u) : %s\n", (utf8? "On" : "Off"));
+ fprintf(stdout, " notime (T) : %s\n", (no_time? "On" : "Off"));
+ fprintf(stdout, " noknownissues (K) : %s\n", (noKnownIssues? "On" : "Off"));
+ fprintf(stdout, " Warn on missing data (w) : %s\n", (warnOnMissingData? "On" : "Off"));
+ fprintf(stdout, " Threads : %d\n", threadCount);
+ for (int32_t i = 0; i < nProps; i++) {
+ fprintf(stdout, " Custom property (prop:) : %s\n", props[i]);
+ }
fprintf(stdout, "-----------------------------------------------\n");
- // Check that u_init() works
- errorCode = U_ZERO_ERROR;
+ if(utf8) {
+ ucnv_setDefaultName("utf-8");
+ }
+ /* Check whether ICU will initialize without forcing the build data directory into
+ * the ICU_DATA path. Success here means either the data dll contains data, or that
+ * this test program was run with ICU_DATA set externally. Failure of this check
+ * is normal when ICU data is not packaged into a shared library.
+ *
+ * Whether or not this test succeeds, we want to cleanup and reinitialize
+ * with a data path so that data loading from individual files can be tested.
+ */
u_init(&errorCode);
if (U_FAILURE(errorCode)) {
- fprintf(stdout,
- "*** u_init() failed with error code = %s\n"
- "*** Check the ICU_DATA environment variable and\n"
- "*** check that the data files are present.\n",
- u_errorName(errorCode));
- if(!warnOnMissingData) {
- fprintf(stdout, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
- return 1;
- }
+ fprintf(stderr,
+ "#### Note: ICU Init without build-specific setDataDirectory() failed.\n");
+ defaultDataFound = FALSE;
+ }
+ else {
+ defaultDataFound = TRUE;
+ }
+ u_cleanup();
+ if(utf8) {
+ ucnv_setDefaultName("utf-8");
}
+ errorCode = U_ZERO_ERROR;
+ /* Initialize ICU */
+ if (!defaultDataFound) {
+ IntlTest::setICU_DATA(); // Must set data directory before u_init() is called.
+ }
+ u_init(&errorCode);
+ if (U_FAILURE(errorCode)) {
+ fprintf(stderr,
+ "#### ERROR! %s: u_init() failed with status = \"%s\".\n"
+ "*** Check the ICU_DATA environment variable and \n"
+ "*** check that the data files are present.\n", argv[0], u_errorName(errorCode));
+ if(warnOnMissingData == 0) {
+ fprintf(stderr, "*** Exiting. Use the '-w' option if data files were\n*** purposely removed, to continue test anyway.\n");
+ u_cleanup();
+ return 1;
+ }
+ }
// initial check for the default converter
errorCode = U_ZERO_ERROR;
}
}
+ Locale originalLocale; // Save the default locale for comparison later on.
+
+ if(ctest_xml_init("intltest"))
+ return 1;
+
+
/* TODO: Add option to call u_cleanup and rerun tests. */
if (all) {
major.runTest();
if (argv[i][0] != '-') {
char* name = argv[i];
fprintf(stdout, "\n=== Handling test: %s: ===\n", name);
+
+ char baseName[1024];
+ sprintf(baseName, "/%s/", name);
+
char* parameter = strchr( name, '@' );
if (parameter) {
*parameter = 0;
parameter += 1;
}
execCount = 0;
- UBool res = major.runTest( name, parameter );
+ UBool res = major.runTest( name, parameter, baseName );
if (leaks && res) {
major.run_phase2( name, parameter );
}
if (!res || (execCount <= 0)) {
fprintf(stdout, "\n---ERROR: Test doesn't exist: %s!\n", name);
- all_tests_exist = FALSE;
}
+ } else if(!strcmp(argv[i],"-x")) {
+ i++;
}
}
}
+
#if !UCONFIG_NO_FORMATTING
CalendarTimeZoneTest::cleanup();
#endif
free(_testDataPath);
_testDataPath = 0;
+ Locale lastDefaultLocale;
+ if (originalLocale != lastDefaultLocale) {
+ major.errln("FAILURE: A test changed the default locale without resetting it.");
+ }
+
fprintf(stdout, "\n--------------------------------------\n");
+ if( major.printKnownIssues() ) {
+ fprintf(stdout, " To run suppressed tests, use the -K option. \n");
+ }
if (major.getErrors() == 0) {
/* Call it twice to make sure that the defaults were reset. */
/* Call it before the OK message to verify proper cleanup. */
u_cleanup();
- u_cleanup();
+ u_cleanup();
fprintf(stdout, "OK: All tests passed without error.\n");
+
+ if (major.getDataErrors() != 0) {
+ fprintf(stdout, "\t*WARNING* some data-loading errors were ignored by the -w option.\n");
+ }
}else{
fprintf(stdout, "Errors in total: %ld.\n", (long)major.getErrors());
major.printErrors();
+ if(summary_file != NULL) {
+ FILE *summf = fopen(summary_file, "w");
+ if( summf != NULL) {
+ char buf[10000];
+ int32_t length = errorList.extract(0, errorList.length(), buf, sizeof(buf));
+ fwrite(buf, sizeof(*buf), length, (FILE*)summf);
+ fclose(summf);
+ }
+ }
+
+
+ if (major.getDataErrors() != 0) {
+ fprintf(stdout, "\t*Note* some errors are data-loading related. If the data used is not the \n"
+ "\tstock ICU data (i.e some have been added or removed), consider using\n"
+ "\tthe '-w' option to turn these errors into warnings.\n");
+ }
+
/* Call afterwards to display errors. */
u_cleanup();
}
+#ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS
+ unistr_printLengths();
+#endif
+
fprintf(stdout, "--------------------------------------\n");
if (execCount <= 0) {
fprintf(stdout, "***** Not all called tests actually exist! *****\n");
}
+ if(!no_time) {
+ endTime = uprv_getRawUTCtime();
+ diffTime = (int32_t)(endTime - startTime);
+ printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
+ (int)((diffTime%U_MILLIS_PER_DAY)/U_MILLIS_PER_HOUR),
+ (int)((diffTime%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE),
+ (int)((diffTime%U_MILLIS_PER_MINUTE)/U_MILLIS_PER_SECOND),
+ (int)(diffTime%U_MILLIS_PER_SECOND));
+ }
+
+ if(ctest_xml_fini())
+ return 1;
+
return major.getErrors();
}
const char* tdrelativepath;
#if defined (U_TOPBUILDDIR)
- tdrelativepath = "test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING;
+ tdrelativepath = "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
directory = U_TOPBUILDDIR;
#else
- tdrelativepath = ".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"out"U_FILE_SEP_STRING;
+ tdrelativepath = ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "out" U_FILE_SEP_STRING;
directory = pathToDataDirectory();
#endif
if(U_FAILURE(err)){
err = U_FILE_ACCESS_ERROR;
- it_errln((UnicodeString)"Could not load testtypes.res in testdata bundle with path " + tdpath + (UnicodeString)" - " + u_errorName(err));
+ it_dataerrln((UnicodeString)"Could not load testtypes.res in testdata bundle with path " + tdpath + (UnicodeString)" - " + u_errorName(err));
return "";
}
ures_close(test);
const char *IntlTest::getSourceTestData(UErrorCode& /*err*/) {
const char *srcDataDir = NULL;
#ifdef U_TOPSRCDIR
- srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
+ srcDataDir = U_TOPSRCDIR U_FILE_SEP_STRING"test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
#else
- srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
- FILE *f = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING"rbbitst.txt", "r");
+ srcDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING;
+ FILE *f = fopen(".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "test" U_FILE_SEP_STRING "testdata" U_FILE_SEP_STRING "rbbitst.txt", "r");
if (f) {
/* We're in icu/source/test/intltest/ */
fclose(f);
}
else {
- /* We're in icu/source/test/intltest/(Debug|Release) */
- srcDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING;
+ /* We're in icu/source/test/intltest/Platform/(Debug|Release) */
+ 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;
}
#endif
return srcDataDir;
}
+char *IntlTest::getUnidataPath(char path[]) {
+ const int kUnicodeDataTxtLength = 15; // strlen("UnicodeData.txt")
+
+ // Look inside ICU_DATA first.
+ strcpy(path, pathToDataDirectory());
+ strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
+ FILE *f = fopen(path, "r");
+ if(f != NULL) {
+ fclose(f);
+ *(strchr(path, 0) - kUnicodeDataTxtLength) = 0; // Remove the basename.
+ return path;
+ }
+
+ // As a fallback, try to guess where the source data was located
+ // at the time ICU was built, and look there.
+# ifdef U_TOPSRCDIR
+ strcpy(path, U_TOPSRCDIR U_FILE_SEP_STRING "data");
+# else
+ UErrorCode errorCode = U_ZERO_ERROR;
+ const char *testDataPath = loadTestData(errorCode);
+ if(U_FAILURE(errorCode)) {
+ it_errln(UnicodeString(
+ "unable to find path to source/data/unidata/ and loadTestData() failed: ") +
+ u_errorName(errorCode));
+ return NULL;
+ }
+ strcpy(path, testDataPath);
+ strcat(path, U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
+ U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".."
+ U_FILE_SEP_STRING "data");
+# endif
+ strcat(path, U_FILE_SEP_STRING);
+ strcat(path, "unidata" U_FILE_SEP_STRING "UnicodeData.txt");
+ f = fopen(path, "r");
+ if(f != NULL) {
+ fclose(f);
+ *(strchr(path, 0) - kUnicodeDataTxtLength) = 0; // Remove the basename.
+ return path;
+ }
+ return NULL;
+}
+
const char* IntlTest::fgDataDir = NULL;
/* returns the path to icu/source/data */
}
else {
/* __FILE__ on MSVC7 does not contain the directory */
- FILE *file = fopen(".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
+ FILE *file = fopen(".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING "Makefile.in", "r");
if (file) {
fclose(file);
- fgDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
+ fgDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
}
else {
- fgDataDir = ".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING".."U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
+ fgDataDir = ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING ".." U_FILE_SEP_STRING "data" U_FILE_SEP_STRING;
}
}
}
/*
* This is a variant of cintltst/ccolltst.c:CharsToUChars().
- * It converts a character string into a UnicodeString, with
+ * It converts an invariant-character string into a UnicodeString, with
* unescaping \u sequences.
*/
-UnicodeString CharsToUnicodeString(const char* chars)
-{
- UnicodeString str(chars, ""); // Invariant conversion
- return str.unescape();
+UnicodeString CharsToUnicodeString(const char* chars){
+ return UnicodeString(chars, -1, US_INV).unescape();
}
UnicodeString ctou(const char* chars) {
return random(&RAND_SEED);
}
+
+/*
+ * Integer random number class implementation.
+ * Similar to C++ std::minstd_rand, with the same algorithm & constants.
+ */
+IntlTest::icu_rand::icu_rand(uint32_t seed) {
+ seed = seed % 2147483647UL;
+ if (seed == 0) {
+ seed = 1;
+ }
+ fLast = seed;
+}
+
+IntlTest::icu_rand::~icu_rand() {}
+
+void IntlTest::icu_rand::seed(uint32_t seed) {
+ if (seed == 0) {
+ seed = 1;
+ }
+ fLast = seed;
+}
+
+uint32_t IntlTest::icu_rand::operator() () {
+ fLast = ((uint64_t)fLast * 48271UL) % 2147483647UL;
+ return fLast;
+}
+
+uint32_t IntlTest::icu_rand::getSeed() {
+ return (uint32_t) fLast;
+}
+
+
+
static inline UChar toHex(int32_t i) {
return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10)));
}
#define VERBOSE_ASSERTIONS
-UBool IntlTest::assertTrue(const char* message, UBool condition, UBool quiet) {
- if (!condition) {
- errln("FAIL: assertTrue() failed: %s", message);
- } else if (!quiet) {
- logln("Ok: %s", message);
+UBool IntlTest::assertTrue(const char* message, UBool condition, UBool quiet, UBool possibleDataError, const char *file, int line) {
+ if (file != NULL) {
+ if (!condition) {
+ if (possibleDataError) {
+ dataerrln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
+ } else {
+ errln("%s:%d: FAIL: assertTrue() failed: %s", file, line, message);
+ }
+ } else if (!quiet) {
+ logln("%s:%d: Ok: %s", file, line, message);
+ }
+ } else {
+ if (!condition) {
+ if (possibleDataError) {
+ dataerrln("FAIL: assertTrue() failed: %s", message);
+ } else {
+ errln("FAIL: assertTrue() failed: %s", message);
+ }
+ } else if (!quiet) {
+ logln("Ok: %s", message);
+ }
+
}
return condition;
}
-UBool IntlTest::assertFalse(const char* message, UBool condition, UBool quiet) {
+UBool IntlTest::assertFalse(const char* message, UBool condition, UBool quiet, UBool possibleDataError) {
if (condition) {
- errln("FAIL: assertFalse() failed: %s", message);
+ if (possibleDataError) {
+ dataerrln("FAIL: assertTrue() failed: %s", message);
+ } else {
+ errln("FAIL: assertTrue() failed: %s", message);
+ }
} else if (!quiet) {
logln("Ok: %s", message);
}
return !condition;
}
-UBool IntlTest::assertSuccess(const char* message, UErrorCode ec) {
+UBool IntlTest::assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError, const char *file, int line) {
+ if( file==NULL ) {
+ file = ""; // prevent failure if no file given
+ }
if (U_FAILURE(ec)) {
- errln("FAIL: %s (%s)", message, u_errorName(ec));
+ if (possibleDataError) {
+ dataerrln("FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
+ } else {
+ errcheckln(ec, "FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec));
+ }
return FALSE;
+ } else {
+ logln("OK: %s:%d: %s - (%s)", file, line, message, u_errorName(ec));
}
return TRUE;
}
UBool IntlTest::assertEquals(const char* message,
const UnicodeString& expected,
- const UnicodeString& actual) {
+ const UnicodeString& actual,
+ UBool possibleDataError) {
if (expected != actual) {
- errln((UnicodeString)"FAIL: " + message + "; got " +
- prettify(actual) +
- "; expected " + prettify(expected));
+ if (possibleDataError) {
+ dataerrln((UnicodeString)"FAIL: " + message + "; got " +
+ prettify(actual) +
+ "; expected " + prettify(expected));
+ } else {
+ errln((UnicodeString)"FAIL: " + message + "; got " +
+ prettify(actual) +
+ "; expected " + prettify(expected));
+ }
return FALSE;
}
#ifdef VERBOSE_ASSERTIONS
return TRUE;
}
-#if !UCONFIG_NO_FORMATTING
UBool IntlTest::assertEquals(const char* message,
- const Formattable& expected,
- const Formattable& actual) {
+ int32_t expected,
+ int32_t actual) {
+ if (expected != actual) {
+ errln((UnicodeString)"FAIL: " + message + "; got " +
+ actual + "=0x" + toHex(actual) +
+ "; expected " + expected + "=0x" + toHex(expected));
+ return FALSE;
+ }
+#ifdef VERBOSE_ASSERTIONS
+ else {
+ logln((UnicodeString)"Ok: " + message + "; got " + actual + "=0x" + toHex(actual));
+ }
+#endif
+ return TRUE;
+}
+
+UBool IntlTest::assertEquals(const char* message,
+ int64_t expected,
+ int64_t actual) {
+ if (expected != actual) {
+ errln((UnicodeString)"FAIL: " + message + "; got int64 " +
+ Int64ToUnicodeString(actual) +
+ "; expected " + Int64ToUnicodeString(expected) );
+ return FALSE;
+ }
+#ifdef VERBOSE_ASSERTIONS
+ else {
+ logln((UnicodeString)"Ok: " + message + "; got int64 " + Int64ToUnicodeString(actual));
+ }
+#endif
+ return TRUE;
+}
+
+UBool IntlTest::assertEquals(const char* message,
+ double expected,
+ double actual) {
+ bool bothNaN = std::isnan(expected) && std::isnan(actual);
+ if (expected != actual && !bothNaN) {
+ errln((UnicodeString)"FAIL: " + message + "; got " +
+ actual +
+ "; expected " + expected);
+ return FALSE;
+ }
+#ifdef VERBOSE_ASSERTIONS
+ else {
+ logln((UnicodeString)"Ok: " + message + "; got " + actual);
+ }
+#endif
+ return TRUE;
+}
+
+
+UBool IntlTest::assertEquals(const char* message,
+ UBool expected,
+ UBool actual) {
if (expected != actual) {
errln((UnicodeString)"FAIL: " + message + "; got " +
toString(actual) +
"; expected " + toString(expected));
return FALSE;
}
+#ifdef VERBOSE_ASSERTIONS
+ else {
+ logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
+ }
+#endif
+ return TRUE;
+}
+
+
+UBool IntlTest::assertEquals(const char* message,
+ UErrorCode expected,
+ UErrorCode actual) {
+ if (expected != actual) {
+ errln((UnicodeString)"FAIL: " + message + "; got " +
+ u_errorName(actual) +
+ "; expected " + u_errorName(expected));
+ return FALSE;
+ }
+#ifdef VERBOSE_ASSERTIONS
+ else {
+ logln((UnicodeString)"Ok: " + message + "; got " + u_errorName(actual));
+ }
+#endif
+ return TRUE;
+}
+
+UBool IntlTest::assertEquals(const char* message,
+ const UnicodeSet& expected,
+ const UnicodeSet& actual) {
+ IcuTestErrorCode status(*this, "assertEqualsUniSet");
+ if (expected != actual) {
+ errln((UnicodeString)"FAIL: " + message + "; got " +
+ toString(actual, status) +
+ "; expected " + toString(expected, status));
+ return FALSE;
+ }
+#ifdef VERBOSE_ASSERTIONS
+ else {
+ logln((UnicodeString)"Ok: " + message + "; got " + toString(actual, status));
+ }
+#endif
+ return TRUE;
+}
+
+
+#if !UCONFIG_NO_FORMATTING
+UBool IntlTest::assertEquals(const char* message,
+ const Formattable& expected,
+ const Formattable& actual,
+ UBool possibleDataError) {
+ if (expected != actual) {
+ if (possibleDataError) {
+ dataerrln((UnicodeString)"FAIL: " + message + "; got " +
+ toString(actual) +
+ "; expected " + toString(expected));
+ } else {
+ errln((UnicodeString)"FAIL: " + message + "; got " +
+ toString(actual) +
+ "; expected " + toString(expected));
+ }
+ return FALSE;
+ }
#ifdef VERBOSE_ASSERTIONS
else {
logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
return ASSERT_BUF;
}
-UBool IntlTest::assertTrue(const UnicodeString& message, UBool condition, UBool quiet) {
- return assertTrue(extractToAssertBuf(message), condition, quiet);
+UBool IntlTest::assertTrue(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) {
+ return assertTrue(extractToAssertBuf(message), condition, quiet, possibleDataError);
}
-UBool IntlTest::assertFalse(const UnicodeString& message, UBool condition, UBool quiet) {
- return assertFalse(extractToAssertBuf(message), condition, quiet);
+UBool IntlTest::assertFalse(const UnicodeString& message, UBool condition, UBool quiet, UBool possibleDataError) {
+ return assertFalse(extractToAssertBuf(message), condition, quiet, possibleDataError);
}
UBool IntlTest::assertSuccess(const UnicodeString& message, UErrorCode ec) {
UBool IntlTest::assertEquals(const UnicodeString& message,
const UnicodeString& expected,
- const UnicodeString& actual) {
- return assertEquals(extractToAssertBuf(message), expected, actual);
+ const UnicodeString& actual,
+ UBool possibleDataError) {
+ return assertEquals(extractToAssertBuf(message), expected, actual, possibleDataError);
}
UBool IntlTest::assertEquals(const UnicodeString& message,
const char* actual) {
return assertEquals(extractToAssertBuf(message), expected, actual);
}
-//--------------------------------------------------------------------
-// Time bomb - allows temporary behavior that expires at a given
-// release
-//--------------------------------------------------------------------
-
-UBool IntlTest::isICUVersionAtLeast(const UVersionInfo x) {
- UVersionInfo v;
- u_getVersion(v);
- return (uprv_memcmp(v, x, U_MAX_VERSION_LENGTH) >= 0);
+UBool IntlTest::assertEquals(const UnicodeString& message,
+ UBool expected,
+ UBool actual) {
+ return assertEquals(extractToAssertBuf(message), expected, actual);
+}
+UBool IntlTest::assertEquals(const UnicodeString& message,
+ int32_t expected,
+ int32_t actual) {
+ return assertEquals(extractToAssertBuf(message), expected, actual);
+}
+UBool IntlTest::assertEquals(const UnicodeString& message,
+ int64_t expected,
+ int64_t actual) {
+ return assertEquals(extractToAssertBuf(message), expected, actual);
+}
+UBool IntlTest::assertEquals(const UnicodeString& message,
+ double expected,
+ double actual) {
+ return assertEquals(extractToAssertBuf(message), expected, actual);
+}
+UBool IntlTest::assertEquals(const UnicodeString& message,
+ UErrorCode expected,
+ UErrorCode actual) {
+ return assertEquals(extractToAssertBuf(message), expected, actual);
+}
+UBool IntlTest::assertEquals(const UnicodeString& message,
+ const UnicodeSet& expected,
+ const UnicodeSet& actual) {
+ return assertEquals(extractToAssertBuf(message), expected, actual);
}
#if !UCONFIG_NO_FORMATTING
}
#endif
+void IntlTest::setProperty(const char* propline) {
+ if (numProps < kMaxProps) {
+ proplines[numProps] = propline;
+ }
+ numProps++;
+}
+
+const char* IntlTest::getProperty(const char* prop) {
+ const char* val = NULL;
+ for (int32_t i = 0; i < numProps; i++) {
+ int32_t plen = static_cast<int32_t>(uprv_strlen(prop));
+ if ((int32_t)uprv_strlen(proplines[i]) > plen + 1
+ && proplines[i][plen] == '='
+ && uprv_strncmp(proplines[i], prop, plen) == 0) {
+ val = &(proplines[i][plen+1]);
+ break;
+ }
+ }
+ return val;
+}
+
/*
* Hey, Emacs, please set the following:
*