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