From fbbb603da642c2702a8fb25d072c335d66862feb Mon Sep 17 00:00:00 2001 From: Umesh Nair Date: Wed, 12 Sep 2012 00:14:25 +0000 Subject: [PATCH] ICU-9568 Adding test case with a pattern with out-of-order placeholders. X-SVN-Rev: 32376 --- icu4c/source/common/listformatter.cpp | 31 +++++++------------ icu4c/source/common/unicode/listformatter.h | 20 +++++++++--- .../test/intltest/listformattertest.cpp | 27 ++++++++++++++++ .../source/test/intltest/listformattertest.h | 1 + 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/icu4c/source/common/listformatter.cpp b/icu4c/source/common/listformatter.cpp index 851c1702b0d..31c46484a2a 100644 --- a/icu4c/source/common/listformatter.cpp +++ b/icu4c/source/common/listformatter.cpp @@ -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; diff --git a/icu4c/source/common/unicode/listformatter.h b/icu4c/source/common/unicode/listformatter.h index 52591bdd522..37042379db6 100644 --- a/icu4c/source/common/unicode/listformatter.h +++ b/icu4c/source/common/unicode/listformatter.h @@ -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 diff --git a/icu4c/source/test/intltest/listformattertest.cpp b/icu4c/source/test/intltest/listformattertest.cpp index 1d5a5a93a70..4f60f8d450a 100644 --- a/icu4c/source/test/intltest/listformattertest.cpp +++ b/icu4c/source/test/intltest/listformattertest.cpp @@ -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; } diff --git a/icu4c/source/test/intltest/listformattertest.h b/icu4c/source/test/intltest/listformattertest.h index 4a012c21556..d780f050817 100644 --- a/icu4c/source/test/intltest/listformattertest.h +++ b/icu4c/source/test/intltest/listformattertest.h @@ -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); -- 2.40.0