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.
5 #include "components/bookmarks/test/bookmark_test_helpers.h"
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"
22 // BookmarkLoadObserver is used when blocking until the BookmarkModel finishes
23 // loading. As soon as the BookmarkModel finishes loading the message loop is
25 class BookmarkLoadObserver
: public BaseBookmarkModelObserver
{
27 explicit BookmarkLoadObserver(const base::Closure
& quit_task
);
28 ~BookmarkLoadObserver() override
;
31 // BaseBookmarkModelObserver:
32 void BookmarkModelChanged() override
;
33 void BookmarkModelLoaded(BookmarkModel
* model
, bool ids_reassigned
) override
;
35 base::Closure quit_task_
;
37 DISALLOW_COPY_AND_ASSIGN(BookmarkLoadObserver
);
40 BookmarkLoadObserver::BookmarkLoadObserver(const base::Closure
& quit_task
)
41 : quit_task_(quit_task
) {}
43 BookmarkLoadObserver::~BookmarkLoadObserver() {}
45 void BookmarkLoadObserver::BookmarkModelChanged() {}
47 void BookmarkLoadObserver::BookmarkModelLoaded(BookmarkModel
* model
,
48 bool ids_reassigned
) {
52 // Helper function which does the actual work of creating the nodes for
53 // a particular level in the hierarchy.
54 std::string::size_type
AddNodesFromString(BookmarkModel
* model
,
55 const BookmarkNode
* node
,
56 const std::string
& model_string
,
57 std::string::size_type start_pos
) {
59 int index
= node
->child_count();
60 static const std::string
folder_tell(":[");
61 std::string::size_type end_pos
= model_string
.find(' ', start_pos
);
62 while (end_pos
!= std::string::npos
) {
63 std::string::size_type part_length
= end_pos
- start_pos
;
64 std::string node_name
= model_string
.substr(start_pos
, part_length
);
65 // Are we at the end of a folder group?
66 if (node_name
!= "]") {
67 // No, is it a folder?
70 tell
= node_name
.substr(part_length
- 2, 2);
71 if (tell
== folder_tell
) {
72 node_name
= node_name
.substr(0, part_length
- 2);
73 const BookmarkNode
* new_node
=
74 model
->AddFolder(node
, index
, base::UTF8ToUTF16(node_name
));
75 end_pos
= AddNodesFromString(model
, new_node
, model_string
,
78 std::string
url_string("http://");
79 url_string
+= std::string(node_name
.begin(), node_name
.end());
82 node
, index
, base::UTF8ToUTF16(node_name
), GURL(url_string
));
87 end_pos
= model_string
.find(' ', start_pos
);
98 void WaitForBookmarkModelToLoad(BookmarkModel
* model
) {
101 base::RunLoop run_loop
;
102 base::MessageLoop::ScopedNestableTaskAllower
allow(
103 base::MessageLoop::current());
105 BookmarkLoadObserver
observer(run_loop
.QuitClosure());
106 model
->AddObserver(&observer
);
108 model
->RemoveObserver(&observer
);
109 DCHECK(model
->loaded());
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
) + "] ";
123 child_string
+= base::UTF16ToUTF8(child
->GetTitle()) + " ";
129 void AddNodesFromModelString(BookmarkModel
* model
,
130 const BookmarkNode
* node
,
131 const std::string
& model_string
) {
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
);
140 } // namespace bookmarks