Home | History | Annotate | Download | only in integration
      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.
      4 
      5 #include "chrome/browser/sync/test/integration/dictionary_helper.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/format_macros.h"
     10 #include "base/strings/stringprintf.h"
     11 #include "chrome/browser/profiles/profile.h"
     12 #include "chrome/browser/spellchecker/spellcheck_factory.h"
     13 #include "chrome/browser/spellchecker/spellcheck_service.h"
     14 #include "chrome/browser/sync/test/integration/dictionary_load_observer.h"
     15 #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h"
     16 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
     17 #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
     18 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
     19 #include "chrome/browser/sync/test/integration/sync_test.h"
     20 #include "chrome/common/chrome_switches.h"
     21 #include "chrome/common/spellcheck_common.h"
     22 #include "content/public/test/test_utils.h"
     23 
     24 class DictionarySyncIntegrationTestHelper {
     25  public:
     26   // Same as SpellcheckCustomDictionary::AddWord/RemoveWord, except does not
     27   // write to disk.
     28   static bool ApplyChange(
     29       SpellcheckCustomDictionary* dictionary,
     30       SpellcheckCustomDictionary::Change& change) {
     31     int result = change.Sanitize(dictionary->GetWords());
     32     dictionary->Apply(change);
     33     dictionary->Notify(change);
     34     dictionary->Sync(change);
     35     return !result;
     36   }
     37 
     38   DISALLOW_COPY_AND_ASSIGN(DictionarySyncIntegrationTestHelper);
     39 };
     40 
     41 
     42 namespace dictionary_helper {
     43 namespace {
     44 
     45 SpellcheckCustomDictionary* GetDictionary(int index) {
     46   return SpellcheckServiceFactory::GetForContext(
     47       sync_datatype_helper::test()->GetProfile(index))->GetCustomDictionary();
     48 }
     49 
     50 SpellcheckCustomDictionary* GetVerifierDictionary() {
     51   return SpellcheckServiceFactory::GetForContext(
     52       sync_datatype_helper::test()->verifier())->GetCustomDictionary();
     53 }
     54 
     55 void LoadDictionary(SpellcheckCustomDictionary* dictionary) {
     56   if (dictionary->IsLoaded())
     57     return;
     58   base::RunLoop run_loop;
     59   DictionaryLoadObserver observer(content::GetQuitTaskForRunLoop(&run_loop));
     60   dictionary->AddObserver(&observer);
     61   dictionary->Load();
     62   content::RunThisRunLoop(&run_loop);
     63   dictionary->RemoveObserver(&observer);
     64   ASSERT_TRUE(dictionary->IsLoaded());
     65 }
     66 
     67 }  // namespace
     68 
     69 
     70 void LoadDictionaries() {
     71   for (int i = 0; i < sync_datatype_helper::test()->num_clients(); ++i)
     72     LoadDictionary(GetDictionary(i));
     73   if (sync_datatype_helper::test()->use_verifier())
     74     LoadDictionary(GetVerifierDictionary());
     75 }
     76 
     77 size_t GetDictionarySize(int index) {
     78   return GetDictionary(index)->GetWords().size();
     79 }
     80 
     81 size_t GetVerifierDictionarySize() {
     82   return GetVerifierDictionary()->GetWords().size();
     83 }
     84 
     85 bool DictionariesMatch() {
     86   const chrome::spellcheck_common::WordSet& reference =
     87       sync_datatype_helper::test()->use_verifier()
     88           ? GetVerifierDictionary()->GetWords()
     89           : GetDictionary(0)->GetWords();
     90   for (int i = 0; i < sync_datatype_helper::test()->num_clients(); ++i) {
     91     const chrome::spellcheck_common::WordSet& dictionary =
     92         GetDictionary(i)->GetWords();
     93     if (reference.size() != dictionary.size() ||
     94         !std::equal(reference.begin(), reference.end(), dictionary.begin())) {
     95       return false;
     96     }
     97   }
     98   return true;
     99 }
    100 
    101 namespace {
    102 
    103 // Helper class used in the implementation of AwaitDictionariesMatch.
    104 class DictionaryMatchStatusChecker : public MultiClientStatusChangeChecker {
    105  public:
    106   DictionaryMatchStatusChecker();
    107   virtual ~DictionaryMatchStatusChecker();
    108 
    109   virtual bool IsExitConditionSatisfied() OVERRIDE;
    110   virtual std::string GetDebugMessage() const OVERRIDE;
    111 };
    112 
    113 DictionaryMatchStatusChecker::DictionaryMatchStatusChecker()
    114     : MultiClientStatusChangeChecker(
    115         sync_datatype_helper::test()->GetSyncServices()) {}
    116 
    117 DictionaryMatchStatusChecker::~DictionaryMatchStatusChecker() {}
    118 
    119 bool DictionaryMatchStatusChecker::IsExitConditionSatisfied() {
    120   return DictionariesMatch();
    121 }
    122 
    123 std::string DictionaryMatchStatusChecker::GetDebugMessage() const {
    124   return "Waiting for matching dictionaries";
    125 }
    126 
    127 // Helper class used in the implementation of AwaitNumDictionaryEntries.
    128 class NumDictionaryEntriesStatusChecker
    129     : public SingleClientStatusChangeChecker {
    130  public:
    131   NumDictionaryEntriesStatusChecker(int index, size_t num_words);
    132   virtual ~NumDictionaryEntriesStatusChecker();
    133 
    134   virtual bool IsExitConditionSatisfied() OVERRIDE;
    135   virtual std::string GetDebugMessage() const OVERRIDE;
    136  private:
    137   int index_;
    138   size_t num_words_;
    139 };
    140 
    141 NumDictionaryEntriesStatusChecker::NumDictionaryEntriesStatusChecker(
    142     int index, size_t num_words)
    143   : SingleClientStatusChangeChecker(
    144       sync_datatype_helper::test()->GetSyncService(index)),
    145   index_(index),
    146   num_words_(num_words) {}
    147 
    148 NumDictionaryEntriesStatusChecker::~NumDictionaryEntriesStatusChecker() {}
    149 
    150 bool NumDictionaryEntriesStatusChecker::IsExitConditionSatisfied() {
    151   return GetDictionarySize(index_) == num_words_;
    152 }
    153 
    154 std::string NumDictionaryEntriesStatusChecker::GetDebugMessage() const {
    155   return base::StringPrintf(
    156       "Waiting for client %d: %" PRIuS " / %" PRIuS " words downloaded",
    157       index_, GetDictionarySize(index_), num_words_);
    158 }
    159 
    160 }  // namespace
    161 
    162 bool AwaitDictionariesMatch() {
    163   DictionaryMatchStatusChecker checker;
    164   checker.Wait();
    165   return !checker.TimedOut();
    166 }
    167 
    168 bool AwaitNumDictionaryEntries(int index, size_t num_words) {
    169   NumDictionaryEntriesStatusChecker checker(index, num_words);
    170   checker.Wait();
    171   return !checker.TimedOut();
    172 }
    173 
    174 bool DictionaryMatchesVerifier(int index) {
    175   const chrome::spellcheck_common::WordSet& expected =
    176       GetVerifierDictionary()->GetWords();
    177   const chrome::spellcheck_common::WordSet& actual =
    178       GetDictionary(index)->GetWords();
    179   return expected.size() == actual.size() &&
    180          std::equal(expected.begin(), expected.end(), actual.begin());
    181 }
    182 
    183 bool AddWord(int index, const std::string& word) {
    184   SpellcheckCustomDictionary::Change dictionary_change;
    185   dictionary_change.AddWord(word);
    186   bool result = DictionarySyncIntegrationTestHelper::ApplyChange(
    187       GetDictionary(index), dictionary_change);
    188   if (sync_datatype_helper::test()->use_verifier()) {
    189     result &= DictionarySyncIntegrationTestHelper::ApplyChange(
    190         GetVerifierDictionary(), dictionary_change);
    191   }
    192   return result;
    193 }
    194 
    195 bool RemoveWord(int index, const std::string& word) {
    196   SpellcheckCustomDictionary::Change dictionary_change;
    197   dictionary_change.RemoveWord(word);
    198   bool result = DictionarySyncIntegrationTestHelper::ApplyChange(
    199       GetDictionary(index), dictionary_change);
    200   if (sync_datatype_helper::test()->use_verifier()) {
    201     result &= DictionarySyncIntegrationTestHelper::ApplyChange(
    202         GetVerifierDictionary(), dictionary_change);
    203   }
    204   return result;
    205 }
    206 
    207 }  // namespace dictionary_helper
    208