1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project
3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License");
5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License.
6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at
7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//      http://www.apache.org/licenses/LICENSE-2.0
9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software
11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS,
12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and
14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License.
15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu//
1627bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
1727bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone#include "shill/property_accessor.h"
1827bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
1927bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone#include <limits>
2027bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone#include <map>
2127bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone#include <string>
2227bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone#include <vector>
2327bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
24a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart#include <base/stl_util.h>
2527bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone#include <gtest/gtest.h>
2627bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone#include <gmock/gmock.h>
2727bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
28ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal#include "shill/error.h"
29ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal
3027bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masoneusing std::map;
3127bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masoneusing std::string;
3227bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masoneusing std::vector;
3327bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masoneusing ::testing::Return;
3427bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masoneusing ::testing::Test;
3527bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
3627bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masonenamespace shill {
3727bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
3827bf1036f4468bd4cd235fe385b7eb460f49c9faChris MasoneTEST(PropertyAccessorTest, SignedIntCorrectness) {
397fab89734d88724a288e96a9996b15548c5294c7Ben Chan  int32_t int_store = 0;
4027bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  {
41ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    Error error;
427fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int32_t orig_value = int_store;
437fab89734d88724a288e96a9996b15548c5294c7Ben Chan    Int32Accessor accessor(new PropertyAccessor<int32_t>(&int_store));
441b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(int_store, accessor->Get(&error));
4527bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
467fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int32_t expected_int32 = 127;
47bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor->Set(expected_int32, &error));
48292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
491b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(expected_int32, accessor->Get(&error));
50bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Resetting to the same value should return false, but without
51bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // an error.
52bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor->Set(expected_int32, &error));
53bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
5427bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
55292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor->Clear(&error);
56292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
57292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(orig_value, accessor->Get(&error));
58292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
597fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int_store = std::numeric_limits<int32_t>::max();
607fab89734d88724a288e96a9996b15548c5294c7Ben Chan    EXPECT_EQ(std::numeric_limits<int32_t>::max(), accessor->Get(&error));
6127bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  }
6227bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  {
63ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    Error error;
647fab89734d88724a288e96a9996b15548c5294c7Ben Chan    Int32Accessor accessor(new ConstPropertyAccessor<int32_t>(&int_store));
651b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(int_store, accessor->Get(&error));
6627bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
677fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int32_t expected_int32 = 127;
68ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    accessor->Set(expected_int32, &error);
69ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    ASSERT_FALSE(error.IsSuccess());
70ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    EXPECT_EQ(Error::kInvalidArguments, error.type());
711b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(int_store, accessor->Get(&error));
7227bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
737fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int_store = std::numeric_limits<int32_t>::max();
747fab89734d88724a288e96a9996b15548c5294c7Ben Chan    EXPECT_EQ(std::numeric_limits<int32_t>::max(), accessor->Get(&error));
751b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  }
761b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  {
771b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    Error error;
787fab89734d88724a288e96a9996b15548c5294c7Ben Chan    Int32Accessor accessor(new ConstPropertyAccessor<int32_t>(&int_store));
79292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor->Clear(&error);
80292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    ASSERT_FALSE(error.IsSuccess());
81292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
82292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
83292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
847fab89734d88724a288e96a9996b15548c5294c7Ben Chan    Int32Accessor accessor(new WriteOnlyPropertyAccessor<int32_t>(&int_store));
851b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    accessor->Get(&error);
86292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsFailure());
871b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(Error::kPermissionDenied, error.type());
881b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  }
891b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  {
901b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    Error error;
917fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int32_t expected_int32 = 127;
927fab89734d88724a288e96a9996b15548c5294c7Ben Chan    WriteOnlyPropertyAccessor<int32_t> accessor(&int_store);
93bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set(expected_int32, &error));
94292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
951b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(expected_int32, *accessor.property_);
96bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Resetting to the same value should return false, but without
97bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // an error.
98bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor.Set(expected_int32, &error));
99bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
100bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // As a write-only, the value can't be read.
1017fab89734d88724a288e96a9996b15548c5294c7Ben Chan    EXPECT_EQ(int32_t(), accessor.Get(&error));
1021b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    ASSERT_FALSE(error.IsSuccess());
1031b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah
1047fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int_store = std::numeric_limits<int32_t>::max();
1057fab89734d88724a288e96a9996b15548c5294c7Ben Chan    EXPECT_EQ(std::numeric_limits<int32_t>::max(), *accessor.property_);
10627bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  }
107292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
108292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
1097fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int32_t orig_value = int_store = 0;
1107fab89734d88724a288e96a9996b15548c5294c7Ben Chan    WriteOnlyPropertyAccessor<int32_t> accessor(&int_store);
111292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
112bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set(127, &error));
113292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor.Clear(&error);
114292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
115292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(orig_value, *accessor.property_);
116292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
11727bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone}
11827bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
11927bf1036f4468bd4cd235fe385b7eb460f49c9faChris MasoneTEST(PropertyAccessorTest, UnsignedIntCorrectness) {
1207fab89734d88724a288e96a9996b15548c5294c7Ben Chan  uint32_t int_store = 0;
12127bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  {
122ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    Error error;
1237fab89734d88724a288e96a9996b15548c5294c7Ben Chan    uint32_t orig_value = int_store;
1247fab89734d88724a288e96a9996b15548c5294c7Ben Chan    Uint32Accessor accessor(new PropertyAccessor<uint32_t>(&int_store));
1251b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(int_store, accessor->Get(&error));
12627bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
1277fab89734d88724a288e96a9996b15548c5294c7Ben Chan    uint32_t expected_uint32 = 127;
128bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor->Set(expected_uint32, &error));
129292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
1301b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(expected_uint32, accessor->Get(&error));
131bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Resetting to the same value should return false, but without
132bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // an error.
133bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor->Set(expected_uint32, &error));
134bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
13527bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
136292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor->Clear(&error);
137292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
138292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(orig_value, accessor->Get(&error));
139292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
1407fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int_store = std::numeric_limits<uint32_t>::max();
1417fab89734d88724a288e96a9996b15548c5294c7Ben Chan    EXPECT_EQ(std::numeric_limits<uint32_t>::max(), accessor->Get(&error));
14227bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  }
14327bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  {
144ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    Error error;
1457fab89734d88724a288e96a9996b15548c5294c7Ben Chan    Uint32Accessor accessor(new ConstPropertyAccessor<uint32_t>(&int_store));
1461b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(int_store, accessor->Get(&error));
14727bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
1487fab89734d88724a288e96a9996b15548c5294c7Ben Chan    uint32_t expected_uint32 = 127;
149bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor->Set(expected_uint32, &error));
150ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    ASSERT_FALSE(error.IsSuccess());
151ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    EXPECT_EQ(Error::kInvalidArguments, error.type());
1521b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(int_store, accessor->Get(&error));
15327bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
1547fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int_store = std::numeric_limits<uint32_t>::max();
1557fab89734d88724a288e96a9996b15548c5294c7Ben Chan    EXPECT_EQ(std::numeric_limits<uint32_t>::max(), accessor->Get(&error));
1561b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  }
1571b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  {
1581b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    Error error;
1597fab89734d88724a288e96a9996b15548c5294c7Ben Chan    Uint32Accessor accessor(new ConstPropertyAccessor<uint32_t>(&int_store));
160292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor->Clear(&error);
161292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    ASSERT_FALSE(error.IsSuccess());
162292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
163292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
164292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
1657fab89734d88724a288e96a9996b15548c5294c7Ben Chan    Uint32Accessor accessor(
1667fab89734d88724a288e96a9996b15548c5294c7Ben Chan        new WriteOnlyPropertyAccessor<uint32_t>(&int_store));
1671b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    accessor->Get(&error);
168292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsFailure());
1691b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(Error::kPermissionDenied, error.type());
1701b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  }
1711b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  {
1721b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    Error error;
1737fab89734d88724a288e96a9996b15548c5294c7Ben Chan    uint32_t expected_uint32 = 127;
1747fab89734d88724a288e96a9996b15548c5294c7Ben Chan    WriteOnlyPropertyAccessor<uint32_t> accessor(&int_store);
175bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set(expected_uint32, &error));
176292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
1771b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(expected_uint32, *accessor.property_);
178bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Resetting to the same value should return false, but without
179bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // an error.
180bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor.Set(expected_uint32, &error));
181bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
182bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // As a write-only, the value can't be read.
1837fab89734d88724a288e96a9996b15548c5294c7Ben Chan    EXPECT_EQ(uint32_t(), accessor.Get(&error));
1841b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    ASSERT_FALSE(error.IsSuccess());
1851b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah
1867fab89734d88724a288e96a9996b15548c5294c7Ben Chan    int_store = std::numeric_limits<uint32_t>::max();
1877fab89734d88724a288e96a9996b15548c5294c7Ben Chan    EXPECT_EQ(std::numeric_limits<uint32_t>::max(), *accessor.property_);
18827bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  }
189292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
190292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
1917fab89734d88724a288e96a9996b15548c5294c7Ben Chan    uint32_t orig_value = int_store = 0;
1927fab89734d88724a288e96a9996b15548c5294c7Ben Chan    WriteOnlyPropertyAccessor<uint32_t> accessor(&int_store);
193292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
194bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set(127, &error));
195292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor.Clear(&error);
196292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
197292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(orig_value, *accessor.property_);
198292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
19927bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone}
20027bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
20127bf1036f4468bd4cd235fe385b7eb460f49c9faChris MasoneTEST(PropertyAccessorTest, StringCorrectness) {
20227bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  string storage;
20327bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  {
204ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    Error error;
205292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    string orig_value = storage;
20627bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone    StringAccessor accessor(new PropertyAccessor<string>(&storage));
2071b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(storage, accessor->Get(&error));
20827bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
20927bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone    string expected_string("what");
210bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor->Set(expected_string, &error));
211292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
2121b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(expected_string, accessor->Get(&error));
213bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Resetting to the same value should return false, but without
214bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // an error.
215bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor->Set(expected_string, &error));
216bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
21727bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
218292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor->Clear(&error);
219292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
220292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(orig_value, accessor->Get(&error));
221292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
22227bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone    storage = "nooooo";
2231b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(storage, accessor->Get(&error));
22427bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  }
22527bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  {
226ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    Error error;
22727bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone    StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
2281b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(storage, accessor->Get(&error));
22927bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
23027bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone    string expected_string("what");
231bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor->Set(expected_string, &error));
232ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    ASSERT_FALSE(error.IsSuccess());
233ffa3d0433d419aa9251f3768a0090a27b6b1c434mukesh agrawal    EXPECT_EQ(Error::kInvalidArguments, error.type());
2341b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(storage, accessor->Get(&error));
23527bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
23627bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone    storage = "nooooo";
2371b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(storage, accessor->Get(&error));
2381b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  }
2391b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  {
2401b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    Error error;
241292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    StringAccessor accessor(new ConstPropertyAccessor<string>(&storage));
242292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor->Clear(&error);
243292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    ASSERT_FALSE(error.IsSuccess());
244292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
245292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
246292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
2471b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    StringAccessor accessor(new WriteOnlyPropertyAccessor<string>(&storage));
2481b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    accessor->Get(&error);
249292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsFailure());
2501b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(Error::kPermissionDenied, error.type());
2511b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  }
2521b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah  {
2531b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    Error error;
2541b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    string expected_string = "what";
255bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    WriteOnlyPropertyAccessor<string> accessor(&storage);
256bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set(expected_string, &error));
257292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
2581b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(expected_string, *accessor.property_);
259bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Resetting to the same value should return false, but without
260bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // an error.
261bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor.Set(expected_string, &error));
262bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
263bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // As a write-only, the value can't be read.
2641b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ(string(), accessor.Get(&error));
2651b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    ASSERT_FALSE(error.IsSuccess());
2661b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah
267bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    storage = "nooooo";
2681b7a616197af7ff753dbe7614a8e207b1e10ac1aGaurav Shah    EXPECT_EQ("nooooo", *accessor.property_);
26927bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone  }
270292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
271292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
272292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    string orig_value = storage = "original value";
273292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    WriteOnlyPropertyAccessor<string> accessor(&storage);
274bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set("new value", &error));
275292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor.Clear(&error);
276292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
277292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(orig_value, *accessor.property_);
278292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
279292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal}
280292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
2811ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor DodonTEST(PropertyAccessorTest, ByteArrayCorrectness) {
2821ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  ByteArray byteArray;
2831ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  {
2841ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    Error error;
2851ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ByteArray orig_byteArray = byteArray;
2861ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ByteArrayAccessor accessor(new PropertyAccessor<ByteArray>(&byteArray));
2871ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(byteArray, accessor->Get(&error));
2881ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
2891ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ByteArray expected_byteArray({ 0x01, 0x7F, 0x80, 0xFF });
2901ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(accessor->Set(expected_byteArray, &error));
2911ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(error.IsSuccess());
2921ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(expected_byteArray, accessor->Get(&error));
2931ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
2941ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    // Resetting to the same value should return false, but without
2951ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    // an error.
2961ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_FALSE(accessor->Set(expected_byteArray, &error));
2971ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(error.IsSuccess());
2981ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
2991ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    accessor->Clear(&error);
3001ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(error.IsSuccess());
3011ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(orig_byteArray, accessor->Get(&error));
3021ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
3031ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    byteArray = ByteArray({ 0xFF, 0x7F, 0x80, 0x00 });
3041ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(byteArray, accessor->Get(&error));
3051ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  }
3061ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  {
3071ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    Error error;
3081ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ByteArrayAccessor accessor(new ConstPropertyAccessor<ByteArray>(&byteArray));
3091ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(byteArray, accessor->Get(&error));
3101ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
3111ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ByteArray expected_byteArray({ 0x01, 0x7F, 0x80, 0xFF });
3121ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_FALSE(accessor->Set(expected_byteArray, &error));
3131ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ASSERT_FALSE(error.IsSuccess());
3141ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(Error::kInvalidArguments, error.type());
3151ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(byteArray, accessor->Get(&error));
3161ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
3171ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    byteArray = ByteArray({ 0xFF, 0x7F, 0x80, 0x00 });
3181ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(byteArray, accessor->Get(&error));
3191ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  }
3201ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  {
3211ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    Error error;
3221ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ByteArrayAccessor accessor(new ConstPropertyAccessor<ByteArray>(&byteArray));
3231ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    accessor->Clear(&error);
3241ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ASSERT_FALSE(error.IsSuccess());
3251ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  }
3261ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  {
3271ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    Error error;
3281ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ByteArrayAccessor accessor(new WriteOnlyPropertyAccessor<ByteArray>(&byteArray));
3291ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    accessor->Get(&error);
3301ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(error.IsFailure());
3311ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(Error::kPermissionDenied, error.type());
3321ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  }
3331ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  {
3341ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    Error error;
3351ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ByteArray expected_byteArray({ 0x01, 0x7F, 0x80, 0xFF });
3361ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    WriteOnlyPropertyAccessor<ByteArray> accessor(&byteArray);
3371ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
3381ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(accessor.Set(expected_byteArray, &error));
3391ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(error.IsSuccess());
3401ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(expected_byteArray, *accessor.property_);
3411ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
3421ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    // Resetting to the same value should return false, but without
3431ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    // an error.
3441ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_FALSE(accessor.Set(expected_byteArray, &error));
3451ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(error.IsSuccess());
3461ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
3471ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    // As a write-only, the value can't be read.
3481ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(ByteArray(), accessor.Get(&error));
3491ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_FALSE(error.IsSuccess());
3501ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
3511ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    byteArray = ByteArray({ 0xFF, 0x7F, 0x80, 0x00 });
3521ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(ByteArray({ 0xFF, 0x7F, 0x80, 0x00 }), *accessor.property_);
3531ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  }
3541ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  {
3551ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    Error error;
3561ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    ByteArray orig_byteArray = byteArray = ByteArray({ 0x00, 0x7F, 0x80, 0xFF });
3571ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    WriteOnlyPropertyAccessor<ByteArray> accessor(&byteArray);
3581ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
3591ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(accessor.Set(ByteArray({ 0xFF, 0x7F, 0x80, 0x00 }), &error));
3601ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    accessor.Clear(&error);
3611ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_TRUE(error.IsSuccess());
3621ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon    EXPECT_EQ(orig_byteArray, *accessor.property_);
3631ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon  }
3641ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon}
3651ee315fe16a7e91f43f1b24f5f2c0a47b52e3455Victor Dodon
366292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawalclass StringWrapper {
367292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal public:
3683b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  string Get(Error* /*error*/) {
369292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    return value_;
370292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
3713b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  string ConstGet(Error* /*error*/) const {
3721cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    return value_;
3731cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  }
3743b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  bool Set(const string& value, Error* /*error*/) {
375bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    if (value_ == value) {
376bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal      return false;
377bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    }
378292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    value_ = value;
379bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    return true;
380292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
3813b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void Clear(Error* /*error*/) {
382292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    value_.clear();
383292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
384292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
385292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  string value_;
386292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal};
387292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
388292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawalTEST(PropertyAccessorTest, CustomAccessorCorrectness) {
389292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  StringWrapper wrapper;
390292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
391bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Custom accessor: read, write, write-same, clear, read-updated.
392bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Together, write and write-same verify that the CustomAccessor
393bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // template passes through the value from the called function.
394292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
395292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    const string orig_value = wrapper.value_ = "original value";
396292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    CustomAccessor<StringWrapper, string> accessor(&wrapper,
397292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal                                                   &StringWrapper::Get,
398292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal                                                   &StringWrapper::Set);
399292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(orig_value, accessor.Get(&error));
400292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
401292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
402292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    const string expected_string = "new value";
403bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set(expected_string, &error));
404292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
405292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(expected_string, accessor.Get(&error));
406bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Set to same value.
407bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor.Set(expected_string, &error));
408bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
409292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
410292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor.Clear(&error);
411292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
412292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(orig_value, accessor.Get(&error));
413292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
414292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    wrapper.value_ = "nooooo";
415292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(wrapper.value_, accessor.Get(&error));
416292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
417292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
418292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    // Custom read-only accessor: read, write, read-updated.
419292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
420292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    CustomAccessor<StringWrapper, string> accessor(&wrapper,
421292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal                                                   &StringWrapper::Get,
422cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan                                                   nullptr);
423292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(wrapper.value_, accessor.Get(&error));
424292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
425292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    const string expected_string = "what";
426bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor.Set(expected_string, &error));
427292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    ASSERT_FALSE(error.IsSuccess());
428292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(Error::kInvalidArguments, error.type());
429292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(wrapper.value_, accessor.Get(&error));
430292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
431292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    wrapper.value_ = "nooooo";
432292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(wrapper.value_, accessor.Get(&error));
433292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
434292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
435292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    // Custom read-only accessor: clear.
436292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
437292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    CustomAccessor<StringWrapper, string> accessor(&wrapper,
438292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal                                                   &StringWrapper::Get,
439cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan                                                   nullptr);
440292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor.Clear(&error);
441292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    ASSERT_FALSE(error.IsSuccess());
442292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
443985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart  {
444985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart    // Custom read-only accessor with custom clear method.
445985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart    Error error;
446985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart    CustomAccessor<StringWrapper, string> accessor(&wrapper,
447985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart                                                   &StringWrapper::Get,
448cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan                                                   nullptr,
449985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart                                                   &StringWrapper::Clear);
450985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart    wrapper.value_ = "empty this";
451985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart    accessor.Clear(&error);
452985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart    ASSERT_TRUE(error.IsSuccess());
453985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart    EXPECT_TRUE(wrapper.value_.empty());
454985d7d5d3c1ef2f00941b89f2b79963f23808489Paul Stewart  }
455292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal}
456292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
457292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawalTEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithDefault) {
458292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  StringWrapper wrapper;
459292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
460292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    // Test reading.
461292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
462292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    const string default_value = "default value";
463292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    CustomWriteOnlyAccessor<StringWrapper, string> accessor(
464cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        &wrapper, &StringWrapper::Set, nullptr, &default_value);
465292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    wrapper.value_ = "can't read this";
466292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(string(), accessor.Get(&error));
467292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsFailure());
468292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(Error::kPermissionDenied, error.type());
469292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
470292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
471292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    // Test writing.
472292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
473292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    const string default_value = "default value";
474292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    const string expected_string = "what";
475292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    CustomWriteOnlyAccessor<StringWrapper, string> accessor(
476cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        &wrapper, &StringWrapper::Set, nullptr, &default_value);
477bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set(expected_string, &error));
478292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
479292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(expected_string, wrapper.value_);
480bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Set to same value. With the above, this verifies that the
481bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // CustomWriteOnlyAccessor template passes through the return
482bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // value.
483bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor.Set(expected_string, &error));
484bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
485292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
486292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
487292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    // Test clearing.
488292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
489292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    const string default_value = "default value";
490292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    CustomWriteOnlyAccessor<StringWrapper, string> accessor(
491cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        &wrapper, &StringWrapper::Set, nullptr, &default_value);
492292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor.Set("new value", &error);
493292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ("new value", wrapper.value_);
494292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor.Clear(&error);
495292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
496292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(default_value, wrapper.value_);
497292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
498292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal}
499292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal
500292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawalTEST(PropertyAccessorTest, CustomWriteOnlyAccessorWithClear) {
501292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  StringWrapper wrapper;
502292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
503292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    // Test reading.
504292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
505292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    CustomWriteOnlyAccessor<StringWrapper, string> accessor(
506cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        &wrapper, &StringWrapper::Set, &StringWrapper::Clear, nullptr);
507292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    wrapper.value_ = "can't read this";
508292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(string(), accessor.Get(&error));
509292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsFailure());
510292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(Error::kPermissionDenied, error.type());
511292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
512292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
513292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    // Test writing.
514292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
515292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    const string expected_string = "what";
516292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    CustomWriteOnlyAccessor<StringWrapper, string> accessor(
517cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        &wrapper, &StringWrapper::Set, &StringWrapper::Clear, nullptr);
518bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set(expected_string, &error));
519292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
520292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ(expected_string, wrapper.value_);
521bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Set to same value. With the above, this verifies that the
522bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // CustomWriteOnlyAccessor template passes through the return
523bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // value.
524bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor.Set(expected_string, &error));
525bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
526292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
527292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  {
528292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    // Test clearing.
529292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    Error error;
530292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    CustomWriteOnlyAccessor<StringWrapper, string> accessor(
531cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan        &wrapper, &StringWrapper::Set, &StringWrapper::Clear, nullptr);
532bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set("new value", &error));
533292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ("new value", wrapper.value_);
534292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    accessor.Clear(&error);
535292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
536292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal    EXPECT_EQ("", wrapper.value_);
537292dc0f18ce6ba7ea1419efc4d8ef909712bb7c2mukesh agrawal  }
53827bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone}
53927bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone
5401cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul StewartTEST(PropertyAccessorTest, CustomReadOnlyAccessor) {
5411cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  StringWrapper wrapper;
5421cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  CustomReadOnlyAccessor<StringWrapper, string> accessor(
5431cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart      &wrapper, &StringWrapper::ConstGet);
5441cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  const string orig_value = wrapper.value_ = "original value";
5451cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  {
5461cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    // Test reading.
5471cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    Error error;
5481cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_EQ(orig_value, accessor.Get(&error));
5491cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_TRUE(error.IsSuccess());
5501cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  }
5511cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  {
5521cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    // Test writing.
5531cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    Error error;
5541cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_FALSE(accessor.Set("new value", &error));
5551cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_EQ(Error::kInvalidArguments, error.type());
5561cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_EQ(orig_value, accessor.Get(&error));
5571cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  }
5581cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  {
5591cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    // Test writing original value -- this also fails.
5601cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    Error error;
5611cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_FALSE(accessor.Set(orig_value, &error));
5621cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_EQ(Error::kInvalidArguments, error.type());
5631cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_EQ(orig_value, accessor.Get(&error));
5641cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  }
5651cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  {
5661cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    // Test clearing.
5671cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    Error error;
5681cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    accessor.Clear(&error);
5691cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_EQ(Error::kInvalidArguments, error.type());
5701cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart    EXPECT_EQ(orig_value, accessor.Get(&error));
5711cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart  }
5721cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart}
5731cf7eb8dcb037d45b23ed85b777c227b7ab39069Paul Stewart
574a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewartclass StringMapWrapper {
575a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart public:
5763b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  void Clear(const string& key, Error* /*error*/) {
577a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    value_.erase(key);
578a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  }
5793b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  string Get(const string& key, Error* /*error*/) {
580a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    EXPECT_TRUE(ContainsKey(value_, key));
581a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    return value_[key];
582a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  }
5833b30ca58d13cf66b75ba0729b222ddc42ae68b33Paul Stewart  bool Set(const string& key, const string& value, Error* /*error*/) {
584bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    if (value_[key] == value) {
585bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal      return false;
586bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    }
587a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    value_[key] = value;
588bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    return true;
589a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  }
590a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart
5918a5322984f2d81bcbfd8d44c59747a11bd9b904bAlex Vakulenko  map<string, string> value_;
592a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart};
593a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart
594a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul StewartTEST(PropertyAccessorTest, CustomMappedAccessor) {
595a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  const string kKey = "entry_key";
596a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  const string kValue = "entry_value";
597a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  {
598a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    // Test reading.
599a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    StringMapWrapper wrapper;
600a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    CustomMappedAccessor<StringMapWrapper, string, string> accessor(
601a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart        &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
602a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart        &StringMapWrapper::Set, kKey);
603a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    wrapper.value_[kKey] = kValue;
604a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    Error error;
605a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    EXPECT_EQ(kValue, accessor.Get(&error));
606a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    EXPECT_TRUE(error.IsSuccess());
607a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  }
608a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  {
609a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    // Test writing.
610a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    StringMapWrapper wrapper;
611a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    CustomMappedAccessor<StringMapWrapper, string, string> accessor(
612a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart        &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
613a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart        &StringMapWrapper::Set, kKey);
614a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    Error error;
615bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(accessor.Set(kValue, &error));
616a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    EXPECT_TRUE(error.IsSuccess());
617a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    EXPECT_EQ(kValue, wrapper.value_[kKey]);
618bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // Set to same value. With the above, this verifies that the
619bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // CustomMappedAccessor template passes through the return
620bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    // value.
621bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_FALSE(accessor.Set(kValue, &error));
622bebf1b8bce52b88c2cc2d93200b9405f9c19cf21mukesh agrawal    EXPECT_TRUE(error.IsSuccess());
623a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  }
624a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  {
625a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    // Test clearing.
626a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    StringMapWrapper wrapper;
627a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    CustomMappedAccessor<StringMapWrapper, string, string> accessor(
628a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart        &wrapper, &StringMapWrapper::Clear, &StringMapWrapper::Get,
629a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart        &StringMapWrapper::Set, kKey);
630a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    wrapper.value_[kKey] = kValue;
631a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    Error error;
632a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    accessor.Clear(&error);
633a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    EXPECT_TRUE(error.IsSuccess());
634a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart    EXPECT_FALSE(ContainsKey(wrapper.value_, kKey));
635a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart  }
636a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart}
637a61593e58a41fb2d6c25e0b1c2405f5246f22699Paul Stewart
63827bf1036f4468bd4cd235fe385b7eb460f49c9faChris Masone}  // namespace shill
639