Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/i18n/message_formatter.h" | |
| 6 | |
| 7 #include "base/i18n/rtl.h" | |
| 8 #include "base/memory/scoped_ptr.h" | |
| 9 #include "base/strings/string_piece.h" | |
| 10 #include "base/strings/string_util.h" | |
| 11 #include "base/strings/utf_string_conversions.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 #include "third_party/icu/source/common/unicode/unistr.h" | |
| 14 #include "third_party/icu/source/i18n/unicode/datefmt.h" | |
| 15 | |
| 16 typedef testing::Test MessageFormatterTest; | |
| 17 | |
| 18 namespace base { | |
| 19 namespace i18n { | |
| 20 | |
| 21 class MessageFormatterTest : public testing::Test { | |
| 22 protected: | |
| 23 void SetUp() override { | |
| 24 original_locale_ = GetConfiguredLocale(); | |
| 25 SetICUDefaultLocale("en-US"); | |
| 26 } | |
| 27 void TearDown() override { | |
| 28 SetICUDefaultLocale(original_locale_); | |
| 29 } | |
|
Ryan Sleevi
2015/07/31 22:19:36
pedantic nit: Rather than using SetUp/TearDown, it
jungshik at Google
2015/08/01 14:00:58
Thanks for the suggestion. DOne
| |
| 30 | |
| 31 private: | |
| 32 std::string original_locale_; | |
| 33 }; | |
| 34 | |
| 35 namespace { | |
| 36 | |
| 37 void AppendFormattedDateTime(const scoped_ptr<icu::DateFormat>& df, | |
| 38 const Time& now, std::string* result) { | |
| 39 icu::UnicodeString formatted; | |
| 40 df->format(static_cast<UDate>(now.ToJsTime()), formatted). | |
| 41 toUTF8String(*result); | |
| 42 } | |
| 43 | |
| 44 } // namespace | |
| 45 | |
| 46 TEST_F(MessageFormatterTest, PluralNamedArgs) { | |
| 47 const string16 pattern = ASCIIToUTF16( | |
| 48 "{num_people, plural, " | |
| 49 "=0 {I met nobody in {place}.}" | |
| 50 "=1 {I met a person in {place}.}" | |
| 51 "other {I met # people in {place}.}}"); | |
| 52 | |
| 53 std::string result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
| 54 pattern, "num_people", 0, "place", "Paris")); | |
| 55 EXPECT_EQ("I met nobody in Paris.", result); | |
| 56 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
| 57 pattern, "num_people", 1, "place", "Paris")); | |
| 58 EXPECT_EQ("I met a person in Paris.", result); | |
| 59 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
| 60 pattern, "num_people", 5, "place", "Paris")); | |
| 61 EXPECT_EQ("I met 5 people in Paris.", result); | |
| 62 } | |
| 63 | |
| 64 TEST_F(MessageFormatterTest, PluralNamedArgsWithOffset) { | |
| 65 const string16 pattern = ASCIIToUTF16( | |
| 66 "{num_people, plural, offset:1 " | |
| 67 "=0 {I met nobody in {place}.}" | |
| 68 "=1 {I met {person} in {place}.}" | |
| 69 "=2 {I met {person} and one other person in {place}.}" | |
| 70 "=13 {I met {person} and a dozen other people in {place}.}" | |
| 71 "other {I met {person} and # other people in {place}.}}"); | |
| 72 | |
| 73 std::string result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
| 74 pattern, "num_people", 0, "place", "Paris")); | |
| 75 EXPECT_EQ("I met nobody in Paris.", result); | |
| 76 // {person} is ignored if {num_people} is 0. | |
| 77 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
| 78 pattern, "num_people", 0, "place", "Paris", "person", "Peter")); | |
| 79 EXPECT_EQ("I met nobody in Paris.", result); | |
| 80 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
| 81 pattern, "num_people", 1, "place", "Paris", "person", "Peter")); | |
| 82 EXPECT_EQ("I met Peter in Paris.", result); | |
| 83 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
| 84 pattern, "num_people", 2, "place", "Paris", "person", "Peter")); | |
| 85 EXPECT_EQ("I met Peter and one other person in Paris.", result); | |
| 86 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
| 87 pattern, "num_people", 13, "place", "Paris", "person", "Peter")); | |
| 88 EXPECT_EQ("I met Peter and a dozen other people in Paris.", result); | |
| 89 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
| 90 pattern, "num_people", 50, "place", "Paris", "person", "Peter")); | |
| 91 EXPECT_EQ("I met Peter and 49 other people in Paris.", result); | |
| 92 } | |
| 93 | |
| 94 TEST_F(MessageFormatterTest, PluralNumberedArgs) { | |
| 95 const string16 pattern = ASCIIToUTF16( | |
| 96 "{1, plural, " | |
| 97 "=1 {The cert for {0} expired yesterday.}" | |
| 98 "=7 {The cert for {0} expired a week ago.}" | |
| 99 "other {The cert for {0} expired # days ago.}}"); | |
| 100 | |
| 101 std::string result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
| 102 pattern, "example.com", 1)); | |
| 103 EXPECT_EQ("The cert for example.com expired yesterday.", result); | |
| 104 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
| 105 pattern, "example.com", 7)); | |
| 106 EXPECT_EQ("The cert for example.com expired a week ago.", result); | |
| 107 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
| 108 pattern, "example.com", 15)); | |
| 109 EXPECT_EQ("The cert for example.com expired 15 days ago.", result); | |
| 110 } | |
| 111 | |
| 112 TEST_F(MessageFormatterTest, PluralNumberedArgsWithDate) { | |
| 113 const string16 pattern = ASCIIToUTF16( | |
| 114 "{1, plural, " | |
| 115 "=1 {The cert for {0} expired yesterday. Today is {2,date,full}}" | |
| 116 "other {The cert for {0} expired # days ago. Today is {2,date,full}}}"); | |
| 117 | |
| 118 base::Time now = base::Time::Now(); | |
| 119 using icu::DateFormat; | |
| 120 scoped_ptr<DateFormat> df(DateFormat::createDateInstance(DateFormat::FULL)); | |
| 121 std::string second_sentence = " Today is "; | |
| 122 AppendFormattedDateTime(df, now, &second_sentence); | |
| 123 | |
| 124 std::string result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
| 125 pattern, "example.com", 1, now)); | |
| 126 EXPECT_EQ("The cert for example.com expired yesterday." + second_sentence, | |
| 127 result); | |
| 128 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
| 129 pattern, "example.com", 15, now)); | |
| 130 EXPECT_EQ("The cert for example.com expired 15 days ago." + second_sentence, | |
| 131 result); | |
| 132 } | |
| 133 | |
| 134 TEST_F(MessageFormatterTest, DateTimeAndNumber) { | |
| 135 // Note that using 'mph' for all locales is not a good i18n practice. | |
| 136 const string16 pattern = ASCIIToUTF16( | |
| 137 "At {0,time, short} on {0,date, medium}, " | |
| 138 "there was {1} at building {2,number,integer}. " | |
| 139 "The speed of the wind was {3,number,###.#} mph."); | |
| 140 | |
| 141 using icu::DateFormat; | |
| 142 scoped_ptr<DateFormat> tf(DateFormat::createTimeInstance(DateFormat::SHORT)); | |
| 143 scoped_ptr<DateFormat> df(DateFormat::createDateInstance(DateFormat::MEDIUM)); | |
| 144 | |
| 145 base::Time now = base::Time::Now(); | |
| 146 std::string expected = "At "; | |
| 147 AppendFormattedDateTime(tf, now, &expected); | |
| 148 expected.append(" on "); | |
| 149 AppendFormattedDateTime(df, now, &expected); | |
| 150 expected.append(", there was an explosion at building 3. " | |
| 151 "The speed of the wind was 37.4 mph."); | |
| 152 | |
| 153 EXPECT_EQ(expected, UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
| 154 pattern, now, "an explosion", 3, 37.413))); | |
| 155 } | |
| 156 | |
| 157 TEST_F(MessageFormatterTest, SelectorSingleOrMultiple) { | |
| 158 const string16 pattern = ASCIIToUTF16( | |
| 159 "{0, select," | |
| 160 "single {Select a file to upload.}" | |
| 161 "multiple {Select files to upload.}" | |
| 162 "other {UNUSED}}"); | |
| 163 | |
| 164 std::string result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
| 165 pattern, "single")); | |
| 166 EXPECT_EQ("Select a file to upload.", result); | |
| 167 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
| 168 pattern, "multiple")); | |
| 169 EXPECT_EQ("Select files to upload.", result); | |
| 170 | |
| 171 // fallback if a parameter is not selectors specified in the message pattern. | |
| 172 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
| 173 pattern, "foobar")); | |
| 174 EXPECT_EQ("UNUSED", result); | |
| 175 } | |
| 176 | |
| 177 } // namespace i18n | |
| 178 } // namespace base | |
| OLD | NEW |