blob: 33d0713f24a7638736d37201fe8d86fdd6d20b9d [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/win/vector.h"
#include <windows.foundation.h>
#include <wrl/client.h>
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ABI {
namespace Windows {
namespace Foundation {
namespace Collections {
// Note: As UWP does not provide int specializations for IObservableVector and
// VectorChangedEventHandler we need to supply our own. UUIDs were generated
// using `uuidgen`.
template <>
struct __declspec(uuid("21c2c195-91a4-4fce-8346-2a85f4478e26"))
IObservableVector<int> : IObservableVector_impl<int> {};
template <>
struct __declspec(uuid("86b0071e-5e72-4d3d-82d3-420ebd2b2716"))
VectorChangedEventHandler<int> : VectorChangedEventHandler_impl<int> {};
namespace {
using UriPtrAggregate = Internal::AggregateType<Uri*, IUriRuntimeClass*>;
}
template <>
struct __declspec(uuid("12311764-f245-4245-9dc9-bab258eddd4e"))
IObservableVector<Uri*> : IObservableVector_impl<UriPtrAggregate> {};
template <>
struct __declspec(uuid("050e4b78-71b2-43ff-bf7c-f6ba589aced9"))
VectorChangedEventHandler<Uri*>
: VectorChangedEventHandler_impl<UriPtrAggregate> {};
} // namespace Collections
} // namespace Foundation
} // namespace Windows
} // namespace ABI
namespace base {
namespace win {
namespace {
using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ABI::Windows::Foundation::Uri;
using ABI::Windows::Foundation::Collections::CollectionChange;
using ABI::Windows::Foundation::Collections::CollectionChange_ItemChanged;
using ABI::Windows::Foundation::Collections::CollectionChange_ItemInserted;
using ABI::Windows::Foundation::Collections::CollectionChange_ItemRemoved;
using ABI::Windows::Foundation::Collections::CollectionChange_Reset;
using ABI::Windows::Foundation::Collections::IObservableVector;
using ABI::Windows::Foundation::Collections::IVectorChangedEventArgs;
using ABI::Windows::Foundation::Collections::IVectorView;
using ABI::Windows::Foundation::Collections::VectorChangedEventHandler;
using ABI::Windows::Foundation::IAsyncOperation;
using Microsoft::WRL::ClassicCom;
using Microsoft::WRL::ComPtr;
using Microsoft::WRL::InhibitRoOriginateError;
using Microsoft::WRL::Make;
using Microsoft::WRL::RuntimeClass;
using Microsoft::WRL::RuntimeClassFlags;
template <typename T>
class FakeVectorChangedEventHandler
: public RuntimeClass<
RuntimeClassFlags<ClassicCom | InhibitRoOriginateError>,
VectorChangedEventHandler<T>> {
public:
explicit FakeVectorChangedEventHandler(ComPtr<IObservableVector<T>> vector)
: vector_(std::move(vector)) {
EXPECT_TRUE(SUCCEEDED(vector_->add_VectorChanged(this, &token_)));
}
~FakeVectorChangedEventHandler() {
EXPECT_TRUE(SUCCEEDED(vector_->remove_VectorChanged(token_)));
}
// VectorChangedEventHandler:
IFACEMETHODIMP Invoke(IObservableVector<T>* sender,
IVectorChangedEventArgs* e) {
sender_ = sender;
EXPECT_TRUE(SUCCEEDED(e->get_CollectionChange(&change_)));
EXPECT_TRUE(SUCCEEDED(e->get_Index(&index_)));
return S_OK;
}
IObservableVector<T>* sender() { return sender_; }
CollectionChange change() { return change_; }
unsigned int index() { return index_; }
private:
ComPtr<IObservableVector<T>> vector_;
EventRegistrationToken token_;
IObservableVector<T>* sender_ = nullptr;
CollectionChange change_ = CollectionChange_Reset;
unsigned int index_ = 0;
};
// The ReplaceAll test requires a non-const data() member, thus these vectors
// are not declared const, even though no test mutates them.
std::vector<int> g_empty;
std::vector<int> g_one = {1};
std::vector<int> g_one_two = {1, 2};
std::vector<int> g_one_two_three = {1, 2, 3};
} // namespace
TEST(VectorTest, GetAt_Empty) {
auto vec = Make<Vector<int>>();
int value;
HRESULT hr = vec->GetAt(0, &value);
EXPECT_EQ(E_BOUNDS, hr);
}
TEST(VectorTest, GetAt_One) {
auto vec = Make<Vector<int>>(g_one);
int value;
HRESULT hr = vec->GetAt(0, &value);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1, value);
hr = vec->GetAt(1, &value);
EXPECT_EQ(E_BOUNDS, hr);
}
TEST(VectorTest, GetAt_OneTwo) {
auto vec = Make<Vector<int>>(g_one_two);
int value;
HRESULT hr = vec->GetAt(0, &value);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1, value);
hr = vec->GetAt(1, &value);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(2, value);
hr = vec->GetAt(2, &value);
EXPECT_EQ(E_BOUNDS, hr);
}
TEST(VectorTest, GetAt_OneTwoThree) {
auto vec = Make<Vector<int>>(g_one_two_three);
int value;
HRESULT hr = vec->GetAt(0, &value);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1, value);
hr = vec->GetAt(1, &value);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(2, value);
hr = vec->GetAt(2, &value);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(3, value);
hr = vec->GetAt(3, &value);
EXPECT_EQ(E_BOUNDS, hr);
}
TEST(VectorTest, get_Size_Empty) {
auto vec = Make<Vector<int>>();
unsigned size;
HRESULT hr = vec->get_Size(&size);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, size);
}
TEST(VectorTest, get_Size_One) {
auto vec = Make<Vector<int>>(g_one);
unsigned size;
HRESULT hr = vec->get_Size(&size);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1u, size);
}
TEST(VectorTest, get_Size_OneTwo) {
auto vec = Make<Vector<int>>(g_one_two);
unsigned size;
HRESULT hr = vec->get_Size(&size);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(2u, size);
}
TEST(VectorTest, get_Size_OneTwoThree) {
auto vec = Make<Vector<int>>(g_one_two_three);
unsigned size;
HRESULT hr = vec->get_Size(&size);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(3u, size);
}
TEST(VectorTest, GetView) {
auto vec = Make<Vector<int>>(g_one_two_three);
ComPtr<IVectorView<int>> view;
HRESULT hr = vec->GetView(&view);
EXPECT_TRUE(SUCCEEDED(hr));
int value;
hr = view->GetAt(0, &value);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1, value);
hr = view->GetAt(1, &value);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(2, value);
hr = view->GetAt(2, &value);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(3, value);
hr = view->GetAt(3, &value);
EXPECT_EQ(E_BOUNDS, hr);
unsigned size;
hr = view->get_Size(&size);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(3u, size);
unsigned index;
boolean found;
hr = view->IndexOf(1, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, index);
EXPECT_TRUE(found);
hr = view->IndexOf(2, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1u, index);
EXPECT_TRUE(found);
hr = view->IndexOf(3, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(2u, index);
EXPECT_TRUE(found);
hr = view->IndexOf(4, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, index);
EXPECT_FALSE(found);
std::vector<int> copy(3);
unsigned actual;
hr = view->GetMany(0, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(3u, actual);
EXPECT_THAT(copy, ElementsAre(1, 2, 3));
hr = vec->Append(4);
EXPECT_TRUE(SUCCEEDED(hr));
// The view is supposed to be a snapshot of the vector when it's created.
// Further modifications to the vector will invalidate the view.
hr = view->GetAt(3, &value);
EXPECT_EQ(E_CHANGED_STATE, hr);
hr = view->get_Size(&size);
EXPECT_EQ(E_CHANGED_STATE, hr);
hr = view->IndexOf(1, &index, &found);
EXPECT_EQ(E_CHANGED_STATE, hr);
hr = view->GetMany(0, copy.size(), copy.data(), &actual);
EXPECT_EQ(E_CHANGED_STATE, hr);
}
TEST(VectorTest, IndexOf_Empty) {
auto vec = Make<Vector<int>>();
unsigned index;
boolean found;
HRESULT hr = vec->IndexOf(1, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, index);
EXPECT_FALSE(found);
}
TEST(VectorTest, IndexOf_One) {
auto vec = Make<Vector<int>>(g_one);
unsigned index;
boolean found;
HRESULT hr = vec->IndexOf(1, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, index);
EXPECT_TRUE(found);
hr = vec->IndexOf(2, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, index);
EXPECT_FALSE(found);
}
TEST(VectorTest, IndexOf_OneTwo) {
auto vec = Make<Vector<int>>(g_one_two);
unsigned index;
boolean found;
HRESULT hr = vec->IndexOf(1, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, index);
EXPECT_TRUE(found);
hr = vec->IndexOf(2, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1u, index);
EXPECT_TRUE(found);
hr = vec->IndexOf(3, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, index);
EXPECT_FALSE(found);
}
TEST(VectorTest, IndexOf_OneTwoThree) {
auto vec = Make<Vector<int>>(g_one_two_three);
unsigned index;
boolean found;
HRESULT hr = vec->IndexOf(1, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, index);
EXPECT_TRUE(found);
hr = vec->IndexOf(2, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1u, index);
EXPECT_TRUE(found);
hr = vec->IndexOf(3, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(2u, index);
EXPECT_TRUE(found);
hr = vec->IndexOf(4, &index, &found);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, index);
EXPECT_FALSE(found);
}
TEST(VectorTest, SetAt) {
auto vec = Make<Vector<int>>(g_one_two_three);
auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
HRESULT hr = vec->SetAt(0, 4);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(4, 2, 3));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemChanged, handler->change());
EXPECT_EQ(0u, handler->index());
hr = vec->SetAt(1, 5);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(4, 5, 3));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemChanged, handler->change());
EXPECT_EQ(1u, handler->index());
hr = vec->SetAt(2, 6);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(4, 5, 6));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemChanged, handler->change());
EXPECT_EQ(2u, handler->index());
hr = vec->SetAt(3, 7);
EXPECT_EQ(E_BOUNDS, hr);
}
TEST(VectorTest, InsertAt) {
auto vec = Make<Vector<int>>(g_one_two_three);
auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
HRESULT hr = vec->InsertAt(4, 4);
EXPECT_EQ(E_BOUNDS, hr);
hr = vec->InsertAt(3, 4);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2, 3, 4));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
EXPECT_EQ(3u, handler->index());
hr = vec->InsertAt(2, 5);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2, 5, 3, 4));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
EXPECT_EQ(2u, handler->index());
hr = vec->InsertAt(1, 6);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 6, 2, 5, 3, 4));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
EXPECT_EQ(1u, handler->index());
hr = vec->InsertAt(0, 7);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(7, 1, 6, 2, 5, 3, 4));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
EXPECT_EQ(0u, handler->index());
}
TEST(VectorTest, RemoveAt) {
auto vec = Make<Vector<int>>(g_one_two_three);
auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
HRESULT hr = vec->RemoveAt(3);
EXPECT_EQ(E_BOUNDS, hr);
hr = vec->RemoveAt(2);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
EXPECT_EQ(2u, handler->index());
hr = vec->RemoveAt(2);
EXPECT_EQ(E_BOUNDS, hr);
hr = vec->RemoveAt(1);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
EXPECT_EQ(1u, handler->index());
hr = vec->RemoveAt(1);
EXPECT_EQ(E_BOUNDS, hr);
hr = vec->RemoveAt(0);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), IsEmpty());
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
EXPECT_EQ(0u, handler->index());
hr = vec->RemoveAt(0);
EXPECT_EQ(E_BOUNDS, hr);
}
TEST(VectorTest, Append) {
auto vec = Make<Vector<int>>();
auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
HRESULT hr = vec->Append(1);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
EXPECT_EQ(0u, handler->index());
hr = vec->Append(2);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
EXPECT_EQ(1u, handler->index());
hr = vec->Append(3);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2, 3));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemInserted, handler->change());
EXPECT_EQ(2u, handler->index());
}
TEST(VectorTest, RemoveAtEnd) {
auto vec = Make<Vector<int>>(g_one_two_three);
auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
HRESULT hr = vec->RemoveAtEnd();
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
EXPECT_EQ(2u, handler->index());
hr = vec->RemoveAtEnd();
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
EXPECT_EQ(1u, handler->index());
hr = vec->RemoveAtEnd();
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), IsEmpty());
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_ItemRemoved, handler->change());
EXPECT_EQ(0u, handler->index());
hr = vec->RemoveAtEnd();
EXPECT_EQ(E_BOUNDS, hr);
}
TEST(VectorTest, Clear) {
auto vec = Make<Vector<int>>(g_one_two_three);
auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
HRESULT hr = vec->Clear();
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), IsEmpty());
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_Reset, handler->change());
EXPECT_EQ(0u, handler->index());
}
TEST(VectorTest, GetMany) {
auto vec = Make<Vector<int>>(g_one_two_three);
std::vector<int> copy;
unsigned actual;
HRESULT hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, actual);
EXPECT_THAT(copy, IsEmpty());
copy.resize(1);
hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1u, actual);
EXPECT_THAT(copy, ElementsAre(1));
copy.resize(2);
hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(2u, actual);
EXPECT_THAT(copy, ElementsAre(1, 2));
copy.resize(3);
hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(3u, actual);
EXPECT_THAT(copy, ElementsAre(1, 2, 3));
copy.resize(4);
hr = vec->GetMany(0, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(3u, actual);
EXPECT_THAT(copy, ElementsAre(1, 2, 3, 0));
copy.resize(0);
hr = vec->GetMany(1, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, actual);
EXPECT_THAT(copy, IsEmpty());
copy.resize(1);
hr = vec->GetMany(1, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1u, actual);
EXPECT_THAT(copy, ElementsAre(2));
copy.resize(2);
hr = vec->GetMany(1, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(2u, actual);
EXPECT_THAT(copy, ElementsAre(2, 3));
copy.resize(3);
hr = vec->GetMany(1, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(2u, actual);
EXPECT_THAT(copy, ElementsAre(2, 3, 0));
copy.resize(0);
hr = vec->GetMany(2, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, actual);
EXPECT_THAT(copy, IsEmpty());
copy.resize(1);
hr = vec->GetMany(2, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1u, actual);
EXPECT_THAT(copy, ElementsAre(3));
copy.resize(2);
hr = vec->GetMany(2, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(1u, actual);
EXPECT_THAT(copy, ElementsAre(3, 0));
hr = vec->GetMany(3, copy.size(), copy.data(), &actual);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, actual);
hr = vec->GetMany(4, copy.size(), copy.data(), &actual);
EXPECT_EQ(E_BOUNDS, hr);
}
TEST(VectorTest, ReplaceAll) {
auto vec = Make<Vector<int>>(g_one_two_three);
auto handler = Make<FakeVectorChangedEventHandler<int>>(vec.Get());
HRESULT hr = vec->ReplaceAll(g_empty.size(), g_empty.data());
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), IsEmpty());
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_Reset, handler->change());
EXPECT_EQ(0u, handler->index());
hr = vec->ReplaceAll(g_one.size(), g_one.data());
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_Reset, handler->change());
EXPECT_EQ(0u, handler->index());
hr = vec->ReplaceAll(g_one_two.size(), g_one_two.data());
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_Reset, handler->change());
EXPECT_EQ(0u, handler->index());
hr = vec->ReplaceAll(g_one_two_three.size(), g_one_two_three.data());
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_THAT(vec->vector_for_testing(), ElementsAre(1, 2, 3));
EXPECT_EQ(vec.Get(), handler->sender());
EXPECT_EQ(CollectionChange_Reset, handler->change());
EXPECT_EQ(0u, handler->index());
}
// Uri* is an AggregateType which ABI representation is IUriRuntimeClass*.
TEST(VectorTest, ConstructWithAggregateType) {
auto vec = Make<Vector<Uri*>>();
unsigned size;
HRESULT hr = vec->get_Size(&size);
EXPECT_TRUE(SUCCEEDED(hr));
EXPECT_EQ(0u, size);
}
} // namespace win
} // namespace base