• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors
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/vector.h"
6 
7 #include <windows.foundation.h>
8 #include <wrl/client.h>
9 
10 #include "base/memory/raw_ptr.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 namespace ABI {
15 namespace Windows {
16 namespace Foundation {
17 namespace Collections {
18 
19 // Note: As UWP does not provide int specializations for IObservableVector and
20 // VectorChangedEventHandler we need to supply our own. UUIDs were generated
21 // using `uuidgen`.
22 template <>
23 struct __declspec(uuid("21c2c195-91a4-4fce-8346-2a85f4478e26"))
24     IObservableVector<int> : IObservableVector_impl<int> {};
25 
26 template <>
27 struct __declspec(uuid("86b0071e-5e72-4d3d-82d3-420ebd2b2716"))
28     VectorChangedEventHandler<int> : VectorChangedEventHandler_impl<int> {};
29 
30 namespace {
31 using UriPtrAggregate = Internal::AggregateType<Uri*, IUriRuntimeClass*>;
32 }
33 
34 template <>
35 struct __declspec(uuid("12311764-f245-4245-9dc9-bab258eddd4e"))
36     IObservableVector<Uri*> : IObservableVector_impl<UriPtrAggregate> {};
37 
38 template <>
39 struct __declspec(uuid("050e4b78-71b2-43ff-bf7c-f6ba589aced9"))
40     VectorChangedEventHandler<Uri*>
41     : VectorChangedEventHandler_impl<UriPtrAggregate> {};
42 
43 #ifdef NTDDI_WIN10_VB  // Windows 10.0.19041
44 // Specialization templates that used to be in windows.foundation.h, removed in
45 // the 10.0.19041.0 SDK, so placed here instead.
46 template <>
47 struct __declspec(uuid("b939af5b-b45d-5489-9149-61442c1905fe")) IVector<int>
48     : IVector_impl<int> {};
49 
50 template <>
51 struct __declspec(uuid("8d720cdf-3934-5d3f-9a55-40e8063b086a")) IVectorView<int>
52     : IVectorView_impl<int> {};
53 
54 template <>
55 struct __declspec(uuid("bfea7f78-50c2-5f1d-a6ea-9e978d2699ff")) IIterator<int>
56     : IIterator_impl<int> {};
57 
58 template <>
59 struct __declspec(uuid("81a643fb-f51c-5565-83c4-f96425777b66")) IIterable<int>
60     : IIterable_impl<int> {};
61 
62 template <>
63 struct __declspec(uuid("0d82bd8d-fe62-5d67-a7b9-7886dd75bc4e")) IVector<Uri*>
64     : IVector_impl<Internal::AggregateType<Uri*, IUriRuntimeClass*>> {};
65 
66 template <>
67 struct __declspec(uuid("4b8385bd-a2cd-5ff1-bf74-7ea580423e50"))
68     IVectorView<Uri*>
69     : IVectorView_impl<Internal::AggregateType<Uri*, IUriRuntimeClass*>> {};
70 
71 template <>
72 struct __declspec(uuid("1c157d0f-5efe-5cec-bbd6-0c6ce9af07a5")) IIterator<Uri*>
73     : IIterator_impl<Internal::AggregateType<Uri*, IUriRuntimeClass*>> {};
74 
75 template <>
76 struct __declspec(uuid("b0d63b78-78ad-5e31-b6d8-e32a0e16c447")) IIterable<Uri*>
77     : IIterable_impl<Internal::AggregateType<Uri*, IUriRuntimeClass*>> {};
78 #endif
79 
80 }  // namespace Collections
81 }  // namespace Foundation
82 }  // namespace Windows
83 }  // namespace ABI
84 
85 namespace base {
86 namespace win {
87 
88 namespace {
89 
90 using ABI::Windows::Foundation::Uri;
91 using ABI::Windows::Foundation::Collections::CollectionChange;
92 using ABI::Windows::Foundation::Collections::CollectionChange_ItemChanged;
93 using ABI::Windows::Foundation::Collections::CollectionChange_ItemInserted;
94 using ABI::Windows::Foundation::Collections::CollectionChange_ItemRemoved;
95 using ABI::Windows::Foundation::Collections::CollectionChange_Reset;
96 using ABI::Windows::Foundation::Collections::IIterator;
97 using ABI::Windows::Foundation::Collections::IObservableVector;
98 using ABI::Windows::Foundation::Collections::IVectorChangedEventArgs;
99 using ABI::Windows::Foundation::Collections::IVectorView;
100 using ABI::Windows::Foundation::Collections::VectorChangedEventHandler;
101 using Microsoft::WRL::ClassicCom;
102 using Microsoft::WRL::ComPtr;
103 using Microsoft::WRL::InhibitRoOriginateError;
104 using Microsoft::WRL::Make;
105 using Microsoft::WRL::RuntimeClass;
106 using Microsoft::WRL::RuntimeClassFlags;
107 using ::testing::ElementsAre;
108 using ::testing::IsEmpty;
109 
110 template <typename T>
111 class FakeVectorChangedEventHandler
112     : public RuntimeClass<
113           RuntimeClassFlags<ClassicCom | InhibitRoOriginateError>,
114           VectorChangedEventHandler<T>> {
115  public:
FakeVectorChangedEventHandler(ComPtr<IObservableVector<T>> vector)116   explicit FakeVectorChangedEventHandler(ComPtr<IObservableVector<T>> vector)
117       : vector_(std::move(vector)) {
118     EXPECT_TRUE(SUCCEEDED(vector_->add_VectorChanged(this, &token_)));
119   }
120 
~FakeVectorChangedEventHandler()121   ~FakeVectorChangedEventHandler() override {
122     EXPECT_TRUE(SUCCEEDED(vector_->remove_VectorChanged(token_)));
123   }
124 
125   // VectorChangedEventHandler:
Invoke(IObservableVector<T> * sender,IVectorChangedEventArgs * e)126   IFACEMETHODIMP Invoke(IObservableVector<T>* sender,
127                         IVectorChangedEventArgs* e) {
128     sender_ = sender;
129     EXPECT_TRUE(SUCCEEDED(e->get_CollectionChange(&change_)));
130     EXPECT_TRUE(SUCCEEDED(e->get_Index(&index_)));
131     return S_OK;
132   }
133 
sender()134   IObservableVector<T>* sender() { return sender_; }
change()135   CollectionChange change() { return change_; }
index()136   unsigned int index() { return index_; }
137 
138  private:
139   ComPtr<IObservableVector<T>> vector_;
140   EventRegistrationToken token_;
141   raw_ptr<IObservableVector<T>> sender_ = nullptr;
142   CollectionChange change_ = CollectionChange_Reset;
143   unsigned int index_ = 0;
144 };
145 
146 // The ReplaceAll test requires a non-const data() member, thus these vectors
147 // are not declared const, even though no test mutates them.
148 std::vector<int> g_empty;
149 std::vector<int> g_one = {1};
150 std::vector<int> g_one_two = {1, 2};
151 std::vector<int> g_one_two_three = {1, 2, 3};
152 
153 }  // namespace
154 
TEST(VectorTest,GetAt_Empty)155 TEST(VectorTest, GetAt_Empty) {
156   auto vec = Make<Vector<int>>();
157   int value;
158   HRESULT hr = vec->GetAt(0, &value);
159   EXPECT_EQ(E_BOUNDS, hr);
160 }
161 
TEST(VectorTest,GetAt_One)162 TEST(VectorTest, GetAt_One) {
163   auto vec = Make<Vector<int>>(g_one);
164   int value;
165   HRESULT hr = vec->GetAt(0, &value);
166   EXPECT_TRUE(SUCCEEDED(hr));
167   EXPECT_EQ(1, value);
168 
169   hr = vec->GetAt(1, &value);
170   EXPECT_EQ(E_BOUNDS, hr);
171 }
172 
TEST(VectorTest,GetAt_OneTwo)173 TEST(VectorTest, GetAt_OneTwo) {
174   auto vec = Make<Vector<int>>(g_one_two);
175   int value;
176   HRESULT hr = vec->GetAt(0, &value);
177   EXPECT_TRUE(SUCCEEDED(hr));
178   EXPECT_EQ(1, value);
179 
180   hr = vec->GetAt(1, &value);
181   EXPECT_TRUE(SUCCEEDED(hr));
182   EXPECT_EQ(2, value);
183 
184   hr = vec->GetAt(2, &value);
185   EXPECT_EQ(E_BOUNDS, hr);
186 }
187 
TEST(VectorTest,GetAt_OneTwoThree)188 TEST(VectorTest, GetAt_OneTwoThree) {
189   auto vec = Make<Vector<int>>(g_one_two_three);
190   int value;
191   HRESULT hr = vec->GetAt(0, &value);
192   EXPECT_TRUE(SUCCEEDED(hr));
193   EXPECT_EQ(1, value);
194 
195   hr = vec->GetAt(1, &value);
196   EXPECT_TRUE(SUCCEEDED(hr));
197   EXPECT_EQ(2, value);
198 
199   hr = vec->GetAt(2, &value);
200   EXPECT_TRUE(SUCCEEDED(hr));
201   EXPECT_EQ(3, value);
202 
203   hr = vec->GetAt(3, &value);
204   EXPECT_EQ(E_BOUNDS, hr);
205 }
206 
TEST(VectorTest,get_Size_Empty)207 TEST(VectorTest, get_Size_Empty) {
208   auto vec = Make<Vector<int>>();
209   unsigned size;
210   HRESULT hr = vec->get_Size(&size);
211   EXPECT_TRUE(SUCCEEDED(hr));
212   EXPECT_EQ(0u, size);
213 }
214 
TEST(VectorTest,get_Size_One)215 TEST(VectorTest, get_Size_One) {
216   auto vec = Make<Vector<int>>(g_one);
217   unsigned size;
218   HRESULT hr = vec->get_Size(&size);
219   EXPECT_TRUE(SUCCEEDED(hr));
220   EXPECT_EQ(1u, size);
221 }
222 
TEST(VectorTest,get_Size_OneTwo)223 TEST(VectorTest, get_Size_OneTwo) {
224   auto vec = Make<Vector<int>>(g_one_two);
225   unsigned size;
226   HRESULT hr = vec->get_Size(&size);
227   EXPECT_TRUE(SUCCEEDED(hr));
228   EXPECT_EQ(2u, size);
229 }
230 
TEST(VectorTest,get_Size_OneTwoThree)231 TEST(VectorTest, get_Size_OneTwoThree) {
232   auto vec = Make<Vector<int>>(g_one_two_three);
233   unsigned size;
234   HRESULT hr = vec->get_Size(&size);
235   EXPECT_TRUE(SUCCEEDED(hr));
236   EXPECT_EQ(3u, size);
237 }
238 
TEST(VectorTest,GetView)239 TEST(VectorTest, GetView) {
240   auto vec = Make<Vector<int>>(g_one_two_three);
241   ComPtr<IVectorView<int>> view;
242   HRESULT hr = vec->GetView(&view);
243   EXPECT_TRUE(SUCCEEDED(hr));
244 
245   int value;
246   hr = view->GetAt(0, &value);
247   EXPECT_TRUE(SUCCEEDED(hr));
248   EXPECT_EQ(1, value);
249 
250   hr = view->GetAt(1, &value);
251   EXPECT_TRUE(SUCCEEDED(hr));
252   EXPECT_EQ(2, value);
253 
254   hr = view->GetAt(2, &value);
255   EXPECT_TRUE(SUCCEEDED(hr));
256   EXPECT_EQ(3, value);
257 
258   hr = view->GetAt(3, &value);
259   EXPECT_EQ(E_BOUNDS, hr);
260 
261   unsigned size;
262   hr = view->get_Size(&size);
263   EXPECT_TRUE(SUCCEEDED(hr));
264   EXPECT_EQ(3u, size);
265 
266   unsigned index;
267   boolean found;
268   hr = view->IndexOf(1, &index, &found);
269   EXPECT_TRUE(SUCCEEDED(hr));
270   EXPECT_EQ(0u, index);
271   EXPECT_TRUE(found);
272 
273   hr = view->IndexOf(2, &index, &found);
274   EXPECT_TRUE(SUCCEEDED(hr));
275   EXPECT_EQ(1u, index);
276   EXPECT_TRUE(found);
277 
278   hr = view->IndexOf(3, &index, &found);
279   EXPECT_TRUE(SUCCEEDED(hr));
280   EXPECT_EQ(2u, index);
281   EXPECT_TRUE(found);
282 
283   hr = view->IndexOf(4, &index, &found);
284   EXPECT_TRUE(SUCCEEDED(hr));
285   EXPECT_EQ(0u, index);
286   EXPECT_FALSE(found);
287 
288   std::vector<int> copy(3);
289   unsigned actual;
290   hr = view->GetMany(0, copy.size(), copy.data(), &actual);
291   EXPECT_TRUE(SUCCEEDED(hr));
292   EXPECT_EQ(3u, actual);
293   EXPECT_THAT(copy, ElementsAre(1, 2, 3));
294 
295   hr = vec->Append(4);
296   EXPECT_TRUE(SUCCEEDED(hr));
297 
298   // The view is supposed to be a snapshot of the vector when it's created.
299   // Further modifications to the vector will invalidate the view.
300   hr = view->GetAt(3, &value);
301   EXPECT_EQ(E_CHANGED_STATE, hr);
302 
303   hr = view->get_Size(&size);
304   EXPECT_EQ(E_CHANGED_STATE, hr);
305 
306   hr = view->IndexOf(1, &index, &found);
307   EXPECT_EQ(E_CHANGED_STATE, hr);
308 
309   hr = view->GetMany(0, copy.size(), copy.data(), &actual);
310   EXPECT_EQ(E_CHANGED_STATE, hr);
311 }
312 
TEST(VectorTest,IndexOf_Empty)313 TEST(VectorTest, IndexOf_Empty) {
314   auto vec = Make<Vector<int>>();
315   unsigned index;
316   boolean found;
317   HRESULT hr = vec->IndexOf(1, &index, &found);
318   EXPECT_TRUE(SUCCEEDED(hr));
319   EXPECT_EQ(0u, index);
320   EXPECT_FALSE(found);
321 }
322 
TEST(VectorTest,IndexOf_One)323 TEST(VectorTest, IndexOf_One) {
324   auto vec = Make<Vector<int>>(g_one);
325   unsigned index;
326   boolean found;
327 
328   HRESULT hr = vec->IndexOf(1, &index, &found);
329   EXPECT_TRUE(SUCCEEDED(hr));
330   EXPECT_EQ(0u, index);
331   EXPECT_TRUE(found);
332 
333   hr = vec->IndexOf(2, &index, &found);
334   EXPECT_TRUE(SUCCEEDED(hr));
335   EXPECT_EQ(0u, index);
336   EXPECT_FALSE(found);
337 }
338 
TEST(VectorTest,IndexOf_OneTwo)339 TEST(VectorTest, IndexOf_OneTwo) {
340   auto vec = Make<Vector<int>>(g_one_two);
341   unsigned index;
342   boolean found;
343 
344   HRESULT hr = vec->IndexOf(1, &index, &found);
345   EXPECT_TRUE(SUCCEEDED(hr));
346   EXPECT_EQ(0u, index);
347   EXPECT_TRUE(found);
348 
349   hr = vec->IndexOf(2, &index, &found);
350   EXPECT_TRUE(SUCCEEDED(hr));
351   EXPECT_EQ(1u, index);
352   EXPECT_TRUE(found);
353 
354   hr = vec->IndexOf(3, &index, &found);
355   EXPECT_TRUE(SUCCEEDED(hr));
356   EXPECT_EQ(0u, index);
357   EXPECT_FALSE(found);
358 }
359 
TEST(VectorTest,IndexOf_OneTwoThree)360 TEST(VectorTest, IndexOf_OneTwoThree) {
361   auto vec = Make<Vector<int>>(g_one_two_three);
362   unsigned index;
363   boolean found;
364 
365   HRESULT hr = vec->IndexOf(1, &index, &found);
366   EXPECT_TRUE(SUCCEEDED(hr));
367   EXPECT_EQ(0u, index);
368   EXPECT_TRUE(found);
369 
370   hr = vec->IndexOf(2, &index, &found);
371   EXPECT_TRUE(SUCCEEDED(hr));
372   EXPECT_EQ(1u, index);
373   EXPECT_TRUE(found);
374 
375   hr = vec->IndexOf(3, &index, &found);
376   EXPECT_TRUE(SUCCEEDED(hr));
377   EXPECT_EQ(2u, index);
378   EXPECT_TRUE(found);
379 
380   hr = vec->IndexOf(4, &index, &found);
381   EXPECT_TRUE(SUCCEEDED(hr));
382   EXPECT_EQ(0u, index);
383   EXPECT_FALSE(found);
384 }
385 
TEST(VectorTest,SetAt)386 TEST(VectorTest, SetAt) {
387   auto vec = Make<Vector<int>>(g_one_two_three);
388   auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
389 
390   HRESULT hr = vec->SetAt(0, 4);
391   EXPECT_TRUE(SUCCEEDED(hr));
392   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(4, 2, 3));
393   EXPECT_EQ(vec.Get(), handler->sender());
394   EXPECT_EQ(CollectionChange_ItemChanged, handler->change());
395   EXPECT_EQ(0u, handler->index());
396 
397   hr = vec->SetAt(1, 5);
398   EXPECT_TRUE(SUCCEEDED(hr));
399   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(4, 5, 3));
400   EXPECT_EQ(vec.Get(), handler->sender());
401   EXPECT_EQ(CollectionChange_ItemChanged, handler->change());
402   EXPECT_EQ(1u, handler->index());
403 
404   hr = vec->SetAt(2, 6);
405   EXPECT_TRUE(SUCCEEDED(hr));
406   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(4, 5, 6));
407   EXPECT_EQ(vec.Get(), handler->sender());
408   EXPECT_EQ(CollectionChange_ItemChanged, handler->change());
409   EXPECT_EQ(2u, handler->index());
410 
411   hr = vec->SetAt(3, 7);
412   EXPECT_EQ(E_BOUNDS, hr);
413 }
414 
TEST(VectorTest,InsertAt)415 TEST(VectorTest, InsertAt) {
416   auto vec = Make<Vector<int>>(g_one_two_three);
417   auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
418   HRESULT hr = vec->InsertAt(4, 4);
419   EXPECT_EQ(E_BOUNDS, hr);
420 
421   hr = vec->InsertAt(3, 4);
422   EXPECT_TRUE(SUCCEEDED(hr));
423   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2, 3, 4));
424   EXPECT_EQ(vec.Get(), handler->sender());
425   EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
426   EXPECT_EQ(3u, handler->index());
427 
428   hr = vec->InsertAt(2, 5);
429   EXPECT_TRUE(SUCCEEDED(hr));
430   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2, 5, 3, 4));
431   EXPECT_EQ(vec.Get(), handler->sender());
432   EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
433   EXPECT_EQ(2u, handler->index());
434 
435   hr = vec->InsertAt(1, 6);
436   EXPECT_TRUE(SUCCEEDED(hr));
437   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 6, 2, 5, 3, 4));
438   EXPECT_EQ(vec.Get(), handler->sender());
439   EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
440   EXPECT_EQ(1u, handler->index());
441 
442   hr = vec->InsertAt(0, 7);
443   EXPECT_TRUE(SUCCEEDED(hr));
444   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(7, 1, 6, 2, 5, 3, 4));
445   EXPECT_EQ(vec.Get(), handler->sender());
446   EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
447   EXPECT_EQ(0u, handler->index());
448 }
449 
TEST(VectorTest,RemoveAt)450 TEST(VectorTest, RemoveAt) {
451   auto vec = Make<Vector<int>>(g_one_two_three);
452   auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
453   HRESULT hr = vec->RemoveAt(3);
454   EXPECT_EQ(E_BOUNDS, hr);
455 
456   hr = vec->RemoveAt(2);
457   EXPECT_TRUE(SUCCEEDED(hr));
458   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2));
459   EXPECT_EQ(vec.Get(), handler->sender());
460   EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
461   EXPECT_EQ(2u, handler->index());
462 
463   hr = vec->RemoveAt(2);
464   EXPECT_EQ(E_BOUNDS, hr);
465 
466   hr = vec->RemoveAt(1);
467   EXPECT_TRUE(SUCCEEDED(hr));
468   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1));
469   EXPECT_EQ(vec.Get(), handler->sender());
470   EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
471   EXPECT_EQ(1u, handler->index());
472 
473   hr = vec->RemoveAt(1);
474   EXPECT_EQ(E_BOUNDS, hr);
475 
476   hr = vec->RemoveAt(0);
477   EXPECT_TRUE(SUCCEEDED(hr));
478   EXPECT_THAT(vec->vector_for_testing(), IsEmpty());
479   EXPECT_EQ(vec.Get(), handler->sender());
480   EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
481   EXPECT_EQ(0u, handler->index());
482 
483   hr = vec->RemoveAt(0);
484   EXPECT_EQ(E_BOUNDS, hr);
485 }
486 
TEST(VectorTest,Append)487 TEST(VectorTest, Append) {
488   auto vec = Make<Vector<int>>();
489   auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
490   HRESULT hr = vec->Append(1);
491   EXPECT_TRUE(SUCCEEDED(hr));
492   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1));
493   EXPECT_EQ(vec.Get(), handler->sender());
494   EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
495   EXPECT_EQ(0u, handler->index());
496 
497   hr = vec->Append(2);
498   EXPECT_TRUE(SUCCEEDED(hr));
499   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2));
500   EXPECT_EQ(vec.Get(), handler->sender());
501   EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
502   EXPECT_EQ(1u, handler->index());
503 
504   hr = vec->Append(3);
505   EXPECT_TRUE(SUCCEEDED(hr));
506   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2, 3));
507   EXPECT_EQ(vec.Get(), handler->sender());
508   EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
509   EXPECT_EQ(2u, handler->index());
510 }
511 
TEST(VectorTest,RemoveAtEnd)512 TEST(VectorTest, RemoveAtEnd) {
513   auto vec = Make<Vector<int>>(g_one_two_three);
514   auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
515   HRESULT hr = vec->RemoveAtEnd();
516   EXPECT_TRUE(SUCCEEDED(hr));
517   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2));
518   EXPECT_EQ(vec.Get(), handler->sender());
519   EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
520   EXPECT_EQ(2u, handler->index());
521 
522   hr = vec->RemoveAtEnd();
523   EXPECT_TRUE(SUCCEEDED(hr));
524   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1));
525   EXPECT_EQ(vec.Get(), handler->sender());
526   EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
527   EXPECT_EQ(1u, handler->index());
528 
529   hr = vec->RemoveAtEnd();
530   EXPECT_TRUE(SUCCEEDED(hr));
531   EXPECT_THAT(vec->vector_for_testing(), IsEmpty());
532   EXPECT_EQ(vec.Get(), handler->sender());
533   EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
534   EXPECT_EQ(0u, handler->index());
535 
536   hr = vec->RemoveAtEnd();
537   EXPECT_EQ(E_BOUNDS, hr);
538 }
539 
TEST(VectorTest,Clear)540 TEST(VectorTest, Clear) {
541   auto vec = Make<Vector<int>>(g_one_two_three);
542   auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
543   HRESULT hr = vec->Clear();
544   EXPECT_TRUE(SUCCEEDED(hr));
545   EXPECT_THAT(vec->vector_for_testing(), IsEmpty());
546   EXPECT_EQ(vec.Get(), handler->sender());
547   EXPECT_EQ(CollectionChange_Reset, handler->change());
548   EXPECT_EQ(0u, handler->index());
549 }
550 
TEST(VectorTest,GetMany)551 TEST(VectorTest, GetMany) {
552   auto vec = Make<Vector<int>>(g_one_two_three);
553   std::vector<int> copy;
554   unsigned actual;
555   HRESULT hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
556   EXPECT_TRUE(SUCCEEDED(hr));
557   EXPECT_EQ(0u, actual);
558   EXPECT_THAT(copy, IsEmpty());
559 
560   copy.resize(1);
561   hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
562   EXPECT_TRUE(SUCCEEDED(hr));
563   EXPECT_EQ(1u, actual);
564   EXPECT_THAT(copy, ElementsAre(1));
565 
566   copy.resize(2);
567   hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
568   EXPECT_TRUE(SUCCEEDED(hr));
569   EXPECT_EQ(2u, actual);
570   EXPECT_THAT(copy, ElementsAre(1, 2));
571 
572   copy.resize(3);
573   hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
574   EXPECT_TRUE(SUCCEEDED(hr));
575   EXPECT_EQ(3u, actual);
576   EXPECT_THAT(copy, ElementsAre(1, 2, 3));
577 
578   copy.resize(4);
579   hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
580   EXPECT_TRUE(SUCCEEDED(hr));
581   EXPECT_EQ(3u, actual);
582   EXPECT_THAT(copy, ElementsAre(1, 2, 3, 0));
583 
584   copy.resize(0);
585   hr = vec->GetMany(1, copy.size(), copy.data(), &actual);
586   EXPECT_TRUE(SUCCEEDED(hr));
587   EXPECT_EQ(0u, actual);
588   EXPECT_THAT(copy, IsEmpty());
589 
590   copy.resize(1);
591   hr = vec->GetMany(1, copy.size(), copy.data(), &actual);
592   EXPECT_TRUE(SUCCEEDED(hr));
593   EXPECT_EQ(1u, actual);
594   EXPECT_THAT(copy, ElementsAre(2));
595 
596   copy.resize(2);
597   hr = vec->GetMany(1, copy.size(), copy.data(), &actual);
598   EXPECT_TRUE(SUCCEEDED(hr));
599   EXPECT_EQ(2u, actual);
600   EXPECT_THAT(copy, ElementsAre(2, 3));
601 
602   copy.resize(3);
603   hr = vec->GetMany(1, copy.size(), copy.data(), &actual);
604   EXPECT_TRUE(SUCCEEDED(hr));
605   EXPECT_EQ(2u, actual);
606   EXPECT_THAT(copy, ElementsAre(2, 3, 0));
607 
608   copy.resize(0);
609   hr = vec->GetMany(2, copy.size(), copy.data(), &actual);
610   EXPECT_TRUE(SUCCEEDED(hr));
611   EXPECT_EQ(0u, actual);
612   EXPECT_THAT(copy, IsEmpty());
613 
614   copy.resize(1);
615   hr = vec->GetMany(2, copy.size(), copy.data(), &actual);
616   EXPECT_TRUE(SUCCEEDED(hr));
617   EXPECT_EQ(1u, actual);
618   EXPECT_THAT(copy, ElementsAre(3));
619 
620   copy.resize(2);
621   hr = vec->GetMany(2, copy.size(), copy.data(), &actual);
622   EXPECT_TRUE(SUCCEEDED(hr));
623   EXPECT_EQ(1u, actual);
624   EXPECT_THAT(copy, ElementsAre(3, 0));
625 
626   hr = vec->GetMany(3, copy.size(), copy.data(), &actual);
627   EXPECT_TRUE(SUCCEEDED(hr));
628   EXPECT_EQ(0u, actual);
629 
630   hr = vec->GetMany(4, copy.size(), copy.data(), &actual);
631   EXPECT_EQ(E_BOUNDS, hr);
632 }
633 
TEST(VectorTest,ReplaceAll)634 TEST(VectorTest, ReplaceAll) {
635   auto vec = Make<Vector<int>>(g_one_two_three);
636   auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
637   HRESULT hr = vec->ReplaceAll(g_empty.size(), g_empty.data());
638   EXPECT_TRUE(SUCCEEDED(hr));
639   EXPECT_THAT(vec->vector_for_testing(), IsEmpty());
640   EXPECT_EQ(vec.Get(), handler->sender());
641   EXPECT_EQ(CollectionChange_Reset, handler->change());
642   EXPECT_EQ(0u, handler->index());
643 
644   hr = vec->ReplaceAll(g_one.size(), g_one.data());
645   EXPECT_TRUE(SUCCEEDED(hr));
646   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1));
647   EXPECT_EQ(vec.Get(), handler->sender());
648   EXPECT_EQ(CollectionChange_Reset, handler->change());
649   EXPECT_EQ(0u, handler->index());
650 
651   hr = vec->ReplaceAll(g_one_two.size(), g_one_two.data());
652   EXPECT_TRUE(SUCCEEDED(hr));
653   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2));
654   EXPECT_EQ(vec.Get(), handler->sender());
655   EXPECT_EQ(CollectionChange_Reset, handler->change());
656   EXPECT_EQ(0u, handler->index());
657 
658   hr = vec->ReplaceAll(g_one_two_three.size(), g_one_two_three.data());
659   EXPECT_TRUE(SUCCEEDED(hr));
660   EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2, 3));
661   EXPECT_EQ(vec.Get(), handler->sender());
662   EXPECT_EQ(CollectionChange_Reset, handler->change());
663   EXPECT_EQ(0u, handler->index());
664 }
665 
666 // Uri* is an AggregateType which ABI representation is IUriRuntimeClass*.
TEST(VectorTest,ConstructWithAggregateType)667 TEST(VectorTest, ConstructWithAggregateType) {
668   auto vec = Make<Vector<Uri*>>();
669   unsigned size;
670   HRESULT hr = vec->get_Size(&size);
671   EXPECT_TRUE(SUCCEEDED(hr));
672   EXPECT_EQ(0u, size);
673 }
674 
TEST(VectorTest,First)675 TEST(VectorTest, First) {
676   auto vec = Make<Vector<int>>(g_one_two_three);
677   ComPtr<IIterator<int>> iterator;
678   HRESULT hr = vec->First(&iterator);
679   EXPECT_TRUE(SUCCEEDED(hr));
680   boolean has_current;
681   hr = iterator->get_HasCurrent(&has_current);
682   EXPECT_TRUE(SUCCEEDED(hr));
683   EXPECT_TRUE(has_current);
684   int current;
685   hr = iterator->get_Current(&current);
686   EXPECT_TRUE(SUCCEEDED(hr));
687   EXPECT_EQ(1, current);
688   hr = iterator->MoveNext(&has_current);
689   EXPECT_TRUE(SUCCEEDED(hr));
690   EXPECT_TRUE(has_current);
691   hr = iterator->get_Current(&current);
692   EXPECT_TRUE(SUCCEEDED(hr));
693   EXPECT_EQ(2, current);
694   hr = iterator->MoveNext(&has_current);
695   EXPECT_TRUE(SUCCEEDED(hr));
696   EXPECT_TRUE(has_current);
697   hr = iterator->get_Current(&current);
698   EXPECT_TRUE(SUCCEEDED(hr));
699   EXPECT_EQ(3, current);
700   hr = iterator->MoveNext(&has_current);
701   EXPECT_TRUE(SUCCEEDED(hr));
702   EXPECT_FALSE(has_current);
703   hr = iterator->get_Current(&current);
704   EXPECT_FALSE(SUCCEEDED(hr));
705   EXPECT_EQ(E_BOUNDS, hr);
706   hr = iterator->MoveNext(&has_current);
707   EXPECT_FALSE(SUCCEEDED(hr));
708   EXPECT_EQ(E_BOUNDS, hr);
709   EXPECT_FALSE(has_current);
710 
711   hr = vec->First(&iterator);
712   EXPECT_TRUE(SUCCEEDED(hr));
713   std::vector<int> copy(3);
714   unsigned actual;
715   hr = iterator->GetMany(copy.size(), copy.data(), &actual);
716   EXPECT_TRUE(SUCCEEDED(hr));
717   EXPECT_EQ(3u, actual);
718   EXPECT_THAT(copy, ElementsAre(1, 2, 3));
719 }
720 
TEST(VectorTest,MoveNext_S_OK_ValidItem)721 TEST(VectorTest, MoveNext_S_OK_ValidItem) {
722   auto vec = Make<Vector<int>>(g_one_two_three);
723   ComPtr<IIterator<int>> iterator;
724   vec->First(&iterator);
725   boolean has_current;
726 
727   // Moving next to a valid item should return S_OK:
728   // [1, 2, 3]
729   //  |->|
730   EXPECT_EQ(S_OK, iterator->MoveNext(&has_current));
731 }
732 
TEST(VectorTest,MoveNext_S_OK_FromLastItem)733 TEST(VectorTest, MoveNext_S_OK_FromLastItem) {
734   auto vec = Make<Vector<int>>(g_one);
735   ComPtr<IIterator<int>> iterator;
736   vec->First(&iterator);
737   boolean has_current;
738 
739   // Moving next past the last item should return S_OK:
740   // [1]
741   //  |->|
742   EXPECT_EQ(S_OK, iterator->MoveNext(&has_current));
743 }
744 
TEST(VectorTest,MoveNext_E_CHANGED_STATE_ValidItem)745 TEST(VectorTest, MoveNext_E_CHANGED_STATE_ValidItem) {
746   auto vec = Make<Vector<int>>(g_one_two_three);
747   ComPtr<IIterator<int>> iterator;
748   vec->First(&iterator);
749   boolean has_current;
750 
751   vec->Append(4);
752 
753   // Moving next after changing the vector should return E_CHANGED_STATE:
754   EXPECT_EQ(E_CHANGED_STATE, iterator->MoveNext(&has_current));
755 }
756 
TEST(VectorTest,MoveNext_E_CHANGED_STATE_AfterLastItem)757 TEST(VectorTest, MoveNext_E_CHANGED_STATE_AfterLastItem) {
758   auto vec = Make<Vector<int>>(g_one);
759   ComPtr<IIterator<int>> iterator;
760   vec->First(&iterator);
761   boolean has_current;
762   iterator->MoveNext(&has_current);
763 
764   vec->Append(4);
765 
766   // Moving next after changing the vector should return E_CHANGED_STATE:
767   EXPECT_EQ(E_CHANGED_STATE, iterator->MoveNext(&has_current));
768 }
769 
TEST(VectorTest,MoveNext_E_BOUNDS)770 TEST(VectorTest, MoveNext_E_BOUNDS) {
771   auto vec = Make<Vector<int>>(g_one);
772   ComPtr<IIterator<int>> iterator;
773   vec->First(&iterator);
774   boolean has_current;
775   iterator->MoveNext(&has_current);
776 
777   // Moving next when already past the last item should return E_BOUNDS:
778   // [1]
779   //     |->|
780   EXPECT_EQ(E_BOUNDS, iterator->MoveNext(&has_current));
781 }
782 
TEST(VectorTest,MoveNext_HasCurrent_ValidItem)783 TEST(VectorTest, MoveNext_HasCurrent_ValidItem) {
784   auto vec = Make<Vector<int>>(g_one_two_three);
785   ComPtr<IIterator<int>> iterator;
786   vec->First(&iterator);
787   boolean has_current;
788 
789   // Moving next to a valid item should set |has_current| to true:
790   // [1, 2, 3]
791   //  |->|
792   iterator->MoveNext(&has_current);
793   EXPECT_TRUE(has_current);
794 }
795 
TEST(VectorTest,MoveNext_HasCurrent_LastItem)796 TEST(VectorTest, MoveNext_HasCurrent_LastItem) {
797   auto vec = Make<Vector<int>>(g_one_two);
798   ComPtr<IIterator<int>> iterator;
799   vec->First(&iterator);
800   boolean has_current;
801 
802   // Moving next to the last item should set |has_current| to true:
803   // [1, 2]
804   //  |->|
805   iterator->MoveNext(&has_current);
806   EXPECT_TRUE(has_current);
807 }
808 
TEST(VectorTest,MoveNext_HasCurrent_FromLastItem)809 TEST(VectorTest, MoveNext_HasCurrent_FromLastItem) {
810   auto vec = Make<Vector<int>>(g_one);
811   ComPtr<IIterator<int>> iterator;
812   vec->First(&iterator);
813   boolean has_current;
814   iterator->MoveNext(&has_current);
815 
816   // Moving next when already past the end should set |has_current| to false:
817   // [1]
818   //     |->|
819   iterator->MoveNext(&has_current);
820   EXPECT_FALSE(has_current);
821 }
822 
TEST(VectorTest,MoveNext_HasCurrent_AfterLastItem)823 TEST(VectorTest, MoveNext_HasCurrent_AfterLastItem) {
824   auto vec = Make<Vector<int>>(g_one);
825   ComPtr<IIterator<int>> iterator;
826   vec->First(&iterator);
827 
828   // Moving next from the last item should set |has_current| to false:
829   // [1]
830   //  |->|
831   boolean has_current;
832   iterator->MoveNext(&has_current);
833   EXPECT_FALSE(has_current);
834 }
835 
TEST(VectorTest,MoveNext_HasCurrent_Changed)836 TEST(VectorTest, MoveNext_HasCurrent_Changed) {
837   auto vec = Make<Vector<int>>(g_one_two);
838   ComPtr<IIterator<int>> iterator;
839   vec->First(&iterator);
840   boolean has_current;
841 
842   vec->Append(4);
843 
844   // Moving next after changing the vector should set |has_current| to false:
845   iterator->MoveNext(&has_current);
846   EXPECT_FALSE(has_current);
847 }
848 
849 }  // namespace win
850 }  // namespace base
851