]>
Commit | Line | Data |
---|---|---|
57a6839d A |
1 | /* |
2 | ******************************************************************************* | |
3 | * Copyright (C) 2014, International Business Machines Corporation and * | |
4 | * others. All Rights Reserved. * | |
5 | ******************************************************************************* | |
6 | * | |
7 | * File SIMPLEPATTERNFORMATTERTEST.CPP | |
8 | * | |
9 | ******************************************************************************** | |
10 | */ | |
11 | #include "cstring.h" | |
12 | #include "intltest.h" | |
13 | #include "simplepatternformatter.h" | |
14 | ||
57a6839d A |
15 | class SimplePatternFormatterTest : public IntlTest { |
16 | public: | |
17 | SimplePatternFormatterTest() { | |
18 | } | |
19 | void TestNoPlaceholders(); | |
20 | void TestOnePlaceholder(); | |
21 | void TestManyPlaceholders(); | |
b331163b A |
22 | void TestTooFewPlaceholderValues(); |
23 | void TestBadArguments(); | |
24 | void TestGetPatternWithNoPlaceholders(); | |
25 | void TestFormatReplaceNoOptimization(); | |
26 | void TestFormatReplaceNoOptimizationLeadingText(); | |
27 | void TestFormatReplaceOptimization(); | |
28 | void TestFormatReplaceNoOptimizationLeadingPlaceholderUsedTwice(); | |
29 | void TestFormatReplaceOptimizationNoOffsets(); | |
30 | void TestFormatReplaceNoOptimizationNoOffsets(); | |
57a6839d A |
31 | void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0); |
32 | private: | |
b331163b A |
33 | void verifyOffsets( |
34 | const int32_t *expected, | |
35 | const int32_t *actual, | |
36 | int32_t count); | |
57a6839d A |
37 | }; |
38 | ||
39 | void SimplePatternFormatterTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/) { | |
40 | TESTCASE_AUTO_BEGIN; | |
41 | TESTCASE_AUTO(TestNoPlaceholders); | |
42 | TESTCASE_AUTO(TestOnePlaceholder); | |
43 | TESTCASE_AUTO(TestManyPlaceholders); | |
b331163b A |
44 | TESTCASE_AUTO(TestTooFewPlaceholderValues); |
45 | TESTCASE_AUTO(TestBadArguments); | |
46 | TESTCASE_AUTO(TestGetPatternWithNoPlaceholders); | |
47 | TESTCASE_AUTO(TestFormatReplaceNoOptimization); | |
48 | TESTCASE_AUTO(TestFormatReplaceNoOptimizationLeadingText); | |
49 | TESTCASE_AUTO(TestFormatReplaceOptimization); | |
50 | TESTCASE_AUTO(TestFormatReplaceNoOptimizationLeadingPlaceholderUsedTwice); | |
51 | TESTCASE_AUTO(TestFormatReplaceOptimizationNoOffsets); | |
52 | TESTCASE_AUTO(TestFormatReplaceNoOptimizationNoOffsets); | |
57a6839d A |
53 | TESTCASE_AUTO_END; |
54 | } | |
55 | ||
56 | void SimplePatternFormatterTest::TestNoPlaceholders() { | |
57 | UErrorCode status = U_ZERO_ERROR; | |
58 | SimplePatternFormatter fmt("This doesn''t have templates '{0}"); | |
59 | assertEquals("PlaceholderCount", 0, fmt.getPlaceholderCount()); | |
60 | UnicodeString appendTo; | |
61 | assertEquals( | |
b331163b | 62 | "format", |
57a6839d A |
63 | "This doesn't have templates {0}", |
64 | fmt.format("unused", appendTo, status)); | |
65 | fmt.compile("This has {} bad {012d placeholders", status); | |
66 | assertEquals("PlaceholderCount", 0, fmt.getPlaceholderCount()); | |
67 | appendTo.remove(); | |
68 | assertEquals( | |
b331163b | 69 | "format", |
57a6839d A |
70 | "This has {} bad {012d placeholders", |
71 | fmt.format("unused", appendTo, status)); | |
72 | assertSuccess("Status", status); | |
73 | } | |
74 | ||
75 | void SimplePatternFormatterTest::TestOnePlaceholder() { | |
76 | UErrorCode status = U_ZERO_ERROR; | |
77 | SimplePatternFormatter fmt; | |
78 | fmt.compile("{0} meter", status); | |
b331163b A |
79 | if (!assertSuccess("Status", status)) { |
80 | return; | |
81 | } | |
57a6839d A |
82 | assertEquals("PlaceholderCount", 1, fmt.getPlaceholderCount()); |
83 | UnicodeString appendTo; | |
84 | assertEquals( | |
b331163b | 85 | "format", |
57a6839d A |
86 | "1 meter", |
87 | fmt.format("1", appendTo, status)); | |
57a6839d A |
88 | |
89 | // assignment | |
90 | SimplePatternFormatter s; | |
91 | s = fmt; | |
92 | appendTo.remove(); | |
93 | assertEquals( | |
94 | "Assignment", | |
95 | "1 meter", | |
96 | s.format("1", appendTo, status)); | |
97 | ||
98 | // Copy constructor | |
99 | SimplePatternFormatter r(fmt); | |
100 | appendTo.remove(); | |
101 | assertEquals( | |
102 | "Copy constructor", | |
103 | "1 meter", | |
104 | r.format("1", appendTo, status)); | |
105 | assertSuccess("Status", status); | |
106 | } | |
107 | ||
108 | void SimplePatternFormatterTest::TestManyPlaceholders() { | |
109 | UErrorCode status = U_ZERO_ERROR; | |
110 | SimplePatternFormatter fmt; | |
111 | fmt.compile( | |
112 | "Templates {2}{1}{5} and {4} are out of order.", status); | |
b331163b A |
113 | if (!assertSuccess("Status", status)) { |
114 | return; | |
115 | } | |
57a6839d A |
116 | assertEquals("PlaceholderCount", 6, fmt.getPlaceholderCount()); |
117 | UnicodeString values[] = { | |
118 | "freddy", "tommy", "frog", "billy", "leg", "{0}"}; | |
119 | UnicodeString *params[] = { | |
120 | &values[0], &values[1], &values[2], &values[3], &values[4], &values[5]}; | |
121 | int32_t offsets[6]; | |
122 | int32_t expectedOffsets[6] = {-1, 22, 18, -1, 35, 27}; | |
123 | UnicodeString appendTo("Prefix: "); | |
124 | assertEquals( | |
b331163b | 125 | "format", |
57a6839d | 126 | "Prefix: Templates frogtommy{0} and leg are out of order.", |
b331163b | 127 | fmt.formatAndAppend( |
57a6839d | 128 | params, |
b331163b | 129 | UPRV_LENGTHOF(params), |
57a6839d A |
130 | appendTo, |
131 | offsets, | |
b331163b | 132 | UPRV_LENGTHOF(offsets), |
57a6839d | 133 | status)); |
b331163b A |
134 | if (!assertSuccess("Status", status)) { |
135 | return; | |
57a6839d | 136 | } |
b331163b | 137 | verifyOffsets(expectedOffsets, offsets, UPRV_LENGTHOF(expectedOffsets)); |
57a6839d | 138 | appendTo.remove(); |
b331163b A |
139 | |
140 | // Ensure we don't write to offsets array beyond its length. | |
57a6839d | 141 | status = U_ZERO_ERROR; |
b331163b | 142 | offsets[UPRV_LENGTHOF(offsets) - 1] = 289; |
57a6839d | 143 | appendTo.remove(); |
b331163b | 144 | fmt.formatAndAppend( |
57a6839d | 145 | params, |
b331163b | 146 | UPRV_LENGTHOF(params), |
57a6839d A |
147 | appendTo, |
148 | offsets, | |
b331163b | 149 | UPRV_LENGTHOF(offsets) - 1, |
57a6839d | 150 | status); |
b331163b | 151 | assertEquals("Offsets buffer length", 289, offsets[UPRV_LENGTHOF(offsets) - 1]); |
57a6839d A |
152 | |
153 | // Test assignment | |
154 | SimplePatternFormatter s; | |
155 | s = fmt; | |
156 | appendTo.remove(); | |
157 | assertEquals( | |
158 | "Assignment", | |
159 | "Templates frogtommy{0} and leg are out of order.", | |
b331163b | 160 | s.formatAndAppend( |
57a6839d | 161 | params, |
b331163b | 162 | UPRV_LENGTHOF(params), |
57a6839d A |
163 | appendTo, |
164 | NULL, | |
165 | 0, | |
166 | status)); | |
167 | ||
168 | // Copy constructor | |
169 | SimplePatternFormatter r(fmt); | |
170 | appendTo.remove(); | |
171 | assertEquals( | |
172 | "Copy constructor", | |
173 | "Templates frogtommy{0} and leg are out of order.", | |
b331163b | 174 | r.formatAndAppend( |
57a6839d | 175 | params, |
b331163b | 176 | UPRV_LENGTHOF(params), |
57a6839d A |
177 | appendTo, |
178 | NULL, | |
179 | 0, | |
180 | status)); | |
181 | r.compile("{0} meter", status); | |
182 | assertEquals("PlaceholderCount", 1, r.getPlaceholderCount()); | |
183 | appendTo.remove(); | |
184 | assertEquals( | |
185 | "Replace with new compile", | |
186 | "freddy meter", | |
187 | r.format("freddy", appendTo, status)); | |
188 | r.compile("{0}, {1}", status); | |
189 | assertEquals("PlaceholderCount", 2, r.getPlaceholderCount()); | |
190 | appendTo.remove(); | |
191 | assertEquals( | |
192 | "2 arg", | |
193 | "foo, bar", | |
194 | r.format("foo", "bar", appendTo, status)); | |
195 | r.compile("{0}, {1} and {2}", status); | |
196 | assertEquals("PlaceholderCount", 3, r.getPlaceholderCount()); | |
197 | appendTo.remove(); | |
198 | assertEquals( | |
199 | "3 arg", | |
200 | "foo, bar and baz", | |
201 | r.format("foo", "bar", "baz", appendTo, status)); | |
202 | assertSuccess("Status", status); | |
203 | } | |
204 | ||
b331163b A |
205 | void SimplePatternFormatterTest::TestTooFewPlaceholderValues() { |
206 | SimplePatternFormatter fmt("{0} and {1}"); | |
207 | UnicodeString appendTo; | |
208 | UnicodeString firstValue; | |
209 | UnicodeString *params[] = {&firstValue}; | |
210 | ||
211 | UErrorCode status = U_ZERO_ERROR; | |
212 | fmt.format( | |
213 | firstValue, appendTo, status); | |
214 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
215 | errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); | |
216 | } | |
217 | ||
218 | status = U_ZERO_ERROR; | |
219 | fmt.formatAndAppend( | |
220 | params, UPRV_LENGTHOF(params), appendTo, NULL, 0, status); | |
221 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
222 | errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); | |
223 | } | |
224 | ||
225 | status = U_ZERO_ERROR; | |
226 | fmt.formatAndReplace( | |
227 | params, UPRV_LENGTHOF(params), appendTo, NULL, 0, status); | |
228 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
229 | errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); | |
230 | } | |
231 | } | |
232 | ||
233 | void SimplePatternFormatterTest::TestBadArguments() { | |
234 | SimplePatternFormatter fmt("pickle"); | |
235 | UnicodeString appendTo; | |
236 | UErrorCode status = U_ZERO_ERROR; | |
237 | ||
238 | // These succeed | |
239 | fmt.formatAndAppend( | |
240 | NULL, 0, appendTo, NULL, 0, status); | |
241 | fmt.formatAndReplace( | |
242 | NULL, 0, appendTo, NULL, 0, status); | |
243 | assertSuccess("", status); | |
244 | status = U_ZERO_ERROR; | |
245 | ||
246 | // fails | |
247 | fmt.formatAndAppend( | |
248 | NULL, 1, appendTo, NULL, 0, status); | |
249 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
250 | errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); | |
251 | } | |
252 | status = U_ZERO_ERROR; | |
253 | ||
254 | // fails | |
255 | fmt.formatAndAppend( | |
256 | NULL, 0, appendTo, NULL, 1, status); | |
257 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
258 | errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); | |
259 | } | |
260 | status = U_ZERO_ERROR; | |
261 | ||
262 | // fails because appendTo used as a parameter value | |
263 | const UnicodeString *params[] = {&appendTo}; | |
264 | fmt.formatAndAppend( | |
265 | params, UPRV_LENGTHOF(params), appendTo, NULL, 0, status); | |
266 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
267 | errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); | |
268 | } | |
269 | status = U_ZERO_ERROR; | |
270 | ||
271 | ||
272 | // fails | |
273 | fmt.formatAndReplace( | |
274 | NULL, 1, appendTo, NULL, 0, status); | |
275 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
276 | errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); | |
277 | } | |
278 | status = U_ZERO_ERROR; | |
279 | ||
280 | // fails | |
281 | fmt.formatAndReplace( | |
282 | NULL, 0, appendTo, NULL, 1, status); | |
283 | if (status != U_ILLEGAL_ARGUMENT_ERROR) { | |
284 | errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); | |
285 | } | |
286 | } | |
287 | ||
288 | void SimplePatternFormatterTest::TestGetPatternWithNoPlaceholders() { | |
289 | SimplePatternFormatter fmt("{0} has no {1} placeholders."); | |
290 | assertEquals( | |
291 | "", " has no placeholders.", fmt.getPatternWithNoPlaceholders()); | |
292 | } | |
293 | ||
294 | void SimplePatternFormatterTest::TestFormatReplaceNoOptimization() { | |
295 | UErrorCode status = U_ZERO_ERROR; | |
296 | SimplePatternFormatter fmt; | |
297 | fmt.compile("{2}, {0}, {1} and {3}", status); | |
298 | if (!assertSuccess("Status", status)) { | |
299 | return; | |
300 | } | |
301 | UnicodeString result("original"); | |
302 | int offsets[4]; | |
303 | UnicodeString freddy("freddy"); | |
304 | UnicodeString frog("frog"); | |
305 | UnicodeString by("by"); | |
306 | const UnicodeString *params[] = {&result, &freddy, &frog, &by}; | |
307 | assertEquals( | |
308 | "", | |
309 | "frog, original, freddy and by", | |
310 | fmt.formatAndReplace( | |
311 | params, | |
312 | UPRV_LENGTHOF(params), | |
313 | result, | |
314 | offsets, | |
315 | UPRV_LENGTHOF(offsets), | |
316 | status)); | |
317 | if (!assertSuccess("Status", status)) { | |
318 | return; | |
319 | } | |
320 | int32_t expectedOffsets[] = {6, 16, 0, 27}; | |
321 | verifyOffsets(expectedOffsets, offsets, UPRV_LENGTHOF(expectedOffsets)); | |
322 | } | |
323 | ||
324 | void SimplePatternFormatterTest::TestFormatReplaceNoOptimizationLeadingText() { | |
325 | UErrorCode status = U_ZERO_ERROR; | |
326 | SimplePatternFormatter fmt; | |
327 | fmt.compile("boo {2}, {0}, {1} and {3}", status); | |
328 | if (!assertSuccess("Status", status)) { | |
329 | return; | |
330 | } | |
331 | UnicodeString result("original"); | |
332 | int offsets[4]; | |
333 | UnicodeString freddy("freddy"); | |
334 | UnicodeString frog("frog"); | |
335 | UnicodeString by("by"); | |
336 | const UnicodeString *params[] = {&freddy, &frog, &result, &by}; | |
337 | assertEquals( | |
338 | "", | |
339 | "boo original, freddy, frog and by", | |
340 | fmt.formatAndReplace( | |
341 | params, | |
342 | UPRV_LENGTHOF(params), | |
343 | result, | |
344 | offsets, | |
345 | UPRV_LENGTHOF(offsets), | |
346 | status)); | |
347 | if (!assertSuccess("Status", status)) { | |
348 | return; | |
349 | } | |
350 | int32_t expectedOffsets[] = {14, 22, 4, 31}; | |
351 | verifyOffsets(expectedOffsets, offsets, UPRV_LENGTHOF(expectedOffsets)); | |
352 | } | |
353 | ||
354 | void SimplePatternFormatterTest::TestFormatReplaceOptimization() { | |
355 | UErrorCode status = U_ZERO_ERROR; | |
356 | SimplePatternFormatter fmt; | |
357 | fmt.compile("{2}, {0}, {1} and {3}", status); | |
358 | if (!assertSuccess("Status", status)) { | |
359 | return; | |
360 | } | |
361 | UnicodeString result("original"); | |
362 | int offsets[4]; | |
363 | UnicodeString freddy("freddy"); | |
364 | UnicodeString frog("frog"); | |
365 | UnicodeString by("by"); | |
366 | const UnicodeString *params[] = {&freddy, &frog, &result, &by}; | |
367 | assertEquals( | |
368 | "", | |
369 | "original, freddy, frog and by", | |
370 | fmt.formatAndReplace( | |
371 | params, | |
372 | UPRV_LENGTHOF(params), | |
373 | result, | |
374 | offsets, | |
375 | UPRV_LENGTHOF(offsets), | |
376 | status)); | |
377 | if (!assertSuccess("Status", status)) { | |
378 | return; | |
379 | } | |
380 | int32_t expectedOffsets[] = {10, 18, 0, 27}; | |
381 | verifyOffsets(expectedOffsets, offsets, UPRV_LENGTHOF(expectedOffsets)); | |
382 | } | |
383 | ||
384 | void SimplePatternFormatterTest::TestFormatReplaceNoOptimizationLeadingPlaceholderUsedTwice() { | |
385 | UErrorCode status = U_ZERO_ERROR; | |
386 | SimplePatternFormatter fmt; | |
387 | fmt.compile("{2}, {0}, {1} and {3} {2}", status); | |
388 | if (!assertSuccess("Status", status)) { | |
389 | return; | |
390 | } | |
391 | UnicodeString result("original"); | |
392 | int offsets[4]; | |
393 | UnicodeString freddy("freddy"); | |
394 | UnicodeString frog("frog"); | |
395 | UnicodeString by("by"); | |
396 | const UnicodeString *params[] = {&freddy, &frog, &result, &by}; | |
397 | assertEquals( | |
398 | "", | |
399 | "original, freddy, frog and by original", | |
400 | fmt.formatAndReplace( | |
401 | params, | |
402 | UPRV_LENGTHOF(params), | |
403 | result, | |
404 | offsets, | |
405 | UPRV_LENGTHOF(offsets), | |
406 | status)); | |
407 | if (!assertSuccess("Status", status)) { | |
408 | return; | |
409 | } | |
410 | int32_t expectedOffsets[] = {10, 18, 30, 27}; | |
411 | verifyOffsets(expectedOffsets, offsets, UPRV_LENGTHOF(expectedOffsets)); | |
412 | } | |
413 | ||
414 | void SimplePatternFormatterTest::TestFormatReplaceOptimizationNoOffsets() { | |
415 | UErrorCode status = U_ZERO_ERROR; | |
416 | SimplePatternFormatter fmt; | |
417 | fmt.compile("{2}, {0}, {1} and {3}", status); | |
418 | if (!assertSuccess("Status", status)) { | |
419 | return; | |
420 | } | |
421 | UnicodeString result("original"); | |
422 | UnicodeString freddy("freddy"); | |
423 | UnicodeString frog("frog"); | |
424 | UnicodeString by("by"); | |
425 | const UnicodeString *params[] = {&freddy, &frog, &result, &by}; | |
426 | assertEquals( | |
427 | "", | |
428 | "original, freddy, frog and by", | |
429 | fmt.formatAndReplace( | |
430 | params, | |
431 | UPRV_LENGTHOF(params), | |
432 | result, | |
433 | NULL, | |
434 | 0, | |
435 | status)); | |
436 | assertSuccess("Status", status); | |
437 | } | |
438 | ||
439 | void SimplePatternFormatterTest::TestFormatReplaceNoOptimizationNoOffsets() { | |
440 | UErrorCode status = U_ZERO_ERROR; | |
441 | SimplePatternFormatter fmt("Placeholders {0} and {1}"); | |
442 | UnicodeString result("previous:"); | |
443 | UnicodeString frog("frog"); | |
444 | const UnicodeString *params[] = {&result, &frog}; | |
445 | assertEquals( | |
446 | "", | |
447 | "Placeholders previous: and frog", | |
448 | fmt.formatAndReplace( | |
449 | params, | |
450 | UPRV_LENGTHOF(params), | |
451 | result, | |
452 | NULL, | |
453 | 0, | |
454 | status)); | |
455 | assertSuccess("Status", status); | |
456 | } | |
457 | ||
458 | void SimplePatternFormatterTest::verifyOffsets( | |
459 | const int32_t *expected, const int32_t *actual, int32_t count) { | |
460 | for (int32_t i = 0; i < count; ++i) { | |
461 | if (expected[i] != actual[i]) { | |
462 | errln("Expected %d, got %d", expected[i], actual[i]); | |
463 | } | |
464 | } | |
465 | } | |
466 | ||
57a6839d A |
467 | extern IntlTest *createSimplePatternFormatterTest() { |
468 | return new SimplePatternFormatterTest(); | |
469 | } | |
b331163b | 470 |