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 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
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 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
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 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
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 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
TestDataModule(const char * name,TestLog & log,UErrorCode &)156 TestDataModule::TestDataModule(const char* name, TestLog& log, UErrorCode& /*status*/)
157 : testName(name),
158 fInfo(NULL),
159 fLog(log)
160 {
161 }
162
~TestDataModule()163 TestDataModule::~TestDataModule() {
164 if(fInfo != NULL) {
165 delete fInfo;
166 }
167 }
168
getName() const169 const char * TestDataModule::getName() const
170 {
171 return testName;
172 }
173
174
175
~RBTestDataModule()176 RBTestDataModule::~RBTestDataModule()
177 {
178 ures_close(fTestData);
179 ures_close(fModuleBundle);
180 ures_close(fInfoRB);
181 uprv_free(tdpath);
182 }
183
RBTestDataModule(const char * name,TestLog & log,UErrorCode & status)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
getInfo(const DataMap * & info,UErrorCode &) const207 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
createTestData(int32_t index,UErrorCode & status) const217 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
createTestData(const char * name,UErrorCode & status) const245 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*
getTestBundle(const char * bundleName,UErrorCode & status)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