diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa568e50..2d37aa36 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,7 @@ jobs: compiler: [MSVC, clang-cl] arch: [x86, x64, arm64] config: [Debug, Release] - test_exe: [test, test_cpp20, test_cpp20_no_sourcelocation, test_win7, test_fast, test_slow, test_old, test_module_lock_custom, test_module_lock_none] + test_exe: [test, test_cpp20, test_cpp20_no_sourcelocation, test_fast, test_slow, test_old, test_module_lock_custom, test_module_lock_none] exclude: - arch: arm64 config: Debug @@ -250,120 +250,6 @@ jobs: _build/${{ matrix.arch }}/${{ matrix.config }}/*.lib _build/${{ matrix.arch }}/${{ matrix.config }}/*.pdb - test-llvm-mingw-cppwinrt: - name: 'llvm-mingw: Build and test' - strategy: - fail-fast: false - matrix: - arch: [i686, x86_64] - config: [Debug, Release] - runs-on: windows-latest - env: - CMAKE_COLOR_DIAGNOSTICS: 1 - CLICOLOR_FORCE: 1 - steps: - - uses: actions/checkout@v3 - - - id: setup-llvm - name: Set up llvm-mingw - uses: ./.github/actions/setup-llvm-mingw - with: - host-arch: ${{ matrix.arch }} - - - name: Build cppwinrt - run: | - mkdir build - cd build - if ("${{ matrix.config }}" -eq "Debug") { - $sanitizers = "TRUE" - } else { - $sanitizers = "FALSE" - } - cmake ../ -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=${{ matrix.config }} ` - -DDOWNLOAD_WINDOWSNUMERICS=TRUE ` - -DUSE_ANSI_COLOR=TRUE ` - -DCMAKE_CXX_FLAGS="-fansi-escape-codes" ` - -DENABLE_TEST_SANITIZERS=$sanitizers - cmake --build . -j2 --target cppwinrt - - - name: Upload cppwinrt.exe - uses: actions/upload-artifact@v3 - with: - name: llvm-mingw-build-${{ matrix.arch }}-bin - path: build/cppwinrt.exe - - - name: Build tests - run: | - cd build - cmake --build . -j2 --target test-vanilla test_cpp20 test_cpp20_no_sourcelocation test_win7 test_old - - - name: Upload test binaries - uses: actions/upload-artifact@v3 - with: - name: llvm-mingw-tests-${{ matrix.arch }}-bin - path: build/test/*.exe - - - name: Run tests - run: | - cd build - $env:UBSAN_OPTIONS = "print_stacktrace=1" - ctest --verbose - - test-msys2-gcc-cppwinrt: - name: 'gcc/msys2: Build and test (${{ matrix.sys }}, ${{ matrix.config }})' - strategy: - fail-fast: false - matrix: - include: - # 32-bit builds are running out of memory - # - { sys: mingw32, arch: i686, config: Release } - - { sys: mingw64, arch: x86_64, config: Debug } - - { sys: mingw64, arch: x86_64, config: Release } - - { sys: ucrt64, arch: x86_64, config: Release } - runs-on: windows-latest - env: - CMAKE_COLOR_DIAGNOSTICS: 1 - CLICOLOR_FORCE: 1 - defaults: - run: - shell: msys2 {0} - steps: - - uses: msys2/setup-msys2@v2 - with: - msystem: ${{matrix.sys}} - update: true - pacboy: >- - crt:p - gcc:p - binutils:p - cmake:p - ninja:p - - - uses: actions/checkout@v3 - - - name: Build cppwinrt - run: | - mkdir build - cd build - if [[ "${{ matrix.arch }}" = "i686" ]]; then - skip_large_pch_arg="-DSKIP_LARGE_PCH=TRUE" - fi - cmake ../ -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.config }} \ - -DDOWNLOAD_WINDOWSNUMERICS=TRUE \ - -DUSE_ANSI_COLOR=TRUE \ - $skip_large_pch_arg - cmake --build . --target cppwinrt - - - name: Build tests - run: | - cd build - cmake --build . -j2 --target test-vanilla test_cpp20 test_cpp20_no_sourcelocation test_win7 test_old - - - name: Run tests - run: | - cd build - ctest --verbose - build-linux-cross-cppwinrt: name: 'cross: Cross-build from Linux' strategy: @@ -398,186 +284,6 @@ jobs: name: cross-build-${{ matrix.arch }}-bin path: install/bin/cppwinrt.exe - test-linux-cross-cppwinrt: - name: 'cross: Test run on Windows' - needs: build-linux-cross-cppwinrt - strategy: - fail-fast: false - matrix: - arch: [i686, x86_64] - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - - - name: Fetch cppwinrt executable - uses: actions/download-artifact@v3 - with: - name: cross-build-${{ matrix.arch }}-bin - path: ./.test - - - name: Run cppwinrt to build projection - run: | - .\.test\cppwinrt.exe -in local -out .\.test\out -verbose - - - id: setup-llvm - name: Set up llvm-mingw - uses: ./.github/actions/setup-llvm-mingw - with: - host-arch: ${{ matrix.arch }} - - - name: Build cppwinrt tests - run: | - mkdir build - cd build - cmake ../test -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug ` - -DCPPWINRT_PROJECTION_INCLUDE_DIR="../.test/out" ` - -DDOWNLOAD_WINDOWSNUMERICS=TRUE ` - -DUSE_ANSI_COLOR=TRUE - cmake --build . -j2 - - - name: Run tests - run: | - cd build - ctest --verbose - - build-linux-native-cppwinrt: - name: 'linux: GCC native build + mingw-w64 cross-build tests' - strategy: - fail-fast: false - matrix: - # TODO: Enable gcc build once Arch Linux gets more recent mingw-w64 headers (ver. 11 perhaps?) - # cross_toolchain: [gcc, llvm-mingw] - cross_toolchain: [llvm-mingw] - cross_arch: [i686, x86_64] - # include: - # - cross_toolchain: gcc - # container: - # image: archlinux:base-devel - runs-on: ubuntu-22.04 - container: ${{ matrix.container }} - defaults: - run: - shell: bash - env: - CMAKE_COLOR_DIAGNOSTICS: 1 - CLICOLOR_FORCE: 1 - steps: - - uses: actions/checkout@v3 - - - name: Install build tools - if: matrix.cross_toolchain == 'gcc' - run: | - pacman --noconfirm -Suuy - pacman --needed --noconfirm -S cmake ninja git - - - name: Build cppwinrt - run: | - cmake -S . -B build/native/ \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_INSTALL_PREFIX=$PWD/install/ - cmake --build build/native/ --target install -j2 - - - name: Test run (cppwinrt -?) - run: | - install/bin/cppwinrt -? - - - name: Test run (build projection using Windows.winmd) - run: | - curl -o Windows.winmd -L https://github.com/microsoft/windows-rs/raw/master/crates/libs/bindgen/default/Windows.winmd - install/bin/cppwinrt -in Windows.winmd -out /tmp/cppwinrt -verbose - - - id: setup-llvm - name: Set up llvm-mingw - if: matrix.cross_toolchain == 'llvm-mingw' - uses: ./.github/actions/setup-llvm-mingw - - - name: Install GCC cross compiler - if: matrix.cross_toolchain == 'gcc' - run: | - pacman --needed --noconfirm -S mingw-w64-gcc - - - name: Cross-build tests using projection - run: | - cmake -S test -B build/cross-tests --toolchain "$PWD/cross-mingw-toolchain.cmake" \ - -DCMAKE_SYSTEM_PROCESSOR=${{ matrix.cross_arch }} \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_CXX_FLAGS="-static" \ - -DCPPWINRT_PROJECTION_INCLUDE_DIR=/tmp/cppwinrt \ - -DDOWNLOAD_WINDOWSNUMERICS=TRUE \ - -DUSE_ANSI_COLOR=TRUE - cmake --build build/cross-tests -j2 - - - name: Upload built tests - uses: actions/upload-artifact@v3 - with: - name: linux-native-cppwinrt-cross-build-tests-${{ matrix.cross_toolchain }}-${{ matrix.cross_arch }}-bin - path: build/cross-tests/*.exe - - test-linux-native-cppwinrt-cross-tests: - name: 'linux: Run llvm-mingw cross-build tests' - needs: build-linux-native-cppwinrt - strategy: - fail-fast: false - matrix: - # TODO: Enable gcc build test when it is buildable - # cross_toolchain: [gcc, llvm-mingw] - cross_toolchain: [llvm-mingw] - cross_arch: [i686, x86_64] - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - - - name: Fetch test executables - uses: actions/download-artifact@v3 - with: - name: linux-native-cppwinrt-cross-build-tests-${{ matrix.cross_toolchain }}-${{ matrix.cross_arch }}-bin - path: ./ - - - name: Run tests - run: | - $test_exes = ls *.exe -Name - $has_failed_tests = 0 - foreach ($test_exe in $test_exes) { - echo "::group::Run '$test_exe'" - & .\$test_exe --use-colour yes - echo "::endgroup::" - if ($LastExitCode -ne 0) { - echo "::error::Test '$test_exe' failed!" - $has_failed_tests = 1 - } - } - if ($has_failed_tests -ne 0) { - exit 1 - } - - build-macos-native-cppwinrt: - name: 'macOS: GCC native build' - runs-on: macos-latest - defaults: - run: - shell: bash - env: - CMAKE_COLOR_DIAGNOSTICS: 1 - CLICOLOR_FORCE: 1 - steps: - - uses: actions/checkout@v3 - - - name: Build cppwinrt - run: | - cmake -S . -B build/native/ \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_INSTALL_PREFIX=$PWD/install/ - cmake --build build/native/ --target install -j2 - - - name: Test run (cppwinrt -?) - run: | - install/bin/cppwinrt -? - - - name: Test run (build projection using Windows.winmd) - run: | - curl -o Windows.winmd -L https://github.com/microsoft/windows-rs/raw/master/crates/libs/bindgen/default/Windows.winmd - install/bin/cppwinrt -in Windows.winmd -out build/out -verbose - build-msvc-natvis: name: 'Build natvis' strategy: diff --git a/.pipelines/jobs/OneBranchTest.yml b/.pipelines/jobs/OneBranchTest.yml index 3acaccf7..d9634ff1 100644 --- a/.pipelines/jobs/OneBranchTest.yml +++ b/.pipelines/jobs/OneBranchTest.yml @@ -22,10 +22,6 @@ jobs: TestExe: 'test_cpp20_no_sourcelocation' TestProject: 'test_cpp20_no_sourcelocation' BuildPlatform: 'x86' - test_win7.x86: - TestExe: 'test_win7' - TestProject: 'test_win7' - BuildPlatform: 'x86' test_fast.x86: TestExe: 'test_fast' TestProject: 'test_fast' diff --git a/build_test_all.cmd b/build_test_all.cmd index 18585bab..89967a04 100644 --- a/build_test_all.cmd +++ b/build_test_all.cmd @@ -32,7 +32,6 @@ call msbuild /p:Configuration=%target_configuration%,Platform=%target_platform%, call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_cpp20 call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_cpp20_no_sourcelocation -call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_win7 call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_fast call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_slow call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_module_lock_custom diff --git a/cppwinrt.sln b/cppwinrt.sln index e08c2d1c..43e96ffa 100644 --- a/cppwinrt.sln +++ b/cppwinrt.sln @@ -104,13 +104,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_module_lock_custom", " EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{3C7EA5F8-6E8C-4376-B499-2CAF596384B0}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_win7", "test\test_win7\test_win7.vcxproj", "{2EF696B9-7F4A-410F-AE5C-5301565C0F08}" - ProjectSection(ProjectDependencies) = postProject - {A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270} = {A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270} - {D613FB39-5035-4043-91E2-BAB323908AF4} = {D613FB39-5035-4043-91E2-BAB323908AF4} - {F1C915B3-2C64-4992-AFB7-7F035B1A7607} = {F1C915B3-2C64-4992-AFB7-7F035B1A7607} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_cpp20", "test\test_cpp20\test_cpp20.vcxproj", "{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}" ProjectSection(ProjectDependencies) = postProject {A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270} = {A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270} @@ -452,22 +445,6 @@ Global {08C40663-B6A3-481E-8755-AE32BAD99501}.Release|x64.Build.0 = Release|x64 {08C40663-B6A3-481E-8755-AE32BAD99501}.Release|x86.ActiveCfg = Release|Win32 {08C40663-B6A3-481E-8755-AE32BAD99501}.Release|x86.Build.0 = Release|Win32 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|ARM.ActiveCfg = Debug|ARM - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|ARM.Build.0 = Debug|ARM - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|ARM64.Build.0 = Debug|ARM64 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|x64.ActiveCfg = Debug|x64 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|x64.Build.0 = Debug|x64 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|x86.ActiveCfg = Debug|Win32 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|x86.Build.0 = Debug|Win32 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|ARM.ActiveCfg = Release|ARM - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|ARM.Build.0 = Release|ARM - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|ARM64.ActiveCfg = Release|ARM64 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|ARM64.Build.0 = Release|ARM64 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x64.ActiveCfg = Release|x64 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x64.Build.0 = Release|x64 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x86.ActiveCfg = Release|Win32 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x86.Build.0 = Release|Win32 {5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM.ActiveCfg = Debug|ARM {5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM.Build.0 = Debug|ARM {5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -521,7 +498,6 @@ Global {303CC0FE-7D66-4F9F-B7A1-0AF7F9359074} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0} {D48A96C2-8512-4CC3-B6E4-7CFF07ED8ED3} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0} {08C40663-B6A3-481E-8755-AE32BAD99501} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0} - {2EF696B9-7F4A-410F-AE5C-5301565C0F08} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0} {5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0} {D4C8F881-84D5-4A7B-8BDE-AB4E34A05374} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0} EndGlobalSection diff --git a/run_tests.cmd b/run_tests.cmd index 71a9d129..77d88364 100644 --- a/run_tests.cmd +++ b/run_tests.cmd @@ -11,7 +11,6 @@ if "%target_configuration%"=="" set target_configuration=Debug call :run_test test call :run_test test_cpp20 call :run_test test_cpp20_no_sourcelocation -call :run_test test_win7 call :run_test test_fast call :run_test test_slow call :run_test test_old diff --git a/strings/base_activation.h b/strings/base_activation.h index b27cefb7..bb6be5ca 100644 --- a/strings/base_activation.h +++ b/strings/base_activation.h @@ -18,13 +18,6 @@ namespace winrt::impl using library_handle = handle_type; - inline int32_t __stdcall fallback_RoGetActivationFactory(void*, guid const&, void** factory) noexcept - { - *factory = nullptr; - return error_class_not_available; - } - - template WINRT_IMPL_NOINLINE hresult get_runtime_activation_factory_impl(param::hstring const& name, winrt::guid const& guid, void** result) noexcept { @@ -33,9 +26,7 @@ namespace winrt::impl return winrt_activation_handler(*(void**)(&name), guid, result); } - static int32_t(__stdcall * handler)(void* classId, winrt::guid const& iid, void** factory) noexcept; - impl::load_runtime_function(L"combase.dll", "RoGetActivationFactory", handler, fallback_RoGetActivationFactory); - hresult hr = handler(*(void**)(&name), guid, result); + hresult hr = WINRT_IMPL_RoGetActivationFactory(*(void**)(&name), guid, result); if (hr == impl::error_not_initialized) { @@ -48,7 +39,7 @@ namespace winrt::impl void* cookie; usage(&cookie); - hr = handler(*(void**)(&name), guid, result); + hr = WINRT_IMPL_RoGetActivationFactory(*(void**)(&name), guid, result); } if (hr == 0) diff --git a/strings/base_agile_ref.h b/strings/base_agile_ref.h index b2ff542d..8993d846 100644 --- a/strings/base_agile_ref.h +++ b/strings/base_agile_ref.h @@ -131,54 +131,9 @@ namespace winrt::impl return WINRT_IMPL_LoadLibraryExW(library, nullptr, 0x00001000 /* LOAD_LIBRARY_SEARCH_DEFAULT_DIRS */); } - template - void load_runtime_function(wchar_t const* library, char const* name, F& result, L fallback) noexcept - { - if (result) - { - return; - } - - result = reinterpret_cast(WINRT_IMPL_GetProcAddress(load_library(library), name)); - - if (result) - { - return; - } - - result = fallback; - } - - inline int32_t __stdcall fallback_RoGetAgileReference(uint32_t, winrt::guid const& iid, void* object, void** reference) noexcept - { - *reference = nullptr; - static constexpr guid git_clsid{ 0x00000323, 0x0000, 0x0000, { 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 } }; - - com_ptr git; - hresult hr = WINRT_IMPL_CoCreateInstance(git_clsid, nullptr, 1 /*CLSCTX_INPROC_SERVER*/, guid_of(), git.put_void()); - - if (hr < 0) - { - return hr; - } - - uint32_t cookie{}; - hr = git->RegisterInterfaceInGlobal(object, iid, &cookie); - - if (hr < 0) - { - return hr; - } - - *reference = new agile_ref_fallback(std::move(git), cookie); - return 0; - } - inline hresult get_agile_reference(winrt::guid const& iid, void* object, void** reference) noexcept { - static int32_t(__stdcall * handler)(uint32_t options, winrt::guid const& iid, void* object, void** reference) noexcept; - load_runtime_function(L"combase.dll", "RoGetAgileReference", handler, fallback_RoGetAgileReference); - return handler(0, iid, object, reference); + return WINRT_IMPL_RoGetAgileReference(0, iid, object, reference); } } diff --git a/strings/base_coroutine_threadpool.h b/strings/base_coroutine_threadpool.h index ba4d742b..e3a283e3 100644 --- a/strings/base_coroutine_threadpool.h +++ b/strings/base_coroutine_threadpool.h @@ -409,17 +409,9 @@ namespace winrt::impl } } - static int32_t __stdcall fallback_SetThreadpoolTimerEx(winrt::impl::ptp_timer, void*, uint32_t, uint32_t) noexcept - { - return 0; // pretend timer has already triggered and a callback is on its way - } - void fire_immediately() noexcept { - static int32_t(__stdcall * handler)(winrt::impl::ptp_timer, void*, uint32_t, uint32_t) noexcept; - impl::load_runtime_function(L"kernel32.dll", "SetThreadpoolTimerEx", handler, fallback_SetThreadpoolTimerEx); - - if (handler(m_timer.get(), nullptr, 0, 0)) + if (WINRT_IMPL_SetThreadpoolTimerEx(m_timer.get(), nullptr, 0, 0)) { int64_t now = 0; WINRT_IMPL_SetThreadpoolTimer(m_timer.get(), &now, 0, 0); @@ -513,10 +505,6 @@ namespace winrt::impl } private: - static int32_t __stdcall fallback_SetThreadpoolWaitEx(winrt::impl::ptp_wait, void*, void*, void*) noexcept - { - return 0; // pretend wait has already triggered and a callback is on its way - } void create_threadpool_wait() { @@ -534,10 +522,7 @@ namespace winrt::impl void fire_immediately() noexcept { - static int32_t(__stdcall * handler)(winrt::impl::ptp_wait, void*, void*, void*) noexcept; - impl::load_runtime_function(L"kernel32.dll", "SetThreadpoolWaitEx", handler, fallback_SetThreadpoolWaitEx); - - if (handler(m_wait.get(), nullptr, nullptr, nullptr)) + if (WINRT_IMPL_SetThreadpoolWaitEx(m_wait.get(), nullptr, nullptr, nullptr)) { int64_t now = 0; WINRT_IMPL_SetThreadpoolWait(m_wait.get(), WINRT_IMPL_GetCurrentProcess(), &now); diff --git a/strings/base_error.h b/strings/base_error.h index 98bb8e89..2a6eea28 100644 --- a/strings/base_error.h +++ b/strings/base_error.h @@ -175,11 +175,6 @@ namespace winrt::impl hstring const m_message; atomic_ref_count m_references{ 1 }; }; - - [[noreturn]] inline void __stdcall fallback_RoFailFastWithErrorContext(int32_t) noexcept - { - abort(); - } } WINRT_EXPORT namespace winrt @@ -301,18 +296,9 @@ WINRT_EXPORT namespace winrt private: - static int32_t __stdcall fallback_RoOriginateLanguageException(int32_t error, void* message, void*) noexcept - { - com_ptr info(new (std::nothrow) impl::error_info_fallback(error, message), take_ownership_from_abi); - WINRT_VERIFY_(0, WINRT_IMPL_SetErrorInfo(0, info.get())); - return 1; - } - void originate(hresult const code, void* message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept { - static int32_t(__stdcall* handler)(int32_t error, void* message, void* exception) noexcept; - impl::load_runtime_function(L"combase.dll", "RoOriginateLanguageException", handler, fallback_RoOriginateLanguageException); - WINRT_VERIFY(handler(code, message, nullptr)); + WINRT_VERIFY(WINRT_IMPL_RoOriginateLanguageException(code, message, nullptr)); // This is an extension point that can be filled in by other libraries (such as WIL) to get call outs when errors are // originated. This is intended for logging purposes. When possible include the std::source_information so that accurate @@ -642,9 +628,7 @@ WINRT_EXPORT namespace winrt [[noreturn]] inline void terminate() noexcept { - static void(__stdcall * handler)(int32_t) noexcept; - impl::load_runtime_function(L"combase.dll", "RoFailFastWithErrorContext", handler, impl::fallback_RoFailFastWithErrorContext); - handler(to_hresult()); + WINRT_IMPL_RoFailFastWithErrorContext(to_hresult()); abort(); } } diff --git a/strings/base_events.h b/strings/base_events.h index 139746fd..77952474 100644 --- a/strings/base_events.h +++ b/strings/base_events.h @@ -337,18 +337,10 @@ namespace winrt::impl return { new(raw) event_array(capacity), take_ownership_from_abi }; } - inline int32_t __stdcall fallback_RoTransformError(int32_t, int32_t, void*) noexcept - { - return 1; - } - WINRT_IMPL_NOINLINE inline bool report_failed_invoke() { int32_t const code = to_hresult(); - - static int32_t(__stdcall * handler)(int32_t, int32_t, void*) noexcept; - impl::load_runtime_function(L"combase.dll", "RoTransformError", handler, fallback_RoTransformError); - handler(code, 0, nullptr); + WINRT_IMPL_RoTransformError(code, 0, nullptr); if (code == static_cast(0x80010108) || // RPC_E_DISCONNECTED code == static_cast(0x800706BA) || // HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) diff --git a/strings/base_extern.h b/strings/base_extern.h index c0fb15ac..92872d41 100644 --- a/strings/base_extern.h +++ b/strings/base_extern.h @@ -24,6 +24,14 @@ __declspec(selectany) int32_t(__stdcall* winrt_activation_handler)(void* classId extern "C" { + int32_t __stdcall WINRT_IMPL_RoGetActivationFactory(void* classId, winrt::guid const& iid, void** factory) noexcept WINRT_IMPL_LINK(RoGetActivationFactory, 12); + int32_t __stdcall WINRT_IMPL_RoGetAgileReference(uint32_t options, winrt::guid const& iid, void* object, void** reference) noexcept WINRT_IMPL_LINK(RoGetAgileReference, 16); + int32_t __stdcall WINRT_IMPL_SetThreadpoolTimerEx(winrt::impl::ptp_timer, void*, uint32_t, uint32_t) noexcept WINRT_IMPL_LINK(SetThreadpoolTimerEx, 16); + int32_t __stdcall WINRT_IMPL_SetThreadpoolWaitEx(winrt::impl::ptp_wait, void*, void*, void*) noexcept WINRT_IMPL_LINK(SetThreadpoolWaitEx, 16); + int32_t __stdcall WINRT_IMPL_RoOriginateLanguageException(int32_t error, void* message, void* exception) noexcept WINRT_IMPL_LINK(RoOriginateLanguageException, 12); + void __stdcall WINRT_IMPL_RoFailFastWithErrorContext(int32_t) noexcept WINRT_IMPL_LINK(RoFailFastWithErrorContext, 4); + int32_t __stdcall WINRT_IMPL_RoTransformError(int32_t, int32_t, void*) noexcept WINRT_IMPL_LINK(RoTransformError, 12); + void* __stdcall WINRT_IMPL_LoadLibraryExW(wchar_t const* name, void* unused, uint32_t flags) noexcept WINRT_IMPL_LINK(LoadLibraryExW, 12); int32_t __stdcall WINRT_IMPL_FreeLibrary(void* library) noexcept WINRT_IMPL_LINK(FreeLibrary, 4); void* __stdcall WINRT_IMPL_GetProcAddress(void* library, char const* name) noexcept WINRT_IMPL_LINK(GetProcAddress, 8); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d9c720a8..ed151552 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -107,7 +107,6 @@ set(SKIP_LARGE_PCH FALSE CACHE BOOL "Skip building large precompiled headers.") add_subdirectory(test) add_subdirectory(test_cpp20) add_subdirectory(test_cpp20_no_sourcelocation) -add_subdirectory(test_win7) if(HAS_WINDOWSNUMERICS) add_subdirectory(old_tests) diff --git a/test/test_win7/CMakeLists.txt b/test/test_win7/CMakeLists.txt deleted file mode 100644 index d1c4120e..00000000 --- a/test/test_win7/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -file(GLOB TEST_SRCS - LIST_DIRECTORIES false - CONFIGURE_DEPENDS - *.cpp -) -list(FILTER TEST_SRCS EXCLUDE REGEX "/(main|pch)\\.cpp") - - -# We can't build test_component[*] for mingw-w64 because it doesn't have an -# alternative to midl that can produce winmd files. Also, even if we do manage -# to reuse the MSVC-compiled binaries, mingw-w64 is still missing -# windowsnumerics.impl.h which is needed to provide the types -# winrt::Windows::Foundation::Numerics::float2 and friends that the components -# use. -list(APPEND BROKEN_TESTS - agility - delegates - enum - in_params - no_make_detection - noexcept - out_params - parent_includes - return_params - structs - uniform_in_params - velocity -) - -list(APPEND BROKEN_TESTS - # depends on pplawait.h - when -) - -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # FIXME: GCC does not compile co_await on thread_pool because it wants - # a copy constructor. Disabling this test for now. - # This might be related to upstream bug: - # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103963 - list(APPEND BROKEN_TESTS - thread_pool - ) -endif() - -# Exclude broken tests -foreach(TEST_SRCS_EXCLUDE_ITEM IN LISTS BROKEN_TESTS) - list(FILTER TEST_SRCS EXCLUDE REGEX "/${TEST_SRCS_EXCLUDE_ITEM}\\.cpp") -endforeach() - -add_executable(test_win7 main.cpp ${TEST_SRCS}) - -target_precompile_headers(test_win7 PRIVATE pch.h) -set_source_files_properties( - main.cpp - coro_foundation.cpp - coro_threadpool.cpp - generic_type_names.cpp - inspectable_interop.cpp - module_lock_dll.cpp - PROPERTIES SKIP_PRECOMPILE_HEADERS true -) - -add_dependencies(test_win7 build-cppwinrt-projection) - -add_test( - NAME test_win7 - COMMAND "$" ${TEST_COLOR_ARG} -) diff --git a/test/test_win7/GetMany.cpp b/test/test_win7/GetMany.cpp deleted file mode 100644 index 29291204..00000000 --- a/test/test_win7/GetMany.cpp +++ /dev/null @@ -1,382 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation::Collections; - -// -// Now that all of the generics are generated (rather than hand-written), it's far less likely -// that something like GetMany is incorrect. And the "FillArray" pattern used by GetMany is -// tested elsewhere in the out_params and return_params tests. However since C++/WinRT provides -// an implementation of GetMany over and above the projection, these tests validate the this -// implementation is correct. Other tests exist for collections under 'old_tests' but new -// optimizations are coming for GetMany and I want to make sure that GetMany is completely -// covered. -// - -namespace -{ - template - IIterator single_threaded_generator(std::vector&& values = {}) - { - // This iterator may only be advanced once, ensuring the GetMany complexity optimization - // is actually enforced with this test. - - struct generator_container - { - explicit generator_container(IIterator const& first) : m_current(first) - { - if (!m_current.HasCurrent()) - { - m_current = nullptr; - } - } - - IIterator begin() const { return m_current; } - IIterator end() const { return nullptr; } - - private: - IIterator m_current; - }; - - struct generator : implements>, iterable_base - { - explicit generator(IIterator const& first) : m_container(first) - { - } - - auto& get_container() noexcept - { - return m_container; - } - - auto& get_container() const noexcept - { - return m_container; - } - - private: - generator_container m_container; - }; - - auto v = single_threaded_vector(std::move(values)); - return make(v.First()).First(); - } -} - -TEST_CASE("GetMany") -{ - // All - { - auto v = single_threaded_vector({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC, 0xCC }; - REQUIRE(3 == v.GetMany(0, buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - REQUIRE(buffer[2] == 3); - } - { - auto v = single_threaded_vector({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC, 0xCC }; - REQUIRE(3 == v.First().GetMany(buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - REQUIRE(buffer[2] == 3); - } - - // None - { - auto v = single_threaded_vector({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC, 0xCC }; - REQUIRE(0 == v.GetMany(3, buffer)); - REQUIRE(buffer[0] == 0xCC); - REQUIRE(buffer[1] == 0xCC); - REQUIRE(buffer[2] == 0xCC); - } - { - auto v = single_threaded_vector({ 1,2,3,4 }); - auto pos = v.First(); - std::array buffer{ 0xCC, 0xCC, 0xCC }; - REQUIRE(3 == pos.GetMany(buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - REQUIRE(buffer[2] == 3); - buffer = { 0xCC, 0xCC, 0xCC }; - REQUIRE(1 == pos.GetMany(buffer)); - REQUIRE(buffer[0] == 4); - REQUIRE(buffer[1] == 0xCC); - REQUIRE(buffer[2] == 0xCC); - buffer = { 0xCC, 0xCC, 0xCC }; - REQUIRE(0 == pos.GetMany(buffer)); - REQUIRE(buffer[0] == 0xCC); - REQUIRE(buffer[1] == 0xCC); - REQUIRE(buffer[2] == 0xCC); - } - - // Less - { - auto v = single_threaded_vector({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC }; - REQUIRE(2 == v.GetMany(0, buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - } - { - auto v = single_threaded_vector({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC }; - REQUIRE(2 == v.First().GetMany(buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - } - - // More - { - auto v = single_threaded_vector({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC, 0xCC, 0xCC }; - REQUIRE(3 == v.GetMany(0, buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - REQUIRE(buffer[2] == 3); - REQUIRE(buffer[3] == 0xCC); - } - { - auto v = single_threaded_vector({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC, 0xCC, 0xCC }; - REQUIRE(3 == v.First().GetMany(buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - REQUIRE(buffer[2] == 3); - REQUIRE(buffer[3] == 0xCC); - } - - // Offset - { - auto v = single_threaded_vector({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC, 0xCC, 0xCC }; - REQUIRE(2 == v.GetMany(1, buffer)); - REQUIRE(buffer[0] == 2); - REQUIRE(buffer[1] == 3); - REQUIRE(buffer[2] == 0xCC); - REQUIRE(buffer[3] == 0xCC); - } - - // The same tests but with a non-trivially destructible type... - - // All - { - auto v = single_threaded_vector({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old", L"old" }; - REQUIRE(3 == v.GetMany(0, buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - REQUIRE(buffer[2] == L"3"); - } - { - auto v = single_threaded_vector({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old", L"old" }; - REQUIRE(3 == v.First().GetMany(buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - REQUIRE(buffer[2] == L"3"); - } - - // None - { - auto v = single_threaded_vector({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old", L"old" }; - REQUIRE(0 == v.GetMany(3, buffer)); - REQUIRE(buffer[0] == L""); - REQUIRE(buffer[1] == L""); - REQUIRE(buffer[2] == L""); - } - { - auto v = single_threaded_vector({ L"1",L"2",L"3",L"4" }); - auto pos = v.First(); - std::array buffer{ L"old", L"old", L"old" }; - REQUIRE(3 == pos.GetMany(buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - REQUIRE(buffer[2] == L"3"); - buffer = { L"old", L"old", L"old" }; - REQUIRE(1 == pos.GetMany(buffer)); - REQUIRE(buffer[0] == L"4"); - REQUIRE(buffer[1] == L""); - REQUIRE(buffer[2] == L""); - buffer = { L"old", L"old", L"old" }; - REQUIRE(0 == pos.GetMany(buffer)); - REQUIRE(buffer[0] == L""); - REQUIRE(buffer[1] == L""); - REQUIRE(buffer[2] == L""); - } - - // Less - { - auto v = single_threaded_vector({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old" }; - REQUIRE(2 == v.GetMany(0, buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - } - { - auto v = single_threaded_vector({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old" }; - REQUIRE(2 == v.First().GetMany(buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - } - - // More - { - auto v = single_threaded_vector({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old", L"old", L"old" }; - REQUIRE(3 == v.GetMany(0, buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - REQUIRE(buffer[2] == L"3"); - REQUIRE(buffer[3] == L""); - } - { - auto v = single_threaded_vector({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old", L"old", L"old" }; - REQUIRE(3 == v.First().GetMany(buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - REQUIRE(buffer[2] == L"3"); - REQUIRE(buffer[3] == L""); - } - - // Offset - { - auto v = single_threaded_vector({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old", L"old", L"old" }; - REQUIRE(2 == v.GetMany(1, buffer)); - REQUIRE(buffer[0] == L"2"); - REQUIRE(buffer[1] == L"3"); - REQUIRE(buffer[2] == L""); - REQUIRE(buffer[3] == L""); - } - -// FIXME: Fail to compile with Clang due to recursive template instantiation using single_threaded_generator. -#if !defined(__clang__) - - // Similar tests but with a list to ensure optimal code gen for containers that don't offer random access. - - // All - { - IIterator v = single_threaded_generator({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC, 0xCC }; - REQUIRE(3 == v.GetMany(buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - REQUIRE(buffer[2] == 3); - } - - // None - { - IIterator v = single_threaded_generator({ 1,2,3,4,5 }); - std::array buffer{ 0xCC, 0xCC, 0xCC }; - REQUIRE(3 == v.GetMany(buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - REQUIRE(buffer[2] == 3); - buffer = { 0xCC, 0xCC, 0xCC }; - REQUIRE(2 == v.GetMany(buffer)); - REQUIRE(buffer[0] == 4); - REQUIRE(buffer[1] == 5); - REQUIRE(buffer[2] == 0xCC); - buffer = { 0xCC, 0xCC, 0xCC }; - REQUIRE(0 == v.GetMany(buffer)); - REQUIRE(buffer[0] == 0xCC); - REQUIRE(buffer[1] == 0xCC); - REQUIRE(buffer[2] == 0xCC); - } - - // Less - { - IIterator v = single_threaded_generator({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC }; - REQUIRE(2 == v.GetMany(buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - } - - // More - { - IIterator v = single_threaded_generator({ 1,2,3 }); - std::array buffer{ 0xCC, 0xCC, 0xCC, 0xCC }; - REQUIRE(3 == v.GetMany(buffer)); - REQUIRE(buffer[0] == 1); - REQUIRE(buffer[1] == 2); - REQUIRE(buffer[2] == 3); - REQUIRE(buffer[3] == 0xCC); - } - - // The same tests but with a non-trivially destructible type... - - // All - { - IIterator v = single_threaded_generator({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old", L"old" }; - REQUIRE(3 == v.GetMany(buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - REQUIRE(buffer[2] == L"3"); - } - - // None - { - IIterator v = single_threaded_generator({ L"1",L"2",L"3",L"4" }); - std::array buffer{ L"old", L"old", L"old" }; - REQUIRE(3 == v.GetMany(buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - REQUIRE(buffer[2] == L"3"); - buffer = { L"old", L"old", L"old" }; - REQUIRE(1 == v.GetMany(buffer)); - REQUIRE(buffer[0] == L"4"); - REQUIRE(buffer[1] == L""); - REQUIRE(buffer[2] == L""); - buffer = { L"old", L"old", L"old" }; - REQUIRE(0 == v.GetMany(buffer)); - REQUIRE(buffer[0] == L""); - REQUIRE(buffer[1] == L""); - REQUIRE(buffer[2] == L""); - } - - // Less - { - IIterator v = single_threaded_generator({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old" }; - REQUIRE(2 == v.GetMany(buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - } - - // More - { - IIterator v = single_threaded_generator({ L"1",L"2",L"3" }); - std::array buffer{ L"old", L"old", L"old", L"old" }; - REQUIRE(3 == v.GetMany(buffer)); - REQUIRE(buffer[0] == L"1"); - REQUIRE(buffer[1] == L"2"); - REQUIRE(buffer[2] == L"3"); - REQUIRE(buffer[3] == L""); - } -#endif - - // Pair - { - auto m = single_threaded_map(); - m.Insert(1, L"1"); - m.Insert(2, L"2"); - m.Insert(3, L"3"); - m.Insert(4, L"4"); - std::array, 3> buffer; - REQUIRE(3 == m.First().GetMany(buffer)); - REQUIRE(buffer[0].Key() == 1); - REQUIRE(buffer[1].Key() == 2); - REQUIRE(buffer[2].Key() == 3); - REQUIRE(buffer[0].Value() == L"1"); - REQUIRE(buffer[1].Value() == L"2"); - REQUIRE(buffer[2].Value() == L"3"); - } -} diff --git a/test/test_win7/abi_guard.cpp b/test/test_win7/abi_guard.cpp deleted file mode 100644 index c0244a47..00000000 --- a/test/test_win7/abi_guard.cpp +++ /dev/null @@ -1,293 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - // - // This implemenetation uses the simplest abi_enter and abi_exit methods - // - struct Simple : implements - { - void Close() - { - } - - hstring ToString() - { - return L""; - } - - void abi_enter() - { - ++m_enter; - } - - void abi_exit() - { - ++m_exit; - } - - int m_enter{}; - int m_exit{}; - }; - - // - // This implemenetation uses the abi_enter but omits the abi_exit method - // - struct OnlyEnter : implements - { - void Close() - { - } - - hstring ToString() - { - return L""; - } - - void abi_enter() - { - ++m_enter; - } - - int m_enter{}; - }; - - // - // This implemenetation throws from the abi_enter method - // - struct Throwing : implements - { - void Close() - { - } - - hstring ToString() - { - return L""; - } - - void abi_enter() - { - throw hresult_wrong_thread(); - } - - void abi_exit() - { - ++m_exit; - } - - int m_exit{}; - }; - - // - // This implemenetation provides a nested abi_guard - // - struct NestedGuard : implements - { - void Close() - { - } - - hstring ToString() - { - return L""; - } - - int m_enter{}; - int m_exit{}; - - struct abi_guard - { - abi_guard(NestedGuard& that) : - m_that(that) - { - ++m_that.m_enter; - } - - ~abi_guard() - { - ++m_that.m_exit; - } - - private: - - NestedGuard& m_that; - }; - }; - - template - struct CountGuard - { - CountGuard(T& that) : - m_that(that) - { - ++m_that.m_enter; - } - - ~CountGuard() - { - ++m_that.m_exit; - } - - private: - - T& m_that; - }; - - // - // This implemenetation use an abi_guard type alias - // - struct GuardAlias : implements - { - void Close() - { - } - - hstring ToString() - { - return L""; - } - - int m_enter{}; - int m_exit{}; - - using abi_guard = CountGuard; - }; - - template - struct ThrowGuard - { - ThrowGuard(T&) - { - throw hresult_wrong_thread(); - } - }; - - // - // This implemenetation use an abi_guard type alias that thows - // - struct ThrowAlias : implements - { - void Close() - { - } - - hstring ToString() - { - return L""; - } - - using abi_guard = ThrowGuard; - }; -} - -TEST_CASE("abi_guard") -{ - { - com_ptr impl = make_self(); - - impl->Close(); - impl->ToString(); - REQUIRE(impl->m_enter == 0); - REQUIRE(impl->m_exit == 0); - - IClosable closable = impl.as(); - closable.Close(); - REQUIRE(impl->m_enter == 1); - REQUIRE(impl->m_exit == 1); - - IStringable stringable = impl.as(); - stringable.ToString(); - REQUIRE(impl->m_enter == 2); - REQUIRE(impl->m_exit == 2); - } - { - com_ptr impl = make_self(); - - impl->Close(); - impl->ToString(); - - REQUIRE(impl->m_enter == 0); - - IClosable closable = impl.as(); - closable.Close(); - - REQUIRE(impl->m_enter == 1); - - IStringable stringable = impl.as(); - stringable.ToString(); - - REQUIRE(impl->m_enter == 2); - } - { - com_ptr impl = make_self(); - - impl->Close(); - impl->ToString(); - - IClosable closable = impl.as(); - REQUIRE_THROWS_AS(closable.Close(), hresult_wrong_thread); - - IStringable stringable = impl.as(); - REQUIRE_THROWS_AS(stringable.ToString(), hresult_wrong_thread); - - REQUIRE(impl->m_exit == 0); - } - { - com_ptr impl = make_self(); - - impl->Close(); - impl->ToString(); - - REQUIRE(impl->m_enter == 0); - REQUIRE(impl->m_exit == 0); - - IClosable closable = impl.as(); - closable.Close(); - - REQUIRE(impl->m_enter == 1); - REQUIRE(impl->m_exit == 1); - - IStringable stringable = impl.as(); - stringable.ToString(); - - REQUIRE(impl->m_enter == 2); - REQUIRE(impl->m_exit == 2); - } - { - com_ptr impl = make_self(); - - impl->Close(); - impl->ToString(); - - REQUIRE(impl->m_enter == 0); - REQUIRE(impl->m_exit == 0); - - IClosable closable = impl.as(); - closable.Close(); - - REQUIRE(impl->m_enter == 1); - REQUIRE(impl->m_exit == 1); - - IStringable stringable = impl.as(); - stringable.ToString(); - - REQUIRE(impl->m_enter == 2); - REQUIRE(impl->m_exit == 2); - } - { - com_ptr impl = make_self(); - - impl->Close(); - impl->ToString(); - - IClosable closable = impl.as(); - REQUIRE_THROWS_AS(closable.Close(), hresult_wrong_thread); - - IStringable stringable = impl.as(); - REQUIRE_THROWS_AS(stringable.ToString(), hresult_wrong_thread); - } -} diff --git a/test/test_win7/agile_ref.cpp b/test/test_win7/agile_ref.cpp deleted file mode 100644 index e0ab43a3..00000000 --- a/test/test_win7/agile_ref.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - struct Object : implements - { - hstring ToString() - { - return L"Object"; - } - }; -} - -TEST_CASE("agile_ref") -{ - agile_ref ref = make(); - - // - // Here we're creating an agile_ref explicitly and using a traditional lambda variable capture - // to pass it to the delegate. - // - - delegate<> a = [ref] - { - IStringable object = ref.get(); - REQUIRE(object.ToString() == L"Object"); - }; - - a(); - - // - // Here's we're using the make_agile helper with generalized lambda capture to produce a - // variable local to the lambda. - // - - delegate<> b = [ref = make_agile(make())] - { - IStringable object = ref.get(); - REQUIRE(object.ToString() == L"Object"); - }; - - b(); - - // - // And it's ok to resolve a nullptr agile_ref. - // - - agile_ref empty; - IStringable object = empty.get(); - REQUIRE(object == nullptr); -} diff --git a/test/test_win7/agility.cpp b/test/test_win7/agility.cpp deleted file mode 100644 index 78fed2fd..00000000 --- a/test/test_win7/agility.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.Delegates.h" - -// -// These tests confirm the COM identity and other behaviours for agile implementations. -// - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - struct TestAgile : implements - { - bool& m_destroyed; - TestAgile(bool& destroyed) : m_destroyed(destroyed) { m_destroyed = false; } - ~TestAgile() { m_destroyed = true; } - - void Close() {} - }; - - struct TestNonAgile : implements - { - void Close() {} - }; -} - -TEST_CASE("agility") -{ - using Windows::Foundation::IUnknown; - using Windows::Foundation::IInspectable; - - // Test agility - { - bool destroyed = false; - - { - IInspectable object = make(destroyed); - - // Confirm agility - object.as(); - - // Confirm legacy agility - com_ptr marshal = object.as(); - - // Confirm tear-off identity - IUnknown object_identity = object.as(); - IUnknown marshal_identity = marshal.as(); - - REQUIRE(object_identity == marshal_identity); - REQUIRE(!destroyed); - } - - // Confirm tear-off does not leak reference - REQUIRE(destroyed); - } - - // Test non-agility - { - IInspectable object = make(); - - // Does not implement IAgileObject - REQUIRE_THROWS_AS(object.as(), hresult_no_interface); - - // Does not implement IMarshal - REQUIRE_THROWS_AS(object.as(), hresult_no_interface); - } - - // Test IMarshal tearoff lifetime - { - bool destroyed = false; - - IInspectable object = make(destroyed); - com_ptr marshal = object.as(); - object = nullptr; - REQUIRE(!destroyed); - - // Confirm agility (back to object) - marshal.as(); - - // QI on tearoff itself - com_ptr marshal2 = marshal.as(); - REQUIRE(marshal == marshal2); - marshal2 = nullptr; - - // Confirm tear-off does not leak reference - REQUIRE(!destroyed); - marshal = nullptr; - REQUIRE(destroyed); - } - - // Test agile delegate - { - IUnknown object = test_component::Delegates::AgileDelegate([] {}); - com_ptr marshal = object.as(); - object = nullptr; - - // Confirm agility (back to object) - marshal.as(); - - // QI on tearoff itself - com_ptr marshal2 = marshal.as(); - REQUIRE(marshal == marshal2); - } - - // Test agile weak reference - { - bool destroyed = false; - IClosable object = make(destroyed); - com_ptr source = object.as(); - - // Clear object but source keeps object alive - object = nullptr; - source.as(); - - com_ptr ref; - check_hresult(source->GetWeakReference(ref.put())); - - // Drop the source object - REQUIRE(S_OK == ref->Resolve(guid_of(), put_abi(object))); - REQUIRE(object != nullptr); - source = nullptr; - REQUIRE(!destroyed); - object = nullptr; - REQUIRE(destroyed); - REQUIRE(S_OK == ref->Resolve(guid_of(), put_abi(object))); - REQUIRE(object == nullptr); - - // Marshaling support on weak ref - com_ptr marshal = ref.as(); - ref = nullptr; - - // Confirm agility (back to object): - marshal.as(); - - // QI on tearoff itself - com_ptr marshal2 = marshal.as(); - REQUIRE(marshal == marshal2); - } -} diff --git a/test/test_win7/async_auto_cancel.cpp b/test/test_win7/async_auto_cancel.cpp deleted file mode 100644 index cceafa44..00000000 --- a/test/test_win7/async_auto_cancel.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ -#ifdef __cpp_lib_coroutine - using std::suspend_never; -#else - using std::experimental::suspend_never; -#endif - - // - // Checks that the coroutine is automatically canceled when reaching a suspension point. - // - - IAsyncAction Action(HANDLE event) - { - co_await resume_on_signal(event); - co_await suspend_never(); - REQUIRE(false); - } - - IAsyncActionWithProgress ActionWithProgress(HANDLE event) - { - co_await resume_on_signal(event); - co_await suspend_never(); - REQUIRE(false); - } - - IAsyncOperation Operation(HANDLE event) - { - co_await resume_on_signal(event); - co_await suspend_never(); - REQUIRE(false); - co_return 1; - } - - IAsyncOperationWithProgress OperationWithProgress(HANDLE event) - { - co_await resume_on_signal(event); - co_await suspend_never(); - REQUIRE(false); - co_return 1; - } - - template - 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); - } -} - -#if defined(__clang__) && defined(_MSC_VER) -// FIXME: Test is known to segfault when built with Clang. -TEST_CASE("async_auto_cancel", "[.clang-crash]") -#else -TEST_CASE("async_auto_cancel") -#endif -{ - Check(Action); - Check(ActionWithProgress); - Check(Operation); - Check(OperationWithProgress); -} diff --git a/test/test_win7/async_cancel_callback.cpp b/test/test_win7/async_cancel_callback.cpp deleted file mode 100644 index 396636eb..00000000 --- a/test/test_win7/async_cancel_callback.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ -#ifdef __cpp_lib_coroutine - using std::suspend_never; -#else - using std::experimental::suspend_never; -#endif - - // - // 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 suspend_never(); - REQUIRE(false); - } - - IAsyncActionWithProgress 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 suspend_never(); - REQUIRE(false); - } - - IAsyncOperation 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 suspend_never(); - REQUIRE(false); - co_return 1; - } - - IAsyncOperationWithProgress 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 suspend_never(); - REQUIRE(false); - co_return 1; - } - - template - 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); - } -} - -#if defined(__clang__) && defined(_MSC_VER) -// FIXME: Test is known to segfault when built with Clang. -TEST_CASE("async_cancel_callback", "[.clang-crash]") -#else -TEST_CASE("async_cancel_callback") -#endif -{ - Check(Action); - Check(ActionWithProgress); - Check(Operation); - Check(OperationWithProgress); -} diff --git a/test/test_win7/async_check_cancel.cpp b/test/test_win7/async_check_cancel.cpp deleted file mode 100644 index 7547609f..00000000 --- a/test/test_win7/async_check_cancel.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ -#ifdef __cpp_lib_coroutine - using std::suspend_never; -#else - using std::experimental::suspend_never; -#endif - - // - // 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 suspend_never(); - REQUIRE(false); - } - - IAsyncActionWithProgress 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 suspend_never(); - REQUIRE(false); - } - - IAsyncOperation 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 suspend_never(); - REQUIRE(false); - co_return 1; - } - - IAsyncOperationWithProgress 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 suspend_never(); - REQUIRE(false); - co_return 1; - } - - template - 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); - } -} - -#if defined(__clang__) && defined(_MSC_VER) -// FIXME: Test is known to segfault when built with Clang. -TEST_CASE("async_check_cancel", "[.clang-crash]") -#else -TEST_CASE("async_check_cancel") -#endif -{ - Check(Action); - Check(ActionWithProgress); - Check(Operation); - Check(OperationWithProgress); -} diff --git a/test/test_win7/async_local.cpp b/test/test_win7/async_local.cpp deleted file mode 100644 index fa96dabb..00000000 --- a/test/test_win7/async_local.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "pch.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 ActionWithProgress(HANDLE event, bool& destroyed) - { - co_await resume_on_signal(event); - Local local{ destroyed }; - } - - IAsyncOperation Operation(HANDLE event, bool& destroyed) - { - co_await resume_on_signal(event); - Local local{ destroyed }; - co_return 1; - } - - IAsyncOperationWithProgress OperationWithProgress(HANDLE event, bool& destroyed) - { - co_await resume_on_signal(event); - Local local{ destroyed }; - co_return 1; - } - - template - 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("async_local") -{ - Check(Action); - Check(ActionWithProgress); - Check(Operation); - Check(OperationWithProgress); -} diff --git a/test/test_win7/async_no_suspend.cpp b/test/test_win7/async_no_suspend.cpp deleted file mode 100644 index 6888d0b9..00000000 --- a/test/test_win7/async_no_suspend.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - // - // Checks that coroutines lacking suspension points work. - // - - IAsyncAction Action() - { - co_return; - } - - IAsyncActionWithProgress ActionWithProgress() - { - co_return; - } - - IAsyncOperation Operation() - { - co_return 1; - } - - IAsyncOperationWithProgress OperationWithProgress() - { - co_return 1; - } - - IAsyncAction Await() - { - co_await Action(); - co_await ActionWithProgress(); - co_await Operation(); - co_await OperationWithProgress(); - } - - template - void Check(T const& async) - { - REQUIRE(async.Status() == AsyncStatus::Completed); - REQUIRE(async.ErrorCode() == 0); - REQUIRE(async.Id() == 1); - - // Should not throw in the Completed state. - async.GetResults(); - - bool completed = false; - - async.Completed([&](auto&& sender, AsyncStatus status) - { - completed = true; - REQUIRE(async == sender); - REQUIRE(status == AsyncStatus::Completed); - }); - - REQUIRE(completed); - - // May only assign Completed handler once. - REQUIRE_THROWS_AS(async.Completed([&](auto && ...) {}), hresult_illegal_delegate_assignment); - - // Close does nothing. - async.Close(); - - // Harmless but too late to cancel. - async.Cancel(); - REQUIRE(async.Status() == AsyncStatus::Completed); - } -} - -TEST_CASE("async_no_suspend") -{ - Action().get(); - ActionWithProgress().get(); - Operation().get(); - OperationWithProgress().get(); - Await().get(); - - Check(Action()); - Check(ActionWithProgress()); - Check(Operation()); - Check(OperationWithProgress()); -} diff --git a/test/test_win7/async_progress.cpp b/test/test_win7/async_progress.cpp deleted file mode 100644 index 0a2790f5..00000000 --- a/test/test_win7/async_progress.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - // - // Checks that progress reporting works. - // - - IAsyncActionWithProgress Action(HANDLE event) - { - co_await resume_on_signal(event); - auto progress = co_await get_progress_token(); - progress(123); - } - - IAsyncOperationWithProgress Operation(HANDLE event) - { - co_await resume_on_signal(event); - auto progress = co_await get_progress_token(); - progress(123); - co_return 1; - } - - template - IAsyncAction Check(F make) - { - // Event not set to allow Progress handler to be wired up. - handle start{ CreateEvent(nullptr, true, false, nullptr) }; - - auto async = make(start.get()); - bool progress = false; - - async.Progress([&](auto&& sender, int value) - { - progress = true; - REQUIRE(async == sender); - REQUIRE(value == 123); - }); - - SetEvent(start.get()); - co_await async; - - REQUIRE(progress); - REQUIRE(async.Status() == AsyncStatus::Completed); - REQUIRE(async.ErrorCode() == S_OK); - } - - template - IAsyncAction TooLate(F make) - { - // Event initially set so that coroutine does not suspend. - handle start{ CreateEvent(nullptr, true, true, nullptr) }; - - auto async = make(start.get()); - REQUIRE(async.Status() == AsyncStatus::Completed); - - bool progress = false; - - async.Progress([&](auto&&...) - { - REQUIRE(false); - }); - - co_await async; - - REQUIRE(!progress); - REQUIRE(async.Status() == AsyncStatus::Completed); - REQUIRE(async.ErrorCode() == S_OK); - } -} - -TEST_CASE("async_progress") -{ - Check(Action); - Check(Operation); - - TooLate(Action); - TooLate(Operation); -} diff --git a/test/test_win7/async_result.cpp b/test/test_win7/async_result.cpp deleted file mode 100644 index 9c1acccc..00000000 --- a/test/test_win7/async_result.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - // - // Checks that result values are propagated properly. - // - - IAsyncOperation Operation(HANDLE event) - { - co_await resume_on_signal(event); - co_return 123; - } - - IAsyncOperationWithProgress OperationWithProgress(HANDLE event) - { - co_await resume_on_signal(event); - co_return 123; - } - - IAsyncAction Await() - { - // Manual reset so that all waiters will resume and initially set so they won't block. - handle event{ CreateEvent(nullptr, true, true, nullptr) }; - - int a = co_await Operation(event.get()); - int b = co_await OperationWithProgress(event.get()); - - REQUIRE(a == 123); - REQUIRE(b == 123); - } - - template - 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); - if constexpr (has_async_progress) - { - // You're allowed to peek at partial results of IAsyncXxxWithProgress. - REQUIRE_NOTHROW(async.GetResults()); - } - else - { - REQUIRE_THROWS_AS(async.GetResults(), hresult_illegal_method_call); - } - - async.Completed([&](auto&& sender, AsyncStatus status) - { - REQUIRE(async == sender); - REQUIRE(status == AsyncStatus::Completed); - SetEvent(completed.get()); - }); - - // Still in Started state waiting for signal. - Sleep(100); - REQUIRE(WaitForSingleObject(completed.get(), 0) == WAIT_TIMEOUT); - REQUIRE(async.Status() == AsyncStatus::Started); - - // Signal async to run. - SetEvent(start.get()); - - // Wait for async to complete. - REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0); - - REQUIRE(async.Status() == AsyncStatus::Completed); - REQUIRE(async.ErrorCode() == S_OK); - REQUIRE(async.GetResults() == 123); - } -} - -TEST_CASE("async_result") -{ - handle start{ CreateEvent(nullptr, true, true, nullptr) }; - REQUIRE(123 == Operation(start.get()).get()); - REQUIRE(123 == OperationWithProgress(start.get()).get()); - Await().get(); - - Check(Operation); - Check(OperationWithProgress); -} diff --git a/test/test_win7/async_return.cpp b/test/test_win7/async_return.cpp deleted file mode 100644 index 23b1c1ee..00000000 --- a/test/test_win7/async_return.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - // - // Checks that return values support both rvalue and lvalue. - // - - IAsyncOperation Operation(bool rvalue) - { - if (rvalue) - { - hstring value = L"rvalue"; - co_return std::move(value); - } - else - { - hstring value = L"lvalue"; - co_return value; - } - } - - IAsyncOperationWithProgress OperationWithProgress(bool rvalue) - { - if (rvalue) - { - hstring value = L"rvalue"; - co_return std::move(value); - } - else - { - hstring value = L"lvalue"; - co_return value; - } - } - - template - void Check(F make) - { - REQUIRE(make(true).get() == L"rvalue"); - REQUIRE(make(false).get() == L"lvalue"); - } -} - -TEST_CASE("async_return") -{ - Check(Operation); - Check(OperationWithProgress); -} diff --git a/test/test_win7/async_suspend.cpp b/test/test_win7/async_suspend.cpp deleted file mode 100644 index f7beee21..00000000 --- a/test/test_win7/async_suspend.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - // - // Checks basic suspension behavior. - // - - IAsyncAction Action(HANDLE event) - { - co_await resume_on_signal(event); - } - - IAsyncActionWithProgress ActionWithProgress(HANDLE event) - { - co_await resume_on_signal(event); - } - - IAsyncOperation Operation(HANDLE event) - { - co_await resume_on_signal(event); - co_return 1; - } - - IAsyncOperationWithProgress OperationWithProgress(HANDLE event) - { - co_await resume_on_signal(event); - co_return 1; - } - - IAsyncAction Await() - { - // Manual reset so that all waiters will resume and initially set so they won't block. - handle event{ CreateEvent(nullptr, true, true, nullptr) }; - - co_await Action(event.get()); - co_await ActionWithProgress(event.get()); - co_await Operation(event.get()); - co_await OperationWithProgress(event.get()); - } - - template - 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); - if constexpr (has_async_progress) - { - // You're allowed to peek at partial results of IAsyncXxxWithProgress. - REQUIRE_NOTHROW(async.GetResults()); - } - else - { - REQUIRE_THROWS_AS(async.GetResults(), hresult_illegal_method_call); - } - - async.Completed([&](auto&& sender, AsyncStatus status) - { - REQUIRE(async == sender); - REQUIRE(status == AsyncStatus::Completed); - SetEvent(completed.get()); - }); - - // Still in Started state waiting for signal. - Sleep(100); - REQUIRE(WaitForSingleObject(completed.get(), 0) == WAIT_TIMEOUT); - REQUIRE(async.Status() == AsyncStatus::Started); - - // Signal async to run. - SetEvent(start.get()); - - // Wait for async to complete. - REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0); - - REQUIRE(async.Status() == AsyncStatus::Completed); - REQUIRE(async.ErrorCode() == S_OK); - } -} - -TEST_CASE("async_suspend") -{ - handle start{ CreateEvent(nullptr, true, true, nullptr) }; - Action(start.get()).get(); - ActionWithProgress(start.get()).get(); - Operation(start.get()).get(); - OperationWithProgress(start.get()).get(); - Await().get(); - - Check(Action); - Check(ActionWithProgress); - Check(Operation); - Check(OperationWithProgress); -} diff --git a/test/test_win7/async_throw.cpp b/test/test_win7/async_throw.cpp deleted file mode 100644 index 88e38d32..00000000 --- a/test/test_win7/async_throw.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; -using namespace std::chrono_literals; - -namespace -{ - // - // Checks that exceptions are correctly captured and propagated. - // - - IAsyncAction Action() - { - co_await 10ms; - throw hresult_invalid_argument(L"Async"); - } - - IAsyncActionWithProgress ActionWithProgress() - { - co_await 10ms; - throw hresult_invalid_argument(L"Async"); - } - - IAsyncOperation Operation() - { - co_await 10ms; - throw hresult_invalid_argument(L"Async"); - co_return 1; - } - - IAsyncOperationWithProgress OperationWithProgress() - { - co_await 10ms; - throw hresult_invalid_argument(L"Async"); - co_return 1; - } - - template - void Check(F make) - { - try - { - make().get(); - REQUIRE(false); - } - catch (hresult_invalid_argument const& e) - { - REQUIRE(e.message() == L"Async"); - } - - handle completed{ CreateEvent(nullptr, true, false, nullptr) }; - auto async = make(); - - async.Completed([&](auto&& sender, AsyncStatus status) - { - REQUIRE(async == sender); - REQUIRE(status == AsyncStatus::Error); - SetEvent(completed.get()); - }); - - REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0); - REQUIRE(async.Status() == AsyncStatus::Error); - - hresult_error e(async.ErrorCode(), take_ownership_from_abi); - REQUIRE(e.message() == L"Async"); - - try - { - async.GetResults(); - REQUIRE(false); - } - catch (hresult_invalid_argument const& e) - { - REQUIRE(e.message() == L"Async"); - } - } -} - -#if defined(__clang__) && defined(_MSC_VER) -// FIXME: Test is known to segfault when built with Clang. -TEST_CASE("async_throw", "[.clang-crash]") -#else -TEST_CASE("async_throw") -#endif -{ - Check(Action); - Check(ActionWithProgress); - Check(Operation); - Check(OperationWithProgress); -} diff --git a/test/test_win7/async_wait_for.cpp b/test/test_win7/async_wait_for.cpp deleted file mode 100644 index d7613083..00000000 --- a/test/test_win7/async_wait_for.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include "pch.h" - -using namespace std::literals; -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - IAsyncAction Action(TimeSpan delay, AsyncStatus result) - { - co_await resume_after(delay); - - if (result == AsyncStatus::Error) - { - throw hresult_invalid_argument(); - } - - if (result == AsyncStatus::Canceled) - { - throw hresult_canceled(); - } - } - - IAsyncActionWithProgress ActionWithProgress(TimeSpan delay, AsyncStatus result) - { - co_await resume_after(delay); - - if (result == AsyncStatus::Error) - { - throw hresult_invalid_argument(); - } - - if (result == AsyncStatus::Canceled) - { - throw hresult_canceled(); - } - } - - IAsyncOperation Operation(TimeSpan delay, AsyncStatus result) - { - co_await resume_after(delay); - - if (result == AsyncStatus::Error) - { - throw hresult_invalid_argument(); - } - - if (result == AsyncStatus::Canceled) - { - throw hresult_canceled(); - } - - co_return 1; - } - - IAsyncOperationWithProgress OperationWithProgress(TimeSpan delay, AsyncStatus result) - { - co_await resume_after(delay); - - if (result == AsyncStatus::Error) - { - throw hresult_invalid_argument(); - } - - if (result == AsyncStatus::Canceled) - { - throw hresult_canceled(); - } - - co_return 1; - } - - template - void check(T const& no_suspend_ok, T const& no_suspend_fail, T const& delay_ok, T const& delay_fail, T const& no_suspend_cancel, T const& delay_cancel, T const& long_delay) - { - REQUIRE(no_suspend_ok.wait_for(0s) == AsyncStatus::Completed); - no_suspend_ok.get(); - REQUIRE_THROWS_AS(no_suspend_ok.wait_for(0s), hresult_illegal_delegate_assignment); - - REQUIRE(no_suspend_fail.wait_for(0s) == AsyncStatus::Error); - REQUIRE_THROWS_AS(no_suspend_fail.get(), hresult_invalid_argument); - - REQUIRE(delay_ok.wait_for(1s) == AsyncStatus::Completed); - delay_ok.get(); - - REQUIRE(delay_fail.wait_for(1s) == AsyncStatus::Error); - REQUIRE_THROWS_AS(delay_fail.get(), hresult_invalid_argument); - - REQUIRE(no_suspend_cancel.wait_for(0s) == AsyncStatus::Canceled); - REQUIRE_THROWS_AS(no_suspend_cancel.get(), hresult_canceled); - - REQUIRE(delay_cancel.wait_for(1s) == AsyncStatus::Canceled); - REQUIRE_THROWS_AS(delay_cancel.get(), hresult_canceled); - - REQUIRE(long_delay.wait_for(100ms) == AsyncStatus::Started); - } -} - -#if defined(__clang__) && defined(_MSC_VER) -// FIXME: Test is known to segfault when built with Clang. -TEST_CASE("async_wait_for", "[.clang-crash]") -#else -TEST_CASE("async_wait_for") -#endif -{ - check( - Action(0s, AsyncStatus::Completed), - Action(0s, AsyncStatus::Error), - Action(100ms, AsyncStatus::Completed), - Action(100ms, AsyncStatus::Error), - Action(0s, AsyncStatus::Canceled), - Action(100ms, AsyncStatus::Canceled), - Action(1h, AsyncStatus::Completed)); - - check( - ActionWithProgress(0s, AsyncStatus::Completed), - ActionWithProgress(0s, AsyncStatus::Error), - ActionWithProgress(100ms, AsyncStatus::Completed), - ActionWithProgress(100ms, AsyncStatus::Error), - ActionWithProgress(0s, AsyncStatus::Canceled), - ActionWithProgress(100ms, AsyncStatus::Canceled), - ActionWithProgress(1h, AsyncStatus::Completed)); - - check( - Operation(0s, AsyncStatus::Completed), - Operation(0s, AsyncStatus::Error), - Operation(100ms, AsyncStatus::Completed), - Operation(100ms, AsyncStatus::Error), - Operation(0s, AsyncStatus::Canceled), - Operation(100ms, AsyncStatus::Canceled), - Operation(1h, AsyncStatus::Completed)); - - check( - OperationWithProgress(0s, AsyncStatus::Completed), - OperationWithProgress(0s, AsyncStatus::Error), - OperationWithProgress(100ms, AsyncStatus::Completed), - OperationWithProgress(100ms, AsyncStatus::Error), - OperationWithProgress(0s, AsyncStatus::Canceled), - OperationWithProgress(100ms, AsyncStatus::Canceled), - OperationWithProgress(1h, AsyncStatus::Completed)); -} diff --git a/test/test_win7/capture.cpp b/test/test_win7/capture.cpp deleted file mode 100644 index 9019d1e3..00000000 --- a/test/test_win7/capture.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -struct DECLSPEC_UUID("5fb96f8d-409c-42a9-99a7-8a95c1459dbd") ICapture : ::IUnknown -{ - virtual int32_t __stdcall GetValue() noexcept = 0; - virtual int32_t __stdcall CreateMemberCapture(int32_t value, GUID const& iid, void** object) noexcept = 0; -}; - -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(ICapture, 0x5fb96f8d, 0x409c, 0x42a9, 0x99, 0xa7, 0x8a, 0x95, 0xc1, 0x45, 0x9d, 0xbd) -#endif - -struct Capture : implements -{ - int32_t const m_value{}; - - Capture(int32_t value) : - m_value{ value } - { - } - - hstring ToString() - { - return hstring{ std::to_wstring(m_value) }; - } - - int32_t __stdcall GetValue() noexcept override - { - return m_value; - } - - int32_t __stdcall CreateMemberCapture(int32_t value, GUID const& iid, void** object) noexcept override - { - auto capture = make(value); - return capture->QueryInterface(iid, object); - } -}; - -HRESULT __stdcall CreateNonMemberCapture(int value, GUID const& iid, void** object) noexcept -{ - auto capture = make(value); - return capture->QueryInterface(iid, object); -} - -TEST_CASE("capture") -{ - com_ptr a = capture(CreateNonMemberCapture, 10); - REQUIRE(a->GetValue() == 10); - a = nullptr; - a.capture(CreateNonMemberCapture, 20); - REQUIRE(a->GetValue() == 20); - - com_ptr b = capture(a, &ICapture::CreateMemberCapture, 30); - REQUIRE(b->GetValue() == 30); - b = nullptr; - b.capture(a, &ICapture::CreateMemberCapture, 40); - REQUIRE(b->GetValue() == 40); - - IStringable c = capture(CreateNonMemberCapture, 50); - REQUIRE(c.ToString() == L"50"); - c = capture(a, &ICapture::CreateMemberCapture, 60); - REQUIRE(c.ToString() == L"60"); - - com_ptr d; - - REQUIRE_THROWS_AS(capture(CreateNonMemberCapture, 0), hresult_no_interface); - REQUIRE_THROWS_AS(capture(CreateNonMemberCapture, 0), hresult_no_interface); - REQUIRE_THROWS_AS(d.capture(CreateNonMemberCapture, 0), hresult_no_interface); - REQUIRE_THROWS_AS(capture(a, &ICapture::CreateMemberCapture, 0), hresult_no_interface); - REQUIRE_THROWS_AS(capture(a, &ICapture::CreateMemberCapture, 0), hresult_no_interface); - REQUIRE_THROWS_AS(d.capture(a, &ICapture::CreateMemberCapture, 0), hresult_no_interface); -} diff --git a/test/test_win7/cmd_reader.cpp b/test/test_win7/cmd_reader.cpp deleted file mode 100644 index 731922fd..00000000 --- a/test/test_win7/cmd_reader.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include "pch.h" -#include "cmd_reader.h" -#include - -using namespace cppwinrt; - -class response_file -{ - const char* resp_file_name = "respfile.txt"; - void write_response_file(const char* input) - { - std::ofstream resp_file(resp_file_name); - if (!resp_file.is_open()) - FAIL("Response file could not be created"); - resp_file << input; - resp_file.close(); - } - - void remove_response_file() - { - std::remove(resp_file_name); - } - -public: - response_file(const char* input) - { - write_response_file(input); - } - - template - reader create_reader(size_t const argc, const char* argv[], const option(&options)[numOptions]) - { - return reader{ argc, argv, options }; - } - - ~response_file() - { - remove_response_file(); - } -}; - -TEST_CASE("cmd_reader") -{ - static constexpr option options[] - { - { "input", 1 }, - { "reference", 0 }, - { "output", 0, 1 }, - { "component", 0, 1 }, - { "filter", 0 }, - { "name", 0, 1 }, - { "verbose", 0, 0 }, - }; - - // input and output - { - const char* argv[] = { "progname", "-in", "example_file.in", "-out", "example_file.out" }; - const size_t argc = 5; - reader args{ argc, argv, options }; - - REQUIRE(args.exists("input")); - REQUIRE(args.value("input") == "example_file.in"); - REQUIRE_FALSE(args.exists("reference")); - REQUIRE(args.exists("output")); - REQUIRE(args.value("output") == "example_file.out"); - REQUIRE_FALSE(args.exists("filter")); - REQUIRE_FALSE(args.exists("name")); - REQUIRE_FALSE(args.exists("verbose")); - } - - // response file #1: filename no quotes - { - const char* argv[] = { "progname", "@respfile.txt" }; - const size_t argc = _countof(argv); - - response_file rf{ R"(-in example_file.in -out example_file.out)" }; - reader args = rf.create_reader(argc, argv, options); - - REQUIRE(args.exists("input")); - REQUIRE(args.value("input") == "example_file.in"); - REQUIRE_FALSE(args.exists("reference")); - REQUIRE(args.exists("output")); - REQUIRE(args.value("output") == "example_file.out"); - REQUIRE_FALSE(args.exists("filter")); - REQUIRE_FALSE(args.exists("name")); - REQUIRE_FALSE(args.exists("verbose")); - } - - // response file #2: filename with quotes - { - const char* argv[] = { "progname", "@respfile.txt" }; - const size_t argc = _countof(argv); - - response_file rf{ R"(-in "example file.in" -out "example file.out")" }; - reader args = rf.create_reader(argc, argv, options); - - REQUIRE(args.exists("input")); - REQUIRE(args.value("input") == "example file.in"); - REQUIRE_FALSE(args.exists("reference")); - REQUIRE(args.exists("output")); - REQUIRE(args.value("output") == "example file.out"); - REQUIRE_FALSE(args.exists("filter")); - REQUIRE_FALSE(args.exists("name")); - REQUIRE_FALSE(args.exists("verbose")); - } - - // response file #3: filename with quote within name - { - const char* argv[] = { "progname", "@respfile.txt" }; - const size_t argc = _countof(argv); - - response_file rf{ R"(-in example\"file.in -out example\"file.out)" }; - reader args = rf.create_reader(argc, argv, options); - - REQUIRE(args.exists("input")); - REQUIRE(args.value("input") == R"(example"file.in)"); - REQUIRE_FALSE(args.exists("reference")); - REQUIRE(args.exists("output")); - REQUIRE(args.value("output") == R"(example"file.out)"); - REQUIRE_FALSE(args.exists("filter")); - REQUIRE_FALSE(args.exists("name")); - REQUIRE_FALSE(args.exists("verbose")); - } - - // response file #4: really really long path - { - const char* argv[] = { "progname", "@respfile.txt" }; - const size_t argc = _countof(argv); - std::string file_name_in(R"(C:\)"); - std::string file_name_out(R"(C:\)"); - std::string input_str("-in "); - - for (int i = 0; i < 500; i++) { - file_name_in.append(R"(dirname\)"); - file_name_out.append(R"(dirname\)"); - } - - file_name_in.append("example_file.in"); - file_name_out.append("example_file.out"); - input_str.append(file_name_in).append(" -out ").append(file_name_out); - - response_file rf{ input_str.data() }; - reader args = rf.create_reader(argc, argv, options); - - REQUIRE(args.exists("input")); - REQUIRE(args.value("input") == file_name_in); - REQUIRE_FALSE(args.exists("reference")); - REQUIRE(args.exists("output")); - REQUIRE(args.value("output") == file_name_out); - REQUIRE_FALSE(args.exists("filter")); - REQUIRE_FALSE(args.exists("name")); - REQUIRE_FALSE(args.exists("verbose")); - } -} diff --git a/test/test_win7/coro_foundation.cpp b/test/test_win7/coro_foundation.cpp deleted file mode 100644 index c2705982..00000000 --- a/test/test_win7/coro_foundation.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Intentionally not using pch... -#include "catch.hpp" - -// Only need winrt/Windows.Foundation.h for IAsyncXxx coroutine support -#include "winrt/Windows.Foundation.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - IAsyncOperation Async() - { - co_return L"hello"; - } -} - -TEST_CASE("coro_foundation") -{ - REQUIRE(Async().get() == L"hello"); -} diff --git a/test/test_win7/coro_threadpool.cpp b/test/test_win7/coro_threadpool.cpp deleted file mode 100644 index 4c31f8a0..00000000 --- a/test/test_win7/coro_threadpool.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Intentionally not using pch... -#include "catch.hpp" - -// Only need winrt/base.h for coroutine thread pool support. -#include "winrt/base.h" - -using namespace winrt; - -namespace -{ - fire_and_forget Async() - { - co_await resume_background(); - } -} - -TEST_CASE("coro_base") -{ - Async(); -} diff --git a/test/test_win7/custom_error.cpp b/test/test_win7/custom_error.cpp deleted file mode 100644 index b9850845..00000000 --- a/test/test_win7/custom_error.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - // Some custom exception type unknown to C++/WinRT - struct CustomError - { - }; - - struct Sample : implements - { - hstring ToString() - { - // Throw custom exception inside C++/WinRT projection - throw CustomError(); - } - }; - - // Global handler to translate custom exception - int32_t __stdcall handler(void* address) noexcept - { - REQUIRE(address); - - try - { - throw; - } - catch (CustomError) - { - return 0x80000018; // E_ILLEGAL_DELEGATE_ASSIGNMENT - } - - REQUIRE(false); - return 0; - } -} - -TEST_CASE("custom_error") -{ - // Set up global handler - REQUIRE(!winrt_to_hresult_handler); - winrt_to_hresult_handler = handler; - - // Validate that handler translated exception - REQUIRE_THROWS_AS(make().ToString(), hresult_illegal_delegate_assignment); - - // Remove global handler - winrt_to_hresult_handler = nullptr; -} diff --git a/test/test_win7/delegate.cpp b/test/test_win7/delegate.cpp deleted file mode 100644 index bade5506..00000000 --- a/test/test_win7/delegate.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "pch.h" - -using namespace winrt; - -TEST_CASE("delegate") -{ - // <> - { - bool invoked = false; - delegate<> d = [&] {invoked = true; }; - d(); - REQUIRE(invoked); - } - - // - { - int result = 0; - delegate d = [&](int a) {result = a; }; - d(123); - REQUIRE(result == 123); - } - - // - { - int result = 0; - delegate d = [&](int a, int b) {result = a + b; }; - d(4,5); - REQUIRE(result == 9); - } - - // void() - { - bool invoked = false; - delegate d = [&] {invoked = true; }; - d(); - REQUIRE(invoked); - } - - // void(int) - { - int result = 0; - delegate d = [&](int a) {result = a; }; - d(123); - REQUIRE(result == 123); - } - - // void(int,int) - { - int result = 0; - delegate d = [&](int a, int b) {result = a + b; }; - d(4, 5); - REQUIRE(result == 9); - } - - // int() - { - delegate d = [] { return 123; }; - REQUIRE(d() == 123); - } - - // int(int) - { - delegate d = [](int a) {return a; }; - REQUIRE(d(123) == 123); - } - - // int(int,int) - { - delegate d = [](int a, int b) {return a + b; }; - REQUIRE(d(4, 5) == 9); - } -} diff --git a/test/test_win7/delegates.cpp b/test/test_win7/delegates.cpp deleted file mode 100644 index af2eb6da..00000000 --- a/test/test_win7/delegates.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.Delegates.h" - -using namespace winrt; -using namespace test_component::Delegates; - -TEST_CASE("delegates") -{ - { - bool run{}; - AgileDelegate d = [&] {run = true; }; - REQUIRE(!run); - d(); - REQUIRE(run); - } - { - hstring value; - InDelegate d = [&](hstring const& in) - { - value = in; - }; - REQUIRE(value.empty()); - d(L"Test"); - REQUIRE(value == L"Test"); - } - { - ReturnStringDelegate d = [] {return L"Test"; }; - REQUIRE(d() == L"Test"); - } - { - ReturnInt32Delegate d = [] {return 123; }; - REQUIRE(d() == 123); - } - { - OutStringDelegate d = [](hstring& value) - { - value = L"Test"; - }; - hstring value; - d(value); - REQUIRE(value == L"Test"); - } - { - OutStringDelegate d = [](hstring&) - { - }; - hstring value = L"old"; - d(value); - REQUIRE(value == L""); - } - { - OutInt32Delegate d = [](int32_t & value) - { - value = 123; - }; - int32_t value{ 0xCC }; - d(value); - REQUIRE(value == 123); - } - { - OutInt32Delegate d = [](int32_t&) - { - }; - int32_t value{ 123 }; - d(value); - REQUIRE(value == 123); - } - { - ReturnStringArrayDelegate d = [] { return com_array{ L"One", L"Two", L"Three" }; }; - com_array value = d(); - REQUIRE(value.size() == 3); - REQUIRE(value[0] == L"One"); - REQUIRE(value[1] == L"Two"); - REQUIRE(value[2] == L"Three"); - } - { - OutStringArrayDelegate d = [](com_array& value) { value = { L"One", L"Two", L"Three" }; }; - - com_array value; - d(value); - - REQUIRE(value.size() == 3); - REQUIRE(value[0] == L"One"); - REQUIRE(value[1] == L"Two"); - REQUIRE(value[2] == L"Three"); - } - { - RefStringArrayDelegate d = [](array_view value) { value[0] = L"One"; value[1] = L"Two"; value[2] = L"Three"; }; - - std::array value{ L"r1", L"r2", L"r3", L"r4" }; - d(value); - - REQUIRE(value[0] == L"One"); - REQUIRE(value[1] == L"Two"); - REQUIRE(value[2] == L"Three"); - REQUIRE(value[3] == L""); - } -} diff --git a/test/test_win7/disconnected.cpp b/test/test_win7/disconnected.cpp deleted file mode 100644 index a69a210d..00000000 --- a/test/test_win7/disconnected.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include "pch.h" - -using namespace std::literals; -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - IAsyncAction Action() - { - co_return; - } - - IAsyncActionWithProgress ActionProgress() - { - co_await 500ms; - auto progress = co_await get_progress_token(); - progress(123); - co_return; - } - - IAsyncOperation Operation() - { - co_return 123; - } - - IAsyncOperationWithProgress OperationProgress() - { - co_await 500ms; - auto progress = co_await get_progress_token(); - progress(123); - co_return 123; - } -} - -TEST_CASE("disconnected,1") -{ - event> source; - - source.add([](auto...) - { - throw hresult_error(RPC_E_DISCONNECTED); - }); - - auto token = source.add([](auto...) - { - throw hresult_error(E_INVALIDARG); - }); - - // Should have two delegates - REQUIRE(source); - - // Should lose the disconnected delegate - source(nullptr, 123); - REQUIRE(source); - - // Fire the remaining delegate - source(nullptr, 123); - REQUIRE(source); - - // Remove the final delegate - source.remove(token); - - // No more delegates - REQUIRE(!source); - - source(nullptr, 123); -} - -TEST_CASE("disconnected,2") -{ - auto async = Action(); - - async.Completed([](auto&&...) - { - throw hresult_error(RPC_E_DISCONNECTED); - }); -} - -TEST_CASE("disconnected,3") -{ - auto async = ActionProgress(); - handle signal{ CreateEventW(nullptr, true, false, nullptr) }; - - async.Progress([](auto&&...) - { - throw hresult_error(RPC_E_DISCONNECTED); - }); - - async.Completed([&](auto&&...) - { - SetEvent(signal.get()); - throw hresult_error(RPC_E_DISCONNECTED); - }); - - WaitForSingleObject(signal.get(), INFINITE); - // Give some time for to_hresult() to complete. - Sleep(500); -} - -TEST_CASE("disconnected,4") -{ - auto async = Operation(); - - async.Completed([](auto&&...) - { - throw hresult_error(RPC_E_DISCONNECTED); - }); -} - -TEST_CASE("disconnected,5") -{ - auto async = OperationProgress(); - handle signal{ CreateEventW(nullptr, true, false, nullptr) }; - - async.Progress([](auto&&...) - { - throw hresult_error(RPC_E_DISCONNECTED); - }); - - async.Completed([&](auto&&...) - { - SetEvent(signal.get()); - throw hresult_error(RPC_E_DISCONNECTED); - }); - - WaitForSingleObject(signal.get(), INFINITE); - // Give some time for to_hresult() to complete. - Sleep(500); -} diff --git a/test/test_win7/enum.cpp b/test/test_win7/enum.cpp deleted file mode 100644 index 48f356a7..00000000 --- a/test/test_win7/enum.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.h" - -using namespace winrt; -using namespace test_component; - -TEST_CASE("enum") -{ - STATIC_REQUIRE(std::is_same_v, int32_t>); - STATIC_REQUIRE(std::is_same_v, uint32_t>); - - STATIC_REQUIRE(name_of() == L"test_component.Signed"sv); - STATIC_REQUIRE(name_of() == L"test_component.Unsigned"sv); - - REQUIRE(((Unsigned::First | Unsigned::Second | Unsigned::Third) & Unsigned::Second) == Unsigned::Second); - - REQUIRE(static_cast(Signed::First) == -1); - REQUIRE(static_cast(Signed::Second) == 0); - REQUIRE(static_cast(Signed::Third) == 1); - - REQUIRE(static_cast(Unsigned::First) == 0); - REQUIRE(static_cast(Unsigned::Second) == 1); - REQUIRE(static_cast(Unsigned::Third) == 2); -} diff --git a/test/test_win7/fast_iterator.cpp b/test/test_win7/fast_iterator.cpp deleted file mode 100644 index 5be28fb3..00000000 --- a/test/test_win7/fast_iterator.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "pch.h" - -TEST_CASE("fast_iterator") -{ - { - auto v = winrt::single_threaded_vector({ 1, 2, 3 }); - - std::vector result; - - std::copy(begin(v), end(v), std::back_inserter(result)); - - REQUIRE((result == std::vector{ 1, 2, 3 })); - } - { - auto v = winrt::single_threaded_vector({ 1, 2, 3 }); - - std::vector result; - - std::copy(rbegin(v), rend(v), std::back_inserter(result)); - - REQUIRE((result == std::vector{ 3, 2, 1 })); - } -} diff --git a/test/test_win7/final_release.cpp b/test/test_win7/final_release.cpp deleted file mode 100644 index c615499c..00000000 --- a/test/test_win7/final_release.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - struct Sample : implements - { - hstring ToString() - { - return L"Sample"; - } - - ~Sample() - { - // It's safe to QI/AddRef/Release inside destructor. - IStringable s; - check_hresult(QueryInterface(guid_of(), put_abi(s))); - REQUIRE(s.ToString() == L"Sample"); - - // Weak references are also supported during destruction. - REQUIRE(weak_ref{ s }.get()); - - REQUIRE(released); - REQUIRE(!destroyed); - destroyed = true; - } - - static void final_release(std::unique_ptr ptr) noexcept - { - // It's safe to QI/AddRef/Release inside final_release. - IStringable s; - check_hresult(ptr->QueryInterface(guid_of(), put_abi(s))); - REQUIRE(s.ToString() == L"Sample"); - - // References must be released prior to destroying the unique_ptr. - s = nullptr; - - REQUIRE(!released); - REQUIRE(!destroyed); - released = true; - ptr = nullptr; - REQUIRE(destroyed); - } - - static inline bool released; - static inline bool destroyed; - }; -} - -TEST_CASE("final_release") -{ - { - auto s = make(); - - // Weak references are supported prior to destruction. - REQUIRE(weak_ref{ s }.get()); - - REQUIRE(!Sample::released); - REQUIRE(!Sample::destroyed); - s = nullptr; - REQUIRE(Sample::released); - REQUIRE(Sample::destroyed); - } -} diff --git a/test/test_win7/generic_type_names.cpp b/test/test_win7/generic_type_names.cpp deleted file mode 100644 index a91266a8..00000000 --- a/test/test_win7/generic_type_names.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// Windows.Foundation is intentionally *not* included here to ensure that stable names/guids -// are generated with only the xxx.0.h header. This ensures that indirect declarations produce -// stable identity values. -#define WINRT_LEAN_AND_MEAN -#include "winrt/Windows.Storage.h" - -#include "catch.hpp" -#include "generic_types.h" - -TEST_CASE("generic_type_names") -{ - using A = IIterable; - using B = IKeyValuePair>; - - test_guids(); - - // - // Generated Windows.Foundation names - // - - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IStringable", - IStringable); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IAsyncActionWithProgress`1>", - IAsyncActionWithProgress); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IAsyncOperationWithProgress`2, Windows.Foundation.Collections.IKeyValuePair`2, Single>>>", - IAsyncOperationWithProgress); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IAsyncOperation`1>", - IAsyncOperation); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReferenceArray`1>", - IReferenceArray); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1>", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncActionProgressHandler`1>", - AsyncActionProgressHandler); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncActionWithProgressCompletedHandler`1>", - AsyncActionWithProgressCompletedHandler); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncOperationCompletedHandler`1>", - AsyncOperationCompletedHandler); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncOperationProgressHandler`2, Windows.Foundation.Collections.IKeyValuePair`2, Single>>>", - AsyncOperationProgressHandler); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncOperationWithProgressCompletedHandler`2, Windows.Foundation.Collections.IKeyValuePair`2, Single>>>", - AsyncOperationWithProgressCompletedHandler); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.EventHandler`1>", - EventHandler); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.TypedEventHandler`2, Windows.Foundation.Collections.IKeyValuePair`2, Single>>>", - TypedEventHandler); - - // - // Generated Windows.Foundation.Collections names - // - - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IIterable`1>", - IIterable); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IIterator`1>", - IIterator); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IKeyValuePair`2, Windows.Foundation.Collections.IKeyValuePair`2, Single>>>", - IKeyValuePair); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IMapChangedEventArgs`1>", - IMapChangedEventArgs); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IMapView`2, Windows.Foundation.Collections.IKeyValuePair`2, Single>>>", - IMapView); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IMap`2, Windows.Foundation.Collections.IKeyValuePair`2, Single>>>", - IMap); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IObservableMap`2, Windows.Foundation.Collections.IKeyValuePair`2, Single>>>", - IObservableMap); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IObservableVector`1>", - IObservableVector); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVectorView`1>", - IVectorView); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVector`1>", - IVector); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.MapChangedEventHandler`2, Windows.Foundation.Collections.IKeyValuePair`2, Single>>>", - MapChangedEventHandler); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.VectorChangedEventHandler`1>", - VectorChangedEventHandler); - - // - // Generated primitive names - // - - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); -#if __has_include() - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); -#endif - - // Enums, structs, IInspectable, classes, and delegates - - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1", - IReference); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVector`1", - IVector); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVector`1", - IVector); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVector`1", - IVector); -} diff --git a/test/test_win7/generic_types.cpp b/test/test_win7/generic_types.cpp deleted file mode 100644 index 081155cd..00000000 --- a/test/test_win7/generic_types.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "pch.h" -#include "generic_types.h" - -TEST_CASE("generic_types") -{ - test_guids(); - - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Uri", Uri); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.PropertyType", PropertyType); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.Point", Point); - REQUIRE_EQUAL_NAME(L"Windows.Foundation.IStringable", IStringable); -} diff --git a/test/test_win7/generic_types.h b/test/test_win7/generic_types.h deleted file mode 100644 index 5ddba76d..00000000 --- a/test/test_win7/generic_types.h +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -using namespace winrt; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -#if __has_include() -using namespace Windows::Foundation::Numerics; -#endif -using namespace std::literals; - -#define REQUIRE_EQUAL_GUID(left, ...) STATIC_REQUIRE(equal(guid(left), guid_of<__VA_ARGS__>())); -#define REQUIRE_EQUAL_NAME(left, ...) STATIC_REQUIRE(left == name_of<__VA_ARGS__>()); - -namespace -{ - constexpr bool equal(guid const& left, guid const& right) noexcept - { - return left.Data1 == right.Data1 && - left.Data2 == right.Data2 && - left.Data3 == right.Data3 && - left.Data4[0] == right.Data4[0] && - left.Data4[1] == right.Data4[1] && - left.Data4[2] == right.Data4[2] && - left.Data4[3] == right.Data4[3] && - left.Data4[4] == right.Data4[4] && - left.Data4[5] == right.Data4[5] && - left.Data4[6] == right.Data4[6] && - left.Data4[7] == right.Data4[7]; - } - - void test_guids() - { - using A = IIterable; - using B = IKeyValuePair>; - - REQUIRE_EQUAL_GUID("96369F54-8EB6-48F0-ABCE-C1B211E627C3"sv, IStringable); - - // - // Generated Windows.Foundation GUIDs - // - - REQUIRE_EQUAL_GUID("DD725452-2DA3-5103-9C7D-22EE9BB14AD3", IAsyncActionWithProgress); - REQUIRE_EQUAL_GUID("94645425-B9E5-5B91-B509-8DA4DF6A8916", IAsyncOperationWithProgress); - REQUIRE_EQUAL_GUID("2BD35EE6-72D9-5C5D-9827-05EBB81487AB", IAsyncOperation); - REQUIRE_EQUAL_GUID("4A33FE03-E8B9-5346-A124-5449913ECA57", IReferenceArray); - REQUIRE_EQUAL_GUID("F9E4006C-6E8C-56DF-811C-61F9990EBFB0", IReference); - REQUIRE_EQUAL_GUID("C261D8D0-71BA-5F38-A239-872342253A18", AsyncActionProgressHandler); - REQUIRE_EQUAL_GUID("9A0D211C-0374-5D23-9E15-EAA3570FAE63", AsyncActionWithProgressCompletedHandler); - REQUIRE_EQUAL_GUID("9D534225-231F-55E7-A6D0-6C938E2D9160", AsyncOperationCompletedHandler); - REQUIRE_EQUAL_GUID("264F1E0C-ABE4-590B-9D37-E1CC118ECC75", AsyncOperationProgressHandler); - REQUIRE_EQUAL_GUID("C2D078D8-AC47-55AB-83E8-123B2BE5BC5A", AsyncOperationWithProgressCompletedHandler); - REQUIRE_EQUAL_GUID("FA0B7D80-7EFA-52DF-9B69-0574CE57ADA4", EventHandler); - REQUIRE_EQUAL_GUID("EDB31843-B4CF-56EB-925A-D4D0CE97A08D", TypedEventHandler); - - // - // Generated Windows.Foundation.Collections GUIDs - // - - REQUIRE_EQUAL_GUID("96565EB9-A692-59C8-BCB5-647CDE4E6C4D", IIterable); - REQUIRE_EQUAL_GUID("3C9B1E27-8357-590B-8828-6E917F172390", IIterator); - REQUIRE_EQUAL_GUID("89336CD9-8B66-50A7-9759-EB88CCB2E1FE", IKeyValuePair); - REQUIRE_EQUAL_GUID("E1AA5138-12BD-51A1-8558-698DFD070ABE", IMapChangedEventArgs); - REQUIRE_EQUAL_GUID("B78F0653-FA89-59CF-BA95-726938AAE666", IMapView); - REQUIRE_EQUAL_GUID("9962CD50-09D5-5C46-B1E1-3C679C1C8FAE", IMap); - REQUIRE_EQUAL_GUID("75F99E2A-137E-537E-A5B1-0B5A6245FC02", IObservableMap); - REQUIRE_EQUAL_GUID("D24C289F-2341-5128-AAA1-292DD0DC1950", IObservableVector); - REQUIRE_EQUAL_GUID("5F07498B-8E14-556E-9D2E-2E98D5615DA9", IVectorView); - REQUIRE_EQUAL_GUID("0E3F106F-A266-50A1-8043-C90FCF3844F6", IVector); - REQUIRE_EQUAL_GUID("19046F0B-CF81-5DEC-BBB2-7CC250DA8B8B", MapChangedEventHandler); - REQUIRE_EQUAL_GUID("A1E9ACD7-E4DF-5A79-AEFA-DE07934AB0FB", VectorChangedEventHandler); - - // - // Generated primitive GUIDs - // - - REQUIRE_EQUAL_GUID("3C00FD60-2950-5939-A21A-2D12C5A01B8A", IReference); - REQUIRE_EQUAL_GUID("95500129-FBF6-5AFC-89DF-70642D741990", IReference); - REQUIRE_EQUAL_GUID("6EC9E41B-6709-5647-9918-A1270110FC4E", IReference); - REQUIRE_EQUAL_GUID("548CEFBD-BC8A-5FA0-8DF2-957440FC8BF4", IReference); - REQUIRE_EQUAL_GUID("4DDA9E24-E69F-5C6A-A0A6-93427365AF2A", IReference); - REQUIRE_EQUAL_GUID("e5198cc8-2873-55f5-b0a1-84ff9e4aad62", IReference); - REQUIRE_EQUAL_GUID("5AB7D2C3-6B62-5E71-A4B6-2D49C4F238FD", IReference); - REQUIRE_EQUAL_GUID("513ef3af-e784-5325-a91e-97c2b8111cf3", IReference); - REQUIRE_EQUAL_GUID("6755e376-53bb-568b-a11d-17239868309e", IReference); - REQUIRE_EQUAL_GUID("719CC2BA-3E76-5DEF-9F1A-38D85A145EA8", IReference); - REQUIRE_EQUAL_GUID("2F2D6C29-5473-5F3E-92E7-96572BB990E2", IReference); - REQUIRE_EQUAL_GUID("FB393EF3-BBAC-5BD5-9144-84F23576F415", IReference); - REQUIRE_EQUAL_GUID("7D50F649-632C-51F9-849A-EE49428933EA", IReference); - REQUIRE_EQUAL_GUID("6FF27A1E-4B6A-59B7-B2C3-D1F2EE474593", IReference); - REQUIRE_EQUAL_GUID("FD416DFB-2A07-52EB-AAE3-DFCE14116C05", IReference); - REQUIRE_EQUAL_GUID("A9B18291-CE2A-5DAE-8A23-B7F7388416DB", IReference); - REQUIRE_EQUAL_GUID("604D0C4C-91DE-5C2A-935F-362F13EAF800", IReference); - REQUIRE_EQUAL_GUID("5541D8A7-497C-5AA4-86FC-7713ADBF2A2C", IReference); - REQUIRE_EQUAL_GUID("84F14C22-A00A-5272-8D3D-82112E66DF00", IReference); - REQUIRE_EQUAL_GUID("80423F11-054F-5EAC-AFD3-63B6CE15E77B", IReference); - REQUIRE_EQUAL_GUID("61723086-8e53-5276-9f36-2a4bb93e2b75", IReference); -#if __has_include() - REQUIRE_EQUAL_GUID("48F6A69E-8465-57AE-9400-9764087F65AD", IReference); - REQUIRE_EQUAL_GUID("1EE770FF-C954-59CA-A754-6199A9BE282C", IReference); - REQUIRE_EQUAL_GUID("A5E843C9-ED20-5339-8F8D-9FE404CF3654", IReference); - REQUIRE_EQUAL_GUID("76358CFD-2CBD-525B-A49E-90EE18247B71", IReference); - REQUIRE_EQUAL_GUID("DACBFFDC-68EF-5FD0-B657-782D0AC9807E", IReference); - REQUIRE_EQUAL_GUID("B27004BB-C014-5DCE-9A21-799C5A3C1461", IReference); - REQUIRE_EQUAL_GUID("46D542A1-52F7-58E7-ACFC-9A6D364DA022", IReference); -#endif - - // Enums, structs, IInspectable, classes, and delegates - - REQUIRE_EQUAL_GUID("ECEBDE54-FAC0-5AEB-9BA9-9E1FE17E31D5", IReference); - REQUIRE_EQUAL_GUID("84F14C22-A00A-5272-8D3D-82112E66DF00", IReference); - REQUIRE_EQUAL_GUID("B32BDCA4-5E52-5B27-BC5D-D66A1A268C2A", IVector); - REQUIRE_EQUAL_GUID("0D82BD8D-FE62-5D67-A7B9-7886DD75BC4E", IVector); - REQUIRE_EQUAL_GUID("5DAFE591-86DC-59AA-BFDA-07F5D59FC708", IVector); - } -} diff --git a/test/test_win7/guid_key.cpp b/test/test_win7/guid_key.cpp deleted file mode 100644 index aaf560e1..00000000 --- a/test/test_win7/guid_key.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -TEST_CASE("guid_key") -{ - auto uri = guid_of(); - auto deferral = guid_of(); - - std::map ordered; - ordered[uri] = "Uri"; - ordered[deferral] = "Deferral"; - REQUIRE(ordered[uri] == "Uri"); - REQUIRE(ordered[deferral] == "Deferral"); - - std::unordered_map unordered; - unordered[uri] = "Uri"; - unordered[deferral] = "Deferral"; - REQUIRE(unordered[uri] == "Uri"); - REQUIRE(unordered[deferral] == "Deferral"); -} diff --git a/test/test_win7/iid_ppv_args.cpp b/test/test_win7/iid_ppv_args.cpp deleted file mode 100644 index 012e1856..00000000 --- a/test/test_win7/iid_ppv_args.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "pch.h" -#include - -namespace -{ - struct Stringable : winrt::implements - { - winrt::hstring ToString() - { - return L"hello"; - } - }; - - HRESULT GetStringable(GUID const& id, void** object) noexcept - { - *object = nullptr; - - if (id != __uuidof(ABI::Windows::Foundation::IStringable)) - { - return E_NOINTERFACE; - } - - *object = winrt::detach_abi(winrt::make()); - return S_OK; - } -} - -TEST_CASE("iid_ppv_args") -{ - { - winrt::com_ptr ptr; - REQUIRE(S_OK == GetStringable(IID_PPV_ARGS(&ptr))); - REQUIRE(ptr.as().ToString() == L"hello"); - } - { - winrt::com_ptr ptr; - REQUIRE(E_NOINTERFACE == GetStringable(IID_PPV_ARGS(&ptr))); - } -} diff --git a/test/test_win7/in_params.cpp b/test/test_win7/in_params.cpp deleted file mode 100644 index dec89693..00000000 --- a/test/test_win7/in_params.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.h" - -using namespace winrt; -using namespace Windows::Foundation; -using namespace test_component; - -namespace -{ - struct Value : implements - { - Value(int32_t value) : - m_value(value) - { - } - - hstring ToString() - { - return hstring{ std::to_wstring(m_value) }; - } - - private: - - int32_t m_value{}; - }; -} - -TEST_CASE("in_params") -{ - Class object; - - REQUIRE(object.InInt32(123) == L"123"); - REQUIRE(object.InString(L"123") == L"123"); - REQUIRE(object.InObject(make(123)) == L"123"); - REQUIRE(object.InStringable(make(123)) == L"123"); - REQUIRE(object.InStruct({ L"1", L"2" }) == L"12"); - REQUIRE(object.InStructRef({ L"1", L"2" }) == L"12ref"); - REQUIRE(object.InEnum(Signed::First) == L"First"); - - REQUIRE(object.InInt32Array({ 1,2 }) == L"12"); - REQUIRE(object.InStringArray({ L"1", L"2" }) == L"12"); - REQUIRE(object.InObjectArray({ make(1), make(2) }) == L"12"); - REQUIRE(object.InStringableArray({ make(1), make(2) }) == L"12"); - REQUIRE(object.InStructArray({ {L"1",L"2"}, {L"3",L"4"} }) == L"1234"); - REQUIRE(object.InEnumArray({ Signed::First, Signed::Second }) == L"FirstSecond"); - - // Ensure 0-length arrays are passed as non-null pointers to the ABI, - // in order to keep RPC happy. - REQUIRE(object.InInt32Array({ }) == L""); - REQUIRE(object.InStringArray({ }) == L""); - REQUIRE(object.InObjectArray({ }) == L""); - REQUIRE(object.InStringableArray({ }) == L""); - REQUIRE(object.InStructArray({ }) == L""); - REQUIRE(object.InEnumArray({ }) == L""); - - // params::hstring optimizations - REQUIRE(object.InString(L"") == L""); - REQUIRE(object.InString({}) == L""); - wchar_t non_const_string[1] = { L'\0' }; - REQUIRE(object.InString(non_const_string) == L""); -} diff --git a/test/test_win7/inspectable_interop.cpp b/test/test_win7/inspectable_interop.cpp deleted file mode 100644 index 0be7a915..00000000 --- a/test/test_win7/inspectable_interop.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include "winrt/Windows.Foundation.h" -#include "catch.hpp" - -using namespace winrt; - -namespace -{ - struct DECLSPEC_UUID("ed0dd761-c31e-4803-8cf9-22a2cb20ec47") IBadInterop : ::IInspectable - { - virtual int32_t __stdcall JustSayNo() noexcept = 0; - }; -} - -#ifdef __CRT_UUID_DECL -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -#endif -__CRT_UUID_DECL(IBadInterop, 0xed0dd761, 0xc31e, 0x4803, 0x8c, 0xf9, 0x22, 0xa2, 0xcb, 0x20, 0xec, 0x47) -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif -#endif - -namespace -{ - struct Sample : implements - { - Windows::Foundation::IInspectable ActivateInstance() - { - throw hresult_not_implemented(); - } - - hstring GetRuntimeClassName() const - { - return L"Sample"; - } - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Woverloaded-virtual" -#endif - Windows::Foundation::TrustLevel GetTrustLevel() const noexcept - { - return Windows::Foundation::TrustLevel::PartialTrust; - } -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - - int32_t __stdcall JustSayNo() noexcept final - { - return 123; - } - }; -} - -TEST_CASE("inspectable_interop") -{ - Windows::Foundation::IActivationFactory a = make(); - REQUIRE(a != nullptr); - - Windows::Foundation::IActivationFactory b = a.as(); - REQUIRE(b != nullptr); - - com_ptr c = a.as(); - REQUIRE(c != nullptr); - REQUIRE(c->JustSayNo() == 123); - - Windows::Foundation::IActivationFactory d = c.as(); - REQUIRE(a == d); - - Windows::Foundation::IInspectable f = c.as(); - REQUIRE(f != nullptr); - - Windows::Foundation::IInspectable e(c.detach(), take_ownership_from_abi); - - REQUIRE(winrt::get_class_name(e) == L"Sample"); - REQUIRE(winrt::get_trust_level(e) == Windows::Foundation::TrustLevel::PartialTrust); - - auto interfaces = winrt::get_interfaces(e); - REQUIRE(interfaces.size() == 1); - REQUIRE(interfaces[0] == guid_of()); -} diff --git a/test/test_win7/interop.cpp b/test/test_win7/interop.cpp deleted file mode 100644 index ec5476d1..00000000 --- a/test/test_win7/interop.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "pch.h" -#include - -struct DECLSPEC_UUID("5040a5f4-796a-42ff-9f06-be89137a518f") IBase : IUnknown -{ -}; - -struct DECLSPEC_UUID("529fed32-514f-4150-b1ba-15b47df700b7") IDerived : IBase -{ -}; - -struct DECLSPEC_UUID("b81fb2a2-eab4-488a-96a7-434873c2c20b") IMoreDerived : IDerived -{ -}; - -#ifdef __CRT_UUID_DECL -__CRT_UUID_DECL(IBase, 0x5040a5f4, 0x796a, 0x42ff, 0x9f, 0x06, 0xbe, 0x89, 0x13, 0x7a, 0x51, 0x8f) -__CRT_UUID_DECL(IDerived, 0x529fed32, 0x514f, 0x4150, 0xb1, 0xba, 0x15, 0xb4, 0x7d, 0xf7, 0x00, 0xb7) -__CRT_UUID_DECL(IMoreDerived, 0xb81fb2a2, 0xeab4, 0x488a, 0x96, 0xa7, 0x43, 0x48, 0x73, 0xc2, 0xc2, 0x0b) -#endif - -namespace winrt -{ - template<> bool is_guid_of(guid const& id) noexcept - { - return is_guid_of(id); - } - - template<> bool is_guid_of(guid const& id) noexcept - { - return is_guid_of(id); - } -} - -using namespace winrt; - -struct MyBase : implements -{ -}; - -struct MyDerived : implements -{ -}; - -struct MyMoreDerived : implements -{ -}; - -Windows::Foundation::IAsyncAction Async() -{ - co_return; -} - -TEST_CASE("interop") -{ - { - Windows::Foundation::IAsyncAction a = Async(); - com_ptr<::IInspectable> b = a.as<::IInspectable>(); - Windows::Foundation::IAsyncAction c = b.as(); - REQUIRE(a == c); - } - { - com_ptr a = make(); - REQUIRE(a); - REQUIRE(a.try_as() != nullptr); - REQUIRE(a.try_as() == nullptr); - REQUIRE(a.try_as() == nullptr); - REQUIRE(a.try_as<::IInspectable>() == nullptr); - } - { - com_ptr a = make(); - REQUIRE(a); - REQUIRE(a.try_as() != nullptr); - REQUIRE(a.try_as() != nullptr); - REQUIRE(a.try_as() == nullptr); - REQUIRE(a.try_as<::IInspectable>() == nullptr); - } - { - com_ptr a = make(); - REQUIRE(a); - REQUIRE(a.try_as() != nullptr); - REQUIRE(a.try_as() != nullptr); - REQUIRE(a.try_as() != nullptr); - REQUIRE(a.try_as<::IInspectable>() != nullptr); - } -} diff --git a/test/test_win7/invalid_events.cpp b/test/test_win7/invalid_events.cpp deleted file mode 100644 index a8f6a69b..00000000 --- a/test/test_win7/invalid_events.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -// -// Checks that invalid tokens may be removed harmlessly. -// - -TEST_CASE("invalid_events") -{ - event> event; - int counter{}; - - auto a = event.add([&](auto && ...) - { - counter += 1; - }); - - auto b = event.add([&](auto && ...) - { - counter += 10; - }); - - REQUIRE(counter == 0); - event(0, 0); - REQUIRE(counter == 11); - - // Remove invalid token (with two valids) - event.remove(event_token {1}); - - counter = 0; - event(0, 0); - REQUIRE(counter == 11); - - // Remove valid token - event.remove(b); - - counter = 0; - event(0, 0); - REQUIRE(counter == 1); - - // Remove invalid token (with one valid) - event.remove(event_token {1}); - - counter = 0; - event(0, 0); - REQUIRE(counter == 1); - - // Remove remaining valid token - event.remove(a); - - counter = 0; - event(0, 0); - REQUIRE(counter == 0); - - // Remove invalid token (with no valids) - event.remove(event_token {1}); - - counter = 0; - event(0, 0); - REQUIRE(counter == 0); -} diff --git a/test/test_win7/main.cpp b/test/test_win7/main.cpp deleted file mode 100644 index 30687e00..00000000 --- a/test/test_win7/main.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -#define CATCH_CONFIG_RUNNER - -// Force reportFatal to be available on mingw-w64 -#define CATCH_CONFIG_WINDOWS_SEH - -#include "catch.hpp" -#include "winrt/base.h" - -using namespace winrt; - -int main(int const argc, char** argv) -{ - init_apartment(); - std::set_terminate([] { reportFatal("Abnormal termination"); ExitProcess(1); }); - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); - (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); - (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); - return Catch::Session().run(argc, argv); -} - -CATCH_TRANSLATE_EXCEPTION(hresult_error const& e) -{ - return to_string(e.message()); -} diff --git a/test/test_win7/module_lock_dll.cpp b/test/test_win7/module_lock_dll.cpp deleted file mode 100644 index 60514212..00000000 --- a/test/test_win7/module_lock_dll.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "catch.hpp" - -// The default behavior (no macro) provides the static winrt::get_module_lock implementation for components/DLLs. - -#include "winrt/Windows.Foundation.h" - -namespace -{ - struct Stringable : winrt::implements - { - winrt::hstring ToString() - { - return L"Stringable"; - } - }; -} - -TEST_CASE("module_lock_dll") -{ - uint32_t const count = winrt::get_module_lock(); - - ++winrt::get_module_lock(); - - REQUIRE(winrt::get_module_lock() == count + 1); - - --winrt::get_module_lock(); - - REQUIRE(winrt::get_module_lock() == count); - - { - auto stringable = winrt::make(); - REQUIRE(winrt::get_module_lock() == count + 1); - } - - REQUIRE(winrt::get_module_lock() == count); - - { - winrt::Windows::Foundation::EventHandler delegate = [](auto&&...) {}; - REQUIRE(winrt::get_module_lock() == count + 1); - } - - REQUIRE(winrt::get_module_lock() == count); - - { - winrt::delegate delegate = [] {}; - REQUIRE(winrt::get_module_lock() == count + 1); - } - - REQUIRE(winrt::get_module_lock() == count); -} diff --git a/test/test_win7/names.cpp b/test/test_win7/names.cpp deleted file mode 100644 index 7730fe82..00000000 --- a/test/test_win7/names.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -void check_terminated(winrt::param::hstring const&) -{ -} - -TEST_CASE("names") -{ - REQUIRE(name_of() == L"{00000000-0000-0000-c000-000000000046}"sv); - STATIC_REQUIRE(name_of() == L"Object"sv); - - check_terminated(name_of()); - check_terminated(name_of()); - check_terminated(name_of>()); - check_terminated(name_of>()); -} diff --git a/test/test_win7/no_make_detection.cpp b/test/test_win7/no_make_detection.cpp deleted file mode 100644 index f098f322..00000000 --- a/test/test_win7/no_make_detection.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.h" - -using namespace winrt; -using namespace test_component; - -TEST_CASE("no_make_detection") -{ - REQUIRE(test_component::Class::TestNoMakeDetection()); -} diff --git a/test/test_win7/noexcept.cpp b/test/test_win7/noexcept.cpp deleted file mode 100644 index 1df30689..00000000 --- a/test/test_win7/noexcept.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.h" - -using namespace winrt; -using namespace test_component; - -TEST_CASE("noexcept") -{ - Class c; - - c.NoexceptVoid(); - int32_t a = c.NoexceptInt32(); - hstring b = c.NoexceptString(); - - REQUIRE(a == 123); - REQUIRE(b == L"123"); -} diff --git a/test/test_win7/numerics.cpp b/test/test_win7/numerics.cpp deleted file mode 100644 index 23b2dfb3..00000000 --- a/test/test_win7/numerics.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation::Numerics; - -TEST_CASE("numerics") -{ -#if __has_include() - // Basic smoke test exercising SIMD intrinsics used by numerics. - - auto one = float4::one(); - - REQUIRE(one * one == one); -#endif -} diff --git a/test/test_win7/out_params.cpp b/test/test_win7/out_params.cpp deleted file mode 100644 index 7aafb63a..00000000 --- a/test/test_win7/out_params.cpp +++ /dev/null @@ -1,278 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.h" - -using namespace winrt; -using namespace Windows::Foundation; -using namespace test_component; - -namespace -{ - struct Stringable : implements - { - hstring ToString() - { - return L"Stringable"; - } - }; -} - -TEST_CASE("out_params") -{ - Class object; - - { - int value; - object.OutInt32(value); - REQUIRE(value == 123); - } - { - hstring value = L"replace"; - object.OutString(value); - REQUIRE(value == L"123"); - } - { - IInspectable value = make(); - object.OutObject(value); - REQUIRE(value.as().ToString() == L"123"); - } - { - IStringable value = make(); - object.OutStringable(value); - REQUIRE(value.ToString() == L"123"); - } - { - Struct value{ L"First", L"Second" }; - object.OutStruct(value); - REQUIRE(value.First == L"1"); - REQUIRE(value.Second == L"2"); - } - { - Signed value; - object.OutEnum(value); - REQUIRE(value == Signed::First); - } - - { - com_array value(10); - object.OutInt32Array(value); - REQUIRE(value.size() == 3); - REQUIRE(value[0] == 1); - REQUIRE(value[1] == 2); - REQUIRE(value[2] == 3); - } - { - com_array value(10); - object.OutStringArray(value); - REQUIRE(value.size() == 3); - REQUIRE(value[0] == L"1"); - REQUIRE(value[1] == L"2"); - REQUIRE(value[2] == L"3"); - } - { - com_array value(10); - object.OutObjectArray(value); - REQUIRE(value.size() == 3); - REQUIRE(value[0].as().ToString() == L"1"); - REQUIRE(value[1].as().ToString() == L"2"); - REQUIRE(value[2].as().ToString() == L"3"); - } - { - com_array value(10); - object.OutStringableArray(value); - REQUIRE(value.size() == 3); - REQUIRE(value[0].ToString() == L"1"); - REQUIRE(value[1].ToString() == L"2"); - REQUIRE(value[2].ToString() == L"3"); - } - { - com_array value(10); - object.OutStructArray(value); - REQUIRE(value.size() == 2); - REQUIRE(value[0].First == L"1"); - REQUIRE(value[0].Second == L"2"); - REQUIRE(value[1].First == L"10"); - REQUIRE(value[1].Second == L"20"); - } - { - com_array value(10); - object.OutEnumArray(value); - REQUIRE(value.size() == 2); - REQUIRE(value[0] == Signed::First); - REQUIRE(value[1] == Signed::Second); - } - - { - std::array value{ 0xCC, 0xCC, 0xCC, 0xCC }; - object.RefInt32Array(value); - REQUIRE(value[0] == 1); - REQUIRE(value[1] == 2); - REQUIRE(value[2] == 3); - REQUIRE(value[3] == 0xCC); - } - { - std::array value{ L"r1", L"r2", L"r3", L"r4" }; - object.RefStringArray(value); - REQUIRE(value[0] == L"1"); - REQUIRE(value[1] == L"2"); - REQUIRE(value[2] == L"3"); - REQUIRE(value[3] == L""); - } - { - std::array value{ make(), make(), make(), make() }; - object.RefObjectArray(value); - REQUIRE(value[0].as().ToString() == L"1"); - REQUIRE(value[1].as().ToString() == L"2"); - REQUIRE(value[2].as().ToString() == L"3"); - REQUIRE(value[3] == nullptr); - } - { - std::array value{ make(), make(), make(), make() }; - object.RefStringableArray(value); - REQUIRE(value[0].ToString() == L"1"); - REQUIRE(value[1].ToString() == L"2"); - REQUIRE(value[2].ToString() == L"3"); - REQUIRE(value[3] == nullptr); - } - { - std::array value{ {L"First", L"Second"} }; - object.RefStructArray(value); - REQUIRE(value[0].First == L"1"); - REQUIRE(value[0].Second == L"2"); - REQUIRE(value[1].First == L"3"); - REQUIRE(value[1].Second == L"4"); - REQUIRE(value[2].First == L""); - REQUIRE(value[2].Second == L""); - } - { - std::array value{}; - object.RefEnumArray(value); - REQUIRE(value.size() == 3); - REQUIRE(value[0] == Signed::First); - REQUIRE(value[1] == Signed::Second); - REQUIRE(value[2] == static_cast(0)); - } - // Ensure 0-length arrays are passed as non-null pointers to the ABI, - // in order to keep RPC happy. - { - REQUIRE_NOTHROW(object.RefInt32Array({})); - REQUIRE_NOTHROW(object.RefStringArray({})); - REQUIRE_NOTHROW(object.RefObjectArray({})); - REQUIRE_NOTHROW(object.RefStringableArray({})); - REQUIRE_NOTHROW(object.RefStructArray({})); - REQUIRE_NOTHROW(object.RefEnumArray({})); - } - - object.Fail(true); - - { - int value = 0xCC; - REQUIRE_THROWS_AS(object.OutInt32(value), hresult_invalid_argument); - REQUIRE(value == 0xCC); - } - { - hstring value = L"replace"; - REQUIRE_THROWS_AS(object.OutString(value), hresult_invalid_argument); - REQUIRE(value == L""); - } - { - IInspectable value = make(); - REQUIRE_THROWS_AS(object.OutObject(value), hresult_invalid_argument); - REQUIRE(value == nullptr); - } - { - IStringable value = make(); - REQUIRE_THROWS_AS(object.OutStringable(value), hresult_invalid_argument); - REQUIRE(value == nullptr); - } - { - Struct value{ L"First", L"Second" }; - REQUIRE_THROWS_AS(object.OutStruct(value), hresult_invalid_argument); - REQUIRE(value.First == L""); - REQUIRE(value.Second == L""); - } - { - Signed value = static_cast(0xCC); - REQUIRE_THROWS_AS(object.OutEnum(value), hresult_invalid_argument); - REQUIRE(static_cast(value) == 0xCC); - } - - { - com_array value(10); - REQUIRE_THROWS_AS(object.OutInt32Array(value), hresult_invalid_argument); - REQUIRE(value.size() == 0); - } - { - com_array value(10); - REQUIRE_THROWS_AS(object.OutStringArray(value), hresult_invalid_argument); - REQUIRE(value.size() == 0); - } - { - com_array value(10); - REQUIRE_THROWS_AS(object.OutObjectArray(value), hresult_invalid_argument); - REQUIRE(value.size() == 0); - } - { - com_array value(10); - REQUIRE_THROWS_AS(object.OutStringableArray(value), hresult_invalid_argument); - REQUIRE(value.size() == 0); - } - { - com_array value(10); - REQUIRE_THROWS_AS(object.OutStructArray(value), hresult_invalid_argument); - REQUIRE(value.size() == 0); - } - { - com_array value(10); - REQUIRE_THROWS_AS(object.OutEnumArray(value), hresult_invalid_argument); - REQUIRE(value.size() == 0); - } - - { - std::array value{ 0xCC, 0xCC, 0xCC, 0xCC }; - REQUIRE_THROWS_AS(object.RefInt32Array(value), hresult_invalid_argument); - REQUIRE(value[0] == 0xCC); - REQUIRE(value[1] == 0xCC); - REQUIRE(value[2] == 0xCC); - REQUIRE(value[3] == 0xCC); - } - { - std::array value{ L"r1", L"r2", L"r3", L"r4" }; - REQUIRE_THROWS_AS(object.RefStringArray(value), hresult_invalid_argument); - REQUIRE(value[0] == L""); - REQUIRE(value[1] == L""); - REQUIRE(value[2] == L""); - REQUIRE(value[3] == L""); - } - { - std::array value{ make(), make(), make(), make() }; - REQUIRE_THROWS_AS(object.RefObjectArray(value), hresult_invalid_argument); - REQUIRE(value[0] == nullptr); - REQUIRE(value[1] == nullptr); - REQUIRE(value[2] == nullptr); - REQUIRE(value[3] == nullptr); - } - { - std::array value{ make(), make(), make(), make() }; - REQUIRE_THROWS_AS(object.RefStringableArray(value), hresult_invalid_argument); - REQUIRE(value[0] == nullptr); - REQUIRE(value[1] == nullptr); - REQUIRE(value[2] == nullptr); - REQUIRE(value[3] == nullptr); - } - { - std::array value{ {L"First", L"Second"} }; - REQUIRE_THROWS_AS(object.RefStructArray(value), hresult_invalid_argument); - REQUIRE(value[0].First == L""); - REQUIRE(value[0].Second == L""); - REQUIRE(value[1].First == L""); - REQUIRE(value[1].Second == L""); - REQUIRE(value[2].First == L""); - REQUIRE(value[2].Second == L""); - } - { - std::array value{ static_cast(0xCC), static_cast(0xCC) }; - REQUIRE_THROWS_AS(object.RefEnumArray(value), hresult_invalid_argument); - REQUIRE(value[0] == static_cast(0xCC)); - REQUIRE(value[1] == static_cast(0xCC)); - } -} diff --git a/test/test_win7/parent_includes.cpp b/test/test_win7/parent_includes.cpp deleted file mode 100644 index f7dc0d0c..00000000 --- a/test/test_win7/parent_includes.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.Parent.One.Two.Three.h" - -using namespace winrt::test_component; - -TEST_CASE("parent_includes") -{ - // Including "...Three.h" should include all (available) ancestors, skipping - // any that are empty. In this case, "Three" and "Parent" are not empty while - // the intermediate namespaces are empty. - - Parent::One::Two::Three::ThreeStruct three; - three.Value = 0; - - Parent::ParentStruct parent; - parent.Value = 0; -} diff --git a/test/test_win7/pch.cpp b/test/test_win7/pch.cpp deleted file mode 100644 index 1d9f38c5..00000000 --- a/test/test_win7/pch.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pch.h" diff --git a/test/test_win7/pch.h b/test/test_win7/pch.h deleted file mode 100644 index 92e8caa9..00000000 --- a/test/test_win7/pch.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "mingw_com_support.h" - -#define WINRT_LEAN_AND_MEAN -#include -#include "winrt/Windows.Foundation.Collections.h" -#include "winrt/Windows.Foundation.Numerics.h" -#include "catch.hpp" - -using namespace std::literals; - -// Extracts return and progress types from IAsyncXxx. - -template -struct async_traits; - -template<> -struct async_traits -{ - using progress_type = void; -}; - -template -struct async_traits> -{ - using progress_type = P; -}; - -template -struct async_traits> -{ - using progress_type = void; -}; - -template -struct async_traits> -{ - using progress_type = P; -}; - -template -using async_return_type = decltype(std::declval().GetResults()); -template -using async_progress_type = typename async_traits>::progress_type; -template -inline constexpr bool has_async_progress = !std::is_same_v>::progress_type>; diff --git a/test/test_win7/return_params.cpp b/test/test_win7/return_params.cpp deleted file mode 100644 index 3ff5026d..00000000 --- a/test/test_win7/return_params.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.h" - -using namespace winrt; -using namespace Windows::Foundation; -using namespace test_component; - -namespace -{ - struct Stringable : implements - { - hstring ToString() - { - return L"Stringable"; - } - }; -} - -TEST_CASE("return_params") -{ - Class object; - - { - int value = object.ReturnInt32(); - REQUIRE(value == 123); - } - { - hstring value = object.ReturnString(); - REQUIRE(value == L"123"); - } - { - IInspectable value = object.ReturnObject(); - REQUIRE(value.as().ToString() == L"123"); - } - { - IStringable value = object.ReturnStringable(); - REQUIRE(value.ToString() == L"123"); - } - { - Struct value = object.ReturnStruct(); - REQUIRE(value.First == L"1"); - REQUIRE(value.Second == L"2"); - } - { - com_array value = object.ReturnInt32Array(); - REQUIRE(value.size() == 3); - REQUIRE(value[0] == 1); - REQUIRE(value[1] == 2); - REQUIRE(value[2] == 3); - } - { - com_array value = object.ReturnStringArray(); - REQUIRE(value.size() == 3); - REQUIRE(value[0] == L"1"); - REQUIRE(value[1] == L"2"); - REQUIRE(value[2] == L"3"); - } - { - com_array value = object.ReturnObjectArray(); - REQUIRE(value.size() == 3); - REQUIRE(value[0].as().ToString() == L"1"); - REQUIRE(value[1].as().ToString() == L"2"); - REQUIRE(value[2].as().ToString() == L"3"); - } - { - com_array value = object.ReturnStringableArray(); - REQUIRE(value.size() == 3); - REQUIRE(value[0].ToString() == L"1"); - REQUIRE(value[1].ToString() == L"2"); - REQUIRE(value[2].ToString() == L"3"); - } - { - com_array value = object.ReturnStructArray(); - REQUIRE(value.size() == 2); - REQUIRE(value[0].First == L"1"); - REQUIRE(value[0].Second == L"2"); - REQUIRE(value[1].First == L"10"); - REQUIRE(value[1].Second == L"20"); - } -} diff --git a/test/test_win7/structs.cpp b/test/test_win7/structs.cpp deleted file mode 100644 index 3926c06e..00000000 --- a/test/test_win7/structs.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.Structs.Nested.h" -#include "winrt/test_component_no_pch.Peer2.h" - -using namespace winrt; - -TEST_CASE("structs") -{ - test_component::Structs::Nested::Outer outer{}; - outer.Depends.InnerValue = 1; - outer.OuterValue = 2; - - test_component_no_pch::Peer2::B depends{}; - depends.First.Value = 1; - - test_component::Structs::All all{}; - all.H = {}; -} diff --git a/test/test_win7/test_win7.vcxproj b/test/test_win7/test_win7.vcxproj deleted file mode 100644 index 831c0c1d..00000000 --- a/test/test_win7/test_win7.vcxproj +++ /dev/null @@ -1,363 +0,0 @@ - - - - - Debug - ARM - - - Debug - ARM64 - - - Debug - Win32 - - - Release - ARM - - - Release - ARM64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {2EF696B9-7F4A-410F-AE5C-5301565C0F08} - unittests - test_win7 - - - - Application - true - - - Application - true - - - Application - true - - - Application - false - true - - - Application - false - true - - - Application - false - true - - - Application - true - - - Application - false - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MaxSpeed - true - true - $(OutputPath);Generated Files;..;..\..\cppwinrt - NOMINMAX;_MBCS;%(PreprocessorDefinitions) - MultiThreaded - - - Console - true - true - - - $(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi - - - - - - - - - Disabled - $(OutputPath);Generated Files;..;..\..\cppwinrt - NOMINMAX;_MBCS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Console - - - $(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi - - - - - - - - - Disabled - $(OutputPath);Generated Files;..;..\..\cppwinrt - NOMINMAX;_MBCS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Console - - - $(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi - - - - - - - - - Disabled - $(OutputPath);Generated Files;..;..\..\cppwinrt - NOMINMAX;_MBCS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Console - - - $(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi - - - - - - - - - Disabled - $(OutputPath);Generated Files;..;..\..\cppwinrt - NOMINMAX;_MBCS;%(PreprocessorDefinitions) - MultiThreadedDebug - - - Console - - - $(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi - - - - - - - - - MaxSpeed - true - true - $(OutputPath);Generated Files;..;..\..\cppwinrt - NOMINMAX;_MBCS;%(PreprocessorDefinitions) - MultiThreaded - - - Console - true - true - - - $(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi - - - - - - - - - MaxSpeed - true - true - $(OutputPath);Generated Files;..;..\..\cppwinrt - NOMINMAX;_MBCS;%(PreprocessorDefinitions) - MultiThreaded - - - Console - true - true - - - $(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi - - - - - - - - - MaxSpeed - true - true - $(OutputPath);Generated Files;..;..\..\cppwinrt - NOMINMAX;_MBCS;%(PreprocessorDefinitions) - MultiThreaded - - - Console - true - true - - - $(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NotUsing - - - NotUsing - - - - - - - - - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - - - - NotUsing - - - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing - - - - - - - - - Create - - - - - - - - - - - - \ No newline at end of file diff --git a/test/test_win7/thread_pool.cpp b/test/test_win7/thread_pool.cpp deleted file mode 100644 index ac75dac1..00000000 --- a/test/test_win7/thread_pool.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "pch.h" - -using namespace winrt; -using namespace Windows::Foundation; - -namespace -{ - struct AsyncQueue - { - thread_pool m_pool; - - AsyncQueue(uint32_t const high, uint32_t const low) - { - m_pool.thread_limits(high, low); - } - - IAsyncAction Async(delegate<> callback) - { - co_await m_pool; - callback(); - } - }; - - uint32_t test(uint32_t const iterations, uint32_t const high, uint32_t const low) - { - AsyncQueue queue(high, low); - std::vector results; - uint32_t counter{}; - - for (uint32_t i = 0; i < iterations; ++i) - { - results.push_back(queue.Async([&] - { - auto value = counter + 1; - Sleep(10); // Induce thread pool to use more threads if available, also force race condition - counter = value; - })); - } - - for (auto&& async : results) - { - async.get(); - } - - return counter; - } -} - -TEST_CASE("thread_pool") -{ - uint32_t const test_iterations = 100; - - uint32_t const stable_counter = test(test_iterations, 1, 1); - uint32_t const unstable_counter = test(test_iterations, 10, 10); - - // This is determinstic since the queue is single-threaded. - REQUIRE(stable_counter == test_iterations); - - // This is unlikely to fail since the pool is multi-threaded. - REQUIRE(unstable_counter < test_iterations); -} diff --git a/test/test_win7/uniform_in_params.cpp b/test/test_win7/uniform_in_params.cpp deleted file mode 100644 index 50eb3fde..00000000 --- a/test/test_win7/uniform_in_params.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.h" - -using namespace winrt; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -using namespace test_component; - -TEST_CASE("uniform_in_params") -{ - Class{ single_threaded_vector({ L"test" }).as>(), 0 }; - Class{ single_threaded_map(std::map{ {L"test", L"test" } }).as>>(), 0, 0 }; - Class{ single_threaded_map(std::map{ {L"test", L"test" } }), 0, 0, 0 }; - Class{ single_threaded_map(std::map{ {L"test", L"test" } }).GetView(), 0, 0, 0, 0 }; - Class{ single_threaded_vector({ L"test" }), 0, 0, 0, 0, 0 }; - Class{ single_threaded_vector({ L"test" }).GetView(), 0, 0, 0, 0, 0, 0 }; - - Class c; - REQUIRE(L"test" == c.InIterable({L"test"})); - REQUIRE(L"test" == c.InIterablePair(single_threaded_map(std::map{ {L"test", L"test" } }))); - REQUIRE(L"test" == c.InAsyncIterable({ L"test" }).get()); - REQUIRE(L"test" == c.InAsyncIterablePair(single_threaded_map(std::map{ {L"test", L"test" } })).get()); - REQUIRE(L"test" == c.InMap(single_threaded_map(std::map{ {L"test", L"test" } }))); - REQUIRE(L"test" == c.InMapView(single_threaded_map(std::map{ {L"test", L"test" } }).GetView())); - REQUIRE(L"test" == c.InAsyncMapView(single_threaded_map(std::map{ {L"test", L"test" } }).GetView()).get()); - REQUIRE(L"test" == c.InVector({ L"test" })); - REQUIRE(L"test" == c.InVectorView({ L"test" })); - REQUIRE(L"test" == c.InAsyncVectorView({ L"test" }).get()); -} diff --git a/test/test_win7/velocity.cpp b/test/test_win7/velocity.cpp deleted file mode 100644 index 11b11c1d..00000000 --- a/test/test_win7/velocity.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "pch.h" -#include "winrt/test_component.Velocity.h" - -using namespace winrt; -using namespace test_component::Velocity; - -TEST_CASE("velocity") -{ - // This interface is always disabled but shows up in the type system - // if it is present in the winmd. - IInterface1 a; - REQUIRE(a == nullptr); - - // This interface is always enabled and is naturally available in - // the projection. - IInterface2 b; - REQUIRE(b == nullptr); - - // Class1 is always disabled and thus will not activate. - REQUIRE_THROWS_AS(Class1(), hresult_class_not_registered); - - // Class2 is always enabled so should activate just fine. - Class2 c; - c.Class2_Method(); - - // Class3 is always disabled and thus will not activate. - REQUIRE_THROWS_AS(Class3(), hresult_class_not_registered); - - // Class4 is not feature-controlled but uses feature interfaces. - Class4 d; - d.Class4_Method(); - - // The single argument constructor is always disabled. - REQUIRE_THROWS_AS(Class4(1), hresult_class_not_registered); - - // The Class4_Static1 static is always disabled. - REQUIRE_THROWS_AS(Class4::Class4_Static1(), hresult_class_not_registered); - - // The two argument constructor is always enabled. - Class4 e(1, 2); - - // The Class4_Static2 static is always enabled. - Class4::Class4_Static2(); -} diff --git a/test/test_win7/when.cpp b/test/test_win7/when.cpp deleted file mode 100644 index a3b28416..00000000 --- a/test/test_win7/when.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "pch.h" -#include - -using namespace concurrency; -using namespace winrt; -using namespace Windows::Foundation; - -task ppl(bool& done) -{ - co_await resume_background(); - done = true; -} - -IAsyncAction async(bool& done) -{ - co_await resume_background(); - done = true; -} - -IAsyncOperation when_signaled(int value, handle const& event) -{ - co_await resume_on_signal(event.get()); - co_return value; -} - -IAsyncAction done() -{ - co_return; -} - -TEST_CASE("when") -{ - { - bool ppl_done = false; - bool async_done = false; - - // Ensures that different async types can be aggregated. - when_all(ppl(ppl_done), async(async_done)).get(); - - REQUIRE(ppl_done); - REQUIRE(async_done); - } - { - // Works with IAsyncAction (with no return value). - IAsyncAction result = when_any(done(), done()); - result.get(); - } - { - handle first_event{ check_pointer(CreateEventW(nullptr, true, false, nullptr)) }; - handle second_event{ check_pointer(CreateEventW(nullptr, true, false, nullptr)) }; - - IAsyncOperation first = when_signaled(1, first_event); - IAsyncOperation second = when_signaled(2, second_event); - - IAsyncOperation result = when_any(first, second); - - // Make sure we're still waiting. - Sleep(100); - REQUIRE(result.Status() == AsyncStatus::Started); - REQUIRE(first.Status() == AsyncStatus::Started); - REQUIRE(second.Status() == AsyncStatus::Started); - - // Allow only one of the async objects to complete. - SetEvent(second_event.get()); - - // This should now complete. - REQUIRE(2 == result.get()); - - REQUIRE(first.Status() == AsyncStatus::Started); - REQUIRE(second.Status() == AsyncStatus::Completed); - - SetEvent(first_event.get()); - } -}