Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
059a113
Build clean with VS 2019 (Dev16/19.20)
kennykerr Jan 2, 2019
55410a6
capture
kennykerr Jan 2, 2019
c4c4e32
VariadicDelegate
kennykerr Jan 2, 2019
93c76d4
Ported abi guard tests from cppwinrt repo.
kennykerr Jan 2, 2019
52836be
Ported agile ref tests from cppwinrt repo.
kennykerr Jan 2, 2019
5811be7
GetResults
kennykerr Jan 3, 2019
f99c3ec
final_suspend
kennykerr Jan 3, 2019
084c731
Moving completion to final_suspend
kennykerr Jan 3, 2019
c85d2dc
AsyncNoSuspend
kennykerr Jan 3, 2019
d6cfbaf
AsyncSuspend
kennykerr Jan 3, 2019
5de8d94
AsyncProgress
kennykerr Jan 3, 2019
3e921d2
AsyncResult
kennykerr Jan 3, 2019
ad2f96d
More tests
kennykerr Jan 3, 2019
bffb2bf
cmake
kennykerr Jan 4, 2019
7d5907e
AsyncAutoCancel
kennykerr Jan 4, 2019
7c1c3eb
AsyncCancelCallback
kennykerr Jan 4, 2019
1f7d97d
AsyncCheckCancel
kennykerr Jan 8, 2019
34f04d9
AsyncThrow
kennykerr Jan 8, 2019
ddf465f
comments
kennykerr Jan 8, 2019
2343cd8
AsyncThrow
kennykerr Jan 8, 2019
3ccb1e9
merge
kennykerr Jan 8, 2019
dd7235f
AsyncLocal
kennykerr Jan 8, 2019
af35324
noexcept
kennykerr Jan 8, 2019
4e4aa80
Sleep
kennykerr Jan 8, 2019
f15d4b2
Gor's feedback
kennykerr Jan 8, 2019
ebeab49
move
kennykerr Jan 9, 2019
df08793
This seems to handle both lvalues and rvalues without forcing a copy …
kennykerr Jan 9, 2019
c363912
Split out rvalue and lvalue to support braces (as "perfect" forwardin…
kennykerr Jan 9, 2019
fb896b5
Clean up
kennykerr Jan 10, 2019
d05c39e
More cancellation testing
kennykerr Jan 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/test/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ target_sources(cpp_test PUBLIC
test/AbiGuard.cpp
test/AgileRef.cpp
test/Async.cpp
test/AsyncNoSuspend.cpp
test/AsyncReturn.cpp
test/Collections.cpp
test/Composable.cpp
test/Edge.cpp
Expand Down Expand Up @@ -52,6 +54,14 @@ else()
main.cpp
test/Interop.cpp
test/Capture.cpp
test/AsyncAutoCancel.cpp
test/AsyncCancelCallback.cpp
test/AsyncCheckCancel.cpp
test/AsyncLocal.cpp
test/AsyncProgress.cpp
test/AsyncResult.cpp
test/AsyncSuspend.cpp
test/AsyncThrow.cpp
)
endif()

Expand Down
75 changes: 75 additions & 0 deletions src/test/cpp/test/AsyncAutoCancel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "catch.hpp"
#include <windows.h>
#include "winrt/Windows.Foundation.h"

using namespace winrt;
using namespace Windows::Foundation;

namespace
{
//
// Checks that the coroutine is automatically canceled when reaching a suspension point.
//

IAsyncAction Action(HANDLE event)
{
co_await resume_on_signal(event);
co_await std::experimental::suspend_never();
REQUIRE(false);
}

IAsyncActionWithProgress<int> ActionWithProgress(HANDLE event)
{
co_await resume_on_signal(event);
co_await std::experimental::suspend_never();
REQUIRE(false);
}

IAsyncOperation<int> Operation(HANDLE event)
{
co_await resume_on_signal(event);
co_await std::experimental::suspend_never();
REQUIRE(false);
co_return 1;
}

IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event)
{
co_await resume_on_signal(event);
co_await std::experimental::suspend_never();
REQUIRE(false);
co_return 1;
}

template <typename F>
void Check(F make)
{
handle start{ CreateEvent(nullptr, true, false, nullptr) };
handle completed{ CreateEvent(nullptr, true, false, nullptr) };
auto async = make(start.get());
REQUIRE(async.Status() == AsyncStatus::Started);

async.Completed([&](auto&& sender, AsyncStatus status)
{
REQUIRE(async == sender);
REQUIRE(status == AsyncStatus::Canceled);
SetEvent(completed.get());
});

async.Cancel();
SetEvent(start.get());
REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0);

REQUIRE(async.Status() == AsyncStatus::Canceled);
REQUIRE(async.ErrorCode() == HRESULT_FROM_WIN32(ERROR_CANCELLED));
REQUIRE_THROWS_AS(async.GetResults(), hresult_canceled);
}
}

TEST_CASE("AsyncAutoCancel")
{
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}
95 changes: 95 additions & 0 deletions src/test/cpp/test/AsyncCancelCallback.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "catch.hpp"
#include <windows.h>
#include "winrt/Windows.Foundation.h"

using namespace winrt;
using namespace Windows::Foundation;

namespace
{
//
// Checks that the cancellation callback is invoked.
//

IAsyncAction Action(HANDLE event, bool& canceled)
{
auto cancel = co_await get_cancellation_token();

cancel.callback([&]
{
REQUIRE(!canceled);
canceled = true;
});

co_await resume_on_signal(event);
co_await std::experimental::suspend_never();
REQUIRE(false);
}

IAsyncActionWithProgress<int> ActionWithProgress(HANDLE event, bool& canceled)
{
auto cancel = co_await get_cancellation_token();

cancel.callback([&]
{
REQUIRE(!canceled);
canceled = true;
});

co_await resume_on_signal(event);
co_await std::experimental::suspend_never();
REQUIRE(false);
}

IAsyncOperation<int> Operation(HANDLE event, bool& canceled)
{
auto cancel = co_await get_cancellation_token();

cancel.callback([&]
{
REQUIRE(!canceled);
canceled = true;
});

co_await resume_on_signal(event);
co_await std::experimental::suspend_never();
REQUIRE(false);
co_return 1;
}

IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event, bool& canceled)
{
auto cancel = co_await get_cancellation_token();

cancel.callback([&]
{
REQUIRE(!canceled);
canceled = true;
});

co_await resume_on_signal(event);
co_await std::experimental::suspend_never();
REQUIRE(false);
co_return 1;
}

template <typename F>
void Check(F make)
{
handle event{ CreateEvent(nullptr, true, false, nullptr) };
bool canceled = false;
auto async = make(event.get(), canceled);
async.Cancel();
REQUIRE(canceled);
SetEvent(event.get());
REQUIRE_THROWS_AS(async.GetResults(), hresult_canceled);
}
}

TEST_CASE("AsyncCancelCallback")
{
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}
109 changes: 109 additions & 0 deletions src/test/cpp/test/AsyncCheckCancel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include "catch.hpp"
#include <windows.h>
#include "winrt/Windows.Foundation.h"

using namespace winrt;
using namespace Windows::Foundation;

namespace
{
//
// Checks that manual cancellation checks work.
//

IAsyncAction Action(HANDLE event, bool& canceled)
{
co_await resume_on_signal(event);
auto cancel = co_await get_cancellation_token();

if (cancel())
{
REQUIRE(!canceled);
canceled = true;
}

co_await std::experimental::suspend_never();
REQUIRE(false);
}

IAsyncActionWithProgress<int> ActionWithProgress(HANDLE event, bool& canceled)
{
co_await resume_on_signal(event);
auto cancel = co_await get_cancellation_token();

if (cancel())
{
REQUIRE(!canceled);
canceled = true;
}

co_await std::experimental::suspend_never();
REQUIRE(false);
}

IAsyncOperation<int> Operation(HANDLE event, bool& canceled)
{
co_await resume_on_signal(event);
auto cancel = co_await get_cancellation_token();

if (cancel())
{
REQUIRE(!canceled);
canceled = true;
}

co_await std::experimental::suspend_never();
REQUIRE(false);
co_return 1;
}

IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event, bool& canceled)
{
co_await resume_on_signal(event);
auto cancel = co_await get_cancellation_token();

if (cancel())
{
REQUIRE(!canceled);
canceled = true;
}

co_await std::experimental::suspend_never();
REQUIRE(false);
co_return 1;
}

template <typename F>
void Check(F make)
{
handle start{ CreateEvent(nullptr, true, false, nullptr) };
handle completed{ CreateEvent(nullptr, true, false, nullptr) };
bool canceled = false;
auto async = make(start.get(), canceled);
REQUIRE(async.Status() == AsyncStatus::Started);

async.Completed([&](auto&& sender, AsyncStatus status)
{
REQUIRE(async == sender);
REQUIRE(status == AsyncStatus::Canceled);
REQUIRE(canceled);
SetEvent(completed.get());
});

async.Cancel();
SetEvent(start.get());
REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0);

REQUIRE(async.Status() == AsyncStatus::Canceled);
REQUIRE(async.ErrorCode() == HRESULT_FROM_WIN32(ERROR_CANCELLED));
REQUIRE_THROWS_AS(async.GetResults(), hresult_canceled);
}
}

TEST_CASE("AsyncCheckCancel")
{
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}
76 changes: 76 additions & 0 deletions src/test/cpp/test/AsyncLocal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "catch.hpp"
#include <windows.h>
#include "winrt/Windows.Foundation.h"

using namespace winrt;
using namespace Windows::Foundation;

namespace
{
//
// Checks that coroutine locals are destroyed prior to notifying waiters.
//

struct Local
{
bool& destroyed;

~Local()
{
REQUIRE(!destroyed);
destroyed = true;
}
};

IAsyncAction Action(HANDLE event, bool& destroyed)
{
co_await resume_on_signal(event);
Local local{ destroyed };
}

IAsyncActionWithProgress<int> ActionWithProgress(HANDLE event, bool& destroyed)
{
co_await resume_on_signal(event);
Local local{ destroyed };
}

IAsyncOperation<int> Operation(HANDLE event, bool& destroyed)
{
co_await resume_on_signal(event);
Local local{ destroyed };
co_return 1;
}

IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event, bool& destroyed)
{
co_await resume_on_signal(event);
Local local{ destroyed };
co_return 1;
}

template <typename F>
void Check(F make)
{
handle start{ CreateEvent(nullptr, true, false, nullptr) };
handle completed{ CreateEvent(nullptr, true, false, nullptr) };
bool destroyed = false;
auto async = make(start.get(), destroyed);

async.Completed([&](auto&&...)
{
REQUIRE(destroyed);
SetEvent(completed.get());
});

SetEvent(start.get());
REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0);
}
}

TEST_CASE("AsyncLocal")
{
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}
Loading