1 // Copyright (c) 2015 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.
5 #include "sync/syncable/proto_value_ptr.h"
7 #include "testing/gtest/include/gtest/gtest.h"
14 // TestValue class is used as a template argument with ProtoValuePtr<T>
17 TestValue() : value_(0), is_initialized_(false), is_default_(false) {}
18 explicit TestValue(int value
)
19 : value_(value
), is_initialized_(true), is_default_(false) {}
21 ~TestValue() { g_delete_count
++; }
23 static void ResetCounters() {
28 static int copy_count() { return g_copy_count
; }
29 static int delete_count() { return g_delete_count
; }
31 int value() const { return value_
; }
32 bool is_initialized() const { return is_initialized_
; }
33 bool is_default() const { return is_default_
; }
35 // TestValue uses the default traits struct with ProtoValuePtr<TestValue>.
36 // The following 3 functions are expected by the traits struct to exist
38 void CopyFrom(const TestValue
& from
) {
39 // Expected to always copy from an initialized instance
40 // to an uninitialized one.
41 // Not expected either value to be default.
42 ASSERT_FALSE(is_initialized());
43 ASSERT_FALSE(is_default());
44 ASSERT_TRUE(from
.is_initialized());
45 ASSERT_FALSE(from
.is_default());
46 value_
= from
.value();
47 is_initialized_
= false;
51 int ByteSize() const { return is_initialized() ? sizeof(int) : 0; }
53 static const TestValue
& default_instance() {
54 static TestValue default_instance
;
55 default_instance
.is_default_
= true;
56 return default_instance
;
60 static int g_copy_count
;
61 static int g_delete_count
;
67 DISALLOW_COPY_AND_ASSIGN(TestValue
);
70 // Static initializers.
71 int TestValue::g_copy_count
= 0;
72 int TestValue::g_delete_count
= 0;
76 typedef ProtoValuePtr
<TestValue
> TestPtr
;
78 class ProtoValuePtrTest
: public testing::Test
{
80 void SetUp() override
{ TestValue::ResetCounters(); }
82 static bool WrappedValuesAreShared(const TestPtr
& ptr1
, const TestPtr
& ptr2
) {
83 const TestValue
& wrapped_value_1
= ptr1
.value();
84 const TestValue
& wrapped_value_2
= ptr2
.value();
86 return &wrapped_value_1
== &wrapped_value_2
;
90 TEST_F(ProtoValuePtrTest
, BasicTest
) {
91 // Basic assignment and default value.
95 EXPECT_TRUE(ptr1
->is_default());
98 EXPECT_FALSE(ptr1
->is_default());
99 EXPECT_EQ(1, ptr1
->value());
102 EXPECT_EQ(1, TestValue::copy_count());
103 EXPECT_EQ(1, TestValue::delete_count());
106 TEST_F(ProtoValuePtrTest
, SharingTest
) {
107 // Sharing between two pointers.
115 EXPECT_TRUE(ptr2
->is_default());
116 EXPECT_TRUE(ptr3
->is_default());
117 EXPECT_EQ(0, TestValue::copy_count());
118 EXPECT_EQ(0, TestValue::delete_count());
121 EXPECT_EQ(1, TestValue::copy_count());
122 EXPECT_EQ(0, TestValue::delete_count());
125 // Both |ptr2| and |ptr3| now share the same value "2".
126 // No additional copies expected.
127 EXPECT_EQ(1, TestValue::copy_count());
128 EXPECT_EQ(0, TestValue::delete_count());
129 EXPECT_FALSE(ptr3
->is_default());
130 EXPECT_EQ(2, ptr3
->value());
131 EXPECT_TRUE(WrappedValuesAreShared(ptr2
, ptr3
));
133 // Stop sharing - |ptr2| is "3" and |ptr3| is still "2".
135 EXPECT_FALSE(WrappedValuesAreShared(ptr2
, ptr3
));
136 EXPECT_EQ(3, ptr2
->value());
137 EXPECT_EQ(2, ptr3
->value());
138 // No extra copies or deletions expected.
139 EXPECT_EQ(2, TestValue::copy_count());
140 EXPECT_EQ(0, TestValue::delete_count());
142 // |ptr3| still has the old value.
143 EXPECT_EQ(2, ptr3
->value());
145 // Share again. Both values are "3".
147 EXPECT_EQ(3, ptr3
->value());
148 // This should have resulted in deleting the wrapper for the value "2".
149 EXPECT_EQ(1, TestValue::delete_count());
150 // No extra copies expected.
151 EXPECT_EQ(2, TestValue::copy_count());
153 // Set default value to one of the pointers.
154 ptr2
.set_value(empty
);
155 EXPECT_TRUE(ptr2
->is_default());
156 // The other one is still intact.
157 EXPECT_FALSE(ptr3
->is_default());
158 EXPECT_EQ(3, ptr3
->value());
159 // No extra copies or deletions expected.
160 EXPECT_EQ(1, TestValue::delete_count());
161 EXPECT_EQ(2, TestValue::copy_count());
163 // Copy the default value between the pointers.
165 EXPECT_TRUE(ptr3
->is_default());
166 // The wrapper for "3" is now deleted.
167 EXPECT_EQ(2, TestValue::delete_count());
170 // No extra deletions expected upon leaving the scope.
171 EXPECT_EQ(2, TestValue::delete_count());
174 } // namespace syncable
175 } // namespace syncer