diff --git a/src/RA_Integration.vcxproj b/src/RA_Integration.vcxproj
index 611699a5..c1ae0ea0 100644
--- a/src/RA_Integration.vcxproj
+++ b/src/RA_Integration.vcxproj
@@ -84,7 +84,6 @@
-
Create
@@ -217,7 +216,6 @@
-
diff --git a/src/RA_Integration.vcxproj.filters b/src/RA_Integration.vcxproj.filters
index 55261723..9c83a149 100644
--- a/src/RA_Integration.vcxproj.filters
+++ b/src/RA_Integration.vcxproj.filters
@@ -339,9 +339,6 @@
UI\ViewModels
-
- Data\Models
-
UI\Win32
@@ -836,9 +833,6 @@
UI\ViewModels
-
- Data\Models
-
UI\Win32
diff --git a/src/data/context/GameContext.hh b/src/data/context/GameContext.hh
index 3d97f608..7511d0e3 100644
--- a/src/data/context/GameContext.hh
+++ b/src/data/context/GameContext.hh
@@ -2,6 +2,10 @@
#define RA_DATA_GAMECONTEXT_HH
#pragma once
+#include "context/IGameContext.hh"
+
+#include "services/ServiceLocator.hh"
+
#include "GameAssets.hh"
#include
@@ -15,10 +19,13 @@ namespace ra {
namespace data {
namespace context {
-class GameContext
+class GameContext : public ra::context::IGameContext
{
public:
- GSL_SUPPRESS_F6 GameContext() = default;
+ GSL_SUPPRESS_F6 GameContext()
+ : m_IGameContextOverride(this)
+ {
+ }
virtual ~GameContext() noexcept = default;
GameContext(const GameContext&) noexcept = delete;
GameContext& operator=(const GameContext&) noexcept = delete;
@@ -47,11 +54,6 @@ public:
///
bool IsGameLoading() const noexcept { return m_nLoadCount != 0; }
- ///
- /// Gets the unique identifier of the currently loaded game.
- ///
- unsigned int GameId() const noexcept { return m_nGameId; }
-
///
/// Gets the unique identifier of the currently loaded subset game.
///
@@ -135,27 +137,6 @@ public:
GameAssets& Assets() noexcept { return m_vAssets; }
const GameAssets& Assets() const noexcept { return m_vAssets; }
- class NotifyTarget
- {
- public:
- NotifyTarget() noexcept = default;
- virtual ~NotifyTarget() noexcept = default;
- NotifyTarget(const NotifyTarget&) noexcept = delete;
- NotifyTarget& operator=(const NotifyTarget&) noexcept = delete;
- NotifyTarget(NotifyTarget&&) noexcept = default;
- NotifyTarget& operator=(NotifyTarget&&) noexcept = default;
-
- virtual void OnBeforeActiveGameChanged() noexcept(false) {}
- virtual void OnActiveGameChanged() noexcept(false) {}
- virtual void OnBeginGameLoad() noexcept(false) {}
- virtual void OnEndGameLoad() noexcept(false) {}
- virtual void OnMemoryNoteChanged(ra::data::ByteAddress, const std::wstring&) noexcept(false) {}
- virtual void OnMemoryNoteMoved(ra::data::ByteAddress, ra::data::ByteAddress, const std::wstring&) noexcept(false) {}
- };
-
- void AddNotifyTarget(NotifyTarget& pTarget) noexcept { m_vNotifyTargets.Add(pTarget); }
- void RemoveNotifyTarget(NotifyTarget& pTarget) noexcept { m_vNotifyTargets.Remove(pTarget); }
-
void DoFrame();
enum SubsetType
@@ -194,6 +175,17 @@ public:
void InitializeSubsets(const rc_api_fetch_game_sets_response_t* game_data_response);
uint32_t GetGameId(uint32_t nSubsetId) const noexcept;
+ ra::data::models::MemoryNotesModel& MemoryNotes() override
+ {
+ auto* pNotes = m_vAssets.FindMemoryNotes();
+ return pNotes ? *pNotes : m_oDefaultNotes;
+ }
+ const ra::data::models::MemoryNotesModel& MemoryNotes() const override
+ {
+ auto* pNotes = m_vAssets.FindMemoryNotes();
+ return pNotes ? *pNotes : m_oDefaultNotes;
+ }
+
private:
void FinishLoadGame(int nResult, const char* sErrorMessage, bool bWasPaused);
void MigrateSubsetUserFiles();
@@ -210,7 +202,6 @@ protected:
void BeginLoad();
void EndLoad();
- unsigned int m_nGameId = 0;
unsigned int m_nActiveGameId = 0;
std::wstring m_sGameTitle;
std::string m_sGameHash;
@@ -219,14 +210,16 @@ protected:
std::vector m_vSubsets;
private:
- NotifyTargetSet m_vNotifyTargets;
-
GameAssets m_vAssets;
std::atomic m_nLoadCount = 0;
int m_nMasteryPopupId = 0;
std::mutex m_mLoadMutex;
+
+ // use the mock helper to register as both GameContext and IGameContext
+ ra::services::ServiceLocator::ServiceOverride m_IGameContextOverride;
+ ra::data::models::MemoryNotesModel m_oDefaultNotes;
};
} // namespace context
diff --git a/src/devkit/RADevKit.vcxproj b/src/devkit/RADevKit.vcxproj
index b9d19001..30cb6ecc 100644
--- a/src/devkit/RADevKit.vcxproj
+++ b/src/devkit/RADevKit.vcxproj
@@ -73,6 +73,7 @@
+
@@ -82,6 +83,7 @@
+
@@ -102,6 +104,7 @@
+
diff --git a/src/devkit/RADevKit.vcxproj.filters b/src/devkit/RADevKit.vcxproj.filters
index c6039c82..330a3926 100644
--- a/src/devkit/RADevKit.vcxproj.filters
+++ b/src/devkit/RADevKit.vcxproj.filters
@@ -179,6 +179,8 @@
+
+
@@ -248,5 +250,6 @@
data\models
+
\ No newline at end of file
diff --git a/src/devkit/context/IGameContext.hh b/src/devkit/context/IGameContext.hh
new file mode 100644
index 00000000..21d5464e
--- /dev/null
+++ b/src/devkit/context/IGameContext.hh
@@ -0,0 +1,67 @@
+#ifndef RA_CONTEXT_IGAMECONTEXT_HH
+#define RA_CONTEXT_IGAMECONTEXT_HH
+#pragma once
+
+#include "data/Memory.hh"
+#include "data/NotifyTargetSet.hh"
+
+#include
+
+namespace ra {
+
+namespace data {
+namespace models {
+ class MemoryNotesModel;
+} // namespace models
+} // namespace data
+
+namespace context {
+
+class IGameContext
+{
+public:
+ IGameContext() noexcept = default;
+ virtual ~IGameContext() noexcept = default;
+ IGameContext(const IGameContext&) noexcept = delete;
+ IGameContext& operator=(const IGameContext&) noexcept = delete;
+ IGameContext(IGameContext&&) noexcept = delete;
+ IGameContext& operator=(IGameContext&&) noexcept = delete;
+
+ ///
+ /// Gets the unique identifier of the currently loaded game.
+ ///
+ unsigned int GameId() const noexcept { return m_nGameId; }
+
+ class NotifyTarget
+ {
+ public:
+ NotifyTarget() noexcept = default;
+ virtual ~NotifyTarget() noexcept = default;
+ NotifyTarget(const NotifyTarget&) noexcept = delete;
+ NotifyTarget& operator=(const NotifyTarget&) noexcept = delete;
+ NotifyTarget(NotifyTarget&&) noexcept = default;
+ NotifyTarget& operator=(NotifyTarget&&) noexcept = default;
+
+ virtual void OnBeforeActiveGameChanged() noexcept(false) {}
+ virtual void OnActiveGameChanged() noexcept(false) {}
+ virtual void OnBeginGameLoad() noexcept(false) {}
+ virtual void OnEndGameLoad() noexcept(false) {}
+ virtual void OnMemoryNoteChanged(ra::data::ByteAddress, const std::wstring&) noexcept(false) {}
+ virtual void OnMemoryNoteMoved(ra::data::ByteAddress, ra::data::ByteAddress, const std::wstring&) noexcept(false) {}
+ };
+
+ void AddNotifyTarget(NotifyTarget& pTarget) noexcept { m_vNotifyTargets.Add(pTarget); }
+ void RemoveNotifyTarget(NotifyTarget& pTarget) noexcept { m_vNotifyTargets.Remove(pTarget); }
+
+ virtual ra::data::models::MemoryNotesModel& MemoryNotes() noexcept(false) = 0;
+ virtual const ra::data::models::MemoryNotesModel& MemoryNotes() const noexcept(false) = 0;
+
+protected:
+ unsigned int m_nGameId = 0;
+ ra::data::NotifyTargetSet m_vNotifyTargets;
+};
+
+} // namespace context
+} // namespace ra
+
+#endif // !RA_CONTEXT_IGAMECONTEXT_HH
diff --git a/src/data/models/TriggerValidation.cpp b/src/devkit/data/models/TriggerValidation.cpp
similarity index 94%
rename from src/data/models/TriggerValidation.cpp
rename to src/devkit/data/models/TriggerValidation.cpp
index 69724f47..786caabe 100644
--- a/src/data/models/TriggerValidation.cpp
+++ b/src/devkit/data/models/TriggerValidation.cpp
@@ -1,13 +1,15 @@
#include "TriggerValidation.hh"
#include "context/IConsoleContext.hh"
+#include "context/IEmulatorMemoryContext.hh"
+#include "context/IGameContext.hh"
+
+#include "data/models/MemoryNotesModel.hh"
#include "services/ServiceLocator.hh"
#include "util/Strings.hh"
-#include "data/context/GameContext.hh"
-
#include
#include
@@ -115,7 +117,7 @@ static bool ValidateMemoryNotesOperand(const rc_operand_t& pOperand, const ra::d
if (nStartAddress != nAddress)
{
sError.append(L" at ");
- sError.append(ra::util::String::Widen(pMemoryContext.FormatAddress(nStartAddress).substr(2)));
+ sError.append(pMemoryContext.FormatAddress(nStartAddress).substr(2));
}
return false;
@@ -166,14 +168,12 @@ static bool ValidateMemoryNotesCondSet(const rc_condset_t* pCondSet, const ra::d
static bool ValidateMemoryNotes(const rc_trigger_t* pTrigger, std::wstring& sError)
{
- if (!ra::services::ServiceLocator::Exists())
+ if (!ra::services::ServiceLocator::Exists())
return true;
- const auto* pNotes = ra::services::ServiceLocator::Get().Assets().FindMemoryNotes();
- if (!pNotes)
- return true;
+ const auto& pNotes = ra::services::ServiceLocator::Get().MemoryNotes();
- if (!ValidateMemoryNotesCondSet(pTrigger->requirement, *pNotes, sError))
+ if (!ValidateMemoryNotesCondSet(pTrigger->requirement, pNotes, sError))
{
if (pTrigger->alternative)
sError = L"Core " + sError;
@@ -185,7 +185,7 @@ static bool ValidateMemoryNotes(const rc_trigger_t* pTrigger, std::wstring& sErr
for (; pCondSet; pCondSet = pCondSet->next)
{
nIndex++;
- if (!ValidateMemoryNotesCondSet(pCondSet, *pNotes, sError))
+ if (!ValidateMemoryNotesCondSet(pCondSet, pNotes, sError))
{
sError = ra::util::String::Printf(L"Alt%u %s", nIndex, sError);
return false;
diff --git a/src/data/models/TriggerValidation.hh b/src/devkit/data/models/TriggerValidation.hh
similarity index 70%
rename from src/data/models/TriggerValidation.hh
rename to src/devkit/data/models/TriggerValidation.hh
index ba8a0c35..12d9a548 100644
--- a/src/data/models/TriggerValidation.hh
+++ b/src/devkit/data/models/TriggerValidation.hh
@@ -1,5 +1,5 @@
-#ifndef RA_DATA_TRIGGER_VALIDATION_H
-#define RA_DATA_TRIGGER_VALIDATION_H
+#ifndef RA_DATA_MODELS_TRIGGERVALIDATION_H
+#define RA_DATA_MODELS_TRIGGERVALIDATION_H
#pragma once
#include "data\models\AssetModelBase.hh"
@@ -18,4 +18,4 @@ public:
} // namespace data
} // namespace ra
-#endif RA_DATA_TRIGGER_VALIDATION_H
+#endif RA_DATA_MODELS_TRIGGERVALIDATION_H
diff --git a/tests/RA_Integration.Tests.vcxproj b/tests/RA_Integration.Tests.vcxproj
index 64cc0a99..2e1257a8 100644
--- a/tests/RA_Integration.Tests.vcxproj
+++ b/tests/RA_Integration.Tests.vcxproj
@@ -85,7 +85,6 @@
-
Create
@@ -159,7 +158,6 @@
-
diff --git a/tests/RA_Integration.Tests.vcxproj.filters b/tests/RA_Integration.Tests.vcxproj.filters
index 74656eab..1aedc3ed 100644
--- a/tests/RA_Integration.Tests.vcxproj.filters
+++ b/tests/RA_Integration.Tests.vcxproj.filters
@@ -351,12 +351,6 @@
Tests\UI\ViewModels
-
- Code
-
-
- Tests\Data\Models
-
Code
diff --git a/tests/data/context/GameAssets_Tests.cpp b/tests/data/context/GameAssets_Tests.cpp
index 52f48ce9..1fab5989 100644
--- a/tests/data/context/GameAssets_Tests.cpp
+++ b/tests/data/context/GameAssets_Tests.cpp
@@ -6,6 +6,7 @@
#include "data\models\LocalBadgesModel.hh"
#include "tests\RA_UnitTestHelpers.h"
+#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh"
#include "tests\devkit\context\mocks\MockRcClient.hh"
#include "tests\devkit\services\mocks\MockLocalStorage.hh"
#include "tests\devkit\testutil\AssetAsserts.hh"
@@ -30,6 +31,7 @@ TEST_CLASS(GameAssets_Tests)
class GameAssetsHarness : public GameAssets
{
public:
+ ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext;
ra::context::mocks::MockRcClient mockRcClient;
ra::data::context::mocks::MockGameContext mockGameContext;
ra::services::mocks::MockAchievementRuntime mockRuntime;
diff --git a/tests/data/models/AchievementModel_Tests.cpp b/tests/data/models/AchievementModel_Tests.cpp
index 7bc32167..19d3779a 100644
--- a/tests/data/models/AchievementModel_Tests.cpp
+++ b/tests/data/models/AchievementModel_Tests.cpp
@@ -8,7 +8,9 @@
#include "tests\RA_UnitTestHelpers.h"
#include "tests\data\DataAsserts.hh"
+#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh"
#include "tests\devkit\context\mocks\MockRcClient.hh"
+#include "tests\devkit\context\mocks\MockUserContext.hh"
#include "tests\devkit\services\mocks\MockClock.hh"
#include "tests\devkit\testutil\AssetAsserts.hh"
#include "tests\mocks\MockAchievementRuntime.hh"
@@ -34,7 +36,9 @@ TEST_CLASS(AchievementModel_Tests)
GSL_SUPPRESS_F6 mockRuntime.MockGame();
}
+ ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext;
ra::context::mocks::MockRcClient mockRcClient;
+ ra::context::mocks::MockUserContext mockUserContext;
ra::data::context::mocks::MockGameContext mockGameContext;
ra::services::impl::StringTextWriter textWriter;
ra::services::mocks::MockAchievementRuntime mockRuntime;
@@ -127,6 +131,7 @@ TEST_CLASS(AchievementModel_Tests)
{
AchievementModelHarness achievement;
achievement.mockGameContext.SetGameId(22);
+ achievement.mockGameContext.SetNote(0x1234, L"Note");
achievement.AddLocalBadgesModel();
achievement.SetBadge(L"12345.png");
achievement.CreateServerCheckpoint();
@@ -204,8 +209,12 @@ TEST_CLASS(AchievementModel_Tests)
achievement.CreateLocalCheckpoint();
std::string sTrigger;
- for (int i = 0; i < 65535/12 - 1; i++)
+ for (int i = 0; i < 65535 / 12 - 1; i++)
+ {
+ achievement.mockGameContext.SetNote(i, L"a");
sTrigger.append(ra::util::String::Printf("0xH00%04X=0_", i));
+ }
+ achievement.mockGameContext.SetNote(0xfff0, L"[32-bit] a");
sTrigger.append("0xX00FFF0=12345");
Assert::AreEqual({65535U}, sTrigger.length());
achievement.SetTrigger(sTrigger);
@@ -222,7 +231,6 @@ TEST_CLASS(AchievementModel_Tests)
TEST_METHOD(TestDeactivateHidesIndicator)
{
-
AchievementModelHarness achievement;
achievement.mockGameContext.SetGameId(22);
achievement.SetID(53U);
diff --git a/tests/data/models/LeaderboardModel_Tests.cpp b/tests/data/models/LeaderboardModel_Tests.cpp
index e27d229f..7aecf4d0 100644
--- a/tests/data/models/LeaderboardModel_Tests.cpp
+++ b/tests/data/models/LeaderboardModel_Tests.cpp
@@ -6,7 +6,9 @@
#include "tests\RA_UnitTestHelpers.h"
+#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh"
#include "tests\devkit\context\mocks\MockRcClient.hh"
+#include "tests\devkit\context\mocks\MockUserContext.hh"
#include "tests\devkit\testutil\AssetAsserts.hh"
#include "tests\devkit\testutil\ValueAsserts.hh"
#include "tests\mocks\MockAchievementRuntime.hh"
@@ -27,7 +29,9 @@ TEST_CLASS(LeaderboardModel_Tests)
class LeaderboardModelHarness : public LeaderboardModel
{
public:
+ ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext;
ra::context::mocks::MockRcClient mockRcClient;
+ ra::context::mocks::MockUserContext mockUserContext;
ra::data::context::mocks::MockGameContext mockGameContext;
ra::services::impl::StringTextWriter textWriter;
ra::services::mocks::MockAchievementRuntime mockRuntime;
@@ -205,6 +209,8 @@ TEST_CLASS(LeaderboardModel_Tests)
TEST_METHOD(TestValidateMissingField)
{
LeaderboardModelHarness leaderboard;
+ leaderboard.mockGameContext.SetNote(0x1234, L"a");
+ leaderboard.mockGameContext.SetNote(0x2345, L"a");
leaderboard.SetID(1U);
leaderboard.SetName(L"Title");
leaderboard.SetDescription(L"Desc");
@@ -236,6 +242,7 @@ TEST_CLASS(LeaderboardModel_Tests)
TEST_METHOD(TestValidateInvalidField)
{
LeaderboardModelHarness leaderboard;
+ leaderboard.mockGameContext.SetNote(0x1234, L"a");
leaderboard.SetID(1U);
leaderboard.SetName(L"Title");
leaderboard.SetDescription(L"Desc");
diff --git a/tests/devkit/RADevKit.Tests.vcxproj b/tests/devkit/RADevKit.Tests.vcxproj
index 8a043a86..ade41895 100644
--- a/tests/devkit/RADevKit.Tests.vcxproj
+++ b/tests/devkit/RADevKit.Tests.vcxproj
@@ -72,9 +72,11 @@
+
+
diff --git a/tests/devkit/RADevKit.Tests.vcxproj.filters b/tests/devkit/RADevKit.Tests.vcxproj.filters
index 0085c27a..4c697283 100644
--- a/tests/devkit/RADevKit.Tests.vcxproj.filters
+++ b/tests/devkit/RADevKit.Tests.vcxproj.filters
@@ -62,6 +62,7 @@
data\models
+
@@ -151,5 +152,6 @@
testutil
+
\ No newline at end of file
diff --git a/tests/devkit/context/mocks/MockGameContext.hh b/tests/devkit/context/mocks/MockGameContext.hh
new file mode 100644
index 00000000..48e359f1
--- /dev/null
+++ b/tests/devkit/context/mocks/MockGameContext.hh
@@ -0,0 +1,98 @@
+#ifndef RA_CONTEXT_MOCK_GAMECONTEXT_HH
+#define RA_CONTEXT_MOCK_GAMECONTEXT_HH
+#pragma once
+
+#include "context/IGameContext.hh"
+
+#include "data/models/MemoryNotesModel.hh"
+
+#include "services/ServiceLocator.hh"
+
+namespace ra {
+namespace context {
+namespace mocks {
+
+class MockGameContext : public IGameContext
+{
+public:
+ GSL_SUPPRESS_F6 MockGameContext() noexcept
+ : m_Override(this)
+ {
+ }
+
+ void SetId(unsigned int nId) noexcept { m_nGameId = nId; }
+
+ ra::data::models::MemoryNotesModel& MemoryNotes() noexcept override { return m_oMemoryNotes; }
+ const ra::data::models::MemoryNotesModel& MemoryNotes() const noexcept override { return m_oMemoryNotes; }
+
+ bool SetNote(ra::data::ByteAddress nAddress, const std::wstring& sNote)
+ {
+ if (m_oMemoryNotes.NoteCount() == 0)
+ {
+ m_oMemoryNotes.Initialize(
+ [this](ra::data::ByteAddress nAddress, const std::wstring& sNote) {
+ // a note with pointer notation is expected to keep track of where each
+ // pointed-at note exists. this normally occurs in DoFrame, but for
+ // the unit tests, force the update immediately after the note is updated
+ GSL_SUPPRESS_TYPE3
+ auto* pNote = const_cast(m_oMemoryNotes.FindMemoryNoteModel(nAddress, false));
+ if (pNote && pNote->IsPointer())
+ {
+ const auto& pMemoryContext = ra::services::ServiceLocator::Get();
+ pNote->UpdateRawPointerValue(nAddress, pMemoryContext, nullptr);
+ }
+
+ OnMemoryNoteChanged(nAddress, sNote);
+ },
+ [this](ra::data::ByteAddress nOldAddress, ra::data::ByteAddress nNewAddress, const std::wstring& sNote) {
+ OnMemoryNoteMoved(nOldAddress, nNewAddress, sNote);
+ });
+ }
+
+ m_oMemoryNotes.SetServerNote(nAddress, sNote);
+ return true;
+ }
+
+private:
+ void OnMemoryNoteChanged(ra::data::ByteAddress nAddress, const std::wstring& sNewNote)
+ {
+ if (m_vNotifyTargets.LockIfNotEmpty())
+ {
+ for (auto& target : m_vNotifyTargets.Targets())
+ target.OnMemoryNoteChanged(nAddress, sNewNote);
+
+ m_vNotifyTargets.Unlock();
+ }
+ }
+
+ void OnMemoryNoteMoved(ra::data::ByteAddress nOldAddress, ra::data::ByteAddress nNewAddress, const std::wstring& sNote)
+ {
+ if (m_vNotifyTargets.LockIfNotEmpty())
+ {
+ for (auto& target : m_vNotifyTargets.Targets())
+ target.OnMemoryNoteMoved(nOldAddress, nNewAddress, sNote);
+
+ m_vNotifyTargets.Unlock();
+ }
+ }
+
+ class MockMemoryNotesModel : public ra::data::models::MemoryNotesModel
+ {
+ public:
+ void Initialize(MemoryNoteChangedFunction fMemoryNoteChanged, MemoryNoteMovedFunction fMemoryNoteMoved)
+ {
+ m_fMemoryNoteChanged = fMemoryNoteChanged;
+ m_fMemoryNoteMoved = fMemoryNoteMoved;
+ }
+ };
+
+ MockMemoryNotesModel m_oMemoryNotes;
+
+ ra::services::ServiceLocator::ServiceOverride m_Override;
+};
+
+} // namespace mocks
+} // namespace context
+} // namespace ra
+
+#endif // !RA_CONTEXT_MOCK_CONSOLECONTEXT_HH
diff --git a/tests/data/models/TriggerValidation_Tests.cpp b/tests/devkit/data/models/TriggerValidation_Tests.cpp
similarity index 96%
rename from tests/data/models/TriggerValidation_Tests.cpp
rename to tests/devkit/data/models/TriggerValidation_Tests.cpp
index 77982925..b8465425 100644
--- a/tests/data/models/TriggerValidation_Tests.cpp
+++ b/tests/devkit/data/models/TriggerValidation_Tests.cpp
@@ -1,13 +1,12 @@
-#include "CppUnitTest.h"
-#include "data\models\TriggerValidation.hh"
+#include "data/models/TriggerValidation.hh"
-#include "tests\devkit\context\mocks\MockConsoleContext.hh"
-#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh"
-#include "tests\devkit\context\mocks\MockUserContext.hh"
-#include "tests\mocks\MockGameContext.hh"
+#include "tests/devkit/context/mocks/MockConsoleContext.hh"
+#include "tests/devkit/context/mocks/MockEmulatorMemoryContext.hh"
+#include "tests/devkit/context/mocks/MockGameContext.hh"
+#include "tests/devkit/context/mocks/MockUserContext.hh"
+#include "tests/devkit/testutil/AssetAsserts.hh"
-using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace ra {
namespace data {
@@ -195,7 +194,7 @@ TEST_CLASS(TriggerValidation_Tests)
TEST_METHOD(TestMemoryNoteSizeComparisons)
{
ra::context::mocks::MockUserContext mockUserContext;
- ra::data::context::mocks::MockGameContext mockGameContext;
+ ra::context::mocks::MockGameContext mockGameContext;
ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext;
mockGameContext.SetNote(0x0008, L"[8-bit] Byte address");
mockGameContext.SetNote(0x0010, L"[16-bit] Word address");
diff --git a/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp b/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp
index 68378974..ff0d4fc2 100644
--- a/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp
+++ b/tests/ui/viewmodels/AssetEditorViewModel_Tests.cpp
@@ -13,6 +13,7 @@
#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh"
#include "tests\devkit\context\mocks\MockRcClient.hh"
+#include "tests\devkit\context\mocks\MockUserContext.hh"
#include "tests\devkit\services\mocks\MockClock.hh"
#include "tests\devkit\services\mocks\MockFileSystem.hh"
#include "tests\devkit\services\mocks\MockThreadPool.hh"
@@ -71,6 +72,7 @@ TEST_CLASS(AssetEditorViewModel_Tests)
ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext;
ra::context::mocks::MockRcClient mockRcClient;
+ ra::context::mocks::MockUserContext mockUserContext;
ra::services::mocks::MockAchievementRuntime mockRuntime;
ra::services::mocks::MockClock mockClock;
ra::services::mocks::MockConfiguration mockConfiguration;
@@ -526,6 +528,7 @@ TEST_CLASS(AssetEditorViewModel_Tests)
TEST_METHOD(TestLoadAchievementValidationError)
{
AssetEditorViewModelHarness editor;
+ editor.mockGameContext.SetNote(0x1234, L"a");
AchievementModel achievement;
achievement.SetName(L"Test Achievement");
achievement.SetID(1234U);
@@ -534,7 +537,7 @@ TEST_CLASS(AssetEditorViewModel_Tests)
achievement.SetCategory(AssetCategory::Unofficial);
achievement.SetPoints(10);
achievement.SetBadge(L"58329");
- achievement.SetTrigger("M:0x1234=10");
+ achievement.SetTrigger("M:0xH1234=10");
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
@@ -565,6 +568,7 @@ TEST_CLASS(AssetEditorViewModel_Tests)
TEST_METHOD(TestLoadAchievementValidationErrorCancel)
{
AssetEditorViewModelHarness editor;
+ editor.mockGameContext.SetNote(0x1234, L"a");
AchievementModel achievement;
achievement.SetName(L"Test Achievement");
achievement.SetID(1234U);
@@ -573,7 +577,7 @@ TEST_CLASS(AssetEditorViewModel_Tests)
achievement.SetCategory(AssetCategory::Unofficial);
achievement.SetPoints(10);
achievement.SetBadge(L"58329");
- achievement.SetTrigger("M:0x1234=10");
+ achievement.SetTrigger("M:0xH1234=10");
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
@@ -606,6 +610,7 @@ TEST_CLASS(AssetEditorViewModel_Tests)
TEST_METHOD(TestLoadAchievementValidationErrorDeleted)
{
AssetEditorViewModelHarness editor;
+ editor.mockGameContext.SetNote(0x1234, L"a");
AchievementModel achievement;
achievement.SetName(L"Test Achievement");
achievement.SetID(1234U);
@@ -614,7 +619,7 @@ TEST_CLASS(AssetEditorViewModel_Tests)
achievement.SetCategory(AssetCategory::Unofficial);
achievement.SetPoints(10);
achievement.SetBadge(L"58329");
- achievement.SetTrigger("M:0x1234=10");
+ achievement.SetTrigger("M:0xH1234=10");
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
@@ -640,6 +645,7 @@ TEST_CLASS(AssetEditorViewModel_Tests)
TEST_METHOD(TestLoadAchievementForcedValidationError)
{
AssetEditorViewModelHarness editor;
+ editor.mockGameContext.SetNote(0x1234, L"a");
AchievementModel achievement;
achievement.SetName(L"Test Achievement");
achievement.SetID(1234U);
@@ -648,7 +654,7 @@ TEST_CLASS(AssetEditorViewModel_Tests)
achievement.SetCategory(AssetCategory::Unofficial);
achievement.SetPoints(10);
achievement.SetBadge(L"58329");
- achievement.SetTrigger("M:0x1234=10");
+ achievement.SetTrigger("M:0xH1234=10");
achievement.CreateServerCheckpoint();
achievement.CreateLocalCheckpoint();
@@ -672,6 +678,8 @@ TEST_CLASS(AssetEditorViewModel_Tests)
TEST_METHOD(TestLoadLeaderboard)
{
AssetEditorViewModelHarness editor;
+ editor.mockGameContext.SetNote(0x1234, L"a");
+ editor.mockGameContext.SetNote(0x2345, L"a");
LeaderboardModel leaderboard;
leaderboard.SetName(L"Test Leaderboard");
leaderboard.SetID(1234U);
diff --git a/tests/ui/viewmodels/AssetListViewModel_Tests.cpp b/tests/ui/viewmodels/AssetListViewModel_Tests.cpp
index ff5622d8..e4a45f1e 100644
--- a/tests/ui/viewmodels/AssetListViewModel_Tests.cpp
+++ b/tests/ui/viewmodels/AssetListViewModel_Tests.cpp
@@ -2606,11 +2606,12 @@ TEST_CLASS(AssetListViewModel_Tests)
TEST_METHOD(TestSaveSelectedValidationWarning)
{
AssetListViewModelHarness vmAssetList;
+ vmAssetList.mockGameContext.SetNote(0x1234, L"[16-bit] a");
vmAssetList.MockGameId(22U);
- vmAssetList.AddAchievement(AssetCategory::Core, 5, L"Test1", L"Desc1", L"12345", "0xH1234=1");
+ vmAssetList.AddAchievement(AssetCategory::Core, 5, L"Test1", L"Desc1", L"12345", "0x1234=1");
vmAssetList.AddAchievement(AssetCategory::Core, 7, L"Test2", L"Desc2", L"11111", "0xH1111=1");
- auto* pItem = dynamic_cast(vmAssetList.mockGameContext.Assets().GetItemAt(0));
+ auto* pItem = vmAssetList.mockGameContext.Assets().FindAchievement(2);
Expects(pItem != nullptr);
pItem->SetName(L"Test1b");
pItem->SetTrigger("A:0x1234");
@@ -2624,7 +2625,7 @@ TEST_CLASS(AssetListViewModel_Tests)
// invalid item can still be saved
const auto& sText = vmAssetList.GetUserFile(L"22");
- AssertContains(sText, "1:\"A:0x1234\":Test1b:Desc1:::::5:::::12345");
+ AssertContains(sText, "2:\"A:0x1234\":Test1b:Desc1:::::5:::::12345");
Assert::AreEqual(std::wstring(L"Condition 1: AddSource condition type expects another condition to follow"), pItem->GetValidationError());
@@ -2633,7 +2634,7 @@ TEST_CLASS(AssetListViewModel_Tests)
// invalid item can still be saved
const auto& sText2 = vmAssetList.GetUserFile(L"22");
- AssertContains(sText2, "1:\"A:0x1234\":Test1c:Desc1:::::5:::::12345");
+ AssertContains(sText2, "2:\"A:0x1234\":Test1c:Desc1:::::5:::::12345");
}
TEST_METHOD(TestSaveSelectedPublishCoreModified)