Home | History | Annotate | Download | only in test
      1 // Copyright 2014 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 "components/bookmarks/test/bookmark_test_helpers.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/callback.h"
      9 #include "base/compiler_specific.h"
     10 #include "base/logging.h"
     11 #include "base/run_loop.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "components/bookmarks/browser/base_bookmark_model_observer.h"
     14 #include "components/bookmarks/browser/bookmark_model.h"
     15 #include "url/gurl.h"
     16 
     17 namespace {
     18 
     19 // BookmarkLoadObserver is used when blocking until the BookmarkModel finishes
     20 // loading. As soon as the BookmarkModel finishes loading the message loop is
     21 // quit.
     22 class BookmarkLoadObserver : public BaseBookmarkModelObserver {
     23  public:
     24   explicit BookmarkLoadObserver(const base::Closure& quit_task);
     25   virtual ~BookmarkLoadObserver();
     26 
     27  private:
     28   // BaseBookmarkModelObserver:
     29   virtual void BookmarkModelChanged() OVERRIDE;
     30   virtual void BookmarkModelLoaded(BookmarkModel* model,
     31                                    bool ids_reassigned) OVERRIDE;
     32 
     33   base::Closure quit_task_;
     34 
     35   DISALLOW_COPY_AND_ASSIGN(BookmarkLoadObserver);
     36 };
     37 
     38 BookmarkLoadObserver::BookmarkLoadObserver(const base::Closure& quit_task)
     39     : quit_task_(quit_task) {}
     40 
     41 BookmarkLoadObserver::~BookmarkLoadObserver() {}
     42 
     43 void BookmarkLoadObserver::BookmarkModelChanged() {}
     44 
     45 void BookmarkLoadObserver::BookmarkModelLoaded(BookmarkModel* model,
     46                                                bool ids_reassigned) {
     47   quit_task_.Run();
     48 }
     49 
     50 // Helper function which does the actual work of creating the nodes for
     51 // a particular level in the hierarchy.
     52 std::string::size_type AddNodesFromString(BookmarkModel* model,
     53                                           const BookmarkNode* node,
     54                                           const std::string& model_string,
     55                                           std::string::size_type start_pos) {
     56   DCHECK(node);
     57   int index = node->child_count();
     58   static const std::string folder_tell(":[");
     59   std::string::size_type end_pos = model_string.find(' ', start_pos);
     60   while (end_pos != std::string::npos) {
     61     std::string::size_type part_length = end_pos - start_pos;
     62     std::string node_name = model_string.substr(start_pos, part_length);
     63     // Are we at the end of a folder group?
     64     if (node_name != "]") {
     65       // No, is it a folder?
     66       std::string tell;
     67       if (part_length > 2)
     68         tell = node_name.substr(part_length - 2, 2);
     69       if (tell == folder_tell) {
     70         node_name = node_name.substr(0, part_length - 2);
     71         const BookmarkNode* new_node =
     72             model->AddFolder(node, index, base::UTF8ToUTF16(node_name));
     73         end_pos = AddNodesFromString(model, new_node, model_string,
     74                                      end_pos + 1);
     75       } else {
     76         std::string url_string("http://");
     77         url_string += std::string(node_name.begin(), node_name.end());
     78         url_string += ".com";
     79         model->AddURL(
     80             node, index, base::UTF8ToUTF16(node_name), GURL(url_string));
     81         ++end_pos;
     82       }
     83       ++index;
     84       start_pos = end_pos;
     85       end_pos = model_string.find(' ', start_pos);
     86     } else {
     87       ++end_pos;
     88       break;
     89     }
     90   }
     91   return end_pos;
     92 }
     93 
     94 }  // namespace
     95 
     96 namespace test {
     97 
     98 void WaitForBookmarkModelToLoad(BookmarkModel* model) {
     99   if (model->loaded())
    100     return;
    101   base::RunLoop run_loop;
    102   base::MessageLoop::ScopedNestableTaskAllower allow(
    103       base::MessageLoop::current());
    104 
    105   BookmarkLoadObserver observer(run_loop.QuitClosure());
    106   model->AddObserver(&observer);
    107   run_loop.Run();
    108   model->RemoveObserver(&observer);
    109   DCHECK(model->loaded());
    110 }
    111 
    112 std::string ModelStringFromNode(const BookmarkNode* node) {
    113   // Since the children of the node are not available as a vector,
    114   // we'll just have to do it the hard way.
    115   int child_count = node->child_count();
    116   std::string child_string;
    117   for (int i = 0; i < child_count; ++i) {
    118     const BookmarkNode* child = node->GetChild(i);
    119     if (child->is_folder()) {
    120       child_string += base::UTF16ToUTF8(child->GetTitle()) + ":[ " +
    121           ModelStringFromNode(child) + "] ";
    122     } else {
    123       child_string += base::UTF16ToUTF8(child->GetTitle()) + " ";
    124     }
    125   }
    126   return child_string;
    127 }
    128 
    129 void AddNodesFromModelString(BookmarkModel* model,
    130                              const BookmarkNode* node,
    131                              const std::string& model_string) {
    132   DCHECK(node);
    133   std::string::size_type start_pos = 0;
    134   std::string::size_type end_pos =
    135       AddNodesFromString(model, node, model_string, start_pos);
    136   DCHECK(end_pos == std::string::npos);
    137 }
    138 
    139 }  // namespace test
    140