2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "platform/text/LocaleWin.h"
34 #include "platform/DateComponents.h"
35 #include "wtf/DateMath.h"
36 #include "wtf/MathExtras.h"
37 #include "wtf/PassOwnPtr.h"
38 #include "wtf/text/CString.h"
39 #include <gtest/gtest.h>
43 class LocaleWinTest
: public ::testing::Test
{
46 January
= 0, February
, March
,
48 July
, August
, September
,
49 October
, November
, December
,
53 Sunday
= 0, Monday
, Tuesday
,
54 Wednesday
, Thursday
, Friday
,
58 // See http://msdn.microsoft.com/en-us/goglobal/bb964664.aspx
59 // Note that some locales are country-neutral.
61 ArabicEG
= 0x0C01, // ar-eg
62 ChineseCN
= 0x0804, // zh-cn
63 ChineseHK
= 0x0C04, // zh-hk
64 ChineseTW
= 0x0404, // zh-tw
65 German
= 0x0407, // de
66 EnglishUS
= 0x409, // en-us
67 FrenchFR
= 0x40C, // fr
68 JapaneseJP
= 0x411, // ja
69 KoreanKR
= 0x0412, // ko
70 Persian
= 0x0429, // fa
71 Spanish
= 0x040A, // es
74 DateComponents
dateComponents(int year
, int month
, int day
)
77 date
.setMillisecondsSinceEpochForDate(msForDate(year
, month
, day
));
81 double msForDate(int year
, int month
, int day
)
83 return dateToDaysFrom1970(year
, month
, day
) * msPerDay
;
86 String
formatDate(LCID lcid
, int year
, int month
, int day
)
88 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
89 return locale
->formatDateTime(dateComponents(year
, month
, day
));
92 unsigned firstDayOfWeek(LCID lcid
)
94 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
95 return locale
->firstDayOfWeek();
98 String
monthLabel(LCID lcid
, unsigned index
)
100 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
101 return locale
->monthLabels()[index
];
104 String
weekDayShortLabel(LCID lcid
, unsigned index
)
106 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
107 return locale
->weekDayShortLabels()[index
];
110 bool isRTL(LCID lcid
)
112 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
113 return locale
->isRTL();
116 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
117 String
monthFormat(LCID lcid
)
119 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
120 return locale
->monthFormat();
123 String
timeFormat(LCID lcid
)
125 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
126 return locale
->timeFormat();
129 String
shortTimeFormat(LCID lcid
)
131 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
132 return locale
->shortTimeFormat();
135 String
shortMonthLabel(LCID lcid
, unsigned index
)
137 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
138 return locale
->shortMonthLabels()[index
];
141 String
timeAMPMLabel(LCID lcid
, unsigned index
)
143 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
144 return locale
->timeAMPMLabels()[index
];
147 String
decimalSeparator(LCID lcid
)
149 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
150 return locale
->localizedDecimalSeparator();
155 TEST_F(LocaleWinTest
, formatDate
)
157 EXPECT_STREQ("04/27/2005", formatDate(EnglishUS
, 2005, April
, 27).utf8().data());
158 EXPECT_STREQ("27/04/2005", formatDate(FrenchFR
, 2005, April
, 27).utf8().data());
159 EXPECT_STREQ("2005/04/27", formatDate(JapaneseJP
, 2005, April
, 27).utf8().data());
162 TEST_F(LocaleWinTest
, firstDayOfWeek
)
164 EXPECT_EQ(Sunday
, firstDayOfWeek(EnglishUS
));
165 EXPECT_EQ(Monday
, firstDayOfWeek(FrenchFR
));
166 EXPECT_EQ(Sunday
, firstDayOfWeek(JapaneseJP
));
169 TEST_F(LocaleWinTest
, monthLabels
)
171 EXPECT_STREQ("January", monthLabel(EnglishUS
, January
).utf8().data());
172 EXPECT_STREQ("June", monthLabel(EnglishUS
, June
).utf8().data());
173 EXPECT_STREQ("December", monthLabel(EnglishUS
, December
).utf8().data());
175 EXPECT_STREQ("janvier", monthLabel(FrenchFR
, January
).utf8().data());
176 EXPECT_STREQ("juin", monthLabel(FrenchFR
, June
).utf8().data());
177 EXPECT_STREQ("d\xC3\xA9" "cembre", monthLabel(FrenchFR
, December
).utf8().data());
179 EXPECT_STREQ("1\xE6\x9C\x88", monthLabel(JapaneseJP
, January
).utf8().data());
180 EXPECT_STREQ("6\xE6\x9C\x88", monthLabel(JapaneseJP
, June
).utf8().data());
181 EXPECT_STREQ("12\xE6\x9C\x88", monthLabel(JapaneseJP
, December
).utf8().data());
184 TEST_F(LocaleWinTest
, weekDayShortLabels
)
186 EXPECT_STREQ("Sun", weekDayShortLabel(EnglishUS
, Sunday
).utf8().data());
187 EXPECT_STREQ("Wed", weekDayShortLabel(EnglishUS
, Wednesday
).utf8().data());
188 EXPECT_STREQ("Sat", weekDayShortLabel(EnglishUS
, Saturday
).utf8().data());
190 EXPECT_STREQ("dim.", weekDayShortLabel(FrenchFR
, Sunday
).utf8().data());
191 EXPECT_STREQ("mer.", weekDayShortLabel(FrenchFR
, Wednesday
).utf8().data());
192 EXPECT_STREQ("sam.", weekDayShortLabel(FrenchFR
, Saturday
).utf8().data());
194 EXPECT_STREQ("\xE6\x97\xA5", weekDayShortLabel(JapaneseJP
, Sunday
).utf8().data());
195 EXPECT_STREQ("\xE6\xB0\xB4", weekDayShortLabel(JapaneseJP
, Wednesday
).utf8().data());
196 EXPECT_STREQ("\xE5\x9C\x9F", weekDayShortLabel(JapaneseJP
, Saturday
).utf8().data());
199 TEST_F(LocaleWinTest
, isRTL
)
201 EXPECT_TRUE(isRTL(ArabicEG
));
202 EXPECT_FALSE(isRTL(EnglishUS
));
205 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
206 TEST_F(LocaleWinTest
, dateFormat
)
208 EXPECT_STREQ("y-M-d", LocaleWin::dateFormat("y-M-d").utf8().data());
209 EXPECT_STREQ("''yy'-'''MM'''-'dd", LocaleWin::dateFormat("''yy-''MM''-dd").utf8().data());
210 EXPECT_STREQ("yyyy'-''''-'MMM'''''-'dd", LocaleWin::dateFormat("yyyy-''''-MMM''''-dd").utf8().data());
211 EXPECT_STREQ("yyyy'-'''''MMMM-dd", LocaleWin::dateFormat("yyyy-''''MMMM-dd").utf8().data());
214 TEST_F(LocaleWinTest
, monthFormat
)
216 // Month format for EnglishUS:
217 // "MMMM, yyyy" on Windows 7 or older.
218 // "MMMM yyyy" on Window 8 or later.
219 EXPECT_STREQ("MMMM yyyy", monthFormat(EnglishUS
).replaceWithLiteral(',', "").utf8().data());
220 EXPECT_STREQ("MMMM yyyy", monthFormat(FrenchFR
).utf8().data());
221 EXPECT_STREQ("yyyy\xE5\xB9\xB4M\xE6\x9C\x88", monthFormat(JapaneseJP
).utf8().data());
224 TEST_F(LocaleWinTest
, timeFormat
)
226 EXPECT_STREQ("h:mm:ss a", timeFormat(EnglishUS
).utf8().data());
227 EXPECT_STREQ("HH:mm:ss", timeFormat(FrenchFR
).utf8().data());
228 EXPECT_STREQ("H:mm:ss", timeFormat(JapaneseJP
).utf8().data());
231 TEST_F(LocaleWinTest
, shortTimeFormat
)
233 EXPECT_STREQ("h:mm a", shortTimeFormat(EnglishUS
).utf8().data());
234 EXPECT_STREQ("HH:mm", shortTimeFormat(FrenchFR
).utf8().data());
235 EXPECT_STREQ("H:mm", shortTimeFormat(JapaneseJP
).utf8().data());
238 TEST_F(LocaleWinTest
, shortMonthLabels
)
240 EXPECT_STREQ("Jan", shortMonthLabel(EnglishUS
, 0).utf8().data());
241 EXPECT_STREQ("Dec", shortMonthLabel(EnglishUS
, 11).utf8().data());
242 EXPECT_STREQ("janv.", shortMonthLabel(FrenchFR
, 0).utf8().data());
243 EXPECT_STREQ("d\xC3\xA9" "c.", shortMonthLabel(FrenchFR
, 11).utf8().data());
244 EXPECT_STREQ("1", shortMonthLabel(JapaneseJP
, 0).utf8().data());
245 EXPECT_STREQ("12", shortMonthLabel(JapaneseJP
, 11).utf8().data());
248 TEST_F(LocaleWinTest
, timeAMPMLabels
)
250 EXPECT_STREQ("AM", timeAMPMLabel(EnglishUS
, 0).utf8().data());
251 EXPECT_STREQ("PM", timeAMPMLabel(EnglishUS
, 1).utf8().data());
253 EXPECT_STREQ("", timeAMPMLabel(FrenchFR
, 0).utf8().data());
254 EXPECT_STREQ("", timeAMPMLabel(FrenchFR
, 1).utf8().data());
256 EXPECT_STREQ("\xE5\x8D\x88\xE5\x89\x8D", timeAMPMLabel(JapaneseJP
, 0).utf8().data());
257 EXPECT_STREQ("\xE5\x8D\x88\xE5\xBE\x8C", timeAMPMLabel(JapaneseJP
, 1).utf8().data());
260 TEST_F(LocaleWinTest
, decimalSeparator
)
262 EXPECT_STREQ(".", decimalSeparator(EnglishUS
).utf8().data());
263 EXPECT_STREQ(",", decimalSeparator(FrenchFR
).utf8().data());
267 static void testNumberIsReversible(LCID lcid
, const char* original
, const char* shouldHave
= 0)
269 OwnPtr
<LocaleWin
> locale
= LocaleWin::create(lcid
, true /* defaultsForLocale */);
270 String localized
= locale
->convertToLocalizedNumber(original
);
272 EXPECT_TRUE(localized
.contains(shouldHave
));
273 String converted
= locale
->convertFromLocalizedNumber(localized
);
274 EXPECT_STREQ(original
, converted
.utf8().data());
277 void testNumbers(LCID lcid
)
279 testNumberIsReversible(lcid
, "123456789012345678901234567890");
280 testNumberIsReversible(lcid
, "-123.456");
281 testNumberIsReversible(lcid
, ".456");
282 testNumberIsReversible(lcid
, "-0.456");
285 TEST_F(LocaleWinTest
, localizedNumberRoundTrip
)
287 testNumberIsReversible(EnglishUS
, "123456789012345678901234567890");
288 testNumberIsReversible(EnglishUS
, "-123.456", ".");
289 testNumberIsReversible(EnglishUS
, ".456", ".");
290 testNumberIsReversible(EnglishUS
, "-0.456", ".");
292 testNumberIsReversible(FrenchFR
, "123456789012345678901234567890");
293 testNumberIsReversible(FrenchFR
, "-123.456", ",");
294 testNumberIsReversible(FrenchFR
, ".456", ",");
295 testNumberIsReversible(FrenchFR
, "-0.456", ",");
297 // Test some of major locales.
298 testNumbers(ArabicEG
);
300 testNumbers(Spanish
);
301 testNumbers(Persian
);
302 testNumbers(JapaneseJP
);
303 testNumbers(KoreanKR
);
304 testNumbers(ChineseCN
);
305 testNumbers(ChineseHK
);
306 testNumbers(ChineseTW
);