X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/4388f060552cc537e71e957d32f35e9d75a61233..4f1e1a09ce4daed860e35d359ce2fceccb0764e8:/icuSources/test/intltest/intltest.cpp diff --git a/icuSources/test/intltest/intltest.cpp b/icuSources/test/intltest/intltest.cpp index 58563504..e85ba87f 100644 --- a/icuSources/test/intltest/intltest.cpp +++ b/icuSources/test/intltest/intltest.cpp @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2011, International Business Machines Corporation and + * Copyright (c) 1997-2016, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -11,34 +13,38 @@ * IntlTest is a base class for tests. */ -#include -#include #include #include +#include #include +#include +#include -#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" -#include "putilimp.h" // for uprv_getRawUTCtime() -#include "unicode/locid.h" -#include "unicode/ctest.h" // for str_timeDelta - #ifdef XP_MAC_CONSOLE #include #include "Files.h" @@ -49,6 +55,8 @@ static char* _testDataPath=NULL; // 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 @@ -102,6 +110,18 @@ Int64ToUnicodeString(int64_t num) 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, @@ -120,6 +140,14 @@ operator+(const UnicodeString& left, return left + buffer; } +#if 0 +UnicodeString +operator+(const UnicodeString& left, + int64_t num) { + return left + Int64ToUnicodeString(num); +} +#endif + #if !UCONFIG_NO_FORMATTING /** @@ -204,6 +232,18 @@ UnicodeString toString(int32_t n) { 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; } @@ -233,22 +273,37 @@ IntlTest::appendHex(uint32_t number, 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; @@ -258,6 +313,13 @@ IntlTest::appendHex(uint32_t number, 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); } @@ -413,7 +475,7 @@ void IntlTest::setICU_DATA() { } 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; } } @@ -508,15 +570,17 @@ IntlTest::IntlTest() errorCount = 0; dataErrorCount = 0; verbose = FALSE; + no_time = FALSE; no_err_msg = FALSE; warn_on_missing_data = FALSE; quick = FALSE; leaks = FALSE; - threadCount = 1; + threadCount = 12; testoutfp = stdout; LL_indentlevel = indentLevel_offset; numProps = 0; strcpy(basePath, "/"); + currName[0]=0; } void IntlTest::setCaller( IntlTest* callingTest ) @@ -527,6 +591,7 @@ void IntlTest::setCaller( IntlTest* callingTest ) 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; @@ -558,6 +623,13 @@ 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; @@ -644,10 +716,10 @@ UBool IntlTest::runTest( char* name, char* par, char *baseName ) 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; @@ -655,8 +727,7 @@ void IntlTest::runIndexedTest( int32_t index, UBool exec, const char* &name, cha default: name = ""; break; } */ - this->errln("*** runIndexedTest needs to be overriden! ***"); - name = ""; exec = exec; index = index; par = par; + this->errln("*** runIndexedTest needs to be overridden! ***"); } @@ -705,12 +776,18 @@ UBool IntlTest::runTestLoop( char* testname, char* par, char *baseName ) 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 secs[256]; - sprintf(secs, "%f", (timeStop-timeStart)/1000.0); + if(!no_time) { + sprintf(secs, "%f", (timeStop-timeStart)/1000.0); + } else { + secs[0]=0; + } strcpy(saveBaseLoc,name); @@ -723,11 +800,11 @@ UBool IntlTest::runTestLoop( char* testname, char* par, char *baseName ) if (lastErrorCount == errorCount) { sprintf( msg, " } OK: %s ", name ); - str_timeDelta(msg+strlen(msg),timeStop-timeStart); + if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart); lastTestFailed = FALSE; }else{ sprintf(msg, " } ERRORS (%li) in %s", (long)(errorCount-lastErrorCount), name); - str_timeDelta(msg+strlen(msg),timeStop-timeStart); + if(!no_time) str_timeDelta(msg+strlen(msg),timeStop-timeStart); for(int i=0;i 0) { - length = length > 10000 ? 10000 : length; + length = length > 30000 ? 30000 : length; fwrite(buffer, sizeof(*buffer), length, (FILE *)testoutfp); } @@ -1066,6 +1206,10 @@ IntlTest::run_phase2( char* name, char* par ) // supports reporting memory leaks # define TRY_CNV_2 "sjis" #endif +#ifdef UNISTR_COUNT_FINAL_STRING_LENGTHS +U_CAPI void unistr_printLengths(); +#endif + int main(int argc, char* argv[]) { @@ -1073,12 +1217,15 @@ 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 = 1; + int32_t threadCount = 12; UErrorCode errorCode = U_ZERO_ERROR; UConverter *cnv = NULL; const char *warnOrErr = "Failure"; @@ -1106,9 +1253,20 @@ main(int argc, char* argv[]) 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("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"); @@ -1151,9 +1309,9 @@ main(int argc, char* argv[]) "### \n" "### Options are: verbose (v), all (a), noerrormsg (n), \n" "### exhaustive (e), leaks (l), -x xmlfile.xml, prop:=, \n" - "### threads: (Mulithreading must first be \n" - "### enabled otherwise this will be ignored. \n" - "### The default thread count is 1.),\n" + "### notime (T), \n" + "### threads:\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" @@ -1173,7 +1331,6 @@ main(int argc, char* argv[]) fprintf(stdout, "### Too many properties. Exiting.\n"); } - UBool all_tests_exist = TRUE; MajorTestLevel major; major.setVerbose( verbose ); major.setNoErrMsg( no_err_msg ); @@ -1181,6 +1338,7 @@ main(int argc, char* argv[]) 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]); } @@ -1212,17 +1370,19 @@ main(int argc, char* argv[]) 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")); -#if (ICU_USE_THREADS==0) - fprintf(stdout, " Threads : Disabled\n"); -#else fprintf(stdout, " Threads : %d\n", threadCount); -#endif for (int32_t i = 0; i < nProps; i++) { fprintf(stdout, " Custom property (prop:) : %s\n", props[i]); } fprintf(stdout, "-----------------------------------------------\n"); + 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 @@ -1241,6 +1401,9 @@ main(int argc, char* argv[]) defaultDataFound = TRUE; } u_cleanup(); + if(utf8) { + ucnv_setDefaultName("utf-8"); + } errorCode = U_ZERO_ERROR; /* Initialize ICU */ @@ -1260,7 +1423,6 @@ main(int argc, char* argv[]) } } - // initial check for the default converter errorCode = U_ZERO_ERROR; cnv = ucnv_open(0, &errorCode); @@ -1341,7 +1503,6 @@ main(int argc, char* argv[]) } 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++; @@ -1363,6 +1524,9 @@ main(int argc, char* argv[]) } 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. */ @@ -1378,6 +1542,16 @@ main(int argc, char* argv[]) 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" @@ -1389,18 +1563,24 @@ main(int argc, char* argv[]) 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"); } - 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(!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; @@ -1416,10 +1596,10 @@ const char* IntlTest::loadTestData(UErrorCode& err){ 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 @@ -1455,22 +1635,65 @@ const char* IntlTest::getTestDataPath(UErrorCode& err) { 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/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; + 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 */ @@ -1523,13 +1746,13 @@ const char * IntlTest::pathToDataDirectory() } 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".."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; } } } @@ -1596,6 +1819,39 @@ float IntlTest::random() { 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))); } @@ -1619,37 +1875,58 @@ static UnicodeString& escape(const UnicodeString& s, UnicodeString& result) { #define VERBOSE_ASSERTIONS -UBool IntlTest::assertTrue(const char* message, UBool condition, UBool quiet, UBool possibleDataError) { - if (!condition) { - if (possibleDataError) { - dataerrln("FAIL: assertTrue() failed: %s", message); - } else { - errln("FAIL: assertTrue() failed: %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 (!quiet) { - logln("Ok: %s", 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 possibleDataError) { +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)) { if (possibleDataError) { - dataerrln("FAIL: %s (%s)", message, u_errorName(ec)); + dataerrln("FAIL: %s:%d: %s (%s)", file, line, message, u_errorName(ec)); } else { - errcheckln(ec, "FAIL: %s (%s)", message, u_errorName(ec)); + 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; } @@ -1695,16 +1972,130 @@ UBool IntlTest::assertEquals(const char* message, 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)); @@ -1724,12 +2115,12 @@ static const char* extractToAssertBuf(const UnicodeString& message) { 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) { @@ -1738,8 +2129,9 @@ 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, @@ -1747,16 +2139,35 @@ 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::isICUVersionBefore(int major, int minor, int milli) { - UVersionInfo iv; - UVersionInfo ov = { (uint8_t)major, (uint8_t)minor, (uint8_t)milli, 0 }; - u_getVersion(iv); - return uprv_memcmp(iv, ov, 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