dolphin/Externals/WIL/tests/UniqueWinRTEventTokenTests.cpp
2020-02-09 19:01:44 +01:00

267 lines
8.9 KiB
C++

#include <wil/winrt.h>
#include <wrl/implements.h>
#include "common.h"
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
namespace wiltest
{
class AbiTestEventSender WrlFinal : public RuntimeClass<
RuntimeClassFlags<RuntimeClassType::WinRtClassicComMix>,
IClosable,
IMemoryBufferReference,
FtmBase>
{
public:
// IMemoryBufferReference
IFACEMETHODIMP get_Capacity(_Out_ UINT32* value)
{
*value = 0;
return S_OK;
}
IFACEMETHODIMP add_Closed(
_In_ ITypedEventHandler<IMemoryBufferReference*, IInspectable*>* handler,
_Out_ ::EventRegistrationToken* token)
{
return m_closedEvent.Add(handler, token);
}
IFACEMETHODIMP remove_Closed(::EventRegistrationToken token)
{
return m_closedEvent.Remove(token);
}
// IClosable
IFACEMETHODIMP Close()
{
RETURN_IF_FAILED(m_closedEvent.InvokeAll(this, nullptr));
return S_OK;
}
private:
Microsoft::WRL::EventSource<ITypedEventHandler<IMemoryBufferReference*, IInspectable*>> m_closedEvent;
};
}
TEST_CASE("UniqueWinRTEventTokenTests::AbiUniqueWinrtEventTokenEventSubscribe", "[winrt][unique_winrt_event_token]")
{
ComPtr<IMemoryBufferReference> testEventSender;
REQUIRE_SUCCEEDED(MakeAndInitialize<wiltest::AbiTestEventSender>(&testEventSender));
ComPtr<IClosable> closable;
testEventSender.As(&closable);
int timesInvoked = 0;
auto handler = Callback<Implements<RuntimeClassFlags<ClassicCom>,
ITypedEventHandler<IMemoryBufferReference*, IInspectable*>, FtmBase>>
([&timesInvoked](IInspectable*, IInspectable*)
{
timesInvoked++;
return S_OK;
});
REQUIRE(timesInvoked == 0);
{
wil::unique_winrt_event_token<IMemoryBufferReference> token;
REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &token));
REQUIRE(static_cast<bool>(token));
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 1);
}
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 1);
}
TEST_CASE("UniqueWinRTEventTokenTests::AbiUniqueWinrtEventTokenEarlyReset", "[winrt][unique_winrt_event_token]")
{
ComPtr<IMemoryBufferReference> testEventSender;
REQUIRE_SUCCEEDED(MakeAndInitialize<wiltest::AbiTestEventSender>(&testEventSender));
ComPtr<IClosable> closable;
testEventSender.As(&closable);
int timesInvoked = 0;
auto handler = Callback<Implements<RuntimeClassFlags<ClassicCom>,
ITypedEventHandler<IMemoryBufferReference*, IInspectable*>, FtmBase>>
([&timesInvoked](IInspectable*, IInspectable*)
{
timesInvoked++;
return S_OK;
});
REQUIRE(timesInvoked == 0);
wil::unique_winrt_event_token<IMemoryBufferReference> token;
REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &token));
REQUIRE(static_cast<bool>(token));
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 1);
token.reset();
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 1);
}
TEST_CASE("UniqueWinRTEventTokenTests::AbiUniqueWinrtEventTokenMoveTokenToDifferentScope", "[winrt][unique_winrt_event_token]")
{
ComPtr<IMemoryBufferReference> testEventSender;
REQUIRE_SUCCEEDED(MakeAndInitialize<wiltest::AbiTestEventSender>(&testEventSender));
ComPtr<IClosable> closable;
testEventSender.As(&closable);
int timesInvoked = 0;
auto handler = Callback<Implements<RuntimeClassFlags<ClassicCom>,
ITypedEventHandler<IMemoryBufferReference*, IInspectable*>, FtmBase>>
([&timesInvoked](IInspectable*, IInspectable*)
{
timesInvoked++;
return S_OK;
});
REQUIRE(timesInvoked == 0);
wil::unique_winrt_event_token<IMemoryBufferReference> outerToken;
REQUIRE_FALSE(static_cast<bool>(outerToken));
{
wil::unique_winrt_event_token<IMemoryBufferReference> token;
REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &token));
REQUIRE(static_cast<bool>(token));
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 1);
outerToken = std::move(token);
REQUIRE_FALSE(static_cast<bool>(token));
REQUIRE(static_cast<bool>(outerToken));
}
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 2);
}
TEST_CASE("UniqueWinRTEventTokenTests::AbiUniqueWinrtEventTokenMoveConstructor", "[winrt][unique_winrt_event_token]")
{
ComPtr<IMemoryBufferReference> testEventSender;
REQUIRE_SUCCEEDED(MakeAndInitialize<wiltest::AbiTestEventSender>(&testEventSender));
ComPtr<IClosable> closable;
testEventSender.As(&closable);
int timesInvoked = 0;
auto handler = Callback<Implements<RuntimeClassFlags<ClassicCom>,
ITypedEventHandler<IMemoryBufferReference*, IInspectable*>, FtmBase>>
([&timesInvoked](IInspectable*, IInspectable*)
{
timesInvoked++;
return S_OK;
});
REQUIRE(timesInvoked == 0);
wil::unique_winrt_event_token<IMemoryBufferReference> firstToken;
REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &firstToken));
REQUIRE(static_cast<bool>(firstToken));
closable->Close();
REQUIRE(timesInvoked == 1);
wil::unique_winrt_event_token<IMemoryBufferReference> secondToken(std::move(firstToken));
REQUIRE_FALSE(static_cast<bool>(firstToken));
REQUIRE(static_cast<bool>(secondToken));
closable->Close();
REQUIRE(timesInvoked == 2);
firstToken.reset();
closable->Close();
REQUIRE(timesInvoked == 3);
secondToken.reset();
closable->Close();
REQUIRE(timesInvoked == 3);
}
TEST_CASE("UniqueWinRTEventTokenTests::AbiUniqueWinrtEventTokenReleaseAndReattachToNewWrapper", "[winrt][unique_winrt_event_token]")
{
ComPtr<IMemoryBufferReference> testEventSender;
REQUIRE_SUCCEEDED(MakeAndInitialize<wiltest::AbiTestEventSender>(&testEventSender));
ComPtr<IClosable> closable;
testEventSender.As(&closable);
int timesInvoked = 0;
auto handler = Callback<Implements<RuntimeClassFlags<ClassicCom>,
ITypedEventHandler<IMemoryBufferReference*, IInspectable*>, FtmBase>>
([&timesInvoked](IInspectable*, IInspectable*)
{
timesInvoked++;
return S_OK;
});
REQUIRE(timesInvoked == 0);
wil::unique_winrt_event_token<IMemoryBufferReference> firstToken;
REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &firstToken));
REQUIRE(static_cast<bool>(firstToken));
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 1);
::EventRegistrationToken rawToken = firstToken.release();
REQUIRE_FALSE(static_cast<bool>(firstToken));
REQUIRE(rawToken.value != 0);
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 2);
wil::unique_winrt_event_token<IMemoryBufferReference> secondToken(
rawToken, testEventSender.Get(), &IMemoryBufferReference::remove_Closed);
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 3);
secondToken.reset();
REQUIRE_SUCCEEDED(closable->Close());
REQUIRE(timesInvoked == 3);
}
TEST_CASE("UniqueWinRTEventTokenTests::AbiUniqueWinrtEventTokenPolicyVariants", "[winrt][unique_winrt_event_token]")
{
ComPtr<IMemoryBufferReference> testEventSender;
REQUIRE_SUCCEEDED(MakeAndInitialize<wiltest::AbiTestEventSender>(&testEventSender));
ComPtr<IClosable> closable;
testEventSender.As(&closable);
int timesInvoked = 0;
auto handler = Callback<Implements<RuntimeClassFlags<ClassicCom>,
ITypedEventHandler<IMemoryBufferReference*, IInspectable*>, FtmBase>>
([&timesInvoked](IInspectable*, IInspectable*)
{
timesInvoked++;
return S_OK;
});
REQUIRE(timesInvoked == 0);
{
#ifdef WIL_ENABLE_EXCEPTIONS
auto exceptionPolicyToken = WI_MakeUniqueWinRtEventToken(Closed, testEventSender.Get(), handler.Get());
REQUIRE(static_cast<bool>(exceptionPolicyToken));
#endif
auto failFastPolicyToken = WI_MakeUniqueWinRtEventTokenFailFast(Closed, testEventSender.Get(), handler.Get());
REQUIRE(static_cast<bool>(failFastPolicyToken));
REQUIRE_SUCCEEDED(closable->Close());
#ifdef WIL_ENABLE_EXCEPTIONS
REQUIRE(timesInvoked == 2);
#else
REQUIRE(timesInvoked == 1);
#endif
}
REQUIRE_SUCCEEDED(closable->Close());
#ifdef WIL_ENABLE_EXCEPTIONS
REQUIRE(timesInvoked == 2);
#else
REQUIRE(timesInvoked == 1);
#endif
}