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