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