From 6038ee28f5c6b6d416d64606b1f24c137e8ccc02 Mon Sep 17 00:00:00 2001 From: George Rhoten Date: Tue, 23 Mar 2004 06:37:36 +0000 Subject: [PATCH] ICU-3662 Move data based test framework to test library X-SVN-Rev: 14733 --- icu4c/source/test/intltest/Makefile.in | 6 +- icu4c/source/test/intltest/convtest.cpp | 13 +- icu4c/source/test/intltest/dadrcoll.cpp | 8 +- icu4c/source/test/intltest/dadrcoll.h | 7 +- icu4c/source/test/intltest/intltest.cpp | 6 +- icu4c/source/test/intltest/intltest.h | 6 +- icu4c/source/test/intltest/intltest.vcproj | 24 +- icu4c/source/test/intltest/strcase.cpp | 9 +- icu4c/source/test/intltest/trcoll.cpp | 21 +- icu4c/source/tools/ctestfw/Makefile.in | 8 +- icu4c/source/tools/ctestfw/ctestfw.vcproj | 28 ++- icu4c/source/tools/ctestfw/datamap.cpp | 220 ++++++++++++++++++ icu4c/source/tools/ctestfw/testdata.cpp | 140 +++++++++++ icu4c/source/tools/ctestfw/tstdtmod.cpp | 168 +++++++++++++ icu4c/source/tools/ctestfw/unicode/ctest.h | 45 +--- icu4c/source/tools/ctestfw/unicode/datamap.h | 135 +++++++++++ icu4c/source/tools/ctestfw/unicode/testdata.h | 109 +++++++++ icu4c/source/tools/ctestfw/unicode/testlog.h | 27 +++ icu4c/source/tools/ctestfw/unicode/testtype.h | 34 +++ icu4c/source/tools/ctestfw/unicode/tstdtmod.h | 113 +++++++++ 20 files changed, 1012 insertions(+), 115 deletions(-) create mode 100644 icu4c/source/tools/ctestfw/datamap.cpp create mode 100644 icu4c/source/tools/ctestfw/testdata.cpp create mode 100644 icu4c/source/tools/ctestfw/tstdtmod.cpp create mode 100644 icu4c/source/tools/ctestfw/unicode/datamap.h create mode 100644 icu4c/source/tools/ctestfw/unicode/testdata.h create mode 100644 icu4c/source/tools/ctestfw/unicode/testlog.h create mode 100644 icu4c/source/tools/ctestfw/unicode/testtype.h create mode 100644 icu4c/source/tools/ctestfw/unicode/tstdtmod.h diff --git a/icu4c/source/test/intltest/Makefile.in b/icu4c/source/test/intltest/Makefile.in index 90f33c1d72e..a1a9c803823 100644 --- a/icu4c/source/test/intltest/Makefile.in +++ b/icu4c/source/test/intltest/Makefile.in @@ -22,9 +22,9 @@ TARGET = intltest$(EXEEXT) BUILDDIR := $(shell pwd)/../../ BUILDDIR := $(BUILDDIR:test/intltest/../../=) -CPPFLAGS += -I$(top_builddir)/common -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(top_srcdir)/tools/toolutil +CPPFLAGS += -I$(top_builddir)/common -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(top_srcdir)/tools/toolutil -I$(top_srcdir)/tools/ctestfw DEFS += -D'U_TOPSRCDIR="$(top_srcdir)/"' -D'U_TOPBUILDDIR="$(BUILDDIR)"' -LIBS = $(LIBICUI18N) $(LIBICUUC) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS) $(LIB_M) +LIBS = $(LIBCTESTFW) $(LIBICUI18N) $(LIBICUUC) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS) $(LIB_M) OBJECTS = allcoll.o apicoll.o astrotst.o callimts.o calregts.o caltest.o \ caltztst.o canittst.o citrtest.o cntabcol.o convtest.o cputilst.o currcoll.o dacoll.o \ @@ -39,7 +39,7 @@ tzregts.o tztest.o ucdtest.o usettest.o ustrtest.o strcase.o transtst.o strtest. itrbbi.o rbbiapts.o rbbitst.o ittrans.o transapi.o cpdtrtst.o \ testutil.o transrt.o trnserr.o normconf.o sfwdchit.o \ jamotest.o srchtest.o reptest.o regextst.o \ -itrbnf.o itrbnfrt.o tstdtmod.o testdata.o datamap.o ucaconf.o icusvtst.o \ +itrbnf.o itrbnfrt.o ucaconf.o icusvtst.o \ uobjtest.o idnaref.o nptrans.o punyref.o testidn.o testidna.o incaltst.o \ calcasts.o v32test.o diff --git a/icu4c/source/test/intltest/convtest.cpp b/icu4c/source/test/intltest/convtest.cpp index 03478b60509..7b7b69afe6e 100644 --- a/icu4c/source/test/intltest/convtest.cpp +++ b/icu4c/source/test/intltest/convtest.cpp @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 2003, International Business Machines +* Copyright (C) 2003-2004, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -36,7 +36,7 @@ #include "unicode/ustring.h" #include "unicode/ures.h" #include "convtest.h" -#include "tstdtmod.h" +#include "unicode/tstdtmod.h" #include #include @@ -74,7 +74,6 @@ ConversionTest::TestToUnicode() { int32_t offsetsLength; UConverterToUCallback callback; - TestLog testLog; TestDataModule *dataModule; TestData *testData; const DataMap *testCase; @@ -82,7 +81,7 @@ ConversionTest::TestToUnicode() { int32_t i; errorCode=U_ZERO_ERROR; - dataModule=TestDataModule::getTestDataModule("conversion", testLog, errorCode); + dataModule=TestDataModule::getTestDataModule("conversion", *this, errorCode); if(U_SUCCESS(errorCode)) { testData=dataModule->createTestData("toUnicode", errorCode); if(U_SUCCESS(errorCode)) { @@ -187,7 +186,6 @@ ConversionTest::TestFromUnicode() { int32_t offsetsLength; UConverterFromUCallback callback; - TestLog testLog; TestDataModule *dataModule; TestData *testData; const DataMap *testCase; @@ -196,7 +194,7 @@ ConversionTest::TestFromUnicode() { int32_t i, length; errorCode=U_ZERO_ERROR; - dataModule=TestDataModule::getTestDataModule("conversion", testLog, errorCode); + dataModule=TestDataModule::getTestDataModule("conversion", *this, errorCode); if(U_SUCCESS(errorCode)) { testData=dataModule->createTestData("fromUnicode", errorCode); if(U_SUCCESS(errorCode)) { @@ -329,7 +327,6 @@ ConversionTest::TestGetUnicodeSet() { UnicodeSet cnvSet, mapSet, mapnotSet, diffSet; UConverter *cnv; - TestLog testLog; TestDataModule *dataModule; TestData *testData; const DataMap *testCase; @@ -337,7 +334,7 @@ ConversionTest::TestGetUnicodeSet() { int32_t i; errorCode=U_ZERO_ERROR; - dataModule=TestDataModule::getTestDataModule("conversion", testLog, errorCode); + dataModule=TestDataModule::getTestDataModule("conversion", *this, errorCode); if(U_SUCCESS(errorCode)) { testData=dataModule->createTestData("getUnicodeSet", errorCode); if(U_SUCCESS(errorCode)) { diff --git a/icu4c/source/test/intltest/dadrcoll.cpp b/icu4c/source/test/intltest/dadrcoll.cpp index 30c6540aff5..6ed1385fe23 100644 --- a/icu4c/source/test/intltest/dadrcoll.cpp +++ b/icu4c/source/test/intltest/dadrcoll.cpp @@ -20,12 +20,10 @@ #if !UCONFIG_NO_COLLATION #include "unicode/uchar.h" - +#include "unicode/tstdtmod.h" #include "cstring.h" #include "ucol_tok.h" - #include "tscoll.h" - #include "dadrcoll.h" U_CDECL_BEGIN @@ -39,9 +37,7 @@ DataDrivenCollatorTest::DataDrivenCollatorTest() status(U_ZERO_ERROR), sequences(status) { - TestLog testLog; - - driver = TestDataModule::getTestDataModule("DataDrivenCollationTest", testLog, status); + driver = TestDataModule::getTestDataModule("DataDrivenCollationTest", *this, status); sequences.setDeleter(deleteSeqElement); } diff --git a/icu4c/source/test/intltest/dadrcoll.h b/icu4c/source/test/intltest/dadrcoll.h index 7dd25051147..c9e99257d2c 100644 --- a/icu4c/source/test/intltest/dadrcoll.h +++ b/icu4c/source/test/intltest/dadrcoll.h @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 2002-2003, International Business Machines Corporation and + * Copyright (c) 2002-2004, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -23,8 +23,9 @@ #include "unicode/tblcoll.h" #include "unicode/sortkey.h" #include "unicode/schriter.h" -#include "unicode/ures.h" -#include "tstdtmod.h" + +class TestDataModule; +class TestData; class SeqElement { public: diff --git a/icu4c/source/test/intltest/intltest.cpp b/icu4c/source/test/intltest/intltest.cpp index f10c0aca965..77112dc6a52 100644 --- a/icu4c/source/test/intltest/intltest.cpp +++ b/icu4c/source/test/intltest/intltest.cpp @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2003, International Business Machines Corporation and + * Copyright (c) 1997-2004, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -1196,6 +1196,10 @@ const char* IntlTest::loadTestData(UErrorCode& err){ return _testDataPath; } +const char* IntlTest::getTestDataPath(UErrorCode& err) { + return loadTestData(err); +} + const char* IntlTest::fgDataDir = NULL; /* returns the path to icu/source/data */ diff --git a/icu4c/source/test/intltest/intltest.h b/icu4c/source/test/intltest/intltest.h index 025ad2b497f..c99294c43d4 100644 --- a/icu4c/source/test/intltest/intltest.h +++ b/icu4c/source/test/intltest/intltest.h @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2003, International Business Machines Corporation and + * Copyright (c) 1997-2004, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -13,6 +13,7 @@ // The following includes utypes.h, uobject.h and unistr.h #include "unicode/fmtable.h" +#include "unicode/testlog.h" U_NAMESPACE_USE @@ -65,7 +66,7 @@ UnicodeString toString(const Formattable& f); // liu } \ break -class IntlTest { +class IntlTest : public TestLog { public: IntlTest(); @@ -189,6 +190,7 @@ public: 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 members public: diff --git a/icu4c/source/test/intltest/intltest.vcproj b/icu4c/source/test/intltest/intltest.vcproj index 479bac2e744..564323843e3 100644 --- a/icu4c/source/test/intltest/intltest.vcproj +++ b/icu4c/source/test/intltest/intltest.vcproj @@ -23,7 +23,7 @@ Optimization="0" ImproveFloatingPointConsistency="TRUE" OptimizeForProcessor="2" - AdditionalIncludeDirectories="..\..\..\include,..\..\..\source\common,..\..\..\source\i18n,..\..\tools\toolutil" + AdditionalIncludeDirectories="..\..\..\include,..\..\..\source\common,..\..\..\source\i18n,..\..\tools\toolutil,..\..\tools\ctestfw" PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE" BasicRuntimeChecks="3" RuntimeLibrary="1" @@ -43,6 +43,7 @@ - - - - @@ -650,24 +646,12 @@ - - - - - - - - createTestData("titlecasing", status); const DataMap *myCase = NULL; diff --git a/icu4c/source/test/intltest/trcoll.cpp b/icu4c/source/test/intltest/trcoll.cpp index 70d5d334876..09f030b4d6c 100644 --- a/icu4c/source/test/intltest/trcoll.cpp +++ b/icu4c/source/test/intltest/trcoll.cpp @@ -1,33 +1,18 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2003, International Business Machines Corporation and + * Copyright (c) 1997-2004, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ -#include "unicode/utypes.h" +#include "unicode/unistr.h" #if !UCONFIG_NO_COLLATION -#ifndef _COLL +#include "unicode/tstdtmod.h" #include "unicode/coll.h" -#endif - -#ifndef _TBLCOLL #include "unicode/tblcoll.h" -#endif - -#ifndef _UNISTR -#include "unicode/unistr.h" -#endif - -#ifndef _SORTKEY #include "unicode/sortkey.h" -#endif - -#ifndef _TRCOLL #include "trcoll.h" -#endif - #include "sfwdchit.h" CollationTurkishTest::CollationTurkishTest() diff --git a/icu4c/source/tools/ctestfw/Makefile.in b/icu4c/source/tools/ctestfw/Makefile.in index e04a7ca54a4..aad43a3df5f 100644 --- a/icu4c/source/tools/ctestfw/Makefile.in +++ b/icu4c/source/tools/ctestfw/Makefile.in @@ -1,5 +1,5 @@ ## Makefile.in for ICU - tools/ctestfw -## Copyright (c) 1999-2003, International Business Machines Corporation and +## Copyright (c) 1999-2004, International Business Machines Corporation and ## others. All Rights Reserved. ## Stephen F. Booth @@ -23,7 +23,7 @@ ifneq ($(ENABLE_STATIC),) TARGET = $(LIBSICU)ctestfw$(ICULIBSUFFIX).a endif -CPPFLAGS += -I$(top_builddir)/common -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(srcdir)/../toolutil +CPPFLAGS += -I$(top_builddir)/common -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(srcdir) DEFS += -DT_CTEST_IMPLEMENTATION @@ -38,9 +38,9 @@ DYNAMICCPPFLAGS = $(SHAREDLIBCPPFLAGS) DYNAMICCFLAGS = $(SHAREDLIBCFLAGS) DYNAMICCXXFLAGS = $(SHAREDLIBCXXFLAGS) -LIBS = $(DEFAULT_LIBS) +LIBS = $(LIBICUUC) $(DEFAULT_LIBS) -OBJECTS = ctest.o +OBJECTS = ctest.o tstdtmod.o testdata.o datamap.o STATIC_OBJECTS = $(OBJECTS:.o=.$(STATIC_O)) diff --git a/icu4c/source/tools/ctestfw/ctestfw.vcproj b/icu4c/source/tools/ctestfw/ctestfw.vcproj index bf21a956e50..12fd16f3409 100644 --- a/icu4c/source/tools/ctestfw/ctestfw.vcproj +++ b/icu4c/source/tools/ctestfw/ctestfw.vcproj @@ -22,7 +22,7 @@ Name="VCCLCompilerTool" InlineFunctionExpansion="2" ImproveFloatingPointConsistency="TRUE" - AdditionalIncludeDirectories="..\..\..\include" + AdditionalIncludeDirectories="..\..\..\include,..\..\common" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;CTESTFW_EXPORTS;T_CTEST_IMPLEMENTATION" StringPooling="TRUE" RuntimeLibrary="2" @@ -87,7 +87,7 @@ Optimization="0" ImproveFloatingPointConsistency="TRUE" OptimizeForProcessor="2" - AdditionalIncludeDirectories="..\..\..\include" + AdditionalIncludeDirectories="..\..\..\include,..\..\common" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;CTESTFW_EXPORTS;T_CTEST_IMPLEMENTATION" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -151,6 +151,15 @@ + + + + + + + + + + + + + + + + + +int32_t +DataMap::utoi(const UnicodeString &s) const +{ + char ch[256]; + const UChar *u = s.getBuffer(); + int32_t len = s.length(); + u_UCharsToChars(u, ch, len); + ch[len] = 0; /* include terminating \0 */ + return atoi(ch); +} + +U_CDECL_BEGIN +void U_CALLCONV +deleteResBund(void *obj) { + delete (ResourceBundle *)obj; +} +U_CDECL_END + + +RBDataMap::~RBDataMap() +{ + delete fData; +} + +RBDataMap::RBDataMap() +{ + UErrorCode status = U_ZERO_ERROR; + fData = new Hashtable(TRUE, status); + fData->setValueDeleter(deleteResBund); +} + +// init from table resource +// will put stuff in hashtable according to +// keys. +RBDataMap::RBDataMap(UResourceBundle *data, UErrorCode &status) +{ + fData = new Hashtable(TRUE, status); + fData->setValueDeleter(deleteResBund); + init(data, status); +} + +// init from headers and resource +// with checking the whether the size of resource matches +// header size +RBDataMap::RBDataMap(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status) +{ + fData = new Hashtable(TRUE, status); + fData->setValueDeleter(deleteResBund); + init(headers, data, status); +} + + +void RBDataMap::init(UResourceBundle *data, UErrorCode &status) { + int32_t i = 0; + fData->removeAll(); + UResourceBundle *t = NULL; + for(i = 0; i < ures_getSize(data); i++) { + t = ures_getByIndex(data, i, t, &status); + fData->put(UnicodeString(ures_getKey(t), ""), new ResourceBundle(t, status), status); + } + ures_close(t); +} + +void RBDataMap::init(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status) +{ + int32_t i = 0; + fData->removeAll(); + UResourceBundle *t = NULL; + const UChar *key = NULL; + int32_t keyLen = 0; + if(ures_getSize(headers) == ures_getSize(data)) { + for(i = 0; i < ures_getSize(data); i++) { + t = ures_getByIndex(data, i, t, &status); + key = ures_getStringByIndex(headers, i, &keyLen, &status); + fData->put(UnicodeString(key, keyLen), new ResourceBundle(t, status), status); + } + } else { + // error + status = U_INVALID_FORMAT_ERROR; + } + ures_close(t); +} + +const ResourceBundle *RBDataMap::getItem(const char* key, UErrorCode &status) const +{ + if(U_FAILURE(status)) { + return NULL; + } + + UnicodeString hashKey(key, ""); + const ResourceBundle *r = (ResourceBundle *)fData->get(hashKey); + if(r != NULL) { + return r; + } else { + status = U_MISSING_RESOURCE_ERROR; + return NULL; + } +} + +const UnicodeString RBDataMap::getString(const char* key, UErrorCode &status) const +{ + const ResourceBundle *r = getItem(key, status); + if(U_SUCCESS(status)) { + return r->getString(status); + } else { + status = U_MISSING_RESOURCE_ERROR; + return UnicodeString(); + } +} + +int32_t +RBDataMap::getInt28(const char* key, UErrorCode &status) const +{ + const ResourceBundle *r = getItem(key, status); + if(U_SUCCESS(status)) { + return r->getInt(status); + } else { + return 0; + } +} + +uint32_t +RBDataMap::getUInt28(const char* key, UErrorCode &status) const +{ + const ResourceBundle *r = getItem(key, status); + if(U_SUCCESS(status)) { + return r->getUInt(status); + } else { + return 0; + } +} + +const int32_t * +RBDataMap::getIntVector(int32_t &length, const char *key, UErrorCode &status) const { + const ResourceBundle *r = getItem(key, status); + if(U_SUCCESS(status)) { + return r->getIntVector(length, status); + } else { + return NULL; + } +} + +const uint8_t * +RBDataMap::getBinary(int32_t &length, const char *key, UErrorCode &status) const { + const ResourceBundle *r = getItem(key, status); + if(U_SUCCESS(status)) { + return r->getBinary(length, status); + } else { + return NULL; + } +} + +int32_t RBDataMap::getInt(const char* key, UErrorCode &status) const +{ + UnicodeString r = this->getString(key, status); + if(U_SUCCESS(status)) { + return utoi(r); + } else { + return 0; + } +} + +const UnicodeString* RBDataMap::getStringArray(int32_t& count, const char* key, UErrorCode &status) const +{ + const ResourceBundle *r = getItem(key, status); + if(U_SUCCESS(status)) { + int32_t i = 0; + + count = r->getSize(); + if(count <= 0) { + return NULL; + } + + UnicodeString *result = new UnicodeString[count]; + for(i = 0; igetStringEx(i, status); + } + return result; + } else { + status = U_MISSING_RESOURCE_ERROR; + return NULL; + } +} + +const int32_t* RBDataMap::getIntArray(int32_t& count, const char* key, UErrorCode &status) const +{ + const ResourceBundle *r = getItem(key, status); + if(U_SUCCESS(status)) { + int32_t i = 0; + + count = r->getSize(); + if(count <= 0) { + return NULL; + } + + int32_t *result = new int32_t[count]; + UnicodeString stringRes; + for(i = 0; igetStringEx(i, status); + result[i] = utoi(stringRes); + } + return result; + } else { + status = U_MISSING_RESOURCE_ERROR; + return NULL; + } +} diff --git a/icu4c/source/tools/ctestfw/testdata.cpp b/icu4c/source/tools/ctestfw/testdata.cpp new file mode 100644 index 00000000000..c0638f041b2 --- /dev/null +++ b/icu4c/source/tools/ctestfw/testdata.cpp @@ -0,0 +1,140 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2002-2003, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by weiv 05/09/2002 */ + +#include "unicode/testdata.h" + +TestData::TestData(const char* name) +: name(name), +fInfo(NULL), +fCurrSettings(NULL), +fCurrCase(NULL), +fSettingsSize(0), +fCasesSize(0), +fCurrentSettings(0), +fCurrentCase(0) + +{ +} + +TestData::~TestData() { + if(fInfo != NULL) { + delete fInfo; + } + if(fCurrSettings != NULL) { + delete fCurrSettings; + } + if(fCurrCase != NULL) { + delete fCurrCase; + } +} + +const char * TestData::getName() const +{ + return name; +} + + + +RBTestData::RBTestData(const char* name) +: TestData(name), +fData(NULL), +fHeaders(NULL), +fSettings(NULL), +fCases(NULL) +{ +} + +RBTestData::RBTestData(UResourceBundle *data, UResourceBundle *headers, UErrorCode& status) +: TestData(ures_getKey(data)), +fData(data), +fHeaders(headers), +fSettings(NULL), +fCases(NULL) +{ + UErrorCode intStatus = U_ZERO_ERROR; + UResourceBundle *currHeaders = ures_getByKey(data, "Headers", NULL, &intStatus); + if(intStatus == U_ZERO_ERROR) { + ures_close(fHeaders); + fHeaders = currHeaders; + } else { + intStatus = U_ZERO_ERROR; + } + fSettings = ures_getByKey(data, "Settings", NULL, &intStatus); + fSettingsSize = ures_getSize(fSettings); + UResourceBundle *info = ures_getByKey(data, "Info", NULL, &intStatus); + if(U_SUCCESS(intStatus)) { + fInfo = new RBDataMap(info, status); + } else { + intStatus = U_ZERO_ERROR; + } + fCases = ures_getByKey(data, "Cases", NULL, &status); + fCasesSize = ures_getSize(fCases); + + ures_close(info); +} + + +RBTestData::~RBTestData() +{ + ures_close(fData); + ures_close(fHeaders); + ures_close(fSettings); + ures_close(fCases); +} + +UBool RBTestData::getInfo(const DataMap *& info, UErrorCode &/*status*/) const +{ + if(fInfo) { + info = fInfo; + return TRUE; + } else { + info = NULL; + return FALSE; + } +} + +UBool RBTestData::nextSettings(const DataMap *& settings, UErrorCode &status) +{ + UErrorCode intStatus = U_ZERO_ERROR; + UResourceBundle *data = ures_getByIndex(fSettings, fCurrentSettings++, NULL, &intStatus); + if(U_SUCCESS(intStatus)) { + // reset the cases iterator + fCurrentCase = 0; + if(fCurrSettings == NULL) { + fCurrSettings = new RBDataMap(data, status); + } else { + ((RBDataMap *)fCurrSettings)->init(data, status); + } + ures_close(data); + settings = fCurrSettings; + return TRUE; + } else { + settings = NULL; + return FALSE; + } +} + +UBool RBTestData::nextCase(const DataMap *& nextCase, UErrorCode &status) +{ + UErrorCode intStatus = U_ZERO_ERROR; + UResourceBundle *currCase = ures_getByIndex(fCases, fCurrentCase++, NULL, &intStatus); + if(U_SUCCESS(intStatus)) { + if(fCurrCase == NULL) { + fCurrCase = new RBDataMap(fHeaders, currCase, status); + } else { + ((RBDataMap *)fCurrCase)->init(fHeaders, currCase, status); + } + ures_close(currCase); + nextCase = fCurrCase; + return TRUE; + } else { + nextCase = NULL; + return FALSE; + } +} + diff --git a/icu4c/source/tools/ctestfw/tstdtmod.cpp b/icu4c/source/tools/ctestfw/tstdtmod.cpp new file mode 100644 index 00000000000..4b08148d616 --- /dev/null +++ b/icu4c/source/tools/ctestfw/tstdtmod.cpp @@ -0,0 +1,168 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2002, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by weiv 05/09/2002 */ + +#include "unicode/tstdtmod.h" +#include "cmemory.h" + +TestDataModule *TestDataModule::getTestDataModule(const char* name, TestLog& log, UErrorCode &status) +{ + if(U_FAILURE(status)) { + return NULL; + } + TestDataModule *result = NULL; + + // TODO: probe for resource bundle and then for XML. + // According to that, construct an appropriate driver object + + result = new RBTestDataModule(name, log, status); + if(U_SUCCESS(status)) { + return result; + } else { + delete result; + return NULL; + } +} + +TestDataModule::TestDataModule(const char* name, TestLog& log, UErrorCode& /*status*/) +: testName(name), +fInfo(NULL), +fLog(log) +{ +} + +TestDataModule::~TestDataModule() { + if(fInfo != NULL) { + delete fInfo; + } +} + +const char * TestDataModule::getName() const +{ + return testName; +} + + + +RBTestDataModule::~RBTestDataModule() +{ + ures_close(fTestData); + ures_close(fModuleBundle); + ures_close(fInfoRB); + uprv_free(tdpath); +} + +RBTestDataModule::RBTestDataModule(const char* name, TestLog& log, UErrorCode& status) +: TestDataModule(name, log, status), + fModuleBundle(NULL), + fTestData(NULL), + fInfoRB(NULL), + tdpath(NULL) +{ + fNumberOfTests = 0; + fDataTestValid = TRUE; + fModuleBundle = getTestBundle(name, status); + if(fDataTestValid) { + fTestData = ures_getByKey(fModuleBundle, "TestData", NULL, &status); + fNumberOfTests = ures_getSize(fTestData); + fInfoRB = ures_getByKey(fModuleBundle, "Info", NULL, &status); + if(status != U_ZERO_ERROR) { + log.errln("Unable to initalize test data - missing mandatory description resources!"); + fDataTestValid = FALSE; + } else { + fInfo = new RBDataMap(fInfoRB, status); + } + } +} + +UBool RBTestDataModule::getInfo(const DataMap *& info, UErrorCode &/*status*/) const +{ + info = fInfo; + if(fInfo) { + return TRUE; + } else { + return FALSE; + } +} + +TestData* RBTestDataModule::createTestData(int32_t index, UErrorCode &status) const +{ + TestData *result = NULL; + UErrorCode intStatus = U_ZERO_ERROR; + + if(fDataTestValid == TRUE) { + // Both of these resources get adopted by a TestData object. + UResourceBundle *DataFillIn = ures_getByIndex(fTestData, index, NULL, &status); + UResourceBundle *headers = ures_getByKey(fInfoRB, "Headers", NULL, &intStatus); + + if(U_SUCCESS(status)) { + result = new RBTestData(DataFillIn, headers, status); + + if(U_SUCCESS(status)) { + return result; + } else { + delete result; + } + } else { + ures_close(DataFillIn); + ures_close(headers); + } + } else { + status = U_MISSING_RESOURCE_ERROR; + } + return NULL; +} + +TestData* RBTestDataModule::createTestData(const char* name, UErrorCode &status) const +{ + TestData *result = NULL; + UErrorCode intStatus = U_ZERO_ERROR; + + if(fDataTestValid == TRUE) { + // Both of these resources get adopted by a TestData object. + UResourceBundle *DataFillIn = ures_getByKey(fTestData, name, NULL, &status); + UResourceBundle *headers = ures_getByKey(fInfoRB, "Headers", NULL, &intStatus); + + if(U_SUCCESS(status)) { + result = new RBTestData(DataFillIn, headers, status); + if(U_SUCCESS(status)) { + return result; + } else { + delete result; + } + } else { + ures_close(DataFillIn); + ures_close(headers); + } + } else { + status = U_MISSING_RESOURCE_ERROR; + } + return NULL; +} + + + +//Get test data from ResourceBundles +UResourceBundle* +RBTestDataModule::getTestBundle(const char* bundleName, UErrorCode &status) +{ + if(U_SUCCESS(status)) { + UResourceBundle *testBundle = NULL; + const char* icu_data = fLog.getTestDataPath(status); + if (testBundle == NULL) { + testBundle = ures_openDirect(icu_data, bundleName, &status); + if (status != U_ZERO_ERROR) { + fLog.errln(UnicodeString("Failed: could not load test data from resourcebundle: ") + UnicodeString(bundleName)); + fDataTestValid = FALSE; + } + } + return testBundle; + } else { + return NULL; + } +} + diff --git a/icu4c/source/tools/ctestfw/unicode/ctest.h b/icu4c/source/tools/ctestfw/unicode/ctest.h index dd00f5c1177..69bb7065767 100644 --- a/icu4c/source/tools/ctestfw/unicode/ctest.h +++ b/icu4c/source/tools/ctestfw/unicode/ctest.h @@ -1,57 +1,18 @@ /* ***************************************************************************************** * -* Copyright (C) 1996-2003, International Business Machines +* Copyright (C) 1996-2004, International Business Machines * Corporation and others. All Rights Reserved. * ***************************************************************************************** */ - #ifndef CTEST_H #define CTEST_H -#include - -#include "unicode/utypes.h" +#include "unicode/testtype.h" #include "unicode/utrace.h" -/*Deals with imports and exports of the dynamic library*/ -#if defined(_WIN32) || defined(U_CYGWIN) - #define T_CTEST_EXPORT __declspec(dllexport) - #define T_CTEST_IMPORT __declspec(dllimport) -#else - #define T_CTEST_EXPORT - #define T_CTEST_IMPORT -#endif - -#ifdef __cplusplus - #define C_CTEST_API extern "C" -#else - #define C_CTEST_API -#endif - -#ifdef T_CTEST_IMPLEMENTATION - #define T_CTEST_API C_CTEST_API T_CTEST_EXPORT - #define T_CTEST_EXPORT_API T_CTEST_EXPORT -#else - #define T_CTEST_API C_CTEST_API T_CTEST_IMPORT - #define T_CTEST_EXPORT_API T_CTEST_IMPORT -#endif - - - -/* True and false for sanity. (removes ICU dependancy) */ - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - - - /* prototypes *********************************/ @@ -174,7 +135,7 @@ T_CTEST_API void log_info(const char* pattern, ...); * @param ap variable-arguments list * @internal Internal APIs for testing purpose only */ -T_CTEST_API void vlog_info(const char *prefix, const char *pattern, va_list ap); +/*T_CTEST_API void vlog_info(const char *prefix, const char *pattern, va_list ap);*/ /** * Log a verbose informational message. (printf style) diff --git a/icu4c/source/tools/ctestfw/unicode/datamap.h b/icu4c/source/tools/ctestfw/unicode/datamap.h new file mode 100644 index 00000000000..bd812796ecc --- /dev/null +++ b/icu4c/source/tools/ctestfw/unicode/datamap.h @@ -0,0 +1,135 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2002-2004, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by weiv 05/09/2002 */ + +#ifndef U_TESTFW_DATAMAP +#define U_TESTFW_DATAMAP + +#include "unicode/resbund.h" +#include "unicode/testtype.h" + +U_NAMESPACE_BEGIN +class Hashtable; +U_NAMESPACE_END + +/** Holder of test data and settings. Allows addressing of items by name. + * For test cases, names are defined in the "Headers" section. For settings + * and info data, names are keys in data. Currently, we return scalar strings + * and integers and arrays of strings and integers. Arrays should be deposited + * of by the user. + */ +class T_CTEST_EXPORT_API DataMap { +public: + virtual ~DataMap() {}; + +protected: + DataMap() {}; + int32_t utoi(const UnicodeString &s) const; + + +public: + /** get the string from the DataMap. Addressed by name + * @param key name of the data field. + * @return a string containing the data + */ + virtual const UnicodeString getString(const char* key, UErrorCode &status) const = 0; + + /** get the string from the DataMap. Addressed by name + * parses a bundle string into an integer + * @param key name of the data field. + * @return an integer containing the data + */ + virtual int32_t getInt(const char* key, UErrorCode &status) const = 0; + + /** + * Get a signed integer without runtime parsing. + * @param key name of the data field. + * @param status UErrorCode in/out parameter + * @return the integer + */ + virtual int32_t getInt28(const char* key, UErrorCode &status) const = 0; + + /** + * Get an unsigned integer without runtime parsing. + * @param key name of the data field. + * @param status UErrorCode in/out parameter + * @return the integer + */ + virtual uint32_t getUInt28(const char* key, UErrorCode &status) const = 0; + + /** + * Get a vector of integers without runtime parsing. + * @param length output parameter for the length of the vector + * @param key name of the data field. + * @param status UErrorCode in/out parameter + * @return the integer vector, do not delete + */ + virtual const int32_t *getIntVector(int32_t &length, const char *key, UErrorCode &status) const = 0; + + /** + * Get binary data without runtime parsing. + * @param length output parameter for the length of the data + * @param key name of the data field. + * @param status UErrorCode in/out parameter + * @return the binary data, do not delete + */ + virtual const uint8_t *getBinary(int32_t &length, const char *key, UErrorCode &status) const = 0; + + /** get an array of strings from the DataMap. Addressed by name. + * The user must dispose of it after usage, using delete. + * @param key name of the data field. + * @return a string array containing the data + */ + virtual const UnicodeString* getStringArray(int32_t& count, const char* key, UErrorCode &status) const = 0; + + /** get an array of integers from the DataMap. Addressed by name. + * The user must dispose of it after usage, using delete. + * @param key name of the data field. + * @return an integer array containing the data + */ + virtual const int32_t* getIntArray(int32_t& count, const char* key, UErrorCode &status) const = 0; + + // ... etc ... +}; + +// This one is already concrete - it is going to be instantiated from +// concrete data by TestData children... +class T_CTEST_EXPORT_API RBDataMap : public DataMap{ +private: + Hashtable *fData; + +public: + virtual ~RBDataMap(); + +public: + RBDataMap(); + + RBDataMap(UResourceBundle *data, UErrorCode &status); + RBDataMap(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status); + +public: + void init(UResourceBundle *data, UErrorCode &status); + void init(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status); + + virtual const ResourceBundle *getItem(const char* key, UErrorCode &status) const; + + virtual const UnicodeString getString(const char* key, UErrorCode &status) const; + virtual int32_t getInt28(const char* key, UErrorCode &status) const; + virtual uint32_t getUInt28(const char* key, UErrorCode &status) const; + virtual const int32_t *getIntVector(int32_t &length, const char *key, UErrorCode &status) const; + virtual const uint8_t *getBinary(int32_t &length, const char *key, UErrorCode &status) const; + + virtual int32_t getInt(const char* key, UErrorCode &status) const; + + virtual const UnicodeString* getStringArray(int32_t& count, const char* key, UErrorCode &status) const; + virtual const int32_t* getIntArray(int32_t& count, const char* key, UErrorCode &status) const; + + // ... etc ... +}; + +#endif + diff --git a/icu4c/source/tools/ctestfw/unicode/testdata.h b/icu4c/source/tools/ctestfw/unicode/testdata.h new file mode 100644 index 00000000000..ef9e73e3660 --- /dev/null +++ b/icu4c/source/tools/ctestfw/unicode/testdata.h @@ -0,0 +1,109 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2002-2004, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by weiv 05/09/2002 */ + +/* Base class for data driven tests */ + +#ifndef U_TESTFW_TESTDATA +#define U_TESTFW_TESTDATA + +#include "unicode/tstdtmod.h" +#include "unicode/datamap.h" + + /** This is the class that abstracts one of the tests in a data file + * It is usually instantiated using TestDataModule::CreateTestData method + * This class provides two important methods: nextSettings and nextCase + * Usually, one walks through all settings and executes all cases for + * each setting. Each call to nextSettings resets the cases iterator. + * Individual test cases have to have the same number of fields as the + * number of entries in headers. Default headers can be specified in + * the TestDataModule info section. The default headers will be overriden + * by per-test headers. + * Example: + * DataMap *settings = NULL; + * DataMap *cases = NULL; + * while(nextSettings(settings, status)) { + * // set settings for the subtest + * while(nextCase(cases, status) { + * // process testcase + * } + * } + */ + +class T_CTEST_EXPORT_API TestData { + const char* name; + +protected: + DataMap *fInfo; + DataMap *fCurrSettings; + DataMap *fCurrCase; + int32_t fSettingsSize; + int32_t fCasesSize; + int32_t fCurrentSettings; + int32_t fCurrentCase; + /** constructor - don't use */ + TestData(const char* name); + +public: + virtual ~TestData(); + + const char* getName() const; + + /** Get a pointer to an object owned DataMap that contains more information on this + * TestData object. + * Usual fields is "Description". + * @param info pass in a const DataMap pointer. If no info, it will be set to NULL + */ + virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const = 0; + + /** Gets the next set of settings for the test. Resets the cases iterator. + * DataMap is owned by the object and should not be deleted. + * @param settings a DataMap pointer provided by the user. Will be NULL if + * no more settings are available. + * @param status for reporting unexpected errors. + * @return A boolean, TRUE if there are settings, FALSE if there is no more + * settings. + */ + virtual UBool nextSettings(const DataMap *& settings, UErrorCode &status) = 0; + + /** Gets the next test case. + * DataMap is owned by the object and should not be deleted. + * @param data a DataMap pointer provided by the user. Will be NULL if + * no more cases are available. + * @param status for reporting unexpected errors. + * @return A boolean, TRUE if there are cases, FALSE if there is no more + * cases. + */ + virtual UBool nextCase(const DataMap *& data, UErrorCode &status) = 0; +}; + +// implementation of TestData that uses resource bundles + +class T_CTEST_EXPORT_API RBTestData : public TestData { + UResourceBundle *fData; + UResourceBundle *fHeaders; + UResourceBundle *fSettings; + UResourceBundle *fCases; + +public: + RBTestData(const char* name); + RBTestData(UResourceBundle *data, UResourceBundle *headers, UErrorCode& status); +private: +// RBTestData() {}; +// RBTestData(const RBTestData& original) {}; + RBTestData& operator=(const RBTestData& /*original*/) {return *this;}; + +public: + virtual ~RBTestData(); + + virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const; + + virtual UBool nextSettings(const DataMap *& settings, UErrorCode &status); + virtual UBool nextCase(const DataMap *& nextCase, UErrorCode &status); +}; + +#endif diff --git a/icu4c/source/tools/ctestfw/unicode/testlog.h b/icu4c/source/tools/ctestfw/unicode/testlog.h new file mode 100644 index 00000000000..83abd5972d1 --- /dev/null +++ b/icu4c/source/tools/ctestfw/unicode/testlog.h @@ -0,0 +1,27 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2004, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by grhoten 03/17/2004 */ + +/* Base class for data driven tests */ + +#ifndef U_TESTFW_TESTLOG +#define U_TESTFW_TESTLOG + +#include "unicode/unistr.h" + +/** Facilitates internal logging of data driven test service + * It would be interesting to develop this into a full + * fledged control system as in Java. + */ +class TestLog { +public: + virtual void errln( const UnicodeString &message ) = 0; + virtual const char* getTestDataPath(UErrorCode& err) = 0; +}; + + +#endif diff --git a/icu4c/source/tools/ctestfw/unicode/testtype.h b/icu4c/source/tools/ctestfw/unicode/testtype.h new file mode 100644 index 00000000000..e6b766d1eb0 --- /dev/null +++ b/icu4c/source/tools/ctestfw/unicode/testtype.h @@ -0,0 +1,34 @@ +/* +***************************************************************************************** +* +* Copyright (C) 2004-2004, International Business Machines +* Corporation and others. All Rights Reserved. +* +***************************************************************************************** +*/ + +#include "unicode/utypes.h" + +/*Deals with imports and exports of the dynamic library*/ +#if defined(_WIN32) || defined(U_CYGWIN) + #define T_CTEST_EXPORT __declspec(dllexport) + #define T_CTEST_IMPORT __declspec(dllimport) +#else + #define T_CTEST_EXPORT + #define T_CTEST_IMPORT +#endif + +#ifdef __cplusplus + #define C_CTEST_API extern "C" +#else + #define C_CTEST_API +#endif + +#ifdef T_CTEST_IMPLEMENTATION + #define T_CTEST_API C_CTEST_API T_CTEST_EXPORT + #define T_CTEST_EXPORT_API T_CTEST_EXPORT +#else + #define T_CTEST_API C_CTEST_API T_CTEST_IMPORT + #define T_CTEST_EXPORT_API T_CTEST_IMPORT +#endif + diff --git a/icu4c/source/tools/ctestfw/unicode/tstdtmod.h b/icu4c/source/tools/ctestfw/unicode/tstdtmod.h new file mode 100644 index 00000000000..77def6b61e2 --- /dev/null +++ b/icu4c/source/tools/ctestfw/unicode/tstdtmod.h @@ -0,0 +1,113 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2002-2004, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ + +/* Created by weiv 05/09/2002 */ + +/* Base class for data driven tests */ + +#ifndef U_TESTFW_TESTMODULE +#define U_TESTFW_TESTMODULE + +#include "unicode/unistr.h" +#include "unicode/ures.h" +#include "unicode/testtype.h" +#include "unicode/testdata.h" +#include "unicode/datamap.h" +#include "unicode/testlog.h" + +/* This class abstracts the actual organization of the + * data for data driven tests + */ + + +class DataMap; +class TestData; + + +/** Main data driven test class. Corresponds to one named data + * unit (such as a resource bundle. It is instantiated using + * a factory method getTestDataModule + */ +class T_CTEST_EXPORT_API TestDataModule { + const char* testName; + +protected: + DataMap *fInfo; + TestLog& fLog; + +public: + /** Factory method. + * @param name name of the test module. Usually name of a resource bundle or a XML file + * @param log a logging class, used for internal error reporting. + * @param status if something goes wrong, status will be set + * @return a TestDataModule object. Use it to get test data from it + */ + static TestDataModule *getTestDataModule(const char* name, TestLog& log, UErrorCode &status); + virtual ~TestDataModule(); + +protected: + TestDataModule(const char* name, TestLog& log, UErrorCode& status); + +public: + /** Name of this TestData module. + * @return a name + */ + const char * getName() const; + + /** Get a pointer to an object owned DataMap that contains more information on this module + * Usual fields are "Description", "LongDescription", "Settings". Also, if containing a + * field "Headers" these will be used as the default headers, so that you don't have to + * to specify per test headers. + * @param info pass in a const DataMap pointer. If no info, it will be set to NULL + */ + virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const = 0; + + /** Create a test data object from an index. Helpful for integrating tests with current + * intltest framework which addresses the tests by index. + * @param index index of the test to be instantiated + * @return an instantiated TestData object, ready to provide settings and cases for + * the tests. + */ + virtual TestData* createTestData(int32_t index, UErrorCode &status) const = 0; + + /** Create a test data object from a name. + * @param name name of the test to be instantiated + * @return an instantiated TestData object, ready to provide settings and cases for + * the tests. + */ + virtual TestData* createTestData(const char* name, UErrorCode &status) const = 0; +}; + +class T_CTEST_EXPORT_API RBTestDataModule : public TestDataModule { +public: + virtual ~RBTestDataModule(); + +public: + RBTestDataModule(const char* name, TestLog& log, UErrorCode& status); + +public: + virtual UBool getInfo(const DataMap *& info, UErrorCode &status) const; + + virtual TestData* createTestData(int32_t index, UErrorCode &status) const; + virtual TestData* createTestData(const char* name, UErrorCode &status) const; + +private: + UResourceBundle *getTestBundle(const char* bundleName, UErrorCode &status); + +private: + UResourceBundle *fModuleBundle; + UResourceBundle *fTestData; + UResourceBundle *fInfoRB; + UBool fDataTestValid; + char *tdpath; + +/* const char* fTestName;*/ /* See name */ + int32_t fNumberOfTests; + +}; + + +#endif