Introduce Localizer::isRTL, and use it in DateTimeChooserImpl
[WebKit-https.git] / Source / WebKit / chromium / tests / LocaleWinTest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
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
13  * distribution.
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.
17  *
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.
29  */
30
31 #include "config.h"
32 #include "LocaleWin.h"
33
34 #include "DateComponents.h"
35 #include <gtest/gtest.h>
36 #include <wtf/DateMath.h>
37 #include <wtf/MathExtras.h>
38 #include <wtf/PassOwnPtr.h>
39 #include <wtf/text/CString.h>
40
41 using namespace WebCore;
42 using namespace std;
43
44 class LocaleWinTest : public ::testing::Test {
45 protected:
46     enum {
47         January = 0, February, March,
48         April, May, June,
49         July, August, September,
50         October, November, December,
51     };
52
53     enum {
54         Sunday = 0, Monday, Tuesday,
55         Wednesday, Thursday, Friday,
56         Saturday,
57     };
58
59     // See http://msdn.microsoft.com/en-us/goglobal/bb964664.aspx
60     // Note that some locales are country-neutral.
61     enum {
62         ArabicEG = 0x0C01, // ar-eg
63         ChineseCN = 0x0804, // zh-cn
64         ChineseHK = 0x0C04, // zh-hk
65         ChineseTW = 0x0404, // zh-tw
66         German = 0x0407, // de
67         EnglishUS = 0x409, // en-us
68         FrenchFR = 0x40C, // fr
69         JapaneseJP = 0x411, // ja
70         KoreanKR = 0x0412, // ko
71         Persian = 0x0429, // fa
72         Spanish = 0x040A, // es
73     };
74
75     DateComponents dateComponents(int year, int month, int day)
76     {
77         DateComponents date;
78         date.setMillisecondsSinceEpochForDate(msForDate(year, month, day));
79         return date;
80     }
81
82     double msForDate(int year, int month, int day)
83     {
84         return dateToDaysFrom1970(year, month, day) * msPerDay;
85     }
86
87     String formatDate(LCID lcid, int year, int month, int day)
88     {
89         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
90         return locale->formatDateTime(dateComponents(year, month, day));
91     }
92
93     double parseDate(LCID lcid, const String& dateString)
94     {
95         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
96         return locale->parseDateTime(dateString, DateComponents::Date);
97     }
98
99 #if ENABLE(CALENDAR_PICKER)
100     String dateFormatText(LCID lcid)
101     {
102         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
103         return locale->dateFormatText();
104     }
105
106     unsigned firstDayOfWeek(LCID lcid)
107     {
108         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
109         return locale->firstDayOfWeek();
110     }
111
112     String monthLabel(LCID lcid, unsigned index)
113     {
114         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
115         return locale->monthLabels()[index];
116     }
117
118     String weekDayShortLabel(LCID lcid, unsigned index)
119     {
120         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
121         return locale->weekDayShortLabels()[index];
122     }
123
124     bool isRTL(LCID lcid)
125     {
126         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
127         return locale->isRTL();
128     }
129 #endif
130
131 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
132     String timeFormat(LCID lcid)
133     {
134         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
135         return locale->timeFormat();
136     }
137
138     String shortTimeFormat(LCID lcid)
139     {
140         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
141         return locale->shortTimeFormat();
142     }
143
144     String timeAMPMLabel(LCID lcid, unsigned index)
145     {
146         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
147         return locale->timeAMPMLabels()[index];
148     }
149
150     String decimalSeparator(LCID lcid)
151     {
152         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
153         return locale->localizedDecimalSeparator();
154     }
155 #endif
156 };
157
158 TEST_F(LocaleWinTest, TestLocalizedDateFormatText)
159 {
160     EXPECT_STREQ("year/month/day", LocaleWin::dateFormatText("y/M/d", "year", "month", "day").utf8().data());
161     EXPECT_STREQ("year/month/day", LocaleWin::dateFormatText("yy/MM/dd", "year", "month", "day").utf8().data());
162     EXPECT_STREQ("year/month/day", LocaleWin::dateFormatText("yyy/MMM/ddd", "year", "month", "day").utf8().data());
163     EXPECT_STREQ("year/month/day", LocaleWin::dateFormatText("yyyy/MMMM/dddd", "year", "month", "day").utf8().data());
164     EXPECT_STREQ("/month/day, year", LocaleWin::dateFormatText("/MM/dd, yyyy", "year", "month", "day").utf8().data());
165     EXPECT_STREQ("month/day, year=year.", LocaleWin::dateFormatText("MM/dd, 'year='yyyy.", "year", "month", "day").utf8().data());
166     EXPECT_STREQ("month-day 'year", LocaleWin::dateFormatText("MM-dd ''yyy", "year", "month", "day").utf8().data());
167     EXPECT_STREQ("month-day aaa'bbb year", LocaleWin::dateFormatText("MM-dd 'aaa''bbb' yyy", "year", "month", "day").utf8().data());
168     EXPECT_STREQ("year/month/day/year/month/day", LocaleWin::dateFormatText("yyyy/MMMM/dddd/yyyy/MMMM/dddd", "year", "month", "day").utf8().data());
169     EXPECT_STREQ("YY/mm/DD", LocaleWin::dateFormatText("YY/mm/DD", "year", "month", "day").utf8().data());
170 }
171
172 TEST_F(LocaleWinTest, TestFormat)
173 {
174     OwnPtr<LocaleWin> locale = LocaleWin::create(EnglishUS);
175
176     EXPECT_STREQ("4/7/2", locale->formatDate("M/d/y", 2012, 2012, April, 7).utf8().data());
177     EXPECT_STREQ("4/7/2007", locale->formatDate("M/d/y", 2012, 2007, April, 7).utf8().data());
178     EXPECT_STREQ("4/7/8", locale->formatDate("M/d/y", 2012, 2008, April, 7).utf8().data());
179     EXPECT_STREQ("4/7/7", locale->formatDate("M/d/y", 2012, 2017, April, 7).utf8().data());
180     EXPECT_STREQ("4/7/2018", locale->formatDate("M/d/y", 2012, 2018, April, 7).utf8().data());
181     EXPECT_STREQ("12/31/2062", locale->formatDate("M/d/y", 2012, 2062, December, 31).utf8().data());
182     EXPECT_STREQ("4/7/0002", locale->formatDate("M/d/y", 2012, 2, April, 7).utf8().data());
183
184     EXPECT_STREQ("04/27/12", locale->formatDate("MM/dd/yy", 2012, 2012, April, 27).utf8().data());
185     EXPECT_STREQ("04/07/1962", locale->formatDate("MM/dd/yy", 2012, 1962, April, 7).utf8().data());
186     EXPECT_STREQ("04/07/63", locale->formatDate("MM/dd/yy", 2012, 1963, April, 7).utf8().data());
187     EXPECT_STREQ("01/31/00", locale->formatDate("MM/dd/yy", 2012, 2000, January, 31).utf8().data());
188     EXPECT_STREQ("04/07/62", locale->formatDate("MM/dd/yy", 2012, 2062, April, 7).utf8().data());
189     EXPECT_STREQ("04/07/2063", locale->formatDate("MM/dd/yy", 2012, 2063, April, 7).utf8().data());
190     EXPECT_STREQ("04/07/0001", locale->formatDate("MM/dd/yy", 2012, 1, April, 7).utf8().data());
191
192     EXPECT_STREQ("Jan/7/2012", locale->formatDate("MMM/d/yyyy", 2012, 2012, January, 7).utf8().data());
193     EXPECT_STREQ("Feb/7/2008", locale->formatDate("MMM/d/yyyy", 2012, 2008, February, 7).utf8().data());
194     EXPECT_STREQ("Mar/7/2017", locale->formatDate("MMM/d/yyyy", 2012, 2017, March, 7).utf8().data());
195     EXPECT_STREQ("Apr/7/2012", locale->formatDate("MMM/d/yyyy", 2012, 2012, April, 7).utf8().data());
196     EXPECT_STREQ("May/7/0002", locale->formatDate("MMM/d/yyyy", 2012, 2, May, 7).utf8().data());
197     EXPECT_STREQ("Jun/7/2008", locale->formatDate("MMM/d/yyyy", 2012, 2008, June, 7).utf8().data());
198     EXPECT_STREQ("Jul/7/2017", locale->formatDate("MMM/d/yyyy", 2012, 2017, July, 7).utf8().data());
199     EXPECT_STREQ("Aug/31/2062", locale->formatDate("MMM/d/yyyy", 2012, 2062, August, 31).utf8().data());
200     EXPECT_STREQ("Sep/7/0002", locale->formatDate("MMM/d/yyyy", 2012, 2, September, 7).utf8().data());
201     EXPECT_STREQ("Oct/7/2012", locale->formatDate("MMM/d/yyyy", 2012, 2012, October, 7).utf8().data());
202     EXPECT_STREQ("Nov/7/2008", locale->formatDate("MMM/d/yyyy", 2012, 2008, November, 7).utf8().data());
203     EXPECT_STREQ("Dec/31/2062", locale->formatDate("MMM/d/yyyy", 2012, 2062, December, 31).utf8().data());
204
205     EXPECT_STREQ("January-7-2017", locale->formatDate("MMMM-d-yyyy", 2012, 2017, January, 7).utf8().data());
206     EXPECT_STREQ("February-31-2062", locale->formatDate("MMMM-d-yyyy", 2012, 2062, February, 31).utf8().data());
207     EXPECT_STREQ("March-7-0002", locale->formatDate("MMMM-d-yyyy", 2012, 2, March, 7).utf8().data());
208     EXPECT_STREQ("April-7-22012", locale->formatDate("MMMM-d-yyyy", 2012, 22012, April, 7).utf8().data());
209     EXPECT_STREQ("May-7-12008", locale->formatDate("MMMM-d-yyyy", 2012, 12008, May, 7).utf8().data());
210     EXPECT_STREQ("June-7-22012", locale->formatDate("MMMM-d-yyyy", 2012, 22012, June, 7).utf8().data());
211     EXPECT_STREQ("July-7-12008", locale->formatDate("MMMM-d-yyyy", 2012, 12008, July, 7).utf8().data());
212     EXPECT_STREQ("August-7-2017", locale->formatDate("MMMM-d-yyyy", 2012, 2017, August, 7).utf8().data());
213     EXPECT_STREQ("September-31-2062", locale->formatDate("MMMM-d-yyyy", 2012, 2062, September, 31).utf8().data());
214     EXPECT_STREQ("October-7-0002", locale->formatDate("MMMM-d-yyyy", 2012, 2, October, 7).utf8().data());
215     EXPECT_STREQ("November-7-22012", locale->formatDate("MMMM-d-yyyy", 2012, 22012, November, 7).utf8().data());
216     EXPECT_STREQ("December-7-12008", locale->formatDate("MMMM-d-yyyy", 2012, 12008, December, 7).utf8().data());
217
218     EXPECT_STREQ("Jan-1-0001", locale->formatDate("MMM-d-yyyy", 2012, 1, January, 1).utf8().data());
219     EXPECT_STREQ("Sep-13-275760", locale->formatDate("MMM-d-yyyy", 2012, 275760, September, 13).utf8().data());
220
221     OwnPtr<LocaleWin> persian = LocaleWin::create(Persian);
222     // U+06F0 U+06F1 / U+06F0 U+06F8 / U+06F0 U+06F0 U+06F0 U+06F2
223     EXPECT_STREQ("\xDB\xB0\xDB\xB1/\xDB\xB0\xDB\xB8/\xDB\xB0\xDB\xB0\xDB\xB0\xDB\xB1", persian->formatDate("dd/MM/yyyy", 2012, 1, August, 1).utf8().data());
224
225     // For the following test, we'd like to confirm they don't crash and their
226     // results are not important because we can assume invalid arguments are
227     // never passed.
228     EXPECT_STREQ("2012-13-00", locale->formatDate("yyyy-MM-dd", -1, 2012, December + 1, 0).utf8().data());
229     EXPECT_STREQ("-1-00--1", locale->formatDate("y-MM-dd", -1, -1, -1, -1).utf8().data());
230     EXPECT_STREQ("-1-124-33", locale->formatDate("y-MM-dd", 2012, -1, 123, 33).utf8().data());
231     
232 }
233
234 TEST_F(LocaleWinTest, TestParse)
235 {
236     OwnPtr<LocaleWin> locale = LocaleWin::create(EnglishUS);
237
238     EXPECT_EQ(msForDate(2012, April, 27), locale->parseDate("MM/dd/yy", 2012, "04/27/12"));
239     EXPECT_EQ(msForDate(2062, April, 27), locale->parseDate("MM/dd/yy", 2012, "04/27/62"));
240     EXPECT_EQ(msForDate(1963, April, 27), locale->parseDate("MM/dd/yy", 2012, "04/27/63"));
241     EXPECT_EQ(msForDate(2012, April, 27), locale->parseDate("MM/dd/yy", 2012, "4/27/2012"));
242     EXPECT_EQ(msForDate(2012, April, 27), locale->parseDate("MM/dd/yy", 2012, "Apr/27/2012"));
243     EXPECT_EQ(msForDate(2, April, 27), locale->parseDate("MM/d/yy", 2012, "April/27/2"));
244     EXPECT_EQ(msForDate(2, April, 27), locale->parseDate("MM/d/yy", 2012, "april/27/2"));
245     EXPECT_TRUE(isnan(locale->parseDate("MM/d/yy", 2012, "april/27")));
246     EXPECT_TRUE(isnan(locale->parseDate("MM/d/yy", 2012, "april/27/")));
247     EXPECT_TRUE(isnan(locale->parseDate("MM/d/yy", 2012, " april/27/")));
248
249     EXPECT_EQ(msForDate(12, April, 7), locale->parseDate("MMM/d/yyyy", 2012, "04/7/12"));
250     EXPECT_EQ(msForDate(62, April, 7), locale->parseDate("MMM/d/yyyy", 2012, "04/07/62"));
251     EXPECT_EQ(msForDate(63, April, 7), locale->parseDate("MMM/d/yyyy", 2012, "04/07/63"));
252     EXPECT_EQ(msForDate(2012, April, 7), locale->parseDate("MMM/d/yyyy", 2012, "4/7/2012"));
253     EXPECT_EQ(msForDate(2012, May, 7), locale->parseDate("MMM/d/yyyy", 2012, "May/007/2012"));
254     EXPECT_EQ(msForDate(2, May, 27), locale->parseDate("MM/d/yyyy", 2012, "May/0027/2"));
255     EXPECT_TRUE(isnan(locale->parseDate("MM/d/yyyy", 2012, "May///0027///2")));
256     EXPECT_TRUE(isnan(locale->parseDate("MM/d/yyyy", 2012, "Mayyyyyy/0027/2")));
257
258     EXPECT_EQ(msForDate(2012, April, 27), locale->parseDate("MMMM/dd/y", 2012, "04/27/2"));
259     EXPECT_EQ(msForDate(2017, April, 27), locale->parseDate("MMMM/dd/y", 2012, "04/27/7"));
260     EXPECT_EQ(msForDate(2008, April, 27), locale->parseDate("MMMM/dd/y", 2012, "04/27/8"));
261     EXPECT_EQ(msForDate(2012, April, 27), locale->parseDate("MMMM/dd/y", 2012, "4/27/2012"));
262     EXPECT_EQ(msForDate(2012, December, 27), locale->parseDate("MMMM/dd/y", 2012, "December/27/2012"));
263     EXPECT_EQ(msForDate(2012, November, 27), locale->parseDate("MMMM/d/y", 2012, "November/27/2"));
264     EXPECT_TRUE(isnan(locale->parseDate("MMMM/d/y", 2012, "November 27 2")));
265     EXPECT_TRUE(isnan(locale->parseDate("MMMM/d/y", 2012, "November 32 2")));
266     EXPECT_TRUE(isnan(locale->parseDate("MMMM/d/y", 2012, "-1/-1/-1")));
267
268     OwnPtr<LocaleWin> persian = LocaleWin::create(Persian);
269     // U+06F1 U+06F6 / U+06F0 U+06F8 / 2012
270     EXPECT_EQ(msForDate(2012, August, 16), persian->parseDate("dd/MM/yyyy", 2012, String::fromUTF8("\xDB\xB1\xDB\xB6/\xDB\xB0\xDB\xB8/2012")));
271 }
272
273 TEST_F(LocaleWinTest, formatDate)
274 {
275     EXPECT_STREQ("4/27/2005", formatDate(EnglishUS, 2005, April, 27).utf8().data());
276     EXPECT_STREQ("27/04/2005", formatDate(FrenchFR, 2005, April, 27).utf8().data());
277     EXPECT_STREQ("2005/04/27", formatDate(JapaneseJP, 2005, April, 27).utf8().data());
278 }
279
280 TEST_F(LocaleWinTest, parseDate)
281 {
282     EXPECT_EQ(msForDate(2005, April, 27), parseDate(EnglishUS, "April/27/2005"));
283     EXPECT_EQ(msForDate(2005, April, 27), parseDate(FrenchFR, "27/avril/2005"));
284     EXPECT_EQ(msForDate(2005, April, 27), parseDate(JapaneseJP, "2005/04/27"));
285 }
286
287 #if ENABLE(CALENDAR_PICKER)
288 TEST_F(LocaleWinTest, dateFormatText)
289 {
290     EXPECT_STREQ("Month/Day/Year", dateFormatText(EnglishUS).utf8().data());
291     EXPECT_STREQ("Day/Month/Year", dateFormatText(FrenchFR).utf8().data());
292     EXPECT_STREQ("Year/Month/Day", dateFormatText(JapaneseJP).utf8().data());
293 }
294
295 TEST_F(LocaleWinTest, firstDayOfWeek)
296 {
297     EXPECT_EQ(Sunday, firstDayOfWeek(EnglishUS));
298     EXPECT_EQ(Monday, firstDayOfWeek(FrenchFR));
299     EXPECT_EQ(Sunday, firstDayOfWeek(JapaneseJP));
300 }
301
302 TEST_F(LocaleWinTest, monthLabels)
303 {
304     EXPECT_STREQ("January", monthLabel(EnglishUS, January).utf8().data());
305     EXPECT_STREQ("June", monthLabel(EnglishUS, June).utf8().data());
306     EXPECT_STREQ("December", monthLabel(EnglishUS, December).utf8().data());
307
308     EXPECT_STREQ("janvier", monthLabel(FrenchFR, January).utf8().data());
309     EXPECT_STREQ("juin", monthLabel(FrenchFR, June).utf8().data());
310     EXPECT_STREQ("d\xC3\xA9" "cembre", monthLabel(FrenchFR, December).utf8().data());
311
312     EXPECT_STREQ("1\xE6\x9C\x88", monthLabel(JapaneseJP, January).utf8().data());
313     EXPECT_STREQ("6\xE6\x9C\x88", monthLabel(JapaneseJP, June).utf8().data());
314     EXPECT_STREQ("12\xE6\x9C\x88", monthLabel(JapaneseJP, December).utf8().data());
315 }
316
317 TEST_F(LocaleWinTest, weekDayShortLabels)
318 {
319     EXPECT_STREQ("Sun", weekDayShortLabel(EnglishUS, Sunday).utf8().data());
320     EXPECT_STREQ("Wed", weekDayShortLabel(EnglishUS, Wednesday).utf8().data());
321     EXPECT_STREQ("Sat", weekDayShortLabel(EnglishUS, Saturday).utf8().data());
322
323     EXPECT_STREQ("dim.", weekDayShortLabel(FrenchFR, Sunday).utf8().data());
324     EXPECT_STREQ("mer.", weekDayShortLabel(FrenchFR, Wednesday).utf8().data());
325     EXPECT_STREQ("sam.", weekDayShortLabel(FrenchFR, Saturday).utf8().data());
326
327     EXPECT_STREQ("\xE6\x97\xA5", weekDayShortLabel(JapaneseJP, Sunday).utf8().data());
328     EXPECT_STREQ("\xE6\xB0\xB4", weekDayShortLabel(JapaneseJP, Wednesday).utf8().data());
329     EXPECT_STREQ("\xE5\x9C\x9F", weekDayShortLabel(JapaneseJP, Saturday).utf8().data());
330 }
331
332 TEST_F(LocaleWinTest, isRTL)
333 {
334     EXPECT_TRUE(isRTL(ArabicEG));
335     EXPECT_FALSE(isRTL(EnglishUS));
336 }
337
338 #endif
339
340 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
341 TEST_F(LocaleWinTest, dateFormat)
342 {
343     EXPECT_STREQ("y'-'M'-'d", LocaleWin::dateFormat("y-M-d").utf8().data());
344     EXPECT_STREQ("''yy'-'''MM'''-'dd", LocaleWin::dateFormat("''yy-''MM''-dd").utf8().data());
345     EXPECT_STREQ("yyyy'-''''-'MMM'''''-'dd", LocaleWin::dateFormat("yyyy-''''-MMM''''-dd").utf8().data());
346     EXPECT_STREQ("yyyy'-'''''MMMM'-'dd", LocaleWin::dateFormat("yyyy-''''MMMM-dd").utf8().data());
347 }
348
349 TEST_F(LocaleWinTest, timeFormat)
350 {
351     EXPECT_STREQ("h:mm:ss a", timeFormat(EnglishUS).utf8().data());
352     EXPECT_STREQ("HH:mm:ss", timeFormat(FrenchFR).utf8().data());
353     EXPECT_STREQ("H:mm:ss", timeFormat(JapaneseJP).utf8().data());
354 }
355
356 TEST_F(LocaleWinTest, shortTimeFormat)
357 {
358     EXPECT_STREQ("h:mm:ss a", shortTimeFormat(EnglishUS).utf8().data());
359     EXPECT_STREQ("HH:mm:ss", shortTimeFormat(FrenchFR).utf8().data());
360     EXPECT_STREQ("H:mm:ss", shortTimeFormat(JapaneseJP).utf8().data());
361 }
362
363 TEST_F(LocaleWinTest, timeAMPMLabels)
364 {
365     EXPECT_STREQ("AM", timeAMPMLabel(EnglishUS, 0).utf8().data());
366     EXPECT_STREQ("PM", timeAMPMLabel(EnglishUS, 1).utf8().data());
367
368     EXPECT_STREQ("", timeAMPMLabel(FrenchFR, 0).utf8().data());
369     EXPECT_STREQ("", timeAMPMLabel(FrenchFR, 1).utf8().data());
370
371     EXPECT_STREQ("\xE5\x8D\x88\xE5\x89\x8D", timeAMPMLabel(JapaneseJP, 0).utf8().data());
372     EXPECT_STREQ("\xE5\x8D\x88\xE5\xBE\x8C", timeAMPMLabel(JapaneseJP, 1).utf8().data());
373 }
374
375 TEST_F(LocaleWinTest, decimalSeparator)
376 {
377     EXPECT_STREQ(".", decimalSeparator(EnglishUS).utf8().data());
378     EXPECT_STREQ(",", decimalSeparator(FrenchFR).utf8().data());
379 }
380 #endif
381
382 static void testNumberIsReversible(LCID lcid, const char* original, const char* shouldHave = 0)
383 {
384     OwnPtr<LocaleWin> locale = LocaleWin::create(lcid);
385     String localized = locale->convertToLocalizedNumber(original);
386     if (shouldHave)
387         EXPECT_TRUE(localized.contains(shouldHave));
388     String converted = locale->convertFromLocalizedNumber(localized);
389     EXPECT_STREQ(original, converted.utf8().data());
390 }
391
392 void testNumbers(LCID lcid)
393 {
394     testNumberIsReversible(lcid, "123456789012345678901234567890");
395     testNumberIsReversible(lcid, "-123.456");
396     testNumberIsReversible(lcid, ".456");
397     testNumberIsReversible(lcid, "-0.456");
398 }
399
400 TEST_F(LocaleWinTest, localizedNumberRoundTrip)
401 {
402     testNumberIsReversible(EnglishUS, "123456789012345678901234567890");
403     testNumberIsReversible(EnglishUS, "-123.456", ".");
404     testNumberIsReversible(EnglishUS, ".456", ".");
405     testNumberIsReversible(EnglishUS, "-0.456", ".");
406
407     testNumberIsReversible(FrenchFR, "123456789012345678901234567890");
408     testNumberIsReversible(FrenchFR, "-123.456", ",");
409     testNumberIsReversible(FrenchFR, ".456", ",");
410     testNumberIsReversible(FrenchFR, "-0.456", ",");
411
412     // Test some of major locales.
413     testNumbers(ArabicEG);
414     testNumbers(German);
415     testNumbers(Spanish);
416     testNumbers(Persian);
417     testNumbers(JapaneseJP);
418     testNumbers(KoreanKR);
419     testNumbers(ChineseCN);
420     testNumbers(ChineseHK);
421     testNumbers(ChineseTW);
422 }