Home | History | Annotate | Download | only in ctestfw
      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) 2002-2014, International Business Machines Corporation and
      6  * others. All Rights Reserved.
      7  ********************************************************************/
      8 
      9 /* Created by weiv 05/09/2002 */
     10 
     11 #include <stdarg.h>
     12 
     13 #include "unicode/tstdtmod.h"
     14 #include "cmemory.h"
     15 #include <stdio.h>
     16 #include "cstr.h"
     17 #include "cstring.h"
     18 
     19 TestLog::~TestLog() {}
     20 
     21 IcuTestErrorCode::~IcuTestErrorCode() {
     22     // Safe because our errlog() does not throw exceptions.
     23     if(isFailure()) {
     24         errlog(FALSE, u"destructor: expected success", nullptr);
     25     }
     26 }
     27 
     28 UBool IcuTestErrorCode::errIfFailureAndReset() {
     29     if(isFailure()) {
     30         errlog(FALSE, u"expected success", nullptr);
     31         reset();
     32         return TRUE;
     33     } else {
     34         reset();
     35         return FALSE;
     36     }
     37 }
     38 
     39 UBool IcuTestErrorCode::errIfFailureAndReset(const char *fmt, ...) {
     40     if(isFailure()) {
     41         char buffer[4000];
     42         va_list ap;
     43         va_start(ap, fmt);
     44         vsprintf(buffer, fmt, ap);
     45         va_end(ap);
     46         errlog(FALSE, u"expected success", buffer);
     47         reset();
     48         return TRUE;
     49     } else {
     50         reset();
     51         return FALSE;
     52     }
     53 }
     54 
     55 UBool IcuTestErrorCode::errDataIfFailureAndReset() {
     56     if(isFailure()) {
     57         errlog(TRUE, u"data: expected success", nullptr);
     58         reset();
     59         return TRUE;
     60     } else {
     61         reset();
     62         return FALSE;
     63     }
     64 }
     65 
     66 UBool IcuTestErrorCode::errDataIfFailureAndReset(const char *fmt, ...) {
     67     if(isFailure()) {
     68         char buffer[4000];
     69         va_list ap;
     70         va_start(ap, fmt);
     71         vsprintf(buffer, fmt, ap);
     72         va_end(ap);
     73         errlog(TRUE, u"data: expected success", buffer);
     74         reset();
     75         return TRUE;
     76     } else {
     77         reset();
     78         return FALSE;
     79     }
     80 }
     81 
     82 UBool IcuTestErrorCode::expectErrorAndReset(UErrorCode expectedError) {
     83     if(get() != expectedError) {
     84         errlog(FALSE, UnicodeString(u"expected: ") + u_errorName(expectedError), nullptr);
     85     }
     86     UBool retval = isFailure();
     87     reset();
     88     return retval;
     89 }
     90 
     91 UBool IcuTestErrorCode::expectErrorAndReset(UErrorCode expectedError, const char *fmt, ...) {
     92     if(get() != expectedError) {
     93         char buffer[4000];
     94         va_list ap;
     95         va_start(ap, fmt);
     96         vsprintf(buffer, fmt, ap);
     97         va_end(ap);
     98         errlog(FALSE, UnicodeString(u"expected: ") + u_errorName(expectedError), buffer);
     99     }
    100     UBool retval = isFailure();
    101     reset();
    102     return retval;
    103 }
    104 
    105 void IcuTestErrorCode::setScope(const char* message) {
    106     scopeMessage.remove().append({ message, -1, US_INV });
    107 }
    108 
    109 void IcuTestErrorCode::setScope(const UnicodeString& message) {
    110     scopeMessage = message;
    111 }
    112 
    113 void IcuTestErrorCode::handleFailure() const {
    114     errlog(FALSE, u"(handleFailure)", nullptr);
    115 }
    116 
    117 void IcuTestErrorCode::errlog(UBool dataErr, const UnicodeString& mainMessage, const char* extraMessage) const {
    118     UnicodeString msg(testName, -1, US_INV);
    119     msg.append(u' ').append(mainMessage);
    120     msg.append(u" but got error: ").append(UnicodeString(errorName(), -1, US_INV));
    121 
    122     if (!scopeMessage.isEmpty()) {
    123         msg.append(u" scope: ").append(scopeMessage);
    124     }
    125 
    126     if (extraMessage != nullptr) {
    127         msg.append(u" - ").append(UnicodeString(extraMessage, -1, US_INV));
    128     }
    129 
    130     if (dataErr || get() == U_MISSING_RESOURCE_ERROR || get() == U_FILE_ACCESS_ERROR) {
    131         testClass.dataerrln(msg);
    132     } else {
    133         testClass.errln(msg);
    134     }
    135 }
    136 
    137 TestDataModule *TestDataModule::getTestDataModule(const char* name, TestLog& log, UErrorCode &status)
    138 {
    139   if(U_FAILURE(status)) {
    140     return NULL;
    141   }
    142   TestDataModule *result = NULL;
    143 
    144   // TODO: probe for resource bundle and then for XML.
    145   // According to that, construct an appropriate driver object
    146 
    147   result = new RBTestDataModule(name, log, status);
    148   if(U_SUCCESS(status)) {
    149     return result;
    150   } else {
    151     delete result;
    152     return NULL;
    153   }
    154 }
    155 
    156 TestDataModule::TestDataModule(const char* name, TestLog& log, UErrorCode& /*status*/)
    157 : testName(name),
    158 fInfo(NULL),
    159 fLog(log)
    160 {
    161 }
    162 
    163 TestDataModule::~TestDataModule() {
    164   if(fInfo != NULL) {
    165     delete fInfo;
    166   }
    167 }
    168 
    169 const char * TestDataModule::getName() const
    170 {
    171   return testName;
    172 }
    173 
    174 
    175 
    176 RBTestDataModule::~RBTestDataModule()
    177 {
    178   ures_close(fTestData);
    179   ures_close(fModuleBundle);
    180   ures_close(fInfoRB);
    181   uprv_free(tdpath);
    182 }
    183 
    184 RBTestDataModule::RBTestDataModule(const char* name, TestLog& log, UErrorCode& status)
    185 : TestDataModule(name, log, status),
    186   fModuleBundle(NULL),
    187   fTestData(NULL),
    188   fInfoRB(NULL),
    189   tdpath(NULL)
    190 {
    191   fNumberOfTests = 0;
    192   fDataTestValid = TRUE;
    193   fModuleBundle = getTestBundle(name, status);
    194   if(fDataTestValid) {
    195     fTestData = ures_getByKey(fModuleBundle, "TestData", NULL, &status);
    196     fNumberOfTests = ures_getSize(fTestData);
    197     fInfoRB = ures_getByKey(fModuleBundle, "Info", NULL, &status);
    198     if(status != U_ZERO_ERROR) {
    199       log.errln(UNICODE_STRING_SIMPLE("Unable to initalize test data - missing mandatory description resources!"));
    200       fDataTestValid = FALSE;
    201     } else {
    202       fInfo = new RBDataMap(fInfoRB, status);
    203     }
    204   }
    205 }
    206 
    207 UBool RBTestDataModule::getInfo(const DataMap *& info, UErrorCode &/*status*/) const
    208 {
    209     info = fInfo;
    210     if(fInfo) {
    211         return TRUE;
    212     } else {
    213         return FALSE;
    214     }
    215 }
    216 
    217 TestData* RBTestDataModule::createTestData(int32_t index, UErrorCode &status) const
    218 {
    219   TestData *result = NULL;
    220   UErrorCode intStatus = U_ZERO_ERROR;
    221 
    222   if(fDataTestValid == TRUE) {
    223     // Both of these resources get adopted by a TestData object.
    224     UResourceBundle *DataFillIn = ures_getByIndex(fTestData, index, NULL, &status);
    225     UResourceBundle *headers = ures_getByKey(fInfoRB, "Headers", NULL, &intStatus);
    226 
    227     if(U_SUCCESS(status)) {
    228       result = new RBTestData(DataFillIn, headers, status);
    229 
    230       if(U_SUCCESS(status)) {
    231         return result;
    232       } else {
    233         delete result;
    234       }
    235     } else {
    236       ures_close(DataFillIn);
    237       ures_close(headers);
    238     }
    239   } else {
    240     status = U_MISSING_RESOURCE_ERROR;
    241   }
    242   return NULL;
    243 }
    244 
    245 TestData* RBTestDataModule::createTestData(const char* name, UErrorCode &status) const
    246 {
    247   TestData *result = NULL;
    248   UErrorCode intStatus = U_ZERO_ERROR;
    249 
    250   if(fDataTestValid == TRUE) {
    251     // Both of these resources get adopted by a TestData object.
    252     UResourceBundle *DataFillIn = ures_getByKey(fTestData, name, NULL, &status);
    253     UResourceBundle *headers = ures_getByKey(fInfoRB, "Headers", NULL, &intStatus);
    254 
    255     if(U_SUCCESS(status)) {
    256       result = new RBTestData(DataFillIn, headers, status);
    257       if(U_SUCCESS(status)) {
    258         return result;
    259       } else {
    260         delete result;
    261       }
    262     } else {
    263       ures_close(DataFillIn);
    264       ures_close(headers);
    265     }
    266   } else {
    267     status = U_MISSING_RESOURCE_ERROR;
    268   }
    269   return NULL;
    270 }
    271 
    272 
    273 
    274 //Get test data from ResourceBundles
    275 UResourceBundle*
    276 RBTestDataModule::getTestBundle(const char* bundleName, UErrorCode &status)
    277 {
    278   if(U_SUCCESS(status)) {
    279     UResourceBundle *testBundle = NULL;
    280     const char* icu_data = fLog.getTestDataPath(status);
    281     if (testBundle == NULL) {
    282         testBundle = ures_openDirect(icu_data, bundleName, &status);
    283         if (status != U_ZERO_ERROR) {
    284             fLog.dataerrln(UNICODE_STRING_SIMPLE("Could not load test data from resourcebundle: ") + UnicodeString(bundleName, -1, US_INV));
    285             fDataTestValid = FALSE;
    286         }
    287     }
    288     return testBundle;
    289   } else {
    290     return NULL;
    291   }
    292 }
    293 
    294