From c0eeb83766121da9af7338ac275037871a66bd2e Mon Sep 17 00:00:00 2001 From: Jamiras Date: Fri, 9 Feb 2024 22:20:03 -0700 Subject: [PATCH] re-enable AchievementRuntimeExport tests --- tests/RA_Integration.Tests.vcxproj | 1 + tests/RA_Integration.Tests.vcxproj.filters | 3 + .../AchievementRuntimeExports_Tests.cpp | 427 ++++++++++++++++++ tests/services/AchievementRuntime_Tests.cpp | 171 ------- 4 files changed, 431 insertions(+), 171 deletions(-) create mode 100644 tests/services/AchievementRuntimeExports_Tests.cpp diff --git a/tests/RA_Integration.Tests.vcxproj b/tests/RA_Integration.Tests.vcxproj index 3d788cc6..4d79463c 100644 --- a/tests/RA_Integration.Tests.vcxproj +++ b/tests/RA_Integration.Tests.vcxproj @@ -383,6 +383,7 @@ + diff --git a/tests/RA_Integration.Tests.vcxproj.filters b/tests/RA_Integration.Tests.vcxproj.filters index 150cf5fa..590114eb 100644 --- a/tests/RA_Integration.Tests.vcxproj.filters +++ b/tests/RA_Integration.Tests.vcxproj.filters @@ -465,6 +465,9 @@ Code + + Tests\Services + diff --git a/tests/services/AchievementRuntimeExports_Tests.cpp b/tests/services/AchievementRuntimeExports_Tests.cpp new file mode 100644 index 00000000..e695c039 --- /dev/null +++ b/tests/services/AchievementRuntimeExports_Tests.cpp @@ -0,0 +1,427 @@ +#include "services\AchievementRuntimeExports.hh" + +#include "services\AchievementRuntime.hh" + +#include "tests\RA_UnitTestHelpers.h" + +#include "tests\mocks\MockConfiguration.hh" +#include "tests\mocks\MockConsoleContext.hh" +#include "tests\mocks\MockDesktop.hh" +#include "tests\mocks\MockEmulatorContext.hh" +#include "tests\mocks\MockUserContext.hh" + +#include +#include +#include + +#include "Exports.hh" +#include "RA_Resource.h" + +// the exported functions are not defined in a header anywhere. the only thing that should normally be +// calling them is rcheevos/rc_client_raintegration, and it binds the function pointers using its own +// definition of the functions. +extern "C" API int CCONV _Rcheevos_GetExternalClient(rc_client_external_t* pClientExternal, int nVersion); +extern "C" API const rc_client_raintegration_menu_t* CCONV _Rcheevos_RAIntegrationGetMenu(); +extern "C" API void CCONV _Rcheevos_SetRAIntegrationWriteMemoryFunction(rc_client_t* client, rc_client_raintegration_write_memory_func_t handler); +extern "C" API void CCONV _Rcheevos_SetRAIntegrationEventHandler(rc_client_t* client, rc_client_raintegration_event_handler_t handler); + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace ra { +namespace services { +namespace tests { + +constexpr int ResetEventBit = (1 << 24); + +class AchievementRuntimeHarness : public AchievementRuntime +{ +public: + GSL_SUPPRESS_F6 AchievementRuntimeHarness() : m_Override(this) + { + mockUserContext.Initialize("User", "ApiToken"); + GetClient()->user.display_name = "UserDisplay"; + GetClient()->state.user = RC_CLIENT_USER_STATE_LOGGED_IN; + } + + ra::data::context::mocks::MockEmulatorContext mockEmulatorContext; + ra::data::context::mocks::MockUserContext mockUserContext; + ra::services::mocks::MockConfiguration mockConfiguration; + + void InitializeEventHandler() + { + s_pRuntimeHarness = this; + + _Rcheevos_SetRAIntegrationEventHandler(&m_pExternalClient, AchievementRuntimeHarness::DispatchRAIntegrationEvent); + } + + void InitializeClientEventHandler() + { + s_pRuntimeHarness = this; + + rc_client_external_t pClient; + memset(&pClient, 0, sizeof(pClient)); + _Rcheevos_GetExternalClient(&pClient, 1); + + pClient.set_event_handler(&m_pExternalClient, AchievementRuntimeHarness::DispatchEvent); + } + + void AssertHardcoreChangedEventSeen() + { + Assert::IsTrue(m_nEventsSeen & (1 << RC_CLIENT_RAINTEGRATION_EVENT_HARDCORE_CHANGED), + L"HARDCORE event not seen"); + } + + void AssertPauseEventSeen() + { + Assert::IsTrue(m_nEventsSeen & (1 << RC_CLIENT_RAINTEGRATION_EVENT_PAUSE), + L"PAUSE event not seen"); + } + + void AssertResetEventSeen() + { + Assert::IsTrue(m_nEventsSeen & ResetEventBit, L"RESET event not seen"); + } + + void AssertMenuItemCheckedChangedEventSeen(uint32_t nMenuItemId) + { + Assert::IsTrue(m_nEventsSeen & (1 << RC_CLIENT_RAINTEGRATION_EVENT_MENUITEM_CHECKED_CHANGED), + L"MENUITEM event not seen"); + + for (const auto nChangedMenuItemId : m_vMenuItemsChanged) + { + if (nChangedMenuItemId == nMenuItemId) + return; + } + Assert::Fail(ra::StringPrintf(L"MENUITEM check changed event not seen for %d", nMenuItemId).c_str()); + } + + void InitializeMemoryFunctions() + { + s_pRuntimeHarness = this; + + rc_client_external_t pClient; + memset(&pClient, 0, sizeof(pClient)); + _Rcheevos_GetExternalClient(&pClient, 1); + + pClient.set_read_memory(&m_pExternalClient, AchievementRuntimeHarness::DispatchReadMemory); + + _Rcheevos_SetRAIntegrationWriteMemoryFunction(&m_pExternalClient, AchievementRuntimeHarness::DispatchWriteMemory); + } + + uint8_t GetMemoryByte(uint32_t nAddress) + { + if (nAddress >= m_vMockMemory.size()) + return 0; + + return m_vMockMemory.at(nAddress); + } + +private: + ra::services::ServiceLocator::ServiceOverride m_Override; + + static void DispatchEvent(const rc_client_event_t* event, rc_client_t* client) + { + Assert::AreEqual((void*)&s_pRuntimeHarness->m_pExternalClient, (void*)client); + + switch (event->type) + { + case RC_CLIENT_EVENT_RESET: + s_pRuntimeHarness->m_nEventsSeen |= ResetEventBit; + break; + } + } + + static void DispatchRAIntegrationEvent(const rc_client_raintegration_event_t* event, rc_client_t* client) + { + Assert::AreEqual((void*)&s_pRuntimeHarness->m_pExternalClient, (void*)client); + + switch (event->type) + { + case RC_CLIENT_RAINTEGRATION_EVENT_MENUITEM_CHECKED_CHANGED: + s_pRuntimeHarness->m_vMenuItemsChanged.push_back(event->menu_item->id); + break; + } + + s_pRuntimeHarness->m_nEventsSeen |= (1 << event->type); + } + + static uint32_t DispatchReadMemory(uint32_t address, uint8_t* buffer, uint32_t num_bytes, rc_client_t* client) + { + Assert::AreEqual((void*)&s_pRuntimeHarness->m_pExternalClient, (void*)client); + + auto nBytesAvailable = (s_pRuntimeHarness->m_vMockMemory.size() > address) ? + gsl::narrow_cast(s_pRuntimeHarness->m_vMockMemory.size() - address) : 0; + + if (nBytesAvailable > num_bytes) + nBytesAvailable = num_bytes; + + if (nBytesAvailable > 0) + memcpy(buffer, &s_pRuntimeHarness->m_vMockMemory.at(address), nBytesAvailable); + + return nBytesAvailable; + } + + static void DispatchWriteMemory(uint32_t address, uint8_t* buffer, uint32_t num_bytes, rc_client_t* client) + { + Assert::AreEqual((void*)&s_pRuntimeHarness->m_pExternalClient, (void*)client); + + if (s_pRuntimeHarness->m_vMockMemory.size() < address + num_bytes + 1) + s_pRuntimeHarness->m_vMockMemory.resize(address + num_bytes + 1); + + memcpy(&s_pRuntimeHarness->m_vMockMemory.at(address), buffer, num_bytes); + } + + static AchievementRuntimeHarness* s_pRuntimeHarness; + rc_client_t m_pExternalClient{}; + int m_nEventsSeen = 0; + std::vector m_vMenuItemsChanged; + std::vector m_vMockMemory; +}; + +AchievementRuntimeHarness* AchievementRuntimeHarness::s_pRuntimeHarness = nullptr; + +TEST_CLASS(AchievementRuntimeExports_Tests) +{ +private: + static void AssertMenuItem(const rc_client_raintegration_menu_t* pMenu, int nIndex, uint32_t nId, const char* label) + { + const auto* pItem = &pMenu->items[nIndex]; + Assert::AreEqual(nId, pItem->id); + Assert::AreEqual(std::string(label), std::string(pItem->label)); + Assert::AreEqual({1}, pItem->enabled); + Assert::AreEqual({0}, pItem->checked); + }; + + static void AssertMenuItemChecked(const rc_client_raintegration_menu_t* pMenu, int nIndex, uint32_t nId, const char* label) + { + const auto* pItem = &pMenu->items[nIndex]; + Assert::AreEqual(nId, pItem->id); + Assert::AreEqual(std::string(label), std::string(pItem->label)); + Assert::AreEqual({1}, pItem->enabled); + Assert::AreEqual({1}, pItem->checked); + }; + + static void AssertMenuSeparator(const rc_client_raintegration_menu_t* pMenu, int nIndex) + { + const auto* pItem = &pMenu->items[nIndex]; + Assert::AreEqual(0U, pItem->id); + Assert::IsNull(pItem->label); + Assert::AreEqual({1}, pItem->enabled); + Assert::AreEqual({0}, pItem->checked); + }; + + static void AssertV1Exports(rc_client_external_t& pClient) + { + Assert::IsNotNull((void*)pClient.destroy, L"destory not set"); + + Assert::IsNotNull((void*)pClient.enable_logging, L"enable_logging not set"); + Assert::IsNotNull((void*)pClient.set_event_handler, L"set_event_handler not set"); + Assert::IsNotNull((void*)pClient.set_read_memory, L"set_read_memory not set"); + Assert::IsNotNull((void*)pClient.set_get_time_millisecs, L"set_get_time_millisecs not set"); + Assert::IsNotNull((void*)pClient.set_host, L"set_host not set"); + + Assert::IsNotNull((void*)pClient.set_hardcore_enabled, L"set_hardcore_enabled not set"); + Assert::IsNotNull((void*)pClient.get_hardcore_enabled, L"get_hardcore_enabled not set"); + Assert::IsNotNull((void*)pClient.set_unofficial_enabled, L"set_unofficial_enabled not set"); + Assert::IsNotNull((void*)pClient.get_unofficial_enabled, L"get_unofficial_enabled not set"); + Assert::IsNotNull((void*)pClient.set_encore_mode_enabled, L"set_encore_mode_enabled not set"); + Assert::IsNotNull((void*)pClient.get_encore_mode_enabled, L"get_encore_mode_enabled not set"); + Assert::IsNotNull((void*)pClient.set_spectator_mode_enabled, L"set_spectator_mode_enabled not set"); + Assert::IsNotNull((void*)pClient.get_spectator_mode_enabled, L"get_spectator_mode_enabled not set"); + + Assert::IsNotNull((void*)pClient.abort_async, L"abort_async not set"); + + Assert::IsNotNull((void*)pClient.begin_login_with_password, L"begin_login_with_password not set"); + Assert::IsNotNull((void*)pClient.begin_login_with_token, L"begin_login_with_token not set"); + Assert::IsNotNull((void*)pClient.logout, L"logout not set"); + Assert::IsNotNull((void*)pClient.get_user_info, L"get_user_info not set"); + + Assert::IsNotNull((void*)pClient.begin_identify_and_load_game, L"begin_identify_and_load_game not set"); + Assert::IsNotNull((void*)pClient.begin_load_game, L"begin_load_game not set"); + Assert::IsNotNull((void*)pClient.get_game_info, L"get_game_info not set"); + Assert::IsNull((void*)pClient.begin_load_subset, L"begin_load_subset set"); + Assert::IsNotNull((void*)pClient.get_subset_info, L"get_subset_info not set"); + Assert::IsNotNull((void*)pClient.unload_game, L"unload_game not set"); + Assert::IsNotNull((void*)pClient.get_user_game_summary, L"get_user_game_summary not set"); + Assert::IsNotNull((void*)pClient.begin_change_media, L"begin_change_media not set"); + + Assert::IsNotNull((void*)pClient.create_achievement_list, L"create_achievement_list not set"); + Assert::IsNotNull((void*)pClient.has_achievements, L"has_achievements not set"); + Assert::IsNotNull((void*)pClient.get_achievement_info, L"get_achievement_info not set"); + + Assert::IsNotNull((void*)pClient.create_leaderboard_list, L"create_leaderboard_list not set"); + Assert::IsNotNull((void*)pClient.has_leaderboards, L"has_leaderboards not set"); + Assert::IsNotNull((void*)pClient.get_leaderboard_info, L"get_leaderboard_info not set"); + Assert::IsNotNull((void*)pClient.begin_fetch_leaderboard_entries, L"begin_fetch_leaderboard_entries not set"); + Assert::IsNotNull((void*)pClient.begin_fetch_leaderboard_entries_around_user, L"begin_fetch_leaderboard_entries_around_user not set"); + + Assert::IsNotNull((void*)pClient.get_rich_presence_message, L"get_rich_presence_message not set"); + Assert::IsNotNull((void*)pClient.has_rich_presence, L"has_rich_presence not set"); + + Assert::IsNotNull((void*)pClient.do_frame, L"do_frame not set"); + Assert::IsNotNull((void*)pClient.idle, L"idle not set"); + Assert::IsNotNull((void*)pClient.is_processing_required, L"is_processing_required not set"); + Assert::IsNotNull((void*)pClient.can_pause, L"can_pause not set"); + Assert::IsNotNull((void*)pClient.reset, L"reset not set"); + + Assert::IsNotNull((void*)pClient.progress_size, L"progress_size not set"); + Assert::IsNotNull((void*)pClient.serialize_progress, L"serialize_progress not set"); + Assert::IsNotNull((void*)pClient.deserialize_progress, L"deserialize_progress not set"); + } + +public: + TEST_METHOD(TestGetExternalClientV1) + { + AchievementRuntimeHarness runtime; + + rc_client_external_t pClient; + memset(&pClient, 0, sizeof(pClient)); + + _Rcheevos_GetExternalClient(&pClient, 1); + + AssertV1Exports(pClient); + + Assert::IsTrue(IsExternalRcheevosClient()); + } + + TEST_METHOD(TestRAIntegrationGetMenu) + { + AchievementRuntimeHarness runtime; + runtime.mockUserContext.Logout(); + + const rc_client_raintegration_menu_t* pMenu; + + pMenu = _Rcheevos_RAIntegrationGetMenu(); + Assert::AreEqual(11U, pMenu->num_items); + AssertMenuItem(pMenu, 0, IDM_RA_HARDCORE_MODE, "&Hardcore Mode"); + AssertMenuItem(pMenu, 1, IDM_RA_NON_HARDCORE_WARNING, "Non-Hardcore &Warning"); + AssertMenuSeparator(pMenu, 2); + AssertMenuItem(pMenu, 3, IDM_RA_FILES_OPENALL, "&Open All"); + AssertMenuItem(pMenu, 4, IDM_RA_FILES_ACHIEVEMENTS, "Assets Li&st"); + AssertMenuItem(pMenu, 5, IDM_RA_FILES_ACHIEVEMENTEDITOR, "Assets &Editor"); + AssertMenuItem(pMenu, 6, IDM_RA_FILES_MEMORYFINDER, "&Memory Inspector"); + AssertMenuItem(pMenu, 7, IDM_RA_FILES_MEMORYBOOKMARKS, "Memory &Bookmarks"); + AssertMenuItem(pMenu, 8, IDM_RA_FILES_POINTERFINDER, "Pointer &Finder"); + AssertMenuItem(pMenu, 9, IDM_RA_FILES_CODENOTES, "Code &Notes"); + AssertMenuItem(pMenu, 10, IDM_RA_PARSERICHPRESENCE, "Rich &Presence Monitor"); + + runtime.mockUserContext.Initialize("User", "ApiToken"); + + pMenu = _Rcheevos_RAIntegrationGetMenu(); + Assert::AreEqual(17U, pMenu->num_items); + AssertMenuItem(pMenu, 0, IDM_RA_OPENUSERPAGE, "Open my &User Page"); + AssertMenuItem(pMenu, 1, IDM_RA_OPENGAMEPAGE, "Open this &Game's Page"); + AssertMenuSeparator(pMenu, 2); + AssertMenuItem(pMenu, 3, IDM_RA_HARDCORE_MODE, "&Hardcore Mode"); + AssertMenuItem(pMenu, 4, IDM_RA_NON_HARDCORE_WARNING, "Non-Hardcore &Warning"); + AssertMenuSeparator(pMenu, 5); + AssertMenuItem(pMenu, 6, IDM_RA_FILES_OPENALL, "&Open All"); + AssertMenuItem(pMenu, 7, IDM_RA_FILES_ACHIEVEMENTS, "Assets Li&st"); + AssertMenuItem(pMenu, 8, IDM_RA_FILES_ACHIEVEMENTEDITOR, "Assets &Editor"); + AssertMenuItem(pMenu, 9, IDM_RA_FILES_MEMORYFINDER, "&Memory Inspector"); + AssertMenuItem(pMenu, 10, IDM_RA_FILES_MEMORYBOOKMARKS, "Memory &Bookmarks"); + AssertMenuItem(pMenu, 11, IDM_RA_FILES_POINTERFINDER, "Pointer &Finder"); + AssertMenuItem(pMenu, 12, IDM_RA_FILES_CODENOTES, "Code &Notes"); + AssertMenuItem(pMenu, 13, IDM_RA_PARSERICHPRESENCE, "Rich &Presence Monitor"); + AssertMenuSeparator(pMenu, 14); + AssertMenuItem(pMenu, 15, IDM_RA_REPORTBROKENACHIEVEMENTS, "&Report Achievement Problem"); + AssertMenuItem(pMenu, 16, IDM_RA_GETROMCHECKSUM, "View Game H&ash"); + + runtime.mockConfiguration.SetFeatureEnabled(ra::services::Feature::Hardcore, true); + runtime.mockConfiguration.SetFeatureEnabled(ra::services::Feature::NonHardcoreWarning, true); + + pMenu = _Rcheevos_RAIntegrationGetMenu(); + Assert::AreEqual(17U, pMenu->num_items); + AssertMenuItem(pMenu, 0, IDM_RA_OPENUSERPAGE, "Open my &User Page"); + AssertMenuItem(pMenu, 1, IDM_RA_OPENGAMEPAGE, "Open this &Game's Page"); + AssertMenuSeparator(pMenu, 2); + AssertMenuItemChecked(pMenu, 3, IDM_RA_HARDCORE_MODE, "&Hardcore Mode"); + AssertMenuItemChecked(pMenu, 4, IDM_RA_NON_HARDCORE_WARNING, "Non-Hardcore &Warning"); + AssertMenuSeparator(pMenu, 5); + AssertMenuItem(pMenu, 6, IDM_RA_FILES_OPENALL, "&Open All"); + AssertMenuItem(pMenu, 7, IDM_RA_FILES_ACHIEVEMENTS, "Assets Li&st"); + AssertMenuItem(pMenu, 8, IDM_RA_FILES_ACHIEVEMENTEDITOR, "Assets &Editor"); + AssertMenuItem(pMenu, 9, IDM_RA_FILES_MEMORYFINDER, "&Memory Inspector"); + AssertMenuItem(pMenu, 10, IDM_RA_FILES_MEMORYBOOKMARKS, "Memory &Bookmarks"); + AssertMenuItem(pMenu, 11, IDM_RA_FILES_POINTERFINDER, "Pointer &Finder"); + AssertMenuItem(pMenu, 12, IDM_RA_FILES_CODENOTES, "Code &Notes"); + AssertMenuItem(pMenu, 13, IDM_RA_PARSERICHPRESENCE, "Rich &Presence Monitor"); + AssertMenuSeparator(pMenu, 14); + AssertMenuItem(pMenu, 15, IDM_RA_REPORTBROKENACHIEVEMENTS, "&Report Achievement Problem"); + AssertMenuItem(pMenu, 16, IDM_RA_GETROMCHECKSUM, "View Game H&ash"); + } + + + TEST_METHOD(TestSyncHardcore) + { + AchievementRuntimeHarness runtime; + runtime.InitializeEventHandler(); + runtime.GetClient()->state.hardcore = 0; + + const rc_client_raintegration_menu_t* pMenu; + + pMenu = _Rcheevos_RAIntegrationGetMenu(); + AssertMenuItem(pMenu, 3, IDM_RA_HARDCORE_MODE, "&Hardcore Mode"); + + runtime.mockConfiguration.SetFeatureEnabled(ra::services::Feature::Hardcore, true); + SyncClientExternalRAIntegrationMenuItem(IDM_RA_HARDCORE_MODE); + SyncClientExternalHardcoreState(); + + runtime.AssertHardcoreChangedEventSeen(); + runtime.AssertMenuItemCheckedChangedEventSeen(IDM_RA_HARDCORE_MODE); + } + + TEST_METHOD(TestReadWriteMemory) + { + AchievementRuntimeHarness runtime; + ra::data::context::mocks::MockConsoleContext mockConsole(NES, L"NES"); + runtime.InitializeMemoryFunctions(); + + Assert::AreEqual({0}, runtime.GetMemoryByte(1)); + Assert::AreEqual({0}, runtime.mockEmulatorContext.ReadMemoryByte(1)); + + runtime.mockEmulatorContext.WriteMemoryByte(1, 3); + + Assert::AreEqual({3}, runtime.GetMemoryByte(1)); + Assert::AreEqual({3}, runtime.mockEmulatorContext.ReadMemoryByte(1)); + + runtime.mockEmulatorContext.WriteMemoryByte(2, 7); + Assert::AreEqual({7}, runtime.GetMemoryByte(2)); + Assert::AreEqual({7}, runtime.mockEmulatorContext.ReadMemoryByte(2)); + Assert::AreEqual({0x0703}, runtime.mockEmulatorContext.ReadMemory(1, MemSize::SixteenBit)); + } + + TEST_METHOD(TestPauseEvent) + { + AchievementRuntimeHarness runtime; + ra::ui::mocks::MockDesktop mockDesktop; // for InvokeOnUIThread + runtime.InitializeEventHandler(); + + rc_client_external_t pClient; + memset(&pClient, 0, sizeof(pClient)); + _Rcheevos_GetExternalClient(&pClient, 1); + + runtime.mockEmulatorContext.Pause(); + + runtime.AssertPauseEventSeen(); + } + + TEST_METHOD(TestResetEvent) + { + AchievementRuntimeHarness runtime; + ra::ui::mocks::MockDesktop mockDesktop; // for InvokeOnUIThread + runtime.InitializeClientEventHandler(); + + rc_client_external_t pClient; + memset(&pClient, 0, sizeof(pClient)); + _Rcheevos_GetExternalClient(&pClient, 1); + + runtime.mockEmulatorContext.Reset(); + + runtime.AssertResetEventSeen(); + } +}; + +} // namespace tests +} // namespace services +} // namespace ra diff --git a/tests/services/AchievementRuntime_Tests.cpp b/tests/services/AchievementRuntime_Tests.cpp index c64510d1..5744392c 100644 --- a/tests/services/AchievementRuntime_Tests.cpp +++ b/tests/services/AchievementRuntime_Tests.cpp @@ -25,15 +25,6 @@ #include #include -#ifdef RC_CLIENT_EXPORTS_EXTERNAL -#include -#include -#include "Exports.hh" -#include "RA_Resource.h" -extern "C" API int CCONV _Rcheevos_GetExternalClient(rc_client_external_t* pClientExternal, int nVersion); -extern "C" API const rc_client_raintegration_menu_t* CCONV _Rcheevos_RAIntegrationGetMenu(); -#endif - using namespace Microsoft::VisualStudio::CppUnitTestFramework; namespace ra { @@ -3257,168 +3248,6 @@ TEST_CLASS(AchievementRuntime_Tests) runtime.mockConfiguration.SetFeatureEnabled(ra::services::Feature::Hardcore, false); Assert::AreEqual(std::string("Developing Achievements"), runtime.GetRichPresenceOverride()); } - -#ifdef RC_CLIENT_EXPORTS_EXTERNAL - static void AssertV1Exports(rc_client_external_t& pClient) - { - Assert::IsNotNull((void*)pClient.destroy, L"destory not set"); - - Assert::IsNotNull((void*)pClient.enable_logging, L"enable_logging not set"); - Assert::IsNotNull((void*)pClient.set_event_handler, L"set_event_handler not set"); - Assert::IsNotNull((void*)pClient.set_read_memory, L"set_read_memory not set"); - Assert::IsNotNull((void*)pClient.set_get_time_millisecs, L"set_get_time_millisecs not set"); - Assert::IsNotNull((void*)pClient.set_host, L"set_host not set"); - - Assert::IsNotNull((void*)pClient.set_hardcore_enabled, L"set_hardcore_enabled not set"); - Assert::IsNotNull((void*)pClient.get_hardcore_enabled, L"get_hardcore_enabled not set"); - Assert::IsNotNull((void*)pClient.set_unofficial_enabled, L"set_unofficial_enabled not set"); - Assert::IsNotNull((void*)pClient.get_unofficial_enabled, L"get_unofficial_enabled not set"); - Assert::IsNotNull((void*)pClient.set_encore_mode_enabled, L"set_encore_mode_enabled not set"); - Assert::IsNotNull((void*)pClient.get_encore_mode_enabled, L"get_encore_mode_enabled not set"); - Assert::IsNotNull((void*)pClient.set_spectator_mode_enabled, L"set_spectator_mode_enabled not set"); - Assert::IsNotNull((void*)pClient.get_spectator_mode_enabled, L"get_spectator_mode_enabled not set"); - - Assert::IsNotNull((void*)pClient.abort_async, L"abort_async not set"); - - Assert::IsNotNull((void*)pClient.begin_login_with_password, L"begin_login_with_password not set"); - Assert::IsNotNull((void*)pClient.begin_login_with_token, L"begin_login_with_token not set"); - Assert::IsNotNull((void*)pClient.logout, L"logout not set"); - Assert::IsNotNull((void*)pClient.get_user_info, L"get_user_info not set"); - - Assert::IsNotNull((void*)pClient.begin_identify_and_load_game, L"begin_identify_and_load_game not set"); - Assert::IsNotNull((void*)pClient.begin_load_game, L"begin_load_game not set"); - Assert::IsNotNull((void*)pClient.get_game_info, L"get_game_info not set"); - Assert::IsNull((void*)pClient.begin_load_subset, L"begin_load_subset set"); - Assert::IsNotNull((void*)pClient.get_subset_info, L"get_subset_info not set"); - Assert::IsNotNull((void*)pClient.unload_game, L"unload_game not set"); - Assert::IsNotNull((void*)pClient.get_user_game_summary, L"get_user_game_summary not set"); - Assert::IsNotNull((void*)pClient.begin_change_media, L"begin_change_media not set"); - - Assert::IsNotNull((void*)pClient.create_achievement_list, L"create_achievement_list not set"); - Assert::IsNotNull((void*)pClient.has_achievements, L"has_achievements not set"); - Assert::IsNotNull((void*)pClient.get_achievement_info, L"get_achievement_info not set"); - - Assert::IsNotNull((void*)pClient.create_leaderboard_list, L"create_leaderboard_list not set"); - Assert::IsNotNull((void*)pClient.has_leaderboards, L"has_leaderboards not set"); - Assert::IsNotNull((void*)pClient.get_leaderboard_info, L"get_leaderboard_info not set"); - Assert::IsNotNull((void*)pClient.begin_fetch_leaderboard_entries, L"begin_fetch_leaderboard_entries not set"); - Assert::IsNotNull((void*)pClient.begin_fetch_leaderboard_entries_around_user, L"begin_fetch_leaderboard_entries_around_user not set"); - - Assert::IsNotNull((void*)pClient.get_rich_presence_message, L"get_rich_presence_message not set"); - Assert::IsNotNull((void*)pClient.has_rich_presence, L"has_rich_presence not set"); - - Assert::IsNotNull((void*)pClient.do_frame, L"do_frame not set"); - Assert::IsNotNull((void*)pClient.idle, L"idle not set"); - Assert::IsNotNull((void*)pClient.is_processing_required, L"is_processing_required not set"); - Assert::IsNotNull((void*)pClient.can_pause, L"can_pause not set"); - Assert::IsNotNull((void*)pClient.reset, L"reset not set"); - - Assert::IsNotNull((void*)pClient.progress_size, L"progress_size not set"); - Assert::IsNotNull((void*)pClient.serialize_progress, L"serialize_progress not set"); - Assert::IsNotNull((void*)pClient.deserialize_progress, L"deserialize_progress not set"); - } - - TEST_METHOD(TestGetExternalClientV1) - { - rc_client_external_t pClient; - memset(&pClient, 0, sizeof(pClient)); - - _Rcheevos_GetExternalClient(&pClient, 1); - - AssertV1Exports(pClient); - } - - TEST_METHOD(TestRAIntegrationGetMenu) - { - AchievementRuntimeHarness runtime; - runtime.mockUserContext.Logout(); - - const rc_client_raintegration_menu_t* pMenu; - - auto AssertMenuItem = [&pMenu](int nIndex, uint32_t nId, const char* label) { - const auto* pItem = &pMenu->items[nIndex]; - Assert::AreEqual(nId, pItem->id); - Assert::AreEqual(std::string(label), std::string(pItem->label)); - Assert::AreEqual({1}, pItem->enabled); - Assert::AreEqual({0}, pItem->checked); - }; - - auto AssertMenuItemChecked = [&pMenu](int nIndex, uint32_t nId, const char* label) { - const auto* pItem = &pMenu->items[nIndex]; - Assert::AreEqual(nId, pItem->id); - Assert::AreEqual(std::string(label), std::string(pItem->label)); - Assert::AreEqual({1}, pItem->enabled); - Assert::AreEqual({1}, pItem->checked); - }; - - auto AssertMenuSeparator = [&pMenu](int nIndex) { - const auto* pItem = &pMenu->items[nIndex]; - Assert::AreEqual(0U, pItem->id); - Assert::IsNull(pItem->label); - Assert::AreEqual({1}, pItem->enabled); - Assert::AreEqual({0}, pItem->checked); - }; - - pMenu = _Rcheevos_RAIntegrationGetMenu(); - Assert::AreEqual(11U, pMenu->num_items); - AssertMenuItem(0, IDM_RA_HARDCORE_MODE, "&Hardcore Mode"); - AssertMenuItem(1, IDM_RA_NON_HARDCORE_WARNING, "Non-Hardcore &Warning"); - AssertMenuSeparator(2); - AssertMenuItem(3, IDM_RA_FILES_OPENALL, "&Open All"); - AssertMenuItem(4, IDM_RA_FILES_ACHIEVEMENTS, "Assets Li&st"); - AssertMenuItem(5, IDM_RA_FILES_ACHIEVEMENTEDITOR, "Assets &Editor"); - AssertMenuItem(6, IDM_RA_FILES_MEMORYFINDER, "&Memory Inspector"); - AssertMenuItem(7, IDM_RA_FILES_MEMORYBOOKMARKS, "Memory &Bookmarks"); - AssertMenuItem(8, IDM_RA_FILES_POINTERFINDER, "Pointer &Finder"); - AssertMenuItem(9, IDM_RA_FILES_CODENOTES, "Code &Notes"); - AssertMenuItem(10, IDM_RA_PARSERICHPRESENCE, "Rich &Presence Monitor"); - - runtime.mockUserContext.Initialize("User", "ApiToken"); - - pMenu = _Rcheevos_RAIntegrationGetMenu(); - Assert::AreEqual(17U, pMenu->num_items); - AssertMenuItem(0, IDM_RA_OPENUSERPAGE, "Open my &User Page"); - AssertMenuItem(1, IDM_RA_OPENGAMEPAGE, "Open this &Game's Page"); - AssertMenuSeparator(2); - AssertMenuItem(3, IDM_RA_HARDCORE_MODE, "&Hardcore Mode"); - AssertMenuItem(4, IDM_RA_NON_HARDCORE_WARNING, "Non-Hardcore &Warning"); - AssertMenuSeparator(5); - AssertMenuItem(6, IDM_RA_FILES_OPENALL, "&Open All"); - AssertMenuItem(7, IDM_RA_FILES_ACHIEVEMENTS, "Assets Li&st"); - AssertMenuItem(8, IDM_RA_FILES_ACHIEVEMENTEDITOR, "Assets &Editor"); - AssertMenuItem(9, IDM_RA_FILES_MEMORYFINDER, "&Memory Inspector"); - AssertMenuItem(10, IDM_RA_FILES_MEMORYBOOKMARKS, "Memory &Bookmarks"); - AssertMenuItem(11, IDM_RA_FILES_POINTERFINDER, "Pointer &Finder"); - AssertMenuItem(12, IDM_RA_FILES_CODENOTES, "Code &Notes"); - AssertMenuItem(13, IDM_RA_PARSERICHPRESENCE, "Rich &Presence Monitor"); - AssertMenuSeparator(14); - AssertMenuItem(15, IDM_RA_REPORTBROKENACHIEVEMENTS, "&Report Achievement Problem"); - AssertMenuItem(16, IDM_RA_GETROMCHECKSUM, "View Game H&ash"); - - runtime.mockConfiguration.SetFeatureEnabled(ra::services::Feature::Hardcore, true); - runtime.mockConfiguration.SetFeatureEnabled(ra::services::Feature::NonHardcoreWarning, true); - - pMenu = _Rcheevos_RAIntegrationGetMenu(); - Assert::AreEqual(17U, pMenu->num_items); - AssertMenuItem(0, IDM_RA_OPENUSERPAGE, "Open my &User Page"); - AssertMenuItem(1, IDM_RA_OPENGAMEPAGE, "Open this &Game's Page"); - AssertMenuSeparator(2); - AssertMenuItemChecked(3, IDM_RA_HARDCORE_MODE, "&Hardcore Mode"); - AssertMenuItemChecked(4, IDM_RA_NON_HARDCORE_WARNING, "Non-Hardcore &Warning"); - AssertMenuSeparator(5); - AssertMenuItem(6, IDM_RA_FILES_OPENALL, "&Open All"); - AssertMenuItem(7, IDM_RA_FILES_ACHIEVEMENTS, "Assets Li&st"); - AssertMenuItem(8, IDM_RA_FILES_ACHIEVEMENTEDITOR, "Assets &Editor"); - AssertMenuItem(9, IDM_RA_FILES_MEMORYFINDER, "&Memory Inspector"); - AssertMenuItem(10, IDM_RA_FILES_MEMORYBOOKMARKS, "Memory &Bookmarks"); - AssertMenuItem(11, IDM_RA_FILES_POINTERFINDER, "Pointer &Finder"); - AssertMenuItem(12, IDM_RA_FILES_CODENOTES, "Code &Notes"); - AssertMenuItem(13, IDM_RA_PARSERICHPRESENCE, "Rich &Presence Monitor"); - AssertMenuSeparator(14); - AssertMenuItem(15, IDM_RA_REPORTBROKENACHIEVEMENTS, "&Report Achievement Problem"); - AssertMenuItem(16, IDM_RA_GETROMCHECKSUM, "View Game H&ash"); - } -#endif }; } // namespace tests