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