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
41U_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)
52UnicodeString UCharToUnicodeString(UChar c);
53UnicodeString Int64ToUnicodeString(int64_t num);
54//UnicodeString operator+(const UnicodeString& left, int64_t num); // Some compilers don't allow this because of the long type.
55UnicodeString operator+(const UnicodeString& left, long num);
56UnicodeString operator+(const UnicodeString& left, unsigned long num);
57UnicodeString operator+(const UnicodeString& left, double num);
58UnicodeString operator+(const UnicodeString& left, char num);
59UnicodeString operator+(const UnicodeString& left, short num);
60UnicodeString operator+(const UnicodeString& left, int num);
61UnicodeString operator+(const UnicodeString& left, unsigned char num);
62UnicodeString operator+(const UnicodeString& left, unsigned short num);
63UnicodeString operator+(const UnicodeString& left, unsigned int num);
64UnicodeString operator+(const UnicodeString& left, float num);
65#if !UCONFIG_NO_FORMATTING
66UnicodeString toString(const Formattable& f); // liu
67UnicodeString toString(int32_t n);
68#endif
69UnicodeString 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
155class IntlTest : public TestLog {
156public:
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
278protected:
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
331private:
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
349protected:
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
364public:
365    static void setICU_DATA();       // Set up ICU_DATA if necessary.
366
367    static const char* pathToDataDirectory();
368
369public:
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
375// static members
376public:
377    static IntlTest* gTest;
378    static const char* fgDataDir;
379
380};
381
382void it_log( UnicodeString message );
383void it_logln( UnicodeString message );
384void it_logln( void );
385void it_info( UnicodeString message );
386void it_infoln( UnicodeString message );
387void it_infoln( void );
388void it_err(void);
389void it_err( UnicodeString message );
390void it_errln( UnicodeString message );
391void it_dataerr( UnicodeString message );
392void it_dataerrln( UnicodeString message );
393
394/**
395 * This is a variant of cintltst/ccolltst.c:CharsToUChars().
396 * It converts a character string into a UnicodeString, with
397 * unescaping \u sequences.
398 */
399extern UnicodeString CharsToUnicodeString(const char* chars);
400
401/* alias for CharsToUnicodeString */
402extern UnicodeString ctou(const char* chars);
403
404#endif // _INTLTEST
405