ICU-9568 Adding test case with a pattern with out-of-order placeholders.

X-SVN-Rev: 32376
This commit is contained in:
Umesh Nair 2012-09-12 00:14:25 +00:00
parent 237e167bce
commit fbbb603da6
4 changed files with 56 additions and 23 deletions

View file

@ -24,13 +24,6 @@
U_NAMESPACE_BEGIN
struct ListFormatData : public UMemory {
UnicodeString twoPattern;
UnicodeString startPattern;
UnicodeString middlePattern;
UnicodeString endPattern;
};
static Hashtable* listPatternHash = NULL;
static UMTX listFormatterMutex = NULL;
static UChar FIRST_PARAMETER[] = { 0x7b, 0x30, 0x7d }; // "{0}"
@ -153,15 +146,16 @@ void ListFormatter::addDataToHash(
return;
}
UnicodeString key(locale, -1, US_INV);
ListFormatData* value = new ListFormatData();
ListFormatData* value = new ListFormatData(
UnicodeString(two, -1, US_INV).unescape(),
UnicodeString(start, -1, US_INV).unescape(),
UnicodeString(middle, -1, US_INV).unescape(),
UnicodeString(end, -1, US_INV).unescape());
if (value == NULL) {
errorCode = U_MEMORY_ALLOCATION_ERROR;
return;
}
value->twoPattern = UnicodeString(two, -1, US_INV).unescape();
value->startPattern = UnicodeString(start, -1, US_INV).unescape();
value->middlePattern = UnicodeString(middle, -1, US_INV).unescape();
value->endPattern = UnicodeString(end, -1, US_INV).unescape();
listPatternHash->put(key, value, errorCode);
}
@ -197,7 +191,7 @@ ListFormatter* ListFormatter::createInstance(const Locale& locale, UErrorCode& e
return NULL;
}
if (listFormatData != NULL) {
ListFormatter* p = new ListFormatter(tempLocale, listFormatData);
ListFormatter* p = new ListFormatter(*listFormatData);
if (p == NULL) {
errorCode = U_MEMORY_ALLOCATION_ERROR;
return NULL;
@ -217,8 +211,7 @@ ListFormatter* ListFormatter::createInstance(const Locale& locale, UErrorCode& e
}
}
ListFormatter::ListFormatter(const Locale& listFormatterLocale, const ListFormatData* listFormatterData)
: locale(listFormatterLocale), data(listFormatterData) {
ListFormatter::ListFormatter(const ListFormatData& listFormatterData) : data(listFormatterData) {
}
ListFormatter::~ListFormatter() {}
@ -267,14 +260,14 @@ UnicodeString& ListFormatter::format(const UnicodeString items[], int32_t nItems
if (nItems > 0) {
UnicodeString newString = items[0];
if (nItems == 2) {
addNewString(data->twoPattern, newString, items[1], errorCode);
addNewString(data.twoPattern, newString, items[1], errorCode);
} else if (nItems > 2) {
addNewString(data->startPattern, newString, items[1], errorCode);
addNewString(data.startPattern, newString, items[1], errorCode);
int i;
for (i = 2; i < nItems - 1; ++i) {
addNewString(data->middlePattern, newString, items[i], errorCode);
addNewString(data.middlePattern, newString, items[i], errorCode);
}
addNewString(data->endPattern, newString, items[nItems - 1], errorCode);
addNewString(data.endPattern, newString, items[nItems - 1], errorCode);
}
if (U_SUCCESS(errorCode)) {
appendTo += newString;

View file

@ -27,7 +27,16 @@ U_NAMESPACE_BEGIN
class Hashtable;
/** @internal */
class ListFormatData;
struct ListFormatData : public UMemory {
UnicodeString twoPattern;
UnicodeString startPattern;
UnicodeString middlePattern;
UnicodeString endPattern;
ListFormatData(const UnicodeString& two, const UnicodeString& start, const UnicodeString& middle, const UnicodeString& end) :
twoPattern(two), startPattern(start), middlePattern(middle), endPattern(end) {}
};
/**
* \file
@ -99,13 +108,17 @@ class U_COMMON_API ListFormatter : public UObject{
*/
static void getFallbackLocale(const Locale& in, Locale& out, UErrorCode& errorCode);
/**
* @internal constructor made public for testing.
*/
ListFormatter(const ListFormatData& listFormatterData);
private:
static void initializeHash(UErrorCode& errorCode);
static void addDataToHash(const char* locale, const char* two, const char* start, const char* middle, const char* end, UErrorCode& errorCode);
static const ListFormatData* getListFormatData(const Locale& locale, UErrorCode& errorCode);
ListFormatter();
ListFormatter(const Locale& listFormatterLocale, const ListFormatData* listFormatterData);
ListFormatter(const ListFormatter&);
ListFormatter& operator = (const ListFormatter&);
@ -113,8 +126,7 @@ class U_COMMON_API ListFormatter : public UObject{
const UnicodeString& newString, UErrorCode& errorCode) const;
virtual UClassID getDynamicClassID() const;
Locale locale;
const ListFormatData* data;
const ListFormatData& data;
};
U_NAMESPACE_END

View file

@ -173,6 +173,32 @@ void ListFormatterTest::TestZulu() {
CheckFourCases("zu", one, two, three, four, results);
}
void ListFormatterTest::TestOutOfOrderPatterns() {
UnicodeString results[4] = {
one,
two + " after " + one,
three + " in the last after " + two + " after the first " + one,
four + " in the last after " + three + " after " + two + " after the first " + one
};
UErrorCode errorCode = U_ZERO_ERROR;
ListFormatData data("{1} after {0}", "{1} after the first {0}",
"{1} after {0}", "{1} in the last after {0}");
ListFormatter formatter(data);
UnicodeString input1[] = {one};
CheckFormatting(&formatter, input1, 1, results[0]);
UnicodeString input2[] = {one, two};
CheckFormatting(&formatter, input2, 2, results[1]);
UnicodeString input3[] = {one, two, three};
CheckFormatting(&formatter, input3, 3, results[2]);
UnicodeString input4[] = {one, two, three, four};
CheckFormatting(&formatter, input4, 4, results[3]);
}
void ListFormatterTest::runIndexedTest(int32_t index, UBool exec,
const char* &name, char* /*par */) {
switch(index) {
@ -184,6 +210,7 @@ void ListFormatterTest::runIndexedTest(int32_t index, UBool exec,
case 5: name = "TestMalayalam"; if (exec) TestMalayalam(); break;
case 6: name = "TestZulu"; if (exec) TestZulu(); break;
case 7: name = "TestLocaleFallback"; if (exec) TestLocaleFallback(); break;
case 8: name = "TestOutOfOrderPatterns"; if (exec) TestLocaleFallback(); break;
default: name = ""; break;
}

View file

@ -35,6 +35,7 @@ class ListFormatterTest : public IntlTest {
void TestRussian();
void TestMalayalam();
void TestZulu();
void TestOutOfOrderPatterns();
private:
void CheckFormatting(const ListFormatter* formatter, UnicodeString data[], int32_t data_size, const UnicodeString& expected_result);