Index: sync/engine/model_thread_sync_entity_unittest.cc |
diff --git a/sync/engine/model_thread_sync_entity_unittest.cc b/sync/engine/model_thread_sync_entity_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..54edd109baf10fbd5c85dd0ba3e1c8f84c9b12f9 |
--- /dev/null |
+++ b/sync/engine/model_thread_sync_entity_unittest.cc |
@@ -0,0 +1,178 @@ |
+// Copyright 2014 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 "sync/engine/model_thread_sync_entity.h" |
+ |
+#include "base/memory/scoped_ptr.h" |
+#include "base/time/time.h" |
+#include "sync/internal_api/public/base/model_type.h" |
+#include "sync/protocol/sync.pb.h" |
+#include "sync/syncable/syncable_util.h" |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace syncer { |
+ |
+// Some simple sanity tests for the ModelThreadSyncEntity. |
+// |
+// A lot of the more complicated sync logic is implemented in the |
+// NonBlockingTypeProcessor that owns the ModelThreadSyncEntity. We |
+// can't unit test it here. |
+// |
+// Instead, we focus on simple tests to make sure that variables are getting |
+// properly intialized and flags properly set. Anything more complicated would |
+// be a redundant and incomplete version of the NonBlockingTypeProcessor tests. |
+class ModelThreadSyncEntityTest : public ::testing::Test { |
+ public: |
+ ModelThreadSyncEntityTest() |
+ : kServerId("ServerID"), |
+ kClientTag("sample.pref.name"), |
+ kClientTagHash(syncable::GenerateSyncableHash(PREFERENCES, kClientTag)), |
+ kCtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(10)), |
+ kMtime(base::Time::UnixEpoch() + base::TimeDelta::FromDays(20)) { |
+ sync_pb::PreferenceSpecifics* pref_specifics = |
+ specifics.mutable_preference(); |
+ pref_specifics->set_name(kClientTag); |
+ pref_specifics->set_value("pref.value"); |
+ } |
+ |
+ const std::string kServerId; |
+ const std::string kClientTag; |
+ const std::string kClientTagHash; |
+ const base::Time kCtime; |
+ const base::Time kMtime; |
+ sync_pb::EntitySpecifics specifics; |
+}; |
+ |
+TEST_F(ModelThreadSyncEntityTest, NewLocalItem) { |
+ scoped_ptr<ModelThreadSyncEntity> entity( |
+ ModelThreadSyncEntity::NewLocalItem("asdf", specifics, kCtime)); |
+ |
+ EXPECT_TRUE(entity->IsWriteRequired()); |
+ EXPECT_TRUE(entity->IsUnsynced()); |
+ EXPECT_FALSE(entity->UpdateIsReflection(1)); |
+ EXPECT_TRUE(entity->UpdateIsInConflict(1)); |
+} |
+ |
+TEST_F(ModelThreadSyncEntityTest, FromServerUpdate) { |
+ scoped_ptr<ModelThreadSyncEntity> entity( |
+ ModelThreadSyncEntity::FromServerUpdate( |
+ kServerId, |
+ kClientTagHash, |
+ kClientTag, // As non-unique name. |
+ 10, |
+ specifics, |
+ false, |
+ kCtime, |
+ kMtime)); |
+ |
+ EXPECT_TRUE(entity->IsWriteRequired()); |
+ EXPECT_FALSE(entity->IsUnsynced()); |
+ EXPECT_TRUE(entity->UpdateIsReflection(9)); |
+ EXPECT_TRUE(entity->UpdateIsReflection(10)); |
+ EXPECT_FALSE(entity->UpdateIsReflection(11)); |
+ EXPECT_FALSE(entity->UpdateIsInConflict(11)); |
+} |
+ |
+// Tombstones should behave just like regular updates. Mostly. The strangest |
+// thing about them is that they don't have specifics, so it can be hard to |
+// detect their type. Fortunately, this class doesn't care about types in |
+// received updates. |
+TEST_F(ModelThreadSyncEntityTest, TombstoneUpdate) { |
+ scoped_ptr<ModelThreadSyncEntity> entity( |
+ ModelThreadSyncEntity::FromServerUpdate( |
+ kServerId, |
+ kClientTagHash, |
+ kClientTag, // As non-unique name. |
+ 10, |
+ sync_pb::EntitySpecifics(), |
+ true, |
+ kCtime, |
+ kMtime)); |
+ |
+ EXPECT_TRUE(entity->IsWriteRequired()); |
+ EXPECT_FALSE(entity->IsUnsynced()); |
+ EXPECT_TRUE(entity->UpdateIsReflection(9)); |
+ EXPECT_TRUE(entity->UpdateIsReflection(10)); |
+ EXPECT_FALSE(entity->UpdateIsReflection(11)); |
+ EXPECT_FALSE(entity->UpdateIsInConflict(11)); |
+} |
+ |
+// Apply a deletion update. |
+TEST_F(ModelThreadSyncEntityTest, ApplyUpdate) { |
+ scoped_ptr<ModelThreadSyncEntity> entity( |
+ ModelThreadSyncEntity::FromServerUpdate( |
+ kServerId, |
+ kClientTagHash, |
+ kClientTag, // As non-unique name. |
+ 10, |
+ specifics, |
+ false, |
+ kCtime, |
+ kMtime)); |
+ |
+ // A deletion update one version later. |
+ entity->ApplyUpdateFromServer(11, |
+ true, |
+ sync_pb::EntitySpecifics(), |
+ kMtime + base::TimeDelta::FromSeconds(10)); |
+ |
+ EXPECT_TRUE(entity->IsWriteRequired()); |
+ EXPECT_FALSE(entity->IsUnsynced()); |
+ EXPECT_TRUE(entity->UpdateIsReflection(11)); |
+ EXPECT_FALSE(entity->UpdateIsReflection(12)); |
+} |
+ |
+TEST_F(ModelThreadSyncEntityTest, LocalChange) { |
+ scoped_ptr<ModelThreadSyncEntity> entity( |
+ ModelThreadSyncEntity::FromServerUpdate( |
+ kServerId, |
+ kClientTagHash, |
+ kClientTag, // As non-unique name. |
+ 10, |
+ specifics, |
+ false, |
+ kCtime, |
+ kMtime)); |
+ |
+ sync_pb::EntitySpecifics specifics2; |
+ specifics2.CopyFrom(specifics); |
+ specifics2.mutable_preference()->set_value("new.pref.value"); |
+ |
+ entity->MakeLocalChange(kClientTag, specifics2); |
+ EXPECT_TRUE(entity->IsWriteRequired()); |
+ EXPECT_TRUE(entity->IsUnsynced()); |
+ |
+ EXPECT_TRUE(entity->UpdateIsReflection(10)); |
+ EXPECT_FALSE(entity->UpdateIsInConflict(10)); |
+ |
+ EXPECT_FALSE(entity->UpdateIsReflection(11)); |
+ EXPECT_TRUE(entity->UpdateIsInConflict(11)); |
+} |
+ |
+TEST_F(ModelThreadSyncEntityTest, LocalDeletion) { |
+ scoped_ptr<ModelThreadSyncEntity> entity( |
+ ModelThreadSyncEntity::FromServerUpdate( |
+ kServerId, |
+ kClientTagHash, |
+ kClientTag, // As non-unique name. |
+ 10, |
+ specifics, |
+ false, |
+ kCtime, |
+ kMtime)); |
+ |
+ entity->Delete(kClientTag); |
+ |
+ EXPECT_TRUE(entity->IsWriteRequired()); |
+ EXPECT_TRUE(entity->IsUnsynced()); |
+ |
+ EXPECT_TRUE(entity->UpdateIsReflection(10)); |
+ EXPECT_FALSE(entity->UpdateIsInConflict(10)); |
+ |
+ EXPECT_FALSE(entity->UpdateIsReflection(11)); |
+ EXPECT_TRUE(entity->UpdateIsInConflict(11)); |
+} |
+ |
+} // namespace syncer |