You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

451 lines
17 KiB

// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2016, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
/**
* IntlTest is a base class for tests. */
#ifndef _INTLTEST
#define _INTLTEST
// The following includes utypes.h, uobject.h and unistr.h
#include "unicode/fmtable.h"
#include "unicode/testlog.h"
#include "unicode/uniset.h"
#include <vector>
#include <string>
U_NAMESPACE_USE
#if U_PLATFORM == U_PF_OS390
// avoid collision with math.h/log()
// this must be after including utypes.h so that U_PLATFORM is actually defined
#pragma map(IntlTest::log( const UnicodeString &message ),"logos390")
#endif
//-----------------------------------------------------------------------------
//convenience classes to ease porting code that uses the Java
//string-concatenation operator (moved from findword test by rtg)
UnicodeString UCharToUnicodeString(UChar c);
UnicodeString Int64ToUnicodeString(int64_t num);
UnicodeString DoubleToUnicodeString(double num);
//UnicodeString operator+(const UnicodeString& left, int64_t num); // Some compilers don't allow this because of the long type.
UnicodeString operator+(const UnicodeString& left, long num);
UnicodeString operator+(const UnicodeString& left, unsigned long num);
UnicodeString operator+(const UnicodeString& left, double num);
UnicodeString operator+(const UnicodeString& left, char num);
UnicodeString operator+(const UnicodeString& left, short num);
UnicodeString operator+(const UnicodeString& left, int num);
UnicodeString operator+(const UnicodeString& left, unsigned char num);
UnicodeString operator+(const UnicodeString& left, unsigned short num);
UnicodeString operator+(const UnicodeString& left, unsigned int num);
UnicodeString operator+(const UnicodeString& left, float num);
#if !UCONFIG_NO_FORMATTING
UnicodeString toString(const Formattable& f); // liu
UnicodeString toString(int32_t n);
#endif
UnicodeString toString(UBool b);
//-----------------------------------------------------------------------------
// Use the TESTCASE macro in subclasses of IntlTest. Define the
// runIndexedTest method in this fashion:
//
//| void MyTest::runIndexedTest(int32_t index, UBool exec,
//| const char* &name, char* /*par*/) {
//| switch (index) {
//| TESTCASE(0,TestSomething);
//| TESTCASE(1,TestSomethingElse);
//| TESTCASE(2,TestAnotherThing);
//| default: name = ""; break;
//| }
//| }
#define TESTCASE(id,test) \
case id: \
name = #test; \
if (exec) { \
logln(#test "---"); \
logln(); \
test(); \
} \
break
// More convenient macros. These allow easy reordering of the test cases.
//
//| void MyTest::runIndexedTest(int32_t index, UBool exec,
//| const char* &name, char* /*par*/) {
//| TESTCASE_AUTO_BEGIN;
//| TESTCASE_AUTO(TestSomething);
//| TESTCASE_AUTO(TestSomethingElse);
//| TESTCASE_AUTO(TestAnotherThing);
//| TESTCASE_AUTO_END;
//| }
#define TESTCASE_AUTO_BEGIN \
do { \
int32_t testCaseAutoNumber = 0
#define TESTCASE_AUTO(test) \
if (index == testCaseAutoNumber++) { \
name = #test; \
if (exec) { \
logln(#test "---"); \
logln(); \
test(); \
} \
break; \
} else (void)0
#define TESTCASE_AUTO_CLASS(TestClass) \
if (index == testCaseAutoNumber++) { \
name = #TestClass; \
if (exec) { \
logln(#TestClass "---"); \
logln(); \
TestClass test; \
callTest(test, par); \
} \
break; \
} else (void)0
#define TESTCASE_AUTO_CREATE_CLASS(TestClass) \
if (index == testCaseAutoNumber++) { \
name = #TestClass; \
if (exec) { \
logln(#TestClass "---"); \
logln(); \
LocalPointer<IntlTest> test(create##TestClass()); \
callTest(*test, par); \
} \
break; \
} else (void)0
#define TESTCASE_AUTO_END \
name = ""; \
break; \
} while (TRUE)
// WHERE Macro yields a literal string of the form "source_file_name:line number "
#define WHERE __FILE__ ":" XLINE(__LINE__) " "
#define XLINE(s) LINE(s)
#define LINE(s) #s
class IntlTest : public TestLog {
public:
IntlTest();
// TestLog has a virtual destructor.
virtual UBool runTest( char* name = NULL, char* par = NULL, char *baseName = NULL); // not to be overidden
virtual UBool setVerbose( UBool verbose = TRUE );
virtual UBool setNoErrMsg( UBool no_err_msg = TRUE );
virtual UBool setQuick( UBool quick = TRUE );
virtual UBool setLeaks( UBool leaks = TRUE );
virtual UBool setNotime( UBool no_time = TRUE );
virtual UBool setWarnOnMissingData( UBool warn_on_missing_data = TRUE );
virtual UBool setWriteGoldenData( UBool write_golden_data = TRUE );
virtual int32_t setThreadCount( int32_t count = 1);
virtual int32_t getErrors( void );
virtual int32_t getDataErrors (void );
virtual void setCaller( IntlTest* callingTest ); // for internal use only
virtual void setPath( char* path ); // for internal use only
virtual void log( const UnicodeString &message );
virtual void logln( const UnicodeString &message );
virtual void logln( void );
/**
* Logs that an issue is known. Can be called multiple times.
* Usually used this way:
* <code>if( ... && logKnownIssue("ICU-12345", "some bug")) continue; </code>
* @param ticket ticket string, "ICU-12345" or "CLDR-1234"
* @param message optional message string
* @return true if test should be skipped
*/
UBool logKnownIssue( const char *ticket, const UnicodeString &message );
/**
* Logs that an issue is known. Can be called multiple times.
* Usually used this way:
* <code>if( ... && logKnownIssue("ICU-12345", "some bug")) continue; </code>
* @param ticket ticket string, "ICU-12345" or "CLDR-1234"
* @return true if test should be skipped
*/
UBool logKnownIssue( const char *ticket );
/**
* Log that an issue is known. Can be called multiple times.
* Usually used this way:
* <code>if( ... && logKnownIssue("ICU-12345", "some bug")) continue; </code>
* @param ticket ticket string, "ICU-12345" or "CLDR-1234"
* @param message optional message string
* @return true if test should be skipped
*/
UBool logKnownIssue( const char *ticket, const char *fmt, ...);
virtual void info( const UnicodeString &message );
virtual void infoln( const UnicodeString &message );
virtual void infoln( void );
virtual void err(void);
virtual void err( const UnicodeString &message );
virtual void errln( const UnicodeString &message );
virtual void dataerr( const UnicodeString &message );
virtual void dataerrln( const UnicodeString &message );
void errcheckln(UErrorCode status, const UnicodeString &message );
// convenience functions: sprintf() + errln() etc.
void log(const char *fmt, ...);
void logln(const char *fmt, ...);
void info(const char *fmt, ...);
void infoln(const char *fmt, ...);
void err(const char *fmt, ...);
void errln(const char *fmt, ...);
void dataerr(const char *fmt, ...);
void dataerrln(const char *fmt, ...);
/**
* logs an error (even if status==U_ZERO_ERROR), but
* calls dataerrln() or errln() depending on the type of error.
* Does not report the status code.
* @param status parameter for selecting whether errln or dataerrln is called.
*/
void errcheckln(UErrorCode status, const char *fmt, ...);
// Print ALL named errors encountered so far
void printErrors();
// print known issues. return TRUE if there were any.
UBool printKnownIssues();
virtual void usage( void ) ;
/**
* Returns a uniform random value x, with 0.0 <= x < 1.0. Use
* with care: Does not return all possible values; returns one of
* 714,025 values, uniformly spaced. However, the period is
* effectively infinite. See: Numerical Recipes, section 7.1.
*
* @param seedp pointer to seed. Set *seedp to any negative value
* to restart the sequence.
*/
static float random(int32_t* seedp);
/**
* Convenience method using a global seed.
*/
static float random();
/**
* Integer random numbers, similar to C++ std::minstd_rand, with the same algorithm
* and constants. Allow additional access to internal state, for use by monkey tests,
* which need to recreate previous random sequences beginning near a failure point.
*/
class icu_rand {
public:
icu_rand(uint32_t seed = 1);
~icu_rand();
void seed(uint32_t seed);
uint32_t operator()();
/**
* Get a seed corresponding to the current state of the generator.
* Seeding any generator with this value will cause it to produce the
* same sequence as this one will from this point forward.
*/
uint32_t getSeed();
private:
uint32_t fLast;
};
enum { kMaxProps = 16 };
virtual void setProperty(const char* propline);
virtual const char* getProperty(const char* prop);
/* JUnit-like assertions. Each returns TRUE if it succeeds. */
UBool assertTrue(const char* message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE, const char *file=NULL, int line=0);
UBool assertFalse(const char* message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE);
/**
* @param possibleDataError - if TRUE, use dataerrln instead of errcheckln on failure
* @return TRUE on success, FALSE on failure.
*/
UBool assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError=FALSE, const char *file=NULL, int line=0);
UBool assertEquals(const char* message, const UnicodeString& expected,
const UnicodeString& actual, UBool possibleDataError=FALSE);
UBool assertEquals(const char* message, const char* expected, const char* actual);
UBool assertEquals(const char* message, UBool expected, UBool actual);
UBool assertEquals(const char* message, int32_t expected, int32_t actual);
UBool assertEquals(const char* message, int64_t expected, int64_t actual);
UBool assertEquals(const char* message, double expected, double actual);
/**
* Asserts that two doubles are equal to within a positive delta. Returns
* false if they are not.
*
* NaNs are considered equal: assertEquals(msg, NaN, NaN, *) passes.
* Infs are considered equal: assertEquals(msg, inf, inf, *) passes.
*
* @param message - the identifying message for the AssertionError.
* @param expected - expected value.
* @param actual - the value to check against expected.
* @param delta - the maximum delta for the absolute difference between
* expected and actual for which both numbers are still considered equal.
*/
UBool assertEqualsNear(const char* message, double expected, double actual, double delta);
UBool assertEquals(const char* message, UErrorCode expected, UErrorCode actual);
UBool assertEquals(const char* message, const UnicodeSet& expected, const UnicodeSet& actual);
UBool assertEquals(const char* message,
const std::vector<std::string>& expected, const std::vector<std::string>& actual);
#if !UCONFIG_NO_FORMATTING
UBool assertEquals(const char* message, const Formattable& expected,
const Formattable& actual, UBool possibleDataError=FALSE);
UBool assertEquals(const UnicodeString& message, const Formattable& expected,
const Formattable& actual);
#endif
UBool assertNotEquals(const char* message, int32_t expectedNot, int32_t actual);
UBool assertTrue(const UnicodeString& message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE);
UBool assertFalse(const UnicodeString& message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE);
UBool assertSuccess(const UnicodeString& message, UErrorCode ec);
UBool assertEquals(const UnicodeString& message, const UnicodeString& expected,
const UnicodeString& actual, UBool possibleDataError=FALSE);
UBool assertEquals(const UnicodeString& message, const char* expected, const char* actual);
UBool assertEquals(const UnicodeString& message, UBool expected, UBool actual);
UBool assertEquals(const UnicodeString& message, int32_t expected, int32_t actual);
UBool assertEquals(const UnicodeString& message, int64_t expected, int64_t actual);
UBool assertEquals(const UnicodeString& message, double expected, double actual);
/**
* Asserts that two doubles are equal to within a positive delta. Returns
* false if they are not.
*
* NaNs are considered equal: assertEquals(msg, NaN, NaN, *) passes.
* Infs are considered equal: assertEquals(msg, inf, inf, *) passes.
*
* @param message - the identifying message for the AssertionError.
* @param expected - expected value.
* @param actual - the value to check against expected.
* @param delta - the maximum delta between expected and actual for which
* both numbers are still considered equal.
*/
UBool assertEqualsNear(const UnicodeString& message, double expected, double actual, double delta);
UBool assertEquals(const UnicodeString& message, UErrorCode expected, UErrorCode actual);
UBool assertEquals(const UnicodeString& message, const UnicodeSet& expected, const UnicodeSet& actual);
UBool assertEquals(const UnicodeString& message,
const std::vector<std::string>& expected, const std::vector<std::string>& actual);
UBool assertNotEquals(const UnicodeString& message, int32_t expectedNot, int32_t actual);
virtual void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide !
virtual UBool runTestLoop( char* testname, char* par, char *baseName );
virtual int32_t IncErrorCount( void );
virtual int32_t IncDataErrorCount( void );
virtual UBool callTest( IntlTest& testToBeCalled, char* par, const char* basename = "");
UBool verbose;
UBool no_err_msg;
UBool quick;
UBool leaks;
UBool warn_on_missing_data;
UBool write_golden_data;
UBool no_time;
int32_t threadCount;
private:
UBool LL_linestart;
int32_t LL_indentlevel;
int32_t errorCount;
int32_t dataErrorCount;
IntlTest* caller;
char* testPath; // specifies subtests
char basePath[1024];
char currName[1024]; // current test name
//FILE *testoutfp;
void *testoutfp;
const char* proplines[kMaxProps];
int32_t numProps;
protected:
std::string currErr; // Error message of the current test case
virtual void LL_err_message( const UnicodeString& message, UBool newline );
virtual void LL_message( UnicodeString message, UBool newlin, UBool isErr = FALSE );
// used for collation result reporting, defined here for convenience
static UnicodeString &prettify(const UnicodeString &source, UnicodeString &target);
static UnicodeString prettify(const UnicodeString &source, UBool parseBackslash=FALSE);
// digits=-1 determines the number of digits automatically
static UnicodeString &appendHex(uint32_t number, int32_t digits, UnicodeString &target);
static UnicodeString toHex(uint32_t number, int32_t digits=-1);
static inline UnicodeString toHex(int32_t number, int32_t digits=-1) {
return toHex((uint32_t)number, digits);
}
public:
static void setICU_DATA(); // Set up ICU_DATA if necessary.
static const char* pathToDataDirectory();
public:
UBool run_phase2( char* name, char* par ); // internally, supports reporting memory leaks
static const char* loadTestData(UErrorCode& err);
virtual const char* getTestDataPath(UErrorCode& err);
static const char* getSourceTestData(UErrorCode& err);
static char *getUnidataPath(char path[]);
// static members
public:
static IntlTest* gTest;
};
void it_log( UnicodeString message );
void it_logln( UnicodeString message );
void it_logln( void );
void it_info( UnicodeString message );
void it_infoln( UnicodeString message );
void it_infoln( void );
void it_err(void);
void it_err( UnicodeString message );
void it_errln( UnicodeString message );
void it_dataerr( UnicodeString message );
void it_dataerrln( UnicodeString message );
/**
* This is a variant of cintltst/ccolltst.c:CharsToUChars().
* It converts a character string into a UnicodeString, with
* unescaping \u sequences.
*/
extern UnicodeString CharsToUnicodeString(const char* chars);
/* alias for CharsToUnicodeString */
extern UnicodeString ctou(const char* chars);
#endif // _INTLTEST