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