Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Side by Side Diff: chrome/browser/ui/views/tabs/touch_tab_strip_layout_unittest.cc

Issue 10213011: Attempt 3 at a better touch tabstrip. There is still a bunch to do, (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove Tab::GetTouchModeMinimumSize Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/views/tabs/touch_tab_strip_layout.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "chrome/browser/ui/views/tabs/touch_tab_strip_layout.h"
6
7 #include <string>
8
9 #include "base/string_number_conversions.h"
10 #include "base/string_util.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/views/view.h"
13 #include "ui/views/view_model.h"
14
15 namespace {
16
17 struct CommonTestData {
18 const int initial_x;
19 const int width;
20 const int tab_size;
21 const int tab_padding;
22 const int stacked_offset;
23 const int mini_tab_count;
24 const int active_index;
25 const std::string start_bounds;
26 const std::string expected_bounds;
27 };
28
29 } // namespace
30
31 class TouchTabStripLayoutTest : public testing::Test {
32 public:
33 TouchTabStripLayoutTest() {}
34
35 protected:
36 void Reset(TouchTabStripLayout* layout,
37 int x,
38 int width,
39 int mini_tab_count,
40 int active_index) {
41 layout->Reset(x, width, mini_tab_count, active_index);
42 }
43
44 void CreateLayout(const CommonTestData& data) {
45 if (!data.start_bounds.empty())
46 PrepareChildViewsFromString(data.start_bounds);
47 else
48 PrepareChildViewsFromString(data.expected_bounds);
49 layout_.reset(new TouchTabStripLayout(
50 gfx::Size(data.tab_size, 10), data.tab_padding,
51 data.stacked_offset, 4, &view_model_));
52 if (data.start_bounds.empty()) {
53 PrepareChildViewsFromString(data.expected_bounds);
54 layout_->Reset(data.initial_x, data.width, data.mini_tab_count,
55 data.active_index);
56 } else {
57 ASSERT_NO_FATAL_FAILURE(SetBoundsFromString(data.start_bounds));
58 layout_->Reset(data.initial_x, data.width, data.mini_tab_count,
59 data.active_index);
60 ASSERT_NO_FATAL_FAILURE(SetBoundsFromString(data.start_bounds));
61 }
62 }
63
64 void AddViewToViewModel(int index) {
65 views::View* child_view = new views::View;
66 view_.AddChildView(child_view);
67 view_model_.Add(child_view, index);
68 }
69
70 void PrepareChildViewsFromString(const std::string& bounds) {
71 std::vector<std::string> positions;
72 Tokenize(bounds, " ", &positions);
73 PrepareChildViews(static_cast<int>(positions.size()));
74 }
75
76 void PrepareChildViews(int count) {
77 view_model_.Clear();
78 view_.RemoveAllChildViews(true);
79 for (int i = 0; i < count; ++i)
80 AddViewToViewModel(i);
81 }
82
83 void SetBoundsFromString(const std::string& bounds) {
84 std::vector<std::string> positions;
85 Tokenize(bounds, " ", &positions);
86 PrepareChildViews(static_cast<int>(positions.size()));
87 for (int i = 0; i < view_model_.view_size(); ++i) {
88 int x = 0;
89 gfx::Rect bounds(view_model_.ideal_bounds(i));
90 ASSERT_TRUE(base::StringToInt(positions[i], &x));
91 bounds.set_x(x);
92 view_model_.set_ideal_bounds(i, bounds);
93 }
94 }
95
96 std::string BoundsString() const {
97 std::string result;
98 for (int i = 0; i < view_model_.view_size(); ++i) {
99 if (!result.empty())
100 result += " ";
101 result += base::IntToString(view_model_.ideal_bounds(i).x());
102 }
103 return result;
104 }
105
106 std::string BoundsString2(int active_index) const {
107 std::string result;
108 for (int i = 0; i < view_model_.view_size(); ++i) {
109 if (!result.empty())
110 result += " ";
111 if (i == active_index)
112 result += "[";
113 result += base::IntToString(view_model_.ideal_bounds(i).x());
114 if (i == active_index)
115 result += "]";
116 }
117 return result;
118 }
119
120 void Validate(int active_index, int max_width) {
121 // Make sure none of the tabs are more than 90 apart
122 // (tab_size(100) + padding (-10)).
123 for (int j = 1; j < view_model_.view_size(); ++j)
124 EXPECT_LE(ideal_x(j) - ideal_x(j - 1), max_width - 100);
125 }
126
127 int ideal_x(int index) const {
128 return view_model_.ideal_bounds(index).x();
129 }
130
131 scoped_ptr<TouchTabStripLayout> layout_;
132 views::ViewModel view_model_;
133
134 private:
135 views::View view_;
136
137 DISALLOW_COPY_AND_ASSIGN(TouchTabStripLayoutTest);
138 };
139
140 // Random data.
141 TEST_F(TouchTabStripLayoutTest, ValidateInitialLayout) {
142 TouchTabStripLayout layout(gfx::Size(100, 10), -10, 2, 4, &view_model_);
143 PrepareChildViews(12);
144
145 for (int i = 120; i < 600; ++i) {
146 for (int j = 0; j < 12; ++j) {
147 Reset(&layout, 0, i, 0, j);
148 Validate(j, i);
149 if (HasNonfatalFailure())
150 return;
151 }
152 }
153 }
154
155 // Ensure initial layout is correct.
156 TEST_F(TouchTabStripLayoutTest, InitialLayout) {
157 struct CommonTestData test_data[] = {
158 { 0, 198, 100, -10, 1, 0, 9, "",
159 "0 0 0 0 0 0 1 2 3 4 94 95 96 97 98 98 98 98" },
160 { 0, 198, 100, -10, 1, 0, 0, "", "0 90 94 95 96 97 98 98 98" },
161 { 0, 300, 100, -10, 1, 0, 0, "",
162 "0 90 180 196 197 198 199 200 200 200 200" },
163 { 0, 300, 100, -10, 1, 0, 10, "", "0 0 0 0 1 2 3 4 20 110 200" },
164 { 0, 300, 100, -10, 1, 0, 1, "", "0 90 180 196 197 198 199 200 200" },
165 { 0, 643, 160, -27, 6, 0, 0, "", "0 133 266 399" },
166 { 0, 300, 100, -10, 1, 0, 7, "", "0 1 2 3 4 20 110 200" },
167 { 0, 300, 100, -10, 1, 0, 6, "", "0 1 2 3 4 20 110 200" },
168 { 0, 300, 100, -10, 1, 0, 4, "", "0 1 2 3 4 94 184 199 200" },
169 };
170 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
171 CreateLayout(test_data[i]);
172 EXPECT_EQ(test_data[i].expected_bounds, BoundsString()) << " at " << i;
173 }
174 }
175
176 // Assertions around dragging the active tab to the right.
177 TEST_F(TouchTabStripLayoutTest, DragActiveTab) {
178 struct TestData {
179 struct CommonTestData common_data;
180 const int delta;
181 } test_data[] = {
182 { { 0, 300, 100, -10, 2, 0, 4, "", "0 90 180 192 194 196 198 200" }, 1000 },
183 { { 0, 120, 100, -10, 2, 0, 3, "", "0 3 10 12 14 16 18 20" }, 13 },
184 { { 0, 200, 100, -10, 2, 0, 0, "", "0 85 92 94 96 98 100 100" }, -5 },
185 { { 0, 300, 100, -10, 2, 0, 4, "", "0 2 4 18 108 196 198 200" }, 100 },
186 { { 0, 300, 100, -10, 2, 0, 5, "", "0 2 4 6 8 21 111 200" }, 1 },
187 { { 0, 120, 100, -10, 2, 0, 3, "", "0 8 10 12 14 16 18 20" }, 95 },
188 { { 0, 300, 100, -10, 2, 0, 5, "", "0 90 180 192 194 196 198 200" }, 1000 },
189 { { 0, 300, 100, -10, 2, 0, 4, "", "0 2 4 7 97 187 198 200" }, 89 },
190 { { 0, 300, 100, -10, 2, 0, 4, "", "0 2 4 6 96 186 198 200" }, 88 },
191 { { 0, 300, 100, -10, 2, 0, 4, "", "0 2 4 8 98 188 198 200" }, 90 },
192 { { 0, 300, 100, -10, 2, 0, 6, "", "0 2 4 6 8 70 160 200" }, 50 },
193 };
194
195 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
196 CreateLayout(test_data[i].common_data);
197 layout_->DragActiveTab(test_data[i].delta);
198 EXPECT_EQ(test_data[i].common_data.expected_bounds,BoundsString()) <<
199 " at " << i;
200 }
201 }
202
203 // Assertions for dragging from an existing configuration.
204 TEST_F(TouchTabStripLayoutTest, DragActiveTabExisting) {
205 struct TestData {
206 struct CommonTestData common_data;
207 const int delta;
208 } test_data[] = {
209 { { 0, 643, 160, -27, 6, 0, 2, "0 84 217 350 483", "0 84 217 350 483" },
210 -11 },
211 { { 0, 685, 160, -27, 6, 0, 3, "0 6 12 18 151 284 417 519 525",
212 "0 6 12 18 150 283 416 519 525" },
213 -1 },
214 { { 0, 120, 100, -10, 2, 0, 3, "0 3 10 12 14 16 18 20",
215 "0 4 10 12 14 16 18 20" },
216 1 },
217 };
218
219 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
220 CreateLayout(test_data[i].common_data);
221 layout_->DragActiveTab(test_data[i].delta);
222 EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
223 " at " << i;
224 }
225 }
226
227 // Assertions for AddTab().
228 TEST_F(TouchTabStripLayoutTest, AddTab) {
229 struct TestData {
230 CommonTestData common_data;
231 int add_index;
232 bool add_active;
233 bool add_mini;
234 } test_data[] = {
235 { { 4, 200, 100, -10, 2, 1, 2, "0 4 10 100", "0 0 8 10 100"},
236 1, false, true },
237 { { 4, 200, 100, -10, 2, 1, 2, "0 4 10 100", "0 0 8 98 100"},
238 1, true, true },
239 { { 4, 200, 100, -10, 2, 1, 2, "0 4 10 100", "0 0 8 98 100"},
240 0, true, true },
241 { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 4 94 98 100"},
242 0, true, true },
243
244 { { 0, 200, 100, -10, 2, 0, 0, "0 90 92 92 94 96 98 100",
245 "0 0 0 2 4 6 8 98 100"},
246 7, true, false },
247 { { 0, 200, 100, -10, 2, 0, 7, "0 2 4 6 8 8 10 100",
248 "0 0 2 4 6 8 96 98 100"},
249 5, true, false },
250 { { 0, 200, 100, -10, 2, 0, 7, "0 2 4 6 8 8 10 100",
251 "0 2 4 6 8 94 96 98 100"},
252 4, true, false },
253 { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 2 10 98 100"},
254 2, true, false },
255 { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 2 4 10 100"},
256 4, true, false },
257 { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 90 96 98 100"},
258 0, true, false },
259 };
260 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
261 CreateLayout(test_data[i].common_data);
262 int add_types = 0;
263 if (test_data[i].add_active)
264 add_types |= TouchTabStripLayout::kAddTypeActive;
265 if (test_data[i].add_mini)
266 add_types |= TouchTabStripLayout::kAddTypeMini;
267 AddViewToViewModel(test_data[i].add_index);
268 layout_->AddTab(test_data[i].add_index, add_types,
269 test_data[i].common_data.initial_x +
270 (test_data[i].add_mini ? 4 : 0));
271 EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
272 " at " << i;
273 }
274 }
275
276 // Assertions around removing tabs.
277 TEST_F(TouchTabStripLayoutTest, RemoveTab) {
278 // TODO: add coverage of removing mini tabs!
279 struct TestData {
280 struct CommonTestData common_data;
281 const int remove_index;
282 const int x_after_remove;
283 } test_data[] = {
284 // Stacked tabs on both sides.
285 { { 0, 200, 100, -10, 2, 0, 4, "0 2 4 6 8 10 80 98 100",
286 "0 2 4 6 10 80 98 100" },
287 4, 0 },
288
289 // Mini-tabs.
290 { { 8, 200, 100, -10, 2, 1, 0, "0 8 94 96 98 100", "0 86 88 90 100" },
291 0, 0 },
292 { { 16, 200, 100, -10, 2, 2, 0, "0 8 16 94 96 98 100", "8 8 86 88 90 100" },
293 0, 8 },
294 { { 16, 200, 100, -10, 2, 2, 0, "0 8 16 94 96 98 100", "0 8 86 88 90 100" },
295 1, 8 },
296
297 // Remove from ideal layout.
298 { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 96 98 100" },
299 0, 0 },
300 { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 96 98 100" },
301 1, 0 },
302 { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 96 98 100" },
303 2, 0 },
304 { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 94 98 100" },
305 3, 0 },
306 { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 94 96 100" },
307 5, 0 },
308 };
309 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
310 CreateLayout(test_data[i].common_data);
311 int old_x = view_model_.ideal_bounds(test_data[i].remove_index).x();
312 view_model_.Remove(test_data[i].remove_index);
313 layout_->RemoveTab(test_data[i].remove_index, test_data[i].x_after_remove,
314 old_x);
315 EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
316 " at " << i;
317 }
318 }
319
320 // Assertions for SetWidth().
321 TEST_F(TouchTabStripLayoutTest, SetWidth) {
322 struct TestData {
323 CommonTestData common_data;
324 int new_width;
325 } test_data[] = {
326 { { 8, 250, 100, -10, 2, 2, 2, "0 4 8 98 148 150", "0 4 8 98 160 250"},
327 350 },
328 { { 8, 250, 100, -10, 2, 2, 2, "0 4 8 98 148 150", "0 4 8 96 98 100"},
329 200 },
330
331 { { 0, 250, 100, -10, 2, 0, 2, "0 40 90 120 150", "0 40 90 98 100"}, 200 },
332 { { 0, 250, 100, -10, 2, 0, 2, "0 2 60 150", "0 2 60 100"}, 200 },
333 { { 0, 250, 100, -10, 2, 0, 2, "0 40 120 150", "0 40 98 100"}, 200 },
334
335 { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 2 60 150"}, 250 },
336 { { 0, 200, 100, -10, 2, 0, 2, "0 2 4 10 100", "0 2 20 110 200"}, 300 },
337 };
338 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
339 CreateLayout(test_data[i].common_data);
340 layout_->SetWidth(test_data[i].new_width);
341 EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
342 " at " << i;
343 }
344 }
345
346 // Assertions for SetActiveIndex().
347 TEST_F(TouchTabStripLayoutTest, SetActiveIndex) {
348 struct TestData {
349 CommonTestData common_data;
350 int new_index;
351 } test_data[] = {
352 { { 0, 250, 100, -10, 2, 0, 2, "0 4 8 98 148 150", "0 90 144 146 148 150"},
353 0 },
354 { { 0, 250, 100, -10, 2, 0, 2, "0 4 8 98 148 150", "0 2 4 58 148 150"}, 4 },
355 { { 0, 250, 100, -10, 2, 0, 2, "0 4 8 98 148 150", "0 2 4 6 60 150"}, 5 },
356 { { 4, 250, 100, -10, 2, 1, 2, "0 4 8 98 148 150", "0 4 94 146 148 150"},
357 0 },
358 };
359 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
360 CreateLayout(test_data[i].common_data);
361 layout_->SetActiveIndex(test_data[i].new_index);
362 EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
363 " at " << i;
364 }
365 }
366
367 TEST_F(TouchTabStripLayoutTest, Foo) {
368 TouchTabStripLayout layout(gfx::Size(160, 10), -27, 6, 4, &view_model_);
369 ASSERT_NO_FATAL_FAILURE(SetBoundsFromString("0 6 12 18 126 259 392 525"));
370 Reset(&layout, 0, 685, 0, 5);
371 ASSERT_NO_FATAL_FAILURE(SetBoundsFromString("0 6 12 18 126 259 392 525"));
372 layout.DragActiveTab(11);
373 layout.DragActiveTab(1);
374 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/tabs/touch_tab_strip_layout.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698