Skip to content

Commit

Permalink
Provide winrt_activation_handler to hook/mock activation (#477)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Jan 16, 2020
1 parent 1e3907d commit 80de096
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
5 changes: 5 additions & 0 deletions strings/base_activation.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ namespace winrt::impl
template <typename Interface>
hresult get_runtime_activation_factory(param::hstring const& name, void** result) noexcept
{
if (winrt_activation_handler)
{
return winrt_activation_handler(*(void**)(&name), guid_of<Interface>(), result);
}

static int32_t(__stdcall * handler)(void* classId, guid const& iid, void** factory) noexcept;

impl::load_runtime_function("RoGetActivationFactory", handler,
Expand Down
1 change: 1 addition & 0 deletions strings/base_extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
__declspec(selectany) int32_t(__stdcall* winrt_to_hresult_handler)(void* address) noexcept {};
__declspec(selectany) void(__stdcall* winrt_suspend_handler)(void const* token) noexcept {};
__declspec(selectany) void(__stdcall* winrt_resume_handler)(void const* token) noexcept {};
__declspec(selectany) int32_t(__stdcall* winrt_activation_handler)(void* classId, winrt::guid const& iid, void** factory) noexcept {};

extern "C"
{
Expand Down
52 changes: 52 additions & 0 deletions test/test/custom_activation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "winrt/Windows.Foundation.Numerics.h"
#include "catch.hpp"

using namespace winrt;
using namespace Windows::Foundation;

namespace
{
struct custom_factory : implements<custom_factory, IUriRuntimeClassFactory>
{
inline static Uri mock_uri{ nullptr };

Uri CreateUri(hstring const& value) const
{
REQUIRE(value == L"http://ignored.com");
return mock_uri;
}

Uri CreateWithRelativeUri(hstring const&, hstring const&) const
{
throw hresult_not_implemented();
}
};

int32_t __stdcall handler(void* classId, winrt::guid const& iid, void** factory) noexcept
{
bool expected = reinterpret_cast<hstring const&>(classId) == L"Windows.Foundation.Uri";
REQUIRE(expected);
REQUIRE(iid == guid_of<IUriRuntimeClassFactory>());

*factory = detach_abi(make<custom_factory>());
return 0;
}
}

TEST_CASE("custom_activation")
{
custom_factory::mock_uri = Uri(L"http://actual.com");
clear_factory_cache();

// Set up global handler
REQUIRE(!winrt_activation_handler);
winrt_activation_handler = handler;

// Windows.Foundation.Uri activation factory now returns mock object
auto uri = Uri(L"http://ignored.com");
REQUIRE(uri.Domain() == L"actual.com");

// Remove global handler
winrt_activation_handler = nullptr;
clear_factory_cache();
}
10 changes: 10 additions & 0 deletions test/test/test.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,16 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="custom_activation.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="custom_error.cpp" />
<ClCompile Include="delegate.cpp" />
<ClCompile Include="delegates.cpp" />
Expand Down

0 comments on commit 80de096

Please sign in to comment.