| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/sync/syncable/parent_child_index.h" | 5 #include "components/sync/syncable/parent_child_index.h" |
| 6 | 6 |
| 7 #include <list> | |
| 8 #include <string> | 7 #include <string> |
| 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/stl_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "components/sync/syncable/entry_kernel.h" | 12 #include "components/sync/syncable/entry_kernel.h" |
| 13 #include "components/sync/syncable/syncable_util.h" | 13 #include "components/sync/syncable/syncable_util.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 15 |
| 16 namespace syncer { | 16 namespace syncer { |
| 17 namespace syncable { | 17 namespace syncable { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 static const std::string kCacheGuid = "8HhNIHlEOCGQbIAALr9QEg=="; | 21 static const std::string kCacheGuid = "8HhNIHlEOCGQbIAALr9QEg=="; |
| 22 | 22 |
| 23 } // namespace | 23 } // namespace |
| 24 | 24 |
| 25 class ParentChildIndexTest : public testing::Test { | 25 class ParentChildIndexTest : public testing::Test { |
| 26 public: | 26 public: |
| 27 void TearDown() override { | 27 void TearDown() override {} |
| 28 // To make memory management easier, we take ownership of all EntryKernels | |
| 29 // returned by our factory methods and delete them here. | |
| 30 base::STLDeleteElements(&owned_entry_kernels_); | |
| 31 } | |
| 32 | 28 |
| 33 // Unfortunately, we can't use the regular Entry factory methods, because the | 29 // Unfortunately, we can't use the regular Entry factory methods, because the |
| 34 // ParentChildIndex deals in EntryKernels. | 30 // ParentChildIndex deals in EntryKernels. |
| 35 | 31 |
| 36 static syncable::Id GetBookmarkRootId() { | 32 static syncable::Id GetBookmarkRootId() { |
| 37 return syncable::Id::CreateFromServerId("bookmark_folder"); | 33 return syncable::Id::CreateFromServerId("bookmark_folder"); |
| 38 } | 34 } |
| 39 | 35 |
| 40 static syncable::Id GetBookmarkId(int n) { | 36 static syncable::Id GetBookmarkId(int n) { |
| 41 return syncable::Id::CreateFromServerId("b" + base::IntToString(n)); | 37 return syncable::Id::CreateFromServerId("b" + base::IntToString(n)); |
| 42 } | 38 } |
| 43 | 39 |
| 44 static syncable::Id GetClientUniqueId(int n) { | 40 static syncable::Id GetClientUniqueId(int n) { |
| 45 return syncable::Id::CreateFromServerId("c" + base::IntToString(n)); | 41 return syncable::Id::CreateFromServerId("c" + base::IntToString(n)); |
| 46 } | 42 } |
| 47 | 43 |
| 48 EntryKernel* MakeRoot() { | 44 EntryKernel* MakeRoot() { |
| 49 // Mimics the root node. | 45 // Mimics the root node. |
| 50 EntryKernel* root = new EntryKernel(); | 46 EntryKernel* root = new EntryKernel(); |
| 51 root->put(META_HANDLE, 1); | 47 root->put(META_HANDLE, 1); |
| 52 root->put(BASE_VERSION, -1); | 48 root->put(BASE_VERSION, -1); |
| 53 root->put(SERVER_VERSION, 0); | 49 root->put(SERVER_VERSION, 0); |
| 54 root->put(IS_DIR, true); | 50 root->put(IS_DIR, true); |
| 55 root->put(ID, syncable::Id::GetRoot()); | 51 root->put(ID, syncable::Id::GetRoot()); |
| 56 root->put(PARENT_ID, syncable::Id::GetRoot()); | 52 root->put(PARENT_ID, syncable::Id::GetRoot()); |
| 57 | 53 |
| 58 owned_entry_kernels_.push_back(root); | 54 owned_entry_kernels_.push_back(base::WrapUnique(root)); |
| 59 return root; | 55 return root; |
| 60 } | 56 } |
| 61 | 57 |
| 62 EntryKernel* MakeTypeRoot(ModelType model_type, const syncable::Id& id) { | 58 EntryKernel* MakeTypeRoot(ModelType model_type, const syncable::Id& id) { |
| 63 // Mimics a server-created bookmark folder. | 59 // Mimics a server-created bookmark folder. |
| 64 EntryKernel* folder = new EntryKernel; | 60 EntryKernel* folder = new EntryKernel; |
| 65 folder->put(META_HANDLE, 1); | 61 folder->put(META_HANDLE, 1); |
| 66 folder->put(BASE_VERSION, 9); | 62 folder->put(BASE_VERSION, 9); |
| 67 folder->put(SERVER_VERSION, 9); | 63 folder->put(SERVER_VERSION, 9); |
| 68 folder->put(IS_DIR, true); | 64 folder->put(IS_DIR, true); |
| 69 folder->put(ID, id); | 65 folder->put(ID, id); |
| 70 folder->put(PARENT_ID, syncable::Id::GetRoot()); | 66 folder->put(PARENT_ID, syncable::Id::GetRoot()); |
| 71 folder->put(UNIQUE_SERVER_TAG, ModelTypeToRootTag(model_type)); | 67 folder->put(UNIQUE_SERVER_TAG, ModelTypeToRootTag(model_type)); |
| 72 | 68 |
| 73 // Ensure that GetModelType() returns a correct value. | 69 // Ensure that GetModelType() returns a correct value. |
| 74 sync_pb::EntitySpecifics specifics; | 70 sync_pb::EntitySpecifics specifics; |
| 75 AddDefaultFieldValue(model_type, &specifics); | 71 AddDefaultFieldValue(model_type, &specifics); |
| 76 folder->put(SPECIFICS, specifics); | 72 folder->put(SPECIFICS, specifics); |
| 77 | 73 |
| 78 owned_entry_kernels_.push_back(folder); | 74 owned_entry_kernels_.push_back(base::WrapUnique(folder)); |
| 79 return folder; | 75 return folder; |
| 80 } | 76 } |
| 81 | 77 |
| 82 EntryKernel* MakeBookmarkRoot() { | 78 EntryKernel* MakeBookmarkRoot() { |
| 83 return MakeTypeRoot(BOOKMARKS, GetBookmarkRootId()); | 79 return MakeTypeRoot(BOOKMARKS, GetBookmarkRootId()); |
| 84 } | 80 } |
| 85 | 81 |
| 86 EntryKernel* MakeBookmark(int n, int pos, bool is_dir) { | 82 EntryKernel* MakeBookmark(int n, int pos, bool is_dir) { |
| 87 // Mimics a regular bookmark or folder. | 83 // Mimics a regular bookmark or folder. |
| 88 EntryKernel* bm = new EntryKernel(); | 84 EntryKernel* bm = new EntryKernel(); |
| 89 bm->put(META_HANDLE, n); | 85 bm->put(META_HANDLE, n); |
| 90 bm->put(BASE_VERSION, 10); | 86 bm->put(BASE_VERSION, 10); |
| 91 bm->put(SERVER_VERSION, 10); | 87 bm->put(SERVER_VERSION, 10); |
| 92 bm->put(IS_DIR, is_dir); | 88 bm->put(IS_DIR, is_dir); |
| 93 bm->put(ID, GetBookmarkId(n)); | 89 bm->put(ID, GetBookmarkId(n)); |
| 94 bm->put(PARENT_ID, GetBookmarkRootId()); | 90 bm->put(PARENT_ID, GetBookmarkRootId()); |
| 95 | 91 |
| 96 bm->put(UNIQUE_BOOKMARK_TAG, syncable::GenerateSyncableBookmarkHash( | 92 bm->put(UNIQUE_BOOKMARK_TAG, syncable::GenerateSyncableBookmarkHash( |
| 97 kCacheGuid, bm->ref(ID).GetServerId())); | 93 kCacheGuid, bm->ref(ID).GetServerId())); |
| 98 | 94 |
| 99 UniquePosition unique_pos = | 95 UniquePosition unique_pos = |
| 100 UniquePosition::FromInt64(pos, bm->ref(UNIQUE_BOOKMARK_TAG)); | 96 UniquePosition::FromInt64(pos, bm->ref(UNIQUE_BOOKMARK_TAG)); |
| 101 bm->put(UNIQUE_POSITION, unique_pos); | 97 bm->put(UNIQUE_POSITION, unique_pos); |
| 102 bm->put(SERVER_UNIQUE_POSITION, unique_pos); | 98 bm->put(SERVER_UNIQUE_POSITION, unique_pos); |
| 103 | 99 |
| 104 owned_entry_kernels_.push_back(bm); | 100 owned_entry_kernels_.push_back(base::WrapUnique(bm)); |
| 105 return bm; | 101 return bm; |
| 106 } | 102 } |
| 107 | 103 |
| 108 EntryKernel* MakeUniqueClientItem(ModelType model_type, | 104 EntryKernel* MakeUniqueClientItem(ModelType model_type, |
| 109 int n, | 105 int n, |
| 110 const syncable::Id& parent_id) { | 106 const syncable::Id& parent_id) { |
| 111 EntryKernel* item = new EntryKernel(); | 107 EntryKernel* item = new EntryKernel(); |
| 112 item->put(META_HANDLE, n); | 108 item->put(META_HANDLE, n); |
| 113 item->put(BASE_VERSION, 10); | 109 item->put(BASE_VERSION, 10); |
| 114 item->put(SERVER_VERSION, 10); | 110 item->put(SERVER_VERSION, 10); |
| 115 item->put(IS_DIR, false); | 111 item->put(IS_DIR, false); |
| 116 item->put(ID, GetClientUniqueId(n)); | 112 item->put(ID, GetClientUniqueId(n)); |
| 117 item->put(UNIQUE_CLIENT_TAG, base::IntToString(n)); | 113 item->put(UNIQUE_CLIENT_TAG, base::IntToString(n)); |
| 118 | 114 |
| 119 if (!parent_id.IsNull()) { | 115 if (!parent_id.IsNull()) { |
| 120 item->put(PARENT_ID, parent_id); | 116 item->put(PARENT_ID, parent_id); |
| 121 } | 117 } |
| 122 | 118 |
| 123 if (model_type != UNSPECIFIED) { | 119 if (model_type != UNSPECIFIED) { |
| 124 // Ensure that GetModelType() returns a correct value. | 120 // Ensure that GetModelType() returns a correct value. |
| 125 sync_pb::EntitySpecifics specifics; | 121 sync_pb::EntitySpecifics specifics; |
| 126 AddDefaultFieldValue(model_type, &specifics); | 122 AddDefaultFieldValue(model_type, &specifics); |
| 127 item->put(SPECIFICS, specifics); | 123 item->put(SPECIFICS, specifics); |
| 128 } | 124 } |
| 129 | 125 |
| 130 owned_entry_kernels_.push_back(item); | 126 owned_entry_kernels_.push_back(base::WrapUnique(item)); |
| 131 return item; | 127 return item; |
| 132 } | 128 } |
| 133 | 129 |
| 134 EntryKernel* MakeUniqueClientItem(int n, const syncable::Id& parent_id) { | 130 EntryKernel* MakeUniqueClientItem(int n, const syncable::Id& parent_id) { |
| 135 return MakeUniqueClientItem(UNSPECIFIED, n, parent_id); | 131 return MakeUniqueClientItem(UNSPECIFIED, n, parent_id); |
| 136 } | 132 } |
| 137 | 133 |
| 138 EntryKernel* MakeUniqueClientItem(ModelType model_type, int n) { | 134 EntryKernel* MakeUniqueClientItem(ModelType model_type, int n) { |
| 139 return MakeUniqueClientItem(model_type, n, Id()); | 135 return MakeUniqueClientItem(model_type, n, Id()); |
| 140 } | 136 } |
| 141 | 137 |
| 142 const syncable::Id& IndexKnownModelTypeRootId(ModelType model_type) const { | 138 const syncable::Id& IndexKnownModelTypeRootId(ModelType model_type) const { |
| 143 return index_.GetModelTypeRootId(model_type); | 139 return index_.GetModelTypeRootId(model_type); |
| 144 } | 140 } |
| 145 | 141 |
| 146 ParentChildIndex index_; | 142 ParentChildIndex index_; |
| 147 | 143 |
| 148 private: | 144 private: |
| 149 std::list<EntryKernel*> owned_entry_kernels_; | 145 std::vector<std::unique_ptr<EntryKernel>> owned_entry_kernels_; |
| 150 }; | 146 }; |
| 151 | 147 |
| 152 TEST_F(ParentChildIndexTest, TestRootNode) { | 148 TEST_F(ParentChildIndexTest, TestRootNode) { |
| 153 EntryKernel* root = MakeRoot(); | 149 EntryKernel* root = MakeRoot(); |
| 154 EXPECT_FALSE(ParentChildIndex::ShouldInclude(root)); | 150 EXPECT_FALSE(ParentChildIndex::ShouldInclude(root)); |
| 155 } | 151 } |
| 156 | 152 |
| 157 TEST_F(ParentChildIndexTest, TestBookmarkRootFolder) { | 153 TEST_F(ParentChildIndexTest, TestBookmarkRootFolder) { |
| 158 EntryKernel* bm_folder = MakeBookmarkRoot(); | 154 EntryKernel* bm_folder = MakeBookmarkRoot(); |
| 159 EXPECT_TRUE(ParentChildIndex::ShouldInclude(bm_folder)); | 155 EXPECT_TRUE(ParentChildIndex::ShouldInclude(bm_folder)); |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 const OrderedChildSet* children = index_.GetChildren(type_root_id); | 511 const OrderedChildSet* children = index_.GetChildren(type_root_id); |
| 516 ASSERT_TRUE(children); | 512 ASSERT_TRUE(children); |
| 517 EXPECT_EQ(2UL, children->size()); | 513 EXPECT_EQ(2UL, children->size()); |
| 518 const OrderedChildSet* children_bad = index_.GetChildren(bad_type_root_id); | 514 const OrderedChildSet* children_bad = index_.GetChildren(bad_type_root_id); |
| 519 ASSERT_TRUE(children_bad); | 515 ASSERT_TRUE(children_bad); |
| 520 EXPECT_EQ(2UL, children_bad->size()); | 516 EXPECT_EQ(2UL, children_bad->size()); |
| 521 } | 517 } |
| 522 | 518 |
| 523 } // namespace syncable | 519 } // namespace syncable |
| 524 } // namespace syncer | 520 } // namespace syncer |
| OLD | NEW |