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 using base::ASCIIToUTF16; 13 14 namespace spellcheck { 15 16 namespace { 17 18 // Identifier for a renderer process. 19 const int kRendererProcessId = 7; 20 21 // Hash identifier for a misspelling. 22 const uint32 kMisspellingHash = 42; 23 24 } // namespace 25 26 // A test fixture to help keep the tests simple. 27 class FeedbackTest : public testing::Test { 28 public: 29 FeedbackTest() {} 30 virtual ~FeedbackTest() {} 31 32 protected: 33 void AddMisspelling(int renderer_process_id, uint32 hash) { 34 Misspelling misspelling; 35 misspelling.hash = hash; 36 feedback_.AddMisspelling(renderer_process_id, misspelling); 37 } 38 39 spellcheck::Feedback feedback_; 40 }; 41 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); 49 } 50 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()); 67 } 68 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()); 78 } 79 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)); 85 } 86 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()); 97 } 98 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()); 108 } 109 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)); 115 } 116 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()); 122 } 123 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); 136 } 137 138 // Should be able to finalize all misspellings. 139 TEST_F(FeedbackTest, FinalizeAllMisspellings) { 140 AddMisspelling(kRendererProcessId, kMisspellingHash); 141 AddMisspelling(kRendererProcessId + 1, kMisspellingHash + 1); 142 { 143 std::vector<Misspelling> pending = feedback_.GetAllMisspellings(); 144 for (std::vector<Misspelling>::const_iterator it = pending.begin(); 145 it != pending.end(); 146 ++it) { 147 EXPECT_FALSE(it->action.IsFinal()); 148 } 149 } 150 feedback_.FinalizeAllMisspellings(); 151 { 152 std::vector<Misspelling> final = feedback_.GetAllMisspellings(); 153 for (std::vector<Misspelling>::const_iterator it = final.begin(); 154 it != final.end(); 155 ++it) { 156 EXPECT_TRUE(it->action.IsFinal()); 157 } 158 } 159 } 160 161 // Should be able to retrieve a copy of all misspellings. 162 TEST_F(FeedbackTest, GetAllMisspellings) { 163 EXPECT_TRUE(feedback_.GetAllMisspellings().empty()); 164 AddMisspelling(kRendererProcessId, kMisspellingHash); 165 AddMisspelling(kRendererProcessId + 1, kMisspellingHash + 1); 166 const std::vector<Misspelling>& result = feedback_.GetAllMisspellings(); 167 EXPECT_EQ(static_cast<size_t>(2), result.size()); 168 EXPECT_NE(result[0].hash, result[1].hash); 169 EXPECT_TRUE(result[0].hash == kMisspellingHash || 170 result[0].hash == kMisspellingHash + 1); 171 EXPECT_TRUE(result[1].hash == kMisspellingHash || 172 result[1].hash == kMisspellingHash + 1); 173 } 174 175 // Should be able to clear all misspellings. 176 TEST_F(FeedbackTest, ClearFeedback) { 177 AddMisspelling(kRendererProcessId, kMisspellingHash); 178 AddMisspelling(kRendererProcessId + 1, kMisspellingHash + 1); 179 EXPECT_FALSE(feedback_.Empty()); 180 feedback_.Clear(); 181 EXPECT_TRUE(feedback_.Empty()); 182 } 183 184 // Should be able to find misspellings by misspelled word. 185 TEST_F(FeedbackTest, FindMisspellingsByText) { 186 static const base::string16 kMisspelledText = 187 ASCIIToUTF16("Helllo world. Helllo world"); 188 static const base::string16 kSuggestion = ASCIIToUTF16("Hello"); 189 static const int kMisspellingStart = 0; 190 static const int kMisspellingLength = 6; 191 static const int kSentenceLength = 14; 192 static const int kNumberOfSentences = 2; 193 static const int kNumberOfRenderers = 2; 194 uint32 hash = kMisspellingHash; 195 for (int renderer_process_id = kRendererProcessId; 196 renderer_process_id < kRendererProcessId + kNumberOfRenderers; 197 ++renderer_process_id) { 198 for (int j = 0; j < kNumberOfSentences; ++j) { 199 feedback_.AddMisspelling( 200 renderer_process_id, 201 Misspelling(kMisspelledText, 202 kMisspellingStart + j * kSentenceLength, 203 kMisspellingLength, 204 std::vector<base::string16>(1, kSuggestion), 205 ++hash)); 206 } 207 } 208 209 static const base::string16 kOtherMisspelledText = 210 ASCIIToUTF16("Somethign else"); 211 static const base::string16 kOtherSuggestion = ASCIIToUTF16("Something"); 212 static const int kOtherMisspellingStart = 0; 213 static const int kOtherMisspellingLength = 9; 214 feedback_.AddMisspelling( 215 kRendererProcessId, 216 Misspelling(kOtherMisspelledText, 217 kOtherMisspellingStart, 218 kOtherMisspellingLength, 219 std::vector<base::string16>(1, kOtherSuggestion), 220 hash + 1)); 221 222 static const base::string16 kMisspelledWord = ASCIIToUTF16("Helllo"); 223 const std::set<uint32>& misspellings = 224 feedback_.FindMisspellings(kMisspelledWord); 225 EXPECT_EQ(static_cast<size_t>(kNumberOfSentences * kNumberOfRenderers), 226 misspellings.size()); 227 228 for (std::set<uint32>::const_iterator it = misspellings.begin(); 229 it != misspellings.end(); 230 ++it) { 231 Misspelling* misspelling = feedback_.GetMisspelling(*it); 232 EXPECT_NE(static_cast<Misspelling*>(NULL), misspelling); 233 EXPECT_TRUE(misspelling->hash >= kMisspellingHash && 234 misspelling->hash <= hash); 235 EXPECT_EQ(kMisspelledWord, misspelling->GetMisspelledString()); 236 } 237 } 238 239 // Should not be able to find misspellings by misspelled word after they have 240 // been removed. 241 TEST_F(FeedbackTest, CannotFindMisspellingsByTextAfterErased) { 242 static const base::string16 kMisspelledText = ASCIIToUTF16("Helllo world"); 243 static const base::string16 kMisspelledWord = ASCIIToUTF16("Helllo"); 244 static const base::string16 kSuggestion = ASCIIToUTF16("Hello"); 245 static const int kMisspellingStart = 0; 246 static const int kMisspellingLength = 6; 247 feedback_.AddMisspelling( 248 kRendererProcessId, 249 Misspelling(kMisspelledText, 250 kMisspellingStart, 251 kMisspellingLength, 252 std::vector<base::string16>(1, kSuggestion), 253 kMisspellingHash)); 254 feedback_.GetMisspelling(kMisspellingHash)->action.Finalize(); 255 feedback_.EraseFinalizedMisspellings(kRendererProcessId); 256 EXPECT_TRUE(feedback_.FindMisspellings(kMisspelledWord).empty()); 257 } 258 259 } // namespace spellcheck 260