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