Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 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. |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 4 | // |
| 5 | // Unit tests for |Feedback| object. |
| 6 | |
| 7 | #include "chrome/browser/spellchecker/feedback.h" |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 8 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 9 | #include "base/strings/utf_string_conversions.h" |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 10 | #include "testing/gtest/include/gtest/gtest.h" |
| 11 | |
| 12 | namespace spellcheck { |
| 13 | |
| 14 | namespace { |
| 15 | |
| 16 | // Identifier for a renderer process. |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 17 | const int kRendererProcessId = 7; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 18 | |
| 19 | // Hash identifier for a misspelling. |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 20 | const uint32 kMisspellingHash = 42; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 21 | |
| 22 | } // namespace |
| 23 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 24 | // A test fixture to help keep the tests simple. |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 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)); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 105 | EXPECT_TRUE(feedback_.GetMisspellingsInRenderer(kRendererProcessId).empty()); |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 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 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 182 | // Should be able to find misspellings by misspelled word. |
| 183 | TEST_F(FeedbackTest, FindMisspellingsByText) { |
| 184 | static const string16 kMisspelledText = |
| 185 | ASCIIToUTF16("Helllo world. Helllo world"); |
| 186 | static const 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<string16>(1, kSuggestion), |
| 203 | ++hash)); |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | static const string16 kOtherMisspelledText = ASCIIToUTF16("Somethign else"); |
| 208 | static const string16 kOtherSuggestion = ASCIIToUTF16("Something"); |
| 209 | static const int kOtherMisspellingStart = 0; |
| 210 | static const int kOtherMisspellingLength = 9; |
| 211 | feedback_.AddMisspelling( |
| 212 | kRendererProcessId, |
| 213 | Misspelling(kOtherMisspelledText, |
| 214 | kOtherMisspellingStart, |
| 215 | kOtherMisspellingLength, |
| 216 | std::vector<string16>(1, kOtherSuggestion), |
| 217 | hash + 1)); |
| 218 | |
| 219 | static const string16 kMisspelledWord = ASCIIToUTF16("Helllo"); |
| 220 | const std::set<uint32>& misspellings = |
| 221 | feedback_.FindMisspellings(kMisspelledWord); |
| 222 | EXPECT_EQ(static_cast<size_t>(kNumberOfSentences * kNumberOfRenderers), |
| 223 | misspellings.size()); |
| 224 | |
| 225 | for (std::set<uint32>::const_iterator it = misspellings.begin(); |
| 226 | it != misspellings.end(); |
| 227 | ++it) { |
| 228 | Misspelling* misspelling = feedback_.GetMisspelling(*it); |
| 229 | EXPECT_NE(static_cast<Misspelling*>(NULL), misspelling); |
| 230 | EXPECT_TRUE(misspelling->hash >= kMisspellingHash && |
| 231 | misspelling->hash <= hash); |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 232 | EXPECT_EQ(kMisspelledWord, misspelling->GetMisspelledString()); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 233 | } |
| 234 | } |
| 235 | |
| 236 | // Should not be able to find misspellings by misspelled word after they have |
| 237 | // been removed. |
| 238 | TEST_F(FeedbackTest, CannotFindMisspellingsByTextAfterErased) { |
| 239 | static const string16 kMisspelledText = ASCIIToUTF16("Helllo world"); |
| 240 | static const string16 kMisspelledWord = ASCIIToUTF16("Helllo"); |
| 241 | static const string16 kSuggestion = ASCIIToUTF16("Hello"); |
| 242 | static const int kMisspellingStart = 0; |
| 243 | static const int kMisspellingLength = 6; |
| 244 | feedback_.AddMisspelling( |
| 245 | kRendererProcessId, |
| 246 | Misspelling(kMisspelledText, |
| 247 | kMisspellingStart, |
| 248 | kMisspellingLength, |
| 249 | std::vector<string16>(1, kSuggestion), |
| 250 | kMisspellingHash)); |
| 251 | feedback_.GetMisspelling(kMisspellingHash)->action.Finalize(); |
| 252 | feedback_.EraseFinalizedMisspellings(kRendererProcessId); |
| 253 | EXPECT_TRUE(feedback_.FindMisspellings(kMisspelledWord).empty()); |
| 254 | } |
| 255 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 256 | } // namespace spellcheck |