• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "platform/text/LocaleWin.h"
33 
34 #include <gtest/gtest.h>
35 #include "platform/DateComponents.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 
dateComponents(int year,int month,int day)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 
msForDate(int year,int month,int day)82     double msForDate(int year, int month, int day)
83     {
84         return dateToDaysFrom1970(year, month, day) * msPerDay;
85     }
86 
formatDate(LCID lcid,int year,int month,int day)87     String formatDate(LCID lcid, int year, int month, int day)
88     {
89         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
90         return locale->formatDateTime(dateComponents(year, month, day));
91     }
92 
firstDayOfWeek(LCID lcid)93     unsigned firstDayOfWeek(LCID lcid)
94     {
95         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
96         return locale->firstDayOfWeek();
97     }
98 
monthLabel(LCID lcid,unsigned index)99     String monthLabel(LCID lcid, unsigned index)
100     {
101         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
102         return locale->monthLabels()[index];
103     }
104 
weekDayShortLabel(LCID lcid,unsigned index)105     String weekDayShortLabel(LCID lcid, unsigned index)
106     {
107         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
108         return locale->weekDayShortLabels()[index];
109     }
110 
isRTL(LCID lcid)111     bool isRTL(LCID lcid)
112     {
113         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
114         return locale->isRTL();
115     }
116 
117 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
monthFormat(LCID lcid)118     String monthFormat(LCID lcid)
119     {
120         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
121         return locale->monthFormat();
122     }
123 
timeFormat(LCID lcid)124     String timeFormat(LCID lcid)
125     {
126         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
127         return locale->timeFormat();
128     }
129 
shortTimeFormat(LCID lcid)130     String shortTimeFormat(LCID lcid)
131     {
132         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
133         return locale->shortTimeFormat();
134     }
135 
shortMonthLabel(LCID lcid,unsigned index)136     String shortMonthLabel(LCID lcid, unsigned index)
137     {
138         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
139         return locale->shortMonthLabels()[index];
140     }
141 
timeAMPMLabel(LCID lcid,unsigned index)142     String timeAMPMLabel(LCID lcid, unsigned index)
143     {
144         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
145         return locale->timeAMPMLabels()[index];
146     }
147 
decimalSeparator(LCID lcid)148     String decimalSeparator(LCID lcid)
149     {
150         OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
151         return locale->localizedDecimalSeparator();
152     }
153 #endif
154 };
155 
TEST_F(LocaleWinTest,formatDate)156 TEST_F(LocaleWinTest, formatDate)
157 {
158     EXPECT_STREQ("04/27/2005", formatDate(EnglishUS, 2005, April, 27).utf8().data());
159     EXPECT_STREQ("27/04/2005", formatDate(FrenchFR, 2005, April, 27).utf8().data());
160     EXPECT_STREQ("2005/04/27", formatDate(JapaneseJP, 2005, April, 27).utf8().data());
161 }
162 
TEST_F(LocaleWinTest,firstDayOfWeek)163 TEST_F(LocaleWinTest, firstDayOfWeek)
164 {
165     EXPECT_EQ(Sunday, firstDayOfWeek(EnglishUS));
166     EXPECT_EQ(Monday, firstDayOfWeek(FrenchFR));
167     EXPECT_EQ(Sunday, firstDayOfWeek(JapaneseJP));
168 }
169 
TEST_F(LocaleWinTest,monthLabels)170 TEST_F(LocaleWinTest, monthLabels)
171 {
172     EXPECT_STREQ("January", monthLabel(EnglishUS, January).utf8().data());
173     EXPECT_STREQ("June", monthLabel(EnglishUS, June).utf8().data());
174     EXPECT_STREQ("December", monthLabel(EnglishUS, December).utf8().data());
175 
176     EXPECT_STREQ("janvier", monthLabel(FrenchFR, January).utf8().data());
177     EXPECT_STREQ("juin", monthLabel(FrenchFR, June).utf8().data());
178     EXPECT_STREQ("d\xC3\xA9" "cembre", monthLabel(FrenchFR, December).utf8().data());
179 
180     EXPECT_STREQ("1\xE6\x9C\x88", monthLabel(JapaneseJP, January).utf8().data());
181     EXPECT_STREQ("6\xE6\x9C\x88", monthLabel(JapaneseJP, June).utf8().data());
182     EXPECT_STREQ("12\xE6\x9C\x88", monthLabel(JapaneseJP, December).utf8().data());
183 }
184 
TEST_F(LocaleWinTest,weekDayShortLabels)185 TEST_F(LocaleWinTest, weekDayShortLabels)
186 {
187     EXPECT_STREQ("Sun", weekDayShortLabel(EnglishUS, Sunday).utf8().data());
188     EXPECT_STREQ("Wed", weekDayShortLabel(EnglishUS, Wednesday).utf8().data());
189     EXPECT_STREQ("Sat", weekDayShortLabel(EnglishUS, Saturday).utf8().data());
190 
191     EXPECT_STREQ("dim.", weekDayShortLabel(FrenchFR, Sunday).utf8().data());
192     EXPECT_STREQ("mer.", weekDayShortLabel(FrenchFR, Wednesday).utf8().data());
193     EXPECT_STREQ("sam.", weekDayShortLabel(FrenchFR, Saturday).utf8().data());
194 
195     EXPECT_STREQ("\xE6\x97\xA5", weekDayShortLabel(JapaneseJP, Sunday).utf8().data());
196     EXPECT_STREQ("\xE6\xB0\xB4", weekDayShortLabel(JapaneseJP, Wednesday).utf8().data());
197     EXPECT_STREQ("\xE5\x9C\x9F", weekDayShortLabel(JapaneseJP, Saturday).utf8().data());
198 }
199 
TEST_F(LocaleWinTest,isRTL)200 TEST_F(LocaleWinTest, isRTL)
201 {
202     EXPECT_TRUE(isRTL(ArabicEG));
203     EXPECT_FALSE(isRTL(EnglishUS));
204 }
205 
206 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
TEST_F(LocaleWinTest,dateFormat)207 TEST_F(LocaleWinTest, dateFormat)
208 {
209     EXPECT_STREQ("y-M-d", LocaleWin::dateFormat("y-M-d").utf8().data());
210     EXPECT_STREQ("''yy'-'''MM'''-'dd", LocaleWin::dateFormat("''yy-''MM''-dd").utf8().data());
211     EXPECT_STREQ("yyyy'-''''-'MMM'''''-'dd", LocaleWin::dateFormat("yyyy-''''-MMM''''-dd").utf8().data());
212     EXPECT_STREQ("yyyy'-'''''MMMM-dd", LocaleWin::dateFormat("yyyy-''''MMMM-dd").utf8().data());
213 }
214 
TEST_F(LocaleWinTest,monthFormat)215 TEST_F(LocaleWinTest, monthFormat)
216 {
217     EXPECT_STREQ("MMMM, yyyy", monthFormat(EnglishUS).utf8().data());
218     EXPECT_STREQ("MMMM yyyy", monthFormat(FrenchFR).utf8().data());
219     EXPECT_STREQ("yyyy\xE5\xB9\xB4M\xE6\x9C\x88", monthFormat(JapaneseJP).utf8().data());
220 }
221 
TEST_F(LocaleWinTest,timeFormat)222 TEST_F(LocaleWinTest, timeFormat)
223 {
224     EXPECT_STREQ("h:mm:ss a", timeFormat(EnglishUS).utf8().data());
225     EXPECT_STREQ("HH:mm:ss", timeFormat(FrenchFR).utf8().data());
226     EXPECT_STREQ("H:mm:ss", timeFormat(JapaneseJP).utf8().data());
227 }
228 
TEST_F(LocaleWinTest,shortTimeFormat)229 TEST_F(LocaleWinTest, shortTimeFormat)
230 {
231     EXPECT_STREQ("h:mm a", shortTimeFormat(EnglishUS).utf8().data());
232     EXPECT_STREQ("HH:mm", shortTimeFormat(FrenchFR).utf8().data());
233     EXPECT_STREQ("H:mm", shortTimeFormat(JapaneseJP).utf8().data());
234 }
235 
TEST_F(LocaleWinTest,shortMonthLabels)236 TEST_F(LocaleWinTest, shortMonthLabels)
237 {
238     EXPECT_STREQ("Jan", shortMonthLabel(EnglishUS, 0).utf8().data());
239     EXPECT_STREQ("Dec", shortMonthLabel(EnglishUS, 11).utf8().data());
240     EXPECT_STREQ("janv.", shortMonthLabel(FrenchFR, 0).utf8().data());
241     EXPECT_STREQ("d\xC3\xA9" "c.", shortMonthLabel(FrenchFR, 11).utf8().data());
242     EXPECT_STREQ("1", shortMonthLabel(JapaneseJP, 0).utf8().data());
243     EXPECT_STREQ("12", shortMonthLabel(JapaneseJP, 11).utf8().data());
244 }
245 
TEST_F(LocaleWinTest,timeAMPMLabels)246 TEST_F(LocaleWinTest, timeAMPMLabels)
247 {
248     EXPECT_STREQ("AM", timeAMPMLabel(EnglishUS, 0).utf8().data());
249     EXPECT_STREQ("PM", timeAMPMLabel(EnglishUS, 1).utf8().data());
250 
251     EXPECT_STREQ("", timeAMPMLabel(FrenchFR, 0).utf8().data());
252     EXPECT_STREQ("", timeAMPMLabel(FrenchFR, 1).utf8().data());
253 
254     EXPECT_STREQ("\xE5\x8D\x88\xE5\x89\x8D", timeAMPMLabel(JapaneseJP, 0).utf8().data());
255     EXPECT_STREQ("\xE5\x8D\x88\xE5\xBE\x8C", timeAMPMLabel(JapaneseJP, 1).utf8().data());
256 }
257 
TEST_F(LocaleWinTest,decimalSeparator)258 TEST_F(LocaleWinTest, decimalSeparator)
259 {
260     EXPECT_STREQ(".", decimalSeparator(EnglishUS).utf8().data());
261     EXPECT_STREQ(",", decimalSeparator(FrenchFR).utf8().data());
262 }
263 #endif
264 
testNumberIsReversible(LCID lcid,const char * original,const char * shouldHave=0)265 static void testNumberIsReversible(LCID lcid, const char* original, const char* shouldHave = 0)
266 {
267     OwnPtr<LocaleWin> locale = LocaleWin::create(lcid, true /* defaultsForLocale */);
268     String localized = locale->convertToLocalizedNumber(original);
269     if (shouldHave)
270         EXPECT_TRUE(localized.contains(shouldHave));
271     String converted = locale->convertFromLocalizedNumber(localized);
272     EXPECT_STREQ(original, converted.utf8().data());
273 }
274 
testNumbers(LCID lcid)275 void testNumbers(LCID lcid)
276 {
277     testNumberIsReversible(lcid, "123456789012345678901234567890");
278     testNumberIsReversible(lcid, "-123.456");
279     testNumberIsReversible(lcid, ".456");
280     testNumberIsReversible(lcid, "-0.456");
281 }
282 
TEST_F(LocaleWinTest,localizedNumberRoundTrip)283 TEST_F(LocaleWinTest, localizedNumberRoundTrip)
284 {
285     testNumberIsReversible(EnglishUS, "123456789012345678901234567890");
286     testNumberIsReversible(EnglishUS, "-123.456", ".");
287     testNumberIsReversible(EnglishUS, ".456", ".");
288     testNumberIsReversible(EnglishUS, "-0.456", ".");
289 
290     testNumberIsReversible(FrenchFR, "123456789012345678901234567890");
291     testNumberIsReversible(FrenchFR, "-123.456", ",");
292     testNumberIsReversible(FrenchFR, ".456", ",");
293     testNumberIsReversible(FrenchFR, "-0.456", ",");
294 
295     // Test some of major locales.
296     testNumbers(ArabicEG);
297     testNumbers(German);
298     testNumbers(Spanish);
299     testNumbers(Persian);
300     testNumbers(JapaneseJP);
301     testNumbers(KoreanKR);
302     testNumbers(ChineseCN);
303     testNumbers(ChineseHK);
304     testNumbers(ChineseTW);
305 }
306