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