• 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         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