blob: 69e16be95e3cbe365ea4c5f8d4ac90b1af977401 [file] [log] [blame]
mukesh agrawal292dc0f2012-01-26 18:02:46 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone27bf1032011-06-28 17:02:01 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/property_accessor.h"
6
7#include <limits>
8#include <map>
9#include <string>
10#include <vector>
11
12#include <base/basictypes.h>
Paul Stewarta61593e2012-03-23 13:06:21 -070013#include <base/stl_util.h>
Chris Masone27bf1032011-06-28 17:02:01 -070014#include <gtest/gtest.h>
15#include <gmock/gmock.h>
16
mukesh agrawalffa3d042011-10-06 15:26:10 -070017#include "shill/error.h"
18
Chris Masone27bf1032011-06-28 17:02:01 -070019using std::map;
20using std::string;
21using std::vector;
22using ::testing::Return;
23using ::testing::Test;
24
25namespace shill {
26
27TEST(PropertyAccessorTest, SignedIntCorrectness) {
28 int32 int_store = 0;
29 {
mukesh agrawalffa3d042011-10-06 15:26:10 -070030 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -080031 int32 orig_value = int_store;
Chris Masone27bf1032011-06-28 17:02:01 -070032 Int32Accessor accessor(new PropertyAccessor<int32>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -080033 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070034
35 int32 expected_int32 = 127;
mukesh agrawalbebf1b82013-04-23 15:06:33 -070036 EXPECT_TRUE(accessor->Set(expected_int32, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -080037 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080038 EXPECT_EQ(expected_int32, accessor->Get(&error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -070039 // Resetting to the same value should return false, but without
40 // an error.
41 EXPECT_FALSE(accessor->Set(expected_int32, &error));
42 EXPECT_TRUE(error.IsSuccess());
Chris Masone27bf1032011-06-28 17:02:01 -070043
mukesh agrawal292dc0f2012-01-26 18:02:46 -080044 accessor->Clear(&error);
45 EXPECT_TRUE(error.IsSuccess());
46 EXPECT_EQ(orig_value, accessor->Get(&error));
47
Chris Masone27bf1032011-06-28 17:02:01 -070048 int_store = std::numeric_limits<int32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -080049 EXPECT_EQ(std::numeric_limits<int32>::max(), accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070050 }
51 {
mukesh agrawalffa3d042011-10-06 15:26:10 -070052 Error error;
Chris Masone27bf1032011-06-28 17:02:01 -070053 Int32Accessor accessor(new ConstPropertyAccessor<int32>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -080054 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070055
56 int32 expected_int32 = 127;
mukesh agrawalffa3d042011-10-06 15:26:10 -070057 accessor->Set(expected_int32, &error);
58 ASSERT_FALSE(error.IsSuccess());
59 EXPECT_EQ(Error::kInvalidArguments, error.type());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080060 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -070061
62 int_store = std::numeric_limits<int32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -080063 EXPECT_EQ(std::numeric_limits<int32>::max(), accessor->Get(&error));
64 }
65 {
66 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -080067 Int32Accessor accessor(new ConstPropertyAccessor<int32>(&int_store));
68 accessor->Clear(&error);
69 ASSERT_FALSE(error.IsSuccess());
70 }
71 {
72 Error error;
Gaurav Shah1b7a6162011-11-09 11:41:01 -080073 Int32Accessor accessor(new WriteOnlyPropertyAccessor<int32>(&int_store));
74 accessor->Get(&error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -080075 EXPECT_TRUE(error.IsFailure());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080076 EXPECT_EQ(Error::kPermissionDenied, error.type());
77 }
78 {
79 Error error;
80 int32 expected_int32 = 127;
mukesh agrawal6b883fe2012-01-30 16:38:15 -080081 WriteOnlyPropertyAccessor<int32> accessor(&int_store);
mukesh agrawalbebf1b82013-04-23 15:06:33 -070082 EXPECT_TRUE(accessor.Set(expected_int32, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -080083 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -080084 EXPECT_EQ(expected_int32, *accessor.property_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -070085 // Resetting to the same value should return false, but without
86 // an error.
87 EXPECT_FALSE(accessor.Set(expected_int32, &error));
88 EXPECT_TRUE(error.IsSuccess());
89 // As a write-only, the value can't be read.
Gaurav Shah1b7a6162011-11-09 11:41:01 -080090 EXPECT_EQ(int32(), accessor.Get(&error));
91 ASSERT_FALSE(error.IsSuccess());
92
mukesh agrawal6b883fe2012-01-30 16:38:15 -080093 int_store = std::numeric_limits<int32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -080094 EXPECT_EQ(std::numeric_limits<int32>::max(), *accessor.property_);
Chris Masone27bf1032011-06-28 17:02:01 -070095 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -080096 {
97 Error error;
98 int32 orig_value = int_store = 0;
99 WriteOnlyPropertyAccessor<int32> accessor(&int_store);
100
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700101 EXPECT_TRUE(accessor.Set(127, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800102 accessor.Clear(&error);
103 EXPECT_TRUE(error.IsSuccess());
104 EXPECT_EQ(orig_value, *accessor.property_);
105 }
Chris Masone27bf1032011-06-28 17:02:01 -0700106}
107
108TEST(PropertyAccessorTest, UnsignedIntCorrectness) {
109 uint32 int_store = 0;
110 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700111 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800112 uint32 orig_value = int_store;
Chris Masone27bf1032011-06-28 17:02:01 -0700113 Uint32Accessor accessor(new PropertyAccessor<uint32>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800114 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700115
116 uint32 expected_uint32 = 127;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700117 EXPECT_TRUE(accessor->Set(expected_uint32, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800118 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800119 EXPECT_EQ(expected_uint32, accessor->Get(&error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700120 // Resetting to the same value should return false, but without
121 // an error.
122 EXPECT_FALSE(accessor->Set(expected_uint32, &error));
123 EXPECT_TRUE(error.IsSuccess());
Chris Masone27bf1032011-06-28 17:02:01 -0700124
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800125 accessor->Clear(&error);
126 EXPECT_TRUE(error.IsSuccess());
127 EXPECT_EQ(orig_value, accessor->Get(&error));
128
Chris Masone27bf1032011-06-28 17:02:01 -0700129 int_store = std::numeric_limits<uint32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800130 EXPECT_EQ(std::numeric_limits<uint32>::max(), accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700131 }
132 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700133 Error error;
Chris Masone27bf1032011-06-28 17:02:01 -0700134 Uint32Accessor accessor(new ConstPropertyAccessor<uint32>(&int_store));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800135 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700136
137 uint32 expected_uint32 = 127;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700138 EXPECT_FALSE(accessor->Set(expected_uint32, &error));
mukesh agrawalffa3d042011-10-06 15:26:10 -0700139 ASSERT_FALSE(error.IsSuccess());
140 EXPECT_EQ(Error::kInvalidArguments, error.type());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800141 EXPECT_EQ(int_store, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700142
143 int_store = std::numeric_limits<uint32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800144 EXPECT_EQ(std::numeric_limits<uint32>::max(), accessor->Get(&error));
145 }
146 {
147 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800148 Uint32Accessor accessor(new ConstPropertyAccessor<uint32>(&int_store));
149 accessor->Clear(&error);
150 ASSERT_FALSE(error.IsSuccess());
151 }
152 {
153 Error error;
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800154 Uint32Accessor accessor(new WriteOnlyPropertyAccessor<uint32>(&int_store));
155 accessor->Get(&error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800156 EXPECT_TRUE(error.IsFailure());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800157 EXPECT_EQ(Error::kPermissionDenied, error.type());
158 }
159 {
160 Error error;
161 uint32 expected_uint32 = 127;
mukesh agrawal6b883fe2012-01-30 16:38:15 -0800162 WriteOnlyPropertyAccessor<uint32> accessor(&int_store);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700163 EXPECT_TRUE(accessor.Set(expected_uint32, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800164 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800165 EXPECT_EQ(expected_uint32, *accessor.property_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700166 // Resetting to the same value should return false, but without
167 // an error.
168 EXPECT_FALSE(accessor.Set(expected_uint32, &error));
169 EXPECT_TRUE(error.IsSuccess());
170 // As a write-only, the value can't be read.
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800171 EXPECT_EQ(uint32(), accessor.Get(&error));
172 ASSERT_FALSE(error.IsSuccess());
173
mukesh agrawal6b883fe2012-01-30 16:38:15 -0800174 int_store = std::numeric_limits<uint32>::max();
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800175 EXPECT_EQ(std::numeric_limits<uint32>::max(), *accessor.property_);
Chris Masone27bf1032011-06-28 17:02:01 -0700176 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800177 {
178 Error error;
179 uint32 orig_value = int_store = 0;
180 WriteOnlyPropertyAccessor<uint32> accessor(&int_store);
181
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700182 EXPECT_TRUE(accessor.Set(127, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800183 accessor.Clear(&error);
184 EXPECT_TRUE(error.IsSuccess());
185 EXPECT_EQ(orig_value, *accessor.property_);
186 }
Chris Masone27bf1032011-06-28 17:02:01 -0700187}
188
189TEST(PropertyAccessorTest, StringCorrectness) {
190 string storage;
191 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700192 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800193 string orig_value = storage;
Chris Masone27bf1032011-06-28 17:02:01 -0700194 StringAccessor accessor(new PropertyAccessor<string>(&storage));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800195 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700196
197 string expected_string("what");
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700198 EXPECT_TRUE(accessor->Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800199 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800200 EXPECT_EQ(expected_string, accessor->Get(&error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700201 // Resetting to the same value should return false, but without
202 // an error.
203 EXPECT_FALSE(accessor->Set(expected_string, &error));
204 EXPECT_TRUE(error.IsSuccess());
Chris Masone27bf1032011-06-28 17:02:01 -0700205
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800206 accessor->Clear(&error);
207 EXPECT_TRUE(error.IsSuccess());
208 EXPECT_EQ(orig_value, accessor->Get(&error));
209
Chris Masone27bf1032011-06-28 17:02:01 -0700210 storage = "nooooo";
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800211 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700212 }
213 {
mukesh agrawalffa3d042011-10-06 15:26:10 -0700214 Error error;
Chris Masone27bf1032011-06-28 17:02:01 -0700215 StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800216 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700217
218 string expected_string("what");
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700219 EXPECT_FALSE(accessor->Set(expected_string, &error));
mukesh agrawalffa3d042011-10-06 15:26:10 -0700220 ASSERT_FALSE(error.IsSuccess());
221 EXPECT_EQ(Error::kInvalidArguments, error.type());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800222 EXPECT_EQ(storage, accessor->Get(&error));
Chris Masone27bf1032011-06-28 17:02:01 -0700223
224 storage = "nooooo";
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800225 EXPECT_EQ(storage, accessor->Get(&error));
226 }
227 {
228 Error error;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800229 StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
230 accessor->Clear(&error);
231 ASSERT_FALSE(error.IsSuccess());
232 }
233 {
234 Error error;
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800235 StringAccessor accessor(new WriteOnlyPropertyAccessor<string>(&storage));
236 accessor->Get(&error);
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800237 EXPECT_TRUE(error.IsFailure());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800238 EXPECT_EQ(Error::kPermissionDenied, error.type());
239 }
240 {
241 Error error;
242 string expected_string = "what";
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700243 WriteOnlyPropertyAccessor<string> accessor(&storage);
244 EXPECT_TRUE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800245 EXPECT_TRUE(error.IsSuccess());
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800246 EXPECT_EQ(expected_string, *accessor.property_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700247 // Resetting to the same value should return false, but without
248 // an error.
249 EXPECT_FALSE(accessor.Set(expected_string, &error));
250 EXPECT_TRUE(error.IsSuccess());
251 // As a write-only, the value can't be read.
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800252 EXPECT_EQ(string(), accessor.Get(&error));
253 ASSERT_FALSE(error.IsSuccess());
254
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700255 storage = "nooooo";
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800256 EXPECT_EQ("nooooo", *accessor.property_);
Chris Masone27bf1032011-06-28 17:02:01 -0700257 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800258 {
259 Error error;
260 string orig_value = storage = "original value";
261 WriteOnlyPropertyAccessor<string> accessor(&storage);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700262 EXPECT_TRUE(accessor.Set("new value", &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800263 accessor.Clear(&error);
264 EXPECT_TRUE(error.IsSuccess());
265 EXPECT_EQ(orig_value, *accessor.property_);
266 }
267}
268
269class StringWrapper {
270 public:
271 string Get(Error */*error*/) {
272 return value_;
273 }
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700274 bool Set(const string &value, Error */*error*/) {
275 if (value_ == value) {
276 return false;
277 }
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800278 value_ = value;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700279 return true;
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800280 }
281 void Clear(Error */*error*/) {
282 value_.clear();
283 }
284
285 string value_;
286};
287
288TEST(PropertyAccessorTest, CustomAccessorCorrectness) {
289 StringWrapper wrapper;
290 {
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700291 // Custom accessor: read, write, write-same, clear, read-updated.
292 // Together, write and write-same verify that the CustomAccessor
293 // template passes through the value from the called function.
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800294 Error error;
295 const string orig_value = wrapper.value_ = "original value";
296 CustomAccessor<StringWrapper, string> accessor(&wrapper,
297 &StringWrapper::Get,
298 &StringWrapper::Set);
299 EXPECT_EQ(orig_value, accessor.Get(&error));
300 EXPECT_TRUE(error.IsSuccess());
301
302 const string expected_string = "new value";
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700303 EXPECT_TRUE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800304 EXPECT_TRUE(error.IsSuccess());
305 EXPECT_EQ(expected_string, accessor.Get(&error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700306 // Set to same value.
307 EXPECT_FALSE(accessor.Set(expected_string, &error));
308 EXPECT_TRUE(error.IsSuccess());
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800309
310 accessor.Clear(&error);
311 EXPECT_TRUE(error.IsSuccess());
312 EXPECT_EQ(orig_value, accessor.Get(&error));
313
314 wrapper.value_ = "nooooo";
315 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
316 }
317 {
318 // Custom read-only accessor: read, write, read-updated.
319 Error error;
320 CustomAccessor<StringWrapper, string> accessor(&wrapper,
321 &StringWrapper::Get,
322 NULL);
323 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
324
325 const string expected_string = "what";
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700326 EXPECT_FALSE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800327 ASSERT_FALSE(error.IsSuccess());
328 EXPECT_EQ(Error::kInvalidArguments, error.type());
329 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
330
331 wrapper.value_ = "nooooo";
332 EXPECT_EQ(wrapper.value_, accessor.Get(&error));
333 }
334 {
335 // Custom read-only accessor: clear.
336 Error error;
337 CustomAccessor<StringWrapper, string> accessor(&wrapper,
338 &StringWrapper::Get,
339 NULL);
340 accessor.Clear(&error);
341 ASSERT_FALSE(error.IsSuccess());
342 }
343}
344
345TEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithDefault) {
346 StringWrapper wrapper;
347 {
348 // Test reading.
349 Error error;
350 const string default_value = "default value";
351 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
352 &wrapper, &StringWrapper::Set, NULL, &default_value);
353 wrapper.value_ = "can't read this";
354 EXPECT_EQ(string(), accessor.Get(&error));
355 EXPECT_TRUE(error.IsFailure());
356 EXPECT_EQ(Error::kPermissionDenied, error.type());
357 }
358 {
359 // Test writing.
360 Error error;
361 const string default_value = "default value";
362 const string expected_string = "what";
363 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
364 &wrapper, &StringWrapper::Set, NULL, &default_value);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700365 EXPECT_TRUE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800366 EXPECT_TRUE(error.IsSuccess());
367 EXPECT_EQ(expected_string, wrapper.value_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700368 // Set to same value. With the above, this verifies that the
369 // CustomWriteOnlyAccessor template passes through the return
370 // value.
371 EXPECT_FALSE(accessor.Set(expected_string, &error));
372 EXPECT_TRUE(error.IsSuccess());
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800373 }
374 {
375 // Test clearing.
376 Error error;
377 const string default_value = "default value";
378 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
379 &wrapper, &StringWrapper::Set, NULL, &default_value);
380 accessor.Set("new value", &error);
381 EXPECT_EQ("new value", wrapper.value_);
382 accessor.Clear(&error);
383 EXPECT_TRUE(error.IsSuccess());
384 EXPECT_EQ(default_value, wrapper.value_);
385 }
386}
387
388TEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithClear) {
389 StringWrapper wrapper;
390 {
391 // Test reading.
392 Error error;
393 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
394 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, NULL);
395 wrapper.value_ = "can't read this";
396 EXPECT_EQ(string(), accessor.Get(&error));
397 EXPECT_TRUE(error.IsFailure());
398 EXPECT_EQ(Error::kPermissionDenied, error.type());
399 }
400 {
401 // Test writing.
402 Error error;
403 const string expected_string = "what";
404 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
405 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, NULL);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700406 EXPECT_TRUE(accessor.Set(expected_string, &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800407 EXPECT_TRUE(error.IsSuccess());
408 EXPECT_EQ(expected_string, wrapper.value_);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700409 // Set to same value. With the above, this verifies that the
410 // CustomWriteOnlyAccessor template passes through the return
411 // value.
412 EXPECT_FALSE(accessor.Set(expected_string, &error));
413 EXPECT_TRUE(error.IsSuccess());
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800414 }
415 {
416 // Test clearing.
417 Error error;
418 CustomWriteOnlyAccessor<StringWrapper, string> accessor(
419 &wrapper, &StringWrapper::Set, &StringWrapper::Clear, NULL);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700420 EXPECT_TRUE(accessor.Set("new value", &error));
mukesh agrawal292dc0f2012-01-26 18:02:46 -0800421 EXPECT_EQ("new value", wrapper.value_);
422 accessor.Clear(&error);
423 EXPECT_TRUE(error.IsSuccess());
424 EXPECT_EQ("", wrapper.value_);
425 }
Chris Masone27bf1032011-06-28 17:02:01 -0700426}
427
Paul Stewarta61593e2012-03-23 13:06:21 -0700428class StringMapWrapper {
429 public:
430 void Clear(const string &key, Error */*error*/) {
431 value_.erase(key);
432 }
433 string Get(const string &key, Error */*error*/) {
434 EXPECT_TRUE(ContainsKey(value_, key));
435 return value_[key];
436 }
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700437 bool Set(const string &key, const string &value, Error */*error*/) {
438 if (value_[key] == value) {
439 return false;
440 }
Paul Stewarta61593e2012-03-23 13:06:21 -0700441 value_[key] = value;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700442 return true;
Paul Stewarta61593e2012-03-23 13:06:21 -0700443 }
444
445 map<string,string> value_;
446};
447
448TEST(PropertyAccessorTest, CustomMappedAccessor) {
449 const string kKey = "entry_key";
450 const string kValue = "entry_value";
451 {
452 // Test reading.
453 StringMapWrapper wrapper;
454 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
455 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
456 &StringMapWrapper::Set, kKey);
457 wrapper.value_[kKey] = kValue;
458 Error error;
459 EXPECT_EQ(kValue, accessor.Get(&error));
460 EXPECT_TRUE(error.IsSuccess());
461 }
462 {
463 // Test writing.
464 StringMapWrapper wrapper;
465 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
466 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
467 &StringMapWrapper::Set, kKey);
468 Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700469 EXPECT_TRUE(accessor.Set(kValue, &error));
Paul Stewarta61593e2012-03-23 13:06:21 -0700470 EXPECT_TRUE(error.IsSuccess());
471 EXPECT_EQ(kValue, wrapper.value_[kKey]);
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700472 // Set to same value. With the above, this verifies that the
473 // CustomMappedAccessor template passes through the return
474 // value.
475 EXPECT_FALSE(accessor.Set(kValue, &error));
476 EXPECT_TRUE(error.IsSuccess());
Paul Stewarta61593e2012-03-23 13:06:21 -0700477 }
478 {
479 // Test clearing.
480 StringMapWrapper wrapper;
481 CustomMappedAccessor<StringMapWrapper, string, string> accessor(
482 &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
483 &StringMapWrapper::Set, kKey);
484 wrapper.value_[kKey] = kValue;
485 Error error;
486 accessor.Clear(&error);
487 EXPECT_TRUE(error.IsSuccess());
488 EXPECT_FALSE(ContainsKey(wrapper.value_, kKey));
489 }
490}
491
Chris Masone27bf1032011-06-28 17:02:01 -0700492} // namespace shill