summaryrefslogtreecommitdiffstats
path: root/chrome/views/table_view_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/views/table_view_unittest.cc')
-rw-r--r--chrome/views/table_view_unittest.cc363
1 files changed, 363 insertions, 0 deletions
diff --git a/chrome/views/table_view_unittest.cc b/chrome/views/table_view_unittest.cc
new file mode 100644
index 0000000..2467f04
--- /dev/null
+++ b/chrome/views/table_view_unittest.cc
@@ -0,0 +1,363 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "base/string_util.h"
+#include "chrome/views/table_view.h"
+#include "chrome/views/window.h"
+#include "chrome/views/window_delegate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ChromeViews::TableView;
+
+// TestTableModel --------------------------------------------------------------
+
+// Trivial TableModel implementation that is backed by a vector of vectors.
+// Provides methods for adding/removing/changing the contents that notify the
+// observer appropriately.
+//
+// Initial contents are:
+// 0, 1
+// 1, 1
+// 2, 2
+class TestTableModel : public ChromeViews::TableModel {
+ public:
+ TestTableModel();
+
+ // Adds a new row at index |row| with values |c1_value| and |c2_value|.
+ void AddRow(int row, int c1_value, int c2_value);
+
+ // Removes the row at index |row|.
+ void RemoveRow(int row);
+
+ // Changes the values of the row at |row|.
+ void ChangeRow(int row, int c1_value, int c2_value);
+
+ // TableModel
+ virtual int RowCount();
+ virtual std::wstring GetText(int row, int column_id);
+ virtual void SetObserver(ChromeViews::TableModelObserver* observer);
+ virtual int CompareValues(int row1, int row2, int column_id);
+
+ private:
+ ChromeViews::TableModelObserver* observer_;
+
+ // The data.
+ std::vector<std::vector<int>> rows_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestTableModel);
+};
+
+TestTableModel::TestTableModel() : observer_(NULL) {
+ AddRow(0, 0, 1);
+ AddRow(1, 1, 1);
+ AddRow(2, 2, 2);
+}
+
+void TestTableModel::AddRow(int row, int c1_value, int c2_value) {
+ DCHECK(row >= 0 && row <= static_cast<int>(rows_.size()));
+ std::vector<int> new_row;
+ new_row.push_back(c1_value);
+ new_row.push_back(c2_value);
+ rows_.insert(rows_.begin() + row, new_row);
+ if (observer_)
+ observer_->OnItemsAdded(row, 1);
+}
+void TestTableModel::RemoveRow(int row) {
+ DCHECK(row >= 0 && row <= static_cast<int>(rows_.size()));
+ rows_.erase(rows_.begin() + row);
+ if (observer_)
+ observer_->OnItemsRemoved(row, 1);
+}
+
+void TestTableModel::ChangeRow(int row, int c1_value, int c2_value) {
+ DCHECK(row >= 0 && row < static_cast<int>(rows_.size()));
+ rows_[row][0] = c1_value;
+ rows_[row][1] = c2_value;
+ if (observer_)
+ observer_->OnItemsChanged(row, 1);
+}
+
+int TestTableModel::RowCount() {
+ return static_cast<int>(rows_.size());
+}
+
+std::wstring TestTableModel::GetText(int row, int column_id) {
+ return IntToWString(rows_[row][column_id]);
+}
+
+void TestTableModel::SetObserver(ChromeViews::TableModelObserver* observer) {
+ observer_ = observer;
+}
+
+int TestTableModel::CompareValues(int row1, int row2, int column_id) {
+ return rows_[row1][column_id] - rows_[row2][column_id];
+}
+
+// TableViewTest ---------------------------------------------------------------
+
+class TableViewTest : public testing::Test, ChromeViews::WindowDelegate {
+ public:
+ virtual void SetUp();
+ virtual void TearDown();
+
+ virtual ChromeViews::View* GetContentsView() {
+ return table_;
+ }
+
+ protected:
+ // Creates the model.
+ TestTableModel* CreateModel();
+
+ // Verifies the view order matches that of the supplied arguments. The
+ // arguments are in terms of the model. For example, values of '1, 0' indicate
+ // the model index at row 0 is 1 and the model index at row 1 is 0.
+ void VeriyViewOrder(int first, ...);
+
+ // Verifies the selection matches the supplied arguments. The supplied
+ // arguments are in terms of this model. This uses the iterator returned by
+ // SelectionBegin.
+ void VerifySelectedRows(int first, ...);
+
+ // Configures the state for the various multi-selection tests.
+ // This selects model rows 0 and 1, and if |sort| is true the first column
+ // is sorted in descending order.
+ void SetUpMultiSelectTestState(bool sort);
+
+ scoped_ptr<TestTableModel> model_;
+
+ // The table. This is owned by the window.
+ TableView* table_;
+
+ private:
+ MessageLoopForUI message_loop_;
+ ChromeViews::Window* window_;
+};
+
+void TableViewTest::SetUp() {
+ model_.reset(CreateModel());
+ std::vector<ChromeViews::TableColumn> columns;
+ columns.resize(2);
+ columns[0].id = 0;
+ columns[1].id = 1;
+ table_ = new TableView(model_.get(), columns, ChromeViews::ICON_AND_TEXT,
+ false, false, false);
+ window_ =
+ ChromeViews::Window::CreateChromeWindow(NULL,
+ gfx::Rect(100, 100, 512, 512),
+ this);
+}
+
+void TableViewTest::TearDown() {
+ window_->CloseNow();
+ // Temporary workaround to avoid leak of RootView::pending_paint_task_.
+ message_loop_.RunAllPending();
+}
+
+void TableViewTest::VeriyViewOrder(int first, ...) {
+ va_list marker;
+ va_start(marker, first);
+ int value = first;
+ int index = 0;
+ for (int value = first, index = 0; value != -1; index++) {
+ ASSERT_EQ(value, table_->view_to_model(index));
+ value = va_arg(marker, int);
+ }
+ va_end(marker);
+}
+
+void TableViewTest::VerifySelectedRows(int first, ...) {
+ va_list marker;
+ va_start(marker, first);
+ int value = first;
+ int index = 0;
+ TableView::iterator selection_iterator = table_->SelectionBegin();
+ for (int value = first, index = 0; value != -1; index++) {
+ ASSERT_TRUE(selection_iterator != table_->SelectionEnd());
+ ASSERT_EQ(value, *selection_iterator);
+ value = va_arg(marker, int);
+ ++selection_iterator;
+ }
+ ASSERT_TRUE(selection_iterator == table_->SelectionEnd());
+ va_end(marker);
+}
+
+void TableViewTest::SetUpMultiSelectTestState(bool sort) {
+ // Select two rows.
+ table_->SetSelectedState(0, true);
+ table_->SetSelectedState(1, true);
+
+ VerifySelectedRows(1, 0, -1);
+ if (!sort || HasFatalFailure())
+ return;
+
+ // Sort by first column descending.
+ TableView::SortDescriptors sd;
+ sd.push_back(TableView::SortDescriptor(0, false));
+ table_->SetSortDescriptors(sd);
+ VeriyViewOrder(2, 1, 0, -1);
+ if (HasFatalFailure())
+ return;
+
+ // Make sure the two rows are sorted.
+ // NOTE: the order changed because iteration happens over view indices.
+ VerifySelectedRows(0, 1, -1);
+}
+
+TestTableModel* TableViewTest::CreateModel() {
+ return new TestTableModel();
+}
+
+// Tests -----------------------------------------------------------------------
+
+// Tests various sorting permutations.
+TEST_F(TableViewTest, Sort) {
+ // Sort by first column descending.
+ TableView::SortDescriptors sort;
+ sort.push_back(TableView::SortDescriptor(0, false));
+ table_->SetSortDescriptors(sort);
+ VeriyViewOrder(2, 1, 0, -1);
+ if (HasFatalFailure())
+ return;
+
+ // Sort by second column ascending, first column descending.
+ sort.clear();
+ sort.push_back(TableView::SortDescriptor(1, true));
+ sort.push_back(TableView::SortDescriptor(0, false));
+ sort[1].ascending = false;
+ table_->SetSortDescriptors(sort);
+ VeriyViewOrder(1, 0, 2, -1);
+ if (HasFatalFailure())
+ return;
+
+ // Clear the sort.
+ table_->SetSortDescriptors(TableView::SortDescriptors());
+ VeriyViewOrder(0, 1, 2, -1);
+ if (HasFatalFailure())
+ return;
+}
+
+// Tests changing the model while sorted.
+TEST_F(TableViewTest, SortThenChange) {
+ // Sort by first column descending.
+ TableView::SortDescriptors sort;
+ sort.push_back(TableView::SortDescriptor(0, false));
+ table_->SetSortDescriptors(sort);
+ VeriyViewOrder(2, 1, 0, -1);
+ if (HasFatalFailure())
+ return;
+
+ model_->ChangeRow(0, 3, 1);
+ VeriyViewOrder(0, 2, 1, -1);
+}
+
+// Tests adding to the model while sorted.
+TEST_F(TableViewTest, AddToSorted) {
+ // Sort by first column descending.
+ TableView::SortDescriptors sort;
+ sort.push_back(TableView::SortDescriptor(0, false));
+ table_->SetSortDescriptors(sort);
+ VeriyViewOrder(2, 1, 0, -1);
+ if (HasFatalFailure())
+ return;
+
+ // Add row so that it occurs first.
+ model_->AddRow(0, 5, -1);
+ VeriyViewOrder(0, 3, 2, 1, -1);
+ if (HasFatalFailure())
+ return;
+
+ // Add row so that it occurs last.
+ model_->AddRow(0, -1, -1);
+ VeriyViewOrder(1, 4, 3, 2, 0, -1);
+}
+
+// Tests selection on sort.
+TEST_F(TableViewTest, PersistSelectionOnSort) {
+ // Select row 0.
+ table_->Select(0);
+
+ // Sort by first column descending.
+ TableView::SortDescriptors sort;
+ sort.push_back(TableView::SortDescriptor(0, false));
+ table_->SetSortDescriptors(sort);
+ VeriyViewOrder(2, 1, 0, -1);
+ if (HasFatalFailure())
+ return;
+
+ // Make sure 0 is still selected.
+ EXPECT_EQ(0, table_->FirstSelectedRow());
+}
+
+// Tests selection iterator with sort.
+TEST_F(TableViewTest, PersistMultiSelectionOnSort) {
+ SetUpMultiSelectTestState(true);
+}
+
+// Tests selection persists after a change when sorted with iterator.
+TEST_F(TableViewTest, PersistMultiSelectionOnChangeWithSort) {
+ SetUpMultiSelectTestState(true);
+ if (HasFatalFailure())
+ return;
+
+ model_->ChangeRow(0, 3, 1);
+
+ VerifySelectedRows(1, 0, -1);
+}
+
+// Tests selection persists after a remove when sorted with iterator.
+TEST_F(TableViewTest, PersistMultiSelectionOnRemoveWithSort) {
+ SetUpMultiSelectTestState(true);
+ if (HasFatalFailure())
+ return;
+
+ model_->RemoveRow(0);
+
+ VerifySelectedRows(0, -1);
+}
+
+// Tests selection persists after a add when sorted with iterator.
+TEST_F(TableViewTest, PersistMultiSelectionOnAddWithSort) {
+ SetUpMultiSelectTestState(true);
+ if (HasFatalFailure())
+ return;
+
+ model_->AddRow(3, 4, 4);
+
+ VerifySelectedRows(0, 1, -1);
+}
+
+// Tests selection persists after a change with iterator.
+TEST_F(TableViewTest, PersistMultiSelectionOnChange) {
+ SetUpMultiSelectTestState(false);
+ if (HasFatalFailure())
+ return;
+
+ model_->ChangeRow(0, 3, 1);
+
+ VerifySelectedRows(1, 0, -1);
+}
+
+// Tests selection persists after a remove with iterator.
+TEST_F(TableViewTest, PersistMultiSelectionOnRemove) {
+ SetUpMultiSelectTestState(false);
+ if (HasFatalFailure())
+ return;
+
+ model_->RemoveRow(0);
+
+ VerifySelectedRows(0, -1);
+}
+
+// Tests selection persists after a add with iterator.
+TEST_F(TableViewTest, PersistMultiSelectionOnAdd) {
+ SetUpMultiSelectTestState(false);
+ if (HasFatalFailure())
+ return;
+
+ model_->AddRow(3, 4, 4);
+
+ VerifySelectedRows(1, 0, -1);
+}