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