1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2013, 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_END \
121        name = ""; \
122        break; \
123    }
124
125#define TEST_ASSERT_TRUE(x) \
126  assertTrue(#x, (x), FALSE, FALSE, __FILE__, __LINE__)
127
128#define TEST_ASSERT_STATUS(x) \
129  assertSuccess(#x, (x), FALSE, __FILE__, __LINE__)
130
131class IntlTest : public TestLog {
132public:
133
134    IntlTest();
135    // TestLog has a virtual destructor.
136
137    virtual UBool runTest( char* name = NULL, char* par = NULL, char *baseName = NULL); // not to be overidden
138
139    virtual UBool setVerbose( UBool verbose = TRUE );
140    virtual UBool setNoErrMsg( UBool no_err_msg = TRUE );
141    virtual UBool setQuick( UBool quick = TRUE );
142    virtual UBool setLeaks( UBool leaks = TRUE );
143    virtual UBool setNotime( UBool no_time = TRUE );
144    virtual UBool setWarnOnMissingData( UBool warn_on_missing_data = TRUE );
145    virtual int32_t setThreadCount( int32_t count = 1);
146
147    virtual int32_t getErrors( void );
148    virtual int32_t getDataErrors (void );
149
150    virtual void setCaller( IntlTest* callingTest ); // for internal use only
151    virtual void setPath( char* path ); // for internal use only
152
153    virtual void log( const UnicodeString &message );
154
155    virtual void logln( const UnicodeString &message );
156
157    virtual void logln( void );
158
159    /**
160     * Replaces isICUVersionAtLeast and isICUVersionBefore
161     * log that an issue is known.
162     * Usually used this way:
163     * <code>if( ... && logKnownIssue("12345", "some bug")) continue; </code>
164     * @param ticket ticket string, "12345" or "cldrbug:1234"
165     * @param message optional message string
166     * @return true if test should be skipped
167     */
168    UBool logKnownIssue( const char *ticket, const UnicodeString &message );
169    /**
170     * Replaces isICUVersionAtLeast and isICUVersionBefore
171     * log that an issue is known.
172     * Usually used this way:
173     * <code>if( ... && logKnownIssue("12345", "some bug")) continue; </code>
174     * @param ticket ticket string, "12345" or "cldrbug:1234"
175     * @return true if test should be skipped
176     */
177    UBool logKnownIssue( const char *ticket );
178    /**
179     * Replaces isICUVersionAtLeast and isICUVersionBefore
180     * log that an issue is known.
181     * Usually used this way:
182     * <code>if( ... && logKnownIssue("12345", "some bug")) continue; </code>
183     * @param ticket ticket string, "12345" or "cldrbug:1234"
184     * @param message optional message string
185     * @return true if test should be skipped
186     */
187    UBool logKnownIssue( const char *ticket, const char *fmt, ...);
188
189    virtual void info( const UnicodeString &message );
190
191    virtual void infoln( const UnicodeString &message );
192
193    virtual void infoln( void );
194
195    virtual void err(void);
196
197    virtual void err( const UnicodeString &message );
198
199    virtual void errln( const UnicodeString &message );
200
201    virtual void dataerr( const UnicodeString &message );
202
203    virtual void dataerrln( const UnicodeString &message );
204
205    void errcheckln(UErrorCode status, const UnicodeString &message );
206
207    // convenience functions: sprintf() + errln() etc.
208    void log(const char *fmt, ...);
209    void logln(const char *fmt, ...);
210    void info(const char *fmt, ...);
211    void infoln(const char *fmt, ...);
212    void err(const char *fmt, ...);
213    void errln(const char *fmt, ...);
214    void dataerr(const char *fmt, ...);
215    void dataerrln(const char *fmt, ...);
216
217    /**
218     * logs an error (even if status==U_ZERO_ERROR), but
219     * calls dataerrln() or errln() depending on the type of error.
220     * Does not report the status code.
221     * @param status parameter for selecting whether errln or dataerrln is called.
222     */
223    void errcheckln(UErrorCode status, const char *fmt, ...);
224
225    // Print ALL named errors encountered so far
226    void printErrors();
227
228    // print known issues. return TRUE if there were any.
229    UBool printKnownIssues();
230
231    virtual void usage( void ) ;
232
233    /**
234     * Returns a uniform random value x, with 0.0 <= x < 1.0.  Use
235     * with care: Does not return all possible values; returns one of
236     * 714,025 values, uniformly spaced.  However, the period is
237     * effectively infinite.  See: Numerical Recipes, section 7.1.
238     *
239     * @param seedp pointer to seed. Set *seedp to any negative value
240     * to restart the sequence.
241     */
242    static float random(int32_t* seedp);
243
244    /**
245     * Convenience method using a global seed.
246     */
247    static float random();
248
249    enum { kMaxProps = 16 };
250
251    virtual void setProperty(const char* propline);
252    virtual const char* getProperty(const char* prop);
253
254protected:
255    /* JUnit-like assertions. Each returns TRUE if it succeeds. */
256    UBool assertTrue(const char* message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE, const char *file=NULL, int line=0);
257    UBool assertFalse(const char* message, UBool condition, UBool quiet=FALSE);
258    /**
259     * @param possibleDataError - if TRUE, use dataerrln instead of errcheckln on failure
260     * @return TRUE on success, FALSE on failure.
261     */
262    UBool assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError=FALSE, const char *file=NULL, int line=0);
263    UBool assertEquals(const char* message, const UnicodeString& expected,
264                       const UnicodeString& actual, UBool possibleDataError=FALSE);
265    UBool assertEquals(const char* message, const char* expected,
266                       const char* actual);
267    UBool assertEquals(const char* message, UBool expected,
268                       UBool actual);
269    UBool assertEquals(const char* message, int32_t expected, int32_t actual);
270    UBool assertEquals(const char* message, int64_t expected, int64_t actual);
271#if !UCONFIG_NO_FORMATTING
272    UBool assertEquals(const char* message, const Formattable& expected,
273                       const Formattable& actual, UBool possibleDataError=FALSE);
274    UBool assertEquals(const UnicodeString& message, const Formattable& expected,
275                       const Formattable& actual);
276#endif
277    UBool assertTrue(const UnicodeString& message, UBool condition, UBool quiet=FALSE);
278    UBool assertFalse(const UnicodeString& message, UBool condition, UBool quiet=FALSE);
279    UBool assertSuccess(const UnicodeString& message, UErrorCode ec);
280    UBool assertEquals(const UnicodeString& message, const UnicodeString& expected,
281                       const UnicodeString& actual, UBool possibleDataError=FALSE);
282    UBool assertEquals(const UnicodeString& message, const char* expected,
283                       const char* actual);
284    UBool assertEquals(const UnicodeString& message, UBool expected, UBool actual);
285    UBool assertEquals(const UnicodeString& message, int32_t expected, int32_t actual);
286    UBool assertEquals(const UnicodeString& message, int64_t expected, int64_t actual);
287
288    virtual void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide !
289
290    virtual UBool runTestLoop( char* testname, char* par, char *baseName );
291
292    virtual int32_t IncErrorCount( void );
293
294    virtual int32_t IncDataErrorCount( void );
295
296    virtual UBool callTest( IntlTest& testToBeCalled, char* par );
297
298
299    UBool       verbose;
300    UBool       no_err_msg;
301    UBool       quick;
302    UBool       leaks;
303    UBool       warn_on_missing_data;
304    UBool       no_time;
305    int32_t     threadCount;
306
307private:
308    UBool       LL_linestart;
309    int32_t     LL_indentlevel;
310
311    int32_t     errorCount;
312    int32_t     dataErrorCount;
313    IntlTest*   caller;
314    char*       testPath;           // specifies subtests
315
316    char basePath[1024];
317    char currName[1024]; // current test name
318
319    //FILE *testoutfp;
320    void *testoutfp;
321
322    const char* proplines[kMaxProps];
323    int32_t     numProps;
324
325protected:
326
327    virtual void LL_message( UnicodeString message, UBool newline );
328
329    // used for collation result reporting, defined here for convenience
330
331    static UnicodeString &prettify(const UnicodeString &source, UnicodeString &target);
332    static UnicodeString prettify(const UnicodeString &source, UBool parseBackslash=FALSE);
333    // digits=-1 determines the number of digits automatically
334    static UnicodeString &appendHex(uint32_t number, int32_t digits, UnicodeString &target);
335    static UnicodeString toHex(uint32_t number, int32_t digits=-1);
336    static inline UnicodeString toHex(int32_t number, int32_t digits=-1) {
337        return toHex((uint32_t)number, digits);
338    }
339
340public:
341    static void setICU_DATA();       // Set up ICU_DATA if necessary.
342
343    static const char* pathToDataDirectory();
344
345public:
346    UBool run_phase2( char* name, char* par ); // internally, supports reporting memory leaks
347    static const char* loadTestData(UErrorCode& err);
348    virtual const char* getTestDataPath(UErrorCode& err);
349    static const char* getSourceTestData(UErrorCode& err);
350
351// static members
352public:
353    static IntlTest* gTest;
354    static const char* fgDataDir;
355
356};
357
358void it_log( UnicodeString message );
359void it_logln( UnicodeString message );
360void it_logln( void );
361void it_info( UnicodeString message );
362void it_infoln( UnicodeString message );
363void it_infoln( void );
364void it_err(void);
365void it_err( UnicodeString message );
366void it_errln( UnicodeString message );
367void it_dataerr( UnicodeString message );
368void it_dataerrln( UnicodeString message );
369
370/**
371 * This is a variant of cintltst/ccolltst.c:CharsToUChars().
372 * It converts a character string into a UnicodeString, with
373 * unescaping \u sequences.
374 */
375extern UnicodeString CharsToUnicodeString(const char* chars);
376
377/* alias for CharsToUnicodeString */
378extern UnicodeString ctou(const char* chars);
379
380#endif // _INTLTEST
381