1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ******************************************************************************* 5 * Copyright (C) 2014-2016, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ******************************************************************************* 8 */ 9 package com.ibm.icu.dev.test.util; 10 11 import org.junit.Test; 12 import org.junit.runner.RunWith; 13 import org.junit.runners.JUnit4; 14 15 import com.ibm.icu.dev.test.TestFmwk; 16 import com.ibm.icu.text.MessageFormat; 17 import com.ibm.icu.text.SimpleFormatter; 18 import com.ibm.icu.util.ULocale; 19 20 @RunWith(JUnit4.class) 21 public class SimpleFormatterTest extends TestFmwk { 22 23 /** 24 * Constructor 25 */ 26 public SimpleFormatterTest() 27 { 28 } 29 30 // public methods ----------------------------------------------- 31 32 @Test 33 public void TestWithNoArguments() { 34 SimpleFormatter fmt = SimpleFormatter.compile("This doesn''t have templates '{0}"); 35 assertEquals( 36 "getArgumentLimit", 37 0, 38 fmt.getArgumentLimit()); 39 assertEquals( 40 "format", 41 "This doesn't have templates {0}", 42 fmt.format("unused")); 43 assertEquals( 44 "format with values=null", 45 "This doesn't have templates {0}", 46 fmt.format((CharSequence[])null)); 47 assertEquals( 48 "toString", 49 "This doesn't have templates {0}", 50 fmt.toString()); 51 int[] offsets = new int[1]; 52 assertEquals( 53 "formatAndAppend", 54 "This doesn't have templates {0}", 55 fmt.formatAndAppend(new StringBuilder(), offsets).toString()); 56 assertEquals( 57 "offsets[0]", 58 -1, 59 offsets[0]); 60 assertEquals( 61 "formatAndAppend with values=null", 62 "This doesn't have templates {0}", 63 fmt.formatAndAppend(new StringBuilder(), null, (CharSequence[])null).toString()); 64 assertEquals( 65 "formatAndReplace with values=null", 66 "This doesn't have templates {0}", 67 fmt.formatAndReplace(new StringBuilder(), null, (CharSequence[])null).toString()); 68 } 69 70 @Test 71 public void TestSyntaxErrors() { 72 try { 73 SimpleFormatter.compile("{}"); 74 fail("Syntax error did not yield an exception."); 75 } catch (IllegalArgumentException expected) { 76 } 77 try { 78 SimpleFormatter.compile("{12d"); 79 fail("Syntax error did not yield an exception."); 80 } catch (IllegalArgumentException expected) { 81 } 82 } 83 84 @Test 85 public void TestOneArgument() { 86 assertEquals("TestOneArgument", 87 "1 meter", 88 SimpleFormatter.compile("{0} meter").format("1")); 89 } 90 91 @Test 92 public void TestBigArgument() { 93 SimpleFormatter fmt = SimpleFormatter.compile("a{20}c"); 94 assertEquals("{20} count", 21, fmt.getArgumentLimit()); 95 CharSequence[] values = new CharSequence[21]; 96 values[20] = "b"; 97 assertEquals("{20}=b", "abc", fmt.format(values)); 98 } 99 100 @Test 101 public void TestGetTextWithNoArguments() { 102 assertEquals( 103 "", 104 "Templates and are here.", 105 SimpleFormatter.compile( 106 "Templates {1}{2} and {3} are here.").getTextWithNoArguments()); 107 } 108 109 @Test 110 public void TestTooFewArgumentValues() { 111 SimpleFormatter fmt = SimpleFormatter.compile( 112 "Templates {2}{1} and {4} are out of order."); 113 try { 114 fmt.format("freddy", "tommy", "frog", "leg"); 115 fail("Expected IllegalArgumentException"); 116 } catch (IllegalArgumentException e) { 117 // Expected 118 } 119 try { 120 fmt.formatAndAppend( 121 new StringBuilder(), null, "freddy", "tommy", "frog", "leg"); 122 fail("Expected IllegalArgumentException"); 123 } catch (IllegalArgumentException e) { 124 // Expected 125 } 126 try { 127 fmt.formatAndReplace( 128 new StringBuilder(), null, "freddy", "tommy", "frog", "leg"); 129 fail("Expected IllegalArgumentException"); 130 } catch (IllegalArgumentException e) { 131 // Expected 132 } 133 } 134 135 @Test 136 public void TestWithArguments() { 137 SimpleFormatter fmt = SimpleFormatter.compile( 138 "Templates {2}{1} and {4} are out of order."); 139 assertEquals( 140 "getArgumentLimit", 141 5, 142 fmt.getArgumentLimit()); 143 assertEquals( 144 "toString", 145 "Templates {2}{1} and {4} are out of order.", 146 fmt.toString()); 147 int[] offsets = new int[6]; 148 assertEquals( 149 "format", 150 "123456: Templates frogtommy and {0} are out of order.", 151 fmt.formatAndAppend( 152 new StringBuilder("123456: "), 153 offsets, 154 "freddy", "tommy", "frog", "leg", "{0}").toString()); 155 156 int[] expectedOffsets = {-1, 22, 18, -1, 32, -1}; 157 verifyOffsets(expectedOffsets, offsets); 158 } 159 160 @Test 161 public void TestFormatUseAppendToAsArgument() { 162 SimpleFormatter fmt = SimpleFormatter.compile( 163 "Arguments {0} and {1}"); 164 StringBuilder appendTo = new StringBuilder("previous:"); 165 try { 166 fmt.formatAndAppend(appendTo, null, appendTo, "frog"); 167 fail("IllegalArgumentException expected."); 168 } catch (IllegalArgumentException e) { 169 // expected. 170 } 171 } 172 173 @Test 174 public void TestFormatReplaceNoOptimization() { 175 SimpleFormatter fmt = SimpleFormatter.compile("{2}, {0}, {1} and {3}"); 176 int[] offsets = new int[4]; 177 StringBuilder result = new StringBuilder("original"); 178 assertEquals( 179 "format", 180 "frog, original, freddy and by", 181 fmt.formatAndReplace( 182 result, 183 offsets, 184 result, "freddy", "frog", "by").toString()); 185 186 int[] expectedOffsets = {6, 16, 0, 27}; 187 verifyOffsets(expectedOffsets, offsets); 188 } 189 190 191 @Test 192 public void TestFormatReplaceNoOptimizationLeadingText() { 193 SimpleFormatter fmt = SimpleFormatter.compile("boo {2}, {0}, {1} and {3}"); 194 int[] offsets = new int[4]; 195 StringBuilder result = new StringBuilder("original"); 196 assertEquals( 197 "format", 198 "boo original, freddy, frog and by", 199 fmt.formatAndReplace( 200 result, 201 offsets, 202 "freddy", "frog", result, "by").toString()); 203 204 int[] expectedOffsets = {14, 22, 4, 31}; 205 verifyOffsets(expectedOffsets, offsets); 206 } 207 208 @Test 209 public void TestFormatReplaceOptimization() { 210 SimpleFormatter fmt = SimpleFormatter.compile("{2}, {0}, {1} and {3}"); 211 int[] offsets = new int[4]; 212 StringBuilder result = new StringBuilder("original"); 213 assertEquals( 214 "format", 215 "original, freddy, frog and by", 216 fmt.formatAndReplace( 217 result, 218 offsets, 219 "freddy", "frog", result, "by").toString()); 220 221 int[] expectedOffsets = {10, 18, 0, 27}; 222 verifyOffsets(expectedOffsets, offsets); 223 } 224 225 @Test 226 public void TestFormatReplaceOptimizationNoOffsets() { 227 SimpleFormatter fmt = SimpleFormatter.compile("{2}, {0}, {1} and {3}"); 228 StringBuilder result = new StringBuilder("original"); 229 assertEquals( 230 "format", 231 "original, freddy, frog and by", 232 fmt.formatAndReplace( 233 result, 234 null, 235 "freddy", "frog", result, "by").toString()); 236 237 } 238 239 @Test 240 public void TestFormatReplaceNoOptimizationNoOffsets() { 241 SimpleFormatter fmt = SimpleFormatter.compile( 242 "Arguments {0} and {1}"); 243 StringBuilder result = new StringBuilder("previous:"); 244 assertEquals( 245 "", 246 "Arguments previous: and frog", 247 fmt.formatAndReplace(result, null, result, "frog").toString()); 248 } 249 250 @Test 251 public void TestFormatReplaceNoOptimizationLeadingArgumentUsedTwice() { 252 SimpleFormatter fmt = SimpleFormatter.compile( 253 "{2}, {0}, {1} and {3} {2}"); 254 StringBuilder result = new StringBuilder("original"); 255 int[] offsets = new int[4]; 256 assertEquals( 257 "", 258 "original, freddy, frog and by original", 259 fmt.formatAndReplace( 260 result, 261 offsets, 262 "freddy", "frog", result, "by").toString()); 263 int[] expectedOffsets = {10, 18, 30, 27}; 264 verifyOffsets(expectedOffsets, offsets); 265 } 266 267 @Test 268 public void TestQuotingLikeMessageFormat() { 269 String pattern = "{0} don't can''t '{5}''}{a' again '}'{1} to the '{end"; 270 SimpleFormatter spf = SimpleFormatter.compile(pattern); 271 MessageFormat mf = new MessageFormat(pattern, ULocale.ROOT); 272 String expected = "X don't can't {5}'}{a again }Y to the {end"; 273 assertEquals("MessageFormat", expected, mf.format(new Object[] { "X", "Y" })); 274 assertEquals("SimpleFormatter", expected, spf.format("X", "Y")); 275 } 276 277 private void verifyOffsets(int[] expected, int[] actual) { 278 for (int i = 0; i < expected.length; ++i) { 279 if (expected[i] != actual[i]) { 280 errln("Expected "+expected[i]+", got " + actual[i]); 281 } 282 } 283 } 284 285 } 286