2 ******************************************************************************* 
   3 * Copyright (C) 2014, International Business Machines Corporation and         * 
   4 * others. All Rights Reserved.                                                * 
   5 ******************************************************************************* 
   7 * File SIMPLEPATTERNFORMATTERTEST.CPP 
   9 ******************************************************************************** 
  13 #include "simplepatternformatter.h" 
  15 class SimplePatternFormatterTest 
: public IntlTest 
{ 
  17     SimplePatternFormatterTest() { 
  19     void TestNoPlaceholders(); 
  20     void TestOnePlaceholder(); 
  21     void TestManyPlaceholders(); 
  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(); 
  31     void runIndexedTest(int32_t index
, UBool exec
, const char *&name
, char *par
=0); 
  34             const int32_t *expected
, 
  35             const int32_t *actual
, 
  39 void SimplePatternFormatterTest::runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* /*par*/) { 
  41   TESTCASE_AUTO(TestNoPlaceholders
); 
  42   TESTCASE_AUTO(TestOnePlaceholder
); 
  43   TESTCASE_AUTO(TestManyPlaceholders
); 
  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
); 
  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
; 
  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()); 
  70             "This has {} bad {012d placeholders",  
  71             fmt
.format("unused", appendTo
, status
)); 
  72     assertSuccess("Status", status
); 
  75 void SimplePatternFormatterTest::TestOnePlaceholder() { 
  76     UErrorCode status 
= U_ZERO_ERROR
; 
  77     SimplePatternFormatter fmt
; 
  78     fmt
.compile("{0} meter", status
); 
  79     if (!assertSuccess("Status", status
)) { 
  82     assertEquals("PlaceholderCount", 1, fmt
.getPlaceholderCount()); 
  83     UnicodeString appendTo
; 
  87             fmt
.format("1", appendTo
, status
)); 
  90     SimplePatternFormatter s
; 
  96             s
.format("1", appendTo
, status
)); 
  99     SimplePatternFormatter 
r(fmt
); 
 104             r
.format("1", appendTo
, status
)); 
 105     assertSuccess("Status", status
); 
 108 void SimplePatternFormatterTest::TestManyPlaceholders() { 
 109     UErrorCode status 
= U_ZERO_ERROR
; 
 110     SimplePatternFormatter fmt
; 
 112             "Templates {2}{1}{5} and {4} are out of order.", status
); 
 113     if (!assertSuccess("Status", status
)) { 
 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]};  
 122     int32_t expectedOffsets
[6] = {-1, 22, 18, -1, 35, 27}; 
 123     UnicodeString 
appendTo("Prefix: "); 
 126             "Prefix: Templates frogtommy{0} and leg are out of order.", 
 129                     UPRV_LENGTHOF(params
), 
 132                     UPRV_LENGTHOF(offsets
), 
 134     if (!assertSuccess("Status", status
)) { 
 137     verifyOffsets(expectedOffsets
, offsets
, UPRV_LENGTHOF(expectedOffsets
)); 
 140     // Ensure we don't write to offsets array beyond its length. 
 141     status 
= U_ZERO_ERROR
; 
 142     offsets
[UPRV_LENGTHOF(offsets
) - 1] = 289; 
 146             UPRV_LENGTHOF(params
), 
 149             UPRV_LENGTHOF(offsets
) - 1, 
 151     assertEquals("Offsets buffer length", 289, offsets
[UPRV_LENGTHOF(offsets
) - 1]); 
 154     SimplePatternFormatter s
; 
 159             "Templates frogtommy{0} and leg are out of order.", 
 162                     UPRV_LENGTHOF(params
), 
 169     SimplePatternFormatter 
r(fmt
); 
 173             "Templates frogtommy{0} and leg are out of order.", 
 176                     UPRV_LENGTHOF(params
), 
 181     r
.compile("{0} meter", status
); 
 182     assertEquals("PlaceholderCount", 1, r
.getPlaceholderCount()); 
 185             "Replace with new compile", 
 187             r
.format("freddy", appendTo
, status
)); 
 188     r
.compile("{0}, {1}", status
); 
 189     assertEquals("PlaceholderCount", 2, r
.getPlaceholderCount()); 
 194             r
.format("foo", "bar", appendTo
, status
)); 
 195     r
.compile("{0}, {1} and {2}", status
); 
 196     assertEquals("PlaceholderCount", 3, r
.getPlaceholderCount()); 
 201             r
.format("foo", "bar", "baz", appendTo
, status
)); 
 202     assertSuccess("Status", status
); 
 205 void SimplePatternFormatterTest::TestTooFewPlaceholderValues() { 
 206     SimplePatternFormatter 
fmt("{0} and {1}"); 
 207     UnicodeString appendTo
; 
 208     UnicodeString firstValue
; 
 209     UnicodeString 
*params
[] = {&firstValue
}; 
 211     UErrorCode status 
= U_ZERO_ERROR
; 
 213             firstValue
, appendTo
, status
); 
 214     if (status 
!= U_ILLEGAL_ARGUMENT_ERROR
) { 
 215         errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); 
 218     status 
= U_ZERO_ERROR
; 
 220             params
, UPRV_LENGTHOF(params
), appendTo
, NULL
, 0, status
); 
 221     if (status 
!= U_ILLEGAL_ARGUMENT_ERROR
) { 
 222         errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); 
 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"); 
 233 void SimplePatternFormatterTest::TestBadArguments() { 
 234     SimplePatternFormatter 
fmt("pickle"); 
 235     UnicodeString appendTo
; 
 236     UErrorCode status 
= U_ZERO_ERROR
; 
 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
; 
 248             NULL
, 1, appendTo
, NULL
, 0, status
); 
 249     if (status 
!= U_ILLEGAL_ARGUMENT_ERROR
) { 
 250         errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); 
 252     status 
= U_ZERO_ERROR
; 
 256             NULL
, 0, appendTo
, NULL
, 1, status
); 
 257     if (status 
!= U_ILLEGAL_ARGUMENT_ERROR
) { 
 258         errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); 
 260     status 
= U_ZERO_ERROR
; 
 262     // fails because appendTo used as a parameter value 
 263     const UnicodeString 
*params
[] = {&appendTo
}; 
 265             params
, UPRV_LENGTHOF(params
), appendTo
, NULL
, 0, status
); 
 266     if (status 
!= U_ILLEGAL_ARGUMENT_ERROR
) { 
 267         errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); 
 269     status 
= U_ZERO_ERROR
; 
 273     fmt
.formatAndReplace( 
 274             NULL
, 1, appendTo
, NULL
, 0, status
); 
 275     if (status 
!= U_ILLEGAL_ARGUMENT_ERROR
) { 
 276         errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); 
 278     status 
= U_ZERO_ERROR
; 
 281     fmt
.formatAndReplace( 
 282             NULL
, 0, appendTo
, NULL
, 1, status
); 
 283     if (status 
!= U_ILLEGAL_ARGUMENT_ERROR
) { 
 284         errln("Expected U_ILLEGAL_ARGUMENT_ERROR"); 
 288 void SimplePatternFormatterTest::TestGetPatternWithNoPlaceholders() { 
 289     SimplePatternFormatter 
fmt("{0} has no {1} placeholders."); 
 291             "", " has no  placeholders.", fmt
.getPatternWithNoPlaceholders()); 
 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
)) { 
 301     UnicodeString 
result("original"); 
 303     UnicodeString 
freddy("freddy"); 
 304     UnicodeString 
frog("frog"); 
 305     UnicodeString 
by("by"); 
 306     const UnicodeString 
*params
[] = {&result
, &freddy
, &frog
, &by
}; 
 309             "frog, original, freddy and by", 
 310             fmt
.formatAndReplace( 
 312                     UPRV_LENGTHOF(params
), 
 315                     UPRV_LENGTHOF(offsets
), 
 317     if (!assertSuccess("Status", status
)) { 
 320     int32_t expectedOffsets
[] = {6, 16, 0, 27}; 
 321     verifyOffsets(expectedOffsets
, offsets
, UPRV_LENGTHOF(expectedOffsets
)); 
 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
)) { 
 331     UnicodeString 
result("original"); 
 333     UnicodeString 
freddy("freddy"); 
 334     UnicodeString 
frog("frog"); 
 335     UnicodeString 
by("by"); 
 336     const UnicodeString 
*params
[] = {&freddy
, &frog
, &result
, &by
}; 
 339             "boo original, freddy, frog and by", 
 340             fmt
.formatAndReplace( 
 342                     UPRV_LENGTHOF(params
), 
 345                     UPRV_LENGTHOF(offsets
), 
 347     if (!assertSuccess("Status", status
)) { 
 350     int32_t expectedOffsets
[] = {14, 22, 4, 31}; 
 351     verifyOffsets(expectedOffsets
, offsets
, UPRV_LENGTHOF(expectedOffsets
)); 
 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
)) { 
 361     UnicodeString 
result("original"); 
 363     UnicodeString 
freddy("freddy"); 
 364     UnicodeString 
frog("frog"); 
 365     UnicodeString 
by("by"); 
 366     const UnicodeString 
*params
[] = {&freddy
, &frog
, &result
, &by
}; 
 369             "original, freddy, frog and by", 
 370             fmt
.formatAndReplace( 
 372                     UPRV_LENGTHOF(params
), 
 375                     UPRV_LENGTHOF(offsets
), 
 377     if (!assertSuccess("Status", status
)) { 
 380     int32_t expectedOffsets
[] = {10, 18, 0, 27}; 
 381     verifyOffsets(expectedOffsets
, offsets
, UPRV_LENGTHOF(expectedOffsets
)); 
 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
)) { 
 391     UnicodeString 
result("original"); 
 393     UnicodeString 
freddy("freddy"); 
 394     UnicodeString 
frog("frog"); 
 395     UnicodeString 
by("by"); 
 396     const UnicodeString 
*params
[] = {&freddy
, &frog
, &result
, &by
}; 
 399             "original, freddy, frog and by original", 
 400             fmt
.formatAndReplace( 
 402                     UPRV_LENGTHOF(params
), 
 405                     UPRV_LENGTHOF(offsets
), 
 407     if (!assertSuccess("Status", status
)) { 
 410     int32_t expectedOffsets
[] = {10, 18, 30, 27}; 
 411     verifyOffsets(expectedOffsets
, offsets
, UPRV_LENGTHOF(expectedOffsets
)); 
 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
)) { 
 421     UnicodeString 
result("original"); 
 422     UnicodeString 
freddy("freddy"); 
 423     UnicodeString 
frog("frog"); 
 424     UnicodeString 
by("by"); 
 425     const UnicodeString 
*params
[] = {&freddy
, &frog
, &result
, &by
}; 
 428             "original, freddy, frog and by", 
 429             fmt
.formatAndReplace( 
 431                     UPRV_LENGTHOF(params
), 
 436     assertSuccess("Status", status
); 
 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
}; 
 447             "Placeholders previous: and frog", 
 448             fmt
.formatAndReplace( 
 450                     UPRV_LENGTHOF(params
), 
 455     assertSuccess("Status", status
); 
 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
]); 
 467 extern IntlTest 
*createSimplePatternFormatterTest() { 
 468     return new SimplePatternFormatterTest();