// Copyright 2020 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/post_async_results.h" #include "base/test/async_results_test_values_win.h" #include "base/test/bind.h" #include "base/test/fake_iasync_operation_win.h" #include "base/test/task_environment.h" #include "testing/gtest/include/gtest/gtest.h" using ABI::Windows::Foundation::IAsyncOperation; using Microsoft::WRL::ComPtr; namespace base { namespace win { template class PostAsyncResultsTest : public ::testing::Test {}; TYPED_TEST_SUITE_P(PostAsyncResultsTest); TYPED_TEST_P(PostAsyncResultsTest, GetAsyncResultsT_Success) { auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); base::test::AsyncResultsTestValues templated_values; ASSERT_NO_FATAL_FAILURE( fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T())); AsyncStatus async_status; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op->get_Status(&async_status)); auto value_received = templated_values.GetDefaultValue_AsyncResultsT(); ASSERT_HRESULT_SUCCEEDED(internal::GetAsyncResultsT( async_op.Get(), async_status, &value_received)); ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received); } TYPED_TEST_P(PostAsyncResultsTest, GetAsyncResultsT_Failure) { auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); HRESULT test_error = (HRESULT)0x87654321L; ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(test_error)); AsyncStatus async_status; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op->get_Status(&async_status)); base::test::AsyncResultsTestValues templated_values; auto value_received = templated_values.GetTestValue_AsyncResultsT(); ASSERT_EQ( internal::GetAsyncResultsT(async_op.Get(), async_status, &value_received), test_error); ASSERT_EQ(templated_values.GetDefaultValue_AsyncResultsT(), value_received); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncOperationCompletedHandler_Success) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); IAsyncOperation* async_op_received; AsyncStatus async_status_received = AsyncStatus::Started; internal::IAsyncOperationCompletedHandlerT completed_handler = base::BindLambdaForTesting( [&](IAsyncOperation* async_operation, AsyncStatus async_status) { async_op_received = async_operation; async_status_received = async_status; std::move(quit_closure).Run(); }); ASSERT_HRESULT_SUCCEEDED(internal::PostAsyncOperationCompletedHandler( async_op.Get(), std::move(completed_handler))); base::test::AsyncResultsTestValues templated_values; ASSERT_NO_FATAL_FAILURE( fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T())); run_loop.Run(); ASSERT_EQ(async_op.Get(), async_op_received); ASSERT_EQ(AsyncStatus::Completed, async_status_received); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncOperationCompletedHandler_Failure) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); IAsyncOperation* async_op_received; AsyncStatus async_status_received = AsyncStatus::Started; internal::IAsyncOperationCompletedHandlerT completed_handler = base::BindLambdaForTesting( [&](IAsyncOperation* async_operation, AsyncStatus async_status) { async_op_received = async_operation; async_status_received = async_status; std::move(quit_closure).Run(); }); ASSERT_HRESULT_SUCCEEDED(internal::PostAsyncOperationCompletedHandler( async_op.Get(), std::move(completed_handler))); ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(E_FAIL)); run_loop.Run(); ASSERT_EQ(async_op.Get(), async_op_received); ASSERT_EQ(AsyncStatus::Error, async_status_received); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncHandlers_OnlySuccessHandler_Success) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); base::test::AsyncResultsTestValues templated_values; auto value_received = templated_values.GetDefaultValue_AsyncResultsT(); ASSERT_HRESULT_SUCCEEDED(PostAsyncHandlers( async_op.Get(), base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { value_received = result; std::move(quit_closure).Run(); }))); ASSERT_NO_FATAL_FAILURE( fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T())); run_loop.Run(); ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncHandlers_OnlySuccessHandler_Failure) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; bool success_handler_called = false; ASSERT_HRESULT_SUCCEEDED(PostAsyncHandlers( async_op.Get(), base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { success_handler_called = true; }))); HRESULT test_error = (HRESULT)0x87654321L; ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(test_error)); run_loop.RunUntilIdle(); ASSERT_FALSE(success_handler_called); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncHandlers_NoArgsFailureHandler_Success) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); base::test::AsyncResultsTestValues templated_values; auto value_received = templated_values.GetDefaultValue_AsyncResultsT(); bool failure_handler_called = false; ASSERT_HRESULT_SUCCEEDED( PostAsyncHandlers(async_op.Get(), base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { value_received = result; std::move(quit_closure).Run(); }), base::BindLambdaForTesting([&]() { failure_handler_called = true; std::move(quit_closure).Run(); }))); ASSERT_NO_FATAL_FAILURE( fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T())); run_loop.Run(); ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received); ASSERT_FALSE(failure_handler_called); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncHandlers_NoArgsFailureHandler_Failure) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); bool failure_handler_called = false; bool success_handler_called = false; ASSERT_HRESULT_SUCCEEDED( PostAsyncHandlers(async_op.Get(), base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { success_handler_called = true; std::move(quit_closure).Run(); }), base::BindLambdaForTesting([&]() { failure_handler_called = true; std::move(quit_closure).Run(); }))); HRESULT test_error = (HRESULT)0x87654321L; ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(test_error)); run_loop.Run(); ASSERT_FALSE(success_handler_called); ASSERT_TRUE(failure_handler_called); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncHandlers_HRESULTFailureHandler_Success) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); base::test::AsyncResultsTestValues templated_values; auto value_received = templated_values.GetDefaultValue_AsyncResultsT(); bool failure_handler_called = false; ASSERT_HRESULT_SUCCEEDED( PostAsyncHandlers(async_op.Get(), base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { value_received = result; std::move(quit_closure).Run(); }), base::BindLambdaForTesting([&](HRESULT hr) { failure_handler_called = true; std::move(quit_closure).Run(); }))); ASSERT_NO_FATAL_FAILURE( fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T())); run_loop.Run(); ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received); ASSERT_FALSE(failure_handler_called); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncHandlers_HRESULTFailureHandler_Failure) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); bool success_handler_called = false; HRESULT hr_received = S_OK; ASSERT_HRESULT_SUCCEEDED( PostAsyncHandlers(async_op.Get(), base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { success_handler_called = true; std::move(quit_closure).Run(); }), base::BindLambdaForTesting([&](HRESULT hr) { hr_received = hr; std::move(quit_closure).Run(); }))); HRESULT test_error = (HRESULT)0x87654321L; ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(test_error)); run_loop.Run(); ASSERT_FALSE(success_handler_called); ASSERT_EQ(test_error, hr_received); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncHandlers_HRESULTAndResultFailureHandler_Success) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); base::test::AsyncResultsTestValues templated_values; auto value_received = templated_values.GetDefaultValue_AsyncResultsT(); bool failure_handler_called = false; ASSERT_HRESULT_SUCCEEDED(PostAsyncHandlers( async_op.Get(), base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { value_received = result; std::move(quit_closure).Run(); }), base::BindLambdaForTesting( [&](HRESULT hr, internal::AsyncResultsT result) { failure_handler_called = true; std::move(quit_closure).Run(); }))); ASSERT_NO_FATAL_FAILURE( fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T())); run_loop.Run(); ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received); ASSERT_FALSE(failure_handler_called); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncHandlers_HRESULTAndResultFailureHandler_Failure) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); bool success_handler_called = false; HRESULT hr_received = S_OK; base::test::AsyncResultsTestValues templated_values; auto value_received = templated_values.GetDefaultValue_AsyncResultsT(); ASSERT_HRESULT_SUCCEEDED(PostAsyncHandlers( async_op.Get(), base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { success_handler_called = true; std::move(quit_closure).Run(); }), base::BindLambdaForTesting( [&](HRESULT hr, internal::AsyncResultsT result) { hr_received = hr; value_received = result; std::move(quit_closure).Run(); }))); ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithErrorResult( templated_values.GetTestValue_T())); run_loop.Run(); ASSERT_FALSE(success_handler_called); ASSERT_HRESULT_SUCCEEDED(hr_received); ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncResults_Success) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); base::test::AsyncResultsTestValues templated_values; auto value_received = templated_values.GetDefaultValue_AsyncResultsT(); ASSERT_HRESULT_SUCCEEDED(PostAsyncResults( async_op, base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { value_received = result; std::move(quit_closure).Run(); }))); ASSERT_NO_FATAL_FAILURE( fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T())); run_loop.Run(); ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received); } TYPED_TEST_P(PostAsyncResultsTest, PostAsyncResults_Failure) { base::test::SingleThreadTaskEnvironment task_environment; auto fake_iasync_op = Microsoft::WRL::Make>(); ComPtr> async_op; ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op)); RunLoop run_loop; auto quit_closure = run_loop.QuitClosure(); base::test::AsyncResultsTestValues templated_values; auto value_received = templated_values.GetTestValue_AsyncResultsT(); ASSERT_HRESULT_SUCCEEDED(PostAsyncResults( async_op, base::BindLambdaForTesting( [&](internal::AsyncResultsT result) { value_received = result; std::move(quit_closure).Run(); }))); ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(E_FAIL)); run_loop.Run(); ASSERT_EQ(templated_values.GetDefaultValue_AsyncResultsT(), value_received); } REGISTER_TYPED_TEST_SUITE_P( PostAsyncResultsTest, GetAsyncResultsT_Success, GetAsyncResultsT_Failure, PostAsyncOperationCompletedHandler_Success, PostAsyncOperationCompletedHandler_Failure, PostAsyncHandlers_OnlySuccessHandler_Success, PostAsyncHandlers_OnlySuccessHandler_Failure, PostAsyncHandlers_NoArgsFailureHandler_Success, PostAsyncHandlers_NoArgsFailureHandler_Failure, PostAsyncHandlers_HRESULTFailureHandler_Success, PostAsyncHandlers_HRESULTFailureHandler_Failure, PostAsyncHandlers_HRESULTAndResultFailureHandler_Success, PostAsyncHandlers_HRESULTAndResultFailureHandler_Failure, PostAsyncResults_Success, PostAsyncResults_Failure); INSTANTIATE_TYPED_TEST_SUITE_P(Win, PostAsyncResultsTest, base::test::AsyncResultsTestValuesTypes); } // namespace win } // namespace base