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(¤t);
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(¤t);
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(¤t);
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(¤t);
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