2 **********************************************************************
\r
3 * Copyright (c) 2004-2010, International Business Machines
\r
4 * Corporation and others. All Rights Reserved.
\r
5 **********************************************************************
\r
7 * Created: April 6, 2004
\r
9 **********************************************************************
\r
11 package com.ibm.icu.dev.test.format;
\r
13 import java.text.AttributedCharacterIterator;
\r
14 import java.text.AttributedString;
\r
15 import java.text.ChoiceFormat;
\r
16 import java.text.FieldPosition;
\r
17 import java.text.Format;
\r
18 import java.text.ParseException;
\r
19 import java.text.ParsePosition;
\r
20 import java.util.Date;
\r
21 import java.util.HashMap;
\r
22 import java.util.Hashtable;
\r
23 import java.util.Iterator;
\r
24 import java.util.Locale;
\r
25 import java.util.Map;
\r
26 import java.util.Set;
\r
28 import com.ibm.icu.text.DateFormat;
\r
29 import com.ibm.icu.text.DecimalFormat;
\r
30 import com.ibm.icu.text.DecimalFormatSymbols;
\r
31 import com.ibm.icu.text.MessageFormat;
\r
32 import com.ibm.icu.text.NumberFormat;
\r
33 import com.ibm.icu.text.SimpleDateFormat;
\r
34 import com.ibm.icu.text.UFormat;
\r
35 import com.ibm.icu.util.TimeZone;
\r
36 import com.ibm.icu.util.ULocale;
\r
38 public class TestMessageFormat extends com.ibm.icu.dev.test.TestFmwk {
\r
40 public static void main(String[] args) throws Exception {
\r
41 new TestMessageFormat().run(args);
\r
44 public void TestBug3()
\r
46 double myNumber = -123456;
\r
47 DecimalFormat form = null;
\r
49 new Locale("ar", "", ""),
\r
50 new Locale("be", "", ""),
\r
51 new Locale("bg", "", ""),
\r
52 new Locale("ca", "", ""),
\r
53 new Locale("cs", "", ""),
\r
54 new Locale("da", "", ""),
\r
55 new Locale("de", "", ""),
\r
56 new Locale("de", "AT", ""),
\r
57 new Locale("de", "CH", ""),
\r
58 new Locale("el", "", ""), // 10
\r
59 new Locale("en", "CA", ""),
\r
60 new Locale("en", "GB", ""),
\r
61 new Locale("en", "IE", ""),
\r
62 new Locale("en", "US", ""),
\r
63 new Locale("es", "", ""),
\r
64 new Locale("et", "", ""),
\r
65 new Locale("fi", "", ""),
\r
66 new Locale("fr", "", ""),
\r
67 new Locale("fr", "BE", ""),
\r
68 new Locale("fr", "CA", ""), // 20
\r
69 new Locale("fr", "CH", ""),
\r
70 new Locale("he", "", ""),
\r
71 new Locale("hr", "", ""),
\r
72 new Locale("hu", "", ""),
\r
73 new Locale("is", "", ""),
\r
74 new Locale("it", "", ""),
\r
75 new Locale("it", "CH", ""),
\r
76 new Locale("ja", "", ""),
\r
77 new Locale("ko", "", ""),
\r
78 new Locale("lt", "", ""), // 30
\r
79 new Locale("lv", "", ""),
\r
80 new Locale("mk", "", ""),
\r
81 new Locale("nl", "", ""),
\r
82 new Locale("nl", "BE", ""),
\r
83 new Locale("no", "", ""),
\r
84 new Locale("pl", "", ""),
\r
85 new Locale("pt", "", ""),
\r
86 new Locale("ro", "", ""),
\r
87 new Locale("ru", "", ""),
\r
88 new Locale("sh", "", ""), // 40
\r
89 new Locale("sk", "", ""),
\r
90 new Locale("sl", "", ""),
\r
91 new Locale("sq", "", ""),
\r
92 new Locale("sr", "", ""),
\r
93 new Locale("sv", "", ""),
\r
94 new Locale("tr", "", ""),
\r
95 new Locale("uk", "", ""),
\r
96 new Locale("zh", "", ""),
\r
97 new Locale("zh", "TW", "") // 49
\r
99 StringBuffer buffer = new StringBuffer();
\r
100 ParsePosition parsePos = new ParsePosition(0);
\r
102 for (i= 0; i < 49; i++) {
\r
103 // form = (DecimalFormat)NumberFormat.getCurrencyInstance(locale[i]);
\r
104 form = (DecimalFormat)NumberFormat.getInstance(locale[i]);
\r
105 if (form == null) {
\r
106 errln("Number format creation failed for " + locale[i].getDisplayName());
\r
109 FieldPosition pos = new FieldPosition(0);
\r
110 buffer.setLength(0);
\r
111 form.format(myNumber, buffer, pos);
\r
112 parsePos.setIndex(0);
\r
113 Object result = form.parse(buffer.toString(), parsePos);
\r
114 logln(locale[i].getDisplayName() + " -> " + result);
\r
115 if (parsePos.getIndex() != buffer.length()) {
\r
116 errln("Number format parse failed.");
\r
121 public void TestBug1()
\r
123 final double limit[] = {0.0, 1.0, 2.0};
\r
124 final String formats[] = {"0.0<=Arg<1.0",
\r
127 ChoiceFormat cf = new ChoiceFormat(limit, formats);
\r
128 assertEquals("ChoiceFormat.format", formats[1], cf.format(1));
\r
131 public void TestBug2()
\r
133 // {sfb} use double format in pattern, so result will match (not strictly necessary)
\r
134 final String pattern = "There {0,choice,0.0#are no files|1.0#is one file|1.0<are {0, number} files} on disk {1}. ";
\r
135 logln("The input pattern : " + pattern);
\r
137 MessageFormat fmt = new MessageFormat(pattern);
\r
138 assertEquals("toPattern", pattern, fmt.toPattern());
\r
139 } catch (IllegalArgumentException e) {
\r
140 errln("MessageFormat pattern creation failed.");
\r
144 public void TestPattern() // aka PatternTest()
\r
146 Object testArgs[] = {
\r
147 new Double(1), new Double(3456),
\r
148 "Disk", new Date(1000000000L)
\r
150 String testCases[] = {
\r
151 "Quotes '', '{', 'a' {0} '{0}'",
\r
152 "Quotes '', '{', 'a' {0,number} '{0}'",
\r
153 "'{'1,number,'#',##} {1,number,'#',##}",
\r
154 "There are {1} files on {2} at {3}.",
\r
155 "On {2}, there are {1} files, with {0,number,currency}.",
\r
156 "'{1,number,percent}', {1,number,percent},",
\r
157 "'{1,date,full}', {1,date,full},",
\r
158 "'{3,date,full}', {3,date,full},",
\r
159 "'{1,number,#,##}' {1,number,#,##}",
\r
162 String testResultPatterns[] = {
\r
163 "Quotes '', '{', a {0} '{'0}",
\r
164 "Quotes '', '{', a {0,number} '{'0}",
\r
165 "'{'1,number,#,##} {1,number,'#'#,##}",
\r
166 "There are {1} files on {2} at {3}.",
\r
167 "On {2}, there are {1} files, with {0,number,currency}.",
\r
168 "'{'1,number,percent}, {1,number,percent},",
\r
169 "'{'1,date,full}, {1,date,full},",
\r
170 "'{'3,date,full}, {3,date,full},",
\r
171 "'{'1,number,#,##} {1,number,#,##}"
\r
174 String testResultStrings[] = {
\r
175 "Quotes ', {, a 1 {0}",
\r
176 "Quotes ', {, a 1 {0}",
\r
177 "{1,number,#,##} #34,56",
\r
178 "There are 3,456 files on Disk at 1/12/70 5:46 AM.",
\r
179 "On Disk, there are 3,456 files, with $1.00.",
\r
180 "{1,number,percent}, 345,600%,",
\r
181 "{1,date,full}, Wednesday, December 31, 1969,",
\r
182 "{3,date,full}, Monday, January 12, 1970,",
\r
183 "{1,number,#,##} 34,56"
\r
186 for (int i = 0; i < 9; ++i) {
\r
187 //it_out << "\nPat in: " << testCases[i]);
\r
190 MessageFormat form = null;
\r
192 form = new MessageFormat(testCases[i], Locale.US);
\r
193 } catch (IllegalArgumentException e1) {
\r
194 errln("MessageFormat for " + testCases[i] + " creation failed.");
\r
197 assertEquals("\"" + testCases[i] + "\".toPattern()", testResultPatterns[i], form.toPattern());
\r
199 //it_out << "Pat out: " << form.toPattern(buffer));
\r
200 StringBuffer result = new StringBuffer();
\r
201 FieldPosition fieldpos = new FieldPosition(0);
\r
202 form.format(testArgs, result, fieldpos);
\r
203 assertEquals("format", testResultStrings[i], result.toString());
\r
205 //it_out << "Result: " << result);
\r
206 // /* TODO: Look at this test and see if this is still a valid test */
\r
207 // logln("---------------- test parse ----------------");
\r
210 // form.toPattern(buffer);
\r
211 // logln("MSG pattern for parse: " + buffer);
\r
213 // int parseCount = 0;
\r
214 // Formattable* values = form.parse(result, parseCount, success);
\r
215 // if (U_FAILURE(success)) {
\r
216 // errln("MessageFormat failed test #5");
\r
217 // logln(String("MessageFormat failed test #5 with error code ")+(int)success);
\r
218 // } else if (parseCount != count) {
\r
219 // errln("MSG count not %d as expected. Got %d", count, parseCount);
\r
221 // UBool failed = FALSE;
\r
222 // for (int j = 0; j < parseCount; ++j) {
\r
223 // if (values == 0 || testArgs[j] != values[j]) {
\r
224 // errln(((String)"MSG testargs[") + j + "]: " + toString(testArgs[j]));
\r
225 // errln(((String)"MSG values[") + j + "] : " + toString(values[j]));
\r
230 // errln("MessageFormat failed test #6");
\r
234 public void TestSample() // aka sample()
\r
236 MessageFormat form = null;
\r
237 StringBuffer buffer2 = new StringBuffer();
\r
239 form = new MessageFormat("There are {0} files on {1}");
\r
240 } catch (IllegalArgumentException e1) {
\r
241 errln("Sample message format creation failed.");
\r
244 Object testArgs1[] = { "abc", "def" };
\r
245 FieldPosition fieldpos = new FieldPosition(0);
\r
246 assertEquals("format",
\r
247 "There are abc files on def",
\r
248 form.format(testArgs1, buffer2, fieldpos).toString());
\r
251 public void TestStaticFormat()
\r
253 Object arguments[] = {
\r
255 new Date(871068000000L),
\r
256 "a disturbance in the Force"
\r
259 assertEquals("format",
\r
260 "At 12:20:00 PM on Aug 8, 1997, there was a disturbance in the Force on planet 7.",
\r
261 MessageFormat.format("At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
\r
265 static final int FieldPosition_DONT_CARE = -1;
\r
267 public void TestSimpleFormat()
\r
269 Object testArgs1[] = {new Integer(0), "MyDisk"};
\r
270 Object testArgs2[] = {new Integer(1), "MyDisk"};
\r
271 Object testArgs3[] = {new Integer(12), "MyDisk"};
\r
273 MessageFormat form = new MessageFormat(
\r
274 "The disk \"{1}\" contains {0} file(s).");
\r
276 StringBuffer string = new StringBuffer();
\r
277 FieldPosition ignore = new FieldPosition(FieldPosition_DONT_CARE);
\r
278 form.format(testArgs1, string, ignore);
\r
279 assertEquals("format",
\r
280 "The disk \"MyDisk\" contains 0 file(s).",
\r
281 string.toString());
\r
283 string.setLength(0);
\r
284 form.format(testArgs2, string, ignore);
\r
285 assertEquals("format",
\r
286 "The disk \"MyDisk\" contains 1 file(s).",
\r
287 string.toString());
\r
289 string.setLength(0);
\r
290 form.format(testArgs3, string, ignore);
\r
291 assertEquals("format",
\r
292 "The disk \"MyDisk\" contains 12 file(s).",
\r
293 string.toString());
\r
296 public void TestMsgFormatChoice()
\r
298 MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
\r
299 double filelimits[] = {0,1,2};
\r
300 String filepart[] = {"no files","one file","{0,number} files"};
\r
301 ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
\r
302 form.setFormat(1, fileform); // NOT zero, see below
\r
304 FieldPosition ignore = new FieldPosition(FieldPosition_DONT_CARE);
\r
305 StringBuffer string = new StringBuffer();
\r
306 Object testArgs1[] = {new Integer(0), "MyDisk"};
\r
307 form.format(testArgs1, string, ignore);
\r
308 assertEquals("format#1",
\r
309 "The disk \"MyDisk\" contains no files.",
\r
310 string.toString());
\r
312 string.setLength(0);
\r
313 Object testArgs2[] = {new Integer(1), "MyDisk"};
\r
314 form.format(testArgs2, string, ignore);
\r
315 assertEquals("format#2",
\r
316 "The disk \"MyDisk\" contains one file.",
\r
317 string.toString());
\r
319 string.setLength(0);
\r
320 Object testArgs3[] = {new Integer(1273), "MyDisk"};
\r
321 form.format(testArgs3, string, ignore);
\r
322 assertEquals("format#3",
\r
323 "The disk \"MyDisk\" contains 1,273 files.",
\r
324 string.toString());
\r
327 //---------------------------------
\r
329 //---------------------------------
\r
331 public void TestClone()
\r
333 MessageFormat x = new MessageFormat("There are {0} files on {1}");
\r
334 MessageFormat z = new MessageFormat("There are {0} files on {1} created");
\r
335 MessageFormat y = null;
\r
336 y = (MessageFormat)x.clone();
\r
340 logln("First test (operator ==): Passed!");
\r
342 errln("First test (operator ==): Failed!");
\r
344 if ((x.equals(y) && y.equals(x)) &&
\r
345 (!x.equals(z) && !z.equals(x)) &&
\r
346 (!y.equals(z) && !z.equals(y)) )
\r
347 logln("Second test (equals): Passed!");
\r
349 errln("Second test (equals): Failed!");
\r
354 public void TestEquals()
\r
356 MessageFormat x = new MessageFormat("There are {0} files on {1}");
\r
357 MessageFormat y = new MessageFormat("There are {0} files on {1}");
\r
358 if (!x.equals(y)) {
\r
359 errln("First test (operator ==): Failed!");
\r
364 public void TestNotEquals()
\r
366 MessageFormat x = new MessageFormat("There are {0} files on {1}");
\r
367 MessageFormat y = new MessageFormat("There are {0} files on {1}");
\r
368 y.setLocale(Locale.FRENCH);
\r
370 errln("First test (operator !=): Failed!");
\r
372 y = new MessageFormat("There are {0} files on {1}");
\r
373 y.applyPattern("There are {0} files on {1} the disk");
\r
375 errln("Second test (operator !=): Failed!");
\r
379 public void TestHashCode()
\r
381 ULocale save = ULocale.getDefault();
\r
382 ULocale.setDefault(ULocale.US);
\r
384 MessageFormat x = new MessageFormat("There are {0} files on {1}");
\r
385 MessageFormat z = new MessageFormat("There are {0} files on {1}");
\r
386 MessageFormat y = null;
\r
387 y = (MessageFormat)x.clone();
\r
388 if (x.hashCode() != y.hashCode())
\r
389 errln("FAIL: identical objects have different hashcodes");
\r
390 if (x.hashCode() != z.hashCode())
\r
391 errln("FAIL: identical objects have different hashcodes");
\r
393 /* These are not errors
\r
394 y.setLocale(ULocale.FRENCH);
\r
395 if (x.hashCode() == y.hashCode())
\r
396 errln("FAIL: different objects have same hashcodes. Locale ignored");
\r
398 z.applyPattern("There are {0} files on {1} the disk");
\r
399 if (x.hashCode() == z.hashCode())
\r
400 errln("FAIL: different objects have same hashcodes. Pattern ignored");
\r
403 ULocale.setDefault(save);
\r
406 public void TestSetLocale()
\r
408 Object arguments[] = {
\r
409 new Double(456.83),
\r
410 new Date(871068000000L),
\r
414 StringBuffer result = new StringBuffer();
\r
416 //String formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
\r
417 String formatStr = "At <time> on {1,date}, you made a {2} of {0,number,currency}.";
\r
418 // {sfb} to get $, would need Locale::US, not Locale::ENGLISH
\r
419 // Just use unlocalized currency symbol.
\r
420 //String compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of $456.83.";
\r
421 String compareStrEng = "At <time> on Aug 8, 1997, you made a deposit of ";
\r
422 compareStrEng += '\u00a4';
\r
423 compareStrEng += "456.83.";
\r
424 // {sfb} to get DM, would need Locale::GERMANY, not Locale::GERMAN
\r
425 // Just use unlocalized currency symbol.
\r
426 //String compareStrGer = "At <time> on 08.08.1997, you made a deposit of 456,83 DM.";
\r
427 String compareStrGer = "At <time> on 08.08.1997, you made a deposit of ";
\r
428 compareStrGer += "456,83\u00a0";
\r
429 compareStrGer += '\u00a4';
\r
430 compareStrGer += ".";
\r
432 MessageFormat msg = new MessageFormat(formatStr, Locale.ENGLISH);
\r
433 result.setLength(0);
\r
434 FieldPosition pos = new FieldPosition(0);
\r
435 result = msg.format(
\r
439 assertEquals("format", compareStrEng, result.toString());
\r
441 msg.setLocale(Locale.ENGLISH);
\r
442 assertEquals("getLocale", Locale.ENGLISH, msg.getLocale());
\r
444 msg.setLocale(Locale.GERMAN);
\r
445 assertEquals("getLocale", Locale.GERMAN, msg.getLocale());
\r
447 msg.applyPattern(formatStr);
\r
448 result.setLength(0);
\r
449 result = msg.format(
\r
453 assertEquals("format", compareStrGer, result.toString());
\r
455 //Cover getULocale()
\r
456 logln("Testing set/get ULocale ...");
\r
457 msg.setLocale(ULocale.ENGLISH);
\r
458 assertEquals("getULocale", ULocale.ENGLISH, msg.getULocale());
\r
460 msg.setLocale(ULocale.GERMAN);
\r
461 assertEquals("getULocale", ULocale.GERMAN, msg.getULocale());
\r
463 msg.applyPattern(formatStr);
\r
464 result.setLength(0);
\r
465 result = msg.format(
\r
469 assertEquals("format", compareStrGer, result.toString());
\r
472 @SuppressWarnings("static-access")
\r
473 public void TestFormat()
\r
475 final Object ft_arr[] =
\r
477 new Date(871068000000L)
\r
480 StringBuffer result = new StringBuffer();
\r
482 //String formatStr = "At {1,time} on {1,date}, you made a {2} of {0,number,currency}.";
\r
483 String formatStr = "On {0,date}, it began.";
\r
484 String compareStr = "On Aug 8, 1997, it began.";
\r
486 MessageFormat msg = new MessageFormat(formatStr);
\r
487 FieldPosition fp = new FieldPosition(0);
\r
490 msg.format(new Date(871068000000L),
\r
493 errln("*** MSG format without expected error code.");
\r
494 } catch (Exception e1) {
\r
497 result.setLength(0);
\r
498 result = msg.format(
\r
502 assertEquals("format", compareStr, result.toString());
\r
504 Map<String,Object> map = new Hashtable<String,Object>();
\r
506 msg.format("", map);
\r
507 } catch(Exception e){
\r
508 errln("MessageFormat.format(String,Map) was not suppose to return " +
\r
513 public void TestParse()
\r
515 String msgFormatString = "{0} =sep= {1}";
\r
516 MessageFormat msg = new MessageFormat(msgFormatString);
\r
517 String source = "abc =sep= def";
\r
520 Object[] fmt_arr = msg.parse(source);
\r
521 if (fmt_arr.length != 2) {
\r
522 errln("*** MSG parse (ustring, count, err) count err.");
\r
524 // TODO: This if statement seems to be redundant. [tschumann]
\r
525 if (fmt_arr.length != 2) {
\r
526 errln("*** MSG parse (ustring, parsepos., count) count err.");
\r
528 assertEquals("parse()[0]", "abc", fmt_arr[0]);
\r
529 assertEquals("parse()[1]", "def", fmt_arr[1]);
\r
532 } catch (ParseException e1) {
\r
533 errln("*** MSG parse (ustring, count, err) error.");
\r
536 ParsePosition pp = new ParsePosition(0);
\r
538 Object[] fmt_arr = msg.parse(source, pp);
\r
539 if (pp.getIndex()==0 || fmt_arr==null) {
\r
540 errln("*** MSG parse (ustring, parsepos., count) error.");
\r
542 if (fmt_arr.length != 2) {
\r
543 errln("*** MSG parse (ustring, parsepos., count) count err.");
\r
545 assertEquals("parse()[0]", "abc", fmt_arr[0]);
\r
546 assertEquals("parse()[1]", "def", fmt_arr[1]);
\r
553 fmta = (Object[]) msg.parseObject( source, pp );
\r
554 if (pp.getIndex() == 0) {
\r
555 errln("*** MSG parse (ustring, Object, parsepos ) error.");
\r
557 if (fmta.length != 2) {
\r
558 errln("*** MSG parse (ustring, count, err) count err.");
\r
560 // TODO: Don't we want to check fmta?
\r
561 // In this case this if statement would be redundant, too.
\r
563 if (fmt_arr.length != 2) {
\r
564 errln("*** MSG parse (ustring, parsepos., count) count err.");
\r
566 // TODO: Don't we want to check fmta? [tschumann]
\r
567 assertEquals("parse()[0]", "abc", fmt_arr[0]);
\r
568 assertEquals("parse()[1]", "def", fmt_arr[1]);
\r
575 * Of course, in Java there is no adopt, but we retain the same
\r
576 * method name. [alan]
\r
578 public void TestAdopt()
\r
580 String formatStr = "{0,date},{1},{2,number}";
\r
581 String formatStrChange = "{0,number},{1,number},{2,date}";
\r
582 MessageFormat msg = new MessageFormat(formatStr);
\r
583 MessageFormat msgCmp = new MessageFormat(formatStr);
\r
584 Format[] formats = msg.getFormats();
\r
585 Format[] formatsCmp = msgCmp.getFormats();
\r
586 Format[] formatsChg = null;
\r
587 Format[] formatsAct = null;
\r
590 Format[] formatsToAdopt = null;
\r
592 if (formats==null || formatsCmp==null || (formats.length <= 0) || (formats.length != formatsCmp.length)) {
\r
593 errln("Error getting Formats");
\r
599 for (i = 0; i < formats.length; i++) {
\r
602 if ((a != null) && (b != null)) {
\r
603 if (!a.equals(b)) {
\r
607 } else if ((a != null) || (b != null)) {
\r
608 errln("(a != null) || (b != null)");
\r
613 msg.applyPattern( formatStrChange ); //set msg formats to something different
\r
614 formatsChg = msg.getFormats(); // tested function
\r
615 if (formatsChg==null || (formatsChg.length != formats.length)) {
\r
616 errln("Error getting Formats");
\r
622 for (i = 0; i < formats.length; i++) {
\r
625 if ((a != null) && (b != null)) {
\r
627 logln("formatsChg == formatsCmp at index " + i);
\r
633 errln("*** MSG getFormats diff err.");
\r
637 logln("MSG getFormats tested.");
\r
639 msg.setFormats( formatsCmp ); //tested function
\r
641 formatsAct = msg.getFormats();
\r
642 if (formatsAct==null || (formatsAct.length <=0) || (formatsAct.length != formatsCmp.length)) {
\r
643 errln("Error getting Formats");
\r
647 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern());
\r
648 assertEquals("msg.toPattern()", formatStr, msg.toPattern());
\r
650 for (i = 0; i < formatsAct.length; i++) {
\r
653 if ((a != null) && (b != null)) {
\r
654 if (!a.equals(b)) {
\r
655 errln("formatsAct != formatsCmp at index " + i);
\r
658 } else if ((a != null) || (b != null)) {
\r
659 errln("(a != null) || (b != null)");
\r
663 logln("MSG setFormats tested.");
\r
667 msg.applyPattern( formatStrChange ); //set msg formats to something different
\r
669 formatsToAdopt = new Format[formatsCmp.length];
\r
670 if (formatsToAdopt==null) {
\r
671 errln("memory allocation error");
\r
675 for (i = 0; i < formatsCmp.length; i++) {
\r
676 if (formatsCmp[i] == null) {
\r
677 formatsToAdopt[i] = null;
\r
679 formatsToAdopt[i] = (Format) formatsCmp[i].clone();
\r
680 if (formatsToAdopt[i]==null) {
\r
681 errln("Can't clone format at index " + i);
\r
686 msg.setFormats( formatsToAdopt ); // function to test
\r
688 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern());
\r
689 assertEquals("msg.toPattern()", formatStr, msg.toPattern());
\r
691 formatsAct = msg.getFormats();
\r
692 if (formatsAct==null || (formatsAct.length <=0) || (formatsAct.length != formatsCmp.length)) {
\r
693 errln("Error getting Formats");
\r
697 for (i = 0; i < formatsAct.length; i++) {
\r
700 if ((a != null) && (b != null)) {
\r
701 if (!a.equals(b)) {
\r
705 } else if ((a != null) || (b != null)) {
\r
706 errln("(a != null) || (b != null)");
\r
710 logln("MSG adoptFormats tested.");
\r
714 msg.applyPattern( formatStrChange ); //set msg formats to something different
\r
716 formatsToAdopt = new Format[formatsCmp.length];
\r
717 if (formatsToAdopt==null) {
\r
718 errln("memory allocation error");
\r
722 for (i = 0; i < formatsCmp.length; i++) {
\r
723 if (formatsCmp[i] == null) {
\r
724 formatsToAdopt[i] = null;
\r
726 formatsToAdopt[i] = (Format) formatsCmp[i].clone();
\r
727 if (formatsToAdopt[i]==null) {
\r
728 errln("Can't clone format at index " + i);
\r
734 for ( i = 0; i < formatsCmp.length; i++ ) {
\r
735 msg.setFormat( i, formatsToAdopt[i] ); // function to test
\r
738 assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern());
\r
739 assertEquals("msg.toPattern()", formatStr, msg.toPattern());
\r
741 formatsAct = msg.getFormats();
\r
742 if (formatsAct==null || (formatsAct.length <=0) || (formatsAct.length != formatsCmp.length)) {
\r
743 errln("Error getting Formats");
\r
747 for (i = 0; i < formatsAct.length; i++) {
\r
750 if ((a != null) && (b != null)) {
\r
751 if (!a.equals(b)) {
\r
755 } else if ((a != null) || (b != null)) {
\r
756 errln("(a != null) || (b != null)");
\r
760 logln("MSG adoptFormat tested.");
\r
764 * Verify that MessageFormat accomodates more than 10 arguments and
\r
765 * more than 10 subformats.
\r
767 public void TestUnlimitedArgsAndSubformats() {
\r
768 final String pattern =
\r
769 "On {0,date} (aka {0,date,short}, aka {0,date,long}) "+
\r
770 "at {0,time} (aka {0,time,short}, aka {0,time,long}) "+
\r
771 "there were {1,number} werjes "+
\r
772 "(a {3,number,percent} increase over {2,number}) "+
\r
773 "despite the {4}''s efforts "+
\r
774 "and to delight of {5}, {6}, {7}, {8}, {9}, and {10} {11}.";
\r
776 MessageFormat msg = new MessageFormat(pattern);
\r
778 final Object ARGS[] = {
\r
779 new Date(10000000000000L),
\r
782 new Double(1303.0/1202 - 1),
\r
794 "On Nov 20, 2286 (aka 11/20/86, aka November 20, 2286) "+
\r
795 "at 9:46:40 AM (aka 9:46 AM, aka 9:46:40 AM PST) "+
\r
796 "there were 1,303 werjes "+
\r
797 "(a 8% increase over 1,202) "+
\r
798 "despite the Glimmung's efforts "+
\r
799 "and to delight of the printers, Nick, his father, "+
\r
800 "his mother, the spiddles, and of course Horace.";
\r
801 assertEquals("format", expected, msg.format(ARGS));
\r
802 } catch (IllegalArgumentException e1) {
\r
803 errln("FAIL: constructor failed");
\r
807 // test RBNF extensions to message format
\r
808 public void TestRBNF() {
\r
809 // WARNING: this depends on the RBNF formats for en_US
\r
810 Locale locale = Locale.US;
\r
811 String[] values = {
\r
812 // decimal values do not format completely for ordinal or duration, and
\r
813 // do not always parse, so do not include them
\r
814 "0", "1", "12", "100", "123", "1001", "123,456", "-17",
\r
816 String[] formats = {
\r
817 "There are {0,spellout} files to search.",
\r
818 "There are {0,spellout,%simplified} files to search.",
\r
819 "The bogus spellout {0,spellout,%BOGUS} files behaves like the default.",
\r
820 "This is the {0,ordinal} file to search.", // TODO fix bug, ordinal does not parse
\r
821 "Searching this file will take {0,duration} to complete.",
\r
822 "Searching this file will take {0,duration,%with-words} to complete.",
\r
824 final NumberFormat numFmt = NumberFormat.getInstance(locale);
\r
825 Object[] args = new Object[1];
\r
827 for (int i = 0; i < formats.length; ++i) {
\r
828 MessageFormat fmt = new MessageFormat(formats[i], locale);
\r
829 logln("Testing format pattern: '" + formats[i] + "'");
\r
830 for (int j = 0; j < values.length; ++j) {
\r
832 num = numFmt.parse(values[j]);
\r
834 catch (Exception e) {
\r
835 throw new IllegalStateException("failed to parse test argument");
\r
838 String result = fmt.format(args);
\r
839 logln("value: " + num + " --> " + result);
\r
841 if (i != 3) { // TODO: fix this, for now skip ordinal parsing (format string at index 3)
\r
843 Object[] parsedArgs = fmt.parse(result);
\r
844 if (parsedArgs.length != 1) {
\r
845 errln("parse returned " + parsedArgs.length + " args");
\r
846 } else if (!parsedArgs[0].equals(num)) {
\r
847 errln("parsed argument " + parsedArgs[0] + " != " + num);
\r
850 catch (Exception e) {
\r
851 errln("parse of '" + result + " returned exception: " + e.getMessage());
\r
858 public void TestSetGetFormats()
\r
860 Object arguments[] = {
\r
861 new Double(456.83),
\r
862 new Date(871068000000L),
\r
866 StringBuffer result = new StringBuffer();
\r
868 String formatStr = "At <time> on {1,date}, you made a {2} of {0,number,currency}.";
\r
869 // original expected format result
\r
870 String compareStr = "At <time> on Aug 8, 1997, you made a deposit of $456.83.";
\r
871 // the date being German-style, but the currency being English-style
\r
872 String compareStr2 = "At <time> on 08.08.1997, you made a deposit of ";
\r
873 compareStr2 += '\u00a4';
\r
874 compareStr2 += "456.83.";
\r
875 // both date and currency formats are German-style
\r
876 String compareStr3 = "At <time> on 08.08.1997, you made a deposit of ";
\r
877 compareStr3 += "456,83\u00a0";
\r
878 compareStr3 += '\u00a4';
\r
879 compareStr3 += ".";
\r
881 MessageFormat msg = new MessageFormat(formatStr, ULocale.US);
\r
882 result.setLength(0);
\r
883 FieldPosition pos = new FieldPosition(0);
\r
884 result = msg.format(
\r
888 assertEquals("format", compareStr, result.toString());
\r
890 // constructs a Format array with a English-style Currency formatter
\r
891 // and a German-style Date formatter
\r
892 // might not meaningful, just for testing setFormatsByArgIndex
\r
893 Format[] fmts = new Format[] {
\r
894 NumberFormat.getCurrencyInstance(ULocale.ENGLISH),
\r
895 DateFormat.getDateInstance(DateFormat.DEFAULT, ULocale.GERMAN)
\r
898 msg.setFormatsByArgumentIndex(fmts);
\r
899 result.setLength(0);
\r
900 pos = new FieldPosition(0);
\r
901 result = msg.format(
\r
905 assertEquals("format", compareStr2, result.toString());
\r
907 // Construct a German-style Currency formatter, replace the corresponding one
\r
908 // Thus both formatters should format objects with German-style
\r
909 Format newFmt = NumberFormat.getCurrencyInstance(ULocale.GERMAN);
\r
910 msg.setFormatByArgumentIndex(0, newFmt);
\r
911 result.setLength(0);
\r
912 pos = new FieldPosition(0);
\r
913 result = msg.format(
\r
917 assertEquals("format", compareStr3, result.toString());
\r
919 // verify getFormatsByArgumentIndex
\r
920 // you should got three formats by that
\r
921 // - DecimalFormat locale: de
\r
922 // - SimpleDateFormat locale: de
\r
924 Format[] fmts2 = msg.getFormatsByArgumentIndex();
\r
925 assertEquals("1st subformmater: Format Class", "com.ibm.icu.text.DecimalFormat", fmts2[0].getClass().getName());
\r
926 assertEquals("1st subformmater: its Locale", ULocale.GERMAN, ((UFormat)fmts2[0]).getLocale(ULocale.VALID_LOCALE));
\r
927 assertEquals("2nd subformatter: Format Class", "com.ibm.icu.text.SimpleDateFormat", fmts2[1].getClass().getName());
\r
928 assertEquals("2nd subformmater: its Locale", ULocale.GERMAN, ((UFormat)fmts2[1]).getLocale(ULocale.VALID_LOCALE));
\r
929 assertTrue("The third subFormatter is null", null == fmts2[2]);
\r
932 // Test the fix pattern api
\r
933 public void TestAutoQuoteApostrophe() {
\r
934 final String[] patterns = { // new pattern, expected pattern
\r
945 "{'a{}'a}'a", "{'a{}'a}''a",
\r
947 "'} '{'}'", "'} '{'}''",
\r
948 "'} {{{''", "'} {{{'''",
\r
950 for (int i = 0; i < patterns.length; i += 2) {
\r
951 assertEquals("[" + (i/2) + "] \"" + patterns[i] + "\"", patterns[i+1], MessageFormat.autoQuoteApostrophe(patterns[i]));
\r
955 // This tests passing named arguments instead of numbers to format().
\r
956 public void testFormatNamedArguments() {
\r
957 Map arguments = new HashMap();
\r
958 arguments.put("startDate", new Date(871068000000L));
\r
960 StringBuffer result = new StringBuffer();
\r
962 String formatStr = "On {startDate,date}, it began.";
\r
963 String compareStr = "On Aug 8, 1997, it began.";
\r
965 MessageFormat msg = new MessageFormat(formatStr);
\r
966 FieldPosition fp = new FieldPosition(0);
\r
969 msg.format(arguments.get("startDate"), result, fp);
\r
970 errln("*** MSG format without expected error code.");
\r
971 } catch (Exception e1) {
\r
974 result.setLength(0);
\r
975 result = msg.format(
\r
979 assertEquals("format", compareStr, result.toString());
\r
982 // This tests parsing formatted messages with named arguments instead of
\r
984 public void testParseNamedArguments() {
\r
985 String msgFormatString = "{foo} =sep= {bar}";
\r
986 MessageFormat msg = new MessageFormat(msgFormatString);
\r
987 String source = "abc =sep= def";
\r
990 Map fmt_map = msg.parseToMap(source);
\r
991 if (fmt_map.keySet().size() != 2) {
\r
992 errln("*** MSG parse (ustring, count, err) count err.");
\r
994 assertEquals("parse()[0]", "abc", fmt_map.get("foo"));
\r
995 assertEquals("parse()[1]", "def", fmt_map.get("bar"));
\r
997 } catch (ParseException e1) {
\r
998 errln("*** MSG parse (ustring, count, err) error.");
\r
1001 ParsePosition pp = new ParsePosition(0);
\r
1002 Map fmt_map = msg.parseToMap(source, pp);
\r
1003 if (pp.getIndex()==0 || fmt_map==null) {
\r
1004 errln("*** MSG parse (ustring, parsepos., count) error.");
\r
1006 if (fmt_map.keySet().size() != 2) {
\r
1007 errln("*** MSG parse (ustring, parsepos., count) count err.");
\r
1009 assertEquals("parse()[0]", "abc", fmt_map.get("foo"));
\r
1010 assertEquals("parse()[1]", "def", fmt_map.get("bar"));
\r
1016 Map fmta = (Map) msg.parseObject( source, pp );
\r
1017 if (pp.getIndex() == 0) {
\r
1018 errln("*** MSG parse (ustring, Object, parsepos ) error.");
\r
1020 if (fmta.keySet().size() != 2) {
\r
1021 errln("*** MSG parse (ustring, count, err) count err.");
\r
1023 assertEquals("parse()[0]", "abc", fmta.get("foo"));
\r
1024 assertEquals("parse()[1]", "def", fmta.get("bar"));
\r
1029 // Ensure that methods designed for numeric arguments only, will throw
\r
1030 // an exception when called on MessageFormat objects created with
\r
1031 // named arguments.
\r
1032 public void testNumericOnlyMethods() {
\r
1033 MessageFormat msg = new MessageFormat("Number of files: {numfiles}");
\r
1034 boolean gotException = false;
\r
1036 Format fmts[] = {new DecimalFormat()};
\r
1037 msg.setFormatsByArgumentIndex(fmts);
\r
1038 } catch (IllegalArgumentException e) {
\r
1039 gotException = true;
\r
1041 if (!gotException) {
\r
1042 errln("MessageFormat.setFormatsByArgumentIndex() should throw an " +
\r
1043 "IllegalArgumentException when called on formats with " +
\r
1044 "named arguments but did not!");
\r
1047 gotException = false;
\r
1049 msg.setFormatByArgumentIndex(0, new DecimalFormat());
\r
1050 } catch (IllegalArgumentException e) {
\r
1051 gotException = true;
\r
1053 if (!gotException) {
\r
1054 errln("MessageFormat.setFormatByArgumentIndex() should throw an " +
\r
1055 "IllegalArgumentException when called on formats with " +
\r
1056 "named arguments but did not!");
\r
1059 gotException = false;
\r
1061 msg.getFormatsByArgumentIndex();
\r
1062 } catch (IllegalArgumentException e) {
\r
1063 gotException = true;
\r
1065 if (!gotException) {
\r
1066 errln("MessageFormat.getFormatsByArgumentIndex() should throw an " +
\r
1067 "IllegalArgumentException when called on formats with " +
\r
1068 "named arguments but did not!");
\r
1071 gotException = false;
\r
1073 Object args[] = {new Long(42)};
\r
1074 msg.format(args, new StringBuffer(), new FieldPosition(0));
\r
1075 } catch (IllegalArgumentException e) {
\r
1076 gotException = true;
\r
1078 if (!gotException) {
\r
1079 errln("MessageFormat.format(Object[], StringBuffer, FieldPosition) " +
\r
1080 "should throw an IllegalArgumentException when called on " +
\r
1081 "formats with named arguments but did not!");
\r
1084 gotException = false;
\r
1086 Object args[] = {new Long(42)};
\r
1087 msg.format((Object) args, new StringBuffer(), new FieldPosition(0));
\r
1088 } catch (IllegalArgumentException e) {
\r
1089 gotException = true;
\r
1091 if (!gotException) {
\r
1092 errln("MessageFormat.format(Object, StringBuffer, FieldPosition) " +
\r
1093 "should throw an IllegalArgumentException when called with " +
\r
1094 "non-Map object as argument on formats with named " +
\r
1095 "arguments but did not!");
\r
1098 gotException = false;
\r
1100 msg.parse("Number of files: 5", new ParsePosition(0));
\r
1101 } catch (IllegalArgumentException e) {
\r
1102 gotException = true;
\r
1104 if (!gotException) {
\r
1105 errln("MessageFormat.parse(String, ParsePosition) " +
\r
1106 "should throw an IllegalArgumentException when called with " +
\r
1107 "non-Map object as argument on formats with named " +
\r
1108 "arguments but did not!");
\r
1111 gotException = false;
\r
1113 msg.parse("Number of files: 5");
\r
1114 } catch (IllegalArgumentException e) {
\r
1115 gotException = true;
\r
1116 } catch (ParseException e) {
\r
1117 errln("Wrong exception thrown.");
\r
1119 if (!gotException) {
\r
1120 errln("MessageFormat.parse(String) " +
\r
1121 "should throw an IllegalArgumentException when called with " +
\r
1122 "non-Map object as argument on formats with named " +
\r
1123 "arguments but did not!");
\r
1127 public void testNamedArguments() {
\r
1128 // Ensure that mixed argument types are not allowed.
\r
1129 // Either all arguments have to be numeric or valid identifiers.
\r
1131 new MessageFormat("Number of files in folder {0}: {numfiles}");
\r
1132 errln("Creating a MessageFormat with mixed argument types " +
\r
1133 "(named and numeric) should throw an " +
\r
1134 "IllegalArgumentException but did not!");
\r
1135 } catch (IllegalArgumentException e) {}
\r
1138 new MessageFormat("Number of files in folder {folder}: {1}");
\r
1139 errln("Creating a MessageFormat with mixed argument types " +
\r
1140 "(named and numeric) should throw an " +
\r
1141 "IllegalArgumentException but did not!");
\r
1142 } catch (IllegalArgumentException e) {}
\r
1144 // Test named arguments.
\r
1145 MessageFormat mf = new MessageFormat("Number of files in folder {folder}: {numfiles}");
\r
1146 if (!mf.usesNamedArguments()) {
\r
1147 errln("message format 1 should have used named arguments");
\r
1149 mf = new MessageFormat("Wavelength: {\u028EValue\uFF14}");
\r
1150 if (!mf.usesNamedArguments()) {
\r
1151 errln("message format 2 should have used named arguments");
\r
1154 // Test argument names with invalid start characters.
\r
1156 new MessageFormat("Wavelength: {_\u028EValue\uFF14}");
\r
1157 errln("Creating a MessageFormat with invalid argument names " +
\r
1158 "should throw an IllegalArgumentException but did not!");
\r
1159 } catch (IllegalArgumentException e) {}
\r
1162 new MessageFormat("Wavelength: {\uFF14\u028EValue}");
\r
1163 errln("Creating a MessageFormat with invalid argument names " +
\r
1164 "should throw an IllegalArgumentException but did not!");
\r
1165 } catch (IllegalArgumentException e) {}
\r
1167 // Test argument names with invalid continue characters.
\r
1169 new MessageFormat("Wavelength: {Value@\uFF14}");
\r
1170 errln("Creating a MessageFormat with invalid argument names " +
\r
1171 "should throw an IllegalArgumentException but did not!");
\r
1172 } catch (IllegalArgumentException e) {}
\r
1175 new MessageFormat("Wavelength: {Value(\uFF14)}");
\r
1176 errln("Creating a MessageFormat with invalid argument names " +
\r
1177 "should throw an IllegalArgumentException but did not!");
\r
1178 } catch (IllegalArgumentException e) {}
\r
1181 public void testNumericFormatWithMap() {
\r
1182 MessageFormat mf = new MessageFormat("X:{2} Y:{1}");
\r
1183 if (mf.usesNamedArguments()) {
\r
1184 errln("should not use named arguments");
\r
1187 Map map12 = new HashMap();
\r
1188 map12.put("1", "one");
\r
1189 map12.put("2", "two");
\r
1191 String target = "X:two Y:one";
\r
1192 String result = mf.format(map12);
\r
1193 if (!target.equals(result)) {
\r
1194 errln("expected '" + target + "' but got '" + result + "'");
\r
1198 Map mapResult = mf.parseToMap(target);
\r
1199 if (!map12.equals(mapResult)) {
\r
1200 errln("expected " + map12 + " but got " + mapResult);
\r
1202 } catch (ParseException e) {
\r
1203 errln("unexpected exception: " + e.getMessage());
\r
1206 Map map10 = new HashMap();
\r
1207 map10.put("1", "one");
\r
1208 map10.put("0", "zero");
\r
1209 target = "X:{2} Y:one";
\r
1210 result = mf.format(map10);
\r
1211 if (!target.equals(result)) {
\r
1212 errln("expected '" + target + "' but got '" + result + "'");
\r
1215 DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
\r
1216 DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.MEDIUM);
\r
1217 Map fmtMap = new HashMap();
\r
1218 fmtMap.put("1", dateFormat);
\r
1219 fmtMap.put("2", timeFormat);
\r
1220 mf.setFormatsByArgumentName(fmtMap);
\r
1221 Date date = new Date(661439820000L);
\r
1224 result = mf.format(map12); // should fail, wrong argument type
\r
1225 fail("expected exception but got '" + result + "'");
\r
1226 } catch (IllegalArgumentException e) {
\r
1230 Map argMap = new HashMap();
\r
1231 argMap.put("1", date);
\r
1232 argMap.put("2", date);
\r
1233 target = "X:5:17:00 AM Y:Dec 17, 1990";
\r
1234 result = mf.format(argMap);
\r
1235 if (!target.equals(result)) {
\r
1236 errln("expected '" + target + "' but got '" + result + "'");
\r
1240 // This tests nested Formats inside PluralFormat.
\r
1241 public void testNestedFormatsInPluralFormat() {
\r
1243 MessageFormat msgFmt = new MessageFormat(
\r
1244 "{0, plural, one {{0, number,C''''est #,##0.0# fichier}} " +
\r
1245 "other {Ce sont # fichiers}} dans la liste.",
\r
1246 new ULocale("fr"));
\r
1247 Object objArray[] = {new Long(0)};
\r
1248 HashMap objMap = new HashMap();
\r
1249 objMap.put("argument", objArray[0]);
\r
1250 String result = msgFmt.format(objArray);
\r
1251 if (!result.equals("C'est 0,0 fichier dans la liste.")) {
\r
1252 errln("PluralFormat produced wrong message string.");
\r
1254 } catch (Exception e) {
\r
1255 e.printStackTrace();
\r
1256 throw new RuntimeException(e.getMessage());
\r
1260 // This tests PluralFormats used inside MessageFormats.
\r
1261 public void testPluralFormat() {
\r
1263 MessageFormat mfNum = new MessageFormat(
\r
1264 "{0, plural, one{C''est # fichier} other " +
\r
1265 "{Ce sont # fichiers}} dans la liste.",
\r
1266 new ULocale("fr"));
\r
1267 MessageFormat mfAlpha = new MessageFormat(
\r
1268 "{argument, plural, one{C''est # fichier} other {Ce " +
\r
1269 "sont # fichiers}} dans la liste.",
\r
1270 new ULocale("fr"));
\r
1271 Object objArray[] = {new Long(0)};
\r
1272 HashMap objMap = new HashMap();
\r
1273 objMap.put("argument", objArray[0]);
\r
1274 String result = mfNum.format(objArray);
\r
1275 if (!result.equals(mfAlpha.format(objMap))) {
\r
1276 errln("PluralFormat's output differs when using named " +
\r
1277 "arguments instead of numbers!");
\r
1279 if (!result.equals("C'est 0 fichier dans la liste.")) {
\r
1280 errln("PluralFormat produced wrong message string.");
\r
1284 MessageFormat mfNum = new MessageFormat (
\r
1285 "There {0, plural, one{is # zavod}few{are {0, " +
\r
1286 "number,###.0} zavoda} other{are # zavodov}} in the " +
\r
1288 new ULocale("ru"));
\r
1289 MessageFormat mfAlpha = new MessageFormat (
\r
1290 "There {argument, plural, one{is # zavod}few{" +
\r
1291 "are {argument, number,###.0} zavoda} other{are # " +
\r
1292 "zavodov}} in the directory.",
\r
1293 new ULocale("ru"));
\r
1294 Object objArray[] = {new Long(4)};
\r
1295 HashMap objMap = new HashMap();
\r
1296 objMap.put("argument", objArray[0]);
\r
1297 String result = mfNum.format(objArray);
\r
1298 if (!result.equals(mfAlpha.format(objMap))) {
\r
1299 errln("PluralFormat's output differs when using named " +
\r
1300 "arguments instead of numbers!");
\r
1302 if (!result.equals("There are 4,0 zavoda in the directory.")) {
\r
1303 errln("PluralFormat produced wrong message string.");
\r
1308 // Test toPattern when there is a PluralFormat
\r
1309 public void testPluralFormatToPattern() {
\r
1310 String[] patterns = {
\r
1311 "Beware of vicious {0, plural, one {hamster} other {hamsters}}.",
\r
1312 "{0, plural, one {{0, number,C''''est #,##0.0# fichier}} other {Ce sont # fichiers}} dans la liste.",
\r
1313 "{0, plural, one {C''est # fichier} other {Ce sont # fichiers}} dans la liste.",
\r
1316 for (int i = 0; i < patterns.length; ++i) {
\r
1317 String pattern = patterns[i];
\r
1318 MessageFormat mf = new MessageFormat(pattern);
\r
1319 MessageFormat mf2 = new MessageFormat(mf.toPattern());
\r
1320 if (!mf.equals(mf2)) {
\r
1321 errln("message formats not equal for pattern:\n*** '" + pattern + "'\n*** '" +
\r
1322 mf.toPattern() + "'");
\r
1328 * This tests SelectFormats used inside MessageFormats.
\r
1330 public void testSelectFormat() {
\r
1331 String pattern = null;
\r
1332 MessageFormat msgFmt = null ;
\r
1334 //Create the MessageFormat with simple French pattern
\r
1335 pattern = "{0} est {1, select, female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.";
\r
1336 msgFmt = new MessageFormat(pattern);
\r
1337 assertNotNull( "ERROR:Failure in constructing with simple French pattern", msgFmt);
\r
1340 Object testArgs[][] ={
\r
1341 {"Kirti","female"} ,
\r
1342 {"Victor","other"} ,
\r
1343 {"Ash","unknown"} ,
\r
1346 "Kirti est all\\u00E9e \\u00E0 Paris." ,
\r
1347 "Victor est all\\u00E9 \\u00E0 Paris.",
\r
1348 "Ash est all\\u00E9 \\u00E0 Paris."
\r
1350 for ( int i=0; i< 3; i++){
\r
1351 assertEquals("ERROR:Failure in format with simple French Pattern" ,
\r
1352 exp[i] , msgFmt.format(testArgs[i]) );
\r
1355 //Create the MessageFormat with Quoted French Pattern
\r
1356 pattern = "{0} est {1, select, female {all\\u00E9e c''est} other {all\\u00E9 c''est}} \\u00E0 Paris.";
\r
1357 msgFmt = new MessageFormat(pattern);
\r
1358 assertNotNull( "ERROR:Failure in constructing with quoted French pattern", msgFmt);
\r
1361 Object testArgs1[][] ={
\r
1362 {"Kirti","female"} ,
\r
1363 {"Victor","other"} ,
\r
1367 "Kirti est all\\u00E9e c'est \\u00E0 Paris." ,
\r
1368 "Victor est all\\u00E9 c'est \\u00E0 Paris.",
\r
1369 "Ash est all\\u00E9 c'est \\u00E0 Paris."
\r
1371 for ( int i=0; i< 3; i++){
\r
1372 assertEquals("ERROR:Failure in format with quoted French Pattern" ,
\r
1373 exp1[i] , msgFmt.format(testArgs1[i]) );
\r
1376 //Nested patterns with plural, number ,choice ,select format etc.
\r
1377 //Select Format with embedded number format
\r
1378 pattern = "{0} est {1, select, female {{2,number,integer} all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.";
\r
1379 msgFmt = new MessageFormat(pattern);
\r
1380 assertNotNull( "ERROR:Failure in constructing with nested pattern 1", msgFmt);
\r
1383 Object testArgs3[][] ={
\r
1384 {"Kirti", "female", 6} ,
\r
1385 {"Kirti", "female", 100.100} ,
\r
1386 {"Kirti", "other", 6} ,
\r
1389 "Kirti est 6 all\\u00E9e \\u00E0 Paris." ,
\r
1390 "Kirti est 100 all\\u00E9e \\u00E0 Paris.",
\r
1391 "Kirti est all\\u00E9 \\u00E0 Paris."
\r
1394 for ( int i=0; i< 3; i++){
\r
1395 assertEquals("ERROR:Failure in format with nested Pattern 1" ,
\r
1396 exp3[i] , msgFmt.format(testArgs3[i]) );
\r
1399 //Plural format with embedded select format
\r
1400 pattern = "{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.";
\r
1401 msgFmt = new MessageFormat(pattern);
\r
1402 assertNotNull( "ERROR:Failure in constructing with nested pattern 2", msgFmt);
\r
1405 Object testArgs4[][] ={
\r
1406 {"Kirti",6,"female"},
\r
1407 {"Kirti",1,"female"},
\r
1408 {"Ash",1,"other"},
\r
1409 {"Ash",5,"other"},
\r
1412 "Kirti sont all\\u00E9es \\u00E0 Paris." ,
\r
1413 "Kirti est all\\u00E9e \\u00E0 Paris.",
\r
1414 "Ash est all\\u00E9 \\u00E0 Paris.",
\r
1415 "Ash sont all\\u00E9s \\u00E0 Paris."
\r
1417 for ( int i=0; i< 4; i++){
\r
1418 assertEquals("ERROR:Failure in format with nested Pattern 2" ,
\r
1419 exp4[i] , msgFmt.format(testArgs4[i]) );
\r
1422 //Select, plural, and number formats heavily nested
\r
1423 pattern = "{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.";
\r
1424 msgFmt = new MessageFormat(pattern);
\r
1425 assertNotNull( "ERROR:Failure in constructing with nested pattern 3", msgFmt);
\r
1428 Object testArgs5[][] ={
\r
1429 {"Kirti","other",1,"other"},
\r
1430 {"Kirti","other",6,"other"},
\r
1431 {"Kirti","other",1,"female"},
\r
1432 {"Kirti","other",3,"female"},
\r
1433 {"Kirti","female",1,"female"},
\r
1434 {"Kirti","female",5,"female"},
\r
1435 {"Kirti","female",1,"other"},
\r
1436 {"Kirti","female",5,"other"},
\r
1437 {"Kirti","mixed",1,"mixed"},
\r
1438 {"Kirti","mixed",1,"other"},
\r
1439 {"Kirti","female",1,"mixed"},
\r
1440 {"Kirti","mixed",5,"mixed"},
\r
1441 {"Kirti","mixed",5,"other"},
\r
1442 {"Kirti","female",5,"mixed"},
\r
1445 "Kirti und sein Freund gingen nach Paris." ,
\r
1446 "Kirti und seine 6 Freunde gingen nach Paris." ,
\r
1447 "Kirti und seine Freundin gingen nach Paris.",
\r
1448 "Kirti und seine 3 Freundinnen gingen nach Paris.",
\r
1449 "Kirti und ihre Freundin gingen nach Paris.",
\r
1450 "Kirti und ihre 5 Freundinnen gingen nach Paris.",
\r
1451 "Kirti und ihr Freund gingen nach Paris.",
\r
1452 "Kirti und ihre 5 Freunde gingen nach Paris.",
\r
1453 "Kirti und sein Freund gingen nach Paris.",
\r
1454 "Kirti und sein Freund gingen nach Paris.",
\r
1455 "Kirti und ihr Freund gingen nach Paris.",
\r
1456 "Kirti und seine 5 Freunde gingen nach Paris." ,
\r
1457 "Kirti und seine 5 Freunde gingen nach Paris." ,
\r
1458 "Kirti und ihre 5 Freunde gingen nach Paris."
\r
1461 for ( int i=0; i< 14; i++){
\r
1462 assertEquals("ERROR:Failure in format with nested Pattern 3" ,
\r
1463 exp5[i] , msgFmt.format(testArgs5[i]) );
\r
1468 * Test toPattern when there is a SelectFormat
\r
1470 public void testSelectFormatToPattern() {
\r
1471 String[] patterns = {
\r
1472 //Pattern with some text at start and at end
\r
1473 "{0} est {1,select, female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.",
\r
1474 //Pattern with some text at start
\r
1475 "{0} est {1,select, female {all\\u00E9e} other {all\\u00E9}}",
\r
1476 //Pattern with some text at end
\r
1477 "{1, select,female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.",
\r
1478 //Pattern with no text at any end
\r
1479 "{1, select,female {all\\u00E9e} other {all\\u00E9}}.",
\r
1480 //Quoted French pattern
\r
1481 "{0} est {1,select, female {all\\u00E9e c''est} other {all\\u00E9 c''est}} \\u00E0 Paris.",
\r
1484 for (int i = 0; i < patterns.length; ++i) {
\r
1485 String pattern = patterns[i];
\r
1486 MessageFormat mf = new MessageFormat(pattern);
\r
1487 MessageFormat mf2 = new MessageFormat(mf.toPattern());
\r
1488 if (!mf.equals(mf2)) {
\r
1489 errln("message formats not equal for pattern:\n*** '"
\r
1490 + pattern + "'\n*** '" + mf.toPattern() + "'");
\r
1495 // Test case for null arguments.
\r
1497 public void TestNullArgs() {
\r
1498 MessageFormat msgfmt = new MessageFormat("{0} - {1}");
\r
1499 Object[][] TEST_CASES = {
\r
1500 {null, "{0} - {1}"},
\r
1501 {new Object[] {null}, "null - {1}"},
\r
1502 {new Object[] {null, null}, "null - null"},
\r
1503 {new Object[] {"one"}, "one - {1}"},
\r
1504 {new Object[] {"one", null}, "one - null"},
\r
1505 {new Object[] {null, "two"}, "null - two"},
\r
1508 for (int i = 0; i < TEST_CASES.length; i++) {
\r
1509 String text = msgfmt.format(TEST_CASES[i][0]);
\r
1510 if (!text.equals(TEST_CASES[i][1])) {
\r
1511 errln("FAIL: Returned[" + text + "] Expected[" + TEST_CASES[i][1] + "]");
\r
1516 public void TestSetFormat() {
\r
1517 MessageFormat ms = new MessageFormat("{number} {date}", ULocale.ENGLISH);
\r
1518 final DecimalFormat decimalFormat = new DecimalFormat("000.000", DecimalFormatSymbols.getInstance(ULocale.ENGLISH));
\r
1519 ms.setFormatByArgumentName("number", decimalFormat);
\r
1520 final SimpleDateFormat dateFormat = new SimpleDateFormat("'year:'yy 'month:'MM 'day:'dd");
\r
1521 dateFormat.setTimeZone(TimeZone.getTimeZone("Etc/GMT"));
\r
1522 ms.setFormatByArgumentName("date", dateFormat);
\r
1523 Map map = new HashMap();
\r
1524 map.put("number", new Integer(1234));
\r
1525 map.put("date", new Date(0,0,0));
\r
1526 String result = ms.format(map);
\r
1527 assertEquals("setFormatByArgumentName", "1234.000 year:99 month:12 day:31", result);
\r
1528 Set formatNames = ms.getFormatArgumentNames();
\r
1529 assertEquals("Format Names match", formatNames, map.keySet());
\r
1530 assertEquals("Decimal", decimalFormat, ms.getFormatByArgumentName("number"));
\r
1531 assertEquals("Date", dateFormat, ms.getFormatByArgumentName("date"));
\r
1534 // Test case for formatToCharacterIterator
\r
1535 public void TestFormatToCharacterIterator() {
\r
1536 MessageFormat[] msgfmts = {
\r
1537 new MessageFormat(
\r
1538 "The {3,ordinal} folder ''{0}'' contains {2,number} file(s), created at {1,time} on {1,date}."),
\r
1539 new MessageFormat(
\r
1540 "The {arg3,ordinal} folder ''{arg0}'' contains {arg2,number} file(s), created at {arg1,time} on {arg1,date}."), // same
\r
1546 new MessageFormat("The folder contains {0}.") };
\r
1548 double filelimits[] = { 0, 1, 2 };
\r
1549 String filepart[] = { "no files", "one file", "{0,number} files" };
\r
1550 ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart);
\r
1551 msgfmts[2].setFormat(0, fileform);
\r
1553 Object[] args0 = new Object[] { "tmp", new Date(1184777888000L), new Integer(15), new Integer(2) };
\r
1555 HashMap args1 = new HashMap();
\r
1556 args1.put("arg0", "tmp");
\r
1557 args1.put("arg1", new Date(1184777888000L));
\r
1558 args1.put("arg2", new Integer(15));
\r
1559 args1.put("arg3", new Integer(2));
\r
1561 Object[] args2 = new Object[] { new Integer(34) };
\r
1563 Object[] args = { args0, args1, args2 };
\r
1565 String[] expectedStrings = {
\r
1566 "The 2\u207f\u1d48 folder 'tmp' contains 15 file(s), created at 9:58:08 AM on Jul 18, 2007.",
\r
1567 "The 2\u207f\u1d48 folder 'tmp' contains 15 file(s), created at 9:58:08 AM on Jul 18, 2007.",
\r
1568 "The folder contains 34 files." };
\r
1570 AttributedString[] expectedAttributedStrings = { new AttributedString(expectedStrings[0]),
\r
1571 new AttributedString(expectedStrings[1]), new AttributedString(expectedStrings[2]) };
\r
1573 // Add expected attributes to the expectedAttributedStrings[0]
\r
1574 expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(3), 4, 7);
\r
1575 expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(0), 16, 19);
\r
1576 expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(2), 30, 32);
\r
1577 expectedAttributedStrings[0].addAttribute(NumberFormat.Field.INTEGER, NumberFormat.Field.INTEGER, 30, 32);
\r
1578 expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(1), 53, 63);
\r
1579 expectedAttributedStrings[0].addAttribute(DateFormat.Field.HOUR1, DateFormat.Field.HOUR1, 53, 54);
\r
1580 expectedAttributedStrings[0].addAttribute(DateFormat.Field.MINUTE, DateFormat.Field.MINUTE, 55, 57);
\r
1581 expectedAttributedStrings[0].addAttribute(DateFormat.Field.SECOND, DateFormat.Field.SECOND, 58, 60);
\r
1582 expectedAttributedStrings[0].addAttribute(DateFormat.Field.AM_PM, DateFormat.Field.AM_PM, 61, 63);
\r
1583 expectedAttributedStrings[0].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(1), 67, 79);
\r
1584 expectedAttributedStrings[0].addAttribute(DateFormat.Field.MONTH, DateFormat.Field.MONTH, 67, 70);
\r
1585 expectedAttributedStrings[0].addAttribute(DateFormat.Field.DAY_OF_MONTH, DateFormat.Field.DAY_OF_MONTH, 71, 73);
\r
1586 expectedAttributedStrings[0].addAttribute(DateFormat.Field.YEAR, DateFormat.Field.YEAR, 75, 79);
\r
1588 // Add expected attributes to the expectedAttributedStrings[1]
\r
1589 expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg3", 4, 7);
\r
1590 expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg0", 16, 19);
\r
1591 expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg2", 30, 32);
\r
1592 expectedAttributedStrings[1].addAttribute(NumberFormat.Field.INTEGER, NumberFormat.Field.INTEGER, 30, 32);
\r
1593 expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg1", 53, 63);
\r
1594 expectedAttributedStrings[1].addAttribute(DateFormat.Field.HOUR1, DateFormat.Field.HOUR1, 53, 54);
\r
1595 expectedAttributedStrings[1].addAttribute(DateFormat.Field.MINUTE, DateFormat.Field.MINUTE, 55, 57);
\r
1596 expectedAttributedStrings[1].addAttribute(DateFormat.Field.SECOND, DateFormat.Field.SECOND, 58, 60);
\r
1597 expectedAttributedStrings[1].addAttribute(DateFormat.Field.AM_PM, DateFormat.Field.AM_PM, 61, 63);
\r
1598 expectedAttributedStrings[1].addAttribute(MessageFormat.Field.ARGUMENT, "arg1", 67, 79);
\r
1599 expectedAttributedStrings[1].addAttribute(DateFormat.Field.MONTH, DateFormat.Field.MONTH, 67, 70);
\r
1600 expectedAttributedStrings[1].addAttribute(DateFormat.Field.DAY_OF_MONTH, DateFormat.Field.DAY_OF_MONTH, 71, 73);
\r
1601 expectedAttributedStrings[1].addAttribute(DateFormat.Field.YEAR, DateFormat.Field.YEAR, 75, 79);
\r
1603 // Add expected attributes to the expectedAttributedStrings[2]
\r
1604 expectedAttributedStrings[2].addAttribute(MessageFormat.Field.ARGUMENT, new Integer(0), 20, 28);
\r
1605 expectedAttributedStrings[2].addAttribute(NumberFormat.Field.INTEGER, NumberFormat.Field.INTEGER, 20, 22);
\r
1607 for (int i = 0; i < msgfmts.length; i++) {
\r
1608 AttributedCharacterIterator acit = msgfmts[i].formatToCharacterIterator(args[i]);
\r
1609 AttributedCharacterIterator expectedAcit = expectedAttributedStrings[i].getIterator();
\r
1611 // Check available attributes
\r
1612 Set attrSet = acit.getAllAttributeKeys();
\r
1613 Set expectedAttrSet = expectedAcit.getAllAttributeKeys();
\r
1614 if (attrSet.size() != expectedAttrSet.size()) {
\r
1615 errln("FAIL: Number of attribute keys is " + attrSet.size() + " expected: " + expectedAttrSet.size());
\r
1617 Iterator attrIterator = attrSet.iterator();
\r
1618 while (attrIterator.hasNext()) {
\r
1619 AttributedCharacterIterator.Attribute attr = (AttributedCharacterIterator.Attribute) attrIterator
\r
1621 if (!expectedAttrSet.contains(attr)) {
\r
1622 errln("FAIL: The attribute " + attr + " is not expected.");
\r
1626 StringBuffer buf = new StringBuffer();
\r
1627 int index = acit.getBeginIndex();
\r
1628 int end = acit.getEndIndex();
\r
1629 int indexExp = expectedAcit.getBeginIndex();
\r
1630 int expectedLen = expectedAcit.getEndIndex() - indexExp;
\r
1631 if (end - index != expectedLen) {
\r
1632 errln("FAIL: Length of the result attributed string is " + (end - index) + " expected: " + expectedLen);
\r
1634 // Check attributes associated with each character
\r
1635 while (index < end) {
\r
1636 char c = acit.setIndex(index);
\r
1638 expectedAcit.setIndex(indexExp);
\r
1640 Map attrs = acit.getAttributes();
\r
1641 Map attrsExp = expectedAcit.getAttributes();
\r
1642 if (attrs.size() != attrsExp.size()) {
\r
1643 errln("FAIL: Number of attributes associated with index " + index + " is " + attrs.size()
\r
1644 + " expected: " + attrsExp.size());
\r
1646 // Check all attributes at the index
\r
1647 Iterator entryIterator = attrsExp.entrySet().iterator();
\r
1648 while (entryIterator.hasNext()) {
\r
1649 Map.Entry entry = (Map.Entry) entryIterator.next();
\r
1650 if (attrs.containsKey(entry.getKey())) {
\r
1651 Object value = attrs.get(entry.getKey());
\r
1652 assertEquals("Attribute value at index " + index, entry.getValue(), value);
\r
1654 errln("FAIL: Attribute " + entry.getKey() + " is missing at index " + index);
\r
1661 assertEquals("AttributedString contents", expectedStrings[i], buf.toString());
\r
1665 // Tests when "if (arguments == null)" is true
\r
1667 MessageFormat mf = new MessageFormat("");
\r
1668 mf.formatToCharacterIterator(null);
\r
1669 errln("MessageFormat.formatToCharacterIterator(Object) was suppose "
\r
1670 + "to return an exception when null is passed.");
\r
1671 } catch (Exception e) {
\r
1676 * Tests the method public Format getFormatByArgumentName(String argumentName)
\r
1678 public void TestGetFormatByArgumentName() {
\r
1679 MessageFormat mf = new MessageFormat("");
\r
1680 if (mf.getFormatByArgumentName("") != null) {
\r
1681 errln("MessageFormat.getFormatByArgumentName(String) was suppose "
\r
1682 + "to return an null if argumentName was not found.");
\r