1// Copyright (c) 2013 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/cocoa/autofill/simple_grid_layout.h" 6 7#include "base/logging.h" 8#include "base/mac/scoped_nsobject.h" 9#include "testing/gtest/include/gtest/gtest.h" 10 11namespace { 12 13// Layout objects as multiple columns in a single row. 14class ColumnLayout : public SimpleGridLayout { 15 public: 16 ColumnLayout(NSView* host) : SimpleGridLayout(host) { AddRow(); } 17 ~ColumnLayout() {} 18}; 19 20class LayoutTest : public testing::Test { 21 public: 22 base::scoped_nsobject<NSView> CreateViewWithWidth(float width) { 23 // Height of 1, since empty rects become 0x0 when run by NSIntegralRect. 24 NSRect frame = NSMakeRect(0, 0, width, 1); 25 base::scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:frame]); 26 return view; 27 } 28 29 // Width of 1, since empty rects become 0x0 when run by NSIntegralRect. 30 base::scoped_nsobject<NSView> CreateViewWithHeight(float height) { 31 NSRect frame = NSMakeRect(0, 0, 1, height); 32 base::scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:frame]); 33 return view; 34 } 35}; 36 37TEST_F(LayoutTest, GridLayoutAddGetColumnSet) { 38 SimpleGridLayout layout(NULL); 39 40 // Non-existing id's are not found. 41 EXPECT_EQ(0L, layout.GetColumnSet(1)); 42 43 // Created ColumnSets can be retrieved. 44 ColumnSet* set1 = layout.AddColumnSet(10); 45 ColumnSet* set2 = layout.AddColumnSet(11); 46 ColumnSet* set3 = layout.AddColumnSet(12); 47 EXPECT_EQ(set2, layout.GetColumnSet(11)); 48 EXPECT_EQ(set1, layout.GetColumnSet(10)); 49 EXPECT_EQ(set3, layout.GetColumnSet(12)); 50} 51 52TEST_F(LayoutTest, AddRowAutogeneratesColumnSetId) { 53 SimpleGridLayout layout(NULL); 54 55 ColumnSet* set1 = layout.AddRow(); 56 EXPECT_NE(0, set1->id()); 57 58 ColumnSet* set2 = layout.AddRow(); 59 EXPECT_NE(set1->id(), set2->id()); 60} 61 62TEST_F(LayoutTest, AddRowResetsNextColumn) { 63 SimpleGridLayout layout(NULL); 64 layout.AddRow(); 65 layout.GetLastValidColumnSet()->AddColumn(0.6f); 66 layout.GetLastValidColumnSet()->AddColumn(0.6f); 67 layout.AddView(nil); 68 EXPECT_EQ(1, layout.next_column()); 69 70 layout.AddRow(); 71 EXPECT_EQ(0, layout.next_column()); 72} 73 74TEST_F(LayoutTest, GetLastValidColumnSet) { 75 SimpleGridLayout layout(NULL); 76 77 EXPECT_EQ(NULL, layout.GetLastValidColumnSet()); 78 79 ColumnSet* cs1 = layout.AddColumnSet(1); 80 ColumnSet* cs2 = layout.AddColumnSet(2); 81 layout.StartRow(0.0, 2); 82 EXPECT_EQ(cs2, layout.GetLastValidColumnSet()); 83 84 layout.AddPaddingRow(10); 85 EXPECT_EQ(cs2, layout.GetLastValidColumnSet()); 86 87 layout.StartRow(0.0, 1); 88 EXPECT_EQ(cs1, layout.GetLastValidColumnSet()); 89} 90 91 92TEST_F(LayoutTest, AddRowCreatesNewColumnSet) { 93 SimpleGridLayout layout(NULL); 94 95 EXPECT_EQ(NULL, layout.GetLastValidColumnSet()); 96 97 ColumnSet* old_column_set = layout.AddRow(); 98 EXPECT_TRUE(old_column_set != NULL); 99 EXPECT_EQ(old_column_set, layout.GetLastValidColumnSet()); 100 101 ColumnSet* new_column_set = layout.AddRow(); 102 EXPECT_TRUE(new_column_set != NULL); 103 EXPECT_EQ(new_column_set, layout.GetLastValidColumnSet()); 104} 105 106TEST_F(LayoutTest, AddPaddingRow) { 107 SimpleGridLayout layout(NULL); 108 109 ColumnSet* cs; 110 cs = layout.AddRow(); 111 cs->AddColumn(1.0f); 112 base::scoped_nsobject<NSView> view1 = CreateViewWithHeight(30.0f); 113 layout.AddView(view1); 114 115 layout.AddPaddingRow(20); 116 117 cs = layout.AddRow(); 118 cs->AddColumn(1.0f); 119 EXPECT_EQ(3, layout.num_rows()); 120 base::scoped_nsobject<NSView> view2 = CreateViewWithHeight(10.0f); 121 layout.AddView(view2); 122 123 layout.SizeRowsAndColumns(0.0f); 124 EXPECT_FLOAT_EQ(30.0f, layout.GetRowHeight(0)); 125 EXPECT_FLOAT_EQ(20.0f, layout.GetRowHeight(1)); 126 EXPECT_FLOAT_EQ(10.0f, layout.GetRowHeight(2)); 127} 128 129TEST_F(LayoutTest, RowsAccomodateHeightOfAllElements) { 130 SimpleGridLayout layout(NULL); 131 132 layout.AddRow(); 133 layout.GetLastValidColumnSet()->AddColumn(0.6f); 134 layout.GetLastValidColumnSet()->AddColumn(0.6f); 135 layout.GetLastValidColumnSet()->AddColumn(0.6f); 136 137 base::scoped_nsobject<NSView> view1 = CreateViewWithHeight(37.0f); 138 layout.AddView(view1); 139 layout.SizeRowsAndColumns(0.0f); 140 EXPECT_FLOAT_EQ(37.0f, layout.GetRowHeight(0)); 141 142 base::scoped_nsobject<NSView> view2 = CreateViewWithHeight(26.0f); 143 layout.AddView(view2); 144 layout.SizeRowsAndColumns(0.0f); 145 EXPECT_FLOAT_EQ(37.0f, layout.GetRowHeight(0)); 146 147 base::scoped_nsobject<NSView> view3 = CreateViewWithHeight(42.0f); 148 layout.AddView(view3); 149 layout.SizeRowsAndColumns(0.0f); 150 EXPECT_FLOAT_EQ(42.0f, layout.GetRowHeight(0)); 151} 152 153TEST_F(LayoutTest, SizeRowsAdjustsRowLocations) { 154 SimpleGridLayout layout(NULL); 155 156 layout.AddRow(); 157 layout.GetLastValidColumnSet()->AddColumn(0.6f); 158 base::scoped_nsobject<NSView> view1 = CreateViewWithHeight(30.0f); 159 layout.AddView(view1); 160 161 layout.AddRow(); 162 layout.GetLastValidColumnSet()->AddColumn(0.6f); 163 base::scoped_nsobject<NSView> view2 = CreateViewWithHeight(40.0f); 164 layout.AddView(view2); 165 166 layout.SizeRowsAndColumns(0.0f); 167 EXPECT_FLOAT_EQ(0.0f, layout.GetRowLocation(0)); 168 EXPECT_FLOAT_EQ(30.0f, layout.GetRowLocation(1)); 169} 170 171TEST_F(LayoutTest, SimpleGridLayoutAdjustsViews) { 172 SimpleGridLayout layout(NULL); 173 174 layout.AddRow(); 175 layout.GetLastValidColumnSet()->AddColumn(0.6f); 176 layout.GetLastValidColumnSet()->AddPaddingColumn(30); 177 layout.GetLastValidColumnSet()->AddColumn(0.4f); 178 179 base::scoped_nsobject<NSView> view1 = CreateViewWithHeight(22.0f); 180 base::scoped_nsobject<NSView> view2 = CreateViewWithHeight(20.0f); 181 layout.AddView(view1); 182 layout.AddView(view2); 183 184 layout.AddRow(); 185 layout.GetLastValidColumnSet()->AddColumn(0.6f); 186 base::scoped_nsobject<NSView> view3 = CreateViewWithHeight(18.0f); 187 layout.AddView(view3); 188 189 base::scoped_nsobject<NSView> host_view = CreateViewWithWidth(150.0f); 190 layout.Layout(host_view); 191 192 EXPECT_FLOAT_EQ(72.0f, NSWidth([view1 frame])); 193 EXPECT_FLOAT_EQ(22.0f, NSHeight([view1 frame])); 194 EXPECT_FLOAT_EQ(0.0f, NSMinX([view1 frame])); 195 EXPECT_FLOAT_EQ(0.0f, NSMinY([view1 frame])); 196 197 EXPECT_FLOAT_EQ(48.0f, NSWidth([view2 frame])); 198 EXPECT_FLOAT_EQ(22.0f, NSHeight([view2 frame])); 199 EXPECT_FLOAT_EQ(102.0f, NSMinX([view2 frame])); 200 EXPECT_FLOAT_EQ(0.0f, NSMinY([view2 frame])); 201 202 EXPECT_FLOAT_EQ(150.0f, NSWidth([view3 frame])); 203 EXPECT_FLOAT_EQ(18.0f, NSHeight([view3 frame])); 204 EXPECT_FLOAT_EQ(0.0f, NSMinX([view3 frame])); 205 EXPECT_FLOAT_EQ(22.0f, NSMinY([view3 frame])); 206} 207 208TEST_F(LayoutTest, PreferredHeightForEmptyLayout) { 209 SimpleGridLayout layout(NULL); 210 EXPECT_FLOAT_EQ(0.0f, layout.GetPreferredHeightForWidth(100.0)); 211} 212 213TEST_F(LayoutTest, SimpleGridLayoutHeightForWidth) 214{ 215 SimpleGridLayout layout(NULL); 216 layout.AddRow(); 217 layout.GetLastValidColumnSet()->AddColumn(0.6f); 218 219 base::scoped_nsobject<NSView> view1 = CreateViewWithHeight(22.0f); 220 layout.AddView(view1); 221 EXPECT_FLOAT_EQ(22.0f, layout.GetPreferredHeightForWidth(100.0)); 222 223 layout.AddPaddingRow(12); 224 EXPECT_FLOAT_EQ(34.0f, layout.GetPreferredHeightForWidth(100.0)); 225 226 layout.AddRow(); 227 layout.GetLastValidColumnSet()->AddColumn(0.6f); 228 base::scoped_nsobject<NSView> view2 = CreateViewWithHeight(13.0f); 229 layout.AddView(view2); 230 EXPECT_FLOAT_EQ(47.0f, layout.GetPreferredHeightForWidth(100.0)); 231} 232 233TEST_F(LayoutTest, SkipColumns) { 234 ColumnLayout layout(NULL); 235 236 ASSERT_TRUE(layout.GetLastValidColumnSet() != NULL); 237 layout.GetLastValidColumnSet()->AddColumn(0.6f); 238 layout.GetLastValidColumnSet()->AddColumn(0.6f); 239 layout.GetLastValidColumnSet()->AddColumn(0.4f); 240 layout.GetLastValidColumnSet()->AddColumn(0.6f); 241 layout.GetLastValidColumnSet()->AddPaddingColumn(30); 242 layout.GetLastValidColumnSet()->AddColumn(0.6f); 243 244 // Skip a single column 245 EXPECT_EQ(0, layout.next_column()); 246 layout.SkipColumns(1); 247 EXPECT_EQ(1, layout.next_column()); 248 249 // Skip multiple columns 250 layout.SkipColumns(2); 251 EXPECT_EQ(3, layout.next_column()); 252 253 // SkipColumns skips padding, too 254 layout.SkipColumns(1); 255 EXPECT_EQ(5, layout.next_column()); 256} 257 258TEST_F(LayoutTest, SkipPaddingColumns) { 259 ColumnLayout layout(NULL); 260 261 ASSERT_TRUE(layout.GetLastValidColumnSet() != NULL); 262 layout.GetLastValidColumnSet()->AddColumn(0.6f); 263 layout.GetLastValidColumnSet()->AddPaddingColumn(30); 264 layout.GetLastValidColumnSet()->AddColumn(0.4f); 265 layout.GetLastValidColumnSet()->AddPaddingColumn(30); 266 layout.GetLastValidColumnSet()->AddPaddingColumn(30); 267 layout.GetLastValidColumnSet()->AddColumn(0.4f); 268 269 // Don't skip over non-padding columns. 270 EXPECT_EQ(0, layout.next_column()); 271 layout.SkipPaddingColumns(); 272 EXPECT_EQ(0, layout.next_column()); 273 274 // Skip a single padding column. 275 layout.AdvanceColumn(); 276 EXPECT_EQ(1, layout.next_column()); 277 layout.SkipPaddingColumns(); 278 EXPECT_EQ(2, layout.next_column()); 279 280 // Skip multiple padding columns. 281 layout.AdvanceColumn(); 282 EXPECT_EQ(3, layout.next_column()); 283 layout.SkipPaddingColumns(); 284 EXPECT_EQ(5, layout.next_column()); 285} 286 287TEST_F(LayoutTest, SizeColumnsAdjustLocationAndSize) { 288 ColumnLayout layout(NULL); 289 290 ASSERT_TRUE(layout.GetLastValidColumnSet() != NULL); 291 layout.GetLastValidColumnSet()->AddColumn(0.6f); 292 layout.GetLastValidColumnSet()->AddPaddingColumn(30); 293 layout.GetLastValidColumnSet()->AddColumn(0.4f); 294 295 layout.SizeRowsAndColumns(130.0f); 296 EXPECT_FLOAT_EQ(0.0f, layout.GetLastValidColumnSet()->ColumnLocation(0)); 297 EXPECT_FLOAT_EQ(60.0f, layout.GetLastValidColumnSet()->GetColumnWidth(0)); 298 EXPECT_FLOAT_EQ(60.0f, layout.GetLastValidColumnSet()->ColumnLocation(1)); 299 EXPECT_FLOAT_EQ(30.0f, layout.GetLastValidColumnSet()->GetColumnWidth(1)); 300 EXPECT_FLOAT_EQ(90.0f, layout.GetLastValidColumnSet()->ColumnLocation(2)); 301 EXPECT_FLOAT_EQ(40.0f, layout.GetLastValidColumnSet()->GetColumnWidth(2)); 302} 303 304TEST_F(LayoutTest, AddViewSkipsPaddingColumns) { 305 ColumnLayout layout(NULL); 306 307 ASSERT_TRUE(layout.GetLastValidColumnSet() != NULL); 308 layout.GetLastValidColumnSet()->AddColumn(0.6f); 309 layout.GetLastValidColumnSet()->AddPaddingColumn(30); 310 layout.GetLastValidColumnSet()->AddColumn(0.4f); 311 312 EXPECT_EQ(0, layout.next_column()); 313 base::scoped_nsobject<NSView> view1 = CreateViewWithWidth(37.0f); 314 layout.AddView(view1); 315 EXPECT_EQ(2, layout.next_column()); 316} 317 318TEST_F(LayoutTest, ColumnLayoutAdjustsViews) { 319 ColumnLayout layout(NULL); 320 321 ASSERT_TRUE(layout.GetLastValidColumnSet() != NULL); 322 layout.GetLastValidColumnSet()->AddColumn(0.6f); 323 layout.GetLastValidColumnSet()->AddPaddingColumn(30); 324 layout.GetLastValidColumnSet()->AddColumn(0.4f); 325 326 base::scoped_nsobject<NSView> view1 = CreateViewWithWidth(37.0f); 327 base::scoped_nsobject<NSView> view2 = CreateViewWithWidth(42.0f); 328 layout.AddView(view1); 329 layout.AddView(view2); 330 331 base::scoped_nsobject<NSView> host_view = CreateViewWithWidth(150.0f); 332 layout.Layout(host_view); 333 334 EXPECT_FLOAT_EQ(72.0f, NSWidth([view1 frame])); 335 EXPECT_FLOAT_EQ(48.0f, NSWidth([view2 frame])); 336} 337 338TEST_F(LayoutTest, ColumnSetAddPadding) { 339 ColumnSet columns(0); 340 341 columns.AddPaddingColumn(20); 342 EXPECT_EQ(1, columns.num_columns()); 343 344 columns.CalculateSize(20.0f); 345 EXPECT_FLOAT_EQ(20.0f, columns.GetColumnWidth(0)); 346 347 columns.CalculateSize(120.0f); 348 EXPECT_FLOAT_EQ(20.0f, columns.GetColumnWidth(0)); 349} 350 351TEST_F(LayoutTest, ColumnSetOneFlexibleColumn) { 352 ColumnSet columns(0); 353 354 columns.AddColumn(1.0f); 355 EXPECT_EQ(1, columns.num_columns()); 356 357 columns.CalculateSize(20.0f); 358 EXPECT_FLOAT_EQ(20.0f, columns.GetColumnWidth(0)); 359 360 columns.CalculateSize(120.0f); 361 EXPECT_FLOAT_EQ(120.0f, columns.GetColumnWidth(0)); 362} 363 364TEST_F(LayoutTest, ColumnSetTwoFlexibleColumns) { 365 ColumnSet columns(0); 366 367 columns.AddColumn(0.6f); 368 columns.AddColumn(0.4f); 369 EXPECT_EQ(2, columns.num_columns()); 370 371 columns.CalculateSize(100.0f); 372 EXPECT_FLOAT_EQ(60.0f, columns.GetColumnWidth(0)); 373 EXPECT_FLOAT_EQ(40.0f, columns.GetColumnWidth(1)); 374 375 columns.CalculateSize(150.0f); 376 EXPECT_FLOAT_EQ(90.0f, columns.GetColumnWidth(0)); 377 EXPECT_FLOAT_EQ(60.0f, columns.GetColumnWidth(1)); 378} 379 380TEST_F(LayoutTest, ColumnSetMixedColumns) { 381 ColumnSet columns(0); 382 383 columns.AddColumn(0.6f); 384 columns.AddPaddingColumn(20); 385 columns.AddColumn(0.4f); 386 EXPECT_EQ(3, columns.num_columns()); 387 388 columns.CalculateSize(100.0f); 389 EXPECT_FLOAT_EQ(48.0f, columns.GetColumnWidth(0)); 390 EXPECT_FLOAT_EQ(20.0f, columns.GetColumnWidth(1)); 391 EXPECT_FLOAT_EQ(32.0f, columns.GetColumnWidth(2)); 392 393 columns.CalculateSize(200.0f); 394 EXPECT_FLOAT_EQ(108.0f, columns.GetColumnWidth(0)); 395 EXPECT_FLOAT_EQ(20.0f, columns.GetColumnWidth(1)); 396 EXPECT_FLOAT_EQ(72.0f, columns.GetColumnWidth(2)); 397} 398 399} // namespace 400