1 // Copyright (c) 2011 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 #include "chrome/browser/sync/test/integration/dictionary_helper.h"
10 #include "base/format_macros.h"
11 #include "base/macros.h"
12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h"
14 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h"
15 #include "chrome/browser/spellchecker/spellcheck_factory.h"
16 #include "chrome/browser/spellchecker/spellcheck_service.h"
17 #include "chrome/browser/sync/test/integration/dictionary_load_observer.h"
18 #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h"
19 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
20 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
21 #include "chrome/browser/sync/test/integration/sync_test.h"
22 #include "content/public/test/test_utils.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 class DictionarySyncIntegrationTestHelper
{
27 // Same as SpellcheckCustomDictionary::AddWord/RemoveWord, except does not
29 static bool ApplyChange(
30 SpellcheckCustomDictionary
* dictionary
,
31 SpellcheckCustomDictionary::Change
& change
) {
32 int result
= change
.Sanitize(dictionary
->GetWords());
33 dictionary
->Apply(change
);
34 dictionary
->Notify(change
);
35 dictionary
->Sync(change
);
39 DISALLOW_COPY_AND_ASSIGN(DictionarySyncIntegrationTestHelper
);
43 namespace dictionary_helper
{
46 SpellcheckCustomDictionary
* GetDictionary(int index
) {
47 return SpellcheckServiceFactory::GetForContext(
48 sync_datatype_helper::test()->GetProfile(index
))->GetCustomDictionary();
51 SpellcheckCustomDictionary
* GetVerifierDictionary() {
52 return SpellcheckServiceFactory::GetForContext(
53 sync_datatype_helper::test()->verifier())->GetCustomDictionary();
56 void LoadDictionary(SpellcheckCustomDictionary
* dictionary
) {
57 if (dictionary
->IsLoaded())
59 base::RunLoop run_loop
;
60 DictionaryLoadObserver
observer(content::GetQuitTaskForRunLoop(&run_loop
));
61 dictionary
->AddObserver(&observer
);
63 content::RunThisRunLoop(&run_loop
);
64 dictionary
->RemoveObserver(&observer
);
65 ASSERT_TRUE(dictionary
->IsLoaded());
71 void LoadDictionaries() {
72 for (int i
= 0; i
< sync_datatype_helper::test()->num_clients(); ++i
)
73 LoadDictionary(GetDictionary(i
));
74 if (sync_datatype_helper::test()->use_verifier())
75 LoadDictionary(GetVerifierDictionary());
78 size_t GetDictionarySize(int index
) {
79 return GetDictionary(index
)->GetWords().size();
82 size_t GetVerifierDictionarySize() {
83 return GetVerifierDictionary()->GetWords().size();
86 bool DictionariesMatch() {
87 const std::set
<std::string
>& reference
=
88 sync_datatype_helper::test()->use_verifier()
89 ? GetVerifierDictionary()->GetWords()
90 : GetDictionary(0)->GetWords();
91 for (int i
= 0; i
< sync_datatype_helper::test()->num_clients(); ++i
) {
92 const std::set
<std::string
>& dictionary
= GetDictionary(i
)->GetWords();
93 if (reference
.size() != dictionary
.size() ||
94 !std::equal(reference
.begin(), reference
.end(), dictionary
.begin())) {
103 // Helper class used in the implementation of AwaitDictionariesMatch.
104 class DictionaryMatchStatusChecker
: public MultiClientStatusChangeChecker
{
106 DictionaryMatchStatusChecker();
107 ~DictionaryMatchStatusChecker() override
;
109 bool IsExitConditionSatisfied() override
;
110 std::string
GetDebugMessage() const override
;
113 DictionaryMatchStatusChecker::DictionaryMatchStatusChecker()
114 : MultiClientStatusChangeChecker(
115 sync_datatype_helper::test()->GetSyncServices()) {}
117 DictionaryMatchStatusChecker::~DictionaryMatchStatusChecker() {}
119 bool DictionaryMatchStatusChecker::IsExitConditionSatisfied() {
120 return DictionariesMatch();
123 std::string
DictionaryMatchStatusChecker::GetDebugMessage() const {
124 return "Waiting for matching dictionaries";
127 // Helper class used in the implementation of AwaitNumDictionaryEntries.
128 class NumDictionaryEntriesStatusChecker
129 : public SingleClientStatusChangeChecker
{
131 NumDictionaryEntriesStatusChecker(int index
, size_t num_words
);
132 ~NumDictionaryEntriesStatusChecker() override
;
134 bool IsExitConditionSatisfied() override
;
135 std::string
GetDebugMessage() const override
;
142 NumDictionaryEntriesStatusChecker::NumDictionaryEntriesStatusChecker(
143 int index
, size_t num_words
)
144 : SingleClientStatusChangeChecker(
145 sync_datatype_helper::test()->GetSyncService(index
)),
147 num_words_(num_words
) {}
149 NumDictionaryEntriesStatusChecker::~NumDictionaryEntriesStatusChecker() {}
151 bool NumDictionaryEntriesStatusChecker::IsExitConditionSatisfied() {
152 return GetDictionarySize(index_
) == num_words_
;
155 std::string
NumDictionaryEntriesStatusChecker::GetDebugMessage() const {
156 return base::StringPrintf(
157 "Waiting for client %d: %" PRIuS
" / %" PRIuS
" words downloaded",
158 index_
, GetDictionarySize(index_
), num_words_
);
163 bool AwaitDictionariesMatch() {
164 DictionaryMatchStatusChecker checker
;
166 return !checker
.TimedOut();
169 bool AwaitNumDictionaryEntries(int index
, size_t num_words
) {
170 NumDictionaryEntriesStatusChecker
checker(index
, num_words
);
172 return !checker
.TimedOut();
175 bool DictionaryMatchesVerifier(int index
) {
176 const std::set
<std::string
>& expected
= GetVerifierDictionary()->GetWords();
177 const std::set
<std::string
>& actual
= GetDictionary(index
)->GetWords();
178 return expected
.size() == actual
.size() &&
179 std::equal(expected
.begin(), expected
.end(), actual
.begin());
182 bool AddWord(int index
, const std::string
& word
) {
183 SpellcheckCustomDictionary::Change dictionary_change
;
184 dictionary_change
.AddWord(word
);
185 bool result
= DictionarySyncIntegrationTestHelper::ApplyChange(
186 GetDictionary(index
), dictionary_change
);
187 if (sync_datatype_helper::test()->use_verifier()) {
188 result
&= DictionarySyncIntegrationTestHelper::ApplyChange(
189 GetVerifierDictionary(), dictionary_change
);
194 bool RemoveWord(int index
, const std::string
& word
) {
195 SpellcheckCustomDictionary::Change dictionary_change
;
196 dictionary_change
.RemoveWord(word
);
197 bool result
= DictionarySyncIntegrationTestHelper::ApplyChange(
198 GetDictionary(index
), dictionary_change
);
199 if (sync_datatype_helper::test()->use_verifier()) {
200 result
&= DictionarySyncIntegrationTestHelper::ApplyChange(
201 GetVerifierDictionary(), dictionary_change
);
206 } // namespace dictionary_helper