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 12using base::ASCIIToUTF16; 13 14namespace spellcheck { 15 16namespace { 17 18// Identifier for a renderer process. 19const int kRendererProcessId = 7; 20 21// Hash identifier for a misspelling. 22const uint32 kMisspellingHash = 42; 23 24} // namespace 25 26// A test fixture to help keep the tests simple. 27class 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. 43TEST_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. 52TEST_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. 70TEST_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. 81TEST_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. 88TEST_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. 100TEST_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. 111TEST_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. 118TEST_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. 125TEST_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. 139TEST_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. 162TEST_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. 176TEST_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. 185TEST_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. 241TEST_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