// Copyright (c) 2012 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 "ui/views/controls/table/table_view.h"

#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/views/controls/table/table_grouper.h"
#include "ui/views/controls/table/table_header.h"
#include "ui/views/controls/table/table_view_observer.h"

// Put the tests in the views namespace to make it easier to declare them as
// friend classes.
namespace views {

class TableViewTestHelper {
 public:
  explicit TableViewTestHelper(TableView* table) : table_(table) {}

  std::string GetPaintRegion(const gfx::Rect& bounds) {
    TableView::PaintRegion region(table_->GetPaintRegion(bounds));
    return "rows=" + base::IntToString(region.min_row) + " " +
        base::IntToString(region.max_row) + " cols=" +
        base::IntToString(region.min_column) + " " +
        base::IntToString(region.max_column);
  }

  size_t visible_col_count() {
    return table_->visible_columns().size();
  }

  TableHeader* header() { return table_->header_; }

 private:
  TableView* table_;

  DISALLOW_COPY_AND_ASSIGN(TableViewTestHelper);
};

namespace {

// TestTableModel2 -------------------------------------------------------------

// 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
// 3, 0
class TestTableModel2 : public ui::TableModel {
 public:
  TestTableModel2();

  // 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);

  // ui::TableModel:
  virtual int RowCount() OVERRIDE;
  virtual base::string16 GetText(int row, int column_id) OVERRIDE;
  virtual void SetObserver(ui::TableModelObserver* observer) OVERRIDE;
  virtual int CompareValues(int row1, int row2, int column_id) OVERRIDE;

 private:
  ui::TableModelObserver* observer_;

  // The data.
  std::vector<std::vector<int> > rows_;

  DISALLOW_COPY_AND_ASSIGN(TestTableModel2);
};

TestTableModel2::TestTableModel2() : observer_(NULL) {
  AddRow(0, 0, 1);
  AddRow(1, 1, 1);
  AddRow(2, 2, 2);
  AddRow(3, 3, 0);
}

void TestTableModel2::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 TestTableModel2::RemoveRow(int row) {
  DCHECK(row >= 0 && row <= static_cast<int>(rows_.size()));
  rows_.erase(rows_.begin() + row);
  if (observer_)
    observer_->OnItemsRemoved(row, 1);
}

void TestTableModel2::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 TestTableModel2::RowCount() {
  return static_cast<int>(rows_.size());
}

base::string16 TestTableModel2::GetText(int row, int column_id) {
  return base::IntToString16(rows_[row][column_id]);
}

void TestTableModel2::SetObserver(ui::TableModelObserver* observer) {
  observer_ = observer;
}

int TestTableModel2::CompareValues(int row1, int row2, int column_id) {
  return rows_[row1][column_id] - rows_[row2][column_id];
}

// Returns the view to model mapping as a string.
std::string GetViewToModelAsString(TableView* table) {
  std::string result;
  for (int i = 0; i < table->RowCount(); ++i) {
    if (i != 0)
      result += " ";
    result += base::IntToString(table->ViewToModel(i));
  }
  return result;
}

// Returns the model to view mapping as a string.
std::string GetModelToViewAsString(TableView* table) {
  std::string result;
  for (int i = 0; i < table->RowCount(); ++i) {
    if (i != 0)
      result += " ";
    result += base::IntToString(table->ModelToView(i));
  }
  return result;
}

class TestTableView : public TableView {
 public:
  TestTableView(ui::TableModel* model,
                const std::vector<ui::TableColumn>& columns)
      : TableView(model, columns, TEXT_ONLY, false) {
  }

  // View overrides:
  virtual bool HasFocus() const OVERRIDE {
    // Overriden so key processing works.
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TestTableView);
};

}  // namespace

class TableViewTest : public testing::Test {
 public:
  TableViewTest() : table_(NULL) {}

  virtual void SetUp() OVERRIDE {
    model_.reset(new TestTableModel2);
    std::vector<ui::TableColumn> columns(2);
    columns[0].title = base::ASCIIToUTF16("Title Column 0");
    columns[0].sortable = true;
    columns[1].title = base::ASCIIToUTF16("Title Column 1");
    columns[1].id = 1;
    columns[1].sortable = true;
    table_ = new TestTableView(model_.get(), columns);
    parent_.reset(table_->CreateParentIfNecessary());
    parent_->SetBounds(0, 0, 10000, 10000);
    parent_->Layout();
    helper_.reset(new TableViewTestHelper(table_));
  }

  void ClickOnRow(int row, int flags) {
    const int y = row * table_->row_height();
    const ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(0, y),
                                 gfx::Point(0, y),
                                 ui::EF_LEFT_MOUSE_BUTTON | flags,
                                 ui::EF_LEFT_MOUSE_BUTTON);
    table_->OnMousePressed(pressed);
  }

  void TapOnRow(int row) {
    const int y = row * table_->row_height();
    const ui::GestureEventDetails event_details(ui::ET_GESTURE_TAP);
    ui::GestureEvent tap(0, y, 0, base::TimeDelta(), event_details);
    table_->OnGestureEvent(&tap);
  }

  // Returns the state of the selection model as a string. The format is:
  // 'active=X anchor=X selection=X X X...'.
  std::string SelectionStateAsString() const {
    const ui::ListSelectionModel& model(table_->selection_model());
    std::string result = "active=" + base::IntToString(model.active()) +
        " anchor=" + base::IntToString(model.anchor()) +
        " selection=";
    const ui::ListSelectionModel::SelectedIndices& selection(
        model.selected_indices());
    for (size_t i = 0; i < selection.size(); ++i) {
      if (i != 0)
        result += " ";
      result += base::IntToString(selection[i]);
    }
    return result;
  }

  void PressKey(ui::KeyboardCode code) {
    ui::KeyEvent event(ui::ET_KEY_PRESSED, code, ui::EF_NONE);
    table_->OnKeyPressed(event);
  }

 protected:
  scoped_ptr<TestTableModel2> model_;

  // Owned by |parent_|.
  TableView* table_;

  scoped_ptr<TableViewTestHelper> helper_;

 private:
  scoped_ptr<View> parent_;

  DISALLOW_COPY_AND_ASSIGN(TableViewTest);
};

// Verifies GetPaintRegion.
TEST_F(TableViewTest, GetPaintRegion) {
  // Two columns should be visible.
  EXPECT_EQ(2u, helper_->visible_col_count());

  EXPECT_EQ("rows=0 4 cols=0 2", helper_->GetPaintRegion(table_->bounds()));
  EXPECT_EQ("rows=0 4 cols=0 1",
            helper_->GetPaintRegion(gfx::Rect(0, 0, 1, table_->height())));
}

// Verifies SetColumnVisibility().
TEST_F(TableViewTest, ColumnVisibility) {
  // Two columns should be visible.
  EXPECT_EQ(2u, helper_->visible_col_count());

  // Should do nothing (column already visible).
  table_->SetColumnVisibility(0, true);
  EXPECT_EQ(2u, helper_->visible_col_count());

  // Hide the first column.
  table_->SetColumnVisibility(0, false);
  ASSERT_EQ(1u, helper_->visible_col_count());
  EXPECT_EQ(1, table_->visible_columns()[0].column.id);
  EXPECT_EQ("rows=0 4 cols=0 1", helper_->GetPaintRegion(table_->bounds()));

  // Hide the second column.
  table_->SetColumnVisibility(1, false);
  EXPECT_EQ(0u, helper_->visible_col_count());

  // Show the second column.
  table_->SetColumnVisibility(1, true);
  ASSERT_EQ(1u, helper_->visible_col_count());
  EXPECT_EQ(1, table_->visible_columns()[0].column.id);
  EXPECT_EQ("rows=0 4 cols=0 1", helper_->GetPaintRegion(table_->bounds()));

  // Show the first column.
  table_->SetColumnVisibility(0, true);
  ASSERT_EQ(2u, helper_->visible_col_count());
  EXPECT_EQ(1, table_->visible_columns()[0].column.id);
  EXPECT_EQ(0, table_->visible_columns()[1].column.id);
  EXPECT_EQ("rows=0 4 cols=0 2", helper_->GetPaintRegion(table_->bounds()));
}

// Verifies resizing a column works.
TEST_F(TableViewTest, Resize) {
  const int x = table_->visible_columns()[0].width;
  EXPECT_NE(0, x);
  // Drag the mouse 1 pixel to the left.
  const ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(x, 0),
                               gfx::Point(x, 0), ui::EF_LEFT_MOUSE_BUTTON,
                               ui::EF_LEFT_MOUSE_BUTTON);
  helper_->header()->OnMousePressed(pressed);
  const ui::MouseEvent dragged(ui::ET_MOUSE_DRAGGED, gfx::Point(x - 1, 0),
                               gfx::Point(x - 1, 0), ui::EF_LEFT_MOUSE_BUTTON,
                               0);
  helper_->header()->OnMouseDragged(dragged);

  // This should shrink the first column and pull the second column in.
  EXPECT_EQ(x - 1, table_->visible_columns()[0].width);
  EXPECT_EQ(x - 1, table_->visible_columns()[1].x);
}

// Verifies resizing a column works with a gesture.
TEST_F(TableViewTest, ResizeViaGesture) {
  const int x = table_->visible_columns()[0].width;
  EXPECT_NE(0, x);
  // Drag the mouse 1 pixel to the left.
  ui::GestureEvent scroll_begin(
      x,
      0,
      0,
      base::TimeDelta(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN));
  helper_->header()->OnGestureEvent(&scroll_begin);
  ui::GestureEvent scroll_update(
      x - 1,
      0,
      0,
      base::TimeDelta(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE));
  helper_->header()->OnGestureEvent(&scroll_update);

  // This should shrink the first column and pull the second column in.
  EXPECT_EQ(x - 1, table_->visible_columns()[0].width);
  EXPECT_EQ(x - 1, table_->visible_columns()[1].x);
}

// Assertions for table sorting.
TEST_F(TableViewTest, Sort) {
  // Toggle the sort order of the first column, shouldn't change anything.
  table_->ToggleSortOrder(0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_TRUE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_));
  EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_));

  // Invert the sort (first column descending).
  table_->ToggleSortOrder(0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_FALSE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("3 2 1 0", GetViewToModelAsString(table_));
  EXPECT_EQ("3 2 1 0", GetModelToViewAsString(table_));

  // Change cell 0x3 to -1, meaning we have 0, 1, 2, -1 (in the first column).
  model_->ChangeRow(3, -1, 0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_FALSE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("2 1 0 3", GetViewToModelAsString(table_));
  EXPECT_EQ("2 1 0 3", GetModelToViewAsString(table_));

  // Invert sort again (first column ascending).
  table_->ToggleSortOrder(0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_TRUE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("3 0 1 2", GetViewToModelAsString(table_));
  EXPECT_EQ("1 2 3 0", GetModelToViewAsString(table_));

  // Add a row so that model has 0, 3, 1, 2, -1.
  model_->AddRow(1, 3, 4);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_TRUE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("4 0 2 3 1", GetViewToModelAsString(table_));
  EXPECT_EQ("1 4 2 3 0", GetModelToViewAsString(table_));

  // Delete the first row, ending up with 3, 1, 2, -1.
  model_->RemoveRow(0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_TRUE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("3 1 2 0", GetViewToModelAsString(table_));
  EXPECT_EQ("3 1 2 0", GetModelToViewAsString(table_));
}

// Verfies clicking on the header sorts.
TEST_F(TableViewTest, SortOnMouse) {
  EXPECT_TRUE(table_->sort_descriptors().empty());

  const int x = table_->visible_columns()[0].width / 2;
  EXPECT_NE(0, x);
  // Press and release the mouse.
  const ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, gfx::Point(x, 0),
                               gfx::Point(x, 0), ui::EF_LEFT_MOUSE_BUTTON,
                               ui::EF_LEFT_MOUSE_BUTTON);
  // The header must return true, else it won't normally get the release.
  EXPECT_TRUE(helper_->header()->OnMousePressed(pressed));
  const ui::MouseEvent release(ui::ET_MOUSE_RELEASED, gfx::Point(x, 0),
                               gfx::Point(x, 0), ui::EF_LEFT_MOUSE_BUTTON,
                               ui::EF_LEFT_MOUSE_BUTTON);
  helper_->header()->OnMouseReleased(release);

  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_TRUE(table_->sort_descriptors()[0].ascending);
}

namespace {

class TableGrouperImpl : public TableGrouper {
 public:
  TableGrouperImpl() {}

  void SetRanges(const std::vector<int>& ranges) {
    ranges_ = ranges;
  }

  // TableGrouper overrides:
  virtual void GetGroupRange(int model_index, GroupRange* range) OVERRIDE {
    int offset = 0;
    size_t range_index = 0;
    for (; range_index < ranges_.size() && offset < model_index; ++range_index)
      offset += ranges_[range_index];

    if (offset == model_index) {
      range->start = model_index;
      range->length = ranges_[range_index];
    } else {
      range->start = offset - ranges_[range_index - 1];
      range->length = ranges_[range_index - 1];
    }
  }

 private:
  std::vector<int> ranges_;

  DISALLOW_COPY_AND_ASSIGN(TableGrouperImpl);
};

}  // namespace

// Assertions around grouping.
TEST_F(TableViewTest, Grouping) {
  // Configure the grouper so that there are two groups:
  // A 0
  //   1
  // B 2
  //   3
  TableGrouperImpl grouper;
  std::vector<int> ranges;
  ranges.push_back(2);
  ranges.push_back(2);
  grouper.SetRanges(ranges);
  table_->SetGrouper(&grouper);

  // Toggle the sort order of the first column, shouldn't change anything.
  table_->ToggleSortOrder(0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_TRUE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_));
  EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_));

  // Sort descending, resulting:
  // B 2
  //   3
  // A 0
  //   1
  table_->ToggleSortOrder(0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_FALSE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("2 3 0 1", GetViewToModelAsString(table_));
  EXPECT_EQ("2 3 0 1", GetModelToViewAsString(table_));

  // Change the entry in the 4th row to -1. The model now becomes:
  // A 0
  //   1
  // B 2
  //   -1
  // Since the first entry in the range didn't change the sort isn't impacted.
  model_->ChangeRow(3, -1, 0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_FALSE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("2 3 0 1", GetViewToModelAsString(table_));
  EXPECT_EQ("2 3 0 1", GetModelToViewAsString(table_));

  // Change the entry in the 3rd row to -1. The model now becomes:
  // A 0
  //   1
  // B -1
  //   -1
  model_->ChangeRow(2, -1, 0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_FALSE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("0 1 2 3", GetViewToModelAsString(table_));
  EXPECT_EQ("0 1 2 3", GetModelToViewAsString(table_));

  // Toggle to ascending sort.
  table_->ToggleSortOrder(0);
  ASSERT_EQ(1u, table_->sort_descriptors().size());
  EXPECT_EQ(0, table_->sort_descriptors()[0].column_id);
  EXPECT_TRUE(table_->sort_descriptors()[0].ascending);
  EXPECT_EQ("2 3 0 1", GetViewToModelAsString(table_));
  EXPECT_EQ("2 3 0 1", GetModelToViewAsString(table_));
}

namespace {

class TableViewObserverImpl : public TableViewObserver {
 public:
  TableViewObserverImpl() : selection_changed_count_(0) {}

  int GetChangedCountAndClear() {
    const int count = selection_changed_count_;
    selection_changed_count_ = 0;
    return count;
  }

  // TableViewObserver overrides:
  virtual void OnSelectionChanged() OVERRIDE {
    selection_changed_count_++;
  }

 private:
  int selection_changed_count_;

  DISALLOW_COPY_AND_ASSIGN(TableViewObserverImpl);
};

}  // namespace

// Assertions around changing the selection.
TEST_F(TableViewTest, Selection) {
  TableViewObserverImpl observer;
  table_->SetObserver(&observer);

  // Initially no selection.
  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());

  // Select the last row.
  table_->Select(3);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=3 anchor=3 selection=3", SelectionStateAsString());

  // Change sort, shouldn't notify of change (toggle twice so that order
  // actually changes).
  table_->ToggleSortOrder(0);
  table_->ToggleSortOrder(0);
  EXPECT_EQ(0, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=3 anchor=3 selection=3", SelectionStateAsString());

  // Remove the selected row, this should notify of a change and update the
  // selection.
  model_->RemoveRow(3);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=2 anchor=2 selection=2", SelectionStateAsString());

  // Insert a row, since the selection in terms of the original model hasn't
  // changed the observer is not notified.
  model_->AddRow(0, 1, 2);
  EXPECT_EQ(0, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=3 anchor=3 selection=3", SelectionStateAsString());

  table_->SetObserver(NULL);
}

// Verifies selection works by way of a gesture.
TEST_F(TableViewTest, SelectOnTap) {
  // Initially no selection.
  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());

  TableViewObserverImpl observer;
  table_->SetObserver(&observer);

  // Click on the first row, should select it.
  TapOnRow(0);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=0 anchor=0 selection=0", SelectionStateAsString());

  table_->SetObserver(NULL);
}

// Verifies up/down correctly navigates through groups.
TEST_F(TableViewTest, KeyUpDown) {
  // Configure the grouper so that there are three groups:
  // A 0
  //   1
  // B 5
  // C 2
  //   3
  model_->AddRow(2, 5, 0);
  TableGrouperImpl grouper;
  std::vector<int> ranges;
  ranges.push_back(2);
  ranges.push_back(1);
  ranges.push_back(2);
  grouper.SetRanges(ranges);
  table_->SetGrouper(&grouper);

  TableViewObserverImpl observer;
  table_->SetObserver(&observer);

  // Initially no selection.
  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=1 anchor=1 selection=0 1", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=2 anchor=2 selection=2", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=3 anchor=3 selection=3 4", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(0, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=3 anchor=3 selection=3 4", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=2 anchor=2 selection=2", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=1 anchor=1 selection=0 1", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(0, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString());

  // Sort the table descending by column 1, view now looks like:
  // B 5   model: 2
  // C 2          3
  //   3          4
  // A 0          0
  //   1          1
  table_->ToggleSortOrder(0);
  table_->ToggleSortOrder(0);

  EXPECT_EQ("2 3 4 0 1", GetViewToModelAsString(table_));

  table_->Select(-1);
  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());

  observer.GetChangedCountAndClear();
  // Up with nothing selected selects the first row.
  PressKey(ui::VKEY_UP);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=2 anchor=2 selection=2", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=3 anchor=3 selection=3 4", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=1 anchor=1 selection=0 1", SelectionStateAsString());

  PressKey(ui::VKEY_DOWN);
  EXPECT_EQ(0, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=1 anchor=1 selection=0 1", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=3 anchor=3 selection=3 4", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=2 anchor=2 selection=2", SelectionStateAsString());

  PressKey(ui::VKEY_UP);
  EXPECT_EQ(0, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=2 anchor=2 selection=2", SelectionStateAsString());

  table_->SetObserver(NULL);
}

// Verifies home/end do the right thing.
TEST_F(TableViewTest, HomeEnd) {
  // Configure the grouper so that there are three groups:
  // A 0
  //   1
  // B 5
  // C 2
  //   3
  model_->AddRow(2, 5, 0);
  TableGrouperImpl grouper;
  std::vector<int> ranges;
  ranges.push_back(2);
  ranges.push_back(1);
  ranges.push_back(2);
  grouper.SetRanges(ranges);
  table_->SetGrouper(&grouper);

  TableViewObserverImpl observer;
  table_->SetObserver(&observer);

  // Initially no selection.
  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());

  PressKey(ui::VKEY_HOME);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString());

  PressKey(ui::VKEY_END);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString());

  table_->SetObserver(NULL);
}

// Verifies multiple selection gestures work (control-click, shift-click ...).
TEST_F(TableViewTest, Multiselection) {
  // Configure the grouper so that there are three groups:
  // A 0
  //   1
  // B 5
  // C 2
  //   3
  model_->AddRow(2, 5, 0);
  TableGrouperImpl grouper;
  std::vector<int> ranges;
  ranges.push_back(2);
  ranges.push_back(1);
  ranges.push_back(2);
  grouper.SetRanges(ranges);
  table_->SetGrouper(&grouper);

  // Initially no selection.
  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());

  TableViewObserverImpl observer;
  table_->SetObserver(&observer);

  // Click on the first row, should select it and the second row.
  ClickOnRow(0, 0);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=0 anchor=0 selection=0 1", SelectionStateAsString());

  // Click on the last row, should select it and the row before it.
  ClickOnRow(4, 0);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString());

  // Shift click on the third row, should extend selection to it.
  ClickOnRow(2, ui::EF_SHIFT_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=2 anchor=4 selection=2 3 4", SelectionStateAsString());

  // Control click on third row, should toggle it.
  ClickOnRow(2, ui::EF_CONTROL_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=2 anchor=2 selection=3 4", SelectionStateAsString());

  // Control-shift click on second row, should extend selection to it.
  ClickOnRow(1, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=1 anchor=2 selection=0 1 2 3 4", SelectionStateAsString());

  // Click on last row again.
  ClickOnRow(4, 0);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString());

  table_->SetObserver(NULL);
}

// Verifies multiple selection gestures work when sorted.
TEST_F(TableViewTest, MultiselectionWithSort) {
  // Configure the grouper so that there are three groups:
  // A 0
  //   1
  // B 5
  // C 2
  //   3
  model_->AddRow(2, 5, 0);
  TableGrouperImpl grouper;
  std::vector<int> ranges;
  ranges.push_back(2);
  ranges.push_back(1);
  ranges.push_back(2);
  grouper.SetRanges(ranges);
  table_->SetGrouper(&grouper);

  // Sort the table descending by column 1, view now looks like:
  // B 5   model: 2
  // C 2          3
  //   3          4
  // A 0          0
  //   1          1
  table_->ToggleSortOrder(0);
  table_->ToggleSortOrder(0);

  // Initially no selection.
  EXPECT_EQ("active=-1 anchor=-1 selection=", SelectionStateAsString());

  TableViewObserverImpl observer;
  table_->SetObserver(&observer);

  // Click on the third row, should select it and the second row.
  ClickOnRow(2, 0);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=4 anchor=4 selection=3 4", SelectionStateAsString());

  // Extend selection to first row.
  ClickOnRow(0, ui::EF_SHIFT_DOWN);
  EXPECT_EQ(1, observer.GetChangedCountAndClear());
  EXPECT_EQ("active=2 anchor=4 selection=2 3 4", SelectionStateAsString());

  table_->SetObserver(NULL);
}

}  // namespace views
