#include #include #include "common.h" using namespace ABI::Windows::Foundation; using namespace Microsoft::WRL; namespace wiltest { class AbiTestEventSender WrlFinal : public RuntimeClass< RuntimeClassFlags, IClosable, IMemoryBufferReference, FtmBase> { public: // IMemoryBufferReference IFACEMETHODIMP get_Capacity(_Out_ UINT32* value) { *value = 0; return S_OK; } IFACEMETHODIMP add_Closed( _In_ ITypedEventHandler* 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> m_closedEvent; }; } TEST_CASE("UniqueWinRTEventTokenTests::AbiUniqueWinrtEventTokenEventSubscribe", "[winrt][unique_winrt_event_token]") { ComPtr testEventSender; REQUIRE_SUCCEEDED(MakeAndInitialize(&testEventSender)); ComPtr closable; testEventSender.As(&closable); int timesInvoked = 0; auto handler = Callback, ITypedEventHandler, FtmBase>> ([×Invoked](IInspectable*, IInspectable*) { timesInvoked++; return S_OK; }); REQUIRE(timesInvoked == 0); { wil::unique_winrt_event_token token; REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &token)); REQUIRE(static_cast(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 testEventSender; REQUIRE_SUCCEEDED(MakeAndInitialize(&testEventSender)); ComPtr closable; testEventSender.As(&closable); int timesInvoked = 0; auto handler = Callback, ITypedEventHandler, FtmBase>> ([×Invoked](IInspectable*, IInspectable*) { timesInvoked++; return S_OK; }); REQUIRE(timesInvoked == 0); wil::unique_winrt_event_token token; REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &token)); REQUIRE(static_cast(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 testEventSender; REQUIRE_SUCCEEDED(MakeAndInitialize(&testEventSender)); ComPtr closable; testEventSender.As(&closable); int timesInvoked = 0; auto handler = Callback, ITypedEventHandler, FtmBase>> ([×Invoked](IInspectable*, IInspectable*) { timesInvoked++; return S_OK; }); REQUIRE(timesInvoked == 0); wil::unique_winrt_event_token outerToken; REQUIRE_FALSE(static_cast(outerToken)); { wil::unique_winrt_event_token token; REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &token)); REQUIRE(static_cast(token)); REQUIRE_SUCCEEDED(closable->Close()); REQUIRE(timesInvoked == 1); outerToken = std::move(token); REQUIRE_FALSE(static_cast(token)); REQUIRE(static_cast(outerToken)); } REQUIRE_SUCCEEDED(closable->Close()); REQUIRE(timesInvoked == 2); } TEST_CASE("UniqueWinRTEventTokenTests::AbiUniqueWinrtEventTokenMoveConstructor", "[winrt][unique_winrt_event_token]") { ComPtr testEventSender; REQUIRE_SUCCEEDED(MakeAndInitialize(&testEventSender)); ComPtr closable; testEventSender.As(&closable); int timesInvoked = 0; auto handler = Callback, ITypedEventHandler, FtmBase>> ([×Invoked](IInspectable*, IInspectable*) { timesInvoked++; return S_OK; }); REQUIRE(timesInvoked == 0); wil::unique_winrt_event_token firstToken; REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &firstToken)); REQUIRE(static_cast(firstToken)); closable->Close(); REQUIRE(timesInvoked == 1); wil::unique_winrt_event_token secondToken(std::move(firstToken)); REQUIRE_FALSE(static_cast(firstToken)); REQUIRE(static_cast(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 testEventSender; REQUIRE_SUCCEEDED(MakeAndInitialize(&testEventSender)); ComPtr closable; testEventSender.As(&closable); int timesInvoked = 0; auto handler = Callback, ITypedEventHandler, FtmBase>> ([×Invoked](IInspectable*, IInspectable*) { timesInvoked++; return S_OK; }); REQUIRE(timesInvoked == 0); wil::unique_winrt_event_token firstToken; REQUIRE_SUCCEEDED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, testEventSender.Get(), handler.Get(), &firstToken)); REQUIRE(static_cast(firstToken)); REQUIRE_SUCCEEDED(closable->Close()); REQUIRE(timesInvoked == 1); ::EventRegistrationToken rawToken = firstToken.release(); REQUIRE_FALSE(static_cast(firstToken)); REQUIRE(rawToken.value != 0); REQUIRE_SUCCEEDED(closable->Close()); REQUIRE(timesInvoked == 2); wil::unique_winrt_event_token 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 testEventSender; REQUIRE_SUCCEEDED(MakeAndInitialize(&testEventSender)); ComPtr closable; testEventSender.As(&closable); int timesInvoked = 0; auto handler = Callback, ITypedEventHandler, FtmBase>> ([×Invoked](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(exceptionPolicyToken)); #endif auto failFastPolicyToken = WI_MakeUniqueWinRtEventTokenFailFast(Closed, testEventSender.Get(), handler.Get()); REQUIRE(static_cast(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 }