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
~TestLog()19 TestLog::~TestLog() {}
20
~IcuTestErrorCode()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
errIfFailureAndReset()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
errIfFailureAndReset(const char * fmt,...)39 UBool IcuTestErrorCode::errIfFailureAndReset(const char *fmt, ...) {
40 if(isFailure()) {
41 char buffer[4000];
42 va_list ap;
43 va_start(ap, fmt);
44 vsnprintf(buffer, sizeof(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
errDataIfFailureAndReset()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
errDataIfFailureAndReset(const char * fmt,...)66 UBool IcuTestErrorCode::errDataIfFailureAndReset(const char *fmt, ...) {
67 if(isFailure()) {
68 char buffer[4000];
69 va_list ap;
70 va_start(ap, fmt);
71 vsnprintf(buffer, sizeof(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
expectErrorAndReset(UErrorCode expectedError)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
expectErrorAndReset(UErrorCode expectedError,const char * fmt,...)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 vsnprintf(buffer, sizeof(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
setScope(const char * message)105 void IcuTestErrorCode::setScope(const char* message) {
106 scopeMessage.remove().append({ message, -1, US_INV });
107 }
108
setScope(const UnicodeString & message)109 void IcuTestErrorCode::setScope(const UnicodeString& message) {
110 scopeMessage = message;
111 }
112
handleFailure() const113 void IcuTestErrorCode::handleFailure() const {
114 errlog(false, u"(handleFailure)", nullptr);
115 }
116
errlog(UBool dataErr,const UnicodeString & mainMessage,const char * extraMessage) const117 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
getTestDataModule(const char * name,TestLog & log,UErrorCode & status)137 TestDataModule *TestDataModule::getTestDataModule(const char* name, TestLog& log, UErrorCode &status)
138 {
139 if(U_FAILURE(status)) {
140 return nullptr;
141 }
142 TestDataModule *result = nullptr;
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 nullptr;
153 }
154 }
155
TestDataModule(const char * name,TestLog & log,UErrorCode &)156 TestDataModule::TestDataModule(const char* name, TestLog& log, UErrorCode& /*status*/)
157 : testName(name),
158 fInfo(nullptr),
159 fLog(log)
160 {
161 }
162
~TestDataModule()163 TestDataModule::~TestDataModule() {
164 delete fInfo;
165 }
166
getName() const167 const char * TestDataModule::getName() const
168 {
169 return testName;
170 }
171
172
173
~RBTestDataModule()174 RBTestDataModule::~RBTestDataModule()
175 {
176 ures_close(fTestData);
177 ures_close(fModuleBundle);
178 ures_close(fInfoRB);
179 uprv_free(tdpath);
180 }
181
RBTestDataModule(const char * name,TestLog & log,UErrorCode & status)182 RBTestDataModule::RBTestDataModule(const char* name, TestLog& log, UErrorCode& status)
183 : TestDataModule(name, log, status),
184 fModuleBundle(nullptr),
185 fTestData(nullptr),
186 fInfoRB(nullptr),
187 tdpath(nullptr)
188 {
189 fNumberOfTests = 0;
190 fDataTestValid = true;
191 fModuleBundle = getTestBundle(name, status);
192 if(fDataTestValid) {
193 fTestData = ures_getByKey(fModuleBundle, "TestData", nullptr, &status);
194 fNumberOfTests = ures_getSize(fTestData);
195 fInfoRB = ures_getByKey(fModuleBundle, "Info", nullptr, &status);
196 if(status != U_ZERO_ERROR) {
197 log.errln(UNICODE_STRING_SIMPLE("Unable to initialize test data - missing mandatory description resources!"));
198 fDataTestValid = false;
199 } else {
200 fInfo = new RBDataMap(fInfoRB, status);
201 }
202 }
203 }
204
getInfo(const DataMap * & info,UErrorCode &) const205 UBool RBTestDataModule::getInfo(const DataMap *& info, UErrorCode &/*status*/) const
206 {
207 info = fInfo;
208 if(fInfo) {
209 return true;
210 } else {
211 return false;
212 }
213 }
214
createTestData(int32_t index,UErrorCode & status) const215 TestData* RBTestDataModule::createTestData(int32_t index, UErrorCode &status) const
216 {
217 TestData *result = nullptr;
218 UErrorCode intStatus = U_ZERO_ERROR;
219
220 if(fDataTestValid == true) {
221 // Both of these resources get adopted by a TestData object.
222 UResourceBundle *DataFillIn = ures_getByIndex(fTestData, index, nullptr, &status);
223 UResourceBundle *headers = ures_getByKey(fInfoRB, "Headers", nullptr, &intStatus);
224
225 if(U_SUCCESS(status)) {
226 result = new RBTestData(DataFillIn, headers, status);
227
228 if(U_SUCCESS(status)) {
229 return result;
230 } else {
231 delete result;
232 }
233 } else {
234 ures_close(DataFillIn);
235 ures_close(headers);
236 }
237 } else {
238 status = U_MISSING_RESOURCE_ERROR;
239 }
240 return nullptr;
241 }
242
createTestData(const char * name,UErrorCode & status) const243 TestData* RBTestDataModule::createTestData(const char* name, UErrorCode &status) const
244 {
245 TestData *result = nullptr;
246 UErrorCode intStatus = U_ZERO_ERROR;
247
248 if(fDataTestValid == true) {
249 // Both of these resources get adopted by a TestData object.
250 UResourceBundle *DataFillIn = ures_getByKey(fTestData, name, nullptr, &status);
251 UResourceBundle *headers = ures_getByKey(fInfoRB, "Headers", nullptr, &intStatus);
252
253 if(U_SUCCESS(status)) {
254 result = new RBTestData(DataFillIn, headers, status);
255 if(U_SUCCESS(status)) {
256 return result;
257 } else {
258 delete result;
259 }
260 } else {
261 ures_close(DataFillIn);
262 ures_close(headers);
263 }
264 } else {
265 status = U_MISSING_RESOURCE_ERROR;
266 }
267 return nullptr;
268 }
269
270
271
272 //Get test data from ResourceBundles
273 UResourceBundle*
getTestBundle(const char * bundleName,UErrorCode & status)274 RBTestDataModule::getTestBundle(const char* bundleName, UErrorCode &status)
275 {
276 if(U_SUCCESS(status)) {
277 UResourceBundle *testBundle = nullptr;
278 const char* icu_data = fLog.getTestDataPath(status);
279 if (testBundle == nullptr) {
280 testBundle = ures_openDirect(icu_data, bundleName, &status);
281 if (status != U_ZERO_ERROR) {
282 fLog.dataerrln(UNICODE_STRING_SIMPLE("Could not load test data from resourcebundle: ") + UnicodeString(bundleName, -1, US_INV));
283 fDataTestValid = false;
284 }
285 }
286 return testBundle;
287 } else {
288 return nullptr;
289 }
290 }
291
292