OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromecast/base/device_capabilities_impl.h" | 5 #include "chromecast/base/device_capabilities_impl.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
| 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" |
9 #include "base/values.h" | 11 #include "base/values.h" |
10 #include "chromecast/base/serializers.h" | 12 #include "chromecast/base/serializers.h" |
11 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
13 | 15 |
14 namespace chromecast { | 16 namespace chromecast { |
15 | 17 |
16 namespace { | 18 namespace { |
17 | 19 |
18 const char kSampleDictionaryCapability[] = | 20 const char kSampleDictionaryCapability[] = |
19 "{" | 21 "{" |
20 " \"dummy_field_bool\": true," | 22 " \"dummy_field_bool\": true," |
21 " \"dummy_field_int\": 99" | 23 " \"dummy_field_int\": 99" |
22 "}"; | 24 "}"; |
23 | 25 |
| 26 void GetSampleDefaultCapability(std::string* key, |
| 27 scoped_ptr<base::Value>* init_value); |
| 28 void TestBasicOperations(DeviceCapabilities* capabilities); |
| 29 |
24 // Simple capability manager that implements the Validator interface. Either | 30 // Simple capability manager that implements the Validator interface. Either |
25 // accepts or rejects all proposed changes based on |accept_changes| constructor | 31 // accepts or rejects all proposed changes based on |accept_changes| constructor |
26 // argument. | 32 // argument. |
27 class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator { | 33 class FakeCapabilityManagerSimple : public DeviceCapabilities::Validator { |
28 public: | 34 public: |
29 // Registers itself as Validator in constructor. If init_value is not null, | 35 // Registers itself as Validator in constructor. If init_value is not null, |
30 // the capability gets initialized to that value. Else capability remains | 36 // the capability gets initialized to that value. Else capability remains |
31 // untouched. | 37 // untouched. |
32 FakeCapabilityManagerSimple(DeviceCapabilities* capabilities, | 38 FakeCapabilityManagerSimple(DeviceCapabilities* capabilities, |
33 const std::string& key, | 39 const std::string& key, |
(...skipping 17 matching lines...) Expand all Loading... |
51 ASSERT_TRUE(path.find(key_) == 0); | 57 ASSERT_TRUE(path.find(key_) == 0); |
52 if (accept_changes_) | 58 if (accept_changes_) |
53 SetValidatedValue(path, proposed_value.Pass()); | 59 SetValidatedValue(path, proposed_value.Pass()); |
54 } | 60 } |
55 | 61 |
56 private: | 62 private: |
57 const std::string key_; | 63 const std::string key_; |
58 const bool accept_changes_; | 64 const bool accept_changes_; |
59 }; | 65 }; |
60 | 66 |
| 67 // Used to test that capabilities/validator can be read and written in |
| 68 // Validate() without encountering deadlocks/unexpected behavior. |
| 69 class FakeCapabilityManagerComplex : public DeviceCapabilities::Validator { |
| 70 public: |
| 71 FakeCapabilityManagerComplex(DeviceCapabilities* capabilities, |
| 72 const std::string& key) |
| 73 : DeviceCapabilities::Validator(capabilities), key_(key) { |
| 74 capabilities->Register(key, this); |
| 75 } |
| 76 |
| 77 // Unregisters itself as Validator. |
| 78 ~FakeCapabilityManagerComplex() override { |
| 79 capabilities()->Unregister(key_, this); |
| 80 } |
| 81 |
| 82 // Runs TestBasicOperations(). |
| 83 void Validate(const std::string& path, |
| 84 scoped_ptr<base::Value> proposed_value) override { |
| 85 TestBasicOperations(capabilities()); |
| 86 } |
| 87 |
| 88 private: |
| 89 const std::string key_; |
| 90 }; |
| 91 |
| 92 // Used to test that capabilities/validators can be read and written in |
| 93 // OnCapabilitiesChanged() without encountering deadlocks/unexpected behavior. |
| 94 class FakeCapabilitiesObserver : public DeviceCapabilities::Observer { |
| 95 public: |
| 96 FakeCapabilitiesObserver(DeviceCapabilities* capabilities) |
| 97 : capabilities_(capabilities), removed_as_observer(false) { |
| 98 capabilities_->AddCapabilitiesObserver(this); |
| 99 } |
| 100 |
| 101 ~FakeCapabilitiesObserver() override { |
| 102 if (!removed_as_observer) |
| 103 capabilities_->RemoveCapabilitiesObserver(this); |
| 104 } |
| 105 |
| 106 // Runs TestBasicOperations(). |
| 107 void OnCapabilitiesChanged(const std::string& path) override { |
| 108 TestBasicOperations(capabilities_); |
| 109 // To prevent infinite loop of SetCapability() -> OnCapabilitiesChanged() |
| 110 // -> SetCapability() -> OnCapabilitiesChanged() etc. |
| 111 capabilities_->RemoveCapabilitiesObserver(this); |
| 112 removed_as_observer = true; |
| 113 } |
| 114 |
| 115 private: |
| 116 DeviceCapabilities* const capabilities_; |
| 117 bool removed_as_observer; |
| 118 }; |
| 119 |
61 // Used to test that OnCapabilitiesChanged() is called when capabilities are | 120 // Used to test that OnCapabilitiesChanged() is called when capabilities are |
62 // modified | 121 // modified |
63 class MockCapabilitiesObserver : public DeviceCapabilities::Observer { | 122 class MockCapabilitiesObserver : public DeviceCapabilities::Observer { |
64 public: | 123 public: |
65 MockCapabilitiesObserver() {} | 124 MockCapabilitiesObserver() {} |
66 ~MockCapabilitiesObserver() override {} | 125 ~MockCapabilitiesObserver() override {} |
67 | 126 |
68 MOCK_METHOD1(OnCapabilitiesChanged, void(const std::string& path)); | 127 MOCK_METHOD1(OnCapabilitiesChanged, void(const std::string& path)); |
69 | 128 |
70 private: | 129 private: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 // specified by |key| and |value|. | 168 // specified by |key| and |value|. |
110 bool JsonStringEquals(const std::string& json, | 169 bool JsonStringEquals(const std::string& json, |
111 const std::string& key, | 170 const std::string& key, |
112 const base::Value& value) { | 171 const base::Value& value) { |
113 base::DictionaryValue dict_value; | 172 base::DictionaryValue dict_value; |
114 dict_value.Set(key, value.CreateDeepCopy()); | 173 dict_value.Set(key, value.CreateDeepCopy()); |
115 scoped_ptr<const std::string> dict_json(SerializeToJson(dict_value)); | 174 scoped_ptr<const std::string> dict_json(SerializeToJson(dict_value)); |
116 return dict_json.get() && *dict_json == json; | 175 return dict_json.get() && *dict_json == json; |
117 } | 176 } |
118 | 177 |
| 178 // The function runs through the set of basic operations of DeviceCapabilities. |
| 179 // Register validator for sample default capability, reads capability, writes |
| 180 // capability, and unregister validator. After it has completed, use |
| 181 // AssertBasicOperationsSuccessful() to ensure that all operations completed |
| 182 // successfully. Sample default capability should not be added or registered in |
| 183 // class before this function is called. |
| 184 void TestBasicOperations(DeviceCapabilities* capabilities) { |
| 185 std::string key; |
| 186 scoped_ptr<base::Value> init_value; |
| 187 GetSampleDefaultCapability(&key, &init_value); |
| 188 |
| 189 ASSERT_FALSE(capabilities->GetCapability(key)); |
| 190 ASSERT_FALSE(capabilities->GetValidator(key)); |
| 191 |
| 192 // Register and write capability |
| 193 FakeCapabilityManagerSimple* manager(new FakeCapabilityManagerSimple( |
| 194 capabilities, key, init_value->CreateDeepCopy(), true)); |
| 195 // Read Validator |
| 196 EXPECT_EQ(capabilities->GetValidator(key), manager); |
| 197 // Read Capability |
| 198 EXPECT_TRUE(base::Value::Equals(capabilities->GetCapability(key).get(), |
| 199 init_value.get())); |
| 200 // Unregister |
| 201 delete manager; |
| 202 |
| 203 // Write capability again. Provides way of checking that this function |
| 204 // ran and was successful. |
| 205 scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); |
| 206 capabilities->SetCapability(key, new_value.Pass()); |
| 207 } |
| 208 |
| 209 // See TestBasicOperations() comment. |
| 210 void AssertBasicOperationsSuccessful(const DeviceCapabilities* capabilities) { |
| 211 base::RunLoop().RunUntilIdle(); |
| 212 std::string key; |
| 213 scoped_ptr<base::Value> init_value; |
| 214 GetSampleDefaultCapability(&key, &init_value); |
| 215 scoped_ptr<base::Value> value = capabilities->GetCapability(key); |
| 216 ASSERT_TRUE(value); |
| 217 scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); |
| 218 EXPECT_TRUE(base::Value::Equals(value.get(), new_value.get())); |
| 219 } |
| 220 |
119 } // namespace | 221 } // namespace |
120 | 222 |
121 class DeviceCapabilitiesImplTest : public ::testing::Test { | 223 class DeviceCapabilitiesImplTest : public ::testing::Test { |
122 protected: | 224 protected: |
123 void SetUp() override { | 225 void SetUp() override { |
| 226 message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO)); |
124 capabilities_ = DeviceCapabilities::Create(); | 227 capabilities_ = DeviceCapabilities::Create(); |
125 mock_capabilities_observer_.reset(new MockCapabilitiesObserver()); | 228 mock_capabilities_observer_.reset(new MockCapabilitiesObserver()); |
126 capabilities_->AddCapabilitiesObserver(mock_capabilities_observer_.get()); | 229 capabilities_->AddCapabilitiesObserver(mock_capabilities_observer_.get()); |
127 | 230 |
128 // We set the default gmock expected calls to any so that tests must | 231 // We set the default gmock expected calls to any so that tests must |
129 // 'opt in' to checking the calls rather than 'opt out'. This avoids having | 232 // 'opt in' to checking the calls rather than 'opt out'. This avoids having |
130 // to add explicit calls in test cases that don't care in order to prevent | 233 // to add explicit calls in test cases that don't care in order to prevent |
131 // lots of useless mock warnings. | 234 // lots of useless mock warnings. |
132 EXPECT_CALL(*mock_capabilities_observer_, OnCapabilitiesChanged(testing::_)) | 235 EXPECT_CALL(*mock_capabilities_observer_, OnCapabilitiesChanged(testing::_)) |
133 .Times(testing::AnyNumber()); | 236 .Times(testing::AnyNumber()); |
134 } | 237 } |
135 | 238 |
136 void TearDown() override { | 239 void TearDown() override { |
137 capabilities_->RemoveCapabilitiesObserver( | 240 capabilities_->RemoveCapabilitiesObserver( |
138 mock_capabilities_observer_.get()); | 241 mock_capabilities_observer_.get()); |
| 242 mock_capabilities_observer_.reset(); |
| 243 capabilities_.reset(); |
| 244 message_loop_.reset(); |
139 } | 245 } |
140 | 246 |
141 DeviceCapabilities* capabilities() const { return capabilities_.get(); } | 247 DeviceCapabilities* capabilities() const { return capabilities_.get(); } |
142 | 248 |
143 MockCapabilitiesObserver* capabilities_observer() const { | 249 MockCapabilitiesObserver* capabilities_observer() const { |
144 return mock_capabilities_observer_.get(); | 250 return mock_capabilities_observer_.get(); |
145 } | 251 } |
146 | 252 |
147 private: | 253 private: |
| 254 scoped_ptr<base::MessageLoop> message_loop_; |
148 scoped_ptr<DeviceCapabilities> capabilities_; | 255 scoped_ptr<DeviceCapabilities> capabilities_; |
149 scoped_ptr<MockCapabilitiesObserver> mock_capabilities_observer_; | 256 scoped_ptr<MockCapabilitiesObserver> mock_capabilities_observer_; |
150 }; | 257 }; |
151 | 258 |
152 // Tests that class is in correct state after Create(). | 259 // Tests that class is in correct state after Create(). |
153 TEST_F(DeviceCapabilitiesImplTest, Create) { | 260 TEST_F(DeviceCapabilitiesImplTest, Create) { |
154 scoped_ptr<const std::string> empty_dict_string( | 261 scoped_ptr<const std::string> empty_dict_string( |
155 SerializeToJson(base::DictionaryValue())); | 262 SerializeToJson(base::DictionaryValue())); |
156 EXPECT_EQ(capabilities()->GetCapabilitiesString(), *empty_dict_string); | 263 EXPECT_EQ(capabilities()->GetData()->json_string(), *empty_dict_string); |
157 EXPECT_TRUE(capabilities()->GetCapabilities()->empty()); | 264 EXPECT_TRUE(capabilities()->GetData()->dictionary().empty()); |
158 } | 265 } |
159 | 266 |
160 // Tests Register() of a default capability. | 267 // Tests Register() of a default capability. |
161 TEST_F(DeviceCapabilitiesImplTest, Register) { | 268 TEST_F(DeviceCapabilitiesImplTest, Register) { |
162 std::string key; | 269 std::string key; |
163 scoped_ptr<base::Value> init_value; | 270 scoped_ptr<base::Value> init_value; |
164 GetSampleDefaultCapability(&key, &init_value); | 271 GetSampleDefaultCapability(&key, &init_value); |
165 | 272 |
166 EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0); | 273 EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0); |
167 FakeCapabilityManagerSimple manager(capabilities(), key, nullptr, true); | 274 FakeCapabilityManagerSimple manager(capabilities(), key, nullptr, true); |
168 | 275 |
169 EXPECT_EQ(capabilities()->GetValidator(key), &manager); | 276 EXPECT_EQ(capabilities()->GetValidator(key), &manager); |
170 scoped_ptr<const std::string> empty_dict_string( | 277 scoped_ptr<const std::string> empty_dict_string( |
171 SerializeToJson(base::DictionaryValue())); | 278 SerializeToJson(base::DictionaryValue())); |
172 EXPECT_EQ(capabilities()->GetCapabilitiesString(), *empty_dict_string); | 279 EXPECT_EQ(capabilities()->GetData()->json_string(), *empty_dict_string); |
173 const base::Value* value = nullptr; | 280 EXPECT_FALSE(capabilities()->GetCapability(key)); |
174 EXPECT_FALSE(capabilities()->GetCapability(key, &value)); | |
175 } | 281 } |
176 | 282 |
177 // Tests Unregister() of a default capability. | 283 // Tests Unregister() of a default capability. |
178 TEST_F(DeviceCapabilitiesImplTest, Unregister) { | 284 TEST_F(DeviceCapabilitiesImplTest, Unregister) { |
179 std::string key; | 285 std::string key; |
180 scoped_ptr<base::Value> init_value; | 286 scoped_ptr<base::Value> init_value; |
181 GetSampleDefaultCapability(&key, &init_value); | 287 GetSampleDefaultCapability(&key, &init_value); |
182 | 288 |
183 EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0); | 289 EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(0); |
184 FakeCapabilityManagerSimple* manager = | 290 FakeCapabilityManagerSimple* manager = |
185 new FakeCapabilityManagerSimple(capabilities(), key, nullptr, true); | 291 new FakeCapabilityManagerSimple(capabilities(), key, nullptr, true); |
186 | 292 |
187 delete manager; | 293 delete manager; |
188 | 294 |
189 EXPECT_EQ(capabilities()->GetValidator(key), nullptr); | 295 EXPECT_FALSE(capabilities()->GetValidator(key)); |
190 scoped_ptr<const std::string> empty_dict_string( | 296 scoped_ptr<const std::string> empty_dict_string( |
191 SerializeToJson(base::DictionaryValue())); | 297 SerializeToJson(base::DictionaryValue())); |
192 EXPECT_EQ(capabilities()->GetCapabilitiesString(), *empty_dict_string); | 298 EXPECT_EQ(capabilities()->GetData()->json_string(), *empty_dict_string); |
193 const base::Value* value = nullptr; | 299 EXPECT_FALSE(capabilities()->GetCapability(key)); |
194 EXPECT_FALSE(capabilities()->GetCapability(key, &value)); | |
195 } | 300 } |
196 | 301 |
197 // Tests GetCapability() and updating the value through SetCapability(). | 302 // Tests GetCapability() and updating the value through SetCapability(). |
198 TEST_F(DeviceCapabilitiesImplTest, GetCapabilityAndSetCapability) { | 303 TEST_F(DeviceCapabilitiesImplTest, GetCapabilityAndSetCapability) { |
199 std::string key; | 304 std::string key; |
200 scoped_ptr<base::Value> init_value; | 305 scoped_ptr<base::Value> init_value; |
201 GetSampleDefaultCapability(&key, &init_value); | 306 GetSampleDefaultCapability(&key, &init_value); |
202 FakeCapabilityManagerSimple manager(capabilities(), key, | 307 FakeCapabilityManagerSimple manager(capabilities(), key, |
203 init_value->CreateDeepCopy(), true); | 308 init_value->CreateDeepCopy(), true); |
204 | 309 |
205 const base::Value* value = nullptr; | 310 EXPECT_TRUE(base::Value::Equals(capabilities()->GetCapability(key).get(), |
206 EXPECT_TRUE(capabilities()->GetCapability(key, &value)); | 311 init_value.get())); |
207 EXPECT_TRUE(base::Value::Equals(value, init_value.get())); | |
208 | 312 |
209 scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); | 313 scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); |
210 capabilities()->SetCapability(key, new_value->CreateDeepCopy()); | 314 capabilities()->SetCapability(key, new_value->CreateDeepCopy()); |
211 value = nullptr; | 315 base::RunLoop().RunUntilIdle(); |
212 EXPECT_TRUE(capabilities()->GetCapability(key, &value)); | 316 EXPECT_TRUE(base::Value::Equals(capabilities()->GetCapability(key).get(), |
213 EXPECT_TRUE(base::Value::Equals(value, new_value.get())); | 317 new_value.get())); |
214 } | 318 } |
215 | 319 |
216 // Tests BluetoothSupported() and updating this value through SetCapability(). | 320 // Tests BluetoothSupported() and updating this value through SetCapability(). |
217 TEST_F(DeviceCapabilitiesImplTest, BluetoothSupportedAndSetCapability) { | 321 TEST_F(DeviceCapabilitiesImplTest, BluetoothSupportedAndSetCapability) { |
218 FakeCapabilityManagerSimple manager( | 322 FakeCapabilityManagerSimple manager( |
219 capabilities(), DeviceCapabilities::kKeyBluetoothSupported, | 323 capabilities(), DeviceCapabilities::kKeyBluetoothSupported, |
220 make_scoped_ptr(new base::FundamentalValue(true)), true); | 324 make_scoped_ptr(new base::FundamentalValue(true)), true); |
221 | 325 |
222 EXPECT_TRUE(capabilities()->BluetoothSupported()); | 326 EXPECT_TRUE(capabilities()->BluetoothSupported()); |
223 capabilities()->SetCapability( | 327 capabilities()->SetCapability( |
224 DeviceCapabilities::kKeyBluetoothSupported, | 328 DeviceCapabilities::kKeyBluetoothSupported, |
225 make_scoped_ptr(new base::FundamentalValue(false))); | 329 make_scoped_ptr(new base::FundamentalValue(false))); |
| 330 base::RunLoop().RunUntilIdle(); |
226 EXPECT_FALSE(capabilities()->BluetoothSupported()); | 331 EXPECT_FALSE(capabilities()->BluetoothSupported()); |
227 } | 332 } |
228 | 333 |
229 // Tests DisplaySupported() and updating this value through SetCapability(). | 334 // Tests DisplaySupported() and updating this value through SetCapability(). |
230 TEST_F(DeviceCapabilitiesImplTest, DisplaySupportedAndSetCapability) { | 335 TEST_F(DeviceCapabilitiesImplTest, DisplaySupportedAndSetCapability) { |
231 FakeCapabilityManagerSimple manager( | 336 FakeCapabilityManagerSimple manager( |
232 capabilities(), DeviceCapabilities::kKeyDisplaySupported, | 337 capabilities(), DeviceCapabilities::kKeyDisplaySupported, |
233 make_scoped_ptr(new base::FundamentalValue(true)), true); | 338 make_scoped_ptr(new base::FundamentalValue(true)), true); |
234 | 339 |
235 EXPECT_TRUE(capabilities()->DisplaySupported()); | 340 EXPECT_TRUE(capabilities()->DisplaySupported()); |
236 capabilities()->SetCapability( | 341 capabilities()->SetCapability( |
237 DeviceCapabilities::kKeyDisplaySupported, | 342 DeviceCapabilities::kKeyDisplaySupported, |
238 make_scoped_ptr(new base::FundamentalValue(false))); | 343 make_scoped_ptr(new base::FundamentalValue(false))); |
| 344 base::RunLoop().RunUntilIdle(); |
239 EXPECT_FALSE(capabilities()->DisplaySupported()); | 345 EXPECT_FALSE(capabilities()->DisplaySupported()); |
240 } | 346 } |
241 | 347 |
242 // Tests SetCapability() for a default capability when the capability's manager | 348 // Tests SetCapability() for a default capability when the capability's manager |
243 // rejects the proposed change. | 349 // rejects the proposed change. |
244 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityInvalid) { | 350 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityInvalid) { |
245 std::string key; | 351 std::string key; |
246 scoped_ptr<base::Value> init_value; | 352 scoped_ptr<base::Value> init_value; |
247 GetSampleDefaultCapability(&key, &init_value); | 353 GetSampleDefaultCapability(&key, &init_value); |
248 FakeCapabilityManagerSimple manager(capabilities(), key, | 354 FakeCapabilityManagerSimple manager(capabilities(), key, |
249 init_value->CreateDeepCopy(), false); | 355 init_value->CreateDeepCopy(), false); |
250 | 356 |
251 capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue()); | 357 capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue()); |
| 358 base::RunLoop().RunUntilIdle(); |
252 | 359 |
253 const base::Value* value = nullptr; | 360 EXPECT_TRUE(base::Value::Equals(capabilities()->GetCapability(key).get(), |
254 EXPECT_TRUE(capabilities()->GetCapability(key, &value)); | 361 init_value.get())); |
255 EXPECT_TRUE(base::Value::Equals(init_value.get(), value)); | |
256 } | 362 } |
257 | 363 |
258 // Test that SetCapability() updates the capabilities string correctly | 364 // Test that SetCapability() updates the capabilities string correctly |
259 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityUpdatesString) { | 365 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityUpdatesString) { |
260 std::string key; | 366 std::string key; |
261 scoped_ptr<base::Value> init_value; | 367 scoped_ptr<base::Value> init_value; |
262 GetSampleDefaultCapability(&key, &init_value); | 368 GetSampleDefaultCapability(&key, &init_value); |
263 FakeCapabilityManagerSimple manager(capabilities(), key, | 369 FakeCapabilityManagerSimple manager(capabilities(), key, |
264 init_value->CreateDeepCopy(), true); | 370 init_value->CreateDeepCopy(), true); |
265 | 371 |
266 EXPECT_TRUE(JsonStringEquals(capabilities()->GetCapabilitiesString(), key, | 372 EXPECT_TRUE(JsonStringEquals(capabilities()->GetData()->json_string(), key, |
267 *init_value)); | 373 *init_value)); |
268 | 374 |
269 scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); | 375 scoped_ptr<base::Value> new_value = GetSampleDefaultCapabilityNewValue(); |
270 capabilities()->SetCapability(key, new_value->CreateDeepCopy()); | 376 capabilities()->SetCapability(key, new_value->CreateDeepCopy()); |
271 EXPECT_TRUE(JsonStringEquals(capabilities()->GetCapabilitiesString(), key, | 377 base::RunLoop().RunUntilIdle(); |
| 378 EXPECT_TRUE(JsonStringEquals(capabilities()->GetData()->json_string(), key, |
272 *new_value)); | 379 *new_value)); |
273 } | 380 } |
274 | 381 |
275 // Test that SetCapability() notifies Observers when the capability's value | 382 // Test that SetCapability() notifies Observers when the capability's value |
276 // changes | 383 // changes |
277 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityNotifiesObservers) { | 384 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityNotifiesObservers) { |
278 std::string key; | 385 std::string key; |
279 scoped_ptr<base::Value> init_value; | 386 scoped_ptr<base::Value> init_value; |
280 GetSampleDefaultCapability(&key, &init_value); | 387 GetSampleDefaultCapability(&key, &init_value); |
281 | 388 |
282 EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(3); | 389 EXPECT_CALL(*capabilities_observer(), OnCapabilitiesChanged(key)).Times(3); |
283 | 390 |
284 // 1st call (register) | 391 // 1st call (register) |
285 FakeCapabilityManagerSimple manager(capabilities(), key, | 392 FakeCapabilityManagerSimple manager(capabilities(), key, |
286 init_value->CreateDeepCopy(), true); | 393 init_value->CreateDeepCopy(), true); |
287 | 394 |
288 // 2nd call | 395 // 2nd call |
289 capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue()); | 396 capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue()); |
290 | 397 |
291 // Observer should not get called when value does not change | 398 // Observer should not get called when value does not change |
292 capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue()); | 399 capabilities()->SetCapability(key, GetSampleDefaultCapabilityNewValue()); |
293 | 400 |
294 // 3rd call | 401 // 3rd call |
295 capabilities()->SetCapability(key, init_value.Pass()); | 402 capabilities()->SetCapability(key, init_value.Pass()); |
| 403 base::RunLoop().RunUntilIdle(); |
296 } | 404 } |
297 | 405 |
298 // Test adding dynamic capabilities | 406 // Test adding dynamic capabilities |
299 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDynamic) { | 407 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDynamic) { |
300 std::string key; | 408 std::string key; |
301 scoped_ptr<base::Value> init_value; | 409 scoped_ptr<base::Value> init_value; |
302 GetSampleDynamicCapability(&key, &init_value); | 410 GetSampleDynamicCapability(&key, &init_value); |
303 | 411 |
304 const base::Value* value = nullptr; | 412 ASSERT_FALSE(capabilities()->GetCapability(key)); |
305 ASSERT_FALSE(capabilities()->GetCapability(key, &value)); | |
306 capabilities()->SetCapability(key, init_value->CreateDeepCopy()); | 413 capabilities()->SetCapability(key, init_value->CreateDeepCopy()); |
| 414 base::RunLoop().RunUntilIdle(); |
307 | 415 |
308 EXPECT_TRUE(capabilities()->GetCapability(key, &value)); | 416 EXPECT_TRUE(base::Value::Equals(capabilities()->GetCapability(key).get(), |
309 EXPECT_TRUE(base::Value::Equals(init_value.get(), value)); | 417 init_value.get())); |
310 EXPECT_TRUE(JsonStringEquals(capabilities()->GetCapabilitiesString(), key, | 418 EXPECT_TRUE(JsonStringEquals(capabilities()->GetData()->json_string(), key, |
311 *init_value)); | 419 *init_value)); |
312 | 420 |
313 scoped_ptr<base::Value> new_value = GetSampleDynamicCapabilityNewValue(); | 421 scoped_ptr<base::Value> new_value = GetSampleDynamicCapabilityNewValue(); |
314 capabilities()->SetCapability(key, new_value->CreateDeepCopy()); | 422 capabilities()->SetCapability(key, new_value->CreateDeepCopy()); |
315 value = nullptr; | 423 base::RunLoop().RunUntilIdle(); |
316 EXPECT_TRUE(capabilities()->GetCapability(key, &value)); | 424 EXPECT_TRUE(base::Value::Equals(capabilities()->GetCapability(key).get(), |
317 EXPECT_TRUE(base::Value::Equals(new_value.get(), value)); | 425 new_value.get())); |
318 EXPECT_TRUE(JsonStringEquals(capabilities()->GetCapabilitiesString(), key, | 426 EXPECT_TRUE(JsonStringEquals(capabilities()->GetData()->json_string(), key, |
319 *new_value)); | 427 *new_value)); |
320 } | 428 } |
321 | 429 |
322 // Tests that SetCapability() works with expanded paths when there is a | 430 // Tests that SetCapability() works with expanded paths when there is a |
323 // capability of type DictionaryValue. | 431 // capability of type DictionaryValue. |
324 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionary) { | 432 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionary) { |
325 std::string key("dummy_dictionary_key"); | 433 std::string key("dummy_dictionary_key"); |
326 scoped_ptr<base::Value> init_value = | 434 scoped_ptr<base::Value> init_value = |
327 DeserializeFromJson(kSampleDictionaryCapability); | 435 DeserializeFromJson(kSampleDictionaryCapability); |
328 ASSERT_NE(init_value, nullptr); | 436 ASSERT_TRUE(init_value); |
329 FakeCapabilityManagerSimple manager(capabilities(), key, init_value.Pass(), | 437 FakeCapabilityManagerSimple manager(capabilities(), key, init_value.Pass(), |
330 true); | 438 true); |
331 | 439 |
332 capabilities()->SetCapability( | 440 capabilities()->SetCapability( |
333 "dummy_dictionary_key.dummy_field_bool", | 441 "dummy_dictionary_key.dummy_field_bool", |
334 make_scoped_ptr(new base::FundamentalValue(false))); | 442 make_scoped_ptr(new base::FundamentalValue(false))); |
335 const base::Value* value = nullptr; | 443 base::RunLoop().RunUntilIdle(); |
336 bool value_bool = true; | 444 bool value_bool = true; |
337 EXPECT_TRUE(capabilities()->GetCapability( | 445 scoped_ptr<base::Value> value = |
338 "dummy_dictionary_key.dummy_field_bool", &value)); | 446 capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool"); |
| 447 ASSERT_TRUE(value); |
339 EXPECT_TRUE(value->GetAsBoolean(&value_bool)); | 448 EXPECT_TRUE(value->GetAsBoolean(&value_bool)); |
340 EXPECT_FALSE(value_bool); | 449 EXPECT_FALSE(value_bool); |
341 | 450 |
342 capabilities()->SetCapability( | 451 capabilities()->SetCapability( |
343 "dummy_dictionary_key.dummy_field_int", | 452 "dummy_dictionary_key.dummy_field_int", |
344 make_scoped_ptr(new base::FundamentalValue(100))); | 453 make_scoped_ptr(new base::FundamentalValue(100))); |
345 value = nullptr; | 454 base::RunLoop().RunUntilIdle(); |
346 int value_int = 0; | 455 int value_int = 0; |
347 EXPECT_TRUE(capabilities()->GetCapability( | 456 value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int"); |
348 "dummy_dictionary_key.dummy_field_int", &value)); | 457 ASSERT_TRUE(value); |
349 EXPECT_TRUE(value->GetAsInteger(&value_int)); | 458 EXPECT_TRUE(value->GetAsInteger(&value_int)); |
350 EXPECT_EQ(value_int, 100); | 459 EXPECT_EQ(value_int, 100); |
351 } | 460 } |
352 | 461 |
353 // Tests that SetCapability() works with expanded paths when there is a | 462 // Tests that SetCapability() works with expanded paths when there is a |
354 // capability of type DictionaryValue and invalid changes are proposed. | 463 // capability of type DictionaryValue and invalid changes are proposed. |
355 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionaryInvalid) { | 464 TEST_F(DeviceCapabilitiesImplTest, SetCapabilityDictionaryInvalid) { |
356 std::string key("dummy_dictionary_key"); | 465 std::string key("dummy_dictionary_key"); |
357 scoped_ptr<base::Value> init_value = | 466 scoped_ptr<base::Value> init_value = |
358 DeserializeFromJson(kSampleDictionaryCapability); | 467 DeserializeFromJson(kSampleDictionaryCapability); |
359 ASSERT_NE(init_value, nullptr); | 468 ASSERT_TRUE(init_value); |
360 FakeCapabilityManagerSimple manager(capabilities(), key, init_value.Pass(), | 469 FakeCapabilityManagerSimple manager(capabilities(), key, init_value.Pass(), |
361 false); | 470 false); |
362 | 471 |
363 capabilities()->SetCapability( | 472 capabilities()->SetCapability( |
364 "dummy_dictionary_key.dummy_field_bool", | 473 "dummy_dictionary_key.dummy_field_bool", |
365 make_scoped_ptr(new base::FundamentalValue(false))); | 474 make_scoped_ptr(new base::FundamentalValue(false))); |
366 const base::Value* value = nullptr; | 475 base::RunLoop().RunUntilIdle(); |
367 bool value_bool = false; | 476 bool value_bool = false; |
368 EXPECT_TRUE(capabilities()->GetCapability( | 477 scoped_ptr<base::Value> value = |
369 "dummy_dictionary_key.dummy_field_bool", &value)); | 478 capabilities()->GetCapability("dummy_dictionary_key.dummy_field_bool"); |
| 479 ASSERT_TRUE(value); |
370 EXPECT_TRUE(value->GetAsBoolean(&value_bool)); | 480 EXPECT_TRUE(value->GetAsBoolean(&value_bool)); |
371 EXPECT_TRUE(value_bool); | 481 EXPECT_TRUE(value_bool); |
372 | 482 |
373 capabilities()->SetCapability( | 483 capabilities()->SetCapability( |
374 "dummy_dictionary_key.dummy_field_int", | 484 "dummy_dictionary_key.dummy_field_int", |
375 make_scoped_ptr(new base::FundamentalValue(100))); | 485 make_scoped_ptr(new base::FundamentalValue(100))); |
376 value = nullptr; | 486 base::RunLoop().RunUntilIdle(); |
377 int value_int = 0; | 487 int value_int = 0; |
378 EXPECT_TRUE(capabilities()->GetCapability( | 488 value = capabilities()->GetCapability("dummy_dictionary_key.dummy_field_int"); |
379 "dummy_dictionary_key.dummy_field_int", &value)); | 489 ASSERT_TRUE(value); |
380 EXPECT_TRUE(value->GetAsInteger(&value_int)); | 490 EXPECT_TRUE(value->GetAsInteger(&value_int)); |
381 EXPECT_EQ(value_int, 99); | 491 EXPECT_EQ(value_int, 99); |
382 } | 492 } |
383 | 493 |
384 // Test MergeDictionary. | 494 // Test MergeDictionary. |
385 TEST_F(DeviceCapabilitiesImplTest, MergeDictionary) { | 495 TEST_F(DeviceCapabilitiesImplTest, MergeDictionary) { |
386 scoped_ptr<base::Value> deserialized_value = | 496 scoped_ptr<base::Value> deserialized_value = |
387 DeserializeFromJson(kSampleDictionaryCapability); | 497 DeserializeFromJson(kSampleDictionaryCapability); |
388 ASSERT_NE(deserialized_value, nullptr); | 498 ASSERT_TRUE(deserialized_value); |
389 base::DictionaryValue* dict_value = nullptr; | 499 base::DictionaryValue* dict_value = nullptr; |
390 ASSERT_TRUE(deserialized_value->GetAsDictionary(&dict_value)); | 500 ASSERT_TRUE(deserialized_value->GetAsDictionary(&dict_value)); |
391 ASSERT_NE(dict_value, nullptr); | 501 ASSERT_TRUE(dict_value); |
392 | 502 |
393 capabilities()->MergeDictionary(*dict_value); | 503 capabilities()->MergeDictionary(*dict_value); |
| 504 base::RunLoop().RunUntilIdle(); |
394 | 505 |
395 // First make sure that capabilities get created if they do not exist | 506 // First make sure that capabilities get created if they do not exist |
396 const base::Value* value = nullptr; | |
397 bool value_bool = false; | 507 bool value_bool = false; |
398 EXPECT_TRUE(capabilities()->GetCapability("dummy_field_bool", &value)); | 508 scoped_ptr<base::Value> value = |
| 509 capabilities()->GetCapability("dummy_field_bool"); |
| 510 ASSERT_TRUE(value); |
399 EXPECT_TRUE(value->GetAsBoolean(&value_bool)); | 511 EXPECT_TRUE(value->GetAsBoolean(&value_bool)); |
400 EXPECT_TRUE(value_bool); | 512 EXPECT_TRUE(value_bool); |
401 | 513 |
402 value = nullptr; | |
403 int value_int = 0; | 514 int value_int = 0; |
404 EXPECT_TRUE(capabilities()->GetCapability("dummy_field_int", &value)); | 515 value = capabilities()->GetCapability("dummy_field_int"); |
| 516 ASSERT_TRUE(value); |
405 EXPECT_TRUE(value->GetAsInteger(&value_int)); | 517 EXPECT_TRUE(value->GetAsInteger(&value_int)); |
406 EXPECT_EQ(value_int, 99); | 518 EXPECT_EQ(value_int, 99); |
407 | 519 |
408 // Now just update one of the fields. Make sure the updated value is changed | 520 // Now just update one of the fields. Make sure the updated value is changed |
409 // in DeviceCapabilities and the other field remains untouched. | 521 // in DeviceCapabilities and the other field remains untouched. |
410 dict_value->SetInteger("dummy_field_int", 100); | 522 dict_value->SetInteger("dummy_field_int", 100); |
411 ASSERT_TRUE(dict_value->Remove("dummy_field_bool", nullptr)); | 523 ASSERT_TRUE(dict_value->Remove("dummy_field_bool", nullptr)); |
412 | 524 |
413 capabilities()->MergeDictionary(*dict_value); | 525 capabilities()->MergeDictionary(*dict_value); |
| 526 base::RunLoop().RunUntilIdle(); |
414 | 527 |
415 value = nullptr; | |
416 value_bool = false; | 528 value_bool = false; |
417 EXPECT_TRUE(capabilities()->GetCapability("dummy_field_bool", &value)); | 529 value = capabilities()->GetCapability("dummy_field_bool"); |
| 530 ASSERT_TRUE(value); |
418 EXPECT_TRUE(value->GetAsBoolean(&value_bool)); | 531 EXPECT_TRUE(value->GetAsBoolean(&value_bool)); |
419 EXPECT_TRUE(value_bool); | 532 EXPECT_TRUE(value_bool); |
420 | 533 |
421 value = nullptr; | 534 value = capabilities()->GetCapability("dummy_field_int"); |
422 EXPECT_TRUE(capabilities()->GetCapability("dummy_field_int", &value)); | 535 ASSERT_TRUE(value); |
423 EXPECT_TRUE(value->GetAsInteger(&value_int)); | 536 EXPECT_TRUE(value->GetAsInteger(&value_int)); |
424 EXPECT_EQ(value_int, 100); | 537 EXPECT_EQ(value_int, 100); |
425 } | 538 } |
426 | 539 |
| 540 // Tests that it is safe to call DeviceCapabilities methods in |
| 541 // an Observer's OnCapabilitiesChanged() implementation safely with correct |
| 542 // behavior and without deadlocking. |
| 543 TEST_F(DeviceCapabilitiesImplTest, OnCapabilitiesChangedSafe) { |
| 544 FakeCapabilitiesObserver observer(capabilities()); |
| 545 |
| 546 // Trigger FakeCapabilitiesObserver::OnCapabilitiesChanged() |
| 547 capabilities()->SetCapability( |
| 548 "dummy_trigger_key", make_scoped_ptr(new base::FundamentalValue(true))); |
| 549 base::RunLoop().RunUntilIdle(); |
| 550 |
| 551 // Check that FakeCapabilitiesObserver::OnCapabilitiesChanged() ran and that |
| 552 // behavior was successful |
| 553 AssertBasicOperationsSuccessful(capabilities()); |
| 554 } |
| 555 |
| 556 // Tests that it is safe to call DeviceCapabilities methods in a Validator's |
| 557 // Validate() implementation safely with correct behavior and without |
| 558 // deadlocking. |
| 559 TEST_F(DeviceCapabilitiesImplTest, ValidateSafe) { |
| 560 FakeCapabilityManagerComplex manager(capabilities(), "dummy_validate_key"); |
| 561 |
| 562 // Trigger FakeCapabilityManagerComplex::Validate() |
| 563 capabilities()->SetCapability( |
| 564 "dummy_validate_key", make_scoped_ptr(new base::FundamentalValue(true))); |
| 565 base::RunLoop().RunUntilIdle(); |
| 566 |
| 567 // Check that FakeCapabilityManagerComplex::Validate() ran and that behavior |
| 568 // was successful |
| 569 AssertBasicOperationsSuccessful(capabilities()); |
| 570 } |
| 571 |
427 } // namespace chromecast | 572 } // namespace chromecast |
OLD | NEW |