Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / views / controls / tree / tree_view_unittest.cc
1 // Copyright (c) 2012 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 "ui/views/controls/tree/tree_view.h"
6
7 #include <string>
8
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "ui/base/models/tree_node_model.h"
12 #include "ui/views/controls/prefix_selector.h"
13 #include "ui/views/controls/textfield/textfield.h"
14 #include "ui/views/test/views_test_base.h"
15
16 using ui::TreeModel;
17 using ui::TreeModelNode;
18 using ui::TreeNode;
19
20 using base::ASCIIToUTF16;
21
22 namespace views {
23
24 class TestNode : public TreeNode<TestNode> {
25  public:
26   TestNode() {}
27   ~TestNode() override {}
28
29  private:
30   DISALLOW_COPY_AND_ASSIGN(TestNode);
31 };
32
33 // Creates the following structure:
34 // 'root'
35 //   'a'
36 //   'b'
37 //     'b1'
38 //   'c'
39 class TreeViewTest : public ViewsTestBase {
40  public:
41   TreeViewTest() : model_(new TestNode) {
42     static_cast<TestNode*>(model_.GetRoot())->SetTitle(ASCIIToUTF16("root"));
43     Add(model_.GetRoot(), 0, "a");
44     Add(Add(model_.GetRoot(), 1, "b"), 0, "b1");
45     Add(model_.GetRoot(), 2, "c");
46   }
47
48  protected:
49   TestNode* Add(TestNode* parent,
50                 int index,
51                 const std::string& title);
52
53   std::string TreeViewContentsAsString();
54
55   std::string GetSelectedNodeTitle();
56
57   std::string GetEditingNodeTitle();
58
59   TestNode* GetNodeByTitle(const std::string& title);
60
61   void IncrementSelection(bool next);
62   void CollapseOrSelectParent();
63   void ExpandOrSelectChild();
64   int GetRowCount();
65   PrefixSelector* selector() { return tree_.selector_.get(); }
66
67   ui::TreeNodeModel<TestNode > model_;
68   TreeView tree_;
69
70  private:
71   std::string InternalNodeAsString(TreeView::InternalNode* node);
72
73   TestNode* GetNodeByTitleImpl(TestNode* node, const base::string16& title);
74
75   DISALLOW_COPY_AND_ASSIGN(TreeViewTest);
76 };
77
78 TestNode* TreeViewTest::Add(TestNode* parent,
79                             int index,
80                             const std::string& title) {
81   TestNode* new_node = new TestNode;
82   new_node->SetTitle(ASCIIToUTF16(title));
83   model_.Add(parent, new_node, index);
84   return new_node;
85 }
86
87 std::string TreeViewTest::TreeViewContentsAsString() {
88   return InternalNodeAsString(&tree_.root_);
89 }
90
91 std::string TreeViewTest::GetSelectedNodeTitle() {
92   TreeModelNode* model_node = tree_.GetSelectedNode();
93   return model_node ? base::UTF16ToASCII(model_node->GetTitle())
94                     : std::string();
95 }
96
97 std::string TreeViewTest::GetEditingNodeTitle() {
98   TreeModelNode* model_node = tree_.GetEditingNode();
99   return model_node ? base::UTF16ToASCII(model_node->GetTitle())
100                     : std::string();
101 }
102
103 TestNode* TreeViewTest::GetNodeByTitle(const std::string& title) {
104   return GetNodeByTitleImpl(model_.GetRoot(), ASCIIToUTF16(title));
105 }
106
107 void TreeViewTest::IncrementSelection(bool next) {
108   tree_.IncrementSelection(next ? TreeView::INCREMENT_NEXT :
109                            TreeView::INCREMENT_PREVIOUS);
110 }
111
112 void TreeViewTest::CollapseOrSelectParent() {
113   tree_.CollapseOrSelectParent();
114 }
115
116 void TreeViewTest::ExpandOrSelectChild() {
117   tree_.ExpandOrSelectChild();
118 }
119
120 int TreeViewTest::GetRowCount() {
121   return tree_.GetRowCount();
122 }
123
124 TestNode* TreeViewTest::GetNodeByTitleImpl(TestNode* node,
125                                            const base::string16& title) {
126   if (node->GetTitle() == title)
127     return node;
128   for (int i = 0; i < node->child_count(); ++i) {
129     TestNode* child = GetNodeByTitleImpl(node->GetChild(i), title);
130     if (child)
131       return child;
132   }
133   return NULL;
134 }
135
136 std::string TreeViewTest::InternalNodeAsString(
137     TreeView::InternalNode* node) {
138   std::string result = base::UTF16ToASCII(node->model_node()->GetTitle());
139   if (node->is_expanded() && node->child_count()) {
140     result += " [";
141     for (int i = 0; i < node->child_count(); ++i) {
142       if (i > 0)
143         result += " ";
144       result += InternalNodeAsString(node->GetChild(i));
145     }
146     result += "]";
147   }
148   return result;
149 }
150
151 // Verifies setting model correctly updates internal state.
152 TEST_F(TreeViewTest, SetModel) {
153   tree_.SetModel(&model_);
154   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
155   EXPECT_EQ("root", GetSelectedNodeTitle());
156   EXPECT_EQ(4, GetRowCount());
157 }
158
159 // Verifies SetSelectedNode works.
160 TEST_F(TreeViewTest, SetSelectedNode) {
161   tree_.SetModel(&model_);
162   EXPECT_EQ("root", GetSelectedNodeTitle());
163
164   // NULL should clear the selection.
165   tree_.SetSelectedNode(NULL);
166   EXPECT_EQ(std::string(), GetSelectedNodeTitle());
167
168   // Select 'c'.
169   tree_.SetSelectedNode(GetNodeByTitle("c"));
170   EXPECT_EQ("c", GetSelectedNodeTitle());
171
172   // Select 'b1', which should expand 'b'.
173   tree_.SetSelectedNode(GetNodeByTitle("b1"));
174   EXPECT_EQ("root [a b [b1] c]", TreeViewContentsAsString());
175   EXPECT_EQ("b1", GetSelectedNodeTitle());
176 }
177
178 // Makes sure SetRootShown doesn't blow up.
179 TEST_F(TreeViewTest, HideRoot) {
180   tree_.SetModel(&model_);
181   tree_.SetRootShown(false);
182   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
183   EXPECT_EQ("a", GetSelectedNodeTitle());
184   EXPECT_EQ(3, GetRowCount());
185 }
186
187 // Expands a node and verifies the children are loaded correctly.
188 TEST_F(TreeViewTest, Expand) {
189   tree_.SetModel(&model_);
190   tree_.Expand(GetNodeByTitle("b1"));
191   EXPECT_EQ("root [a b [b1] c]", TreeViewContentsAsString());
192   EXPECT_EQ("root",GetSelectedNodeTitle());
193   EXPECT_EQ(5, GetRowCount());
194 }
195
196 // Collapes a node and verifies state.
197 TEST_F(TreeViewTest, Collapse) {
198   tree_.SetModel(&model_);
199   tree_.Expand(GetNodeByTitle("b1"));
200   EXPECT_EQ("root [a b [b1] c]", TreeViewContentsAsString());
201   EXPECT_EQ(5, GetRowCount());
202   tree_.SetSelectedNode(GetNodeByTitle("b1"));
203   EXPECT_EQ("b1", GetSelectedNodeTitle());
204   tree_.Collapse(GetNodeByTitle("b"));
205   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
206   // Selected node should have moved to 'b'
207   EXPECT_EQ("b", GetSelectedNodeTitle());
208   EXPECT_EQ(4, GetRowCount());
209 }
210
211 // Verifies adding nodes works.
212 TEST_F(TreeViewTest, TreeNodesAdded) {
213   tree_.SetModel(&model_);
214   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
215   // Add a node between b and c.
216   Add(model_.GetRoot(), 2, "B");
217   EXPECT_EQ("root [a b B c]", TreeViewContentsAsString());
218   EXPECT_EQ("root", GetSelectedNodeTitle());
219   EXPECT_EQ(5, GetRowCount());
220
221   // Add a child of b1, which hasn't been loaded and shouldn't do anything.
222   Add(GetNodeByTitle("b1"), 0, "b11");
223   EXPECT_EQ("root [a b B c]", TreeViewContentsAsString());
224   EXPECT_EQ("root", GetSelectedNodeTitle());
225   EXPECT_EQ(5, GetRowCount());
226
227   // Add a child of b, which isn't expanded yet, so it shouldn't effect
228   // anything.
229   Add(GetNodeByTitle("b"), 1, "b2");
230   EXPECT_EQ("root [a b B c]", TreeViewContentsAsString());
231   EXPECT_EQ("root", GetSelectedNodeTitle());
232   EXPECT_EQ(5, GetRowCount());
233
234   // Expand b and make sure b2 is there.
235   tree_.Expand(GetNodeByTitle("b"));
236   EXPECT_EQ("root [a b [b1 b2] B c]", TreeViewContentsAsString());
237   EXPECT_EQ("root",GetSelectedNodeTitle());
238   EXPECT_EQ(7, GetRowCount());
239 }
240
241 // Verifies removing nodes works.
242 TEST_F(TreeViewTest, TreeNodesRemoved) {
243   // Add c1 as a child of c and c11 as a child of c1.
244   Add(Add(GetNodeByTitle("c"), 0, "c1"), 0, "c11");
245   tree_.SetModel(&model_);
246
247   // Remove c11, which shouldn't have any effect on the tree.
248   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
249   EXPECT_EQ("root", GetSelectedNodeTitle());
250   EXPECT_EQ(4, GetRowCount());
251
252   // Expand b1, then collapse it and remove its only child, b1. This shouldn't
253   // effect the tree.
254   tree_.Expand(GetNodeByTitle("b"));
255   tree_.Collapse(GetNodeByTitle("b"));
256   delete model_.Remove(GetNodeByTitle("b1")->parent(), GetNodeByTitle("b1"));
257   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
258   EXPECT_EQ("root", GetSelectedNodeTitle());
259   EXPECT_EQ(4, GetRowCount());
260
261   // Remove 'b'.
262   delete model_.Remove(GetNodeByTitle("b")->parent(), GetNodeByTitle("b"));
263   EXPECT_EQ("root [a c]", TreeViewContentsAsString());
264   EXPECT_EQ("root", GetSelectedNodeTitle());
265   EXPECT_EQ(3, GetRowCount());
266
267   // Remove 'c11', shouldn't visually change anything.
268   delete model_.Remove(GetNodeByTitle("c11")->parent(), GetNodeByTitle("c11"));
269   EXPECT_EQ("root [a c]", TreeViewContentsAsString());
270   EXPECT_EQ("root", GetSelectedNodeTitle());
271   EXPECT_EQ(3, GetRowCount());
272
273   // Select 'c1', remove 'c' and make sure selection changes.
274   tree_.SetSelectedNode(GetNodeByTitle("c1"));
275   EXPECT_EQ("c1", GetSelectedNodeTitle());
276   delete model_.Remove(GetNodeByTitle("c")->parent(), GetNodeByTitle("c"));
277   EXPECT_EQ("root [a]", TreeViewContentsAsString());
278   EXPECT_EQ("root", GetSelectedNodeTitle());
279   EXPECT_EQ(2, GetRowCount());
280
281   tree_.SetRootShown(false);
282   // Add 'b' select it and remove it. Because we're not showing the root
283   // selection should change to 'a'.
284   Add(GetNodeByTitle("root"), 1, "b");
285   tree_.SetSelectedNode(GetNodeByTitle("b"));
286   delete model_.Remove(GetNodeByTitle("b")->parent(), GetNodeByTitle("b"));
287   EXPECT_EQ("root [a]", TreeViewContentsAsString());
288   EXPECT_EQ("a", GetSelectedNodeTitle());
289   EXPECT_EQ(1, GetRowCount());
290 }
291
292 // Verifies changing a node title works.
293 TEST_F(TreeViewTest, TreeNodeChanged) {
294   // Add c1 as a child of c and c11 as a child of c1.
295   Add(Add(GetNodeByTitle("c"), 0, "c1"), 0, "c11");
296   tree_.SetModel(&model_);
297
298   // Change c11, shouldn't do anything.
299   model_.SetTitle(GetNodeByTitle("c11"), ASCIIToUTF16("c11.new"));
300   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
301   EXPECT_EQ("root", GetSelectedNodeTitle());
302   EXPECT_EQ(4, GetRowCount());
303
304   // Change 'b1', shouldn't do anything.
305   model_.SetTitle(GetNodeByTitle("b1"), ASCIIToUTF16("b1.new"));
306   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
307   EXPECT_EQ("root", GetSelectedNodeTitle());
308   EXPECT_EQ(4, GetRowCount());
309
310   // Change 'b'.
311   model_.SetTitle(GetNodeByTitle("b"), ASCIIToUTF16("b.new"));
312   EXPECT_EQ("root [a b.new c]", TreeViewContentsAsString());
313   EXPECT_EQ("root", GetSelectedNodeTitle());
314   EXPECT_EQ(4, GetRowCount());
315 }
316
317 // Verifies IncrementSelection() works.
318 TEST_F(TreeViewTest, IncrementSelection) {
319   tree_.SetModel(&model_);
320
321   IncrementSelection(true);
322   EXPECT_EQ("a", GetSelectedNodeTitle());
323   IncrementSelection(true);
324   EXPECT_EQ("b", GetSelectedNodeTitle());
325   IncrementSelection(true);
326   tree_.Expand(GetNodeByTitle("b"));
327   IncrementSelection(false);
328   EXPECT_EQ("b1", GetSelectedNodeTitle());
329   IncrementSelection(true);
330   EXPECT_EQ("c", GetSelectedNodeTitle());
331   IncrementSelection(true);
332   EXPECT_EQ("c", GetSelectedNodeTitle());
333
334   tree_.SetRootShown(false);
335   tree_.SetSelectedNode(GetNodeByTitle("a"));
336   EXPECT_EQ("a", GetSelectedNodeTitle());
337   IncrementSelection(false);
338   EXPECT_EQ("a", GetSelectedNodeTitle());
339 }
340
341 // Verifies CollapseOrSelectParent works.
342 TEST_F(TreeViewTest, CollapseOrSelectParent) {
343   tree_.SetModel(&model_);
344
345   tree_.SetSelectedNode(GetNodeByTitle("root"));
346   CollapseOrSelectParent();
347   EXPECT_EQ("root", TreeViewContentsAsString());
348   EXPECT_EQ("root", GetSelectedNodeTitle());
349
350   // Hide the root, which should implicitly expand the root.
351   tree_.SetRootShown(false);
352   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
353   EXPECT_EQ("a", GetSelectedNodeTitle());
354
355   tree_.SetSelectedNode(GetNodeByTitle("b1"));
356   EXPECT_EQ("root [a b [b1] c]", TreeViewContentsAsString());
357   EXPECT_EQ("b1", GetSelectedNodeTitle());
358   CollapseOrSelectParent();
359   EXPECT_EQ("root [a b [b1] c]", TreeViewContentsAsString());
360   EXPECT_EQ("b", GetSelectedNodeTitle());
361   CollapseOrSelectParent();
362   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
363   EXPECT_EQ("b", GetSelectedNodeTitle());
364 }
365
366 // Verifies ExpandOrSelectChild works.
367 TEST_F(TreeViewTest, ExpandOrSelectChild) {
368   tree_.SetModel(&model_);
369
370   tree_.SetSelectedNode(GetNodeByTitle("root"));
371   ExpandOrSelectChild();
372   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
373   EXPECT_EQ("a", GetSelectedNodeTitle());
374
375   ExpandOrSelectChild();
376   EXPECT_EQ("root [a b c]", TreeViewContentsAsString());
377   EXPECT_EQ("a", GetSelectedNodeTitle());
378
379   tree_.SetSelectedNode(GetNodeByTitle("b"));
380   ExpandOrSelectChild();
381   EXPECT_EQ("root [a b [b1] c]", TreeViewContentsAsString());
382   EXPECT_EQ("b", GetSelectedNodeTitle());
383   ExpandOrSelectChild();
384   EXPECT_EQ("root [a b [b1] c]", TreeViewContentsAsString());
385   EXPECT_EQ("b1", GetSelectedNodeTitle());
386   ExpandOrSelectChild();
387   EXPECT_EQ("root [a b [b1] c]", TreeViewContentsAsString());
388   EXPECT_EQ("b1", GetSelectedNodeTitle());
389 }
390
391 // Verify selection is properly updated on each keystroke.
392 TEST_F(TreeViewTest, SelectOnKeyStroke) {
393   tree_.SetModel(&model_);
394   tree_.ExpandAll(model_.GetRoot());
395   tree_.GetTextInputClient();
396   selector()->InsertText(ASCIIToUTF16("b"));
397   EXPECT_EQ("b", GetSelectedNodeTitle());
398   selector()->InsertText(ASCIIToUTF16("1"));
399   EXPECT_EQ("b1", GetSelectedNodeTitle());
400
401   // Invoke OnViewBlur() to reset time.
402   selector()->OnViewBlur();
403   selector()->InsertText(ASCIIToUTF16("z"));
404   EXPECT_EQ("b1", GetSelectedNodeTitle());
405
406   selector()->OnViewBlur();
407   selector()->InsertText(ASCIIToUTF16("a"));
408   EXPECT_EQ("a", GetSelectedNodeTitle());
409 }
410
411 // Verifies edits are committed when focus is lost.
412 TEST_F(TreeViewTest, CommitOnFocusLost) {
413   tree_.SetModel(&model_);
414
415   tree_.SetSelectedNode(GetNodeByTitle("root"));
416   ExpandOrSelectChild();
417   tree_.SetEditable(true);
418   tree_.StartEditing(GetNodeByTitle("a"));
419   tree_.editor()->SetText(ASCIIToUTF16("a changed"));
420   tree_.OnDidChangeFocus(NULL, NULL);
421   EXPECT_TRUE(GetNodeByTitle("a changed") != NULL);
422 }
423
424 }  // namespace views