1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2014, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ********************************************************************/ 6 7 8 /** 9 * IntlTest is a base class for tests. */ 10 11 #ifndef _INTLTEST 12 #define _INTLTEST 13 14 // The following includes utypes.h, uobject.h and unistr.h 15 #include "unicode/fmtable.h" 16 #include "unicode/testlog.h" 17 18 19 #if U_NO_DEFAULT_INCLUDE_UTF_HEADERS 20 /* deprecated - make tests pass with U_NO_DEFAULT_INCLUDE_UTF_HEADERS */ 21 #include "unicode/utf_old.h" 22 #endif 23 24 /** 25 * \def ICU_USE_THREADS 26 * 27 * Enables multi-threaded testing. Moved here from uconfig.h. 28 * Default: enabled 29 * 30 * This switch used to allow thread support (use of mutexes) to be compiled out of ICU. 31 */ 32 #ifdef ICU_USE_THREADS 33 /* Use the predefined value. */ 34 #elif defined(APP_NO_THREADS) 35 /* APP_NO_THREADS is an old symbol. We'll honour it if present. */ 36 # define ICU_USE_THREADS 0 37 #else 38 # define ICU_USE_THREADS 1 39 #endif 40 41 U_NAMESPACE_USE 42 43 #if U_PLATFORM == U_PF_OS390 44 // avoid collision with math.h/log() 45 // this must be after including utypes.h so that U_PLATFORM is actually defined 46 #pragma map(IntlTest::log( const UnicodeString &message ),"logos390") 47 #endif 48 49 //----------------------------------------------------------------------------- 50 //convenience classes to ease porting code that uses the Java 51 //string-concatenation operator (moved from findword test by rtg) 52 UnicodeString UCharToUnicodeString(UChar c); 53 UnicodeString Int64ToUnicodeString(int64_t num); 54 //UnicodeString operator+(const UnicodeString& left, int64_t num); // Some compilers don't allow this because of the long type. 55 UnicodeString operator+(const UnicodeString& left, long num); 56 UnicodeString operator+(const UnicodeString& left, unsigned long num); 57 UnicodeString operator+(const UnicodeString& left, double num); 58 UnicodeString operator+(const UnicodeString& left, char num); 59 UnicodeString operator+(const UnicodeString& left, short num); 60 UnicodeString operator+(const UnicodeString& left, int num); 61 UnicodeString operator+(const UnicodeString& left, unsigned char num); 62 UnicodeString operator+(const UnicodeString& left, unsigned short num); 63 UnicodeString operator+(const UnicodeString& left, unsigned int num); 64 UnicodeString operator+(const UnicodeString& left, float num); 65 #if !UCONFIG_NO_FORMATTING 66 UnicodeString toString(const Formattable& f); // liu 67 UnicodeString toString(int32_t n); 68 #endif 69 UnicodeString toString(UBool b); 70 71 //----------------------------------------------------------------------------- 72 73 // Use the TESTCASE macro in subclasses of IntlTest. Define the 74 // runIndexedTest method in this fashion: 75 // 76 //| void MyTest::runIndexedTest(int32_t index, UBool exec, 77 //| const char* &name, char* /*par*/) { 78 //| switch (index) { 79 //| TESTCASE(0,TestSomething); 80 //| TESTCASE(1,TestSomethingElse); 81 //| TESTCASE(2,TestAnotherThing); 82 //| default: name = ""; break; 83 //| } 84 //| } 85 #define TESTCASE(id,test) \ 86 case id: \ 87 name = #test; \ 88 if (exec) { \ 89 logln(#test "---"); \ 90 logln(); \ 91 test(); \ 92 } \ 93 break 94 95 // More convenient macros. These allow easy reordering of the test cases. 96 // 97 //| void MyTest::runIndexedTest(int32_t index, UBool exec, 98 //| const char* &name, char* /*par*/) { 99 //| TESTCASE_AUTO_BEGIN; 100 //| TESTCASE_AUTO(TestSomething); 101 //| TESTCASE_AUTO(TestSomethingElse); 102 //| TESTCASE_AUTO(TestAnotherThing); 103 //| TESTCASE_AUTO_END; 104 //| } 105 #define TESTCASE_AUTO_BEGIN \ 106 for(;;) { \ 107 int32_t testCaseAutoNumber = 0 108 109 #define TESTCASE_AUTO(test) \ 110 if (index == testCaseAutoNumber++) { \ 111 name = #test; \ 112 if (exec) { \ 113 logln(#test "---"); \ 114 logln(); \ 115 test(); \ 116 } \ 117 break; \ 118 } 119 120 #define TESTCASE_AUTO_CLASS(TestClass) \ 121 if (index == testCaseAutoNumber++) { \ 122 name = #TestClass; \ 123 if (exec) { \ 124 logln(#TestClass "---"); \ 125 logln(); \ 126 TestClass test; \ 127 callTest(test, par); \ 128 } \ 129 break; \ 130 } 131 132 #define TESTCASE_AUTO_CREATE_CLASS(TestClass) \ 133 if (index == testCaseAutoNumber++) { \ 134 name = #TestClass; \ 135 if (exec) { \ 136 logln(#TestClass "---"); \ 137 logln(); \ 138 LocalPointer<IntlTest> test(create##TestClass()); \ 139 callTest(*test, par); \ 140 } \ 141 break; \ 142 } 143 144 #define TESTCASE_AUTO_END \ 145 name = ""; \ 146 break; \ 147 } 148 149 #define TEST_ASSERT_TRUE(x) \ 150 assertTrue(#x, (x), FALSE, FALSE, __FILE__, __LINE__) 151 152 #define TEST_ASSERT_STATUS(x) \ 153 assertSuccess(#x, (x), FALSE, __FILE__, __LINE__) 154 155 class IntlTest : public TestLog { 156 public: 157 158 IntlTest(); 159 // TestLog has a virtual destructor. 160 161 virtual UBool runTest( char* name = NULL, char* par = NULL, char *baseName = NULL); // not to be overidden 162 163 virtual UBool setVerbose( UBool verbose = TRUE ); 164 virtual UBool setNoErrMsg( UBool no_err_msg = TRUE ); 165 virtual UBool setQuick( UBool quick = TRUE ); 166 virtual UBool setLeaks( UBool leaks = TRUE ); 167 virtual UBool setNotime( UBool no_time = TRUE ); 168 virtual UBool setWarnOnMissingData( UBool warn_on_missing_data = TRUE ); 169 virtual int32_t setThreadCount( int32_t count = 1); 170 171 virtual int32_t getErrors( void ); 172 virtual int32_t getDataErrors (void ); 173 174 virtual void setCaller( IntlTest* callingTest ); // for internal use only 175 virtual void setPath( char* path ); // for internal use only 176 177 virtual void log( const UnicodeString &message ); 178 179 virtual void logln( const UnicodeString &message ); 180 181 virtual void logln( void ); 182 183 /** 184 * Replaces isICUVersionAtLeast and isICUVersionBefore 185 * log that an issue is known. 186 * Usually used this way: 187 * <code>if( ... && logKnownIssue("12345", "some bug")) continue; </code> 188 * @param ticket ticket string, "12345" or "cldrbug:1234" 189 * @param message optional message string 190 * @return true if test should be skipped 191 */ 192 UBool logKnownIssue( const char *ticket, const UnicodeString &message ); 193 /** 194 * Replaces isICUVersionAtLeast and isICUVersionBefore 195 * log that an issue is known. 196 * Usually used this way: 197 * <code>if( ... && logKnownIssue("12345", "some bug")) continue; </code> 198 * @param ticket ticket string, "12345" or "cldrbug:1234" 199 * @return true if test should be skipped 200 */ 201 UBool logKnownIssue( const char *ticket ); 202 /** 203 * Replaces isICUVersionAtLeast and isICUVersionBefore 204 * log that an issue is known. 205 * Usually used this way: 206 * <code>if( ... && logKnownIssue("12345", "some bug")) continue; </code> 207 * @param ticket ticket string, "12345" or "cldrbug:1234" 208 * @param message optional message string 209 * @return true if test should be skipped 210 */ 211 UBool logKnownIssue( const char *ticket, const char *fmt, ...); 212 213 virtual void info( const UnicodeString &message ); 214 215 virtual void infoln( const UnicodeString &message ); 216 217 virtual void infoln( void ); 218 219 virtual void err(void); 220 221 virtual void err( const UnicodeString &message ); 222 223 virtual void errln( const UnicodeString &message ); 224 225 virtual void dataerr( const UnicodeString &message ); 226 227 virtual void dataerrln( const UnicodeString &message ); 228 229 void errcheckln(UErrorCode status, const UnicodeString &message ); 230 231 // convenience functions: sprintf() + errln() etc. 232 void log(const char *fmt, ...); 233 void logln(const char *fmt, ...); 234 void info(const char *fmt, ...); 235 void infoln(const char *fmt, ...); 236 void err(const char *fmt, ...); 237 void errln(const char *fmt, ...); 238 void dataerr(const char *fmt, ...); 239 void dataerrln(const char *fmt, ...); 240 241 /** 242 * logs an error (even if status==U_ZERO_ERROR), but 243 * calls dataerrln() or errln() depending on the type of error. 244 * Does not report the status code. 245 * @param status parameter for selecting whether errln or dataerrln is called. 246 */ 247 void errcheckln(UErrorCode status, const char *fmt, ...); 248 249 // Print ALL named errors encountered so far 250 void printErrors(); 251 252 // print known issues. return TRUE if there were any. 253 UBool printKnownIssues(); 254 255 virtual void usage( void ) ; 256 257 /** 258 * Returns a uniform random value x, with 0.0 <= x < 1.0. Use 259 * with care: Does not return all possible values; returns one of 260 * 714,025 values, uniformly spaced. However, the period is 261 * effectively infinite. See: Numerical Recipes, section 7.1. 262 * 263 * @param seedp pointer to seed. Set *seedp to any negative value 264 * to restart the sequence. 265 */ 266 static float random(int32_t* seedp); 267 268 /** 269 * Convenience method using a global seed. 270 */ 271 static float random(); 272 273 enum { kMaxProps = 16 }; 274 275 virtual void setProperty(const char* propline); 276 virtual const char* getProperty(const char* prop); 277 278 protected: 279 /* JUnit-like assertions. Each returns TRUE if it succeeds. */ 280 UBool assertTrue(const char* message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE, const char *file=NULL, int line=0); 281 UBool assertFalse(const char* message, UBool condition, UBool quiet=FALSE); 282 /** 283 * @param possibleDataError - if TRUE, use dataerrln instead of errcheckln on failure 284 * @return TRUE on success, FALSE on failure. 285 */ 286 UBool assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError=FALSE, const char *file=NULL, int line=0); 287 UBool assertEquals(const char* message, const UnicodeString& expected, 288 const UnicodeString& actual, UBool possibleDataError=FALSE); 289 UBool assertEquals(const char* message, const char* expected, 290 const char* actual); 291 UBool assertEquals(const char* message, UBool expected, 292 UBool actual); 293 UBool assertEquals(const char* message, int32_t expected, int32_t actual); 294 UBool assertEquals(const char* message, int64_t expected, int64_t actual); 295 #if !UCONFIG_NO_FORMATTING 296 UBool assertEquals(const char* message, const Formattable& expected, 297 const Formattable& actual, UBool possibleDataError=FALSE); 298 UBool assertEquals(const UnicodeString& message, const Formattable& expected, 299 const Formattable& actual); 300 #endif 301 UBool assertTrue(const UnicodeString& message, UBool condition, UBool quiet=FALSE); 302 UBool assertFalse(const UnicodeString& message, UBool condition, UBool quiet=FALSE); 303 UBool assertSuccess(const UnicodeString& message, UErrorCode ec); 304 UBool assertEquals(const UnicodeString& message, const UnicodeString& expected, 305 const UnicodeString& actual, UBool possibleDataError=FALSE); 306 UBool assertEquals(const UnicodeString& message, const char* expected, 307 const char* actual); 308 UBool assertEquals(const UnicodeString& message, UBool expected, UBool actual); 309 UBool assertEquals(const UnicodeString& message, int32_t expected, int32_t actual); 310 UBool assertEquals(const UnicodeString& message, int64_t expected, int64_t actual); 311 312 virtual void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide ! 313 314 virtual UBool runTestLoop( char* testname, char* par, char *baseName ); 315 316 virtual int32_t IncErrorCount( void ); 317 318 virtual int32_t IncDataErrorCount( void ); 319 320 virtual UBool callTest( IntlTest& testToBeCalled, char* par ); 321 322 323 UBool verbose; 324 UBool no_err_msg; 325 UBool quick; 326 UBool leaks; 327 UBool warn_on_missing_data; 328 UBool no_time; 329 int32_t threadCount; 330 331 private: 332 UBool LL_linestart; 333 int32_t LL_indentlevel; 334 335 int32_t errorCount; 336 int32_t dataErrorCount; 337 IntlTest* caller; 338 char* testPath; // specifies subtests 339 340 char basePath[1024]; 341 char currName[1024]; // current test name 342 343 //FILE *testoutfp; 344 void *testoutfp; 345 346 const char* proplines[kMaxProps]; 347 int32_t numProps; 348 349 protected: 350 351 virtual void LL_message( UnicodeString message, UBool newline ); 352 353 // used for collation result reporting, defined here for convenience 354 355 static UnicodeString &prettify(const UnicodeString &source, UnicodeString &target); 356 static UnicodeString prettify(const UnicodeString &source, UBool parseBackslash=FALSE); 357 // digits=-1 determines the number of digits automatically 358 static UnicodeString &appendHex(uint32_t number, int32_t digits, UnicodeString &target); 359 static UnicodeString toHex(uint32_t number, int32_t digits=-1); 360 static inline UnicodeString toHex(int32_t number, int32_t digits=-1) { 361 return toHex((uint32_t)number, digits); 362 } 363 364 public: 365 static void setICU_DATA(); // Set up ICU_DATA if necessary. 366 367 static const char* pathToDataDirectory(); 368 369 public: 370 UBool run_phase2( char* name, char* par ); // internally, supports reporting memory leaks 371 static const char* loadTestData(UErrorCode& err); 372 virtual const char* getTestDataPath(UErrorCode& err); 373 static const char* getSourceTestData(UErrorCode& err); 374 static char *getUnidataPath(char path[]); 375 376 // static members 377 public: 378 static IntlTest* gTest; 379 static const char* fgDataDir; 380 381 }; 382 383 void it_log( UnicodeString message ); 384 void it_logln( UnicodeString message ); 385 void it_logln( void ); 386 void it_info( UnicodeString message ); 387 void it_infoln( UnicodeString message ); 388 void it_infoln( void ); 389 void it_err(void); 390 void it_err( UnicodeString message ); 391 void it_errln( UnicodeString message ); 392 void it_dataerr( UnicodeString message ); 393 void it_dataerrln( UnicodeString message ); 394 395 /** 396 * This is a variant of cintltst/ccolltst.c:CharsToUChars(). 397 * It converts a character string into a UnicodeString, with 398 * unescaping \u sequences. 399 */ 400 extern UnicodeString CharsToUnicodeString(const char* chars); 401 402 /* alias for CharsToUnicodeString */ 403 extern UnicodeString ctou(const char* chars); 404 405 #endif // _INTLTEST 406