]>
Commit | Line | Data |
---|---|---|
b75a7d8f | 1 | /******************************************************************** |
729e4ab9 | 2 | * COPYRIGHT: |
2ca993e8 | 3 | * Copyright (c) 1997-2016, International Business Machines Corporation and |
729e4ab9 | 4 | * others. All Rights Reserved. |
46f4442e A |
5 | ******************************************************************** |
6 | * File TMSGFMT.CPP | |
7 | * | |
8 | * Modification History: | |
9 | * | |
10 | * Date Name Description | |
11 | * 03/24/97 helena Converted from Java. | |
12 | * 07/11/97 helena Updated to work on AIX. | |
13 | * 08/04/97 jfitz Updated to intltest | |
14 | *******************************************************************/ | |
b75a7d8f A |
15 | |
16 | #include "unicode/utypes.h" | |
17 | ||
18 | #if !UCONFIG_NO_FORMATTING | |
19 | ||
20 | #include "tmsgfmt.h" | |
b331163b | 21 | #include "cmemory.h" |
b75a7d8f A |
22 | |
23 | #include "unicode/format.h" | |
24 | #include "unicode/decimfmt.h" | |
51004dcb | 25 | #include "unicode/localpointer.h" |
b75a7d8f A |
26 | #include "unicode/locid.h" |
27 | #include "unicode/msgfmt.h" | |
28 | #include "unicode/numfmt.h" | |
29 | #include "unicode/choicfmt.h" | |
4388f060 | 30 | #include "unicode/messagepattern.h" |
729e4ab9 | 31 | #include "unicode/selfmt.h" |
b75a7d8f | 32 | #include "unicode/gregocal.h" |
73c04bcf | 33 | #include <stdio.h> |
b75a7d8f A |
34 | |
35 | void | |
36 | TestMessageFormat::runIndexedTest(int32_t index, UBool exec, | |
37 | const char* &name, char* /*par*/) { | |
4388f060 A |
38 | TESTCASE_AUTO_BEGIN; |
39 | TESTCASE_AUTO(testBug1); | |
40 | TESTCASE_AUTO(testBug2); | |
41 | TESTCASE_AUTO(sample); | |
42 | TESTCASE_AUTO(PatternTest); | |
43 | TESTCASE_AUTO(testStaticFormat); | |
44 | TESTCASE_AUTO(testSimpleFormat); | |
45 | TESTCASE_AUTO(testMsgFormatChoice); | |
46 | TESTCASE_AUTO(testCopyConstructor); | |
47 | TESTCASE_AUTO(testAssignment); | |
48 | TESTCASE_AUTO(testClone); | |
49 | TESTCASE_AUTO(testEquals); | |
50 | TESTCASE_AUTO(testNotEquals); | |
51 | TESTCASE_AUTO(testSetLocale); | |
52 | TESTCASE_AUTO(testFormat); | |
53 | TESTCASE_AUTO(testParse); | |
54 | TESTCASE_AUTO(testAdopt); | |
55 | TESTCASE_AUTO(testCopyConstructor2); | |
56 | TESTCASE_AUTO(TestUnlimitedArgsAndSubformats); | |
57 | TESTCASE_AUTO(TestRBNF); | |
58 | TESTCASE_AUTO(TestTurkishCasing); | |
59 | TESTCASE_AUTO(testAutoQuoteApostrophe); | |
60 | TESTCASE_AUTO(testMsgFormatPlural); | |
61 | TESTCASE_AUTO(testMsgFormatSelect); | |
62 | TESTCASE_AUTO(testApostropheInPluralAndSelect); | |
63 | TESTCASE_AUTO(TestApostropheMode); | |
64 | TESTCASE_AUTO(TestCompatibleApostrophe); | |
65 | TESTCASE_AUTO(testCoverage); | |
51004dcb | 66 | TESTCASE_AUTO(testGetFormatNames); |
4388f060 | 67 | TESTCASE_AUTO(TestTrimArgumentName); |
51004dcb | 68 | TESTCASE_AUTO(TestSelectOrdinal); |
57a6839d | 69 | TESTCASE_AUTO(TestDecimals); |
2ca993e8 | 70 | TESTCASE_AUTO(TestArgIsPrefixOfAnother); |
4388f060 | 71 | TESTCASE_AUTO_END; |
b75a7d8f A |
72 | } |
73 | ||
74 | void TestMessageFormat::testBug3() | |
75 | { | |
76 | double myNumber = -123456; | |
77 | DecimalFormat *form = 0; | |
78 | Locale locale[] = { | |
79 | Locale("ar", "", ""), | |
80 | Locale("be", "", ""), | |
81 | Locale("bg", "", ""), | |
82 | Locale("ca", "", ""), | |
83 | Locale("cs", "", ""), | |
84 | Locale("da", "", ""), | |
85 | Locale("de", "", ""), | |
86 | Locale("de", "AT", ""), | |
87 | Locale("de", "CH", ""), | |
88 | Locale("el", "", ""), // 10 | |
89 | Locale("en", "CA", ""), | |
90 | Locale("en", "GB", ""), | |
91 | Locale("en", "IE", ""), | |
92 | Locale("en", "US", ""), | |
93 | Locale("es", "", ""), | |
94 | Locale("et", "", ""), | |
95 | Locale("fi", "", ""), | |
96 | Locale("fr", "", ""), | |
97 | Locale("fr", "BE", ""), | |
98 | Locale("fr", "CA", ""), // 20 | |
99 | Locale("fr", "CH", ""), | |
100 | Locale("he", "", ""), | |
101 | Locale("hr", "", ""), | |
102 | Locale("hu", "", ""), | |
103 | Locale("is", "", ""), | |
104 | Locale("it", "", ""), | |
105 | Locale("it", "CH", ""), | |
106 | Locale("ja", "", ""), | |
107 | Locale("ko", "", ""), | |
108 | Locale("lt", "", ""), // 30 | |
109 | Locale("lv", "", ""), | |
110 | Locale("mk", "", ""), | |
111 | Locale("nl", "", ""), | |
112 | Locale("nl", "BE", ""), | |
113 | Locale("no", "", ""), | |
114 | Locale("pl", "", ""), | |
115 | Locale("pt", "", ""), | |
116 | Locale("ro", "", ""), | |
117 | Locale("ru", "", ""), | |
118 | Locale("sh", "", ""), // 40 | |
119 | Locale("sk", "", ""), | |
120 | Locale("sl", "", ""), | |
121 | Locale("sq", "", ""), | |
122 | Locale("sr", "", ""), | |
123 | Locale("sv", "", ""), | |
124 | Locale("tr", "", ""), | |
125 | Locale("uk", "", ""), | |
126 | Locale("zh", "", ""), | |
127 | Locale("zh", "TW", "") // 49 | |
128 | }; | |
129 | int32_t i; | |
130 | for (i= 0; i < 49; i++) { | |
131 | UnicodeString buffer; | |
132 | logln(locale[i].getDisplayName(buffer)); | |
133 | UErrorCode success = U_ZERO_ERROR; | |
134 | // form = (DecimalFormat*)NumberFormat::createCurrencyInstance(locale[i], success); | |
135 | form = (DecimalFormat*)NumberFormat::createInstance(locale[i], success); | |
136 | if (U_FAILURE(success)) { | |
137 | errln("Err: Number Format "); | |
138 | logln("Number format creation failed."); | |
139 | continue; | |
140 | } | |
141 | Formattable result; | |
142 | FieldPosition pos(0); | |
143 | buffer.remove(); | |
144 | form->format(myNumber, buffer, pos); | |
145 | success = U_ZERO_ERROR; | |
146 | ParsePosition parsePos; | |
147 | form->parse(buffer, result, parsePos); | |
374ca955 | 148 | logln(UnicodeString(" -> ") /* + << dec*/ + toString(result) + UnicodeString("[supposed output for result]")); |
b75a7d8f A |
149 | if (U_FAILURE(success)) { |
150 | errln("Err: Number Format parse"); | |
151 | logln("Number format parse failed."); | |
152 | } | |
153 | delete form; | |
154 | } | |
155 | } | |
156 | ||
157 | void TestMessageFormat::testBug1() | |
158 | { | |
159 | const double limit[] = {0.0, 1.0, 2.0}; | |
160 | const UnicodeString formats[] = {"0.0<=Arg<1.0", | |
161 | "1.0<=Arg<2.0", | |
162 | "2.0<-Arg"}; | |
163 | ChoiceFormat *cf = new ChoiceFormat(limit, formats, 3); | |
164 | FieldPosition status(0); | |
165 | UnicodeString toAppendTo; | |
166 | cf->format((int32_t)1, toAppendTo, status); | |
167 | if (toAppendTo != "1.0<=Arg<2.0") { | |
168 | errln("ChoiceFormat cmp in testBug1"); | |
169 | } | |
170 | logln(toAppendTo); | |
171 | delete cf; | |
172 | } | |
173 | ||
174 | void TestMessageFormat::testBug2() | |
175 | { | |
176 | UErrorCode status = U_ZERO_ERROR; | |
177 | UnicodeString result; | |
178 | // {sfb} use double format in pattern, so result will match (not strictly necessary) | |
46f4442e | 179 | const UnicodeString pattern = "There {0,choice,0#are no files|1#is one file|1<are {0, number} files} on disk {1}. "; |
b75a7d8f A |
180 | logln("The input pattern : " + pattern); |
181 | MessageFormat *fmt = new MessageFormat(pattern, status); | |
182 | if (U_FAILURE(status)) { | |
4388f060 | 183 | dataerrln("MessageFormat pattern creation failed. - %s", u_errorName(status)); |
b75a7d8f A |
184 | return; |
185 | } | |
186 | logln("The output pattern is : " + fmt->toPattern(result)); | |
187 | if (pattern != result) { | |
188 | errln("MessageFormat::toPattern() failed."); | |
189 | } | |
190 | delete fmt; | |
191 | } | |
192 | ||
193 | #if 0 | |
4388f060 | 194 | #if defined(_DEBUG) && U_IOSTREAM_SOURCE >= 199711 |
b75a7d8f A |
195 | //---------------------------------------------------- |
196 | // console I/O | |
197 | //---------------------------------------------------- | |
198 | ||
4388f060 A |
199 | #include <iostream> |
200 | std::ostream& operator<<(std::ostream& stream, const Formattable& obj); | |
b75a7d8f A |
201 | |
202 | #include "unicode/datefmt.h" | |
203 | #include <stdlib.h> | |
b75a7d8f A |
204 | #include <string.h> |
205 | ||
206 | IntlTest& | |
207 | operator<<( IntlTest& stream, | |
208 | const Formattable& obj) | |
209 | { | |
210 | static DateFormat *defDateFormat = 0; | |
211 | ||
212 | UnicodeString buffer; | |
213 | switch(obj.getType()) { | |
214 | case Formattable::kDate : | |
215 | if (defDateFormat == 0) { | |
216 | defDateFormat = DateFormat::createInstance(); | |
217 | } | |
218 | defDateFormat->format(obj.getDate(), buffer); | |
219 | stream << buffer; | |
220 | break; | |
221 | case Formattable::kDouble : | |
222 | char convert[20]; | |
223 | sprintf( convert, "%lf", obj.getDouble() ); | |
224 | stream << convert << "D"; | |
225 | break; | |
226 | case Formattable::kLong : | |
227 | stream << obj.getLong() << "L"; | |
228 | break; | |
229 | case Formattable::kString: | |
230 | stream << "\"" << obj.getString(buffer) << "\""; | |
231 | break; | |
232 | case Formattable::kArray: | |
233 | int32_t i, count; | |
234 | const Formattable* array; | |
235 | array = obj.getArray(count); | |
236 | stream << "["; | |
237 | for (i=0; i<count; ++i) stream << array[i] << ( (i==(count-1)) ? "" : ", " ); | |
238 | stream << "]"; | |
239 | break; | |
240 | default: | |
241 | stream << "INVALID_Formattable"; | |
242 | } | |
243 | return stream; | |
244 | } | |
4388f060 | 245 | #endif /* defined(_DEBUG) && U_IOSTREAM_SOURCE >= 199711 */ |
b75a7d8f A |
246 | #endif |
247 | ||
248 | void TestMessageFormat::PatternTest() | |
249 | { | |
250 | Formattable testArgs[] = { | |
251 | Formattable(double(1)), Formattable(double(3456)), | |
252 | Formattable("Disk"), Formattable(UDate((int32_t)1000000000L), Formattable::kIsDate) | |
253 | }; | |
254 | UnicodeString testCases[] = { | |
255 | "Quotes '', '{', 'a' {0} '{0}'", | |
256 | "Quotes '', '{', 'a' {0,number} '{0}'", | |
257 | "'{'1,number,'#',##} {1,number,'#',##}", | |
258 | "There are {1} files on {2} at {3}.", | |
259 | "On {2}, there are {1} files, with {0,number,currency}.", | |
260 | "'{1,number,percent}', {1,number,percent},", | |
261 | "'{1,date,full}', {1,date,full},", | |
262 | "'{3,date,full}', {3,date,full},", | |
263 | "'{1,number,#,##}' {1,number,#,##}", | |
264 | }; | |
265 | ||
4388f060 A |
266 | // ICU 4.8 returns the original pattern (testCases), |
267 | // rather than toPattern() reconstituting a new, equivalent pattern string (testResultPatterns). | |
268 | /*UnicodeString testResultPatterns[] = { | |
b75a7d8f A |
269 | "Quotes '', '{', a {0} '{'0}", |
270 | "Quotes '', '{', a {0,number} '{'0}", | |
271 | "'{'1,number,#,##} {1,number,'#'#,##}", | |
272 | "There are {1} files on {2} at {3}.", | |
273 | "On {2}, there are {1} files, with {0,number,currency}.", | |
274 | "'{'1,number,percent}, {1,number,percent},", | |
275 | "'{'1,date,full}, {1,date,full},", | |
276 | "'{'3,date,full}, {3,date,full},", | |
277 | "'{'1,number,#,##} {1,number,#,##}" | |
4388f060 | 278 | };*/ |
b75a7d8f A |
279 | |
280 | UnicodeString testResultStrings[] = { | |
4388f060 A |
281 | "Quotes ', {, 'a' 1 {0}", |
282 | "Quotes ', {, 'a' 1 {0}", | |
283 | "{1,number,'#',##} #34,56", | |
51004dcb | 284 | "There are 3,456 files on Disk at 1/12/70, 5:46 AM.", |
b75a7d8f A |
285 | "On Disk, there are 3,456 files, with $1.00.", |
286 | "{1,number,percent}, 345,600%,", | |
287 | "{1,date,full}, Wednesday, December 31, 1969,", | |
288 | "{3,date,full}, Monday, January 12, 1970,", | |
289 | "{1,number,#,##} 34,56" | |
290 | }; | |
291 | ||
292 | ||
293 | for (int32_t i = 0; i < 9; ++i) { | |
294 | //it_out << "\nPat in: " << testCases[i]); | |
295 | ||
296 | MessageFormat *form = 0; | |
297 | UErrorCode success = U_ZERO_ERROR; | |
298 | UnicodeString buffer; | |
299 | form = new MessageFormat(testCases[i], Locale::getUS(), success); | |
300 | if (U_FAILURE(success)) { | |
729e4ab9 | 301 | dataerrln("MessageFormat creation failed.#1 - %s", u_errorName(success)); |
b75a7d8f A |
302 | logln(((UnicodeString)"MessageFormat for ") + testCases[i] + " creation failed.\n"); |
303 | continue; | |
304 | } | |
4388f060 A |
305 | // ICU 4.8 returns the original pattern (testCases), |
306 | // rather than toPattern() reconstituting a new, equivalent pattern string (testResultPatterns). | |
307 | if (form->toPattern(buffer) != testCases[i]) { | |
308 | // Note: An alternative test would be to build MessagePattern objects for | |
309 | // both the input and output patterns and compare them, taking SKIP_SYNTAX etc. | |
310 | // into account. | |
311 | // (Too much trouble...) | |
b75a7d8f A |
312 | errln(UnicodeString("TestMessageFormat::PatternTest failed test #2, i = ") + i); |
313 | //form->toPattern(buffer); | |
314 | errln(((UnicodeString)" Orig: ") + testCases[i]); | |
4388f060 | 315 | errln(((UnicodeString)" Exp: ") + testCases[i]); |
b75a7d8f A |
316 | errln(((UnicodeString)" Got: ") + buffer); |
317 | } | |
318 | ||
319 | //it_out << "Pat out: " << form->toPattern(buffer)); | |
320 | UnicodeString result; | |
321 | int32_t count = 4; | |
322 | FieldPosition fieldpos(0); | |
323 | form->format(testArgs, count, result, fieldpos, success); | |
324 | if (U_FAILURE(success)) { | |
729e4ab9 | 325 | dataerrln("MessageFormat failed test #3 - %s", u_errorName(success)); |
b75a7d8f A |
326 | logln("TestMessageFormat::PatternTest failed test #3"); |
327 | continue; | |
328 | } | |
329 | if (result != testResultStrings[i]) { | |
330 | errln("TestMessageFormat::PatternTest failed test #4"); | |
331 | logln("TestMessageFormat::PatternTest failed #4."); | |
332 | logln(UnicodeString(" Result: ") + result ); | |
333 | logln(UnicodeString(" Expected: ") + testResultStrings[i] ); | |
334 | } | |
4388f060 | 335 | |
b75a7d8f A |
336 | |
337 | //it_out << "Result: " << result); | |
338 | #if 0 | |
339 | /* TODO: Look at this test and see if this is still a valid test */ | |
340 | logln("---------------- test parse ----------------"); | |
341 | ||
342 | form->toPattern(buffer); | |
343 | logln("MSG pattern for parse: " + buffer); | |
344 | ||
345 | int32_t parseCount = 0; | |
346 | Formattable* values = form->parse(result, parseCount, success); | |
347 | if (U_FAILURE(success)) { | |
348 | errln("MessageFormat failed test #5"); | |
349 | logln(UnicodeString("MessageFormat failed test #5 with error code ")+(int32_t)success); | |
350 | } else if (parseCount != count) { | |
351 | errln("MSG count not %d as expected. Got %d", count, parseCount); | |
352 | } | |
353 | UBool failed = FALSE; | |
354 | for (int32_t j = 0; j < parseCount; ++j) { | |
355 | if (values == 0 || testArgs[j] != values[j]) { | |
356 | errln(((UnicodeString)"MSG testargs[") + j + "]: " + toString(testArgs[j])); | |
357 | errln(((UnicodeString)"MSG values[") + j + "] : " + toString(values[j])); | |
358 | failed = TRUE; | |
359 | } | |
360 | } | |
361 | if (failed) | |
362 | errln("MessageFormat failed test #6"); | |
363 | #endif | |
364 | delete form; | |
365 | } | |
366 | } | |
367 | ||
368 | void TestMessageFormat::sample() | |
369 | { | |
370 | MessageFormat *form = 0; | |
371 | UnicodeString buffer1, buffer2; | |
372 | UErrorCode success = U_ZERO_ERROR; | |
373 | form = new MessageFormat("There are {0} files on {1}", success); | |
374 | if (U_FAILURE(success)) { | |
375 | errln("Err: Message format creation failed"); | |
376 | logln("Sample message format creation failed."); | |
377 | return; | |
378 | } | |
379 | UnicodeString abc("abc"); | |
380 | UnicodeString def("def"); | |
381 | Formattable testArgs1[] = { abc, def }; | |
382 | FieldPosition fieldpos(0); | |
374ca955 A |
383 | assertEquals("format", |
384 | "There are abc files on def", | |
385 | form->format(testArgs1, 2, buffer2, fieldpos, success)); | |
386 | assertSuccess("format", success); | |
b75a7d8f A |
387 | delete form; |
388 | } | |
389 | ||
374ca955 | 390 | void TestMessageFormat::testStaticFormat() |
b75a7d8f | 391 | { |
b75a7d8f | 392 | UErrorCode err = U_ZERO_ERROR; |
b75a7d8f A |
393 | Formattable arguments[] = { |
394 | (int32_t)7, | |
395 | Formattable(UDate(8.71068e+011), Formattable::kIsDate), | |
396 | "a disturbance in the Force" | |
397 | }; | |
398 | ||
399 | UnicodeString result; | |
400 | result = MessageFormat::format( | |
401 | "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.", | |
402 | arguments, | |
403 | 3, | |
404 | result, | |
405 | err); | |
406 | ||
407 | if (U_FAILURE(err)) { | |
729e4ab9 | 408 | dataerrln("TestMessageFormat::testStaticFormat #1 - %s", u_errorName(err)); |
b75a7d8f A |
409 | logln(UnicodeString("TestMessageFormat::testStaticFormat failed test #1 with error code ")+(int32_t)err); |
410 | return; | |
411 | } | |
412 | ||
413 | const UnicodeString expected( | |
414 | "At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force on planet 7.", ""); | |
415 | if (result != expected) { | |
416 | errln("TestMessageFormat::testStaticFormat failed on test"); | |
417 | logln( UnicodeString(" Result: ") + result ); | |
418 | logln( UnicodeString(" Expected: ") + expected ); | |
419 | } | |
420 | } | |
421 | ||
73c04bcf A |
422 | /* When the default locale is tr, make sure that the pattern can still be parsed. */ |
423 | void TestMessageFormat::TestTurkishCasing() | |
424 | { | |
425 | UErrorCode err = U_ZERO_ERROR; | |
426 | Locale saveDefaultLocale; | |
427 | Locale::setDefault( Locale("tr"), err ); | |
428 | ||
429 | Formattable arguments[] = { | |
430 | (int32_t)7, | |
431 | Formattable(UDate(8.71068e+011), Formattable::kIsDate), | |
432 | "a disturbance in the Force" | |
433 | }; | |
434 | ||
435 | UnicodeString result; | |
436 | result = MessageFormat::format( | |
437 | "At {1,TIME} on {1,DATE,SHORT}, there was {2} on planet {0,NUMBER,INTEGER}.", | |
438 | arguments, | |
439 | 3, | |
440 | result, | |
441 | err); | |
442 | ||
443 | if (U_FAILURE(err)) { | |
729e4ab9 | 444 | dataerrln("TestTurkishCasing #1 with error code %s", u_errorName(err)); |
73c04bcf A |
445 | return; |
446 | } | |
447 | ||
448 | const UnicodeString expected( | |
51004dcb | 449 | "At 12:20:00 on 8.08.1997, there was a disturbance in the Force on planet 7.", ""); |
73c04bcf A |
450 | if (result != expected) { |
451 | errln("TestTurkishCasing failed on test"); | |
452 | errln( UnicodeString(" Result: ") + result ); | |
453 | errln( UnicodeString(" Expected: ") + expected ); | |
454 | } | |
455 | Locale::setDefault( saveDefaultLocale, err ); | |
456 | } | |
b75a7d8f A |
457 | |
458 | void TestMessageFormat::testSimpleFormat(/* char* par */) | |
459 | { | |
460 | logln("running TestMessageFormat::testSimpleFormat"); | |
461 | ||
462 | UErrorCode err = U_ZERO_ERROR; | |
463 | ||
464 | Formattable testArgs1[] = {(int32_t)0, "MyDisk"}; | |
465 | Formattable testArgs2[] = {(int32_t)1, "MyDisk"}; | |
466 | Formattable testArgs3[] = {(int32_t)12, "MyDisk"}; | |
467 | ||
468 | MessageFormat* form = new MessageFormat( | |
469 | "The disk \"{1}\" contains {0} file(s).", err); | |
470 | ||
471 | UnicodeString string; | |
472 | FieldPosition ignore(FieldPosition::DONT_CARE); | |
473 | form->format(testArgs1, 2, string, ignore, err); | |
474 | if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 0 file(s).") { | |
729e4ab9 | 475 | dataerrln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #1 - ") + u_errorName(err)); |
b75a7d8f A |
476 | } |
477 | ||
478 | ignore.setField(FieldPosition::DONT_CARE); | |
479 | string.remove(); | |
480 | form->format(testArgs2, 2, string, ignore, err); | |
481 | if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 1 file(s).") { | |
482 | logln(string); | |
729e4ab9 | 483 | dataerrln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #2")+string + " - " + u_errorName(err)); |
b75a7d8f A |
484 | } |
485 | ||
486 | ignore.setField(FieldPosition::DONT_CARE); | |
487 | string.remove(); | |
488 | form->format(testArgs3, 2, string, ignore, err); | |
489 | if (U_FAILURE(err) || string != "The disk \"MyDisk\" contains 12 file(s).") { | |
729e4ab9 | 490 | dataerrln(UnicodeString("TestMessageFormat::testSimpleFormat failed on test #3")+string + " - " + u_errorName(err)); |
b75a7d8f A |
491 | } |
492 | ||
493 | delete form; | |
494 | } | |
495 | ||
496 | void TestMessageFormat::testMsgFormatChoice(/* char* par */) | |
497 | { | |
498 | logln("running TestMessageFormat::testMsgFormatChoice"); | |
499 | ||
500 | UErrorCode err = U_ZERO_ERROR; | |
501 | ||
502 | MessageFormat* form = new MessageFormat("The disk \"{1}\" contains {0}.", err); | |
503 | double filelimits[] = {0,1,2}; | |
504 | UnicodeString filepart[] = {"no files","one file","{0,number} files"}; | |
505 | ChoiceFormat* fileform = new ChoiceFormat(filelimits, filepart, 3); | |
506 | form->setFormat(1,*fileform); // NOT zero, see below | |
507 | //is the format adopted? | |
508 | ||
509 | FieldPosition ignore(FieldPosition::DONT_CARE); | |
510 | UnicodeString string; | |
511 | Formattable testArgs1[] = {(int32_t)0, "MyDisk"}; | |
512 | form->format(testArgs1, 2, string, ignore, err); | |
513 | if (string != "The disk \"MyDisk\" contains no files.") { | |
514 | errln("TestMessageFormat::testMsgFormatChoice failed on test #1"); | |
515 | } | |
516 | ||
517 | ignore.setField(FieldPosition::DONT_CARE); | |
518 | string.remove(); | |
519 | Formattable testArgs2[] = {(int32_t)1, "MyDisk"}; | |
520 | form->format(testArgs2, 2, string, ignore, err); | |
521 | if (string != "The disk \"MyDisk\" contains one file.") { | |
522 | errln("TestMessageFormat::testMsgFormatChoice failed on test #2"); | |
523 | } | |
524 | ||
525 | ignore.setField(FieldPosition::DONT_CARE); | |
526 | string.remove(); | |
527 | Formattable testArgs3[] = {(int32_t)1273, "MyDisk"}; | |
528 | form->format(testArgs3, 2, string, ignore, err); | |
529 | if (string != "The disk \"MyDisk\" contains 1,273 files.") { | |
729e4ab9 | 530 | dataerrln("TestMessageFormat::testMsgFormatChoice failed on test #3 - %s", u_errorName(err)); |
b75a7d8f A |
531 | } |
532 | ||
533 | delete form; | |
534 | delete fileform; | |
535 | } | |
536 | ||
537 | ||
46f4442e A |
538 | void TestMessageFormat::testMsgFormatPlural(/* char* par */) |
539 | { | |
540 | logln("running TestMessageFormat::testMsgFormatPlural"); | |
541 | ||
542 | UErrorCode err = U_ZERO_ERROR; | |
543 | UnicodeString t1("{0, plural, one{C''est # fichier} other{Ce sont # fichiers}} dans la liste."); | |
544 | UnicodeString t2("{argument, plural, one{C''est # fichier} other {Ce sont # fichiers}} dans la liste."); | |
545 | UnicodeString t3("There {0, plural, one{is # zavod}few{are {0, number,###.0} zavoda} other{are # zavodov}} in the directory."); | |
546 | UnicodeString t4("There {argument, plural, one{is # zavod}few{are {argument, number,###.0} zavoda} other{are #zavodov}} in the directory."); | |
4388f060 | 547 | UnicodeString t5("{0, plural, one {{0, number,C''est #,##0.0# fichier}} other {Ce sont # fichiers}} dans la liste."); |
46f4442e A |
548 | MessageFormat* mfNum = new MessageFormat(t1, Locale("fr"), err); |
549 | if (U_FAILURE(err)) { | |
729e4ab9 | 550 | dataerrln("TestMessageFormat::testMsgFormatPlural #1 - argumentIndex - %s", u_errorName(err)); |
46f4442e A |
551 | logln(UnicodeString("TestMessageFormat::testMsgFormatPlural #1 with error code ")+(int32_t)err); |
552 | return; | |
553 | } | |
554 | Formattable testArgs1((int32_t)0); | |
555 | FieldPosition ignore(FieldPosition::DONT_CARE); | |
556 | UnicodeString numResult1; | |
557 | mfNum->format(&testArgs1, 1, numResult1, ignore, err); | |
558 | ||
559 | MessageFormat* mfAlpha = new MessageFormat(t2, Locale("fr"), err); | |
560 | UnicodeString argName[] = {UnicodeString("argument")}; | |
561 | UnicodeString argNameResult; | |
562 | mfAlpha->format(argName, &testArgs1, 1, argNameResult, err); | |
563 | if (U_FAILURE(err)) { | |
4388f060 | 564 | dataerrln("TestMessageFormat::testMsgFormatPlural #1 - argumentName - %s", u_errorName(err)); |
46f4442e A |
565 | logln(UnicodeString("TestMessageFormat::testMsgFormatPlural #1 with error code ")+(int32_t)err); |
566 | delete mfNum; | |
567 | return; | |
568 | } | |
569 | if ( numResult1 != argNameResult){ | |
570 | errln("TestMessageFormat::testMsgFormatPlural #1"); | |
571 | logln(UnicodeString("The results of argumentName and argumentIndex are not the same.")); | |
572 | } | |
573 | if ( numResult1 != UnicodeString("C\'est 0 fichier dans la liste.")) { | |
574 | errln("TestMessageFormat::testMsgFormatPlural #1"); | |
575 | logln(UnicodeString("The results of argumentName and argumentIndex are not the same.")); | |
576 | } | |
577 | err = U_ZERO_ERROR; | |
578 | ||
579 | delete mfNum; | |
580 | delete mfAlpha; | |
581 | ||
57a6839d | 582 | MessageFormat* mfNum2 = new MessageFormat(t3, Locale("uk"), err); |
46f4442e A |
583 | numResult1.remove(); |
584 | Formattable testArgs2((int32_t)4); | |
585 | mfNum2->format(&testArgs2, 1, numResult1, ignore, err); | |
57a6839d | 586 | MessageFormat* mfAlpha2 = new MessageFormat(t4, Locale("uk"), err); |
46f4442e A |
587 | argNameResult.remove(); |
588 | mfAlpha2->format(argName, &testArgs2, 1, argNameResult, err); | |
589 | ||
590 | if (U_FAILURE(err)) { | |
591 | errln("TestMessageFormat::testMsgFormatPlural #2 - argumentName"); | |
592 | logln(UnicodeString("TestMessageFormat::testMsgFormatPlural #2 with error code ")+(int32_t)err); | |
593 | delete mfNum2; | |
594 | return; | |
595 | } | |
596 | if ( numResult1 != argNameResult){ | |
597 | errln("TestMessageFormat::testMsgFormatPlural #2"); | |
598 | logln(UnicodeString("The results of argumentName and argumentIndex are not the same.")); | |
599 | } | |
600 | if ( numResult1 != UnicodeString("There are 4,0 zavoda in the directory.")) { | |
601 | errln("TestMessageFormat::testMsgFormatPlural #2"); | |
602 | logln(UnicodeString("The results of argumentName and argumentIndex are not the same.")); | |
603 | } | |
604 | ||
605 | delete mfNum2; | |
606 | delete mfAlpha2; | |
607 | ||
608 | // nested formats | |
609 | err = U_ZERO_ERROR; | |
610 | MessageFormat* msgFmt = new MessageFormat(t5, Locale("fr"), err); | |
611 | if (U_FAILURE(err)) { | |
612 | errln("TestMessageFormat::test nested PluralFormat with argumentName"); | |
613 | logln(UnicodeString("TestMessageFormat::test nested PluralFormat with error code ")+(int32_t)err); | |
614 | delete msgFmt; | |
615 | return; | |
616 | } | |
617 | Formattable testArgs3((int32_t)0); | |
618 | argNameResult.remove(); | |
619 | msgFmt->format(&testArgs3, 1, argNameResult, ignore, err); | |
620 | if (U_FAILURE(err)) { | |
621 | errln("TestMessageFormat::test nested PluralFormat with argumentName"); | |
622 | } | |
623 | if ( argNameResult!= UnicodeString("C'est 0,0 fichier dans la liste.")) { | |
4388f060 | 624 | errln(UnicodeString("TestMessageFormat::test nested named PluralFormat: ") + argNameResult); |
46f4442e A |
625 | logln(UnicodeString("The unexpected nested named PluralFormat.")); |
626 | } | |
627 | delete msgFmt; | |
628 | } | |
629 | ||
4388f060 A |
630 | void TestMessageFormat::testApostropheInPluralAndSelect() { |
631 | UErrorCode errorCode = U_ZERO_ERROR; | |
632 | MessageFormat msgFmt(UNICODE_STRING_SIMPLE( | |
633 | "abc_{0,plural,other{#'#'#'{'#''}}_def_{1,select,other{sel'}'ect''}}_xyz"), | |
634 | Locale::getEnglish(), | |
635 | errorCode); | |
636 | if (U_FAILURE(errorCode)) { | |
637 | errln("MessageFormat constructor failed - %s\n", u_errorName(errorCode)); | |
638 | return; | |
639 | } | |
640 | UnicodeString expected = UNICODE_STRING_SIMPLE("abc_3#3{3'_def_sel}ect'_xyz"); | |
641 | Formattable args[] = { (int32_t)3, UNICODE_STRING_SIMPLE("x") }; | |
642 | internalFormat( | |
643 | &msgFmt, args, 2, expected, | |
644 | "MessageFormat with apostrophes in plural/select arguments failed:\n"); | |
645 | } | |
646 | ||
729e4ab9 A |
647 | void TestMessageFormat::internalFormat(MessageFormat* msgFmt , |
648 | Formattable* args , int32_t numOfArgs , | |
4388f060 | 649 | UnicodeString expected, const char* errMsg) |
729e4ab9 A |
650 | { |
651 | UnicodeString result; | |
652 | FieldPosition ignore(FieldPosition::DONT_CARE); | |
653 | UErrorCode status = U_ZERO_ERROR; | |
654 | ||
655 | //Format with passed arguments | |
656 | msgFmt->format( args , numOfArgs , result, ignore, status); | |
657 | if (U_FAILURE(status)) { | |
57a6839d | 658 | dataerrln( "%s error while formatting with ErrorCode as %s" ,errMsg, u_errorName(status) ); |
729e4ab9 A |
659 | } |
660 | //Compare expected with obtained result | |
661 | if ( result!= expected ) { | |
662 | UnicodeString err = UnicodeString(errMsg); | |
663 | err+= UnicodeString(":Unexpected Result \n Expected: " + expected + "\n Obtained: " + result + "\n"); | |
664 | dataerrln(err); | |
665 | } | |
666 | } | |
667 | ||
668 | MessageFormat* TestMessageFormat::internalCreate( | |
669 | UnicodeString pattern ,Locale locale ,UErrorCode &status , char* errMsg) | |
670 | { | |
671 | //Create the MessageFormat with simple SelectFormat | |
672 | MessageFormat* msgFmt = new MessageFormat(pattern, locale, status); | |
673 | if (U_FAILURE(status)) { | |
57a6839d | 674 | dataerrln( "%s error while constructing with ErrorCode as %s" ,errMsg, u_errorName(status) ); |
729e4ab9 A |
675 | logln(UnicodeString("TestMessageFormat::testMsgFormatSelect #1 with error code ")+(int32_t)status); |
676 | return NULL; | |
677 | } | |
678 | return msgFmt; | |
679 | } | |
680 | ||
681 | void TestMessageFormat::testMsgFormatSelect(/* char* par */) | |
682 | { | |
683 | logln("running TestMessageFormat::testMsgFormatSelect"); | |
684 | ||
685 | UErrorCode err = U_ZERO_ERROR; | |
686 | //French Pattern | |
687 | UnicodeString t1("{0} est {1, select, female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris."); | |
688 | ||
689 | err = U_ZERO_ERROR; | |
690 | //Create the MessageFormat with simple French pattern | |
691 | MessageFormat* msgFmt1 = internalCreate(t1.unescape(), Locale("fr"),err,(char*)"From TestMessageFormat::TestSelectFormat create t1"); | |
692 | if (!U_FAILURE(err)) { | |
693 | //Arguments | |
694 | Formattable testArgs10[] = {"Kirti","female"}; | |
695 | Formattable testArgs11[] = {"Victor","other"}; | |
696 | Formattable testArgs12[] = {"Ash","unknown"}; | |
697 | Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12}; | |
698 | UnicodeString exp[] = { | |
699 | "Kirti est all\\u00E9e \\u00E0 Paris." , | |
700 | "Victor est all\\u00E9 \\u00E0 Paris.", | |
701 | "Ash est all\\u00E9 \\u00E0 Paris."}; | |
702 | //Format | |
703 | for( int i=0; i< 3; i++){ | |
704 | internalFormat( msgFmt1 , testArgs[i], 2, exp[i].unescape() ,(char*)"From TestMessageFormat::testSelectFormat format t1"); | |
705 | } | |
706 | } | |
707 | delete msgFmt1; | |
708 | ||
709 | //Quoted French Pattern | |
710 | UnicodeString t2("{0} est {1, select, female {all\\u00E9e c''est} other {all\\u00E9 c''est}} \\u00E0 Paris."); | |
711 | err = U_ZERO_ERROR; | |
712 | //Create the MessageFormat with Quoted French pattern | |
713 | MessageFormat* msgFmt2 = internalCreate(t2.unescape(), Locale("fr"),err,(char*)"From TestMessageFormat::TestSelectFormat create t2"); | |
714 | if (!U_FAILURE(err)) { | |
715 | //Arguments | |
716 | Formattable testArgs10[] = {"Kirti","female"}; | |
717 | Formattable testArgs11[] = {"Victor","other"}; | |
718 | Formattable testArgs12[] = {"Ash","male"}; | |
719 | Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12}; | |
720 | UnicodeString exp[] = { | |
721 | "Kirti est all\\u00E9e c'est \\u00E0 Paris." , | |
722 | "Victor est all\\u00E9 c'est \\u00E0 Paris.", | |
723 | "Ash est all\\u00E9 c'est \\u00E0 Paris."}; | |
724 | //Format | |
725 | for( int i=0; i< 3; i++){ | |
726 | internalFormat( msgFmt2 , testArgs[i], 2, exp[i].unescape() ,(char*)"From TestMessageFormat::testSelectFormat format t2"); | |
727 | } | |
728 | } | |
729 | delete msgFmt2; | |
730 | ||
731 | //English Pattern | |
732 | UnicodeString t3("{0, select , male {MALE FR company} female {FEMALE FR company} other {FR otherValue}} published new books."); | |
733 | err = U_ZERO_ERROR; | |
734 | //Create the MessageFormat with English pattern | |
735 | MessageFormat* msgFmt3 = internalCreate(t3, Locale("en"),err,(char*)"From TestMessageFormat::TestSelectFormat create t3"); | |
736 | if (!U_FAILURE(err)) { | |
737 | //Arguments | |
738 | Formattable testArgs10[] = {"female"}; | |
739 | Formattable testArgs11[] = {"other"}; | |
740 | Formattable testArgs12[] = {"male"}; | |
741 | Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12}; | |
742 | UnicodeString exp[] = { | |
743 | "FEMALE FR company published new books." , | |
744 | "FR otherValue published new books.", | |
745 | "MALE FR company published new books."}; | |
746 | //Format | |
747 | for( int i=0; i< 3; i++){ | |
748 | internalFormat( msgFmt3 , testArgs[i], 1, exp[i] ,(char*)"From TestMessageFormat::testSelectFormat format t3"); | |
749 | } | |
750 | } | |
751 | delete msgFmt3; | |
752 | ||
753 | //Nested patterns with plural, number ,choice ,select format etc. | |
754 | //Select Format with embedded number format | |
755 | UnicodeString t4("{0} est {1, select, female {{2,number,integer} all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris."); | |
57a6839d | 756 | err = U_ZERO_ERROR; |
729e4ab9 A |
757 | //Create the MessageFormat with Select Format with embedded number format (nested pattern) |
758 | MessageFormat* msgFmt4 = internalCreate(t4.unescape(), Locale("fr"),err,(char*)"From TestMessageFormat::TestSelectFormat create t4"); | |
759 | if (!U_FAILURE(err)) { | |
760 | //Arguments | |
761 | Formattable testArgs10[] = {"Kirti","female",(int32_t)6}; | |
762 | Formattable testArgs11[] = {"Kirti","female",100.100}; | |
763 | Formattable testArgs12[] = {"Kirti","other",(int32_t)6}; | |
764 | Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12}; | |
765 | UnicodeString exp[] = { | |
766 | "Kirti est 6 all\\u00E9e \\u00E0 Paris." , | |
767 | "Kirti est 100 all\\u00E9e \\u00E0 Paris.", | |
768 | "Kirti est all\\u00E9 \\u00E0 Paris."}; | |
769 | //Format | |
770 | for( int i=0; i< 3; i++){ | |
771 | internalFormat( msgFmt4 , testArgs[i], 3, exp[i].unescape() ,(char*)"From TestMessageFormat::testSelectFormat format t4"); | |
772 | } | |
773 | } | |
774 | delete msgFmt4; | |
775 | ||
729e4ab9 A |
776 | //Plural format with embedded select format |
777 | UnicodeString t5("{0} {1, plural, one {est {2, select, female {all\\u00E9e} other {all\\u00E9}}} other {sont {2, select, female {all\\u00E9es} other {all\\u00E9s}}}} \\u00E0 Paris."); | |
778 | err = U_ZERO_ERROR; | |
779 | //Create the MessageFormat with Plural format with embedded select format(nested pattern) | |
780 | MessageFormat* msgFmt5 = internalCreate(t5.unescape(), Locale("fr"),err,(char*)"From TestMessageFormat::TestSelectFormat create t5"); | |
781 | if (!U_FAILURE(err)) { | |
782 | //Arguments | |
783 | Formattable testArgs10[] = {"Kirti",(int32_t)6,"female"}; | |
784 | Formattable testArgs11[] = {"Kirti",(int32_t)1,"female"}; | |
785 | Formattable testArgs12[] = {"Ash",(int32_t)1,"other"}; | |
786 | Formattable testArgs13[] = {"Ash",(int32_t)5,"other"}; | |
787 | Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12,testArgs13}; | |
788 | UnicodeString exp[] = { | |
789 | "Kirti sont all\\u00E9es \\u00E0 Paris." , | |
790 | "Kirti est all\\u00E9e \\u00E0 Paris.", | |
791 | "Ash est all\\u00E9 \\u00E0 Paris.", | |
792 | "Ash sont all\\u00E9s \\u00E0 Paris."}; | |
793 | //Format | |
794 | for( int i=0; i< 4; i++){ | |
795 | internalFormat( msgFmt5 , testArgs[i], 3, exp[i].unescape() ,(char*)"From TestMessageFormat::testSelectFormat format t5"); | |
796 | } | |
797 | } | |
798 | delete msgFmt5; | |
799 | ||
800 | err = U_ZERO_ERROR; | |
801 | //Select, plural, and number formats heavily nested | |
802 | UnicodeString t6("{0} und {1, select, female {{2, plural, one {{3, select, female {ihre Freundin} other {ihr Freund}} } other {ihre {2, number, integer} {3, select, female {Freundinnen} other {Freunde}} } }} other{{2, plural, one {{3, select, female {seine Freundin} other {sein Freund}}} other {seine {2, number, integer} {3, select, female {Freundinnen} other {Freunde}}}}} } gingen nach Paris."); | |
803 | //Create the MessageFormat with Select, plural, and number formats heavily nested | |
804 | MessageFormat* msgFmt6 = internalCreate(t6, Locale("de"),err,(char*)"From TestMessageFormat::TestSelectFormat create t6"); | |
805 | if (!U_FAILURE(err)) { | |
806 | //Arguments | |
807 | Formattable testArgs10[] = {"Kirti","other",(int32_t)1,"other"}; | |
808 | Formattable testArgs11[] = {"Kirti","other",(int32_t)6,"other"}; | |
809 | Formattable testArgs12[] = {"Kirti","other",(int32_t)1,"female"}; | |
810 | Formattable testArgs13[] = {"Kirti","other",(int32_t)3,"female"}; | |
811 | Formattable testArgs14[] = {"Kirti","female",(int32_t)1,"female"}; | |
812 | Formattable testArgs15[] = {"Kirti","female",(int32_t)5,"female"}; | |
813 | Formattable testArgs16[] = {"Kirti","female",(int32_t)1,"other"}; | |
814 | Formattable testArgs17[] = {"Kirti","female",(int32_t)5,"other"}; | |
815 | Formattable testArgs18[] = {"Kirti","mixed",(int32_t)1,"mixed"}; | |
816 | Formattable testArgs19[] = {"Kirti","mixed",(int32_t)1,"other"}; | |
817 | Formattable testArgs20[] = {"Kirti","female",(int32_t)1,"mixed"}; | |
818 | Formattable testArgs21[] = {"Kirti","mixed",(int32_t)5,"mixed"}; | |
819 | Formattable testArgs22[] = {"Kirti","mixed",(int32_t)5,"other"}; | |
820 | Formattable testArgs23[] = {"Kirti","female",(int32_t)5,"mixed"}; | |
821 | Formattable* testArgs[] = {testArgs10,testArgs11,testArgs12,testArgs13, | |
822 | testArgs14,testArgs15,testArgs16,testArgs17, | |
823 | testArgs18,testArgs19,testArgs20,testArgs21, | |
824 | testArgs22,testArgs23 }; | |
825 | UnicodeString exp[] = { | |
826 | "Kirti und sein Freund gingen nach Paris." , | |
827 | "Kirti und seine 6 Freunde gingen nach Paris." , | |
828 | "Kirti und seine Freundin gingen nach Paris.", | |
829 | "Kirti und seine 3 Freundinnen gingen nach Paris.", | |
830 | "Kirti und ihre Freundin gingen nach Paris.", | |
831 | "Kirti und ihre 5 Freundinnen gingen nach Paris.", | |
832 | "Kirti und ihr Freund gingen nach Paris.", | |
833 | "Kirti und ihre 5 Freunde gingen nach Paris.", | |
834 | "Kirti und sein Freund gingen nach Paris.", | |
835 | "Kirti und sein Freund gingen nach Paris.", | |
836 | "Kirti und ihr Freund gingen nach Paris.", | |
837 | "Kirti und seine 5 Freunde gingen nach Paris." , | |
838 | "Kirti und seine 5 Freunde gingen nach Paris." , | |
839 | "Kirti und ihre 5 Freunde gingen nach Paris." | |
840 | }; | |
841 | //Format | |
842 | for( int i=0; i< 14; i++){ | |
843 | internalFormat( msgFmt6 , testArgs[i], 4, exp[i] ,(char*)"From TestMessageFormat::testSelectFormat format t6"); | |
844 | } | |
845 | } | |
846 | delete msgFmt6; | |
847 | } | |
46f4442e | 848 | |
b75a7d8f A |
849 | //--------------------------------- |
850 | // API Tests | |
851 | //--------------------------------- | |
852 | ||
853 | void TestMessageFormat::testCopyConstructor() | |
854 | { | |
b75a7d8f A |
855 | UErrorCode success = U_ZERO_ERROR; |
856 | MessageFormat *x = new MessageFormat("There are {0} files on {1}", success); | |
857 | MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success); | |
858 | MessageFormat *y = 0; | |
859 | y = new MessageFormat(*x); | |
860 | if ( (*x == *y) && | |
861 | (*x != *z) && | |
862 | (*y != *z) ) | |
863 | logln("First test (operator ==): Passed!"); | |
864 | else { | |
865 | errln("TestMessageFormat::testCopyConstructor failed #1"); | |
866 | logln("First test (operator ==): Failed!"); | |
867 | } | |
868 | if ( ((*x == *y) && (*y == *x)) && | |
869 | ((*x != *z) && (*z != *x)) && | |
870 | ((*y != *z) && (*z != *y)) ) | |
871 | logln("Second test (equals): Passed!"); | |
872 | else { | |
873 | errln("TestMessageFormat::testCopyConstructor failed #2"); | |
874 | logln("Second test (equals): Failed!"); | |
875 | } | |
876 | ||
877 | delete x; | |
878 | delete y; | |
879 | delete z; | |
880 | } | |
881 | ||
882 | ||
883 | void TestMessageFormat::testAssignment() | |
884 | { | |
b75a7d8f A |
885 | UErrorCode success = U_ZERO_ERROR; |
886 | MessageFormat *x = new MessageFormat("There are {0} files on {1}", success); | |
887 | MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success); | |
888 | MessageFormat *y = new MessageFormat("There are {0} files on {1} created", success); | |
889 | *y = *x; | |
890 | if ( (*x == *y) && | |
891 | (*x != *z) && | |
892 | (*y != *z) ) | |
893 | logln("First test (operator ==): Passed!"); | |
894 | else { | |
895 | errln( "TestMessageFormat::testAssignment failed #1"); | |
896 | logln("First test (operator ==): Failed!"); | |
897 | } | |
898 | if ( ((*x == *y) && (*y == *x)) && | |
899 | ((*x != *z) && (*z != *x)) && | |
900 | ((*y != *z) && (*z != *y)) ) | |
901 | logln("Second test (equals): Passed!"); | |
902 | else { | |
903 | errln("TestMessageFormat::testAssignment failed #2"); | |
904 | logln("Second test (equals): Failed!"); | |
905 | } | |
906 | ||
907 | delete x; | |
908 | delete y; | |
909 | delete z; | |
910 | } | |
911 | ||
912 | void TestMessageFormat::testClone() | |
913 | { | |
b75a7d8f A |
914 | UErrorCode success = U_ZERO_ERROR; |
915 | MessageFormat *x = new MessageFormat("There are {0} files on {1}", success); | |
916 | MessageFormat *z = new MessageFormat("There are {0} files on {1} created", success); | |
917 | MessageFormat *y = 0; | |
918 | y = (MessageFormat*)x->clone(); | |
919 | if ( (*x == *y) && | |
920 | (*x != *z) && | |
921 | (*y != *z) ) | |
922 | logln("First test (operator ==): Passed!"); | |
923 | else { | |
924 | errln("TestMessageFormat::testClone failed #1"); | |
925 | logln("First test (operator ==): Failed!"); | |
926 | } | |
927 | if ( ((*x == *y) && (*y == *x)) && | |
928 | ((*x != *z) && (*z != *x)) && | |
929 | ((*y != *z) && (*z != *y)) ) | |
930 | logln("Second test (equals): Passed!"); | |
931 | else { | |
932 | errln("TestMessageFormat::testClone failed #2"); | |
933 | logln("Second test (equals): Failed!"); | |
934 | } | |
935 | ||
936 | delete x; | |
937 | delete y; | |
938 | delete z; | |
939 | } | |
940 | ||
941 | void TestMessageFormat::testEquals() | |
942 | { | |
b75a7d8f A |
943 | UErrorCode success = U_ZERO_ERROR; |
944 | MessageFormat x("There are {0} files on {1}", success); | |
945 | MessageFormat y("There are {0} files on {1}", success); | |
946 | if (!(x == y)) { | |
947 | errln( "TestMessageFormat::testEquals failed #1"); | |
948 | logln("First test (operator ==): Failed!"); | |
949 | } | |
950 | ||
951 | } | |
952 | ||
953 | void TestMessageFormat::testNotEquals() | |
954 | { | |
955 | UErrorCode success = U_ZERO_ERROR; | |
956 | MessageFormat x("There are {0} files on {1}", success); | |
957 | MessageFormat y(x); | |
958 | y.setLocale(Locale("fr")); | |
959 | if (!(x != y)) { | |
960 | errln( "TestMessageFormat::testEquals failed #1"); | |
961 | logln("First test (operator !=): Failed!"); | |
962 | } | |
963 | y = x; | |
964 | y.applyPattern("There are {0} files on {1} the disk", success); | |
965 | if (!(x != y)) { | |
966 | errln( "TestMessageFormat::testEquals failed #1"); | |
374ca955 | 967 | logln("Second test (operator !=): Failed!"); |
b75a7d8f A |
968 | } |
969 | } | |
970 | ||
971 | ||
972 | void TestMessageFormat::testSetLocale() | |
973 | { | |
974 | UErrorCode err = U_ZERO_ERROR; | |
975 | GregorianCalendar cal(err); | |
976 | Formattable arguments[] = { | |
977 | 456.83, | |
978 | Formattable(UDate(8.71068e+011), Formattable::kIsDate), | |
979 | "deposit" | |
980 | }; | |
981 | ||
982 | UnicodeString result; | |
983 | ||
984 | //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}."; | |
985 | UnicodeString formatStr = "At <time> on {1,date}, you made a {2} of {0,number,currency}."; | |
986 | // {sfb} to get $, would need Locale::US, not Locale::ENGLISH | |
987 | // Just use unlocalized currency symbol. | |
988 | //UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of $456.83."; | |
989 | UnicodeString compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of "; | |
990 | compareStrEng += (UChar) 0x00a4; | |
991 | compareStrEng += "456.83."; | |
992 | // {sfb} to get DM, would need Locale::GERMANY, not Locale::GERMAN | |
993 | // Just use unlocalized currency symbol. | |
994 | //UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit of 456,83 DM."; | |
995 | UnicodeString compareStrGer = "At <time> on 08.08.1997, you made a deposit of "; | |
46f4442e A |
996 | compareStrGer += "456,83"; |
997 | compareStrGer += (UChar) 0x00a0; | |
b75a7d8f | 998 | compareStrGer += (UChar) 0x00a4; |
46f4442e | 999 | compareStrGer += "."; |
b75a7d8f A |
1000 | |
1001 | MessageFormat msg( formatStr, err); | |
1002 | result = ""; | |
1003 | FieldPosition pos(0); | |
1004 | result = msg.format( | |
1005 | arguments, | |
1006 | 3, | |
1007 | result, | |
1008 | pos, | |
1009 | err); | |
1010 | ||
1011 | logln(result); | |
1012 | if (result != compareStrEng) { | |
729e4ab9 | 1013 | dataerrln("*** MSG format err. - %s", u_errorName(err)); |
b75a7d8f A |
1014 | } |
1015 | ||
1016 | msg.setLocale(Locale::getEnglish()); | |
1017 | UBool getLocale_ok = TRUE; | |
1018 | if (msg.getLocale() != Locale::getEnglish()) { | |
1019 | errln("*** MSG getLocal err."); | |
1020 | getLocale_ok = FALSE; | |
1021 | } | |
1022 | ||
1023 | msg.setLocale(Locale::getGerman()); | |
1024 | ||
1025 | if (msg.getLocale() != Locale::getGerman()) { | |
1026 | errln("*** MSG getLocal err."); | |
1027 | getLocale_ok = FALSE; | |
1028 | } | |
1029 | ||
1030 | msg.applyPattern( formatStr, err); | |
1031 | ||
1032 | pos.setField(0); | |
1033 | result = ""; | |
1034 | result = msg.format( | |
1035 | arguments, | |
1036 | 3, | |
1037 | result, | |
1038 | pos, | |
1039 | err); | |
1040 | ||
1041 | logln(result); | |
1042 | if (result == compareStrGer) { | |
1043 | logln("MSG setLocale tested."); | |
1044 | }else{ | |
729e4ab9 | 1045 | dataerrln( "*** MSG setLocale err. - %s", u_errorName(err)); |
b75a7d8f A |
1046 | } |
1047 | ||
1048 | if (getLocale_ok) { | |
1049 | logln("MSG getLocale tested."); | |
1050 | } | |
1051 | } | |
1052 | ||
1053 | void TestMessageFormat::testFormat() | |
1054 | { | |
1055 | UErrorCode err = U_ZERO_ERROR; | |
1056 | GregorianCalendar cal(err); | |
1057 | ||
1058 | const Formattable ftarray[] = | |
1059 | { | |
1060 | Formattable( UDate(8.71068e+011), Formattable::kIsDate ) | |
1061 | }; | |
2ca993e8 | 1062 | const int32_t ft_cnt = UPRV_LENGTHOF(ftarray); |
b75a7d8f A |
1063 | Formattable ft_arr( ftarray, ft_cnt ); |
1064 | ||
1065 | Formattable* fmt = new Formattable(UDate(8.71068e+011), Formattable::kIsDate); | |
1066 | ||
1067 | UnicodeString result; | |
1068 | ||
1069 | //UnicodeString formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}."; | |
1070 | UnicodeString formatStr = "On {0,date}, it began."; | |
1071 | UnicodeString compareStr = "On Aug 8, 1997, it began."; | |
1072 | ||
1073 | err = U_ZERO_ERROR; | |
1074 | MessageFormat msg( formatStr, err); | |
1075 | FieldPosition fp(0); | |
1076 | ||
1077 | result = ""; | |
1078 | fp = 0; | |
1079 | result = msg.format( | |
1080 | *fmt, | |
1081 | result, | |
1082 | //FieldPosition(0), | |
1083 | fp, | |
1084 | err); | |
1085 | ||
1086 | if (err != U_ILLEGAL_ARGUMENT_ERROR) { | |
729e4ab9 | 1087 | dataerrln("*** MSG format without expected error code. - %s", u_errorName(err)); |
b75a7d8f A |
1088 | } |
1089 | err = U_ZERO_ERROR; | |
1090 | ||
1091 | result = ""; | |
1092 | fp = 0; | |
1093 | result = msg.format( | |
1094 | ft_arr, | |
1095 | result, | |
1096 | //FieldPosition(0), | |
1097 | fp, | |
1098 | err); | |
1099 | ||
1100 | logln("MSG format( Formattable&, ... ) expected:" + compareStr); | |
1101 | logln("MSG format( Formattable&, ... ) result:" + result); | |
1102 | if (result != compareStr) { | |
729e4ab9 | 1103 | dataerrln("*** MSG format( Formattable&, .... ) err. - %s", u_errorName(err)); |
b75a7d8f A |
1104 | }else{ |
1105 | logln("MSG format( Formattable&, ... ) tested."); | |
1106 | } | |
1107 | ||
1108 | delete fmt; | |
1109 | ||
1110 | } | |
1111 | ||
1112 | void TestMessageFormat::testParse() | |
1113 | { | |
1114 | UErrorCode err = U_ZERO_ERROR; | |
1115 | int32_t count; | |
1116 | UnicodeString msgFormatString = "{0} =sep= {1}"; | |
1117 | MessageFormat msg( msgFormatString, err); | |
1118 | UnicodeString source = "abc =sep= def"; | |
1119 | UnicodeString tmp1, tmp2; | |
1120 | ||
1121 | Formattable* fmt_arr = msg.parse( source, count, err ); | |
1122 | if (U_FAILURE(err) || (!fmt_arr)) { | |
1123 | errln("*** MSG parse (ustring, count, err) error."); | |
1124 | }else{ | |
1125 | logln("MSG parse -- count: %d", count); | |
1126 | if (count != 2) { | |
1127 | errln("*** MSG parse (ustring, count, err) count err."); | |
1128 | }else{ | |
1129 | if ((fmt_arr[0].getType() == Formattable::kString) | |
1130 | && (fmt_arr[1].getType() == Formattable::kString) | |
1131 | && (fmt_arr[0].getString(tmp1) == "abc") | |
1132 | && (fmt_arr[1].getString(tmp2) == "def")) { | |
1133 | logln("MSG parse (ustring, count, err) tested."); | |
1134 | }else{ | |
1135 | errln("*** MSG parse (ustring, count, err) result err."); | |
1136 | } | |
1137 | } | |
1138 | } | |
1139 | delete[] fmt_arr; | |
1140 | ||
1141 | ParsePosition pp(0); | |
1142 | ||
1143 | fmt_arr = msg.parse( source, pp, count ); | |
1144 | if ((pp == 0) || (!fmt_arr)) { | |
1145 | errln("*** MSG parse (ustring, parsepos., count) error."); | |
1146 | }else{ | |
1147 | logln("MSG parse -- count: %d", count); | |
1148 | if (count != 2) { | |
1149 | errln("*** MSG parse (ustring, parsepos., count) count err."); | |
1150 | }else{ | |
1151 | if ((fmt_arr[0].getType() == Formattable::kString) | |
1152 | && (fmt_arr[1].getType() == Formattable::kString) | |
1153 | && (fmt_arr[0].getString(tmp1) == "abc") | |
1154 | && (fmt_arr[1].getString(tmp2) == "def")) { | |
1155 | logln("MSG parse (ustring, parsepos., count) tested."); | |
1156 | }else{ | |
1157 | errln("*** MSG parse (ustring, parsepos., count) result err."); | |
1158 | } | |
1159 | } | |
1160 | } | |
1161 | delete[] fmt_arr; | |
1162 | ||
1163 | pp = 0; | |
1164 | Formattable fmta; | |
1165 | ||
1166 | msg.parseObject( source, fmta, pp ); | |
1167 | if (pp == 0) { | |
1168 | errln("*** MSG parse (ustring, Formattable, parsepos ) error."); | |
1169 | }else{ | |
1170 | logln("MSG parse -- count: %d", count); | |
1171 | fmta.getArray(count); | |
1172 | if (count != 2) { | |
1173 | errln("*** MSG parse (ustring, Formattable, parsepos ) count err."); | |
1174 | }else{ | |
1175 | if ((fmta[0].getType() == Formattable::kString) | |
1176 | && (fmta[1].getType() == Formattable::kString) | |
1177 | && (fmta[0].getString(tmp1) == "abc") | |
1178 | && (fmta[1].getString(tmp2) == "def")) { | |
1179 | logln("MSG parse (ustring, Formattable, parsepos ) tested."); | |
1180 | }else{ | |
1181 | errln("*** MSG parse (ustring, Formattable, parsepos ) result err."); | |
1182 | } | |
1183 | } | |
1184 | } | |
1185 | } | |
1186 | ||
1187 | ||
1188 | void TestMessageFormat::testAdopt() | |
1189 | { | |
1190 | UErrorCode err = U_ZERO_ERROR; | |
1191 | ||
1192 | UnicodeString formatStr("{0,date},{1},{2,number}", ""); | |
1193 | UnicodeString formatStrChange("{0,number},{1,number},{2,date}", ""); | |
1194 | err = U_ZERO_ERROR; | |
1195 | MessageFormat msg( formatStr, err); | |
1196 | MessageFormat msgCmp( formatStr, err); | |
4388f060 A |
1197 | if (U_FAILURE(err)) { |
1198 | dataerrln("Unable to instantiate MessageFormat - %s", u_errorName(err)); | |
1199 | return; | |
1200 | } | |
b75a7d8f A |
1201 | int32_t count, countCmp; |
1202 | const Format** formats = msg.getFormats(count); | |
1203 | const Format** formatsCmp = msgCmp.getFormats(countCmp); | |
1204 | const Format** formatsChg = 0; | |
1205 | const Format** formatsAct = 0; | |
1206 | int32_t countAct; | |
1207 | const Format* a; | |
1208 | const Format* b; | |
1209 | UnicodeString patCmp; | |
1210 | UnicodeString patAct; | |
1211 | Format** formatsToAdopt; | |
1212 | ||
1213 | if (!formats || !formatsCmp || (count <= 0) || (count != countCmp)) { | |
729e4ab9 | 1214 | dataerrln("Error getting Formats"); |
b75a7d8f A |
1215 | return; |
1216 | } | |
1217 | ||
1218 | int32_t i; | |
1219 | ||
1220 | for (i = 0; i < count; i++) { | |
1221 | a = formats[i]; | |
1222 | b = formatsCmp[i]; | |
1223 | if ((a != NULL) && (b != NULL)) { | |
1224 | if (*a != *b) { | |
1225 | errln("a != b"); | |
1226 | return; | |
1227 | } | |
1228 | }else if ((a != NULL) || (b != NULL)) { | |
1229 | errln("(a != NULL) || (b != NULL)"); | |
1230 | return; | |
1231 | } | |
1232 | } | |
1233 | ||
1234 | msg.applyPattern( formatStrChange, err ); //set msg formats to something different | |
1235 | int32_t countChg; | |
1236 | formatsChg = msg.getFormats(countChg); // tested function | |
1237 | if (!formatsChg || (countChg != count)) { | |
1238 | errln("Error getting Formats"); | |
1239 | return; | |
1240 | } | |
1241 | ||
1242 | UBool diff; | |
1243 | diff = TRUE; | |
1244 | for (i = 0; i < count; i++) { | |
1245 | a = formatsChg[i]; | |
1246 | b = formatsCmp[i]; | |
1247 | if ((a != NULL) && (b != NULL)) { | |
1248 | if (*a == *b) { | |
374ca955 | 1249 | logln("formatsChg == formatsCmp at index %d", i); |
b75a7d8f A |
1250 | diff = FALSE; |
1251 | } | |
1252 | } | |
1253 | } | |
1254 | if (!diff) { | |
1255 | errln("*** MSG getFormats diff err."); | |
1256 | return; | |
1257 | } | |
1258 | ||
1259 | logln("MSG getFormats tested."); | |
1260 | ||
1261 | msg.setFormats( formatsCmp, countCmp ); //tested function | |
1262 | ||
1263 | formatsAct = msg.getFormats(countAct); | |
1264 | if (!formatsAct || (countAct <=0) || (countAct != countCmp)) { | |
1265 | errln("Error getting Formats"); | |
1266 | return; | |
1267 | } | |
1268 | ||
374ca955 | 1269 | assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove())); |
4388f060 A |
1270 | // ICU 4.8 does not support toPattern() when there are custom formats (from setFormat() etc.). |
1271 | // assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove())); | |
1272 | msg.toPattern(patCmp.remove()); | |
1273 | if (!patCmp.isBogus()) { | |
1274 | errln("msg.setFormat().toPattern() succeeds."); | |
1275 | } | |
b75a7d8f A |
1276 | |
1277 | for (i = 0; i < countAct; i++) { | |
1278 | a = formatsAct[i]; | |
1279 | b = formatsCmp[i]; | |
1280 | if ((a != NULL) && (b != NULL)) { | |
1281 | if (*a != *b) { | |
1282 | logln("formatsAct != formatsCmp at index %d", i); | |
1283 | errln("a != b"); | |
1284 | return; | |
1285 | } | |
1286 | }else if ((a != NULL) || (b != NULL)) { | |
1287 | errln("(a != NULL) || (b != NULL)"); | |
1288 | return; | |
1289 | } | |
1290 | } | |
1291 | logln("MSG setFormats tested."); | |
1292 | ||
b75a7d8f A |
1293 | //---- |
1294 | ||
1295 | msg.applyPattern( formatStrChange, err ); //set msg formats to something different | |
1296 | ||
1297 | formatsToAdopt = new Format* [countCmp]; | |
1298 | if (!formatsToAdopt) { | |
1299 | errln("memory allocation error"); | |
1300 | return; | |
1301 | } | |
1302 | ||
1303 | for (i = 0; i < countCmp; i++) { | |
1304 | if (formatsCmp[i] == NULL) { | |
1305 | formatsToAdopt[i] = NULL; | |
1306 | }else{ | |
1307 | formatsToAdopt[i] = formatsCmp[i]->clone(); | |
1308 | if (!formatsToAdopt[i]) { | |
1309 | errln("Can't clone format at index %d", i); | |
1310 | return; | |
1311 | } | |
1312 | } | |
1313 | } | |
1314 | msg.adoptFormats( formatsToAdopt, countCmp ); // function to test | |
1315 | delete[] formatsToAdopt; | |
1316 | ||
374ca955 | 1317 | assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove())); |
4388f060 A |
1318 | // ICU 4.8 does not support toPattern() when there are custom formats (from setFormat() etc.). |
1319 | // assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove())); | |
b75a7d8f A |
1320 | |
1321 | formatsAct = msg.getFormats(countAct); | |
1322 | if (!formatsAct || (countAct <=0) || (countAct != countCmp)) { | |
1323 | errln("Error getting Formats"); | |
1324 | return; | |
1325 | } | |
1326 | ||
1327 | for (i = 0; i < countAct; i++) { | |
1328 | a = formatsAct[i]; | |
1329 | b = formatsCmp[i]; | |
1330 | if ((a != NULL) && (b != NULL)) { | |
1331 | if (*a != *b) { | |
1332 | errln("a != b"); | |
1333 | return; | |
1334 | } | |
1335 | }else if ((a != NULL) || (b != NULL)) { | |
1336 | errln("(a != NULL) || (b != NULL)"); | |
1337 | return; | |
1338 | } | |
1339 | } | |
1340 | logln("MSG adoptFormats tested."); | |
1341 | ||
1342 | //---- adoptFormat | |
1343 | ||
1344 | msg.applyPattern( formatStrChange, err ); //set msg formats to something different | |
1345 | ||
1346 | formatsToAdopt = new Format* [countCmp]; | |
1347 | if (!formatsToAdopt) { | |
1348 | errln("memory allocation error"); | |
1349 | return; | |
1350 | } | |
1351 | ||
1352 | for (i = 0; i < countCmp; i++) { | |
1353 | if (formatsCmp[i] == NULL) { | |
1354 | formatsToAdopt[i] = NULL; | |
1355 | }else{ | |
1356 | formatsToAdopt[i] = formatsCmp[i]->clone(); | |
1357 | if (!formatsToAdopt[i]) { | |
1358 | errln("Can't clone format at index %d", i); | |
1359 | return; | |
1360 | } | |
1361 | } | |
1362 | } | |
1363 | ||
1364 | for ( i = 0; i < countCmp; i++ ) { | |
1365 | msg.adoptFormat( i, formatsToAdopt[i] ); // function to test | |
1366 | } | |
1367 | delete[] formatsToAdopt; // array itself not needed in this case; | |
1368 | ||
374ca955 | 1369 | assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove())); |
4388f060 A |
1370 | // ICU 4.8 does not support toPattern() when there are custom formats (from setFormat() etc.). |
1371 | // assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove())); | |
b75a7d8f A |
1372 | |
1373 | formatsAct = msg.getFormats(countAct); | |
1374 | if (!formatsAct || (countAct <=0) || (countAct != countCmp)) { | |
1375 | errln("Error getting Formats"); | |
1376 | return; | |
1377 | } | |
1378 | ||
1379 | for (i = 0; i < countAct; i++) { | |
1380 | a = formatsAct[i]; | |
1381 | b = formatsCmp[i]; | |
1382 | if ((a != NULL) && (b != NULL)) { | |
1383 | if (*a != *b) { | |
1384 | errln("a != b"); | |
1385 | return; | |
1386 | } | |
1387 | }else if ((a != NULL) || (b != NULL)) { | |
1388 | errln("(a != NULL) || (b != NULL)"); | |
1389 | return; | |
1390 | } | |
1391 | } | |
1392 | logln("MSG adoptFormat tested."); | |
1393 | } | |
1394 | ||
1395 | // This test is a regression test for a fixed bug in the copy constructor. | |
1396 | // It is kept as a global function rather than as a method since the test depends on memory values. | |
1397 | // (At least before the bug was fixed, whether it showed up or not depended on memory contents, | |
1398 | // which is probably why it didn't show up in the regular test for the copy constructor.) | |
1399 | // For this reason, the test isn't changed even though it contains function calls whose results are | |
1400 | // not tested and had no problems. Actually, the test failed by *crashing*. | |
1401 | static void _testCopyConstructor2() | |
1402 | { | |
1403 | UErrorCode status = U_ZERO_ERROR; | |
1404 | UnicodeString formatStr("Hello World on {0,date,full}", ""); | |
1405 | UnicodeString resultStr(" ", ""); | |
1406 | UnicodeString result; | |
1407 | FieldPosition fp(0); | |
1408 | UDate d = Calendar::getNow(); | |
1409 | const Formattable fargs( d, Formattable::kIsDate ); | |
1410 | ||
1411 | MessageFormat* fmt1 = new MessageFormat( formatStr, status ); | |
4388f060 A |
1412 | MessageFormat* fmt2 = NULL; |
1413 | MessageFormat* fmt3 = NULL; | |
1414 | MessageFormat* fmt4 = NULL; | |
b75a7d8f | 1415 | |
4388f060 A |
1416 | if (fmt1 == NULL) { |
1417 | it_err("testCopyConstructor2: (fmt1 != NULL)"); | |
1418 | goto cleanup; | |
1419 | } | |
b75a7d8f | 1420 | |
4388f060 | 1421 | fmt2 = new MessageFormat( *fmt1 ); |
b75a7d8f A |
1422 | result = fmt1->format( &fargs, 1, resultStr, fp, status ); |
1423 | ||
4388f060 A |
1424 | if (fmt2 == NULL) { |
1425 | it_err("testCopyConstructor2: (fmt2 != NULL)"); | |
1426 | goto cleanup; | |
1427 | } | |
b75a7d8f A |
1428 | |
1429 | fmt3 = (MessageFormat*) fmt1->clone(); | |
1430 | fmt4 = (MessageFormat*) fmt2->clone(); | |
1431 | ||
4388f060 A |
1432 | if (fmt3 == NULL) { |
1433 | it_err("testCopyConstructor2: (fmt3 != NULL)"); | |
1434 | goto cleanup; | |
1435 | } | |
1436 | if (fmt4 == NULL) { | |
1437 | it_err("testCopyConstructor2: (fmt4 != NULL)"); | |
1438 | goto cleanup; | |
1439 | } | |
b75a7d8f A |
1440 | |
1441 | result = fmt1->format( &fargs, 1, resultStr, fp, status ); | |
1442 | result = fmt2->format( &fargs, 1, resultStr, fp, status ); | |
1443 | result = fmt3->format( &fargs, 1, resultStr, fp, status ); | |
1444 | result = fmt4->format( &fargs, 1, resultStr, fp, status ); | |
4388f060 A |
1445 | |
1446 | cleanup: | |
b75a7d8f A |
1447 | delete fmt1; |
1448 | delete fmt2; | |
1449 | delete fmt3; | |
1450 | delete fmt4; | |
1451 | } | |
1452 | ||
1453 | void TestMessageFormat::testCopyConstructor2() { | |
1454 | _testCopyConstructor2(); | |
1455 | } | |
1456 | ||
1457 | /** | |
1458 | * Verify that MessageFormat accomodates more than 10 arguments and | |
1459 | * more than 10 subformats. | |
1460 | */ | |
1461 | void TestMessageFormat::TestUnlimitedArgsAndSubformats() { | |
1462 | UErrorCode ec = U_ZERO_ERROR; | |
1463 | const UnicodeString pattern = | |
1464 | "On {0,date} (aka {0,date,short}, aka {0,date,long}) " | |
1465 | "at {0,time} (aka {0,time,short}, aka {0,time,long}) " | |
1466 | "there were {1,number} werjes " | |
1467 | "(a {3,number,percent} increase over {2,number}) " | |
1468 | "despite the {4}''s efforts " | |
1469 | "and to delight of {5}, {6}, {7}, {8}, {9}, and {10} {11}."; | |
1470 | MessageFormat msg(pattern, ec); | |
1471 | if (U_FAILURE(ec)) { | |
729e4ab9 | 1472 | dataerrln("FAIL: constructor failed - %s", u_errorName(ec)); |
b75a7d8f A |
1473 | return; |
1474 | } | |
1475 | ||
1476 | const Formattable ARGS[] = { | |
1477 | Formattable(UDate(1e13), Formattable::kIsDate), | |
1478 | Formattable((int32_t)1303), | |
1479 | Formattable((int32_t)1202), | |
1480 | Formattable(1303.0/1202 - 1), | |
1481 | Formattable("Glimmung"), | |
1482 | Formattable("the printers"), | |
1483 | Formattable("Nick"), | |
1484 | Formattable("his father"), | |
1485 | Formattable("his mother"), | |
1486 | Formattable("the spiddles"), | |
1487 | Formattable("of course"), | |
1488 | Formattable("Horace"), | |
1489 | }; | |
2ca993e8 | 1490 | const int32_t ARGS_LENGTH = UPRV_LENGTHOF(ARGS); |
b75a7d8f A |
1491 | Formattable ARGS_OBJ(ARGS, ARGS_LENGTH); |
1492 | ||
1493 | UnicodeString expected = | |
1494 | "On Nov 20, 2286 (aka 11/20/86, aka November 20, 2286) " | |
1495 | "at 9:46:40 AM (aka 9:46 AM, aka 9:46:40 AM PST) " | |
1496 | "there were 1,303 werjes " | |
1497 | "(a 8% increase over 1,202) " | |
1498 | "despite the Glimmung's efforts " | |
1499 | "and to delight of the printers, Nick, his father, " | |
1500 | "his mother, the spiddles, and of course Horace."; | |
1501 | UnicodeString result; | |
1502 | msg.format(ARGS_OBJ, result, ec); | |
1503 | if (result == expected) { | |
1504 | logln(result); | |
1505 | } else { | |
1506 | errln((UnicodeString)"FAIL: Got " + result + | |
1507 | ", expected " + expected); | |
1508 | } | |
1509 | } | |
1510 | ||
374ca955 A |
1511 | // test RBNF extensions to message format |
1512 | void TestMessageFormat::TestRBNF(void) { | |
1513 | // WARNING: this depends on the RBNF formats for en_US | |
1514 | Locale locale("en", "US", ""); | |
1515 | ||
1516 | UErrorCode ec = U_ZERO_ERROR; | |
1517 | ||
1518 | UnicodeString values[] = { | |
1519 | // decimal values do not format completely for ordinal or duration, and | |
1520 | // do not always parse, so do not include them | |
1521 | "0", "1", "12", "100", "123", "1001", "123,456", "-17", | |
1522 | }; | |
2ca993e8 | 1523 | int32_t values_count = UPRV_LENGTHOF(values); |
374ca955 A |
1524 | |
1525 | UnicodeString formats[] = { | |
1526 | "There are {0,spellout} files to search.", | |
1527 | "There are {0,spellout,%simplified} files to search.", | |
1528 | "The bogus spellout {0,spellout,%BOGUS} files behaves like the default.", | |
2ca993e8 | 1529 | "This is the {0,ordinal} file to search.", |
374ca955 A |
1530 | "Searching this file will take {0,duration} to complete.", |
1531 | "Searching this file will take {0,duration,%with-words} to complete.", | |
1532 | }; | |
2ca993e8 | 1533 | int32_t formats_count = UPRV_LENGTHOF(formats); |
374ca955 A |
1534 | |
1535 | Formattable args[1]; | |
1536 | ||
1537 | NumberFormat* numFmt = NumberFormat::createInstance(locale, ec); | |
73c04bcf A |
1538 | if (U_FAILURE(ec)) { |
1539 | dataerrln("Error calling NumberFormat::createInstance()"); | |
1540 | return; | |
1541 | } | |
1542 | ||
374ca955 A |
1543 | for (int i = 0; i < formats_count; ++i) { |
1544 | MessageFormat* fmt = new MessageFormat(formats[i], locale, ec); | |
1545 | logln((UnicodeString)"Testing format pattern: '" + formats[i] + "'"); | |
73c04bcf | 1546 | |
374ca955 A |
1547 | for (int j = 0; j < values_count; ++j) { |
1548 | ec = U_ZERO_ERROR; | |
1549 | numFmt->parse(values[j], args[0], ec); | |
1550 | if (U_FAILURE(ec)) { | |
1551 | errln((UnicodeString)"Failed to parse test argument " + values[j]); | |
1552 | } else { | |
1553 | FieldPosition fp(0); | |
1554 | UnicodeString result; | |
1555 | fmt->format(args, 1, result, fp, ec); | |
1556 | logln((UnicodeString)"value: " + toString(args[0]) + " --> " + result + UnicodeString(" ec: ") + u_errorName(ec)); | |
1557 | ||
2ca993e8 A |
1558 | int32_t count = 0; |
1559 | Formattable* parseResult = fmt->parse(result, count, ec); | |
1560 | if (count != 1) { | |
1561 | errln((UnicodeString)"parse returned " + count + " args"); | |
1562 | } else if (parseResult[0] != args[0]) { | |
1563 | errln((UnicodeString)"parsed argument " + toString(parseResult[0]) + " != " + toString(args[0])); | |
374ca955 | 1564 | } |
2ca993e8 | 1565 | delete []parseResult; |
374ca955 A |
1566 | } |
1567 | } | |
1568 | delete fmt; | |
1569 | } | |
1570 | delete numFmt; | |
1571 | } | |
1572 | ||
4388f060 A |
1573 | UnicodeString TestMessageFormat::GetPatternAndSkipSyntax(const MessagePattern& pattern) { |
1574 | UnicodeString us(pattern.getPatternString()); | |
1575 | int count = pattern.countParts(); | |
1576 | for (int i = count; i > 0;) { | |
1577 | const MessagePattern::Part& part = pattern.getPart(--i); | |
1578 | if (part.getType() == UMSGPAT_PART_TYPE_SKIP_SYNTAX) { | |
1579 | us.remove(part.getIndex(), part.getLimit() - part.getIndex()); | |
1580 | } | |
1581 | } | |
1582 | return us; | |
1583 | } | |
1584 | ||
1585 | void TestMessageFormat::TestApostropheMode() { | |
1586 | UErrorCode status = U_ZERO_ERROR; | |
1587 | MessagePattern *ado_mp = new MessagePattern(UMSGPAT_APOS_DOUBLE_OPTIONAL, status); | |
1588 | MessagePattern *adr_mp = new MessagePattern(UMSGPAT_APOS_DOUBLE_REQUIRED, status); | |
1589 | if (ado_mp->getApostropheMode() != UMSGPAT_APOS_DOUBLE_OPTIONAL) { | |
1590 | errln("wrong value from ado_mp->getApostropheMode()."); | |
1591 | } | |
1592 | if (adr_mp->getApostropheMode() != UMSGPAT_APOS_DOUBLE_REQUIRED) { | |
1593 | errln("wrong value from adr_mp->getApostropheMode()."); | |
1594 | } | |
1595 | ||
1596 | ||
1597 | UnicodeString tuples[] = { | |
1598 | // Desired output | |
1599 | // DOUBLE_OPTIONAL pattern | |
1600 | // DOUBLE_REQUIRED pattern (empty=same as DOUBLE_OPTIONAL) | |
1601 | "I see {many}", "I see '{many}'", "", | |
1602 | "I said {'Wow!'}", "I said '{''Wow!''}'", "", | |
1603 | "I dont know", "I dont know", "I don't know", | |
1604 | "I don't know", "I don't know", "I don''t know", | |
1605 | "I don't know", "I don''t know", "I don''t know" | |
1606 | }; | |
b331163b | 1607 | int32_t tuples_count = UPRV_LENGTHOF(tuples); |
4388f060 A |
1608 | |
1609 | for (int i = 0; i < tuples_count; i += 3) { | |
1610 | UnicodeString& desired = tuples[i]; | |
1611 | UnicodeString& ado_pattern = tuples[i + 1]; | |
1612 | UErrorCode status = U_ZERO_ERROR; | |
1613 | assertEquals("DOUBLE_OPTIONAL failure", | |
1614 | desired, | |
1615 | GetPatternAndSkipSyntax(ado_mp->parse(ado_pattern, NULL, status))); | |
1616 | UnicodeString& adr_pattern = tuples[i + 2].isEmpty() ? ado_pattern : tuples[i + 2]; | |
1617 | assertEquals("DOUBLE_REQUIRED failure", desired, | |
1618 | GetPatternAndSkipSyntax(adr_mp->parse(adr_pattern, NULL, status))); | |
1619 | } | |
1620 | delete adr_mp; | |
1621 | delete ado_mp; | |
1622 | } | |
1623 | ||
1624 | ||
1625 | // Compare behavior of DOUBLE_OPTIONAL (new default) and DOUBLE_REQUIRED JDK-compatibility mode. | |
1626 | void TestMessageFormat::TestCompatibleApostrophe() { | |
1627 | // Message with choice argument which does not contain another argument. | |
1628 | // The JDK performs only one apostrophe-quoting pass on this pattern. | |
1629 | UnicodeString pattern = "ab{0,choice,0#1'2''3'''4''''.}yz"; | |
1630 | ||
1631 | UErrorCode ec = U_ZERO_ERROR; | |
1632 | MessageFormat compMsg("", Locale::getUS(), ec); | |
1633 | compMsg.applyPattern(pattern, UMSGPAT_APOS_DOUBLE_REQUIRED, NULL, ec); | |
1634 | if (compMsg.getApostropheMode() != UMSGPAT_APOS_DOUBLE_REQUIRED) { | |
1635 | errln("wrong value from compMsg.getApostropheMode()."); | |
1636 | } | |
1637 | ||
1638 | MessageFormat icuMsg("", Locale::getUS(), ec); | |
1639 | icuMsg.applyPattern(pattern, UMSGPAT_APOS_DOUBLE_OPTIONAL, NULL, ec); | |
1640 | if (icuMsg.getApostropheMode() != UMSGPAT_APOS_DOUBLE_OPTIONAL) { | |
1641 | errln("wrong value from icuMsg.getApostropheMode()."); | |
1642 | } | |
1643 | ||
1644 | Formattable zero0[] = { (int32_t)0 }; | |
1645 | FieldPosition fieldpos(0); | |
1646 | UnicodeString buffer1, buffer2; | |
1647 | assertEquals("incompatible ICU MessageFormat compatibility-apostrophe behavior", | |
1648 | "ab12'3'4''.yz", | |
1649 | compMsg.format(zero0, 1, buffer1, fieldpos, ec)); | |
1650 | assertEquals("unexpected ICU MessageFormat double-apostrophe-optional behavior", | |
1651 | "ab1'2'3''4''.yz", | |
1652 | icuMsg.format(zero0, 1, buffer2, fieldpos, ec)); | |
1653 | ||
1654 | // Message with choice argument which contains a nested simple argument. | |
1655 | // The DOUBLE_REQUIRED version performs two apostrophe-quoting passes. | |
1656 | buffer1.remove(); | |
1657 | buffer2.remove(); | |
1658 | pattern = "ab{0,choice,0#1'2''3'''4''''.{0,number,'#x'}}yz"; | |
1659 | compMsg.applyPattern(pattern, ec); | |
1660 | icuMsg.applyPattern(pattern, ec); | |
1661 | if (U_FAILURE(ec)) { | |
1662 | dataerrln("Unable to applyPattern - %s", u_errorName(ec)); | |
1663 | } else { | |
1664 | assertEquals("incompatible ICU MessageFormat compatibility-apostrophe behavior", | |
1665 | "ab1234'.0xyz", | |
1666 | compMsg.format(zero0, 1, buffer1, fieldpos, ec)); | |
1667 | assertEquals("unexpected ICU MessageFormat double-apostrophe-optional behavior", | |
1668 | "ab1'2'3''4''.#x0yz", | |
1669 | icuMsg.format(zero0, 1, buffer2, fieldpos, ec)); | |
1670 | } | |
1671 | ||
1672 | // This part is copied over from Java tests but cannot be properly tested here | |
1673 | // because we do not have a live reference implementation with JDK behavior. | |
1674 | // The JDK ChoiceFormat itself always performs one apostrophe-quoting pass. | |
1675 | /* | |
1676 | ChoiceFormat choice = new ChoiceFormat("0#1'2''3'''4''''."); | |
1677 | assertEquals("unexpected JDK ChoiceFormat apostrophe behavior", | |
1678 | "12'3'4''.", | |
1679 | choice.format(0)); | |
1680 | choice.applyPattern("0#1'2''3'''4''''.{0,number,'#x'}"); | |
1681 | assertEquals("unexpected JDK ChoiceFormat apostrophe behavior", | |
1682 | "12'3'4''.{0,number,#x}", | |
1683 | choice.format(0)); | |
1684 | */ | |
1685 | } | |
1686 | ||
73c04bcf A |
1687 | void TestMessageFormat::testAutoQuoteApostrophe(void) { |
1688 | const char* patterns[] = { // pattern, expected pattern | |
1689 | "'", "''", | |
1690 | "''", "''", | |
1691 | "'{", "'{'", | |
1692 | "' {", "'' {", | |
1693 | "'a", "''a", | |
1694 | "'{'a", "'{'a", | |
1695 | "'{a'", "'{a'", | |
1696 | "'{}", "'{}'", | |
1697 | "{'", "{'", | |
1698 | "{'a", "{'a", | |
1699 | "{'a{}'a}'a", "{'a{}'a}''a", | |
1700 | "'}'", "'}'", | |
1701 | "'} '{'}'", "'} '{'}''", | |
1702 | "'} {{{''", "'} {{{'''", | |
1703 | }; | |
2ca993e8 | 1704 | int32_t pattern_count = UPRV_LENGTHOF(patterns); |
73c04bcf A |
1705 | |
1706 | for (int i = 0; i < pattern_count; i += 2) { | |
1707 | UErrorCode status = U_ZERO_ERROR; | |
1708 | UnicodeString result = MessageFormat::autoQuoteApostrophe(patterns[i], status); | |
1709 | UnicodeString target(patterns[i+1]); | |
1710 | if (target != result) { | |
1711 | const int BUF2_LEN = 64; | |
1712 | char buf[256]; | |
1713 | char buf2[BUF2_LEN]; | |
1714 | int32_t len = result.extract(0, result.length(), buf2, BUF2_LEN); | |
1715 | if (len >= BUF2_LEN) { | |
1716 | buf2[BUF2_LEN-1] = 0; | |
1717 | } | |
1718 | sprintf(buf, "[%2d] test \"%s\": target (\"%s\") != result (\"%s\")\n", i/2, patterns[i], patterns[i+1], buf2); | |
1719 | errln(buf); | |
1720 | } | |
1721 | } | |
1722 | } | |
1723 | ||
729e4ab9 A |
1724 | void TestMessageFormat::testCoverage(void) { |
1725 | UErrorCode status = U_ZERO_ERROR; | |
1726 | UnicodeString testformat("{argument, plural, one{C''est # fichier} other {Ce sont # fichiers}} dans la liste."); | |
1727 | MessageFormat *msgfmt = new MessageFormat(testformat, Locale("fr"), status); | |
1728 | if (msgfmt == NULL || U_FAILURE(status)) { | |
1729 | dataerrln("FAIL: Unable to create MessageFormat.: %s", u_errorName(status)); | |
1730 | return; | |
1731 | } | |
1732 | if (!msgfmt->usesNamedArguments()) { | |
1733 | errln("FAIL: Unable to detect usage of named arguments."); | |
1734 | } | |
1735 | const double limit[] = {0.0, 1.0, 2.0}; | |
1736 | const UnicodeString formats[] = {"0.0<=Arg<1.0", | |
1737 | "1.0<=Arg<2.0", | |
1738 | "2.0<-Arg"}; | |
1739 | ChoiceFormat cf(limit, formats, 3); | |
1740 | ||
1741 | msgfmt->setFormat("set", cf, status); | |
1742 | ||
1743 | StringEnumeration *en = msgfmt->getFormatNames(status); | |
1744 | if (en == NULL || U_FAILURE(status)) { | |
1745 | errln("FAIL: Unable to get format names enumeration."); | |
1746 | } else { | |
1747 | int32_t count = 0; | |
1748 | en->reset(status); | |
1749 | count = en->count(status); | |
1750 | if (U_FAILURE(status)) { | |
1751 | errln("FAIL: Unable to get format name enumeration count."); | |
1752 | } else { | |
1753 | for (int32_t i = 0; i < count; i++) { | |
1754 | en->snext(status); | |
1755 | if (U_FAILURE(status)) { | |
1756 | errln("FAIL: Error enumerating through names."); | |
1757 | break; | |
1758 | } | |
1759 | } | |
1760 | } | |
1761 | } | |
1762 | ||
4388f060 A |
1763 | // adoptFormat() takes ownership of the input Format object. |
1764 | // We need to clone the stack-allocated cf so that we do not attempt to delete cf. | |
1765 | Format *cfClone = cf.clone(); | |
1766 | msgfmt->adoptFormat("adopt", cfClone, status); | |
729e4ab9 A |
1767 | |
1768 | delete en; | |
1769 | delete msgfmt; | |
1770 | ||
1771 | msgfmt = new MessageFormat("'", status); | |
1772 | if (msgfmt == NULL || U_FAILURE(status)) { | |
1773 | errln("FAIL: Unable to create MessageFormat."); | |
1774 | return; | |
1775 | } | |
1776 | if (msgfmt->usesNamedArguments()) { | |
1777 | errln("FAIL: Unable to detect usage of named arguments."); | |
1778 | } | |
1779 | ||
4388f060 A |
1780 | // Starting with ICU 4.8, we support setFormat(name, ...) and getFormatNames() |
1781 | // on a MessageFormat without named arguments. | |
729e4ab9 | 1782 | msgfmt->setFormat("formatName", cf, status); |
4388f060 A |
1783 | if (U_FAILURE(status)) { |
1784 | errln("FAIL: Should work to setFormat(name, ...) regardless of pattern."); | |
729e4ab9 A |
1785 | } |
1786 | status = U_ZERO_ERROR; | |
1787 | en = msgfmt->getFormatNames(status); | |
4388f060 A |
1788 | if (U_FAILURE(status)) { |
1789 | errln("FAIL: Should work to get format names enumeration regardless of pattern."); | |
729e4ab9 A |
1790 | } |
1791 | ||
1792 | delete en; | |
1793 | delete msgfmt; | |
1794 | } | |
1795 | ||
51004dcb A |
1796 | void TestMessageFormat::testGetFormatNames() { |
1797 | IcuTestErrorCode errorCode(*this, "testGetFormatNames"); | |
1798 | MessageFormat msgfmt("Hello, {alice,number} {oops,date,full} {zip,spellout} World.", Locale::getRoot(), errorCode); | |
1799 | if(errorCode.logDataIfFailureAndReset("MessageFormat() failed")) { | |
1800 | return; | |
1801 | } | |
1802 | LocalPointer<StringEnumeration> names(msgfmt.getFormatNames(errorCode)); | |
1803 | if(errorCode.logIfFailureAndReset("msgfmt.getFormatNames() failed")) { | |
1804 | return; | |
1805 | } | |
1806 | const UnicodeString *name; | |
1807 | name = names->snext(errorCode); | |
1808 | if (name == NULL || errorCode.isFailure()) { | |
1809 | errln("msgfmt.getFormatNames()[0] failed: %s", errorCode.errorName()); | |
1810 | errorCode.reset(); | |
1811 | return; | |
1812 | } | |
1813 | if (!assertEquals("msgfmt.getFormatNames()[0]", UNICODE_STRING_SIMPLE("alice"), *name)) { | |
1814 | return; | |
1815 | } | |
1816 | name = names->snext(errorCode); | |
1817 | if (name == NULL || errorCode.isFailure()) { | |
1818 | errln("msgfmt.getFormatNames()[1] failed: %s", errorCode.errorName()); | |
1819 | errorCode.reset(); | |
1820 | return; | |
1821 | } | |
1822 | if (!assertEquals("msgfmt.getFormatNames()[1]", UNICODE_STRING_SIMPLE("oops"), *name)) { | |
1823 | return; | |
1824 | } | |
1825 | name = names->snext(errorCode); | |
1826 | if (name == NULL || errorCode.isFailure()) { | |
1827 | errln("msgfmt.getFormatNames()[2] failed: %s", errorCode.errorName()); | |
1828 | errorCode.reset(); | |
1829 | return; | |
1830 | } | |
1831 | if (!assertEquals("msgfmt.getFormatNames()[2]", UNICODE_STRING_SIMPLE("zip"), *name)) { | |
1832 | return; | |
1833 | } | |
1834 | name = names->snext(errorCode); | |
1835 | if (name != NULL) { | |
1836 | errln(UnicodeString("msgfmt.getFormatNames()[3] should be NULL but is: ") + *name); | |
1837 | return; | |
1838 | } | |
1839 | } | |
1840 | ||
4388f060 A |
1841 | void TestMessageFormat::TestTrimArgumentName() { |
1842 | // ICU 4.8 allows and ignores white space around argument names and numbers. | |
1843 | IcuTestErrorCode errorCode(*this, "TestTrimArgumentName"); | |
1844 | MessageFormat m("a { 0 , number , '#,#'#.0 } z", Locale::getEnglish(), errorCode); | |
1845 | if (errorCode.logDataIfFailureAndReset("Unable to instantiate MessageFormat")) { | |
1846 | return; | |
1847 | } | |
1848 | Formattable args[1] = { (int32_t)2 }; | |
1849 | FieldPosition ignore(0); | |
1850 | UnicodeString result; | |
1851 | assertEquals("trim-numbered-arg format() failed", "a #,#2.0 z", | |
1852 | m.format(args, 1, result, ignore, errorCode)); | |
1853 | ||
1854 | m.applyPattern("x { _oOo_ , number , integer } y", errorCode); | |
1855 | UnicodeString argName = UNICODE_STRING_SIMPLE("_oOo_"); | |
1856 | args[0].setLong(3); | |
1857 | result.remove(); | |
1858 | assertEquals("trim-named-arg format() failed", "x 3 y", | |
1859 | m.format(&argName, args, 1, result, errorCode)); | |
1860 | } | |
1861 | ||
51004dcb A |
1862 | void TestMessageFormat::TestSelectOrdinal() { |
1863 | IcuTestErrorCode errorCode(*this, "TestSelectOrdinal"); | |
1864 | // Test plural & ordinal together, | |
1865 | // to make sure that we get the correct cached PluralSelector for each. | |
1866 | MessageFormat m( | |
1867 | "{0,plural,one{1 file}other{# files}}, " | |
1868 | "{0,selectordinal,one{#st file}two{#nd file}few{#rd file}other{#th file}}", | |
1869 | Locale::getEnglish(), errorCode); | |
1870 | if (errorCode.logDataIfFailureAndReset("Unable to instantiate MessageFormat")) { | |
1871 | return; | |
1872 | } | |
1873 | Formattable args[1] = { (int32_t)21 }; | |
1874 | FieldPosition ignore(0); | |
1875 | UnicodeString result; | |
1876 | assertEquals("plural-and-ordinal format(21) failed", "21 files, 21st file", | |
1877 | m.format(args, 1, result, ignore, errorCode), TRUE); | |
1878 | ||
1879 | args[0].setLong(2); | |
1880 | assertEquals("plural-and-ordinal format(2) failed", "2 files, 2nd file", | |
1881 | m.format(args, 1, result.remove(), ignore, errorCode), TRUE); | |
1882 | ||
1883 | args[0].setLong(1); | |
1884 | assertEquals("plural-and-ordinal format(1) failed", "1 file, 1st file", | |
1885 | m.format(args, 1, result.remove(), ignore, errorCode), TRUE); | |
1886 | ||
1887 | args[0].setLong(3); | |
1888 | assertEquals("plural-and-ordinal format(3) failed", "3 files, 3rd file", | |
1889 | m.format(args, 1, result.remove(), ignore, errorCode), TRUE); | |
1890 | ||
1891 | errorCode.logDataIfFailureAndReset(""); | |
1892 | } | |
1893 | ||
57a6839d A |
1894 | void TestMessageFormat::TestDecimals() { |
1895 | IcuTestErrorCode errorCode(*this, "TestDecimals"); | |
1896 | // Simple number replacement. | |
1897 | MessageFormat m( | |
1898 | "{0,plural,one{one meter}other{# meters}}", | |
1899 | Locale::getEnglish(), errorCode); | |
1900 | Formattable args[1] = { (int32_t)1 }; | |
1901 | FieldPosition ignore; | |
1902 | UnicodeString result; | |
1903 | assertEquals("simple format(1)", "one meter", | |
1904 | m.format(args, 1, result, ignore, errorCode), TRUE); | |
1905 | ||
1906 | args[0] = (double)1.5; | |
1907 | result.remove(); | |
1908 | assertEquals("simple format(1.5)", "1.5 meters", | |
1909 | m.format(args, 1, result, ignore, errorCode), TRUE); | |
1910 | ||
1911 | // Simple but explicit. | |
1912 | MessageFormat m0( | |
1913 | "{0,plural,one{one meter}other{{0} meters}}", | |
1914 | Locale::getEnglish(), errorCode); | |
1915 | args[0] = (int32_t)1; | |
1916 | result.remove(); | |
1917 | assertEquals("explicit format(1)", "one meter", | |
1918 | m0.format(args, 1, result, ignore, errorCode), TRUE); | |
1919 | ||
1920 | args[0] = (double)1.5; | |
1921 | result.remove(); | |
1922 | assertEquals("explicit format(1.5)", "1.5 meters", | |
1923 | m0.format(args, 1, result, ignore, errorCode), TRUE); | |
1924 | ||
1925 | // With offset and specific simple format with optional decimals. | |
1926 | MessageFormat m1( | |
1927 | "{0,plural,offset:1 one{another meter}other{{0,number,00.#} meters}}", | |
1928 | Locale::getEnglish(), errorCode); | |
1929 | args[0] = (int32_t)1; | |
1930 | result.remove(); | |
1931 | assertEquals("offset format(1)", "01 meters", | |
1932 | m1.format(args, 1, result, ignore, errorCode), TRUE); | |
1933 | ||
1934 | args[0] = (int32_t)2; | |
1935 | result.remove(); | |
1936 | assertEquals("offset format(1)", "another meter", | |
1937 | m1.format(args, 1, result, ignore, errorCode), TRUE); | |
1938 | ||
1939 | args[0] = (double)2.5; | |
1940 | result.remove(); | |
1941 | assertEquals("offset format(1)", "02.5 meters", | |
1942 | m1.format(args, 1, result, ignore, errorCode), TRUE); | |
1943 | ||
1944 | // With offset and specific simple format with forced decimals. | |
1945 | MessageFormat m2( | |
1946 | "{0,plural,offset:1 one{another meter}other{{0,number,0.0} meters}}", | |
1947 | Locale::getEnglish(), errorCode); | |
1948 | args[0] = (int32_t)1; | |
1949 | result.remove(); | |
1950 | assertEquals("offset-decimals format(1)", "1.0 meters", | |
1951 | m2.format(args, 1, result, ignore, errorCode), TRUE); | |
1952 | ||
1953 | args[0] = (int32_t)2; | |
1954 | result.remove(); | |
1955 | assertEquals("offset-decimals format(1)", "2.0 meters", | |
1956 | m2.format(args, 1, result, ignore, errorCode), TRUE); | |
1957 | ||
1958 | args[0] = (double)2.5; | |
1959 | result.remove(); | |
1960 | assertEquals("offset-decimals format(1)", "2.5 meters", | |
1961 | m2.format(args, 1, result, ignore, errorCode), TRUE); | |
1962 | errorCode.reset(); | |
1963 | } | |
1964 | ||
2ca993e8 A |
1965 | void TestMessageFormat::TestArgIsPrefixOfAnother() { |
1966 | IcuTestErrorCode errorCode(*this, "TestArgIsPrefixOfAnother"); | |
1967 | // Ticket #11952 | |
1968 | MessageFormat mf1("{0,select,a{A}ab{AB}abc{ABC}other{?}}", Locale::getEnglish(), errorCode); | |
1969 | Formattable args[3]; | |
1970 | FieldPosition ignore; | |
1971 | UnicodeString result; | |
1972 | args[0].setString("a"); | |
1973 | assertEquals("a", "A", mf1.format(args, 1, result, ignore, errorCode)); | |
1974 | args[0].setString("ab"); | |
1975 | assertEquals("ab", "AB", mf1.format(args, 1, result.remove(), ignore, errorCode)); | |
1976 | args[0].setString("abc"); | |
1977 | assertEquals("abc", "ABC", mf1.format(args, 1, result.remove(), ignore, errorCode)); | |
1978 | ||
1979 | // Ticket #12172 | |
1980 | MessageFormat mf2("{a} {aa} {aaa}", Locale::getEnglish(), errorCode); | |
1981 | UnicodeString argNames[3] = { "a", "aa", "aaa" }; | |
1982 | args[0].setString("A"); | |
1983 | args[1].setString("AB"); | |
1984 | args[2].setString("ABC"); | |
1985 | assertEquals("a aa aaa", "A AB ABC", mf2.format(argNames, args, 3, result.remove(), errorCode)); | |
1986 | ||
1987 | // Ticket #12172 | |
1988 | MessageFormat mf3("{aa} {aaa}", Locale::getEnglish(), errorCode); | |
1989 | assertEquals("aa aaa", "AB ABC", mf3.format(argNames + 1, args + 1, 2, result.remove(), errorCode)); | |
1990 | } | |
1991 | ||
b75a7d8f | 1992 | #endif /* #if !UCONFIG_NO_FORMATTING */ |