1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/controls/treectrltest.cpp
3 // Purpose: wxTreeCtrl unit test
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
7 // (c) 2010 Steven Lamerton
8 ///////////////////////////////////////////////////////////////////////////////
10 // ----------------------------------------------------------------------------
12 // ----------------------------------------------------------------------------
26 #include "wx/artprov.h"
27 #include "wx/imaglist.h"
28 #include "wx/treectrl.h"
29 #include "wx/uiaction.h"
30 #include "testableframe.h"
32 // ----------------------------------------------------------------------------
34 // ----------------------------------------------------------------------------
36 class TreeCtrlTestCase
: public CppUnit::TestCase
39 TreeCtrlTestCase() { }
42 virtual void tearDown();
45 CPPUNIT_TEST_SUITE( TreeCtrlTestCase
);
46 WXUISIM_TEST( ItemClick
);
47 CPPUNIT_TEST( DeleteItem
);
48 WXUISIM_TEST( LabelEdit
);
49 WXUISIM_TEST( KeyDown
);
51 WXUISIM_TEST( CollapseExpandEvents
);
52 WXUISIM_TEST( SelectionChange
);
55 CPPUNIT_TEST( ItemData
);
56 CPPUNIT_TEST( Iteration
);
57 CPPUNIT_TEST( Parent
);
58 CPPUNIT_TEST( CollapseExpand
);
59 CPPUNIT_TEST( AssignImageList
);
60 CPPUNIT_TEST( Focus
);
62 CPPUNIT_TEST( Visible
);
64 WXUISIM_TEST( KeyNavigation
);
65 CPPUNIT_TEST( HasChildren
);
66 CPPUNIT_TEST( SelectItemSingle
);
67 CPPUNIT_TEST( PseudoTest_MultiSelect
);
68 CPPUNIT_TEST( SelectItemMulti
);
69 CPPUNIT_TEST( PseudoTest_SetHiddenRoot
);
70 CPPUNIT_TEST( HasChildren
);
71 CPPUNIT_TEST_SUITE_END();
78 void CollapseExpandEvents();
79 void SelectionChange();
85 void CollapseExpand();
86 void AssignImageList();
93 void SelectItemSingle();
94 void SelectItemMulti();
95 void PseudoTest_MultiSelect() { ms_multiSelect
= true; }
96 void PseudoTest_SetHiddenRoot() { ms_hiddenRoot
= true; }
98 static bool ms_multiSelect
;
99 static bool ms_hiddenRoot
;
101 // the tree control itself
104 // and some of its items
110 DECLARE_NO_COPY_CLASS(TreeCtrlTestCase
)
113 // register in the unnamed registry so that these tests are run by default
114 CPPUNIT_TEST_SUITE_REGISTRATION( TreeCtrlTestCase
);
116 // also include in its own registry so that these tests can be run alone
117 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TreeCtrlTestCase
, "TreeCtrlTestCase" );
119 // ----------------------------------------------------------------------------
120 // test initialization
121 // ----------------------------------------------------------------------------
123 bool TreeCtrlTestCase::ms_multiSelect
= false;
124 bool TreeCtrlTestCase::ms_hiddenRoot
= false;
126 void TreeCtrlTestCase::setUp()
128 m_tree
= new wxTreeCtrl(wxTheApp
->GetTopWindow(),
132 wxTR_DEFAULT_STYLE
| wxTR_EDIT_LABELS
);
134 if ( ms_multiSelect
)
135 m_tree
->ToggleWindowStyle(wxTR_MULTIPLE
);
138 m_tree
->ToggleWindowStyle(wxTR_HIDE_ROOT
); // actually set it
140 m_root
= m_tree
->AddRoot("root");
141 m_child1
= m_tree
->AppendItem(m_root
, "child1");
142 m_child2
= m_tree
->AppendItem(m_root
, "child2");
143 m_grandchild
= m_tree
->AppendItem(m_child1
, "grandchild");
145 m_tree
->SetSize(400, 200);
151 void TreeCtrlTestCase::tearDown()
159 m_grandchild
= wxTreeItemId();
162 // ----------------------------------------------------------------------------
163 // the tests themselves
164 // ----------------------------------------------------------------------------
166 void TreeCtrlTestCase::HasChildren()
168 CPPUNIT_ASSERT( m_tree
->HasChildren(m_root
) );
169 CPPUNIT_ASSERT( m_tree
->HasChildren(m_child1
) );
170 CPPUNIT_ASSERT( !m_tree
->HasChildren(m_child2
) );
171 CPPUNIT_ASSERT( !m_tree
->HasChildren(m_grandchild
) );
174 void TreeCtrlTestCase::SelectItemSingle()
176 // this test should be only ran in single-selection control
177 CPPUNIT_ASSERT( !m_tree
->HasFlag(wxTR_MULTIPLE
) );
179 // initially nothing is selected
180 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
182 // selecting an item should make it selected
183 m_tree
->SelectItem(m_child1
);
184 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
186 // selecting it again shouldn't change anything
187 m_tree
->SelectItem(m_child1
);
188 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
190 // selecting another item should switch the selection to it
191 m_tree
->SelectItem(m_child2
);
192 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
193 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
195 // selecting it again still shouldn't change anything
196 m_tree
->SelectItem(m_child2
);
197 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
198 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
200 // deselecting an item should remove the selection entirely
201 m_tree
->UnselectItem(m_child2
);
202 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
203 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child2
) );
206 void TreeCtrlTestCase::SelectItemMulti()
208 // this test should be only ran in multi-selection control
209 CPPUNIT_ASSERT( m_tree
->HasFlag(wxTR_MULTIPLE
) );
211 // initially nothing is selected
212 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
214 // selecting an item should make it selected
215 m_tree
->SelectItem(m_child1
);
216 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
218 // selecting it again shouldn't change anything
219 m_tree
->SelectItem(m_child1
);
220 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
222 // selecting another item shouldn't deselect the previously selected one
223 m_tree
->SelectItem(m_child2
);
224 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
225 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
227 // selecting it again still shouldn't change anything
228 m_tree
->SelectItem(m_child2
);
229 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child1
) );
230 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
232 // deselecting one of the items should leave the others selected
233 m_tree
->UnselectItem(m_child1
);
234 CPPUNIT_ASSERT( !m_tree
->IsSelected(m_child1
) );
235 CPPUNIT_ASSERT( m_tree
->IsSelected(m_child2
) );
238 void TreeCtrlTestCase::ItemClick()
240 #if wxUSE_UIACTIONSIMULATOR
241 EventCounter
activated(m_tree
, wxEVT_TREE_ITEM_ACTIVATED
);
242 EventCounter
rclick(m_tree
, wxEVT_TREE_ITEM_RIGHT_CLICK
);
244 wxUIActionSimulator sim
;
247 m_tree
->GetBoundingRect(m_child1
, pos
, true);
249 // We move in slightly so we are not on the edge
250 wxPoint point
= m_tree
->ClientToScreen(pos
.GetPosition()) + wxPoint(4, 4);
252 sim
.MouseMove(point
);
258 sim
.MouseClick(wxMOUSE_BTN_RIGHT
);
261 CPPUNIT_ASSERT_EQUAL(1, activated
.GetCount());
262 CPPUNIT_ASSERT_EQUAL(1, rclick
.GetCount());
263 #endif // wxUSE_UIACTIONSIMULATOR
266 void TreeCtrlTestCase::DeleteItem()
268 EventCounter
deleteitem(m_tree
, wxEVT_TREE_DELETE_ITEM
);
270 wxTreeItemId todelete
= m_tree
->AppendItem(m_root
, "deleteme");
271 m_tree
->Delete(todelete
);
272 // We do not test DeleteAllItems() as under some versions of Windows events
273 // are not generated.
275 CPPUNIT_ASSERT_EQUAL(1, deleteitem
.GetCount());
278 #if wxUSE_UIACTIONSIMULATOR
280 void TreeCtrlTestCase::LabelEdit()
282 EventCounter
beginedit(m_tree
, wxEVT_TREE_BEGIN_LABEL_EDIT
);
283 EventCounter
endedit(m_tree
, wxEVT_TREE_END_LABEL_EDIT
);
285 wxUIActionSimulator sim
;
287 m_tree
->SetFocusedItem(m_tree
->GetRootItem());
288 m_tree
->EditLabel(m_tree
->GetRootItem());
290 sim
.Text("newroottext");
293 CPPUNIT_ASSERT_EQUAL(1, beginedit
.GetCount());
295 sim
.Char(WXK_RETURN
);
298 CPPUNIT_ASSERT_EQUAL(1, endedit
.GetCount());
301 void TreeCtrlTestCase::KeyDown()
303 EventCounter
keydown(m_tree
, wxEVT_TREE_KEY_DOWN
);
305 wxUIActionSimulator sim
;
311 CPPUNIT_ASSERT_EQUAL(6, keydown
.GetCount());
314 #if !defined(__WXGTK__)
316 void TreeCtrlTestCase::CollapseExpandEvents()
318 m_tree
->CollapseAll();
320 EventCounter
collapsed(m_tree
, wxEVT_TREE_ITEM_COLLAPSED
);
321 EventCounter
collapsing(m_tree
, wxEVT_TREE_ITEM_COLLAPSING
);
322 EventCounter
expanded(m_tree
, wxEVT_TREE_ITEM_EXPANDED
);
323 EventCounter
expanding(m_tree
, wxEVT_TREE_ITEM_EXPANDING
);
325 wxUIActionSimulator sim
;
328 m_tree
->GetBoundingRect(m_root
, pos
, true);
330 // We move in slightly so we are not on the edge
331 wxPoint point
= m_tree
->ClientToScreen(pos
.GetPosition()) + wxPoint(4, 4);
333 sim
.MouseMove(point
);
339 CPPUNIT_ASSERT_EQUAL(1, expanding
.GetCount());
340 CPPUNIT_ASSERT_EQUAL(1, expanded
.GetCount());
345 CPPUNIT_ASSERT_EQUAL(1, collapsing
.GetCount());
346 CPPUNIT_ASSERT_EQUAL(1, collapsed
.GetCount());
349 void TreeCtrlTestCase::SelectionChange()
352 m_tree
->UnselectAll();
354 EventCounter
changed(m_tree
, wxEVT_TREE_SEL_CHANGED
);
355 EventCounter
changing(m_tree
, wxEVT_TREE_SEL_CHANGING
);
357 wxUIActionSimulator sim
;
359 wxRect poschild1
, poschild2
;
360 m_tree
->GetBoundingRect(m_child1
, poschild1
, true);
361 m_tree
->GetBoundingRect(m_child2
, poschild2
, true);
363 // We move in slightly so we are not on the edge
364 wxPoint point1
= m_tree
->ClientToScreen(poschild1
.GetPosition()) + wxPoint(4, 4);
365 wxPoint point2
= m_tree
->ClientToScreen(poschild2
.GetPosition()) + wxPoint(4, 4);
367 sim
.MouseMove(point1
);
373 sim
.MouseMove(point2
);
379 CPPUNIT_ASSERT_EQUAL(2, changed
.GetCount());
380 CPPUNIT_ASSERT_EQUAL(2, changing
.GetCount());
385 void TreeCtrlTestCase::Menu()
387 EventCounter
menu(m_tree
, wxEVT_TREE_ITEM_MENU
);
388 wxUIActionSimulator sim
;
391 m_tree
->GetBoundingRect(m_child1
, pos
, true);
393 // We move in slightly so we are not on the edge
394 wxPoint point
= m_tree
->ClientToScreen(pos
.GetPosition()) + wxPoint(4, 4);
396 sim
.MouseMove(point
);
399 sim
.MouseClick(wxMOUSE_BTN_RIGHT
);
402 CPPUNIT_ASSERT_EQUAL(1, menu
.GetCount());
405 #endif // wxUSE_UIACTIONSIMULATOR
407 void TreeCtrlTestCase::ItemData()
409 wxTreeItemData
* child1data
= new wxTreeItemData();
410 wxTreeItemData
* appenddata
= new wxTreeItemData();
411 wxTreeItemData
* insertdata
= new wxTreeItemData();
413 m_tree
->SetItemData(m_child1
, child1data
);
415 CPPUNIT_ASSERT_EQUAL(child1data
, m_tree
->GetItemData(m_child1
));
416 CPPUNIT_ASSERT_EQUAL(m_child1
, child1data
->GetId());
418 wxTreeItemId append
= m_tree
->AppendItem(m_root
, "new", -1, -1, appenddata
);
420 CPPUNIT_ASSERT_EQUAL(appenddata
, m_tree
->GetItemData(append
));
421 CPPUNIT_ASSERT_EQUAL(append
, appenddata
->GetId());
423 wxTreeItemId insert
= m_tree
->InsertItem(m_root
, m_child1
, "new", -1, -1,
426 CPPUNIT_ASSERT_EQUAL(insertdata
, m_tree
->GetItemData(insert
));
427 CPPUNIT_ASSERT_EQUAL(insert
, insertdata
->GetId());
430 void TreeCtrlTestCase::Iteration()
432 // Get first / next / last child
433 wxTreeItemIdValue cookie
;
434 CPPUNIT_ASSERT_EQUAL(m_tree
->GetFirstChild(m_root
, cookie
), m_child1
);
435 CPPUNIT_ASSERT_EQUAL(m_tree
->GetNextChild(m_root
, cookie
),
436 m_tree
->GetLastChild(m_root
));
437 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetLastChild(m_root
));
439 // Get next / previous sibling
440 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetNextSibling(m_child1
));
441 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetPrevSibling(m_child2
));
444 void TreeCtrlTestCase::Parent()
446 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetRootItem());
447 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetItemParent(m_child1
));
448 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetItemParent(m_child2
));
449 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetItemParent(m_grandchild
));
452 void TreeCtrlTestCase::CollapseExpand()
456 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_root
));
457 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
459 m_tree
->CollapseAll();
461 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
462 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_child1
));
464 m_tree
->ExpandAllChildren(m_root
);
466 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_root
));
467 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
469 m_tree
->CollapseAllChildren(m_child1
);
471 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_child1
));
473 m_tree
->Expand(m_child1
);
475 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
477 m_tree
->Collapse(m_root
);
479 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
480 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
482 m_tree
->CollapseAndReset(m_root
);
484 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
487 void TreeCtrlTestCase::AssignImageList()
491 wxImageList
*imagelist
= new wxImageList(size
.x
, size
.y
);
492 imagelist
->Add(wxArtProvider::GetIcon(wxART_QUESTION
, wxART_OTHER
, size
));
494 wxImageList
*statelist
= new wxImageList(size
.x
, size
.y
);
495 statelist
->Add(wxArtProvider::GetIcon(wxART_ERROR
, wxART_OTHER
, size
));
497 m_tree
->AssignImageList(imagelist
);
498 m_tree
->AssignStateImageList(statelist
);
500 CPPUNIT_ASSERT_EQUAL(imagelist
, m_tree
->GetImageList());
501 CPPUNIT_ASSERT_EQUAL(statelist
, m_tree
->GetStateImageList());
504 void TreeCtrlTestCase::Focus()
506 #if !defined(__WXGTK__) && !defined(__WXOSX__)
507 m_tree
->SetFocusedItem(m_child1
);
509 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetFocusedItem());
511 m_tree
->ClearFocusedItem();
513 CPPUNIT_ASSERT(!m_tree
->GetFocusedItem());
517 void TreeCtrlTestCase::Bold()
519 CPPUNIT_ASSERT(!m_tree
->IsBold(m_child1
));
521 m_tree
->SetItemBold(m_child1
);
523 CPPUNIT_ASSERT(m_tree
->IsBold(m_child1
));
525 m_tree
->SetItemBold(m_child1
, false);
527 CPPUNIT_ASSERT(!m_tree
->IsBold(m_child1
));
530 void TreeCtrlTestCase::Visible()
532 m_tree
->CollapseAll();
534 CPPUNIT_ASSERT(m_tree
->IsVisible(m_root
));
535 CPPUNIT_ASSERT(!m_tree
->IsVisible(m_child1
));
537 m_tree
->EnsureVisible(m_grandchild
);
539 CPPUNIT_ASSERT(m_tree
->IsVisible(m_grandchild
));
543 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetFirstVisibleItem());
544 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetNextVisible(m_root
));
545 CPPUNIT_ASSERT_EQUAL(m_grandchild
, m_tree
->GetNextVisible(m_child1
));
546 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetNextVisible(m_grandchild
));
548 CPPUNIT_ASSERT(!m_tree
->GetNextVisible(m_child2
));
549 CPPUNIT_ASSERT(!m_tree
->GetPrevVisible(m_root
));
552 void TreeCtrlTestCase::Sort()
554 wxTreeItemId zitem
= m_tree
->AppendItem(m_root
, "zzzz");
555 wxTreeItemId aitem
= m_tree
->AppendItem(m_root
, "aaaa");
557 m_tree
->SortChildren(m_root
);
559 wxTreeItemIdValue cookie
;
561 CPPUNIT_ASSERT_EQUAL(aitem
, m_tree
->GetFirstChild(m_root
, cookie
));
562 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetNextChild(m_root
, cookie
));
563 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetNextChild(m_root
, cookie
));
564 CPPUNIT_ASSERT_EQUAL(zitem
, m_tree
->GetNextChild(m_root
, cookie
));
567 void TreeCtrlTestCase::KeyNavigation()
569 #if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__)
570 wxUIActionSimulator sim
;
572 m_tree
->CollapseAll();
574 m_tree
->SelectItem(m_root
);
580 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_root
));
585 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
591 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetSelection());
596 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetSelection());
600 #endif //wxUSE_TREECTRL