[Test] Add tests for widgets code
This creates a vbam-wx-widgets target for the custom widgets code and adds tests for them.
This commit is contained in:
parent
5766b9b9c7
commit
4f1a5dd726
|
@ -1,4 +1,4 @@
|
||||||
name: macOS Latest Build
|
name: macOS Latest
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -60,4 +60,4 @@ jobs:
|
||||||
- if: matrix.build_options == 'default'
|
- if: matrix.build_options == 'default'
|
||||||
name: Run tests
|
name: Run tests
|
||||||
run: >-
|
run: >-
|
||||||
nix-shell --command 'cd build && ctest -j'
|
nix-shell --command 'cd build && ctest -j --output-on-failure'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
name: MSYS2 Build
|
name: MSYS2
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
name: Ubuntu Latest Build
|
name: Ubuntu Latest
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -45,6 +45,9 @@ jobs:
|
||||||
run: >-
|
run: >-
|
||||||
bash installdeps; if [ "${{ matrix.build_compiler }}" = clang ]; then sudo apt -y install clang; fi
|
bash installdeps; if [ "${{ matrix.build_compiler }}" = clang ]; then sudo apt -y install clang; fi
|
||||||
|
|
||||||
|
- name: Install xvfb
|
||||||
|
run: sudo apt -y install xvfb
|
||||||
|
|
||||||
# CMake build
|
# CMake build
|
||||||
- if: matrix.build_options != 'libretro'
|
- if: matrix.build_options != 'libretro'
|
||||||
name: Configure CMake
|
name: Configure CMake
|
||||||
|
@ -65,4 +68,4 @@ jobs:
|
||||||
# Run tests
|
# Run tests
|
||||||
- if: matrix.build_options == 'default'
|
- if: matrix.build_options == 'default'
|
||||||
name: Run tests
|
name: Run tests
|
||||||
run: cd build && ctest -j
|
run: cd build && xvfb-run ctest -j --output-on-failure
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
name: Visual Studio Build
|
name: Visual Studio
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -57,4 +57,4 @@ jobs:
|
||||||
# Run tests
|
# Run tests
|
||||||
- if: matrix.build_options == 'default' && matrix.msvc_arch != 'amd64_arm64'
|
- if: matrix.build_options == 'default' && matrix.msvc_arch != 'amd64_arm64'
|
||||||
name: Run tests
|
name: Run tests
|
||||||
run: cd build && ctest -j
|
run: cd build && ctest -j --output-on-failure
|
||||||
|
|
|
@ -51,6 +51,28 @@ if(NOT DEFINED VCPKG_TARGET_TRIPLET)
|
||||||
message(STATUS "Inferred VCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}")
|
message(STATUS "Inferred VCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
function(vcpkg_seconds)
|
||||||
|
if(CMAKE_HOST_SYSTEM MATCHES Windows OR ((NOT DEFINED CMAKE_HOST_SYSTEM) AND WIN32))
|
||||||
|
execute_process(
|
||||||
|
COMMAND cmd /c echo %TIME:~0,8%
|
||||||
|
OUTPUT_VARIABLE time
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
execute_process(
|
||||||
|
COMMAND date +%H:%M:%S
|
||||||
|
OUTPUT_VARIABLE time
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(SUBSTRING "${time}" 0 2 hours)
|
||||||
|
string(SUBSTRING "${time}" 3 2 minutes)
|
||||||
|
string(SUBSTRING "${time}" 6 2 secs)
|
||||||
|
|
||||||
|
math(EXPR seconds "(${hours} * 60 * 60) + (${minutes} * 60) + ${secs}")
|
||||||
|
|
||||||
|
set(seconds ${seconds} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
function(vcpkg_check_git_status git_status)
|
function(vcpkg_check_git_status git_status)
|
||||||
# The VS vcpkg component cannot be written to without elevation.
|
# The VS vcpkg component cannot be written to without elevation.
|
||||||
if(NOT git_status EQUAL 0 AND NOT VCPKG_ROOT MATCHES "Visual Studio")
|
if(NOT git_status EQUAL 0 AND NOT VCPKG_ROOT MATCHES "Visual Studio")
|
||||||
|
|
|
@ -60,3 +60,5 @@ target_link_libraries(vbam-core-base
|
||||||
PRIVATE vbam-fex stb-image
|
PRIVATE vbam-fex stb-image
|
||||||
PUBLIC ${ZLIB_LIBRARY}
|
PUBLIC ${ZLIB_LIBRARY}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_subdirectory(test)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#define VBAM_IMMEDIATE_CRASH_DETAIL() __builtin_trap()
|
#define VBAM_IMMEDIATE_CRASH_DETAIL() __builtin_trap()
|
||||||
#define VBAM_INTRINSIC_UNREACHABLE_DETAIL() __builtin_unreachable()
|
#define VBAM_INTRINSIC_UNREACHABLE_DETAIL() __builtin_unreachable()
|
||||||
|
|
||||||
#elif defined(_MSC_VER) // defined(__GNUC__) || defined(__clang__)
|
#elif defined(_MSC_VER) // defined(__GNUC__) || defined(__clang__)
|
||||||
|
|
||||||
// MSVC.
|
// MSVC.
|
||||||
#define VBAM_IMMEDIATE_CRASH_DETAIL() __debugbreak()
|
#define VBAM_IMMEDIATE_CRASH_DETAIL() __debugbreak()
|
||||||
|
@ -33,29 +33,25 @@
|
||||||
#define VBAM_STRINGIFY(x) VBAM_STRINGIFY_DETAIL(x)
|
#define VBAM_STRINGIFY(x) VBAM_STRINGIFY_DETAIL(x)
|
||||||
|
|
||||||
#define VBAM_REQUIRE_SEMICOLON_DETAIL() \
|
#define VBAM_REQUIRE_SEMICOLON_DETAIL() \
|
||||||
static_assert(true, "Require a semicolon after macros invocation.")
|
static_assert(true, "Require a semicolon after macros invocation.")
|
||||||
|
|
||||||
#define VBAM_CHECK(condition) \
|
#define VBAM_CHECK(condition) \
|
||||||
if (!(condition)) { \
|
if (!(condition)) { \
|
||||||
fputs("CHECK failed at " __FILE__ ":" VBAM_STRINGIFY(__LINE__) ": " #condition "\n", stderr); \
|
fputs("CHECK failed at " __FILE__ ":" VBAM_STRINGIFY(__LINE__) ": " #condition "\n", \
|
||||||
VBAM_IMMEDIATE_CRASH_DETAIL(); \
|
stderr); \
|
||||||
} \
|
VBAM_IMMEDIATE_CRASH_DETAIL(); \
|
||||||
VBAM_REQUIRE_SEMICOLON_DETAIL()
|
} \
|
||||||
|
VBAM_REQUIRE_SEMICOLON_DETAIL()
|
||||||
#define VBAM_NOTREACHED_MESSAGE_DETAIL() \
|
|
||||||
fputs("NOTREACHED code reached at " __FILE__ ":" VBAM_STRINGIFY(__LINE__) "\n", stderr)
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
|
|
||||||
#define VBAM_NOTREACHED() \
|
#define VBAM_NOTREACHED() \
|
||||||
VBAM_NOTREACHED_MESSAGE_DETAIL(); \
|
fputs("NOTREACHED code reached at " __FILE__ ":" VBAM_STRINGIFY(__LINE__) "\n", stderr); \
|
||||||
VBAM_IMMEDIATE_CRASH_DETAIL()
|
VBAM_IMMEDIATE_CRASH_DETAIL()
|
||||||
|
|
||||||
#else // defined(DEBUG)
|
#else // defined(DEBUG)
|
||||||
|
|
||||||
#define VBAM_NOTREACHED() \
|
#define VBAM_NOTREACHED() VBAM_INTRINSIC_UNREACHABLE_DETAIL()
|
||||||
VBAM_NOTREACHED_MESSAGE_DETAIL(); \
|
|
||||||
VBAM_INTRINSIC_UNREACHABLE_DETAIL()
|
|
||||||
|
|
||||||
#endif // defined(DEBUG)
|
#endif // defined(DEBUG)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# This defines the `vbam-core-base-test` library.
|
||||||
|
|
||||||
|
if(NOT BUILD_TESTING)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(vbam-core-base-test
|
||||||
|
INTERFACE
|
||||||
|
notreached.h)
|
||||||
|
|
||||||
|
target_link_libraries(vbam-core-base-test
|
||||||
|
INTERFACE GTest::gtest)
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef VBAM_CORE_BASE_TEST_NOTREACHED_H_
|
||||||
|
#define VBAM_CORE_BASE_TEST_NOTREACHED_H_
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
|
||||||
|
#define VBAM_EXPECT_NOTREACHED(statement) EXPECT_DEATH(statement, "NOTREACHED")
|
||||||
|
|
||||||
|
#else // defined(DEBUG)
|
||||||
|
|
||||||
|
// There is no way to test this in release builds as the compiler might optimize
|
||||||
|
// this code path away. Eat the statement to avoid unused variable warnings.
|
||||||
|
#define VBAM_EXPECT_NOTREACHED(statement) \
|
||||||
|
if constexpr (false) { \
|
||||||
|
statement; \
|
||||||
|
} \
|
||||||
|
static_assert(true, "")
|
||||||
|
|
||||||
|
#endif // defined(DEBUG)
|
||||||
|
|
||||||
|
#endif // VBAM_CORE_BASE_TEST_NOTREACHED_H_
|
|
@ -46,33 +46,6 @@ set(VBAM_WX_COMMON
|
||||||
viewsupt.h
|
viewsupt.h
|
||||||
wayland.cpp
|
wayland.cpp
|
||||||
wayland.h
|
wayland.h
|
||||||
# from external source with minor modifications
|
|
||||||
widgets/checkedlistctrl.cpp
|
|
||||||
widgets/checkedlistctrl.h
|
|
||||||
widgets/client-data.h
|
|
||||||
widgets/dpi-support.h
|
|
||||||
widgets/event-handler-provider.h
|
|
||||||
widgets/group-check-box.cpp
|
|
||||||
widgets/group-check-box.h
|
|
||||||
widgets/keep-on-top-styler.cpp
|
|
||||||
widgets/keep-on-top-styler.h
|
|
||||||
widgets/option-validator.cpp
|
|
||||||
widgets/option-validator.h
|
|
||||||
widgets/render-plugin.cpp
|
|
||||||
widgets/render-plugin.h
|
|
||||||
widgets/user-input-ctrl.cpp
|
|
||||||
widgets/user-input-ctrl.h
|
|
||||||
widgets/user-input-event.cpp
|
|
||||||
widgets/user-input-event.h
|
|
||||||
widgets/sdl-poller.cpp
|
|
||||||
widgets/sdl-poller.h
|
|
||||||
widgets/shortcut-menu-bar.cpp
|
|
||||||
widgets/shortcut-menu-bar.h
|
|
||||||
widgets/utils.cpp
|
|
||||||
widgets/utils.h
|
|
||||||
widgets/webupdatedef.h
|
|
||||||
widgets/wxmisc.h
|
|
||||||
widgets/wxmisc.cpp
|
|
||||||
wxhead.h
|
wxhead.h
|
||||||
wxlogdebug.h
|
wxlogdebug.h
|
||||||
wxvbam.cpp
|
wxvbam.cpp
|
||||||
|
@ -253,6 +226,9 @@ function(configure_wx_target target)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
# Core emulator.
|
||||||
|
_add_link_libraries(vbam-core)
|
||||||
|
|
||||||
# Nonstd.
|
# Nonstd.
|
||||||
_add_link_libraries(nonstd-lib)
|
_add_link_libraries(nonstd-lib)
|
||||||
_add_include_directories(${NONSTD_INCLUDE_DIR})
|
_add_include_directories(${NONSTD_INCLUDE_DIR})
|
||||||
|
@ -311,6 +287,7 @@ endfunction()
|
||||||
# Sub-projects.
|
# Sub-projects.
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
add_subdirectory(config)
|
add_subdirectory(config)
|
||||||
|
add_subdirectory(widgets)
|
||||||
|
|
||||||
set(VBAM_ICON visualboyadvance-m.icns)
|
set(VBAM_ICON visualboyadvance-m.icns)
|
||||||
set(VBAM_ICON_PATH ${CMAKE_CURRENT_SOURCE_DIR}/icons/${VBAM_ICON})
|
set(VBAM_ICON_PATH ${CMAKE_CURRENT_SOURCE_DIR}/icons/${VBAM_ICON})
|
||||||
|
@ -326,13 +303,13 @@ target_include_directories(visualboyadvance-m PRIVATE ${SDL2_INCLUDE_DIRS})
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
visualboyadvance-m
|
visualboyadvance-m
|
||||||
vbam-core
|
|
||||||
vbam-components-draw-text
|
vbam-components-draw-text
|
||||||
vbam-components-filters
|
vbam-components-filters
|
||||||
vbam-components-filters-agb
|
vbam-components-filters-agb
|
||||||
vbam-components-filters-interframe
|
vbam-components-filters-interframe
|
||||||
vbam-components-user-config
|
vbam-components-user-config
|
||||||
vbam-wx-config
|
vbam-wx-config
|
||||||
|
vbam-wx-widgets
|
||||||
)
|
)
|
||||||
|
|
||||||
# adjust link command when making a static binary for gcc
|
# adjust link command when making a static binary for gcc
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# This defines the vbam-wx-config target and the
|
# This defines the vbam-wx-config target and the
|
||||||
# `VBAM_LOCALIZABLE_WX_CONFIG_FILES` variable, containing the list of
|
# `VBAM_LOCALIZABLE_WX_CONFIG_FILES` variable, containing the list of
|
||||||
# localizable files in the vbam-wx-config target.
|
# localizable files in the vbam-wx-config target.
|
||||||
|
|
||||||
# I don't like duplicating/triplicating code, so I only declare
|
# I don't like duplicating/triplicating code, so I only declare
|
||||||
|
@ -61,15 +61,9 @@ target_sources(vbam-wx-config
|
||||||
user-input.h
|
user-input.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(vbam-wx-config
|
|
||||||
PUBLIC
|
|
||||||
nonstd-lib
|
|
||||||
vbam-core
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_wx_target(vbam-wx-config)
|
configure_wx_target(vbam-wx-config)
|
||||||
|
|
||||||
if (BUILD_TESTING)
|
if(BUILD_TESTING)
|
||||||
add_executable(vbam-wx-config-tests
|
add_executable(vbam-wx-config-tests
|
||||||
bindings-test.cpp
|
bindings-test.cpp
|
||||||
command-test.cpp
|
command-test.cpp
|
||||||
|
@ -79,10 +73,12 @@ if (BUILD_TESTING)
|
||||||
user-input-test.cpp
|
user-input-test.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(vbam-wx-config-tests
|
target_link_libraries(vbam-wx-config-tests
|
||||||
vbam-core
|
# Test deps.
|
||||||
vbam-core-fake
|
vbam-core-fake
|
||||||
vbam-wx-config
|
|
||||||
vbam-wx-fake-opts
|
vbam-wx-fake-opts
|
||||||
|
|
||||||
|
# Target deps.
|
||||||
|
vbam-wx-config
|
||||||
GTest::gtest_main
|
GTest::gtest_main
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,8 @@ TEST_F(GamepadTest, NonDefaultInput) {
|
||||||
const config::KeyboardInput f1(WXK_F1);
|
const config::KeyboardInput f1(WXK_F1);
|
||||||
|
|
||||||
// Assign F1 to "Up".
|
// Assign F1 to "Up".
|
||||||
bindings()->AssignInputToCommand(f1, config::GameCommand(config::GameJoy(0), config::GameKey::Up));
|
bindings()->AssignInputToCommand(f1,
|
||||||
|
config::GameCommand(config::GameJoy(0), config::GameKey::Up));
|
||||||
|
|
||||||
// Press F1, the up key should be pressed.
|
// Press F1, the up key should be pressed.
|
||||||
EXPECT_TRUE(gamepad()->OnInputPressed(f1));
|
EXPECT_TRUE(gamepad()->OnInputPressed(f1));
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "core/base/check.h"
|
#include "core/base/check.h"
|
||||||
#include "wx/config/option.h"
|
#include "wx/config/option.h"
|
||||||
|
|
||||||
|
#include "core/base/check.h"
|
||||||
|
|
||||||
namespace config {
|
namespace config {
|
||||||
|
|
||||||
// An Option::Observer that calls a callback when an option has changed.
|
// An Option::Observer that calls a callback when an option has changed.
|
||||||
|
|
|
@ -6,10 +6,8 @@ if(NOT BUILD_TESTING)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(vbam-wx-fake-opts OBJECT)
|
add_library(vbam-wx-fake-opts OBJECT)
|
||||||
|
|
||||||
target_sources(vbam-wx-fake-opts
|
target_sources(vbam-wx-fake-opts
|
||||||
PRIVATE
|
PRIVATE
|
||||||
fake_opts.cpp
|
fake-opts.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_wx_target(vbam-wx-fake-opts)
|
configure_wx_target(vbam-wx-fake-opts)
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
# This defines the vbam-wx-widgets target.
|
||||||
|
# This does not export any localizable file as there is no localized string
|
||||||
|
# in this target.
|
||||||
|
|
||||||
|
add_library(vbam-wx-widgets OBJECT)
|
||||||
|
|
||||||
|
target_sources(vbam-wx-widgets
|
||||||
|
PRIVATE
|
||||||
|
# from external source with minor modifications
|
||||||
|
checkedlistctrl.cpp
|
||||||
|
group-check-box.cpp
|
||||||
|
keep-on-top-styler.cpp
|
||||||
|
option-validator.cpp
|
||||||
|
render-plugin.cpp
|
||||||
|
user-input-ctrl.cpp
|
||||||
|
user-input-event.cpp
|
||||||
|
sdl-poller.cpp
|
||||||
|
shortcut-menu-bar.cpp
|
||||||
|
utils.cpp
|
||||||
|
wxmisc.cpp
|
||||||
|
|
||||||
|
PUBLIC
|
||||||
|
# from external source with minor modifications
|
||||||
|
checkedlistctrl.h
|
||||||
|
client-data.h
|
||||||
|
dpi-support.h
|
||||||
|
event-handler-provider.h
|
||||||
|
group-check-box.h
|
||||||
|
keep-on-top-styler.h
|
||||||
|
option-validator.h
|
||||||
|
render-plugin.h
|
||||||
|
user-input-ctrl.h
|
||||||
|
user-input-event.h
|
||||||
|
sdl-poller.h
|
||||||
|
shortcut-menu-bar.h
|
||||||
|
utils.h
|
||||||
|
wxmisc.h
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(vbam-wx-widgets PUBLIC vbam-wx-config)
|
||||||
|
configure_wx_target(vbam-wx-widgets)
|
||||||
|
|
||||||
|
if(BUILD_TESTING)
|
||||||
|
add_executable(vbam-wx-widgets-tests
|
||||||
|
client-data-test.cpp
|
||||||
|
group-check-box-test.cpp
|
||||||
|
keep-on-top-styler-test.cpp
|
||||||
|
option-validator-test.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(vbam-wx-widgets-tests
|
||||||
|
# Test deps.
|
||||||
|
vbam-core-base-test
|
||||||
|
vbam-core-fake
|
||||||
|
vbam-wx-fake-opts
|
||||||
|
vbam-wx-widgets-test-fixture
|
||||||
|
|
||||||
|
# Target deps.
|
||||||
|
vbam-wx-config
|
||||||
|
vbam-wx-widgets
|
||||||
|
GTest::gtest_main
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_wx_target(vbam-wx-widgets-tests)
|
||||||
|
if (NOT CMAKE_CROSSCOMPILING)
|
||||||
|
gtest_discover_tests(vbam-wx-widgets-tests)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(test)
|
|
@ -13,10 +13,21 @@
|
||||||
#define VBAM_WX_WIDGETS_CHECKEDLISTCTRL_H_
|
#define VBAM_WX_WIDGETS_CHECKEDLISTCTRL_H_
|
||||||
|
|
||||||
// wxWidgets headers
|
// wxWidgets headers
|
||||||
#include "wx/widgets/webupdatedef.h" // for the WXDLLIMPEXP_WEBUPDATE macro
|
|
||||||
#include <wx/imaglist.h>
|
#include <wx/imaglist.h>
|
||||||
#include <wx/listctrl.h>
|
#include <wx/listctrl.h>
|
||||||
|
|
||||||
|
// this will never be part of a DLL
|
||||||
|
#define WXDLLIMPEXP_WEBUPDATE
|
||||||
|
// why would I include it and not enable it?
|
||||||
|
#define wxUSE_CHECKEDLISTCTRL 1
|
||||||
|
// enable customizations:
|
||||||
|
// - include wx/settings.h (bugfix; always enabled)
|
||||||
|
// - make a dynamic class so it can be subclass in xrc
|
||||||
|
// - only make col0 checkable
|
||||||
|
// - use "native" checkbox (also requires CLC_USE_SYSICONS)
|
||||||
|
#define CLC_VBAM_USAGE 1
|
||||||
|
#define CLC_USE_SYSICONS 1
|
||||||
|
|
||||||
#if wxUSE_CHECKEDLISTCTRL
|
#if wxUSE_CHECKEDLISTCTRL
|
||||||
|
|
||||||
// image indexes (used internally by wxCheckedListCtrl)
|
// image indexes (used internally by wxCheckedListCtrl)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "wx/widgets/client-data.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <wx/window.h>
|
||||||
|
|
||||||
|
#include "wx/config/user-input.h"
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
// Test the ClientData class with a simple type.
|
||||||
|
TEST(ClientDataTest, Int) {
|
||||||
|
std::unique_ptr<wxWindow> window(std::make_unique<wxWindow>());
|
||||||
|
window->SetClientObject(new ClientData<int>(42));
|
||||||
|
|
||||||
|
EXPECT_EQ(ClientData<int>::From(window.get()), 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the ClientData class with a complex type.
|
||||||
|
TEST(ClientDataTest, Object) {
|
||||||
|
std::unique_ptr<wxWindow> window(std::make_unique<wxWindow>());
|
||||||
|
window->SetClientObject(new ClientData<config::UserInput>(config::KeyboardInput('4')));
|
||||||
|
|
||||||
|
EXPECT_EQ(ClientData<config::UserInput>::From(window.get()).device(),
|
||||||
|
config::UserInput::Device::Keyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace widgets
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include "wx/widgets/group-check-box.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <wx/frame.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
|
||||||
|
#include "wx/widgets/test/widgets-test.h"
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
TEST_F(WidgetsTest, GroupCheckBoxTest) {
|
||||||
|
// Add 2 GroupCheckBoxes to the frame, `frame()` takes ownership here.
|
||||||
|
GroupCheckBox* check_box_1 = new GroupCheckBox(frame(), XRCID("One"), "One");
|
||||||
|
GroupCheckBox* check_box_2 = new GroupCheckBox(frame(), XRCID("Two"), "Two");
|
||||||
|
|
||||||
|
// Tick one checkbox and check the other is unticked.
|
||||||
|
check_box_1->SetValue(true);
|
||||||
|
EXPECT_FALSE(check_box_2->GetValue());
|
||||||
|
|
||||||
|
// And vice-versa.
|
||||||
|
check_box_2->SetValue(true);
|
||||||
|
EXPECT_FALSE(check_box_1->GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace widgets
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include "wx/widgets/keep-on-top-styler.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <wx/frame.h>
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
|
||||||
|
#include "wx/config/option-proxy.h"
|
||||||
|
#include "wx/widgets/test/widgets-test.h"
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
TEST_F(WidgetsTest, KeepOnTopStyler) {
|
||||||
|
// Enable the keep on top option.
|
||||||
|
OPTION(kDispKeepOnTop) = true;
|
||||||
|
|
||||||
|
// Create a Frame, it should not have the wxSTAY_ON_TOP style.
|
||||||
|
EXPECT_EQ(frame()->GetWindowStyle() & wxSTAY_ON_TOP, 0);
|
||||||
|
|
||||||
|
// Add a KeepOnTopStyler to the frame.
|
||||||
|
KeepOnTopStyler styler(frame());
|
||||||
|
|
||||||
|
// Send the Show event to the frame.
|
||||||
|
wxShowEvent show_event(wxEVT_SHOW, true);
|
||||||
|
frame()->GetEventHandler()->ProcessEvent(show_event);
|
||||||
|
|
||||||
|
// The frame should have the wxSTAY_ON_TOP style.
|
||||||
|
EXPECT_EQ(frame()->GetWindowStyle() & wxSTAY_ON_TOP, wxSTAY_ON_TOP);
|
||||||
|
|
||||||
|
// Disable the keep on top option.
|
||||||
|
OPTION(kDispKeepOnTop) = false;
|
||||||
|
|
||||||
|
// The frame should no longer have the wxSTAY_ON_TOP style.
|
||||||
|
EXPECT_EQ(frame()->GetWindowStyle() & wxSTAY_ON_TOP, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace widgets
|
|
@ -0,0 +1,156 @@
|
||||||
|
#include "wx/widgets/option-validator.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <wx/checkbox.h>
|
||||||
|
#include <wx/choice.h>
|
||||||
|
#include <wx/frame.h>
|
||||||
|
#include <wx/spinctrl.h>
|
||||||
|
#include <wx/window.h>
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
|
||||||
|
#include "core/base/test/notreached.h"
|
||||||
|
#include "wx/config/option.h"
|
||||||
|
#include "wx/widgets/test/widgets-test.h"
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
TEST_F(WidgetsTest, OptionSelectedValidator) {
|
||||||
|
wxCheckBox* check_box_0 = new wxCheckBox(frame(), XRCID("Zero"), "Zero");
|
||||||
|
wxCheckBox* check_box_1 = new wxCheckBox(frame(), XRCID("One"), "One");
|
||||||
|
config::Option* option = config::Option::ByID(config::OptionID::kPrefCaptureFormat);
|
||||||
|
|
||||||
|
check_box_0->SetValidator(OptionSelectedValidator(config::OptionID::kPrefCaptureFormat, 0));
|
||||||
|
check_box_1->SetValidator(OptionSelectedValidator(config::OptionID::kPrefCaptureFormat, 1));
|
||||||
|
|
||||||
|
// Tick the first checkbox, the second should be unticked.
|
||||||
|
check_box_0->SetValue(true);
|
||||||
|
frame()->TransferDataFromWindow();
|
||||||
|
EXPECT_EQ(option->GetUnsigned(), 0);
|
||||||
|
EXPECT_FALSE(check_box_1->GetValue());
|
||||||
|
|
||||||
|
// And vice-versa.
|
||||||
|
check_box_1->SetValue(true);
|
||||||
|
frame()->TransferDataFromWindow();
|
||||||
|
EXPECT_EQ(option->GetUnsigned(), 1);
|
||||||
|
EXPECT_FALSE(check_box_0->GetValue());
|
||||||
|
|
||||||
|
// Set the kPrefCaptureFormat option to 0, the first checkbox should be ticked.
|
||||||
|
option->SetUnsigned(0);
|
||||||
|
frame()->TransferDataToWindow();
|
||||||
|
EXPECT_TRUE(check_box_0->GetValue());
|
||||||
|
EXPECT_FALSE(check_box_1->GetValue());
|
||||||
|
|
||||||
|
// Set the kPrefCaptureFormat option to 1, the second checkbox should be ticked.
|
||||||
|
option->SetUnsigned(1);
|
||||||
|
frame()->TransferDataToWindow();
|
||||||
|
EXPECT_FALSE(check_box_0->GetValue());
|
||||||
|
EXPECT_TRUE(check_box_1->GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WidgetsTest, OptionSelectedValidator_InvalidData) {
|
||||||
|
wxCheckBox* check_box = new wxCheckBox(frame(), XRCID("Checbox"), "Checkbox");
|
||||||
|
|
||||||
|
// The value is higher than the max for this option.
|
||||||
|
EXPECT_DEATH(
|
||||||
|
check_box->SetValidator(OptionSelectedValidator(config::OptionID::kPrefCaptureFormat, 2)),
|
||||||
|
"value_ <= option\\(\\)->GetUnsignedMax\\(\\)");
|
||||||
|
|
||||||
|
// The option is not an unsigned option.
|
||||||
|
EXPECT_DEATH(check_box->SetValidator(OptionSelectedValidator(config::OptionID::kDispFilter, 0)),
|
||||||
|
"option\\(\\)->is_unsigned\\(\\)");
|
||||||
|
|
||||||
|
// Unsupported wxWindow type.
|
||||||
|
wxWindow* window = new wxWindow(frame(), XRCID("Window"));
|
||||||
|
#if WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
|
VBAM_EXPECT_NOTREACHED(
|
||||||
|
window->SetValidator(OptionSelectedValidator(config::OptionID::kPrefCaptureFormat, 0)));
|
||||||
|
#else // WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
|
window->SetValidator(OptionSelectedValidator(config::OptionID::kPrefCaptureFormat, 0));
|
||||||
|
VBAM_EXPECT_NOTREACHED(frame()->TransferDataToWindow());
|
||||||
|
#endif // WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WidgetsTest, OptionIntValidator) {
|
||||||
|
wxSpinCtrl* spin_ctrl = new wxSpinCtrl(frame(), XRCID("SpinCtrl"));
|
||||||
|
config::Option* option = config::Option::ByID(config::OptionID::kDispMaxThreads);
|
||||||
|
|
||||||
|
spin_ctrl->SetValidator(OptionIntValidator(config::OptionID::kDispMaxThreads));
|
||||||
|
|
||||||
|
// Set the kPrefCaptureFormat option to 0, the spin control should be set to 0.
|
||||||
|
option->SetInt(0);
|
||||||
|
frame()->TransferDataToWindow();
|
||||||
|
EXPECT_EQ(spin_ctrl->GetValue(), 0);
|
||||||
|
|
||||||
|
// Set the spin control to 100, the kPrefCaptureFormat option should be set to 100.
|
||||||
|
spin_ctrl->SetValue(100);
|
||||||
|
frame()->TransferDataFromWindow();
|
||||||
|
EXPECT_EQ(option->GetInt(), 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WidgetsTest, OptionIntValidator_InvalidData) {
|
||||||
|
wxSpinCtrl* spin_ctrl = new wxSpinCtrl(frame(), XRCID("SpinCtrl"));
|
||||||
|
|
||||||
|
// The option is not an int option.
|
||||||
|
EXPECT_DEATH(spin_ctrl->SetValidator(OptionIntValidator(config::OptionID::kDispFilter)),
|
||||||
|
"option\\(\\)->is_int\\(\\)");
|
||||||
|
|
||||||
|
// Unsupported wxWindow type.
|
||||||
|
wxWindow* window = new wxWindow(frame(), XRCID("Window"));
|
||||||
|
#if WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
|
VBAM_EXPECT_NOTREACHED(
|
||||||
|
window->SetValidator(OptionIntValidator(config::OptionID::kDispMaxThreads)));
|
||||||
|
#else // WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
|
window->SetValidator(OptionIntValidator(config::OptionID::kDispMaxThreads));
|
||||||
|
VBAM_EXPECT_NOTREACHED(frame()->TransferDataToWindow());
|
||||||
|
#endif // WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WidgetsTest, OptionChoiceValidator) {
|
||||||
|
wxChoice* choice = new wxChoice(frame(), XRCID("Choice"));
|
||||||
|
choice->Append("Zero");
|
||||||
|
choice->Append("One");
|
||||||
|
config::Option* option = config::Option::ByID(config::OptionID::kPrefCaptureFormat);
|
||||||
|
|
||||||
|
choice->SetValidator(OptionChoiceValidator(config::OptionID::kPrefCaptureFormat));
|
||||||
|
|
||||||
|
// Set the kPrefCaptureFormat option to 0, the first item should be selected.
|
||||||
|
option->SetUnsigned(0);
|
||||||
|
frame()->TransferDataToWindow();
|
||||||
|
EXPECT_EQ(choice->GetSelection(), 0);
|
||||||
|
|
||||||
|
// Set the kPrefCaptureFormat option to 1, the second item should be selected.
|
||||||
|
option->SetUnsigned(1);
|
||||||
|
frame()->TransferDataToWindow();
|
||||||
|
EXPECT_EQ(choice->GetSelection(), 1);
|
||||||
|
|
||||||
|
// Select the first item, the kPrefCaptureFormat option should be 0.
|
||||||
|
choice->SetSelection(0);
|
||||||
|
frame()->TransferDataFromWindow();
|
||||||
|
EXPECT_EQ(option->GetUnsigned(), 0);
|
||||||
|
|
||||||
|
// Select the second item, the kPrefCaptureFormat option should be 1.
|
||||||
|
choice->SetSelection(1);
|
||||||
|
frame()->TransferDataFromWindow();
|
||||||
|
EXPECT_EQ(option->GetUnsigned(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(WidgetsTest, OptionChoiceValidator_InvalidData) {
|
||||||
|
wxChoice* choice = new wxChoice(frame(), XRCID("Choice"));
|
||||||
|
|
||||||
|
// The option is not an unsigned option.
|
||||||
|
EXPECT_DEATH(choice->SetValidator(OptionChoiceValidator(config::OptionID::kDispFilter)),
|
||||||
|
"option\\(\\)->is_unsigned\\(\\)");
|
||||||
|
|
||||||
|
// Unsupported wxWindow type.
|
||||||
|
wxWindow* window = new wxWindow(frame(), XRCID("Window"));
|
||||||
|
#if WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
|
VBAM_EXPECT_NOTREACHED(
|
||||||
|
window->SetValidator(OptionChoiceValidator(config::OptionID::kPrefCaptureFormat)));
|
||||||
|
#else // WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
|
window->SetValidator(OptionChoiceValidator(config::OptionID::kPrefCaptureFormat));
|
||||||
|
VBAM_EXPECT_NOTREACHED(frame()->TransferDataToWindow());
|
||||||
|
#endif // WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace widgets
|
|
@ -28,18 +28,15 @@ bool OptionValidator::TransferToWindow() {
|
||||||
#if WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
#if WX_HAS_VALIDATOR_SET_WINDOW_OVERRIDE
|
||||||
void OptionValidator::SetWindow(wxWindow* window) {
|
void OptionValidator::SetWindow(wxWindow* window) {
|
||||||
wxValidator::SetWindow(window);
|
wxValidator::SetWindow(window);
|
||||||
[[maybe_unused]] const bool write_success = WriteToWindow();
|
OnValueChanged();
|
||||||
VBAM_CHECK(write_success);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void OptionValidator::OnValueChanged() {
|
void OptionValidator::OnValueChanged() {
|
||||||
[[maybe_unused]] const bool write_success = WriteToWindow();
|
VBAM_CHECK(WriteToWindow());
|
||||||
VBAM_CHECK(write_success);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionSelectedValidator::OptionSelectedValidator(config::OptionID option_id,
|
OptionSelectedValidator::OptionSelectedValidator(config::OptionID option_id, uint32_t value)
|
||||||
uint32_t value)
|
|
||||||
: OptionValidator(option_id), value_(value) {
|
: OptionValidator(option_id), value_(value) {
|
||||||
VBAM_CHECK(option()->is_unsigned());
|
VBAM_CHECK(option()->is_unsigned());
|
||||||
VBAM_CHECK(value_ >= option()->GetUnsignedMin());
|
VBAM_CHECK(value_ >= option()->GetUnsignedMin());
|
||||||
|
@ -80,8 +77,7 @@ bool OptionSelectedValidator::WriteToOption() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxRadioButton* radio_button =
|
const wxRadioButton* radio_button = wxDynamicCast(GetWindow(), wxRadioButton);
|
||||||
wxDynamicCast(GetWindow(), wxRadioButton);
|
|
||||||
if (radio_button) {
|
if (radio_button) {
|
||||||
if (radio_button->GetValue()) {
|
if (radio_button->GetValue()) {
|
||||||
option()->SetUnsigned(value_);
|
option()->SetUnsigned(value_);
|
||||||
|
@ -93,8 +89,7 @@ bool OptionSelectedValidator::WriteToOption() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionIntValidator::OptionIntValidator(config::OptionID option_id)
|
OptionIntValidator::OptionIntValidator(config::OptionID option_id) : OptionValidator(option_id) {
|
||||||
: OptionValidator(option_id) {
|
|
||||||
VBAM_CHECK(option()->is_int());
|
VBAM_CHECK(option()->is_int());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,19 +148,26 @@ bool OptionChoiceValidator::IsWindowValueValid() {
|
||||||
|
|
||||||
bool OptionChoiceValidator::WriteToWindow() {
|
bool OptionChoiceValidator::WriteToWindow() {
|
||||||
wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
|
wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
|
||||||
VBAM_CHECK(choice);
|
if (choice) {
|
||||||
choice->SetSelection(option()->GetUnsigned());
|
choice->SetSelection(option()->GetUnsigned());
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
VBAM_NOTREACHED();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OptionChoiceValidator::WriteToOption() {
|
bool OptionChoiceValidator::WriteToOption() {
|
||||||
const wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
|
const wxChoice* choice = wxDynamicCast(GetWindow(), wxChoice);
|
||||||
VBAM_CHECK(choice);
|
if (choice) {
|
||||||
return option()->SetUnsigned(choice->GetSelection());
|
return option()->SetUnsigned(choice->GetSelection());
|
||||||
|
}
|
||||||
|
|
||||||
|
VBAM_NOTREACHED();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionBoolValidator::OptionBoolValidator(config::OptionID option_id)
|
OptionBoolValidator::OptionBoolValidator(config::OptionID option_id) : OptionValidator(option_id) {
|
||||||
: OptionValidator(option_id) {
|
|
||||||
VBAM_CHECK(option()->is_bool());
|
VBAM_CHECK(option()->is_bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,15 +181,23 @@ bool OptionBoolValidator::IsWindowValueValid() {
|
||||||
|
|
||||||
bool OptionBoolValidator::WriteToWindow() {
|
bool OptionBoolValidator::WriteToWindow() {
|
||||||
wxCheckBox* checkbox = wxDynamicCast(GetWindow(), wxCheckBox);
|
wxCheckBox* checkbox = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||||
VBAM_CHECK(checkbox);
|
if (checkbox) {
|
||||||
checkbox->SetValue(option()->GetBool());
|
checkbox->SetValue(option()->GetBool());
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
VBAM_NOTREACHED();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OptionBoolValidator::WriteToOption() {
|
bool OptionBoolValidator::WriteToOption() {
|
||||||
const wxCheckBox* checkbox = wxDynamicCast(GetWindow(), wxCheckBox);
|
const wxCheckBox* checkbox = wxDynamicCast(GetWindow(), wxCheckBox);
|
||||||
VBAM_CHECK(checkbox);
|
if (checkbox) {
|
||||||
return option()->SetBool(checkbox->GetValue());
|
return option()->SetBool(checkbox->GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
VBAM_NOTREACHED();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace widgets
|
} // namespace widgets
|
||||||
|
|
|
@ -85,7 +85,7 @@ private:
|
||||||
void OnValueChanged() final;
|
void OnValueChanged() final;
|
||||||
};
|
};
|
||||||
|
|
||||||
// "Generic" validator for a wxChecBox or wxRadioButton widget with a kUnsigned
|
// "Generic" validator for a wxCheckBox or wxRadioButton widget with a kUnsigned
|
||||||
// Option. This will make sure the kUnsigned Option and the wxRadioButton or
|
// Option. This will make sure the kUnsigned Option and the wxRadioButton or
|
||||||
// wxCheckBox are kept in sync. The widget will be checked if the kUnsigned
|
// wxCheckBox are kept in sync. The widget will be checked if the kUnsigned
|
||||||
// Option matches the provided `value` parameter in the constructor.
|
// Option matches the provided `value` parameter in the constructor.
|
||||||
|
|
|
@ -36,10 +36,10 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Helper method to find a joystick state from a joystick ID.
|
// Helper method to find a joystick state from a joystick ID.
|
||||||
// Returns nullptr if not present. Called from the SDL worker thread.
|
// Returns nullptr if not present.
|
||||||
JoyState* FindJoyState(const SDL_JoystickID& joy_id);
|
JoyState* FindJoyState(const SDL_JoystickID& joy_id);
|
||||||
|
|
||||||
// Remap all controllers. Called from the SDL worker thread.
|
// Remap all controllers.
|
||||||
void RemapControllers();
|
void RemapControllers();
|
||||||
|
|
||||||
// Reconnects all controllers.
|
// Reconnects all controllers.
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
# This defines the `vbam-wx-widgets-test-fixture` library, which is used for
|
||||||
|
# providing a base fixture for tests using wxWidgets.
|
||||||
|
|
||||||
|
if(NOT BUILD_TESTING)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(vbam-wx-widgets-test-fixture OBJECT)
|
||||||
|
target_sources(vbam-wx-widgets-test-fixture
|
||||||
|
PRIVATE
|
||||||
|
test-app.cpp
|
||||||
|
widgets-test.cpp
|
||||||
|
|
||||||
|
PUBLIC
|
||||||
|
test-app.h
|
||||||
|
widgets-test.h
|
||||||
|
)
|
||||||
|
configure_wx_target(vbam-wx-widgets-test-fixture)
|
||||||
|
target_link_libraries(vbam-wx-widgets-test-fixture PUBLIC GTest::gtest)
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "wx/widgets/test/test-app.h"
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
TestApp::TestApp() : previous_app_(wxApp::GetInstance()) {
|
||||||
|
// Initialize the wxWidgets app.
|
||||||
|
int argc = 0;
|
||||||
|
wxApp::Initialize(argc, nullptr);
|
||||||
|
|
||||||
|
// Set the wxApp instance to this object.
|
||||||
|
wxApp::SetInstance(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestApp::~TestApp() {
|
||||||
|
// Clean up the wxWidgets app.
|
||||||
|
wxApp::CleanUp();
|
||||||
|
|
||||||
|
// Restore the previous wxApp instance.
|
||||||
|
wxApp::SetInstance(previous_app_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace widgets
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef VBAM_WX_WIDGETS_TEST_TEST_APP_H_
|
||||||
|
#define VBAM_WX_WIDGETS_TEST_TEST_APP_H_
|
||||||
|
|
||||||
|
#include <wx/app.h>
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
// While this object is in scope, wxApp::GetInstance() will return this object.
|
||||||
|
class TestApp : public wxApp {
|
||||||
|
public:
|
||||||
|
TestApp();
|
||||||
|
~TestApp() override;
|
||||||
|
|
||||||
|
bool OnInit() override { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The previous wxApp instance, active before we set this one.
|
||||||
|
wxAppConsole* const previous_app_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace widgets
|
||||||
|
|
||||||
|
#endif // VBAM_WX_WIDGETS_TEST_TEST_APP_H_
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include "wx/widgets/test/widgets-test.h"
|
||||||
|
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
WidgetsTest::WidgetsTest() {
|
||||||
|
// wxWidgets can run multi-threaded so set this up for death tests.
|
||||||
|
GTEST_FLAG_SET(death_test_style, "threadsafe");
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetsTest::~WidgetsTest() = default;
|
||||||
|
|
||||||
|
void WidgetsTest::SetUp() {
|
||||||
|
// Give the wxFrame a unique name and initialize it.
|
||||||
|
const char* test_name(testing::UnitTest::GetInstance()->current_test_info()->name());
|
||||||
|
frame_ = std::make_unique<wxFrame>(nullptr, wxXmlResource ::DoGetXRCID(test_name), test_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsTest::TearDown() {
|
||||||
|
ASSERT_FALSE(frame_->IsShown());
|
||||||
|
ASSERT_FALSE(frame_->IsBeingDeleted());
|
||||||
|
|
||||||
|
// Ensure the frame is destroyed before the app.
|
||||||
|
frame_->Destroy();
|
||||||
|
frame_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace widgets
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef VBAM_WX_WIDGETS_TEST_WIDGETS_TEST_H_
|
||||||
|
#define VBAM_WX_WIDGETS_TEST_WIDGETS_TEST_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <wx/frame.h>
|
||||||
|
|
||||||
|
#include "wx/widgets/test/test-app.h"
|
||||||
|
|
||||||
|
namespace widgets {
|
||||||
|
|
||||||
|
// A base fixture for tests that use wxWidgets widgets. An app and a wxFrame are
|
||||||
|
// provided for convenience. They will be deleted on test teardown.
|
||||||
|
class WidgetsTest : public testing::Test {
|
||||||
|
public:
|
||||||
|
WidgetsTest();
|
||||||
|
~WidgetsTest() override;
|
||||||
|
|
||||||
|
// testing::Test implementation.
|
||||||
|
void SetUp() override;
|
||||||
|
void TearDown() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxFrame* frame() { return frame_.get(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
TestApp test_app_;
|
||||||
|
std::unique_ptr<wxFrame> frame_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace widgets
|
||||||
|
|
||||||
|
#endif // VBAM_WX_WIDGETS_TEST_WIDGETS_TEST_H_
|
|
@ -39,7 +39,7 @@ public:
|
||||||
// Returns the first pressed input, if any.
|
// Returns the first pressed input, if any.
|
||||||
nonstd::optional<config::UserInput> FirstReleasedInput() const;
|
nonstd::optional<config::UserInput> FirstReleasedInput() const;
|
||||||
|
|
||||||
// Mark `event_data` as processed and returns the new event filter. This is
|
// Marks `user_input` as processed and returns the new event filter. This is
|
||||||
// meant to be used with FilterEvent() to process global shortcuts before
|
// meant to be used with FilterEvent() to process global shortcuts before
|
||||||
// sending the event to the next handler.
|
// sending the event to the next handler.
|
||||||
int FilterProcessedInput(const config::UserInput& user_input);
|
int FilterProcessedInput(const config::UserInput& user_input);
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
// dummy webupdatedef.h for checklistctrl
|
|
||||||
#ifndef WXDLLIMPEXP_WEBUPDATE
|
|
||||||
// this will never be part of a DLL
|
|
||||||
#define WXDLLIMPEXP_WEBUPDATE
|
|
||||||
// why would I include it and not enable it?
|
|
||||||
#define wxUSE_CHECKEDLISTCTRL 1
|
|
||||||
// enable customizations:
|
|
||||||
// - include wx/settings.h (bugfix; always enabled)
|
|
||||||
// - make a dynamic class so it can be subclass in xrc
|
|
||||||
// - only make col0 checkable
|
|
||||||
// - use "native" checkbox (also requires CLC_USE_SYSICONS)
|
|
||||||
#define CLC_VBAM_USAGE 1
|
|
||||||
#define CLC_USE_SYSICONS 1
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue