• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
FeedbackTest()27   FeedbackTest() {}
~FeedbackTest()28   virtual ~FeedbackTest() {}
29 
30  protected:
AddMisspelling(int renderer_process_id,uint32 hash)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.
TEST_F(FeedbackTest,RetreiveMisspelling)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.
TEST_F(FeedbackTest,FinalizeRemovedMisspellings)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.
TEST_F(FeedbackTest,DuplicateMisspellingFinalization)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.
TEST_F(FeedbackTest,RendererHasMisspellings)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.
TEST_F(FeedbackTest,GetMisspellingsInRenderer)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.
TEST_F(FeedbackTest,EraseFinalizedMisspellings)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.
TEST_F(FeedbackTest,HasMisspelling)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.
TEST_F(FeedbackTest,EmptyFeedback)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.
TEST_F(FeedbackTest,GetRendersWithMisspellings)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.
TEST_F(FeedbackTest,FinalizeAllMisspellings)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.
TEST_F(FeedbackTest,GetAllMisspellings)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.
TEST_F(FeedbackTest,ClearFeedback)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.
TEST_F(FeedbackTest,FindMisspellingsByText)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.
TEST_F(FeedbackTest,CannotFindMisspellingsByTextAfterErased)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