Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(290)

Side by Side Diff: mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc

Issue 274733004: Deletion/ownership (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/services/public/cpp/view_manager/view_manager.h" 5 #include "mojo/services/public/cpp/view_manager/view_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h" 9 #include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
10 #include "mojo/services/public/cpp/view_manager/util.h" 10 #include "mojo/services/public/cpp/view_manager/util.h"
(...skipping 13 matching lines...) Expand all
24 current_run_loop->Run(); 24 current_run_loop->Run();
25 current_run_loop = NULL; 25 current_run_loop = NULL;
26 } 26 }
27 27
28 void QuitRunLoop() { 28 void QuitRunLoop() {
29 current_run_loop->Quit(); 29 current_run_loop->Quit();
30 } 30 }
31 31
32 // ViewManager ----------------------------------------------------------------- 32 // ViewManager -----------------------------------------------------------------
33 33
34 // These tests model synchronization of two peer connections to the view manager
35 // service, that are given access to some root node.
36
34 class ViewManagerTest : public testing::Test { 37 class ViewManagerTest : public testing::Test {
35 public: 38 public:
36 ViewManagerTest() : commit_count_(0) {} 39 ViewManagerTest() : commit_count_(0) {}
37 40
38 protected: 41 protected:
39 ViewManager* view_manager_1() { return view_manager_1_.get(); } 42 ViewManager* view_manager_1() { return view_manager_1_.get(); }
40 ViewManager* view_manager_2() { return view_manager_2_.get(); } 43 ViewManager* view_manager_2() { return view_manager_2_.get(); }
41 44
42 scoped_ptr<ViewTreeNode> CreateNodeInParent(ViewTreeNode* parent) { 45 ViewTreeNode* CreateNodeInParent(ViewTreeNode* parent) {
43 ViewManager* parent_manager = ViewTreeNodePrivate(parent).view_manager(); 46 ViewManager* parent_manager = ViewTreeNodePrivate(parent).view_manager();
44 scoped_ptr<ViewTreeNode> node(new ViewTreeNode(parent_manager)); 47 ViewTreeNode* node = ViewTreeNode::Create(parent_manager);
45 parent->AddChild(node.get()); 48 parent->AddChild(node);
46 return node.Pass(); 49 return node;
50 }
51
52 void DestroyViewManager1() {
53 view_manager_1_.reset();
47 } 54 }
48 55
49 private: 56 private:
50 // Overridden from testing::Test: 57 // Overridden from testing::Test:
51 virtual void SetUp() OVERRIDE { 58 virtual void SetUp() OVERRIDE {
52 test_helper_.Init(); 59 test_helper_.Init();
53 view_manager_1_.reset(new ViewManager(test_helper_.shell())); 60 view_manager_1_.reset(new ViewManager(test_helper_.shell()));
54 view_manager_2_.reset(new ViewManager(test_helper_.shell())); 61 view_manager_2_.reset(new ViewManager(test_helper_.shell()));
55 view_manager_1_->Init(); 62 view_manager_1_->Init();
56 view_manager_2_->Init(); 63 view_manager_2_->Init();
(...skipping 21 matching lines...) Expand all
78 } 85 }
79 86
80 protected: 87 protected:
81 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) = 0; 88 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) = 0;
82 89
83 ViewManager* view_manager() { return view_manager_; } 90 ViewManager* view_manager() { return view_manager_; }
84 91
85 private: 92 private:
86 // Overridden from ViewTreeNodeObserver: 93 // Overridden from ViewTreeNodeObserver:
87 virtual void OnTreeChange(const TreeChangeParams& params) OVERRIDE { 94 virtual void OnTreeChange(const TreeChangeParams& params) OVERRIDE {
88 if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
89 return;
90 if (ShouldQuitRunLoop(params)) 95 if (ShouldQuitRunLoop(params))
91 QuitRunLoop(); 96 QuitRunLoop();
92 } 97 }
93 98
94 ViewManager* view_manager_; 99 ViewManager* view_manager_;
95 DISALLOW_COPY_AND_ASSIGN(TreeObserverBase); 100 DISALLOW_COPY_AND_ASSIGN(TreeObserverBase);
96 }; 101 };
97 102
98 // Spins a runloop until the tree beginning at |root| has |tree_size| nodes 103 // Spins a runloop until the tree beginning at |root| has |tree_size| nodes
99 // (including |root|). 104 // (including |root|).
100 class TreeSizeMatchesWaiter : public TreeObserverBase { 105 class TreeSizeMatchesWaiter : public TreeObserverBase {
101 public: 106 public:
102 TreeSizeMatchesWaiter(ViewManager* view_manager, size_t tree_size) 107 TreeSizeMatchesWaiter(ViewManager* view_manager, size_t tree_size)
103 : TreeObserverBase(view_manager), 108 : TreeObserverBase(view_manager),
104 tree_size_(tree_size) { 109 tree_size_(tree_size) {
105 DoRunLoop(); 110 DoRunLoop();
106 } 111 }
107 virtual ~TreeSizeMatchesWaiter() {} 112 virtual ~TreeSizeMatchesWaiter() {}
108 113
109 private: 114 private:
110 // Overridden from TreeObserverBase: 115 // Overridden from TreeObserverBase:
111 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE { 116 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE {
117 if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
118 return false;
112 return CountNodes(view_manager()->tree()) == tree_size_; 119 return CountNodes(view_manager()->tree()) == tree_size_;
113 } 120 }
114 121
115 size_t CountNodes(ViewTreeNode* node) const { 122 size_t CountNodes(ViewTreeNode* node) const {
116 size_t count = 1; 123 size_t count = 1;
117 ViewTreeNode::Children::const_iterator it = node->children().begin(); 124 ViewTreeNode::Children::const_iterator it = node->children().begin();
118 for (; it != node->children().end(); ++it) 125 for (; it != node->children().end(); ++it)
119 count += CountNodes(*it); 126 count += CountNodes(*it);
120 return count; 127 return count;
121 } 128 }
122 129
123 size_t tree_size_; 130 size_t tree_size_;
124 DISALLOW_COPY_AND_ASSIGN(TreeSizeMatchesWaiter); 131 DISALLOW_COPY_AND_ASSIGN(TreeSizeMatchesWaiter);
125 }; 132 };
126 133
127 134
128 class HierarchyChanged_NodeCreatedObserver : public TreeObserverBase { 135 class HierarchyChanged_NodeCreatedObserver : public TreeObserverBase {
129 public: 136 public:
130 explicit HierarchyChanged_NodeCreatedObserver(ViewManager* view_manager) 137 explicit HierarchyChanged_NodeCreatedObserver(ViewManager* view_manager)
131 : TreeObserverBase(view_manager) {} 138 : TreeObserverBase(view_manager) {}
132 virtual ~HierarchyChanged_NodeCreatedObserver() {} 139 virtual ~HierarchyChanged_NodeCreatedObserver() {}
133 140
134 private: 141 private:
135 // Overridden from TreeObserverBase: 142 // Overridden from TreeObserverBase:
136 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE { 143 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE {
144 if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
145 return false;
137 return params.receiver == view_manager()->tree() && 146 return params.receiver == view_manager()->tree() &&
138 !params.old_parent && 147 !params.old_parent &&
139 params.new_parent == view_manager()->tree(); 148 params.new_parent == view_manager()->tree();
140 } 149 }
141 150
142 DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeCreatedObserver); 151 DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeCreatedObserver);
143 }; 152 };
144 153
145 TEST_F(ViewManagerTest, HierarchyChanged_NodeCreated) { 154 TEST_F(ViewManagerTest, HierarchyChanged_NodeCreated) {
146 HierarchyChanged_NodeCreatedObserver observer(view_manager_2()); 155 HierarchyChanged_NodeCreatedObserver observer(view_manager_2());
147 scoped_ptr<ViewTreeNode> node1(new ViewTreeNode(view_manager_1())); 156 ViewTreeNode* node1 = ViewTreeNode::Create(view_manager_1());
148 view_manager_1()->tree()->AddChild(node1.get()); 157 view_manager_1()->tree()->AddChild(node1);
149 DoRunLoop(); 158 DoRunLoop();
150 159
151 EXPECT_EQ(view_manager_2()->tree()->children().front()->id(), node1->id()); 160 EXPECT_EQ(view_manager_2()->tree()->children().front()->id(), node1->id());
152 } 161 }
153 162
154 // Quits the current runloop when the root is notified about a node moved from 163 // Quits the current runloop when the root is notified about a node moved from
155 // |old_parent_id| to |new_parent_id|. 164 // |old_parent_id| to |new_parent_id|.
156 class HierarchyChanged_NodeMovedObserver : public TreeObserverBase { 165 class HierarchyChanged_NodeMovedObserver : public TreeObserverBase {
157 public: 166 public:
158 HierarchyChanged_NodeMovedObserver(ViewManager* view_manager, 167 HierarchyChanged_NodeMovedObserver(ViewManager* view_manager,
159 TransportNodeId old_parent_id, 168 TransportNodeId old_parent_id,
160 TransportNodeId new_parent_id) 169 TransportNodeId new_parent_id)
161 : TreeObserverBase(view_manager), 170 : TreeObserverBase(view_manager),
162 old_parent_id_(old_parent_id), 171 old_parent_id_(old_parent_id),
163 new_parent_id_(new_parent_id) {} 172 new_parent_id_(new_parent_id) {}
164 virtual ~HierarchyChanged_NodeMovedObserver() {} 173 virtual ~HierarchyChanged_NodeMovedObserver() {}
165 174
166 private: 175 private:
167 // Overridden from TreeObserverBase: 176 // Overridden from TreeObserverBase:
168 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE { 177 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE {
178 if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
179 return false;
169 return params.receiver == view_manager()->tree() && 180 return params.receiver == view_manager()->tree() &&
170 params.old_parent->id() == old_parent_id_&& 181 params.old_parent->id() == old_parent_id_&&
171 params.new_parent->id() == new_parent_id_; 182 params.new_parent->id() == new_parent_id_;
172 } 183 }
173 184
174 TransportNodeId old_parent_id_; 185 TransportNodeId old_parent_id_;
175 TransportNodeId new_parent_id_; 186 TransportNodeId new_parent_id_;
176 187
177 DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeMovedObserver); 188 DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeMovedObserver);
178 }; 189 };
179 190
180 TEST_F(ViewManagerTest, HierarchyChanged_NodeMoved) { 191 TEST_F(ViewManagerTest, HierarchyChanged_NodeMoved) {
181 scoped_ptr<ViewTreeNode> node1(CreateNodeInParent(view_manager_1()->tree())); 192 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
182 scoped_ptr<ViewTreeNode> node2(CreateNodeInParent(view_manager_1()->tree())); 193 ViewTreeNode* node2 = CreateNodeInParent(view_manager_1()->tree());
183 scoped_ptr<ViewTreeNode> node21(CreateNodeInParent(node2.get())); 194 ViewTreeNode* node21 = CreateNodeInParent(node2);
184 TreeSizeMatchesWaiter waiter(view_manager_2(), 4); 195 TreeSizeMatchesWaiter waiter(view_manager_2(), 4);
185 196
186 HierarchyChanged_NodeMovedObserver observer(view_manager_2(), 197 HierarchyChanged_NodeMovedObserver observer(view_manager_2(),
187 node2->id(), 198 node2->id(),
188 node1->id()); 199 node1->id());
189 200
190 node1->AddChild(node21.get()); 201 node1->AddChild(node21);
191 DoRunLoop(); 202 DoRunLoop();
192 203
193 ViewTreeNode* tree2 = view_manager_2()->tree(); 204 ViewTreeNode* tree2 = view_manager_2()->tree();
194 205
195 EXPECT_EQ(tree2->children().size(), 2u); 206 EXPECT_EQ(tree2->children().size(), 2u);
196 ViewTreeNode* tree2_node1 = tree2->GetChildById(node1->id()); 207 ViewTreeNode* tree2_node1 = tree2->GetChildById(node1->id());
197 EXPECT_EQ(tree2_node1->children().size(), 1u); 208 EXPECT_EQ(tree2_node1->children().size(), 1u);
198 ViewTreeNode* tree2_node2 = tree2->GetChildById(node2->id()); 209 ViewTreeNode* tree2_node2 = tree2->GetChildById(node2->id());
199 EXPECT_TRUE(tree2_node2->children().empty()); 210 EXPECT_TRUE(tree2_node2->children().empty());
200 ViewTreeNode* tree2_node21 = tree2->GetChildById(node21->id()); 211 ViewTreeNode* tree2_node21 = tree2->GetChildById(node21->id());
201 EXPECT_EQ(tree2_node21->parent(), tree2_node1); 212 EXPECT_EQ(tree2_node21->parent(), tree2_node1);
202 } 213 }
203 214
204 // TODO(beng): node destruction 215 class HierarchyChanged_NodeRemovedObserver : public TreeObserverBase {
216 public:
217 HierarchyChanged_NodeRemovedObserver(ViewManager* view_manager)
218 : TreeObserverBase(view_manager) {}
219 virtual ~HierarchyChanged_NodeRemovedObserver() {}
220
221 private:
222 // Overridden from TreeObserverBase:
223 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE {
224 if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGING)
225 return false;
226 return params.receiver == view_manager()->tree() &&
227 params.old_parent->id() == params.receiver->id() &&
228 params.new_parent == 0;
229 }
230
231 DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeRemovedObserver);
232 };
233
234 TEST_F(ViewManagerTest, HierarchyChanged_NodeRemoved) {
235 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
236 TreeSizeMatchesWaiter waiter(view_manager_2(), 2);
237
238 HierarchyChanged_NodeRemovedObserver observer(view_manager_2());
239
240 view_manager_1()->tree()->RemoveChild(node1);
241 DoRunLoop();
242
243 ViewTreeNode* tree2 = view_manager_2()->tree();
244
245 EXPECT_TRUE(tree2->children().empty());
246 }
247
248 class NodeDestroyed_Waiter : public ViewTreeNodeObserver {
249 public:
250 NodeDestroyed_Waiter(ViewManager* view_manager, TransportNodeId id)
251 : id_(id),
252 view_manager_(view_manager) {
253 view_manager_->GetNodeById(id)->AddObserver(this);
254 DoRunLoop();
255 }
256 virtual ~NodeDestroyed_Waiter() {
257 }
258
259 private:
260 // Overridden from TreeObserverBase:
261 virtual void OnNodeDestroy(ViewTreeNode* node,
262 DispositionChangePhase phase) OVERRIDE {
263 if (phase != DISPOSITION_CHANGED)
264 return;
265 if (node->id() == id_)
266 QuitRunLoop();
267 }
268
269 TransportNodeId id_;
270 ViewManager* view_manager_;
271
272 DISALLOW_COPY_AND_ASSIGN(NodeDestroyed_Waiter);
273 };
274
275 TEST_F(ViewManagerTest, NodeDestroyed) {
276 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
277 TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2);
278
279 // |node1| will be deleted after calling Destroy() below.
280 TransportNodeId id = node1->id();
281 node1->Destroy();
282 NodeDestroyed_Waiter destroyed_waiter(view_manager_2(), id);
283
284 EXPECT_TRUE(view_manager_2()->tree()->children().empty());
285 }
286
287 TEST_F(ViewManagerTest, ViewManagerDestroyed) {
288 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
289 TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2);
290
291 TransportNodeId id = node1->id();
292 DestroyViewManager1();
293 NodeDestroyed_Waiter destroyed_waiter(view_manager_2(), id);
294
295 // tree() should still be valid, since it's owned by neither connection.
296 EXPECT_TRUE(view_manager_2()->tree()->children().empty());
297 }
205 298
206 } // namespace view_manager 299 } // namespace view_manager
207 } // namespace services 300 } // namespace services
208 } // namespace mojo 301 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698