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 wxTestableFrame
* frame
= wxStaticCast(wxTheApp
->GetTopWindow(),
245 EventCounter
count(m_tree
, wxEVT_COMMAND_TREE_ITEM_ACTIVATED
);
246 EventCounter
count1(m_tree
, wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK
);
248 wxUIActionSimulator sim
;
251 m_tree
->GetBoundingRect(m_child1
, pos
, true);
253 // We move in slightly so we are not on the edge
254 wxPoint point
= m_tree
->ClientToScreen(pos
.GetPosition()) + wxPoint(4, 4);
256 sim
.MouseMove(point
);
262 sim
.MouseClick(wxMOUSE_BTN_RIGHT
);
265 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount(wxEVT_COMMAND_TREE_ITEM_ACTIVATED
));
266 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK
));
267 #endif // wxUSE_UIACTIONSIMULATOR
270 void TreeCtrlTestCase::DeleteItem()
272 wxTestableFrame
* frame
= wxStaticCast(wxTheApp
->GetTopWindow(),
275 EventCounter
count(m_tree
, wxEVT_COMMAND_TREE_DELETE_ITEM
);
277 wxTreeItemId todelete
= m_tree
->AppendItem(m_root
, "deleteme");
278 m_tree
->Delete(todelete
);
279 // We do not test DeleteAllItems() as under some versions of Windows events
280 // are not generated.
282 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount());
285 #if wxUSE_UIACTIONSIMULATOR
287 void TreeCtrlTestCase::LabelEdit()
289 wxTestableFrame
* frame
= wxStaticCast(wxTheApp
->GetTopWindow(),
292 EventCounter
count(m_tree
, wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT
);
293 EventCounter
count1(m_tree
, wxEVT_COMMAND_TREE_END_LABEL_EDIT
);
295 wxUIActionSimulator sim
;
297 m_tree
->SetFocusedItem(m_tree
->GetRootItem());
298 m_tree
->EditLabel(m_tree
->GetRootItem());
300 sim
.Text("newroottext");
303 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount());
305 sim
.Char(WXK_RETURN
);
308 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount());
311 void TreeCtrlTestCase::KeyDown()
313 wxTestableFrame
* frame
= wxStaticCast(wxTheApp
->GetTopWindow(),
316 EventCounter
count(m_tree
, wxEVT_COMMAND_TREE_KEY_DOWN
);
318 wxUIActionSimulator sim
;
324 CPPUNIT_ASSERT_EQUAL(6, frame
->GetEventCount());
327 #if !defined(__WXGTK__)
329 void TreeCtrlTestCase::CollapseExpandEvents()
331 wxTestableFrame
* frame
= wxStaticCast(wxTheApp
->GetTopWindow(),
334 m_tree
->CollapseAll();
336 EventCounter
count(m_tree
, wxEVT_COMMAND_TREE_ITEM_COLLAPSED
);
337 EventCounter
count1(m_tree
, wxEVT_COMMAND_TREE_ITEM_COLLAPSING
);
338 EventCounter
count2(m_tree
, wxEVT_COMMAND_TREE_ITEM_EXPANDED
);
339 EventCounter
count3(m_tree
, wxEVT_COMMAND_TREE_ITEM_EXPANDING
);
341 wxUIActionSimulator sim
;
344 m_tree
->GetBoundingRect(m_root
, pos
, true);
346 // We move in slightly so we are not on the edge
347 wxPoint point
= m_tree
->ClientToScreen(pos
.GetPosition()) + wxPoint(4, 4);
349 sim
.MouseMove(point
);
355 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount(wxEVT_COMMAND_TREE_ITEM_EXPANDING
));
356 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount(wxEVT_COMMAND_TREE_ITEM_EXPANDED
));
361 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount(wxEVT_COMMAND_TREE_ITEM_COLLAPSING
));
362 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount(wxEVT_COMMAND_TREE_ITEM_COLLAPSED
));
365 void TreeCtrlTestCase::SelectionChange()
367 wxTestableFrame
* frame
= wxStaticCast(wxTheApp
->GetTopWindow(),
371 m_tree
->UnselectAll();
373 EventCounter
count(m_tree
, wxEVT_COMMAND_TREE_SEL_CHANGED
);
374 EventCounter
count1(m_tree
, wxEVT_COMMAND_TREE_SEL_CHANGING
);
376 wxUIActionSimulator sim
;
378 wxRect poschild1
, poschild2
;
379 m_tree
->GetBoundingRect(m_child1
, poschild1
, true);
380 m_tree
->GetBoundingRect(m_child1
, poschild2
, true);
382 // We move in slightly so we are not on the edge
383 wxPoint point1
= m_tree
->ClientToScreen(poschild1
.GetPosition()) + wxPoint(4, 4);
384 wxPoint point2
= m_tree
->ClientToScreen(poschild2
.GetPosition()) + wxPoint(4, 4);
386 sim
.MouseMove(point1
);
392 sim
.MouseMove(point2
);
398 CPPUNIT_ASSERT_EQUAL(2, frame
->GetEventCount(wxEVT_COMMAND_TREE_SEL_CHANGED
));
399 CPPUNIT_ASSERT_EQUAL(2, frame
->GetEventCount(wxEVT_COMMAND_TREE_SEL_CHANGING
));
404 void TreeCtrlTestCase::Menu()
406 wxTestableFrame
* frame
= wxStaticCast(wxTheApp
->GetTopWindow(),
409 EventCounter
count(m_tree
, wxEVT_COMMAND_TREE_ITEM_MENU
);
410 wxUIActionSimulator sim
;
413 m_tree
->GetBoundingRect(m_child1
, pos
, true);
415 // We move in slightly so we are not on the edge
416 wxPoint point
= m_tree
->ClientToScreen(pos
.GetPosition()) + wxPoint(4, 4);
418 sim
.MouseMove(point
);
421 sim
.MouseClick(wxMOUSE_BTN_RIGHT
);
424 CPPUNIT_ASSERT_EQUAL(1, frame
->GetEventCount(wxEVT_COMMAND_TREE_ITEM_MENU
));
427 #endif // wxUSE_UIACTIONSIMULATOR
429 void TreeCtrlTestCase::ItemData()
431 wxTreeItemData
* child1data
= new wxTreeItemData();
432 wxTreeItemData
* appenddata
= new wxTreeItemData();
433 wxTreeItemData
* insertdata
= new wxTreeItemData();
435 m_tree
->SetItemData(m_child1
, child1data
);
437 CPPUNIT_ASSERT_EQUAL(child1data
, m_tree
->GetItemData(m_child1
));
438 CPPUNIT_ASSERT_EQUAL(m_child1
, child1data
->GetId());
440 wxTreeItemId append
= m_tree
->AppendItem(m_root
, "new", -1, -1, appenddata
);
442 CPPUNIT_ASSERT_EQUAL(appenddata
, m_tree
->GetItemData(append
));
443 CPPUNIT_ASSERT_EQUAL(append
, appenddata
->GetId());
445 wxTreeItemId insert
= m_tree
->InsertItem(m_root
, m_child1
, "new", -1, -1,
448 CPPUNIT_ASSERT_EQUAL(insertdata
, m_tree
->GetItemData(insert
));
449 CPPUNIT_ASSERT_EQUAL(insert
, insertdata
->GetId());
452 void TreeCtrlTestCase::Iteration()
454 // Get first / next / last child
455 wxTreeItemIdValue cookie
;
456 CPPUNIT_ASSERT_EQUAL(m_tree
->GetFirstChild(m_root
, cookie
), m_child1
);
457 CPPUNIT_ASSERT_EQUAL(m_tree
->GetNextChild(m_root
, cookie
),
458 m_tree
->GetLastChild(m_root
));
459 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetLastChild(m_root
));
461 // Get next / previous sibling
462 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetNextSibling(m_child1
));
463 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetPrevSibling(m_child2
));
466 void TreeCtrlTestCase::Parent()
468 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetRootItem());
469 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetItemParent(m_child1
));
470 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetItemParent(m_child2
));
471 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetItemParent(m_grandchild
));
474 void TreeCtrlTestCase::CollapseExpand()
478 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_root
));
479 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
481 m_tree
->CollapseAll();
483 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
484 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_child1
));
486 m_tree
->ExpandAllChildren(m_root
);
488 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_root
));
489 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
491 m_tree
->CollapseAllChildren(m_child1
);
493 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_child1
));
495 m_tree
->Expand(m_child1
);
497 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
499 m_tree
->Collapse(m_root
);
501 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
502 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_child1
));
504 m_tree
->CollapseAndReset(m_root
);
506 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
509 void TreeCtrlTestCase::AssignImageList()
513 wxImageList
*imagelist
= new wxImageList(size
.x
, size
.y
);
514 imagelist
->Add(wxArtProvider::GetIcon(wxART_QUESTION
, wxART_OTHER
, size
));
516 wxImageList
*statelist
= new wxImageList(size
.x
, size
.y
);
517 statelist
->Add(wxArtProvider::GetIcon(wxART_ERROR
, wxART_OTHER
, size
));
519 m_tree
->AssignImageList(imagelist
);
520 m_tree
->AssignStateImageList(statelist
);
522 CPPUNIT_ASSERT_EQUAL(imagelist
, m_tree
->GetImageList());
523 CPPUNIT_ASSERT_EQUAL(statelist
, m_tree
->GetStateImageList());
526 void TreeCtrlTestCase::Focus()
528 #if !defined(__WXGTK__) && !defined(__WXOSX__)
529 m_tree
->SetFocusedItem(m_child1
);
531 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetFocusedItem());
533 m_tree
->ClearFocusedItem();
535 CPPUNIT_ASSERT(!m_tree
->GetFocusedItem());
539 void TreeCtrlTestCase::Bold()
541 CPPUNIT_ASSERT(!m_tree
->IsBold(m_child1
));
543 m_tree
->SetItemBold(m_child1
);
545 CPPUNIT_ASSERT(m_tree
->IsBold(m_child1
));
547 m_tree
->SetItemBold(m_child1
, false);
549 CPPUNIT_ASSERT(!m_tree
->IsBold(m_child1
));
552 void TreeCtrlTestCase::Visible()
554 m_tree
->CollapseAll();
556 CPPUNIT_ASSERT(m_tree
->IsVisible(m_root
));
557 CPPUNIT_ASSERT(!m_tree
->IsVisible(m_child1
));
559 m_tree
->EnsureVisible(m_grandchild
);
561 CPPUNIT_ASSERT(m_tree
->IsVisible(m_grandchild
));
565 CPPUNIT_ASSERT_EQUAL(m_root
, m_tree
->GetFirstVisibleItem());
566 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetNextVisible(m_root
));
567 CPPUNIT_ASSERT_EQUAL(m_grandchild
, m_tree
->GetNextVisible(m_child1
));
568 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetNextVisible(m_grandchild
));
570 CPPUNIT_ASSERT(!m_tree
->GetNextVisible(m_child2
));
571 CPPUNIT_ASSERT(!m_tree
->GetPrevVisible(m_root
));
574 void TreeCtrlTestCase::Sort()
576 wxTreeItemId zitem
= m_tree
->AppendItem(m_root
, "zzzz");
577 wxTreeItemId aitem
= m_tree
->AppendItem(m_root
, "aaaa");
579 m_tree
->SortChildren(m_root
);
581 wxTreeItemIdValue cookie
;
583 CPPUNIT_ASSERT_EQUAL(aitem
, m_tree
->GetFirstChild(m_root
, cookie
));
584 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetNextChild(m_root
, cookie
));
585 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetNextChild(m_root
, cookie
));
586 CPPUNIT_ASSERT_EQUAL(zitem
, m_tree
->GetNextChild(m_root
, cookie
));
589 void TreeCtrlTestCase::KeyNavigation()
591 #if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__)
592 wxUIActionSimulator sim
;
594 m_tree
->CollapseAll();
596 m_tree
->SelectItem(m_root
);
602 CPPUNIT_ASSERT(m_tree
->IsExpanded(m_root
));
607 CPPUNIT_ASSERT(!m_tree
->IsExpanded(m_root
));
613 CPPUNIT_ASSERT_EQUAL(m_child1
, m_tree
->GetSelection());
618 CPPUNIT_ASSERT_EQUAL(m_child2
, m_tree
->GetSelection());
622 #endif //wxUSE_TREECTRL