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
20U_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)
31UnicodeString UCharToUnicodeString(UChar c);
32UnicodeString Int64ToUnicodeString(int64_t num);
33UnicodeString DoubleToUnicodeString(double num);
34//UnicodeString operator+(const UnicodeString& left, int64_t num); // Some compilers don't allow this because of the long type.
35UnicodeString operator+(const UnicodeString& left, long num);
36UnicodeString operator+(const UnicodeString& left, unsigned long num);
37UnicodeString operator+(const UnicodeString& left, double num);
38UnicodeString operator+(const UnicodeString& left, char num);
39UnicodeString operator+(const UnicodeString& left, short num);
40UnicodeString operator+(const UnicodeString& left, int num);
41UnicodeString operator+(const UnicodeString& left, unsigned char num);
42UnicodeString operator+(const UnicodeString& left, unsigned short num);
43UnicodeString operator+(const UnicodeString& left, unsigned int num);
44UnicodeString operator+(const UnicodeString& left, float num);
45#if !UCONFIG_NO_FORMATTING
46UnicodeString toString(const Formattable& f); // liu
47UnicodeString toString(int32_t n);
48#endif
49UnicodeString 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
135class IntlTest : public TestLog {
136public:
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
335private:
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
353protected:
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
368public:
369    static void setICU_DATA();       // Set up ICU_DATA if necessary.
370
371    static const char* pathToDataDirectory();
372
373public:
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
381public:
382    static IntlTest* gTest;
383    static const char* fgDataDir;
384
385};
386
387void it_log( UnicodeString message );
388void it_logln( UnicodeString message );
389void it_logln( void );
390void it_info( UnicodeString message );
391void it_infoln( UnicodeString message );
392void it_infoln( void );
393void it_err(void);
394void it_err( UnicodeString message );
395void it_errln( UnicodeString message );
396void it_dataerr( UnicodeString message );
397void 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 */
404extern UnicodeString CharsToUnicodeString(const char* chars);
405
406/* alias for CharsToUnicodeString */
407extern UnicodeString ctou(const char* chars);
408
409#endif // _INTLTEST
410