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.
5 // Unit tests for |Feedback| object.
7 #include "chrome/browser/spellchecker/feedback.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 using base::ASCIIToUTF16
;
14 namespace spellcheck
{
18 // Maximum number of bytes of feedback that would be sent to the server at once.
19 const size_t kMaxFeedbackSize
= 1024;
21 // Identifier for a renderer process.
22 const int kRendererProcessId
= 7;
24 // Hash identifier for a misspelling.
25 const uint32 kMisspellingHash
= 42;
29 // A test fixture to help keep the tests simple.
30 class FeedbackTest
: public testing::Test
{
32 FeedbackTest() : feedback_(kMaxFeedbackSize
) {}
33 ~FeedbackTest() override
{}
36 void AddMisspelling(int renderer_process_id
, uint32 hash
) {
37 feedback_
.AddMisspelling(renderer_process_id
,
38 Misspelling(base::string16(), 0, 0,
39 std::vector
<base::string16
>(), hash
));
42 spellcheck::Feedback feedback_
;
45 TEST_F(FeedbackTest
, LimitFeedbackSize
) {
46 // Adding too much feedback data should prevent adding more feedback.
47 feedback_
.AddMisspelling(
50 base::ASCIIToUTF16("0123456789"), 0, 1,
51 std::vector
<base::string16
>(50, base::ASCIIToUTF16("9876543210")),
53 feedback_
.AddMisspelling(
56 base::ASCIIToUTF16("0123456789"), 0, 1,
57 std::vector
<base::string16
>(50, base::ASCIIToUTF16("9876543210")),
59 EXPECT_EQ(nullptr, feedback_
.GetMisspelling(kMisspellingHash
));
61 // Clearing the existing feedback data should allow adding feedback again.
63 feedback_
.AddMisspelling(
66 base::ASCIIToUTF16("0123456789"), 0, 1,
67 std::vector
<base::string16
>(50, base::ASCIIToUTF16("9876543210")),
69 EXPECT_NE(nullptr, feedback_
.GetMisspelling(kMisspellingHash
));
72 // Erasing finalized misspellings should allow adding feedback again.
73 feedback_
.AddMisspelling(
76 base::ASCIIToUTF16("0123456789"), 0, 1,
77 std::vector
<base::string16
>(50, base::ASCIIToUTF16("9876543210")),
79 feedback_
.FinalizeRemovedMisspellings(kRendererProcessId
,
80 std::vector
<uint32
>());
81 feedback_
.EraseFinalizedMisspellings(kRendererProcessId
);
82 feedback_
.AddMisspelling(
85 base::ASCIIToUTF16("0123456789"), 0, 1,
86 std::vector
<base::string16
>(50, base::ASCIIToUTF16("9876543210")),
88 EXPECT_NE(nullptr, feedback_
.GetMisspelling(kMisspellingHash
));
91 // Should be able to retrieve misspelling after it's added.
92 TEST_F(FeedbackTest
, RetreiveMisspelling
) {
93 EXPECT_EQ(nullptr, feedback_
.GetMisspelling(kMisspellingHash
));
94 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
95 Misspelling
* result
= feedback_
.GetMisspelling(kMisspellingHash
);
96 EXPECT_NE(nullptr, result
);
97 EXPECT_EQ(kMisspellingHash
, result
->hash
);
100 // Removed misspellings should be finalized.
101 TEST_F(FeedbackTest
, FinalizeRemovedMisspellings
) {
102 static const int kRemovedMisspellingHash
= 1;
103 static const int kRemainingMisspellingHash
= 2;
104 AddMisspelling(kRendererProcessId
, kRemovedMisspellingHash
);
105 AddMisspelling(kRendererProcessId
, kRemainingMisspellingHash
);
106 std::vector
<uint32
> remaining_markers(1, kRemainingMisspellingHash
);
107 feedback_
.FinalizeRemovedMisspellings(kRendererProcessId
, remaining_markers
);
108 Misspelling
* removed_misspelling
=
109 feedback_
.GetMisspelling(kRemovedMisspellingHash
);
110 EXPECT_NE(nullptr, removed_misspelling
);
111 EXPECT_TRUE(removed_misspelling
->action
.IsFinal());
112 Misspelling
* remaining_misspelling
=
113 feedback_
.GetMisspelling(kRemainingMisspellingHash
);
114 EXPECT_NE(nullptr, remaining_misspelling
);
115 EXPECT_FALSE(remaining_misspelling
->action
.IsFinal());
118 // Duplicate misspellings should not be finalized.
119 TEST_F(FeedbackTest
, DuplicateMisspellingFinalization
) {
120 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
121 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
122 std::vector
<uint32
> remaining_markers(1, kMisspellingHash
);
123 feedback_
.FinalizeRemovedMisspellings(kRendererProcessId
, remaining_markers
);
124 std::vector
<Misspelling
> misspellings
= feedback_
.GetAllMisspellings();
125 EXPECT_EQ(static_cast<size_t>(1), misspellings
.size());
126 EXPECT_FALSE(misspellings
[0].action
.IsFinal());
129 // Misspellings should be associated with a renderer.
130 TEST_F(FeedbackTest
, RendererHasMisspellings
) {
131 EXPECT_FALSE(feedback_
.RendererHasMisspellings(kRendererProcessId
));
132 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
133 EXPECT_TRUE(feedback_
.RendererHasMisspellings(kRendererProcessId
));
136 // Should be able to retrieve misspellings in renderer.
137 TEST_F(FeedbackTest
, GetMisspellingsInRenderer
) {
138 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
139 const std::vector
<Misspelling
>& renderer_with_misspellings
=
140 feedback_
.GetMisspellingsInRenderer(kRendererProcessId
);
141 EXPECT_EQ(static_cast<size_t>(1), renderer_with_misspellings
.size());
142 EXPECT_EQ(kMisspellingHash
, renderer_with_misspellings
[0].hash
);
143 const std::vector
<Misspelling
>& renderer_without_misspellings
=
144 feedback_
.GetMisspellingsInRenderer(kRendererProcessId
+ 1);
145 EXPECT_EQ(static_cast<size_t>(0), renderer_without_misspellings
.size());
148 // Finalized misspellings should be erased.
149 TEST_F(FeedbackTest
, EraseFinalizedMisspellings
) {
150 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
151 feedback_
.FinalizeRemovedMisspellings(kRendererProcessId
,
152 std::vector
<uint32
>());
153 EXPECT_TRUE(feedback_
.RendererHasMisspellings(kRendererProcessId
));
154 feedback_
.EraseFinalizedMisspellings(kRendererProcessId
);
155 EXPECT_FALSE(feedback_
.RendererHasMisspellings(kRendererProcessId
));
156 EXPECT_TRUE(feedback_
.GetMisspellingsInRenderer(kRendererProcessId
).empty());
159 // Should be able to check for misspelling existence.
160 TEST_F(FeedbackTest
, HasMisspelling
) {
161 EXPECT_FALSE(feedback_
.HasMisspelling(kMisspellingHash
));
162 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
163 EXPECT_TRUE(feedback_
.HasMisspelling(kMisspellingHash
));
166 // Should be able to check for feedback data presence.
167 TEST_F(FeedbackTest
, EmptyFeedback
) {
168 EXPECT_TRUE(feedback_
.Empty());
169 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
170 EXPECT_FALSE(feedback_
.Empty());
173 // Should be able to retrieve a list of all renderers with misspellings.
174 TEST_F(FeedbackTest
, GetRendersWithMisspellings
) {
175 EXPECT_TRUE(feedback_
.GetRendersWithMisspellings().empty());
176 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
177 AddMisspelling(kRendererProcessId
+ 1, kMisspellingHash
+ 1);
178 std::vector
<int> result
= feedback_
.GetRendersWithMisspellings();
179 EXPECT_EQ(static_cast<size_t>(2), result
.size());
180 EXPECT_NE(result
[0], result
[1]);
181 EXPECT_TRUE(result
[0] == kRendererProcessId
||
182 result
[0] == kRendererProcessId
+ 1);
183 EXPECT_TRUE(result
[1] == kRendererProcessId
||
184 result
[1] == kRendererProcessId
+ 1);
187 // Should be able to finalize all misspellings.
188 TEST_F(FeedbackTest
, FinalizeAllMisspellings
) {
189 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
190 AddMisspelling(kRendererProcessId
+ 1, kMisspellingHash
+ 1);
192 std::vector
<Misspelling
> pending
= feedback_
.GetAllMisspellings();
193 for (std::vector
<Misspelling
>::const_iterator it
= pending
.begin();
194 it
!= pending
.end(); ++it
) {
195 EXPECT_FALSE(it
->action
.IsFinal());
198 feedback_
.FinalizeAllMisspellings();
200 std::vector
<Misspelling
> final
= feedback_
.GetAllMisspellings();
201 for (std::vector
<Misspelling
>::const_iterator it
= final
.begin();
202 it
!= final
.end(); ++it
) {
203 EXPECT_TRUE(it
->action
.IsFinal());
208 // Should be able to retrieve a copy of all misspellings.
209 TEST_F(FeedbackTest
, GetAllMisspellings
) {
210 EXPECT_TRUE(feedback_
.GetAllMisspellings().empty());
211 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
212 AddMisspelling(kRendererProcessId
+ 1, kMisspellingHash
+ 1);
213 const std::vector
<Misspelling
>& result
= feedback_
.GetAllMisspellings();
214 EXPECT_EQ(static_cast<size_t>(2), result
.size());
215 EXPECT_NE(result
[0].hash
, result
[1].hash
);
216 EXPECT_TRUE(result
[0].hash
== kMisspellingHash
||
217 result
[0].hash
== kMisspellingHash
+ 1);
218 EXPECT_TRUE(result
[1].hash
== kMisspellingHash
||
219 result
[1].hash
== kMisspellingHash
+ 1);
222 // Should be able to clear all misspellings.
223 TEST_F(FeedbackTest
, ClearFeedback
) {
224 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
225 AddMisspelling(kRendererProcessId
+ 1, kMisspellingHash
+ 1);
226 EXPECT_FALSE(feedback_
.Empty());
228 EXPECT_TRUE(feedback_
.Empty());
231 // Should be able to find misspellings by misspelled word.
232 TEST_F(FeedbackTest
, FindMisspellingsByText
) {
233 static const base::string16 kMisspelledText
=
234 ASCIIToUTF16("Helllo world. Helllo world");
235 static const base::string16 kSuggestion
= ASCIIToUTF16("Hello");
236 static const int kMisspellingStart
= 0;
237 static const int kMisspellingLength
= 6;
238 static const int kSentenceLength
= 14;
239 static const int kNumberOfSentences
= 2;
240 static const int kNumberOfRenderers
= 2;
241 uint32 hash
= kMisspellingHash
;
242 for (int renderer_process_id
= kRendererProcessId
;
243 renderer_process_id
< kRendererProcessId
+ kNumberOfRenderers
;
244 ++renderer_process_id
) {
245 for (int j
= 0; j
< kNumberOfSentences
; ++j
) {
246 feedback_
.AddMisspelling(
248 Misspelling(kMisspelledText
, kMisspellingStart
+ j
* kSentenceLength
,
250 std::vector
<base::string16
>(1, kSuggestion
), ++hash
));
254 static const base::string16 kOtherMisspelledText
=
255 ASCIIToUTF16("Somethign else");
256 static const base::string16 kOtherSuggestion
= ASCIIToUTF16("Something");
257 static const int kOtherMisspellingStart
= 0;
258 static const int kOtherMisspellingLength
= 9;
259 feedback_
.AddMisspelling(
261 Misspelling(kOtherMisspelledText
, kOtherMisspellingStart
,
262 kOtherMisspellingLength
,
263 std::vector
<base::string16
>(1, kOtherSuggestion
), hash
+ 1));
265 static const base::string16 kMisspelledWord
= ASCIIToUTF16("Helllo");
266 const std::set
<uint32
>& misspellings
=
267 feedback_
.FindMisspellings(kMisspelledWord
);
268 EXPECT_EQ(static_cast<size_t>(kNumberOfSentences
* kNumberOfRenderers
),
269 misspellings
.size());
271 for (std::set
<uint32
>::const_iterator it
= misspellings
.begin();
272 it
!= misspellings
.end(); ++it
) {
273 Misspelling
* misspelling
= feedback_
.GetMisspelling(*it
);
274 EXPECT_NE(nullptr, misspelling
);
275 EXPECT_TRUE(misspelling
->hash
>= kMisspellingHash
&&
276 misspelling
->hash
<= hash
);
277 EXPECT_EQ(kMisspelledWord
, GetMisspelledString(*misspelling
));
281 // Should not be able to find misspellings by misspelled word after they have
283 TEST_F(FeedbackTest
, CannotFindMisspellingsByTextAfterErased
) {
284 static const base::string16 kMisspelledText
= ASCIIToUTF16("Helllo world");
285 static const base::string16 kMisspelledWord
= ASCIIToUTF16("Helllo");
286 static const base::string16 kSuggestion
= ASCIIToUTF16("Hello");
287 static const int kMisspellingStart
= 0;
288 static const int kMisspellingLength
= 6;
289 feedback_
.AddMisspelling(
291 Misspelling(kMisspelledText
, kMisspellingStart
, kMisspellingLength
,
292 std::vector
<base::string16
>(1, kSuggestion
),
294 feedback_
.GetMisspelling(kMisspellingHash
)->action
.Finalize();
295 feedback_
.EraseFinalizedMisspellings(kRendererProcessId
);
296 EXPECT_TRUE(feedback_
.FindMisspellings(kMisspelledWord
).empty());
299 } // namespace spellcheck