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