Home | History | Annotate | Download | only in spellchecker
      1 // Copyright (c) 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 // Unit tests for |Feedback| object.
      6 
      7 #include "chrome/browser/spellchecker/feedback.h"
      8 
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 using base::ASCIIToUTF16;
     13 
     14 namespace spellcheck {
     15 
     16 namespace {
     17 
     18 // Identifier for a renderer process.
     19 const int kRendererProcessId = 7;
     20 
     21 // Hash identifier for a misspelling.
     22 const uint32 kMisspellingHash = 42;
     23 
     24 }  // namespace
     25 
     26 // A test fixture to help keep the tests simple.
     27 class FeedbackTest : public testing::Test {
     28  public:
     29   FeedbackTest() {}
     30   virtual ~FeedbackTest() {}
     31 
     32  protected:
     33   void AddMisspelling(int renderer_process_id, uint32 hash) {
     34     Misspelling misspelling;
     35     misspelling.hash = hash;
     36     feedback_.AddMisspelling(renderer_process_id, misspelling);
     37   }
     38 
     39   spellcheck::Feedback feedback_;
     40 };
     41 
     42 // Should be able to retrieve misspelling after it's added.
     43 TEST_F(FeedbackTest, RetreiveMisspelling) {
     44   EXPECT_EQ(NULL, feedback_.GetMisspelling(kMisspellingHash));
     45   AddMisspelling(kRendererProcessId, kMisspellingHash);
     46   Misspelling* result = feedback_.GetMisspelling(kMisspellingHash);
     47   EXPECT_NE(static_cast<Misspelling*>(NULL), result);
     48   EXPECT_EQ(kMisspellingHash, result->hash);
     49 }
     50 
     51 // Removed misspellings should be finalized.
     52 TEST_F(FeedbackTest, FinalizeRemovedMisspellings) {
     53   static const int kRemovedMisspellingHash = 1;
     54   static const int kRemainingMisspellingHash = 2;
     55   AddMisspelling(kRendererProcessId, kRemovedMisspellingHash);
     56   AddMisspelling(kRendererProcessId, kRemainingMisspellingHash);
     57   std::vector<uint32> remaining_markers(1, kRemainingMisspellingHash);
     58   feedback_.FinalizeRemovedMisspellings(kRendererProcessId, remaining_markers);
     59   Misspelling* removed_misspelling =
     60       feedback_.GetMisspelling(kRemovedMisspellingHash);
     61   EXPECT_NE(static_cast<Misspelling*>(NULL), removed_misspelling);
     62   EXPECT_TRUE(removed_misspelling->action.IsFinal());
     63   Misspelling* remaining_misspelling =
     64       feedback_.GetMisspelling(kRemainingMisspellingHash);
     65   EXPECT_NE(static_cast<Misspelling*>(NULL), remaining_misspelling);
     66   EXPECT_FALSE(remaining_misspelling->action.IsFinal());
     67 }
     68 
     69 // Duplicate misspellings should not be finalized.
     70 TEST_F(FeedbackTest, DuplicateMisspellingFinalization) {
     71   AddMisspelling(kRendererProcessId, kMisspellingHash);
     72   AddMisspelling(kRendererProcessId, kMisspellingHash);
     73   std::vector<uint32> remaining_markers(1, kMisspellingHash);
     74   feedback_.FinalizeRemovedMisspellings(kRendererProcessId, remaining_markers);
     75   std::vector<Misspelling> misspellings = feedback_.GetAllMisspellings();
     76   EXPECT_EQ(static_cast<size_t>(1), misspellings.size());
     77   EXPECT_FALSE(misspellings[0].action.IsFinal());
     78 }
     79 
     80 // Misspellings should be associated with a renderer.
     81 TEST_F(FeedbackTest, RendererHasMisspellings) {
     82   EXPECT_FALSE(feedback_.RendererHasMisspellings(kRendererProcessId));
     83   AddMisspelling(kRendererProcessId, kMisspellingHash);
     84   EXPECT_TRUE(feedback_.RendererHasMisspellings(kRendererProcessId));
     85 }
     86 
     87 // Should be able to retrieve misspellings in renderer.
     88 TEST_F(FeedbackTest, GetMisspellingsInRenderer) {
     89   AddMisspelling(kRendererProcessId, kMisspellingHash);
     90   const std::vector<Misspelling>& renderer_with_misspellings =
     91       feedback_.GetMisspellingsInRenderer(kRendererProcessId);
     92   EXPECT_EQ(static_cast<size_t>(1), renderer_with_misspellings.size());
     93   EXPECT_EQ(kMisspellingHash, renderer_with_misspellings[0].hash);
     94   const std::vector<Misspelling>& renderer_without_misspellings =
     95       feedback_.GetMisspellingsInRenderer(kRendererProcessId + 1);
     96   EXPECT_EQ(static_cast<size_t>(0), renderer_without_misspellings.size());
     97 }
     98 
     99 // Finalized misspellings should be erased.
    100 TEST_F(FeedbackTest, EraseFinalizedMisspellings) {
    101   AddMisspelling(kRendererProcessId, kMisspellingHash);
    102   feedback_.FinalizeRemovedMisspellings(kRendererProcessId,
    103                                         std::vector<uint32>());
    104   EXPECT_TRUE(feedback_.RendererHasMisspellings(kRendererProcessId));
    105   feedback_.EraseFinalizedMisspellings(kRendererProcessId);
    106   EXPECT_FALSE(feedback_.RendererHasMisspellings(kRendererProcessId));
    107   EXPECT_TRUE(feedback_.GetMisspellingsInRenderer(kRendererProcessId).empty());
    108 }
    109 
    110 // Should be able to check for misspelling existence.
    111 TEST_F(FeedbackTest, HasMisspelling) {
    112   EXPECT_FALSE(feedback_.HasMisspelling(kMisspellingHash));
    113   AddMisspelling(kRendererProcessId, kMisspellingHash);
    114   EXPECT_TRUE(feedback_.HasMisspelling(kMisspellingHash));
    115 }
    116 
    117 // Should be able to check for feedback data presence.
    118 TEST_F(FeedbackTest, EmptyFeedback) {
    119   EXPECT_TRUE(feedback_.Empty());
    120   AddMisspelling(kRendererProcessId, kMisspellingHash);
    121   EXPECT_FALSE(feedback_.Empty());
    122 }
    123 
    124 // Should be able to retrieve a list of all renderers with misspellings.
    125 TEST_F(FeedbackTest, GetRendersWithMisspellings) {
    126   EXPECT_TRUE(feedback_.GetRendersWithMisspellings().empty());
    127   AddMisspelling(kRendererProcessId, kMisspellingHash);
    128   AddMisspelling(kRendererProcessId + 1, kMisspellingHash + 1);
    129   std::vector<int> result = feedback_.GetRendersWithMisspellings();
    130   EXPECT_EQ(static_cast<size_t>(2), result.size());
    131   EXPECT_NE(result[0], result[1]);
    132   EXPECT_TRUE(result[0] == kRendererProcessId ||
    133               result[0] == kRendererProcessId + 1);
    134   EXPECT_TRUE(result[1] == kRendererProcessId ||
    135               result[1] == kRendererProcessId + 1);
    136 }
    137 
    138 // Should be able to finalize all misspellings.
    139 TEST_F(FeedbackTest, FinalizeAllMisspellings) {
    140   AddMisspelling(kRendererProcessId, kMisspellingHash);
    141   AddMisspelling(kRendererProcessId + 1, kMisspellingHash + 1);
    142   {
    143     std::vector<Misspelling> pending = feedback_.GetAllMisspellings();
    144     for (std::vector<Misspelling>::const_iterator it = pending.begin();
    145          it != pending.end();
    146          ++it) {
    147       EXPECT_FALSE(it->action.IsFinal());
    148     }
    149   }
    150   feedback_.FinalizeAllMisspellings();
    151   {
    152     std::vector<Misspelling> final = feedback_.GetAllMisspellings();
    153     for (std::vector<Misspelling>::const_iterator it = final.begin();
    154          it != final.end();
    155          ++it) {
    156       EXPECT_TRUE(it->action.IsFinal());
    157     }
    158   }
    159 }
    160 
    161 // Should be able to retrieve a copy of all misspellings.
    162 TEST_F(FeedbackTest, GetAllMisspellings) {
    163   EXPECT_TRUE(feedback_.GetAllMisspellings().empty());
    164   AddMisspelling(kRendererProcessId, kMisspellingHash);
    165   AddMisspelling(kRendererProcessId + 1, kMisspellingHash + 1);
    166   const std::vector<Misspelling>& result = feedback_.GetAllMisspellings();
    167   EXPECT_EQ(static_cast<size_t>(2), result.size());
    168   EXPECT_NE(result[0].hash, result[1].hash);
    169   EXPECT_TRUE(result[0].hash == kMisspellingHash ||
    170               result[0].hash == kMisspellingHash + 1);
    171   EXPECT_TRUE(result[1].hash == kMisspellingHash ||
    172               result[1].hash == kMisspellingHash + 1);
    173 }
    174 
    175 // Should be able to clear all misspellings.
    176 TEST_F(FeedbackTest, ClearFeedback) {
    177   AddMisspelling(kRendererProcessId, kMisspellingHash);
    178   AddMisspelling(kRendererProcessId + 1, kMisspellingHash + 1);
    179   EXPECT_FALSE(feedback_.Empty());
    180   feedback_.Clear();
    181   EXPECT_TRUE(feedback_.Empty());
    182 }
    183 
    184 // Should be able to find misspellings by misspelled word.
    185 TEST_F(FeedbackTest, FindMisspellingsByText) {
    186   static const base::string16 kMisspelledText =
    187       ASCIIToUTF16("Helllo world. Helllo world");
    188   static const base::string16 kSuggestion = ASCIIToUTF16("Hello");
    189   static const int kMisspellingStart = 0;
    190   static const int kMisspellingLength = 6;
    191   static const int kSentenceLength = 14;
    192   static const int kNumberOfSentences = 2;
    193   static const int kNumberOfRenderers = 2;
    194   uint32 hash = kMisspellingHash;
    195   for (int renderer_process_id = kRendererProcessId;
    196        renderer_process_id < kRendererProcessId + kNumberOfRenderers;
    197        ++renderer_process_id) {
    198     for (int j = 0; j < kNumberOfSentences; ++j) {
    199       feedback_.AddMisspelling(
    200           renderer_process_id,
    201           Misspelling(kMisspelledText,
    202                       kMisspellingStart + j * kSentenceLength,
    203                       kMisspellingLength,
    204                       std::vector<base::string16>(1, kSuggestion),
    205                       ++hash));
    206     }
    207   }
    208 
    209   static const base::string16 kOtherMisspelledText =
    210       ASCIIToUTF16("Somethign else");
    211   static const base::string16 kOtherSuggestion = ASCIIToUTF16("Something");
    212   static const int kOtherMisspellingStart = 0;
    213   static const int kOtherMisspellingLength = 9;
    214   feedback_.AddMisspelling(
    215       kRendererProcessId,
    216       Misspelling(kOtherMisspelledText,
    217                   kOtherMisspellingStart,
    218                   kOtherMisspellingLength,
    219                   std::vector<base::string16>(1, kOtherSuggestion),
    220                   hash + 1));
    221 
    222   static const base::string16 kMisspelledWord = ASCIIToUTF16("Helllo");
    223   const std::set<uint32>& misspellings =
    224       feedback_.FindMisspellings(kMisspelledWord);
    225   EXPECT_EQ(static_cast<size_t>(kNumberOfSentences * kNumberOfRenderers),
    226             misspellings.size());
    227 
    228   for (std::set<uint32>::const_iterator it = misspellings.begin();
    229        it != misspellings.end();
    230       ++it) {
    231     Misspelling* misspelling = feedback_.GetMisspelling(*it);
    232     EXPECT_NE(static_cast<Misspelling*>(NULL), misspelling);
    233     EXPECT_TRUE(misspelling->hash >= kMisspellingHash &&
    234                 misspelling->hash <= hash);
    235     EXPECT_EQ(kMisspelledWord, misspelling->GetMisspelledString());
    236   }
    237 }
    238 
    239 // Should not be able to find misspellings by misspelled word after they have
    240 // been removed.
    241 TEST_F(FeedbackTest, CannotFindMisspellingsByTextAfterErased) {
    242   static const base::string16 kMisspelledText = ASCIIToUTF16("Helllo world");
    243   static const base::string16 kMisspelledWord = ASCIIToUTF16("Helllo");
    244   static const base::string16 kSuggestion = ASCIIToUTF16("Hello");
    245   static const int kMisspellingStart = 0;
    246   static const int kMisspellingLength = 6;
    247   feedback_.AddMisspelling(
    248       kRendererProcessId,
    249       Misspelling(kMisspelledText,
    250                   kMisspellingStart,
    251                   kMisspellingLength,
    252                   std::vector<base::string16>(1, kSuggestion),
    253                   kMisspellingHash));
    254   feedback_.GetMisspelling(kMisspellingHash)->action.Finalize();
    255   feedback_.EraseFinalizedMisspellings(kRendererProcessId);
    256   EXPECT_TRUE(feedback_.FindMisspellings(kMisspelledWord).empty());
    257 }
    258 
    259 }  // namespace spellcheck
    260