1 /* 2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4031438 4058973 4074764 4094906 4104976 4105380 4106659 4106660 4106661 27 * 4111739 4112104 4113018 4114739 4114743 4116444 4118592 4118594 4120552 28 * 4142938 4169959 4232154 4293229 8187551 29 * @summary Regression tests for MessageFormat and associated classes 30 * @library /java/text/testlib 31 * @run main MessageRegression 32 */ 33 /* 34 (C) Copyright Taligent, Inc. 1996 - All Rights Reserved 35 (C) Copyright IBM Corp. 1996 - All Rights Reserved 36 37 The original version of this source code and documentation is copyrighted and 38 owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These materials are 39 provided under terms of a License Agreement between Taligent and Sun. This 40 technology is protected by multiple US and International patents. This notice and 41 attribution to Taligent may not be removed. 42 Taligent is a registered trademark of Taligent, Inc. 43 */ 44 45 package test.java.text.Format.MessageFormat; 46 47 import java.text.*; 48 import java.util.*; 49 import java.io.IOException; 50 import java.io.FileOutputStream; 51 import java.io.FileInputStream; 52 import java.io.ByteArrayInputStream; 53 import java.io.ByteArrayOutputStream; 54 import java.io.ObjectOutputStream; 55 import java.io.ObjectInputStream; 56 import java.io.Serializable; 57 58 import test.java.text.testlib.IntlTest; 59 import test.java.text.testlib.TestUtils; 60 61 public class MessageRegression extends IntlTest { 62 main(String[] args)63 public static void main(String[] args) throws Exception { 64 new MessageRegression().run(args); 65 } 66 67 /* @bug 4074764 68 * Null exception when formatting pattern with MessageFormat 69 * with no parameters. 70 */ Test4074764()71 public void Test4074764() { 72 String[] pattern = {"Message without param", 73 "Message with param:{0}", 74 "Longer Message with param {0}"}; 75 //difference between the two param strings are that 76 //in the first one, the param position is within the 77 //length of the string without param while it is not so 78 //in the other case. 79 80 MessageFormat messageFormatter = new MessageFormat(""); 81 82 try { 83 //Apply pattern with param and print the result 84 messageFormatter.applyPattern(pattern[1]); 85 Object[] params = {new String("BUG"), new Date()}; 86 String tempBuffer = messageFormatter.format(params); 87 if (!tempBuffer.equals("Message with param:BUG")) 88 errln("MessageFormat with one param test failed."); 89 logln("Formatted with one extra param : " + tempBuffer); 90 91 //Apply pattern without param and print the result 92 messageFormatter.applyPattern(pattern[0]); 93 tempBuffer = messageFormatter.format(null); 94 if (!tempBuffer.equals("Message without param")) 95 errln("MessageFormat with no param test failed."); 96 logln("Formatted with no params : " + tempBuffer); 97 98 tempBuffer = messageFormatter.format(params); 99 if (!tempBuffer.equals("Message without param")) 100 errln("Formatted with arguments > subsitution failed. result = " + tempBuffer.toString()); 101 logln("Formatted with extra params : " + tempBuffer); 102 //This statement gives an exception while formatting... 103 //If we use pattern[1] for the message with param, 104 //we get an NullPointerException in MessageFormat.java(617) 105 //If we use pattern[2] for the message with param, 106 //we get an StringArrayIndexOutOfBoundsException in MessageFormat.java(614) 107 //Both are due to maxOffset not being reset to -1 108 //in applyPattern() when the pattern does not 109 //contain any param. 110 } catch (Exception foo) { 111 errln("Exception when formatting with no params."); 112 } 113 } 114 115 /* @bug 4058973 116 * MessageFormat.toPattern has weird rounding behavior. 117 */ Test4058973()118 public void Test4058973() { 119 120 MessageFormat fmt = new MessageFormat("{0,choice,0#no files|1#one file|1< {0,number,integer} files}"); 121 String pat = fmt.toPattern(); 122 if (!pat.equals("{0,choice,0.0#no files|1.0#one file|1.0< {0,number,integer} files}")) { 123 errln("MessageFormat.toPattern failed"); 124 } 125 } 126 /* @bug 4031438 127 * More robust message formats. 128 */ Test4031438()129 public void Test4031438() { 130 Locale locale = Locale.getDefault(); 131 if (!TestUtils.usesAsciiDigits(locale)) { 132 logln("Skipping this test because locale is " + locale); 133 return; 134 } 135 136 String pattern1 = "Impossible {1} has occurred -- status code is {0} and message is {2}."; 137 String pattern2 = "Double '' Quotes {0} test and quoted '{1}' test plus 'other {2} stuff'."; 138 139 MessageFormat messageFormatter = new MessageFormat(""); 140 141 try { 142 logln("Apply with pattern : " + pattern1); 143 messageFormatter.applyPattern(pattern1); 144 Object[] params = {7}; 145 String tempBuffer = messageFormatter.format(params); 146 if (!tempBuffer.equals("Impossible {1} has occurred -- status code is 7 and message is {2}.")) 147 errln("Tests arguments < substitution failed. Formatted text=" + 148 "<" + tempBuffer + ">"); 149 logln("Formatted with 7 : " + tempBuffer); 150 ParsePosition status = new ParsePosition(0); 151 Object[] objs = messageFormatter.parse(tempBuffer, status); 152 if (objs[params.length] != null) 153 errln("Parse failed with more than expected arguments"); 154 for (int i = 0; i < objs.length; i++) { 155 if (objs[i] != null && !objs[i].toString().equals(params[i].toString())) { 156 errln("Parse failed on object " + objs[i] + " at index : " + i); 157 } 158 } 159 tempBuffer = messageFormatter.format(null); 160 if (!tempBuffer.equals("Impossible {1} has occurred -- status code is {0} and message is {2}.")) 161 errln("Tests with no arguments failed"); 162 logln("Formatted with null : " + tempBuffer); 163 logln("Apply with pattern : " + pattern2); 164 messageFormatter.applyPattern(pattern2); 165 tempBuffer = messageFormatter.format(params); 166 if (!tempBuffer.equals("Double ' Quotes 7 test and quoted {1} test plus other {2} stuff.")) 167 errln("quote format test (w/ params) failed."); 168 logln("Formatted with params : " + tempBuffer); 169 tempBuffer = messageFormatter.format(null); 170 if (!tempBuffer.equals("Double ' Quotes {0} test and quoted {1} test plus other {2} stuff.")) 171 errln("quote format test (w/ null) failed."); 172 logln("Formatted with null : " + tempBuffer); 173 logln("toPattern : " + messageFormatter.toPattern()); 174 } catch (Exception foo) { 175 errln("Exception when formatting in bug 4031438. "+foo.getMessage()); 176 } 177 } Test4052223()178 public void Test4052223() 179 { 180 ParsePosition pos = new ParsePosition(0); 181 if (pos.getErrorIndex() != -1) { 182 errln("ParsePosition.getErrorIndex initialization failed."); 183 } 184 MessageFormat fmt = new MessageFormat("There are {0} apples growing on the {1} tree."); 185 String str = new String("There is one apple growing on the peach tree."); 186 Object[] objs = fmt.parse(str, pos); 187 logln("unparsable string , should fail at " + pos.getErrorIndex()); 188 if (pos.getErrorIndex() == -1) 189 errln("Bug 4052223 failed : parsing string " + str); 190 pos.setErrorIndex(4); 191 if (pos.getErrorIndex() != 4) 192 errln("setErrorIndex failed, got " + pos.getErrorIndex() + " instead of 4"); 193 ChoiceFormat f = new ChoiceFormat( 194 "-1#are negative|0#are no or fraction|1#is one|1.0<is 1+|2#are two|2<are more than 2."); 195 pos.setIndex(0); pos.setErrorIndex(-1); 196 Number obj = f.parse("are negative", pos); 197 if (pos.getErrorIndex() != -1 && obj.doubleValue() == -1.0) 198 errln("Parse with \"are negative\" failed, at " + pos.getErrorIndex()); 199 pos.setIndex(0); pos.setErrorIndex(-1); 200 obj = f.parse("are no or fraction ", pos); 201 if (pos.getErrorIndex() != -1 && obj.doubleValue() == 0.0) 202 errln("Parse with \"are no or fraction\" failed, at " + pos.getErrorIndex()); 203 pos.setIndex(0); pos.setErrorIndex(-1); 204 obj = f.parse("go postal", pos); 205 if (pos.getErrorIndex() == -1 && !Double.isNaN(obj.doubleValue())) 206 errln("Parse with \"go postal\" failed, at " + pos.getErrorIndex()); 207 } 208 /* @bug 4104976 209 * ChoiceFormat.equals(null) throws NullPointerException 210 */ Test4104976()211 public void Test4104976() 212 { 213 double[] limits = {1, 20}; 214 String[] formats = {"xyz", "abc"}; 215 ChoiceFormat cf = new ChoiceFormat(limits, formats); 216 try { 217 log("Compares to null is always false, returned : "); 218 logln(cf.equals(null) ? "TRUE" : "FALSE"); 219 } catch (Exception foo) { 220 errln("ChoiceFormat.equals(null) throws exception."); 221 } 222 } 223 /* @bug 4106659 224 * ChoiceFormat.ctor(double[], String[]) doesn't check 225 * whether lengths of input arrays are equal. 226 */ Test4106659()227 public void Test4106659() 228 { 229 double[] limits = {1, 2, 3}; 230 String[] formats = {"one", "two"}; 231 ChoiceFormat cf = null; 232 try { 233 cf = new ChoiceFormat(limits, formats); 234 } catch (Exception foo) { 235 logln("ChoiceFormat constructor should check for the array lengths"); 236 cf = null; 237 } 238 if (cf != null) errln(cf.format(5)); 239 } 240 241 /* @bug 4106660 242 * ChoiceFormat.ctor(double[], String[]) allows unordered double array. 243 * This is not a bug, added javadoc to emphasize the use of limit 244 * array must be in ascending order. 245 */ Test4106660()246 public void Test4106660() 247 { 248 double[] limits = {3, 1, 2}; 249 String[] formats = {"Three", "One", "Two"}; 250 ChoiceFormat cf = new ChoiceFormat(limits, formats); 251 double d = 5.0; 252 String str = cf.format(d); 253 if (!str.equals("Two")) 254 errln("format(" + d + ") = " + cf.format(d)); 255 } 256 257 /* @bug 4111739 258 * MessageFormat is incorrectly serialized/deserialized. 259 */ Test4111739()260 public void Test4111739() 261 { 262 MessageFormat format1 = null; 263 MessageFormat format2 = null; 264 ObjectOutputStream ostream = null; 265 ByteArrayOutputStream baos = null; 266 ObjectInputStream istream = null; 267 268 try { 269 baos = new ByteArrayOutputStream(); 270 ostream = new ObjectOutputStream(baos); 271 } catch(IOException e) { 272 errln("Unexpected exception : " + e.getMessage()); 273 return; 274 } 275 276 try { 277 format1 = new MessageFormat("pattern{0}"); 278 ostream.writeObject(format1); 279 ostream.flush(); 280 281 byte bytes[] = baos.toByteArray(); 282 283 istream = new ObjectInputStream(new ByteArrayInputStream(bytes)); 284 format2 = (MessageFormat)istream.readObject(); 285 } catch(Exception e) { 286 errln("Unexpected exception : " + e.getMessage()); 287 } 288 289 if (!format1.equals(format2)) { 290 errln("MessageFormats before and after serialization are not" + 291 " equal\nformat1 = " + format1 + "(" + format1.toPattern() + ")\nformat2 = " + 292 format2 + "(" + format2.toPattern() + ")"); 293 } else { 294 logln("Serialization for MessageFormat is OK."); 295 } 296 } 297 /* @bug 4114743 298 * MessageFormat.applyPattern allows illegal patterns. 299 */ Test4114743()300 public void Test4114743() 301 { 302 String originalPattern = "initial pattern"; 303 MessageFormat mf = new MessageFormat(originalPattern); 304 try { 305 String illegalPattern = "ab { '}' de"; 306 mf.applyPattern(illegalPattern); 307 errln("illegal pattern: \"" + illegalPattern + "\""); 308 } catch (IllegalArgumentException foo) { 309 if (!originalPattern.equals(mf.toPattern())) 310 errln("pattern after: \"" + mf.toPattern() + "\""); 311 } 312 } 313 314 /* @bug 4116444 315 * MessageFormat.parse has different behavior in case of null. 316 */ Test4116444()317 public void Test4116444() 318 { 319 String[] patterns = {"", "one", "{0,date,short}"}; 320 MessageFormat mf = new MessageFormat(""); 321 322 for (int i = 0; i < patterns.length; i++) { 323 String pattern = patterns[i]; 324 mf.applyPattern(pattern); 325 try { 326 Object[] array = mf.parse(null, new ParsePosition(0)); 327 logln("pattern: \"" + pattern + "\""); 328 log(" parsedObjects: "); 329 if (array != null) { 330 log("{"); 331 for (int j = 0; j < array.length; j++) { 332 if (array[j] != null) 333 err("\"" + array[j].toString() + "\""); 334 else 335 log("null"); 336 if (j < array.length - 1) log(","); 337 } 338 log("}") ; 339 } else { 340 log("null"); 341 } 342 logln(""); 343 } catch (Exception e) { 344 errln("pattern: \"" + pattern + "\""); 345 errln(" Exception: " + e.getMessage()); 346 } 347 } 348 349 } 350 /* @bug 4114739 (FIX and add javadoc) 351 * MessageFormat.format has undocumented behavior about empty format objects. 352 */ Test4114739()353 public void Test4114739() 354 { 355 356 MessageFormat mf = new MessageFormat("<{0}>"); 357 Object[] objs1 = null; 358 Object[] objs2 = {}; 359 Object[] objs3 = {null}; 360 try { 361 logln("pattern: \"" + mf.toPattern() + "\""); 362 log("format(null) : "); 363 logln("\"" + mf.format(objs1) + "\""); 364 log("format({}) : "); 365 logln("\"" + mf.format(objs2) + "\""); 366 log("format({null}) :"); 367 logln("\"" + mf.format(objs3) + "\""); 368 } catch (Exception e) { 369 errln("Exception thrown for null argument tests."); 370 } 371 } 372 373 /* @bug 4113018 374 * MessageFormat.applyPattern works wrong with illegal patterns. 375 */ Test4113018()376 public void Test4113018() 377 { 378 String originalPattern = "initial pattern"; 379 MessageFormat mf = new MessageFormat(originalPattern); 380 String illegalPattern = "format: {0, xxxYYY}"; 381 logln("pattern before: \"" + mf.toPattern() + "\""); 382 logln("illegal pattern: \"" + illegalPattern + "\""); 383 try { 384 mf.applyPattern(illegalPattern); 385 errln("Should have thrown IllegalArgumentException for pattern : " + illegalPattern); 386 } catch (IllegalArgumentException e) { 387 if (!originalPattern.equals(mf.toPattern())) 388 errln("pattern after: \"" + mf.toPattern() + "\""); 389 } 390 } 391 /* @bug 4106661 392 * ChoiceFormat is silent about the pattern usage in javadoc. 393 */ Test4106661()394 public void Test4106661() 395 { 396 ChoiceFormat fmt = new ChoiceFormat( 397 "-1#are negative| 0#are no or fraction | 1#is one |1.0<is 1+ |2#are two |2<are more than 2."); 398 logln("Formatter Pattern : " + fmt.toPattern()); 399 400 logln("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY)); 401 logln("Format with -1.0 : " + fmt.format(-1.0)); 402 logln("Format with 0 : " + fmt.format(0)); 403 logln("Format with 0.9 : " + fmt.format(0.9)); 404 logln("Format with 1.0 : " + fmt.format(1)); 405 logln("Format with 1.5 : " + fmt.format(1.5)); 406 logln("Format with 2 : " + fmt.format(2)); 407 logln("Format with 2.1 : " + fmt.format(2.1)); 408 logln("Format with NaN : " + fmt.format(Double.NaN)); 409 logln("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY)); 410 } 411 /* @bug 4094906 412 * ChoiceFormat should accept \u221E as eq. to INF. 413 */ Test4094906()414 public void Test4094906() 415 { 416 ChoiceFormat fmt = new ChoiceFormat( 417 "-\u221E<are negative|0<are no or fraction|1#is one|1.0<is 1+|\u221E<are many."); 418 if (!fmt.toPattern().startsWith("-\u221E<are negative|0.0<are no or fraction|1.0#is one|1.0<is 1+|\u221E<are many.")) 419 errln("Formatter Pattern : " + fmt.toPattern()); 420 logln("Format with -INF : " + fmt.format(Double.NEGATIVE_INFINITY)); 421 logln("Format with -1.0 : " + fmt.format(-1.0)); 422 logln("Format with 0 : " + fmt.format(0)); 423 logln("Format with 0.9 : " + fmt.format(0.9)); 424 logln("Format with 1.0 : " + fmt.format(1)); 425 logln("Format with 1.5 : " + fmt.format(1.5)); 426 logln("Format with 2 : " + fmt.format(2)); 427 logln("Format with +INF : " + fmt.format(Double.POSITIVE_INFINITY)); 428 } 429 430 /* @bug 4118592 431 * MessageFormat.parse fails with ChoiceFormat. 432 */ Test4118592()433 public void Test4118592() 434 { 435 MessageFormat mf = new MessageFormat(""); 436 String pattern = "{0,choice,1#YES|2#NO}"; 437 String prefix = ""; 438 for (int i = 0; i < 5; i++) { 439 String formatted = prefix + "YES"; 440 mf.applyPattern(prefix + pattern); 441 prefix += "x"; 442 Object[] objs = mf.parse(formatted, new ParsePosition(0)); 443 logln(i + ". pattern :\"" + mf.toPattern() + "\""); 444 log(" \"" + formatted + "\" parsed as "); 445 if (objs == null) logln(" null"); 446 else logln(" " + objs[0]); 447 } 448 } 449 /* @bug 4118594 450 * MessageFormat.parse fails for some patterns. 451 */ Test4118594()452 public void Test4118594() 453 { 454 MessageFormat mf = new MessageFormat("{0}, {0}, {0}"); 455 String forParsing = "x, y, z"; 456 Object[] objs = mf.parse(forParsing, new ParsePosition(0)); 457 logln("pattern: \"" + mf.toPattern() + "\""); 458 logln("text for parsing: \"" + forParsing + "\""); 459 if (!objs[0].toString().equals("z")) 460 errln("argument0: \"" + objs[0] + "\""); 461 mf.setLocale(Locale.US); 462 mf.applyPattern("{0,number,#.##}, {0,number,#.#}"); 463 Object[] oldobjs = {3.1415}; 464 String result = mf.format( oldobjs ); 465 logln("pattern: \"" + mf.toPattern() + "\""); 466 logln("text for parsing: \"" + result + "\""); 467 // result now equals "3.14, 3.1" 468 if (!result.equals("3.14, 3.1")) 469 errln("result = " + result); 470 Object[] newobjs = mf.parse(result, new ParsePosition(0)); 471 // newobjs now equals {new Double(3.1)} 472 if (((Double)newobjs[0]).doubleValue() != 3.1) 473 errln( "newobjs[0] = " + newobjs[0]); 474 } 475 /* @bug 4105380 476 * When using ChoiceFormat, MessageFormat is not good for I18n. 477 */ Test4105380()478 public void Test4105380() 479 { 480 String patternText1 = "The disk \"{1}\" contains {0}."; 481 String patternText2 = "There are {0} on the disk \"{1}\""; 482 MessageFormat form1 = new MessageFormat(patternText1); 483 MessageFormat form2 = new MessageFormat(patternText2); 484 double[] filelimits = {0,1,2}; 485 String[] filepart = {"no files","one file","{0,number} files"}; 486 ChoiceFormat fileform = new ChoiceFormat(filelimits, filepart); 487 form1.setFormat(1, fileform); 488 form2.setFormat(0, fileform); 489 Object[] testArgs = {12373L, "MyDisk"}; 490 logln(form1.format(testArgs)); 491 logln(form2.format(testArgs)); 492 } 493 /* @bug 4120552 494 * MessageFormat.parse incorrectly sets errorIndex. 495 */ Test4120552()496 public void Test4120552() 497 { 498 MessageFormat mf = new MessageFormat("pattern"); 499 String texts[] = {"pattern", "pat", "1234"}; 500 logln("pattern: \"" + mf.toPattern() + "\""); 501 for (int i = 0; i < texts.length; i++) { 502 ParsePosition pp = new ParsePosition(0); 503 Object[] objs = mf.parse(texts[i], pp); 504 log(" text for parsing: \"" + texts[i] + "\""); 505 if (objs == null) { 506 logln(" (incorrectly formatted string)"); 507 if (pp.getErrorIndex() == -1) 508 errln("Incorrect error index: " + pp.getErrorIndex()); 509 } else { 510 logln(" (correctly formatted string)"); 511 } 512 } 513 } 514 515 /** 516 * @bug 4142938 517 * MessageFormat handles single quotes in pattern wrong. 518 * This is actually a problem in ChoiceFormat; it doesn't 519 * understand single quotes. 520 */ Test4142938()521 public void Test4142938() { 522 String pat = "''Vous'' {0,choice,0#n''|1#}avez s\u00E9lectionne\u00E9 " + 523 "{0,choice,0#aucun|1#{0}} client{0,choice,0#s|1#|2#s} " + 524 "personnel{0,choice,0#s|1#|2#s}."; 525 MessageFormat mf = new MessageFormat(pat); 526 527 String[] PREFIX = { 528 "'Vous' n'avez s\u00E9lectionne\u00E9 aucun clients personnels.", 529 "'Vous' avez s\u00E9lectionne\u00E9 ", 530 "'Vous' avez s\u00E9lectionne\u00E9 " 531 }; 532 String[] SUFFIX = { 533 null, 534 " client personnel.", 535 " clients personnels." 536 }; 537 538 for (int i=0; i<3; i++) { 539 String out = mf.format(new Object[]{i}); 540 if (SUFFIX[i] == null) { 541 if (!out.equals(PREFIX[i])) 542 errln("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\""); 543 } 544 else { 545 if (!out.startsWith(PREFIX[i]) || 546 !out.endsWith(SUFFIX[i])) 547 errln("" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"...\"" + 548 SUFFIX[i] + "\""); 549 } 550 } 551 } 552 553 /** 554 * @bug 4142938 555 * Test the applyPattern and toPattern handling of single quotes 556 * by ChoiceFormat. (This is in here because this was a bug reported 557 * against MessageFormat.) The single quote is used to quote the 558 * pattern characters '|', '#', '<', and '\u2264'. Two quotes in a row 559 * is a quote literal. 560 */ TestChoicePatternQuote()561 public void TestChoicePatternQuote() { 562 String[] DATA = { 563 // Pattern 0 value 1 value 564 "0#can''t|1#can", "can't", "can", 565 "0#'pound(#)=''#'''|1#xyz", "pound(#)='#'", "xyz", 566 "0#'1<2 | 1\u22641'|1#''", "1<2 | 1\u22641", "'", 567 }; 568 for (int i=0; i<DATA.length; i+=3) { 569 try { 570 ChoiceFormat cf = new ChoiceFormat(DATA[i]); 571 for (int j=0; j<=1; ++j) { 572 String out = cf.format(j); 573 if (!out.equals(DATA[i+1+j])) 574 errln("Fail: Pattern \"" + DATA[i] + "\" x "+j+" -> " + 575 out + "; want \"" + DATA[i+1+j] + '"'); 576 } 577 String pat = cf.toPattern(); 578 String pat2 = new ChoiceFormat(pat).toPattern(); 579 if (!pat.equals(pat2)) 580 errln("Fail: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"'); 581 else 582 logln("Ok: Pattern \"" + DATA[i] + "\" x toPattern -> \"" + pat + '"'); 583 } 584 catch (IllegalArgumentException e) { 585 errln("Fail: Pattern \"" + DATA[i] + "\" -> " + e); 586 } 587 } 588 } 589 590 /** 591 * @bug 4112104 592 * MessageFormat.equals(null) throws a NullPointerException. The JLS states 593 * that it should return false. 594 */ Test4112104()595 public void Test4112104() { 596 MessageFormat format = new MessageFormat(""); 597 try { 598 // This should NOT throw an exception 599 if (format.equals(null)) { 600 // It also should return false 601 errln("MessageFormat.equals(null) returns false"); 602 } 603 } 604 catch (NullPointerException e) { 605 errln("MessageFormat.equals(null) throws " + e); 606 } 607 } 608 609 /** 610 * @bug 4169959 611 * MessageFormat does not format null objects. CANNOT REPRODUCE THIS BUG. 612 */ Test4169959()613 public void Test4169959() { 614 // This works 615 logln(MessageFormat.format( "This will {0}", "work")); 616 617 // This fails 618 logln(MessageFormat.format( "This will {0}", 619 new Object[]{ null } ) ); 620 } 621 test4232154()622 public void test4232154() { 623 boolean gotException = false; 624 try { 625 MessageFormat format = new MessageFormat("The date is {0:date}"); 626 } catch (Exception e) { 627 gotException = true; 628 if (!(e instanceof IllegalArgumentException)) { 629 throw new RuntimeException("got wrong exception type"); 630 } 631 if ("argument number too large at ".equals(e.getMessage())) { 632 throw new RuntimeException("got wrong exception message"); 633 } 634 } 635 if (!gotException) { 636 throw new RuntimeException("didn't get exception for invalid input"); 637 } 638 } 639 test4293229()640 public void test4293229() { 641 MessageFormat format = new MessageFormat("'''{'0}'' '''{0}'''"); 642 Object[] args = { null }; 643 String expected = "'{0}' '{0}'"; 644 String result = format.format(args); 645 if (!result.equals(expected)) { 646 throw new RuntimeException("wrong format result - expected \"" + 647 expected + "\", got \"" + result + "\""); 648 } 649 } 650 651 /** 652 * @bug 8187551 653 * test MessageFormat.setFormat() method to throw AIOOBE on invalid index. 654 */ test8187551()655 public void test8187551() { 656 //invalid cases ("pattern", "invalid format element index") 657 String[][] invalidCases = {{"The disk \"{1}\" contains {0}.", "2"}, 658 {"The disk \"{1}\" contains {0}.", "9"}, 659 {"On {1}, there are {0} and {2} folders", "3"}}; 660 661 //invalid cases (must throw exception) 662 Arrays.stream(invalidCases).forEach(entry -> messageSetFormat(entry[0], 663 Integer.valueOf(entry[1]))); 664 } 665 666 // test MessageFormat.setFormat() method for the given pattern and 667 // format element index messageSetFormat(String pattern, int elemIndex)668 private void messageSetFormat(String pattern, int elemIndex) { 669 MessageFormat form = new MessageFormat(pattern); 670 671 double[] fileLimits = {0, 1, 2}; 672 String[] filePart = {"no files", "one file", "{0,number} files"}; 673 ChoiceFormat fileForm = new ChoiceFormat(fileLimits, filePart); 674 675 boolean AIOOBEThrown = false; 676 try { 677 form.setFormat(elemIndex, fileForm); 678 } catch (ArrayIndexOutOfBoundsException ex) { 679 AIOOBEThrown = true; 680 } 681 682 if (!AIOOBEThrown) { 683 throw new RuntimeException("[FAILED: Must throw" + 684 " ArrayIndexOutOfBoundsException for" + 685 " invalid index " + elemIndex + " used in" + 686 " MessageFormat.setFormat(index, format)]"); 687 } 688 } 689 690 } 691