1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/win/map.h"
6
7 #include <windows.foundation.h>
8
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/win/core_winrt_util.h"
11 #include "base/win/hstring_reference.h"
12 #include "base/win/scoped_hstring.h"
13 #include "base/win/windows_version.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace ABI {
17 namespace Windows {
18 namespace Foundation {
19 namespace Collections {
20
21 // Add missing template specializations (since UWP doesn't provide them):
22
23 // Map<int, double> specializations:
24 template <>
25 struct __declspec(uuid("34784dd6-b37b-4680-b391-899be4f755b6"))
26 IKeyValuePair<int, double> : IKeyValuePair_impl<int, double> {};
27
28 template <>
29 struct __declspec(uuid("c00bd9bd-cce5-46d6-9dc7-f03067e6d523"))
30 IMap<int, double> : IMap_impl<int, double> {};
31
32 template <>
33 struct __declspec(uuid("30e075af-9ba2-4562-9f10-a13a0e57ca5b"))
34 IMapView<int, double> : IMapView_impl<int, double> {};
35
36 template <>
37 struct __declspec(uuid("0a0e8ed6-7deb-4fd4-8033-38d270c69301"))
38 IObservableMap<int, double> : IObservableMap_impl<int, double> {};
39
40 template <>
41 struct __declspec(uuid("f41f9179-9c95-4755-af55-929a250fc0aa"))
42 IMapChangedEventArgs<int> : IMapChangedEventArgs_impl<int> {};
43
44 template <>
45 struct __declspec(uuid("79196029-07f6-47c6-9933-9ac3a04e7731"))
46 MapChangedEventHandler<int, double>
47 : MapChangedEventHandler_impl<int, double> {};
48
49 template <>
50 struct __declspec(uuid("bfd254c3-5ede-4f8f-9e48-3636347f6fe0"))
51 IIterable<IKeyValuePair<int, double>*>
52 : IIterable_impl<IKeyValuePair<int, double>*> {};
53
54 template <>
55 struct __declspec(uuid("6bb5c7ff-964e-469f-87d3-42daaea8e58d"))
56 IIterator<IKeyValuePair<int, double>*>
57 : IIterator_impl<IKeyValuePair<int, double>*> {};
58
59 template <>
60 struct __declspec(uuid("7d27014c-8df7-4977-bf98-b0c821f5f988"))
61 IVector<IKeyValuePair<int, double>*>
62 : IVector_impl<IKeyValuePair<int, double>*> {};
63
64 template <>
65 struct __declspec(uuid("d33b7a5c-9da6-4a6a-8b2e-e08cc0240d77"))
66 IVectorView<IKeyValuePair<int, double>*>
67 : IVectorView_impl<IKeyValuePair<int, double>*> {};
68
69 template <>
70 struct __declspec(uuid("e5b0d7f2-915d-4831-9a04-466fed63cfa0"))
71 VectorChangedEventHandler<IKeyValuePair<int, double>*>
72 : VectorChangedEventHandler_impl<IKeyValuePair<int, double>*> {};
73
74 template <>
75 struct __declspec(uuid("27c3ee04-457f-42dd-9556-8f7c4994d7af"))
76 IObservableVector<IKeyValuePair<int, double>*>
77 : IObservableVector_impl<IKeyValuePair<int, double>*> {};
78
79 // Map<Uri*, Uri*> specializations:
80 template <>
81 struct __declspec(uuid("c03984bc-b800-43e4-a36e-3c8c4a34c005")) IMap<Uri*, Uri*>
82 : IMap_impl<Uri*, Uri*> {};
83
84 template <>
85 struct __declspec(uuid("93ec9c52-1b0b-4fd8-ab5a-f6ea32db0e35"))
86 IMapView<Uri*, Uri*> : IMapView_impl<Uri*, Uri*> {};
87
88 template <>
89 struct __declspec(uuid("9b711c83-5f01-4604-9e01-3d586b3f9cdd"))
90 IObservableMap<Uri*, Uri*> : IObservableMap_impl<Uri*, Uri*> {};
91
92 template <>
93 struct __declspec(uuid("f41f9179-9c95-4755-af55-929a250fc0aa"))
94 IMapChangedEventArgs<Uri*> : IMapChangedEventArgs_impl<Uri*> {};
95
96 template <>
97 struct __declspec(uuid("6d758124-f99a-47e7-ab74-7cff7359b206"))
98 MapChangedEventHandler<Uri*, Uri*>
99 : MapChangedEventHandler_impl<Uri*, Uri*> {};
100
101 template <>
102 struct __declspec(uuid("8b270b8a-d74b-459b-9933-81cb234d7c5e"))
103 IKeyValuePair<Uri*, Uri*> : IKeyValuePair_impl<Uri*, Uri*> {};
104
105 template <>
106 struct __declspec(uuid("6368bcea-dfbc-4847-ba50-9e217fc2d5c3"))
107 IIterable<IKeyValuePair<Uri*, Uri*>*>
108 : IIterable_impl<IKeyValuePair<Uri*, Uri*>*> {};
109
110 template <>
111 struct __declspec(uuid("7653cf9f-9d0b-46d3-882e-4c0afb209333"))
112 IIterator<IKeyValuePair<Uri*, Uri*>*>
113 : IIterator_impl<IKeyValuePair<Uri*, Uri*>*> {};
114
115 template <>
116 struct __declspec(uuid("98c3f5a7-237d-494b-ba89-4a49368d5491"))
117 IVector<IKeyValuePair<Uri*, Uri*>*>
118 : IVector_impl<IKeyValuePair<Uri*, Uri*>*> {};
119
120 template <>
121 struct __declspec(uuid("2cfc2617-7c88-4482-8158-97bf7cc458d7"))
122 IVectorView<IKeyValuePair<Uri*, Uri*>*>
123 : IVectorView_impl<IKeyValuePair<Uri*, Uri*>*> {};
124
125 template <>
126 struct __declspec(uuid("bb581e03-3ee7-4c01-8035-4f581c5e91f5"))
127 VectorChangedEventHandler<IKeyValuePair<Uri*, Uri*>*>
128 : VectorChangedEventHandler_impl<IKeyValuePair<Uri*, Uri*>*> {};
129
130 template <>
131 struct __declspec(uuid("fb0bd692-34c3-4242-a085-58ed71e8ea6b"))
132 IObservableVector<IKeyValuePair<Uri*, Uri*>*>
133 : IObservableVector_impl<IKeyValuePair<Uri*, Uri*>*> {};
134
135 // Map<HSTRING*, IInspectable*> specializations:
136 template <>
137 struct __declspec(uuid("c6682be1-963c-4101-85aa-63db583eb0d5"))
138 IVector<IKeyValuePair<HSTRING, IInspectable*>*>
139 : IVector_impl<IKeyValuePair<HSTRING, IInspectable*>*> {};
140
141 template <>
142 struct __declspec(uuid("868e5342-49c8-478f-af0f-1691e1bbbb7c"))
143 IVectorView<IKeyValuePair<HSTRING, IInspectable*>*>
144 : IVectorView_impl<IKeyValuePair<HSTRING, IInspectable*>*> {};
145
146 template <>
147 struct __declspec(uuid("cd99b82f-a768-405f-9123-be509146fef8"))
148 VectorChangedEventHandler<IKeyValuePair<HSTRING, IInspectable*>*>
149 : VectorChangedEventHandler_impl<IKeyValuePair<HSTRING, IInspectable*>*> {};
150
151 template <>
152 struct __declspec(uuid("079e2180-0c7a-4508-85ff-7a5f2b29b92b"))
153 IObservableVector<IKeyValuePair<HSTRING, IInspectable*>*>
154 : IObservableVector_impl<IKeyValuePair<HSTRING, IInspectable*>*> {};
155
156 } // namespace Collections
157 } // namespace Foundation
158 } // namespace Windows
159 } // namespace ABI
160
161 namespace base {
162 namespace win {
163
164 namespace {
165
166 using ABI::Windows::Foundation::IPropertyValue;
167 using ABI::Windows::Foundation::IPropertyValueStatics;
168 using ABI::Windows::Foundation::Uri;
169 using ABI::Windows::Foundation::Collections::CollectionChange;
170 using ABI::Windows::Foundation::Collections::CollectionChange_ItemChanged;
171 using ABI::Windows::Foundation::Collections::CollectionChange_ItemInserted;
172 using ABI::Windows::Foundation::Collections::CollectionChange_ItemRemoved;
173 using ABI::Windows::Foundation::Collections::CollectionChange_Reset;
174 using ABI::Windows::Foundation::Collections::IIterator;
175 using ABI::Windows::Foundation::Collections::IKeyValuePair;
176 using ABI::Windows::Foundation::Collections::IMapChangedEventArgs;
177 using ABI::Windows::Foundation::Collections::IMapView;
178 using ABI::Windows::Foundation::Collections::IObservableMap;
179 using ABI::Windows::Foundation::Collections::MapChangedEventHandler;
180 using Microsoft::WRL::ClassicCom;
181 using Microsoft::WRL::ComPtr;
182 using Microsoft::WRL::InhibitRoOriginateError;
183 using Microsoft::WRL::Make;
184 using Microsoft::WRL::RuntimeClass;
185 using Microsoft::WRL::RuntimeClassFlags;
186
187 const wchar_t kTestKey[] = L"Test key";
188 const wchar_t kTestValue[] = L"Test value";
189
190 const std::map<int, double, internal::Less> g_one{{1, 10.7}};
191 const std::map<int, double, internal::Less> g_two{{1, 10.7}, {2, 20.3}};
192
ResolveCoreWinRT()193 bool ResolveCoreWinRT() {
194 return base::win::ResolveCoreWinRTDelayload() &&
195 base::win::ScopedHString::ResolveCoreWinRTStringDelayload() &&
196 base::win::HStringReference::ResolveCoreWinRTStringDelayload();
197 }
198
GetPropertyValueStaticsActivationFactory(IPropertyValueStatics ** statics)199 HRESULT GetPropertyValueStaticsActivationFactory(
200 IPropertyValueStatics** statics) {
201 return base::win::GetActivationFactory<
202 IPropertyValueStatics, RuntimeClass_Windows_Foundation_PropertyValue>(
203 statics);
204 }
205
206 template <typename K, typename V>
207 class FakeMapChangedEventHandler
208 : public RuntimeClass<
209 RuntimeClassFlags<ClassicCom | InhibitRoOriginateError>,
210 MapChangedEventHandler<K, V>> {
211 public:
FakeMapChangedEventHandler(ComPtr<IObservableMap<K,V>> map)212 explicit FakeMapChangedEventHandler(ComPtr<IObservableMap<K, V>> map)
213 : map_(std::move(map)) {
214 EXPECT_HRESULT_SUCCEEDED(map_->add_MapChanged(this, &token_));
215 }
216
~FakeMapChangedEventHandler()217 ~FakeMapChangedEventHandler() override {
218 EXPECT_HRESULT_SUCCEEDED(map_->remove_MapChanged(token_));
219 }
220
221 // MapChangedEventHandler:
Invoke(IObservableMap<K,V> * sender,IMapChangedEventArgs<K> * e)222 IFACEMETHODIMP Invoke(IObservableMap<K, V>* sender,
223 IMapChangedEventArgs<K>* e) {
224 sender_ = sender;
225 EXPECT_HRESULT_SUCCEEDED(e->get_CollectionChange(&change_));
226 EXPECT_HRESULT_SUCCEEDED(e->get_Key(&key_));
227 return S_OK;
228 }
229
sender()230 IObservableMap<K, V>* sender() { return sender_; }
change()231 CollectionChange change() { return change_; }
key() const232 K key() const { return key_; }
233
234 private:
235 ComPtr<IObservableMap<K, V>> map_;
236 EventRegistrationToken token_;
237 IObservableMap<K, V>* sender_ = nullptr;
238 CollectionChange change_ = CollectionChange_Reset;
239 K key_ = 0;
240 };
241
242 } // namespace
243
TEST(MapTest,Lookup_Empty)244 TEST(MapTest, Lookup_Empty) {
245 auto map = Make<Map<int, double>>();
246 double value;
247 HRESULT hr = map->Lookup(1, &value);
248 EXPECT_EQ(E_BOUNDS, hr);
249 hr = map->Lookup(2, &value);
250 EXPECT_EQ(E_BOUNDS, hr);
251 }
252
TEST(MapTest,Lookup_One)253 TEST(MapTest, Lookup_One) {
254 auto map = Make<Map<int, double>>(g_one);
255 double value;
256 HRESULT hr = map->Lookup(1, &value);
257 EXPECT_EQ(S_OK, hr);
258 EXPECT_EQ(10.7, value);
259 hr = map->Lookup(2, &value);
260 EXPECT_EQ(E_BOUNDS, hr);
261 }
262
TEST(MapTest,Lookup_Two)263 TEST(MapTest, Lookup_Two) {
264 auto map = Make<Map<int, double>>(g_two);
265 double value;
266 HRESULT hr = map->Lookup(1, &value);
267 EXPECT_EQ(S_OK, hr);
268 EXPECT_EQ(10.7, value);
269 hr = map->Lookup(2, &value);
270 EXPECT_EQ(S_OK, hr);
271 EXPECT_EQ(20.3, value);
272 }
273
TEST(MapTest,get_Size_Empty)274 TEST(MapTest, get_Size_Empty) {
275 auto map = Make<Map<int, double>>();
276 unsigned int size;
277 HRESULT hr = map->get_Size(&size);
278 EXPECT_HRESULT_SUCCEEDED(hr);
279 EXPECT_EQ(0u, size);
280 }
281
TEST(MapTest,get_Size_One)282 TEST(MapTest, get_Size_One) {
283 auto map = Make<Map<int, double>>(g_one);
284 unsigned int size;
285 HRESULT hr = map->get_Size(&size);
286 EXPECT_HRESULT_SUCCEEDED(hr);
287 EXPECT_EQ(1u, size);
288 }
289
TEST(MapTest,get_Size_Two)290 TEST(MapTest, get_Size_Two) {
291 auto map = Make<Map<int, double>>(g_two);
292 unsigned int size;
293 HRESULT hr = map->get_Size(&size);
294 EXPECT_HRESULT_SUCCEEDED(hr);
295 EXPECT_EQ(2u, size);
296 }
297
TEST(MapTest,HasKey_Empty)298 TEST(MapTest, HasKey_Empty) {
299 auto map = Make<Map<int, double>>();
300 boolean found;
301 HRESULT hr = map->HasKey(1, &found);
302 EXPECT_HRESULT_SUCCEEDED(hr);
303 EXPECT_FALSE(found);
304 }
305
TEST(MapTest,HasKey_One)306 TEST(MapTest, HasKey_One) {
307 auto map = Make<Map<int, double>>(g_one);
308 boolean found;
309 HRESULT hr = map->HasKey(1, &found);
310 EXPECT_HRESULT_SUCCEEDED(hr);
311 EXPECT_TRUE(found);
312 hr = map->HasKey(2, &found);
313 EXPECT_HRESULT_SUCCEEDED(hr);
314 EXPECT_FALSE(found);
315 }
316
TEST(MapTest,HasKey_Two)317 TEST(MapTest, HasKey_Two) {
318 auto map = Make<Map<int, double>>(g_two);
319 boolean found;
320 HRESULT hr = map->HasKey(1, &found);
321 EXPECT_HRESULT_SUCCEEDED(hr);
322 EXPECT_TRUE(found);
323 hr = map->HasKey(2, &found);
324 EXPECT_HRESULT_SUCCEEDED(hr);
325 EXPECT_TRUE(found);
326 }
327
TEST(MapTest,GetView)328 TEST(MapTest, GetView) {
329 auto map = Make<Map<int, double>>(g_two);
330 ComPtr<IMapView<int, double>> view;
331 HRESULT hr = map->GetView(&view);
332 EXPECT_HRESULT_SUCCEEDED(hr);
333
334 double value;
335 hr = view->Lookup(1, &value);
336 EXPECT_EQ(S_OK, hr);
337 EXPECT_EQ(10.7, value);
338 hr = view->Lookup(2, &value);
339 EXPECT_EQ(S_OK, hr);
340 EXPECT_EQ(20.3, value);
341
342 unsigned int size;
343 hr = view->get_Size(&size);
344 EXPECT_HRESULT_SUCCEEDED(hr);
345 EXPECT_EQ(2u, size);
346
347 boolean found;
348 hr = view->HasKey(1, &found);
349 EXPECT_HRESULT_SUCCEEDED(hr);
350 EXPECT_TRUE(found);
351 hr = view->HasKey(2, &found);
352 EXPECT_HRESULT_SUCCEEDED(hr);
353 EXPECT_TRUE(found);
354
355 // The view is supposed to be a snapshot of the map when it's created.
356 // Further modifications to the map will invalidate the view.
357 boolean replaced;
358 hr = map->Insert(3, 11.2, &replaced);
359 EXPECT_HRESULT_SUCCEEDED(hr);
360 EXPECT_FALSE(replaced);
361
362 hr = view->Lookup(1, &value);
363 EXPECT_EQ(E_CHANGED_STATE, hr);
364
365 hr = view->get_Size(&size);
366 EXPECT_EQ(E_CHANGED_STATE, hr);
367
368 hr = view->HasKey(1, &found);
369 EXPECT_EQ(E_CHANGED_STATE, hr);
370 }
371
TEST(MapTest,Insert_Empty)372 TEST(MapTest, Insert_Empty) {
373 auto map = Make<Map<int, double>>();
374 auto handler = Make<FakeMapChangedEventHandler<int, double>>(map.Get());
375 boolean replaced;
376 HRESULT hr = map->Insert(1, 11.2, &replaced);
377 EXPECT_HRESULT_SUCCEEDED(hr);
378 EXPECT_FALSE(replaced);
379 EXPECT_EQ(map.Get(), handler->sender());
380 EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
381 EXPECT_EQ(1, handler->key());
382 double value;
383 hr = map->Lookup(1, &value);
384 EXPECT_EQ(S_OK, hr);
385 EXPECT_EQ(11.2, value);
386 }
387
TEST(MapTest,Insert_One)388 TEST(MapTest, Insert_One) {
389 auto map = Make<Map<int, double>>(g_one);
390 auto handler = Make<FakeMapChangedEventHandler<int, double>>(map.Get());
391 double value;
392 HRESULT hr = map->Lookup(1, &value);
393 EXPECT_EQ(S_OK, hr);
394 EXPECT_EQ(10.7, value);
395 boolean replaced;
396 hr = map->Insert(1, 11.2, &replaced);
397 EXPECT_HRESULT_SUCCEEDED(hr);
398 EXPECT_TRUE(replaced);
399 EXPECT_EQ(map.Get(), handler->sender());
400 EXPECT_EQ(CollectionChange_ItemChanged, handler->change());
401 EXPECT_EQ(1, handler->key());
402 hr = map->Lookup(1, &value);
403 EXPECT_EQ(S_OK, hr);
404 EXPECT_EQ(11.2, value);
405 }
406
TEST(MapTest,Remove_One)407 TEST(MapTest, Remove_One) {
408 auto map = Make<Map<int, double>>(g_one);
409 auto handler = Make<FakeMapChangedEventHandler<int, double>>(map.Get());
410 double value;
411 HRESULT hr = map->Lookup(1, &value);
412 EXPECT_EQ(S_OK, hr);
413 EXPECT_EQ(10.7, value);
414 hr = map->Remove(1);
415 EXPECT_EQ(S_OK, hr);
416 EXPECT_EQ(map.Get(), handler->sender());
417 EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
418 EXPECT_EQ(1, handler->key());
419 hr = map->Lookup(1, &value);
420 EXPECT_EQ(E_BOUNDS, hr);
421 }
422
TEST(MapTest,Clear)423 TEST(MapTest, Clear) {
424 auto map = Make<Map<int, double>>(g_one);
425 auto handler = Make<FakeMapChangedEventHandler<int, double>>(map.Get());
426 HRESULT hr = map->Clear();
427 EXPECT_EQ(map.Get(), handler->sender());
428 EXPECT_EQ(CollectionChange_Reset, handler->change());
429 EXPECT_EQ(0, handler->key());
430 unsigned int size;
431 hr = map->get_Size(&size);
432 EXPECT_HRESULT_SUCCEEDED(hr);
433 EXPECT_EQ(0u, size);
434 }
435
436 // Uri* is an AggregateType which ABI representation is IUriRuntimeClass*.
TEST(MapTest,ConstructWithAggregateTypes)437 TEST(MapTest, ConstructWithAggregateTypes) {
438 auto map = Make<Map<Uri*, Uri*>>();
439 unsigned size;
440 HRESULT hr = map->get_Size(&size);
441 EXPECT_HRESULT_SUCCEEDED(hr);
442 EXPECT_EQ(0u, size);
443 }
444
TEST(MapTest,First)445 TEST(MapTest, First) {
446 auto map = Make<Map<int, double>>(g_two);
447 ComPtr<IIterator<IKeyValuePair<int, double>*>> iterator;
448
449 // Test iteration.
450 HRESULT hr = map->First(&iterator);
451 EXPECT_HRESULT_SUCCEEDED(hr);
452 boolean has_current;
453 hr = iterator->get_HasCurrent(&has_current);
454 EXPECT_HRESULT_SUCCEEDED(hr);
455 EXPECT_TRUE(has_current);
456 ComPtr<IKeyValuePair<int, double>> current;
457 hr = iterator->get_Current(¤t);
458 EXPECT_HRESULT_SUCCEEDED(hr);
459 int key;
460 hr = current->get_Key(&key);
461 EXPECT_HRESULT_SUCCEEDED(hr);
462 EXPECT_EQ(1, key);
463 double value;
464 hr = current->get_Value(&value);
465 EXPECT_HRESULT_SUCCEEDED(hr);
466 EXPECT_EQ(10.7, value);
467 hr = iterator->MoveNext(&has_current);
468 EXPECT_HRESULT_SUCCEEDED(hr);
469 EXPECT_TRUE(has_current);
470 hr = iterator->get_Current(¤t);
471 EXPECT_HRESULT_SUCCEEDED(hr);
472 hr = current->get_Key(&key);
473 EXPECT_HRESULT_SUCCEEDED(hr);
474 EXPECT_EQ(2, key);
475 hr = current->get_Value(&value);
476 EXPECT_HRESULT_SUCCEEDED(hr);
477 EXPECT_EQ(20.3, value);
478 hr = iterator->MoveNext(&has_current);
479 EXPECT_HRESULT_SUCCEEDED(hr);
480 EXPECT_FALSE(has_current);
481 hr = iterator->get_Current(¤t);
482 EXPECT_FALSE(SUCCEEDED(hr));
483 EXPECT_EQ(E_BOUNDS, hr);
484 hr = iterator->MoveNext(&has_current);
485 EXPECT_FALSE(SUCCEEDED(hr));
486 EXPECT_EQ(E_BOUNDS, hr);
487 EXPECT_FALSE(has_current);
488
489 // Test invalidation.
490 hr = map->First(&iterator);
491 EXPECT_HRESULT_SUCCEEDED(hr);
492 hr = iterator->get_HasCurrent(&has_current);
493 EXPECT_HRESULT_SUCCEEDED(hr);
494 EXPECT_TRUE(has_current);
495 boolean replaced;
496 hr = map->Insert(3, 11.2, &replaced);
497 EXPECT_HRESULT_SUCCEEDED(hr);
498 EXPECT_FALSE(replaced);
499 hr = iterator->get_HasCurrent(&has_current);
500 EXPECT_EQ(E_CHANGED_STATE, hr);
501 hr = iterator->MoveNext(&has_current);
502 EXPECT_EQ(E_CHANGED_STATE, hr);
503 }
504
TEST(MapTest,Properties)505 TEST(MapTest, Properties) {
506 // This test case validates Map against Windows property key system,
507 // which is used to store WinRT device properties.
508 if (GetVersion() < Version::WIN8)
509 return;
510
511 ASSERT_TRUE(ResolveCoreWinRT());
512 ASSERT_HRESULT_SUCCEEDED(base::win::RoInitialize(RO_INIT_MULTITHREADED));
513
514 auto map = Make<Map<HSTRING, IInspectable*>>();
515
516 ComPtr<IPropertyValueStatics> property_value_statics;
517 HRESULT hr =
518 GetPropertyValueStaticsActivationFactory(&property_value_statics);
519 EXPECT_HRESULT_SUCCEEDED(hr);
520
521 base::win::HStringReference value_stringref_inserted(kTestValue);
522 ComPtr<IPropertyValue> value_inserted;
523 hr = property_value_statics->CreateString(value_stringref_inserted.Get(),
524 &value_inserted);
525 EXPECT_HRESULT_SUCCEEDED(hr);
526
527 base::win::HStringReference key_stringref_inserted(kTestKey);
528 boolean replaced;
529 hr = map->Insert(key_stringref_inserted.Get(), value_inserted.Get(),
530 &replaced);
531 EXPECT_HRESULT_SUCCEEDED(hr);
532
533 base::win::HStringReference key_stringref_lookedup(kTestKey);
534 ComPtr<IInspectable> value_inspectable_lookedup;
535 hr = map->Lookup(key_stringref_lookedup.Get(), &value_inspectable_lookedup);
536 EXPECT_HRESULT_SUCCEEDED(hr);
537
538 ComPtr<IPropertyValue> value_lookedup;
539 hr = value_inspectable_lookedup.As(&value_lookedup);
540 EXPECT_HRESULT_SUCCEEDED(hr);
541
542 HSTRING value_string_lookedup;
543 hr = value_lookedup->GetString(&value_string_lookedup);
544 EXPECT_HRESULT_SUCCEEDED(hr);
545
546 auto value_stringref_lookedup = ScopedHString(value_string_lookedup);
547 EXPECT_EQ(kTestValue, value_stringref_lookedup.Get());
548 }
549
550 } // namespace win
551 } // namespace base
552