203 lines
8.4 KiB
C++
203 lines
8.4 KiB
C++
// Copyright 2020 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "base/test/fake_iasync_operation_win.h"
|
|
|
|
#include <asyncinfo.h>
|
|
#include <wrl/event.h>
|
|
#include <wrl/implements.h>
|
|
|
|
#include "base/test/async_results_test_values_win.h"
|
|
#include "testing/gtest/include/gtest/gtest-spi.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
using ABI::Windows::Foundation::IAsyncOperation;
|
|
using ABI::Windows::Foundation::IAsyncOperationCompletedHandler;
|
|
using Microsoft::WRL::Callback;
|
|
using Microsoft::WRL::Make;
|
|
|
|
namespace base {
|
|
namespace win {
|
|
namespace {
|
|
constexpr HRESULT kTestError = 0x87654321;
|
|
}
|
|
|
|
template <typename T>
|
|
class FakeIAsyncOperationTest : public ::testing::Test {};
|
|
|
|
TYPED_TEST_SUITE_P(FakeIAsyncOperationTest);
|
|
|
|
TYPED_TEST_P(FakeIAsyncOperationTest, MultipleCompletedHandlers) {
|
|
auto operation = Make<FakeIAsyncOperation<TypeParam>>();
|
|
auto handler = Callback<IAsyncOperationCompletedHandler<TypeParam>>(
|
|
[](auto async_operation, AsyncStatus async_status) { return S_OK; });
|
|
ASSERT_HRESULT_SUCCEEDED(operation->put_Completed(handler.Get()));
|
|
EXPECT_NONFATAL_FAILURE(
|
|
ASSERT_HRESULT_SUCCEEDED(operation->put_Completed(handler.Get()));
|
|
, "put_Completed");
|
|
}
|
|
|
|
TYPED_TEST_P(FakeIAsyncOperationTest, MultipleCompletions) {
|
|
auto operation = Make<FakeIAsyncOperation<TypeParam>>();
|
|
base::test::AsyncResultsTestValues<TypeParam> test_values;
|
|
ASSERT_NO_FATAL_FAILURE(
|
|
operation->CompleteWithResults(test_values.GetTestValue_T()));
|
|
// EXPECT_FATAL_FAILURE() can only reference globals and statics.
|
|
// https://github.com/google/googletest/blob/main/docs/advanced.md#catching-failures
|
|
static auto test_value_t = test_values.GetTestValue_T();
|
|
static auto& static_operation = operation;
|
|
EXPECT_FATAL_FAILURE(static_operation->CompleteWithResults(test_value_t),
|
|
"already completed");
|
|
|
|
operation = Make<FakeIAsyncOperation<TypeParam>>();
|
|
static_operation = operation;
|
|
ASSERT_NO_FATAL_FAILURE(operation->CompleteWithError(E_FAIL));
|
|
EXPECT_FATAL_FAILURE(static_operation->CompleteWithError(E_FAIL),
|
|
"already completed");
|
|
|
|
operation = Make<FakeIAsyncOperation<TypeParam>>();
|
|
static_operation = operation;
|
|
ASSERT_NO_FATAL_FAILURE(operation->CompleteWithError(E_FAIL));
|
|
EXPECT_FATAL_FAILURE(static_operation->CompleteWithResults(test_value_t),
|
|
"already completed");
|
|
|
|
operation = Make<FakeIAsyncOperation<TypeParam>>();
|
|
static_operation = operation;
|
|
ASSERT_NO_FATAL_FAILURE(
|
|
operation->CompleteWithResults(test_values.GetTestValue_T()));
|
|
EXPECT_FATAL_FAILURE(static_operation->CompleteWithError(E_FAIL),
|
|
"already completed");
|
|
}
|
|
|
|
TYPED_TEST_P(FakeIAsyncOperationTest, CompleteWithResults_WithHandler) {
|
|
auto operation = Make<FakeIAsyncOperation<TypeParam>>();
|
|
|
|
bool completed_handler_called = false;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->put_Completed(
|
|
Callback<IAsyncOperationCompletedHandler<TypeParam>>(
|
|
[operation, &completed_handler_called](auto async_operation,
|
|
AsyncStatus async_status) {
|
|
completed_handler_called = true;
|
|
EXPECT_EQ(operation.Get(), async_operation);
|
|
EXPECT_EQ(async_status, AsyncStatus::Completed);
|
|
return S_OK;
|
|
})
|
|
.Get()));
|
|
ASSERT_FALSE(completed_handler_called);
|
|
AsyncStatus async_status;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
|
|
ASSERT_EQ(async_status, AsyncStatus::Started);
|
|
HRESULT error_code;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
|
|
ASSERT_EQ(error_code, S_OK);
|
|
base::test::AsyncResultsTestValues<TypeParam> test_values;
|
|
auto results = test_values.GetDefaultValue_AsyncResultsT();
|
|
EXPECT_NONFATAL_FAILURE(
|
|
ASSERT_HRESULT_FAILED(operation->GetResults(&results)), "GetResults");
|
|
|
|
operation->CompleteWithResults(test_values.GetTestValue_AsyncResultsT());
|
|
ASSERT_TRUE(completed_handler_called);
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
|
|
ASSERT_EQ(async_status, AsyncStatus::Completed);
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
|
|
ASSERT_EQ(error_code, S_OK);
|
|
ASSERT_HRESULT_SUCCEEDED(operation->GetResults(&results));
|
|
ASSERT_EQ(results, test_values.GetTestValue_AsyncResultsT());
|
|
}
|
|
|
|
TYPED_TEST_P(FakeIAsyncOperationTest, CompleteWithResults_WithoutHandler) {
|
|
auto operation = Make<FakeIAsyncOperation<TypeParam>>();
|
|
|
|
AsyncStatus async_status;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
|
|
ASSERT_EQ(async_status, AsyncStatus::Started);
|
|
HRESULT error_code;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
|
|
ASSERT_EQ(error_code, S_OK);
|
|
base::test::AsyncResultsTestValues<TypeParam> test_values;
|
|
auto results = test_values.GetDefaultValue_AsyncResultsT();
|
|
EXPECT_NONFATAL_FAILURE(
|
|
ASSERT_HRESULT_FAILED(operation->GetResults(&results)), "GetResults");
|
|
|
|
operation->CompleteWithResults(test_values.GetTestValue_AsyncResultsT());
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
|
|
ASSERT_EQ(async_status, AsyncStatus::Completed);
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
|
|
ASSERT_EQ(error_code, S_OK);
|
|
ASSERT_HRESULT_SUCCEEDED(operation->GetResults(&results));
|
|
ASSERT_EQ(results, test_values.GetTestValue_AsyncResultsT());
|
|
}
|
|
|
|
TYPED_TEST_P(FakeIAsyncOperationTest, CompleteWithError_WithHandler) {
|
|
auto operation = Make<FakeIAsyncOperation<TypeParam>>();
|
|
|
|
bool completed_handler_called = false;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->put_Completed(
|
|
Callback<IAsyncOperationCompletedHandler<TypeParam>>(
|
|
[operation, &completed_handler_called](auto async_operation,
|
|
AsyncStatus async_status) {
|
|
completed_handler_called = true;
|
|
EXPECT_EQ(operation.Get(), async_operation);
|
|
EXPECT_EQ(async_status, AsyncStatus::Error);
|
|
return S_OK;
|
|
})
|
|
.Get()));
|
|
ASSERT_FALSE(completed_handler_called);
|
|
AsyncStatus async_status;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
|
|
ASSERT_EQ(async_status, AsyncStatus::Started);
|
|
HRESULT error_code;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
|
|
ASSERT_EQ(error_code, S_OK);
|
|
base::test::AsyncResultsTestValues<TypeParam> test_values;
|
|
auto results = test_values.GetDefaultValue_AsyncResultsT();
|
|
EXPECT_NONFATAL_FAILURE(
|
|
ASSERT_HRESULT_FAILED(operation->GetResults(&results)), "GetResults");
|
|
|
|
operation->CompleteWithError(kTestError);
|
|
ASSERT_TRUE(completed_handler_called);
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
|
|
ASSERT_EQ(async_status, AsyncStatus::Error);
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
|
|
ASSERT_EQ(error_code, kTestError);
|
|
ASSERT_HRESULT_FAILED(operation->GetResults(&results));
|
|
}
|
|
|
|
TYPED_TEST_P(FakeIAsyncOperationTest, CompleteWithError_WithoutHandler) {
|
|
auto operation = Make<FakeIAsyncOperation<TypeParam>>();
|
|
|
|
AsyncStatus async_status;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
|
|
ASSERT_EQ(async_status, AsyncStatus::Started);
|
|
HRESULT error_code;
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
|
|
ASSERT_EQ(error_code, S_OK);
|
|
base::test::AsyncResultsTestValues<TypeParam> test_values;
|
|
auto results = test_values.GetDefaultValue_AsyncResultsT();
|
|
EXPECT_NONFATAL_FAILURE(
|
|
ASSERT_HRESULT_FAILED(operation->GetResults(&results)), "GetResults");
|
|
|
|
operation->CompleteWithError(kTestError);
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
|
|
ASSERT_EQ(async_status, AsyncStatus::Error);
|
|
ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
|
|
ASSERT_EQ(error_code, kTestError);
|
|
ASSERT_HRESULT_FAILED(operation->GetResults(&results));
|
|
}
|
|
|
|
REGISTER_TYPED_TEST_SUITE_P(FakeIAsyncOperationTest,
|
|
MultipleCompletedHandlers,
|
|
MultipleCompletions,
|
|
CompleteWithResults_WithHandler,
|
|
CompleteWithResults_WithoutHandler,
|
|
CompleteWithError_WithHandler,
|
|
CompleteWithError_WithoutHandler);
|
|
|
|
INSTANTIATE_TYPED_TEST_SUITE_P(Win,
|
|
FakeIAsyncOperationTest,
|
|
base::test::AsyncResultsTestValuesTypes);
|
|
|
|
} // namespace win
|
|
} // namespace base
|