• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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