Files
RAIntegration/tests/ui/viewmodels/MemorySearchViewModel_Tests.cpp

2466 lines
114 KiB
C++

#include "CppUnitTest.h"
#include "ui\viewmodels\FileDialogViewModel.hh"
#include "ui\viewmodels\MemorySearchViewModel.hh"
#include "tests\RA_UnitTestHelpers.h"
#include "tests\ui\UIAsserts.hh"
#include "tests\devkit\context\mocks\MockConsoleContext.hh"
#include "tests\devkit\context\mocks\MockEmulatorMemoryContext.hh"
#include "tests\devkit\context\mocks\MockUserContext.hh"
#include "tests\devkit\services\mocks\MockClock.hh"
#include "tests\devkit\services\mocks\MockConfiguration.hh"
#include "tests\devkit\services\mocks\MockFileSystem.hh"
#include "tests\devkit\testutil\MemoryAsserts.hh"
#include "tests\mocks\MockDesktop.hh"
#include "tests\mocks\MockGameContext.hh"
#include "tests\mocks\MockWindowManager.hh"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace Microsoft {
namespace VisualStudio {
namespace CppUnitTestFramework {
template<>
std::wstring ToString<ra::services::SearchType>(
const ra::services::SearchType& nSearchType)
{
switch (nSearchType)
{
case ra::services::SearchType::FourBit:
return L"FourBit";
case ra::services::SearchType::EightBit:
return L"EightBit";
case ra::services::SearchType::SixteenBit:
return L"SixteenBit";
case ra::services::SearchType::ThirtyTwoBit:
return L"ThirtyTwoBit";
case ra::services::SearchType::SixteenBitAligned:
return L"SixteenBitAligned";
case ra::services::SearchType::ThirtyTwoBitAligned:
return L"ThirtyTwoBitAligned";
case ra::services::SearchType::AsciiText:
return L"AsciiText";
default:
return std::to_wstring(static_cast<int>(nSearchType));
}
}
template<>
std::wstring ToString<ra::services::SearchFilterType>(
const ra::services::SearchFilterType& nValueType)
{
switch (nValueType)
{
case ra::services::SearchFilterType::Constant:
return L"Constant";
case ra::services::SearchFilterType::LastKnownValue:
return L"LastKnownValue";
case ra::services::SearchFilterType::LastKnownValuePlus:
return L"LastKnownValuePlus";
case ra::services::SearchFilterType::LastKnownValueMinus:
return L"LastKnownValueMinus";
default:
return std::to_wstring(static_cast<int>(nValueType));
}
}
} // namespace CppUnitTestFramework
} // namespace VisualStudio
} // namespace Microsoft
namespace ra {
namespace ui {
namespace viewmodels {
namespace tests {
TEST_CLASS(MemorySearchViewModel_Tests)
{
private:
class MemorySearchViewModelHarness : public MemorySearchViewModel
{
public:
GSL_SUPPRESS_F6 MemorySearchViewModelHarness() : MemorySearchViewModel()
{
InitializeNotifyTargets();
mockGameContext.InitializeNotes();
}
ra::context::mocks::MockConsoleContext mockConsoleContext;
ra::context::mocks::MockEmulatorMemoryContext mockEmulatorMemoryContext;
ra::context::mocks::MockUserContext mockUserContext;
ra::data::context::mocks::MockGameContext mockGameContext;
ra::services::mocks::MockClock mockClock;
ra::services::mocks::MockConfiguration mockConfiguration;
ra::services::mocks::MockFileSystem mockFileSystem;
ra::ui::mocks::MockDesktop mockDesktop;
ra::ui::viewmodels::mocks::MockWindowManager mockWindowManager;
std::array<unsigned char, 32> memory{};
void InitializeMemory()
{
for (size_t i = 0; i < memory.size(); ++i)
memory.at(i) = gsl::narrow_cast<unsigned char>(i);
mockEmulatorMemoryContext.MockMemory(memory);
}
void InitializeAsciiMemory()
{
std::array<unsigned char, 36> text {
'S', 'h', 'e', ' ', 's', 'e', 'l', 'l', 's', ' ', 's', 'e', 'a', 's', 'h', 'e',
'l', 'l', 's', ' ', 'b', 'y', ' ', 't', 'h', 'e', ' ', 's', 'e', 'a', 's', 'h',
'o', 'r', 'e', '.'
};
for (size_t i = 0; i < memory.size(); ++i)
memory.at(i) = text.at(i);
mockEmulatorMemoryContext.MockMemory(memory);
}
bool CanBeginNewSearch() const { return GetValue(CanBeginNewSearchProperty); }
bool CanFilter() const { return GetValue(CanFilterProperty); }
bool CanContinuousFilter() const { return GetValue(CanContinuousFilterProperty); }
bool CanEditFilterValue() const { return GetValue(CanEditFilterValueProperty); }
bool CanGoToPreviousPage() const { return GetValue(CanGoToPreviousPageProperty); }
bool CanGoToNextPage() const { return GetValue(CanGoToNextPageProperty); }
void SetScrollOffset(int nValue) { SetValue(ScrollOffsetProperty, nValue); }
const std::wstring& ContinuousFilterLabel() const { return GetValue(ContinuousFilterLabelProperty); }
};
void AssertRow(MemorySearchViewModelHarness& search, gsl::index nRow, ra::data::ByteAddress nAddress,
const wchar_t* sAddress, const wchar_t* sCurrentValue)
{
auto* pRow = search.Results().GetItemAt(nRow);
Assert::IsNotNull(pRow);
Ensures(pRow != nullptr);
Assert::AreEqual(std::wstring(sAddress), pRow->GetAddress());
Assert::AreEqual(std::wstring(sCurrentValue), pRow->GetCurrentValue());
Assert::AreEqual(nAddress, pRow->nAddress);
}
public:
TEST_METHOD(TestInitialValues)
{
MemorySearchViewModelHarness search;
Assert::AreEqual({ 0U }, search.Results().Count());
Assert::AreEqual(ra::data::Memory::Size::Bit0, search.ResultMemSize());
Assert::AreEqual({ 0U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L""), search.GetFilterRange());
Assert::AreEqual(std::wstring(L""), search.GetFilterValue());
Assert::AreEqual({ 14U }, search.SearchTypes().Count());
Assert::AreEqual((int)ra::services::SearchType::FourBit, search.SearchTypes().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"4-bit"), search.SearchTypes().GetItemAt(0)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::EightBit, search.SearchTypes().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"8-bit"), search.SearchTypes().GetItemAt(1)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::SixteenBit, search.SearchTypes().GetItemAt(2)->GetId());
Assert::AreEqual(std::wstring(L"16-bit"), search.SearchTypes().GetItemAt(2)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::ThirtyTwoBit, search.SearchTypes().GetItemAt(3)->GetId());
Assert::AreEqual(std::wstring(L"32-bit"), search.SearchTypes().GetItemAt(3)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::SixteenBitBigEndian, search.SearchTypes().GetItemAt(4)->GetId());
Assert::AreEqual(std::wstring(L"16-bit BE"), search.SearchTypes().GetItemAt(4)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::ThirtyTwoBitBigEndian, search.SearchTypes().GetItemAt(5)->GetId());
Assert::AreEqual(std::wstring(L"32-bit BE"), search.SearchTypes().GetItemAt(5)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::BitCount, search.SearchTypes().GetItemAt(6)->GetId());
Assert::AreEqual(std::wstring(L"BitCount"), search.SearchTypes().GetItemAt(6)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::Float, search.SearchTypes().GetItemAt(7)->GetId());
Assert::AreEqual(std::wstring(L"Float"), search.SearchTypes().GetItemAt(7)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::FloatBigEndian, search.SearchTypes().GetItemAt(8)->GetId());
Assert::AreEqual(std::wstring(L"Float BE"), search.SearchTypes().GetItemAt(8)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::Double32, search.SearchTypes().GetItemAt(9)->GetId());
Assert::AreEqual(std::wstring(L"Double32"), search.SearchTypes().GetItemAt(9)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::Double32BigEndian, search.SearchTypes().GetItemAt(10)->GetId());
Assert::AreEqual(std::wstring(L"Double32 BE"), search.SearchTypes().GetItemAt(10)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::MBF32, search.SearchTypes().GetItemAt(11)->GetId());
Assert::AreEqual(std::wstring(L"MBF32"), search.SearchTypes().GetItemAt(11)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::MBF32LE, search.SearchTypes().GetItemAt(12)->GetId());
Assert::AreEqual(std::wstring(L"MBF32 LE"), search.SearchTypes().GetItemAt(12)->GetLabel());
Assert::AreEqual((int)ra::services::SearchType::AsciiText, search.SearchTypes().GetItemAt(13)->GetId());
Assert::AreEqual(std::wstring(L"ASCII Text"), search.SearchTypes().GetItemAt(13)->GetLabel());
Assert::AreEqual(ra::services::SearchType::EightBit, search.GetSearchType());
Assert::AreEqual(true, search.IsAligned());
Assert::AreEqual(false, search.CanAlign());
Assert::AreEqual({ 6U }, search.ComparisonTypes().Count());
Assert::AreEqual((int)ComparisonType::Equals, search.ComparisonTypes().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"="), search.ComparisonTypes().GetItemAt(0)->GetLabel());
Assert::AreEqual((int)ComparisonType::LessThan, search.ComparisonTypes().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"<"), search.ComparisonTypes().GetItemAt(1)->GetLabel());
Assert::AreEqual((int)ComparisonType::LessThanOrEqual, search.ComparisonTypes().GetItemAt(2)->GetId());
Assert::AreEqual(std::wstring(L"<="), search.ComparisonTypes().GetItemAt(2)->GetLabel());
Assert::AreEqual((int)ComparisonType::GreaterThan, search.ComparisonTypes().GetItemAt(3)->GetId());
Assert::AreEqual(std::wstring(L">"), search.ComparisonTypes().GetItemAt(3)->GetLabel());
Assert::AreEqual((int)ComparisonType::GreaterThanOrEqual, search.ComparisonTypes().GetItemAt(4)->GetId());
Assert::AreEqual(std::wstring(L">="), search.ComparisonTypes().GetItemAt(4)->GetLabel());
Assert::AreEqual((int)ComparisonType::NotEqualTo, search.ComparisonTypes().GetItemAt(5)->GetId());
Assert::AreEqual(std::wstring(L"!="), search.ComparisonTypes().GetItemAt(5)->GetLabel());
Assert::AreEqual(ComparisonType::Equals, search.GetComparisonType());
Assert::AreEqual({ 5U }, search.ValueTypes().Count());
Assert::AreEqual((int)ra::services::SearchFilterType::Constant, search.ValueTypes().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"Constant"), search.ValueTypes().GetItemAt(0)->GetLabel());
Assert::AreEqual((int)ra::services::SearchFilterType::LastKnownValue, search.ValueTypes().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"Last Value"), search.ValueTypes().GetItemAt(1)->GetLabel());
Assert::AreEqual((int)ra::services::SearchFilterType::LastKnownValuePlus, search.ValueTypes().GetItemAt(2)->GetId());
Assert::AreEqual(std::wstring(L"Last Value Plus"), search.ValueTypes().GetItemAt(2)->GetLabel());
Assert::AreEqual((int)ra::services::SearchFilterType::LastKnownValueMinus, search.ValueTypes().GetItemAt(3)->GetId());
Assert::AreEqual(std::wstring(L"Last Value Minus"), search.ValueTypes().GetItemAt(3)->GetLabel());
Assert::AreEqual((int)ra::services::SearchFilterType::InitialValue, search.ValueTypes().GetItemAt(4)->GetId());
Assert::AreEqual(std::wstring(L"Initial Value"), search.ValueTypes().GetItemAt(4)->GetLabel());
Assert::AreEqual(ra::services::SearchFilterType::LastKnownValue, search.GetValueType());
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"0/0"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L""), search.GetFilterSummary());
Assert::IsFalse(search.CanBeginNewSearch());
Assert::IsFalse(search.CanFilter());
Assert::IsFalse(search.CanEditFilterValue());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
Assert::IsFalse(search.HasSelection());
}
TEST_METHOD(TestBeginNewSearchEightBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
Assert::IsFalse(search.CanFilter());
search.BeginNewSearch();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 0 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 32U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"New 8-bit Search"), search.GetFilterSummary());
Assert::IsTrue(search.CanFilter());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
}
TEST_METHOD(TestBeginNewSearchSixteenBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::SixteenBit);
search.SetAligned(false);
Assert::IsFalse(search.CanFilter());
search.BeginNewSearch();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 0 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 31U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::SixteenBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"New 16-bit Search"), search.GetFilterSummary());
Assert::IsTrue(search.CanFilter());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
}
TEST_METHOD(TestBeginNewSearchFourBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::FourBit);
Assert::IsFalse(search.CanFilter());
search.BeginNewSearch();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 0 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 64U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::NibbleLower, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"New 4-bit Search"), search.GetFilterSummary());
Assert::IsTrue(search.CanFilter());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
}
TEST_METHOD(TestBeginNewSearchFloat)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::Float);
Assert::IsFalse(search.CanFilter());
search.BeginNewSearch();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 0 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 8U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::Float, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"New Float (aligned) Search"), search.GetFilterSummary());
Assert::IsTrue(search.CanFilter());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
}
TEST_METHOD(TestApplyFilterEightBitConstantDecimal)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"12");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= 12"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x0c");
}
TEST_METHOD(TestApplyFilterEightBitConstantHex)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"0x0C");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= 0x0C"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x0c");
}
TEST_METHOD(TestApplyFilterEightBitConstantInvalid)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::Constant);
Assert::IsTrue(search.CanEditFilterValue());
search.SetFilterValue(L"banana");
bool bSawDialog = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>([&bSawDialog](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox)
{
bSawDialog = true;
Assert::AreEqual(std::wstring(L"Invalid filter value"), vmMessageBox.GetMessage());
return ra::ui::DialogResult::OK;
});
search.ApplyFilter();
Assert::IsTrue(bSawDialog);
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 32U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"32"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"New 8-bit Search"), search.GetFilterSummary());
Assert::AreEqual({ 0U }, search.Results().Count());
}
TEST_METHOD(TestApplyFilterEightBitConstantNoValue)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::Constant);
Assert::IsTrue(search.CanEditFilterValue());
search.SetFilterValue(L"");
bool bSawDialog = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>([&bSawDialog](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox)
{
bSawDialog = true;
Assert::AreEqual(std::wstring(L"Invalid filter value"), vmMessageBox.GetMessage());
return ra::ui::DialogResult::OK;
});
search.ApplyFilter();
Assert::IsTrue(bSawDialog);
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 32U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"32"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"New 8-bit Search"), search.GetFilterSummary());
Assert::AreEqual({ 0U }, search.Results().Count());
}
TEST_METHOD(TestApplyFilterEightBitLastKnown)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
Assert::IsFalse(search.CanEditFilterValue());
search.memory.at(12) = 9;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x09");
search.memory.at(12) = 7;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"2/2"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x07");
}
TEST_METHOD(TestApplyFilterEightBitLastKnownNoChange)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.memory.at(12) = 9;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x09");
// if results don't change and filter does change, generate a new page
search.SetComparisonType(ComparisonType::Equals);
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"2/2"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x09");
}
TEST_METHOD(TestApplyFilterEightBitLastKnownPlus)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValuePlus);
Assert::IsTrue(search.CanEditFilterValue());
search.SetFilterValue(L"2");
search.memory.at(12) = 14;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= Last +2"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x0e");
}
TEST_METHOD(TestApplyFilterEightBitLastKnownMinus)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValueMinus);
Assert::IsTrue(search.CanEditFilterValue());
search.SetFilterValue(L"2");
search.memory.at(12) = 10;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= Last -2"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x0a");
}
TEST_METHOD(TestApplyFilterEightBitCompareToInitialValue)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::GreaterThan);
search.SetValueType(ra::services::SearchFilterType::InitialValue);
Assert::IsFalse(search.CanEditFilterValue());
search.memory.at(10) = 20;
search.memory.at(20) = 30;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 2U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"2"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"> Initial"), search.GetFilterSummary());
Assert::AreEqual({ 2U }, search.Results().Count());
AssertRow(search, 0, 10U, L"0x000a", L"0x14");
AssertRow(search, 1, 20U, L"0x0014", L"0x1e");
// 15 is still greater than initial value (10), but less than current value (20).
search.memory.at(10) = 15;
search.ApplyFilter();
Assert::AreEqual({ 2U }, search.Results().Count());
AssertRow(search, 0, 10U, L"0x000a", L"0x0f");
AssertRow(search, 1, 20U, L"0x0014", L"0x1e");
// 5 is less than initial value and should be filtered out.
search.memory.at(10) = 5;
search.ApplyFilter();
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 20U, L"0x0014", L"0x1e");
}
TEST_METHOD(TestApplyFilterEightBitLastKnownPreviousPage)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
Assert::IsFalse(search.CanEditFilterValue());
search.memory.at(12) = 9;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x09");
search.memory.at(12) = 7;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"2/2"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x07");
search.PreviousPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/2"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x07");
// reapply filter - make sure it's comparing against the prev and not the last results
// if comparing against the last, will have 0 results because the value is unchanged
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"2/2"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x07");
}
TEST_METHOD(TestApplyFilterEightBitPreserveScrollOffset)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
Assert::AreEqual({0}, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({32U}, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= Last Known"), search.GetFilterSummary());
Assert::AreEqual({9U}, search.Results().Count());
search.SetScrollOffset(12);
Assert::AreEqual({12U}, search.Results().GetItemAt(0)->nAddress);
const auto sFirstItem = search.Results().GetItemAt(0)->GetCurrentValue();
// filter item after scroll offset - scroll offset should not change
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(std::wstring(L"15"));
search.ApplyFilter();
Assert::AreEqual({12}, search.GetScrollOffset());
Assert::AreEqual({31U}, search.GetResultCount());
Assert::AreEqual(sFirstItem, search.Results().GetItemAt(0)->GetCurrentValue());
// filter item before scroll offset - scroll offset should change so first item doesn't
search.SetFilterValue(std::wstring(L"6"));
search.ApplyFilter();
Assert::AreEqual({11}, search.GetScrollOffset());
Assert::AreEqual({30U}, search.GetResultCount());
Assert::AreEqual(sFirstItem, search.Results().GetItemAt(0)->GetCurrentValue());
// filter item at scroll offset - scroll offset should change
search.SetFilterValue(sFirstItem);
search.ApplyFilter();
Assert::AreEqual({10}, search.GetScrollOffset());
Assert::AreEqual({29U}, search.GetResultCount());
Assert::AreNotEqual(sFirstItem, search.Results().GetItemAt(0)->GetCurrentValue());
// filter item after scroll offset when scroll offset at maximum
search.SetScrollOffset(20);
search.SetFilterValue(std::wstring(L"30"));
search.ApplyFilter();
Assert::AreEqual({19}, search.GetScrollOffset());
Assert::AreEqual({28U}, search.GetResultCount());
// go to previous results page does not change offset
search.PreviousPage();
Assert::AreEqual({19}, search.GetScrollOffset());
Assert::AreEqual({29U}, search.GetResultCount());
}
TEST_METHOD(TestApplyFilterAsciiTextConstant)
{
MemorySearchViewModelHarness search;
search.InitializeAsciiMemory();
search.SetSearchType(ra::services::SearchType::AsciiText);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"sea");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 2U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::Text, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= sea"), search.GetFilterSummary());
Assert::AreEqual({ 2U }, search.Results().Count());
AssertRow(search, 0, 10U, L"0x000a", L"seashells by the");
AssertRow(search, 1, 27U, L"0x001b", L"seash");
}
TEST_METHOD(TestApplyFilterMaxPages)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
Assert::IsFalse(search.CanEditFilterValue());
for (int i = 0; i < 100; ++i)
{
search.memory.at(12)++;
search.ApplyFilter();
}
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"50/50"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x70");
// test initial value == 12 to check first buffered result
// which should still be the initial capture, even if the history had to be cycled
search.SetValueType(ra::services::SearchFilterType::InitialValue);
search.SetComparisonType(ComparisonType::Equals);
search.memory.at(12) = 12;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"50/50"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= Initial"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x0c");
}
TEST_METHOD(TestApplyFilterMaxPagesInitialValue)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::InitialValue);
Assert::IsFalse(search.CanEditFilterValue());
for (int i = 0; i < 100; ++i)
{
search.memory.at(12)++;
search.ApplyFilter();
}
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"50/50"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Initial"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x70");
// test initial value == 12 to check first buffered result. since every step along
// the way was an initial value check, should still be the original initial value
search.SetValueType(ra::services::SearchFilterType::InitialValue);
search.SetComparisonType(ComparisonType::Equals);
search.memory.at(12) = 12;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"50/50"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= Initial"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x0c");
}
TEST_METHOD(TestDoFrameEightBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
search.memory.at(2) = 9;
search.DoFrame();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 32U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"32"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::IsTrue(search.Results().Count() > 3);
AssertRow(search, 0, 0U, L"0x0000", L"0x00");
AssertRow(search, 1, 1U, L"0x0001", L"0x01");
AssertRow(search, 2, 2U, L"0x0002", L"0x09");
}
TEST_METHOD(TestDoFrameSixteenBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::SixteenBit);
search.SetAligned(false);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
search.memory.at(2) = 9;
search.DoFrame();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 31U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::SixteenBit, search.ResultMemSize());
Assert::IsTrue(search.Results().Count() > 3);
AssertRow(search, 0, 0U, L"0x0000", L"0x0100");
AssertRow(search, 1, 1U, L"0x0001", L"0x0901");
AssertRow(search, 2, 2U, L"0x0002", L"0x0309");
}
TEST_METHOD(TestDoFrameEightBitFlapping)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
search.memory.at(2) = 9;
search.DoFrame();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 32U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"32"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::IsTrue(search.Results().Count() > 3);
AssertRow(search, 0, 0U, L"0x0000", L"0x00");
AssertRow(search, 1, 1U, L"0x0001", L"0x01");
AssertRow(search, 2, 2U, L"0x0002", L"0x09");
search.memory.at(2) = 2; // change back to value captured in the filter, make sure the results update
search.DoFrame();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 32U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"32"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::IsTrue(search.Results().Count() > 3);
AssertRow(search, 0, 0U, L"0x0000", L"0x00");
AssertRow(search, 1, 1U, L"0x0001", L"0x01");
AssertRow(search, 2, 2U, L"0x0002", L"0x02");
}
TEST_METHOD(TestApplyFilterFourBitLastKnownPlus)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::FourBit);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValuePlus);
Assert::IsTrue(search.CanEditFilterValue());
search.SetFilterValue(L"2");
search.memory.at(6) = 0x28;
search.memory.at(12) = 14;
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 3U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"3"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::NibbleLower, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"= Last +2"), search.GetFilterSummary());
Assert::AreEqual({ 3U }, search.Results().Count());
AssertRow(search, 0, 12U, L"0x0006L", L"0x8");
AssertRow(search, 1, 13U, L"0x0006U", L"0x2");
AssertRow(search, 2, 24U, L"0x000cL", L"0xe");
}
TEST_METHOD(TestDoFrameFourBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::FourBit);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
search.memory.at(1) = 9;
search.DoFrame();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 64U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::NibbleLower, search.ResultMemSize());
Assert::IsTrue(search.Results().Count() > 3);
AssertRow(search, 0, 0U, L"0x0000L", L"0x0");
AssertRow(search, 1, 1U, L"0x0000U", L"0x0");
AssertRow(search, 2, 2U, L"0x0001L", L"0x9");
}
TEST_METHOD(TestNextPagePreviousPage)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::LessThan);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"8");
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 8 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"< 8"), search.GetFilterSummary());
Assert::AreEqual({ 8U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"8"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual({ 8U }, search.Results().Count());
AssertRow(search, 2, 2U, L"0x0002", L"0x02");
Assert::IsTrue(search.CanFilter());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
search.SetComparisonType(ComparisonType::GreaterThan);
search.SetFilterValue(L"3");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 4 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"2/2"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"> 3"), search.GetFilterSummary());
Assert::AreEqual({ 4U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"4"), search.GetResultCountText());
Assert::AreEqual({ 4U }, search.Results().Count());
AssertRow(search, 2, 6U, L"0x0006", L"0x06");
Assert::IsTrue(search.CanFilter());
Assert::IsTrue(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetFilterValue(L"6");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 3 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"3/3"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"!= 6"), search.GetFilterSummary());
Assert::AreEqual({ 3U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"3"), search.GetResultCountText());
Assert::AreEqual({ 3U }, search.Results().Count());
AssertRow(search, 2, 7U, L"0x0007", L"0x07");
Assert::IsTrue(search.CanFilter());
Assert::IsTrue(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
// cannot go forward
search.NextPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 3 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"3/3"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"!= 6"), search.GetFilterSummary());
Assert::AreEqual({ 3U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"3"), search.GetResultCountText());
Assert::AreEqual({ 3U }, search.Results().Count());
AssertRow(search, 2, 7U, L"0x0007", L"0x07");
Assert::IsTrue(search.CanFilter());
Assert::IsTrue(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
search.PreviousPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 4 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"2/3"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"> 3"), search.GetFilterSummary());
Assert::AreEqual({ 4U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"4"), search.GetResultCountText());
Assert::AreEqual({ 4U }, search.Results().Count());
AssertRow(search, 2, 6U, L"0x0006", L"0x06");
Assert::IsTrue(search.CanFilter());
Assert::IsTrue(search.CanGoToPreviousPage());
Assert::IsTrue(search.CanGoToNextPage());
search.PreviousPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 8 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"1/3"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"< 8"), search.GetFilterSummary());
Assert::AreEqual({ 8U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"8"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual({ 8U }, search.Results().Count());
AssertRow(search, 2, 2U, L"0x0002", L"0x02");
Assert::IsTrue(search.CanFilter());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsTrue(search.CanGoToNextPage());
// cannot go back any further
search.PreviousPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 8 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"1/3"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"< 8"), search.GetFilterSummary());
Assert::AreEqual({ 8U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"8"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual({ 8U }, search.Results().Count());
AssertRow(search, 2, 2U, L"0x0002", L"0x02");
Assert::IsTrue(search.CanFilter());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsTrue(search.CanGoToNextPage());
search.NextPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 4 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"2/3"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"> 3"), search.GetFilterSummary());
Assert::AreEqual({ 4U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"4"), search.GetResultCountText());
Assert::AreEqual({ 4U }, search.Results().Count());
AssertRow(search, 2, 6U, L"0x0006", L"0x06");
Assert::IsTrue(search.CanFilter());
Assert::IsTrue(search.CanGoToPreviousPage());
Assert::IsTrue(search.CanGoToNextPage());
search.PreviousPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 8 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"1/3"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"< 8"), search.GetFilterSummary());
Assert::AreEqual({ 8U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"8"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual({ 8U }, search.Results().Count());
AssertRow(search, 2, 2U, L"0x0002", L"0x02");
Assert::IsTrue(search.CanFilter());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsTrue(search.CanGoToNextPage());
// not at last page - filter should replace any pages after current
search.SetComparisonType(ComparisonType::Equals);
search.SetFilterValue(L"5");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 1 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"2/2"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"= 5"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 5U, L"0x0005", L"0x05");
Assert::IsTrue(search.CanFilter());
Assert::IsTrue(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
search.PreviousPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 8 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"1/2"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"< 8"), search.GetFilterSummary());
Assert::AreEqual({ 8U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"8"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual({ 8U }, search.Results().Count());
AssertRow(search, 2, 2U, L"0x0002", L"0x02");
Assert::IsTrue(search.CanFilter());
Assert::IsFalse(search.CanGoToPreviousPage());
Assert::IsTrue(search.CanGoToNextPage());
search.NextPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual({ 1 }, search.GetScrollMaximum());
Assert::AreEqual(std::wstring(L"2/2"), search.GetSelectedPage());
Assert::AreEqual(std::wstring(L"= 5"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 5U, L"0x0005", L"0x05");
Assert::IsTrue(search.CanFilter());
Assert::IsTrue(search.CanGoToPreviousPage());
Assert::IsFalse(search.CanGoToNextPage());
}
TEST_METHOD(TestDoFramePreviousPage)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::LessThan);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"8");
search.ApplyFilter();
Assert::AreEqual({ 8U }, search.GetResultCount());
search.SetComparisonType(ComparisonType::GreaterThan);
search.SetFilterValue(L"3");
search.ApplyFilter();
Assert::AreEqual({ 4U }, search.GetResultCount());
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetFilterValue(L"6");
search.ApplyFilter();
Assert::AreEqual({ 3U }, search.GetResultCount());
search.PreviousPage();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"2/3"), search.GetSelectedPage());
Assert::AreEqual({ 4U }, search.GetResultCount());
Assert::AreEqual({ 4U }, search.Results().Count());
AssertRow(search, 2, 6U, L"0x0006", L"0x06");
search.memory.at(6) = 9;
search.DoFrame();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"2/3"), search.GetSelectedPage());
Assert::AreEqual({ 4U }, search.GetResultCount());
Assert::AreEqual({ 4U }, search.Results().Count());
AssertRow(search, 2, 6U, L"0x0006", L"0x09");
}
TEST_METHOD(TestExcludeSelectedEightBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::LessThan);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"5");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 5U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual({ 5U }, search.Results().Count());
Assert::IsFalse(search.HasSelection());
search.Results().GetItemAt(2)->SetSelected(true);
Assert::IsTrue(search.HasSelection());
search.Results().GetItemAt(3)->SetSelected(true);
Assert::IsTrue(search.HasSelection());
search.ExcludeSelected();
Assert::AreEqual({ 3U }, search.Results().Count());
Assert::IsFalse(search.HasSelection());
Assert::AreEqual(0U, search.Results().GetItemAt(0)->nAddress);
Assert::AreEqual(1U, search.Results().GetItemAt(1)->nAddress);
Assert::AreEqual(4U, search.Results().GetItemAt(2)->nAddress);
Assert::IsFalse(search.Results().GetItemAt(2)->IsSelected());
search.ExcludeSelected();
Assert::IsFalse(search.HasSelection());
Assert::AreEqual({ 3U }, search.Results().Count());
}
TEST_METHOD(TestExcludeSelectedFourBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::FourBit);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::LessThan);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"1");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 18U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::NibbleLower, search.ResultMemSize());
Assert::IsFalse(search.HasSelection());
Assert::AreEqual(0U, search.Results().GetItemAt(0)->nAddress); // 0L
search.Results().GetItemAt(0)->SetSelected(true);
Assert::IsTrue(search.HasSelection());
Assert::AreEqual(3U, search.Results().GetItemAt(2)->nAddress); // 1H
search.Results().GetItemAt(2)->SetSelected(true);
Assert::IsTrue(search.HasSelection());
search.ExcludeSelected();
Assert::AreEqual({ 16U }, search.GetResultCount());
Assert::IsFalse(search.HasSelection());
Assert::AreEqual(1U, search.Results().GetItemAt(0)->nAddress); // 0H
Assert::AreEqual(5U, search.Results().GetItemAt(1)->nAddress); // 2H
Assert::AreEqual(7U, search.Results().GetItemAt(2)->nAddress); // 3H
Assert::IsFalse(search.Results().GetItemAt(2)->IsSelected());
search.ExcludeSelected();
Assert::IsFalse(search.HasSelection());
Assert::AreEqual({ 16U }, search.GetResultCount());
}
TEST_METHOD(TestExcludeSelectedEightBitPrevious)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::LessThan);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"5");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 5U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
Assert::AreEqual(std::wstring(L"2/2"), search.GetSelectedPage());
Assert::AreEqual({ 5U }, search.GetResultCount());
search.memory.at(3) = 4;
search.ApplyFilter();
Assert::AreEqual(std::wstring(L"3/3"), search.GetSelectedPage());
Assert::AreEqual({ 4U }, search.GetResultCount()); // 0,1,2,4
search.PreviousPage();
Assert::AreEqual(std::wstring(L"2/3"), search.GetSelectedPage());
Assert::AreEqual({ 5U }, search.GetResultCount()); // 0,1,2,3,4
Assert::IsFalse(search.HasSelection());
search.Results().GetItemAt(2)->SetSelected(true); // 2
Assert::IsTrue(search.HasSelection());
search.ExcludeSelected();
Assert::AreEqual({ 4U }, search.Results().Count());
Assert::IsFalse(search.HasSelection());
Assert::AreEqual(0U, search.Results().GetItemAt(0)->nAddress);
Assert::AreEqual(1U, search.Results().GetItemAt(1)->nAddress);
Assert::AreEqual(3U, search.Results().GetItemAt(2)->nAddress);
Assert::AreEqual(4U, search.Results().GetItemAt(3)->nAddress);
}
TEST_METHOD(TestBookmarkSelected)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::LessThan);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"5");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 5U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual({ 5U }, search.Results().Count());
Assert::IsFalse(search.HasSelection());
search.Results().GetItemAt(2)->SetSelected(true);
Assert::IsTrue(search.HasSelection());
search.Results().GetItemAt(3)->SetSelected(true);
Assert::IsTrue(search.HasSelection());
search.BookmarkSelected();
Assert::AreEqual({ 5U }, search.Results().Count());
Assert::IsTrue(search.HasSelection());
const auto& pBookmarks = search.mockWindowManager.MemoryBookmarks.Bookmarks();
Assert::AreEqual({ 2U }, pBookmarks.Items().Count());
Assert::AreEqual({ 2U }, pBookmarks.Items().GetItemAt(0)->GetAddress());
Assert::AreEqual({ 3U }, pBookmarks.Items().GetItemAt(1)->GetAddress());
Assert::IsTrue(search.Results().GetItemAt(2)->IsSelected());
Assert::IsTrue(search.Results().GetItemAt(3)->IsSelected());
}
TEST_METHOD(TestBookmarkSelectedFourBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.memory.at(30) = 0xFF;
search.SetSearchType(ra::services::SearchType::FourBit);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::GreaterThan);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"13");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 5U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::NibbleLower, search.ResultMemSize());
Assert::AreEqual({ 5U }, search.Results().Count());
search.Results().GetItemAt(2)->SetSelected(true);
search.Results().GetItemAt(3)->SetSelected(true);
search.BookmarkSelected();
Assert::AreEqual({ 5U }, search.Results().Count());
const auto& pBookmarks = search.mockWindowManager.MemoryBookmarks.Bookmarks();
Assert::AreEqual({ 2U }, pBookmarks.Items().Count());
Assert::AreEqual({ 30U }, pBookmarks.Items().GetItemAt(0)->GetAddress());
Assert::AreEqual({ 30U }, pBookmarks.Items().GetItemAt(1)->GetAddress());
Assert::AreEqual(ra::data::Memory::Size::NibbleLower, pBookmarks.Items().GetItemAt(0)->GetSize());
Assert::AreEqual(ra::data::Memory::Size::NibbleUpper, pBookmarks.Items().GetItemAt(1)->GetSize());
Assert::IsTrue(search.Results().GetItemAt(2)->IsSelected());
Assert::IsTrue(search.Results().GetItemAt(3)->IsSelected());
}
TEST_METHOD(TestBookmarkSelectedFloat)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.memory.at(12) = 0xDB;
search.memory.at(13) = 0x0F;
search.memory.at(14) = 0x49;
search.memory.at(15) = 0x40;
search.SetSearchType(ra::services::SearchType::Float);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::GreaterThan);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"3");
search.ApplyFilter();
search.SetComparisonType(ComparisonType::LessThan);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"4");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"2/2"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::Float, search.ResultMemSize());
Assert::AreEqual({ 1U }, search.Results().Count());
search.Results().GetItemAt(0)->SetSelected(true);
search.BookmarkSelected();
Assert::AreEqual({ 1U }, search.Results().Count());
const auto& pBookmarks = search.mockWindowManager.MemoryBookmarks.Bookmarks();
Assert::AreEqual({ 1U }, pBookmarks.Items().Count());
Assert::AreEqual({ 12U }, pBookmarks.Items().GetItemAt(0)->GetAddress());
Assert::AreEqual(ra::data::Memory::Size::Float, pBookmarks.Items().GetItemAt(0)->GetSize());
Assert::IsTrue(search.Results().GetItemAt(0)->IsSelected());
}
TEST_METHOD(TestBookmarkSelectedText)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.memory.at(8) = 'T';
search.memory.at(9) = 'E';
search.memory.at(10) = 'S';
search.memory.at(11) = 'T';
search.SetSearchType(ra::services::SearchType::AsciiText);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"TEST");
search.ApplyFilter();
Assert::AreEqual({ 0 }, search.GetScrollOffset());
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(ra::data::Memory::Size::Text, search.ResultMemSize());
Assert::AreEqual({ 1U }, search.Results().Count());
search.Results().GetItemAt(0)->SetSelected(true);
search.BookmarkSelected();
Assert::AreEqual({ 1U }, search.Results().Count());
const auto& pBookmarks = search.mockWindowManager.MemoryBookmarks.Bookmarks();
Assert::AreEqual({ 1U }, pBookmarks.Items().Count());
Assert::AreEqual({ 8U }, pBookmarks.Items().GetItemAt(0)->GetAddress());
Assert::AreEqual(ra::data::Memory::Size::Text, pBookmarks.Items().GetItemAt(0)->GetSize());
Assert::IsTrue(search.Results().GetItemAt(0)->IsSelected());
}
TEST_METHOD(TestPredefinedFilterRangeNone)
{
// no memory ranges defined
MemorySearchViewModelHarness search;
Assert::AreEqual({ 2U }, search.PredefinedFilterRanges().Count());
Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"All"), search.PredefinedFilterRanges().GetItemAt(0)->GetLabel());
Assert::AreEqual(-3, search.PredefinedFilterRanges().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"Custom"), search.PredefinedFilterRanges().GetItemAt(1)->GetLabel());
}
TEST_METHOD(TestPredefinedFilterRangeNoneWithGame)
{
// no memory ranges defined
MemorySearchViewModelHarness search;
Assert::AreEqual({ 2U }, search.PredefinedFilterRanges().Count());
// as soon as a game starts loading, the "Customize..." item is added
search.mockGameContext.SetGameId(1);
search.mockGameContext.NotifyBeforeActiveGameChanged();
Assert::AreEqual({ 3U }, search.PredefinedFilterRanges().Count());
Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"All"), search.PredefinedFilterRanges().GetItemAt(0)->GetLabel());
Assert::AreEqual(-3, search.PredefinedFilterRanges().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"Custom"), search.PredefinedFilterRanges().GetItemAt(1)->GetLabel());
Assert::AreEqual(-4, search.PredefinedFilterRanges().GetItemAt(2)->GetId());
Assert::AreEqual(std::wstring(L"Customize..."), search.PredefinedFilterRanges().GetItemAt(2)->GetLabel());
}
TEST_METHOD(TestPredefinedFilterRangeOnlySystem)
{
// only system range defined
MemorySearchViewModelHarness search;
search.mockConsoleContext.AddMemoryRegion(0U, 0xFFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM");
search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U);
Assert::AreEqual({ 2U }, search.PredefinedFilterRanges().Count());
Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"All"), search.PredefinedFilterRanges().GetItemAt(0)->GetLabel());
Assert::AreEqual(-3, search.PredefinedFilterRanges().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"Custom"), search.PredefinedFilterRanges().GetItemAt(1)->GetLabel());
}
TEST_METHOD(TestPredefinedFilterRangeSystemAndCartridge)
{
// system and game ranges defined
MemorySearchViewModelHarness search;
search.mockConsoleContext.AddMemoryRegion(0U, 0xBFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM");
search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM");
search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U);
Assert::AreEqual({ 4U }, search.PredefinedFilterRanges().Count());
Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"All"), search.PredefinedFilterRanges().GetItemAt(0)->GetLabel());
Assert::AreEqual(1, search.PredefinedFilterRanges().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"System RAM (0x0000-0xbfff)"), search.PredefinedFilterRanges().GetItemAt(1)->GetLabel());
Assert::AreEqual(2, search.PredefinedFilterRanges().GetItemAt(2)->GetId());
Assert::AreEqual(std::wstring(L"Cartridge RAM (0xe000-0xefff)"), search.PredefinedFilterRanges().GetItemAt(2)->GetLabel());
Assert::AreEqual(-3, search.PredefinedFilterRanges().GetItemAt(3)->GetId());
Assert::AreEqual(std::wstring(L"Custom"), search.PredefinedFilterRanges().GetItemAt(3)->GetLabel());
}
TEST_METHOD(TestPredefinedFilterRangeMergeSimilar)
{
// multiple similar system and game ranges defined
MemorySearchViewModelHarness search;
search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM");
search.mockConsoleContext.AddMemoryRegion(0x8000U, 0xBFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM");
search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM");
search.mockConsoleContext.AddMemoryRegion(0xF000U, 0xFFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM");
search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U);
Assert::AreEqual({ 4U }, search.PredefinedFilterRanges().Count());
Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"All"), search.PredefinedFilterRanges().GetItemAt(0)->GetLabel());
Assert::AreEqual(1, search.PredefinedFilterRanges().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"System RAM (0x0000-0xbfff)"), search.PredefinedFilterRanges().GetItemAt(1)->GetLabel());
Assert::AreEqual(2, search.PredefinedFilterRanges().GetItemAt(2)->GetId());
Assert::AreEqual(std::wstring(L"Cartridge RAM (0xe000-0xffff)"), search.PredefinedFilterRanges().GetItemAt(2)->GetLabel());
Assert::AreEqual(-3, search.PredefinedFilterRanges().GetItemAt(3)->GetId());
Assert::AreEqual(std::wstring(L"Custom"), search.PredefinedFilterRanges().GetItemAt(3)->GetLabel());
}
TEST_METHOD(TestPredefinedFilterRangeDontMergeDistinct)
{
// multiple distinct system and game ranges defined
MemorySearchViewModelHarness search;
search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM 1");
search.mockConsoleContext.AddMemoryRegion(0x8000U, 0xBFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM 2");
search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xEFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM 1");
search.mockConsoleContext.AddMemoryRegion(0xF000U, 0xFFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM 2");
search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U);
Assert::AreEqual({ 8U }, search.PredefinedFilterRanges().Count());
Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"All"), search.PredefinedFilterRanges().GetItemAt(0)->GetLabel());
Assert::AreEqual(-1, search.PredefinedFilterRanges().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"All System Memory (0x0000-0xbfff)"), search.PredefinedFilterRanges().GetItemAt(1)->GetLabel());
Assert::AreEqual(-2, search.PredefinedFilterRanges().GetItemAt(2)->GetId());
Assert::AreEqual(std::wstring(L"All Extra Memory (0xe000-0xffff)"), search.PredefinedFilterRanges().GetItemAt(2)->GetLabel());
Assert::AreEqual(3, search.PredefinedFilterRanges().GetItemAt(3)->GetId());
Assert::AreEqual(std::wstring(L"System RAM 1 (0x0000-0x7fff)"), search.PredefinedFilterRanges().GetItemAt(3)->GetLabel());
Assert::AreEqual(4, search.PredefinedFilterRanges().GetItemAt(4)->GetId());
Assert::AreEqual(std::wstring(L"System RAM 2 (0x8000-0xbfff)"), search.PredefinedFilterRanges().GetItemAt(4)->GetLabel());
Assert::AreEqual(5, search.PredefinedFilterRanges().GetItemAt(5)->GetId());
Assert::AreEqual(std::wstring(L"Cartridge RAM 1 (0xe000-0xefff)"), search.PredefinedFilterRanges().GetItemAt(5)->GetLabel());
Assert::AreEqual(6, search.PredefinedFilterRanges().GetItemAt(6)->GetId());
Assert::AreEqual(std::wstring(L"Cartridge RAM 2 (0xf000-0xffff)"), search.PredefinedFilterRanges().GetItemAt(6)->GetLabel());
Assert::AreEqual(-3, search.PredefinedFilterRanges().GetItemAt(7)->GetId());
Assert::AreEqual(std::wstring(L"Custom"), search.PredefinedFilterRanges().GetItemAt(7)->GetLabel());
}
TEST_METHOD(TestPredefinedFilterRangeSuperfluous)
{
// non-system/cartridge memory regions should be ignored
MemorySearchViewModelHarness search;
search.mockConsoleContext.AddMemoryRegion(0x0000U, 0x00FFU, ra::data::MemoryRegion::Type::HardwareController, L"Interrupt Vector");
search.mockConsoleContext.AddMemoryRegion(0x0100U, 0x014FU, ra::data::MemoryRegion::Type::ReadOnlyMemory, L"Cartridge Header");
search.mockConsoleContext.AddMemoryRegion(0x0150U, 0x3FFFU, ra::data::MemoryRegion::Type::ReadOnlyMemory, L"Cartridge ROM (fixed)");
search.mockConsoleContext.AddMemoryRegion(0x4000U, 0x7FFFU, ra::data::MemoryRegion::Type::ReadOnlyMemory, L"Cartridge ROM (paged)");
search.mockConsoleContext.AddMemoryRegion(0x8000U, 0x97FFU, ra::data::MemoryRegion::Type::VideoRAM, L"Title RAM");
search.mockConsoleContext.AddMemoryRegion(0x9800U, 0x9BFFU, ra::data::MemoryRegion::Type::VideoRAM, L"BG1 map data");
search.mockConsoleContext.AddMemoryRegion(0x9C00U, 0x9FFFU, ra::data::MemoryRegion::Type::VideoRAM, L"MD2 map data");
search.mockConsoleContext.AddMemoryRegion(0xA000U, 0xBFFFU, ra::data::MemoryRegion::Type::SaveRAM, L"Cartridge RAM (bank 0)");
search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM (fixed)");
search.mockConsoleContext.AddMemoryRegion(0xD000U, 0xDFFFU, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM (fixed)");
search.mockConsoleContext.AddMemoryRegion(0xE000U, 0xFDFFU, ra::data::MemoryRegion::Type::VirtualRAM, L"Echo RAM");
search.mockConsoleContext.AddMemoryRegion(0xFE00U, 0xFE9FU, ra::data::MemoryRegion::Type::VideoRAM, L"Sprite RAM");
search.mockConsoleContext.AddMemoryRegion(0xFEA0U, 0xFEFFU, ra::data::MemoryRegion::Type::Unused, L"");
search.mockConsoleContext.AddMemoryRegion(0xFF00U, 0xFF7FU, ra::data::MemoryRegion::Type::HardwareController, L"Hardware I/O");
search.mockConsoleContext.AddMemoryRegion(0xFF80U, 0xFFFEU, ra::data::MemoryRegion::Type::SystemRAM, L"Quick RAM");
search.mockConsoleContext.AddMemoryRegion(0xFFFFU, 0xFFFFU, ra::data::MemoryRegion::Type::HardwareController, L"Interrupt Enable");
search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U);
Assert::AreEqual({ 6U }, search.PredefinedFilterRanges().Count());
Assert::AreEqual(0, search.PredefinedFilterRanges().GetItemAt(0)->GetId());
Assert::AreEqual(std::wstring(L"All"), search.PredefinedFilterRanges().GetItemAt(0)->GetLabel());
Assert::AreEqual(-1, search.PredefinedFilterRanges().GetItemAt(1)->GetId());
Assert::AreEqual(std::wstring(L"All System Memory (0xc000-0xfffe)"), search.PredefinedFilterRanges().GetItemAt(1)->GetLabel());
Assert::AreEqual(2, search.PredefinedFilterRanges().GetItemAt(2)->GetId());
Assert::AreEqual(std::wstring(L"Cartridge RAM (bank 0) (0xa000-0xbfff)"), search.PredefinedFilterRanges().GetItemAt(2)->GetLabel());
Assert::AreEqual(3, search.PredefinedFilterRanges().GetItemAt(3)->GetId());
Assert::AreEqual(std::wstring(L"System RAM (fixed) (0xc000-0xdfff)"), search.PredefinedFilterRanges().GetItemAt(3)->GetLabel());
Assert::AreEqual(4, search.PredefinedFilterRanges().GetItemAt(4)->GetId());
Assert::AreEqual(std::wstring(L"Quick RAM (0xff80-0xfffe)"), search.PredefinedFilterRanges().GetItemAt(4)->GetLabel());
Assert::AreEqual(-3, search.PredefinedFilterRanges().GetItemAt(5)->GetId());
Assert::AreEqual(std::wstring(L"Custom"), search.PredefinedFilterRanges().GetItemAt(5)->GetLabel());
}
TEST_METHOD(TestPredefinedFilterRangeAll)
{
MemorySearchViewModelHarness search;
search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM);
search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM);
search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U);
search.SetFilterRange(L"0x0000-0x1FFF");
search.SetPredefinedFilterRange(0);
Assert::AreEqual(std::wstring(L""), search.GetFilterRange());
}
TEST_METHOD(TestPredefinedFilterRangeSystem)
{
MemorySearchViewModelHarness search;
search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM);
search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM);
search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U);
search.SetFilterRange(L"0x0000-0x1FFF");
search.SetPredefinedFilterRange(1);
Assert::AreEqual(std::wstring(L"0x0000-0x7fff"), search.GetFilterRange());
}
TEST_METHOD(TestPredefinedFilterRangeGame)
{
MemorySearchViewModelHarness search;
search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM);
search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM);
search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U);
search.SetFilterRange(L"0x0000-0x1FFF");
search.SetPredefinedFilterRange(2);
Assert::AreEqual(std::wstring(L"0xc000-0xcfff"), search.GetFilterRange());
}
TEST_METHOD(TestPredefinedFilterRangeCustom)
{
MemorySearchViewModelHarness search;
search.mockConsoleContext.AddMemoryRegion(0U, 0x7FFFU, ra::data::MemoryRegion::Type::SystemRAM);
search.mockConsoleContext.AddMemoryRegion(0xC000U, 0xCFFFU, ra::data::MemoryRegion::Type::SaveRAM);
search.mockEmulatorMemoryContext.MockTotalMemorySizeChanged(0x10000U);
search.SetFilterRange(L"0x0000-0x1FFF");
search.SetPredefinedFilterRange(0);
Assert::AreEqual(std::wstring(L""), search.GetFilterRange());
Assert::AreEqual(-3, search.PredefinedFilterRanges().GetItemAt(3)->GetId());
Assert::AreEqual(std::wstring(L"Custom (0x0000-0x1fff)"), search.PredefinedFilterRanges().GetItemAt(3)->GetLabel());
search.SetPredefinedFilterRange(-3);
Assert::AreEqual(std::wstring(L"0x0000-0x1fff"), search.GetFilterRange());
}
TEST_METHOD(TestToggleContinousFilter)
{
MemorySearchViewModelHarness search;
Assert::IsFalse(search.CanFilter());
Assert::IsFalse(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Continuous Filter"), search.ContinuousFilterLabel());
search.InitializeMemory();
search.BeginNewSearch();
Assert::IsTrue(search.CanFilter());
Assert::IsTrue(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Continuous Filter"), search.ContinuousFilterLabel());
search.ToggleContinuousFilter();
Assert::IsFalse(search.CanFilter());
Assert::IsTrue(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Stop Filtering"), search.ContinuousFilterLabel());
search.ToggleContinuousFilter();
Assert::IsTrue(search.CanFilter());
Assert::IsTrue(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Continuous Filter"), search.ContinuousFilterLabel());
}
TEST_METHOD(TestContinousFilterEightBitLastKnown)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.memory.at(10) = 9;
search.memory.at(11) = 9;
search.memory.at(12) = 9;
search.memory.at(13) = 9;
search.memory.at(14) = 9;
search.memory.at(15) = 9;
// enabling performs the first filter
search.ToggleContinuousFilter();
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 6U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"6"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 6U }, search.Results().Count());
AssertRow(search, 0, 10U, L"0x000a", L"0x09");
AssertRow(search, 1, 11U, L"0x000b", L"0x09");
AssertRow(search, 2, 12U, L"0x000c", L"0x09");
AssertRow(search, 3, 13U, L"0x000d", L"0x09");
AssertRow(search, 4, 14U, L"0x000e", L"0x09");
AssertRow(search, 5, 15U, L"0x000f", L"0x09");
search.memory.at(10) = 7;
search.memory.at(11) = 7;
search.memory.at(12) = 7;
search.memory.at(14) = 7;
search.memory.at(15) = 7;
// next filter is performed in DoFrame - should not create a new page
search.DoFrame();
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 5U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"5"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 5U }, search.Results().Count());
AssertRow(search, 0, 10U, L"0x000a", L"0x07");
AssertRow(search, 1, 11U, L"0x000b", L"0x07");
AssertRow(search, 2, 12U, L"0x000c", L"0x07");
AssertRow(search, 3, 14U, L"0x000e", L"0x07");
AssertRow(search, 4, 15U, L"0x000f", L"0x07");
Assert::IsFalse(search.CanFilter());
Assert::IsTrue(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Stop Filtering"), search.ContinuousFilterLabel());
search.memory.at(11) = 4;
// next filter is performed in DoFrame - should not create a new page
search.DoFrame();
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 11U, L"0x000b", L"0x04");
Assert::IsFalse(search.CanFilter());
Assert::IsTrue(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Stop Filtering"), search.ContinuousFilterLabel());
// when no results remain, continuous filtering is automatically disabled
search.DoFrame();
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 0U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"0"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Last Known"), search.GetFilterSummary());
Assert::AreEqual({ 0U }, search.Results().Count());
Assert::IsFalse(search.CanFilter());
Assert::IsFalse(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Continuous Filter"), search.ContinuousFilterLabel());
}
TEST_METHOD(TestContinousFilterEightBitInitialValue)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::InitialValue);
search.memory.at(10) = 9;
search.memory.at(11) = 9;
search.memory.at(12) = 9;
search.memory.at(13) = 9;
search.memory.at(14) = 9;
search.memory.at(15) = 9;
// enabling performs the first filter
search.ToggleContinuousFilter();
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 6U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"6"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Initial"), search.GetFilterSummary());
Assert::AreEqual({ 6U }, search.Results().Count());
AssertRow(search, 0, 10U, L"0x000a", L"0x09");
AssertRow(search, 1, 11U, L"0x000b", L"0x09");
AssertRow(search, 2, 12U, L"0x000c", L"0x09");
AssertRow(search, 3, 13U, L"0x000d", L"0x09");
AssertRow(search, 4, 14U, L"0x000e", L"0x09");
AssertRow(search, 5, 15U, L"0x000f", L"0x09");
search.memory.at(10) = 10;
search.memory.at(12) = 7;
search.memory.at(14) = 14;
search.memory.at(15) = 7;
// next filter is performed in DoFrame - should not create a new page
search.DoFrame();
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 4U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"4"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Initial"), search.GetFilterSummary());
Assert::AreEqual({ 4U }, search.Results().Count());
AssertRow(search, 0, 11U, L"0x000b", L"0x09");
AssertRow(search, 1, 12U, L"0x000c", L"0x07");
AssertRow(search, 2, 13U, L"0x000d", L"0x09");
AssertRow(search, 3, 15U, L"0x000f", L"0x07");
Assert::IsFalse(search.CanFilter());
Assert::IsTrue(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Stop Filtering"), search.ContinuousFilterLabel());
search.memory.at(11) = 11;
search.memory.at(12) = 12;
search.memory.at(13) = 3;
search.memory.at(15) = 15;
// next filter is performed in DoFrame - should not create a new page
search.DoFrame();
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 1U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"1"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Initial"), search.GetFilterSummary());
Assert::AreEqual({ 1U }, search.Results().Count());
AssertRow(search, 0, 13U, L"0x000d", L"0x03");
Assert::IsFalse(search.CanFilter());
Assert::IsTrue(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Stop Filtering"), search.ContinuousFilterLabel());
search.memory.at(13) = 13;
// when no results remain, continuous filtering is automatically disabled
search.DoFrame();
Assert::AreEqual(std::wstring(L"1/1"), search.GetSelectedPage());
Assert::AreEqual({ 0U }, search.GetResultCount());
Assert::AreEqual(std::wstring(L"0"), search.GetResultCountText());
Assert::AreEqual(ra::data::Memory::Size::EightBit, search.ResultMemSize());
Assert::AreEqual(std::wstring(L"!= Initial"), search.GetFilterSummary());
Assert::AreEqual({ 0U }, search.Results().Count());
Assert::IsFalse(search.CanFilter());
Assert::IsFalse(search.CanContinuousFilter());
Assert::AreEqual(std::wstring(L"Continuous Filter"), search.ContinuousFilterLabel());
}
TEST_METHOD(TestOnMemoryNoteChanged)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.mockConsoleContext.AddMemoryRegion({ 0U }, { 0xFFU }, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM");
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"12");
search.ApplyFilter();
Assert::AreEqual({ 1U }, search.Results().Count());
auto* pRow = search.Results().GetItemAt(0);
Assert::IsNotNull(pRow);
Ensures(pRow != nullptr);
Assert::AreEqual({ 12U }, pRow->nAddress);
Assert::AreEqual(std::wstring(L"System RAM"), pRow->GetDescription());
Assert::IsFalse(pRow->bHasMemoryNote);
search.mockGameContext.SetNote({ 12U }, L"Note");
Assert::AreEqual(std::wstring(L"Note"), pRow->GetDescription());
Assert::IsTrue(pRow->bHasMemoryNote);
search.mockGameContext.SetNote({ 12U }, L"Note 2");
Assert::AreEqual(std::wstring(L"Note 2"), pRow->GetDescription());
Assert::IsTrue(pRow->bHasMemoryNote);
search.mockGameContext.SetNote({ 12U }, L"");
Assert::AreEqual(std::wstring(L"System RAM"), pRow->GetDescription());
Assert::IsFalse(pRow->bHasMemoryNote);
}
TEST_METHOD(TestOnMemoryNoteChangedMultiline)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.mockConsoleContext.AddMemoryRegion({ 0U }, { 0xFFU }, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM");
search.BeginNewSearch();
search.mockGameContext.SetNote({ 12U }, L"Summary\n1=A\n2=B");
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"12");
search.ApplyFilter();
Assert::AreEqual({ 1U }, search.Results().Count());
auto* pRow = search.Results().GetItemAt(0);
Assert::IsNotNull(pRow);
Ensures(pRow != nullptr);
Assert::AreEqual({ 12U }, pRow->nAddress);
Assert::AreEqual(std::wstring(L"Summary"), pRow->GetDescription());
Assert::IsTrue(pRow->bHasMemoryNote);
search.mockGameContext.SetNote({ 12U }, L"Summary\n1=C\2=D");
Assert::AreEqual(std::wstring(L"Summary"), pRow->GetDescription());
Assert::IsTrue(pRow->bHasMemoryNote);
}
TEST_METHOD(TestOnMemoryNoteChangedPartial)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.mockConsoleContext.AddMemoryRegion({ 0U }, { 0xFFU }, ra::data::MemoryRegion::Type::SystemRAM, L"System RAM");
search.BeginNewSearch();
search.mockGameContext.SetNote({ 10U }, L"[4-byte] Summary");
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::Constant);
search.SetFilterValue(L"12");
search.ApplyFilter();
Assert::AreEqual({ 1U }, search.Results().Count());
auto* pRow = search.Results().GetItemAt(0);
Assert::IsNotNull(pRow);
Ensures(pRow != nullptr);
Assert::AreEqual({ 12U }, pRow->nAddress);
Assert::AreEqual(std::wstring(L"[4-byte] Summary [3/4]"), pRow->GetDescription());
Assert::IsTrue(pRow->bHasMemoryNote);
search.mockGameContext.SetNote({ 10U }, L"[4-byte] Banana");
Assert::AreEqual(std::wstring(L"[4-byte] Banana [3/4]"), pRow->GetDescription());
Assert::IsTrue(pRow->bHasMemoryNote);
}
TEST_METHOD(TestScrollDisplaysCurrentValue)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
search.memory.at(2) = 9;
search.DoFrame();
Assert::IsTrue(search.Results().Count() > 3);
AssertRow(search, 0, 0U, L"0x0000", L"0x00");
AssertRow(search, 1, 1U, L"0x0001", L"0x01");
AssertRow(search, 2, 2U, L"0x0002", L"0x09");
search.SetScrollOffset(1U);
Assert::IsTrue(search.Results().Count() > 3);
AssertRow(search, 0, 1U, L"0x0001", L"0x01");
AssertRow(search, 1, 2U, L"0x0002", L"0x09");
AssertRow(search, 2, 3U, L"0x0003", L"0x03");
}
TEST_METHOD(TestGetTooltipEightBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
const auto& vmResult = *search.Results().GetItemAt(2);
Assert::AreEqual(std::wstring(L"0x0002\n0x02 | Current\n0x02 | Last Filter\n0x02 | Initial"), search.GetTooltip(vmResult));
search.memory.at(2) = 9;
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002\n0x09 | Current\n0x02 | Last Filter\n0x02 | Initial"), search.GetTooltip(vmResult));
search.memory.at(2) = 0x0c;
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002\n0x0c | Current\n0x02 | Last Filter\n0x02 | Initial"), search.GetTooltip(vmResult));
search.SetComparisonType(ComparisonType::NotEqualTo);
search.ApplyFilter();
Assert::AreEqual({ 1U }, search.Results().Count());
const auto& vmResult2 = *search.Results().GetItemAt(0);
Assert::AreEqual(std::wstring(L"0x0002\n0x0c | Current\n0x0c | Last Filter\n0x02 | Initial"), search.GetTooltip(vmResult2));
search.memory.at(2) = 0x35;
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002\n0x35 | Current\n0x0c | Last Filter\n0x02 | Initial"), search.GetTooltip(vmResult2));
}
TEST_METHOD(TestGetTooltipFourBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::FourBit);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
const auto& vmResult = *search.Results().GetItemAt(4);
Assert::AreEqual(std::wstring(L"0x0002L\n0x2 | Current\n0x2 | Last Filter\n0x2 | Initial"), search.GetTooltip(vmResult));
search.memory.at(2) = 9;
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002L\n0x9 | Current\n0x2 | Last Filter\n0x2 | Initial"), search.GetTooltip(vmResult));
search.memory.at(2) = 0x0c;
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002L\n0xc | Current\n0x2 | Last Filter\n0x2 | Initial"), search.GetTooltip(vmResult));
search.SetComparisonType(ComparisonType::NotEqualTo);
search.ApplyFilter();
Assert::AreEqual({ 1U }, search.Results().Count());
const auto& vmResult2 = *search.Results().GetItemAt(0);
Assert::AreEqual(std::wstring(L"0x0002L\n0xc | Current\n0xc | Last Filter\n0x2 | Initial"), search.GetTooltip(vmResult2));
search.memory.at(2) = 0x35;
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002L\n0x5 | Current\n0xc | Last Filter\n0x2 | Initial"), search.GetTooltip(vmResult2));
}
TEST_METHOD(TestGetTooltipSixteenBit)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::SixteenBit);
search.SetAligned(false);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
const auto& vmResult = *search.Results().GetItemAt(2);
Assert::AreEqual(std::wstring(L"0x0002\n0x0302 | Current\n0x0302 | Last Filter\n0x0302 | Initial"), search.GetTooltip(vmResult));
search.memory.at(2) = 9;
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002\n0x0309 | Current\n0x0302 | Last Filter\n0x0302 | Initial"), search.GetTooltip(vmResult));
search.memory.at(3) = 0x0c;
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002\n0x0c09 | Current\n0x0302 | Last Filter\n0x0302 | Initial"), search.GetTooltip(vmResult));
search.SetComparisonType(ComparisonType::NotEqualTo);
search.ApplyFilter();
Assert::AreEqual({ 3U }, search.Results().Count()); // 01=0901 02=0c09 03=030c
const auto& vmResult2 = *search.Results().GetItemAt(1);
Assert::AreEqual(std::wstring(L"0x0002\n0x0c09 | Current\n0x0c09 | Last Filter\n0x0302 | Initial"), search.GetTooltip(vmResult2));
search.memory.at(2) = 0x35;
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002\n0x0c35 | Current\n0x0c09 | Last Filter\n0x0302 | Initial"), search.GetTooltip(vmResult2));
}
TEST_METHOD(TestGetTooltipText)
{
MemorySearchViewModelHarness search;
search.InitializeMemory();
search.memory.at(2) = 'T';
search.memory.at(3) = 'E';
search.memory.at(4) = 'S';
search.memory.at(5) = 'T';
search.memory.at(6) = 0;
search.SetSearchType(ra::services::SearchType::AsciiText);
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::Equals);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
const auto& vmResult = *search.Results().GetItemAt(2);
Assert::AreEqual(std::wstring(L"0x0002\nTEST | Current\nTEST | Last Filter\nTEST | Initial"), search.GetTooltip(vmResult));
search.memory.at(4) = 'X';
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002\nTEXT | Current\nTEST | Last Filter\nTEST | Initial"), search.GetTooltip(vmResult));
search.memory.at(2) = 'N';
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002\nNEXT | Current\nTEST | Last Filter\nTEST | Initial"), search.GetTooltip(vmResult));
search.SetComparisonType(ComparisonType::NotEqualTo);
search.ApplyFilter();
const auto& vmResult2 = *search.Results().GetItemAt(1); // 01=?NEXT 02=NEXT 03=EXT 04=XT
Assert::AreEqual(std::wstring(L"0x0002\nNEXT | Current\nNEXT | Last Filter\nTEST | Initial"), search.GetTooltip(vmResult2));
search.memory.at(4) = 'A';
search.DoFrame();
Assert::AreEqual(std::wstring(L"0x0002\nNEAT | Current\nNEXT | Last Filter\nTEST | Initial"), search.GetTooltip(vmResult2));
}
TEST_METHOD(TestExportResults)
{
MemorySearchViewModelHarness search;
search.mockGameContext.SetGameId(3);
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.memory.at(5) = 8;
search.memory.at(12) = 9;
search.ApplyFilter();
Assert::AreEqual({2U}, search.Results().Count());
AssertRow(search, 0, 5U, L"0x0005", L"0x08");
AssertRow(search, 1, 12U, L"0x000c", L"0x09");
search.memory.at(5) = 5;
search.memory.at(12) = 7;
search.ApplyFilter();
Assert::AreEqual({2U}, search.Results().Count());
AssertRow(search, 0, 5U, L"0x0005", L"0x05");
AssertRow(search, 1, 12U, L"0x000c", L"0x07");
bool bDialogSeen = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::FileDialogViewModel>(
[&bDialogSeen](ra::ui::viewmodels::FileDialogViewModel& vmFileDialog) {
bDialogSeen = true;
Assert::AreEqual(std::wstring(L"Export Search Results"), vmFileDialog.GetWindowTitle());
Assert::AreEqual({1U}, vmFileDialog.GetFileTypes().size());
Assert::AreEqual(std::wstring(L"csv"), vmFileDialog.GetDefaultExtension());
Assert::AreEqual(std::wstring(L"3-SearchResults.csv"), vmFileDialog.GetFileName());
vmFileDialog.SetFileName(L"E:\\Data\\3-SearchResults.csv");
return DialogResult::OK;
});
search.ExportResults();
Assert::IsTrue(bDialogSeen);
const std::string& sContents = search.mockFileSystem.GetFileContents(L"E:\\Data\\3-SearchResults.csv");
Assert::AreEqual(std::string("Address,Value,PreviousValue,InitialValue\n0x0005,0x05,0x08,0x05\n0x000c,0x07,0x09,0x0c\n"),
sContents);
}
TEST_METHOD(TestExportResultsCancel)
{
MemorySearchViewModelHarness search;
search.mockGameContext.SetGameId(3);
search.InitializeMemory();
search.BeginNewSearch();
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.memory.at(12) = 9;
search.ApplyFilter();
Assert::AreEqual({1U}, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x09");
search.memory.at(12) = 7;
search.ApplyFilter();
Assert::AreEqual({1U}, search.Results().Count());
AssertRow(search, 0, 12U, L"0x000c", L"0x07");
bool bDialogSeen = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::FileDialogViewModel>(
[&bDialogSeen](ra::ui::viewmodels::FileDialogViewModel& vmFileDialog) {
bDialogSeen = true;
Assert::AreEqual(std::wstring(L"Export Search Results"), vmFileDialog.GetWindowTitle());
Assert::AreEqual({1U}, vmFileDialog.GetFileTypes().size());
Assert::AreEqual(std::wstring(L"csv"), vmFileDialog.GetDefaultExtension());
Assert::AreEqual(std::wstring(L"3-SearchResults.csv"), vmFileDialog.GetFileName());
vmFileDialog.SetFileName(L"E:\\Data\\3-SearchResults.csv");
return DialogResult::Cancel;
});
search.ExportResults();
Assert::IsTrue(bDialogSeen);
const std::string& sContents = search.mockFileSystem.GetFileContents(L"E:\\Data\\3-SearchResults.csv");
Assert::AreEqual(std::string(), sContents);
}
TEST_METHOD(TestExportResultsNone)
{
MemorySearchViewModelHarness search;
search.mockGameContext.SetGameId(3);
search.InitializeMemory();
bool bMessageSeen = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>(
[&bMessageSeen](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox) {
bMessageSeen = true;
Assert::AreEqual(std::wstring(L"Nothing to export"), vmMessageBox.GetMessage());
return ra::ui::DialogResult::OK;
});
bool bDialogSeen = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::FileDialogViewModel>(
[&bDialogSeen](ra::ui::viewmodels::FileDialogViewModel&) {
bDialogSeen = true;
return DialogResult::Cancel;
});
// search not started
search.ExportResults();
Assert::IsTrue(bMessageSeen);
Assert::IsFalse(bDialogSeen);
bMessageSeen = false;
// start search. no filter applied. no results
search.BeginNewSearch();
search.ExportResults();
Assert::IsTrue(bMessageSeen);
Assert::IsFalse(bDialogSeen);
bMessageSeen = false;
// filter applied. one result
search.memory.at(12) = 9;
search.SetComparisonType(ComparisonType::NotEqualTo);
search.SetValueType(ra::services::SearchFilterType::LastKnownValue);
search.ApplyFilter();
Assert::AreEqual({1U}, search.Results().Count());
search.ExportResults();
Assert::IsFalse(bMessageSeen);
Assert::IsTrue(bDialogSeen);
bDialogSeen = false;
// filter applied again. no results remaining
search.ApplyFilter();
Assert::AreEqual({0U}, search.Results().Count());
search.ExportResults();
Assert::IsTrue(bMessageSeen);
Assert::IsFalse(bDialogSeen);
}
TEST_METHOD(TestImportResults)
{
MemorySearchViewModelHarness search;
search.mockGameContext.SetGameId(3);
search.InitializeMemory();
const std::string sContents = "Address,Value,PreviousValue,InitialValue\n0x0005,0x05,0x08,0x05\n0x000c,0x07,0x09,0x0c\n";
search.mockFileSystem.MockFile(L"E:\\Data\\3-SearchResults.csv", sContents);
bool bDialogSeen = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::FileDialogViewModel>(
[&bDialogSeen](ra::ui::viewmodels::FileDialogViewModel& vmFileDialog) {
bDialogSeen = true;
Assert::AreEqual(std::wstring(L"Import Search Results"), vmFileDialog.GetWindowTitle());
Assert::AreEqual({1U}, vmFileDialog.GetFileTypes().size());
Assert::AreEqual(std::wstring(L"csv"), vmFileDialog.GetDefaultExtension());
Assert::AreEqual(std::wstring(L"3-SearchResults.csv"), vmFileDialog.GetFileName());
vmFileDialog.SetFileName(L"E:\\Data\\3-SearchResults.csv");
return DialogResult::OK;
});
search.ImportResults();
Assert::IsTrue(bDialogSeen);
Assert::AreEqual({2U}, search.Results().Count());
AssertRow(search, 0, 5U, L"0x0005", L"0x05");
AssertRow(search, 1, 12U, L"0x000c", L"0x0c");
// use tooltip to validate "initial" value for $000c is 0x07
const auto sTooltip = search.GetTooltip(*search.Results().GetItemAt(1));
Assert::AreEqual(std::wstring(L"0x000c\n0x0c | Current\n0x07 | Last Filter\n0x07 | Initial"), sTooltip);
}
TEST_METHOD(TestImportResultsThirtyTwoBit)
{
MemorySearchViewModelHarness search;
search.mockGameContext.SetGameId(3);
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::ThirtyTwoBit);
const std::string sContents =
"Address,Value,PreviousValue,InitialValue\n0x0005,0x12345678,0x08,0x05\n";
search.mockFileSystem.MockFile(L"E:\\Data\\3-SearchResults.csv", sContents);
bool bDialogSeen = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::FileDialogViewModel>(
[&bDialogSeen](ra::ui::viewmodels::FileDialogViewModel& vmFileDialog) {
bDialogSeen = true;
Assert::AreEqual(std::wstring(L"Import Search Results"), vmFileDialog.GetWindowTitle());
Assert::AreEqual({1U}, vmFileDialog.GetFileTypes().size());
Assert::AreEqual(std::wstring(L"csv"), vmFileDialog.GetDefaultExtension());
Assert::AreEqual(std::wstring(L"3-SearchResults.csv"), vmFileDialog.GetFileName());
vmFileDialog.SetFileName(L"E:\\Data\\3-SearchResults.csv");
return DialogResult::OK;
});
search.ImportResults();
Assert::IsTrue(bDialogSeen);
Assert::AreEqual({1U}, search.Results().Count());
AssertRow(search, 0, 5U, L"0x0005", L"0x08070605");
// use tooltip to validate "initial" value
const auto sTooltip = search.GetTooltip(*search.Results().GetItemAt(0));
Assert::AreEqual(std::wstring(L"0x0005\n0x08070605 | Current\n0x12345678 | Last Filter\n0x12345678 | Initial"), sTooltip);
}
TEST_METHOD(TestImportResultsFloat)
{
MemorySearchViewModelHarness search;
search.mockGameContext.SetGameId(3);
search.InitializeMemory();
search.memory.at(4) = 0xDB;
search.memory.at(5) = 0x0F;
search.memory.at(6) = 0x49;
search.memory.at(7) = 0x40;
search.SetSearchType(ra::services::SearchType::Float);
const std::string sContents = "Address,Value,PreviousValue,InitialValue\n0x0004,1.5,2.6,2.6\n";
search.mockFileSystem.MockFile(L"E:\\Data\\3-SearchResults.csv", sContents);
bool bDialogSeen = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::FileDialogViewModel>(
[&bDialogSeen](ra::ui::viewmodels::FileDialogViewModel& vmFileDialog) {
bDialogSeen = true;
Assert::AreEqual(std::wstring(L"Import Search Results"), vmFileDialog.GetWindowTitle());
Assert::AreEqual({1U}, vmFileDialog.GetFileTypes().size());
Assert::AreEqual(std::wstring(L"csv"), vmFileDialog.GetDefaultExtension());
Assert::AreEqual(std::wstring(L"3-SearchResults.csv"), vmFileDialog.GetFileName());
vmFileDialog.SetFileName(L"E:\\Data\\3-SearchResults.csv");
return DialogResult::OK;
});
search.ImportResults();
Assert::IsTrue(bDialogSeen);
Assert::AreEqual({1U}, search.Results().Count());
AssertRow(search, 0, 4U, L"0x0004", L"3.141593");
// use tooltip to validate "initial" value
const auto sTooltip = search.GetTooltip(*search.Results().GetItemAt(0));
Assert::AreEqual(std::wstring(L"0x0004\n3.141593 | Current\n1.5 | Last Filter\n1.5 | Initial"), sTooltip);
}
TEST_METHOD(TestImportResultsAsciiText)
{
MemorySearchViewModelHarness search;
search.mockGameContext.SetGameId(3);
search.InitializeMemory();
search.SetSearchType(ra::services::SearchType::AsciiText);
bool bDialogSeen = false;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>(
[&bDialogSeen](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox) {
bDialogSeen = true;
Assert::AreEqual(std::wstring(L"Cannot import ASCII Text search results"), vmMessageBox.GetMessage());
return ra::ui::DialogResult::OK;
});
search.ImportResults();
Assert::IsTrue(bDialogSeen);
Assert::AreEqual({0U}, search.Results().Count());
}
TEST_METHOD(TestImportResultsConfirmOverwrite)
{
MemorySearchViewModelHarness search;
search.mockGameContext.SetGameId(3);
search.InitializeMemory();
search.BeginNewSearch();
search.ApplyFilter();
Assert::AreEqual({32U}, search.GetResultCount());
const std::string sContents =
"Address,Value,PreviousValue,InitialValue\n0x0005,0x05,0x08,0x05\n0x000c,0x07,0x09,0x0c\n";
search.mockFileSystem.MockFile(L"E:\\Data\\3-SearchResults.csv", sContents);
int nDialogSeen = 0;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>(
[&nDialogSeen](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox) {
nDialogSeen++;
Assert::AreEqual(std::wstring(L"Start new search?"), vmMessageBox.GetHeader());
Assert::AreEqual(std::wstring(L"This will initialize a new search with previously exported search results."), vmMessageBox.GetMessage());
Assert::AreEqual(ra::ui::viewmodels::MessageBoxViewModel::Buttons::YesNo, vmMessageBox.GetButtons());
return (nDialogSeen == 1) ? DialogResult::No : DialogResult::Yes;
});
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::FileDialogViewModel>(
[&nDialogSeen](ra::ui::viewmodels::FileDialogViewModel& vmFileDialog) {
nDialogSeen++;
Assert::AreEqual(std::wstring(L"Import Search Results"), vmFileDialog.GetWindowTitle());
Assert::AreEqual({1U}, vmFileDialog.GetFileTypes().size());
Assert::AreEqual(std::wstring(L"csv"), vmFileDialog.GetDefaultExtension());
Assert::AreEqual(std::wstring(L"3-SearchResults.csv"), vmFileDialog.GetFileName());
vmFileDialog.SetFileName(L"E:\\Data\\3-SearchResults.csv");
return DialogResult::OK;
});
search.ImportResults();
Assert::AreEqual(1, nDialogSeen); // one dialog, canceled
Assert::AreEqual({32U}, search.GetResultCount());
search.ImportResults();
Assert::AreEqual(3, nDialogSeen); // second confirmation dialog + file selection dialog
Assert::AreEqual({2U}, search.GetResultCount());
AssertRow(search, 0, 5U, L"0x0005", L"0x05");
AssertRow(search, 1, 12U, L"0x000c", L"0x0c");
// use tooltip to validate "initial" value for $000c is 0x07
const auto sTooltip = search.GetTooltip(*search.Results().GetItemAt(1));
Assert::AreEqual(std::wstring(L"0x000c\n0x0c | Current\n0x07 | Last Filter\n0x07 | Initial"), sTooltip);
}
TEST_METHOD(TestImportResultsEmptyFile)
{
MemorySearchViewModelHarness search;
search.mockGameContext.SetGameId(3);
search.InitializeMemory();
const std::string sContents = "";
search.mockFileSystem.MockFile(L"E:\\Data\\3-SearchResults.csv", sContents);
int nDialogSeen = 0;
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::FileDialogViewModel>(
[&nDialogSeen](ra::ui::viewmodels::FileDialogViewModel& vmFileDialog) {
nDialogSeen++;
Assert::AreEqual(std::wstring(L"Import Search Results"), vmFileDialog.GetWindowTitle());
Assert::AreEqual({1U}, vmFileDialog.GetFileTypes().size());
Assert::AreEqual(std::wstring(L"csv"), vmFileDialog.GetDefaultExtension());
Assert::AreEqual(std::wstring(L"3-SearchResults.csv"), vmFileDialog.GetFileName());
vmFileDialog.SetFileName(L"E:\\Data\\3-SearchResults.csv");
return DialogResult::OK;
});
search.mockDesktop.ExpectWindow<ra::ui::viewmodels::MessageBoxViewModel>(
[&nDialogSeen](ra::ui::viewmodels::MessageBoxViewModel& vmMessageBox) {
nDialogSeen++;
Assert::AreEqual(std::wstring(L"File does not appear to be an exported search result"), vmMessageBox.GetMessage());
return ra::ui::DialogResult::OK;
});
search.ImportResults();
Assert::AreEqual(2, nDialogSeen);
Assert::AreEqual({0U}, search.Results().Count());
}
};
} // namespace tests
} // namespace viewmodels
} // namespace ui
} // namespace ra