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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/views/tabs/touch_tab_strip_layout_unittest.cc
diff --git a/chrome/browser/ui/views/tabs/touch_tab_strip_layout_unittest.cc b/chrome/browser/ui/views/tabs/touch_tab_strip_layout_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1b28ad822e751d01895cdae77c016ccc64965846
--- /dev/null
+++ b/chrome/browser/ui/views/tabs/touch_tab_strip_layout_unittest.cc
@@ -0,0 +1,374 @@
+// 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 "chrome/browser/ui/views/tabs/touch_tab_strip_layout.h"
+
+#include <string>
+
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/views/view.h"
+#include "ui/views/view_model.h"
+
+namespace {
+
+struct CommonTestData {
+ const int initial_x;
+ const int width;
+ const int tab_size;
+ const int tab_padding;
+ const int stacked_offset;
+ const int mini_tab_count;
+ const int active_index;
+ const std::string start_bounds;
+ const std::string expected_bounds;
+};
+
+} // namespace
+
+class TouchTabStripLayoutTest : public testing::Test {
+ public:
+ TouchTabStripLayoutTest() {}
+
+ protected:
+ void Reset(TouchTabStripLayout* layout,
+ int x,
+ int width,
+ int mini_tab_count,
+ int active_index) {
+ layout->Reset(x, width, mini_tab_count, active_index);
+ }
+
+ void CreateLayout(const CommonTestData& data) {
+ if (!data.start_bounds.empty())
+ PrepareChildViewsFromString(data.start_bounds);
+ else
+ PrepareChildViewsFromString(data.expected_bounds);
+ layout_.reset(new TouchTabStripLayout(
+ gfx::Size(data.tab_size, 10), data.tab_padding,
+ data.stacked_offset, 4, &view_model_));
+ if (data.start_bounds.empty()) {
+ PrepareChildViewsFromString(data.expected_bounds);
+ layout_->Reset(data.initial_x, data.width, data.mini_tab_count,
+ data.active_index);
+ } else {
+ ASSERT_NO_FATAL_FAILURE(SetBoundsFromString(data.start_bounds));
+ layout_->Reset(data.initial_x, data.width, data.mini_tab_count,
+ data.active_index);
+ ASSERT_NO_FATAL_FAILURE(SetBoundsFromString(data.start_bounds));
+ }
+ }
+
+ void AddViewToViewModel(int index) {
+ views::View* child_view = new views::View;
+ view_.AddChildView(child_view);
+ view_model_.Add(child_view, index);
+ }
+
+ void PrepareChildViewsFromString(const std::string& bounds) {
+ std::vector<std::string> positions;
+ Tokenize(bounds, " ", &positions);
+ PrepareChildViews(static_cast<int>(positions.size()));
+ }
+
+ void PrepareChildViews(int count) {
+ view_model_.Clear();
+ view_.RemoveAllChildViews(true);
+ for (int i = 0; i < count; ++i)
+ AddViewToViewModel(i);
+ }
+
+ void SetBoundsFromString(const std::string& bounds) {
+ std::vector<std::string> positions;
+ Tokenize(bounds, " ", &positions);
+ PrepareChildViews(static_cast<int>(positions.size()));
+ for (int i = 0; i < view_model_.view_size(); ++i) {
+ int x = 0;
+ gfx::Rect bounds(view_model_.ideal_bounds(i));
+ ASSERT_TRUE(base::StringToInt(positions[i], &x));
+ bounds.set_x(x);
+ view_model_.set_ideal_bounds(i, bounds);
+ }
+ }
+
+ std::string BoundsString() const {
+ std::string result;
+ for (int i = 0; i < view_model_.view_size(); ++i) {
+ if (!result.empty())
+ result += " ";
+ result += base::IntToString(view_model_.ideal_bounds(i).x());
+ }
+ return result;
+ }
+
+ std::string BoundsString2(int active_index) const {
+ std::string result;
+ for (int i = 0; i < view_model_.view_size(); ++i) {
+ if (!result.empty())
+ result += " ";
+ if (i == active_index)
+ result += "[";
+ result += base::IntToString(view_model_.ideal_bounds(i).x());
+ if (i == active_index)
+ result += "]";
+ }
+ return result;
+ }
+
+ void Validate(int active_index, int max_width) {
+ // Make sure none of the tabs are more than 90 apart
+ // (tab_size(100) + padding (-10)).
+ for (int j = 1; j < view_model_.view_size(); ++j)
+ EXPECT_LE(ideal_x(j) - ideal_x(j - 1), max_width - 100);
+ }
+
+ int ideal_x(int index) const {
+ return view_model_.ideal_bounds(index).x();
+ }
+
+ scoped_ptr<TouchTabStripLayout> layout_;
+ views::ViewModel view_model_;
+
+ private:
+ views::View view_;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchTabStripLayoutTest);
+};
+
+// Random data.
+TEST_F(TouchTabStripLayoutTest, ValidateInitialLayout) {
+ TouchTabStripLayout layout(gfx::Size(100, 10), -10, 2, 4, &view_model_);
+ PrepareChildViews(12);
+
+ for (int i = 120; i < 600; ++i) {
+ for (int j = 0; j < 12; ++j) {
+ Reset(&layout, 0, i, 0, j);
+ Validate(j, i);
+ if (HasNonfatalFailure())
+ return;
+ }
+ }
+}
+
+// Ensure initial layout is correct.
+TEST_F(TouchTabStripLayoutTest, InitialLayout) {
+ struct CommonTestData test_data[] = {
+ { 0, 198, 100, -10, 1, 0, 9, "",
+ "0 0 0 0 0 0 1 2 3 4 94 95 96 97 98 98 98 98" },
+ { 0, 198, 100, -10, 1, 0, 0, "", "0 90 94 95 96 97 98 98 98" },
+ { 0, 300, 100, -10, 1, 0, 0, "",
+ "0 90 180 196 197 198 199 200 200 200 200" },
+ { 0, 300, 100, -10, 1, 0, 10, "", "0 0 0 0 1 2 3 4 20 110 200" },
+ { 0, 300, 100, -10, 1, 0, 1, "", "0 90 180 196 197 198 199 200 200" },
+ { 0, 643, 160, -27, 6, 0, 0, "", "0 133 266 399" },
+ { 0, 300, 100, -10, 1, 0, 7, "", "0 1 2 3 4 20 110 200" },
+ { 0, 300, 100, -10, 1, 0, 6, "", "0 1 2 3 4 20 110 200" },
+ { 0, 300, 100, -10, 1, 0, 4, "", "0 1 2 3 4 94 184 199 200" },
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
+ CreateLayout(test_data[i]);
+ EXPECT_EQ(test_data[i].expected_bounds, BoundsString()) << " at " << i;
+ }
+}
+
+// Assertions around dragging the active tab to the right.
+TEST_F(TouchTabStripLayoutTest, DragActiveTab) {
+ struct TestData {
+ struct CommonTestData common_data;
+ const int delta;
+ } test_data[] = {
+ { { 0, 300, 100, -10, 2, 0, 4, "", "0 90 180 192 194 196 198 200" }, 1000 },
+ { { 0, 120, 100, -10, 2, 0, 3, "", "0 3 10 12 14 16 18 20" }, 13 },
+ { { 0, 200, 100, -10, 2, 0, 0, "", "0 85 92 94 96 98 100 100" }, -5 },
+ { { 0, 300, 100, -10, 2, 0, 4, "", "0 2 4 18 108 196 198 200" }, 100 },
+ { { 0, 300, 100, -10, 2, 0, 5, "", "0 2 4 6 8 21 111 200" }, 1 },
+ { { 0, 120, 100, -10, 2, 0, 3, "", "0 8 10 12 14 16 18 20" }, 95 },
+ { { 0, 300, 100, -10, 2, 0, 5, "", "0 90 180 192 194 196 198 200" }, 1000 },
+ { { 0, 300, 100, -10, 2, 0, 4, "", "0 2 4 7 97 187 198 200" }, 89 },
+ { { 0, 300, 100, -10, 2, 0, 4, "", "0 2 4 6 96 186 198 200" }, 88 },
+ { { 0, 300, 100, -10, 2, 0, 4, "", "0 2 4 8 98 188 198 200" }, 90 },
+ { { 0, 300, 100, -10, 2, 0, 6, "", "0 2 4 6 8 70 160 200" }, 50 },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
+ CreateLayout(test_data[i].common_data);
+ layout_->DragActiveTab(test_data[i].delta);
+ EXPECT_EQ(test_data[i].common_data.expected_bounds,BoundsString()) <<
+ " at " << i;
+ }
+}
+
+// Assertions for dragging from an existing configuration.
+TEST_F(TouchTabStripLayoutTest, DragActiveTabExisting) {
+ struct TestData {
+ struct CommonTestData common_data;
+ const int delta;
+ } test_data[] = {
+ { { 0, 643, 160, -27, 6, 0, 2, "0 84 217 350 483", "0 84 217 350 483" },
+ -11 },
+ { { 0, 685, 160, -27, 6, 0, 3, "0 6 12 18 151 284 417 519 525",
+ "0 6 12 18 150 283 416 519 525" },
+ -1 },
+ { { 0, 120, 100, -10, 2, 0, 3, "0 3 10 12 14 16 18 20",
+ "0 4 10 12 14 16 18 20" },
+ 1 },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
+ CreateLayout(test_data[i].common_data);
+ layout_->DragActiveTab(test_data[i].delta);
+ EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
+ " at " << i;
+ }
+}
+
+// Assertions for AddTab().
+TEST_F(TouchTabStripLayoutTest, AddTab) {
+ struct TestData {
+ CommonTestData common_data;
+ int add_index;
+ bool add_active;
+ bool add_mini;
+ } test_data[] = {
+ { { 4, 200, 100, -10, 2, 1, 2, "0 4 10 100", "0 0 8 10 100"},
+ 1, false, true },
+ { { 4, 200, 100, -10, 2, 1, 2, "0 4 10 100", "0 0 8 98 100"},
+ 1, true, true },
+ { { 4, 200, 100, -10, 2, 1, 2, "0 4 10 100", "0 0 8 98 100"},
+ 0, true, true },
+ { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 4 94 98 100"},
+ 0, true, true },
+
+ { { 0, 200, 100, -10, 2, 0, 0, "0 90 92 92 94 96 98 100",
+ "0 0 0 2 4 6 8 98 100"},
+ 7, true, false },
+ { { 0, 200, 100, -10, 2, 0, 7, "0 2 4 6 8 8 10 100",
+ "0 0 2 4 6 8 96 98 100"},
+ 5, true, false },
+ { { 0, 200, 100, -10, 2, 0, 7, "0 2 4 6 8 8 10 100",
+ "0 2 4 6 8 94 96 98 100"},
+ 4, true, false },
+ { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 2 10 98 100"},
+ 2, true, false },
+ { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 2 4 10 100"},
+ 4, true, false },
+ { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 90 96 98 100"},
+ 0, true, false },
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
+ CreateLayout(test_data[i].common_data);
+ int add_types = 0;
+ if (test_data[i].add_active)
+ add_types |= TouchTabStripLayout::kAddTypeActive;
+ if (test_data[i].add_mini)
+ add_types |= TouchTabStripLayout::kAddTypeMini;
+ AddViewToViewModel(test_data[i].add_index);
+ layout_->AddTab(test_data[i].add_index, add_types,
+ test_data[i].common_data.initial_x +
+ (test_data[i].add_mini ? 4 : 0));
+ EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
+ " at " << i;
+ }
+}
+
+// Assertions around removing tabs.
+TEST_F(TouchTabStripLayoutTest, RemoveTab) {
+ // TODO: add coverage of removing mini tabs!
+ struct TestData {
+ struct CommonTestData common_data;
+ const int remove_index;
+ const int x_after_remove;
+ } test_data[] = {
+ // Stacked tabs on both sides.
+ { { 0, 200, 100, -10, 2, 0, 4, "0 2 4 6 8 10 80 98 100",
+ "0 2 4 6 10 80 98 100" },
+ 4, 0 },
+
+ // Mini-tabs.
+ { { 8, 200, 100, -10, 2, 1, 0, "0 8 94 96 98 100", "0 86 88 90 100" },
+ 0, 0 },
+ { { 16, 200, 100, -10, 2, 2, 0, "0 8 16 94 96 98 100", "8 8 86 88 90 100" },
+ 0, 8 },
+ { { 16, 200, 100, -10, 2, 2, 0, "0 8 16 94 96 98 100", "0 8 86 88 90 100" },
+ 1, 8 },
+
+ // Remove from ideal layout.
+ { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 96 98 100" },
+ 0, 0 },
+ { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 96 98 100" },
+ 1, 0 },
+ { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 96 98 100" },
+ 2, 0 },
+ { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 94 98 100" },
+ 3, 0 },
+ { { 0, 200, 100, -10, 2, 0, 0, "0 90 94 96 98 100", "0 90 94 96 100" },
+ 5, 0 },
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
+ CreateLayout(test_data[i].common_data);
+ int old_x = view_model_.ideal_bounds(test_data[i].remove_index).x();
+ view_model_.Remove(test_data[i].remove_index);
+ layout_->RemoveTab(test_data[i].remove_index, test_data[i].x_after_remove,
+ old_x);
+ EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
+ " at " << i;
+ }
+}
+
+// Assertions for SetWidth().
+TEST_F(TouchTabStripLayoutTest, SetWidth) {
+ struct TestData {
+ CommonTestData common_data;
+ int new_width;
+ } test_data[] = {
+ { { 8, 250, 100, -10, 2, 2, 2, "0 4 8 98 148 150", "0 4 8 98 160 250"},
+ 350 },
+ { { 8, 250, 100, -10, 2, 2, 2, "0 4 8 98 148 150", "0 4 8 96 98 100"},
+ 200 },
+
+ { { 0, 250, 100, -10, 2, 0, 2, "0 40 90 120 150", "0 40 90 98 100"}, 200 },
+ { { 0, 250, 100, -10, 2, 0, 2, "0 2 60 150", "0 2 60 100"}, 200 },
+ { { 0, 250, 100, -10, 2, 0, 2, "0 40 120 150", "0 40 98 100"}, 200 },
+
+ { { 0, 200, 100, -10, 2, 0, 2, "0 2 10 100", "0 2 60 150"}, 250 },
+ { { 0, 200, 100, -10, 2, 0, 2, "0 2 4 10 100", "0 2 20 110 200"}, 300 },
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
+ CreateLayout(test_data[i].common_data);
+ layout_->SetWidth(test_data[i].new_width);
+ EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
+ " at " << i;
+ }
+}
+
+// Assertions for SetActiveIndex().
+TEST_F(TouchTabStripLayoutTest, SetActiveIndex) {
+ struct TestData {
+ CommonTestData common_data;
+ int new_index;
+ } test_data[] = {
+ { { 0, 250, 100, -10, 2, 0, 2, "0 4 8 98 148 150", "0 90 144 146 148 150"},
+ 0 },
+ { { 0, 250, 100, -10, 2, 0, 2, "0 4 8 98 148 150", "0 2 4 58 148 150"}, 4 },
+ { { 0, 250, 100, -10, 2, 0, 2, "0 4 8 98 148 150", "0 2 4 6 60 150"}, 5 },
+ { { 4, 250, 100, -10, 2, 1, 2, "0 4 8 98 148 150", "0 4 94 146 148 150"},
+ 0 },
+ };
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) {
+ CreateLayout(test_data[i].common_data);
+ layout_->SetActiveIndex(test_data[i].new_index);
+ EXPECT_EQ(test_data[i].common_data.expected_bounds, BoundsString()) <<
+ " at " << i;
+ }
+}
+
+TEST_F(TouchTabStripLayoutTest, Foo) {
+ TouchTabStripLayout layout(gfx::Size(160, 10), -27, 6, 4, &view_model_);
+ ASSERT_NO_FATAL_FAILURE(SetBoundsFromString("0 6 12 18 126 259 392 525"));
+ Reset(&layout, 0, 685, 0, 5);
+ ASSERT_NO_FATAL_FAILURE(SetBoundsFromString("0 6 12 18 126 259 392 525"));
+ layout.DragActiveTab(11);
+ layout.DragActiveTab(1);
+}
« 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