Merge master into feature/GraphingCalculator branch (#585)

* Merge master into feature/GraphingCalculator branch
This commit is contained in:
Stephanie Anderl
2019-07-15 11:17:21 -07:00
committed by GitHub
parent 1475b49120
commit a418777f02
447 changed files with 18056 additions and 19323 deletions

View File

@@ -15,20 +15,14 @@ using namespace Windows::ApplicationModel::Core;
task<void> AsyncHelper::RunOnUIThreadAsync(function<void()>&& action)
{
auto callback = ref new DispatchedHandler([action]()
{
action();
});
auto callback = ref new DispatchedHandler([action]() { action(); });
return create_task(CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::Normal, callback));
}
void AsyncHelper::RunOnUIThread(function<void()>&& action, DWORD timeout)
{
task<void> waitTask = RunOnUIThreadAsync([action]()
{
action();
});
task<void> waitTask = RunOnUIThreadAsync([action]() { action(); });
WaitForTask<void>(waitTask, timeout);
}

View File

@@ -13,22 +13,17 @@ namespace CalculatorApp
static void RunOnUIThread(std::function<void()>&& action, DWORD timeout = INFINITE);
static void Delay(DWORD milliseconds);
template<typename T>
template <typename T>
static void RunOnUIThread(std::function<concurrency::task<T>()>&& action, DWORD timeout = INFINITE)
{
concurrency::task<T> t;
concurrency::task<void> uiTask = RunOnUIThreadAsync([&t, action]()
{
t = action();
}).then([&t]()
{
t.wait();
}, concurrency::task_continuation_context::use_arbitrary());
concurrency::task<void> uiTask =
RunOnUIThreadAsync([&t, action]() { t = action(); }).then([&t]() { t.wait(); }, concurrency::task_continuation_context::use_arbitrary());
WaitForTask<void>(uiTask, timeout);
}
template<typename T>
template <typename T>
static bool WaitForTask(concurrency::task<T>& t, DWORD timeout = INFINITE)
{
Microsoft::WRL::Wrappers::Event event(CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
@@ -37,25 +32,26 @@ namespace CalculatorApp
throw std::bad_alloc();
}
Platform::Exception^ ex;
t.then([&event, &ex](concurrency::task<T> prevTask)
{
try
{
prevTask.get();
}
catch (Platform::Exception^ e)
{
ex = e;
}
Platform::Exception ^ ex;
t.then(
[&event, &ex](concurrency::task<T> prevTask) {
try
{
prevTask.get();
}
catch (Platform::Exception ^ e)
{
ex = e;
}
if (event.IsValid())
{
SetEvent(event.Get());
}
}, concurrency::task_continuation_context::use_arbitrary());
if (event.IsValid())
{
SetEvent(event.Get());
}
},
concurrency::task_continuation_context::use_arbitrary());
DWORD waitResult;// = STATUS_PENDING;
DWORD waitResult; // = STATUS_PENDING;
waitResult = WaitForSingleObjectEx(event.Get(), timeout, true);
event.Close();
@@ -71,6 +67,7 @@ namespace CalculatorApp
return waitResult == WAIT_OBJECT_0;
}
private:
static void Sleep(DWORD milliseconds);
};

View File

@@ -13,7 +13,7 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
static constexpr size_t MAX_HISTORY_SIZE = 20;
namespace CalculatorUnitTests
namespace CalculatorEngineTests
{
TEST_CLASS(CalcEngineTests)
{
@@ -22,7 +22,8 @@ namespace CalculatorUnitTests
m_resourceProvider = make_shared<EngineResourceProvider>();
m_history = make_shared<CalculatorHistory>(MAX_HISTORY_SIZE);
CCalcEngine::InitialOneTimeOnlySetup(*(m_resourceProvider.get()));
m_calcEngine = make_unique<CCalcEngine>(false /* Respect Order of Operations */, false /* Set to Integer Mode */, m_resourceProvider.get(), nullptr, m_history);
m_calcEngine = make_unique<CCalcEngine>(
false /* Respect Order of Operations */, false /* Set to Integer Mode */, m_resourceProvider.get(), nullptr, m_history);
}
TEST_METHOD_CLEANUP(Cleanup)
{
@@ -51,7 +52,8 @@ namespace CalculatorUnitTests
VERIFY_ARE_EQUAL(L"1,234,567,890", m_calcEngine->GroupDigitsPerRadix(L"1234567890", 10), L"Verify grouping in base10.");
VERIFY_ARE_EQUAL(L"1,234,567.89", m_calcEngine->GroupDigitsPerRadix(L"1234567.89", 10), L"Verify grouping in base10 with decimal.");
VERIFY_ARE_EQUAL(L"1,234,567e89", m_calcEngine->GroupDigitsPerRadix(L"1234567e89", 10), L"Verify grouping in base10 with exponent.");
VERIFY_ARE_EQUAL(L"1,234,567.89e5", m_calcEngine->GroupDigitsPerRadix(L"1234567.89e5", 10), L"Verify grouping in base10 with decimal and exponent.");
VERIFY_ARE_EQUAL(
L"1,234,567.89e5", m_calcEngine->GroupDigitsPerRadix(L"1234567.89e5", 10), L"Verify grouping in base10 with decimal and exponent.");
VERIFY_ARE_EQUAL(L"-123,456,789", m_calcEngine->GroupDigitsPerRadix(L"-123456789", 10), L"Verify grouping in base10 with negative.");
}
@@ -115,22 +117,32 @@ namespace CalculatorUnitTests
// Regex matching (descriptions taken from CalcUtils.cpp)
// Use 100 for exp/mantissa length as they are tested above
vector<wstring> validDecStrs{
// Start with an optional + or -
L"+1", L"-1", L"1",
// Followed by zero or more digits
L"-", L"", L"1234567890",
// Followed by an optional decimal point
L"1.0", L"-.", L"1.",
// Followed by zero or more digits
L"0.0", L"0.123456",
// Followed by an optional exponent ('e')
L"1e", L"1.e", L"-e",
// If there's an exponent, its optionally followed by + or -
// and followed by zero or more digits
L"1e+12345", L"1e-12345", L"1e123",
// All together
L"-123.456e+789"
vector<wstring> validDecStrs{ // Start with an optional + or -
L"+1",
L"-1",
L"1",
// Followed by zero or more digits
L"-",
L"",
L"1234567890",
// Followed by an optional decimal point
L"1.0",
L"-.",
L"1.",
// Followed by zero or more digits
L"0.0",
L"0.123456",
// Followed by an optional exponent ('e')
L"1e",
L"1.e",
L"-e",
// If there's an exponent, its optionally followed by + or -
// and followed by zero or more digits
L"1e+12345",
L"1e-12345",
L"1e123",
// All together
L"-123.456e+789"
};
vector<wstring> invalidDecStrs{ L"x123", L"123-", L"1e1.2", L"1-e2" };
for (wstring const& str : validDecStrs)
@@ -141,7 +153,6 @@ namespace CalculatorUnitTests
{
VERIFY_ARE_EQUAL(IDS_ERR_UNK_CH, m_calcEngine->IsNumberInvalid(str, 100, 100, 10 /* Dec */));
}
}
TEST_METHOD(TestDigitGroupingStringToGroupingVector)
@@ -204,14 +215,18 @@ namespace CalculatorUnitTests
VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 3, 0, 0 }, L"1234567890123456", false), L"Verify expanded form non-repeating grouping.");
result = L"12,34,56,78,901,23456";
VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 5, 3, 2, 0 }, L"1234567890123456", false), L"Verify multigroup with repeating grouping.");
VERIFY_ARE_EQUAL(
result, m_calcEngine->GroupDigits(L",", { 5, 3, 2, 0 }, L"1234567890123456", false), L"Verify multigroup with repeating grouping.");
result = L"1234,5678,9012,3456";
VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 4, 0 }, L"1234567890123456", false), L"Verify repeating non-standard grouping.");
result = L"123456,78,901,23456";
VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 5, 3, 2 }, L"1234567890123456", false), L"Verify multigroup non-repeating grouping.");
VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 5, 3, 2, 0, 0 }, L"1234567890123456", false), L"Verify expanded form multigroup non-repeating grouping.");
VERIFY_ARE_EQUAL(
result,
m_calcEngine->GroupDigits(L",", { 5, 3, 2, 0, 0 }, L"1234567890123456", false),
L"Verify expanded form multigroup non-repeating grouping.");
}
private:

View File

@@ -8,7 +8,7 @@ using namespace std;
using namespace CalculationManager;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace CalculatorUnitTests
namespace CalculatorEngineTests
{
TEST_CLASS(CalcInputTest)
{
@@ -173,7 +173,8 @@ namespace CalculatorUnitTests
m_calcInput.Backspace();
m_calcInput.TryToggleSign(true, L"127");
VERIFY_IS_FALSE(m_calcInput.TryAddDigit(9, 10, true, L"127", 8, 2), L"Negative value: verify we cannot add a digit if digit exceeds max value.");
VERIFY_IS_TRUE(m_calcInput.TryAddDigit(8, 10, true, L"127", 8, 2), L"Negative value: verify we can add a digit if digit does not exceed max value.");
VERIFY_IS_TRUE(
m_calcInput.TryAddDigit(8, 10, true, L"127", 8, 2), L"Negative value: verify we can add a digit if digit does not exceed max value.");
}
TEST_METHOD(TryAddDecimalPtEmpty)

View File

@@ -16,7 +16,7 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace CalculatorManagerTest
{
class CalculatorManagerDisplayTester : public ICalcDisplay
class CalculatorManagerDisplayTester final : public ICalcDisplay
{
public:
CalculatorManagerDisplayTester()
@@ -40,11 +40,13 @@ namespace CalculatorManagerTest
{
m_isError = isError;
}
void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const & /*commands*/)
void SetExpressionDisplay(
_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const& tokens,
_Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const& /*commands*/) override
{
m_expression.clear();
unsigned int nTokens = 0;
std::pair <std::wstring, int> currentPair;
std::pair<std::wstring, int> currentPair;
tokens->GetSize(&nTokens);
for (unsigned int i = 0; i < nTokens; ++i)
{
@@ -57,7 +59,7 @@ namespace CalculatorManagerTest
m_memorizedNumberStrings = numbers;
}
void SetParenDisplayText(const std::wstring& parenthesisCount) override
void SetParenthesisNumber(unsigned int parenthesisCount) override
{
m_parenDisplay = parenthesisCount;
}
@@ -84,7 +86,7 @@ namespace CalculatorManagerTest
return m_isError;
}
void OnHistoryItemAdded(_In_ unsigned int /*addedItemIndex */)
void OnHistoryItemAdded(_In_ unsigned int /*addedItemIndex */) override
{
}
@@ -98,12 +100,12 @@ namespace CalculatorManagerTest
return m_maxDigitsCalledCount;
}
void BinaryOperatorReceived()
void BinaryOperatorReceived() override
{
m_binaryOperatorReceivedCallCount++;
}
void MemoryItemChanged(unsigned int /*indexOfMemory*/)
void MemoryItemChanged(unsigned int /*indexOfMemory*/) override
{
}
@@ -115,14 +117,13 @@ namespace CalculatorManagerTest
private:
wstring m_primaryDisplay;
wstring m_expression;
wstring m_parenDisplay;
unsigned int m_parenDisplay;
bool m_isError;
vector<wstring> m_memorizedNumberStrings;
int m_maxDigitsCalledCount;
int m_binaryOperatorReceivedCallCount;
};
class TestDriver
{
private:
@@ -136,8 +137,7 @@ namespace CalculatorManagerTest
m_calculatorManager = calculatorManager;
}
static void Test(wstring expectedPrimary, wstring expectedExpression, Command testCommands[],
bool cleanup = true, bool isScientific = false)
static void Test(wstring expectedPrimary, wstring expectedExpression, Command testCommands[], bool cleanup = true, bool isScientific = false)
{
if (cleanup)
{
@@ -181,24 +181,17 @@ namespace CalculatorManagerTest
TEST_METHOD(CalculatorManagerTestMemory);
TEST_METHOD(CalculatorManagerTestSerialize);
TEST_METHOD(CalculatorManagerTestSerializePrecision);
TEST_METHOD(CalculatorManagerTestSerializeMultiple);
TEST_METHOD(CalculatorManagerTestSerializeDegreeMode);
TEST_METHOD(CalculatorManagerTestSerializeMemory);
TEST_METHOD(CalculatorManagerTestMaxDigitsReached);
TEST_METHOD(CalculatorManagerTestMaxDigitsReached_LeadingDecimal);
TEST_METHOD(CalculatorManagerTestMaxDigitsReached_TrailingDecimal);
// TODO re-enable when cause of failure is determined. Bug 20226670
//TEST_METHOD(CalculatorManagerTestBinaryOperatorReceived);
//TEST_METHOD(CalculatorManagerTestBinaryOperatorReceived_Multiple);
//TEST_METHOD(CalculatorManagerTestBinaryOperatorReceived_LongInput);
// TEST_METHOD(CalculatorManagerTestBinaryOperatorReceived);
// TEST_METHOD(CalculatorManagerTestBinaryOperatorReceived_Multiple);
// TEST_METHOD(CalculatorManagerTestBinaryOperatorReceived_LongInput);
TEST_METHOD_CLEANUP(Cleanup);
private:
static std::shared_ptr<CalculatorManager> m_calculatorManager;
static std::shared_ptr<IResourceProvider> m_resourceProvider;
@@ -234,7 +227,7 @@ namespace CalculatorManagerTest
void TestMaxDigitsReachedScenario(const wstring& constInput)
{
CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester *)m_calculatorDisplayTester.get();
CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester*)m_calculatorDisplayTester.get();
// Make sure we're in a clean state.
VERIFY_ARE_EQUAL(0, pCalculatorDisplay->GetMaxDigitsCalledCount());
@@ -264,35 +257,6 @@ namespace CalculatorManagerTest
// MaxDigitsReached should have been called once
VERIFY_IS_LESS_THAN(0, pCalculatorDisplay->GetMaxDigitsCalledCount());
}
void SerializeAndDeSerialize()
{
auto serializedCommands = m_calculatorManager->SerializeCommands();
auto serializedMemory = m_calculatorManager->GetSerializedMemory();
auto serializedDisplay = m_calculatorManager->GetSerializedPrimaryDisplay();
Cleanup();
m_calculatorManager->DeSerializePrimaryDisplay(serializedDisplay);
m_calculatorManager->DeSerializeMemory(serializedMemory);
m_calculatorManager->DeSerializeCommands(serializedCommands);
}
void VerifyPersistence()
{
auto savedPrimary = m_calculatorDisplayTester->GetPrimaryDisplay();
auto savedExpression = m_calculatorDisplayTester->GetExpression();
auto savedMemory = m_calculatorDisplayTester->GetMemorizedNumbers();
SerializeAndDeSerialize();
VERIFY_ARE_EQUAL(savedPrimary, m_calculatorDisplayTester->GetPrimaryDisplay());
VERIFY_ARE_EQUAL(savedExpression, m_calculatorDisplayTester->GetExpression());
auto loadedMemory = m_calculatorDisplayTester->GetMemorizedNumbers();
VERIFY_ARE_EQUAL(savedMemory.size(), loadedMemory.size());
for (unsigned int i = 0; i < savedMemory.size(); i++)
{
VERIFY_ARE_EQUAL(savedMemory.at(i), loadedMemory.at(i));
}
}
};
std::shared_ptr<CalculatorManager> CalculatorManagerTest::m_calculatorManager;
@@ -342,8 +306,8 @@ namespace CalculatorManagerTest
void CalculatorManagerTest::CalculatorManagerTestStandard()
{
Command commands1[] = { Command::Command1, Command::Command2, Command::Command3,
Command::CommandPNT, Command::Command4, Command::Command5, Command::Command6, Command::CommandNULL };
Command commands1[] = { Command::Command1, Command::Command2, Command::Command3, Command::CommandPNT,
Command::Command4, Command::Command5, Command::Command6, Command::CommandNULL };
TestDriver::Test(L"123.456", L"", commands1);
Command commands2[] = { Command::CommandADD, Command::CommandNULL };
@@ -352,93 +316,78 @@ namespace CalculatorManagerTest
Command commands3[] = { Command::CommandSQRT, Command::CommandNULL };
TestDriver::Test(L"0", L"\x221A(0)", commands3);
Command commands4[] = { Command::Command2, Command::CommandADD, Command::Command3,
Command::CommandEQU, Command::Command4, Command::CommandEQU, Command::CommandNULL };
Command commands4[] = { Command::Command2, Command::CommandADD, Command::Command3, Command::CommandEQU,
Command::Command4, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"7", L"", commands4);
Command commands5[] = { Command::Command4, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"4", L"", commands5);
Command commands6[] = { Command::Command2, Command::Command5, Command::Command6,
Command::CommandSQRT, Command::CommandSQRT, Command::CommandSQRT, Command::CommandNULL };
Command commands6[] = { Command::Command2, Command::Command5, Command::Command6, Command::CommandSQRT,
Command::CommandSQRT, Command::CommandSQRT, Command::CommandNULL };
TestDriver::Test(L"2", L"\x221A(\x221A(\x221A(256)))", commands6);
Command commands7[] = { Command::Command3, Command::CommandSUB, Command::Command6,
Command::CommandEQU, Command::CommandMUL, Command::Command3,
Command::CommandEQU, Command::CommandNULL };
Command commands7[] = { Command::Command3, Command::CommandSUB, Command::Command6, Command::CommandEQU,
Command::CommandMUL, Command::Command3, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"-9", L"", commands7);
Command commands8[] = { Command::Command9, Command::CommandMUL, Command::Command6,
Command::CommandSUB, Command::CommandCENTR, Command::Command8,
Command::CommandEQU, Command::CommandNULL };
Command commands8[] = { Command::Command9, Command::CommandMUL, Command::Command6, Command::CommandSUB,
Command::CommandCENTR, Command::Command8, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"46", L"", commands8);
Command commands9[] = { Command::Command6, Command::CommandMUL, Command::Command6,
Command::CommandPERCENT, Command::CommandEQU, Command::CommandNULL };
Command commands9[] = { Command::Command6, Command::CommandMUL, Command::Command6, Command::CommandPERCENT, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"0.36", L"", commands9);
Command commands10[] = { Command::Command5, Command::Command0, Command::CommandADD,
Command::Command2, Command::Command0, Command::CommandPERCENT,
Command::CommandEQU, Command::CommandNULL };
Command commands10[] = { Command::Command5, Command::Command0, Command::CommandADD, Command::Command2,
Command::Command0, Command::CommandPERCENT, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"60", L"", commands10);
Command commands11[] = { Command::Command4, Command::CommandADD, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"8", L"", commands11);
Command commands12[] = { Command::Command5, Command::CommandADD, Command::CommandMUL,
Command::Command3, Command::CommandNULL };
Command commands12[] = { Command::Command5, Command::CommandADD, Command::CommandMUL, Command::Command3, Command::CommandNULL };
TestDriver::Test(L"3", L"5 \x00D7 ", commands12);
Command commands13[] = { Command::Command1, Command::CommandEXP, Command::CommandSIGN,
Command::Command9, Command::Command9, Command::Command9,
Command::Command9, Command::CommandDIV, Command::Command1,
Command::Command0, Command::CommandEQU, Command::CommandNULL };
Command commands13[] = { Command::Command1, Command::CommandEXP, Command::CommandSIGN, Command::Command9, Command::Command9, Command::Command9,
Command::Command9, Command::CommandDIV, Command::Command1, Command::Command0, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"Overflow", L"1.e-9999 \x00F7 ", commands13);
Command commands14[] = { Command::Command5, Command::Command0, Command::CommandADD,
Command::Command2, Command::Command0, Command::CommandPERCENT,
Command::CommandEQU, Command::CommandNULL };
Command commands14[] = { Command::Command5, Command::Command0, Command::CommandADD, Command::Command2,
Command::Command0, Command::CommandPERCENT, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"60", L"", commands14);
Command commands15[] = { Command::Command0, Command::CommandDIV, Command::Command0,
Command::CommandEQU, Command::CommandNULL };
Command commands15[] = { Command::Command0, Command::CommandDIV, Command::Command0, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"Result is undefined", L"0 \x00F7 ", commands15);
Command commands16[] = { Command::Command1, Command::CommandDIV, Command::Command0,
Command::CommandEQU, Command::CommandNULL };
Command commands16[] = { Command::Command1, Command::CommandDIV, Command::Command0, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"Cannot divide by zero", L"1 \x00F7 ", commands16);
Command commands17[] = { Command::Command1, Command::Command2, Command::CommandADD,
Command::Command5, Command::CommandCENTR, Command::Command2,
Command::CommandADD, Command::CommandNULL };
Command commands17[] = { Command::Command1, Command::Command2, Command::CommandADD, Command::Command5,
Command::CommandCENTR, Command::Command2, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"14", L"12 + 2 + ", commands17);
Command commands18[] = { Command::Command1, Command::Command0, Command::Command0,
Command::CommandSIGN, Command::CommandREC, Command::CommandNULL };
Command commands18[] = { Command::Command1, Command::Command0, Command::Command0, Command::CommandSIGN, Command::CommandREC, Command::CommandNULL };
TestDriver::Test(L"-0.01", L"1/(-100)", commands18);
Command commands19[] = { Command::Command1, Command::Command2, Command::Command3,
Command::CommandBACK, Command::CommandBACK, Command::CommandNULL };
Command commands19[] = { Command::Command1, Command::Command2, Command::Command3, Command::CommandBACK, Command::CommandBACK, Command::CommandNULL };
TestDriver::Test(L"1", L"", commands19);
Command commands20[] = { Command::Command1, Command::Command2, Command::Command3,
Command::CommandBACK, Command::CommandBACK, Command::CommandBACK, Command::CommandNULL };
Command commands20[] = { Command::Command1, Command::Command2, Command::Command3, Command::CommandBACK,
Command::CommandBACK, Command::CommandBACK, Command::CommandNULL };
TestDriver::Test(L"0", L"", commands20);
Command commands21[] = { Command::Command4, Command::CommandSQRT, Command::CommandSUB,
Command::Command2, Command::CommandADD, Command::CommandNULL };
Command commands21[] = { Command::Command4, Command::CommandSQRT, Command::CommandSUB, Command::Command2, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"0", L"\x221A(4) - 2 + ", commands21);
Command commands22[] = { Command::Command1, Command::Command0, Command::Command2, Command::Command4,
Command::CommandSQRT, Command::CommandSUB, Command::Command3, Command::Command2,
Command::CommandADD, Command::CommandNULL };
Command commands22[] = { Command::Command1, Command::Command0, Command::Command2, Command::Command4, Command::CommandSQRT,
Command::CommandSUB, Command::Command3, Command::Command2, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"0", L"\x221A(1024) - 32 + ", commands22);
}
void CalculatorManagerTest::CalculatorManagerTestScientific()
{
Command commands1[] = { Command::Command1, Command::Command2, Command::Command3,
Command::CommandPNT, Command::Command4, Command::Command5, Command::Command6, Command::CommandNULL };
Command commands1[] = { Command::Command1, Command::Command2, Command::Command3, Command::CommandPNT,
Command::Command4, Command::Command5, Command::Command6, Command::CommandNULL };
TestDriver::Test(L"123.456", L"", commands1, true, true);
Command commands2[] = { Command::CommandADD, Command::CommandNULL };
@@ -447,93 +396,78 @@ namespace CalculatorManagerTest
Command commands3[] = { Command::CommandSQRT, Command::CommandNULL };
TestDriver::Test(L"0", L"\x221A(0)", commands3, true, true);
Command commands4[] = { Command::Command1, Command::CommandADD, Command::Command0,
Command::CommandMUL, Command::Command2, Command::CommandEQU, Command::CommandNULL };
Command commands4[] = { Command::Command1, Command::CommandADD, Command::Command0, Command::CommandMUL,
Command::Command2, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"1", L"", commands4, true, true);
Command commands5[] = { Command::Command4, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"4", L"", commands5, true, true);
Command commands6[] = { Command::Command2, Command::Command5, Command::Command6,
Command::CommandSQRT, Command::CommandSQRT, Command::CommandSQRT, Command::CommandNULL };
Command commands6[] = { Command::Command2, Command::Command5, Command::Command6, Command::CommandSQRT,
Command::CommandSQRT, Command::CommandSQRT, Command::CommandNULL };
TestDriver::Test(L"2", L"\x221A(\x221A(\x221A(256)))", commands6, true, true);
Command commands7[] = { Command::Command3, Command::CommandSUB, Command::Command6,
Command::CommandEQU, Command::CommandMUL, Command::Command3, \
Command::CommandADD, Command::CommandNULL };
Command commands7[] = { Command::Command3, Command::CommandSUB, Command::Command6, Command::CommandEQU,
Command::CommandMUL, Command::Command3, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"-9", L"-3 \x00D7 3 + ", commands7, true, true);
Command commands8[] = { Command::Command9, Command::CommandMUL, Command::Command6,
Command::CommandSUB, Command::CommandCENTR, Command::Command8,
Command::CommandMUL, Command::Command2, Command::CommandADD, Command::CommandNULL };
Command commands8[] = { Command::Command9, Command::CommandMUL, Command::Command6, Command::CommandSUB, Command::CommandCENTR,
Command::Command8, Command::CommandMUL, Command::Command2, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"38", L"9 \x00D7 6 - 8 \x00D7 2 + ", commands8, true, true);
Command commands9[] = { Command::Command6, Command::CommandMUL, Command::Command6,
Command::CommandSIGN, Command::CommandSQRT, Command::CommandNULL };
Command commands9[] = { Command::Command6, Command::CommandMUL, Command::Command6, Command::CommandSIGN, Command::CommandSQRT, Command::CommandNULL };
TestDriver::Test(L"Invalid input", L"6 \x00D7 \x221A(-6)", commands9, true, true);
Command commands10[] = { Command::Command5, Command::Command0, Command::CommandADD,
Command::Command2, Command::Command0, Command::CommandREC,
Command::CommandSUB, Command::CommandNULL };
Command commands10[] = { Command::Command5, Command::Command0, Command::CommandADD, Command::Command2,
Command::Command0, Command::CommandREC, Command::CommandSUB, Command::CommandNULL };
TestDriver::Test(L"50.05", L"50 + 1/(20) - ", commands10, true, true);
Command commands11[] = { Command::Command4, Command::CommandADD, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"8", L"", commands11, true, true);
Command commands12[] = { Command::Command5, Command::CommandADD, Command::CommandMUL,
Command::Command3, Command::CommandNULL };
Command commands12[] = { Command::Command5, Command::CommandADD, Command::CommandMUL, Command::Command3, Command::CommandNULL };
TestDriver::Test(L"3", L"5 \x00D7 ", commands12, true, true);
Command commands13[] = { Command::Command1, Command::CommandEXP, Command::CommandSIGN,
Command::Command9, Command::Command9, Command::Command9,
Command::Command9, Command::CommandDIV, Command::Command1,
Command::Command0, Command::CommandEQU, Command::CommandNULL };
Command commands13[] = { Command::Command1, Command::CommandEXP, Command::CommandSIGN, Command::Command9, Command::Command9, Command::Command9,
Command::Command9, Command::CommandDIV, Command::Command1, Command::Command0, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"Overflow", L"1.e-9999 \x00F7 ", commands13, true, true);
Command commands14[] = { Command::Command5, Command::Command0, Command::CommandADD,
Command::Command2, Command::Command0, Command::CommandPERCENT,
Command::CommandEQU, Command::CommandNULL };
Command commands14[] = { Command::Command5, Command::Command0, Command::CommandADD, Command::Command2,
Command::Command0, Command::CommandPERCENT, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"60", L"", commands14, true, true);
Command commands15[] = { Command::Command0, Command::CommandDIV, Command::Command0,
Command::CommandEQU, Command::CommandNULL };
Command commands15[] = { Command::Command0, Command::CommandDIV, Command::Command0, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"Result is undefined", L"0 \x00F7 ", commands15, true, true);
Command commands16[] = { Command::Command1, Command::CommandDIV, Command::Command0,
Command::CommandEQU, Command::CommandNULL };
Command commands16[] = { Command::Command1, Command::CommandDIV, Command::Command0, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"Cannot divide by zero", L"1 \x00F7 ", commands16, true, true);
Command commands17[] = { Command::Command1, Command::Command2, Command::CommandADD,
Command::Command5, Command::CommandCENTR, Command::Command2,
Command::CommandADD, Command::CommandNULL };
Command commands17[] = { Command::Command1, Command::Command2, Command::CommandADD, Command::Command5,
Command::CommandCENTR, Command::Command2, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"14", L"12 + 2 + ", commands17, true, true);
Command commands18[] = { Command::Command1, Command::Command0, Command::Command0,
Command::CommandSIGN, Command::CommandREC, Command::CommandNULL };
Command commands18[] = { Command::Command1, Command::Command0, Command::Command0, Command::CommandSIGN, Command::CommandREC, Command::CommandNULL };
TestDriver::Test(L"-0.01", L"1/(-100)", commands18, true, true);
Command commands19[] = { Command::Command1, Command::Command2, Command::Command3,
Command::CommandBACK, Command::CommandBACK, Command::CommandNULL };
Command commands19[] = { Command::Command1, Command::Command2, Command::Command3, Command::CommandBACK, Command::CommandBACK, Command::CommandNULL };
TestDriver::Test(L"1", L"", commands19, true, true);
Command commands20[] = { Command::Command1, Command::Command2, Command::Command3,
Command::CommandBACK, Command::CommandBACK, Command::CommandBACK, Command::CommandNULL };
Command commands20[] = { Command::Command1, Command::Command2, Command::Command3, Command::CommandBACK,
Command::CommandBACK, Command::CommandBACK, Command::CommandNULL };
TestDriver::Test(L"0", L"", commands20, true, true);
Command commands21[] = { Command::Command4, Command::CommandSQRT, Command::CommandSUB,
Command::Command2, Command::CommandADD, Command::CommandNULL };
Command commands21[] = { Command::Command4, Command::CommandSQRT, Command::CommandSUB, Command::Command2, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"0", L"\x221A(4) - 2 + ", commands21);
Command commands22[] = { Command::Command0, Command::CommandSQRT, Command::CommandNULL };
TestDriver::Test(L"0", L"\x221A(0)", commands22);
Command commands23[] = { Command::Command1, Command::Command0, Command::Command2, Command::Command4,
Command::CommandSQRT, Command::CommandSUB, Command::Command3, Command::Command2,
Command::CommandADD, Command::CommandNULL };
Command commands23[] = { Command::Command1, Command::Command0, Command::Command2, Command::Command4, Command::CommandSQRT,
Command::CommandSUB, Command::Command3, Command::Command2, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"0", L"\x221A(1024) - 32 + ", commands23);
Command commands24[] = { Command::Command2, Command::Command5, Command::Command7,
Command::CommandSQRT, Command::CommandSQRT, Command::CommandSQRT, Command::CommandNULL };
Command commands24[] = { Command::Command2, Command::Command5, Command::Command7, Command::CommandSQRT,
Command::CommandSQRT, Command::CommandSQRT, Command::CommandNULL };
TestDriver::Test(L"2.0009748976330773374220277351385", L"\x221A(\x221A(\x221A(257)))", commands24, true, true);
}
@@ -546,19 +480,17 @@ namespace CalculatorManagerTest
Command commands2[] = { Command::Command5, Command::CommandFAC, Command::CommandNULL };
TestDriver::Test(L"120", L"fact(5)", commands2, true, true);
Command commands3[] = { Command::Command5, Command::CommandPWR, Command::Command2,
Command::CommandADD, Command::CommandNULL };
Command commands3[] = { Command::Command5, Command::CommandPWR, Command::Command2, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"25", L"5 ^ 2 + ", commands3, true, true);
Command commands4[] = { Command::Command8, Command::CommandROOT, Command::Command3,
Command::CommandMUL, Command::CommandNULL };
Command commands4[] = { Command::Command8, Command::CommandROOT, Command::Command3, Command::CommandMUL, Command::CommandNULL };
TestDriver::Test(L"2", L"8 yroot 3 \x00D7 ", commands4, true, true);
Command commands5[] = { Command::Command8, Command::CommandCUB, Command::CommandNULL };
TestDriver::Test(L"512", L"cube(8)", commands5, true, true);
/*
Command commands6[] = { Command::Command8, Command::CommandCUB, Command::CommandCUBEROOT, Command::CommandNULL };
TestDriver::Test(L"8", L"cuberoot(cube(8))", commands6, true, true);*/
/*
Command commands6[] = { Command::Command8, Command::CommandCUB, Command::CommandCUBEROOT, Command::CommandNULL };
TestDriver::Test(L"8", L"cuberoot(cube(8))", commands6, true, true);*/
Command commands7[] = { Command::Command1, Command::Command0, Command::CommandLOG, Command::CommandNULL };
TestDriver::Test(L"1", L"log(10)", commands7, true, true);
@@ -590,61 +522,59 @@ namespace CalculatorManagerTest
Command commands16[] = { Command::Command2, Command::CommandPOWE, Command::CommandNULL };
TestDriver::Test(L"7.389056098930650227230427460575", L"e^(2)", commands16, true, true);
Command commands17[] = { Command::Command5, Command::CommandPWR, Command::Command0,
Command::CommandADD, Command::CommandNULL };
Command commands17[] = { Command::Command5, Command::CommandPWR, Command::Command0, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"1", L"5 ^ 0 + ", commands17);
Command commands18[] = { Command::Command0, Command::CommandPWR, Command::Command0,
Command::CommandADD, Command::CommandNULL };
Command commands18[] = { Command::Command0, Command::CommandPWR, Command::Command0, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"1", L"0 ^ 0 + ", commands18);
Command commands19[] = { Command::Command2, Command::Command7, Command::CommandSIGN, Command::CommandROOT,
Command::Command3, Command::CommandADD, Command::CommandNULL };
Command commands19[] = { Command::Command2, Command::Command7, Command::CommandSIGN, Command::CommandROOT,
Command::Command3, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"-3", L"-27 yroot 3 + ", commands19, true, true);
Command commands20[] = { Command::Command8, Command::CommandPWR, Command::CommandOPENP,
Command::Command2, Command::CommandDIV, Command::Command3, Command::CommandCLOSEP,
Command::CommandSUB, Command::Command4, Command::CommandADD, Command::CommandNULL };
Command commands20[] = { Command::Command8, Command::CommandPWR, Command::CommandOPENP, Command::Command2,
Command::CommandDIV, Command::Command3, Command::CommandCLOSEP, Command::CommandSUB,
Command::Command4, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"0", L"8 ^ (2 \x00F7 3) - 4 + ", commands20, true, true);
Command commands21[] = { Command::Command4, Command::CommandPWR, Command::CommandOPENP,
Command::Command3, Command::CommandDIV, Command::Command2, Command::CommandCLOSEP,
Command::CommandSUB, Command::Command8, Command::CommandADD, Command::CommandNULL };
Command commands21[] = { Command::Command4, Command::CommandPWR, Command::CommandOPENP, Command::Command3,
Command::CommandDIV, Command::Command2, Command::CommandCLOSEP, Command::CommandSUB,
Command::Command8, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"0", L"4 ^ (3 \x00F7 2) - 8 + ", commands21, true, true);
Command commands22[] = { Command::Command1, Command::Command0, Command::CommandPWR, Command::Command1,
Command::CommandPNT, Command::Command2, Command::Command3, Command::Command4, Command::Command5,
Command::Command6, Command::CommandADD, Command::CommandNULL };
Command commands22[] = { Command::Command1, Command::Command0, Command::CommandPWR, Command::Command1, Command::CommandPNT, Command::Command2,
Command::Command3, Command::Command4, Command::Command5, Command::Command6, Command::CommandADD, Command::CommandNULL };
TestDriver::Test(L"17.161687912241792074207286679393", L"10 ^ 1.23456 + ", commands22, true, true);
}
void CalculatorManagerTest::CalculatorManagerTestScientificParenthesis()
{
Command commands1[] = { Command::Command1, Command::CommandADD, Command::CommandOPENP,
Command::CommandADD, Command::Command3, Command::CommandCLOSEP, Command::CommandNULL };
Command commands1[] = { Command::Command1, Command::CommandADD, Command::CommandOPENP, Command::CommandADD,
Command::Command3, Command::CommandCLOSEP, Command::CommandNULL };
TestDriver::Test(L"3", L"1 + (0 + 3)", commands1, true, true);
Command commands2[] = { Command::CommandOPENP, Command::CommandOPENP, Command::Command1,
Command::Command2, Command::CommandCLOSEP, Command::CommandNULL };
Command commands2[] = {
Command::CommandOPENP, Command::CommandOPENP, Command::Command1, Command::Command2, Command::CommandCLOSEP, Command::CommandNULL
};
TestDriver::Test(L"12", L"((12)", commands2, true, true);
Command commands3[] = { Command::Command1, Command::Command2, Command::CommandCLOSEP,
Command::CommandCLOSEP, Command::CommandOPENP, Command::CommandNULL };
Command commands3[] = { Command::Command1, Command::Command2, Command::CommandCLOSEP,
Command::CommandCLOSEP, Command::CommandOPENP, Command::CommandNULL };
TestDriver::Test(L"12", L"(", commands3, true, true);
Command commands4[] = { Command::Command2, Command::CommandOPENP, Command::Command2,
Command::CommandCLOSEP, Command::CommandADD, Command::CommandNULL };
Command commands4[] = {
Command::Command2, Command::CommandOPENP, Command::Command2, Command::CommandCLOSEP, Command::CommandADD, Command::CommandNULL
};
TestDriver::Test(L"2", L"(2) + ", commands4, true, true);
Command commands5[] = { Command::Command2, Command::CommandOPENP, Command::Command2,
Command::CommandCLOSEP, Command::CommandADD, Command::CommandEQU, Command::CommandNULL };
Command commands5[] = { Command::Command2, Command::CommandOPENP, Command::Command2, Command::CommandCLOSEP,
Command::CommandADD, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"4", L"", commands5, true, true);
}
void CalculatorManagerTest::CalculatorManagerTestScientificError()
{
Command commands1[] = { Command::Command1, Command::CommandDIV, Command::Command0,
Command::CommandEQU, Command::CommandNULL };
Command commands1[] = { Command::Command1, Command::CommandDIV, Command::Command0, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"Cannot divide by zero", L"1 \x00F7 ", commands1, true, true);
VERIFY_IS_TRUE(m_calculatorDisplayTester->GetIsError());
@@ -652,8 +582,7 @@ namespace CalculatorManagerTest
TestDriver::Test(L"Invalid input", L"log(-2)", commands2, true, true);
VERIFY_IS_TRUE(m_calculatorDisplayTester->GetIsError());
Command commands3[] = { Command::Command0, Command::CommandDIV, Command::Command0,
Command::CommandEQU, Command::CommandNULL };
Command commands3[] = { Command::Command0, Command::CommandDIV, Command::Command0, Command::CommandEQU, Command::CommandNULL };
TestDriver::Test(L"Result is undefined", L"0 \x00F7 ", commands3, true, true);
VERIFY_IS_TRUE(m_calculatorDisplayTester->GetIsError());
@@ -678,16 +607,13 @@ namespace CalculatorManagerTest
Command commands3[] = { Command::CommandRAD, Command::CommandPI, Command::CommandTAN, Command::CommandNULL };
TestDriver::Test(L"0", L"N/A", commands3, true, true);
Command commands4[] = { Command::CommandGRAD, Command::Command4, Command::Command0, Command::Command0,
Command::CommandSIN, Command::CommandNULL };
Command commands4[] = { Command::CommandGRAD, Command::Command4, Command::Command0, Command::Command0, Command::CommandSIN, Command::CommandNULL };
TestDriver::Test(L"0", L"N/A", commands4, true, true);
Command commands5[] = { Command::CommandGRAD, Command::Command4, Command::Command0, Command::Command0,
Command::CommandCOS, Command::CommandNULL };
Command commands5[] = { Command::CommandGRAD, Command::Command4, Command::Command0, Command::Command0, Command::CommandCOS, Command::CommandNULL };
TestDriver::Test(L"1", L"N/A", commands5, true, true);
Command commands6[] = { Command::CommandGRAD, Command::Command4, Command::Command0, Command::Command0,
Command::CommandTAN, Command::CommandNULL };
Command commands6[] = { Command::CommandGRAD, Command::Command4, Command::Command0, Command::Command0, Command::CommandTAN, Command::CommandNULL };
TestDriver::Test(L"0", L"N/A", commands6, true, true);
}
@@ -728,7 +654,7 @@ namespace CalculatorManagerTest
wstring expectedPrimaryDisplayTestScientific53(L"1");
wstring expectedExpressionDisplayTestScientific53(L"");
CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester *)m_calculatorDisplayTester.get();
CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester*)m_calculatorDisplayTester.get();
wstring resultPrimary = L"";
wstring resultExpression = L"";
@@ -781,7 +707,6 @@ namespace CalculatorManagerTest
expectedMemorizedNumbers.push_back(L"1");
expectedMemorizedNumbers.push_back(L"-1");
bool isEqual = false;
if (memorizedNumbers.size() < expectedMemorizedNumbers.size())
{
@@ -866,182 +791,6 @@ namespace CalculatorManagerTest
m_calculatorManager->MemorizeNumber();
}
void CalculatorManagerTest::CalculatorManagerTestSerializeMemory()
{
Cleanup();
Command commands[] = { Command::Command1, Command::CommandNULL };
ExecuteCommands(commands);
for (int i = 0; i < 110; i++)
{
m_calculatorManager->MemorizeNumber();
}
VerifyPersistence();
}
void CalculatorManagerTest::CalculatorManagerTestSerializeDegreeMode()
{
Cleanup();
Command commands[] = { Command::Command1, Command::CommandRAD, Command::CommandSIN, Command::CommandADD,
Command::Command1, Command::CommandGRAD, Command::CommandCOS, Command::CommandADD,
Command::Command1, Command::CommandDEG, Command::CommandTAN, Command::CommandADD,
Command::CommandNULL };
ExecuteCommands(commands);
VerifyPersistence();
}
// 1 + 2 then serialize and deserialize 3 times
// Check if the values are persisted correctly
void CalculatorManagerTest::CalculatorManagerTestSerializeMultiple()
{
Cleanup();
Command commands[] = { Command::Command1, Command::CommandADD, Command::Command2, Command::CommandNULL };
ExecuteCommands(commands);
VerifyPersistence();
VerifyPersistence();
VerifyPersistence();
}
// Calculate 1/3 then serialize and deserialize
// Multiply by 3 and check if the result is 1 not 0.999999999999999999...
void CalculatorManagerTest::CalculatorManagerTestSerializePrecision()
{
CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester *)m_calculatorDisplayTester.get();
wstring resultPrimary = L"";
wstring resultExpression = L"";
Cleanup();
Command commands[] = { Command::Command1, Command::CommandDIV, Command::Command3, Command::CommandEQU, Command::CommandNULL };
ExecuteCommands(commands);
SerializeAndDeSerialize();
Command commands2[] = { Command::CommandMUL, Command::Command3, Command::CommandEQU, Command::CommandNULL };
ExecuteCommands(commands2);
VERIFY_ARE_EQUAL(StringReference(L"1"), ref new String(pCalculatorDisplay->GetPrimaryDisplay().c_str()));
}
void CalculatorManagerTest::CalculatorManagerTestSerialize()
{
CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester *)m_calculatorDisplayTester.get();
wstring resultPrimary = L"";
wstring resultExpression = L"";
Cleanup();
m_calculatorManager->SendCommand(Command::ModeScientific);
m_calculatorManager->SendCommand(Command::Command1);
m_calculatorManager->SendCommand(Command::CommandADD);
m_calculatorManager->SendCommand(Command::Command2);
m_calculatorManager->SendCommand(Command::CommandMUL);
m_calculatorManager->SendCommand(Command::Command2);
m_calculatorManager->MemorizeNumber();
m_calculatorManager->SendCommand(Command::CommandEQU);
m_calculatorManager->MemorizeNumber();
vector<wstring> memorizedNumbers = pCalculatorDisplay->GetMemorizedNumbers();
wstring primaryDisplay = pCalculatorDisplay->GetPrimaryDisplay();
wstring expressionDisplay = pCalculatorDisplay->GetExpression();
SerializeAndDeSerialize();
vector<wstring> memorizedNumbersAfterDeSerialize = pCalculatorDisplay->GetMemorizedNumbers();
wstring primaryDisplayAfterDeSerialize = pCalculatorDisplay->GetPrimaryDisplay();
wstring expressionDisplayAfterDeSerialize = pCalculatorDisplay->GetExpression();
VERIFY_ARE_EQUAL(primaryDisplay, primaryDisplayAfterDeSerialize);
VERIFY_ARE_EQUAL(expressionDisplay, expressionDisplayAfterDeSerialize);
bool isEqual = false;
if (memorizedNumbers.size() < memorizedNumbersAfterDeSerialize.size())
{
isEqual = std::equal(memorizedNumbers.begin(), memorizedNumbers.end(), memorizedNumbersAfterDeSerialize.begin());
}
else
{
isEqual = std::equal(memorizedNumbersAfterDeSerialize.begin(), memorizedNumbersAfterDeSerialize.end(), memorizedNumbers.begin());
}
VERIFY_IS_TRUE(isEqual);
m_calculatorManager->SendCommand(Command::CommandGRAD);
m_calculatorManager->SendCommand(Command::Command5);
m_calculatorManager->SendCommand(Command::Command0);
m_calculatorManager->SendCommand(Command::CommandSIGN);
m_calculatorManager->SendCommand(Command::CommandMUL);
memorizedNumbers = pCalculatorDisplay->GetMemorizedNumbers();
primaryDisplay = pCalculatorDisplay->GetPrimaryDisplay();
expressionDisplay = pCalculatorDisplay->GetExpression();
SerializeAndDeSerialize();
memorizedNumbersAfterDeSerialize = pCalculatorDisplay->GetMemorizedNumbers();
primaryDisplayAfterDeSerialize = pCalculatorDisplay->GetPrimaryDisplay();
expressionDisplayAfterDeSerialize = pCalculatorDisplay->GetExpression();
VERIFY_ARE_EQUAL(primaryDisplay, primaryDisplayAfterDeSerialize);
VERIFY_ARE_EQUAL(expressionDisplay, expressionDisplayAfterDeSerialize);
isEqual = false;
if (memorizedNumbers.size() < memorizedNumbersAfterDeSerialize.size())
{
isEqual = std::equal(memorizedNumbers.begin(), memorizedNumbers.end(), memorizedNumbersAfterDeSerialize.begin());
}
else
{
isEqual = std::equal(memorizedNumbersAfterDeSerialize.begin(), memorizedNumbersAfterDeSerialize.end(), memorizedNumbers.begin());
}
VERIFY_IS_TRUE(isEqual);
m_calculatorManager->SendCommand(Command::Command1);
m_calculatorManager->SendCommand(Command::Command2);
m_calculatorManager->SendCommand(Command::Command3);
m_calculatorManager->SendCommand(Command::CommandPNT);
m_calculatorManager->SendCommand(Command::Command8);
m_calculatorManager->SendCommand(Command::CommandSIGN);
m_calculatorManager->MemorizeNumber();
m_calculatorManager->SendCommand(Command::Command2);
m_calculatorManager->SendCommand(Command::Command3);
m_calculatorManager->MemorizedNumberAdd(0);
m_calculatorManager->SendCommand(Command::CommandCENTR);
m_calculatorManager->SendCommand(Command::Command3);
m_calculatorManager->SendCommand(Command::Command1);
m_calculatorManager->SendCommand(Command::CommandSIN);
m_calculatorManager->MemorizedNumberSubtract(2);
m_calculatorManager->MemorizedNumberLoad(2);
memorizedNumbers = pCalculatorDisplay->GetMemorizedNumbers();
primaryDisplay = pCalculatorDisplay->GetPrimaryDisplay();
expressionDisplay = pCalculatorDisplay->GetExpression();
SerializeAndDeSerialize();
memorizedNumbersAfterDeSerialize = pCalculatorDisplay->GetMemorizedNumbers();
primaryDisplayAfterDeSerialize = pCalculatorDisplay->GetPrimaryDisplay();
expressionDisplayAfterDeSerialize = pCalculatorDisplay->GetExpression();
VERIFY_ARE_EQUAL(primaryDisplay, primaryDisplayAfterDeSerialize);
VERIFY_ARE_EQUAL(expressionDisplay, expressionDisplayAfterDeSerialize);
isEqual = false;
if (memorizedNumbers.size() < memorizedNumbersAfterDeSerialize.size())
{
isEqual = std::equal(memorizedNumbers.begin(), memorizedNumbers.end(), memorizedNumbersAfterDeSerialize.begin());
}
else
{
isEqual = std::equal(memorizedNumbersAfterDeSerialize.begin(), memorizedNumbersAfterDeSerialize.end(), memorizedNumbers.begin());
}
VERIFY_IS_TRUE(isEqual);
}
// Send 12345678910111213 and verify MaxDigitsReached
void CalculatorManagerTest::CalculatorManagerTestMaxDigitsReached()
{

View File

@@ -7,8 +7,8 @@
<MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.17763.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.18362.0</WindowsTargetPlatformMinVersion>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<UnitTestPlatformVersion Condition="'$(UnitTestPlatformVersion)' == ''">15.0</UnitTestPlatformVersion>
<ProjectSubType>NativeUnitTestProject</ProjectSubType>
@@ -55,50 +55,50 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -134,7 +134,7 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- /utf-8 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
@@ -143,7 +143,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- /utf-8 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
@@ -152,7 +152,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- /utf-8 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
@@ -161,7 +161,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- /utf-8 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
@@ -170,7 +170,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- /utf-8 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
@@ -179,7 +179,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- /utf-8 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
@@ -188,7 +188,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- /utf-8 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
@@ -197,7 +197,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/bigobj /await /std:c++17 /permissive- /Zc:twoPhase- /utf-8 %(AdditionalOptions)</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
@@ -248,6 +248,7 @@
<ClCompile Include="Module.cpp" />
<ClCompile Include="MultiWindowUnitTests.cpp" />
<ClCompile Include="NavCategoryUnitTests.cpp" />
<ClCompile Include="RationalTest.cpp" />
<ClCompile Include="StandardViewModelUnitTests.cpp" />
<ClCompile Include="UnitConverterTest.cpp" />
<ClCompile Include="UnitConverterViewModelUnitTests.cpp" />

View File

@@ -29,6 +29,7 @@
<ClCompile Include="Mocks\CurrencyHttpClient.cpp">
<Filter>Mocks</Filter>
</ClCompile>
<ClCompile Include="RationalTest.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AsyncHelper.h" />

File diff suppressed because it is too large Load Diff

View File

@@ -28,38 +28,40 @@ namespace CalculatorApp
class MockCurrencyHttpClientWithResult : public CurrencyHttpClient
{
public:
MockCurrencyHttpClientWithResult(String^ staticResponse, String^ allRatiosResponse) :
m_staticResponse(staticResponse),
m_allRatiosResponse(allRatiosResponse)
MockCurrencyHttpClientWithResult(String ^ staticResponse, String ^ allRatiosResponse)
: m_staticResponse(staticResponse)
, m_allRatiosResponse(allRatiosResponse)
{
}
IAsyncOperationWithProgress<String^, HttpProgress>^ GetCurrencyMetadata() override
IAsyncOperationWithProgress<String ^, HttpProgress> ^ GetCurrencyMetadata() override
{
return ref new MockAsyncOperationWithProgress(m_staticResponse);
}
IAsyncOperationWithProgress<String^, HttpProgress>^ GetCurrencyRatios() override
IAsyncOperationWithProgress<String ^, HttpProgress> ^ GetCurrencyRatios() override
{
return ref new MockAsyncOperationWithProgress(m_allRatiosResponse);
}
private:
String^ m_staticResponse;
String^ m_allRatiosResponse;
String ^ m_staticResponse;
String ^ m_allRatiosResponse;
};
class MockCurrencyHttpClientThrowsException : public CurrencyHttpClient
{
public:
MockCurrencyHttpClientThrowsException() {}
MockCurrencyHttpClientThrowsException()
{
}
IAsyncOperationWithProgress<String^, HttpProgress>^ GetCurrencyMetadata() override
IAsyncOperationWithProgress<String ^, HttpProgress> ^ GetCurrencyMetadata() override
{
throw ref new NotImplementedException();
}
IAsyncOperationWithProgress<String^, HttpProgress>^ GetCurrencyRatios() override
IAsyncOperationWithProgress<String ^, HttpProgress> ^ GetCurrencyRatios() override
{
throw ref new NotImplementedException();
}
@@ -70,19 +72,28 @@ namespace CalculatorApp
class DataLoadedCallback : public UnitConversionManager::IViewModelCurrencyCallback
{
public:
DataLoadedCallback(task_completion_event<void> tce) :
m_task_completion_event{ tce }
{}
DataLoadedCallback(task_completion_event<void> tce)
: m_task_completion_event{ tce }
{
}
void CurrencyDataLoadFinished(bool /*didLoad*/) override
{
m_task_completion_event.set();
}
void CurrencySymbolsCallback(_In_ const wstring& /*fromSymbol*/, _In_ const wstring& /*toSymbol*/) override {}
void CurrencyRatiosCallback(_In_ const wstring& /*ratioEquality*/, _In_ const wstring& /*accRatioEquality*/) override {}
void CurrencyTimestampCallback(_In_ const std::wstring& /*timestamp*/, bool /*isWeekOldData*/) override {}
void NetworkBehaviorChanged(_In_ int /*newBehavior*/) override {}
void CurrencySymbolsCallback(_In_ const wstring& /*fromSymbol*/, _In_ const wstring& /*toSymbol*/) override
{
}
void CurrencyRatiosCallback(_In_ const wstring& /*ratioEquality*/, _In_ const wstring& /*accRatioEquality*/) override
{
}
void CurrencyTimestampCallback(_In_ const std::wstring& /*timestamp*/, bool /*isWeekOldData*/) override
{
}
void NetworkBehaviorChanged(_In_ int /*newBehavior*/) override
{
}
private:
Concurrency::task_completion_event<void> m_task_completion_event;
@@ -94,7 +105,7 @@ namespace CalculatorUnitTests
const UCM::Category CURRENCY_CATEGORY = { NavCategory::Serialize(ViewMode::Currency), L"Currency", false /*supportsNegative*/ };
unique_ptr<CurrencyDataLoader> MakeLoaderWithResults(String^ staticResponse, String^ allRatiosResponse)
unique_ptr<CurrencyDataLoader> MakeLoaderWithResults(String ^ staticResponse, String ^ allRatiosResponse)
{
auto client = make_unique<MockCurrencyHttpClientWithResult>(staticResponse, allRatiosResponse);
client->SetSourceCurrencyCode(StringReference(DefaultCurrencyCode.data()));
@@ -117,28 +128,28 @@ namespace CalculatorUnitTests
{
try
{
StorageFolder^ localFolder = ApplicationData::Current->LocalCacheFolder;
StorageFile^ file = create_task(localFolder->CreateFileAsync(filename, CreationCollisionOption::ReplaceExisting)).get();
StorageFolder ^ localFolder = ApplicationData::Current->LocalCacheFolder;
StorageFile ^ file = create_task(localFolder->CreateFileAsync(filename, CreationCollisionOption::ReplaceExisting)).get();
create_task(FileIO::WriteTextAsync(file, content)).wait();
return true;
}
catch (Exception^ ex)
catch (Exception ^ ex)
{
return false;
}
}
bool DeleteFileFromLocalCacheFolder(String^ filename)
bool DeleteFileFromLocalCacheFolder(String ^ filename)
{
try
{
StorageFolder^ folder = ApplicationData::Current->LocalCacheFolder;
IAsyncOperation<StorageFile^>^ fileOperation = folder->GetFileAsync(filename);
StorageFile^ file = create_task(fileOperation).get();
StorageFolder ^ folder = ApplicationData::Current->LocalCacheFolder;
IAsyncOperation<StorageFile ^> ^ fileOperation = folder->GetFileAsync(filename);
StorageFile ^ file = create_task(fileOperation).get();
create_task(file->DeleteAsync()).get();
return true;
}
catch (Platform::Exception^ ex)
catch (Platform::Exception ^ ex)
{
// FileNotFoundException is a valid result
return ex->HResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
@@ -164,12 +175,12 @@ namespace CalculatorUnitTests
}
}
void InsertToLocalSettings(String^ key, Object^ value)
void InsertToLocalSettings(String ^ key, Object ^ value)
{
ApplicationData::Current->LocalSettings->Values->Insert(key, value);
}
void RemoveFromLocalSettings(String^ key)
void RemoveFromLocalSettings(String ^ key)
{
// Safe to call, even if the key does not exist.
ApplicationData::Current->LocalSettings->Values->Remove(key);
@@ -188,414 +199,397 @@ namespace CalculatorUnitTests
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename, CurrencyHttpClient::GetRawAllRatiosDataResponse()));
}
TEST_CLASS(CurrencyConverterLoadTests)
{
public:
TEST_METHOD_INITIALIZE(DeleteCacheFiles)
{
DeleteCurrencyCacheFiles();
}
TEST_METHOD(LoadFromCache_Fail_NoCacheKey)
{
RemoveFromLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey);
CurrencyDataLoader loader{ nullptr };
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Fail_OlderThanADay)
{
// Insert 24 hours ago so data is considered stale.
// This will cause the load from cache to fail.
DateTime now = Utils::GetUniversalSystemTime();
DateTime dayOld;
dayOld.UniversalTime = now.UniversalTime - CurrencyDataLoaderConstants::DayDuration - 1;
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, dayOld);
CurrencyDataLoader loader{ nullptr };
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Fail_StaticDataFileDoesNotExist)
{
// Insert current time so data is less than a day old.
// This will cause the load to continue to attempt to load the file.
DateTime now = Utils::GetUniversalSystemTime();
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, now);
VERIFY_IS_TRUE(DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename));
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename, CurrencyHttpClient::GetRawAllRatiosDataResponse()));
CurrencyDataLoader loader{ nullptr };
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Fail_AllRatiosDataFileDoesNotExist)
{
// Insert current time so data is less than a day old.
// This will cause the load to continue to attempt to load the file.
DateTime now = Utils::GetUniversalSystemTime();
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, now);
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient::GetRawStaticDataResponse()));
VERIFY_IS_TRUE(DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename));
CurrencyDataLoader loader{ nullptr };
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Fail_ResponseLanguageChanged)
{
DateTime now = Utils::GetUniversalSystemTime();
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, now);
// Tests always use en-US as response language. Insert a different lang-code to fail the test.
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheLangcodeKey, L"ar-SA");
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient::GetRawStaticDataResponse()));
VERIFY_IS_TRUE(DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename));
CurrencyDataLoader loader{ nullptr };
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Success)
{
StandardCacheSetup();
CurrencyDataLoader loader{ nullptr };
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_TRUE(didLoad);
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromWeb_Fail_ClientIsNullptr)
{
CurrencyDataLoader loader{ nullptr };
bool didLoad = loader.TryLoadDataFromWebAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
}
TEST_METHOD(LoadFromWeb_Fail_WebException)
{
CurrencyDataLoader loader{ make_unique<MockCurrencyHttpClientThrowsException>() };
bool didLoad = loader.TryLoadDataFromWebAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
}
TEST_METHOD(LoadFromWeb_Success)
{
String^ staticResponse = CurrencyHttpClient::GetRawStaticDataResponse();
String^ allRatiosResponse = CurrencyHttpClient::GetRawAllRatiosDataResponse();
unique_ptr<CurrencyDataLoader> loader = MakeLoaderWithResults(staticResponse, allRatiosResponse);
bool didLoad = loader->TryLoadDataFromWebAsync().get();
VERIFY_IS_TRUE(didLoad);
VERIFY_IS_TRUE(loader->LoadFinished());
VERIFY_IS_TRUE(loader->LoadedFromWeb());
}
TEST_METHOD(Load_Success_LoadedFromCache)
{
StandardCacheSetup();
CurrencyDataLoader loader{ nullptr };
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
}
TEST_METHOD(Load_Success_LoadedFromWeb)
{
// Insert 24 hours ago so data is considered stale.
// This will cause the load from cache to fail.
DateTime now = Utils::GetUniversalSystemTime();
DateTime dayOld;
dayOld.UniversalTime = now.UniversalTime - CurrencyDataLoaderConstants::DayDuration - 1;
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, dayOld);
String^ staticResponse = CurrencyHttpClient::GetRawStaticDataResponse();
String^ allRatiosResponse = CurrencyHttpClient::GetRawAllRatiosDataResponse();
unique_ptr<CurrencyDataLoader> loader = MakeLoaderWithResults(staticResponse, allRatiosResponse);
auto data_loaded_event = task_completion_event<void>();
loader->SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader->LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader->LoadFinished());
VERIFY_IS_FALSE(loader->LoadedFromCache());
VERIFY_IS_TRUE(loader->LoadedFromWeb());
}
};
TEST_CLASS(CurrencyConverterUnitTests)
{
const UCM::Unit GetUnit(const vector<UCM::Unit>& unitList, const wstring& target)
{
return *find_if(begin(unitList), end(unitList), [&target](const UCM::Unit& u) { return u.abbreviation == target; });
}
TEST_METHOD(Loaded_LoadOrderedUnits)
{
StandardCacheSetup();
CurrencyDataLoader loader{ nullptr };
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
const UCM::Unit eurUnit = GetUnit(unitList, L"EUR");
VERIFY_ARE_EQUAL(wstring(L"United States - Dollar"), usdUnit.name);
VERIFY_ARE_EQUAL(wstring(L"USD"), usdUnit.abbreviation);
VERIFY_ARE_EQUAL(wstring(L"Europe - Euro"), eurUnit.name);
VERIFY_ARE_EQUAL(wstring(L"EUR"), eurUnit.abbreviation);
}
TEST_METHOD(Loaded_LoadOrderedRatios)
{
StandardCacheSetup();
CurrencyDataLoader loader{ nullptr };
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
const UCM::Unit eurUnit = GetUnit(unitList, L"EUR");
unordered_map<UCM::Unit, UCM::ConversionData, UCM::UnitHash> ratios = loader.LoadOrderedRatios(usdUnit);
VERIFY_ARE_EQUAL(size_t{ 2 }, ratios.size());
UCM::ConversionData usdRatioData = ratios[usdUnit];
VERIFY_IS_TRUE((std::abs(1.0 - usdRatioData.ratio) < 1e-1));
UCM::ConversionData eurRatioData = ratios[eurUnit];
VERIFY_IS_TRUE((std::abs(0.920503 - eurRatioData.ratio) < 1e-6));
}
TEST_METHOD(Loaded_GetCurrencySymbols_Valid)
{
StandardCacheSetup();
CurrencyDataLoader loader{ nullptr };
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
const UCM::Unit eurUnit = GetUnit(unitList, L"EUR");
const pair<wstring, wstring> symbols = loader.GetCurrencySymbols(usdUnit, eurUnit);
VERIFY_ARE_EQUAL(wstring(L"$"), symbols.first);
VERIFY_ARE_EQUAL(wstring(L"\x20ac"), symbols.second); // €
}
TEST_METHOD(Loaded_GetCurrencySymbols_Invalid)
{
StandardCacheSetup();
CurrencyDataLoader loader{ nullptr };
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
const UCM::Unit fakeUnit1 = {
1, L"fakeUnit1", L"FUD1", false, false, false
};
const UCM::Unit fakeUnit2 = {
2, L"fakeUnit2", L"FUD2", false, false, false
};
pair<wstring, wstring> symbols = loader.GetCurrencySymbols(fakeUnit1, fakeUnit2);
VERIFY_ARE_EQUAL(wstring(L""), wstring(symbols.first.c_str()));
VERIFY_ARE_EQUAL(wstring(L""), wstring(symbols.second.c_str()));
// Verify that when only one unit is valid, both symbols return as empty string.
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
symbols = loader.GetCurrencySymbols(fakeUnit1, usdUnit);
VERIFY_ARE_EQUAL(wstring(L""), symbols.first);
VERIFY_ARE_EQUAL(wstring(L""), symbols.second);
symbols = loader.GetCurrencySymbols(usdUnit, fakeUnit1);
VERIFY_ARE_EQUAL(wstring(L""), symbols.first);
VERIFY_ARE_EQUAL(wstring(L""), symbols.second);
}
TEST_METHOD(Loaded_GetCurrencyRatioEquality_Valid)
{
StandardCacheSetup();
CurrencyDataLoader loader{ nullptr };
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
const UCM::Unit eurUnit = GetUnit(unitList, L"EUR");
const pair<wstring, wstring> ratio = loader.GetCurrencyRatioEquality(usdUnit, eurUnit);
VERIFY_ARE_EQUAL(wstring(L"1 USD = 0.9205 EUR"), ratio.first);
VERIFY_ARE_EQUAL(wstring(L"1 United States Dollar = 0.9205 Europe Euro"), ratio.second);
}
TEST_METHOD(Loaded_GetCurrencyRatioEquality_Invalid)
{
StandardCacheSetup();
CurrencyDataLoader loader{ nullptr };
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
const UCM::Unit fakeUnit1 = {
1, L"fakeUnit1", L"fakeCountry1", L"FUD1", false, false, false
};
const UCM::Unit fakeUnit2 = {
2, L"fakeUnit2", L"fakeCountry2", L"FUD2", false, false, false
};
pair<wstring, wstring> ratio = loader.GetCurrencyRatioEquality(fakeUnit1, fakeUnit2);
VERIFY_ARE_EQUAL(wstring(L""), ratio.first);
VERIFY_ARE_EQUAL(wstring(L""), ratio.second);
// Verify that when only one unit is valid, both symbols return as empty string.
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
ratio = loader.GetCurrencyRatioEquality(fakeUnit1, usdUnit);
VERIFY_ARE_EQUAL(wstring(L""), ratio.first);
VERIFY_ARE_EQUAL(wstring(L""), ratio.second);
ratio = loader.GetCurrencyRatioEquality(usdUnit, fakeUnit1);
VERIFY_ARE_EQUAL(wstring(L""), ratio.first);
VERIFY_ARE_EQUAL(wstring(L""), ratio.second);
}
};
TEST_CLASS(CurrencyConverterLoadTests){ public: TEST_METHOD_INITIALIZE(DeleteCacheFiles){ DeleteCurrencyCacheFiles();
}
TEST_METHOD(LoadFromCache_Fail_NoCacheKey)
{
RemoveFromLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey);
CurrencyDataLoader loader(nullptr, L"en-US");
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Fail_OlderThanADay)
{
// Insert 24 hours ago so data is considered stale.
// This will cause the load from cache to fail.
DateTime now = Utils::GetUniversalSystemTime();
DateTime dayOld;
dayOld.UniversalTime = now.UniversalTime - CurrencyDataLoaderConstants::DayDuration - 1;
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, dayOld);
CurrencyDataLoader loader(nullptr, L"en-US");
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Fail_StaticDataFileDoesNotExist)
{
// Insert current time so data is less than a day old.
// This will cause the load to continue to attempt to load the file.
DateTime now = Utils::GetUniversalSystemTime();
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, now);
VERIFY_IS_TRUE(DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename));
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename, CurrencyHttpClient::GetRawAllRatiosDataResponse()));
CurrencyDataLoader loader(nullptr, L"en-US");
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Fail_AllRatiosDataFileDoesNotExist)
{
// Insert current time so data is less than a day old.
// This will cause the load to continue to attempt to load the file.
DateTime now = Utils::GetUniversalSystemTime();
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, now);
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient::GetRawStaticDataResponse()));
VERIFY_IS_TRUE(DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename));
CurrencyDataLoader loader(nullptr, L"en-US");
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Fail_ResponseLanguageChanged)
{
DateTime now = Utils::GetUniversalSystemTime();
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, now);
// Tests always use en-US as response language. Insert a different lang-code to fail the test.
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheLangcodeKey, L"ar-SA");
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient::GetRawStaticDataResponse()));
VERIFY_IS_TRUE(DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename));
CurrencyDataLoader loader(nullptr, L"en-US");
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromCache_Success)
{
StandardCacheSetup();
CurrencyDataLoader loader(nullptr, L"en-US");
bool didLoad = loader.TryLoadDataFromCacheAsync().get();
VERIFY_IS_TRUE(didLoad);
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
}
TEST_METHOD(LoadFromWeb_Fail_ClientIsNullptr)
{
CurrencyDataLoader loader(nullptr, L"en-US");
bool didLoad = loader.TryLoadDataFromWebAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
}
TEST_METHOD(LoadFromWeb_Fail_WebException)
{
CurrencyDataLoader loader(make_unique<MockCurrencyHttpClientThrowsException>(), L"en-US");
bool didLoad = loader.TryLoadDataFromWebAsync().get();
VERIFY_IS_FALSE(didLoad);
VERIFY_IS_FALSE(loader.LoadFinished());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
}
TEST_METHOD(LoadFromWeb_Success)
{
String ^ staticResponse = CurrencyHttpClient::GetRawStaticDataResponse();
String ^ allRatiosResponse = CurrencyHttpClient::GetRawAllRatiosDataResponse();
unique_ptr<CurrencyDataLoader> loader = MakeLoaderWithResults(staticResponse, allRatiosResponse);
bool didLoad = loader->TryLoadDataFromWebAsync().get();
VERIFY_IS_TRUE(didLoad);
VERIFY_IS_TRUE(loader->LoadFinished());
VERIFY_IS_TRUE(loader->LoadedFromWeb());
}
TEST_METHOD(Load_Success_LoadedFromCache)
{
StandardCacheSetup();
CurrencyDataLoader loader(nullptr, L"en-US");
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
}
TEST_METHOD(Load_Success_LoadedFromWeb)
{
// Insert 24 hours ago so data is considered stale.
// This will cause the load from cache to fail.
DateTime now = Utils::GetUniversalSystemTime();
DateTime dayOld;
dayOld.UniversalTime = now.UniversalTime - CurrencyDataLoaderConstants::DayDuration - 1;
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, dayOld);
String ^ staticResponse = CurrencyHttpClient::GetRawStaticDataResponse();
String ^ allRatiosResponse = CurrencyHttpClient::GetRawAllRatiosDataResponse();
unique_ptr<CurrencyDataLoader> loader = MakeLoaderWithResults(staticResponse, allRatiosResponse);
auto data_loaded_event = task_completion_event<void>();
loader->SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader->LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader->LoadFinished());
VERIFY_IS_FALSE(loader->LoadedFromCache());
VERIFY_IS_TRUE(loader->LoadedFromWeb());
}
}
;
TEST_CLASS(CurrencyConverterUnitTests){ const UCM::Unit GetUnit(const vector<UCM::Unit>& unitList, const wstring& target){
return *find_if(begin(unitList), end(unitList), [&target](const UCM::Unit& u) { return u.abbreviation == target; });
}
TEST_METHOD(Loaded_LoadOrderedUnits)
{
StandardCacheSetup();
CurrencyDataLoader loader(nullptr, L"en-US");
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
const UCM::Unit eurUnit = GetUnit(unitList, L"EUR");
VERIFY_ARE_EQUAL(wstring(L"United States - Dollar"), usdUnit.name);
VERIFY_ARE_EQUAL(wstring(L"USD"), usdUnit.abbreviation);
VERIFY_ARE_EQUAL(wstring(L"Europe - Euro"), eurUnit.name);
VERIFY_ARE_EQUAL(wstring(L"EUR"), eurUnit.abbreviation);
}
TEST_METHOD(Loaded_LoadOrderedRatios)
{
StandardCacheSetup();
CurrencyDataLoader loader(nullptr, L"en-US");
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
const UCM::Unit eurUnit = GetUnit(unitList, L"EUR");
unordered_map<UCM::Unit, UCM::ConversionData, UCM::UnitHash> ratios = loader.LoadOrderedRatios(usdUnit);
VERIFY_ARE_EQUAL(size_t{ 2 }, ratios.size());
UCM::ConversionData usdRatioData = ratios[usdUnit];
VERIFY_IS_TRUE((std::abs(1.0 - usdRatioData.ratio) < 1e-1));
UCM::ConversionData eurRatioData = ratios[eurUnit];
VERIFY_IS_TRUE((std::abs(0.920503 - eurRatioData.ratio) < 1e-6));
}
TEST_METHOD(Loaded_GetCurrencySymbols_Valid)
{
StandardCacheSetup();
CurrencyDataLoader loader(nullptr, L"en-US");
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
const UCM::Unit eurUnit = GetUnit(unitList, L"EUR");
const pair<wstring, wstring> symbols = loader.GetCurrencySymbols(usdUnit, eurUnit);
VERIFY_ARE_EQUAL(wstring(L"$"), symbols.first);
VERIFY_ARE_EQUAL(wstring(L"\x20ac"), symbols.second); // €
}
TEST_METHOD(Loaded_GetCurrencySymbols_Invalid)
{
StandardCacheSetup();
CurrencyDataLoader loader(nullptr, L"en-US");
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
const UCM::Unit fakeUnit1 = { 1, L"fakeUnit1", L"FUD1", false, false, false };
const UCM::Unit fakeUnit2 = { 2, L"fakeUnit2", L"FUD2", false, false, false };
pair<wstring, wstring> symbols = loader.GetCurrencySymbols(fakeUnit1, fakeUnit2);
VERIFY_ARE_EQUAL(wstring(L""), wstring(symbols.first.c_str()));
VERIFY_ARE_EQUAL(wstring(L""), wstring(symbols.second.c_str()));
// Verify that when only one unit is valid, both symbols return as empty string.
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
symbols = loader.GetCurrencySymbols(fakeUnit1, usdUnit);
VERIFY_ARE_EQUAL(wstring(L""), symbols.first);
VERIFY_ARE_EQUAL(wstring(L""), symbols.second);
symbols = loader.GetCurrencySymbols(usdUnit, fakeUnit1);
VERIFY_ARE_EQUAL(wstring(L""), symbols.first);
VERIFY_ARE_EQUAL(wstring(L""), symbols.second);
}
TEST_METHOD(Loaded_GetCurrencyRatioEquality_Valid)
{
StandardCacheSetup();
CurrencyDataLoader loader(nullptr, L"en-US");
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
const UCM::Unit eurUnit = GetUnit(unitList, L"EUR");
const pair<wstring, wstring> ratio = loader.GetCurrencyRatioEquality(usdUnit, eurUnit);
VERIFY_ARE_EQUAL(wstring(L"1 USD = 0.9205 EUR"), ratio.first);
VERIFY_ARE_EQUAL(wstring(L"1 United States Dollar = 0.9205 Europe Euro"), ratio.second);
}
TEST_METHOD(Loaded_GetCurrencyRatioEquality_Invalid)
{
StandardCacheSetup();
CurrencyDataLoader loader(nullptr, L"en-US");
auto data_loaded_event = task_completion_event<void>();
loader.SetViewModelCallback(make_shared<DataLoadedCallback>(data_loaded_event));
auto data_loaded_task = create_task(data_loaded_event);
loader.LoadData();
data_loaded_task.wait();
VERIFY_IS_TRUE(loader.LoadFinished());
VERIFY_IS_TRUE(loader.LoadedFromCache());
VERIFY_IS_FALSE(loader.LoadedFromWeb());
const UCM::Unit fakeUnit1 = { 1, L"fakeUnit1", L"fakeCountry1", L"FUD1", false, false, false };
const UCM::Unit fakeUnit2 = { 2, L"fakeUnit2", L"fakeCountry2", L"FUD2", false, false, false };
pair<wstring, wstring> ratio = loader.GetCurrencyRatioEquality(fakeUnit1, fakeUnit2);
VERIFY_ARE_EQUAL(wstring(L""), ratio.first);
VERIFY_ARE_EQUAL(wstring(L""), ratio.second);
// Verify that when only one unit is valid, both symbols return as empty string.
vector<UCM::Unit> unitList = loader.LoadOrderedUnits(CURRENCY_CATEGORY);
VERIFY_ARE_EQUAL(size_t{ 2 }, unitList.size());
const UCM::Unit usdUnit = GetUnit(unitList, L"USD");
ratio = loader.GetCurrencyRatioEquality(fakeUnit1, usdUnit);
VERIFY_ARE_EQUAL(wstring(L""), ratio.first);
VERIFY_ARE_EQUAL(wstring(L""), ratio.second);
ratio = loader.GetCurrencyRatioEquality(usdUnit, fakeUnit1);
VERIFY_ARE_EQUAL(wstring(L""), ratio.first);
VERIFY_ARE_EQUAL(wstring(L""), ratio.second);
}
}
;
}

File diff suppressed because it is too large Load Diff

View File

@@ -38,8 +38,7 @@ namespace DateCalculationUnitTests
}
// Returns long date format for a date
static Platform::String^ GetLongDate(SYSTEMTIME systemTime)
{
static Platform::String ^ GetLongDate(SYSTEMTIME systemTime) {
auto formatter = ref new Windows::Globalization::DateTimeFormatting::DateTimeFormatter(
L"longdate",
Windows::Globalization::ApplicationLanguages::Languages,

View File

@@ -8,9 +8,9 @@
namespace CalculatorUnitTests
{
#define StandardModePrecision 16
#define ScientificModePrecision 32
#define ProgrammerModePrecision 64
#define StandardModePrecision 16
#define ScientificModePrecision 32
#define ProgrammerModePrecision 64
typedef struct item
{
@@ -19,7 +19,8 @@ namespace CalculatorUnitTests
std::wstring expectedExpressions;
} TESTITEM;
namespace UtfUtils {
namespace UtfUtils
{
constexpr wchar_t LRE = 0x202a; // Left-to-Right Embedding
constexpr wchar_t PDF = 0x202c; // Pop Directional Formatting
constexpr wchar_t LRO = 0x202d; // Left-to-Right Override
@@ -27,71 +28,70 @@ namespace CalculatorUnitTests
}
}
#define VERIFY_THROWS_EXPECTEDEXCEPTION(__operation, __exception) \
{ \
bool __exceptionHit = false; \
try \
{ \
__operation; \
} \
catch(__exception) \
{ \
__exceptionHit = true; \
} \
\
if (!__exceptionHit) \
{ \
Assert::Fail(L"Expected exception was not caught"); \
} \
#define VERIFY_THROWS_EXPECTEDEXCEPTION(__operation, __exception) \
{ \
bool __exceptionHit = false; \
try \
{ \
__operation; \
} \
catch (__exception) \
{ \
__exceptionHit = true; \
} \
\
if (!__exceptionHit) \
{ \
Assert::Fail(L"Expected exception was not caught"); \
} \
}
#define VERIFY_IS_NULL(__operation, ...) \
{ \
Assert::IsTrue(nullptr == __operation, __VA_ARGS__); \
} \
#define VERIFY_IS_NULL(__operation, ...) \
{ \
Assert::IsTrue(nullptr == __operation, __VA_ARGS__); \
}
#define VERIFY_IS_NOT_NULL(__operation, ...) \
{ \
Assert::IsTrue(nullptr != __operation, __VA_ARGS__); \
} \
#define VERIFY_IS_NOT_NULL(__operation, ...) \
{ \
Assert::IsTrue(nullptr != __operation, __VA_ARGS__); \
}
#define VERIFY_IS_LESS_THAN(__expectedLess, __expectedGreater, ...) \
{ \
Assert::IsTrue(__expectedLess < __expectedGreater, __VA_ARGS__); \
} \
#define VERIFY_IS_LESS_THAN(__expectedLess, __expectedGreater, ...) \
{ \
Assert::IsTrue(__expectedLess < __expectedGreater, __VA_ARGS__); \
}
#define VERIFY_IS_GREATER_THAN(__expectedGreater, __expectedLess, ...) \
{ \
Assert::IsTrue(__expectedGreater > __expectedLess, __VA_ARGS__); \
} \
#define VERIFY_IS_GREATER_THAN(__expectedGreater, __expectedLess, ...) \
{ \
Assert::IsTrue(__expectedGreater > __expectedLess, __VA_ARGS__); \
}
#define VERIFY_ARE_EQUAL(__f1, __f2, ...) \
{ \
Assert::IsTrue(__f1 == __f2, __VA_ARGS__); \
} \
#define VERIFY_ARE_EQUAL(__f1, __f2, ...) \
{ \
Assert::IsTrue(__f1 == __f2, __VA_ARGS__); \
}
#define VERIFY_ARE_NOT_EQUAL(__f1, __f2, ...) \
{ \
Assert::IsTrue(__f1 != __f2, __VA_ARGS__); \
} \
#define VERIFY_ARE_NOT_EQUAL(__f1, __f2, ...) \
{ \
Assert::IsTrue(__f1 != __f2, __VA_ARGS__); \
}
#define VERIFY_IS_TRUE(__operation, ...) \
{ \
Assert::IsTrue(__operation, __VA_ARGS__); \
} \
#define VERIFY_IS_TRUE(__operation, ...) \
{ \
Assert::IsTrue(__operation, __VA_ARGS__); \
}
#define VERIFY_IS_FALSE(__operation, ...) \
{ \
Assert::IsFalse(__operation, __VA_ARGS__); \
} \
#define VERIFY_IS_FALSE(__operation, ...) \
{ \
Assert::IsFalse(__operation, __VA_ARGS__); \
}
#define VERIFY_IS_LESS_THAN_OR_EQUAL(__expectedLess, __expectedGreater, ...) \
{ \
Assert::IsTrue(__expectedLess <= __expectedGreater, __VA_ARGS__); \
} \
#define VERIFY_IS_GREATER_THAN_OR_EQUAL(__expectedGreater, __expectedLess, ...) \
{ \
Assert::IsTrue(__expectedGreater >= __expectedLess, __VA_ARGS__); \
} \
#define VERIFY_IS_LESS_THAN_OR_EQUAL(__expectedLess, __expectedGreater, ...) \
{ \
Assert::IsTrue(__expectedLess <= __expectedGreater, __VA_ARGS__); \
}
#define VERIFY_IS_GREATER_THAN_OR_EQUAL(__expectedGreater, __expectedLess, ...) \
{ \
Assert::IsTrue(__expectedGreater >= __expectedLess, __VA_ARGS__); \
}

View File

@@ -39,8 +39,8 @@ namespace CalculatorFunctionalTests
TEST_METHOD(TestHistoryEmpty);
private:
HistoryViewModel^ m_historyViewModel;
StandardCalculatorViewModel^ m_standardViewModel;
HistoryViewModel ^ m_historyViewModel;
StandardCalculatorViewModel ^ m_standardViewModel;
void Initialize()
{
@@ -59,9 +59,9 @@ namespace CalculatorFunctionalTests
m_standardViewModel->m_standardCalculatorManager.Reset();
}
bool IsHistoryContainerEmpty(_In_ String^ historyContainerKey)
bool IsHistoryContainerEmpty(_In_ String ^ historyContainerKey)
{
ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings;
ApplicationDataContainer ^ localSettings = ApplicationData::Current->LocalSettings;
return !(localSettings->Containers->HasKey(historyContainerKey));
}
@@ -75,7 +75,7 @@ namespace CalculatorFunctionalTests
{
m_standardViewModel->SetHistoryExpressionDisplay(e->GetTokens(), e->GetCommands());
m_standardViewModel->SetExpressionDisplay(e->GetTokens(), e->GetCommands());
m_standardViewModel->SetPrimaryDisplay(e->Result->Data(), false/*IsError*/);
m_standardViewModel->SetPrimaryDisplay(e->Result->Data(), false /*IsError*/);
m_standardViewModel->IsFToEEnabled = false;
}
@@ -89,8 +89,8 @@ namespace CalculatorFunctionalTests
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandEQU);
int sizeAfterItemAdd = m_historyViewModel->ItemSize;
auto historyItem = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(0);
String^ expression = UtfUtils::LRO + L"1 + 8 =" + UtfUtils::PDF;
String ^result = StringReference(L"9");
String ^ expression = UtfUtils::LRO + L"1 + 8 =" + UtfUtils::PDF;
String ^ result = StringReference(L"9");
VERIFY_ARE_EQUAL(initialSize + 1, sizeAfterItemAdd);
VERIFY_ARE_EQUAL(expression, StringReference(historyItem->historyItemVector.expression.c_str()));
VERIFY_ARE_EQUAL(result, StringReference(historyItem->historyItemVector.result.c_str()));
@@ -112,9 +112,9 @@ namespace CalculatorFunctionalTests
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandEQU);
}
VERIFY_ARE_EQUAL((size_t)m_historyViewModel->ItemSize, m_standardViewModel->m_standardCalculatorManager.MaxHistorySize());
String ^expression = UtfUtils::LRO + L"1 + 1 =" + UtfUtils::PDF;
String ^ expression = UtfUtils::LRO + L"1 + 1 =" + UtfUtils::PDF;
int output = 2;
String ^result = output.ToString();
String ^ result = output.ToString();
auto historyItem = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(0);
VERIFY_ARE_EQUAL(expression, StringReference(historyItem->historyItemVector.expression.c_str()));
VERIFY_ARE_EQUAL(result, StringReference(historyItem->historyItemVector.result.c_str()));
@@ -167,7 +167,7 @@ namespace CalculatorFunctionalTests
wstring expr = L"1 + " + wstring(i.ToString()->Data()) + L" =";
expr = UtfUtils::LRO + expr + UtfUtils::PDF;
int output = 1 + i;
String ^result = output.ToString();
String ^ result = output.ToString();
auto historyItem = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(i);
VERIFY_ARE_EQUAL(expr, historyItem->historyItemVector.expression);
VERIFY_ARE_EQUAL(result, StringReference(historyItem->historyItemVector.result.c_str()));
@@ -181,7 +181,7 @@ namespace CalculatorFunctionalTests
wstring expr = L"1 + " + wstring(i.ToString()->Data()) + L" =";
expr = UtfUtils::LRO + expr + UtfUtils::PDF;
int output = 1 + i;
String ^result = output.ToString();
String ^ result = output.ToString();
auto historyItem = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(i);
VERIFY_ARE_EQUAL(expr, historyItem->historyItemVector.expression);
VERIFY_ARE_EQUAL(result, StringReference(historyItem->historyItemVector.result.c_str()));
@@ -221,7 +221,11 @@ namespace CalculatorFunctionalTests
m_historyViewModel->SaveHistory();
m_historyViewModel->ReloadHistory(ViewMode::Scientific);
auto itemAfterSerializeDeserialize = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(0);
VERIFY_IS_TRUE((itemBeforeSerializeDeserialize->historyItemVector.expression == itemAfterSerializeDeserialize->historyItemVector.expression) && (itemBeforeSerializeDeserialize->historyItemVector.result == itemAfterSerializeDeserialize->historyItemVector.result) && (itemBeforeSerializeDeserialize->historyItemVector.spCommands == itemAfterSerializeDeserialize->historyItemVector.spCommands) && (itemBeforeSerializeDeserialize->historyItemVector.spTokens == itemAfterSerializeDeserialize->historyItemVector.spTokens));
VERIFY_IS_TRUE(
(itemBeforeSerializeDeserialize->historyItemVector.expression == itemAfterSerializeDeserialize->historyItemVector.expression)
&& (itemBeforeSerializeDeserialize->historyItemVector.result == itemAfterSerializeDeserialize->historyItemVector.result)
&& (itemBeforeSerializeDeserialize->historyItemVector.spCommands == itemAfterSerializeDeserialize->historyItemVector.spCommands)
&& (itemBeforeSerializeDeserialize->historyItemVector.spTokens == itemAfterSerializeDeserialize->historyItemVector.spTokens));
Cleanup();
}
@@ -249,7 +253,7 @@ namespace CalculatorFunctionalTests
wstring expr = L"1 + 8 =";
// add double quotes around the expression
expr = UtfUtils::LRO + expr + UtfUtils::PDF;
String ^result = StringReference(L"9");
String ^ result = StringReference(L"9");
int itemsAfterSaveAndReload = m_historyViewModel->ItemSize;
auto historyItem = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(0);
@@ -263,11 +267,12 @@ namespace CalculatorFunctionalTests
void HistoryItemWithPrettyExpressions()
{
Initialize();
Command commands[] = { Command::CommandSIN, Command::CommandCOS, Command::CommandTAN, Command::CommandASIN, Command::CommandACOS, Command::CommandATAN };
Command commands[] = { Command::CommandSIN, Command::CommandCOS, Command::CommandTAN,
Command::CommandASIN, Command::CommandACOS, Command::CommandATAN };
Command mode[] = { Command::CommandDEG, Command::CommandRAD, Command::CommandGRAD };
int modes = sizeof(mode) / sizeof(Command);
int commandsSize = sizeof(commands) / sizeof(Command);
ResourceLoader^ m_uiResourceLoader = ResourceLoader::GetForViewIndependentUse(L"CEngineStrings");
ResourceLoader ^ m_uiResourceLoader = ResourceLoader::GetForViewIndependentUse(L"CEngineStrings");
int itemIndex = 0;
int commandResource = 67;
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::ModeScientific);
@@ -280,7 +285,7 @@ namespace CalculatorFunctionalTests
m_standardViewModel->m_standardCalculatorManager.SendCommand(commands[command]);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandEQU);
auto historyItem = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(itemIndex);
String^ expression = m_uiResourceLoader->GetString(commandResource.ToString());
String ^ expression = m_uiResourceLoader->GetString(commandResource.ToString());
expression += L"( 1 ) =";
wstring expr = wstring(expression->Data());
expr = UtfUtils::LRO + expr + UtfUtils::PDF;
@@ -295,7 +300,7 @@ namespace CalculatorFunctionalTests
void HistoryItemWithPrettyExpressionsMixedRadix()
{
Initialize();
ResourceLoader^ m_uiResourceLoader = ResourceLoader::GetForViewIndependentUse(L"CEngineStrings");
ResourceLoader ^ m_uiResourceLoader = ResourceLoader::GetForViewIndependentUse(L"CEngineStrings");
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::ModeScientific);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandDEG);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::Command1);
@@ -310,7 +315,7 @@ namespace CalculatorFunctionalTests
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandSIN);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandEQU);
auto historyItem = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(0);
String^ expression = m_uiResourceLoader->GetString(L"67");
String ^ expression = m_uiResourceLoader->GetString(L"67");
expression += L"( 1 ) + ";
expression += m_uiResourceLoader->GetString(L"73");
expression += L"( 1 ) + ";
@@ -334,9 +339,10 @@ namespace CalculatorFunctionalTests
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::Command3);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandEQU);
auto historyItem = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(0);
String^ expression = StringReference(historyItem->historyItemVector.expression.c_str());
String^ result = StringReference(historyItem->historyItemVector.result.c_str());
HistoryItemViewModel ^ item = ref new HistoryItemViewModel(expression, result, historyItem->historyItemVector.spTokens, historyItem->historyItemVector.spCommands);
String ^ expression = StringReference(historyItem->historyItemVector.expression.c_str());
String ^ result = StringReference(historyItem->historyItemVector.result.c_str());
HistoryItemViewModel ^ item =
ref new HistoryItemViewModel(expression, result, historyItem->historyItemVector.spTokens, historyItem->historyItemVector.spCommands);
MockOnHistoryItemClicked(item);
VERIFY_ARE_EQUAL(StringReference(L"9"), m_standardViewModel->DisplayValue);
VERIFY_ARE_EQUAL(StringReference(L"1"), m_standardViewModel->ExpressionTokens->GetAt(0)->Token);
@@ -362,9 +368,10 @@ namespace CalculatorFunctionalTests
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandEQU);
auto historyItem = m_standardViewModel->m_standardCalculatorManager.GetHistoryItem(0);
String^ expression = StringReference(historyItem->historyItemVector.expression.c_str());
String^ result = StringReference(historyItem->historyItemVector.result.c_str());
HistoryItemViewModel ^ item = ref new HistoryItemViewModel(expression, result, historyItem->historyItemVector.spTokens, historyItem->historyItemVector.spCommands);
String ^ expression = StringReference(historyItem->historyItemVector.expression.c_str());
String ^ result = StringReference(historyItem->historyItemVector.result.c_str());
HistoryItemViewModel ^ item =
ref new HistoryItemViewModel(expression, result, historyItem->historyItemVector.spTokens, historyItem->historyItemVector.spCommands);
MockOnHistoryItemClicked(item);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandADD);
@@ -394,7 +401,7 @@ namespace CalculatorFunctionalTests
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandADD);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::Command8);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandEQU);
String ^expression = StringReference(L"Display is 9");
String ^ expression = StringReference(L"Display is 9");
VERIFY_ARE_EQUAL(expression, m_standardViewModel->CalculationResultAutomationName);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::ModeScientific);
@@ -425,8 +432,8 @@ namespace CalculatorFunctionalTests
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandADD);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::Command7);
m_standardViewModel->m_standardCalculatorManager.SendCommand(Command::CommandEQU);
String ^expression = L"HexaDecimal" + L" 8";
String ^result = L"HexaDecimal " + Utils::GetStringValue(m_standardViewModel->HexDisplayValue);
String ^ expression = L"HexaDecimal" + L" 8";
String ^ result = L"HexaDecimal " + Utils::GetStringValue(m_standardViewModel->HexDisplayValue);
VERIFY_ARE_EQUAL(expression, result);
expression = StringReference(L"Octal 10");
result = L"Octal " + Utils::GetStringValue(m_standardViewModel->OctalDisplayValue);
@@ -454,7 +461,6 @@ namespace CalculatorFunctionalTests
m_historyViewModel->OnClearCommand(nullptr);
VERIFY_ARE_EQUAL(0, m_historyViewModel->ItemSize);
Cleanup();
}
};

View File

@@ -13,35 +13,37 @@ using namespace Windows::System::UserProfile;
using namespace Windows::Web::Http;
// Generic responses so unit tests will pass.
static constexpr auto STATIC_DATA_RESPONSE = LR"([{"CountryCode":"USA","CountryName":"United States","CurrencyCode":"USD","CurrencyName":"Dollar","CurrencySymbol":"$"},{"CountryCode":"EUR","CountryName":"Europe","CurrencyCode":"EUR","CurrencyName":"Euro","CurrencySymbol":""}])";
static constexpr auto ALL_RATIOS_RESPONSE = LR"([{"An":"USD","Ch":0,"Pc":0,"Rt":1},{"An":"EUR","Ch":0.003803,"Pc":0.4149,"Rt":0.920503,"Yh":0.9667,"Yl":0.86701}])";
static constexpr auto STATIC_DATA_RESPONSE =
LR"([{"CountryCode":"USA","CountryName":"United States","CurrencyCode":"USD","CurrencyName":"Dollar","CurrencySymbol":"$"},{"CountryCode":"EUR","CountryName":"Europe","CurrencyCode":"EUR","CurrencyName":"Euro","CurrencySymbol":""}])";
static constexpr auto ALL_RATIOS_RESPONSE =
LR"([{"An":"USD","Ch":0,"Pc":0,"Rt":1},{"An":"EUR","Ch":0.003803,"Pc":0.4149,"Rt":0.920503,"Yh":0.9667,"Yl":0.86701}])";
CurrencyHttpClient::CurrencyHttpClient()
{
}
String^ CurrencyHttpClient::GetRawStaticDataResponse()
String ^ CurrencyHttpClient::GetRawStaticDataResponse()
{
return StringReference(STATIC_DATA_RESPONSE);
}
String^ CurrencyHttpClient::GetRawAllRatiosDataResponse()
String ^ CurrencyHttpClient::GetRawAllRatiosDataResponse()
{
return StringReference(ALL_RATIOS_RESPONSE);
}
IAsyncOperationWithProgress<String^, HttpProgress>^ CurrencyHttpClient::GetCurrencyMetadata()
IAsyncOperationWithProgress<String ^, HttpProgress> ^ CurrencyHttpClient::GetCurrencyMetadata()
{
return ref new MockAsyncOperationWithProgress(StringReference(STATIC_DATA_RESPONSE));
}
IAsyncOperationWithProgress<String^, HttpProgress>^ CurrencyHttpClient::GetCurrencyRatios()
IAsyncOperationWithProgress<String ^, HttpProgress> ^ CurrencyHttpClient::GetCurrencyRatios()
{
return ref new MockAsyncOperationWithProgress(StringReference(ALL_RATIOS_RESPONSE));
}
MockAsyncOperationWithProgress::MockAsyncOperationWithProgress(String^ result) :
m_result(result)
MockAsyncOperationWithProgress::MockAsyncOperationWithProgress(String ^ result)
: m_result(result)
{
}

View File

@@ -14,23 +14,28 @@ namespace CalculatorApp
public:
CurrencyHttpClient();
static Platform::String^ GetRawStaticDataResponse();
static Platform::String^ GetRawAllRatiosDataResponse();
static Platform::String ^ GetRawStaticDataResponse();
static Platform::String ^ GetRawAllRatiosDataResponse();
// ICurrencyHttpClient
void SetSourceCurrencyCode(Platform::String^ sourceCurrencyCode) override {}
void SetResponseLanguage(Platform::String^ responseLanguage) override {}
void SetSourceCurrencyCode(Platform::String ^ sourceCurrencyCode) override
{
}
void SetResponseLanguage(Platform::String ^ responseLanguage) override
{
}
virtual Windows::Foundation::IAsyncOperationWithProgress<Platform::String^, Windows::Web::Http::HttpProgress>^ GetCurrencyMetadata() override;
virtual Windows::Foundation::IAsyncOperationWithProgress<Platform::String^, Windows::Web::Http::HttpProgress>^ GetCurrencyRatios() override;
virtual Windows::Foundation::IAsyncOperationWithProgress<Platform::String ^, Windows::Web::Http::HttpProgress> ^ GetCurrencyMetadata() override;
virtual Windows::Foundation::IAsyncOperationWithProgress<Platform::String ^, Windows::Web::Http::HttpProgress> ^ GetCurrencyRatios() override;
// ICurrencyHttpClient
};
public ref class MockAsyncOperationWithProgress sealed :
public Windows::Foundation::IAsyncOperationWithProgress<Platform::String^, Windows::Web::Http::HttpProgress>
public
ref class MockAsyncOperationWithProgress sealed
: public Windows::Foundation::IAsyncOperationWithProgress<Platform::String ^, Windows::Web::Http::HttpProgress>
{
public:
MockAsyncOperationWithProgress(Platform::String^ result);
MockAsyncOperationWithProgress(Platform::String ^ result);
// IAsyncInfo
virtual property Windows::Foundation::HResult ErrorCode
@@ -40,16 +45,26 @@ namespace CalculatorApp
virtual property unsigned int Id
{
unsigned int get() { return 128u; }
unsigned int get()
{
return 128u;
}
}
virtual property Windows::Foundation::AsyncStatus Status
{
Windows::Foundation::AsyncStatus get() { return Windows::Foundation::AsyncStatus::Completed; }
Windows::Foundation::AsyncStatus get()
{
return Windows::Foundation::AsyncStatus::Completed;
}
}
virtual void Cancel() {}
virtual void Close() {}
virtual void Cancel()
{
}
virtual void Close()
{
}
// IAsyncInfo
// IAsyncOperationWithProgress

View File

@@ -9,10 +9,10 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace CalculatorUnitTests
{
BEGIN_TEST_MODULE_ATTRIBUTE()
TEST_MODULE_ATTRIBUTE(L"APPX:CertificateFileName", L"CalculatorUnitTests.cer:TrustedPeople")
END_TEST_MODULE_ATTRIBUTE()
TEST_MODULE_ATTRIBUTE(L"APPX:CertificateFileName", L"CalculatorUnitTests.cer:TrustedPeople")
END_TEST_MODULE_ATTRIBUTE()
TEST_MODULE_INITIALIZE(ModuleSetup)
TEST_MODULE_INITIALIZE(ModuleSetup)
{
}

File diff suppressed because it is too large Load Diff

View File

@@ -372,12 +372,12 @@ namespace CalculatorUnitTests
TEST_METHOD(CreateNavCategoryGroup);
private:
void ValidateNavCategory(IObservableVector<NavCategory^>^ categories, unsigned int index, ViewMode expectedMode, int expectedPosition)
void ValidateNavCategory(IObservableVector<NavCategory ^> ^ categories, unsigned int index, ViewMode expectedMode, int expectedPosition)
{
VERIFY_IS_LESS_THAN(0u, categories->Size);
VERIFY_IS_GREATER_THAN(categories->Size, index);
NavCategory^ category = categories->GetAt(index);
NavCategory ^ category = categories->GetAt(index);
VERIFY_ARE_EQUAL(expectedMode, category->Mode);
VERIFY_ARE_EQUAL(expectedPosition, category->Position);
}
@@ -385,11 +385,11 @@ namespace CalculatorUnitTests
void NavCategoryGroupUnitTests::CreateNavCategoryGroup()
{
IObservableVector<NavCategoryGroup^>^ menuOptions = NavCategoryGroup::CreateMenuOptions();
IObservableVector<NavCategoryGroup ^> ^ menuOptions = NavCategoryGroup::CreateMenuOptions();
VERIFY_ARE_EQUAL(2, menuOptions->Size);
NavCategoryGroup^ calculatorGroup = menuOptions->GetAt(0);
NavCategoryGroup ^ calculatorGroup = menuOptions->GetAt(0);
VERIFY_ARE_EQUAL(CategoryGroupType::Calculator, calculatorGroup->GroupType);
IObservableVector<NavCategory^>^ calculatorCategories = calculatorGroup->Categories;
@@ -400,10 +400,10 @@ namespace CalculatorUnitTests
ValidateNavCategory(calculatorCategories, 3u, ViewMode::Date, 4);
ValidateNavCategory(calculatorCategories, 4u, ViewMode::Graphing, 5);
NavCategoryGroup^ converterGroup = menuOptions->GetAt(1);
NavCategoryGroup ^ converterGroup = menuOptions->GetAt(1);
VERIFY_ARE_EQUAL(CategoryGroupType::Converter, converterGroup->GroupType);
IObservableVector<NavCategory^>^ converterCategories = converterGroup->Categories;
IObservableVector<NavCategory ^> ^ converterCategories = converterGroup->Categories;
VERIFY_ARE_EQUAL(13, converterCategories->Size);
ValidateNavCategory(converterCategories, 0u, ViewMode::Currency, 6);
ValidateNavCategory(converterCategories, 1u, ViewMode::Volume, 7);

View File

@@ -0,0 +1,221 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
#include <CppUnitTest.h>
#include "Header Files/Rational.h"
#include "Header Files/RationalMath.h"
using namespace CalcEngine;
using namespace CalcEngine::RationalMath;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace CalculatorEngineTests
{
TEST_CLASS(RationalTest){ public: TEST_CLASS_INITIALIZE(CommonSetup){ ChangeConstants(10, 128);
}
TEST_METHOD(TestModuloOperandsNotModified)
{
// Verify results but also check that operands are not modified
Rational rat25(25);
Rational ratminus25(-25);
Rational rat4(4);
Rational ratminus4(-4);
Rational res = Mod(rat25, rat4);
VERIFY_ARE_EQUAL(res, 1);
VERIFY_ARE_EQUAL(rat25, 25);
VERIFY_ARE_EQUAL(rat4, 4);
res = Mod(rat25, ratminus4);
VERIFY_ARE_EQUAL(res, -3);
VERIFY_ARE_EQUAL(rat25, 25);
VERIFY_ARE_EQUAL(ratminus4, -4);
res = Mod(ratminus25, ratminus4);
VERIFY_ARE_EQUAL(res, -1);
VERIFY_ARE_EQUAL(ratminus25, -25);
VERIFY_ARE_EQUAL(ratminus4, -4);
res = Mod(ratminus25, rat4);
VERIFY_ARE_EQUAL(res, 3);
VERIFY_ARE_EQUAL(ratminus25, -25);
VERIFY_ARE_EQUAL(rat4, 4);
}
TEST_METHOD(TestModuloInteger)
{
// Check with integers
auto res = Mod(Rational(426), Rational(56478));
VERIFY_ARE_EQUAL(res, 426);
res = Mod(Rational(56478), Rational(426));
VERIFY_ARE_EQUAL(res, 246);
res = Mod(Rational(-643), Rational(8756));
VERIFY_ARE_EQUAL(res, 8113);
res = Mod(Rational(643), Rational(-8756));
VERIFY_ARE_EQUAL(res, -8113);
res = Mod(Rational(-643), Rational(-8756));
VERIFY_ARE_EQUAL(res, -643);
res = Mod(Rational(1000), Rational(250));
VERIFY_ARE_EQUAL(res, 0);
res = Mod(Rational(1000), Rational(-250));
VERIFY_ARE_EQUAL(res, 0);
}
TEST_METHOD(TestModuloZero)
{
// Test with Zero
auto res = Mod(Rational(343654332), Rational(0));
VERIFY_ARE_EQUAL(res, 343654332);
res = Mod(Rational(0), Rational(8756));
VERIFY_ARE_EQUAL(res, 0);
res = Mod(Rational(0), Rational(-242));
VERIFY_ARE_EQUAL(res, 0);
res = Mod(Rational(0), Rational(0));
VERIFY_ARE_EQUAL(res, 0);
res = Mod(Rational(Number(1, 0, { 23242 }), Number(1, 0, { 2 })), Rational(Number(1, 0, { 0 }), Number(1, 0, { 23 })));
VERIFY_ARE_EQUAL(res, 11621);
}
TEST_METHOD(TestModuloRational)
{
// Test with rational numbers
auto res = Mod(Rational(Number(1, 0, { 250 }), Number(1, 0, { 100 })), Rational(89));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"2.5");
res = Mod(Rational(Number(1, 0, { 3330 }), Number(1, 0, { 1332 })), Rational(1));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"0.5");
res = Mod(Rational(Number(1, 0, { 12250 }), Number(1, 0, { 100 })), Rational(10));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"2.5");
res = Mod(Rational(Number(-1, 0, { 12250 }), Number(1, 0, { 100 })), Rational(10));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"7.5");
res = Mod(Rational(Number(-1, 0, { 12250 }), Number(1, 0, { 100 })), Rational(-10));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"-2.5");
res = Mod(Rational(Number(1, 0, { 12250 }), Number(1, 0, { 100 })), Rational(-10));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"-7.5");
res = Mod(Rational(Number(1, 0, { 1000 }), Number(1, 0, { 3 })), Rational(1));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"0.33333333");
res = Mod(Rational(Number(1, 0, { 1000 }), Number(1, 0, { 3 })), Rational(-10));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"-6.6666667");
res = Mod(Rational(834345), Rational(Number(1, 0, { 103 }), Number(1, 0, { 100 })));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"0.71");
res = Mod(Rational(834345), Rational(Number(-1, 0, { 103 }), Number(1, 0, { 100 })));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"-0.32");
}
TEST_METHOD(TestRemainderOperandsNotModified)
{
// Verify results but also check that operands are not modified
Rational rat25(25);
Rational ratminus25(-25);
Rational rat4(4);
Rational ratminus4(-4);
Rational res = rat25 % rat4;
VERIFY_ARE_EQUAL(res, 1);
VERIFY_ARE_EQUAL(rat25, 25);
VERIFY_ARE_EQUAL(rat4, 4);
res = rat25 % ratminus4;
VERIFY_ARE_EQUAL(res, 1);
VERIFY_ARE_EQUAL(rat25, 25);
VERIFY_ARE_EQUAL(ratminus4, -4);
res = ratminus25 % ratminus4;
VERIFY_ARE_EQUAL(res, -1);
VERIFY_ARE_EQUAL(ratminus25, -25);
VERIFY_ARE_EQUAL(ratminus4, -4);
res = ratminus25 % rat4;
VERIFY_ARE_EQUAL(res, -1);
VERIFY_ARE_EQUAL(ratminus25, -25);
VERIFY_ARE_EQUAL(rat4, 4);
}
TEST_METHOD(TestRemainderInteger)
{
// Check with integers
auto res = Rational(426) % Rational(56478);
VERIFY_ARE_EQUAL(res, 426);
res = Rational(56478) % Rational(426);
VERIFY_ARE_EQUAL(res, 246);
res = Rational(-643) % Rational(8756);
VERIFY_ARE_EQUAL(res, -643);
res = Rational(643) % Rational(-8756);
VERIFY_ARE_EQUAL(res, 643);
res = Rational(-643) % Rational(-8756);
VERIFY_ARE_EQUAL(res, -643);
res = Rational(-124) % Rational(-124);
VERIFY_ARE_EQUAL(res, 0);
res = Rational(24) % Rational(24);
VERIFY_ARE_EQUAL(res, 0);
}
TEST_METHOD(TestRemainderZero)
{
// Test with Zero
auto res = Rational(0) % Rational(3654);
VERIFY_ARE_EQUAL(res, 0);
res = Rational(0) % Rational(-242);
VERIFY_ARE_EQUAL(res, 0);
for (auto number : { 343654332, 0, -23423 })
{
try
{
res = Rational(number) % Rational(0);
Assert::Fail();
}
catch (uint32_t t)
{
if (t != CALC_E_INDEFINITE)
{
Assert::Fail();
}
}
catch (...)
{
Assert::Fail();
}
try
{
res = Rational(Number(1, number, { 0 }), Number(1, 0, { 2 })) % Rational(Number(1, 0, { 0 }), Number(1, 0, { 23 }));
Assert::Fail();
}
catch (uint32_t t)
{
if (t != CALC_E_INDEFINITE)
{
Assert::Fail();
}
}
catch (...)
{
Assert::Fail();
}
}
}
TEST_METHOD(TestRemainderRational)
{
// Test with rational numbers
auto res = Rational(Number(1, 0, { 250 }), Number(1, 0, { 100 })) % Rational(89);
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"2.5");
res = Rational(Number(1, 0, { 3330 }), Number(1, 0, { 1332 })) % Rational(1);
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"0.5");
res = Rational(Number(1, 0, { 12250 }), Number(1, 0, { 100 })) % Rational(10);
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"2.5");
res = Rational(Number(-1, 0, { 12250 }), Number(1, 0, { 100 })) % Rational(10);
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"-2.5");
res = Rational(Number(-1, 0, { 12250 }), Number(1, 0, { 100 })) % Rational(-10);
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"-2.5");
res = Rational(Number(1, 0, { 12250 }), Number(1, 0, { 100 })) % Rational(-10);
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"2.5");
res = Rational(Number(1, 0, { 1000 }), Number(1, 0, { 3 })) % Rational(1);
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"0.33333333");
res = Rational(Number(1, 0, { 1000 }), Number(1, 0, { 3 })) % Rational(-10);
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"3.3333333");
res = Rational(Number(-1, 0, { 1000 }), Number(1, 0, { 3 })) % Rational(-10);
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"-3.3333333");
res = Rational(834345) % Rational(Number(1, 0, { 103 }), Number(1, 0, { 100 }));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"0.71");
res = Rational(834345) % Rational(Number(-1, 0, { 103 }), Number(1, 0, { 100 }));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"0.71");
res = Rational(-834345) % Rational(Number(1, 0, { 103 }), Number(1, 0, { 100 }));
VERIFY_ARE_EQUAL(res.ToString(10, FMT_FLOAT, 8), L"-0.71");
}
}
;
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,6 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitConverterUnitTests
{
void SetUnitParams(Unit* type, int id, wstring name, wstring abbreviation, bool conversionSource, bool conversionTarget, bool isWhimsical)
{
type->id = id;
@@ -39,8 +38,8 @@ namespace UnitConverterUnitTests
class TestUnitConverterConfigLoader : public IConverterDataLoader
{
public:
TestUnitConverterConfigLoader() :
m_loadDataCallCount(0)
TestUnitConverterConfigLoader()
: m_loadDataCallCount(0)
{
Category c1, c2;
SetCategoryParams(&c1, 1, L"Length", true);
@@ -89,7 +88,6 @@ namespace UnitConverterUnitTests
unit4Map[u3] = conversion5;
unit4Map[u4] = conversion1;
m_ratioMaps[u1] = unit1Map;
m_ratioMaps[u2] = unit2Map;
m_ratioMaps[u3] = unit3Map;
@@ -122,6 +120,7 @@ namespace UnitConverterUnitTests
}
UINT m_loadDataCallCount;
private:
vector<Category> m_categories;
CategoryToUnitVectorMap m_units;
@@ -179,6 +178,7 @@ namespace UnitConverterUnitTests
}
return returnValue;
}
private:
wstring m_lastFrom;
wstring m_lastTo;
@@ -199,8 +199,6 @@ namespace UnitConverterUnitTests
TEST_METHOD(UnitConverterTestGetters);
TEST_METHOD(UnitConverterTestGetCategory);
TEST_METHOD(UnitConverterTestUnitTypeSwitching);
TEST_METHOD(UnitConverterTestSerialization);
TEST_METHOD(UnitConverterTestDeSerialization);
TEST_METHOD(UnitConverterTestQuote);
TEST_METHOD(UnitConverterTestUnquote);
TEST_METHOD(UnitConverterTestBackspace);
@@ -210,6 +208,7 @@ namespace UnitConverterUnitTests
TEST_METHOD(UnitConverterTestMaxDigitsReached_LeadingDecimal);
TEST_METHOD(UnitConverterTestMaxDigitsReached_TrailingDecimal);
TEST_METHOD(UnitConverterTestMaxDigitsReached_MultipleTimes);
private:
static void ExecuteCommands(vector<Command> commands);
@@ -252,7 +251,7 @@ namespace UnitConverterUnitTests
// Resets calculator state to start state after each test
void UnitConverterTest::Cleanup()
{
s_unitConverter->DeSerialize(wstring());
s_unitConverter->SendCommand(Command::Reset);
s_testVMCallback->Reset();
}
@@ -267,16 +266,16 @@ namespace UnitConverterUnitTests
// Test ctor/initialization states
void UnitConverterTest::UnitConverterTestInit()
{
VERIFY_ARE_EQUAL((UINT)0, s_xmlLoader->m_loadDataCallCount); // shouldn't have initialized the loader yet
VERIFY_ARE_EQUAL((UINT)0, s_xmlLoader->m_loadDataCallCount); // shouldn't have initialized the loader yet
s_unitConverter->Initialize();
VERIFY_ARE_EQUAL((UINT)1, s_xmlLoader->m_loadDataCallCount); // now we should have loaded
VERIFY_ARE_EQUAL((UINT)1, s_xmlLoader->m_loadDataCallCount); // now we should have loaded
}
// Verify a basic input command stream.'3', '2', '.', '0'
void UnitConverterTest::UnitConverterTestBasic()
{
tuple<wstring, Unit> test1[] = { tuple<wstring,Unit>(wstring(L"0.25"), s_testFeet) };
tuple<wstring, Unit> test2[] = { tuple<wstring,Unit>(wstring(L"2.5"), s_testFeet) };
tuple<wstring, Unit> test1[] = { tuple<wstring, Unit>(wstring(L"0.25"), s_testFeet) };
tuple<wstring, Unit> test2[] = { tuple<wstring, Unit>(wstring(L"2.5"), s_testFeet) };
s_unitConverter->SendCommand(Command::Three);
VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"3"), wstring(L"3")));
@@ -324,18 +323,6 @@ namespace UnitConverterUnitTests
VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector<tuple<wstring, Unit>>()));
}
// Test serialization
void UnitConverterTest::UnitConverterTestSerialization()
{
wstring test1 = wstring(L"4;Kilograms;Kg;0;0;0;|3;Pounds;Lb;1;1;0;|2;0;Weight;|1;1;0;52.8;116.4039;|1;1;Length;,2;0;Weight;,|1;1;Length;[1;Inches;In;1;1;0;,2;Feet;Ft;0;0;0;,[]2;0;Weight;[3;Pounds;Lb;1;1;0;,4;Kilograms;Kg;0;0;0;,[]|1;Inches;In;1;1;0;[1;Inches;In;1;1;0;:1;0;0;:,2;Feet;Ft;0;0;0;:0.08333333333333332870740406406185;0;0;:,[]2;Feet;Ft;0;0;0;[1;Inches;In;1;1;0;:12;0;0;:,2;Feet;Ft;0;0;0;:1;0;0;:,[]3;Pounds;Lb;1;1;0;[3;Pounds;Lb;1;1;0;:1;0;0;:,4;Kilograms;Kg;0;0;0;:0.45359199999999999519673110626172;0;0;:,[]4;Kilograms;Kg;0;0;0;[3;Pounds;Lb;1;1;0;:2.20461999999999980204279381723609;0;0;:,4;Kilograms;Kg;0;0;0;:1;0;0;:,[]|");
s_unitConverter->SendCommand(Command::Five);
s_unitConverter->SendCommand(Command::Two);
s_unitConverter->SendCommand(Command::Decimal);
s_unitConverter->SendCommand(Command::Eight);
s_unitConverter->SetCurrentCategory(s_testWeight);
s_unitConverter->SetCurrentUnitTypes(s_testKilograms, s_testPounds);
VERIFY_IS_TRUE(s_unitConverter->Serialize().compare(test1) == 0);
}
// Test input escaping
void UnitConverterTest::UnitConverterTestQuote()
@@ -363,22 +350,13 @@ namespace UnitConverterUnitTests
VERIFY_IS_TRUE(UnitConverter::Unquote(UnitConverter::Quote(input3)) == input3);
}
// Test de-serialization
void UnitConverterTest::UnitConverterTestDeSerialization()
{
wstring test1 = wstring(L"4;Kilograms;Kg;0;0;0;|3;Pounds;Lb;1;1;0;|2;0;Weight;|1;1;0;52.8;116.4039;|1;1;Length;,2;0;Weight;,|1;1;Length;[1;Inches;In;1;1;0;,2;Feet;Ft;0;0;0;,[]2;0;Weight;[3;Pounds;Lb;1;1;0;,4;Kilograms;Kg;0;0;0;,[]|1;Inches;In;1;1;0;[1;Inches;In;1;1;0;:1;0;0;:,2;Feet;Ft;0;0;0;:0.08333333333333332870740406406185;0;0;:,[]2;Feet;Ft;0;0;0;[1;Inches;In;1;1;0;:12;0;0;:,2;Feet;Ft;0;0;0;:1;0;0;:,[]3;Pounds;Lb;1;1;0;[3;Pounds;Lb;1;1;0;:1;0;0;:,4;Kilograms;Kg;0;0;0;:0.45359199999999999519673110626172;0;0;:,[]4;Kilograms;Kg;0;0;0;[3;Pounds;Lb;1;1;0;:2.20461999999999980204279381723609;0;0;:,4;Kilograms;Kg;0;0;0;:1;0;0;:,[]|");
s_unitConverter->DeSerialize(test1);
VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"52.8"), wstring(L"116.4039")));
VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector<tuple<wstring, Unit>>()));
}
// Test backspace commands
void UnitConverterTest::UnitConverterTestBackspace()
{
tuple<wstring, Unit> test1[] = { tuple<wstring,Unit>(wstring(L"13.66"), s_testKilograms) };
tuple<wstring, Unit> test2[] = { tuple<wstring,Unit>(wstring(L"13.65"), s_testKilograms) };
tuple<wstring, Unit> test3[] = { tuple<wstring,Unit>(wstring(L"13.61"), s_testKilograms) };
tuple<wstring, Unit> test4[] = { tuple<wstring,Unit>(wstring(L"1.36"), s_testKilograms) };
tuple<wstring, Unit> test1[] = { tuple<wstring, Unit>(wstring(L"13.66"), s_testKilograms) };
tuple<wstring, Unit> test2[] = { tuple<wstring, Unit>(wstring(L"13.65"), s_testKilograms) };
tuple<wstring, Unit> test3[] = { tuple<wstring, Unit>(wstring(L"13.61"), s_testKilograms) };
tuple<wstring, Unit> test4[] = { tuple<wstring, Unit>(wstring(L"1.36"), s_testKilograms) };
s_unitConverter->SetCurrentCategory(s_testWeight);
s_unitConverter->SetCurrentUnitTypes(s_testPounds, s_testPounds);
@@ -469,9 +447,9 @@ namespace UnitConverterUnitTests
// Test large values
void UnitConverterTest::UnitConverterTestSupplementaryResultRounding()
{
tuple<wstring, Unit> test1[] = { tuple<wstring,Unit>(wstring(L"27.75"), s_testFeet) };
tuple<wstring, Unit> test2[] = { tuple<wstring,Unit>(wstring(L"277.8"), s_testFeet) };
tuple<wstring, Unit> test3[] = { tuple<wstring,Unit>(wstring(L"2778"), s_testFeet) };
tuple<wstring, Unit> test1[] = { tuple<wstring, Unit>(wstring(L"27.75"), s_testFeet) };
tuple<wstring, Unit> test2[] = { tuple<wstring, Unit>(wstring(L"277.8"), s_testFeet) };
tuple<wstring, Unit> test3[] = { tuple<wstring, Unit>(wstring(L"2778"), s_testFeet) };
s_unitConverter->SendCommand(Command::Three);
s_unitConverter->SendCommand(Command::Three);
s_unitConverter->SendCommand(Command::Three);
@@ -484,23 +462,21 @@ namespace UnitConverterUnitTests
void UnitConverterTest::UnitConverterTestMaxDigitsReached()
{
ExecuteCommands({
Command::One,
Command::Two,
Command::Three,
Command::Four,
Command::Five,
Command::Six,
Command::Seven,
Command::Eight,
Command::Nine,
Command::One,
Command::Zero,
Command::One,
Command::One,
Command::One,
Command::Two
});
ExecuteCommands({ Command::One,
Command::Two,
Command::Three,
Command::Four,
Command::Five,
Command::Six,
Command::Seven,
Command::Eight,
Command::Nine,
Command::One,
Command::Zero,
Command::One,
Command::One,
Command::One,
Command::Two });
VERIFY_ARE_EQUAL(0, s_testVMCallback->GetMaxDigitsReachedCallCount());
@@ -511,24 +487,22 @@ namespace UnitConverterUnitTests
void UnitConverterTest::UnitConverterTestMaxDigitsReached_LeadingDecimal()
{
ExecuteCommands({
Command::Zero,
Command::Decimal,
Command::One,
Command::Two,
Command::Three,
Command::Four,
Command::Five,
Command::Six,
Command::Seven,
Command::Eight,
Command::Nine,
Command::One,
Command::Zero,
Command::One,
Command::One,
Command::One
});
ExecuteCommands({ Command::Zero,
Command::Decimal,
Command::One,
Command::Two,
Command::Three,
Command::Four,
Command::Five,
Command::Six,
Command::Seven,
Command::Eight,
Command::Nine,
Command::One,
Command::Zero,
Command::One,
Command::One,
Command::One });
VERIFY_ARE_EQUAL(0, s_testVMCallback->GetMaxDigitsReachedCallCount());
@@ -539,24 +513,22 @@ namespace UnitConverterUnitTests
void UnitConverterTest::UnitConverterTestMaxDigitsReached_TrailingDecimal()
{
ExecuteCommands({
Command::One,
Command::Two,
Command::Three,
Command::Four,
Command::Five,
Command::Six,
Command::Seven,
Command::Eight,
Command::Nine,
Command::One,
Command::Zero,
Command::One,
Command::One,
Command::One,
Command::Two,
Command::Decimal
});
ExecuteCommands({ Command::One,
Command::Two,
Command::Three,
Command::Four,
Command::Five,
Command::Six,
Command::Seven,
Command::Eight,
Command::Nine,
Command::One,
Command::Zero,
Command::One,
Command::One,
Command::One,
Command::Two,
Command::Decimal });
VERIFY_ARE_EQUAL(0, s_testVMCallback->GetMaxDigitsReachedCallCount());
@@ -567,23 +539,21 @@ namespace UnitConverterUnitTests
void UnitConverterTest::UnitConverterTestMaxDigitsReached_MultipleTimes()
{
ExecuteCommands({
Command::One,
Command::Two,
Command::Three,
Command::Four,
Command::Five,
Command::Six,
Command::Seven,
Command::Eight,
Command::Nine,
Command::One,
Command::Zero,
Command::One,
Command::One,
Command::One,
Command::Two
});
ExecuteCommands({ Command::One,
Command::Two,
Command::Three,
Command::Four,
Command::Five,
Command::Six,
Command::Seven,
Command::Eight,
Command::Nine,
Command::One,
Command::Zero,
Command::One,
Command::One,
Command::One,
Command::Two });
VERIFY_ARE_EQUAL(0, s_testVMCallback->GetMaxDigitsReachedCallCount());

File diff suppressed because it is too large Load Diff

View File

@@ -20,50 +20,53 @@ namespace CalculatorUnitTests
static UCM::Unit UNIT9 = { 9, L"UNIT9", L"U9", true, false, false };
static UCM::Unit UNITWHIMSY = { 10, L"Whimsy", L"UW", true, false, true };
static UCM::Category CAT1 = { 1, L"CAT1", false }; // contains Unit1 - Unit3
static UCM::Category CAT2 = { 2, L"CAT2", false }; // contains Unit4 - Unit6
static UCM::Category CAT3 = { 3, L"CAT3", false }; // contains Unit7 - Unit9
static UCM::Category CAT1 = { 1, L"CAT1", false }; // contains Unit1 - Unit3
static UCM::Category CAT2 = { 2, L"CAT2", false }; // contains Unit4 - Unit6
static UCM::Category CAT3 = { 3, L"CAT3", false }; // contains Unit7 - Unit9
class UnitConverterMock : public UnitConversionManager::IUnitConverter
{
public:
UnitConverterMock();
void Initialize() override;
std::vector<UCM::Category> GetCategories() override;
UCM::CategorySelectionInitializer SetCurrentCategory(const UCM::Category& input) override;
UCM::Category GetCurrentCategory();
void SetCurrentUnitTypes(const UCM::Unit& fromType, const UCM::Unit& toType) override;
void SwitchActive(const std::wstring& newValue);
std::wstring Serialize() override;
void DeSerialize(const std::wstring& serializedData) override;
std::wstring SaveUserPreferences() override;
void RestoreUserPreferences(_In_ const std::wstring& userPreferences) override;
void SendCommand(UCM::Command command) override;
void SetViewModelCallback(const std::shared_ptr<UCM::IUnitConverterVMCallback>& newCallback) override;
void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<UCM::IViewModelCurrencyCallback>& /*newCallback*/) override {}
concurrency::task<std::pair<bool, std::wstring>> RefreshCurrencyRatios() override
{
co_return std::make_pair(L"", L"");
}
public:
UnitConverterMock();
void Initialize() override;
std::vector<UCM::Category> GetCategories() override;
UCM::CategorySelectionInitializer SetCurrentCategory(const UCM::Category& input) override;
UCM::Category GetCurrentCategory();
void SetCurrentUnitTypes(const UCM::Unit& fromType, const UCM::Unit& toType) override;
void SwitchActive(const std::wstring& newValue);
std::wstring SaveUserPreferences() override;
void RestoreUserPreferences(_In_ const std::wstring& userPreferences) override;
void SendCommand(UCM::Command command) override;
void SetViewModelCallback(const std::shared_ptr<UCM::IUnitConverterVMCallback>& newCallback) override;
void SetViewModelCurrencyCallback(_In_ const std::shared_ptr<UCM::IViewModelCurrencyCallback>& /*newCallback*/) override
{
}
void Calculate() override
{
}
void ResetCategoriesAndRatios() override
{
}
std::future<std::pair<bool, std::wstring>> RefreshCurrencyRatios() override
{
co_return std::make_pair(true, L"");
}
UINT m_initCallCount;
UINT m_getCategoriesCallCount;
UINT m_setCurrentCategoryCallCount;
UINT m_setCurUnitTypesCallCount;
UINT m_switchActiveCallCount;
UINT m_sendCommandCallCount;
UINT m_setVMCallbackCallCount;
UINT m_serializeCallCount;
UINT m_deSerializeCallCount;
UINT m_initCallCount;
UINT m_getCategoriesCallCount;
UINT m_setCurrentCategoryCallCount;
UINT m_setCurUnitTypesCallCount;
UINT m_switchActiveCallCount;
UINT m_sendCommandCallCount;
UINT m_setVMCallbackCallCount;
UCM::Category m_curCategory;
UCM::Unit m_curFrom;
UCM::Unit m_curTo;
UCM::Command m_lastCommand;
UCM::Category m_curCategory;
UCM::Unit m_curFrom;
UCM::Unit m_curTo;
UCM::Command m_lastCommand;
std::shared_ptr<UCM::IUnitConverterVMCallback> m_vmCallback;
std::vector<std::tuple<std::wstring, UCM::Unit>> m_suggestedList;
std::wstring m_curValue;
std::shared_ptr<UCM::IUnitConverterVMCallback> m_vmCallback;
std::vector<std::tuple<std::wstring, UCM::Unit>> m_suggestedList;
std::wstring m_curValue;
};
}

View File

@@ -8,6 +8,7 @@
#include "pch.h"
#include "UnitTestApp.xaml.h"
#include "Common/LocalizationService.h"
using namespace CalculatorUnitTests;
@@ -42,9 +43,8 @@ App::App()
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs ^ e)
{
#if _DEBUG
// Show graphics profiling information while debugging.
if (IsDebuggerPresent())
@@ -54,7 +54,7 @@ void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEvent
}
#endif
auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
auto rootFrame = dynamic_cast<Frame ^>(Window::Current->Content);
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
@@ -70,7 +70,6 @@ void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEvent
{
// TODO: Restore the saved session state only when appropriate, scheduling the
// final launch steps after the restore is complete
}
// Place the frame in the current Window
@@ -81,6 +80,9 @@ void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEvent
Window::Current->Activate();
// Override the current locale to use English (US) to be compatible with all tests based on formatting
CalculatorApp::Common::LocalizationService::OverrideWithLanguage(L"en-US");
Microsoft::VisualStudio::TestPlatform::TestExecutor::WinRTCore::UnitTestClient::Run(e->Arguments);
}
@@ -91,10 +93,10 @@ void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEvent
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
void App::OnSuspending(Object ^ sender, SuspendingEventArgs ^ e)
{
(void) sender; // Unused parameter
(void) e; // Unused parameter
(void)sender; // Unused parameter
(void)e; // Unused parameter
// TODO: Save application state and stop any background activity
}
@@ -104,7 +106,7 @@ void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e)
void App::OnNavigationFailed(Platform::Object ^ sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^ e)
{
throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name);
}

View File

@@ -22,13 +22,12 @@ namespace CalculatorUnitTests
ref class App sealed
{
protected:
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override;
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs ^ e) override;
internal:
App();
internal : App();
private:
void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e);
void OnSuspending(Platform::Object ^ sender, Windows::ApplicationModel::SuspendingEventArgs ^ e);
void OnNavigationFailed(Platform::Object ^ sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^ e);
};
}

View File

@@ -8,37 +8,33 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace CalculatorUnitTests
{
TEST_CLASS(UtilsTests)
{
public:
TEST_METHOD(IsLastCharacterSuccess)
{
VERIFY_IS_TRUE(Utils::IsLastCharacterTarget(L"Test.", L'.'));
}
TEST_METHOD(IsLastCharacterSuccessMultipleSuffices)
{
VERIFY_IS_TRUE(Utils::IsLastCharacterTarget(L"Test..", L'.'));
}
TEST_METHOD(IsLastCharacterFailure)
{
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget(L"Test", L'.'));
}
TEST_METHOD(IsLastCharacterFailureAllButLastMatch)
{
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget(L".....T", L'.'));
}
TEST_METHOD(IsLastCharacterFailureEmptyInput)
{
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget({}, L'.'));
}
TEST_METHOD(IsLastCharacterFailureNullTarget)
{
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget({}, NULL));
}
};
TEST_CLASS(UtilsTests){ public: TEST_METHOD(IsLastCharacterSuccess){ VERIFY_IS_TRUE(Utils::IsLastCharacterTarget(L"Test.", L'.'));
}
TEST_METHOD(IsLastCharacterSuccessMultipleSuffices)
{
VERIFY_IS_TRUE(Utils::IsLastCharacterTarget(L"Test..", L'.'));
}
TEST_METHOD(IsLastCharacterFailure)
{
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget(L"Test", L'.'));
}
TEST_METHOD(IsLastCharacterFailureAllButLastMatch)
{
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget(L".....T", L'.'));
}
TEST_METHOD(IsLastCharacterFailureEmptyInput)
{
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget({}, L'.'));
}
TEST_METHOD(IsLastCharacterFailureNullTarget)
{
VERIFY_IS_FALSE(Utils::IsLastCharacterTarget({}, NULL));
}
}
;
}

View File

@@ -74,7 +74,9 @@ namespace CalculatorApp
// Once the app switches to min version RS3, the namespaces can be removed.
// TODO - MSFT 12735088
namespace StandardPeers = Windows::UI::Xaml::Automation::Peers;
namespace CalculatorApp::Common::Automation {}
namespace CalculatorApp::Common::Automation
{
}
namespace CustomPeers = CalculatorApp::Common::Automation;
// CalcManager Headers

View File

@@ -6,9 +6,9 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif