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 } | |
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 | |
Avi (use Gerrit)
2015/07/30 19:19:49
no need for the blank line.
jungshik at Google
2015/07/31 21:36:15
Done.
| |
63 } | |
64 | |
65 TEST_F(MessageFormatterTest, PluralNamedArgsWithOffset) { | |
66 const string16 pattern = ASCIIToUTF16( | |
67 "{num_people, plural, offset:1 " | |
68 "=0 {I met nobody in {place}.}" | |
69 "=1 {I met {person} in {place}.}" | |
70 "=2 {I met {person} and one other person in {place}.}" | |
71 "=13 {I met {person} and dozen other people in {place}.}" | |
Avi (use Gerrit)
2015/07/30 19:19:48
... and a dozen other people ...
is proper Englis
jungshik at Google
2015/07/31 21:36:15
Done.
| |
72 "other {I met {person} and # other people in {place}.}}"); | |
73 | |
74 std::string result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
75 pattern, "num_people", 0, "place", "Paris")); | |
76 EXPECT_EQ("I met nobody in Paris.", result); | |
77 // {person} is ignored if {num_people} is 0. | |
78 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
79 pattern, "num_people", 0, "place", "Paris", "person", "Peter")); | |
80 EXPECT_EQ("I met nobody in Paris.", result); | |
81 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
82 pattern, "num_people", 1, "place", "Paris", "person", "Peter")); | |
83 EXPECT_EQ("I met Peter in Paris.", result); | |
84 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
85 pattern, "num_people", 2, "place", "Paris", "person", "Peter")); | |
86 EXPECT_EQ("I met Peter and one other person in Paris.", result); | |
87 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
88 pattern, "num_people", 13, "place", "Paris", "person", "Peter")); | |
89 EXPECT_EQ("I met Peter and dozen other people in Paris.", result); | |
90 result = UTF16ToASCII(MessageFormatter::FormatWithNamedArgs( | |
91 pattern, "num_people", 50, "place", "Paris", "person", "Peter")); | |
92 EXPECT_EQ("I met Peter and 49 other people in Paris.", result); | |
93 } | |
94 | |
95 TEST_F(MessageFormatterTest, PluralNumberedArgs) { | |
96 const string16 pattern = ASCIIToUTF16( | |
97 "{1, plural, " | |
98 "=1 {The cert for {0} expired yesterday.}" | |
99 "=7 {The cert for {0} expired a week ago.}" | |
100 "other {The cert for {0} expired # days ago.}}"); | |
101 | |
102 std::string result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
103 pattern, "example.com", 1)); | |
104 EXPECT_EQ("The cert for example.com expired yesterday.", result); | |
105 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
106 pattern, "example.com", 7)); | |
107 EXPECT_EQ("The cert for example.com expired a week ago.", result); | |
108 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
109 pattern, "example.com", 15)); | |
110 EXPECT_EQ("The cert for example.com expired 15 days ago.", result); | |
111 } | |
112 | |
113 TEST_F(MessageFormatterTest, PluralNumberedArgsWithDate) { | |
114 const string16 pattern = ASCIIToUTF16( | |
115 "{1, plural, " | |
116 "=1 {The cert for {0} expired yesterday. Today is {2,date,full}}" | |
117 "other {The cert for {0} expired # days ago. Today is {2,date,full}}}"); | |
118 | |
119 base::Time now = base::Time::Now(); | |
120 using icu::DateFormat; | |
121 scoped_ptr<DateFormat> df(DateFormat::createDateInstance(DateFormat::FULL)); | |
122 std::string second_sentence = " Today is "; | |
123 AppendFormattedDateTime(df, now, &second_sentence); | |
124 | |
125 std::string result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
126 pattern, "example.com", 1, now)); | |
127 EXPECT_EQ("The cert for example.com expired yesterday." + second_sentence, | |
128 result); | |
129 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
130 pattern, "example.com", 15, now)); | |
131 EXPECT_EQ("The cert for example.com expired 15 days ago." + second_sentence, | |
132 result); | |
133 } | |
134 | |
135 TEST_F(MessageFormatterTest, DateTimeAndNumber) { | |
136 // Note that using 'mph' for all locales is not a good i18n practice. | |
137 const string16 pattern = ASCIIToUTF16( | |
138 "At {0,time, short} on {0,date, medium}, " | |
139 "there was {1} at building {2,number,integer}. " | |
140 "The speed of the wind was {3,number,###.#} mph."); | |
141 | |
142 using icu::DateFormat; | |
143 scoped_ptr<DateFormat> tf(DateFormat::createTimeInstance(DateFormat::SHORT)); | |
144 scoped_ptr<DateFormat> df(DateFormat::createDateInstance(DateFormat::MEDIUM)); | |
145 | |
146 base::Time now = base::Time::Now(); | |
147 std::string expected = "At "; | |
148 AppendFormattedDateTime(tf, now, &expected); | |
149 expected.append(" on "); | |
150 AppendFormattedDateTime(df, now, &expected); | |
151 expected.append(", there was an explosion at building 3. " | |
152 "The speed of the wind was 37.4 mph."); | |
153 | |
154 EXPECT_EQ(expected, UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
155 pattern, now, "an explosion", 3, 37.413))); | |
156 } | |
157 | |
158 TEST_F(MessageFormatterTest, SelectorSingleOrMultiple) { | |
159 const string16 pattern = ASCIIToUTF16( | |
160 "{0, select," | |
161 "single {Select a file to upload.}" | |
162 "multiple {Select files to upload.}" | |
163 "other {UNUSED}}"); | |
164 | |
165 std::string result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
166 pattern, "single")); | |
167 EXPECT_EQ("Select a file to upload.", result); | |
168 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
169 pattern, "multiple")); | |
170 EXPECT_EQ("Select files to upload.", result); | |
171 | |
172 // fallback if a parameter is not selectors specified in the message pattern. | |
173 result = UTF16ToASCII(MessageFormatter::FormatWithNumberedArgs( | |
174 pattern, "foobar")); | |
175 EXPECT_EQ("UNUSED", result); | |
176 } | |
177 | |
178 } // namespace i18n | |
179 } // namespace base | |
OLD | NEW |