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
3// found in the LICENSE file.
4
5#include "ui/base/models/list_selection_model.h"
6
7#include <algorithm>
8#include <string>
9
10#include "base/strings/string_number_conversions.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace ui {
14
15typedef testing::Test ListSelectionModelTest;
16
17// Returns the state of the selection model as a string. The format is:
18// 'active=X anchor=X selection=X X X...'.
19static std::string StateAsString(const ListSelectionModel& model) {
20  std::string result = "active=" + base::IntToString(model.active()) +
21      " anchor=" + base::IntToString(model.anchor()) +
22      " selection=";
23  const ListSelectionModel::SelectedIndices& selection(
24      model.selected_indices());
25  for (size_t i = 0; i < selection.size(); ++i) {
26    if (i != 0)
27      result += " ";
28    result += base::IntToString(selection[i]);
29  }
30  return result;
31}
32
33TEST_F(ListSelectionModelTest, InitialState) {
34  ListSelectionModel model;
35  EXPECT_EQ("active=-1 anchor=-1 selection=", StateAsString(model));
36  EXPECT_TRUE(model.empty());
37}
38
39TEST_F(ListSelectionModelTest, SetSelectedIndex) {
40  ListSelectionModel model;
41  model.SetSelectedIndex(2);
42  EXPECT_EQ("active=2 anchor=2 selection=2", StateAsString(model));
43  EXPECT_FALSE(model.empty());
44}
45
46TEST_F(ListSelectionModelTest, SetSelectedIndexToEmpty) {
47  ListSelectionModel model;
48  model.SetSelectedIndex(-1);
49  EXPECT_EQ("active=-1 anchor=-1 selection=", StateAsString(model));
50  EXPECT_TRUE(model.empty());
51}
52
53TEST_F(ListSelectionModelTest, IncrementFrom) {
54  ListSelectionModel model;
55  model.SetSelectedIndex(1);
56  model.IncrementFrom(1);
57  EXPECT_EQ("active=2 anchor=2 selection=2", StateAsString(model));
58
59  // Increment from 4. This shouldn't effect the selection as its past the
60  // end of the selection.
61  model.IncrementFrom(4);
62  EXPECT_EQ("active=2 anchor=2 selection=2", StateAsString(model));
63}
64
65TEST_F(ListSelectionModelTest, DecrementFrom) {
66  ListSelectionModel model;
67  model.SetSelectedIndex(2);
68  model.DecrementFrom(0);
69  EXPECT_EQ("active=1 anchor=1 selection=1", StateAsString(model));
70
71  // Shift down from 1. As the selection as the index being removed, this should
72  // clear the selection.
73  model.DecrementFrom(1);
74  EXPECT_EQ("active=-1 anchor=-1 selection=", StateAsString(model));
75
76  // Reset the selection to 2, and shift down from 4. This shouldn't do
77  // anything.
78  model.SetSelectedIndex(2);
79  model.DecrementFrom(4);
80  EXPECT_EQ("active=2 anchor=2 selection=2", StateAsString(model));
81}
82
83TEST_F(ListSelectionModelTest, IsSelected) {
84  ListSelectionModel model;
85  model.SetSelectedIndex(2);
86  EXPECT_FALSE(model.IsSelected(0));
87  EXPECT_TRUE(model.IsSelected(2));
88}
89
90TEST_F(ListSelectionModelTest, AddIndexToSelected) {
91  ListSelectionModel model;
92  model.AddIndexToSelection(2);
93  EXPECT_EQ("active=-1 anchor=-1 selection=2", StateAsString(model));
94
95  model.AddIndexToSelection(4);
96  EXPECT_EQ("active=-1 anchor=-1 selection=2 4", StateAsString(model));
97}
98
99TEST_F(ListSelectionModelTest, RemoveIndexFromSelection) {
100  ListSelectionModel model;
101  model.SetSelectedIndex(2);
102  model.AddIndexToSelection(4);
103  EXPECT_EQ("active=2 anchor=2 selection=2 4", StateAsString(model));
104
105  model.RemoveIndexFromSelection(4);
106  EXPECT_EQ("active=2 anchor=2 selection=2", StateAsString(model));
107
108  model.RemoveIndexFromSelection(2);
109  EXPECT_EQ("active=2 anchor=2 selection=", StateAsString(model));
110}
111
112TEST_F(ListSelectionModelTest, SetSelectionFromAnchorTo) {
113  ListSelectionModel model;
114  model.SetSelectedIndex(2);
115  model.SetSelectionFromAnchorTo(7);
116  EXPECT_EQ("active=7 anchor=2 selection=2 3 4 5 6 7", StateAsString(model));
117
118  model.Clear();
119  model.SetSelectedIndex(7);
120  model.SetSelectionFromAnchorTo(2);
121  EXPECT_EQ("active=2 anchor=7 selection=2 3 4 5 6 7", StateAsString(model));
122
123  model.Clear();
124  model.SetSelectionFromAnchorTo(7);
125  EXPECT_EQ("active=7 anchor=7 selection=7", StateAsString(model));
126}
127
128TEST_F(ListSelectionModelTest, Clear) {
129  ListSelectionModel model;
130  model.SetSelectedIndex(2);
131
132  model.Clear();
133  EXPECT_EQ("active=-1 anchor=-1 selection=", StateAsString(model));
134}
135
136TEST_F(ListSelectionModelTest, MoveToLeft) {
137  ListSelectionModel model;
138  model.SetSelectedIndex(0);
139  model.AddIndexToSelection(4);
140  model.AddIndexToSelection(10);
141  model.set_anchor(4);
142  model.set_active(4);
143  model.Move(4, 0);
144  EXPECT_EQ("active=0 anchor=0 selection=0 1 10", StateAsString(model));
145}
146
147TEST_F(ListSelectionModelTest, MoveToRight) {
148  ListSelectionModel model;
149  model.SetSelectedIndex(0);
150  model.AddIndexToSelection(4);
151  model.AddIndexToSelection(10);
152  model.set_anchor(0);
153  model.set_active(0);
154  model.Move(0, 3);
155  EXPECT_EQ("active=3 anchor=3 selection=3 4 10", StateAsString(model));
156}
157
158TEST_F(ListSelectionModelTest, Copy) {
159  ListSelectionModel model;
160  model.SetSelectedIndex(0);
161  model.AddIndexToSelection(4);
162  model.AddIndexToSelection(10);
163  EXPECT_EQ("active=0 anchor=0 selection=0 4 10", StateAsString(model));
164  ListSelectionModel model2;
165  model2.Copy(model);
166  EXPECT_EQ("active=0 anchor=0 selection=0 4 10", StateAsString(model2));
167}
168
169TEST_F(ListSelectionModelTest, AddSelectionFromAnchorTo) {
170  ListSelectionModel model;
171  model.SetSelectedIndex(2);
172
173  model.AddSelectionFromAnchorTo(4);
174  EXPECT_EQ("active=4 anchor=2 selection=2 3 4", StateAsString(model));
175
176  model.AddSelectionFromAnchorTo(0);
177  EXPECT_EQ("active=0 anchor=2 selection=0 1 2 3 4", StateAsString(model));
178}
179
180TEST_F(ListSelectionModelTest, Equals) {
181  ListSelectionModel model1;
182  model1.SetSelectedIndex(0);
183  model1.AddSelectionFromAnchorTo(4);
184
185  ListSelectionModel model2;
186  model2.SetSelectedIndex(0);
187  model2.AddSelectionFromAnchorTo(4);
188
189  EXPECT_TRUE(model1.Equals(model2));
190  EXPECT_TRUE(model2.Equals(model1));
191
192  model2.SetSelectedIndex(0);
193  EXPECT_FALSE(model1.Equals(model2));
194  EXPECT_FALSE(model2.Equals(model1));
195}
196
197}  // namespace ui
198