• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
BookmarkLoadObserver(const base::Closure & quit_task)38 BookmarkLoadObserver::BookmarkLoadObserver(const base::Closure& quit_task)
39     : quit_task_(quit_task) {}
40 
~BookmarkLoadObserver()41 BookmarkLoadObserver::~BookmarkLoadObserver() {}
42 
BookmarkModelChanged()43 void BookmarkLoadObserver::BookmarkModelChanged() {}
44 
BookmarkModelLoaded(BookmarkModel * model,bool ids_reassigned)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.
AddNodesFromString(BookmarkModel * model,const BookmarkNode * node,const std::string & model_string,std::string::size_type start_pos)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 
WaitForBookmarkModelToLoad(BookmarkModel * model)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 
ModelStringFromNode(const BookmarkNode * node)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 
AddNodesFromModelString(BookmarkModel * model,const BookmarkNode * node,const std::string & model_string)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