Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / sync / syncable / proto_value_ptr_unittest.cc
blob4686286c62cd76bb93036477ed7764951b356e21
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"
9 namespace syncer {
10 namespace syncable {
12 namespace {
14 // TestValue class is used as a template argument with ProtoValuePtr<T>
15 class TestValue {
16 public:
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() {
24 g_copy_count = 0;
25 g_parse_count = 0;
26 g_delete_count = 0;
29 static int copy_count() { return g_copy_count; }
30 static int parse_count() { return g_parse_count; }
31 static int delete_count() { return g_delete_count; }
33 int value() const { return value_; }
34 bool is_initialized() const { return is_initialized_; }
35 bool is_default() const { return is_default_; }
37 // TestValue uses the default traits struct with ProtoValuePtr<TestValue>.
38 // The following 4 functions are expected by the traits struct to exist
39 // in this class.
40 void CopyFrom(const TestValue& from) {
41 // Expected to always copy from an initialized instance
42 // to an uninitialized one.
43 // Not expected either value to be default.
44 ASSERT_FALSE(is_initialized());
45 ASSERT_FALSE(is_default());
46 ASSERT_TRUE(from.is_initialized());
47 ASSERT_FALSE(from.is_default());
48 value_ = from.value();
49 is_initialized_ = true;
50 g_copy_count++;
53 void ParseFromArray(const void* blob, int length) {
54 // Similarly to CopyFrom this is expected to be called on
55 // an uninitialized instance.
56 ASSERT_FALSE(is_initialized());
57 ASSERT_FALSE(is_default());
58 // The blob is an address of an integer
59 ASSERT_EQ(static_cast<int>(sizeof(int)), length);
60 value_ = *static_cast<const int*>(blob);
61 is_initialized_ = true;
62 g_parse_count++;
65 int ByteSize() const { return is_initialized() ? sizeof(int) : 0; }
67 static const TestValue& default_instance() {
68 static TestValue default_instance;
69 default_instance.is_default_ = true;
70 return default_instance;
73 private:
74 static int g_copy_count;
75 static int g_parse_count;
76 static int g_delete_count;
78 int value_;
79 bool is_initialized_;
80 bool is_default_;
82 DISALLOW_COPY_AND_ASSIGN(TestValue);
85 // Static initializers.
86 int TestValue::g_copy_count = 0;
87 int TestValue::g_parse_count = 0;
88 int TestValue::g_delete_count = 0;
90 } // namespace
92 typedef ProtoValuePtr<TestValue> TestPtr;
94 class ProtoValuePtrTest : public testing::Test {
95 public:
96 void SetUp() override { TestValue::ResetCounters(); }
98 static bool WrappedValuesAreShared(const TestPtr& ptr1, const TestPtr& ptr2) {
99 const TestValue& wrapped_value_1 = ptr1.value();
100 const TestValue& wrapped_value_2 = ptr2.value();
101 // Compare addresses.
102 return &wrapped_value_1 == &wrapped_value_2;
106 TEST_F(ProtoValuePtrTest, BasicTest) {
107 // Basic assignment and default value.
108 TestValue t1(1);
110 TestPtr ptr1;
111 EXPECT_TRUE(ptr1->is_default());
113 ptr1.set_value(t1);
114 EXPECT_FALSE(ptr1->is_default());
115 EXPECT_EQ(1, ptr1->value());
118 EXPECT_EQ(1, TestValue::copy_count());
119 EXPECT_EQ(1, TestValue::delete_count());
122 TEST_F(ProtoValuePtrTest, SharingTest) {
123 // Sharing between two pointers.
124 TestValue empty;
125 TestValue t2(2);
126 TestValue t3(3);
128 TestPtr ptr2;
129 TestPtr ptr3;
131 EXPECT_TRUE(ptr2->is_default());
132 EXPECT_TRUE(ptr3->is_default());
133 EXPECT_EQ(0, TestValue::copy_count());
134 EXPECT_EQ(0, TestValue::delete_count());
136 ptr2.set_value(t2);
137 EXPECT_EQ(1, TestValue::copy_count());
138 EXPECT_EQ(0, TestValue::delete_count());
140 ptr3 = ptr2;
141 // Both |ptr2| and |ptr3| now share the same value "2".
142 // No additional copies expected.
143 EXPECT_EQ(1, TestValue::copy_count());
144 EXPECT_EQ(0, TestValue::delete_count());
145 EXPECT_FALSE(ptr3->is_default());
146 EXPECT_EQ(2, ptr3->value());
147 EXPECT_TRUE(WrappedValuesAreShared(ptr2, ptr3));
149 // Stop sharing - |ptr2| is "3" and |ptr3| is still "2".
150 ptr2.set_value(t3);
151 EXPECT_FALSE(WrappedValuesAreShared(ptr2, ptr3));
152 EXPECT_EQ(3, ptr2->value());
153 EXPECT_EQ(2, ptr3->value());
154 // No extra copies or deletions expected.
155 EXPECT_EQ(2, TestValue::copy_count());
156 EXPECT_EQ(0, TestValue::delete_count());
158 // |ptr3| still has the old value.
159 EXPECT_EQ(2, ptr3->value());
161 // Share again. Both values are "3".
162 ptr3 = ptr2;
163 EXPECT_EQ(3, ptr3->value());
164 // This should have resulted in deleting the wrapper for the value "2".
165 EXPECT_EQ(1, TestValue::delete_count());
166 // No extra copies expected.
167 EXPECT_EQ(2, TestValue::copy_count());
169 // Set default value to one of the pointers.
170 ptr2.set_value(empty);
171 EXPECT_TRUE(ptr2->is_default());
172 // The other one is still intact.
173 EXPECT_FALSE(ptr3->is_default());
174 EXPECT_EQ(3, ptr3->value());
175 // No extra copies or deletions expected.
176 EXPECT_EQ(1, TestValue::delete_count());
177 EXPECT_EQ(2, TestValue::copy_count());
179 // Copy the default value between the pointers.
180 ptr3 = ptr2;
181 EXPECT_TRUE(ptr3->is_default());
182 // The wrapper for "3" is now deleted.
183 EXPECT_EQ(2, TestValue::delete_count());
186 // No extra deletions expected upon leaving the scope.
187 EXPECT_EQ(2, TestValue::delete_count());
190 TEST_F(ProtoValuePtrTest, ParsingTest) {
191 int v1 = 21;
194 TestPtr ptr1;
196 ptr1.load(&v1, sizeof(int));
198 EXPECT_EQ(1, TestValue::parse_count());
199 EXPECT_EQ(0, TestValue::copy_count());
201 EXPECT_EQ(v1, ptr1->value());
204 EXPECT_EQ(1, TestValue::delete_count());
207 } // namespace syncable
208 } // namespace syncer