map_unittest.cc 17 KB

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