OLD | NEW |
(Empty) | |
| 1 // Copyright 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 "base/strings/sys_string_conversions.h" |
| 6 #include "base/strings/utf_string_conversions.h" |
| 7 #include "base/time/time.h" |
| 8 #include "components/bookmarks/browser/bookmark_model.h" |
| 9 #include "ios/chrome/browser/experimental_flags.h" |
| 10 #include "ios/chrome/browser/ui/bookmarks/bookmark_ios_unittest.h" |
| 11 #import "ios/chrome/browser/ui/bookmarks/bookmark_menu_item.h" |
| 12 #import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h" |
| 13 #include "testing/gtest_mac.h" |
| 14 |
| 15 using bookmarks::BookmarkNode; |
| 16 |
| 17 namespace { |
| 18 |
| 19 using bookmark_utils_ios::NodesSection; |
| 20 |
| 21 class BookmarkIOSUtilsUnitTest : public BookmarkIOSUnitTest { |
| 22 protected: |
| 23 base::Time timeFromEpoch(int days, int hours) { |
| 24 return base::Time::UnixEpoch() + base::TimeDelta::FromDays(days) + |
| 25 base::TimeDelta::FromHours(hours); |
| 26 } |
| 27 |
| 28 void SetUp() override { |
| 29 BookmarkIOSUnitTest::SetUp(); |
| 30 bookmark_utils_ios::ClearPositionCache(); |
| 31 } |
| 32 |
| 33 void TearDown() override { |
| 34 bookmark_utils_ios::ClearPositionCache(); |
| 35 BookmarkIOSUnitTest::TearDown(); |
| 36 } |
| 37 }; |
| 38 |
| 39 TEST_F(BookmarkIOSUtilsUnitTest, segregateNodesByCreationDate) { |
| 40 const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); |
| 41 const BookmarkNode* f1 = AddFolder(mobileNode, @"f1"); |
| 42 const BookmarkNode* a = AddBookmark(mobileNode, @"a"); |
| 43 _bookmarkModel->SetDateAdded(a, timeFromEpoch(169, 5)); |
| 44 const BookmarkNode* b = AddBookmark(mobileNode, @"b"); |
| 45 _bookmarkModel->SetDateAdded(b, timeFromEpoch(170, 6)); |
| 46 const BookmarkNode* f2 = AddFolder(mobileNode, @"f2"); |
| 47 |
| 48 const BookmarkNode* f1a = AddBookmark(f1, @"f1a"); |
| 49 _bookmarkModel->SetDateAdded(f1a, timeFromEpoch(129, 5)); |
| 50 const BookmarkNode* f1b = AddBookmark(f1, @"f1b"); |
| 51 _bookmarkModel->SetDateAdded(f1b, timeFromEpoch(130, 6)); |
| 52 const BookmarkNode* f2a = AddBookmark(f2, @"f2a"); |
| 53 _bookmarkModel->SetDateAdded(f2a, timeFromEpoch(201, 5)); |
| 54 const BookmarkNode* f2b = AddBookmark(f2, @"f2b"); |
| 55 _bookmarkModel->SetDateAdded(f2b, timeFromEpoch(10, 5)); |
| 56 |
| 57 std::vector<const BookmarkNode*> toSort; |
| 58 toSort.push_back(a); |
| 59 toSort.push_back(b); |
| 60 toSort.push_back(f1a); |
| 61 toSort.push_back(f1b); |
| 62 toSort.push_back(f2a); |
| 63 toSort.push_back(f2b); |
| 64 |
| 65 ScopedVector<NodesSection> nodesSectionVector; |
| 66 bookmark_utils_ios::segregateNodes(toSort, nodesSectionVector); |
| 67 |
| 68 // Expect the nodes to be sorted in reverse chronological order, grouped by |
| 69 // month. |
| 70 ASSERT_EQ(nodesSectionVector.size(), 4u); |
| 71 NodesSection* section = nodesSectionVector[0]; |
| 72 ASSERT_EQ(section->vector.size(), 1u); |
| 73 EXPECT_EQ(section->vector[0], f2a); |
| 74 |
| 75 section = nodesSectionVector[1]; |
| 76 ASSERT_EQ(section->vector.size(), 2u); |
| 77 EXPECT_EQ(section->vector[0], b); |
| 78 EXPECT_EQ(section->vector[1], a); |
| 79 |
| 80 section = nodesSectionVector[2]; |
| 81 ASSERT_EQ(section->vector.size(), 2u); |
| 82 EXPECT_EQ(section->vector[0], f1b); |
| 83 EXPECT_EQ(section->vector[1], f1a); |
| 84 |
| 85 section = nodesSectionVector[3]; |
| 86 ASSERT_EQ(section->vector.size(), 1u); |
| 87 EXPECT_EQ(section->vector[0], f2b); |
| 88 } |
| 89 |
| 90 TEST_F(BookmarkIOSUtilsUnitTest, DeleteNodes) { |
| 91 const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); |
| 92 const BookmarkNode* f1 = AddFolder(mobileNode, @"f1"); |
| 93 const BookmarkNode* a = AddBookmark(mobileNode, @"a"); |
| 94 const BookmarkNode* b = AddBookmark(mobileNode, @"b"); |
| 95 const BookmarkNode* f2 = AddFolder(mobileNode, @"f2"); |
| 96 |
| 97 AddBookmark(f1, @"f1a"); |
| 98 AddBookmark(f1, @"f1b"); |
| 99 AddBookmark(f1, @"f1c"); |
| 100 AddBookmark(f2, @"f2a"); |
| 101 const BookmarkNode* f2b = AddBookmark(f2, @"f2b"); |
| 102 |
| 103 std::set<const BookmarkNode*> toDelete; |
| 104 toDelete.insert(a); |
| 105 toDelete.insert(f2b); |
| 106 toDelete.insert(f2); |
| 107 |
| 108 bookmark_utils_ios::DeleteBookmarks(toDelete, _bookmarkModel); |
| 109 |
| 110 EXPECT_EQ(mobileNode->child_count(), 2); |
| 111 const BookmarkNode* child0 = mobileNode->GetChild(0); |
| 112 EXPECT_EQ(child0, f1); |
| 113 EXPECT_EQ(child0->child_count(), 3); |
| 114 const BookmarkNode* child1 = mobileNode->GetChild(1); |
| 115 EXPECT_EQ(child1, b); |
| 116 EXPECT_EQ(child1->child_count(), 0); |
| 117 } |
| 118 |
| 119 TEST_F(BookmarkIOSUtilsUnitTest, MoveNodes) { |
| 120 const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); |
| 121 const BookmarkNode* f1 = AddFolder(mobileNode, @"f1"); |
| 122 const BookmarkNode* a = AddBookmark(mobileNode, @"a"); |
| 123 const BookmarkNode* b = AddBookmark(mobileNode, @"b"); |
| 124 const BookmarkNode* f2 = AddFolder(mobileNode, @"f2"); |
| 125 |
| 126 AddBookmark(f1, @"f1a"); |
| 127 AddBookmark(f1, @"f1b"); |
| 128 AddBookmark(f1, @"f1c"); |
| 129 AddBookmark(f2, @"f2a"); |
| 130 const BookmarkNode* f2b = AddBookmark(f2, @"f2b"); |
| 131 |
| 132 std::set<const BookmarkNode*> toMove; |
| 133 toMove.insert(a); |
| 134 toMove.insert(f2b); |
| 135 toMove.insert(f2); |
| 136 |
| 137 bookmark_utils_ios::MoveBookmarks(toMove, _bookmarkModel, f1); |
| 138 |
| 139 EXPECT_EQ(mobileNode->child_count(), 2); |
| 140 const BookmarkNode* child0 = mobileNode->GetChild(0); |
| 141 EXPECT_EQ(child0, f1); |
| 142 EXPECT_EQ(child0->child_count(), 6); |
| 143 const BookmarkNode* child1 = mobileNode->GetChild(1); |
| 144 EXPECT_EQ(child1, b); |
| 145 EXPECT_EQ(child1->child_count(), 0); |
| 146 } |
| 147 |
| 148 TEST_F(BookmarkIOSUtilsUnitTest, TestDefaultMoveFolder) { |
| 149 const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); |
| 150 const BookmarkNode* f1 = AddFolder(mobileNode, @"f1"); |
| 151 const BookmarkNode* a = AddBookmark(mobileNode, @"a"); |
| 152 AddBookmark(mobileNode, @"b"); |
| 153 const BookmarkNode* f2 = AddFolder(mobileNode, @"f2"); |
| 154 |
| 155 AddBookmark(f1, @"f1a"); |
| 156 AddBookmark(f1, @"f1b"); |
| 157 AddBookmark(f1, @"f1c"); |
| 158 const BookmarkNode* f2a = AddBookmark(f2, @"f2a"); |
| 159 const BookmarkNode* f2b = AddBookmark(f2, @"f2b"); |
| 160 |
| 161 std::set<const BookmarkNode*> toMove; |
| 162 toMove.insert(a); |
| 163 toMove.insert(f2b); |
| 164 toMove.insert(f2); |
| 165 |
| 166 const BookmarkNode* folder = |
| 167 bookmark_utils_ios::defaultMoveFolder(toMove, _bookmarkModel); |
| 168 EXPECT_EQ(folder, mobileNode); |
| 169 |
| 170 toMove.clear(); |
| 171 toMove.insert(f2a); |
| 172 toMove.insert(f2b); |
| 173 folder = bookmark_utils_ios::defaultMoveFolder(toMove, _bookmarkModel); |
| 174 EXPECT_EQ(folder, f2); |
| 175 } |
| 176 |
| 177 TEST_F(BookmarkIOSUtilsUnitTest, TestPositionCache) { |
| 178 // Try to store and retrieve a cache for the allMenuItem. |
| 179 BookmarkMenuItem* item = [BookmarkMenuItem allMenuItem]; |
| 180 CGFloat position = 23; |
| 181 bookmark_utils_ios::CachePosition(position, item); |
| 182 CGFloat outPosition; |
| 183 BookmarkMenuItem* outItem; |
| 184 BOOL result = bookmark_utils_ios::GetPositionCache(_bookmarkModel, &outItem, |
| 185 &outPosition); |
| 186 if (experimental_flags::IsAllBookmarksEnabled()) { |
| 187 ASSERT_TRUE(result); |
| 188 EXPECT_NSEQ(item, outItem); |
| 189 EXPECT_NEAR(position, outPosition, 0.01); |
| 190 } else { |
| 191 ASSERT_FALSE(result); |
| 192 } |
| 193 |
| 194 // Try to store and retrieve a cache for the folderMenuItem. |
| 195 const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); |
| 196 const BookmarkNode* f1 = AddFolder(mobileNode, @"f1"); |
| 197 item = [BookmarkMenuItem folderMenuItemForNode:f1 rootAncestor:NULL]; |
| 198 bookmark_utils_ios::CachePosition(position, item); |
| 199 result = bookmark_utils_ios::GetPositionCache(_bookmarkModel, &outItem, |
| 200 &outPosition); |
| 201 ASSERT_TRUE(result); |
| 202 EXPECT_NSEQ(item, outItem); |
| 203 EXPECT_NEAR(position, outPosition, 0.01); |
| 204 EXPECT_EQ(f1, outItem.folder); |
| 205 EXPECT_EQ(bookmarks::MenuItemFolder, outItem.type); |
| 206 } |
| 207 |
| 208 TEST_F(BookmarkIOSUtilsUnitTest, TestBookmarkModelChangesPositionCache) { |
| 209 // Try to store and retrieve a cache for the folderMenuItem |
| 210 const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); |
| 211 const BookmarkNode* f1 = AddFolder(mobileNode, @"f1"); |
| 212 BookmarkMenuItem* item = |
| 213 [BookmarkMenuItem folderMenuItemForNode:f1 rootAncestor:NULL]; |
| 214 CGFloat position = 23; |
| 215 bookmark_utils_ios::CachePosition(position, item); |
| 216 |
| 217 // Delete the folder. |
| 218 _bookmarkModel->Remove(f1); |
| 219 |
| 220 CGFloat outPosition; |
| 221 BookmarkMenuItem* outItem; |
| 222 BOOL result = bookmark_utils_ios::GetPositionCache(_bookmarkModel, &outItem, |
| 223 &outPosition); |
| 224 ASSERT_FALSE(result); |
| 225 } |
| 226 |
| 227 TEST_F(BookmarkIOSUtilsUnitTest, TestVisibleNonDescendantNodes) { |
| 228 const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); |
| 229 const BookmarkNode* music = AddFolder(mobileNode, @"music"); |
| 230 |
| 231 const BookmarkNode* pop = AddFolder(music, @"pop"); |
| 232 const BookmarkNode* lindsey = AddBookmark(pop, @"lindsey lohan"); |
| 233 AddBookmark(pop, @"katy perry"); |
| 234 const BookmarkNode* gaga = AddFolder(pop, @"lady gaga"); |
| 235 AddBookmark(gaga, @"gaga song 1"); |
| 236 AddFolder(gaga, @"gaga folder 1"); |
| 237 |
| 238 const BookmarkNode* metal = AddFolder(music, @"metal"); |
| 239 AddFolder(metal, @"opeth"); |
| 240 AddFolder(metal, @"F12"); |
| 241 AddFolder(metal, @"f31"); |
| 242 |
| 243 const BookmarkNode* animals = AddFolder(mobileNode, @"animals"); |
| 244 AddFolder(animals, @"cat"); |
| 245 const BookmarkNode* camel = AddFolder(animals, @"camel"); |
| 246 AddFolder(camel, @"al paca"); |
| 247 |
| 248 AddFolder(_bookmarkModel->other_node(), @"buildings"); |
| 249 |
| 250 std::set<const BookmarkNode*> obstructions; |
| 251 // Editing a folder and a bookmark. |
| 252 obstructions.insert(gaga); |
| 253 obstructions.insert(lindsey); |
| 254 |
| 255 bookmark_utils_ios::NodeVector result = |
| 256 bookmark_utils_ios::VisibleNonDescendantNodes(obstructions, |
| 257 _bookmarkModel); |
| 258 ASSERT_EQ(13u, result.size()); |
| 259 |
| 260 EXPECT_NSEQ(base::SysUTF16ToNSString(result[0]->GetTitle()), |
| 261 @"Mobile Bookmarks"); |
| 262 EXPECT_NSEQ(base::SysUTF16ToNSString(result[1]->GetTitle()), @"animals"); |
| 263 EXPECT_NSEQ(base::SysUTF16ToNSString(result[2]->GetTitle()), @"camel"); |
| 264 EXPECT_NSEQ(base::SysUTF16ToNSString(result[3]->GetTitle()), @"al paca"); |
| 265 EXPECT_NSEQ(base::SysUTF16ToNSString(result[4]->GetTitle()), @"cat"); |
| 266 EXPECT_NSEQ(base::SysUTF16ToNSString(result[5]->GetTitle()), @"music"); |
| 267 EXPECT_NSEQ(base::SysUTF16ToNSString(result[6]->GetTitle()), @"metal"); |
| 268 EXPECT_NSEQ(base::SysUTF16ToNSString(result[7]->GetTitle()), @"F12"); |
| 269 EXPECT_NSEQ(base::SysUTF16ToNSString(result[8]->GetTitle()), @"f31"); |
| 270 EXPECT_NSEQ(base::SysUTF16ToNSString(result[9]->GetTitle()), @"opeth"); |
| 271 EXPECT_NSEQ(base::SysUTF16ToNSString(result[10]->GetTitle()), @"pop"); |
| 272 EXPECT_NSEQ(base::SysUTF16ToNSString(result[11]->GetTitle()), |
| 273 @"Other Bookmarks"); |
| 274 EXPECT_NSEQ(base::SysUTF16ToNSString(result[12]->GetTitle()), @"buildings"); |
| 275 } |
| 276 |
| 277 TEST_F(BookmarkIOSUtilsUnitTest, TestIsSubvectorOfNodes) { |
| 278 // Empty vectors: [] - []. |
| 279 bookmark_utils_ios::NodeVector vector1; |
| 280 bookmark_utils_ios::NodeVector vector2; |
| 281 EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 282 EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 283 |
| 284 // Empty vs vector with one element: [] - [1]. |
| 285 const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); |
| 286 const BookmarkNode* bookmark1 = AddBookmark(mobileNode, @"1"); |
| 287 vector2.push_back(bookmark1); |
| 288 EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 289 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 290 |
| 291 // The same element in each: [1] - [1]. |
| 292 vector1.push_back(bookmark1); |
| 293 EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 294 EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 295 |
| 296 // One different element in each: [2] - [1]. |
| 297 vector1.pop_back(); |
| 298 const BookmarkNode* bookmark2 = AddBookmark(mobileNode, @"2"); |
| 299 vector1.push_back(bookmark2); |
| 300 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 301 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 302 |
| 303 // [2] - [1, 2]. |
| 304 vector2.push_back(bookmark2); |
| 305 EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 306 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 307 |
| 308 // [3] - [1, 2]. |
| 309 vector1.pop_back(); |
| 310 const BookmarkNode* bookmark3 = AddBookmark(mobileNode, @"3"); |
| 311 vector1.push_back(bookmark3); |
| 312 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 313 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 314 |
| 315 // [2, 3] - [1, 2, 3]. |
| 316 vector1.insert(vector1.begin(), bookmark2); |
| 317 vector2.push_back(bookmark3); |
| 318 EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 319 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 320 |
| 321 // [2, 3, 1] - [1, 2, 3]. |
| 322 vector1.push_back(bookmark2); |
| 323 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 324 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 325 |
| 326 // [1, 3] - [1, 2, 3]. |
| 327 vector1.clear(); |
| 328 vector1.push_back(bookmark1); |
| 329 vector1.push_back(bookmark2); |
| 330 EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 331 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 332 |
| 333 // [1, 1] - [1, 2, 3]. |
| 334 vector1.pop_back(); |
| 335 vector1.push_back(bookmark1); |
| 336 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 337 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 338 |
| 339 // [1, 1] - [1, 1, 2, 3]. |
| 340 vector2.insert(vector2.begin(), bookmark1); |
| 341 EXPECT_TRUE(bookmark_utils_ios::IsSubvectorOfNodes(vector1, vector2)); |
| 342 EXPECT_FALSE(bookmark_utils_ios::IsSubvectorOfNodes(vector2, vector1)); |
| 343 } |
| 344 |
| 345 TEST_F(BookmarkIOSUtilsUnitTest, TestMissingNodes) { |
| 346 // [] - []. |
| 347 bookmark_utils_ios::NodeVector vector1; |
| 348 bookmark_utils_ios::NodeVector vector2; |
| 349 EXPECT_EQ(0u, |
| 350 bookmark_utils_ios::MissingNodesIndices(vector1, vector2).size()); |
| 351 |
| 352 // [] - [1]. |
| 353 const BookmarkNode* mobileNode = _bookmarkModel->mobile_node(); |
| 354 const BookmarkNode* bookmark1 = AddBookmark(mobileNode, @"1"); |
| 355 vector2.push_back(bookmark1); |
| 356 std::vector<bookmark_utils_ios::NodeVector::size_type> missingNodesIndices = |
| 357 bookmark_utils_ios::MissingNodesIndices(vector1, vector2); |
| 358 EXPECT_EQ(1u, missingNodesIndices.size()); |
| 359 EXPECT_EQ(0u, missingNodesIndices[0]); |
| 360 |
| 361 // [1] - [1]. |
| 362 vector1.push_back(bookmark1); |
| 363 EXPECT_EQ(0u, |
| 364 bookmark_utils_ios::MissingNodesIndices(vector1, vector2).size()); |
| 365 |
| 366 // [2] - [1, 2]. |
| 367 vector1.pop_back(); |
| 368 const BookmarkNode* bookmark2 = AddBookmark(mobileNode, @"2"); |
| 369 vector1.push_back(bookmark2); |
| 370 vector2.push_back(bookmark2); |
| 371 missingNodesIndices = |
| 372 bookmark_utils_ios::MissingNodesIndices(vector1, vector2); |
| 373 EXPECT_EQ(1u, missingNodesIndices.size()); |
| 374 EXPECT_EQ(0u, missingNodesIndices[0]); |
| 375 |
| 376 // [2, 3] - [1, 2, 3]. |
| 377 const BookmarkNode* bookmark3 = AddBookmark(mobileNode, @"3"); |
| 378 vector1.push_back(bookmark3); |
| 379 vector2.push_back(bookmark3); |
| 380 missingNodesIndices = |
| 381 bookmark_utils_ios::MissingNodesIndices(vector1, vector2); |
| 382 EXPECT_EQ(1u, missingNodesIndices.size()); |
| 383 EXPECT_EQ(0u, missingNodesIndices[0]); |
| 384 |
| 385 // [1, 3] - [1, 2, 3]. |
| 386 vector1.clear(); |
| 387 vector1.push_back(bookmark1); |
| 388 vector1.push_back(bookmark3); |
| 389 missingNodesIndices = |
| 390 bookmark_utils_ios::MissingNodesIndices(vector1, vector2); |
| 391 EXPECT_EQ(1u, missingNodesIndices.size()); |
| 392 EXPECT_EQ(1u, missingNodesIndices[0]); |
| 393 |
| 394 // [1, 1] - [1, 1, 2, 3]. |
| 395 vector1.pop_back(); |
| 396 vector1.push_back(bookmark1); |
| 397 vector2.insert(vector2.begin(), bookmark1); |
| 398 missingNodesIndices = |
| 399 bookmark_utils_ios::MissingNodesIndices(vector1, vector2); |
| 400 EXPECT_EQ(2u, missingNodesIndices.size()); |
| 401 EXPECT_EQ(2u, missingNodesIndices[0]); |
| 402 EXPECT_EQ(3u, missingNodesIndices[1]); |
| 403 } |
| 404 |
| 405 } // namespace |
OLD | NEW |