Home | History | Annotate | Download | only in text
      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
      6  * are met:
      7  * 1.  Redistributions of source code must retain the above copyright
      8  *     notice, this list of conditions and the following disclaimer.
      9  * 2.  Redistributions in binary form must reproduce the above copyright
     10  *     notice, this list of conditions and the following disclaimer in the
     11  *     documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
     14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     16  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
     17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     20  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     23  * SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "platform/text/DateTimeFormat.h"
     28 
     29 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
     30 #include "wtf/text/CString.h"
     31 #include "wtf/text/StringBuilder.h"
     32 #include <gtest/gtest.h>
     33 
     34 using namespace blink;
     35 
     36 class DateTimeFormatTest : public ::testing::Test {
     37 public:
     38     typedef DateTimeFormat::FieldType FieldType;
     39 
     40     struct Token {
     41         String string;
     42         int count;
     43         FieldType fieldType;
     44 
     45         Token(FieldType fieldType, int count = 1)
     46             : count(count)
     47             , fieldType(fieldType)
     48         {
     49             ASSERT(fieldType != DateTimeFormat::FieldTypeLiteral);
     50         }
     51 
     52         Token(const String& string)
     53             : string(string)
     54             , count(0)
     55             , fieldType(DateTimeFormat::FieldTypeLiteral)
     56         {
     57         }
     58 
     59         bool operator==(const Token& other) const
     60         {
     61             return fieldType == other.fieldType && count == other.count && string == other.string;
     62         }
     63 
     64         String toString() const
     65         {
     66             switch (fieldType) {
     67             case DateTimeFormat::FieldTypeInvalid:
     68                 return "*invalid*";
     69             case DateTimeFormat::FieldTypeLiteral: {
     70                 StringBuilder builder;
     71                 builder.append('"');
     72                 builder.append(string);
     73                 builder.append('"');
     74                 return builder.toString();
     75             }
     76             default:
     77                 return String::format("Token(%d, %d)", fieldType, count);
     78             }
     79         }
     80     };
     81 
     82     class Tokens {
     83     public:
     84         Tokens() { }
     85 
     86         explicit Tokens(const Vector<Token> tokens)
     87             : m_tokens(tokens)
     88         {
     89         }
     90 
     91         explicit Tokens(const String& string)
     92         {
     93             m_tokens.append(Token(string));
     94         }
     95 
     96         explicit Tokens(Token token1)
     97         {
     98             m_tokens.append(token1);
     99         }
    100 
    101         Tokens(Token token1, Token token2)
    102         {
    103             m_tokens.append(token1);
    104             m_tokens.append(token2);
    105         }
    106 
    107         Tokens(Token token1, Token token2, Token token3)
    108         {
    109             m_tokens.append(token1);
    110             m_tokens.append(token2);
    111             m_tokens.append(token3);
    112         }
    113 
    114         Tokens(Token token1, Token token2, Token token3, Token token4)
    115         {
    116             m_tokens.append(token1);
    117             m_tokens.append(token2);
    118             m_tokens.append(token3);
    119             m_tokens.append(token4);
    120         }
    121 
    122         Tokens(Token token1, Token token2, Token token3, Token token4, Token token5)
    123         {
    124             m_tokens.append(token1);
    125             m_tokens.append(token2);
    126             m_tokens.append(token3);
    127             m_tokens.append(token4);
    128             m_tokens.append(token5);
    129         }
    130 
    131         Tokens(Token token1, Token token2, Token token3, Token token4, Token token5, Token token6)
    132         {
    133             m_tokens.append(token1);
    134             m_tokens.append(token2);
    135             m_tokens.append(token3);
    136             m_tokens.append(token4);
    137             m_tokens.append(token5);
    138             m_tokens.append(token6);
    139         }
    140 
    141         bool operator==(const Tokens& other) const
    142         {
    143             return m_tokens == other.m_tokens;
    144         }
    145 
    146         String toString() const
    147         {
    148             StringBuilder builder;
    149             builder.append("Tokens(");
    150             for (unsigned index = 0; index < m_tokens.size(); ++index) {
    151                 if (index)
    152                     builder.append(",");
    153                 builder.append(m_tokens[index].toString());
    154             }
    155             builder.append(")");
    156             return builder.toString();
    157         }
    158 
    159     private:
    160         Vector<Token> m_tokens;
    161     };
    162 
    163 protected:
    164     Tokens parse(const String& formatString)
    165     {
    166         TokenHandler handler;
    167         if (!DateTimeFormat::parse(formatString, handler))
    168             return Tokens(Token("*failed*"));
    169         return handler.tokens();
    170     }
    171 
    172     FieldType single(const char ch)
    173     {
    174         char formatString[2];
    175         formatString[0] = ch;
    176         formatString[1] = 0;
    177         TokenHandler handler;
    178         if (!DateTimeFormat::parse(formatString, handler))
    179             return DateTimeFormat::FieldTypeInvalid;
    180         return handler.fieldType(0);
    181     }
    182 
    183 private:
    184     class TokenHandler : public DateTimeFormat::TokenHandler {
    185     public:
    186         virtual ~TokenHandler() { }
    187 
    188         FieldType fieldType(int index) const
    189         {
    190             return index >=0 && index < static_cast<int>(m_tokens.size()) ? m_tokens[index].fieldType : DateTimeFormat::FieldTypeInvalid;
    191         }
    192 
    193         Tokens tokens() const { return Tokens(m_tokens); }
    194 
    195     private:
    196         virtual void visitField(FieldType fieldType, int count) OVERRIDE
    197         {
    198             m_tokens.append(Token(fieldType, count));
    199         }
    200 
    201         virtual void visitLiteral(const String& string) OVERRIDE
    202         {
    203             m_tokens.append(Token(string));
    204         }
    205 
    206         Vector<Token> m_tokens;
    207     };
    208 };
    209 
    210 std::ostream& operator<<(std::ostream& os, const DateTimeFormatTest::Tokens& tokens)
    211 {
    212     return os << tokens.toString().ascii().data();
    213 }
    214 
    215 TEST_F(DateTimeFormatTest, CommonPattern)
    216 {
    217     EXPECT_EQ(Tokens(), parse(""));
    218 
    219     EXPECT_EQ(
    220         Tokens(
    221             Token(DateTimeFormat::FieldTypeYear, 4), Token("-"),
    222             Token(DateTimeFormat::FieldTypeMonth, 2), Token("-"),
    223             Token(DateTimeFormat::FieldTypeDayOfMonth, 2)),
    224         parse("yyyy-MM-dd"));
    225 
    226     EXPECT_EQ(
    227         Tokens(
    228             Token(DateTimeFormat::FieldTypeHour24, 2), Token(":"),
    229             Token(DateTimeFormat::FieldTypeMinute, 2), Token(":"),
    230             Token(DateTimeFormat::FieldTypeSecond, 2)),
    231         parse("kk:mm:ss"));
    232 
    233     EXPECT_EQ(
    234         Tokens(
    235             Token(DateTimeFormat::FieldTypeHour12), Token(":"),
    236             Token(DateTimeFormat::FieldTypeMinute), Token(" "),
    237             Token(DateTimeFormat::FieldTypePeriod)),
    238         parse("h:m a"));
    239 
    240     EXPECT_EQ(
    241         Tokens(
    242             Token(DateTimeFormat::FieldTypeYear), Token("Nen "),
    243             Token(DateTimeFormat::FieldTypeMonth), Token("Getsu "),
    244             Token(DateTimeFormat::FieldTypeDayOfMonth), Token("Nichi")),
    245         parse("y'Nen' M'Getsu' d'Nichi'"));
    246 }
    247 
    248 TEST_F(DateTimeFormatTest, MissingClosingQuote)
    249 {
    250     EXPECT_EQ(Tokens("*failed*"), parse("'foo"));
    251     EXPECT_EQ(Tokens("*failed*"), parse("fo'o"));
    252     EXPECT_EQ(Tokens("*failed*"), parse("foo'"));
    253 }
    254 
    255 TEST_F(DateTimeFormatTest, Quote)
    256 {
    257     EXPECT_EQ(Tokens("FooBar"), parse("'FooBar'"));
    258     EXPECT_EQ(Tokens("'"), parse("''"));
    259     EXPECT_EQ(Tokens("'-'"), parse("''-''"));
    260     EXPECT_EQ(Tokens("Foo'Bar"), parse("'Foo''Bar'"));
    261     EXPECT_EQ(
    262         Tokens(Token(DateTimeFormat::FieldTypeEra), Token("'s")),
    263         parse("G'''s'"));
    264     EXPECT_EQ(
    265         Tokens(Token(DateTimeFormat::FieldTypeEra), Token("'"), Token(DateTimeFormat::FieldTypeSecond)),
    266         parse("G''s"));
    267 }
    268 
    269 TEST_F(DateTimeFormatTest, SingleLowerCaseCharacter)
    270 {
    271     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('b'));
    272     EXPECT_EQ(DateTimeFormat::FieldTypeLocalDayOfWeekStandAlon, single('c'));
    273     EXPECT_EQ(DateTimeFormat::FieldTypeDayOfMonth, single('d'));
    274     EXPECT_EQ(DateTimeFormat::FieldTypeLocalDayOfWeek, single('e'));
    275     EXPECT_EQ(DateTimeFormat::FieldTypeModifiedJulianDay, single('g'));
    276     EXPECT_EQ(DateTimeFormat::FieldTypeHour12, single('h'));
    277     EXPECT_EQ(DateTimeFormat::FieldTypeHour24, single('k'));
    278     EXPECT_EQ(DateTimeFormat::FieldTypeMinute, single('m'));
    279     EXPECT_EQ(DateTimeFormat::FieldTypeQuaterStandAlone, single('q'));
    280     EXPECT_EQ(DateTimeFormat::FieldTypeSecond, single('s'));
    281     EXPECT_EQ(DateTimeFormat::FieldTypeExtendedYear, single('u'));
    282     EXPECT_EQ(DateTimeFormat::FieldTypeNonLocationZone, single('v'));
    283     EXPECT_EQ(DateTimeFormat::FieldTypeWeekOfMonth, single('W'));
    284     EXPECT_EQ(DateTimeFormat::FieldTypeYear, single('y'));
    285     EXPECT_EQ(DateTimeFormat::FieldTypeZone, single('z'));
    286 }
    287 
    288 TEST_F(DateTimeFormatTest, SingleLowerCaseInvalid)
    289 {
    290     EXPECT_EQ(DateTimeFormat::FieldTypePeriod, single('a'));
    291     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('f'));
    292     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('i'));
    293     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('j'));
    294     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('l'));
    295     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('n'));
    296     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('o'));
    297     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('p'));
    298     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('r'));
    299     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('t'));
    300     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('x'));
    301 }
    302 
    303 TEST_F(DateTimeFormatTest, SingleUpperCaseCharacter)
    304 {
    305     EXPECT_EQ(DateTimeFormat::FieldTypeMillisecondsInDay, single('A'));
    306     EXPECT_EQ(DateTimeFormat::FieldTypeDayOfYear, single('D'));
    307     EXPECT_EQ(DateTimeFormat::FieldTypeDayOfWeek, single('E'));
    308     EXPECT_EQ(DateTimeFormat::FieldTypeDayOfWeekInMonth, single('F'));
    309     EXPECT_EQ(DateTimeFormat::FieldTypeEra, single('G'));
    310     EXPECT_EQ(DateTimeFormat::FieldTypeHour23, single('H'));
    311     EXPECT_EQ(DateTimeFormat::FieldTypeHour11, single('K'));
    312     EXPECT_EQ(DateTimeFormat::FieldTypeMonthStandAlone, single('L'));
    313     EXPECT_EQ(DateTimeFormat::FieldTypeMonth, single('M'));
    314     EXPECT_EQ(DateTimeFormat::FieldTypeQuater, single('Q'));
    315     EXPECT_EQ(DateTimeFormat::FieldTypeFractionalSecond, single('S'));
    316     EXPECT_EQ(DateTimeFormat::FieldTypeWeekOfYear, single('w'));
    317     EXPECT_EQ(DateTimeFormat::FieldTypeYearOfWeekOfYear, single('Y'));
    318     EXPECT_EQ(DateTimeFormat::FieldTypeRFC822Zone, single('Z'));
    319 }
    320 
    321 TEST_F(DateTimeFormatTest, SingleUpperCaseInvalid)
    322 {
    323     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('B'));
    324     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('C'));
    325     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('I'));
    326     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('J'));
    327     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('N'));
    328     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('O'));
    329     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('P'));
    330     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('R'));
    331     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('T'));
    332     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('U'));
    333     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('V'));
    334     EXPECT_EQ(DateTimeFormat::FieldTypeInvalid, single('X'));
    335 }
    336 
    337 #endif
    338