Home | History | Annotate | Download | only in search
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/app_list/search/tokenized_string_char_iterator.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/strings/string_util.h"
     11 #include "base/strings/stringprintf.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 namespace app_list {
     16 namespace test {
     17 
     18 namespace {
     19 
     20 // Returns a string represents the current state of |iter|. The state string
     21 // has three fields. The first is the current char. The second is the offset of
     22 // the current char in terms of the original text of the TokenizedString. The
     23 // last one is optional and only shows up when IsFirstCharOfToken returns true.
     24 std::string GetIterateState(const TokenizedStringCharIterator& iter) {
     25   return base::StringPrintf("%s%d%s",
     26                             base::UTF16ToUTF8(
     27                                 base::string16(1, iter.Get())).c_str(),
     28                             iter.GetArrayPos(),
     29                             iter.IsFirstCharOfToken() ? "!" : "");
     30 }
     31 
     32 void TestBeyondTheEnd(TokenizedStringCharIterator* iter) {
     33   ASSERT_TRUE(iter->end());
     34   ASSERT_FALSE(iter->NextChar());
     35   ASSERT_FALSE(iter->NextToken());
     36 
     37   // Don't care what it returns, but this shouldn't crash.
     38   iter->Get();
     39 }
     40 
     41 void TestEveryChar(const std::string& text, const std::string& expects) {
     42   TokenizedString tokens(base::UTF8ToUTF16(text));
     43   TokenizedStringCharIterator iter(tokens);
     44 
     45   std::vector<std::string> results;
     46   while (!iter.end()) {
     47     results.push_back(GetIterateState(iter));
     48     iter.NextChar();
     49   }
     50 
     51   EXPECT_EQ(expects, JoinString(results, ' '));
     52   TestBeyondTheEnd(&iter);
     53 }
     54 
     55 void TestNextToken(const std::string& text, const std::string& expects) {
     56   TokenizedString tokens(base::UTF8ToUTF16(text));
     57   TokenizedStringCharIterator iter(tokens);
     58 
     59   std::vector<std::string> results;
     60   while (!iter.end()) {
     61     results.push_back(GetIterateState(iter));
     62     iter.NextToken();
     63   }
     64 
     65   EXPECT_EQ(expects, JoinString(results, ' '));
     66   TestBeyondTheEnd(&iter);
     67 }
     68 
     69 void TestFirstTwoCharInEveryToken(const std::string& text,
     70                                   const std::string& expects) {
     71   TokenizedString tokens(base::UTF8ToUTF16(text));
     72   TokenizedStringCharIterator iter(tokens);
     73 
     74   std::vector<std::string> results;
     75   while (!iter.end()) {
     76     results.push_back(GetIterateState(iter));
     77     if (iter.NextChar())
     78       results.push_back(GetIterateState(iter));
     79 
     80     iter.NextToken();
     81   }
     82 
     83   EXPECT_EQ(expects, JoinString(results, ' '));
     84   TestBeyondTheEnd(&iter);
     85 }
     86 
     87 }  // namespace
     88 
     89 TEST(TokenizedStringCharIteratorTest, NoTerms) {
     90   const char* text;
     91 
     92   text = "";
     93   TestEveryChar(text, "");
     94   TestNextToken(text, "");
     95   TestFirstTwoCharInEveryToken(text, "");
     96 
     97   text = "!@#$%^&*()<<<**>>>";
     98   TestEveryChar(text, "");
     99   TestNextToken(text, "");
    100   TestFirstTwoCharInEveryToken(text, "");
    101 }
    102 
    103 TEST(TokenizedStringCharIteratorTest, Basic) {
    104   const char* text;
    105 
    106   text = "c";
    107   TestEveryChar(text, "c0!");
    108   TestNextToken(text, "c0!");
    109   TestFirstTwoCharInEveryToken(text, "c0!");
    110 
    111   text = "Simple";
    112   TestEveryChar(text, "s0! i1 m2 p3 l4 e5");
    113   TestNextToken(text, "s0!");
    114   TestFirstTwoCharInEveryToken(text, "s0! i1");
    115 
    116   text = "ScratchPad";
    117   TestEveryChar(text, "s0! c1 r2 a3 t4 c5 h6 p7! a8 d9");
    118   TestNextToken(text, "s0! p7!");
    119   TestFirstTwoCharInEveryToken(text, "s0! c1 p7! a8");
    120 
    121   text = "Chess2.0";
    122   TestEveryChar(text, "c0! h1 e2 s3 s4 25! .6 07");
    123   TestNextToken(text, "c0! 25!");
    124   TestFirstTwoCharInEveryToken(text, "c0! h1 25! .6");
    125 
    126   text = "Cut the rope";
    127   TestEveryChar(text, "c0! u1 t2 t4! h5 e6 r8! o9 p10 e11");
    128   TestNextToken(text, "c0! t4! r8!");
    129   TestFirstTwoCharInEveryToken(text, "c0! u1 t4! h5 r8! o9");
    130 
    131   text = "AutoCAD WS";
    132   TestEveryChar(text, "a0! u1 t2 o3 c4! a5 d6 w8! s9");
    133   TestNextToken(text, "a0! c4! w8!");
    134   TestFirstTwoCharInEveryToken(text, "a0! u1 c4! a5 w8! s9");
    135 
    136   text = "Great TweetDeck";
    137   TestEveryChar(text, "g0! r1 e2 a3 t4 t6! w7 e8 e9 t10 d11! e12 c13 k14");
    138   TestNextToken(text, "g0! t6! d11!");
    139   TestFirstTwoCharInEveryToken(text, "g0! r1 t6! w7 d11! e12");
    140 
    141   text = "Draw-It!";
    142   TestEveryChar(text, "d0! r1 a2 w3 i5! t6");
    143   TestNextToken(text, "d0! i5!");
    144   TestFirstTwoCharInEveryToken(text, "d0! r1 i5! t6");
    145 
    146   text = "Faxing & Signing";
    147   TestEveryChar(text, "f0! a1 x2 i3 n4 g5 s9! i10 g11 n12 i13 n14 g15");
    148   TestNextToken(text, "f0! s9!");
    149   TestFirstTwoCharInEveryToken(text, "f0! a1 s9! i10");
    150 }
    151 
    152 }  // namespace test
    153 }  // namespace app_list
    154