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 // Identifier for a renderer process.
19 const int kRendererProcessId
= 7;
21 // Hash identifier for a misspelling.
22 const uint32 kMisspellingHash
= 42;
26 // A test fixture to help keep the tests simple.
27 class FeedbackTest
: public testing::Test
{
30 ~FeedbackTest() override
{}
33 void AddMisspelling(int renderer_process_id
, uint32 hash
) {
34 Misspelling misspelling
;
35 misspelling
.hash
= hash
;
36 feedback_
.AddMisspelling(renderer_process_id
, misspelling
);
39 spellcheck::Feedback feedback_
;
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
);
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());
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());
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
));
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());
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());
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
));
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());
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);
138 // Should be able to finalize all misspellings.
139 TEST_F(FeedbackTest
, FinalizeAllMisspellings
) {
140 AddMisspelling(kRendererProcessId
, kMisspellingHash
);
141 AddMisspelling(kRendererProcessId
+ 1, kMisspellingHash
+ 1);
143 std::vector
<Misspelling
> pending
= feedback_
.GetAllMisspellings();
144 for (std::vector
<Misspelling
>::const_iterator it
= pending
.begin();
145 it
!= pending
.end(); ++it
) {
146 EXPECT_FALSE(it
->action
.IsFinal());
149 feedback_
.FinalizeAllMisspellings();
151 std::vector
<Misspelling
> final
= feedback_
.GetAllMisspellings();
152 for (std::vector
<Misspelling
>::const_iterator it
= final
.begin();
153 it
!= final
.end(); ++it
) {
154 EXPECT_TRUE(it
->action
.IsFinal());
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);
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());
179 EXPECT_TRUE(feedback_
.Empty());
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(
199 Misspelling(kMisspelledText
, kMisspellingStart
+ j
* kSentenceLength
,
201 std::vector
<base::string16
>(1, kSuggestion
), ++hash
));
205 static const base::string16 kOtherMisspelledText
=
206 ASCIIToUTF16("Somethign else");
207 static const base::string16 kOtherSuggestion
= ASCIIToUTF16("Something");
208 static const int kOtherMisspellingStart
= 0;
209 static const int kOtherMisspellingLength
= 9;
210 feedback_
.AddMisspelling(
212 Misspelling(kOtherMisspelledText
, kOtherMisspellingStart
,
213 kOtherMisspellingLength
,
214 std::vector
<base::string16
>(1, kOtherSuggestion
), hash
+ 1));
216 static const base::string16 kMisspelledWord
= ASCIIToUTF16("Helllo");
217 const std::set
<uint32
>& misspellings
=
218 feedback_
.FindMisspellings(kMisspelledWord
);
219 EXPECT_EQ(static_cast<size_t>(kNumberOfSentences
* kNumberOfRenderers
),
220 misspellings
.size());
222 for (std::set
<uint32
>::const_iterator it
= misspellings
.begin();
223 it
!= misspellings
.end(); ++it
) {
224 Misspelling
* misspelling
= feedback_
.GetMisspelling(*it
);
225 EXPECT_NE(static_cast<Misspelling
*>(NULL
), misspelling
);
226 EXPECT_TRUE(misspelling
->hash
>= kMisspellingHash
&&
227 misspelling
->hash
<= hash
);
228 EXPECT_EQ(kMisspelledWord
, misspelling
->GetMisspelledString());
232 // Should not be able to find misspellings by misspelled word after they have
234 TEST_F(FeedbackTest
, CannotFindMisspellingsByTextAfterErased
) {
235 static const base::string16 kMisspelledText
= ASCIIToUTF16("Helllo world");
236 static const base::string16 kMisspelledWord
= ASCIIToUTF16("Helllo");
237 static const base::string16 kSuggestion
= ASCIIToUTF16("Hello");
238 static const int kMisspellingStart
= 0;
239 static const int kMisspellingLength
= 6;
240 feedback_
.AddMisspelling(
242 Misspelling(kMisspelledText
, kMisspellingStart
, kMisspellingLength
,
243 std::vector
<base::string16
>(1, kSuggestion
),
245 feedback_
.GetMisspelling(kMisspellingHash
)->action
.Finalize();
246 feedback_
.EraseFinalizedMisspellings(kRendererProcessId
);
247 EXPECT_TRUE(feedback_
.FindMisspellings(kMisspelledWord
).empty());
250 } // namespace spellcheck