| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ui/views/controls/table/table_view.h" | 5 #include "ui/views/controls/table/table_view.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 #include "ui/events/event_utils.h" | 13 #include "ui/events/event_utils.h" |
| 14 #include "ui/events/test/event_generator.h" |
| 14 #include "ui/views/controls/table/table_grouper.h" | 15 #include "ui/views/controls/table/table_grouper.h" |
| 15 #include "ui/views/controls/table/table_header.h" | 16 #include "ui/views/controls/table/table_header.h" |
| 16 #include "ui/views/controls/table/table_view_observer.h" | 17 #include "ui/views/controls/table/table_view_observer.h" |
| 18 #include "ui/views/test/views_test_base.h" |
| 17 | 19 |
| 18 // Put the tests in the views namespace to make it easier to declare them as | 20 // Put the tests in the views namespace to make it easier to declare them as |
| 19 // friend classes. | 21 // friend classes. |
| 20 namespace views { | 22 namespace views { |
| 21 | 23 |
| 22 class TableViewTestHelper { | 24 class TableViewTestHelper { |
| 23 public: | 25 public: |
| 24 explicit TableViewTestHelper(TableView* table) : table_(table) {} | 26 explicit TableViewTestHelper(TableView* table) : table_(table) {} |
| 25 | 27 |
| 26 std::string GetPaintRegion(const gfx::Rect& bounds) { | 28 std::string GetPaintRegion(const gfx::Rect& bounds) { |
| 27 TableView::PaintRegion region(table_->GetPaintRegion(bounds)); | 29 TableView::PaintRegion region(table_->GetPaintRegion(bounds)); |
| 28 return "rows=" + base::IntToString(region.min_row) + " " + | 30 return "rows=" + base::IntToString(region.min_row) + " " + |
| 29 base::IntToString(region.max_row) + " cols=" + | 31 base::IntToString(region.max_row) + " cols=" + |
| 30 base::IntToString(region.min_column) + " " + | 32 base::IntToString(region.min_column) + " " + |
| 31 base::IntToString(region.max_column); | 33 base::IntToString(region.max_column); |
| 32 } | 34 } |
| 33 | 35 |
| 34 size_t visible_col_count() { | 36 size_t visible_col_count() { |
| 35 return table_->visible_columns().size(); | 37 return table_->visible_columns().size(); |
| 36 } | 38 } |
| 37 | 39 |
| 38 TableHeader* header() { return table_->header_; } | 40 TableHeader* header() { return table_->header_; } |
| 39 | 41 |
| 40 void SetSelectionModel(const ui::ListSelectionModel& new_selection) { | 42 void SetSelectionModel(const ui::ListSelectionModel& new_selection) { |
| 41 table_->SetSelectionModel(new_selection); | 43 table_->SetSelectionModel(new_selection); |
| 42 } | 44 } |
| 43 | 45 |
| 44 void OnFocus() { | |
| 45 table_->OnFocus(); | |
| 46 } | |
| 47 | |
| 48 private: | 46 private: |
| 49 TableView* table_; | 47 TableView* table_; |
| 50 | 48 |
| 51 DISALLOW_COPY_AND_ASSIGN(TableViewTestHelper); | 49 DISALLOW_COPY_AND_ASSIGN(TableViewTestHelper); |
| 52 }; | 50 }; |
| 53 | 51 |
| 54 namespace { | 52 namespace { |
| 55 | 53 |
| 56 // TestTableModel2 ------------------------------------------------------------- | 54 // TestTableModel2 ------------------------------------------------------------- |
| 57 | 55 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 result += ", "; // Comma between each value in the row. | 175 result += ", "; // Comma between each value in the row. |
| 178 | 176 |
| 179 result += base::UTF16ToUTF8( | 177 result += base::UTF16ToUTF8( |
| 180 table->model()->GetText(table->ViewToModel(i), column.id)); | 178 table->model()->GetText(table->ViewToModel(i), column.id)); |
| 181 } | 179 } |
| 182 result += "]"; | 180 result += "]"; |
| 183 } | 181 } |
| 184 return result; | 182 return result; |
| 185 } | 183 } |
| 186 | 184 |
| 187 class TestTableView : public TableView { | |
| 188 public: | |
| 189 TestTableView(ui::TableModel* model, | |
| 190 const std::vector<ui::TableColumn>& columns) | |
| 191 : TableView(model, columns, TEXT_ONLY, false) { | |
| 192 } | |
| 193 | |
| 194 // View overrides: | |
| 195 bool HasFocus() const override { | |
| 196 // Overriden so key processing works. | |
| 197 return true; | |
| 198 } | |
| 199 | |
| 200 private: | |
| 201 DISALLOW_COPY_AND_ASSIGN(TestTableView); | |
| 202 }; | |
| 203 | |
| 204 } // namespace | 185 } // namespace |
| 205 | 186 |
| 206 class TableViewTest : public testing::Test { | 187 class TableViewTest : public ViewsTestBase { |
| 207 public: | 188 public: |
| 208 TableViewTest() : table_(NULL) {} | 189 TableViewTest() : table_(NULL) {} |
| 209 | 190 |
| 210 void SetUp() override { | 191 void SetUp() override { |
| 192 ViewsTestBase::SetUp(); |
| 193 |
| 211 model_.reset(new TestTableModel2); | 194 model_.reset(new TestTableModel2); |
| 212 std::vector<ui::TableColumn> columns(2); | 195 std::vector<ui::TableColumn> columns(2); |
| 213 columns[0].title = base::ASCIIToUTF16("Title Column 0"); | 196 columns[0].title = base::ASCIIToUTF16("Title Column 0"); |
| 214 columns[0].sortable = true; | 197 columns[0].sortable = true; |
| 215 columns[1].title = base::ASCIIToUTF16("Title Column 1"); | 198 columns[1].title = base::ASCIIToUTF16("Title Column 1"); |
| 216 columns[1].id = 1; | 199 columns[1].id = 1; |
| 217 columns[1].sortable = true; | 200 columns[1].sortable = true; |
| 218 table_ = new TestTableView(model_.get(), columns); | 201 table_ = new TableView(model_.get(), columns, TEXT_ONLY, false); |
| 219 parent_.reset(table_->CreateParentIfNecessary()); | 202 View* parent = table_->CreateParentIfNecessary(); |
| 220 parent_->SetBounds(0, 0, 10000, 10000); | 203 parent->SetBounds(0, 0, 10000, 10000); |
| 221 parent_->Layout(); | 204 parent->Layout(); |
| 222 helper_.reset(new TableViewTestHelper(table_)); | 205 helper_.reset(new TableViewTestHelper(table_)); |
| 206 |
| 207 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW); |
| 208 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 209 params.bounds = gfx::Rect(0, 0, 650, 650); |
| 210 widget_.reset(new Widget); |
| 211 widget_->Init(params); |
| 212 widget_->GetContentsView()->AddChildView(parent); |
| 213 widget_->Show(); |
| 214 } |
| 215 |
| 216 void TearDown() override { |
| 217 widget_.reset(); |
| 218 ViewsTestBase::TearDown(); |
| 223 } | 219 } |
| 224 | 220 |
| 225 void ClickOnRow(int row, int flags) { | 221 void ClickOnRow(int row, int flags) { |
| 226 const int y = row * table_->row_height(); | 222 ui::test::EventGenerator generator(widget_->GetNativeWindow()); |
| 227 const ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(0, y), | 223 generator.set_flags(flags); |
| 228 gfx::Point(0, y), ui::EventTimeForNow(), | 224 generator.set_current_location(GetPointForRow(row)); |
| 229 ui::EF_LEFT_MOUSE_BUTTON | flags, | 225 generator.PressLeftButton(); |
| 230 ui::EF_LEFT_MOUSE_BUTTON); | |
| 231 table_->OnMousePressed(pressed); | |
| 232 } | 226 } |
| 233 | 227 |
| 234 void TapOnRow(int row) { | 228 void TapOnRow(int row) { |
| 235 const int y = row * table_->row_height(); | 229 ui::test::EventGenerator generator(widget_->GetNativeWindow()); |
| 236 const ui::GestureEventDetails event_details(ui::ET_GESTURE_TAP); | 230 generator.GestureTapAt(GetPointForRow(row)); |
| 237 ui::GestureEvent tap(0, y, 0, base::TimeTicks(), event_details); | |
| 238 table_->OnGestureEvent(&tap); | |
| 239 } | 231 } |
| 240 | 232 |
| 241 // Returns the state of the selection model as a string. The format is: | 233 // Returns the state of the selection model as a string. The format is: |
| 242 // 'active=X anchor=X selection=X X X...'. | 234 // 'active=X anchor=X selection=X X X...'. |
| 243 std::string SelectionStateAsString() const { | 235 std::string SelectionStateAsString() const { |
| 244 const ui::ListSelectionModel& model(table_->selection_model()); | 236 const ui::ListSelectionModel& model(table_->selection_model()); |
| 245 std::string result = "active=" + base::IntToString(model.active()) + | 237 std::string result = "active=" + base::IntToString(model.active()) + |
| 246 " anchor=" + base::IntToString(model.anchor()) + | 238 " anchor=" + base::IntToString(model.anchor()) + |
| 247 " selection="; | 239 " selection="; |
| 248 const ui::ListSelectionModel::SelectedIndices& selection( | 240 const ui::ListSelectionModel::SelectedIndices& selection( |
| 249 model.selected_indices()); | 241 model.selected_indices()); |
| 250 for (size_t i = 0; i < selection.size(); ++i) { | 242 for (size_t i = 0; i < selection.size(); ++i) { |
| 251 if (i != 0) | 243 if (i != 0) |
| 252 result += " "; | 244 result += " "; |
| 253 result += base::IntToString(selection[i]); | 245 result += base::IntToString(selection[i]); |
| 254 } | 246 } |
| 255 return result; | 247 return result; |
| 256 } | 248 } |
| 257 | 249 |
| 258 void PressKey(ui::KeyboardCode code) { | 250 void PressKey(ui::KeyboardCode code) { |
| 259 ui::KeyEvent event(ui::ET_KEY_PRESSED, code, ui::EF_NONE); | 251 ui::test::EventGenerator generator(widget_->GetNativeWindow()); |
| 260 table_->OnKeyPressed(event); | 252 generator.PressKey(code, ui::EF_NONE); |
| 261 } | 253 } |
| 262 | 254 |
| 263 protected: | 255 protected: |
| 264 std::unique_ptr<TestTableModel2> model_; | 256 std::unique_ptr<TestTableModel2> model_; |
| 265 | 257 |
| 266 // Owned by |parent_|. | 258 // Owned by |parent_|. |
| 267 TableView* table_; | 259 TableView* table_; |
| 268 | 260 |
| 269 std::unique_ptr<TableViewTestHelper> helper_; | 261 std::unique_ptr<TableViewTestHelper> helper_; |
| 270 | 262 |
| 271 private: | 263 private: |
| 272 std::unique_ptr<View> parent_; | 264 gfx::Point GetPointForRow(int row) { |
| 265 const int y = (row + 0.5) * table_->row_height(); |
| 266 return table_->GetBoundsInScreen().origin() + gfx::Vector2d(5, y); |
| 267 } |
| 268 |
| 269 std::unique_ptr<Widget> widget_; |
| 273 | 270 |
| 274 DISALLOW_COPY_AND_ASSIGN(TableViewTest); | 271 DISALLOW_COPY_AND_ASSIGN(TableViewTest); |
| 275 }; | 272 }; |
| 276 | 273 |
| 277 // Verifies GetPaintRegion. | 274 // Verifies GetPaintRegion. |
| 278 TEST_F(TableViewTest, GetPaintRegion) { | 275 TEST_F(TableViewTest, GetPaintRegion) { |
| 279 // Two columns should be visible. | 276 // Two columns should be visible. |
| 280 EXPECT_EQ(2u, helper_->visible_col_count()); | 277 EXPECT_EQ(2u, helper_->visible_col_count()); |
| 281 | 278 |
| 282 EXPECT_EQ("rows=0 4 cols=0 2", helper_->GetPaintRegion(table_->bounds())); | 279 EXPECT_EQ("rows=0 4 cols=0 2", helper_->GetPaintRegion(table_->bounds())); |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 EXPECT_EQ("active=0 anchor=0 selection=0", SelectionStateAsString()); | 717 EXPECT_EQ("active=0 anchor=0 selection=0", SelectionStateAsString()); |
| 721 | 718 |
| 722 // Remove the selected row. | 719 // Remove the selected row. |
| 723 model_->RemoveRow(0); | 720 model_->RemoveRow(0); |
| 724 EXPECT_EQ(1, observer.GetChangedCountAndClear()); | 721 EXPECT_EQ(1, observer.GetChangedCountAndClear()); |
| 725 EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString()); | 722 EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString()); |
| 726 | 723 |
| 727 table_->set_observer(nullptr); | 724 table_->set_observer(nullptr); |
| 728 } | 725 } |
| 729 | 726 |
| 727 // No touch on desktop Mac. Tracked in http://crbug.com/445520. |
| 728 #if !defined(OS_MACOSX) |
| 730 // Verifies selection works by way of a gesture. | 729 // Verifies selection works by way of a gesture. |
| 731 TEST_F(TableViewTest, SelectOnTap) { | 730 TEST_F(TableViewTest, SelectOnTap) { |
| 732 // Initially no selection. | 731 // Initially no selection. |
| 733 EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString()); | 732 EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString()); |
| 734 | 733 |
| 735 TableViewObserverImpl observer; | 734 TableViewObserverImpl observer; |
| 736 table_->set_observer(&observer); | 735 table_->set_observer(&observer); |
| 737 | 736 |
| 738 // Click on the first row, should select it. | 737 // Tap on the first row, should select it. |
| 739 TapOnRow(0); | 738 TapOnRow(0); |
| 740 EXPECT_EQ(1, observer.GetChangedCountAndClear()); | 739 EXPECT_EQ(1, observer.GetChangedCountAndClear()); |
| 741 EXPECT_EQ("active=0 anchor=0 selection=0", SelectionStateAsString()); | 740 EXPECT_EQ("active=0 anchor=0 selection=0", SelectionStateAsString()); |
| 742 | 741 |
| 743 table_->set_observer(NULL); | 742 table_->set_observer(NULL); |
| 744 } | 743 } |
| 744 #endif |
| 745 | 745 |
| 746 // Verifies up/down correctly navigates through groups. | 746 // Verifies up/down correctly navigates through groups. |
| 747 TEST_F(TableViewTest, KeyUpDown) { | 747 TEST_F(TableViewTest, KeyUpDown) { |
| 748 // Configure the grouper so that there are three groups: | 748 // Configure the grouper so that there are three groups: |
| 749 // A 0 | 749 // A 0 |
| 750 // 1 | 750 // 1 |
| 751 // B 5 | 751 // B 5 |
| 752 // C 2 | 752 // C 2 |
| 753 // 3 | 753 // 3 |
| 754 model_->AddRow(2, 5, 0); | 754 model_->AddRow(2, 5, 0); |
| 755 TableGrouperImpl grouper; | 755 TableGrouperImpl grouper; |
| 756 std::vector<int> ranges; | 756 std::vector<int> ranges; |
| 757 ranges.push_back(2); | 757 ranges.push_back(2); |
| 758 ranges.push_back(1); | 758 ranges.push_back(1); |
| 759 ranges.push_back(2); | 759 ranges.push_back(2); |
| 760 grouper.SetRanges(ranges); | 760 grouper.SetRanges(ranges); |
| 761 table_->SetGrouper(&grouper); | 761 table_->SetGrouper(&grouper); |
| 762 | 762 |
| 763 TableViewObserverImpl observer; | 763 TableViewObserverImpl observer; |
| 764 table_->set_observer(&observer); | 764 table_->set_observer(&observer); |
| 765 table_->RequestFocus(); |
| 765 | 766 |
| 766 // Initially no selection. | 767 // Initially no selection. |
| 767 EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString()); | 768 EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString()); |
| 768 | 769 |
| 769 PressKey(ui::VKEY_DOWN); | 770 PressKey(ui::VKEY_DOWN); |
| 770 EXPECT_EQ(1, observer.GetChangedCountAndClear()); | 771 EXPECT_EQ(1, observer.GetChangedCountAndClear()); |
| 771 EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString()); | 772 EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString()); |
| 772 | 773 |
| 773 PressKey(ui::VKEY_DOWN); | 774 PressKey(ui::VKEY_DOWN); |
| 774 EXPECT_EQ(1, observer.GetChangedCountAndClear()); | 775 EXPECT_EQ(1, observer.GetChangedCountAndClear()); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 TableGrouperImpl grouper; | 886 TableGrouperImpl grouper; |
| 886 std::vector<int> ranges; | 887 std::vector<int> ranges; |
| 887 ranges.push_back(2); | 888 ranges.push_back(2); |
| 888 ranges.push_back(1); | 889 ranges.push_back(1); |
| 889 ranges.push_back(2); | 890 ranges.push_back(2); |
| 890 grouper.SetRanges(ranges); | 891 grouper.SetRanges(ranges); |
| 891 table_->SetGrouper(&grouper); | 892 table_->SetGrouper(&grouper); |
| 892 | 893 |
| 893 TableViewObserverImpl observer; | 894 TableViewObserverImpl observer; |
| 894 table_->set_observer(&observer); | 895 table_->set_observer(&observer); |
| 896 table_->RequestFocus(); |
| 895 | 897 |
| 896 // Initially no selection. | 898 // Initially no selection. |
| 897 EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString()); | 899 EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString()); |
| 898 | 900 |
| 899 PressKey(ui::VKEY_HOME); | 901 PressKey(ui::VKEY_HOME); |
| 900 EXPECT_EQ(1, observer.GetChangedCountAndClear()); | 902 EXPECT_EQ(1, observer.GetChangedCountAndClear()); |
| 901 EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString()); | 903 EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString()); |
| 902 | 904 |
| 903 PressKey(ui::VKEY_END); | 905 PressKey(ui::VKEY_END); |
| 904 EXPECT_EQ(1, observer.GetChangedCountAndClear()); | 906 EXPECT_EQ(1, observer.GetChangedCountAndClear()); |
| 905 EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString()); | 907 EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString()); |
| 906 | 908 |
| 909 PressKey(ui::VKEY_HOME); |
| 910 EXPECT_EQ(1, observer.GetChangedCountAndClear()); |
| 911 EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString()); |
| 912 |
| 907 table_->set_observer(NULL); | 913 table_->set_observer(NULL); |
| 908 } | 914 } |
| 909 | 915 |
| 916 // TODO(tapted): enable these tests on Mac. |
| 917 #if !defined(OS_MACOSX) |
| 910 // Verifies multiple selection gestures work (control-click, shift-click ...). | 918 // Verifies multiple selection gestures work (control-click, shift-click ...). |
| 911 TEST_F(TableViewTest, Multiselection) { | 919 TEST_F(TableViewTest, Multiselection) { |
| 912 // Configure the grouper so that there are three groups: | 920 // Configure the grouper so that there are three groups: |
| 913 // A 0 | 921 // A 0 |
| 914 // 1 | 922 // 1 |
| 915 // B 5 | 923 // B 5 |
| 916 // C 2 | 924 // C 2 |
| 917 // 3 | 925 // 3 |
| 918 model_->AddRow(2, 5, 0); | 926 model_->AddRow(2, 5, 0); |
| 919 TableGrouperImpl grouper; | 927 TableGrouperImpl grouper; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 EXPECT_EQ(1, observer.GetChangedCountAndClear()); | 1008 EXPECT_EQ(1, observer.GetChangedCountAndClear()); |
| 1001 EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString()); | 1009 EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString()); |
| 1002 | 1010 |
| 1003 // Extend selection to first row. | 1011 // Extend selection to first row. |
| 1004 ClickOnRow(0, ui::EF_SHIFT_DOWN); | 1012 ClickOnRow(0, ui::EF_SHIFT_DOWN); |
| 1005 EXPECT_EQ(1, observer.GetChangedCountAndClear()); | 1013 EXPECT_EQ(1, observer.GetChangedCountAndClear()); |
| 1006 EXPECT_EQ("active=2 anchor=4 selection=2 3 4", SelectionStateAsString()); | 1014 EXPECT_EQ("active=2 anchor=4 selection=2 3 4", SelectionStateAsString()); |
| 1007 | 1015 |
| 1008 table_->set_observer(NULL); | 1016 table_->set_observer(NULL); |
| 1009 } | 1017 } |
| 1018 #endif |
| 1010 | 1019 |
| 1011 // Verifies we don't crash after removing the selected row when there is | 1020 // Verifies we don't crash after removing the selected row when there is |
| 1012 // sorting and the anchor/active index also match the selected row. | 1021 // sorting and the anchor/active index also match the selected row. |
| 1013 TEST_F(TableViewTest, FocusAfterRemovingAnchor) { | 1022 TEST_F(TableViewTest, FocusAfterRemovingAnchor) { |
| 1014 table_->ToggleSortOrder(0); | 1023 table_->ToggleSortOrder(0); |
| 1015 | 1024 |
| 1016 ui::ListSelectionModel new_selection; | 1025 ui::ListSelectionModel new_selection; |
| 1017 new_selection.AddIndexToSelection(0); | 1026 new_selection.AddIndexToSelection(0); |
| 1018 new_selection.AddIndexToSelection(1); | 1027 new_selection.AddIndexToSelection(1); |
| 1019 new_selection.set_active(0); | 1028 new_selection.set_active(0); |
| 1020 new_selection.set_anchor(0); | 1029 new_selection.set_anchor(0); |
| 1021 helper_->SetSelectionModel(new_selection); | 1030 helper_->SetSelectionModel(new_selection); |
| 1022 model_->RemoveRow(0); | 1031 model_->RemoveRow(0); |
| 1023 helper_->OnFocus(); | 1032 table_->RequestFocus(); |
| 1024 } | |
| 1025 | |
| 1026 // Tests that focusing the table will activate the first row, but only if | |
| 1027 // there's no active row. | |
| 1028 TEST_F(TableViewTest, InitialFocusActivatesFirstRow) { | |
| 1029 EXPECT_EQ(-1, table_->selection_model().active()); | |
| 1030 helper_->OnFocus(); | |
| 1031 EXPECT_EQ(0, table_->selection_model().active()); | |
| 1032 | |
| 1033 ui::ListSelectionModel new_selection; | |
| 1034 new_selection.set_active(1); | |
| 1035 helper_->SetSelectionModel(new_selection); | |
| 1036 EXPECT_EQ(1, table_->selection_model().active()); | |
| 1037 helper_->OnFocus(); | |
| 1038 EXPECT_EQ(1, table_->selection_model().active()); | |
| 1039 | |
| 1040 // Remove all rows; focusing should not activate a non existent first row. | |
| 1041 while (model_->RowCount()) | |
| 1042 model_->RemoveRow(0); | |
| 1043 | |
| 1044 new_selection.set_active(-1); | |
| 1045 helper_->SetSelectionModel(new_selection); | |
| 1046 helper_->OnFocus(); | |
| 1047 EXPECT_EQ(-1, table_->selection_model().active()); | |
| 1048 } | 1033 } |
| 1049 | 1034 |
| 1050 } // namespace views | 1035 } // namespace views |
| OLD | NEW |