1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/controls/treectrltest.cpp
3 // Purpose: wxTreeCtrl unit test
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // (c) 2010 Steven Lamerton
9 ///////////////////////////////////////////////////////////////////////////////
11 // ----------------------------------------------------------------------------
13 // ----------------------------------------------------------------------------
27 #include "wx/artprov.h"
28 #include "wx/imaglist.h"
29 #include "wx/treectrl.h"
30 #include "wx/uiaction.h"
31 #include "testableframe.h"
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
37 class TreeCtrlTestCase
: public CppUnit::TestCase
40 TreeCtrlTestCase() { }
43 virtual void tearDown();
46 CPPUNIT_TEST_SUITE( TreeCtrlTestCase
);
47 WXUISIM_TEST( ItemClick
);
48 CPPUNIT_TEST( DeleteItem
);
49 WXUISIM_TEST( LabelEdit
);
50 WXUISIM_TEST( KeyDown
);
52 WXUISIM_TEST( CollapseExpandEvents
);
53 WXUISIM_TEST( SelectionChange
);
56 CPPUNIT_TEST( ItemData
);
57 CPPUNIT_TEST( Iteration
);
58 CPPUNIT_TEST( Parent
);
59 CPPUNIT_TEST( CollapseExpand
);
60 CPPUNIT_TEST( AssignImageList
);
61 CPPUNIT_TEST( Focus
);
63 CPPUNIT_TEST( Visible
);
65 WXUISIM_TEST( KeyNavigation
);
66 CPPUNIT_TEST( HasChildren
);
67 CPPUNIT_TEST( SelectItemSingle
);
68 CPPUNIT_TEST( PseudoTest_MultiSelect
);
69 CPPUNIT_TEST( SelectItemMulti
);
70 CPPUNIT_TEST( PseudoTest_SetHiddenRoot
);
71 CPPUNIT_TEST( HasChildren
);
72 CPPUNIT_TEST_SUITE_END();
79 void CollapseExpandEvents();
80 void SelectionChange();
86 void CollapseExpand();
87 void AssignImageList();
94 void SelectItemSingle();
95 void SelectItemMulti();
96 void PseudoTest_MultiSelect() { ms_multiSelect
= true; }
97 void PseudoTest_SetHiddenRoot() { ms_hiddenRoot
= true; }
99 static bool ms_multiSelect
;
100 static bool ms_hiddenRoot
;
102 // the tree control itself
105 // and some of its items
111 DECLARE_NO_COPY_CLASS(TreeCtrlTestCase
)
114 // register in the unnamed registry so that these tests are run by default
115 CPPUNIT_TEST_SUITE_REGISTRATION( TreeCtrlTestCase
);
117 // also include in its own registry so that these tests can be run alone
118 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TreeCtrlTestCase
, "TreeCtrlTestCase" );
120 // ----------------------------------------------------------------------------
121 // test initialization
122 // ----------------------------------------------------------------------------
124 bool TreeCtrlTestCase::ms_multiSelect
= false;
125 bool TreeCtrlTestCase::ms_hiddenRoot
= false;
127 void TreeCtrlTestCase::setUp()
129 m_tree
= new wxTreeCtrl(wxTheApp
->GetTopWindow(),
133 wxTR_DEFAULT_STYLE
| wxTR_EDIT_LABELS
);
135 if ( ms_multiSelect
)
136 m_tree
->ToggleWindowStyle(wxTR_MULTIPLE
);
139 m_tree
->ToggleWindowStyle(wxTR_HIDE_ROOT
); // actually set it
141 m_root
= m_tree
->AddRoot("root");
142 m_child1
= m_tree
->AppendItem(m_root
, "child1");
143 m_child2
= m_tree
->AppendItem(m_root
, "child2");
144 m_grandchild
= m_tree
->AppendItem(m_child1
, "grandchild");
146 m_tree
->SetSize(400, 200);
152 void TreeCtrlTestCase::tearDown()
160 m_grandchild
= wxTreeItemId();
163 // ----------------------------------------------------------------------------
164 // the tests themselves
165 // ----------------------------------------------------------------------------
167 void TreeCtrlTestCase::HasChildren()
169 CPPUNIT_ASSERT( m_tree
->HasChildren(m_root
) );
170 CPPUNIT_ASSERT( m_tree
->HasChildren(m_child1
) );
171 CPPUNIT_ASSERT( !m_tree
->HasChildren(m_child2
) );
172 CPPUNIT_ASSERT( !m_tree
->HasChildren(m_grandchild
) );
175 void TreeCtrlTestCase::SelectItemSingle()
177 // this test should be only ran in single-selection control
178 CPPUNIT_ASSERT( !m_tree
->HasFlag(wxTR_MULTIPLE
) );
180 // initially nothing is selected
181 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
183 // selecting an item should make it selected
184 m_tree
->SelectItem(m_child1
);
185 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
187 // selecting it again shouldn't change anything
188 m_tree
->SelectItem(m_child1
);
189 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
191 // selecting another item should switch the selection to it
192 m_tree
->SelectItem(m_child2
);
193 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
194 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
196 // selecting it again still shouldn't change anything
197 m_tree
->SelectItem(m_child2
);
198 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
199 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
201 // deselecting an item should remove the selection entirely
202 m_tree
->UnselectItem(m_child2
);
203 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
204 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child2
) );
207 void TreeCtrlTestCase::SelectItemMulti()
209 // this test should be only ran in multi-selection control
210 CPPUNIT_ASSERT( m_tree
->HasFlag(wxTR_MULTIPLE
) );
212 // initially nothing is selected
213 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
215 // selecting an item should make it selected
216 m_tree
->SelectItem(m_child1
);
217 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
219 // selecting it again shouldn't change anything
220 m_tree
->SelectItem(m_child1
);
221 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
223 // selecting another item shouldn't deselect the previously selected one
224 m_tree
->SelectItem(m_child2
);
225 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
226 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
228 // selecting it again still shouldn't change anything
229 m_tree
->SelectItem(m_child2
);
230 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
231 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
233 // deselecting one of the items should leave the others selected
234 m_tree
->UnselectItem(m_child1
);
235 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
236 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
239 void TreeCtrlTestCase::ItemClick()
241 #if wxUSE_UIACTIONSIMULATOR
242 EventCounter
activated(m_tree
, wxEVT_COMMAND_TREE_ITEM_ACTIVATED
);
243 EventCounter
rclick(m_tree
, wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK
);
245 wxUIActionSimulator sim
;
248 m_tree
->GetBoundingRect(m_child1
, pos
, true);
250 // We move in slightly so we are not on the edge
251 wxPoint point
= m_tree
->ClientToScreen(pos
.GetPosition()) + wxPoint(4, 4);
253 sim
.MouseMove(point
);
259 sim
.MouseClick(wxMOUSE_BTN_RIGHT
);
262 CPPUNIT_ASSERT_EQUAL(1, activated
.GetCount());
263 CPPUNIT_ASSERT_EQUAL(1, rclick
.GetCount());
264 #endif // wxUSE_UIACTIONSIMULATOR
267 void TreeCtrlTestCase::DeleteItem()
269 EventCounter
deleteitem(m_tree
, wxEVT_COMMAND_TREE_DELETE_ITEM
);
271 wxTreeItemId todelete
= m_tree
->AppendItem(m_root
, "deleteme");
272 m_tree
->Delete(todelete
);
273 // We do not test DeleteAllItems() as under some versions of Windows events
274 // are not generated.
276 CPPUNIT_ASSERT_EQUAL(1, deleteitem
.GetCount());
279 #if wxUSE_UIACTIONSIMULATOR
281 void TreeCtrlTestCase::LabelEdit()
283 EventCounter
beginedit(m_tree
, wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
);
284 EventCounter
endedit(m_tree
, wxEVT_COMMAND_TREE_END_LABEL_EDIT
);
286 wxUIActionSimulator sim
;
288 m_tree
->SetFocusedItem(m_tree
->GetRootItem());
289 m_tree
->EditLabel(m_tree
->GetRootItem());
291 sim
.Text("newroottext");
294 CPPUNIT_ASSERT_EQUAL(1, beginedit
.GetCount());
296 sim
.Char(WXK_RETURN
);
299 CPPUNIT_ASSERT_EQUAL(1, endedit
.GetCount());
302 void TreeCtrlTestCase::KeyDown()
304 EventCounter
keydown(m_tree
, wxEVT_COMMAND_TREE_KEY_DOWN
);
306 wxUIActionSimulator sim
;
312 CPPUNIT_ASSERT_EQUAL(6, keydown
.GetCount());
315 #if !defined(__WXGTK__)
317 void TreeCtrlTestCase::CollapseExpandEvents()
319 m_tree
->CollapseAll();
321 EventCounter
collapsed(m_tree
, wxEVT_COMMAND_TREE_ITEM_COLLAPSED
);
322 EventCounter
collapsing(m_tree
, wxEVT_COMMAND_TREE_ITEM_COLLAPSING
);
323 EventCounter
expanded(m_tree
, wxEVT_COMMAND_TREE_ITEM_EXPANDED
);
324 EventCounter
expanding(m_tree
, wxEVT_COMMAND_TREE_ITEM_EXPANDING
);
326 wxUIActionSimulator sim
;
329 m_tree
->GetBoundingRect(m_root
, pos
, true);
331 // We move in slightly so we are not on the edge
332 wxPoint point
= m_tree
->ClientToScreen(pos
.GetPosition()) + wxPoint(4, 4);
334 sim
.MouseMove(point
);
340 CPPUNIT_ASSERT_EQUAL(1, expanding
.GetCount());
341 CPPUNIT_ASSERT_EQUAL(1, expanded
.GetCount());
346 CPPUNIT_ASSERT_EQUAL(1, collapsing
.GetCount());
347 CPPUNIT_ASSERT_EQUAL(1, collapsed
.GetCount());
350 void TreeCtrlTestCase::SelectionChange()
353 m_tree
->UnselectAll();
355 EventCounter
changed(m_tree
, wxEVT_COMMAND_TREE_SEL_CHANGED
);
356 EventCounter
changing(m_tree
, wxEVT_COMMAND_TREE_SEL_CHANGING
);
358 wxUIActionSimulator sim
;
360 wxRect poschild1
, poschild2
;
361 m_tree
->GetBoundingRect(m_child1
, poschild1
, true);
362 m_tree
->GetBoundingRect(m_child1
, poschild2
, true);
364 // We move in slightly so we are not on the edge
365 wxPoint point1
= m_tree
->ClientToScreen(poschild1
.GetPosition()) + wxPoint(4, 4);
366 wxPoint point2
= m_tree
->ClientToScreen(poschild2
.GetPosition()) + wxPoint(4, 4);
368 sim
.MouseMove(point1
);
374 sim
.MouseMove(point2
);
380 CPPUNIT_ASSERT_EQUAL(2, changed
.GetCount());
381 CPPUNIT_ASSERT_EQUAL(2, changing
.GetCount());
386 void TreeCtrlTestCase::Menu()
388 EventCounter
menu(m_tree
, wxEVT_COMMAND_TREE_ITEM_MENU
);
389 wxUIActionSimulator sim
;
392 m_tree
->GetBoundingRect(m_child1
, pos
, true);
394 // We move in slightly so we are not on the edge
395 wxPoint point
= m_tree
->ClientToScreen(pos
.GetPosition()) + wxPoint(4, 4);
397 sim
.MouseMove(point
);
400 sim
.MouseClick(wxMOUSE_BTN_RIGHT
);
403 CPPUNIT_ASSERT_EQUAL(1, menu
.GetCount());
406 #endif // wxUSE_UIACTIONSIMULATOR
408 void TreeCtrlTestCase::ItemData()
410 wxTreeItemData
* child1data
= new wxTreeItemData();
411 wxTreeItemData
* appenddata
= new wxTreeItemData();
412 wxTreeItemData
* insertdata
= new wxTreeItemData();
414 m_tree
->SetItemData(m_child1
, child1data
);
416 CPPUNIT_ASSERT_EQUAL(child1data
, m_tree
->GetItemData(m_child1
));
417 CPPUNIT_ASSERT_EQUAL(m_child1
, child1data
->GetId());
419 wxTreeItemId append
= m_tree
->AppendItem(m_root
, "new", -1, -1, appenddata
);
421 CPPUNIT_ASSERT_EQUAL(appenddata
, m_tree
->GetItemData(append
));
422 CPPUNIT_ASSERT_EQUAL(append
, appenddata
->GetId());
424 wxTreeItemId insert
= m_tree
->InsertItem(m_root
, m_child1
, "new", -1, -1,
427 CPPUNIT_ASSERT_EQUAL(insertdata
, m_tree
->GetItemData(insert
));
428 CPPUNIT_ASSERT_EQUAL(insert
, insertdata
->GetId());
431 void TreeCtrlTestCase::Iteration()
433 // Get first / next / last child
434 wxTreeItemIdValue cookie
;
435 CPPUNIT_ASSERT_EQUAL(m_tree
->GetFirstChild(m_root
, cookie
), m_child1
);
436 CPPUNIT_ASSERT_EQUAL(m_tree
->GetNextChild(m_root
, cookie
),
437 m_tree
->GetLastChild(m_root
));
438 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetLastChild(m_root
));
440 // Get next / previous sibling
441 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetNextSibling(m_child1
));
442 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetPrevSibling(m_child2
));
445 void TreeCtrlTestCase::Parent()
447 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetRootItem());
448 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetItemParent(m_child1
));
449 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetItemParent(m_child2
));
450 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetItemParent(m_grandchild
));
453 void TreeCtrlTestCase::CollapseExpand()
457 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_root
));
458 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
460 m_tree
->CollapseAll();
462 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
463 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_child1
));
465 m_tree
->ExpandAllChildren(m_root
);
467 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_root
));
468 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
470 m_tree
->CollapseAllChildren(m_child1
);
472 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_child1
));
474 m_tree
->Expand(m_child1
);
476 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
478 m_tree
->Collapse(m_root
);
480 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
481 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
483 m_tree
->CollapseAndReset(m_root
);
485 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
488 void TreeCtrlTestCase::AssignImageList()
492 wxImageList
*imagelist
= new wxImageList(size
.x
, size
.y
);
493 imagelist
->Add(wxArtProvider::GetIcon(wxART_QUESTION
, wxART_OTHER
, size
));
495 wxImageList
*statelist
= new wxImageList(size
.x
, size
.y
);
496 statelist
->Add(wxArtProvider::GetIcon(wxART_ERROR
, wxART_OTHER
, size
));
498 m_tree
->AssignImageList(imagelist
);
499 m_tree
->AssignStateImageList(statelist
);
501 CPPUNIT_ASSERT_EQUAL(imagelist
, m_tree
->GetImageList());
502 CPPUNIT_ASSERT_EQUAL(statelist
, m_tree
->GetStateImageList());
505 void TreeCtrlTestCase::Focus()
507 #if !defined(__WXGTK__) && !defined(__WXOSX__)
508 m_tree
->SetFocusedItem(m_child1
);
510 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetFocusedItem());
512 m_tree
->ClearFocusedItem();
514 CPPUNIT_ASSERT(!m_tree
->GetFocusedItem());
518 void TreeCtrlTestCase::Bold()
520 CPPUNIT_ASSERT(!m_tree
->IsBold(m_child1
));
522 m_tree
->SetItemBold(m_child1
);
524 CPPUNIT_ASSERT(m_tree
->IsBold(m_child1
));
526 m_tree
->SetItemBold(m_child1
, false);
528 CPPUNIT_ASSERT(!m_tree
->IsBold(m_child1
));
531 void TreeCtrlTestCase::Visible()
533 m_tree
->CollapseAll();
535 CPPUNIT_ASSERT(m_tree
->IsVisible(m_root
));
536 CPPUNIT_ASSERT(!m_tree
->IsVisible(m_child1
));
538 m_tree
->EnsureVisible(m_grandchild
);
540 CPPUNIT_ASSERT(m_tree
->IsVisible(m_grandchild
));
544 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetFirstVisibleItem());
545 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetNextVisible(m_root
));
546 CPPUNIT_ASSERT_EQUAL(m_grandchild
, m_tree
->GetNextVisible(m_child1
));
547 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetNextVisible(m_grandchild
));
549 CPPUNIT_ASSERT(!m_tree
->GetNextVisible(m_child2
));
550 CPPUNIT_ASSERT(!m_tree
->GetPrevVisible(m_root
));
553 void TreeCtrlTestCase::Sort()
555 wxTreeItemId zitem
= m_tree
->AppendItem(m_root
, "zzzz");
556 wxTreeItemId aitem
= m_tree
->AppendItem(m_root
, "aaaa");
558 m_tree
->SortChildren(m_root
);
560 wxTreeItemIdValue cookie
;
562 CPPUNIT_ASSERT_EQUAL(aitem
, m_tree
->GetFirstChild(m_root
, cookie
));
563 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetNextChild(m_root
, cookie
));
564 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetNextChild(m_root
, cookie
));
565 CPPUNIT_ASSERT_EQUAL(zitem
, m_tree
->GetNextChild(m_root
, cookie
));
568 void TreeCtrlTestCase::KeyNavigation()
570 #if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__)
571 wxUIActionSimulator sim
;
573 m_tree
->CollapseAll();
575 m_tree
->SelectItem(m_root
);
581 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_root
));
586 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
592 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetSelection());
597 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetSelection());
601 #endif //wxUSE_TREECTRL