diff --git a/.gitignore b/.gitignore index 459b8a3..80d64f5 100644 --- a/.gitignore +++ b/.gitignore @@ -289,13 +289,5 @@ __pycache__/ # Calculator specific Generated Files/ -# Don't ignore anything under SpkgDefs or TrexDefs -!/SpkgDefs/** -!/TrexDefs/** !/build/config/TRexDefs/** - -# Localized strings -# LCT files are loc system artifacts that we don't want in our repo. -*.lct - -WorkspaceInfo.xml +!src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx \ No newline at end of file diff --git a/README.md b/README.md index 97099ba..1570243 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Prerequisites: - Install the latest Windows 10 SDK ![Visual Studio Installation Screenshot](docs/Images/VSInstallationScreenshot.png) -- Install the [XamlStyler](https://marketplace.visualstudio.com/items?itemName=TeamXavalon.XAMLStyler) Visual Studio extension +- Install the [XAML Styler](https://marketplace.visualstudio.com/items?itemName=TeamXavalon.XAMLStyler) Visual Studio extension - Get the code: ``` @@ -40,4 +40,4 @@ Prerequisites: Want to contribute? The team encourages community feedback and contributions. Please follow our [contributing guidelines](CONTRIBUTING.md). If Calculator is not working properly, please file a report in the [Feedback Hub](https://insider.windows.com/en-us/fb/?contextid=130). -We also welcome [issues submitted on GitHub](https://github.com/Microsoft/calculator/issues). \ No newline at end of file +We also welcome [issues submitted on GitHub](https://github.com/Microsoft/calculator/issues). diff --git a/build/pipelines/templates/run-unit-tests.yaml b/build/pipelines/templates/run-unit-tests.yaml index 89c3167..708b30b 100644 --- a/build/pipelines/templates/run-unit-tests.yaml +++ b/build/pipelines/templates/run-unit-tests.yaml @@ -24,18 +24,18 @@ jobs: displayName: Download CalculatorUnitTests inputs: artifactName: drop - itemPattern: drop/Release/${{ parameters.platform }}/CalculatorUnitTests_VS/AppPackages/CalculatorUnitTests_Test/** + itemPattern: drop/Release/${{ parameters.platform }}/CalculatorUnitTests/AppPackages/CalculatorUnitTests_Test/** - task: PowerShell@2 displayName: Install Certificate inputs: - filePath: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests_VS\AppPackages\CalculatorUnitTests_Test\Add-AppDevPackage.ps1 - arguments: -CertificatePath $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests_VS\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.cer -Force + filePath: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests\AppPackages\CalculatorUnitTests_Test\Add-AppDevPackage.ps1 + arguments: -CertificatePath $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.cer -Force - task: VSTest@2 displayName: Run CalculatorUnitTests inputs: - testAssemblyVer2: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests_VS\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.appx + testAssemblyVer2: $(Build.ArtifactStagingDirectory)\drop\Release\${{ parameters.platform }}\CalculatorUnitTests\AppPackages\CalculatorUnitTests_Test\CalculatorUnitTests.appx otherConsoleOptions: /Platform:${{ parameters.platform }} - job: CleanUpUnitTests${{ parameters.platform }} diff --git a/docs/ApplicationArchitecture.md b/docs/ApplicationArchitecture.md index 816c35f..4f71b10 100644 --- a/docs/ApplicationArchitecture.md +++ b/docs/ApplicationArchitecture.md @@ -141,8 +141,19 @@ property and a `PropertyChanged` event will be raised, allowing the UI to respon -------- ## Model -The Model for the Calculator modes is contained in the [CalcManager][CalcManager folder] project. - +The Model for the Calculator modes is contained in the [CalcManager][CalcManager folder] project. It consists of three layers: a `CalculatorManager`, which relies on a `CalcEngine`, which relies on the `Ratpack`. + +### CalculatorManager + +The CalculatorManager contains the logic for managing the overall Calculator app's data such as the History and Memory lists, as well as maintaining the instances of calculator engines used for the various modes. The interface to this layer is defined in [CalculatorManager.h][CalculatorManager.h]. + +### CalcEngine + +The CalcEngine contains the logic for interpreting and performing operations according to the commands passed to it. It maintains the current state of calculations and relies on the RatPack for performing mathematical operations. The interface to this layer is defined in [CalcEngine.h][CalcEngine.h]. + +### RatPack + +The RatPack (short for Rational Pack) is the core of the Calculator model and contains the logic for performing its mathematical operations. The interface to this layer is defined in [ratpak.h][ratpak.h]. [References]:#################################################################################################### @@ -186,3 +197,6 @@ The Model for the Calculator modes is contained in the [CalcManager][CalcManager [Utils.h]: ../src/CalcViewModel/Common/Utils.h [CalcManager folder]: ../src/CalcManager +[CalculatorManager.h]: ../src/CalcManager/CalculatorManager.h +[CalcEngine.h]: ../src/CalcManager/Header Files/CalcEngine.h +[ratpak.h]: ../src/CalcManager/Ratpack/ratpak.h \ No newline at end of file diff --git a/internal/CalculatorInternal.sln b/internal/CalculatorInternal.sln index a6ee5b1..98be0fb 100644 --- a/internal/CalculatorInternal.sln +++ b/internal/CalculatorInternal.sln @@ -11,16 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution nuget.config = nuget.config EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Calculator", "..\src\Calculator\Calculator.vcxproj", "{9447424A-0E05-4911-BEB8-E0354405F39A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalcViewModel", "..\src\CalcViewModel\CalcViewModel.vcxproj", "{90E9761D-9262-4773-942D-CAEAE75D7140}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalcManager", "..\src\CalcManager\CalcManager.vcxproj", "{311E866D-8B93-4609-A691-265941FEE101}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Calculator.TestPackage", "Calculator.TestPackage\Calculator.TestPackage.csproj", "{24767C43-CD5A-4DC9-8D6B-429F255524E5}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalculatorUnitTests", "CalculatorUnitTests\CalculatorUnitTests.vcxproj", "{E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -61,62 +53,6 @@ Global {0224A709-0C48-4C4F-BA17-843A49842C15}.Release|x64.Build.0 = Release|x64 {0224A709-0C48-4C4F-BA17-843A49842C15}.Release|x86.ActiveCfg = Release|x86 {0224A709-0C48-4C4F-BA17-843A49842C15}.Release|x86.Build.0 = Release|x86 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.ActiveCfg = Debug|ARM - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.Build.0 = Debug|ARM - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM.Deploy.0 = Debug|ARM - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM64.Build.0 = Debug|ARM64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|x64.ActiveCfg = Debug|x64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|x64.Build.0 = Debug|x64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|x64.Deploy.0 = Debug|x64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|x86.ActiveCfg = Debug|Win32 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|x86.Build.0 = Debug|Win32 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Debug|x86.Deploy.0 = Debug|Win32 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|ARM.ActiveCfg = Release|ARM - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|ARM.Build.0 = Release|ARM - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|ARM.Deploy.0 = Release|ARM - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|ARM64.ActiveCfg = Release|ARM64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|ARM64.Build.0 = Release|ARM64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|ARM64.Deploy.0 = Release|ARM64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x64.ActiveCfg = Release|x64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x64.Build.0 = Release|x64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x64.Deploy.0 = Release|x64 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.ActiveCfg = Release|Win32 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.Build.0 = Release|Win32 - {9447424A-0E05-4911-BEB8-E0354405F39A}.Release|x86.Deploy.0 = Release|Win32 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM.ActiveCfg = Debug|ARM - {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM.Build.0 = Debug|ARM - {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|ARM64.Build.0 = Debug|ARM64 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|x64.ActiveCfg = Debug|x64 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|x64.Build.0 = Debug|x64 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|x86.ActiveCfg = Debug|Win32 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Debug|x86.Build.0 = Debug|Win32 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|ARM.ActiveCfg = Release|ARM - {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|ARM.Build.0 = Release|ARM - {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|ARM64.ActiveCfg = Release|ARM64 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|ARM64.Build.0 = Release|ARM64 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|x64.ActiveCfg = Release|x64 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|x64.Build.0 = Release|x64 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|x86.ActiveCfg = Release|Win32 - {90E9761D-9262-4773-942D-CAEAE75D7140}.Release|x86.Build.0 = Release|Win32 - {311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM.ActiveCfg = Debug|ARM - {311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM.Build.0 = Debug|ARM - {311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {311E866D-8B93-4609-A691-265941FEE101}.Debug|ARM64.Build.0 = Debug|ARM64 - {311E866D-8B93-4609-A691-265941FEE101}.Debug|x64.ActiveCfg = Debug|x64 - {311E866D-8B93-4609-A691-265941FEE101}.Debug|x64.Build.0 = Debug|x64 - {311E866D-8B93-4609-A691-265941FEE101}.Debug|x86.ActiveCfg = Debug|Win32 - {311E866D-8B93-4609-A691-265941FEE101}.Debug|x86.Build.0 = Debug|Win32 - {311E866D-8B93-4609-A691-265941FEE101}.Release|ARM.ActiveCfg = Release|ARM - {311E866D-8B93-4609-A691-265941FEE101}.Release|ARM.Build.0 = Release|ARM - {311E866D-8B93-4609-A691-265941FEE101}.Release|ARM64.ActiveCfg = Release|ARM64 - {311E866D-8B93-4609-A691-265941FEE101}.Release|ARM64.Build.0 = Release|ARM64 - {311E866D-8B93-4609-A691-265941FEE101}.Release|x64.ActiveCfg = Release|x64 - {311E866D-8B93-4609-A691-265941FEE101}.Release|x64.Build.0 = Release|x64 - {311E866D-8B93-4609-A691-265941FEE101}.Release|x86.ActiveCfg = Release|Win32 - {311E866D-8B93-4609-A691-265941FEE101}.Release|x86.Build.0 = Release|Win32 {24767C43-CD5A-4DC9-8D6B-429F255524E5}.Debug|ARM.ActiveCfg = Debug|ARM {24767C43-CD5A-4DC9-8D6B-429F255524E5}.Debug|ARM.Build.0 = Debug|ARM {24767C43-CD5A-4DC9-8D6B-429F255524E5}.Debug|ARM64.ActiveCfg = Debug|ARM64 @@ -131,30 +67,6 @@ Global {24767C43-CD5A-4DC9-8D6B-429F255524E5}.Release|x64.Build.0 = Release|x64 {24767C43-CD5A-4DC9-8D6B-429F255524E5}.Release|x86.ActiveCfg = Release|x86 {24767C43-CD5A-4DC9-8D6B-429F255524E5}.Release|x86.Build.0 = Release|x86 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|ARM.ActiveCfg = Debug|ARM - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|ARM.Build.0 = Debug|ARM - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|ARM.Deploy.0 = Debug|ARM - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|ARM64.Build.0 = Debug|ARM64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|x64.ActiveCfg = Debug|x64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|x64.Build.0 = Debug|x64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|x64.Deploy.0 = Debug|x64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|x86.ActiveCfg = Debug|Win32 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|x86.Build.0 = Debug|Win32 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Debug|x86.Deploy.0 = Debug|Win32 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|ARM.ActiveCfg = Release|ARM - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|ARM.Build.0 = Release|ARM - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|ARM.Deploy.0 = Release|ARM - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|ARM64.ActiveCfg = Release|ARM64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|ARM64.Build.0 = Release|ARM64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|ARM64.Deploy.0 = Release|ARM64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|x64.ActiveCfg = Release|x64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|x64.Build.0 = Release|x64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|x64.Deploy.0 = Release|x64 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|x86.ActiveCfg = Release|Win32 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|x86.Build.0 = Release|Win32 - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE}.Release|x86.Deploy.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/internal/CalculatorUnitTests/CalcEngineTests.cpp b/internal/CalculatorUnitTests/CalcEngineTests.cpp deleted file mode 100644 index 7589084..0000000 --- a/internal/CalculatorUnitTests/CalcEngineTests.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include - -#include "CalcViewModel\Common\EngineResourceProvider.h" - -using namespace std; -using namespace WEX::Common; -using namespace WEX::Logging; -using namespace WEX::TestExecution; - -using namespace CalculatorApp; -using namespace CalculationManager; - -static constexpr size_t MAX_HISTORY_SIZE = 20; - -namespace CalculatorUnitTests -{ - class CalcEngineTests - { - TEST_CLASS(CalcEngineTests); - TEST_CLASS_SETUP(CommonSetup) - { - m_resourceProvider = make_shared(); - m_history = make_shared(CM_STD, MAX_HISTORY_SIZE); - CCalcEngine::InitialOneTimeOnlySetup(*(m_resourceProvider.get())); - m_calcEngine = make_unique(false /* Respect Order of Operations */, false /* Set to Integer Mode */, m_resourceProvider.get(), nullptr, m_history); - return true; - } - TEST_METHOD_CLEANUP(Cleanup) - { - return true; - } - - TEST_METHOD(TestGroupDigitsPerRadix) - { - // Empty/Error cases - VERIFY_IS_TRUE(m_calcEngine->GroupDigitsPerRadix(L"", 10).empty(), L"Verify grouping empty string returns empty string."); - VERIFY_ARE_EQUAL(L"12345678", m_calcEngine->GroupDigitsPerRadix(L"12345678", 9), L"Verify grouping on invalid base returns original string"); - - // Octal - VERIFY_ARE_EQUAL(L"1 234 567", m_calcEngine->GroupDigitsPerRadix(L"1234567", 8), L"Verify grouping in octal."); - VERIFY_ARE_EQUAL(L"123", m_calcEngine->GroupDigitsPerRadix(L"123", 8), L"Verify minimum grouping in octal."); - - // Binary/Hexadecimal - VERIFY_ARE_EQUAL(L"12 3456 7890", m_calcEngine->GroupDigitsPerRadix(L"1234567890", 2), L"Verify grouping in binary."); - VERIFY_ARE_EQUAL(L"1234", m_calcEngine->GroupDigitsPerRadix(L"1234", 2), L"Verify minimum grouping in binary."); - VERIFY_ARE_EQUAL(L"12 3456 7890", m_calcEngine->GroupDigitsPerRadix(L"1234567890", 16), L"Verify grouping in hexadecimal."); - VERIFY_ARE_EQUAL(L"1234", m_calcEngine->GroupDigitsPerRadix(L"1234", 16), L"Verify minimum grouping in hexadecimal."); - - // Decimal - 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"-123,456,789", m_calcEngine->GroupDigitsPerRadix(L"-123456789", 10), L"Verify grouping in base10 with negative."); - } - - TEST_METHOD(TestIsNumberInvalid) - { - // Binary Number Checks - vector validBinStrs{ L"0", L"1", L"0011", L"1100" }; - vector invalidBinStrs{ L"2", L"A", L"0.1" }; - for (wstring const& str : validBinStrs) - { - VERIFY_ARE_EQUAL(0, m_calcEngine->IsNumberInvalid(str, 0, 0, 2 /* Binary */)); - } - for (wstring const& str : invalidBinStrs) - { - VERIFY_ARE_EQUAL(IDS_ERR_UNK_CH, m_calcEngine->IsNumberInvalid(str, 0, 0, 2 /* Binary */)); - } - - // Octal Number Checks - vector validOctStrs{ L"0", L"7", L"01234567", L"76543210" }; - vector invalidOctStrs{ L"8", L"A", L"0.7" }; - for (wstring const& str : validOctStrs) - { - VERIFY_ARE_EQUAL(0, m_calcEngine->IsNumberInvalid(str, 0, 0, 8 /* Octal */)); - } - for (wstring const& str : invalidOctStrs) - { - VERIFY_ARE_EQUAL(IDS_ERR_UNK_CH, m_calcEngine->IsNumberInvalid(str, 0, 0, 8 /* Octal */)); - } - - // Hexadecimal Number Checks - vector validHexStrs{ L"0", L"F", L"0123456789ABCDEF", L"FEDCBA9876543210" }; - vector invalidHexStrs{ L"G", L"abcdef", L"x", L"0.1" }; - for (wstring const& str : validHexStrs) - { - VERIFY_ARE_EQUAL(0, m_calcEngine->IsNumberInvalid(str, 0, 0, 16 /* HEx */)); - } - for (wstring const& str : invalidHexStrs) - { - VERIFY_ARE_EQUAL(IDS_ERR_UNK_CH, m_calcEngine->IsNumberInvalid(str, 0, 0, 16 /* Hex */)); - } - - // Decimal Number Checks - - // Special case errors: long exponent, long mantissa - wstring longExp(L"1e12345"); - VERIFY_ARE_EQUAL(0, m_calcEngine->IsNumberInvalid(longExp, 5 /* Max exp length */, 100, 10 /* Decimal */)); - VERIFY_ARE_EQUAL(IDS_ERR_INPUT_OVERFLOW, m_calcEngine->IsNumberInvalid(longExp, 4 /* Max exp length */, 100, 10 /* Decimal */)); - // Mantissa length is sum of: - // - digits before decimal separator, minus leading zeroes - // - digits after decimal separator, including trailing zeroes - // Each of these mantissa values should calculate as a length of 5 - vector longMantStrs{ L"10000", L"10.000", L"0000012345", L"123.45", L"0.00123", L"0.12345", L"-123.45e678" }; - for (wstring const& str : longMantStrs) - { - VERIFY_ARE_EQUAL(0, m_calcEngine->IsNumberInvalid(str, 100, 5 /* Max mantissa length */, 10 /* Decimal */)); - } - for (wstring const& str : longMantStrs) - { - VERIFY_ARE_EQUAL(IDS_ERR_INPUT_OVERFLOW, m_calcEngine->IsNumberInvalid(str, 100, 4 /* Max mantissa length */, 10 /* Decimal */)); - } - - // Regex matching (descriptions taken from CalcUtils.cpp) - // Use 100 for exp/mantissa length as they are tested above - vector 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 invalidDecStrs{ L"x123", L"123-", L"1e1.2", L"1-e2" }; - for (wstring const& str : validDecStrs) - { - VERIFY_ARE_EQUAL(0, m_calcEngine->IsNumberInvalid(str, 100, 100, 10 /* Dec */)); - } - for (wstring const& str : invalidDecStrs) - { - VERIFY_ARE_EQUAL(IDS_ERR_UNK_CH, m_calcEngine->IsNumberInvalid(str, 100, 100, 10 /* Dec */)); - } - - } - - TEST_METHOD(TestDigitGroupingStringToGroupingVector) - { - vector groupingVector{}; - VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(L""), L"Verify empty grouping"); - - groupingVector = { 1 }; - VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(L"1"), L"Verify simple grouping"); - - groupingVector = { 3, 0 }; - VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(L"3;0"), L"Verify standard grouping"); - - groupingVector = { 3, 0, 0 }; - VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(L"3;0;0"), L"Verify expanded non-repeating grouping"); - - groupingVector = { 5, 3, 2, 4, 6 }; - VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(L"5;3;2;4;6"), L"Verify long grouping"); - - groupingVector = { 15, 15, 15, 0 }; - VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(L"15;15;15;0"), L"Verify large grouping"); - - groupingVector = { 4, 7, 0 }; - VERIFY_ARE_EQUAL(groupingVector, CCalcEngine::DigitGroupingStringToGroupingVector(L"4;16;7;25;0"), L"Verify we ignore oversize grouping"); - } - - TEST_METHOD(TestGroupDigits) - { - wstring result{ L"1234567" }; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L"", { 3, 0 }, L"1234567", false), L"Verify handling of empty delimiter."); - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", {}, L"1234567", false), L"Verify handling of empty grouping."); - - result = L"1,234,567"; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 3, 0 }, L"1234567", false), L"Verify standard digit grouping."); - - result = L"1 234 567"; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L" ", { 3, 0 }, L"1234567", false), L"Verify delimiter change."); - - result = L"1|||234|||567"; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L"|||", { 3, 0 }, L"1234567", false), L"Verify long delimiter."); - - result = L"12,345e67"; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 3, 0 }, L"12345e67", false), L"Verify respect of exponent."); - - result = L"12,345.67"; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 3, 0 }, L"12345.67", false), L"Verify respect of decimal."); - - result = L"1,234.56e7"; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 3, 0 }, L"1234.56e7", false), L"Verify respect of exponent and decimal."); - - result = L"-1,234,567"; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 3, 0 }, L"-1234567", true), L"Verify negative number grouping."); - - // Test various groupings - result = L"1234567890123456"; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 0, 0 }, L"1234567890123456", false), L"Verify no grouping."); - - result = L"1234567890123,456"; - VERIFY_ARE_EQUAL(result, m_calcEngine->GroupDigits(L",", { 3 }, L"1234567890123456", false), L"Verify non-repeating grouping."); - 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."); - - 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."); - } - - private: - unique_ptr m_calcEngine; - shared_ptr m_resourceProvider; - shared_ptr m_history; - }; -} diff --git a/internal/CalculatorUnitTests/CalcInputTest.cpp b/internal/CalculatorUnitTests/CalcInputTest.cpp deleted file mode 100644 index e29072b..0000000 --- a/internal/CalculatorUnitTests/CalcInputTest.cpp +++ /dev/null @@ -1,366 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include - -using namespace std; -using namespace WEX::Common; -using namespace WEX::Logging; -using namespace WEX::TestExecution; - -using namespace CalculationManager; - -namespace CalculatorUnitTests -{ - class CalcInputTest - { - TEST_CLASS(CalcInputTest); - TEST_CLASS_SETUP(CommonSetup) - { - m_calcInput = CalcEngine::CalcInput(L'.'); - return true; - } - TEST_METHOD_CLEANUP(Cleanup) - { - m_calcInput.Clear(); - m_calcInput.SetDecimalSymbol(L'.'); - return true; - } - - TEST_METHOD(Clear) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryToggleSign(false, L"999"); - m_calcInput.TryAddDecimalPt(); - m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 32); - m_calcInput.TryBeginExponent(); - m_calcInput.TryAddDigit(3, 10, false, L"999", 64, 32); - - VERIFY_ARE_EQUAL(L"-1.2e+3", m_calcInput.ToString(10, false), L"Verify input is correct."); - - m_calcInput.Clear(); - - ::Log::Comment(m_calcInput.ToString(10, false).c_str()); - VERIFY_ARE_EQUAL(L"0", m_calcInput.ToString(10, false), L"Verify input is 0 after clear."); - } - - TEST_METHOD(TryToggleSignZero) - { - VERIFY_IS_TRUE(m_calcInput.TryToggleSign(false, L"999"), L"Verify toggling 0 succeeds."); - VERIFY_ARE_EQUAL(L"0", m_calcInput.ToString(10, false), L"Verify toggling 0 does not create -0."); - } - TEST_METHOD(TryToggleSignExponent) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryBeginExponent(); - m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryToggleSign(false, L"999"), L"Verify toggling exponent sign succeeds."); - VERIFY_ARE_EQUAL(L"1.e-2", m_calcInput.ToString(10, false), L"Verify toggling exponent sign does not toggle base sign."); - VERIFY_IS_TRUE(m_calcInput.TryToggleSign(false, L"999"), L"Verify toggling exponent sign succeeds."); - VERIFY_ARE_EQUAL(L"1.e+2", m_calcInput.ToString(10, false), L"Verify toggling negative exponent sign does not toggle base sign."); - } - TEST_METHOD(TryToggleSignBase) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryToggleSign(false, L"999"), L"Verify toggling base sign succeeds."); - VERIFY_ARE_EQUAL(L"-1", m_calcInput.ToString(10, false), L"Verify toggling base sign creates negative base."); - VERIFY_IS_TRUE(m_calcInput.TryToggleSign(false, L"999"), L"Verify toggling base sign succeeds."); - VERIFY_ARE_EQUAL(L"1", m_calcInput.ToString(10, false), L"Verify toggling negative base sign creates positive base."); - } - TEST_METHOD(TryToggleSignBaseIntegerMode) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryToggleSign(true, L"999"), L"Verify toggling base sign in integer mode succeeds."); - VERIFY_ARE_EQUAL(L"-1", m_calcInput.ToString(10, false), L"Verify toggling base sign creates negative base."); - } - TEST_METHOD(TryToggleSignRollover) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryToggleSign(true, L"127"), L"Verify toggling base sign in integer mode succeeds."); - m_calcInput.TryAddDigit(8, 10, false, L"999", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryToggleSign(true, L"127"), L"Verify toggling base sign in integer mode fails on rollover."); - VERIFY_ARE_EQUAL(L"-128", m_calcInput.ToString(10, false), L"Verify toggling base sign on rollover does not change value."); - } - - TEST_METHOD(TryAddDigitLeadingZeroes) - { - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(0, 10, false, L"999", 64, 32), L"Verify TryAddDigit succeeds."); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(0, 10, false, L"999", 64, 32), L"Verify TryAddDigit succeeds."); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(0, 10, false, L"999", 64, 32), L"Verify TryAddDigit succeeds."); - VERIFY_ARE_EQUAL(L"0", m_calcInput.ToString(10, false), L"Verify leading zeroes are ignored."); - } - TEST_METHOD(TryAddDigitMaxCount) - { - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32), L"Verify TryAddDigit for base with length < maxDigits succeeds."); - VERIFY_ARE_EQUAL(L"1", m_calcInput.ToString(10, false), L"Verify adding digit for base with length < maxDigits succeeded."); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 1), L"Verify TryAddDigit for base with length > maxDigits fails."); - VERIFY_ARE_EQUAL(L"1", m_calcInput.ToString(10, false), L"Verify digit for base was not added."); - m_calcInput.TryBeginExponent(); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32), L"Verify TryAddDigit for exponent with length < maxDigits succeeds."); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 32), L"Verify TryAddDigit for exponent with length < maxDigits succeeds."); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(3, 10, false, L"999", 64, 32), L"Verify TryAddDigit for exponent with length < maxDigits succeeds."); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(4, 10, false, L"999", 64, 32), L"Verify TryAddDigit for exponent with length < maxDigits succeeds."); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(5, 10, false, L"999", 64, 32), L"Verify TryAddDigit for exponent with length > maxDigits fails."); - VERIFY_ARE_EQUAL(L"1.e+1234", m_calcInput.ToString(10, false), L"Verify adding digits for exponent with length < maxDigits succeeded."); - - m_calcInput.Clear(); - m_calcInput.TryAddDecimalPt(); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 1), L"Verify decimal point and leading zero does not count toward maxDigits."); - VERIFY_ARE_EQUAL(L"0.1", m_calcInput.ToString(10, false), L"Verify input value checking dec pt and leading zero impact on maxDigits."); - } - TEST_METHOD(TryAddDigitValues) - { - // Use an arbitrary value > 16 to test that input accepts digits > hexadecimal 0xF. - // TryAddDigit does not validate whether the digit fits within the current radix. - for (unsigned int i = 0; i < 25; i++) - { - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(i, 10, false, L"999", 64, 32), String().Format(L"Verify TryAddDigit succeeds for %d", i)); - m_calcInput.Clear(); - } - } - TEST_METHOD(TryAddDigitRolloverBaseCheck) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(2, 16, true, L"999", 64, 1), L"Verify TryAddDigit rollover fails for bases other than 8,10."); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(1, 2, true, L"999", 64, 1), L"Verify TryAddDigit rollover fails for bases other than 8,10."); - } - TEST_METHOD(TryAddDigitRolloverOctalByte) - { - m_calcInput.TryAddDigit(1, 8, true, L"777", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(2, 8, true, L"377", 8, 1), L"Verify we can add an extra digit in OctalByte if first digit <= 3."); - - m_calcInput.Clear(); - m_calcInput.TryAddDigit(4, 8, true, L"777", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(2, 8, true, L"377", 8, 1), L"Verify we cannot add an extra digit in OctalByte if first digit > 3."); - } - TEST_METHOD(TryAddDigitRolloverOctalWord) - { - m_calcInput.TryAddDigit(1, 8, true, L"777", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(2, 8, true, L"377", 16, 1), L"Verify we can add an extra digit in OctalByte if first digit == 1."); - - m_calcInput.Clear(); - m_calcInput.TryAddDigit(2, 8, true, L"777", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(2, 8, true, L"377", 16, 1), L"Verify we cannot add an extra digit in OctalByte if first digit > 1."); - } - TEST_METHOD(TryAddDigitRolloverOctalDword) - { - m_calcInput.TryAddDigit(1, 8, true, L"777", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(2, 8, true, L"377", 32, 1), L"Verify we can add an extra digit in OctalByte if first digit <= 3."); - - m_calcInput.Clear(); - m_calcInput.TryAddDigit(4, 8, true, L"777", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(2, 8, true, L"377", 32, 1), L"Verify we cannot add an extra digit in OctalByte if first digit > 3."); - } - TEST_METHOD(TryAddDigitRolloverOctalQword) - { - m_calcInput.TryAddDigit(1, 8, true, L"777", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(2, 8, true, L"377", 64, 1), L"Verify we can add an extra digit in OctalByte if first digit == 1."); - - m_calcInput.Clear(); - m_calcInput.TryAddDigit(2, 8, true, L"777", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(2, 8, true, L"377", 64, 1), L"Verify we cannot add an extra digit in OctalByte if first digit > 1."); - } - TEST_METHOD(TryAddDigitRolloverDecimal) - { - m_calcInput.TryAddDigit(1, 10, true, L"127", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(0, 10, true, L"1", 8, 1), L"Verify we cannot add a digit if input size matches maxStr size."); - m_calcInput.TryAddDigit(2, 10, true, L"127", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(2, 10, true, L"110", 8, 2), L"Verify we cannot add a digit if n char comparison > 0."); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(7, 10, true, L"130", 8, 2), L"Verify we can add a digit if n char comparison < 0."); - - m_calcInput.Clear(); - m_calcInput.TryAddDigit(1, 10, true, L"127", 64, 32); - m_calcInput.TryAddDigit(2, 10, true, L"127", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryAddDigit(8, 10, true, L"127", 8, 2), L"Verify we cannot add a digit if digit exceeds max value."); - VERIFY_IS_TRUE(m_calcInput.TryAddDigit(7, 10, true, L"127", 8, 2), L"Verify we can add a digit if digit does not exceed max value."); - - 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."); - } - - TEST_METHOD(TryAddDecimalPtEmpty) - { - VERIFY_IS_FALSE(m_calcInput.HasDecimalPt(), L"Verify input has no decimal point."); - VERIFY_IS_TRUE(m_calcInput.TryAddDecimalPt(), L"Verify adding decimal to empty input."); - VERIFY_IS_TRUE(m_calcInput.HasDecimalPt(), L"Verify input has decimal point."); - VERIFY_ARE_EQUAL(L"0.", m_calcInput.ToString(10, false), L"Verify decimal on empty input."); - } - TEST_METHOD(TryAddDecimalPointTwice) - { - VERIFY_IS_FALSE(m_calcInput.HasDecimalPt(), L"Verify input has no decimal point."); - VERIFY_IS_TRUE(m_calcInput.TryAddDecimalPt(), L"Verify adding decimal to empty input."); - VERIFY_IS_TRUE(m_calcInput.HasDecimalPt(), L"Verify input has decimal point."); - VERIFY_IS_FALSE(m_calcInput.TryAddDecimalPt(), L"Verify adding decimal point fails if input has decimal point."); - } - TEST_METHOD(TryAddDecimalPointExponent) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryBeginExponent(); - m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 32); - VERIFY_IS_FALSE(m_calcInput.TryAddDecimalPt(), L"Verify adding decimal point fails if input has exponent."); - } - - TEST_METHOD(TryBeginExponentNoExponent) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryBeginExponent(), L"Verify adding exponent succeeds on input without exponent."); - VERIFY_ARE_EQUAL(L"1.e+0", m_calcInput.ToString(10, false), L"Verify exponent present."); - } - TEST_METHOD(TryBeginExponentWithExponent) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - VERIFY_IS_TRUE(m_calcInput.TryBeginExponent(), L"Verify adding exponent succeeds on input without exponent."); - VERIFY_IS_FALSE(m_calcInput.TryBeginExponent(), L"Verify cannot add exponent if input already has exponent."); - } - - TEST_METHOD(BackspaceZero) - { - m_calcInput.Backspace(); - VERIFY_ARE_EQUAL(L"0", m_calcInput.ToString(10, false), L"Verify backspace on 0 is still 0."); - } - TEST_METHOD(BackspaceSingleChar) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - VERIFY_ARE_EQUAL(L"1", m_calcInput.ToString(10, false), L"Verify input before backspace."); - m_calcInput.Backspace(); - VERIFY_ARE_EQUAL(L"0", m_calcInput.ToString(10, false), L"Verify input after backspace."); - } - TEST_METHOD(BackspaceMultiChar) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 32); - VERIFY_ARE_EQUAL(L"12", m_calcInput.ToString(10, false), L"Verify input before backspace."); - m_calcInput.Backspace(); - VERIFY_ARE_EQUAL(L"1", m_calcInput.ToString(10, false), L"Verify input after backspace."); - } - TEST_METHOD(BackspaceDecimal) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryAddDecimalPt(); - VERIFY_ARE_EQUAL(L"1.", m_calcInput.ToString(10, false), L"Verify input before backspace."); - VERIFY_IS_TRUE(m_calcInput.HasDecimalPt(), L"Verify input has decimal point."); - m_calcInput.Backspace(); - VERIFY_ARE_EQUAL(L"1", m_calcInput.ToString(10, false), L"Verify input after backspace."); - VERIFY_IS_FALSE(m_calcInput.HasDecimalPt(), L"Verify decimal point was removed."); - } - TEST_METHOD(BackspaceMultiCharDecimal) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryAddDecimalPt(); - m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 32); - m_calcInput.TryAddDigit(3, 10, false, L"999", 64, 32); - VERIFY_ARE_EQUAL(L"1.23", m_calcInput.ToString(10, false), L"Verify input before backspace."); - m_calcInput.Backspace(); - VERIFY_ARE_EQUAL(L"1.2", m_calcInput.ToString(10, false), L"Verify input after backspace."); - } - - TEST_METHOD(SetDecimalSymbol) - { - m_calcInput.TryAddDecimalPt(); - VERIFY_ARE_EQUAL(L"0.", m_calcInput.ToString(10, false), L"Verify default decimal point."); - m_calcInput.SetDecimalSymbol(L','); - VERIFY_ARE_EQUAL(L"0,", m_calcInput.ToString(10, false), L"Verify new decimal point."); - } - - TEST_METHOD(ToStringEmpty) - { - VERIFY_ARE_EQUAL(L"0", m_calcInput.ToString(10, false), L"Verify ToString of empty value."); - } - TEST_METHOD(ToStringNegative) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryToggleSign(false, L"999"); - VERIFY_ARE_EQUAL(L"-1", m_calcInput.ToString(10, false), L"Verify ToString of negative value."); - } - TEST_METHOD(ToStringExponentBase10) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryBeginExponent(); - VERIFY_ARE_EQUAL(L"1.e+0", m_calcInput.ToString(10, false), L"Verify ToString of empty base10 exponent."); - } - TEST_METHOD(ToStringExponentBase8) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryBeginExponent(); - VERIFY_ARE_EQUAL(L"1.^+0", m_calcInput.ToString(8, false), L"Verify ToString of empty base8 exponent."); - } - TEST_METHOD(ToStringExponentNegative) - { - m_calcInput.TryAddDigit(1, 8, false, L"999", 64, 32); - m_calcInput.TryBeginExponent(); - m_calcInput.TryToggleSign(false, L"999"); - VERIFY_ARE_EQUAL(L"1.e-0", m_calcInput.ToString(10, false), L"Verify ToString of empty negative exponent."); - } - TEST_METHOD(ToStringExponentPositive) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryBeginExponent(); - m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 32); - m_calcInput.TryAddDigit(3, 10, false, L"999", 64, 32); - m_calcInput.TryAddDigit(4, 10, false, L"999", 64, 32); - VERIFY_ARE_EQUAL(L"1.e+234", m_calcInput.ToString(10, false), L"Verify ToString of exponent with value."); - } - TEST_METHOD(ToStringInteger) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - VERIFY_ARE_EQUAL(L"1", m_calcInput.ToString(10, true), L"Verify ToString of integer value hides decimal."); - } - TEST_METHOD(ToStringBaseTooLong) - { - wstring maxStr{}; - for (size_t i = 0; i < MAX_STRLEN + 1; i++) - { - maxStr += L"1"; - m_calcInput.TryAddDigit(1, 10, false, maxStr, 64, 100); - } - auto result = m_calcInput.ToString(10, false); - VERIFY_IS_TRUE(result.empty(), L"Verify ToString of base value that is too large yields empty string."); - } - TEST_METHOD(ToStringExponentTooLong) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryBeginExponent(); - wstring maxStr{L"11"}; - bool exponentCapped = false; - for (size_t i = 0; i < MAX_STRLEN + 1; i++) - { - maxStr += L"1"; - if (!m_calcInput.TryAddDigit(1, 10, false, maxStr, 64, MAX_STRLEN + 25)) - { - exponentCapped = true; - } - } - auto result = m_calcInput.ToString(10, false); - - // TryAddDigit caps the exponent length to C_EXP_MAX_DIGITS = 4, so ToString() succeeds. - // If that cap is removed, ToString() should return an empty string. - if (exponentCapped) - { - VERIFY_ARE_EQUAL(L"1.e+1111", result, L"Verify ToString succeeds; exponent length is capped at C_EXP_MAX_DIGITS."); - } - else - { - VERIFY_IS_TRUE(result.empty(), L"Verify ToString of exponent value that is too large yields empty string."); - } - } - - TEST_METHOD(ToRational) - { - m_calcInput.TryAddDigit(1, 10, false, L"999", 64, 32); - m_calcInput.TryAddDigit(2, 10, false, L"999", 64, 32); - m_calcInput.TryAddDigit(3, 10, false, L"999", 64, 32); - VERIFY_ARE_EQUAL(L"123", m_calcInput.ToString(10, false), L"Verify input before conversion to rational."); - - auto rat = m_calcInput.ToRational(10, false); - VERIFY_ARE_EQUAL(1, rat.P().Mantissa().size(), L"Verify digit count of rational."); - VERIFY_ARE_EQUAL(123, rat.P().Mantissa().front(), L"Verify first digit of mantissa."); - } - - private: - CalcEngine::CalcInput m_calcInput; - }; -} diff --git a/internal/CalculatorUnitTests/CalculatorManagerTest.cpp b/internal/CalculatorUnitTests/CalculatorManagerTest.cpp deleted file mode 100644 index 5101e7d..0000000 --- a/internal/CalculatorUnitTests/CalculatorManagerTest.cpp +++ /dev/null @@ -1,1123 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" - -#include - -#include "CalcManager\CalculatorHistory.h" -#include "CalcViewModel\Common\EngineResourceProvider.h" - -using namespace CalculatorApp; -using namespace CalculationManager; -using namespace Platform; -using namespace std; - -namespace CalculatorManagerTest -{ - class CalculatorManagerDisplayTester : public ICalcDisplay - { - public: - CalculatorManagerDisplayTester() - { - Reset(); - } - - void Reset() - { - m_isError = false; - m_maxDigitsCalledCount = 0; - m_binaryOperatorReceivedCallCount = 0; - } - - void SetPrimaryDisplay(const wstring& text, bool isError) override - { - m_primaryDisplay = text; - m_isError = isError; - } - void SetIsInError(bool isError) override - { - m_isError = isError; - } - void SetExpressionDisplay(_Inout_ std::shared_ptr>> const &tokens, _Inout_ std::shared_ptr>> const &commands) - { - m_expression.clear(); - unsigned int nTokens = 0; - std::pair currentPair; - tokens->GetSize(&nTokens); - for (unsigned int i = 0; i < nTokens; ++i) - { - tokens->GetAt(i, ¤tPair); - m_expression += currentPair.first; - } - } - void SetMemorizedNumbers(const vector& numbers) override - { - m_memorizedNumberStrings = numbers; - } - - void SetParenDisplayText(const std::wstring& parenthesisCount) override - { - m_parenDisplay = parenthesisCount; - } - - const wstring& GetPrimaryDisplay() const - { - return m_primaryDisplay; - } - const wstring& GetExpression() const - { - return m_expression; - } - const vector& GetMemorizedNumbers() const - { - return m_memorizedNumberStrings; - } - bool GetIsError() const - { - return m_isError; - } - - void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) - { - } - - void MaxDigitsReached() override - { - m_maxDigitsCalledCount++; - } - - int GetMaxDigitsCalledCount() - { - return m_maxDigitsCalledCount; - } - - void BinaryOperatorReceived() - { - m_binaryOperatorReceivedCallCount++; - } - - void MemoryItemChanged(unsigned int indexOfMemory) - { - } - - int GetBinaryOperatorReceivedCallCount() - { - return m_binaryOperatorReceivedCallCount; - } - - private: - wstring m_primaryDisplay; - wstring m_expression; - wstring m_parenDisplay; - bool m_isError; - vector m_memorizedNumberStrings; - int m_maxDigitsCalledCount; - int m_binaryOperatorReceivedCallCount; - }; - - - class TestDriver - { - private: - static shared_ptr m_displayTester; - static shared_ptr m_calculatorManager; - - public: - static void Initialize(shared_ptr displayTester, shared_ptr calculatorManager) - { - m_displayTester = displayTester; - m_calculatorManager = calculatorManager; - } - - static void Test(wstring expectedPrimary, wstring expectedExpression, Command testCommands[], - bool cleanup = true, bool isScientific = false) - { - if (cleanup) - { - m_calculatorManager->Reset(); - } - - if (isScientific) - { - m_calculatorManager->SendCommand(Command::ModeScientific); - } - - Command* currentCommand = testCommands; - while (*currentCommand != Command::CommandNULL) - { - m_calculatorManager->SendCommand(*currentCommand++); - } - - VERIFY_ARE_EQUAL(expectedPrimary, m_displayTester->GetPrimaryDisplay()); - if (expectedExpression != L"N/A") - { - VERIFY_ARE_EQUAL(expectedExpression, m_displayTester->GetExpression()); - } - } - }; - - class CalculatorManagerTest - { - public: - // Declare this class as a TestClass, and supply metadata if necessary. - TEST_CLASS(CalculatorManagerTest); - TEST_CLASS_SETUP(CommonSetup); - - TEST_METHOD(CalculatorManagerTestStandard); - - TEST_METHOD(CalculatorManagerTestScientific); - TEST_METHOD(CalculatorManagerTestScientific2); - TEST_METHOD(CalculatorManagerTestScientificParenthesis); - TEST_METHOD(CalculatorManagerTestScientificError); - TEST_METHOD(CalculatorManagerTestScientificModeChange); - - TEST_METHOD(CalculatorManagerTestModeChange); - - 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); - - TEST_METHOD(CalculatorManagerTestBinaryOperatorReceived); - TEST_METHOD(CalculatorManagerTestBinaryOperatorReceived_Multiple); - TEST_METHOD(CalculatorManagerTestBinaryOperatorReceived_LongInput); - - TEST_METHOD_CLEANUP(Cleanup); - - - private: - static std::shared_ptr m_calculatorManager; - static std::shared_ptr m_resourceProvider; - static std::shared_ptr m_calculatorDisplayTester; - void ExecuteCommands(Command commands[]); - void ExecuteCommands(const vector& commands); - - vector CommandListFromStringInput(const wstring& input) - { - vector result{}; - for (auto iter = input.begin(); iter != input.end(); iter++) - { - wchar_t ch = *iter; - Command asCommand = Command::CommandNULL; - if (ch == L'.') - { - asCommand = Command::CommandPNT; - } - else if (L'0' <= ch && ch <= L'9') - { - int diff = static_cast(ch) - static_cast(L'0'); - asCommand = static_cast(diff + static_cast(Command::Command0)); - } - - if (asCommand != Command::CommandNULL) - { - result.push_back(asCommand); - } - } - - return result; - } - - void TestMaxDigitsReachedScenario(const wstring& constInput) - { - CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester *)m_calculatorDisplayTester.get(); - - // Make sure we're in a clean state. - VERIFY_ARE_EQUAL(0, pCalculatorDisplay->GetMaxDigitsCalledCount()); - - vector commands = CommandListFromStringInput(constInput); - VERIFY_IS_FALSE(commands.empty()); - - // The last element in the list should always cause MaxDigitsReached - // Remember the command but remove from the actual input that is sent - Command finalInput = commands[commands.size() - 1]; - commands.pop_back(); - wstring input = constInput.substr(0, constInput.length() - 1); - - m_calculatorManager->SetStandardMode(); - ExecuteCommands(commands); - - wstring expectedDisplay = input; - wstring display = pCalculatorDisplay->GetPrimaryDisplay(); - VERIFY_ARE_EQUAL(expectedDisplay, display); - - m_calculatorManager->SendCommand(finalInput); - - // Verify MaxDigitsReached - display = pCalculatorDisplay->GetPrimaryDisplay(); - VERIFY_ARE_EQUAL(expectedDisplay, display); - - // MaxDigitsReached should have been called once - VERIFY_IS_LESS_THAN(0, pCalculatorDisplay->GetMaxDigitsCalledCount()); - } - - void SerialzieAndDeSerialize() - { - 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(); - SerialzieAndDeSerialize(); - 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 CalculatorManagerTest::m_calculatorManager; - std::shared_ptr CalculatorManagerTest::m_calculatorDisplayTester; - std::shared_ptr CalculatorManagerTest::m_resourceProvider; - std::shared_ptr TestDriver::m_displayTester; - std::shared_ptr TestDriver::m_calculatorManager; - - // Creates instance of CalculationManager before running tests - bool CalculatorManagerTest::CommonSetup() - { - m_calculatorDisplayTester = std::make_shared(); - m_resourceProvider = std::make_shared(); - m_calculatorManager = std::make_shared(m_calculatorDisplayTester.get(), m_resourceProvider.get()); - TestDriver::Initialize(m_calculatorDisplayTester, m_calculatorManager); - return true; - } - - // Resets calculator state to start state after each test - bool CalculatorManagerTest::Cleanup() - { - m_calculatorManager->Reset(); - m_calculatorDisplayTester->Reset(); - return true; - } - - void CalculatorManagerTest::ExecuteCommands(Command commands[]) - { - Command* itr = commands; - while (*itr != Command::CommandNULL) - { - m_calculatorManager->SendCommand(*itr); - itr++; - } - } - - void CalculatorManagerTest::ExecuteCommands(const vector& commands) - { - for (const Command& command : commands) - { - if (command == Command::CommandNULL) - { - break; - } - - m_calculatorManager->SendCommand(command); - } - } - - void CalculatorManagerTest::CalculatorManagerTestStandard() - { - 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 }; - TestDriver::Test(L"0", L"0 + ", commands2); - - 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 }; - 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 }; - 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 }; - TestDriver::Test(L"-9", L"", commands7); - - 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 }; - 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 }; - 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 }; - 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 }; - 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 }; - TestDriver::Test(L"60", L"", commands14); - - 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 }; - 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 }; - TestDriver::Test(L"14", L"12 + 2 + ", commands17); - - 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 }; - TestDriver::Test(L"1", L"", commands19); - - 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 }; - 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 }; - 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 }; - TestDriver::Test(L"123.456", L"", commands1, true, true); - - Command commands2[] = { Command::CommandADD, Command::CommandNULL }; - TestDriver::Test(L"0", L"0 + ", commands2, true, true); - - 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 }; - 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 }; - 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 }; - 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 }; - 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 }; - 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 }; - 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 }; - 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 }; - 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 }; - TestDriver::Test(L"60", L"", commands14, true, true); - - 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 }; - 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 }; - TestDriver::Test(L"14", L"12 + 2 + ", commands17, true, true); - - 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 }; - TestDriver::Test(L"1", L"", commands19, true, true); - - 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 }; - 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 }; - 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 }; - TestDriver::Test(L"2.0009748976330773374220277351385", L"\x221A(\x221A(\x221A(257)))", commands24, true, true); - } - - // Scientific functions from the scientific calculator - void CalculatorManagerTest::CalculatorManagerTestScientific2() - { - Command commands1[] = { Command::Command1, Command::Command2, Command::CommandSQR, Command::CommandNULL }; - TestDriver::Test(L"144", L"sqr(12)", commands1, true, true); - - 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 }; - TestDriver::Test(L"25", L"5 ^ 2 + ", commands3, true, true); - - 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 commands7[] = { Command::Command1, Command::Command0, Command::CommandLOG, Command::CommandNULL }; - TestDriver::Test(L"1", L"log(10)", commands7, true, true); - - Command commands8[] = { Command::Command5, Command::CommandPOW10, Command::CommandNULL }; - TestDriver::Test(L"100,000", L"10^(5)", commands8, true, true); - - Command commands9[] = { Command::Command1, Command::Command0, Command::CommandLN, Command::CommandNULL }; - TestDriver::Test(L"2.3025850929940456840179914546844", L"ln(10)", commands9, true, true); - - Command commands10[] = { Command::Command1, Command::CommandSIN, Command::CommandNULL }; - TestDriver::Test(L"0.01745240643728351281941897851632", L"sin\x2080(1)", commands10, true, true); - - Command commands11[] = { Command::Command1, Command::CommandCOS, Command::CommandNULL }; - TestDriver::Test(L"0.99984769515639123915701155881391", L"cos\x2080(1)", commands11, true, true); - - Command commands12[] = { Command::Command1, Command::CommandTAN, Command::CommandNULL }; - TestDriver::Test(L"0.01745506492821758576512889521973", L"tan\x2080(1)", commands12, true, true); - - Command commands13[] = { Command::Command1, Command::CommandASIN, Command::CommandNULL }; - TestDriver::Test(L"90", L"sin\x2080\x207B\x00B9(1)", commands13, true, true); - - Command commands14[] = { Command::Command1, Command::CommandACOS, Command::CommandNULL }; - TestDriver::Test(L"0", L"cos\x2080\x207B\x00B9(1)", commands14, true, true); - - Command commands15[] = { Command::Command1, Command::CommandATAN, Command::CommandNULL }; - TestDriver::Test(L"45", L"tan\x2080\x207B\x00B9(1)", commands15, true, true); - - 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 }; - TestDriver::Test(L"1", L"5 ^ 0 + ", commands17); - - 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 }; - 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 }; - 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 }; - 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 }; - 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 }; - 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 }; - TestDriver::Test(L"12", L"((12)", commands2, true, true); - - 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 }; - 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 }; - TestDriver::Test(L"4", L"", commands5, true, true); - } - - void CalculatorManagerTest::CalculatorManagerTestScientificError() - { - 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()); - - Command commands2[] = { Command::Command2, Command::CommandSIGN, Command::CommandLOG, Command::CommandNULL }; - 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 }; - TestDriver::Test(L"Result is undefined", L"0 \x00F7 ", commands3, true, true); - VERIFY_IS_TRUE(m_calculatorDisplayTester->GetIsError()); - - // Do the same tests for the basic calculator - TestDriver::Test(L"Cannot divide by zero", L"1 \x00F7 ", commands1); - VERIFY_IS_TRUE(m_calculatorDisplayTester->GetIsError()); - TestDriver::Test(L"Invalid input", L"log(-2)", commands2); - VERIFY_IS_TRUE(m_calculatorDisplayTester->GetIsError()); - TestDriver::Test(L"Result is undefined", L"0 \x00F7 ", commands3); - VERIFY_IS_TRUE(m_calculatorDisplayTester->GetIsError()); - } - - // Radians and Grads Test - void CalculatorManagerTest::CalculatorManagerTestScientificModeChange() - { - Command commands1[] = { Command::CommandRAD, Command::CommandPI, Command::CommandSIN, Command::CommandNULL }; - TestDriver::Test(L"0", L"N/A", commands1, true, true); - - Command commands2[] = { Command::CommandRAD, Command::CommandPI, Command::CommandCOS, Command::CommandNULL }; - TestDriver::Test(L"-1", L"N/A", commands2, true, true); - - 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 }; - TestDriver::Test(L"0", L"N/A", commands4, true, true); - - 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 }; - TestDriver::Test(L"0", L"N/A", commands6, true, true); - } - - void CalculatorManagerTest::CalculatorManagerTestModeChange() - { - Command commands1[] = { Command::Command1, Command::Command2, Command::Command3, Command::CommandNULL }; - TestDriver::Test(L"123", L"", commands1, true, false); - - Command commands2[] = { Command::ModeScientific, Command::CommandNULL }; - TestDriver::Test(L"0", L"", commands2, true, false); - - Command commands3[] = { Command::Command1, Command::Command2, Command::Command3, Command::CommandNULL }; - TestDriver::Test(L"123", L"", commands3, true, false); - - Command commands4[] = { Command::ModeProgrammer, Command::CommandNULL }; - TestDriver::Test(L"0", L"", commands4, true, false); - - Command commands5[] = { Command::Command1, Command::Command2, Command::Command3, Command::CommandNULL }; - TestDriver::Test(L"123", L"", commands5, true, false); - - Command commands6[] = { Command::ModeScientific, Command::CommandNULL }; - TestDriver::Test(L"0", L"", commands6, true, false); - - Command commands7[] = { Command::Command6, Command::Command7, Command::CommandADD, Command::CommandNULL }; - TestDriver::Test(L"67", L"67 + ", commands7, true, false); - - Command commands8[] = { Command::ModeBasic, Command::CommandNULL }; - TestDriver::Test(L"0", L"", commands8, true, false); - } - - void CalculatorManagerTest::CalculatorManagerTestMemory() - { - Command scientificCalculatorTest52[] = { Command::Command1, Command::CommandSTORE, Command::CommandNULL }; - wstring expectedPrimaryDisplayTestScientific52(L"1"); - wstring expectedExpressionDisplayTestScientific52(L""); - - Command scientificCalculatorTest53[] = { Command::Command1, Command::CommandNULL }; - wstring expectedPrimaryDisplayTestScientific53(L"1"); - wstring expectedExpressionDisplayTestScientific53(L""); - - CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester *)m_calculatorDisplayTester.get(); - wstring resultPrimary = L""; - wstring resultExpression = L""; - - Cleanup(); - ExecuteCommands(scientificCalculatorTest52); - resultPrimary = pCalculatorDisplay->GetPrimaryDisplay(); - resultExpression = pCalculatorDisplay->GetExpression(); - VERIFY_ARE_EQUAL(expectedPrimaryDisplayTestScientific52, resultPrimary); - - Cleanup(); - ExecuteCommands(scientificCalculatorTest53); - m_calculatorManager->MemorizeNumber(); - m_calculatorManager->SendCommand(Command::CommandCLEAR); - m_calculatorManager->MemorizedNumberLoad(0); - resultPrimary = pCalculatorDisplay->GetPrimaryDisplay(); - resultExpression = pCalculatorDisplay->GetExpression(); - VERIFY_ARE_EQUAL(expectedPrimaryDisplayTestScientific52, resultPrimary); - - Cleanup(); - m_calculatorManager->SendCommand(Command::Command1); - m_calculatorManager->MemorizeNumber(); - m_calculatorManager->SendCommand(Command::CommandCLEAR); - m_calculatorManager->SendCommand(Command::Command2); - m_calculatorManager->MemorizeNumber(); - m_calculatorManager->SendCommand(Command::CommandCLEAR); - m_calculatorManager->MemorizedNumberLoad(1); - resultPrimary = pCalculatorDisplay->GetPrimaryDisplay(); - VERIFY_ARE_EQUAL(wstring(L"1"), resultPrimary); - - m_calculatorManager->MemorizedNumberLoad(0); - resultPrimary = pCalculatorDisplay->GetPrimaryDisplay(); - VERIFY_ARE_EQUAL(wstring(L"2"), resultPrimary); - - Cleanup(); - m_calculatorManager->SendCommand(Command::Command1); - m_calculatorManager->SendCommand(Command::CommandSIGN); - m_calculatorManager->MemorizeNumber(); - m_calculatorManager->SendCommand(Command::CommandADD); - m_calculatorManager->SendCommand(Command::Command2); - m_calculatorManager->SendCommand(Command::CommandEQU); - m_calculatorManager->MemorizeNumber(); - m_calculatorManager->SendCommand(Command::CommandMUL); - m_calculatorManager->SendCommand(Command::Command2); - m_calculatorManager->MemorizeNumber(); - - vector memorizedNumbers = pCalculatorDisplay->GetMemorizedNumbers(); - - vector expectedMemorizedNumbers; - expectedMemorizedNumbers.push_back(L"2"); - expectedMemorizedNumbers.push_back(L"1"); - expectedMemorizedNumbers.push_back(L"-1"); - - - bool isEqual = false; - if (memorizedNumbers.size() < expectedMemorizedNumbers.size()) - { - isEqual = std::equal(memorizedNumbers.begin(), memorizedNumbers.end(), expectedMemorizedNumbers.begin()); - } - else - { - isEqual = std::equal(expectedMemorizedNumbers.begin(), expectedMemorizedNumbers.end(), memorizedNumbers.begin()); - } - VERIFY_IS_TRUE(isEqual); - - m_calculatorManager->SendCommand(Command::CommandCLEAR); - m_calculatorManager->SendCommand(Command::Command2); - m_calculatorManager->MemorizedNumberAdd(0); - m_calculatorManager->MemorizedNumberAdd(1); - m_calculatorManager->MemorizedNumberAdd(2); - - memorizedNumbers = pCalculatorDisplay->GetMemorizedNumbers(); - - expectedMemorizedNumbers.clear(); - expectedMemorizedNumbers.push_back(L"4"); - expectedMemorizedNumbers.push_back(L"3"); - expectedMemorizedNumbers.push_back(L"1"); - - if (memorizedNumbers.size() < expectedMemorizedNumbers.size()) - { - isEqual = std::equal(memorizedNumbers.begin(), memorizedNumbers.end(), expectedMemorizedNumbers.begin()); - } - else - { - isEqual = std::equal(expectedMemorizedNumbers.begin(), expectedMemorizedNumbers.end(), memorizedNumbers.begin()); - } - VERIFY_IS_TRUE(isEqual); - - m_calculatorManager->SendCommand(Command::CommandCLEAR); - m_calculatorManager->SendCommand(Command::Command1); - m_calculatorManager->SendCommand(Command::CommandPNT); - m_calculatorManager->SendCommand(Command::Command5); - - m_calculatorManager->MemorizedNumberSubtract(0); - m_calculatorManager->MemorizedNumberSubtract(1); - m_calculatorManager->MemorizedNumberSubtract(2); - - memorizedNumbers = pCalculatorDisplay->GetMemorizedNumbers(); - - expectedMemorizedNumbers.clear(); - expectedMemorizedNumbers.push_back(L"2.5"); - expectedMemorizedNumbers.push_back(L"1.5"); - expectedMemorizedNumbers.push_back(L"-0.5"); - - if (memorizedNumbers.size() < expectedMemorizedNumbers.size()) - { - isEqual = std::equal(memorizedNumbers.begin(), memorizedNumbers.end(), expectedMemorizedNumbers.begin()); - } - else - { - isEqual = std::equal(expectedMemorizedNumbers.begin(), expectedMemorizedNumbers.end(), memorizedNumbers.begin()); - } - VERIFY_IS_TRUE(isEqual); - - // Memorizing 101 numbers, which exceeds the limit. - Cleanup(); - for (int i = 0; i < 101; i++) - { - m_calculatorManager->SendCommand(Command::Command1); - m_calculatorManager->MemorizeNumber(); - } - - memorizedNumbers = pCalculatorDisplay->GetMemorizedNumbers(); - VERIFY_ARE_EQUAL((size_t)100, memorizedNumbers.size()); - - // Memorizing new number, which should show up at the top of the memory - m_calculatorManager->SendCommand(Command::Command2); - m_calculatorManager->MemorizeNumber(); - memorizedNumbers = pCalculatorDisplay->GetMemorizedNumbers(); - VERIFY_ARE_EQUAL(wstring(L"2"), memorizedNumbers.at(0)); - - // Test for trying to memorize invalid value - m_calculatorManager->SendCommand(Command::Command2); - m_calculatorManager->SendCommand(Command::CommandSIGN); - m_calculatorManager->SendCommand(Command::CommandSQRT); - 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 deserialze 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); - - SerialzieAndDeSerialize(); - - 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 memorizedNumbers = pCalculatorDisplay->GetMemorizedNumbers(); - wstring primaryDisplay = pCalculatorDisplay->GetPrimaryDisplay(); - wstring expressionDisplay = pCalculatorDisplay->GetExpression(); - - SerialzieAndDeSerialize(); - - vector 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(); - - SerialzieAndDeSerialize(); - - 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(); - - SerialzieAndDeSerialize(); - - 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() - { - TestMaxDigitsReachedScenario(L"1,234,567,891,011,1213"); - } - - void CalculatorManagerTest::CalculatorManagerTestMaxDigitsReached_LeadingDecimal() - { - TestMaxDigitsReachedScenario(L"0.12345678910111213"); - } - - void CalculatorManagerTest::CalculatorManagerTestMaxDigitsReached_TrailingDecimal() - { - TestMaxDigitsReachedScenario(L"123,456,789,101,112.13"); - } - - void CalculatorManagerTest::CalculatorManagerTestBinaryOperatorReceived() - { - CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester *)m_calculatorDisplayTester.get(); - - VERIFY_ARE_EQUAL(0, pCalculatorDisplay->GetBinaryOperatorReceivedCallCount()); - - ExecuteCommands({ - Command::Command1, - Command::CommandADD - }); - - wstring display = pCalculatorDisplay->GetPrimaryDisplay(); - VERIFY_ARE_EQUAL(wstring(L"1"), display); - - // Verify BinaryOperatorReceived - VERIFY_ARE_EQUAL(1, pCalculatorDisplay->GetBinaryOperatorReceivedCallCount()); - } - - void CalculatorManagerTest::CalculatorManagerTestBinaryOperatorReceived_Multiple() - { - CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester *)m_calculatorDisplayTester.get(); - - VERIFY_ARE_EQUAL(0, pCalculatorDisplay->GetBinaryOperatorReceivedCallCount()); - - ExecuteCommands({ - Command::Command1, - Command::CommandADD, - Command::CommandSUB, - Command::CommandMUL - }); - - wstring display = pCalculatorDisplay->GetPrimaryDisplay(); - VERIFY_ARE_EQUAL(wstring(L"1"), display); - - // Verify BinaryOperatorReceived - VERIFY_ARE_EQUAL(3, pCalculatorDisplay->GetBinaryOperatorReceivedCallCount()); - } - - void CalculatorManagerTest::CalculatorManagerTestBinaryOperatorReceived_LongInput() - { - CalculatorManagerDisplayTester* pCalculatorDisplay = (CalculatorManagerDisplayTester *)m_calculatorDisplayTester.get(); - - VERIFY_ARE_EQUAL(0, pCalculatorDisplay->GetBinaryOperatorReceivedCallCount()); - - ExecuteCommands({ - Command::Command1, - Command::CommandADD, - Command::Command2, - Command::CommandMUL, - Command::Command1, - Command::Command0, - Command::CommandSUB, - Command::Command5, - Command::CommandDIV, - Command::Command5, - Command::CommandEQU - }); - - wstring display = pCalculatorDisplay->GetPrimaryDisplay(); - VERIFY_ARE_EQUAL(wstring(L"5"), display); - - // Verify BinaryOperatorReceived - VERIFY_ARE_EQUAL(4, pCalculatorDisplay->GetBinaryOperatorReceivedCallCount()); - } - -} /* namespace CalculationManagerUnitTests */ - diff --git a/internal/CalculatorUnitTests/CalculatorUnitTests.vcxproj b/internal/CalculatorUnitTests/CalculatorUnitTests.vcxproj deleted file mode 100644 index e92bdfa..0000000 --- a/internal/CalculatorUnitTests/CalculatorUnitTests.vcxproj +++ /dev/null @@ -1,365 +0,0 @@ - - - - - - - {E527A1F4-6B63-4DD0-B540-B8C06CFC3AFE} - CalculatorUnitTests - en-US - 15.0 - true - Windows Store - 10.0.17763.0 - 10.0.17134.0 - 10.0 - CalculatorUnitTests - - true - true - - true - - - - - x64 - - - true - true - false - - - true - true - false - - - true - false - - - true - false - - - true - true - false - - - true - false - - - true - true - false - - - true - false - - - - Debug - ARM - - - Debug - ARM64 - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - ARM64 - - - Release - Win32 - - - Release - x64 - - - - Application - true - v141 - - - Application - true - v141 - - - Application - true - v141 - - - Application - true - v141 - - - Application - false - true - v141 - - - Application - false - true - v141 - - - Application - false - true - v141 - - - Application - false - true - v141 - - - - - - - - - - - - - - - - - - - - - - - - - - - - TemporaryKey.pfx - - - - /bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions) - 4453;28204 - $(SolutionDir)..\src\;$(SolutionDir)..\src\CalcManager;$(SolutionDir)..\src\CalcViewModel;%(AdditionalIncludeDirectories) - - - %(AdditionalLibraryDirectories) - - - - - /bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions) - 4453;28204 - $(SolutionDir)..\src\;$(SolutionDir)..\src\CalcManager;$(SolutionDir)..\src\CalcViewModel;%(AdditionalIncludeDirectories) - - - %(AdditionalLibraryDirectories) - - - - - /bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions) - 4453;28204 - $(SolutionDir)..\src\;$(SolutionDir)..\src\CalcManager;$(SolutionDir)..\src\CalcViewModel;%(AdditionalIncludeDirectories) - - - %(AdditionalLibraryDirectories) - - - - - /bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions) - 4453;28204 - $(SolutionDir)..\src\;$(SolutionDir)..\src\CalcManager;$(SolutionDir)..\src\CalcViewModel;%(AdditionalIncludeDirectories) - - - %(AdditionalLibraryDirectories) - - - - - /bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions) - 4453;28204 - $(SolutionDir)..\src\;$(SolutionDir)..\src\CalcManager;$(SolutionDir)..\src\CalcViewModel;%(AdditionalIncludeDirectories) - - - %(AdditionalLibraryDirectories) - - - - - /bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions) - 4453;28204 - $(SolutionDir)..\src\;$(SolutionDir)..\src\CalcManager;$(SolutionDir)..\src\CalcViewModel;%(AdditionalIncludeDirectories) - - - %(AdditionalLibraryDirectories) - - - - - /bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions) - 4453;28204 - $(SolutionDir)..\src\;$(SolutionDir)..\src\CalcManager;$(SolutionDir)..\src\CalcViewModel;%(AdditionalIncludeDirectories) - - - %(AdditionalLibraryDirectories) - - - - - /bigobj /await /std:c++17 /permissive- /Zc:twoPhase- %(AdditionalOptions) - 4453;28204 - $(SolutionDir)..\src\;$(SolutionDir)..\src\CalcManager;$(SolutionDir)..\src\CalcViewModel;%(AdditionalIncludeDirectories) - - - %(AdditionalLibraryDirectories) - - - - - - - - - - - - - - - - - - - - - - UnitTestApp.xaml - - - - - Designer - - - - - Designer - - - - - - - - - - - - - - - - - - - - - UnitTestApp.xaml - - - Create - Create - Create - Create - Create - Create - Create - Create - - - - - - - - - - - - - - - - - - {311e866d-8b93-4609-a691-265941fee101} - - - {90e9761d-9262-4773-942d-caeae75d7140} - - - - - - - $(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\x86\Microsoft.VCLibs.x86.Debug.14.00.appx; - $(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\x86\Microsoft.VCLibs.x86.14.00.appx; - $(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\x64\Microsoft.VCLibs.x64.Debug.14.00.appx; - $(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\x64\Microsoft.VCLibs.x64.14.00.appx; - $(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\ARM\Microsoft.VCLibs.arm.Debug.14.00.appx; - $(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\ARM64\Microsoft.VCLibs.arm64.Debug.14.00.appx; - $(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\ARM\Microsoft.VCLibs.arm.14.00.appx; - $(UniversalTestCustomMacros)AppxPackageVCLibsDependency=$(AppxPackageTestDir)Dependencies\ARM64\Microsoft.VCLibs.arm64.14.00.appx; - $(UniversalTestCustomMacros)AppxPackagePublicKeyFile=$(AppxPackagePublicKeyFile);AppxPackageOutput=$(AppxPackageOutput); - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - \ No newline at end of file diff --git a/internal/CalculatorUnitTests/CalculatorUnitTests.vcxproj.filters b/internal/CalculatorUnitTests/CalculatorUnitTests.vcxproj.filters deleted file mode 100644 index ac251d6..0000000 --- a/internal/CalculatorUnitTests/CalculatorUnitTests.vcxproj.filters +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/internal/CalculatorUnitTests/CopyPasteManagerTest.cpp b/internal/CalculatorUnitTests/CopyPasteManagerTest.cpp deleted file mode 100644 index f4e9329..0000000 --- a/internal/CalculatorUnitTests/CopyPasteManagerTest.cpp +++ /dev/null @@ -1,602 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include - -#include "CalcViewModel\StandardCalculatorViewModel.h" -#include "CalcViewModel\Common\CopyPasteManager.h" - -using namespace CalculationManager; -using namespace CalculatorApp; -using namespace CalculatorApp::Common; -using namespace CalculatorApp::ViewModel; -using namespace Platform; -using namespace std; -using namespace WEX::Logging; -using namespace Windows::ApplicationModel::DataTransfer; -using namespace Windows::ApplicationModel::Resources; -using namespace Windows::Globalization; -using namespace Windows::Storage; - -namespace CalculatorUnitTests -{ - extern void ChangeMode(StandardCalculatorViewModel^ viewModel, int mode); - -#define ASSERT_POSITIVE_TESTCASES(func, dataSet) \ -{\ - int size = sizeof(dataSet)/sizeof(*dataSet);\ - while(--size)\ - {\ - VERIFY_ARE_EQUAL(func(dataSet[size]), dataSet[size]);\ - }\ -} - -#define ASSERT_NEGATIVE_TESTCASES(func, dataSet) \ -{\ - int size = sizeof(dataSet)/sizeof(*dataSet);;\ - while(--size)\ - {\ - VERIFY_ARE_EQUAL(func(dataSet[size]), StringReference(L"NoOp"));\ - }\ -} - -// returns a iterator from end -#define START_LOOP(dataSet)\ -{\ - int size = sizeof(dataSet)/sizeof(*dataSet);\ - while(--size)\ - { - -#define END_LOOP\ - }\ -} - - class CopyPasteManagerTest - { - public: - TEST_CLASS(CopyPasteManagerTest); - - TEST_METHOD(FunctionalCopyPasteTest); - TEST_METHOD(ValidateStandardPasteExpressionTest); - TEST_METHOD(ValidateScientificPasteExpressionTest); - TEST_METHOD(ValidateProgrammerDecPasteExpressionTest); - TEST_METHOD(ValidateProgrammerOctPasteExpressionTest); - TEST_METHOD(ValidateProgrammerHexPasteExpressionTest); - TEST_METHOD(ValidateProgrammerBinPasteExpressionTest); - TEST_METHOD(ValidateConverterPasteExpressionTest); - - TEST_METHOD(ValidatePasteExpressionErrorStates) - { - wstring exp_TooLong = L""; - for (int i = 0; i < m_CopyPasteManager.MaxPasteableLength / 8; i++) - { - exp_TooLong += L"-1234567"; - } - VERIFY_ARE_EQUAL(m_CopyPasteManager.ValidatePasteExpression(StringReference(exp_TooLong.c_str()), ViewMode::Standard, CategoryGroupType::Calculator, -1, -1), StringReference(exp_TooLong.c_str()), L"Verify ValidatePasteExpression handles expressions up to max length"); - exp_TooLong += L"1"; - VERIFY_ARE_EQUAL(m_CopyPasteManager.ValidatePasteExpression(StringReference(exp_TooLong.c_str()), ViewMode::Standard, CategoryGroupType::Calculator, -1, -1), StringReference(L"NoOp"), L"Verify ValidatePasteExpression returns NoOp for strings over max length"); - - VERIFY_ARE_EQUAL(m_CopyPasteManager.ValidatePasteExpression(StringReference(L""), ViewMode::Standard, CategoryGroupType::Calculator, -1, -1), StringReference(L"NoOp"), L"Verify empty string is invalid"); - - VERIFY_ARE_EQUAL(m_CopyPasteManager.ValidatePasteExpression(StringReference(L"123e456"), ViewMode::Standard, CategoryGroupType::Calculator, -1, -1), StringReference(L"NoOp"), L"Verify pasting unsupported strings for the current mode is invalid"); - - VERIFY_ARE_EQUAL(m_CopyPasteManager.ValidatePasteExpression(StringReference(L"123"), ViewMode::None, CategoryGroupType::None, -1, -1), StringReference(L"NoOp"), L"Verify pasting without a ViewMode or Category is invalid"); - }; - - TEST_METHOD(ValidateExtractOperands) - { - vector results = {}; - - vector oneOperand = { L"123456" }; - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"123456", ViewMode::Standard), oneOperand); - oneOperand = { L"123^456" }; - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"123^456", ViewMode::Standard), oneOperand); - - vector twoOperands = { L"123", L"456" }; - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"123+456", ViewMode::Standard), twoOperands); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"123-456", ViewMode::Standard), twoOperands); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"123*456", ViewMode::Standard), twoOperands); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"123/456", ViewMode::Standard), twoOperands); - - vector expOperand = { L"123e456" }; - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"123e456", ViewMode::Standard), expOperand); - expOperand = { L"123e4567" }; - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"123e4567", ViewMode::Standard), expOperand); - - vector twoOperandsParens = { L"((45)", L"(-30))" }; - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"((45)+(-30))", ViewMode::Scientific), twoOperandsParens); - }; - - TEST_METHOD(ValidateExtractOperandsErrors) - { - wstring exp_OperandLimit = L""; - for (int i = 0; i < m_CopyPasteManager.MaxOperandCount; i++) - { - exp_OperandLimit += L"+1"; - } - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(exp_OperandLimit, ViewMode::Standard).size(), 100, L"Verify ExtractOperands handles up to MaxOperandCount operands"); - - exp_OperandLimit += L"+1"; - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(exp_OperandLimit, ViewMode::Standard).size(), 0, L"Verify ExtractOperands returns empty vector on too many operands"); - - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"12e9999", ViewMode::Standard).size(), 1, L"Verify ExtractOperands handles up to 4 digit exponents"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ExtractOperands(L"12e10000", ViewMode::Standard).size(), 0, L"Verify ExtractOperands returns empty vector when the exponent is too long"); - }; - - TEST_METHOD(ValidateExpressionRegExMatch) - { - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{}, ViewMode::Standard, CategoryGroupType::Calculator, -1, -1), L"Verify empty list of operands returns false."); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"123" }, ViewMode::None, CategoryGroupType::Calculator, -1, -1), L"Verify invalid ViewMode/CategoryGroups return false."); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"123" }, ViewMode::Currency, CategoryGroupType::None, -1, -1), L"Verify invalid ViewMode/CategoryGroups return false."); - - Log::Comment(L"Verify operand lengths > max return false."); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"12345678901234567" }, ViewMode::Standard, CategoryGroupType::Calculator, -1, -1)); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"123456789012345678901234567890123" }, ViewMode::Scientific, CategoryGroupType::Calculator, -1, -1)); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"12345678901234567" }, ViewMode::None, CategoryGroupType::Converter, -1, -1)); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"11111111111111111" }, ViewMode::Programmer, CategoryGroupType::Calculator, HexBase, QwordType)); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"12345678901234567890" }, ViewMode::Programmer, CategoryGroupType::Calculator, DecBase, QwordType)); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"11111111111111111111111" }, ViewMode::Programmer, CategoryGroupType::Calculator, OctBase, QwordType)); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"10000000000000000000000000000000000000000000000000000000000000000" }, ViewMode::Programmer, CategoryGroupType::Calculator, BinBase, QwordType)); - - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"9223372036854775808" }, ViewMode::Programmer, CategoryGroupType::Calculator, DecBase, QwordType), L"Verify operand values > max return false."); - - VERIFY_IS_TRUE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"((((((((((((((((((((123))))))))))))))))))))" }, ViewMode::Scientific, CategoryGroupType::Calculator, -1, -1), L"Verify sanitized operand is detected as within max length."); - VERIFY_IS_TRUE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"9223372036854775807" }, ViewMode::Programmer, CategoryGroupType::Calculator, DecBase, QwordType), L"Verify operand values == max return true."); - - Log::Comment(L"Verify all operands must match patterns."); - VERIFY_IS_TRUE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"123", L"456" }, ViewMode::Standard, CategoryGroupType::Calculator, -1, -1)); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"123", L"1e23" }, ViewMode::Standard, CategoryGroupType::Calculator, -1, -1)); - - VERIFY_IS_TRUE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"1.23e+456" }, ViewMode::Scientific, CategoryGroupType::Calculator, -1, -1), L"Verify operand only needs to match one pattern."); - - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"123", L"12345678901234567" }, ViewMode::Standard, CategoryGroupType::Calculator, -1, -1), L"Verify all operands must be within maxlength"); - VERIFY_IS_FALSE(m_CopyPasteManager.ExpressionRegExMatch(vector{ L"123", L"9223372036854775808" }, ViewMode::Programmer, CategoryGroupType::Calculator, DecBase, QwordType), L"Verify all operand must be within max value."); - }; - - TEST_METHOD(ValidateGetMaxOperandLengthAndValue) - { - pair standardModeMaximums = make_pair(m_CopyPasteManager.MaxStandardOperandLength, 0); - pair scientificModeMaximums = make_pair(m_CopyPasteManager.MaxScientificOperandLength, 0); - pair converterModeMaximums = make_pair(m_CopyPasteManager.MaxConverterInputLength, 0); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Standard, CategoryGroupType::None, -1, -1), standardModeMaximums, L"Verify Standard mode maximum values"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Scientific, CategoryGroupType::None, -1, -1), scientificModeMaximums, L"Verify Scientific mode maximum values"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::None, CategoryGroupType::Converter, -1, -1), converterModeMaximums, L"Verify Converter mode maximum values"); - - unsigned long long int ullQwordMax = UINT64_MAX; - unsigned long long int ullDwordMax = UINT32_MAX; - unsigned long long int ullWordMax = UINT16_MAX; - unsigned long long int ullByteMax = UINT8_MAX; - Log::Comment(L"Verify Programmer Mode HexBase maximum values"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, HexBase, QwordType), make_pair((size_t)16u, ullQwordMax)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, HexBase, DwordType), make_pair((size_t)8u, ullDwordMax)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, HexBase, WordType), make_pair((size_t)4u, ullWordMax)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, HexBase, ByteType), make_pair((size_t)2u, ullByteMax)); - - Log::Comment(L"Verify Programmer Mode DecBase maximum values"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, DecBase, QwordType), make_pair((size_t)19u, ullQwordMax >> 1)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, DecBase, DwordType), make_pair((size_t)10u, ullDwordMax >> 1)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, DecBase, WordType), make_pair((size_t)5u, ullWordMax >> 1)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, DecBase, ByteType), make_pair((size_t)3u, ullByteMax >> 1)); - - Log::Comment(L"Verify Programmer Mode OctBase maximum values"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, OctBase, QwordType), make_pair((size_t)22u, ullQwordMax)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, OctBase, DwordType), make_pair((size_t)11u, ullDwordMax)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, OctBase, WordType), make_pair((size_t)6u, ullWordMax)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, OctBase, ByteType), make_pair((size_t)3u, ullByteMax)); - - Log::Comment(L"Verify Programmer Mode BinBase maximum values"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, BinBase, QwordType), make_pair((size_t)64u, ullQwordMax)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, BinBase, DwordType), make_pair((size_t)32u, ullDwordMax)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, BinBase, WordType), make_pair((size_t)16u, ullWordMax)); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::Programmer, CategoryGroupType::None, BinBase, ByteType), make_pair((size_t)8u, ullByteMax)); - - Log::Comment(L"Verify invalid ViewModes/Categories return 0 for max values"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.GetMaxOperandLengthAndValue(ViewMode::None, CategoryGroupType::None, -1, -1), make_pair((size_t)0u, 0ull)); - }; - - TEST_METHOD(ValidateSanitizeOperand) - { - VERIFY_ARE_EQUAL(m_CopyPasteManager.SanitizeOperand(L"((1234"), L"1234"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.SanitizeOperand(L"1234))"), L"1234"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.SanitizeOperand(L"-1234"), L"1234"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.SanitizeOperand(L"12-34"), L"1234"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.SanitizeOperand(L"((((1234))))"), L"1234"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.SanitizeOperand(L"1'2'3'4"), L"1234"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.SanitizeOperand(L"'''''1234''''"), L"1234"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.SanitizeOperand(L"1_2_3_4"), L"1234"); - VERIFY_ARE_EQUAL(m_CopyPasteManager.SanitizeOperand(L"______1234___"), L"1234"); - }; - - TEST_METHOD(ValidateTryOperandToULL) - { - unsigned long long int result = 0; - - Log::Comment(L"Verify TryOperandToULL HexBase conversion"); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"1234", HexBase, result)); - VERIFY_ARE_EQUAL(result, 0x1234ull); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"FF", HexBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFull); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"FFFFFFFFFFFFFFFF", HexBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"0xFFFFFFFFFFFFFFFF", HexBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"0XFFFFFFFFFFFFFFFF", HexBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"0X0FFFFFFFFFFFFFFFF", HexBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - - Log::Comment(L"Verify TryOperandToULL DecBase conversion"); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"1234", DecBase, result)); - VERIFY_ARE_EQUAL(result, 1234ull); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"18446744073709551615", DecBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"018446744073709551615", DecBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - - Log::Comment(L"Verify TryOperandToULL OctBase conversion"); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"777", OctBase, result)); - VERIFY_ARE_EQUAL(result, 0777ull); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"0777", OctBase, result)); - VERIFY_ARE_EQUAL(result, 0777ull); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"1777777777777777777777", OctBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"01777777777777777777777", OctBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - - Log::Comment(L"Verify TryOperandToULL BinBase conversion"); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"1111", BinBase, result)); - VERIFY_ARE_EQUAL(result, 0b1111ull); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"0010", BinBase, result)); - VERIFY_ARE_EQUAL(result, 0b10ull); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"1111111111111111111111111111111111111111111111111111111111111111", BinBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"01111111111111111111111111111111111111111111111111111111111111111", BinBase, result)); - VERIFY_ARE_EQUAL(result, 0xFFFF'FFFF'FFFF'FFFF); - - Log::Comment(L"Verify TryOperandToULL invalid numberBase defaults to DecBase"); - VERIFY_IS_TRUE(m_CopyPasteManager.TryOperandToULL(L"1234", 128, result)); - VERIFY_ARE_EQUAL(result, 1234ull); - - Log::Comment(L"Verify TryOperandToULL returns false when input is invalid or strtoull throws exceptions"); - // Max values + 1 - VERIFY_IS_FALSE(m_CopyPasteManager.TryOperandToULL(L"0xFFFFFFFFFFFFFFFFF1", HexBase, result)); - VERIFY_IS_FALSE(m_CopyPasteManager.TryOperandToULL(L"18446744073709551616", DecBase, result)); - VERIFY_IS_FALSE(m_CopyPasteManager.TryOperandToULL(L"2000000000000000000000", OctBase, result)); - VERIFY_IS_FALSE(m_CopyPasteManager.TryOperandToULL(L"11111111111111111111111111111111111111111111111111111111111111111", BinBase, result)); - // Invalid values/characters - VERIFY_IS_FALSE(m_CopyPasteManager.TryOperandToULL(L"-1", DecBase, result)); - VERIFY_IS_FALSE(m_CopyPasteManager.TryOperandToULL(L"5555", BinBase, result)); - VERIFY_IS_FALSE(m_CopyPasteManager.TryOperandToULL(L"xyz", BinBase, result)); - - }; - - TEST_METHOD(ValidateStandardScientificOperandLength) - { - VERIFY_ARE_EQUAL(m_CopyPasteManager.StandardScientificOperandLength(L""), 0); - VERIFY_ARE_EQUAL(m_CopyPasteManager.StandardScientificOperandLength(L"0.2"), 1); - VERIFY_ARE_EQUAL(m_CopyPasteManager.StandardScientificOperandLength(L"1.2"), 2); - VERIFY_ARE_EQUAL(m_CopyPasteManager.StandardScientificOperandLength(L"0."), 0); - VERIFY_ARE_EQUAL(m_CopyPasteManager.StandardScientificOperandLength(L"12345"), 5); - VERIFY_ARE_EQUAL(m_CopyPasteManager.StandardScientificOperandLength(L"-12345"), 6); - - }; - - TEST_METHOD(ValidateProgrammerOperandLength) - { - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"1001", BinBase), 4); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"1001b", BinBase), 4); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"1001B", BinBase), 4); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0b1001", BinBase), 4); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0B1001", BinBase), 4); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0y1001", BinBase), 4); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0Y1001", BinBase), 4); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0b", BinBase), 1); - - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"123456", OctBase), 6); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0t123456", OctBase), 6); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0T123456", OctBase), 6); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0o123456", OctBase), 6); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0O123456", OctBase), 6); - - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"", DecBase), 0); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"-", DecBase), 0); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"12345", DecBase), 5); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"-12345", DecBase), 5); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0n12345", DecBase), 5); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0N12345", DecBase), 5); - - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"123ABC", HexBase), 6); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0x123ABC", HexBase), 6); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"0X123ABC", HexBase), 6); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"123ABCh", HexBase), 6); - VERIFY_ARE_EQUAL(m_CopyPasteManager.ProgrammerOperandLength(L"123ABCH", HexBase), 6); - }; - - private: - CopyPasteManager m_CopyPasteManager; - String^ ValidateStandardPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Standard, -1/*number base*/, -1/*bitlength Type*/); - } - - String^ ValidateScientificPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Scientific, -1/*number base*/, -1/*bitlength Type*/); - } - - String^ ValidateConverterPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::None, CategoryGroupType::Converter, -1/*number base*/, -1/*bitlength Type*/); - } - - String^ ValidateProgrammerHexQwordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, HexBase/*number base*/, QwordType/*bitlength Type*/); - } - - String^ ValidateProgrammerHexDwordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, HexBase/*number base*/, DwordType/*bitlength Type*/); - } - - String^ ValidateProgrammerHexWordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, HexBase/*number base*/, WordType/*bitlength Type*/); - } - - String^ ValidateProgrammerHexBytePasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, HexBase/*number base*/, ByteType/*bitlength Type*/); - } - - String^ ValidateProgrammerDecQwordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, DecBase/*number base*/, QwordType/*bitlength Type*/); - } - - String^ ValidateProgrammerDecDwordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, DecBase/*number base*/, DwordType/*bitlength Type*/); - } - - String^ ValidateProgrammerDecWordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, DecBase/*number base*/, WordType/*bitlength Type*/); - } - - String^ ValidateProgrammerDecBytePasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, DecBase/*number base*/, ByteType/*bitlength Type*/); - } - - String^ ValidateProgrammerOctQwordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, OctBase/*number base*/, QwordType/*bitlength Type*/); - } - - String^ ValidateProgrammerOctDwordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, OctBase/*number base*/, DwordType/*bitlength Type*/); - } - - String^ ValidateProgrammerOctWordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, OctBase/*number base*/, WordType/*bitlength Type*/); - } - - String^ ValidateProgrammerOctBytePasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, OctBase/*number base*/, ByteType/*bitlength Type*/); - } - - String^ ValidateProgrammerBinQwordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, BinBase/*number base*/, QwordType/*bitlength Type*/); - } - - String^ ValidateProgrammerBinDwordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, BinBase/*number base*/, DwordType/*bitlength Type*/); - } - - String^ ValidateProgrammerBinWordPasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, BinBase/*number base*/, WordType/*bitlength Type*/); - } - - String^ ValidateProgrammerBinBytePasteExpression(_In_ String^ pastedText) - { - return m_CopyPasteManager.ValidatePasteExpression(pastedText, ViewMode::Programmer, BinBase/*number base*/, ByteType/*bitlength Type*/); - } - - - }; - - /************************************* - standard: - can paste simple numbers / expressions not exponential numbers / expressions - - scientific : - can paste exponential numbers / expressions too - - programmer : - can paste specific numbers / expressions based on radixes.Hex numbers such 13abe is allowed when radix is set to hex, but not allowed otherwise. - - converter : - can paste simple numbers not expressions - - List of test cases: - 1. simple unsigned number - 2. negative number - 3. exponential number with positive exp - 4. exponential number with negative exp - 5. exponential number with unsigned exp - 6. exponential number with very large(larger than 4 digit) exp - 7. expression involving simple numbers - 8. expression involving exponential numbers - 9. number with random text like xyz - 10. hex numbers - 11. binary numbers - 12. octal numbers - 13. very large number - 14. number with some escape characters in b/w like ",/. \n\r ", '" - 15. expression involving sin, cos or other mathematic functions - 16. expression having more than one operator in b/w operands - 17. expression involving open and close parenthesis (, ) - - ****************************************/ - - void CopyPasteManagerTest::FunctionalCopyPasteTest() - { - // Doesn't have test where converter is involved. Will add such a test later. - StandardCalculatorViewModel^ scvm = ref new StandardCalculatorViewModel(); - scvm->IsStandard = true; - String^ input[] = { L"123", L"12345", L"123+456", L"1,234", L"1 2 3", L"\n\r1,234\n", L"\n 1+\n2 ", L"1\"2" }; - - START_LOOP(input) - // paste number in standard mode and then validate the pastability of displayed number for other modes - scvm->OnPaste(input[size], ViewMode::Standard); - VERIFY_ARE_EQUAL(ValidateStandardPasteExpression(scvm->DisplayValue), scvm->DisplayValue); - VERIFY_ARE_EQUAL(ValidateScientificPasteExpression(scvm->DisplayValue), scvm->DisplayValue); - VERIFY_ARE_EQUAL(ValidateProgrammerHexQwordPasteExpression(scvm->DisplayValue), scvm->DisplayValue); - END_LOOP - } - - - void CopyPasteManagerTest::ValidateStandardPasteExpressionTest() - { - String^ positiveInput[] = { L"123", L"+123", L"-133", L"12345.", L"+12.34", L"12.345", L"012.034", L"-23.032", L"-.123", L".1234", L"012.012", L"123+456", L"123+-234", L"123*-345", L"123*4*-3", L"123*+4*-3", L"1,234", L"1 2 3", L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85", L"\n 1+\n2 ", L"1\"2", L"1234567891234567"/*boundary condition <=16 digits*/, L"2+2=", L"2+2= " }; - String^ negativeInput[] = { L"(123)+(456)", L"1.2e23"/*unsigned exponent*/, L"12345e-23", L"abcdef", L"xyz", L"ABab", L"e+234", L"12345678912345678"/*boundary condition: greater than 16 digits*/, L"SIN(2)", L"2+2==", L"2=+2" }; - - ASSERT_POSITIVE_TESTCASES(ValidateStandardPasteExpression, positiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateStandardPasteExpression, negativeInput); - } - - void CopyPasteManagerTest::ValidateScientificPasteExpressionTest() - { - String^ positiveInput[] = { L"123", L"+123", L"-133", L"123+456", L"12345e+023", L"1,234", L"1.23", L"-.123", L".1234", L"012.012", L"123+-234", L"123*-345", L"123*4*-3", L"123*+4*-3", L"1 2 3", L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85", L"\n 1+\n2 ", L"1\"2", L"1.2e+023", L"12345e-23", L"(123)+(456)", L"12345678912345678123456789012345", L"(123)+(456)=", L"2+2= " }; - String^ negativeInput[] = { L"1.2e23"/*unsigned exponent*/, L"abcdef", L"xyz", L"ABab", L"e+234", L"123456789123456781234567890123456"/*boundary condition: greater than 32 digits*/, L"SIN(2)", L"2+2==", L"2=+2" }; - - ASSERT_POSITIVE_TESTCASES(ValidateScientificPasteExpression, positiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateScientificPasteExpression, negativeInput); - } - - void CopyPasteManagerTest::ValidateProgrammerHexPasteExpressionTest() - { - String^ qwordPositiveInput[] = { L"123", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"12345e-23"/*note: here is considered as E of hex*/, L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85", L"\f\n1+2\t\r\v\x85", L"\n 1+\n2 ", L"e+234", L"1\"2", L"(123)+(456)", L"abcdef", L"ABab", L"ABCDF21abc41a"/*within boundary*/, L"0x1234", L"0xab12", L"0X1234", L"AB12h", L"BC34H", L"1234u", L"1234ul", L"1234ULL", L"2+2=", L"2+2= " }; - String^ qwordNegativeInput[] = { L"+123", L"1.23"/*floating number*/, L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"-133", L"1.2e+023", L"1.2e23"/*unsigned exponent*/, L"xyz", L"ABCDEF21abc41abc7"/*outside boundary of 16 digitis*/, L"SIN(2)", L"123+-234", L"1234x", L"A0x1234", L"0xx1234", L"1234uu", L"1234ulll", L"2+2==", L"2=+2" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerHexQwordPasteExpression, qwordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerHexQwordPasteExpression, qwordNegativeInput); - - String^ dwordPositiveInput[] = { L"123", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"12345e-23"/*note: here is considered as E of hex*/, L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85", L"\n 1+\n2 ", L"e+234", L"1\"2", L"(123)+(456)", L"abcdef", L"ABab", L"ABCD123a"/*within boundary*/, L"0x1234", L"0xab12", L"0X1234", L"AB12h", L"BC34H", L"1234u", L"1234ul", L"1234ULL" }; - String^ dwordNegativeInput[] = { L"+123", L"1.23"/*floating number*/, L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"-133", L"1.2e+023", L"1.2e23"/*unsigned exponent*/, L"xyz", L"ABCD123ab"/*outside boundary of 8 digitis*/, L"SIN(2)", L"123+-234", L"1234x", L"A0x1234", L"0xx1234", L"1234uu", L"1234ulll" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerHexDwordPasteExpression, dwordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerHexDwordPasteExpression, dwordNegativeInput); - - String^ wordPositiveInput[] = { L"123", L"13+456", L"1,34", L"12 3", L"1'2'3'4", L"1_2_3_4", L"15e-23"/*note: here is considered as E of hex*/, L"\r1", L"\n\r1,4", L"\n1,4\n", L"\f\n1+2\t\r\v", L"\n 1+\n2 ", L"e+24", L"1\"2", L"(23)+(4)", L"aef", L"ABab", L"A1a3"/*within boundary*/, L"0x1234", L"0xab12", L"0X1234", L"AB12h", L"BC34H", L"1234u", L"1234ul", L"1234ULL" }; - String^ wordNegativeInput[] = { L"+123", L"1.23"/*floating number*/, L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"-133", L"1.2e+023", L"1.2e23"/*unsigned exponent*/, L"xyz", L"A1a3b"/*outside boundary of 4 digitis*/, L"SIN(2)", L"123+-234", L"1234x", L"A0x1234", L"0xx1234", L"1234uu", L"1234ulll" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerHexWordPasteExpression, wordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerHexWordPasteExpression, wordNegativeInput); - - String^ bytePositiveInput[] = { L"13", L"13+6", L"1,4", L"2 3", L"1'2", L"1_2", L"5e-3"/*note: here is considered as E of hex*/, L"\r1", L"a", L"ab", L"A1"/*within boundary*/, L"0x12", L"0xab", L"0X12", L"A9h", L"B8H", L"12u", L"12ul", L"12ULL" }; - String^ byteNegativeInput[] = { L"+3", L"1.2"/*floating number*/, L"1''2", L"'12", L"12'", L"1__2", L"_12", L"12_", L"-3", L"1.1e+02", L"1.2e3"/*unsigned exponent*/, L"xz", L"A3a"/*outside boundary of 2 digitis*/, L"SIN(2)", L"13+-23", L"12x", L"A0x1", L"0xx12", L"12uu", L"12ulll" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerHexBytePasteExpression, bytePositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerHexBytePasteExpression, byteNegativeInput); - } - - void CopyPasteManagerTest::ValidateProgrammerDecPasteExpressionTest() - { - String^ qwordPositiveInput[] = { L"123", L"+123", L"-133", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85", L"\n 1+\n2 ", L"1\"2", L"(123)+(456)", L"123+-234", L"123*-345", L"123*4*-3", L"123*+4*-3", L"9223372036854775807", L"-9223372036854775807"/*boundary condition: max/min allowed number*/, L"0n1234", L"0N1234", L"1234u", L"1234ul", L"1234ULL", L"2+2=", L"2+2= " }; - String^ qwordNegativeInput[] = { L"1.23", L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"12345e-23", L"abcdef", L"xyz", L"ABab", L"e+234", L"9223372036854775809"/*boundary condition: greater than max allowed number 9223372036854775807*/, L"SIN(2)", L"-0n123", L"0nn1234", L"1234uu", L"1234ulll", L"2+2==", L"2=+2" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerDecQwordPasteExpression, qwordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerDecQwordPasteExpression, qwordNegativeInput); - - String^ dwordPositiveInput[] = { L"123", L"+123", L"-133", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85", L"\n 1+\n2 ", L"1\"2", L"(123)+(456)", L"123+-234", L"123*-345", L"123*4*-3", L"123*+4*-3", L"2147483647", L"-2147483647"/*boundary condition: max/min allowed number*/, L"0n1234", L"0N1234", L"1234u", L"1234ul", L"1234ULL" }; - String^ dwordNegativeInput[] = { L"1.23", L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"12345e-23", L"abcdef", L"xyz", L"ABab", L"e+234", L"2147483649"/*boundary condition: greater than max allowed number 2147483647*/, L"SIN(2)", L"-0n123", L"0nn1234", L"1234uu", L"1234ulll" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerDecDwordPasteExpression, dwordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerDecDwordPasteExpression, dwordNegativeInput); - - String^ wordPositiveInput[] = { L"123", L"+123", L"-133", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"\f\n1+2\t\r\v\x85", L"1\"2", L"(123)+(456)", L"123+-234", L"123*-345", L"123*4*-3", L"123*+4*-3", L"32767", L"-32767"/*boundary condition: max/min allowed number*/, L"0n1234", L"0N1234", L"1234u", L"1234ul", L"1234ULL" }; - String^ wordNegativeInput[] = { L"1.23", L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"12345e-23", L"abcdef", L"xyz", L"ABab", L"e+234", L"32769"/*boundary condition: greater than max allowed number 32769*/, L"SIN(2)", L"-0n123", L"0nn1234", L"1234uu", L"1234ulll" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerDecWordPasteExpression, wordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerDecWordPasteExpression, wordNegativeInput); - - String^ bytePositiveInput[] = { L"13", L"+13", L"-13", L"13+46", L"13+-34", L"13*-3", L"3*4*-3", L"3*+4*-3", L"1,3", L"1 3", L"1'2'3", L"1_2_3", L"1\"2", L"127", L"-127"/*boundary condition: max/min allowed number*/, L"0n123", L"0N123", L"123u", L"123ul", L"123ULL" }; - String^ byteNegativeInput[] = { L"1.23", L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"15e-23", L"abcdef", L"xyz", L"ABab", L"e+24", L"129"/*boundary condition: greater than max allowed number 127*/, L"SIN(2)", L"-0n123", L"0nn1234", L"123uu", L"123ulll" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerDecBytePasteExpression, bytePositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerDecBytePasteExpression, byteNegativeInput); - } - - void CopyPasteManagerTest::ValidateProgrammerOctPasteExpressionTest() - { - String^ qwordPositiveInput[] = { L"123", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85", L"\n 1+\n2 ", L"1\"2", L"(123)+(456)", L"0t1234", L"0T1234", L"0o1234", L"0O1234", L"1234u", L"1234ul", L"1234ULL", L"2+2=", L"2+2= " }; - String^ qwordNegativeInput[] = { L"+123", L"1.23", L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"-133", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"12345e-23", L"abcdef", L"xyz", L"ABab", L"e+234", L"12345678901234567890123"/*boundary condition: greater than max allowed digits 22*/, L"SIN(2)", L"123+-234", L"0ot1234", L"1234uu", L"1234ulll", L"2+2==", L"2=+2" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerOctQwordPasteExpression, qwordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerOctQwordPasteExpression, qwordNegativeInput); - - String^ dwordPositiveInput[] = { L"123", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"\n\r1,234\n", L"\f\n1+2\t\r\v\x85", L"\n 1+\n2 ", L"1\"2", L"(123)+(456)", L"37777777777"/*boundary condition: max allowed number*/, L"0t1234", L"0T1234", L"0o1234", L"0O1234", L"1234u", L"1234ul", L"1234ULL" }; - String^ dwordNegativeInput[] = { L"+123", L"1.23", L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"-133", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"12345e-23", L"abcdef", L"xyz", L"ABab", L"e+234", L"377777777771"/*boundary condition: greater than max allowed number 37777777777*/, L"SIN(2)", L"123+-234", L"0ot1234", L"1234uu", L"1234ulll" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerOctDwordPasteExpression, dwordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerOctDwordPasteExpression, dwordNegativeInput); - - String^ wordPositiveInput[] = { L"123", L"123+456", L"1,234", L"1 2 3", L"1'2'3'4", L"1_2_3_4", L"\f\n1+2\t\r\v\x85", L"1\"2", L"(123)+(456)", L"177777"/*boundary condition: max allowed number*/, L"0t1234", L"0T1234", L"0o1234", L"0O1234", L"1234u", L"1234ul", L"1234ULL" }; - String^ wordNegativeInput[] = { L"+123", L"1.23", L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"-133", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"12345e-23", L"abcdef", L"xyz", L"ABab", L"e+234", L"1777771"/*boundary condition: greater than max allowed number 177777*/, L"SIN(2)", L"123+-234", L"0ot1234", L"1234uu", L"1234ulll" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerOctWordPasteExpression, wordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerOctWordPasteExpression, wordNegativeInput); - - String^ bytePositiveInput[] = { L"13", L"13+46", L"1,3", L"1 3", L"1'2'3", L"1_2_3", L"1\"2", L"377"/*boundary condition: max allowed number*/, L"0t123", L"0T123", L"0o123", L"0O123", L"123u", L"123ul", L"123ULL" }; - String^ byteNegativeInput[] = { L"+123", L"1.23", L"1''2", L"'123", L"123'", L"1__2", L"_123", L"123_", L"-13", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"15e-23", L"abcdef", L"xyz", L"ABab", L"e+24", L"477"/*boundary condition: greater than max allowed number 377*/, L"SIN(2)", L"123+-34", L"0ot123", L"123uu", L"123ulll" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerOctBytePasteExpression, bytePositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerOctBytePasteExpression, byteNegativeInput); - } - - void CopyPasteManagerTest::ValidateProgrammerBinPasteExpressionTest() - { - String^ qwordPositiveInput[] = { L"100", L"100+101", L"1,001", L"1 0 1", L"1'0'0'1", L"1_0_0_1", L"\n\r1,010\n", L"\f\n1+11\t\r\v\x85", L"\n 1+\n1 ", L"1\"1", L"(101)+(10)", L"0b1001", L"0B1111", L"0y1001", L"0Y1001", L"1100b", L"1101B", L"1111u", L"1111ul", L"1111ULL", L"1010101010101010101010101011110110100100101010101001010101001010"/*boundary condition: max allowed digits 64*/, L"1+10=", L"1+10= " }; - String^ qwordNegativeInput[] = { L"+10101", L"1.01", L"1''0", L"'101", L"101'", L"1__0", L"_101", L"101_", L"-10101001", L"123", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"101010e-1010", L"abcdef", L"xyz", L"ABab", L"e+10101", L"b1001", L"10b01", L"0x10", L"1001x", L"1001h", L"0bb1111", L"1111uu", L"1111ulll", L"10101010101010101010101010111101101001001010101010010101010010100"/*boundary condition: greater than max allowed digits 64*/, L"SIN(01010)", L"10+-10101010101", L"1+10==", L"1=+10" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerBinQwordPasteExpression, qwordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerBinQwordPasteExpression, qwordNegativeInput); - - String^ dwordPositiveInput[] = { L"100", L"100+101", L"1,001", L"1 0 1", L"1'0'0'1", L"1_0_0_1", L"\n\r1,010\n", L"\f\n1+11\t\r\v\x85", L"\n 1+\n1 ", L"1\"1", L"(101)+(10)", L"0b1001", L"0B1111", L"0y1001", L"0Y1001", L"1100b", L"1101B", L"1111u", L"1111ul", L"1111ULL", L"10101001001010101101010111111100"/*boundary condition: max allowed number*/ }; - String^ dwordNegativeInput[] = { L"+10101", L"1.01", L"1''0", L"'101", L"101'", L"1__0", L"_101", L"101_", L"-10101001", L"123", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"101010e-1010", L"abcdef", L"xyz", L"ABab", L"e+10101", L"b1001", L"10b01", L"0x10", L"1001x", L"1001h", L"0bb1111", L"1111uu", L"1111ulll", L"101010010010101011010101111111001"/*boundary condition: greater than max allowed digits 32*/, L"SIN(01010)", L"10+-10101010101" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerBinDwordPasteExpression, dwordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerBinDwordPasteExpression, dwordNegativeInput); - - String^ wordPositiveInput[] = { L"100", L"100+101", L"1,001", L"1 0 1", L"1'0'0'1", L"1_0_0_1", L"\n\r1,010\n", L"\f\n1+11\t\r\v\x85", L"\n 1+\n1 ", L"1\"1", L"(101)+(10)", L"0b1001", L"0B1111", L"0y1001", L"0Y1001", L"1100b", L"1101B", L"1111u", L"1111ul", L"1111ULL", L"1010101010010010"/*boundary condition: max allowed number*/ }; - String^ wordNegativeInput[] = { L"+10101", L"1.01", L"1''0", L"'101", L"101'", L"1__0", L"_101", L"101_", L"-10101001", L"123", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"101010e-1010", L"abcdef", L"xyz", L"ABab", L"e+10101", L"b1001", L"10b01", L"0x10", L"1001x", L"1001h", L"0bb1111", L"1111uu", L"1111ulll", L"10101010100100101"/*boundary condition: greater than max allowed digits 16*/, L"SIN(01010)", L"10+-10101010101" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerBinWordPasteExpression, wordPositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerBinWordPasteExpression, wordNegativeInput); - - String^ bytePositiveInput[] = { L"100", L"100+101", L"1,001", L"1 0 1", L"1'0'0'1", L"1_0_0_1", L"\n\r1,010\n", L"\n 1+\n1 ", L"1\"1", L"(101)+(10)", L"0b1001", L"0B1111", L"0y1001", L"0Y1001", L"1100b", L"1101B", L"1111u", L"1111ul", L"1111ULL", L"10100010"/*boundary condition: max allowed number*/ }; - String^ byteNegativeInput[] = { L"+10101", L"1.01", L"1''0", L"'101", L"101'", L"1__0", L"_101", L"101_", L"-10101001", L"123", L"1.2e23"/*unsigned exponent*/, L"1.2e+023", L"101010e-1010", L"abcdef", L"xyz", L"ABab", L"e+10101", L"b1001", L"10b01", L"0x10", L"1001x", L"1001h", L"0bb1111", L"1111uu", L"1111ulll", L"101000101"/*boundary condition: greater than max allowed digits 8*/, L"SIN(01010)", L"10+-1010101" }; - - ASSERT_POSITIVE_TESTCASES(ValidateProgrammerBinBytePasteExpression, bytePositiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateProgrammerBinBytePasteExpression, byteNegativeInput); - } - - void CopyPasteManagerTest::ValidateConverterPasteExpressionTest() - { - String^ positiveInput[] = { L"123", L"+123", L"-133", L"12345.", L"012.012", L"1,234", L"1 2 3", L"\n\r1,234\n", L"\f\n12\t\r\v\x85", L"1\"2", L"100=", L"100= " }; - String^ negativeInput[] = { L"(123)+(456)", L"1.2e23"/*unsigned exponent*/, L"12345e-23", L"\n 1+\n2 ", L"123+456", L"abcdef", L"\n 1+\n2 ", L"xyz", L"ABab", L"e+234", L"12345678912345678"/*boundary condition: greater than 16 bits*/, L"SIN(2)", L"123+-234", L"100==", L"=100" }; - - ASSERT_POSITIVE_TESTCASES(ValidateConverterPasteExpression, positiveInput); - ASSERT_NEGATIVE_TESTCASES(ValidateConverterPasteExpression, negativeInput); - } -} - diff --git a/internal/CalculatorUnitTests/CurrencyConverterUnitTests.cpp b/internal/CalculatorUnitTests/CurrencyConverterUnitTests.cpp deleted file mode 100644 index 04aaa7d..0000000 --- a/internal/CalculatorUnitTests/CurrencyConverterUnitTests.cpp +++ /dev/null @@ -1,605 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include - -#include "CalcViewModel\DataLoaders\CurrencyDataLoader.h" -#include "CalcViewModel\Common\LocalizationService.h" - -using namespace CalculatorApp::Common; -using namespace CalculatorApp::Common::LocalizationServiceProperties; -using namespace CalculatorApp::DataLoaders; -using namespace CalculatorApp::ViewModel; -using namespace CalculatorUnitTests; -using namespace Concurrency; -using namespace Platform; -using namespace std; -using namespace UnitConversionManager; -using namespace Windows::Foundation; -using namespace Windows::Storage; -using namespace Windows::Web::Http; - -namespace CalculatorApp -{ - namespace DataLoaders - { - class MockCurrencyHttpClientWithResult : public CurrencyHttpClient - { - public: - MockCurrencyHttpClientWithResult(String^ staticResponse, String^ allRatiosResponse) : - m_staticResponse(staticResponse), - m_allRatiosResponse(allRatiosResponse) - { - } - - IAsyncOperationWithProgress^ GetCurrencyMetadata() override - { - return ref new MockAsyncOperationWithProgress(m_staticResponse); - } - - IAsyncOperationWithProgress^ GetCurrencyRatios() override - { - return ref new MockAsyncOperationWithProgress(m_allRatiosResponse); - } - - private: - String^ m_staticResponse; - String^ m_allRatiosResponse; - }; - - class MockCurrencyHttpClientThrowsException : public CurrencyHttpClient - { - public: - MockCurrencyHttpClientThrowsException() {} - - IAsyncOperationWithProgress^ GetCurrencyMetadata() override - { - throw ref new NotImplementedException(); - } - - IAsyncOperationWithProgress^ GetCurrencyRatios() override - { - throw ref new NotImplementedException(); - } - }; - } -} - -class DataLoadedCallback : public UnitConversionManager::IViewModelCurrencyCallback -{ -public: - DataLoadedCallback(task_completion_event 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 {} - -private: - Concurrency::task_completion_event m_task_completion_event; -}; - -namespace CalculatorUnitTests -{ - constexpr auto sc_Language_EN = L"en-US"; - - const UCM::Category CURRENCY_CATEGORY = { NavCategory::Serialize(ViewMode::Currency), L"Currency", false /*supportsNegative*/ }; - - unique_ptr MakeLoaderWithResults(String^ staticResponse, String^ allRatiosResponse) - { - auto client = make_unique(staticResponse, allRatiosResponse); - client->SetSourceCurrencyCode(StringReference(DefaultCurrencyCode.data())); - return make_unique(move(client)); - } - - String^ SerializeContent(const vector& data) - { - String^ result = L""; - String^ delimiter = CurrencyDataLoaderConstants::CacheDelimiter; - for (String^ content : data) - { - result += (delimiter + content); - } - - return result; - } - - bool WriteToFileInLocalCacheFolder(String^ filename, String^ content) - { - try - { - 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) - { - return false; - } - } - - bool DeleteFileFromLocalCacheFolder(String^ filename) - { - try - { - StorageFolder^ folder = ApplicationData::Current->LocalCacheFolder; - IAsyncOperation^ fileOperation = folder->GetFileAsync(filename); - StorageFile^ file = create_task(fileOperation).get(); - create_task(file->DeleteAsync()).get(); - return true; - } - catch (Platform::Exception^ ex) - { - // FileNotFoundException is a valid result - return ex->HResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - } - catch (...) - { - return false; - } - } - - bool DeleteCurrencyCacheFiles() - { - try - { - bool deletedStaticData = DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename); - bool deletedAllRatiosData = DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename); - - return deletedStaticData && deletedAllRatiosData; - } - catch (...) - { - return false; - } - } - - void InsertToLocalSettings(String^ key, Object^ value) - { - ApplicationData::Current->LocalSettings->Values->Insert(key, value); - } - - void RemoveFromLocalSettings(String^ key) - { - // Safe to call, even if the key does not exist. - ApplicationData::Current->LocalSettings->Values->Remove(key); - } - - void StandardCacheSetup() - { - // Insert current time so data is less than a day old. - DateTime now = Utils::GetUniversalSystemTime(); - InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, now); - InsertToLocalSettings(CurrencyDataLoaderConstants::CacheLangcodeKey, StringReference(sc_Language_EN)); - - VERIFY_IS_TRUE(DeleteCurrencyCacheFiles()); - - VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient::GetRawStaticDataResponse())); - VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename, CurrencyHttpClient::GetRawAllRatiosDataResponse())); - } - - class CurrencyConverterLoadTests - { - public: - TEST_CLASS(CurrencyConverterLoadTests); - - - TEST_METHOD_SETUP(DeleteCacheFiles) - { - return 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() }; - - 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 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(); - loader.SetViewModelCallback(make_shared(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 loader = MakeLoaderWithResults(staticResponse, allRatiosResponse); - - auto data_loaded_event = task_completion_event(); - loader->SetViewModelCallback(make_shared(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()); - } - }; - - class CurrencyConverterUnitTests - { - TEST_CLASS(CurrencyConverterUnitTests); - - const UCM::Unit GetUnit(const vector& 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(); - loader.SetViewModelCallback(make_shared(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 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(StringReference(L"United States - Dollar"), ref new String(usdUnit.name.c_str())); - VERIFY_ARE_EQUAL(StringReference(L"USD"), ref new String(usdUnit.abbreviation.c_str())); - - VERIFY_ARE_EQUAL(StringReference(L"Europe - Euro"), ref new String(eurUnit.name.c_str())); - VERIFY_ARE_EQUAL(StringReference(L"EUR"), ref new String(eurUnit.abbreviation.c_str())); - } - - TEST_METHOD(Loaded_LoadOrderedRatios) - { - StandardCacheSetup(); - - CurrencyDataLoader loader{ nullptr }; - - auto data_loaded_event = task_completion_event(); - loader.SetViewModelCallback(make_shared(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 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 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(); - loader.SetViewModelCallback(make_shared(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 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 symbols = loader.GetCurrencySymbols(usdUnit, eurUnit); - - VERIFY_ARE_EQUAL(ref new String(L"$"), StringReference(symbols.first.c_str())); - VERIFY_ARE_EQUAL(ref new String(L"€"), StringReference(symbols.second.c_str())); - } - - TEST_METHOD(Loaded_GetCurrencySymbols_Invalid) - { - StandardCacheSetup(); - - CurrencyDataLoader loader{ nullptr }; - - auto data_loaded_event = task_completion_event(); - loader.SetViewModelCallback(make_shared(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 symbols = loader.GetCurrencySymbols(fakeUnit1, fakeUnit2); - - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(symbols.first.c_str())); - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(symbols.second.c_str())); - - // Verify that when only one unit is valid, both symbols return as empty string. - vector 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(ref new String(L""), StringReference(symbols.first.c_str())); - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(symbols.second.c_str())); - - symbols = loader.GetCurrencySymbols(usdUnit, fakeUnit1); - - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(symbols.first.c_str())); - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(symbols.second.c_str())); - } - - TEST_METHOD(Loaded_GetCurrencyRatioEquality_Valid) - { - StandardCacheSetup(); - - CurrencyDataLoader loader{ nullptr }; - - auto data_loaded_event = task_completion_event(); - loader.SetViewModelCallback(make_shared(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 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 ratio = loader.GetCurrencyRatioEquality(usdUnit, eurUnit); - - VERIFY_ARE_EQUAL(ref new String(L"1 USD = 0.9205 EUR"), StringReference(ratio.first.c_str())); - VERIFY_ARE_EQUAL(ref new String(L"1 United States Dollar = 0.9205 Europe Euro"), StringReference(ratio.second.c_str())); - } - - TEST_METHOD(Loaded_GetCurrencyRatioEquality_Invalid) - { - StandardCacheSetup(); - - CurrencyDataLoader loader{ nullptr }; - - auto data_loaded_event = task_completion_event(); - loader.SetViewModelCallback(make_shared(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 ratio = loader.GetCurrencyRatioEquality(fakeUnit1, fakeUnit2); - - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(ratio.first.c_str())); - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(ratio.second.c_str())); - - // Verify that when only one unit is valid, both symbols return as empty string. - vector 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(ref new String(L""), StringReference(ratio.first.c_str())); - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(ratio.second.c_str())); - - ratio = loader.GetCurrencyRatioEquality(usdUnit, fakeUnit1); - - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(ratio.first.c_str())); - VERIFY_ARE_EQUAL(ref new String(L""), StringReference(ratio.second.c_str())); - } - }; -} diff --git a/internal/CalculatorUnitTests/DateCalculatorUnitTests.cpp b/internal/CalculatorUnitTests/DateCalculatorUnitTests.cpp deleted file mode 100644 index d6df439..0000000 --- a/internal/CalculatorUnitTests/DateCalculatorUnitTests.cpp +++ /dev/null @@ -1,582 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include -#include "DateUtils.h" - -#include "CalcViewModel\Common\DateCalculator.h" -#include "CalcViewModel\DateCalculatorViewModel.h" - -using namespace Platform; -using namespace std; -using namespace Windows::Foundation; -using namespace Windows::Globalization; -using namespace Windows::Globalization::DateTimeFormatting; -using namespace CalculatorApp::Common::DateCalculation; -using namespace CalculatorApp::ViewModel; - -namespace DateCalculationUnitTests -{ - const int c_numDate = 15; - const int c_diffTestCase = 9; - const int c_numAddOobDate = 2; - const int c_numSubtractOobDate = 2; - const int c_addCases = 3; - const int c_subtractCases = 3; - const int c_dateDiff = 14; - - DateCalculationEngine m_DateCalcEngine(CalendarIdentifiers::Gregorian); - - typedef struct - { - SYSTEMTIME startDate; - SYSTEMTIME endDate; - DateDifference dateDiff; - } DateTimeTestCase; - - SYSTEMTIME date[c_numDate]; - DateDifference dateDifference[c_dateDiff]; - DateTimeTestCase datetimeDifftest[c_diffTestCase]; - DateTimeTestCase datetimeBoundAdd[c_numAddOobDate]; - DateTimeTestCase datetimeBoundSubtract[c_numSubtractOobDate]; - DateTimeTestCase datetimeAddCase[c_addCases]; - DateTimeTestCase datetimeSubtractCase[c_subtractCases]; - - - // Test Class - class DateCalculatorUnitTests - { - public: - TEST_CLASS(DateCalculatorUnitTests); - - TEST_CLASS_SETUP(TestClassSetup) - { - /* Test Case Data */ - - // Dates - DD.MM.YYYY - /*31.12.9999*/ date[0].wYear = 9999; date[0].wMonth = 12; date[0].wDayOfWeek = 5; date[0].wDay = 31; date[0].wHour = 0; date[0].wMinute = 0; date[0].wSecond = 0; date[0].wMilliseconds = 0; - /*30.12.9999*/ date[1].wYear = 9999; date[1].wMonth = 12; date[1].wDayOfWeek = 4; date[1].wDay = 30; date[1].wHour = 0; date[1].wMinute = 0; date[1].wSecond = 0; date[1].wMilliseconds = 0; - /*31.12.9998*/ date[2].wYear = 9998; date[2].wMonth = 12; date[2].wDayOfWeek = 4; date[2].wDay = 31; date[2].wHour = 0; date[2].wMinute = 0; date[2].wSecond = 0; date[2].wMilliseconds = 0; - /*01.01.1601*/ date[3].wYear = 1601; date[3].wMonth = 1; date[3].wDayOfWeek = 1; date[3].wDay = 1; date[3].wHour = 0; date[3].wMinute = 0; date[3].wSecond = 0; date[3].wMilliseconds = 0; - /*02.01.1601*/ date[4].wYear = 1601; date[4].wMonth = 1; date[4].wDayOfWeek = 2; date[4].wDay = 2; date[4].wHour = 0; date[4].wMinute = 0; date[4].wSecond = 0; date[4].wMilliseconds = 0; - /*10.05.2008*/ date[5].wYear = 2008; date[5].wMonth = 5; date[5].wDayOfWeek = 6; date[5].wDay = 10; date[5].wHour = 0; date[5].wMinute = 0; date[5].wSecond = 0; date[5].wMilliseconds = 0; - /*10.03.2008*/ date[6].wYear = 2008; date[6].wMonth = 3; date[6].wDayOfWeek = 1; date[6].wDay = 10; date[6].wHour = 0; date[6].wMinute = 0; date[6].wSecond = 0; date[6].wMilliseconds = 0; - /*29.02.2008*/ date[7].wYear = 2008; date[7].wMonth = 2; date[7].wDayOfWeek = 5; date[7].wDay = 29; date[7].wHour = 0; date[7].wMinute = 0; date[7].wSecond = 0; date[7].wMilliseconds = 0; - /*28.02.2007*/ date[8].wYear = 2007; date[8].wMonth = 2; date[8].wDayOfWeek = 3; date[8].wDay = 28; date[8].wHour = 0; date[8].wMinute = 0; date[8].wSecond = 0; date[8].wMilliseconds = 0; - /*10.03.2007*/ date[9].wYear = 2007; date[9].wMonth = 3; date[9].wDayOfWeek = 6; date[9].wDay = 10; date[9].wHour = 0; date[9].wMinute = 0; date[9].wSecond = 0; date[9].wMilliseconds = 0; - /*10.05.2007*/ date[10].wYear = 2007; date[10].wMonth = 5; date[10].wDayOfWeek = 4; date[10].wDay = 10; date[10].wHour = 0; date[10].wMinute = 0; date[10].wSecond = 0; date[10].wMilliseconds = 0; - /*29.01.2008*/ date[11].wYear = 2008; date[11].wMonth = 1; date[11].wDayOfWeek = 2; date[11].wDay = 29; date[11].wHour = 0; date[11].wMinute = 0; date[11].wSecond = 0; date[11].wMilliseconds = 0; - /*28.01.2007*/ date[12].wYear = 2007; date[12].wMonth = 1; date[12].wDayOfWeek = 0; date[12].wDay = 28; date[12].wHour = 0; date[12].wMinute = 0; date[12].wSecond = 0; date[12].wMilliseconds = 0; - /*31.01.2008*/ date[13].wYear = 2008; date[13].wMonth = 1; date[13].wDayOfWeek = 4; date[13].wDay = 31; date[13].wHour = 0; date[13].wMinute = 0; date[13].wSecond = 0; date[13].wMilliseconds = 0; - /*31.03.2008*/ date[14].wYear = 2008; date[14].wMonth = 3; date[14].wDayOfWeek = 1; date[14].wDay = 31; date[14].wHour = 0; date[14].wMinute = 0; date[14].wSecond = 0; date[14].wMilliseconds = 0; - - // Date Differences - dateDifference[0].year = 1; dateDifference[0].month = 1; - dateDifference[1].month = 1; dateDifference[1].day = 10; - dateDifference[2].day = 2; - /*date[2]-[0]*/ dateDifference[3].week = 52; dateDifference[3].day = 1; - /*date[2]-[0]*/ dateDifference[4].year = 1; - dateDifference[5].day = 365; - dateDifference[6].month = 1; - dateDifference[7].month = 1; dateDifference[7].day = 2; - dateDifference[8].day = 31; - dateDifference[9].month = 11; dateDifference[9].day = 1; - dateDifference[10].year = 8398; dateDifference[10].month = 11; dateDifference[10].day = 30; - dateDifference[11].year = 2008; - dateDifference[12].year = 7991; dateDifference[12].month = 11; - dateDifference[13].week = 416998; dateDifference[13].day = 1; - - - - /* Test Cases */ - - // Date Difference test cases - datetimeDifftest[0].startDate = date[0]; datetimeDifftest[0].endDate = date[3]; datetimeDifftest[0].dateDiff = dateDifference[10]; - datetimeDifftest[1].startDate = date[0]; datetimeDifftest[1].endDate = date[2]; datetimeDifftest[1].dateDiff = dateDifference[5]; - datetimeDifftest[2].startDate = date[0]; datetimeDifftest[2].endDate = date[2]; datetimeDifftest[2].dateDiff = dateDifference[4]; - datetimeDifftest[3].startDate = date[0]; datetimeDifftest[3].endDate = date[2]; datetimeDifftest[3].dateDiff = dateDifference[3]; - datetimeDifftest[4].startDate = date[14]; datetimeDifftest[4].endDate = date[7]; datetimeDifftest[4].dateDiff = dateDifference[7]; - datetimeDifftest[5].startDate = date[14]; datetimeDifftest[5].endDate = date[7]; datetimeDifftest[5].dateDiff = dateDifference[8]; - datetimeDifftest[6].startDate = date[11]; datetimeDifftest[6].endDate = date[8]; datetimeDifftest[6].dateDiff = dateDifference[9]; - datetimeDifftest[7].startDate = date[13]; datetimeDifftest[7].endDate = date[0]; datetimeDifftest[7].dateDiff = dateDifference[12]; - datetimeDifftest[8].startDate = date[13]; datetimeDifftest[8].endDate = date[0]; datetimeDifftest[8].dateDiff = dateDifference[13]; - - // Date Add Out of Bound test cases (Negative tests) - /*OutofBound*/ datetimeBoundAdd[0].startDate = date[1]; datetimeBoundAdd[0].endDate = date[0]; datetimeBoundAdd[0].dateDiff = dateDifference[2]; // on Add date[0] not used - /*OutofBound*/ datetimeBoundAdd[1].startDate = date[2]; datetimeBoundAdd[1].endDate = date[0]; datetimeBoundAdd[1].dateDiff = dateDifference[11]; // on Add date[0] not used - - // Date Subtract Out of Bound test cases (Negative tests) - /*OutofBound*/ datetimeBoundSubtract[0].startDate = date[3]; datetimeBoundSubtract[0].endDate = date[0]; datetimeBoundSubtract[0].dateDiff = dateDifference[2]; // on subtract date[0] not used - /*OutofBound*/ datetimeBoundSubtract[1].startDate = date[14]; datetimeBoundSubtract[1].endDate = date[0]; datetimeBoundSubtract[1].dateDiff = dateDifference[11]; // on subtract date[0] not used - - // Date Add test cases (Positive tests) - datetimeAddCase[0].startDate = date[13]; datetimeAddCase[0].endDate = date[7]; datetimeAddCase[0].dateDiff = dateDifference[6];// add - datetimeAddCase[1].startDate = date[14]; datetimeAddCase[1].endDate = date[5]; datetimeAddCase[1].dateDiff = dateDifference[1];// add - datetimeAddCase[2].startDate = date[13]; datetimeAddCase[2].endDate = date[6]; datetimeAddCase[2].dateDiff = dateDifference[1];// add - - // Date Subtract test cases (Positive tests) - datetimeSubtractCase[0].startDate = date[14]; datetimeSubtractCase[0].endDate = date[7]; datetimeSubtractCase[0].dateDiff = dateDifference[6];// subtract - datetimeSubtractCase[1].startDate = date[6]; datetimeSubtractCase[1].endDate = date[11]; datetimeSubtractCase[1].dateDiff = dateDifference[1];// subtract - datetimeSubtractCase[2].startDate = date[9]; datetimeSubtractCase[2].endDate = date[12]; datetimeSubtractCase[2].dateDiff = dateDifference[1];// subtract - - return true; - } - - - /* Duration Between Two Date Tests -- Timediff obtained after calculation should be checked to be identical */ - TEST_METHOD(TestDateDiff) - { - // TODO - MSFT 10331900, fix this test - - //for (int testIndex = 0; testIndex < c_diffTestCase; testIndex++) - //{ - // DateDifference diff; - // DateUnit dateOutputFormat; - - // switch (testIndex) - // { - // case 0: - // case 2: - // dateOutputFormat = DateUnit::Year | DateUnit::Month | DateUnit::Day; - // break; - // case 1: - // dateOutputFormat = DateUnit::Day; - // break; - // case 3: - // case 8: - // dateOutputFormat = DateUnit::Week | DateUnit::Day; - // break; - // case 7: - // dateOutputFormat = DateUnit::Year | DateUnit::Month | DateUnit::Day; - // break; - // case 4: - // case 6: - // dateOutputFormat = DateUnit::Month | DateUnit::Day; - // break; - // case 5: - // dateOutputFormat = DateUnit::Day; - // break; - // } - - // // Calculate the difference - // m_DateCalcEngine.GetDateDifference(DateUtils::SystemTimeToDateTime(datetimeDifftest[testIndex].startDate), DateUtils::SystemTimeToDateTime(datetimeDifftest[testIndex].endDate), dateOutputFormat, &diff); - - // // Assert for the result - // bool areIdentical = true; - // if (diff.year != datetimeDifftest[testIndex].dateDiff.year || - // diff.month != datetimeDifftest[testIndex].dateDiff.month || - // diff.week != datetimeDifftest[testIndex].dateDiff.week || - // diff.day != datetimeDifftest[testIndex].dateDiff.day) - // { - // areIdentical = false; - // } - - // VERIFY_IS_TRUE(areIdentical); - //} - } - - /*Add Out of bound Tests*/ - TEST_METHOD(TestAddOob) - { - // TODO - MSFT 10331900, fix this test - - //for (int testIndex = 0; testIndex< c_numAddOobDate; testIndex++) - //{ - // DateTime endDate; - - // // Add Duration - // bool isValid = m_DateCalcEngine.AddDuration(DateUtils::SystemTimeToDateTime(datetimeBoundAdd[testIndex].startDate), datetimeBoundAdd[testIndex].dateDiff, &endDate); - - // // Assert for the result - // VERIFY_IS_FALSE(isValid); - //} - } - - /*Subtract Out of bound Tests*/ - TEST_METHOD(TestSubtractOob) - { - for (int testIndex = 0; testIndex< c_numSubtractOobDate; testIndex++) - { - DateTime endDate; - - // Subtract Duration - bool isValid = m_DateCalcEngine.SubtractDuration(DateUtils::SystemTimeToDateTime(datetimeBoundSubtract[testIndex].startDate), datetimeBoundSubtract[testIndex].dateDiff, &endDate); - - // Assert for the result - VERIFY_IS_FALSE(isValid); - } - } - - // Add Tests - TEST_METHOD(TestAddition) - { - // TODO - MSFT 10331900, fix this test - - //for (int testIndex = 0; testIndex < c_addCases; testIndex++) - //{ - // DateTime endDate; - - // // Add Duration - // bool isValid = m_DateCalcEngine.AddDuration(DateUtils::SystemTimeToDateTime(datetimeAddCase[testIndex].startDate), datetimeAddCase[testIndex].dateDiff, &endDate); - - // // Assert for the result - // VERIFY_IS_TRUE(isValid); - - // SYSTEMTIME systemTime = DateUtils::DateTimeToSystemTime(endDate); - // if (systemTime.wYear != datetimeAddCase[testIndex].endDate.wYear || - // systemTime.wMonth != datetimeAddCase[testIndex].endDate.wMonth || - // systemTime.wDay != datetimeAddCase[testIndex].endDate.wDay || - // systemTime.wDayOfWeek != datetimeAddCase[testIndex].endDate.wDayOfWeek) - // { - // isValid = false; - // } - - // VERIFY_IS_TRUE(isValid); - //} - } - - // Subtract Tests - TEST_METHOD(TestSubtraction) - { - // TODO - MSFT 10331900, fix this test - - //for (int testIndex = 0; testIndex < c_subtractCases; testIndex++) - //{ - // DateTime endDate; - - // // Subtract Duration - // bool isValid = m_DateCalcEngine.SubtractDuration(DateUtils::SystemTimeToDateTime(datetimeSubtractCase[testIndex].startDate), datetimeSubtractCase[testIndex].dateDiff, &endDate); - - // // assert for the result - // VERIFY_IS_TRUE(isValid); - - // SYSTEMTIME systemTime = DateUtils::DateTimeToSystemTime(endDate); - // if (systemTime.wYear != datetimeSubtractCase[testIndex].endDate.wYear || - // systemTime.wMonth != datetimeSubtractCase[testIndex].endDate.wMonth || - // systemTime.wDay != datetimeSubtractCase[testIndex].endDate.wDay || - // systemTime.wDayOfWeek != datetimeSubtractCase[testIndex].endDate.wDayOfWeek) - // { - // isValid = false; - // } - - // VERIFY_IS_TRUE(isValid); - //} - } - - private: - - }; - - class DateCalculatorViewModelTests - { - public: - TEST_CLASS(DateCalculatorViewModelTests); - - TEST_CLASS_SETUP(TestClassSetup) - { - /* Test Case Data */ - - // Dates - DD.MM.YYYY - /*31.12.9999*/ date[0].wYear = 9999; date[0].wMonth = 12; date[0].wDayOfWeek = 5; date[0].wDay = 31; date[0].wHour = 0; date[0].wMinute = 0; date[0].wSecond = 0; date[0].wMilliseconds = 0; - /*30.12.9999*/ date[1].wYear = 9999; date[1].wMonth = 12; date[1].wDayOfWeek = 4; date[1].wDay = 30; date[1].wHour = 0; date[1].wMinute = 0; date[1].wSecond = 0; date[1].wMilliseconds = 0; - /*31.12.9998*/ date[2].wYear = 9998; date[2].wMonth = 12; date[2].wDayOfWeek = 4; date[2].wDay = 31; date[2].wHour = 0; date[2].wMinute = 0; date[2].wSecond = 0; date[2].wMilliseconds = 0; - /*01.01.1601*/ date[3].wYear = 1601; date[3].wMonth = 1; date[3].wDayOfWeek = 1; date[3].wDay = 1; date[3].wHour = 0; date[3].wMinute = 0; date[3].wSecond = 0; date[3].wMilliseconds = 0; - /*02.01.1601*/ date[4].wYear = 1601; date[4].wMonth = 1; date[4].wDayOfWeek = 2; date[4].wDay = 2; date[4].wHour = 0; date[4].wMinute = 0; date[4].wSecond = 0; date[4].wMilliseconds = 0; - /*10.05.2008*/ date[5].wYear = 2008; date[5].wMonth = 5; date[5].wDayOfWeek = 6; date[5].wDay = 10; date[5].wHour = 0; date[5].wMinute = 0; date[5].wSecond = 0; date[5].wMilliseconds = 0; - /*10.03.2008*/ date[6].wYear = 2008; date[6].wMonth = 3; date[6].wDayOfWeek = 1; date[6].wDay = 10; date[6].wHour = 0; date[6].wMinute = 0; date[6].wSecond = 0; date[6].wMilliseconds = 0; - /*29.02.2008*/ date[7].wYear = 2008; date[7].wMonth = 2; date[7].wDayOfWeek = 5; date[7].wDay = 29; date[7].wHour = 0; date[7].wMinute = 0; date[7].wSecond = 0; date[7].wMilliseconds = 0; - /*28.02.2007*/ date[8].wYear = 2007; date[8].wMonth = 2; date[8].wDayOfWeek = 3; date[8].wDay = 28; date[8].wHour = 0; date[8].wMinute = 0; date[8].wSecond = 0; date[8].wMilliseconds = 0; - /*10.03.2007*/ date[9].wYear = 2007; date[9].wMonth = 3; date[9].wDayOfWeek = 6; date[9].wDay = 10; date[9].wHour = 0; date[9].wMinute = 0; date[9].wSecond = 0; date[9].wMilliseconds = 0; - /*10.05.2007*/ date[10].wYear = 2007; date[10].wMonth = 5; date[10].wDayOfWeek = 4; date[10].wDay = 10; date[10].wHour = 0; date[10].wMinute = 0; date[10].wSecond = 0; date[10].wMilliseconds = 0; - /*29.01.2008*/ date[11].wYear = 2008; date[11].wMonth = 1; date[11].wDayOfWeek = 2; date[11].wDay = 29; date[11].wHour = 0; date[11].wMinute = 0; date[11].wSecond = 0; date[11].wMilliseconds = 0; - /*28.01.2007*/ date[12].wYear = 2007; date[12].wMonth = 1; date[12].wDayOfWeek = 0; date[12].wDay = 28; date[12].wHour = 0; date[12].wMinute = 0; date[12].wSecond = 0; date[12].wMilliseconds = 0; - /*31.01.2008*/ date[13].wYear = 2008; date[13].wMonth = 1; date[13].wDayOfWeek = 4; date[13].wDay = 31; date[13].wHour = 0; date[13].wMinute = 0; date[13].wSecond = 0; date[13].wMilliseconds = 0; - /*31.03.2008*/ date[14].wYear = 2008; date[14].wMonth = 3; date[14].wDayOfWeek = 1; date[14].wDay = 31; date[14].wHour = 0; date[14].wMinute = 0; date[14].wSecond = 0; date[14].wMilliseconds = 0; - - // Date Differences - dateDifference[0].year = 1; dateDifference[0].month = 1; - dateDifference[1].month = 1; dateDifference[1].day = 10; - dateDifference[2].day = 2; - /*date[2]-[0]*/ dateDifference[3].week = 52; dateDifference[3].day = 1; - /*date[2]-[0]*/ dateDifference[4].year = 1; - dateDifference[5].day = 365; - dateDifference[6].month = 1; - dateDifference[7].month = 1; dateDifference[7].day = 2; - dateDifference[8].day = 31; - dateDifference[9].month = 11; dateDifference[9].day = 1; - dateDifference[10].year = 8398; dateDifference[10].month = 11; dateDifference[10].day = 30; - dateDifference[11].year = 2008; - dateDifference[12].year = 7991; dateDifference[12].month = 11; - dateDifference[13].week = 416998; dateDifference[13].day = 1; - - - - /* Test Cases */ - - // Date Difference test cases - datetimeDifftest[0].startDate = date[0]; datetimeDifftest[0].endDate = date[3]; datetimeDifftest[0].dateDiff = dateDifference[10]; - datetimeDifftest[1].startDate = date[0]; datetimeDifftest[1].endDate = date[2]; datetimeDifftest[1].dateDiff = dateDifference[5]; - datetimeDifftest[2].startDate = date[0]; datetimeDifftest[2].endDate = date[2]; datetimeDifftest[2].dateDiff = dateDifference[4]; - datetimeDifftest[3].startDate = date[0]; datetimeDifftest[3].endDate = date[2]; datetimeDifftest[3].dateDiff = dateDifference[3]; - datetimeDifftest[4].startDate = date[14]; datetimeDifftest[4].endDate = date[7]; datetimeDifftest[4].dateDiff = dateDifference[7]; - datetimeDifftest[5].startDate = date[14]; datetimeDifftest[5].endDate = date[7]; datetimeDifftest[5].dateDiff = dateDifference[8]; - datetimeDifftest[6].startDate = date[11]; datetimeDifftest[6].endDate = date[8]; datetimeDifftest[6].dateDiff = dateDifference[9]; - datetimeDifftest[7].startDate = date[13]; datetimeDifftest[7].endDate = date[0]; datetimeDifftest[7].dateDiff = dateDifference[12]; - datetimeDifftest[8].startDate = date[13]; datetimeDifftest[8].endDate = date[0]; datetimeDifftest[8].dateDiff = dateDifference[13]; - - // Date Add Out of Bound test cases (Negative tests) - /*OutofBound*/ datetimeBoundAdd[0].startDate = date[1]; datetimeBoundAdd[0].endDate = date[0]; datetimeBoundAdd[0].dateDiff = dateDifference[2]; // on Add date[0] not used - /*OutofBound*/ datetimeBoundAdd[1].startDate = date[2]; datetimeBoundAdd[1].endDate = date[0]; datetimeBoundAdd[1].dateDiff = dateDifference[11]; // on Add date[0] not used - - // Date Subtract Out of Bound test cases (Negative tests) - /*OutofBound*/ datetimeBoundSubtract[0].startDate = date[3]; datetimeBoundSubtract[0].endDate = date[0]; datetimeBoundSubtract[0].dateDiff = dateDifference[2]; // on subtract date[0] not used - /*OutofBound*/ datetimeBoundSubtract[1].startDate = date[14]; datetimeBoundSubtract[1].endDate = date[0]; datetimeBoundSubtract[1].dateDiff = dateDifference[11]; // on subtract date[0] not used - - // Date Add test cases (Positive tests) - datetimeAddCase[0].startDate = date[13]; datetimeAddCase[0].endDate = date[7]; datetimeAddCase[0].dateDiff = dateDifference[6];// add - datetimeAddCase[1].startDate = date[14]; datetimeAddCase[1].endDate = date[5]; datetimeAddCase[1].dateDiff = dateDifference[1];// add - datetimeAddCase[2].startDate = date[13]; datetimeAddCase[2].endDate = date[6]; datetimeAddCase[2].dateDiff = dateDifference[1];// add - - // Date Subtract test cases (Positive tests) - datetimeSubtractCase[0].startDate = date[14]; datetimeSubtractCase[0].endDate = date[7]; datetimeSubtractCase[0].dateDiff = dateDifference[6];// subtract - datetimeSubtractCase[1].startDate = date[6]; datetimeSubtractCase[1].endDate = date[11]; datetimeSubtractCase[1].dateDiff = dateDifference[1];// subtract - datetimeSubtractCase[2].startDate = date[9]; datetimeSubtractCase[2].endDate = date[12]; datetimeSubtractCase[2].dateDiff = dateDifference[1];// subtract - return true; - } - - TEST_METHOD(DateCalcViewModelInitializationTest) - { - auto viewModel = ref new DateCalculatorViewModel(); - - // Check for the initialized values - VERIFY_IS_TRUE(viewModel->IsDateDiffMode); - VERIFY_IS_TRUE(viewModel->IsAddMode); - - VERIFY_IS_TRUE(0 != viewModel->FromDate.UniversalTime); - VERIFY_IS_TRUE(0 != viewModel->ToDate.UniversalTime); - VERIFY_IS_TRUE(0 != viewModel->StartDate.UniversalTime); - - VERIFY_ARE_EQUAL(0, viewModel->DaysOffset); - VERIFY_ARE_EQUAL(0, viewModel->MonthsOffset); - VERIFY_ARE_EQUAL(0, viewModel->YearsOffset); - - VERIFY_IS_TRUE(viewModel->IsDiffInDays); - VERIFY_ARE_EQUAL(StringReference(L"Same dates"), viewModel->StrDateDiffResult); - VERIFY_IS_NULL(viewModel->StrDateDiffResultInDays); - - VERIFY_IS_NULL(viewModel->StrDateResult); - } - - TEST_METHOD(DateCalcViewModelAddSubtractInitTest) - { - auto viewModel = ref new DateCalculatorViewModel(); - viewModel->IsDateDiffMode = false; - - // Check for the initialized values - VERIFY_IS_FALSE(viewModel->IsDateDiffMode); - VERIFY_IS_TRUE(viewModel->IsAddMode); - - VERIFY_IS_TRUE(0 != viewModel->FromDate.UniversalTime); - VERIFY_IS_TRUE(0 != viewModel->ToDate.UniversalTime); - VERIFY_IS_TRUE(0 != viewModel->StartDate.UniversalTime); - - VERIFY_ARE_EQUAL(0, viewModel->DaysOffset); - VERIFY_ARE_EQUAL(0, viewModel->MonthsOffset); - VERIFY_ARE_EQUAL(0, viewModel->YearsOffset); - - VERIFY_IS_TRUE(viewModel->IsDiffInDays); - VERIFY_ARE_EQUAL(StringReference(L"Same dates"), viewModel->StrDateDiffResult); - VERIFY_IS_NULL(viewModel->StrDateDiffResultInDays); - - VERIFY_IS_NOT_NULL(viewModel->StrDateResult); - VERIFY_IS_TRUE(StringReference(L"") != viewModel->StrDateResult); - } - - TEST_METHOD(DateCalcViewModelAddTest) - { - // TODO - MSFT 10331900, fix this test - // A few issues to be investigated.. - // The date returned by DateUtils::GetLongDate can be a different string than expected - // based on the values of date[7]. This is because date[7] is in UTC but GetLongDate - // doesn't format according to UTC. If it did, the test would still be incorrect because - // the ViewModel is not necessarily in UTC. - // - // The DateTime value assigned to StartDate after the conversion SystemTimeToDateTime is not - // the same DateTime value as if the user were to select the same date from the CalendarDatePicker. - // This means testing a specific date here, is *not* the same as selecting that date in the app. - - //auto viewModel = ref new DateCalculatorViewModel(); - //viewModel->Initialize(); - - //viewModel->IsDateDiffMode = false; - //viewModel->IsAddMode = true; - //VERIFY_IS_FALSE(viewModel->IsDateDiffMode); - //VERIFY_IS_TRUE(viewModel->IsAddMode); - - //viewModel->StartDate = DateUtils::SystemTimeToDateTime(datetimeAddCase[0].startDate); - //viewModel->DaysOffset = datetimeAddCase[0].dateDiff.day; - //viewModel->MonthsOffset = datetimeAddCase[0].dateDiff.month; - //viewModel->YearsOffset = datetimeAddCase[0].dateDiff.year; - - //// Assert for the result - //VERIFY_ARE_EQUAL(DateUtils::GetLongDate(date[7]), viewModel->StrDateResult); - } - - TEST_METHOD(DateCalcViewModelSubtractTest) - { - // TODO - MSFT 10331900, fix this test - // A few issues to be investigated.. - // The date returned by DateUtils::GetLongDate can be a different string than expected - // based on the values of date[7]. This is because date[7] is in UTC but GetLongDate - // doesn't format according to UTC. If it did, the test would still be incorrect because - // the ViewModel is not necessarily in UTC. - // - // The DateTime value assigned to StartDate after the conversion SystemTimeToDateTime is not - // the same DateTime value as if the user were to select the same date from the CalendarDatePicker. - // This means testing a specific date here, is *not* the same as selecting that date in the app. - - //auto viewModel = ref new DateCalculatorViewModel(); - //viewModel->Initialize(); - - //viewModel->IsDateDiffMode = false; - //viewModel->IsAddMode = false; - //VERIFY_IS_FALSE(viewModel->IsDateDiffMode); - //VERIFY_IS_FALSE(viewModel->IsAddMode); - - //viewModel->StartDate = DateUtils::SystemTimeToDateTime(datetimeSubtractCase[0].startDate); - //viewModel->DaysOffset = datetimeSubtractCase[0].dateDiff.day; - //viewModel->MonthsOffset = datetimeSubtractCase[0].dateDiff.month; - //viewModel->YearsOffset = datetimeSubtractCase[0].dateDiff.year; - - //// Assert for the result - //VERIFY_ARE_EQUAL(DateUtils::GetLongDate(date[7]), viewModel->StrDateResult); - } - - TEST_METHOD(DateCalcViewModelAddOobTest) - { - // TODO - MSFT 10331900, fix this test - // Curiously enough, this test fails because it fails to go Oob. - // Possibly need to update test to use a new max date. - - //auto viewModel = ref new DateCalculatorViewModel(); - //viewModel->Initialize(); - - //viewModel->IsDateDiffMode = false; - //viewModel->IsAddMode = true; - //VERIFY_IS_FALSE(viewModel->IsDateDiffMode); - //VERIFY_IS_TRUE(viewModel->IsAddMode); - - //for (int testIndex = 0; testIndex< c_numAddOobDate; testIndex++) - //{ - // viewModel->StartDate = DateUtils::SystemTimeToDateTime(datetimeBoundAdd[testIndex].startDate); - // viewModel->DaysOffset = datetimeBoundAdd[testIndex].dateDiff.day; - // viewModel->MonthsOffset = datetimeBoundAdd[testIndex].dateDiff.month; - // viewModel->YearsOffset = datetimeBoundAdd[testIndex].dateDiff.year; - - // // Assert for the result - // VERIFY_ARE_EQUAL(StringReference(L"Date out of Bound"), viewModel->StrDateResult); - //} - } - - TEST_METHOD(DateCalcViewModelSubtractOobTest) - { - auto viewModel = ref new DateCalculatorViewModel(); - - viewModel->IsDateDiffMode = false; - viewModel->IsAddMode = false; - VERIFY_IS_FALSE(viewModel->IsDateDiffMode); - VERIFY_IS_FALSE(viewModel->IsAddMode); - - for (int testIndex = 0; testIndex < c_numSubtractOobDate; testIndex++) - { - viewModel->StartDate = DateUtils::SystemTimeToDateTime(datetimeBoundSubtract[testIndex].startDate); - viewModel->DaysOffset = datetimeBoundSubtract[testIndex].dateDiff.day; - viewModel->MonthsOffset = datetimeBoundSubtract[testIndex].dateDiff.month; - viewModel->YearsOffset = datetimeBoundSubtract[testIndex].dateDiff.year; - - // Assert for the result - VERIFY_ARE_EQUAL(StringReference(L"Date out of Bound"), viewModel->StrDateResult); - } - } - - TEST_METHOD(DateCalcViewModelDateDiffTest) - { - // TODO - MSFT 10331900, fix this test - // The last VERIFY checks with expected value "8398 years, 11 months, 4 weeks, 2 days" - // The viewmodel result is something like "8398 years, 12 months, 6568892 weeks, 1 day", - // which shows there is a problem with the viewmodel's reduction algorithm. - - //auto viewModel = ref new DateCalculatorViewModel(); - //viewModel->Initialize(); - - //viewModel->IsDateDiffMode = true; - //VERIFY_IS_TRUE(viewModel->IsDateDiffMode); - - //viewModel->FromDate = DateUtils::SystemTimeToDateTime(datetimeDifftest[0].startDate); - //viewModel->ToDate = DateUtils::SystemTimeToDateTime(datetimeDifftest[0].endDate); - - //// Assert for the result - //VERIFY_IS_FALSE(viewModel->IsDiffInDays); - //VERIFY_ARE_EQUAL(StringReference(L"3067670 days"), viewModel->StrDateDiffResultInDays); - //VERIFY_ARE_EQUAL(StringReference(L"8398 years, 11 months, 4 weeks, 2 days"), viewModel->StrDateDiffResult); - } - - TEST_METHOD(DateCalcViewModelDateDiffResultInDaysTest) - { - auto viewModel = ref new DateCalculatorViewModel(); - - viewModel->IsDateDiffMode = true; - VERIFY_IS_TRUE(viewModel->IsDateDiffMode); - - viewModel->FromDate = DateUtils::SystemTimeToDateTime(date[0]); - viewModel->ToDate = DateUtils::SystemTimeToDateTime(date[1]); - - // Assert for the result - VERIFY_IS_TRUE(viewModel->IsDiffInDays); - VERIFY_ARE_EQUAL(StringReference(L"1 day"), viewModel->StrDateDiffResult); - VERIFY_IS_NULL(viewModel->StrDateDiffResultInDays); - } - - // Tests that the automation name for the resulting date in Add Mode - // contains the DayOfWeek, Day, Month, and Year - TEST_METHOD(DateCalcViewModelAddSubtractResultAutomationNameTest) - { - auto viewModel = ref new DateCalculatorViewModel(); - - auto cal = ref new Calendar(); - cal->Year = 2007; - cal->Month = 5; - cal->Day = 10; - cal->Hour = 12; - cal->Period = 2; - cal->Nanosecond = 0; - cal->Second = 0; - - DateTime startDate = cal->GetDateTime(); - viewModel->StartDate = startDate; - - viewModel->IsDateDiffMode = false; - viewModel->IsAddMode = true; - - wstring actualValue = viewModel->StrDateResultAutomationName->Data(); - - // Verify each component is present in the result - wstring components[] = { - L"dayofweek.full", - L"month.full", - L"year.full", - L"day" - }; - - for (const wstring &component : components) - { - auto formatter = ref new DateTimeFormatter(ref new String(component.c_str())); - wstring expectedValue = formatter->Format(startDate)->Data(); - wstring message = L"Verifying " + component + L" is present in the result"; - VERIFY_IS_TRUE(actualValue.find(expectedValue) != wstring::npos, message.c_str()); - } - } - }; -} - diff --git a/internal/CalculatorUnitTests/DateUtils.h b/internal/CalculatorUnitTests/DateUtils.h deleted file mode 100644 index c2625bd..0000000 --- a/internal/CalculatorUnitTests/DateUtils.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" - -namespace DateCalculationUnitTests -{ - /** Date Utils **/ - class DateUtils - { - public: - // Converts SYSTEMTIME structure to DateTime value - // Converts: SYSTEMTIME -> FILETIME -> DateTime - static Windows::Foundation::DateTime SystemTimeToDateTime(SYSTEMTIME systemTime) - { - LPFILETIME lpFileTime = new FILETIME(); - SystemTimeToFileTime(&systemTime, lpFileTime); - - Windows::Foundation::DateTime dateTime; - dateTime.UniversalTime = (DWORD)lpFileTime->dwHighDateTime; - dateTime.UniversalTime <<= 32; - dateTime.UniversalTime |= (DWORD)lpFileTime->dwLowDateTime; - - return dateTime; - } - - // Converts DateTime value to SYSTEMTIME structure - // Converts: DateTime -> FILETIME -> SYSTEMTIME - static SYSTEMTIME DateTimeToSystemTime(Windows::Foundation::DateTime dateTime) - { - FILETIME fileTime; - fileTime.dwLowDateTime = (DWORD)(dateTime.UniversalTime & 0xffffffff); - fileTime.dwHighDateTime = (DWORD)(dateTime.UniversalTime >> 32); - - SYSTEMTIME systemTime; - FileTimeToSystemTime(&fileTime, &systemTime); - - return systemTime; - } - - // Returns long date format for a date - static Platform::String^ GetLongDate(SYSTEMTIME systemTime) - { - auto formatter = ref new Windows::Globalization::DateTimeFormatting::DateTimeFormatter( - L"longdate", - Windows::Globalization::ApplicationLanguages::Languages, - Windows::System::UserProfile::GlobalizationPreferences::HomeGeographicRegion, - Windows::Globalization::CalendarIdentifiers::Gregorian, - Windows::Globalization::ClockIdentifiers::TwentyFourHour); - - Windows::Foundation::DateTime dateTime = SystemTimeToDateTime(systemTime); - return formatter->Format(dateTime); - } - }; -} - diff --git a/internal/CalculatorUnitTests/Helpers.h b/internal/CalculatorUnitTests/Helpers.h deleted file mode 100644 index c7df962..0000000 --- a/internal/CalculatorUnitTests/Helpers.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" - -#pragma once -#include "CalcViewModel\Common\CalculatorButtonUser.h" - -namespace CalculatorUnitTests -{ - #define StandardModePrecision 16 - #define ScientificModePrecision 32 - #define ProgrammerModePrecision 64 - - typedef struct item - { - CalculatorApp::NumbersAndOperatorsEnum command; - std::wstring expectedPrimaryDisplay; - std::wstring expectedExpressions; - } TESTITEM; - - 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 - constexpr wchar_t MUL = 0x00d7; // Multiplication Symbol - } - - -} - diff --git a/internal/CalculatorUnitTests/HistoryTests.cpp b/internal/CalculatorUnitTests/HistoryTests.cpp deleted file mode 100644 index 53012fa..0000000 --- a/internal/CalculatorUnitTests/HistoryTests.cpp +++ /dev/null @@ -1,533 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include - -#include "CalcViewModel\HistoryViewModel.h" -#include "CalcViewModel\StandardCalculatorViewModel.h" - -using namespace CalculationManager; -using namespace CalculatorApp; -using namespace CalculatorApp::Common; -using namespace CalculatorApp::ViewModel; -using namespace CalculatorUnitTests; -using namespace Platform; -using namespace std; -using namespace Windows::Storage; -using namespace Windows::ApplicationModel::Resources; - -namespace CalculatorFunctionalTests -{ - class HistoryTests - { - public: - TEST_CLASS(HistoryTests); - TEST_METHOD(TestHistoryItemClicked); - TEST_METHOD(TestHistoryItemAddSingleItem); - TEST_METHOD(TestHistoryItemAddMaxItems); - TEST_METHOD(TestHistoryClearCommand); - TEST_METHOD(TestHistoryClearCommandWithEmptyHistory); - TEST_METHOD(TestReLoadHistory); - TEST_METHOD(TestSaveAndReloadHistory); - TEST_METHOD(TestSerializeDeSerializeHistoryItem); - TEST_METHOD(TestHistoryItemWithPrettyExpressions); - TEST_METHOD(TestHistoryItemWithPrettyExpressionsMixedRadix); - TEST_METHOD(TestHistoryItemLoadAndContinueCalculation); - TEST_METHOD(TestDisplayValueAutomationNames); - TEST_METHOD(TestRadixAutomationName); - TEST_METHOD(TestHistoryEmpty); - - private: - HistoryViewModel^ m_historyViewModel; - StandardCalculatorViewModel^ m_standardViewModel; - - void Initialize(unsigned int windowId = 0) - { - m_standardViewModel = ref new StandardCalculatorViewModel(); - m_standardViewModel->IsStandard = true; - m_historyViewModel = ref new HistoryViewModel(m_standardViewModel->m_standardCalculatorManager.get()); - m_historyViewModel->SetCalculatorDisplay(m_standardViewModel->m_calculatorDisplay); - } - - void Cleanup(unsigned int windowId = 0) - { - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeBasic); - m_historyViewModel->OnClearCommand(nullptr); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - m_historyViewModel->OnClearCommand(nullptr); - m_standardViewModel->m_standardCalculatorManager->Reset(); - } - - bool IsHistoryContainerEmpty(_In_ String^ historyContainerKey) - { - ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings; - return !(localSettings->Containers->HasKey(historyContainerKey)); - } - - String^ GetHistoryContainerKeyHelper(CalculationManager::CALCULATOR_MODE cMode) - { - ValueType^ modeValue = static_cast(cMode); - return String::Concat(modeValue->ToString(), L"_History"); - } - - void MockOnHistoryItemClicked(CalculatorApp::ViewModel::HistoryItemViewModel^ e) - { - m_standardViewModel->SetHistoryExpressionDisplay(e->GetTokens(), e->GetCommands()); - m_standardViewModel->SetExpressionDisplay(e->GetTokens(), e->GetCommands()); - m_standardViewModel->SetPrimaryDisplay(e->Result->Data(), false/*IsError*/); - m_standardViewModel->IsFToEEnabled = false; - } - - void AddSingleHistoryItem(unsigned int windowId = 0) - { - Initialize(windowId); - int initialSize = m_historyViewModel->ItemSize; - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command8); - 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"); - 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())); - Cleanup(windowId); - } - - void AddMaxHistoryItems(unsigned int windowId = 0) - { - Initialize(windowId); - int initialSize = m_historyViewModel->ItemSize; - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - for (int i = 1; i < m_standardViewModel->m_standardCalculatorManager->MaxHistorySize(); i++) - { - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command2); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - } - VERIFY_ARE_EQUAL(m_historyViewModel->ItemSize, m_standardViewModel->m_standardCalculatorManager->MaxHistorySize()); - String ^expression = UtfUtils::LRO + L"1 + 1 =" + UtfUtils::PDF; - int output = 2; - 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())); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command5); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - VERIFY_ARE_EQUAL(m_historyViewModel->ItemSize, m_standardViewModel->m_standardCalculatorManager->MaxHistorySize()); - expression = UtfUtils::LRO + L"1 + 2 =" + UtfUtils::PDF; - output = 3; - result = output.ToString(); - 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())); - Cleanup(windowId); - } - - void ReloadHistory(unsigned int windowId = 0) - { - Initialize(windowId); - - m_standardViewModel->m_standardCalculatorManager->Reset(); - int scientificItems = 5; - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - for (int i = 0; i < scientificItems; i++) - { - Command nextCommand = Command(130 + i); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(nextCommand); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - } - - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeBasic); - int standardItems = 2; - for (int i = 0; i < standardItems; i++) - { - Command nextCommand = Command(130 + i); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(nextCommand); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - } - - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - m_historyViewModel->ReloadHistory(ViewMode::Scientific); - VERIFY_ARE_EQUAL(scientificItems, m_historyViewModel->ItemSize); - for (int i = 0; i < scientificItems; i++) - { - wstring expr = L"1 + " + wstring(i.ToString()->Data()) + L" ="; - expr = UtfUtils::LRO + expr + UtfUtils::PDF; - int output = 1 + i; - 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())); - } - - m_historyViewModel->ReloadHistory(ViewMode::Standard); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeBasic); - VERIFY_ARE_EQUAL(standardItems, m_historyViewModel->ItemSize); - for (int i = 0; i < standardItems; i++) - { - wstring expr = L"1 + " + wstring(i.ToString()->Data()) + L" ="; - expr = UtfUtils::LRO + expr + UtfUtils::PDF; - int output = 1 + i; - 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())); - } - Cleanup(windowId); - } - - void ClearHistory(unsigned int windowId = 0) - { - Initialize(windowId); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command2); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeBasic); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command2); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - m_historyViewModel->OnClearCommand(nullptr); - VERIFY_ARE_EQUAL(0, m_historyViewModel->ItemSize); - VERIFY_IS_TRUE(IsHistoryContainerEmpty(GetHistoryContainerKeyHelper(CM_STD))); - VERIFY_IS_TRUE(IsHistoryContainerEmpty(GetHistoryContainerKeyHelper(CM_SCI))); - Cleanup(windowId); - } - - void SerializeDeSerializeHistoryItem(unsigned int windowId = 0) - { - Initialize(windowId); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command2); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - auto itemBeforeSerializeDeserialize = m_standardViewModel->m_standardCalculatorManager->GetHistoryItem(0); - 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)); - Cleanup(windowId); - } - - void SaveAndReloadHistory(unsigned int windowid = 0) - { - Initialize(windowid); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command8); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command2); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeBasic); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command6); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - int itemsBeforeSaveAndReload = m_historyViewModel->ItemSize; - m_historyViewModel->SaveHistory(); - m_historyViewModel->ReloadHistory(ViewMode::Scientific); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - wstring expr = L"1 + 8 ="; - // add double quotes around the expression - expr = UtfUtils::LRO + expr + UtfUtils::PDF; - String ^result = StringReference(L"9"); - int itemsAfterSaveAndReload = m_historyViewModel->ItemSize; - auto historyItem = m_standardViewModel->m_standardCalculatorManager->GetHistoryItem(0); - - VERIFY_ARE_EQUAL(expr, historyItem->historyItemVector.expression); - VERIFY_ARE_EQUAL(result, StringReference(historyItem->historyItemVector.result.c_str())); - VERIFY_ARE_NOT_EQUAL(itemsBeforeSaveAndReload, itemsAfterSaveAndReload); - VERIFY_ARE_EQUAL(itemsBeforeSaveAndReload, itemsAfterSaveAndReload + 1); - Cleanup(windowid); - } - - void HistoryItemWithPrettyExpressions(unsigned int windowId = 0) - { - Initialize(windowId); - 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"); - int itemIndex = 0; - int commandResource = 67; - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - for (int index = 0; index < modes; index++) - { - m_standardViewModel->m_standardCalculatorManager->SendCommand(mode[index]); - for (int command = 0; command < commandsSize; command++) - { - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - 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()); - expression += L"( 1 ) ="; - wstring expr = wstring(expression->Data()); - expr = UtfUtils::LRO + expr + UtfUtils::PDF; - VERIFY_ARE_EQUAL(historyItem->historyItemVector.expression, expr); - commandResource++; - itemIndex++; - } - } - Cleanup(windowId); - } - - void HistoryItemWithPrettyExpressionsMixedRadix(unsigned int windowId = 0) - { - Initialize(windowId); - 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); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandSIN); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandRAD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandSIN); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandGRAD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - 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"); - expression += L"( 1 ) + "; - expression += m_uiResourceLoader->GetString(L"73"); - expression += L"( 1 ) + "; - expression += m_uiResourceLoader->GetString(L"79"); - expression += L"( 1 ) ="; - wstring expr = wstring(expression->Data()); - expr = UtfUtils::LRO + expr + UtfUtils::PDF; - VERIFY_ARE_EQUAL(historyItem->historyItemVector.expression,expr); - - Cleanup(windowId); - } - - void HistoryItemClicked(unsigned int windowId = 0) - { - Initialize(windowId); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command5); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - 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); - MockOnHistoryItemClicked(item); - VERIFY_ARE_EQUAL(StringReference(L"9"), m_standardViewModel->DisplayValue); - VERIFY_ARE_EQUAL(StringReference(L"1"), m_standardViewModel->ExpressionTokens->GetAt(0)->Token); - VERIFY_ARE_EQUAL(StringReference(L" "), m_standardViewModel->ExpressionTokens->GetAt(1)->Token); - VERIFY_ARE_EQUAL(StringReference(L"+"), m_standardViewModel->ExpressionTokens->GetAt(2)->Token); - VERIFY_ARE_EQUAL(StringReference(L" "), m_standardViewModel->ExpressionTokens->GetAt(3)->Token); - VERIFY_ARE_EQUAL(StringReference(L"5"), m_standardViewModel->ExpressionTokens->GetAt(4)->Token); - VERIFY_ARE_EQUAL(StringReference(L" "), m_standardViewModel->ExpressionTokens->GetAt(5)->Token); - VERIFY_ARE_EQUAL(StringReference(L"+"), m_standardViewModel->ExpressionTokens->GetAt(6)->Token); - VERIFY_ARE_EQUAL(StringReference(L" "), m_standardViewModel->ExpressionTokens->GetAt(7)->Token); - Cleanup(windowId); - } - - void HistoryItemLoadAndContinueCalculation(unsigned int windowId = 0) - { - Initialize(windowId); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeBasic); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command5); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - 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); - MockOnHistoryItemClicked(item); - - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command5); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - VERIFY_ARE_EQUAL(StringReference(L"14"), m_standardViewModel->DisplayValue); - historyItem = m_standardViewModel->m_standardCalculatorManager->GetHistoryItem(0); - expression = StringReference(historyItem->historyItemVector.expression.c_str()); - result = StringReference(historyItem->historyItemVector.result.c_str()); - item = ref new HistoryItemViewModel(expression, result, historyItem->historyItemVector.spTokens, historyItem->historyItemVector.spCommands); - MockOnHistoryItemClicked(item); - VERIFY_ARE_EQUAL(StringReference(L"9"), m_standardViewModel->DisplayValue); - - historyItem = m_standardViewModel->m_standardCalculatorManager->GetHistoryItem(1); - expression = StringReference(historyItem->historyItemVector.expression.c_str()); - result = StringReference(historyItem->historyItemVector.result.c_str()); - item = ref new HistoryItemViewModel(expression, result, historyItem->historyItemVector.spTokens, historyItem->historyItemVector.spCommands); - MockOnHistoryItemClicked(item); - VERIFY_ARE_EQUAL(StringReference(L"14"), m_standardViewModel->DisplayValue); - Cleanup(windowId); - } - - void DisplayValueAutomationNames(unsigned int windowId = 0) - { - Initialize(windowId); - - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - 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"); - VERIFY_ARE_EQUAL(expression, m_standardViewModel->CalculationResultAutomationName); - - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command5); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - expression = StringReference(L"Display is 6"); - VERIFY_ARE_EQUAL(expression, m_standardViewModel->CalculationResultAutomationName); - - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeProgrammer); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandADD); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command2); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::CommandEQU); - expression = StringReference(L"Display is 3"); - VERIFY_ARE_EQUAL(expression, m_standardViewModel->CalculationResultAutomationName); - - Cleanup(windowId); - } - - void RadixAutomationName(unsigned int windowId = 0) - { - Initialize(windowId); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeProgrammer); - m_standardViewModel->IsProgrammer = true; - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::Command1); - 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); - VERIFY_ARE_EQUAL(expression, result); - expression = StringReference(L"Octal 10"); - result = L"Octal " + Utils::GetStringValue(m_standardViewModel->OctalDisplayValue); - VERIFY_ARE_EQUAL(expression, result); - expression = StringReference(L"Binary 1000"); - result = L"Binary " + Utils::GetStringValue(m_standardViewModel->BinaryDisplayValue); - VERIFY_ARE_EQUAL(expression, result); - Cleanup(windowId); - } - - void HistoryEmpty(unsigned int windowId = 0) - { - Initialize(windowId); - VERIFY_ARE_EQUAL(0, m_historyViewModel->ItemSize); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - VERIFY_ARE_EQUAL(0, m_historyViewModel->ItemSize); - Cleanup(windowId); - } - - void HistoryClearCommandWithEmptyHistory(unsigned int windowId = 0) - { - Initialize(windowId); - VERIFY_ARE_EQUAL(0, m_historyViewModel->ItemSize); - m_standardViewModel->m_standardCalculatorManager->SendCommand(Command::ModeScientific); - m_historyViewModel->OnClearCommand(nullptr); - VERIFY_ARE_EQUAL(0, m_historyViewModel->ItemSize); - Cleanup(windowId); - - } - }; - - void HistoryTests::TestHistoryItemAddSingleItem() - { - AddSingleHistoryItem(); - } - - void HistoryTests::TestHistoryItemAddMaxItems() - { - AddMaxHistoryItems(); - } - - void HistoryTests::TestReLoadHistory() - { - ReloadHistory(); - } - - void HistoryTests::TestHistoryClearCommand() - { - ClearHistory(); - } - - void HistoryTests::TestSerializeDeSerializeHistoryItem() - { - SerializeDeSerializeHistoryItem(); - } - - void HistoryTests::TestSaveAndReloadHistory() - { - SaveAndReloadHistory(); - } - - void HistoryTests::TestHistoryItemWithPrettyExpressions() - { - HistoryItemWithPrettyExpressions(); - } - - void HistoryTests::TestHistoryItemWithPrettyExpressionsMixedRadix() - { - HistoryItemWithPrettyExpressionsMixedRadix(); - } - - void HistoryTests::TestHistoryItemClicked() - { - HistoryItemClicked(); - } - - void HistoryTests::TestHistoryItemLoadAndContinueCalculation() - { - HistoryItemLoadAndContinueCalculation(); - } - - void HistoryTests::TestDisplayValueAutomationNames() - { - DisplayValueAutomationNames(); - } - - void HistoryTests::TestRadixAutomationName() - { - RadixAutomationName(); - } - - void HistoryTests::TestHistoryEmpty() - { - HistoryEmpty(); - } - - void HistoryTests::TestHistoryClearCommandWithEmptyHistory() - { - HistoryClearCommandWithEmptyHistory(); - } -} - diff --git a/internal/CalculatorUnitTests/Mocks/CurrencyHttpClient.cpp b/internal/CalculatorUnitTests/Mocks/CurrencyHttpClient.cpp deleted file mode 100644 index 9eb5d06..0000000 --- a/internal/CalculatorUnitTests/Mocks/CurrencyHttpClient.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#pragma once - -#include "pch.h" -#include "CurrencyHttpClient.h" - -#include "CalcViewModel\Common\NetworkManager.h" - -using namespace CalculatorApp::DataLoaders; -using namespace Platform; -using namespace Windows::Foundation; -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}])"; - -CurrencyHttpClient::CurrencyHttpClient() -{ -} - -String^ CurrencyHttpClient::GetRawStaticDataResponse() -{ - return StringReference(STATIC_DATA_RESPONSE); -} - -String^ CurrencyHttpClient::GetRawAllRatiosDataResponse() -{ - return StringReference(ALL_RATIOS_RESPONSE); -} - -IAsyncOperationWithProgress^ CurrencyHttpClient::GetCurrencyMetadata() -{ - return ref new MockAsyncOperationWithProgress(StringReference(STATIC_DATA_RESPONSE)); -} - -IAsyncOperationWithProgress^ CurrencyHttpClient::GetCurrencyRatios() -{ - return ref new MockAsyncOperationWithProgress(StringReference(ALL_RATIOS_RESPONSE)); -} - -MockAsyncOperationWithProgress::MockAsyncOperationWithProgress(String^ result) : - m_result(result) -{ -} - -HResult MockAsyncOperationWithProgress::ErrorCode::get() -{ - HResult okayResult; - okayResult.Value = S_OK; - return okayResult; -} - diff --git a/internal/CalculatorUnitTests/Module.cpp b/internal/CalculatorUnitTests/Module.cpp deleted file mode 100644 index 3cb0d4c..0000000 --- a/internal/CalculatorUnitTests/Module.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include - -namespace CalculatorUnitTests -{ - BEGIN_MODULE() - MODULE_PROPERTY(L"APPX:CertificateFileName", L"CalculatorUnitTests.cer:TrustedPeople") - END_MODULE() - - MODULE_SETUP(ModuleSetup) - { - return true; - } - - MODULE_CLEANUP(ModuleCleanup) - { - return true; - } -} diff --git a/internal/CalculatorUnitTests/MultiWindowUnitTests.cpp b/internal/CalculatorUnitTests/MultiWindowUnitTests.cpp deleted file mode 100644 index 6b8887c..0000000 --- a/internal/CalculatorUnitTests/MultiWindowUnitTests.cpp +++ /dev/null @@ -1,1012 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include -#include "UnitConverterViewModelUnitTests.h" -#include "DateUtils.h" - -#include "CalcViewModel\StandardCalculatorViewModel.h" -#include "CalcViewModel\UnitConverterViewModel.h" -#include "CalcViewModel\DateCalculatorViewModel.h" -#include "CalcViewModel\DataLoaders\UnitConverterDataLoader.h" - -using namespace Platform; -using namespace Platform::Collections; -using namespace CalculatorApp; -using namespace CalculatorApp::Common; -using namespace CalculatorApp::ViewModel; -using namespace CalculationManager; -using namespace Windows::ApplicationModel::Resources; -using namespace Windows::Devices::Input; -using namespace Windows::Foundation::Collections; -using namespace Windows::Globalization; -using namespace Utils; -using namespace DateCalculationUnitTests; - -namespace CalculatorUnitTests -{ - extern void ChangeMode(StandardCalculatorViewModel^ viewModel, int mode); - extern void ValidateViewModelByCommands(StandardCalculatorViewModel^ viewModel, TESTITEM item[], bool doReset = false); - - // Validated the Mode set for a given instance of Standard Calculator View Model - void ValidateViewModelMode(StandardCalculatorViewModel^ viewModel, int mode) - { - // Standard - if (mode == 0) - { - VERIFY_IS_TRUE(viewModel->IsStandard); - VERIFY_IS_FALSE(viewModel->IsScientific); - VERIFY_IS_FALSE(viewModel->IsProgrammer); - } - // Scientific - else if (mode == 1) - { - VERIFY_IS_FALSE(viewModel->IsStandard); - VERIFY_IS_TRUE(viewModel->IsScientific); - VERIFY_IS_FALSE(viewModel->IsProgrammer); - } - // Programmer - else if (mode == 2) - { - VERIFY_IS_FALSE(viewModel->IsStandard); - VERIFY_IS_FALSE(viewModel->IsScientific); - VERIFY_IS_TRUE(viewModel->IsProgrammer); - } - } - - // Test class containing Test Methods to validate Multi Window - class MultiWindowUnitTests - { - public: - TEST_CLASS(MultiWindowUnitTests); - - // Create 3 instances of StandardCalculatorViewModel - TEST_METHOD(InitializeMultipleInstancesTest) - { - std::vector viewModels(3); - - // Create 3 instances of StandardCalculatorViewModel - for (int i = 0; i < 3; i++) - { - viewModels[i] = ref new StandardCalculatorViewModel(); - viewModels[i]->IsStandard = true; - } - - // Assert that the Display Value is "0" for all instances - for (int i = 0; i < 3; i++) - { - VERIFY_IS_TRUE("0" == viewModels[i]->DisplayValue); - } - } - - // Create 3 separate instances of Calulator in different modes - TEST_METHOD(InitializeMultipleModeInstancesTest) - { - std::vector viewModels(3); - - // Create 3 instances of StandardCalculatorViewModel in different modes - for (int i = 0; i < 3; i++) - { - viewModels[i] = ref new StandardCalculatorViewModel(); - - ChangeMode(viewModels[i], i); - } - - // Assert for the Modes and DisplayValues - for (int i = 0; i < 3; i++) - { - ValidateViewModelMode(viewModels[i], i); - - VERIFY_IS_TRUE("0" == viewModels[i]->DisplayValue); - } - } - - // Perform calculations on diferent calculator modes and verify that they work independently - TEST_METHOD(MultipleModesCalculationTest) - { - std::vector viewModels(3); - - // Create 3 instances of StandardCalculatorViewModel in different modes - for (int i = 0; i < 3; i++) - { - viewModels[i] = ref new StandardCalculatorViewModel(); - - ChangeMode(viewModels[i], i); - } - - // Perform Calculations on all instances and check that they work independently - - // Standard Mode: Expression 1+2= - TESTITEM standardModeTestItems[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Equals, L"3", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[0], standardModeTestItems, true); - - // Scientific Mode: Expression 1+2*3 - TESTITEM scientificModeTestItems[] = { - { NumbersAndOperatorsEnum::IsScientificMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Multiply, L"2", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Three, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Equals, L"7", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[1], scientificModeTestItems, true); - - // Programmer Mode: Expression F - TESTITEM programmerModeTestItems[] = { - { NumbersAndOperatorsEnum::HexButton, L"0", L"" }, - { NumbersAndOperatorsEnum::F, L"F", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[2], programmerModeTestItems, false); - VERIFY_ARE_EQUAL(GetStringValue(viewModels[2]->HexDisplayValue), StringReference(L"F")); - VERIFY_ARE_EQUAL(GetStringValue(viewModels[2]->DecimalDisplayValue), StringReference(L"15")); - VERIFY_ARE_EQUAL(GetStringValue(viewModels[2]->OctalDisplayValue), StringReference(L"17")); - VERIFY_ARE_EQUAL(GetStringValue(viewModels[2]->BinaryDisplayValue), StringReference(L"1111")); - - // Assert that Standard and Scientific mode Display Values are unchanged - VERIFY_ARE_EQUAL(GetStringValue(viewModels[0]->DisplayValue), StringReference(L"3")); - VERIFY_ARE_EQUAL(GetStringValue(viewModels[1]->DisplayValue), StringReference(L"7")); - } - - // Perform calculations on 2 instances of Calculator in Standard Mode and verify that they work independently - TEST_METHOD(MultipleStandardModeCalculationTest) - { - // Create 2 instances of Standard Mode - StandardCalculatorViewModel^ standardViewModel1 = ref new StandardCalculatorViewModel(); - StandardCalculatorViewModel^ standardViewModel2 = ref new StandardCalculatorViewModel(); - - ChangeMode(standardViewModel1, 0); - ChangeMode(standardViewModel2, 0); - - ValidateViewModelMode(standardViewModel1, 0); - ValidateViewModelMode(standardViewModel2, 0); - - // Perform Calculations on the 2 instances and check that they work independently - - // Standard Mode 1: Expression 3-2= - TESTITEM standardModeTestItems1[] = { - { NumbersAndOperatorsEnum::Three, L"3", L"" }, - { NumbersAndOperatorsEnum::Subtract, L"3", L"3 - " }, - { NumbersAndOperatorsEnum::Two, L"2", L"3 - " }, - { NumbersAndOperatorsEnum::Equals, L"1", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(standardViewModel1, standardModeTestItems1, true); - - // Standard Mode 2: Expression 4*5= - TESTITEM standardModeTestItems2[] = { - { NumbersAndOperatorsEnum::Four, L"4", L"" }, - { NumbersAndOperatorsEnum::Multiply, L"4", L"4 * " }, - { NumbersAndOperatorsEnum::Five, L"5", L"4 * " }, - { NumbersAndOperatorsEnum::Equals, L"20", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(standardViewModel2, standardModeTestItems2, true); - - // Assert that the Display Value of 1st instance is unchanged - VERIFY_ARE_EQUAL(GetStringValue(standardViewModel1->DisplayValue), StringReference(L"1")); - } - - // Perform calculations on 2 instances of Calculator in Scientific Mode and verify that they work independently - TEST_METHOD(MultipleScientificModeCalculationTest) - { - // Create 2 instances of Standard Mode - StandardCalculatorViewModel^ scientificViewModel1 = ref new StandardCalculatorViewModel(); - StandardCalculatorViewModel^ scientificViewModel2 = ref new StandardCalculatorViewModel(); - - ChangeMode(scientificViewModel1, 1); - ChangeMode(scientificViewModel2, 1); - - ValidateViewModelMode(scientificViewModel1, 1); - ValidateViewModelMode(scientificViewModel2, 1); - - // Perform Calculations on the 2 instances and check that they work independently - - // Standard Mode 1: Expression 3-2= - TESTITEM scientificModeTestItems1[] = { - { NumbersAndOperatorsEnum::Three, L"3", L"" }, - { NumbersAndOperatorsEnum::Subtract, L"3", L"3 - " }, - { NumbersAndOperatorsEnum::Two, L"2", L"3 - " }, - { NumbersAndOperatorsEnum::Equals, L"1", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(scientificViewModel1, scientificModeTestItems1, true); - - // Standard Mode 2: Expression 4*5= - TESTITEM scientificModeTestItems2[] = { - { NumbersAndOperatorsEnum::Four, L"4", L"" }, - { NumbersAndOperatorsEnum::Multiply, L"4", L"4 * " }, - { NumbersAndOperatorsEnum::Five, L"5", L"4 * " }, - { NumbersAndOperatorsEnum::Equals, L"20", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(scientificViewModel2, scientificModeTestItems2, true); - - // Assert that the Display Value of 1st instance is unchanged - VERIFY_ARE_EQUAL(GetStringValue(scientificViewModel1->DisplayValue), StringReference(L"1")); - } - - // Perform calculations on 2 instances of Calculator in Scientific Mode - // (with different Angle types, HYP and F-E settings) and verify that they work independently - TEST_METHOD(MultipleScientificModeWithDifferentSettingsTest) - { - // Create 2 instances of Standard Mode - StandardCalculatorViewModel^ scientificViewModel1 = ref new StandardCalculatorViewModel(); - StandardCalculatorViewModel^ scientificViewModel2 = ref new StandardCalculatorViewModel(); - - ChangeMode(scientificViewModel1, 1); - ChangeMode(scientificViewModel2, 1); - - ValidateViewModelMode(scientificViewModel1, 1); - ValidateViewModelMode(scientificViewModel2, 1); - - // Perform Calculations on the 2 instances and check that they work independently - - // Scientific Mode 1: Degrees with HYP checked - TESTITEM scientificModeInitializeItems1[] = { - { NumbersAndOperatorsEnum::Degree, L"0", L"" }, - { NumbersAndOperatorsEnum::Hyp, L"0", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(scientificViewModel1, scientificModeInitializeItems1, true); - - // Scientific Mode 2: Radians with F-E checked - TESTITEM scientificModeInitializeItems2[] = { - { NumbersAndOperatorsEnum::Radians, L"0", L"" }, - { NumbersAndOperatorsEnum::FToE, L"0.e+0", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(scientificViewModel2, scientificModeInitializeItems2, true); - - // Scientific Mode 1: Expression CosH(0 degrees) - TESTITEM scientificModeTestItems1[] = { - { NumbersAndOperatorsEnum::Zero, L"0", L"" }, - { NumbersAndOperatorsEnum::Cosh, L"1", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(scientificViewModel1, scientificModeTestItems1, true); - - // Scientific Mode 2: Expression Cos(pi radians) - TESTITEM scientificModeTestItems2[] = { - { NumbersAndOperatorsEnum::Pi, L"3.1415926535897932384626433832795e+0", L"" }, - { NumbersAndOperatorsEnum::Cos, L"-1.e+0", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(scientificViewModel2, scientificModeTestItems2, true); - } - - // Perform calculations on 2 instances of Calculator in Programmer Mode and verify that they work independently - TEST_METHOD(MultipleProgrammerModeCalculationTest) - { - // Create 2 instances of Standard Mode - StandardCalculatorViewModel^ programmerViewModel1 = ref new StandardCalculatorViewModel(); - StandardCalculatorViewModel^ programmerViewModel2 = ref new StandardCalculatorViewModel(); - - ChangeMode(programmerViewModel1, 2); - ChangeMode(programmerViewModel2, 2); - - ValidateViewModelMode(programmerViewModel1, 2); - ValidateViewModelMode(programmerViewModel2, 2); - - // Perform Calculations on the 2 instances and check that they work independently - - // Radix Type: Hexadecimal, Expression: F - TESTITEM programmerModeTestItems1[] = { - { NumbersAndOperatorsEnum::HexButton, L"0", L"" }, - { NumbersAndOperatorsEnum::F, L"F", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - - ValidateViewModelByCommands(programmerViewModel1, programmerModeTestItems1, false); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->HexDisplayValue), StringReference(L"F")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->DecimalDisplayValue), StringReference(L"15")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->OctalDisplayValue), StringReference(L"17")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->BinaryDisplayValue), StringReference(L"1111")); - - // Radix Type: Octal, Expression: 7 - TESTITEM programmerModeTestItems2[] = { - { NumbersAndOperatorsEnum::OctButton, L"0", L"" }, - { NumbersAndOperatorsEnum::Seven, L"7", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - - ValidateViewModelByCommands(programmerViewModel2, programmerModeTestItems2, false); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel2->HexDisplayValue), StringReference(L"7")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel2->DecimalDisplayValue), StringReference(L"7")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel2->OctalDisplayValue), StringReference(L"7")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel2->BinaryDisplayValue), StringReference(L"0111")); - - // Assert that displayed values of 1st instance are unchanged - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->DisplayValue), StringReference(L"F")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->HexDisplayValue), StringReference(L"F")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->DecimalDisplayValue), StringReference(L"15")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->OctalDisplayValue), StringReference(L"17")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->BinaryDisplayValue), StringReference(L"1111")); - } - - // Perform calculations on 2 instances of Calculator in Programmer Mode - // (with different Bit lengths and Radix types) and verify that they work independently - TEST_METHOD(MultipleProgrammerModeWithDifferentSettingsTest) - { - // Create 2 instances of Standard Mode - StandardCalculatorViewModel^ programmerViewModel1 = ref new StandardCalculatorViewModel(); - StandardCalculatorViewModel^ programmerViewModel2 = ref new StandardCalculatorViewModel(); - - ChangeMode(programmerViewModel1, 2); - ChangeMode(programmerViewModel2, 2); - - ValidateViewModelMode(programmerViewModel1, 2); - ValidateViewModelMode(programmerViewModel2, 2); - - // Perform Calculations on the 2 instances and check that they work independently - - // Bit length: Byte & Radix Type: Hex - TESTITEM programmerModeInitializeItems1[] = { - { NumbersAndOperatorsEnum::Byte, L"0", L"" }, - { NumbersAndOperatorsEnum::HexButton, L"0", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - - ValidateViewModelByCommands(programmerViewModel1, programmerModeInitializeItems1, false); - - // Bit Length: Word & Radix Type: Oct - TESTITEM programmerModeInitializeItems2[] = { - { NumbersAndOperatorsEnum::Word, L"0", L"" }, - { NumbersAndOperatorsEnum::OctButton, L"0", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - - ValidateViewModelByCommands(programmerViewModel2, programmerModeInitializeItems2, false); - - TESTITEM programmerModeTestItems1[] = { - { NumbersAndOperatorsEnum::F, L"F", L"" }, - { NumbersAndOperatorsEnum::F, L"FF", L"" }, - // One more F shouldn't have any effect, testing for precision - { NumbersAndOperatorsEnum::F, L"FF", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - - ValidateViewModelByCommands(programmerViewModel1, programmerModeTestItems1, false); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->HexDisplayValue), StringReference(L"FF")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->DecimalDisplayValue), StringReference(L"-1")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->OctalDisplayValue), StringReference(L"377")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel1->BinaryDisplayValue), StringReference(L"1111 1111")); - - TESTITEM programmerModeTestItems2[] = { - { NumbersAndOperatorsEnum::Seven, L"7", L"" }, - { NumbersAndOperatorsEnum::Seven, L"77", L"" }, - { NumbersAndOperatorsEnum::Seven, L"777", L"" }, - { NumbersAndOperatorsEnum::Seven, L"7 777", L"" }, - { NumbersAndOperatorsEnum::Seven, L"77 777", L"" }, - // One more '7' shouldn't have any effect, testing for precision - { NumbersAndOperatorsEnum::Seven, L"77 777", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - - ValidateViewModelByCommands(programmerViewModel2, programmerModeTestItems2, false); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel2->HexDisplayValue), StringReference(L"7FFF")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel2->DecimalDisplayValue), StringReference(L"32,767")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel2->OctalDisplayValue), StringReference(L"77 777")); - VERIFY_ARE_EQUAL(GetStringValue(programmerViewModel2->BinaryDisplayValue), StringReference(L"0111 1111 1111 1111")); - } - - // Perform calculations on 2 separate instances of Calculator and verify that their History list items are maintained separately - TEST_METHOD(MultipleModesHistoryAddItemTest) - { - std::vector viewModels(2); - - // Create 3 instances of StandardCalculatorViewModel in Standard and Scientific mode - for (int i = 0; i < 2; i++) - { - viewModels[i] = ref new StandardCalculatorViewModel(); - - ChangeMode(viewModels[i], i); - - // Validate that the history items list is initially empty - VERIFY_IS_TRUE(0 == viewModels[i]->m_standardCalculatorManager->GetHistoryItems().size()); - } - - // Perform Calculations on both the instances and check that the History items work independently - - // Standard Mode: Expression 1+2= - TESTITEM standardModeTestItems[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Equals, L"3", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[0], standardModeTestItems, true); - - // Scientific Mode: Expression 1+2*3 - TESTITEM scientificModeTestItems[] = { - { NumbersAndOperatorsEnum::IsScientificMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Multiply, L"2", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Three, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Equals, L"7", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[1], scientificModeTestItems, true); - - // Assert for the history list items of 1st instance - VERIFY_IS_TRUE(1 == viewModels[0]->m_standardCalculatorManager->GetHistoryItems().size()); - - auto item1 = viewModels[0]->m_standardCalculatorManager->GetHistoryItem(0); - String ^expression1 = UtfUtils::LRO + L"1 + 2 =" + UtfUtils::PDF; - String^ result1 = L"3"; - - VERIFY_ARE_EQUAL(expression1, StringReference(item1->historyItemVector.expression.c_str())); - VERIFY_ARE_EQUAL(result1, StringReference(item1->historyItemVector.result.c_str())); - - // Assert for the history list items of 2nd instance - VERIFY_IS_TRUE(1 == viewModels[1]->m_standardCalculatorManager->GetHistoryItems().size()); - - auto item2 = viewModels[1]->m_standardCalculatorManager->GetHistoryItem(0); - String^ expression2 = UtfUtils::LRO + L"1 + 2 " + UtfUtils::MUL + L" 3 =" + UtfUtils::PDF; - String^ result2 = L"7"; - - VERIFY_ARE_EQUAL(expression2, StringReference(item2->historyItemVector.expression.c_str())); - VERIFY_ARE_EQUAL(result2, StringReference(item2->historyItemVector.result.c_str())); - } - - // Perform calculations on 2 separate instances of Standard Modes and verify that their History list items are maintained separately - TEST_METHOD(MultipleStandardModesHistoryAddItemTest) - { - std::vector viewModels(2); - - // Create 3 instances of StandardCalculatorViewModel in Standard and Scientific mode - for (int i = 0; i < 2; i++) - { - viewModels[i] = ref new StandardCalculatorViewModel(); - - // Standard Mode - ChangeMode(viewModels[i], 0); - - // Validate that the history items list is initially empty - VERIFY_IS_TRUE(0 == viewModels[i]->m_standardCalculatorManager->GetHistoryItems().size()); - } - - // Perform Calculations on both the instances and check that the History items work independently - - // Standard Mode: Expression 1+2= - TESTITEM standardModeTestItems[2][8] = { - { - { NumbersAndOperatorsEnum::IsScientificMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Equals, L"3", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }, - { - { NumbersAndOperatorsEnum::IsScientificMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Multiply, L"2", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Three, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Equals, L"7", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - } - }; - - // Run the commands - for (int i = 0; i < 2; i++) - { - ValidateViewModelByCommands(viewModels[i], standardModeTestItems[i], true); - } - - String^ expression[] = { UtfUtils::LRO + L"1 + 2 =" + UtfUtils::PDF, UtfUtils::LRO + L"1 + 2 " + UtfUtils::MUL + L" 3 =" + UtfUtils::PDF }; - String^ result[] = { L"3", L"7" }; - - // Assert for the history list items of the instances - for (int i = 0; i < 2; i++) - { - VERIFY_IS_TRUE(1 == viewModels[i]->m_standardCalculatorManager->GetHistoryItems().size()); - - auto item = viewModels[i]->m_standardCalculatorManager->GetHistoryItem(0); - - VERIFY_ARE_EQUAL(expression[i], StringReference(item->historyItemVector.expression.c_str())); - VERIFY_ARE_EQUAL(result[i], StringReference(item->historyItemVector.result.c_str())); - } - } - - // Perform calculations on 2 separate instances of Scientific Modes and verify that their History list items are maintained separately - TEST_METHOD(MultipleScientificModesHistoryAddItemTest) - { - std::vector viewModels(2); - - // Create 3 instances of StandardCalculatorViewModel in Standard and Scientific mode - for (int i = 0; i < 2; i++) - { - viewModels[i] = ref new StandardCalculatorViewModel(); - - // Scientific Mode - ChangeMode(viewModels[i], 1); - - // Validate that the history items list is initially empty - VERIFY_IS_TRUE(0 == viewModels[i]->m_standardCalculatorManager->GetHistoryItems().size()); - } - - // Perform Calculations on both the instances and check that the History items work independently - - // Standard Mode: Expression 1+2= - TESTITEM standardModeTestItems[2][8] = { - { - { NumbersAndOperatorsEnum::IsStandardMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Equals, L"3", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }, - { - { NumbersAndOperatorsEnum::IsStandardMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Multiply, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Three, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Equals, L"9", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - } - }; - - // Run the commands - for (int i = 0; i < 2; i++) - { - ValidateViewModelByCommands(viewModels[i], standardModeTestItems[i], true); - } - - String^ expression[] = { UtfUtils::LRO + L"1 + 2 =" + Utils::PDF, UtfUtils::LRO + L"1 + 2 " + UtfUtils::MUL + L" 3 =" + Utils::PDF }; - String^ result[] = { L"3", L"9" }; - - // Assert for the history list items of the instances - for (int i = 0; i < 2; i++) - { - VERIFY_IS_TRUE(1 == viewModels[i]->m_standardCalculatorManager->GetHistoryItems().size()); - - auto item = viewModels[i]->m_standardCalculatorManager->GetHistoryItem(0); - - VERIFY_ARE_EQUAL(expression[i], StringReference(item->historyItemVector.expression.c_str())); - VERIFY_ARE_EQUAL(result[i], StringReference(item->historyItemVector.result.c_str())); - } - } - - // Perform calculations on 3 separate instances of Calcuator and verify that their Memory List items are maintained separately - TEST_METHOD(MultipleModesMemoryAddItemTest) - { - std::vector viewModels(3); - - // Create 3 instances of StandardCalculatorViewModel in Standard and Scientific mode - for (int i = 0; i < 3; i++) - { - viewModels[i] = ref new StandardCalculatorViewModel(); - - ChangeMode(viewModels[i], i); - - // Validate that the history items list is initially empty - VERIFY_IS_TRUE(0 == viewModels[i]->MemorizedNumbers->Size); - } - - // Perform Calculations on both the instances and check that the Memory items work independently - - // Standard Mode: Expression 1+2= - TESTITEM standardModeTestItems[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Equals, L"3", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[0], standardModeTestItems, true); - - // Scientific Mode: Expression 1+2*3 - TESTITEM scientificModeTestItems[] = { - { NumbersAndOperatorsEnum::IsScientificMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Multiply, L"2", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Three, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Equals, L"7", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[1], scientificModeTestItems, true); - - // Programmer Mode: Expression F - TESTITEM programmerModeTestItems[] = { - { NumbersAndOperatorsEnum::HexButton, L"0", L"" }, - { NumbersAndOperatorsEnum::F, L"F", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[2], programmerModeTestItems, false); - - // Press the Memory Button to save Values to Memory - for (int i = 0; i < 3; i++) - { - viewModels[i]->ButtonPressed->Execute(NumbersAndOperatorsEnum::Memory); - } - - String^ expectedMemoryValues[] = { - UtfUtils::LRO + L"3" + UtfUtils::PDF, - UtfUtils::LRO + L"7" + UtfUtils::PDF, - UtfUtils::LRO + L"F" + UtfUtils::PDF}; - - // Validate that only one item is present in the memory - // Also assert for their value - for (int i = 0; i < 3; i++) - { - VERIFY_IS_TRUE(1 == viewModels[i]->MemorizedNumbers->Size); - auto memorySlot = viewModels[i]->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(expectedMemoryValues[i], memorySlot->Value); - } - } - - TEST_METHOD(MultipleDateCalculatorTest) - { - // TODO - MSFT 10331900, fix this test - // This test mostly passes, but the last set of VERIFYs succeeds for - // the check of viewModels[2]->StrDateResult when in a UTC- time, - // however, both the expected and actual results are incorrect. Test - // needs to be updated with correct expected value and viewmodel needs - // to be updated to calculate correct value. - - //DateCalculatorViewModel^ viewModels[4]; - - //// Initialize the view models - //for (int i = 0; i < 4; i++) - //{ - // auto vm = ref new DateCalculatorViewModel(); - // vm->Initialize(); - - // viewModels[i] = vm; - //} - - //viewModels[2]->IsDateDiffMode = false; - //viewModels[3]->IsDateDiffMode = false; - - //viewModels[2]->IsAddMode = true; - //viewModels[3]->IsAddMode = false; - - //// Verify the initialization - //for (int i = 0; i < 2; i++) - //{ - // VERIFY_IS_TRUE(viewModels[i]->IsDateDiffMode); - // VERIFY_IS_TRUE(viewModels[i]->FromDate.UniversalTime != 0); - // VERIFY_IS_TRUE(viewModels[i]->ToDate.UniversalTime != 0); - // VERIFY_ARE_EQUAL(StringReference(L"Same dates"), viewModels[i]->StrDateDiffResult); - // VERIFY_IS_NULL(viewModels[i]->StrDateDiffResultInDays); - //} - - //for (int i = 2; i < 4; i++) - //{ - // VERIFY_IS_FALSE(viewModels[i]->IsDateDiffMode); - // VERIFY_IS_TRUE(viewModels[i]->DaysOffset == 0); - // VERIFY_IS_TRUE(viewModels[i]->MonthsOffset == 0); - // VERIFY_IS_TRUE(viewModels[i]->YearsOffset == 0); - // VERIFY_IS_NOT_NULL(viewModels[i]->StrDateResult); - // VERIFY_IS_TRUE(StringReference(L"") != viewModels[i]->StrDateResult); - //} - - //VERIFY_IS_TRUE(viewModels[2]->IsAddMode); - //VERIFY_IS_FALSE(viewModels[3]->IsAddMode); - - //// Perform some calculations - //// Diff in viewModels[0] - //SYSTEMTIME date1, date2, resultDate; - ///* 01-10-2015 */ date1.wDay = 1; date1.wMonth = 10; date1.wYear = 2015; date1.wDayOfWeek = 4; date1.wHour = 0; date1.wMinute = 0; date1.wSecond = 0; date1.wMilliseconds = 0; - ///* 15-02-2016 */ date2.wDay = 15; date2.wMonth = 2; date2.wYear = 2016; date2.wDayOfWeek = 1; date2.wHour = 0; date2.wMinute = 0; date2.wSecond = 0; date2.wMilliseconds = 0; - - //viewModels[0]->FromDate = DateUtils::SystemTimeToDateTime(date1); - //viewModels[0]->ToDate = DateUtils::SystemTimeToDateTime(date2); - - //// Diff in viewModels[1] - ///* 12-12-2015 */ date1.wDay = 12; date1.wMonth = 12; date1.wYear = 2015; date1.wDayOfWeek = 6; - ///* 15-12-2015 */ date2.wDay = 15; date2.wMonth = 12; date2.wYear = 2015; date2.wDayOfWeek = 2; - ///* 17-01-2018 */ resultDate.wDay = 17; resultDate.wMonth = 1; resultDate.wYear = 2018; resultDate.wDayOfWeek = 3; resultDate.wHour = 0; resultDate.wMinute = 0; resultDate.wSecond = 0; resultDate.wMilliseconds = 0; - - //viewModels[1]->FromDate = DateUtils::SystemTimeToDateTime(date1); - //viewModels[1]->ToDate = DateUtils::SystemTimeToDateTime(date2); - - //// Add in viewModels[2] - //viewModels[2]->StartDate = DateUtils::SystemTimeToDateTime(date1); - //viewModels[2]->DaysOffset = 5; - //viewModels[2]->MonthsOffset = 1; - //viewModels[2]->YearsOffset = 2; - - //// Subtract OOB in viewModels[3] - //viewModels[3]->StartDate = DateUtils::SystemTimeToDateTime(date2); - //viewModels[3]->DaysOffset = 5; - //viewModels[3]->MonthsOffset = 1; - //viewModels[3]->YearsOffset = 500; - - //// Assert for the result - //VERIFY_IS_FALSE(viewModels[0]->IsDiffInDays); - //VERIFY_ARE_EQUAL(StringReference(L"137 days"), viewModels[0]->StrDateDiffResultInDays); - //VERIFY_ARE_EQUAL(StringReference(L"4 months, 2 weeks"), viewModels[0]->StrDateDiffResult); - - //VERIFY_IS_TRUE(viewModels[1]->IsDiffInDays); - //VERIFY_ARE_EQUAL(StringReference(L"3 days"), viewModels[1]->StrDateDiffResult); - //VERIFY_IS_NULL(viewModels[1]->StrDateDiffResultInDays); - - //// TODO - MSFT 10331900 : both GetLongDate and viewmodel return incorrect values! - //VERIFY_ARE_EQUAL(DateUtils::GetLongDate(resultDate), viewModels[2]->StrDateResult); - //VERIFY_ARE_EQUAL(StringReference(L"Date out of Bound"), viewModels[3]->StrDateResult); - } - - TEST_METHOD(InitializeMultipleConverterTest) - { - std::shared_ptr unitConverterMocks[3]; - UnitConverterViewModel^ viewModels[3]; - - for (int i = 0; i < 3; i++) - { - unitConverterMocks[i] = std::make_shared(); - viewModels[i] = ref new UnitConverterViewModel(unitConverterMocks[i]); - IObservableVector^ cats = viewModels[i]->Categories; - VERIFY_ARE_EQUAL((UINT)1, unitConverterMocks[i]->m_getCategoriesCallCount); - VERIFY_ARE_EQUAL((UINT)3, cats->Size); - // Verify that we match current category - VERIFY_IS_TRUE(CAT2 == viewModels[i]->CurrentCategory->GetModelCategory()); - } - - // Change category of 1st instance to CAT1 and that of 2nd instance to CAT2 - viewModels[0]->CurrentCategory = viewModels[0]->Categories->GetAt(0); - viewModels[2]->CurrentCategory = viewModels[1]->Categories->GetAt(2); - - // Verify that the instance properties were set independently - for (int i = 0; i < 2; i++) - { - VERIFY_ARE_EQUAL((UINT)3, viewModels[i]->Categories->Size); - VERIFY_ARE_EQUAL((UINT)3, viewModels[i]->Units->Size); - } - - VERIFY_IS_TRUE(CAT1 == viewModels[0]->CurrentCategory->GetModelCategory()); - VERIFY_IS_TRUE(CAT2 == viewModels[1]->CurrentCategory->GetModelCategory()); - VERIFY_IS_TRUE(CAT3 == viewModels[2]->CurrentCategory->GetModelCategory()); - - VERIFY_IS_TRUE(UNIT1 == viewModels[0]->Unit1->GetModelUnit()); - VERIFY_IS_TRUE(UNIT2 == viewModels[0]->Unit2->GetModelUnit()); - - VERIFY_IS_TRUE(UNIT4 == viewModels[1]->Unit1->GetModelUnit()); - VERIFY_IS_TRUE(UNIT6 == viewModels[1]->Unit2->GetModelUnit()); - - VERIFY_IS_TRUE(UNIT9 == viewModels[2]->Unit1->GetModelUnit()); - VERIFY_IS_TRUE(UNIT7 == viewModels[2]->Unit2->GetModelUnit()); - } - - TEST_METHOD(MultipleConverterModeCalculationTest) - { - UnitConverterViewModel^ viewModels[3]; - ResourceLoader^ resLoader = ResourceLoader::GetForViewIndependentUse("Test"); - - for (int i = 0; i < 3; i++) - { - viewModels[i] = ref new UnitConverterViewModel(std::make_shared(std::make_shared(ref new GeographicRegion()), nullptr)); - IObservableVector^ categories = viewModels[i]->Categories; - VERIFY_ARE_EQUAL((UINT)13, categories->Size); - } - - IObservableVector^ categoryList = viewModels[0]->Categories; - IObservableVector^ unitsList[3]; - - // viewModels 0 & 1 have same category(Volume) and viewModel 2 has different category(Length) - int volumeIndex = NavCategory::GetIndexInGroup(ViewMode::Volume, CategoryGroupType::Converter); - int lengthIndex = NavCategory::GetIndexInGroup(ViewMode::Length, CategoryGroupType::Converter); - viewModels[0]->CurrentCategory = categoryList->GetAt(volumeIndex); - viewModels[1]->CurrentCategory = categoryList->GetAt(volumeIndex); - viewModels[2]->CurrentCategory = categoryList->GetAt(lengthIndex); - - for (int i = 0; i < 3; i++) - { - unitsList[i] = viewModels[i]->Units; - } - - // Milliliters - viewModels[0]->Unit1 = unitsList[0]->GetAt(0); - // Cubic centimeters - viewModels[0]->Unit2 = unitsList[0]->GetAt(1); - - // Liters - viewModels[1]->Unit1 = unitsList[1]->GetAt(2); - // Cubic meters - viewModels[1]->Unit2 = unitsList[1]->GetAt(3); - - // Nanometers - viewModels[2]->Unit1 = unitsList[2]->GetAt(0); - // Microns - viewModels[2]->Unit2 = unitsList[2]->GetAt(1); - - // Check that the units in multiple instances got set correctly - VERIFY_IS_TRUE(unitsList[0]->GetAt(0) == viewModels[0]->Unit1); - VERIFY_IS_TRUE(unitsList[0]->GetAt(1) == viewModels[0]->Unit2); - - VERIFY_IS_TRUE(unitsList[1]->GetAt(2) == viewModels[1]->Unit1); - VERIFY_IS_TRUE(unitsList[1]->GetAt(3) == viewModels[1]->Unit2); - - VERIFY_IS_TRUE(unitsList[2]->GetAt(0) == viewModels[2]->Unit1); - VERIFY_IS_TRUE(unitsList[2]->GetAt(1) == viewModels[2]->Unit2); - - // Perform conversions - viewModels[0]->ButtonPressed->Execute(NumbersAndOperatorsEnum::One); - - viewModels[1]->ButtonPressed->Execute(NumbersAndOperatorsEnum::Two); - - viewModels[2]->ButtonPressed->Execute(NumbersAndOperatorsEnum::Three); - - // Validate Value1 and Value2 which is the result - for (int i = 0; i < 3; i++) - { - auto expectedValue1 = (i + 1).ToString(); - auto actualValue1 = viewModels[i]->Value1; - - VERIFY_ARE_EQUAL(expectedValue1, GetStringValue(actualValue1)); - - std::wstring unit1Name = viewModels[i]->Unit1->Name->Data(); - std::wstring unit2Name = viewModels[i]->Unit2->Name->Data(); - - auto resKey = String::Concat(ref new String((unit1Name + L"-" + unit2Name + L"-").c_str()), expectedValue1); - String^ expectedResult = resLoader->GetString(resKey); - - String^ actualResult = GetStringValue(viewModels[i]->Value2); - - VERIFY_ARE_EQUAL(expectedResult, actualResult); - } - } - - TEST_METHOD(TestStandardUnitConverterAndDateViewModels) - { - // Create instances of SCVM in Standard Mode and UnitConverterViewModel - StandardCalculatorViewModel^ standardViewModel = ref new StandardCalculatorViewModel(); - UnitConverterViewModel^ unitConverterViewModel = ref new UnitConverterViewModel(std::make_shared(std::make_shared(ref new GeographicRegion()), nullptr)); - DateCalculatorViewModel^ dateCalcViewModel = ref new DateCalculatorViewModel(); - - // Initialize Standard Calculator - ChangeMode(standardViewModel, 0); - - // Initialize Date Calculator - dateCalcViewModel->IsDateDiffMode = false; - dateCalcViewModel->IsAddMode = true; - - // Initialize Unit Converter - int volumeCategoryIndex = NavCategory::GetIndexInGroup(ViewMode::Volume, CategoryGroupType::Converter); - IObservableVector^ categories = unitConverterViewModel->Categories; - unitConverterViewModel->CurrentCategory = categories->GetAt(volumeCategoryIndex); - unitConverterViewModel->Unit1 = unitConverterViewModel->Units->GetAt(2); - unitConverterViewModel->Unit2 = unitConverterViewModel->Units->GetAt(3); - - // Validate Calculator mode and UC Category and Units - ValidateViewModelMode(standardViewModel, 0); - - VERIFY_ARE_EQUAL(categories->GetAt(volumeCategoryIndex), unitConverterViewModel->CurrentCategory); - VERIFY_ARE_EQUAL(unitConverterViewModel->Units->GetAt(2), unitConverterViewModel->Unit1); - VERIFY_ARE_EQUAL(unitConverterViewModel->Units->GetAt(3), unitConverterViewModel->Unit2); - - // Perform Calculations on these instances and check that they work independently - - // Standard Mode 1: Expression 3-2= - TESTITEM standardModeTestItems1[] = { - { NumbersAndOperatorsEnum::Three, L"3", L"" }, - { NumbersAndOperatorsEnum::Subtract, L"3", L"3 - " }, - { NumbersAndOperatorsEnum::Two, L"2", L"3 - " }, - { NumbersAndOperatorsEnum::Equals, L"1", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(standardViewModel, standardModeTestItems1, true); - - SYSTEMTIME startDate, endDate; - /* 01-10-2015 */ startDate.wDay = 1; startDate.wMonth = 10; startDate.wYear = 2015; startDate.wDayOfWeek = 4; startDate.wHour = 0; startDate.wMinute = 0; startDate.wSecond = 0; startDate.wMilliseconds = 0; - /* 02-12-2018 */ endDate.wDay = 2; endDate.wMonth = 12; endDate.wYear = 2018; endDate.wDayOfWeek = 0; endDate.wHour = 0; endDate.wMinute = 0; endDate.wSecond = 0; endDate.wMilliseconds = 0; - - dateCalcViewModel->StartDate = DateUtils::SystemTimeToDateTime(startDate); - dateCalcViewModel->DaysOffset = 1; - dateCalcViewModel->MonthsOffset = 2; - dateCalcViewModel->YearsOffset = 3; - - unitConverterViewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Two); - - // Validate the Result - VERIFY_ARE_EQUAL(StringReference(L"2"), GetStringValue(unitConverterViewModel->Value1)); - VERIFY_ARE_EQUAL(StringReference(L"0.002"), GetStringValue(unitConverterViewModel->Value2)); - - // Assert that the Display Value of Standard Calc instance is unchanged - VERIFY_ARE_EQUAL(GetStringValue(standardViewModel->DisplayValue), StringReference(L"1")); - - // Again perform calculations on Standard Calc instance and validate that the Converter remains unaffected - - // Standard Mode: Expression 1+2= - TESTITEM standardModeTestItems2[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Equals, L"3", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(standardViewModel, standardModeTestItems2, true); - VERIFY_ARE_EQUAL(StringReference(L"3"), GetStringValue(standardViewModel->DisplayValue)); - - // Validate the Date Calculator - VERIFY_ARE_EQUAL(DateUtils::GetLongDate(endDate), dateCalcViewModel->StrDateResult); - - // Validate the Unit Converter - VERIFY_ARE_EQUAL(StringReference(L"2"), GetStringValue(unitConverterViewModel->Value1)); - VERIFY_ARE_EQUAL(StringReference(L"0.002"), GetStringValue(unitConverterViewModel->Value2)); - } - - // Change the radix in programmer mode and check that other modes are not affected - TEST_METHOD(MultipleModesWithChangeInProgrammerRadix) - { - std::vector viewModels(3); - - // Create 2 instances of StandardCalculatorViewModel in Standard and Programmer modes - viewModels[0] = ref new StandardCalculatorViewModel(); - ChangeMode(viewModels[0], 0); - - viewModels[1] = ref new StandardCalculatorViewModel(); - ChangeMode(viewModels[1], 2); - - // Change the programmer mode radix to hex - TESTITEM programmerModeTestItems[] = { - { NumbersAndOperatorsEnum::HexButton, L"0", L"" }, - { NumbersAndOperatorsEnum::F, L"F", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[1], programmerModeTestItems, false /*doReset*/); - VERIFY_ARE_EQUAL(GetStringValue(viewModels[1]->HexDisplayValue), StringReference(L"F")); - - // Standard Mode: Expression 10+2= - // Radix should be decimal, not hex - TESTITEM standardModeTestItems[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Add, L"10", L"10 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"10 + " }, - { NumbersAndOperatorsEnum::Equals, L"12", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[0], standardModeTestItems, false /*doReset*/); - - //Launch a new instance in standard mode - viewModels[2] = ref new StandardCalculatorViewModel(); - ChangeMode(viewModels[2], 0); - - // Standard Mode: Expression 10+2= - // Radix will be decimal by default - TESTITEM standardModeTestItemsNew[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Add, L"10", L"10 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"10 + " }, - { NumbersAndOperatorsEnum::Equals, L"12", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[2], standardModeTestItemsNew, false /*doReset*/); - - //Radix in the programmer mode launched should still be hex. - // A + 1 = B - TESTITEM programmerModeTestItemsNew[] = { - { NumbersAndOperatorsEnum::A, L"A", L"" }, - { NumbersAndOperatorsEnum::Add, L"A", L"A + " }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Equals, L"B", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(viewModels[1], programmerModeTestItemsNew, true /*doReset*/); - VERIFY_ARE_EQUAL(GetStringValue(viewModels[1]->HexDisplayValue), StringReference(L"B")); - } - }; -} - diff --git a/internal/CalculatorUnitTests/NavCategoryUnitTests.cpp b/internal/CalculatorUnitTests/NavCategoryUnitTests.cpp deleted file mode 100644 index e0ecebb..0000000 --- a/internal/CalculatorUnitTests/NavCategoryUnitTests.cpp +++ /dev/null @@ -1,410 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include - -using namespace CalculatorApp::Common; -using namespace CalculatorUnitTests; -using namespace Platform; -using namespace std; -using namespace Windows::Foundation::Collections; - -namespace CalculatorUnitTests -{ - class NavCategoryUnitTests - { - public: - TEST_CLASS(NavCategoryUnitTests); - - TEST_METHOD(Serialize); - TEST_METHOD(Deserialize_AllValid); - TEST_METHOD(Deserialize_AllInvalid); - - TEST_METHOD(IsValidViewMode_AllValid); - TEST_METHOD(IsValidViewMode_AllInvalid); - - TEST_METHOD(IsCalculatorViewMode); - TEST_METHOD(IsDateCalculatorViewMode); - TEST_METHOD(IsConverterViewMode); - - TEST_METHOD(GetFriendlyName); - TEST_METHOD(GetGroupType); - TEST_METHOD(GetIndex); - TEST_METHOD(GetPosition); - TEST_METHOD(GetIndex_GetPosition_Relationship); - TEST_METHOD(GetIndexInGroup); - - TEST_METHOD(GetViewModeForVirtualKey); - }; - - void NavCategoryUnitTests::Serialize() - { - // While values in other tests may change (for example, the order - // of a navigation item might change), these values should NEVER - // change. We are validating the unique ID for each mode, not - // it's position or index. - VERIFY_ARE_EQUAL(0, NavCategory::Serialize(ViewMode::Standard)); - VERIFY_ARE_EQUAL(1, NavCategory::Serialize(ViewMode::Scientific)); - VERIFY_ARE_EQUAL(2, NavCategory::Serialize(ViewMode::Programmer)); - VERIFY_ARE_EQUAL(3, NavCategory::Serialize(ViewMode::Date)); - VERIFY_ARE_EQUAL(16, NavCategory::Serialize(ViewMode::Currency)); - VERIFY_ARE_EQUAL(4, NavCategory::Serialize(ViewMode::Volume)); - VERIFY_ARE_EQUAL(5, NavCategory::Serialize(ViewMode::Length)); - VERIFY_ARE_EQUAL(6, NavCategory::Serialize(ViewMode::Weight)); - VERIFY_ARE_EQUAL(7, NavCategory::Serialize(ViewMode::Temperature)); - VERIFY_ARE_EQUAL(8, NavCategory::Serialize(ViewMode::Energy)); - VERIFY_ARE_EQUAL(9, NavCategory::Serialize(ViewMode::Area)); - VERIFY_ARE_EQUAL(10, NavCategory::Serialize(ViewMode::Speed)); - VERIFY_ARE_EQUAL(11, NavCategory::Serialize(ViewMode::Time)); - VERIFY_ARE_EQUAL(12, NavCategory::Serialize(ViewMode::Power)); - VERIFY_ARE_EQUAL(13, NavCategory::Serialize(ViewMode::Data)); - VERIFY_ARE_EQUAL(14, NavCategory::Serialize(ViewMode::Pressure)); - VERIFY_ARE_EQUAL(15, NavCategory::Serialize(ViewMode::Angle)); - - VERIFY_ARE_EQUAL(-1, NavCategory::Serialize(ViewMode::None)); - } - - void NavCategoryUnitTests::Deserialize_AllValid() - { - // While values in other tests may change (for example, the order - // of a navigation item might change), these values should NEVER - // change. We are validating the unique ID for each mode, not - // it's position or index. - VERIFY_ARE_EQUAL(ViewMode::Standard, NavCategory::Deserialize(ref new Box(0))); - VERIFY_ARE_EQUAL(ViewMode::Scientific, NavCategory::Deserialize(ref new Box(1))); - VERIFY_ARE_EQUAL(ViewMode::Programmer, NavCategory::Deserialize(ref new Box(2))); - VERIFY_ARE_EQUAL(ViewMode::Date, NavCategory::Deserialize(ref new Box(3))); - VERIFY_ARE_EQUAL(ViewMode::Currency, NavCategory::Deserialize(ref new Box(16))); - VERIFY_ARE_EQUAL(ViewMode::Volume, NavCategory::Deserialize(ref new Box(4))); - VERIFY_ARE_EQUAL(ViewMode::Length, NavCategory::Deserialize(ref new Box(5))); - VERIFY_ARE_EQUAL(ViewMode::Weight, NavCategory::Deserialize(ref new Box(6))); - VERIFY_ARE_EQUAL(ViewMode::Temperature, NavCategory::Deserialize(ref new Box(7))); - VERIFY_ARE_EQUAL(ViewMode::Energy, NavCategory::Deserialize(ref new Box(8))); - VERIFY_ARE_EQUAL(ViewMode::Area, NavCategory::Deserialize(ref new Box(9))); - VERIFY_ARE_EQUAL(ViewMode::Speed, NavCategory::Deserialize(ref new Box(10))); - VERIFY_ARE_EQUAL(ViewMode::Time, NavCategory::Deserialize(ref new Box(11))); - VERIFY_ARE_EQUAL(ViewMode::Power, NavCategory::Deserialize(ref new Box(12))); - VERIFY_ARE_EQUAL(ViewMode::Data, NavCategory::Deserialize(ref new Box(13))); - VERIFY_ARE_EQUAL(ViewMode::Pressure, NavCategory::Deserialize(ref new Box(14))); - VERIFY_ARE_EQUAL(ViewMode::Angle, NavCategory::Deserialize(ref new Box(15))); - } - - void NavCategoryUnitTests::Deserialize_AllInvalid() - { - VERIFY_ARE_EQUAL(ViewMode::None, NavCategory::Deserialize(nullptr)); - VERIFY_ARE_EQUAL(ViewMode::None, NavCategory::Deserialize(ref new String(L"fail"))); - - // Boundary testing - VERIFY_ARE_EQUAL(ViewMode::None, NavCategory::Deserialize(ref new Box(-1))); - VERIFY_ARE_EQUAL(ViewMode::None, NavCategory::Deserialize(ref new Box(17))); - } - - void NavCategoryUnitTests::IsValidViewMode_AllValid() - { - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Standard)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Scientific)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Programmer)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Date)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Currency)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Volume)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Length)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Weight)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Temperature)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Energy)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Area)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Speed)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Time)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Power)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Data)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Pressure)); - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(ViewMode::Angle)); - } - - void NavCategoryUnitTests::IsValidViewMode_AllInvalid() - { - VERIFY_IS_FALSE(NavCategory::IsValidViewMode(ViewMode::None)); - - // There are 17 total options so int 17 should be the first invalid - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(static_cast(16))); - VERIFY_IS_FALSE(NavCategory::IsValidViewMode(static_cast(17))); - - // Also verify the lower bound - VERIFY_IS_TRUE(NavCategory::IsValidViewMode(static_cast(0))); - VERIFY_IS_FALSE(NavCategory::IsValidViewMode(static_cast(-1))); - } - - void NavCategoryUnitTests::IsCalculatorViewMode() - { - VERIFY_IS_TRUE(NavCategory::IsCalculatorViewMode(ViewMode::Standard)); - VERIFY_IS_TRUE(NavCategory::IsCalculatorViewMode(ViewMode::Scientific)); - VERIFY_IS_TRUE(NavCategory::IsCalculatorViewMode(ViewMode::Programmer)); - - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Date)); - - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Currency)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Volume)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Length)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Weight)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Temperature)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Energy)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Area)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Speed)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Time)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Power)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Data)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Pressure)); - VERIFY_IS_FALSE(NavCategory::IsCalculatorViewMode(ViewMode::Angle)); - } - - void NavCategoryUnitTests::IsDateCalculatorViewMode() - { - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Standard)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Scientific)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Programmer)); - - VERIFY_IS_TRUE(NavCategory::IsDateCalculatorViewMode(ViewMode::Date)); - - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Currency)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Volume)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Length)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Weight)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Temperature)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Energy)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Area)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Speed)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Time)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Power)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Data)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Pressure)); - VERIFY_IS_FALSE(NavCategory::IsDateCalculatorViewMode(ViewMode::Angle)); - } - - void NavCategoryUnitTests::IsConverterViewMode() - { - VERIFY_IS_FALSE(NavCategory::IsConverterViewMode(ViewMode::Standard)); - VERIFY_IS_FALSE(NavCategory::IsConverterViewMode(ViewMode::Scientific)); - VERIFY_IS_FALSE(NavCategory::IsConverterViewMode(ViewMode::Programmer)); - - VERIFY_IS_FALSE(NavCategory::IsConverterViewMode(ViewMode::Date)); - - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Currency)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Volume)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Length)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Weight)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Temperature)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Energy)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Area)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Speed)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Time)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Power)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Data)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Pressure)); - VERIFY_IS_TRUE(NavCategory::IsConverterViewMode(ViewMode::Angle)); - } - - void NavCategoryUnitTests::GetFriendlyName() - { - VERIFY_ARE_EQUAL(StringReference(L"Standard"), NavCategory::GetFriendlyName(ViewMode::Standard)); - VERIFY_ARE_EQUAL(StringReference(L"Scientific"), NavCategory::GetFriendlyName(ViewMode::Scientific)); - VERIFY_ARE_EQUAL(StringReference(L"Programmer"), NavCategory::GetFriendlyName(ViewMode::Programmer)); - VERIFY_ARE_EQUAL(StringReference(L"Date"), NavCategory::GetFriendlyName(ViewMode::Date)); - VERIFY_ARE_EQUAL(StringReference(L"Currency"), NavCategory::GetFriendlyName(ViewMode::Currency)); - VERIFY_ARE_EQUAL(StringReference(L"Volume"), NavCategory::GetFriendlyName(ViewMode::Volume)); - VERIFY_ARE_EQUAL(StringReference(L"Length"), NavCategory::GetFriendlyName(ViewMode::Length)); - VERIFY_ARE_EQUAL(StringReference(L"Weight and Mass"), NavCategory::GetFriendlyName(ViewMode::Weight)); - VERIFY_ARE_EQUAL(StringReference(L"Temperature"), NavCategory::GetFriendlyName(ViewMode::Temperature)); - VERIFY_ARE_EQUAL(StringReference(L"Energy"), NavCategory::GetFriendlyName(ViewMode::Energy)); - VERIFY_ARE_EQUAL(StringReference(L"Area"), NavCategory::GetFriendlyName(ViewMode::Area)); - VERIFY_ARE_EQUAL(StringReference(L"Speed"), NavCategory::GetFriendlyName(ViewMode::Speed)); - VERIFY_ARE_EQUAL(StringReference(L"Time"), NavCategory::GetFriendlyName(ViewMode::Time)); - VERIFY_ARE_EQUAL(StringReference(L"Power"), NavCategory::GetFriendlyName(ViewMode::Power)); - VERIFY_ARE_EQUAL(StringReference(L"Data"), NavCategory::GetFriendlyName(ViewMode::Data)); - VERIFY_ARE_EQUAL(StringReference(L"Pressure"), NavCategory::GetFriendlyName(ViewMode::Pressure)); - VERIFY_ARE_EQUAL(StringReference(L"Angle"), NavCategory::GetFriendlyName(ViewMode::Angle)); - - VERIFY_ARE_EQUAL(StringReference(L"None"), NavCategory::GetFriendlyName(ViewMode::None)); - } - - void NavCategoryUnitTests::GetGroupType() - { - VERIFY_ARE_EQUAL(CategoryGroupType::Calculator, NavCategory::GetGroupType(ViewMode::Standard)); - VERIFY_ARE_EQUAL(CategoryGroupType::Calculator, NavCategory::GetGroupType(ViewMode::Scientific)); - VERIFY_ARE_EQUAL(CategoryGroupType::Calculator, NavCategory::GetGroupType(ViewMode::Programmer)); - VERIFY_ARE_EQUAL(CategoryGroupType::Calculator, NavCategory::GetGroupType(ViewMode::Date)); - - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Currency)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Volume)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Length)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Weight)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Temperature)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Energy)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Area)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Speed)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Time)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Power)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Data)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Pressure)); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, NavCategory::GetGroupType(ViewMode::Angle)); - } - - void NavCategoryUnitTests::GetIndex() - { - // Index is the 0-based ordering of modes - vector orderedModes = { - ViewMode::Standard, - ViewMode::Scientific, - ViewMode::Programmer, - ViewMode::Date, - ViewMode::Currency, - ViewMode::Volume, - ViewMode::Length, - ViewMode::Weight, - ViewMode::Temperature, - ViewMode::Energy, - ViewMode::Area, - ViewMode::Speed, - ViewMode::Time, - ViewMode::Power, - ViewMode::Data, - ViewMode::Pressure, - ViewMode::Angle - }; - - for (size_t index = 0; index < orderedModes.size(); index++) - { - ViewMode mode = orderedModes[index]; - VERIFY_ARE_EQUAL(index, NavCategory::GetIndex(mode)); - } - - VERIFY_ARE_EQUAL(-1, NavCategory::GetIndex(ViewMode::None)); - } - - void NavCategoryUnitTests::GetPosition() - { - // Position is the 1-based ordering of modes - vector orderedModes = { - ViewMode::Standard, - ViewMode::Scientific, - ViewMode::Programmer, - ViewMode::Date, - ViewMode::Currency, - ViewMode::Volume, - ViewMode::Length, - ViewMode::Weight, - ViewMode::Temperature, - ViewMode::Energy, - ViewMode::Area, - ViewMode::Speed, - ViewMode::Time, - ViewMode::Power, - ViewMode::Data, - ViewMode::Pressure, - ViewMode::Angle - }; - - for (size_t pos = 1; pos <= orderedModes.size(); pos++) - { - ViewMode mode = orderedModes[pos - 1]; - VERIFY_ARE_EQUAL(pos, NavCategory::GetPosition(mode)); - } - - VERIFY_ARE_EQUAL(-1, NavCategory::GetPosition(ViewMode::None)); - } - - void NavCategoryUnitTests::GetIndex_GetPosition_Relationship() - { - // Index should be 1 less than Position. - // The other checks verify the order of Index and Position. - // Just verify the relationship here. - VERIFY_ARE_EQUAL(NavCategory::GetIndex(ViewMode::Standard) + 1, NavCategory::GetPosition(ViewMode::Standard)); - VERIFY_ARE_EQUAL(NavCategory::GetPosition(ViewMode::Volume) - 1, NavCategory::GetIndex(ViewMode::Volume)); - } - - void NavCategoryUnitTests::GetIndexInGroup() - { - VERIFY_ARE_EQUAL(0, NavCategory::GetIndexInGroup(ViewMode::Standard, CategoryGroupType::Calculator)); - VERIFY_ARE_EQUAL(1, NavCategory::GetIndexInGroup(ViewMode::Scientific, CategoryGroupType::Calculator)); - VERIFY_ARE_EQUAL(2, NavCategory::GetIndexInGroup(ViewMode::Programmer, CategoryGroupType::Calculator)); - VERIFY_ARE_EQUAL(3, NavCategory::GetIndexInGroup(ViewMode::Date, CategoryGroupType::Calculator)); - - VERIFY_ARE_EQUAL(0, NavCategory::GetIndexInGroup(ViewMode::Currency, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(1, NavCategory::GetIndexInGroup(ViewMode::Volume, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(2, NavCategory::GetIndexInGroup(ViewMode::Length, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(3, NavCategory::GetIndexInGroup(ViewMode::Weight, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(4, NavCategory::GetIndexInGroup(ViewMode::Temperature, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(5, NavCategory::GetIndexInGroup(ViewMode::Energy, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(6, NavCategory::GetIndexInGroup(ViewMode::Area, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(7, NavCategory::GetIndexInGroup(ViewMode::Speed, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(8, NavCategory::GetIndexInGroup(ViewMode::Time, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(9, NavCategory::GetIndexInGroup(ViewMode::Power, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(10, NavCategory::GetIndexInGroup(ViewMode::Data, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(11, NavCategory::GetIndexInGroup(ViewMode::Pressure, CategoryGroupType::Converter)); - VERIFY_ARE_EQUAL(12, NavCategory::GetIndexInGroup(ViewMode::Angle, CategoryGroupType::Converter)); - - VERIFY_ARE_EQUAL(-1, NavCategory::GetIndexInGroup(ViewMode::None, CategoryGroupType::Calculator)); - VERIFY_ARE_EQUAL(-1, NavCategory::GetIndexInGroup(ViewMode::None, CategoryGroupType::Converter)); - } - - void NavCategoryUnitTests::GetViewModeForVirtualKey() - { - VERIFY_ARE_EQUAL(ViewMode::Standard, NavCategory::GetViewModeForVirtualKey(MyVirtualKey::Number1)); - VERIFY_ARE_EQUAL(ViewMode::Scientific, NavCategory::GetViewModeForVirtualKey(MyVirtualKey::Number2)); - VERIFY_ARE_EQUAL(ViewMode::Programmer, NavCategory::GetViewModeForVirtualKey(MyVirtualKey::Number3)); - } - - class NavCategoryGroupUnitTests - { - public: - TEST_CLASS(NavCategoryGroupUnitTests); - - TEST_METHOD(CreateNavCategoryGroup); - - private: - void ValidateNavCategory(IObservableVector^ 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); - VERIFY_ARE_EQUAL(expectedMode, category->Mode); - VERIFY_ARE_EQUAL(expectedPosition, category->Position); - } - }; - - void NavCategoryGroupUnitTests::CreateNavCategoryGroup() - { - IObservableVector^ menuOptions = NavCategoryGroup::CreateMenuOptions(); - - VERIFY_ARE_EQUAL(2, menuOptions->Size); - - NavCategoryGroup^ calculatorGroup = menuOptions->GetAt(0); - VERIFY_ARE_EQUAL(CategoryGroupType::Calculator, calculatorGroup->GroupType); - - IObservableVector^ calculatorCategories = calculatorGroup->Categories; - VERIFY_ARE_EQUAL(4, calculatorCategories->Size); - ValidateNavCategory(calculatorCategories, 0u, ViewMode::Standard, 1); - ValidateNavCategory(calculatorCategories, 1u, ViewMode::Scientific, 2); - ValidateNavCategory(calculatorCategories, 2u, ViewMode::Programmer, 3); - ValidateNavCategory(calculatorCategories, 3u, ViewMode::Date, 4); - - NavCategoryGroup^ converterGroup = menuOptions->GetAt(1); - VERIFY_ARE_EQUAL(CategoryGroupType::Converter, converterGroup->GroupType); - - IObservableVector^ converterCategories = converterGroup->Categories; - VERIFY_ARE_EQUAL(13, converterCategories->Size); - ValidateNavCategory(converterCategories, 0u, ViewMode::Currency, 5); - ValidateNavCategory(converterCategories, 1u, ViewMode::Volume, 6); - ValidateNavCategory(converterCategories, 2u, ViewMode::Length, 7); - ValidateNavCategory(converterCategories, 3u, ViewMode::Weight, 8); - ValidateNavCategory(converterCategories, 4u, ViewMode::Temperature, 9); - ValidateNavCategory(converterCategories, 5u, ViewMode::Energy, 10); - ValidateNavCategory(converterCategories, 6u, ViewMode::Area, 11); - ValidateNavCategory(converterCategories, 7u, ViewMode::Speed, 12); - ValidateNavCategory(converterCategories, 8u, ViewMode::Time, 13); - ValidateNavCategory(converterCategories, 9u, ViewMode::Power, 14); - ValidateNavCategory(converterCategories, 10u, ViewMode::Data, 15); - ValidateNavCategory(converterCategories, 11u, ViewMode::Pressure, 16); - ValidateNavCategory(converterCategories, 12u, ViewMode::Angle, 17); - } -} diff --git a/internal/CalculatorUnitTests/Package.appxmanifest b/internal/CalculatorUnitTests/Package.appxmanifest deleted file mode 100644 index 62c0b67..0000000 --- a/internal/CalculatorUnitTests/Package.appxmanifest +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - CalculatorUnitTests - Microsoft Corporation - Assets\StoreLogo.png - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/internal/CalculatorUnitTests/StandardViewModelUnitTests.cpp b/internal/CalculatorUnitTests/StandardViewModelUnitTests.cpp deleted file mode 100644 index 3164303..0000000 --- a/internal/CalculatorUnitTests/StandardViewModelUnitTests.cpp +++ /dev/null @@ -1,1144 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include - -#include "CalcViewModel/StandardCalculatorViewModel.h" -#include "CalcViewModel/Common/CalculatorButtonPressedEventArgs.h" - -#include "CalcViewModel/StandardCalculatorViewModel.h" -#include "CalcViewModel/Common/CalculatorButtonPressedEventArgs.h" - -using namespace CalculationManager; -using namespace CalculatorApp; -using namespace CalculatorApp::Common; -using namespace CalculatorApp::ViewModel; -using namespace Platform; - -namespace CalculatorUnitTests -{ - - void ChangeMode(StandardCalculatorViewModel^ viewModel, int mode) - { - if (mode == 0) - { - viewModel->IsStandard = true; - viewModel->IsScientific = false; - viewModel->IsProgrammer = false; - viewModel->ResetDisplay(); - viewModel->SetPrecision(StandardModePrecision); - } - else if (mode == 1) - { - viewModel->IsScientific = true; - viewModel->IsProgrammer = false; - viewModel->IsStandard = false; - viewModel->ResetDisplay(); - viewModel->SetPrecision(ScientificModePrecision); - } - else if (mode == 2) - { - viewModel->IsProgrammer = true; - viewModel->IsScientific = false; - viewModel->IsStandard = false; - viewModel->ResetDisplay(); - viewModel->SetPrecision(ProgrammerModePrecision); - } - } - - Object^ CommandParameterFromTestItem(TESTITEM* item) - { - // Need to wrap Binary Operators with their feedback - static const std::vector> binOps = { - { NumbersAndOperatorsEnum::Add, L"plus" }, - { NumbersAndOperatorsEnum::Subtract, L"minus" }, - { NumbersAndOperatorsEnum::Multiply, L"times" }, - { NumbersAndOperatorsEnum::Divide, L"divided by" } - }; - - for (auto& binOp : binOps) - { - if (item->command == binOp.first) - { - return ref new CalculatorButtonPressedEventArgs(binOp.second, binOp.first); - } - } - - return item->command; - } - - void ValidateViewModelByCommands(StandardCalculatorViewModel^ viewModel, TESTITEM item[], bool doReset = false) - { - if (doReset) - { - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Clear); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::ClearEntry); - viewModel->ClearMemoryCommand->Execute(nullptr); - viewModel->Deserialize(ref new Platform::Array(0)); - } - - TESTITEM* currentItem = item; - - while (currentItem->command != NumbersAndOperatorsEnum::None) - { - Object^ commandParam = CommandParameterFromTestItem(currentItem); - viewModel->ButtonPressed->Execute(commandParam); - - if (currentItem->expectedPrimaryDisplay != L"N/A") - { - VERIFY_ARE_EQUAL(Platform::StringReference(currentItem->expectedPrimaryDisplay.c_str()), viewModel->DisplayValue); - } - if (currentItem->expectedExpressions != L"N/A" && viewModel->DisplayStringExpression != nullptr) - { - VERIFY_ARE_EQUAL(Platform::StringReference(currentItem->expectedExpressions.c_str()), viewModel->DisplayStringExpression); - } - currentItem++; - } - } - - class StandardViewModelUnitTests - { - public: - TEST_CLASS(StandardViewModelUnitTests); - - TEST_METHOD_SETUP(InitializeViewModel) - { - m_viewModel = ref new StandardCalculatorViewModel(); - m_viewModel->IsStandard = true; - m_engineResourceProvider = std::make_shared(); - m_decimalSeparator = ref new Platform::String(m_engineResourceProvider->GetCEngineString(L"sDecimal").c_str()); - return true; - } - - void ValidateViewModelValueAndExpression(String ^ value, String ^expression = nullptr) - { - String^ displayValue = m_viewModel->DisplayValue; - String^ displayExpression = m_viewModel->DisplayStringExpression; - if (value != nullptr) - { - VERIFY_ARE_EQUAL(value, displayValue); - } - - if (expression != nullptr) - { - VERIFY_ARE_EQUAL(expression, displayExpression); - } - } - - void ValidateViewModelValueAndSecondaryExpression(String ^ value, String ^expression = nullptr) - { - String^ displayValue = m_viewModel->DisplayValue; - - unsigned int nTokens = m_viewModel->ExpressionTokens->Size; - String^ displaySecondaryExpression = ref new String(); - - for (unsigned int i = 0; i < nTokens; ++i) - { - DisplayExpressionToken^ currentToken; - currentToken = m_viewModel->ExpressionTokens->GetAt(i); - displaySecondaryExpression = String::Concat(displaySecondaryExpression, currentToken->Token); - } - - if (value != nullptr) - { - VERIFY_ARE_EQUAL(value, displayValue); - } - - if (expression != nullptr) - { - VERIFY_ARE_EQUAL(expression, displaySecondaryExpression); - } - } - - TEST_METHOD(ViewModelConstructorDisplayValueAndExpressionInitializedTest) - { - StandardCalculatorViewModel^ vmconstructortest = ref new StandardCalculatorViewModel(); - vmconstructortest->IsStandard = true; - String^ displayValue = vmconstructortest->DisplayValue; - String^ displayExpression = vmconstructortest->DisplayStringExpression; - String^ calculationResultAutomationName = vmconstructortest->CalculationResultAutomationName; - - VERIFY_ARE_EQUAL(StringReference(L"0"), displayValue); - VERIFY_ARE_EQUAL(StringReference(L"Display is 0"), calculationResultAutomationName); - } - - TEST_METHOD(ViewModelConstructorButtonPressedInitializedTest) - { - StandardCalculatorViewModel^ vmconstructortest = ref new StandardCalculatorViewModel(); - vmconstructortest->IsStandard = true; - VERIFY_IS_NOT_NULL(vmconstructortest->ButtonPressed); - } - - /// Expression : 135 - TEST_METHOD(ButtonPressedLeftHandOperandEnteredTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Three, L"13", L"" }, - { NumbersAndOperatorsEnum::Five, L"135", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 13. - TEST_METHOD(ButtonPressedLeftHandOperandAndDecimalEnteredTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Three, L"13", L"" }, - { NumbersAndOperatorsEnum::Decimal, L"13" + std::wstring(m_decimalSeparator->Data()), L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 13== - TEST_METHOD(ButtonPressedLeftHandOperandAndEqualsEnteredTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Three, L"13", L"" }, - { NumbersAndOperatorsEnum::Equals, L"13", L"" }, - { NumbersAndOperatorsEnum::Equals, L"13", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 13+ - TEST_METHOD(ButtonPressedLeftHandOperandAndOperationEnteredTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Three, L"13", L"" }, - { NumbersAndOperatorsEnum::Add, L"13", L"13 + " }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 13+801 - TEST_METHOD(ButtonPressedRightHandOperandEnteredTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Three, L"13", L"" }, - { NumbersAndOperatorsEnum::Add, L"13", L"13 + " }, - { NumbersAndOperatorsEnum::Eight, L"8", L"13 + " }, - { NumbersAndOperatorsEnum::Zero, L"80", L"13 + " }, - { NumbersAndOperatorsEnum::One, L"801", L"13 + " }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 1+2= - TEST_METHOD(ButtonPressedAdditionWithEqualsTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Equals, L"3", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 1-2= - TEST_METHOD(ButtonPressedSubtractionWithEqualsTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Subtract, L"1", L"1 - " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 - " }, - { NumbersAndOperatorsEnum::Equals, L"-1", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 3*5= - TEST_METHOD(ButtonPressedMultiplyWithEqualsTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::Three, L"3", L"" }, - { NumbersAndOperatorsEnum::Multiply, L"3", L"3 * " }, - { NumbersAndOperatorsEnum::Five, L"5", L"3 * " }, - { NumbersAndOperatorsEnum::Equals, L"15", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 9/3= - TEST_METHOD(ButtonPressedDivideTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::Nine, L"9", L"" }, - { NumbersAndOperatorsEnum::Divide, L"9", L"9 / " }, - { NumbersAndOperatorsEnum::Three, L"3", L"9 / " }, - { NumbersAndOperatorsEnum::Equals, L"3", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 7.555*3= - TEST_METHOD(ButtonPressedDecimalOperationTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::Seven, L"7", L"" }, - { NumbersAndOperatorsEnum::Decimal, L"7" + std::wstring(m_decimalSeparator->Data()), L"" }, - { NumbersAndOperatorsEnum::Five, L"7" + std::wstring(m_decimalSeparator->Data()) + L"5", L"" }, - { NumbersAndOperatorsEnum::Five, L"7" + std::wstring(m_decimalSeparator->Data()) + L"55", L"" }, - { NumbersAndOperatorsEnum::Five, L"7" + std::wstring(m_decimalSeparator->Data()) + L"555", L"" }, - { NumbersAndOperatorsEnum::Multiply, L"7" + std::wstring(m_decimalSeparator->Data()) + L"555", L"7" + std::wstring(m_decimalSeparator->Data()) + L"555 * " }, - { NumbersAndOperatorsEnum::Three, L"3", L"7" + std::wstring(m_decimalSeparator->Data()) + L"555 * " }, - { NumbersAndOperatorsEnum::Equals, L"22" + std::wstring(m_decimalSeparator->Data()) + L"665", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 7/0 - TEST_METHOD(ButtonPressedDivideByZeroNegativeTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::Seven, L"7", L"" }, - { NumbersAndOperatorsEnum::Divide, L"7", L"7 / " }, - { NumbersAndOperatorsEnum::Zero, L"0", L"7 / " }, - { NumbersAndOperatorsEnum::Equals, L"Cannot divide by zero", L"7 / " }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 8/2* - TEST_METHOD(ButtonPressedExpressionWithMultipleOperatorsTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::Eight, L"8", L"" }, - { NumbersAndOperatorsEnum::Divide, L"8", L"8 / " }, - { NumbersAndOperatorsEnum::Two, L"2", L"8 / " }, - { NumbersAndOperatorsEnum::Multiply, L"4", L"8 / 2 * " }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 8/+*2* - TEST_METHOD(ButtonPressedExpressionWithMultipleOperatorsInSuccessionTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::Eight, L"8", L"" }, - { NumbersAndOperatorsEnum::Divide, L"8", L"8 / " }, - { NumbersAndOperatorsEnum::Add, L"8", L"8 + " }, - { NumbersAndOperatorsEnum::Multiply, L"8", L"8 * " }, - { NumbersAndOperatorsEnum::Two, L"2", L"8 * " }, - { NumbersAndOperatorsEnum::Multiply, L"16", L"8 * 2 * " }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 8*2== - TEST_METHOD(ButtonPressedExpressionWithMultipleEqualsAfterEvaluateTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::Eight, L"8", L"" }, - { NumbersAndOperatorsEnum::Multiply, L"8", L"8 * " }, - { NumbersAndOperatorsEnum::Two, L"2", L"8 * " }, - { NumbersAndOperatorsEnum::Equals, L"16", L"" }, - { NumbersAndOperatorsEnum::Equals, L"32", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 7-6 and Backspace - TEST_METHOD(ButtonPressedExpressionWithBackSpaceTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::Seven, L"7", L"" }, - { NumbersAndOperatorsEnum::Subtract, L"7", L"7 - " }, - { NumbersAndOperatorsEnum::Six, L"6", L"7 - " }, - { NumbersAndOperatorsEnum::Backspace, L"0", L"7 - " }, - { NumbersAndOperatorsEnum::Backspace, L"0", L"7 - " }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// Expression : 91-68 and Clear - TEST_METHOD(ButtonPressedExpressionWithClearTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::Nine, L"9", L"" }, - { NumbersAndOperatorsEnum::One, L"91", L"" }, - { NumbersAndOperatorsEnum::Subtract, L"91", L"91 - " }, - { NumbersAndOperatorsEnum::Six, L"6", L"91 - " }, - { NumbersAndOperatorsEnum::Eight, L"68", L"91 - " }, - { NumbersAndOperatorsEnum::Clear, L"0", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - } - - /// - /// Paste tests - /// - template - void ValidateIntegralsAreEqual(NumbersAndOperatorsEnum a, NumbersAndOperatorsEnum b) - { - VERIFY_ARE_EQUAL(static_cast(a), static_cast(b)); - } - - void ValidateNumbersAndOperatorsAreEqual(NumbersAndOperatorsEnum a, NumbersAndOperatorsEnum b) - { - ValidateIntegralsAreEqual(a, b); - } - - /// Low-level test of character mapping - TEST_METHOD(VerifyCorrectCharacterMapping) - { - bool canSendNegate = false; - - // Valid numbers - NumbersAndOperatorsEnum n = m_viewModel->MapCharacterToButtonId(L'0', canSendNegate); - ValidateNumbersAndOperatorsAreEqual(n, NumbersAndOperatorsEnum::Zero); - - n = m_viewModel->MapCharacterToButtonId(L'1', canSendNegate); - ValidateNumbersAndOperatorsAreEqual(n, NumbersAndOperatorsEnum::One); - - // Valid operators - n = m_viewModel->MapCharacterToButtonId(L'+', canSendNegate); - ValidateNumbersAndOperatorsAreEqual(n, NumbersAndOperatorsEnum::Add); - - n = m_viewModel->MapCharacterToButtonId(L'=', canSendNegate); - ValidateNumbersAndOperatorsAreEqual(n, NumbersAndOperatorsEnum::Equals); - - n = m_viewModel->MapCharacterToButtonId(L'a', canSendNegate); - ValidateNumbersAndOperatorsAreEqual(n, NumbersAndOperatorsEnum::A); - - // Invalid character - n = m_viewModel->MapCharacterToButtonId(L'$', canSendNegate); - ValidateNumbersAndOperatorsAreEqual(n, NumbersAndOperatorsEnum::None); - } - - /// Various strings get pasted - TEST_METHOD(PasteExpressions) - { - m_viewModel->IsScientific = false; - - m_viewModel->OnPaste("-0.99", ViewMode::Standard); - ValidateViewModelValueAndExpression("-0" + m_decimalSeparator + "99", ""); - - m_viewModel->OnPaste("1+1=", ViewMode::Standard); - ValidateViewModelValueAndExpression("2", ""); - - // This result is not obvious: it's the result of the previous operation - m_viewModel->OnPaste("0=", ViewMode::Standard); - ValidateViewModelValueAndExpression("1", ""); - - // Negative value - m_viewModel->OnPaste("-1", ViewMode::Standard); - ValidateViewModelValueAndExpression("-1", ""); - - // Negated expression - m_viewModel->OnPaste("-(1+1)", ViewMode::Standard); - ValidateViewModelValueAndSecondaryExpression("-2", "negate(1 + 1)"); - - // More complicated Negated expression - m_viewModel->OnPaste("-(-(-1))", ViewMode::Standard); - ValidateViewModelValueAndSecondaryExpression("-1", "negate(0 - (0 - 1))"); - - // Switch to scientific mode - m_viewModel->IsScientific = true; - - VERIFY_IS_FALSE(m_viewModel->IsFToEChecked); - - //// Positive exponent - m_viewModel->OnPaste("1.23e+10", ViewMode::Scientific); - ValidateViewModelValueAndExpression("1" + m_decimalSeparator + "23e+10", ""); - - //// Negative exponent - m_viewModel->OnPaste("1.23e-10", ViewMode::Scientific); - ValidateViewModelValueAndExpression("1" + m_decimalSeparator + "23e-10", ""); - - //// Uppercase E (for exponent) - m_viewModel->OnPaste("1.23E-10", ViewMode::Scientific); - ValidateViewModelValueAndExpression("1" + m_decimalSeparator + "23e-10", ""); - } - - // Verify Calculator CalculationResultAutomationName is set correctly - TEST_METHOD(CalculationResultAutomationNameVerification) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::IsStandardMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Two, L"12", L"" }, - { NumbersAndOperatorsEnum::Three, L"123", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - VERIFY_ARE_EQUAL(StringReference(L"Display is 123"), m_viewModel->CalculationResultAutomationName); - - TESTITEM items2[] = { - { NumbersAndOperatorsEnum::IsScientificMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Multiply, L"2", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Three, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Equals, L"7", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items2, true); - VERIFY_ARE_EQUAL(StringReference(L"Display is 7"), m_viewModel->CalculationResultAutomationName); - - TESTITEM items3[] = { - { NumbersAndOperatorsEnum::Clear, L"0", L"" }, - { NumbersAndOperatorsEnum::IsScientificMode, L"0", L"" }, - { NumbersAndOperatorsEnum::Five, L"5", L"" }, - { NumbersAndOperatorsEnum::InvSin, L"Invalid input", L"asind(5)" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items3, false); - VERIFY_ARE_EQUAL(StringReference(L"Display is Invalid input"), m_viewModel->CalculationResultAutomationName); - } - - // Switch Calculator Mode and verify if mode switch is happening as expected. - // Test precendence to check if mode switch is happening - // Standard mode 1+2*3 = 9; Scientific mode 1+2*3 = 7 - // Intermediate value is also different. after 1 + 2 * , standard shows 3, scientific shows 2 - TEST_METHOD(ButtonPressedCalculatorModeSwitch) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::IsStandardMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Multiply, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Three, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Equals, L"9", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - - TESTITEM items2[] = { - { NumbersAndOperatorsEnum::IsScientificMode, L"0", L"" }, - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Add, L"1", L"1 + " }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 + " }, - { NumbersAndOperatorsEnum::Multiply, L"2", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Three, L"3", L"1 + 2 * " }, - { NumbersAndOperatorsEnum::Equals, L"7", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items2, true); - } - - // Test AutoConvertedValue - TEST_METHOD(ProgrammerModeAutoConvertedValue) - { - TESTITEM none[] = { - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, none, true); - m_viewModel->IsProgrammer = true; - TESTITEM items[] = { - { NumbersAndOperatorsEnum::HexButton, L"0", L"" }, - { NumbersAndOperatorsEnum::F, L"F", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, false); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->HexDisplayValue), StringReference(L"F")); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->DecimalDisplayValue), StringReference(L"15")); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->OctalDisplayValue), StringReference(L"17")); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->BinaryDisplayValue), StringReference(L"1111")); - } - - // Test Button disabling in different Radixes - TEST_METHOD(ProgrammerModeButtonsDisable) - { - /* m_viewModel->IsProgrammer = true; - m_viewModel->SwitchProgrammerModeBase(OCT_RADIX); - VERIFY_IS_TRUE(m_viewModel->AreOCTButtonsEnabled); - VERIFY_IS_FALSE(m_viewModel->AreHEXButtonsEnabled); - VERIFY_IS_FALSE(m_viewModel->AreDECButtonsEnabled); - m_viewModel->SwitchProgrammerModeBase(DEC_RADIX); - VERIFY_IS_FALSE(m_viewModel->AreHEXButtonsEnabled); - VERIFY_IS_TRUE(m_viewModel->AreDECButtonsEnabled); - VERIFY_IS_TRUE(m_viewModel->AreOCTButtonsEnabled); - m_viewModel->SwitchProgrammerModeBase(HEX_RADIX); - VERIFY_IS_TRUE(m_viewModel->AreHEXButtonsEnabled); - VERIFY_IS_TRUE(m_viewModel->AreDECButtonsEnabled); - VERIFY_IS_TRUE(m_viewModel->AreOCTButtonsEnabled); - m_viewModel->SwitchProgrammerModeBase(BIN_RADIX); - VERIFY_IS_FALSE(m_viewModel->AreHEXButtonsEnabled); - VERIFY_IS_FALSE(m_viewModel->AreDECButtonsEnabled); - VERIFY_IS_FALSE(m_viewModel->AreOCTButtonsEnabled);*/ - - } - - // Test digit grouping for different radix in programmer mode - TEST_METHOD(ProgrammerModeRadixGrouping) - { - TESTITEM none[] = { - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, none, true); - m_viewModel->IsProgrammer = true; - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Two, L"12", L"" }, - { NumbersAndOperatorsEnum::Three, L"123", L"" }, - { NumbersAndOperatorsEnum::Four, L"1,234", L"" }, - { NumbersAndOperatorsEnum::Five, L"12,345", L"" }, - { NumbersAndOperatorsEnum::Six, L"123,456", L"" }, - { NumbersAndOperatorsEnum::Seven, L"1,234,567", L"" }, - { NumbersAndOperatorsEnum::Eight, L"12,345,678", L"" }, - { NumbersAndOperatorsEnum::Nine, L"123,456,789", L"" }, - { NumbersAndOperatorsEnum::None, L"1", L"" }, - }; - ValidateViewModelByCommands(m_viewModel, items, true); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->HexDisplayValue), StringReference(L"75B CD15")); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->DecimalDisplayValue), StringReference(L"123,456,789")); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->OctalDisplayValue), StringReference(L"726 746 425")); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->BinaryDisplayValue), StringReference(L"0111 0101 1011 1100 1101 0001 0101")); - } - - // Test Not functionality - TEST_METHOD(ProgrammerModeNot) - { - TESTITEM none[] = { - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, none, true); - m_viewModel->IsProgrammer = true; - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Not, L"-2", L"~(1)" }, - { NumbersAndOperatorsEnum::None, L"N/A", L"N/A" } - }; - ValidateViewModelByCommands(m_viewModel, items, false); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->HexDisplayValue), StringReference(L"FFFF FFFF FFFF FFFE")); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->DecimalDisplayValue), StringReference(L"-2")); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->OctalDisplayValue), StringReference(L"1 777 777 777 777 777 777 776")); - VERIFY_ARE_EQUAL(Utils::GetStringValue(m_viewModel->BinaryDisplayValue), StringReference(L"1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110")); - VERIFY_ARE_EQUAL(m_viewModel->DisplayValue, StringReference(L"-2")); - } - - // Test And Or functionality - TEST_METHOD(ProgrammerModeAndOr) - { - TESTITEM none[] = { - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, none, true); - m_viewModel->IsProgrammer = true; - - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Or, L"1", L"1 ||" }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 ||" }, - { NumbersAndOperatorsEnum::Equals, L"3", L"" }, - { NumbersAndOperatorsEnum::None, L"3", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, false); - - TESTITEM items2[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::And, L"1", L"1 &" }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 &" }, - { NumbersAndOperatorsEnum::Equals, L"0", L"" }, - { NumbersAndOperatorsEnum::None, L"0", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items2, false); - } - - // Test CE and C buttons functionality - TEST_METHOD(ProgrammerModeClear) - { - TESTITEM none[] = { - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, none, true); - m_viewModel->IsProgrammer = true; - - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Or, L"1", L"1 ||" }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 ||" }, - { NumbersAndOperatorsEnum::ClearEntry, L"0", L"1 ||" }, - { NumbersAndOperatorsEnum::None, L"", L"1 ||" } - }; - ValidateViewModelByCommands(m_viewModel, items, false); - - TESTITEM items2[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::And, L"1", L"1 &" }, - { NumbersAndOperatorsEnum::Two, L"2", L"1 &" }, - { NumbersAndOperatorsEnum::Clear, L"0", L"" }, - { NumbersAndOperatorsEnum::None, L"0", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items2, false); - } - - // Test unary operators - TEST_METHOD(ButtonPressedUnaryOperatorTest) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::IsStandardMode, L"0", L"" }, - { NumbersAndOperatorsEnum::Five, L"5", L"" }, - { NumbersAndOperatorsEnum::Invert, L"0" + std::wstring(m_decimalSeparator->Data()) + L"2", L"reciproc(5)" }, - { NumbersAndOperatorsEnum::Equals, L"0" + std::wstring(m_decimalSeparator->Data()) + L"2", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - - TESTITEM items2[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Six, L"16", L"" }, - { NumbersAndOperatorsEnum::Sqrt, L"4", L"sqrt(16)" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items2, false); - - TESTITEM items3[] = { - { NumbersAndOperatorsEnum::Six, L"6", L"" }, - { NumbersAndOperatorsEnum::Negate, L"-6", L"" }, - { NumbersAndOperatorsEnum::Nine, L"-69", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items3, false); - - TESTITEM items4[] = { - { NumbersAndOperatorsEnum::Clear, L"0", L"" }, - { NumbersAndOperatorsEnum::IsScientificMode, L"0", L"" }, - { NumbersAndOperatorsEnum::Five, L"5", L"" }, - { NumbersAndOperatorsEnum::InvSin, L"Invalid input", L"asind(5)" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items4, false); - - TESTITEM items5[] = { - { NumbersAndOperatorsEnum::Clear, L"0", L"" }, - { NumbersAndOperatorsEnum::Four, L"4", L"" }, - { NumbersAndOperatorsEnum::Factorial, L"24", L"fact(4)" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items5, false); - } - - // IsMemoryEmpty Property - TEST_METHOD(IsMemoryEmptyTest) - { - StandardCalculatorViewModel^ viewModel = ref new StandardCalculatorViewModel(); - viewModel->IsStandard = true; - VERIFY_ARE_EQUAL(static_cast(0), viewModel->MemorizedNumbers->Size); - viewModel->OnMemoryButtonPressed(); - VERIFY_ARE_EQUAL(static_cast(1), viewModel->MemorizedNumbers->Size); - viewModel->ClearMemoryCommand->Execute(nullptr); - VERIFY_ARE_EQUAL(static_cast(0), viewModel->MemorizedNumbers->Size); - } - - // IsOperatorCommand Property - TEST_METHOD(IsOperatorCommandTest) - { - StandardCalculatorViewModel^ viewModel = ref new StandardCalculatorViewModel(); - viewModel->IsStandard = true; - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::One); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Two); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Three); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Four); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Five); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Six); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Seven); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Eight); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Nine); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Decimal); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Zero); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Multiply); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, true); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Add); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, true); - viewModel->ButtonPressed->Execute(NumbersAndOperatorsEnum::Zero); - VERIFY_ARE_EQUAL(viewModel->IsOperatorCommand, false); - } - - //When memory button is pressed - verify if display value is being stored in vector - TEST_METHOD(OnMemoryButtonPressed) - { - StandardCalculatorViewModel^ viewModel = ref new StandardCalculatorViewModel(); - viewModel->IsStandard = true; - viewModel->DisplayValue = L"1001"; - viewModel->OnMemoryButtonPressed(); - viewModel->OnMemoryButtonPressed(); - VERIFY_ARE_EQUAL((int)viewModel->MemorizedNumbers->Size, 2); - } - - //when memory list is empty and M+ is pressed - TEST_METHOD(OnMemoryAddWhenMemoryEmpty) - { - m_viewModel->IsStandard = true; - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - m_viewModel->OnMemoryAdd(ref new Platform::Box(0)); - m_viewModel->OnMemoryItemPressed(ref new Platform::Box(0)); - VERIFY_ARE_EQUAL(Platform::StringReference(L"1,001"), m_viewModel->DisplayValue); - } - - - //when memory list is empty and M- is pressed - TEST_METHOD(OnMemorySubtractWhenMemoryEmpty) - { - m_viewModel->IsStandard = true; - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - m_viewModel->OnMemorySubtract(ref new Platform::Box(0)); - m_viewModel->OnMemoryItemPressed(ref new Platform::Box(0)); - VERIFY_ARE_EQUAL(Platform::StringReference(L"-1,001"), m_viewModel->DisplayValue); - } - - //when negative number is saved in memory - TEST_METHOD(OnNegativeEntryInMemory) - { - ChangeMode(m_viewModel, 0/*Standard*/); - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::Negate, L"N/A", L"N/A" }, - { NumbersAndOperatorsEnum::None, L"", L"" }, - }; - ValidateViewModelByCommands(m_viewModel, items, true); - m_viewModel->OnMemoryButtonPressed(); - m_viewModel->OnMemoryItemPressed(ref new Platform::Box(0)); - VERIFY_ARE_EQUAL(Platform::StringReference(L"-1,001"), m_viewModel->DisplayValue); - MemoryItemViewModel^ memorySlotStandard = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"-1,001"), Utils::GetStringValue(memorySlotStandard->Value)); - ChangeMode(m_viewModel, 1/*scientific*/); - MemoryItemViewModel^ memorySlotScientific = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"-1,001"), Utils::GetStringValue(memorySlotScientific->Value)); - ChangeMode(m_viewModel, 2/*Programmer*/); - MemoryItemViewModel^ memorySlotProgrammer = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"-1,001"), Utils::GetStringValue(memorySlotProgrammer->Value)); - } - - //when decimal number is saved in memory - TEST_METHOD(OnDecimalEntryInMemory) - { - ChangeMode(m_viewModel, 0/*Standard*/); - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::Decimal, L"1,001.", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001.1", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" }, - }; - ValidateViewModelByCommands(m_viewModel, items, true); - m_viewModel->OnMemoryButtonPressed(); - m_viewModel->OnMemoryItemPressed(ref new Platform::Box(0)); - VERIFY_ARE_EQUAL(Platform::StringReference(L"1,001.1"), m_viewModel->DisplayValue); - MemoryItemViewModel^ memorySlotStandard = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"1,001.1"), Utils::GetStringValue(memorySlotStandard->Value)); - ChangeMode(m_viewModel, 1/*Scientific*/); - MemoryItemViewModel^ memorySlotScientific = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"1,001.1"), Utils::GetStringValue(memorySlotScientific->Value)); - ChangeMode(m_viewModel, 2/*Programmer*/); - MemoryItemViewModel^ memorySlotProgrammer = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"1,001"), Utils::GetStringValue(memorySlotProgrammer->Value)); - } - - //when negative decimal number is saved in memory - TEST_METHOD(OnNegativeDecimalInMemory) - { - m_viewModel->IsStandard = true; - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::Decimal, L"1,001.", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001.1", L"" }, - { NumbersAndOperatorsEnum::Negate, L"N/A", L"N/A" }, - { NumbersAndOperatorsEnum::None, L"", L"" }, - }; - ValidateViewModelByCommands(m_viewModel, items, true); - m_viewModel->OnMemoryButtonPressed(); - m_viewModel->OnMemoryItemPressed(ref new Platform::Box(0)); - VERIFY_ARE_EQUAL(Platform::StringReference(L"-1,001.1"), m_viewModel->DisplayValue); - } - - //when decimal number is added to the memory - TEST_METHOD(OnDecimalAddedToMemory) - { - m_viewModel->IsStandard = true; - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::Decimal, L"1,001.", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001.1", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" }, - }; - ValidateViewModelByCommands(m_viewModel, items, true); - m_viewModel->OnMemoryButtonPressed(); - TESTITEM items2[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::Decimal, L"1,001.", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" }, - }; - ValidateViewModelByCommands(m_viewModel, items2, false); - m_viewModel->OnMemoryButtonPressed(); - m_viewModel->OnMemoryAdd(1); - m_viewModel->OnMemoryItemPressed(1); - VERIFY_ARE_EQUAL(Platform::StringReference(L"2,002.1"), m_viewModel->DisplayValue); - } - - //when memory is saved in programmer as Hex value and then we switch to standard mode, test to see that memory gets converted to decimal - TEST_METHOD(OnMemorySavedInHexRadixAndSwitchedToStandardMode) - { - ChangeMode(m_viewModel, 2/*programmer*/); - TESTITEM items[] = { - { NumbersAndOperatorsEnum::HexButton, L"0", L"" }, - { NumbersAndOperatorsEnum::F, L"F", L"" }, - { NumbersAndOperatorsEnum::F, L"FF", L"" }, - { NumbersAndOperatorsEnum::None, L"FF", L"" }, - }; - ValidateViewModelByCommands(m_viewModel, items, true); - m_viewModel->OnMemoryButtonPressed(); - ChangeMode(m_viewModel, 1/*Scientific*/); - m_viewModel->OnMemoryItemPressed(ref new Box(0)); - VERIFY_ARE_EQUAL(Platform::StringReference(L"255"), m_viewModel->DisplayValue); - MemoryItemViewModel^ memorySlot = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"255"), Utils::GetStringValue(memorySlot->Value)); - } - - - TEST_METHOD(OnMemorySavedInHexRadixAndRadixChanges) - { - ChangeMode(m_viewModel, 2/*programmer*/); - TESTITEM items[] = { - { NumbersAndOperatorsEnum::HexButton, L"0", L"" }, - { NumbersAndOperatorsEnum::F, L"F", L"" }, - { NumbersAndOperatorsEnum::F, L"FF", L"" }, - { NumbersAndOperatorsEnum::None, L"FF", L"" }, - }; - ValidateViewModelByCommands(m_viewModel, items, true); - m_viewModel->OnMemoryButtonPressed(); - m_viewModel->SwitchProgrammerModeBase(RADIX_TYPE::OCT_RADIX); - MemoryItemViewModel^ memorySlotOct = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"377"), Utils::GetStringValue(memorySlotOct->Value)); - m_viewModel->SwitchProgrammerModeBase(RADIX_TYPE::DEC_RADIX); - MemoryItemViewModel^ memorySlotDec = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"255"), Utils::GetStringValue(memorySlotDec->Value)); - m_viewModel->SwitchProgrammerModeBase(RADIX_TYPE::BIN_RADIX); - MemoryItemViewModel^ memorySlotBin = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"1111 1111"), Utils::GetStringValue(memorySlotBin->Value)); - - } - - //When memory button is pressed more than max number of slots allowed, - //the MemorizedNumbers vector size should not increase. - TEST_METHOD(OnMemoryButtonPressedMaxTimes) - { - StandardCalculatorViewModel^ viewModel = ref new StandardCalculatorViewModel(); - viewModel->IsStandard = true; - viewModel->DisplayValue = L"1001"; - for (int i = 0; i < 110; i++) - { - viewModel->OnMemoryButtonPressed(); - } - VERIFY_ARE_EQUAL((int)viewModel->MemorizedNumbers->Size, 100); - } - - // When memory slot is pressed verify if the display value is updated correctly - TEST_METHOD(OnMemoryItemPressed) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - - m_viewModel->OnMemoryButtonPressed(); - - TESTITEM items2[] = { - { NumbersAndOperatorsEnum::Two, L"2", L"" }, - { NumbersAndOperatorsEnum::Zero, L"20", L"" }, - { NumbersAndOperatorsEnum::Zero, L"200", L"" }, - { NumbersAndOperatorsEnum::Two, L"2,002", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items2, false); - - m_viewModel->OnMemoryButtonPressed(); - m_viewModel->OnMemoryItemPressed(1); - - VERIFY_ARE_EQUAL(Platform::StringReference(L"1,001"), m_viewModel->DisplayValue); - } - - // verify nothing happens if there is no memory and the memory slot pressed action is taken - TEST_METHOD(OnMemoryItemPressedNoMemory) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Two, L"12", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - - m_viewModel->OnMemoryItemPressed(ref new Platform::Box(0)); - - VERIFY_ARE_EQUAL(StringReference(L"12"), m_viewModel->DisplayValue); - VERIFY_ARE_EQUAL((UINT)0, m_viewModel->MemorizedNumbers->Size); - } - - // When memory slot is pressed verify if the display value is updated correctly - TEST_METHOD(OnMemoryItemAddAndSubtract) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - - m_viewModel->OnMemoryButtonPressed(); - - TESTITEM items2[] = { - { NumbersAndOperatorsEnum::Two, L"2", L"" }, - { NumbersAndOperatorsEnum::Zero, L"20", L"" }, - { NumbersAndOperatorsEnum::Zero, L"200", L"" }, - { NumbersAndOperatorsEnum::Two, L"2,002", L"" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items2, false); - - m_viewModel->OnMemoryButtonPressed(); - m_viewModel->OnMemoryItemPressed(1); - m_viewModel->OnMemoryAdd(ref new Platform::Box(0)); - MemoryItemViewModel^ memorySlot = (MemoryItemViewModel^)m_viewModel->MemorizedNumbers->GetAt(0); - VERIFY_ARE_EQUAL(Platform::StringReference(L"3,003"), Utils::GetStringValue(memorySlot->Value)); - } - - // Verify that raw, unformatted numbers are provided correctly - TEST_METHOD(VerifyRawFormatting) - { - m_viewModel->DisplayValue = L"1,001"; - VERIFY_ARE_EQUAL(StringReference(L"1001"), m_viewModel->GetRawDisplayValue()); - - m_viewModel->DisplayValue = L"999"; - VERIFY_ARE_EQUAL(StringReference(L"999"), m_viewModel->GetRawDisplayValue()); - - m_viewModel->DisplayValue = L"1,001,001"; - VERIFY_ARE_EQUAL(StringReference(L"1001001"), m_viewModel->GetRawDisplayValue()); - - m_viewModel->DisplayValue = L"1,001, 001"; - VERIFY_ARE_EQUAL(StringReference(L"1001001"), m_viewModel->GetRawDisplayValue()); - - } - - TEST_METHOD(VerifyAnnouncementAfterBinaryOperatorReceived) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::Multiply, L"1,001", L"1001 x" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - - VERIFY_ARE_EQUAL(StringReference(L"Display is 1,001 times"), m_viewModel->Announcement->Announcement); - } - - TEST_METHOD(VerifyAnnouncementAfterMultipleBinaryOperatorsReceived) - { - TESTITEM items[] = { - { NumbersAndOperatorsEnum::One, L"1", L"" }, - { NumbersAndOperatorsEnum::Zero, L"10", L"" }, - { NumbersAndOperatorsEnum::Zero, L"100", L"" }, - { NumbersAndOperatorsEnum::One, L"1,001", L"" }, - { NumbersAndOperatorsEnum::Multiply, L"1,001", L"1001 x" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items, true); - - VERIFY_ARE_EQUAL(StringReference(L"Display is 1,001 times"), m_viewModel->Announcement->Announcement); - - - TESTITEM items2[] = { - { NumbersAndOperatorsEnum::Divide, L"1,001", L"1001 ÷" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items2, false /*reset*/); - - VERIFY_ARE_EQUAL(StringReference(L"Display is 1,001 divided by"), m_viewModel->Announcement->Announcement); - - TESTITEM items3[] = { - { NumbersAndOperatorsEnum::Add, L"1,001", L"1001 +" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items3, false /*reset*/); - - VERIFY_ARE_EQUAL(StringReference(L"Display is 1,001 plus"), m_viewModel->Announcement->Announcement); - - - TESTITEM items4[] = { - { NumbersAndOperatorsEnum::Subtract, L"1,001", L"1001 x" }, - { NumbersAndOperatorsEnum::None, L"", L"" } - }; - ValidateViewModelByCommands(m_viewModel, items4, false /*reset*/); - - VERIFY_ARE_EQUAL(StringReference(L"Display is 1,001 minus"), m_viewModel->Announcement->Announcement); - } - - private: - StandardCalculatorViewModel^ m_viewModel; - std::shared_ptr m_engineResourceProvider; - Platform::String^ m_decimalSeparator; - }; -} - diff --git a/internal/CalculatorUnitTests/Test.resw b/internal/CalculatorUnitTests/Test.resw deleted file mode 100644 index 5cb77d9..0000000 --- a/internal/CalculatorUnitTests/Test.resw +++ /dev/null @@ -1,440 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - -4046.8564224 - -1 - -0.09290304 - -0.83612736 - -0.000001 - -0.0001 - -0.00064516 - -2589988.110336 - -1000000 - -10000 - -0.012516104 - -0.06032246 - -10869.66 - -100000 - -0.000000125 - -0.000001 - -0.001 - -1 - -1000 - -1000000 - -1000000000 - -1000000000000 - -1000000000000000 - -1000000000000000000 - -0.000125 - -0.125 - -125 - -125000 - -125000000 - -125000000000 - -125000000000000 - -125000000000000000 - -134.217728 - -1073.741824 - -0.000128 - -0.001024 - -0.131072 - -1.048576 - -140737488.355328 - -1125899906.842624 - -137438.953472 - -1099511.627776 - -144115188075.855872 - -1152921504606.846976 - -147573952589676.412928 - -1180591620717411.303424 - -151115727451828646.838272 - -1208925819614629174.706176 - -1.509949 - -734.003200 - -5046.586573 - -4.184 - -4184 - -1055.056 - -1000 - -0.0000000000000000001602176565 - -1 - -1.3558179483314 - -9000 - -439614 - -1046700 - -0.0254 - -0.3048 - -0.9144 - -1609.344 - -0.000001 - -0.001 - -0.000000001 - -0.01 - -1 - -1000 - -1852 - -0.035052 - -0.18669 - -76 - -17.58426666666667 - -0.0225969658055233 - -1 - -1000 - -745.69987158227022 - -60 - -745.7 - -2982799.486329081 - -86400 - -1 - -604800 - -31557600 - -0.001 - -0.000001 - -60 - -3600 - -236.588237 - -473.176473 - -568.26125 - -946.352946 - -1136.5225 - -3785.411784 - -4546.09 - -1000 - -4.928922 - -14.786765 - -1 - -764554.857984 - -1000000 - -1 - -16.387064 - -28316.846592 - -29.5735295625 - -28.4130625 - -5.91938802083333333333 - -17.7581640625 - -236.5882 - -378541.2 - -3750000000 - -1 - -0.1 - -0.01 - -0.001 - -0.45359237 - -0.028349523125 - -0.000001 - -0.00001 - -0.0001 - -1016.0469088 - -1000 - -6.35029318 - -0.0002 - -907.18474 - -0.000002 - -0.4325 - -4000 - -90000 - -1 - -30.48 - -27.777777777777777777778 - -51.44 - -34030 - -100 - -44.7 - -8.94 - -2011.5 - -24585 - -1 - -57.29577951308233 - -0.9 - -1 - -0.9869232667160128 - -0.0098692326671601 - -0.0013155687145324 - -9.869232667160128e-6 - -0.068045961016531 - - 0.002 - - - 1 - - - 1 - - - 1000 - - - 1 - - - 0.003 - - \ No newline at end of file diff --git a/internal/CalculatorUnitTests/UnitConverterTest.cpp b/internal/CalculatorUnitTests/UnitConverterTest.cpp deleted file mode 100644 index 8c002d6..0000000 --- a/internal/CalculatorUnitTests/UnitConverterTest.cpp +++ /dev/null @@ -1,600 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" - -#include - -using namespace UnitConversionManager; -using namespace std; - -namespace UnitConverterUnitTests -{ - - void SetUnitParams(Unit* type, int id, wstring name, wstring abbreviation, bool conversionSource, bool conversionTarget, bool isWhimsical) - { - type->id = id; - type->name = name; - type->abbreviation = abbreviation; - type->isConversionSource = conversionSource; - type->isConversionTarget = conversionTarget; - type->isWhimsical = isWhimsical; - } - - void SetCategoryParams(Category* type, int id, wstring name, bool supportsNegative) - { - type->id = id; - type->name = name; - type->supportsNegative = supportsNegative; - } - - void SetConversionDataParams(ConversionData* type, double ratio, double offset, bool offsetFirst) - { - type->ratio = ratio; - type->offset = offset; - type->offsetFirst = offsetFirst; - } - - class TestUnitConverterConfigLoader : public IConverterDataLoader - { - public: - TestUnitConverterConfigLoader() : - m_loadDataCallCount(0) - { - Category c1, c2; - SetCategoryParams(&c1, 1, L"Length", true); - SetCategoryParams(&c2, 2, L"Weight", false); - m_categories.push_back(c1); - m_categories.push_back(c2); - - Unit u1, u2, u3, u4; - SetUnitParams(&u1, 1, L"Inches", L"In", true, true, false); - SetUnitParams(&u2, 2, L"Feet", L"Ft", false, false, false); - SetUnitParams(&u3, 3, L"Pounds", L"Lb", true, true, false); - SetUnitParams(&u4, 4, L"Kilograms", L"Kg", false, false, false); - - vector c1units = vector(); - vector c2units = vector(); - c1units.push_back(u1); - c1units.push_back(u2); - c2units.push_back(u3); - c2units.push_back(u4); - - m_units[c1] = c1units; - m_units[c2] = c2units; - - unordered_map unit1Map = unordered_map(); - unordered_map unit2Map = unordered_map(); - unordered_map unit3Map = unordered_map(); - unordered_map unit4Map = unordered_map(); - - ConversionData conversion1, conversion2, conversion3, conversion4, conversion5; - SetConversionDataParams(&conversion1, 1.0, 0, false); - SetConversionDataParams(&conversion2, 0.08333333333333333333333333333333, 0, false); - SetConversionDataParams(&conversion3, 12.0, 0, false); - SetConversionDataParams(&conversion4, 0.453592, 0, false); - SetConversionDataParams(&conversion5, 2.20462, 0, false); - - //Setting the conversion ratios for testing - unit1Map[u1] = conversion1; - unit1Map[u2] = conversion2; - - unit2Map[u1] = conversion3; - unit2Map[u2] = conversion1; - - unit3Map[u3] = conversion1; - unit3Map[u4] = conversion4; - - unit4Map[u3] = conversion5; - unit4Map[u4] = conversion1; - - - m_ratioMaps[u1] = unit1Map; - m_ratioMaps[u2] = unit2Map; - m_ratioMaps[u3] = unit3Map; - m_ratioMaps[u4] = unit4Map; - } - - void LoadData() - { - m_loadDataCallCount++; - } - - vector LoadOrderedCategories() - { - return m_categories; - } - - vector LoadOrderedUnits(const Category& c) - { - return m_units[c]; - } - - unordered_map LoadOrderedRatios(const Unit& u) - { - return m_ratioMaps[u]; - } - - bool SupportsCategory(const Category& target) - { - return true; - } - - UINT m_loadDataCallCount; - private: - vector m_categories; - CategoryToUnitVectorMap m_units; - UnitToUnitToConversionDataMap m_ratioMaps; - }; - - class TestUnitConverterVMCallback : public IUnitConverterVMCallback - { - public: - void Reset() - { - m_maxDigitsReachedCallCount = 0; - } - - void DisplayCallback(const wstring& from, const wstring& to) override - { - m_lastFrom = from; - m_lastTo = to; - } - - void SuggestedValueCallback(const vector>& suggestedValues) override - { - m_lastSuggested = suggestedValues; - } - - void MaxDigitsReached() override - { - m_maxDigitsReachedCallCount++; - } - - int GetMaxDigitsReachedCallCount() - { - return m_maxDigitsReachedCallCount; - } - - bool CheckDisplayValues(wstring from, wstring to) - { - return (from == m_lastFrom && to == m_lastTo); - } - - bool CheckSuggestedValues(vector> suggested) - { - if (suggested.size() != m_lastSuggested.size()) - { - return false; - } - bool returnValue = true; - for (unsigned int i = 0; i < suggested.size(); i++) - { - if (suggested[i] != m_lastSuggested[i]) - { - returnValue = false; - break; - } - } - return returnValue; - } - private: - wstring m_lastFrom; - wstring m_lastTo; - vector> m_lastSuggested; - int m_maxDigitsReachedCallCount = 0; - }; - - class UnitConverterTest - { - public: - // Declare this class as a TestClass, and supply metadata if necessary. - TEST_CLASS(UnitConverterTest); - TEST_CLASS_SETUP(CommonSetup); - - TEST_METHOD_CLEANUP(Cleanup); - - TEST_METHOD(UnitConverterTestInit); - TEST_METHOD(UnitConverterTestBasic); - TEST_METHOD(UnitConverterTestGetters); - TEST_METHOD(UnitConverterTestGetCategory); - TEST_METHOD(UnitConverterTestUnitTypeSwitching); - TEST_METHOD(UnitConverterTestSerialization); - TEST_METHOD(UnitConverterTestDeSerialization); - TEST_METHOD(UnitConverterTestQuote); - TEST_METHOD(UnitConverterTestUnquote); - TEST_METHOD(UnitConverterTestBackspace); - TEST_METHOD(UnitConverterTestScientificInputs); - TEST_METHOD(UnitConverterTestSupplementaryResultRounding); - TEST_METHOD(UnitConverterTestMaxDigitsReached); - TEST_METHOD(UnitConverterTestMaxDigitsReached_LeadingDecimal); - TEST_METHOD(UnitConverterTestMaxDigitsReached_TrailingDecimal); - TEST_METHOD(UnitConverterTestMaxDigitsReached_MultipleTimes); - private: - static void ExecuteCommands(vector commands); - - static shared_ptr s_unitConverter; - static shared_ptr s_xmlLoader; - static shared_ptr s_testVMCallback; - static Category s_testLength; - static Category s_testWeight; - static Unit s_testInches; - static Unit s_testFeet; - static Unit s_testPounds; - static Unit s_testKilograms; - }; - - shared_ptr UnitConverterTest::s_unitConverter; - shared_ptr UnitConverterTest::s_xmlLoader; - shared_ptr UnitConverterTest::s_testVMCallback; - Category UnitConverterTest::s_testLength; - Category UnitConverterTest::s_testWeight; - Unit UnitConverterTest::s_testInches; - Unit UnitConverterTest::s_testFeet; - Unit UnitConverterTest::s_testPounds; - Unit UnitConverterTest::s_testKilograms; - - // Creates instance of UnitConverter before running tests - bool UnitConverterTest::CommonSetup() - { - s_testVMCallback = make_shared(); - s_xmlLoader = make_shared(); - s_unitConverter = make_shared(s_xmlLoader); - s_unitConverter->SetViewModelCallback(s_testVMCallback); - SetCategoryParams(&s_testLength, 1, L"Length", true); - SetCategoryParams(&s_testWeight, 2, L"Weight", false); - SetUnitParams(&s_testInches, 1, L"Inches", L"In", true, true, false); - SetUnitParams(&s_testFeet, 2, L"Feet", L"Ft", false, false, false); - SetUnitParams(&s_testPounds, 3, L"Pounds", L"Lb", true, true, false); - SetUnitParams(&s_testKilograms, 4, L"Kilograms", L"Kg", false, false, false); - return true; - } - - // Resets calculator state to start state after each test - bool UnitConverterTest::Cleanup() - { - s_unitConverter->DeSerialize(wstring()); - s_testVMCallback->Reset(); - return true; - } - - void UnitConverterTest::ExecuteCommands(vector commands) - { - for (size_t i = 0; i < commands.size() && commands[i] != Command::None; i++) - { - s_unitConverter->SendCommand(commands[i]); - } - } - - // Test ctor/initialization states - void UnitConverterTest::UnitConverterTestInit() - { - 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 a basic input command stream.'3', '2', '.', '0' - void UnitConverterTest::UnitConverterTestBasic() - { - tuple test1[] = {tuple(wstring(L"0.25"), s_testFeet)}; - tuple test2[] = {tuple(wstring(L"2.5"), s_testFeet)}; - - s_unitConverter->SendCommand(Command::Three); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"3"), wstring(L"3"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test1),end(test1)))); - s_unitConverter->SendCommand(Command::Zero); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"30"), wstring(L"30"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test2),end(test2)))); - s_unitConverter->SendCommand(Command::Decimal); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"30."), wstring(L"30"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test2),end(test2)))); - s_unitConverter->SendCommand(Command::Zero); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"30.0"), wstring(L"30"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test2),end(test2)))); - } - - // Check the getter functions - void UnitConverterTest::UnitConverterTestGetters() - { - Category test1[] = {s_testLength, s_testWeight}; - Unit test2[] = {s_testInches, s_testFeet}; - - VERIFY_IS_TRUE(s_unitConverter->GetCategories() == vector(begin(test1),end(test1))); - VERIFY_IS_TRUE(get<0>(s_unitConverter->SetCurrentCategory(test1[0])) == vector(begin(test2),end(test2))); - } - - // Test getting category after it has been set. - void UnitConverterTest::UnitConverterTestGetCategory() - { - s_unitConverter->SetCurrentCategory(s_testWeight); - VERIFY_IS_TRUE(s_unitConverter->GetCurrentCategory() == s_testWeight); - } - - // Test switching of unit types - void UnitConverterTest::UnitConverterTestUnitTypeSwitching() - { - // Enter 57 into the from field, then switch focus to the to field (making it the new from field) - s_unitConverter->SendCommand(Command::Five); - s_unitConverter->SendCommand(Command::Seven); - s_unitConverter->SwitchActive(wstring(L"57")); - // Now set unit conversion to go from kilograms to pounds - s_unitConverter->SetCurrentCategory(s_testWeight); - s_unitConverter->SetCurrentUnitTypes(s_testKilograms, s_testPounds); - s_unitConverter->SendCommand(Command::Five); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"5"), wstring(L"11.0231"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>())); - } - - // 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() - { - wstring input1 = L"Weight"; - wstring output1 = L"Weight"; - wstring input2 = L"{p}Weig;[ht|"; - wstring output2 = L"{lb}p{rb}Weig{sc}{lc}ht{p}"; - wstring input3 = L"{{{t;s}}},:]"; - wstring output3 = L"{lb}{lb}{lb}t{sc}s{rb}{rb}{rb}{cm}{co}{rc}"; - VERIFY_IS_TRUE(UnitConverter::Quote(input1) == output1); - VERIFY_IS_TRUE(UnitConverter::Quote(input2) == output2); - VERIFY_IS_TRUE(UnitConverter::Quote(input3) == output3); - } - - // Test output unescaping - void UnitConverterTest::UnitConverterTestUnquote() - { - wstring input1 = L"Weight"; - wstring input2 = L"{p}Weig;[ht|"; - wstring input3 = L"{{{t;s}}},:]"; - VERIFY_IS_TRUE(UnitConverter::Unquote(input1) == input1); - VERIFY_IS_TRUE(UnitConverter::Unquote(UnitConverter::Quote(input1)) == input1); - VERIFY_IS_TRUE(UnitConverter::Unquote(UnitConverter::Quote(input2)) == input2); - 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>())); - } - - // Test backspace commands - void UnitConverterTest::UnitConverterTestBackspace() - { - tuple test1[] = {tuple(wstring(L"13.66"), s_testKilograms)}; - tuple test2[] = {tuple(wstring(L"13.65"), s_testKilograms)}; - tuple test3[] = {tuple(wstring(L"13.61"), s_testKilograms)}; - tuple test4[] = {tuple(wstring(L"1.36"), s_testKilograms)}; - - s_unitConverter->SetCurrentCategory(s_testWeight); - s_unitConverter->SetCurrentUnitTypes(s_testPounds, s_testPounds); - s_unitConverter->SendCommand(Command::Three); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Decimal); - s_unitConverter->SendCommand(Command::One); - s_unitConverter->SendCommand(Command::Two); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"30.12"), wstring(L"30.12"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test1),end(test1)))); - s_unitConverter->SendCommand(Command::Backspace); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"30.1"), wstring(L"30.1"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test2),end(test2)))); - s_unitConverter->SendCommand(Command::Backspace); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"30."), wstring(L"30"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test3),end(test3)))); - s_unitConverter->SendCommand(Command::Backspace); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"30"), wstring(L"30"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test3),end(test3)))); - s_unitConverter->SendCommand(Command::Backspace); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"3"), wstring(L"3"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test4),end(test4)))); - s_unitConverter->SendCommand(Command::Backspace); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"0"), wstring(L"0"))); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>())); - } - - // Test large values - void UnitConverterTest::UnitConverterTestScientificInputs() - { - s_unitConverter->SetCurrentCategory(s_testWeight); - s_unitConverter->SetCurrentUnitTypes(s_testPounds, s_testKilograms); - s_unitConverter->SendCommand(Command::Decimal); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::Zero); - s_unitConverter->SendCommand(Command::One); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"0.00000000000001"), wstring(L"4.535920e-15"))); - s_unitConverter->SwitchActive(wstring(L"4.535920e-15")); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - s_unitConverter->SendCommand(Command::Nine); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"999999999999999"), wstring(L"2.204620e+15"))); - s_unitConverter->SwitchActive(wstring(L"2.20463e+15")); - s_unitConverter->SendCommand(Command::One); - s_unitConverter->SendCommand(Command::Two); - s_unitConverter->SendCommand(Command::Three); - s_unitConverter->SendCommand(Command::Four); - s_unitConverter->SendCommand(Command::Five); - s_unitConverter->SendCommand(Command::Six); - s_unitConverter->SendCommand(Command::Seven); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"1234567"), wstring(L"559989.7"))); - s_unitConverter->SwitchActive(wstring(L"559989.7")); - s_unitConverter->SendCommand(Command::One); - s_unitConverter->SendCommand(Command::Two); - s_unitConverter->SendCommand(Command::Three); - s_unitConverter->SendCommand(Command::Four); - s_unitConverter->SendCommand(Command::Five); - s_unitConverter->SendCommand(Command::Six); - s_unitConverter->SendCommand(Command::Seven); - s_unitConverter->SendCommand(Command::Eight); - VERIFY_IS_TRUE(s_testVMCallback->CheckDisplayValues(wstring(L"12345678"), wstring(L"27217528.63236"))); - } - - // Test large values - void UnitConverterTest::UnitConverterTestSupplementaryResultRounding() - { - tuple test1[] = {tuple(wstring(L"27.75"), s_testFeet)}; - tuple test2[] = {tuple(wstring(L"277.8"), s_testFeet)}; - tuple test3[] = {tuple(wstring(L"2778"), s_testFeet)}; - s_unitConverter->SendCommand(Command::Three); - s_unitConverter->SendCommand(Command::Three); - s_unitConverter->SendCommand(Command::Three); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test1),end(test1)))); - s_unitConverter->SendCommand(Command::Three); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test2),end(test2)))); - s_unitConverter->SendCommand(Command::Three); - VERIFY_IS_TRUE(s_testVMCallback->CheckSuggestedValues(vector>(begin(test3),end(test3)))); - } - - 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 - }); - - VERIFY_ARE_EQUAL(0, s_testVMCallback->GetMaxDigitsReachedCallCount()); - - ExecuteCommands({ Command::One }); - - VERIFY_ARE_EQUAL(1, s_testVMCallback->GetMaxDigitsReachedCallCount()); - } - - 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 - }); - - VERIFY_ARE_EQUAL(0, s_testVMCallback->GetMaxDigitsReachedCallCount()); - - ExecuteCommands({ Command::Two }); - - VERIFY_ARE_EQUAL(1, s_testVMCallback->GetMaxDigitsReachedCallCount()); - } - - 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 - }); - - VERIFY_ARE_EQUAL(0, s_testVMCallback->GetMaxDigitsReachedCallCount()); - - ExecuteCommands({ Command::One }); - - VERIFY_ARE_EQUAL(1, s_testVMCallback->GetMaxDigitsReachedCallCount()); - } - - 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 - }); - - VERIFY_ARE_EQUAL(0, s_testVMCallback->GetMaxDigitsReachedCallCount()); - - for (auto count = 1; count <= 10; count++) - { - ExecuteCommands({ Command::Three }); - - VERIFY_ARE_EQUAL(count, s_testVMCallback->GetMaxDigitsReachedCallCount(), to_wstring(count).c_str()); - } - } -} - diff --git a/internal/CalculatorUnitTests/UnitConverterViewModelUnitTests.cpp b/internal/CalculatorUnitTests/UnitConverterViewModelUnitTests.cpp deleted file mode 100644 index 7d4d18e..0000000 --- a/internal/CalculatorUnitTests/UnitConverterViewModelUnitTests.cpp +++ /dev/null @@ -1,1115 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include -#include "UnitConverterViewModelUnitTests.h" - -#include "CalcViewModel\UnitConverterViewModel.h" -#include "CalcViewModel\DataLoaders\UnitConverterDataLoader.h" - -using namespace CalculatorApp; -using namespace CalculatorApp::Common; -using namespace CalculatorApp::ViewModel; -using namespace Platform; -using namespace Platform::Collections; -using namespace std; -using namespace Utils; -using namespace Windows::ApplicationModel::Resources; -using namespace Windows::Foundation::Collections; -using namespace Windows::UI::Xaml; -using namespace Windows::UI::Xaml::Data; - -namespace UCM = UnitConversionManager; -namespace VM = CalculatorApp::ViewModel; -using namespace Windows::Globalization; - -namespace CalculatorUnitTests -{ - String^ AddUnicodeLTRMarkers(wstring str) - { - str.insert(str.begin(), L'\u202a'); - str.push_back(L'\u202c'); - return ref new String(str.c_str()); - } - - class CategoryViewModelTests - { - public: - TEST_CLASS(CategoryViewModelTests); - - // Test all binding values: - - TEST_METHOD(TestGetNameReturnsCorrectName) - { - wstring name = L"TestName"; - UCM::Category cat; - cat.name = name; - VM::Category^ vmcat = ref new VM::Category(cat); - VERIFY_ARE_EQUAL(vmcat->Name->Data(), name); - } - - TEST_METHOD(TestGetVisibilityReturnsVisible) - { - UCM::Category cat; - cat.supportsNegative = true; - VM::Category^ vmcat = ref new VM::Category(cat); - VERIFY_IS_TRUE(Visibility::Visible == vmcat->NegateVisibility); - } - - TEST_METHOD(TestGetVisibilityReturnsCollapsed) - { - UCM::Category cat; - cat.supportsNegative = false; - VM::Category^ vmcat = ref new VM::Category(cat); - VERIFY_IS_TRUE(Visibility::Collapsed == vmcat->NegateVisibility); - } - }; - - class UnitViewModelTests - { - public: - TEST_CLASS(UnitViewModelTests); - - // Test all binding values: - - TEST_METHOD(TestGetNameReturnsCorrectName) - { - wstring name = L"TestName"; - UCM::Unit unit; - unit.name = name; - VM::Unit^ vmunit = ref new VM::Unit(unit); - VERIFY_ARE_EQUAL(vmunit->Name->Data(), name); - } - - TEST_METHOD(TestGetAbbreviationReturnsCorrectAbbreviation) - { - wstring abbr = L"TestName"; - UCM::Unit unit; - unit.abbreviation = abbr; - VM::Unit^ vmunit = ref new VM::Unit(unit); - VERIFY_ARE_EQUAL(vmunit->Abbreviation->Data(), abbr); - } - }; - - class SupplementaryResultsViewModelTests - { - public: - TEST_CLASS(SupplementaryResultsViewModelTests); - - // Test all binding values: - - TEST_METHOD(TestGetValueReturnsCorrectValue) - { - wstring value = L"TestName"; - UCM::Unit unit = { 1, L"", L"", false, false, false }; - VM::Unit^ vmunit = ref new VM::Unit(unit); - VM::SupplementaryResult^ vmsupp = ref new VM::SupplementaryResult(ref new String(value.c_str()), vmunit); - VERIFY_ARE_EQUAL(vmsupp->Value->Data(), value); - } - - TEST_METHOD(TestGetUnitNameReturnsCorrectValue) - { - wstring name = L"TestName"; - UCM::Unit unit = { 1, name, L"", false, false, false }; - unit.name = name; - VM::Unit^ vmunit = ref new VM::Unit(unit); - VM::SupplementaryResult^ vmsupp = ref new VM::SupplementaryResult(L"", vmunit); - VERIFY_ARE_EQUAL(vmsupp->Unit->Name->Data(), name); - } - - TEST_METHOD(TestGetIsWhimsicalReturnsCorrectValue) - { - UCM::Unit unit = { 1, L"", L"", false, false, false }; - UCM::Unit unitW = { 2, L"", L"", false, false, true }; - VM::Unit^ vmUnit = ref new VM::Unit(unit); - VM::Unit^ vmUnitW = ref new VM::Unit(unitW); - VM::SupplementaryResult^ vmsupp = ref new VM::SupplementaryResult(L"", vmUnit); - VM::SupplementaryResult^ vmsuppW = ref new VM::SupplementaryResult(L"", vmUnitW); - VERIFY_IS_FALSE(vmsupp->IsWhimsical()); - VERIFY_IS_TRUE(vmsuppW->IsWhimsical()); - } - }; - - UnitConverterMock::UnitConverterMock() : - m_initCallCount(0), - m_getCategoriesCallCount(0), - m_setCurrentCategoryCallCount(0), - m_setCurUnitTypesCallCount(0), - m_switchActiveCallCount(0), - m_sendCommandCallCount(0), - m_setVMCallbackCallCount(0), - m_serializeCallCount(0), - m_deSerializeCallCount(0) - { } - - // IUnitConverter - - void UnitConverterMock::Initialize() - { - m_initCallCount++; - } - - vector UnitConverterMock::GetCategories() - { - m_getCategoriesCallCount++; - - vector cats; - cats.push_back(CAT1); - cats.push_back(CAT2); - cats.push_back(CAT3); - - m_curCategory = CAT2; - - return cats; - } - - UCM::CategorySelectionInitializer UnitConverterMock::SetCurrentCategory(const UCM::Category& input) - { - m_setCurrentCategoryCallCount++; - m_curCategory = input; - vector units; - switch (input.id) - { - case 1: - { - units.push_back(UNIT1); - units.push_back(UNIT2); - units.push_back(UNIT3); - break; - } - case 2: - { - units.push_back(UNIT4); - units.push_back(UNIT5); - units.push_back(UNIT6); - break; - } - case 3: - { - units.push_back(UNIT7); - units.push_back(UNIT8); - units.push_back(UNIT9); - break; - } - default: - throw; - } - - for (const UCM::Unit& unit : units) - { - if (unit.isConversionSource) - { - m_curFrom = unit; - } - - if (unit.isConversionTarget) - { - m_curTo = unit; - } - } - - units.push_back(UNITWHIMSY); // needs to be filtered out - - return make_tuple(units, m_curFrom, m_curTo); - } - - UCM::Category UnitConverterMock::GetCurrentCategory() - { - return m_curCategory; - } - - void UnitConverterMock::SetCurrentUnitTypes(const UCM::Unit& fromType, const UCM::Unit& toType) - { - m_setCurUnitTypesCallCount++; - m_curFrom = fromType; - m_curTo = toType; - m_vmCallback->SuggestedValueCallback(m_suggestedList); - } - - void UnitConverterMock::SwitchActive(const std::wstring& newValue) - { - m_switchActiveCallCount++; - m_curValue = newValue; - } - - wstring UnitConverterMock::Serialize() - { - m_serializeCallCount++; - return wstring(L""); - } - - void UnitConverterMock::DeSerialize(const wstring& serializedData) - { - m_deSerializeCallCount++; - } - - std::wstring UnitConverterMock::SaveUserPreferences() - { - return L"TEST"; - }; - - void UnitConverterMock::RestoreUserPreferences(_In_ const std::wstring& userPreferences) - { - }; - - void UnitConverterMock::SendCommand(UCM::Command command) - { - m_sendCommandCallCount++; - m_lastCommand = command; - - m_vmCallback->SuggestedValueCallback(m_suggestedList); - } - - void UnitConverterMock::SetViewModelCallback(const shared_ptr& newCallback) - { - m_setVMCallbackCallCount++; - m_vmCallback = newCallback; - } - - ref class MockActivatable sealed : public VM::IActivatable - { - private: - bool m_active; - - public: - MockActivatable(bool active) : m_active(active) - { } - - virtual property bool IsActive - { - bool get() { return m_active; } - void set(bool value) { m_active = value; } - } - }; - - class UnitConverterDataLoaderTests - { - public: - TEST_CLASS(UnitConverterDataLoaderTests); - - TEST_METHOD(FuncUnitConverterAllUnitCombinations) - { - VM::UnitConverterViewModel^ vm = ref new UnitConverterViewModel(make_shared(make_shared(ref new GeographicRegion()), nullptr)); - IObservableVector^ categoryList = vm->Categories; - ResourceLoader^ m_resLoader = ResourceLoader::GetForViewIndependentUse("Test"); - double epsilon = 0.1; //Could be more precise like 0.001 except atm to pascal conversion - - for (unsigned int k = 0; k < categoryList->Size; k++) - { - vm->CurrentCategory = categoryList->GetAt(k); - IObservableVector^ unitList = vm->Units; - for (unsigned int i = 0; i < unitList->Size; i++) - { - vm->Unit1 = unitList->GetAt(i); - wstring unit1Name = vm->Unit1->Name->Data(); - for (unsigned int j = 0; j < unitList->Size; j++) - { - vm->Value2Active = true; - vm->Value1Active = false; - vm->Unit2 = unitList->GetAt(j); - wstring unit2Name = vm->Unit2->Name->Data(); - //change value2 as 1. - vm->ButtonPressed->Execute(NumbersAndOperatorsEnum::One); - String^ expectedResult = m_resLoader->GetString(ref new String((unit1Name + L"-" + unit2Name).c_str())); - - // if the corresponding conversion ratio is present in Test.resw file - if (expectedResult != nullptr) - { - wstring expResult = expectedResult->Data(); - - double expectedConversion = GetDoubleFromWstring(expResult); - double actualConversion = GetDoubleFromWstring(GetStringValue(vm->Value1)->Data()); - double diff = abs(expectedConversion - actualConversion); - - // assert for diff less than epsilonth fraction of expected conversion result - VERIFY_IS_LESS_THAN_OR_EQUAL(diff, epsilon*expectedConversion); - } - //clearing the value1 - vm->ButtonPressed->Execute(NumbersAndOperatorsEnum::Clear); - } - } - } - } - }; - - class UnitConverterViewModelTests - { - public: - TEST_CLASS(UnitConverterViewModelTests); - - // Test that the ctor makes value1 active and value2 passive - TEST_METHOD(TestUnitConverterCtorSetsUpCorrectActiveValue) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - VERIFY_IS_TRUE(vm.Value1Active); - VERIFY_IS_FALSE(vm.Value2Active); - } - - // Test that we've created all the vectors on init. - TEST_METHOD(TestUnitConverterCtorSetsUpVectors) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - VERIFY_IS_NOT_NULL(vm.Categories); - VERIFY_IS_NOT_NULL(vm.Units); - VERIFY_IS_NOT_NULL(vm.SupplementaryResults); - } - - // Test that we've set up all the display callbacks on init. - TEST_METHOD(TestUnitConverterLoadSetsUpCallbacks) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - VERIFY_ARE_EQUAL((UINT)1, mock->m_setVMCallbackCallCount); - } - - // Test that we've set up all categories on load and that the first - // category is selected. - TEST_METHOD(TestUnitConverterLoadSetsUpCategories) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - IObservableVector^ cats = vm.Categories; - VERIFY_ARE_EQUAL((UINT)1, mock->m_getCategoriesCallCount); - VERIFY_ARE_EQUAL((UINT)3, cats->Size); - // Verify that we match current category - VERIFY_IS_TRUE(CAT2 == vm.CurrentCategory->GetModelCategory()); - } - - // Test that we've set up all units on load and that the default - // units are selected. - TEST_METHOD(TestUnitConverterLoadSetsUpUnits) - { - shared_ptr mock = make_shared(); - - VM::UnitConverterViewModel vm(mock); - IObservableVector^ units = vm.Units; - VERIFY_ARE_EQUAL((UINT)1, mock->m_setCurrentCategoryCallCount); - VERIFY_ARE_EQUAL((UINT)3, units->Size); - VERIFY_IS_TRUE(UNIT4 == vm.Unit1->GetModelUnit()); - VERIFY_IS_TRUE(UNIT6 == vm.Unit2->GetModelUnit()); - VERIFY_ARE_EQUAL((UINT)1, mock->m_setCurUnitTypesCallCount); - VERIFY_IS_TRUE(mock->m_curFrom == UNIT4); - VERIFY_IS_TRUE(mock->m_curTo == UNIT6); - } - - // Test that changing units updates the current unit types - // in the model - TEST_METHOD(TestUnitSelectionChangeUpdatesModel) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - vm.Unit1 = vm.Units->GetAt(1); // Change from u4 to u5 - // count will be 2 here since it was already called once at init - VERIFY_ARE_EQUAL((UINT)2, mock->m_setCurUnitTypesCallCount); - VERIFY_IS_TRUE(UNIT5 == mock->m_curFrom); - VERIFY_IS_TRUE(UNIT6 == mock->m_curTo); - vm.Unit2 = vm.Units->GetAt(0); // Change from u3 to u1 - VERIFY_ARE_EQUAL((UINT)3, mock->m_setCurUnitTypesCallCount); - VERIFY_IS_TRUE(UNIT5 == mock->m_curFrom); - VERIFY_IS_TRUE(UNIT4 == mock->m_curTo); - } - - // Test that changing categories updates the unit list - TEST_METHOD(TestCategorySelectionChangeUpdatesUnits) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - vm.CurrentCategory = vm.Categories->GetAt(2); // Change from cat1 to cat3 - // counts will be 2 here since the first call should have happened during init - VERIFY_IS_GREATER_THAN_OR_EQUAL(2u, mock->m_setCurrentCategoryCallCount); - VERIFY_ARE_EQUAL((UINT)3, vm.Units->Size); - VERIFY_IS_TRUE(UNIT7 == vm.Units->GetAt(0)->GetModelUnit()); - VERIFY_IS_TRUE(UNIT8 == vm.Units->GetAt(1)->GetModelUnit()); - VERIFY_IS_TRUE(UNIT9 == vm.Units->GetAt(2)->GetModelUnit()); - } - - // Test that changing categories updates the current unit types - // in the model - TEST_METHOD(TestCategorySelectionChangeUpdatesModel) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - vm.CurrentCategory = vm.Categories->GetAt(2); // Change from cat1 to cat3 - // counts will be 2 here since the first call should have happened during init - VERIFY_IS_GREATER_THAN_OR_EQUAL(2u, mock->m_setCurrentCategoryCallCount); - VERIFY_IS_TRUE(UNIT9 == vm.Unit1->GetModelUnit()); - VERIFY_IS_TRUE(UNIT7 == vm.Unit2->GetModelUnit()); - VERIFY_IS_GREATER_THAN_OR_EQUAL(2u, mock->m_setCurUnitTypesCallCount); - VERIFY_IS_TRUE(UNIT9 == mock->m_curFrom); - VERIFY_IS_TRUE(UNIT7 == mock->m_curTo); - } - - // Test that the displaycallback updates the display values - TEST_METHOD(TestDisplayCallbackUpdatesDisplayValues) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1234", *vTo = L"56.78"; - vm.UpdateDisplay(vFrom, vTo); - VERIFY_IS_TRUE(vm.Value1 == AddUnicodeLTRMarkers(L"1,234")); - VERIFY_IS_TRUE(vm.Value2 == AddUnicodeLTRMarkers(vTo)); - } - - // Test that the calculator button command correctly fires - // commands to the model. - TEST_METHOD(TestButtonCommandFiresModelCommands) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - // Call count is being set to 1 because we send 'CE' command as the first call - UINT callCount = 1; - - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Zero); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Zero == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::One); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::One == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Two); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Two == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Three); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Three == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Four); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Four == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Five); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Five == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Six); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Six == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Seven); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Seven == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Eight); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Eight == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Nine); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Nine == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Decimal); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Decimal == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Negate); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Negate == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Backspace); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Backspace == mock->m_lastCommand); - vm.ButtonPressed->Execute(CalculatorApp::NumbersAndOperatorsEnum::Clear); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Clear == mock->m_lastCommand); - - for (NumbersAndOperatorsEnum button = NumbersAndOperatorsEnum::Add; button <= NumbersAndOperatorsEnum::None; button++) - { - if (button == NumbersAndOperatorsEnum::Decimal || - button == NumbersAndOperatorsEnum::Negate || - button == NumbersAndOperatorsEnum::Backspace) - { - continue; - } - vm.ButtonPressed->Execute(button); - VERIFY_ARE_EQUAL(++callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::None == mock->m_lastCommand); - } - } - - // Tests that when we fire the OnGotFocus, it activates the given control - TEST_METHOD(TestOnValueGotFocusActivatesControl) - { - //shared_ptr mock = make_shared(); - //VM::UnitConverterViewModel vm(mock); - //MockActivatable^ activatable = ref new MockActivatable(false); - //vm.OnValueGotFocus(AsActivatable(activatable)); - //VERIFY_IS_TRUE(activatable->IsActive); - //vm.OnValueGotFocus(AsActivatable(activatable)); // try again, starting with true - //VERIFY_IS_TRUE(activatable->IsActive); - } - - // Tests that when we select the currently active value, nothing - // happens - TEST_METHOD(TestReselectCurrentlyActiveValueDoesNothing) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - // Establish base condition - VERIFY_ARE_EQUAL((UINT)0, mock->m_switchActiveCallCount); - VERIFY_ARE_EQUAL((UINT)1, mock->m_sendCommandCallCount); - VERIFY_ARE_EQUAL((UINT)1, mock->m_setCurUnitTypesCallCount); - vm.Value1Active = true; - VERIFY_ARE_EQUAL((UINT)0, mock->m_switchActiveCallCount); - VERIFY_ARE_EQUAL((UINT)1, mock->m_sendCommandCallCount); - VERIFY_ARE_EQUAL((UINT)1, mock->m_setCurUnitTypesCallCount); - } - - // Tests that when we set switch the active value, it sets the oppsite value - // to inactive - TEST_METHOD(TestActivatingValueDeactivatesOther) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - vm.Value1Active = true; // base - VERIFY_IS_TRUE(vm.Value1Active); - VERIFY_IS_FALSE(vm.Value2Active); - vm.Value2Active = true; // change - VERIFY_IS_TRUE(vm.Value2Active); - VERIFY_IS_FALSE(vm.Value1Active); - vm.Value2Active = true; // setting it to true again doesnt change anything - VERIFY_IS_TRUE(vm.Value2Active); - VERIFY_IS_FALSE(vm.Value1Active); - vm.Value1Active = true; // back to 1 - VERIFY_IS_TRUE(vm.Value1Active); - VERIFY_IS_FALSE(vm.Value2Active); - } - - // Tests that when we switch the active value, the active value - // gets updated in the model - TEST_METHOD(TestSwitchActiveValueUpdatesActiveValueInModel) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.Value2Active = true; - VERIFY_ARE_EQUAL((UINT)1, mock->m_switchActiveCallCount); - VERIFY_ARE_EQUAL(0, mock->m_curValue.compare(vTo)); - } - - // Tests that the suggested visibility value gets updated correctly - TEST_METHOD(TestSuggestedVisibilityIsUpdated) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - VERIFY_IS_TRUE(Visibility::Collapsed == vm.SupplementaryVisibility); - vector> supp; - supp.push_back(tuple(L"1", UNIT1)); - vm.UpdateSupplementaryResults(supp); - WaitForSingleObjectEx(GetCurrentThread(), 1100, FALSE); - VERIFY_IS_TRUE(Visibility::Visible == vm.SupplementaryVisibility); - vm.UpdateSupplementaryResults(vector>()); - WaitForSingleObjectEx(GetCurrentThread(), 1100, FALSE); - VERIFY_IS_TRUE(Visibility::Collapsed == vm.SupplementaryVisibility); - } - - // Tests that when we switch the active field and get display - // updates, the correct values are being updated. - TEST_METHOD(TestDisplayValueUpdatesAfterSwitchingActiveUpdateTheRightDisplay) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.Value2Active = true; - const WCHAR * newvFrom = L"3", *newvTo = L"57"; - vm.UpdateDisplay(newvFrom, newvTo); - VERIFY_IS_TRUE(vm.Value2 == AddUnicodeLTRMarkers(newvFrom)); - VERIFY_IS_TRUE(vm.Value1 == AddUnicodeLTRMarkers(newvTo)); - } - - // Tests that when we switch the active field and get change units, - // the correct unit values are being passed. - TEST_METHOD(TestUnitChangeAfterSwitchingActiveUpdateUnitsCorrectly) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.Value2Active = true; - vm.Unit2 = vm.Units->GetAt(0); - VERIFY_IS_TRUE(UNIT4 == mock->m_curFrom); - vm.Unit1 = vm.Units->GetAt(2); - VERIFY_IS_TRUE(UNIT6 == mock->m_curTo); - } - - // Test that if we switch categories and come back, our first - // and second units are still the same - TEST_METHOD(TestCategorySwitchAndBackKeepsUnitsUnchanged) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.CurrentCategory = vm.Categories->GetAt(2); - vm.CurrentCategory = vm.Categories->GetAt(0); - VERIFY_IS_TRUE(UNIT1 == vm.Unit1->GetModelUnit()); - VERIFY_IS_TRUE(UNIT2 == vm.Unit2->GetModelUnit()); - } - - // Test that if we switch categories and active, and then - // come back, our first and second units are swapped - // and second unit is active - TEST_METHOD(TestCategoryAndActiveSwitchAndBack) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.CurrentCategory = vm.Categories->GetAt(2); - vm.Value2Active = true; - vm.CurrentCategory = vm.Categories->GetAt(0); - VERIFY_IS_TRUE(UNIT2 == vm.Unit1->GetModelUnit()); - VERIFY_IS_TRUE(UNIT1 == vm.Unit2->GetModelUnit()); - VERIFY_IS_TRUE(vm.Value2Active); - } - - // Tests that when we switch the active field and then change - // category, the correct units are displayed. - TEST_METHOD(TestCategoryChangeAfterSwitchingActiveUpdatesDisplayCorrectly) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.Value2Active = true; - vm.CurrentCategory = vm.Categories->GetAt(2); - VERIFY_IS_TRUE(UNIT7 == vm.Unit1->GetModelUnit()); - VERIFY_IS_TRUE(UNIT9 == vm.Unit2->GetModelUnit()); - VERIFY_IS_TRUE(UNIT9 == mock->m_curFrom); - VERIFY_IS_TRUE(UNIT7 == mock->m_curTo); - VERIFY_ARE_EQUAL((UINT)1, mock->m_switchActiveCallCount); - const wchar_t * newvFrom = L"5", *newvTo = L"7"; - vm.UpdateDisplay(newvFrom, newvTo); - VERIFY_IS_TRUE(vm.Value2 == AddUnicodeLTRMarkers(newvFrom)); - VERIFY_IS_TRUE(vm.Value1 == AddUnicodeLTRMarkers(newvTo)); - } - - // Repeat above active switch tests but with a second switch to ensure - // transitions work both ways. - TEST_METHOD(TestSwitchAndReselectCurrentlyActiveValueDoesNothing) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.Value2Active = true; - // Establish base condition - VERIFY_ARE_EQUAL((UINT)1, mock->m_switchActiveCallCount); - VERIFY_ARE_EQUAL((UINT)1, mock->m_sendCommandCallCount); - VERIFY_ARE_EQUAL((UINT)1, mock->m_setCurUnitTypesCallCount); - vm.Value2Active = true; - VERIFY_ARE_EQUAL((UINT)1, mock->m_switchActiveCallCount); - VERIFY_ARE_EQUAL((UINT)1, mock->m_sendCommandCallCount); - VERIFY_ARE_EQUAL((UINT)1, mock->m_setCurUnitTypesCallCount); - } - - TEST_METHOD(TestSwitchActiveValueTwiceUpdatesActiveValueInModel) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.Value2Active = true; - vm.Value1Active = true; - VERIFY_ARE_EQUAL((UINT)2, mock->m_switchActiveCallCount); - VERIFY_ARE_EQUAL(0, mock->m_curValue.compare(vFrom)); - } - - TEST_METHOD(TestDisplayValueUpdatesAfterSwitchingActiveTwiceUpdateTheRightDisplay) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.Value2Active = true; - vm.Value1Active = true; - const WCHAR * newvFrom = L"3", *newvTo = L"57"; - vm.UpdateDisplay(newvFrom, newvTo); - VERIFY_IS_TRUE(vm.Value1 == AddUnicodeLTRMarkers(newvFrom)); - VERIFY_IS_TRUE(vm.Value2 == AddUnicodeLTRMarkers(newvTo)); - } - - TEST_METHOD(TestUnitChangeAfterSwitchingActiveTwiceUpdateUnitsCorrectly) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.Value2Active = true; - vm.Value1Active = true; - vm.Unit2 = vm.Units->GetAt(0); - VERIFY_IS_TRUE(UNIT4 == mock->m_curTo); - vm.Unit1 = vm.Units->GetAt(2); - VERIFY_IS_TRUE(UNIT6 == mock->m_curFrom); - } - - TEST_METHOD(TestCategoryChangeAfterSwitchingActiveTwiceUpdatesDisplayCorrectly) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"1", *vTo = L"234"; - vm.UpdateDisplay(vFrom, vTo); - vm.Value2Active = true; - vm.Value1Active = true; - vm.CurrentCategory = vm.Categories->GetAt(2); - VERIFY_IS_TRUE(UNIT9 == vm.Unit1->GetModelUnit()); - VERIFY_IS_TRUE(UNIT7 == vm.Unit2->GetModelUnit()); - VERIFY_IS_TRUE(UNIT9 == mock->m_curFrom); - VERIFY_IS_TRUE(UNIT7 == mock->m_curTo); - VERIFY_ARE_EQUAL((UINT)2, mock->m_switchActiveCallCount); - const wchar_t * newvFrom = L"5", *newvTo = L"7"; - vm.UpdateDisplay(newvFrom, newvTo); - VERIFY_IS_TRUE(vm.Value1 == AddUnicodeLTRMarkers(newvFrom)); - VERIFY_IS_TRUE(vm.Value2 == AddUnicodeLTRMarkers(newvTo)); - } - - // There is a 100 ms fudge time for the time based tests below - - // Test that UpdateSupplementaryResults updates the supplementary results - // after a delay - TEST_METHOD(TestSuggestedValuesCallbackUpdatesSupplementaryResults) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - vector> supp; - supp.push_back(tuple(L"1", UNIT1)); - supp.push_back(tuple(L"2", UNIT2)); - supp.push_back(tuple(L"3", UNIT3)); - vm.UpdateSupplementaryResults(supp); - VERIFY_ARE_EQUAL((UINT)0, vm.SupplementaryResults->Size); - WaitForSingleObjectEx(GetCurrentThread(), 200, FALSE); - // Now we should see it - VERIFY_ARE_EQUAL((UINT)3, vm.SupplementaryResults->Size); - VERIFY_IS_TRUE((AddUnicodeLTRMarkers(L"1")) == vm.SupplementaryResults->GetAt(0)->Value); - VERIFY_IS_TRUE(UNIT1 == vm.SupplementaryResults->GetAt(0)->Unit->GetModelUnit()); - VERIFY_IS_TRUE((AddUnicodeLTRMarkers(L"2")) == vm.SupplementaryResults->GetAt(1)->Value); - VERIFY_IS_TRUE(UNIT2 == vm.SupplementaryResults->GetAt(1)->Unit->GetModelUnit()); - VERIFY_IS_TRUE((AddUnicodeLTRMarkers(L"3")) == vm.SupplementaryResults->GetAt(2)->Value); - VERIFY_IS_TRUE(UNIT3 == vm.SupplementaryResults->GetAt(2)->Unit->GetModelUnit()); - } - - // Test that changing category immediately updates supplementary results - TEST_METHOD(TestCategoryChangeImmediatelyUpdatesSupplementaryResults) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - vector> supp; - supp.push_back(tuple(L"1", UNIT1)); - supp.push_back(tuple(L"2", UNIT2)); - supp.push_back(tuple(L"3", UNIT3)); - vm.UpdateSupplementaryResults(supp); - WaitForSingleObjectEx(GetCurrentThread(), 1100, FALSE); - VERIFY_ARE_EQUAL((UINT)3, vm.SupplementaryResults->Size); // Verify we're in the state we expect as a pre condition - - vm.CurrentCategory = vm.Categories->GetAt(2); - VERIFY_ARE_EQUAL((UINT)0, vm.SupplementaryResults->Size); - } - - // Test that changing category immediately updates supplementary results - TEST_METHOD(TestCategoryChangeImmediatelyUpdatesSupplementaryResultsWhimsy) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - vector> supp; - supp.push_back(tuple(L"1", UNIT1)); - supp.push_back(tuple(L"2", UNIT2)); - supp.push_back(tuple(L"3", UNIT3)); - supp.push_back(tuple(L"4", UNITWHIMSY)); - vm.UpdateSupplementaryResults(supp); - WaitForSingleObjectEx(GetCurrentThread(), 1100, FALSE); - VERIFY_ARE_EQUAL((UINT)4, vm.SupplementaryResults->Size); // Verify we're in the state we expect as a pre condition - - VERIFY_IS_TRUE(vm.SupplementaryResults->GetAt(3)->Unit->GetModelUnit().isWhimsical); - VERIFY_IS_FALSE(vm.SupplementaryResults->GetAt(0)->Unit->GetModelUnit().isWhimsical); - } - - // Test that changing units immediately updates supplementary results - TEST_METHOD(TestUnitChangeImmediatelyUpdatesSupplementaryResults) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - vector> supp; - supp.push_back(tuple(L"1", UNIT1)); - supp.push_back(tuple(L"2", UNIT2)); - supp.push_back(tuple(L"3", UNIT3)); - vm.UpdateSupplementaryResults(supp); - WaitForSingleObjectEx(GetCurrentThread(), 1100, FALSE); - VERIFY_ARE_EQUAL((UINT)3, vm.SupplementaryResults->Size); // Verify we're in the state we expect as a pre condition - - vm.Unit1 = vm.Units->GetAt(2); - VERIFY_ARE_EQUAL((UINT)0, vm.SupplementaryResults->Size); - - // Reset and try with other unit - vm.UpdateSupplementaryResults(supp); - WaitForSingleObjectEx(GetCurrentThread(), 1100, FALSE); - VERIFY_ARE_EQUAL((UINT)3, vm.SupplementaryResults->Size); // Verify we're in the state we expect as a pre condition - - vm.Unit2 = vm.Units->GetAt(0); - VERIFY_ARE_EQUAL((UINT)0, vm.SupplementaryResults->Size); - } - - // Test that only the first whimsical unit is selected and is appended - // to end of supplementary results. - TEST_METHOD(TestSupplementaryResultsWhimsicalUnits) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - UCM::Unit unit; - unit.isWhimsical = false; - - UCM::Unit unitWhimSubsequent; - unitWhimSubsequent.isWhimsical = true; - - vector> suggestedList; - suggestedList.push_back(tuple(L"", unit)); - suggestedList.push_back(tuple(L"", unit)); - suggestedList.push_back(tuple(L"", UNITWHIMSY)); - suggestedList.push_back(tuple(L"", unitWhimSubsequent)); - suggestedList.push_back(tuple(L"", unit)); - suggestedList.push_back(tuple(L"", unit)); - suggestedList.push_back(tuple(L"", unitWhimSubsequent)); - suggestedList.push_back(tuple(L"", unit)); - - vm.UpdateSupplementaryResults(suggestedList); - WaitForSingleObjectEx(GetCurrentThread(), 1100, FALSE); - VERIFY_ARE_EQUAL((UINT)6, vm.SupplementaryResults->Size); - while (vm.SupplementaryResults->Size > 1) - { - VERIFY_IS_FALSE(vm.SupplementaryResults->GetAt(0)->IsWhimsical()); - vm.SupplementaryResults->RemoveAt(0); - } - // Last item - VERIFY_IS_TRUE(vm.SupplementaryResults->GetAt(0)->Unit->GetModelUnit() == UNITWHIMSY); - } - - // Test deserialization - TEST_METHOD(TestUnitConverterViewModelDeserialization) - { - String ^ serializedTest = L"0[;;;]0[;;;]0[;;;]1[;;;]1.5[;;;]25[;;;]1.5[;;;]25[;;;][###][###]"; - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - vm.Deserialize(serializedTest); - VERIFY_IS_TRUE(vm.Value1 == L"1.5"); - VERIFY_IS_TRUE(vm.Value2 == L"25"); - VERIFY_IS_TRUE(vm.GetValueFromUnlocalized() == L"1.5"); - VERIFY_IS_TRUE(vm.GetValueToUnlocalized() == L"25"); - VERIFY_ARE_EQUAL(vm.Value1Active, false); - VERIFY_ARE_EQUAL(vm.Value2Active, true); - VERIFY_IS_TRUE(mock->m_deSerializeCallCount == 1); - } - - // Test serialization - /*TEST_METHOD(TestUnitConverterViewModelSerialization) - { - String ^ serializedTest = L"0[;;;]0[;;;]0[;;;]1[;;;];;;]1.5[;;;[;;;]25[###[;;;]0[;;;]0[;;;][###][###]"; - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - vm.Value1 = L";;;]1.5[;;;"; - vm.Value2 = L"25[###"; - vm.Value1Active = false; - vm.Value2Active = true; - String ^ test = vm.Serialize(); - VERIFY_IS_TRUE(serializedTest == test); - VERIFY_IS_TRUE(mock->m_serializeCallCount == 1); - }*/ - - TEST_METHOD(TestOnPaste) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - // Call count is being set to 1 because we send 'CE' command as the first call in OnPaste method of the ViewModel - UINT callCount = 1; - ViewMode mode = ViewMode::Volume; // Some temp mode for UnitConverter - - // Paste an invalid character - verify that call count doesn't increment - vm.OnPaste("z", mode); - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - - - // Test all valid characters. Verify that two commands are sent for each character - vm.OnPaste("0", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Zero == mock->m_lastCommand); - - vm.OnPaste("1", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::One == mock->m_lastCommand); - - vm.OnPaste("2", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Two == mock->m_lastCommand); - - vm.OnPaste("3", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Three == mock->m_lastCommand); - - vm.OnPaste("4", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Four == mock->m_lastCommand); - - vm.OnPaste("5", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Five == mock->m_lastCommand); - - vm.OnPaste("6", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Six == mock->m_lastCommand); - - vm.OnPaste("7", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Seven == mock->m_lastCommand); - - vm.OnPaste("8", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Eight == mock->m_lastCommand); - - vm.OnPaste("9", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Nine == mock->m_lastCommand); - - vm.OnPaste(".", mode); - callCount += 2; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - VERIFY_IS_TRUE(UCM::Command::Decimal == mock->m_lastCommand); - - vm.OnPaste("-", mode); - // Call count should increment by one (the Clear command) since negate isn't - // sent by itself, only after another legal character - ++callCount; - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - - // Send an invalid character - - vm.OnPaste("a", mode); - // Count should remain the same - VERIFY_ARE_EQUAL(callCount, mock->m_sendCommandCallCount); - // Last command should remain the same - VERIFY_IS_TRUE(UCM::Command::Clear == mock->m_lastCommand); - } - - TEST_METHOD(TestDecimalFormattingLogic) - { - // verify that a dangling decimal is left alone until the user switches active fields, and that trailing zeroes - // entered by the user remain in the display even after a switch. - - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - const WCHAR * vFrom = L"3.", *vTo = L"2.50"; - vm.UpdateDisplay(vFrom, vTo); - // Establish base condition - VERIFY_IS_TRUE(vm.Value1 == AddUnicodeLTRMarkers(L"3.")); - VERIFY_IS_TRUE(vm.Value2 == AddUnicodeLTRMarkers(L"2.50")); - vm.SwitchActive->Execute(nullptr); - VERIFY_IS_TRUE(vm.Value1 == AddUnicodeLTRMarkers(L"3")); // dangling decimal now removed - VERIFY_IS_TRUE(vm.Value2 == AddUnicodeLTRMarkers(L"2.50")); - vm.SwitchActive->Execute(nullptr); - VERIFY_IS_TRUE(vm.Value1 == AddUnicodeLTRMarkers(L"3")); - VERIFY_IS_TRUE(vm.Value2 == AddUnicodeLTRMarkers(L"2.50")); - } - // Tests that when we switch the active field and get display - // updates, the correct automation names are are being updated. - TEST_METHOD(TestValue1AndValue2AutomationNameChanges) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - vm.Value1 = L"1"; - vm.Unit1 = vm.Units->GetAt(1); - VERIFY_IS_TRUE(vm.Value1AutomationName == L"Convert from 1 UNIT5"); - VERIFY_IS_TRUE(vm.Value2AutomationName == L"Converts into 0 UNIT6"); - vm.Value2 = L"234"; - vm.Value2Active = true; - VERIFY_IS_TRUE(vm.Value2AutomationName == L"Convert from 234 UNIT6"); - VERIFY_IS_TRUE(vm.Value1AutomationName == L"Converts into 1 UNIT5"); - vm.Value2 = L"3"; - vm.Unit2 = vm.Units->GetAt(0); - VERIFY_IS_TRUE(vm.Value2AutomationName == L"Convert from 3 UNIT4"); - VERIFY_IS_TRUE(vm.Value1AutomationName == L"Converts into 1 UNIT5"); - vm.Value1Active = true; - VERIFY_IS_TRUE(vm.Value1AutomationName == L"Convert from 1 UNIT5"); - VERIFY_IS_TRUE(vm.Value2AutomationName == L"Converts into 3 UNIT4"); - } - - // Test that an invalid model unit list results in a Units list of size 1 - // containing EMPTY_UNIT. - TEST_METHOD(TestUnitsListBuildsFromEmptyModelUnitList) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - vm.BuildUnitList({}); - - VERIFY_ARE_EQUAL(1u, vm.Units->Size); - VERIFY_ARE_EQUAL((UCM::EMPTY_UNIT).id, (vm.Units->GetAt(0)->GetModelUnit()).id); - } - - // Test that a valid model unit list vuilds - TEST_METHOD(TestUnitsListBuildsFromValidModelUnitList) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - vm.BuildUnitList({ - UNIT1, - UNIT2, - UNIT3 - }); - - VERIFY_ARE_EQUAL(3u, vm.Units->Size); - VERIFY_ARE_EQUAL(UNIT1.id, (vm.Units->GetAt(0)->GetModelUnit()).id); - VERIFY_ARE_EQUAL(UNIT2.id, (vm.Units->GetAt(1)->GetModelUnit()).id); - VERIFY_ARE_EQUAL(UNIT3.id, (vm.Units->GetAt(2)->GetModelUnit()).id); - } - - TEST_METHOD(TestFindInListWhenListIsValid) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - vm.BuildUnitList({ - UNIT1, - UNIT2, - UNIT3 - }); - - Unit^ foundUnit = vm.FindUnitInList(UNIT1); - VERIFY_ARE_EQUAL(UNIT1.id, foundUnit->GetModelUnit().id); - } - - TEST_METHOD(TestFindInListWhenListIsInvalid) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - vm.BuildUnitList({}); - - Unit^ foundUnit = vm.FindUnitInList(UNIT1); - - VERIFY_ARE_EQUAL(UCM::EMPTY_UNIT.id, foundUnit->GetModelUnit().id); - } - - TEST_METHOD(TestSetSelectedUnits) - { - shared_ptr mock = make_shared(); - VM::UnitConverterViewModel vm(mock); - - vm.CurrentCategory = vm.Categories->GetAt(0); - - vm.SetSelectedUnits(); - VERIFY_ARE_NOT_EQUAL(UCM::EMPTY_UNIT.id, vm.Unit1->GetModelUnit().id); - VERIFY_ARE_NOT_EQUAL(UCM::EMPTY_UNIT.id, vm.Unit2->GetModelUnit().id); - } - }; -} - diff --git a/internal/CalculatorUnitTests/UnitConverterViewModelUnitTests.h b/internal/CalculatorUnitTests/UnitConverterViewModelUnitTests.h deleted file mode 100644 index 2585f75..0000000 --- a/internal/CalculatorUnitTests/UnitConverterViewModelUnitTests.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" - -namespace UCM = UnitConversionManager; - -#pragma once - -namespace CalculatorUnitTests -{ - static UCM::Unit UNIT1 = { 1, L"UNIT1", L"U1", true, false, false }; - static UCM::Unit UNIT2 = { 2, L"UNIT2", L"U2", false, true, false }; - static UCM::Unit UNIT3 = { 3, L"UNIT3", L"U3", false, false, false }; - static UCM::Unit UNIT4 = { 4, L"UNIT4", L"U4", true, false, false }; - static UCM::Unit UNIT5 = { 5, L"UNIT5", L"U5", false, false, false }; - static UCM::Unit UNIT6 = { 6, L"UNIT6", L"U6", false, true, false }; - static UCM::Unit UNIT7 = { 7, L"UNIT7", L"U7", false, true, false }; - static UCM::Unit UNIT8 = { 8, L"UNIT8", L"U8", false, false, false }; - 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 - - - class UnitConverterMock : public UnitConversionManager::IUnitConverter - { - public: - UnitConverterMock(); - void Initialize() override; - std::vector 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& newCallback) override; - void SetViewModelCurrencyCallback(_In_ const std::shared_ptr& newCallback) override {} - concurrency::task> RefreshCurrencyRatios() override - { - co_return std::make_pair(L"", 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; - - UCM::Category m_curCategory; - UCM::Unit m_curFrom; - UCM::Unit m_curTo; - UCM::Command m_lastCommand; - - std::shared_ptr m_vmCallback; - std::vector> m_suggestedList; - std::wstring m_curValue; - }; -} - diff --git a/internal/CalculatorUnitTests/UnitTestApp.rd.xml b/internal/CalculatorUnitTests/UnitTestApp.rd.xml deleted file mode 100644 index 74506cf..0000000 --- a/internal/CalculatorUnitTests/UnitTestApp.rd.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/internal/CalculatorUnitTests/UnitTestApp.xaml b/internal/CalculatorUnitTests/UnitTestApp.xaml deleted file mode 100644 index 54e3454..0000000 --- a/internal/CalculatorUnitTests/UnitTestApp.xaml +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/internal/CalculatorUnitTests/UnitTestApp.xaml.cpp b/internal/CalculatorUnitTests/UnitTestApp.xaml.cpp deleted file mode 100644 index 88cfcb1..0000000 --- a/internal/CalculatorUnitTests/UnitTestApp.xaml.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// -// App.xaml.cpp -// Implementation of the App class. -// - -#include "pch.h" -#include "UnitTestApp.xaml.h" - -using namespace CalculatorUnitTests; - -using namespace Platform; -using namespace Windows::ApplicationModel; -using namespace Windows::ApplicationModel::Activation; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -using namespace Windows::UI::Xaml; -using namespace Windows::UI::Xaml::Controls; -using namespace Windows::UI::Xaml::Controls::Primitives; -using namespace Windows::UI::Xaml::Data; -using namespace Windows::UI::Xaml::Input; -using namespace Windows::UI::Xaml::Interop; -using namespace Windows::UI::Xaml::Media; -using namespace Windows::UI::Xaml::Navigation; - -// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=402347&clcid=0x409 - -/// -/// Initializes the singleton application object. This is the first line of authored code -/// executed, and as such is the logical equivalent of main() or WinMain(). -/// -App::App() -{ - InitializeComponent(); - Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending); -} - -/// -/// Invoked when the application is launched normally by the end user. Other entry points -/// will be used such as when the application is launched to open a specific file. -/// -/// Details about the launch request and process. -void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) -{ - -#if _DEBUG - // Show graphics profiling information while debugging. - if (IsDebuggerPresent()) - { - // Display the current frame rate counters - DebugSettings->EnableFrameRateCounter = true; - } -#endif - - auto rootFrame = dynamic_cast(Window::Current->Content); - - // Do not repeat app initialization when the Window already has content, - // just ensure that the window is active - if (rootFrame == nullptr) - { - // Create a Frame to act as the navigation context and associate it with - // a SuspensionManager key - rootFrame = ref new Frame(); - - rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed); - - if (e->PreviousExecutionState == ApplicationExecutionState::Terminated) - { - // 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 - Window::Current->Content = rootFrame; - } - - Microsoft::VisualStudio::TestPlatform::TestExecutor::WinRTCore::UnitTestClient::CreateDefaultUI(); - - Window::Current->Activate(); - - Microsoft::VisualStudio::TestPlatform::TestExecutor::WinRTCore::UnitTestClient::Run(e->Arguments); -} - -/// -/// Invoked when application execution is being suspended. Application state is saved -/// without knowing whether the application will be terminated or resumed with the contents -/// of memory still intact. -/// -/// The source of the suspend request. -/// Details about the suspend request. -void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e) -{ - (void) sender; // Unused parameter - (void) e; // Unused parameter - - //TODO: Save application state and stop any background activity -} - -/// -/// Invoked when Navigation to a certain page fails -/// -/// The Frame which failed navigation -/// Details about the navigation failure -void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e) -{ - throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name); -} - diff --git a/internal/CalculatorUnitTests/UnitTestApp.xaml.h b/internal/CalculatorUnitTests/UnitTestApp.xaml.h deleted file mode 100644 index f514d6d..0000000 --- a/internal/CalculatorUnitTests/UnitTestApp.xaml.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// -// App.xaml.h -// Declaration of the App class. -// - -#pragma once - -#include "UnitTestApp.g.h" -#include "CalcViewModel\DateCalculatorViewModel.h" -#include "CalcViewModel\StandardCalculatorViewModel.h" -#include "CalcViewModel\UnitConverterViewModel.h" -#include "CalcViewModel\MemoryItemViewModel.h" - -namespace CalculatorUnitTests -{ - /// - /// Provides application-specific behavior to supplement the default Application class. - /// - ref class App sealed - { - protected: - virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override; - - internal: - App(); - - private: - void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e); - void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e); - }; -} - diff --git a/internal/CalculatorUnitTests/UtilsTests.cpp b/internal/CalculatorUnitTests/UtilsTests.cpp deleted file mode 100644 index 7b53a0c..0000000 --- a/internal/CalculatorUnitTests/UtilsTests.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include - -namespace CalculatorUnitTests -{ - class UtilsTests - { - public: - TEST_CLASS(UtilsTests); - - 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)); - } - }; -} diff --git a/internal/CalculatorUnitTests/packages.config b/internal/CalculatorUnitTests/packages.config deleted file mode 100644 index 6b2ab24..0000000 --- a/internal/CalculatorUnitTests/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/internal/CalculatorUnitTests/pch.cpp b/internal/CalculatorUnitTests/pch.cpp deleted file mode 100644 index 2297336..0000000 --- a/internal/CalculatorUnitTests/pch.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// -// pch.cpp -// Include the standard header and generate the precompiled header. -// - -#include "pch.h" - diff --git a/internal/CalculatorUnitTests/pch.h b/internal/CalculatorUnitTests/pch.h deleted file mode 100644 index fd760ad..0000000 --- a/internal/CalculatorUnitTests/pch.h +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// -// pch.h -// Header for standard system include files. -// - -#pragma once - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#define UNIT_TESTS - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// C++\WinRT Headers -#include "winrt\base.h" -#include "winrt\Windows.Foundation.Diagnostics.h" -#include "winrt\Windows.Globalization.h" -#include "winrt\Windows.Globalization.DateTimeFormatting.h" -#include "winrt\Windows.System.UserProfile.h" - -namespace CalculatorApp -{ - namespace WF = Windows::Foundation; - namespace WUC = Windows::UI::Core; - namespace WX = Windows::UI::Xaml; - namespace WXC = Windows::UI::Xaml::Controls; - namespace WXCP = Windows::UI::Xaml::Controls::Primitives; - namespace P = Platform; - namespace PC = Platform::Collections; - namespace WXI = Windows::UI::Xaml::Input; - namespace WFC = Windows::Foundation::Collections; - namespace WS = Windows::System; - namespace WAR = Windows::ApplicationModel::Resources; - namespace WXMA = Windows::UI::Xaml::Media::Animation; - namespace WXD = Windows::UI::Xaml::Data; - namespace WXInt = Windows::UI::Xaml::Interop; - namespace WXM = Windows::UI::Xaml::Markup; - namespace WXA = Windows::UI::Xaml::Automation; -} - -// The following namespaces exist as a convenience to resolve -// ambiguity for Windows types in the Windows::UI::Xaml::Automation::Peers -// namespace that only exist on RS3. -// 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 CustomPeers = CalculatorApp::Common::Automation; - -//CalcManager Headers -#include "CalcManager\CalculatorVector.h" -#include "CalcManager\ExpressionCommand.h" -#include "CalcManager\CalculatorResource.h" -#include "CalcManager\CalculatorManager.h" -#include "CalcManager\UnitConverter.h" - -// CalcViewModel Headers -#include "CalcViewModel\Common\DelegateCommand.h" -#include "CalcViewModel\Common\Utils.h" -#include "CalcViewModel\Common\MyVirtualKey.h" -#include "CalcViewModel\Common\NavCategory.h" -#include "CalcViewModel\Common\CalculatorButtonUser.h" -#include "CalcViewModel\Common\NetworkManager.h" - -#include "Mocks\CurrencyHttpClient.h" -#include "Helpers.h" - -#include "UnitTestApp.xaml.h" - -#define TEST_METHOD_IGNORE();\ - BEGIN_TEST_METHOD_PROPERTIES()\ - TEST_METHOD_PROPERTY(L"Ignore", L"true")\ - END_TEST_METHOD_PROPERTIES() - -#define VERIFY_THROWS_WINRT(__operation, __exception, ...) \ -{ \ - bool __exceptionHit = false; \ - try \ - { \ - __operation; \ - } \ - catch(__exception __e) \ - { \ - WEX::TestExecution::Private::MacroVerify::ExpectedExceptionThrown(__e, L#__exception, L#__operation, __VA_ARGS__); \ - __exceptionHit = true; \ - } \ - \ - if (!__exceptionHit) \ - { \ - WEX::TestExecution::Private::MacroVerify::ExpectedExceptionNotThrown(L#__exception, L#__operation, PRIVATE_VERIFY_ERROR_INFO, __VA_ARGS__); \ - } \ -} - - diff --git a/internal/CalculatorUnitTests/testmd.definition b/internal/CalculatorUnitTests/testmd.definition deleted file mode 100644 index d3ca47d..0000000 --- a/internal/CalculatorUnitTests/testmd.definition +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "http://universaltest/schema/testmddefinition-4.json", - "Package": { - "ComponentName": "Calculator", - "SubComponentName": "UnitTests" - }, - "SupportedArchitectures": [ "All" ], - "Execution": { - "Type": "TAEF", - "Parameter": "/APPX:CertificateFileName=CalculatorUnitTests.cer:TrustedPeople /screenCaptureOnError /TestMode:EnsureLoggedOnUser /TestMode:EtwLogger", - "ExecutionTimeoutInMinutes": "30" - }, - "Dependencies": { - "Files": [ - { - "SourcePath": "$(AppxPackagePublicKeyFile)", - "DestinationFolderPath": "$$(TEST_DEPLOY_BIN)" - }, - { - "SourcePath": "$(AppxPackageVCLibsDependency)", - "DestinationFolderPath": "$$(TEST_DEPLOY_BIN)" - } - ], - "Packages": [ - "Microsoft-Windows-Test-Taef", - "Microsoft-Windows-Test-EtwProcessor", - "Microsoft-Test-Taef-EnsureLoggedOnUserTestMode", - "Microsoft-Test-Taef-EtwLoggerTestMode" - ] - }, - "Logs": [], - "Plugins": [], - "Profiles": [] -} diff --git a/src/CalcManager/CEngine/History.cpp b/src/CalcManager/CEngine/History.cpp index 092b4d9..95347a5 100644 --- a/src/CalcManager/CEngine/History.cpp +++ b/src/CalcManager/CEngine/History.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include "pch.h" @@ -12,6 +12,7 @@ constexpr int ASCII_0 = 48; using namespace std; +using namespace CalcEngine; void CHistoryCollector::ReinitHistory() { @@ -51,7 +52,7 @@ CHistoryCollector::~CHistoryCollector() } } -void CHistoryCollector::AddOpndToHistory(wstring_view numStr, PRAT hNoNum, bool fRepetition) +void CHistoryCollector::AddOpndToHistory(wstring_view numStr, Rational const& rat, bool fRepetition) { std::shared_ptr> commands = std::make_shared>(); // Check for negate @@ -92,7 +93,7 @@ void CHistoryCollector::AddOpndToHistory(wstring_view numStr, PRAT hNoNum, bool } auto operandCommand = std::make_shared(commands, fNegative, fDecimal, fSciFmt); - operandCommand->Initialize(hNoNum); + operandCommand->Initialize(rat); int iCommandEnd = AddCommand(operandCommand); m_lastOpStartIndex = IchAddSzToEquationSz(numStr, iCommandEnd); diff --git a/src/CalcManager/CEngine/scicomm.cpp b/src/CalcManager/CEngine/scicomm.cpp index 354fb37..7dbbf02 100644 --- a/src/CalcManager/CEngine/scicomm.cpp +++ b/src/CalcManager/CEngine/scicomm.cpp @@ -211,9 +211,7 @@ void CCalcEngine::ProcessCommandWorker(WPARAM wParam) if (!m_HistoryCollector.FOpndAddedToHistory()) { // if the prev command was ) or unop then it is already in history as a opnd form (...) - PRAT curRat = m_currentVal.ToPRAT(); - m_HistoryCollector.AddOpndToHistory(m_numberString, curRat); - destroyrat(curRat); + m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); } /* m_bChangeOp is true if there was an operation done and the */ @@ -310,10 +308,7 @@ DoPrecedenceCheckAgain: { if (!m_HistoryCollector.FOpndAddedToHistory()) { - - PRAT curRat = m_currentVal.ToPRAT(); - m_HistoryCollector.AddOpndToHistory(m_numberString, curRat); - destroyrat(curRat); + m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); } m_HistoryCollector.AddUnaryOpToHistory((INT)wParam, m_bInv, m_angletype); @@ -339,9 +334,7 @@ DoPrecedenceCheckAgain: if(wParam == IDC_PERCENT) { CheckAndAddLastBinOpToHistory(); - PRAT curRat = m_currentVal.ToPRAT(); - m_HistoryCollector.AddOpndToHistory(m_numberString, curRat, true); - destroyrat(curRat); + m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal, true /* Add to primary and secondary display */); } /* reset the m_bInv flag and indicators if it is set @@ -464,9 +457,7 @@ DoPrecedenceCheckAgain: if (!m_HistoryCollector.FOpndAddedToHistory()) { - PRAT curRat = m_currentVal.ToPRAT(); - m_HistoryCollector.AddOpndToHistory(m_numberString, curRat); - destroyrat(curRat); + m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); } do { @@ -485,9 +476,7 @@ DoPrecedenceCheckAgain: m_currentVal = m_holdVal; DisplayNum(); // to update the m_numberString m_HistoryCollector.AddBinOpToHistory(m_nOpCode, false); - PRAT curRat = m_currentVal.ToPRAT(); - m_HistoryCollector.AddOpndToHistory(m_numberString, curRat); // Adding the repeated last op to history - destroyrat(curRat); + m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); // Adding the repeated last op to history } // Do the current or last operation. @@ -595,9 +584,7 @@ DoPrecedenceCheckAgain: if (!m_HistoryCollector.FOpndAddedToHistory()) { - PRAT curRat = m_currentVal.ToPRAT(); - m_HistoryCollector.AddOpndToHistory(m_numberString, curRat); - destroyrat(curRat); + m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); } // Get the operation and number and return result. @@ -701,9 +688,7 @@ DoPrecedenceCheckAgain: if (!m_HistoryCollector.FOpndAddedToHistory()) { - PRAT curRat = m_currentVal.ToPRAT(); - m_HistoryCollector.AddOpndToHistory(m_numberString, curRat); - destroyrat(curRat); + m_HistoryCollector.AddOpndToHistory(m_numberString, m_currentVal); } PRAT curRat = m_currentVal.ToPRAT(); diff --git a/src/CalcManager/CalcManager.vcxproj b/src/CalcManager/CalcManager.vcxproj index 02e5f8a..9a9ea38 100644 --- a/src/CalcManager/CalcManager.vcxproj +++ b/src/CalcManager/CalcManager.vcxproj @@ -288,7 +288,7 @@ - + @@ -315,9 +315,6 @@ - Create Create diff --git a/src/CalcManager/CalcManager.vcxproj.filters b/src/CalcManager/CalcManager.vcxproj.filters index fd61b03..7c4ad53 100644 --- a/src/CalcManager/CalcManager.vcxproj.filters +++ b/src/CalcManager/CalcManager.vcxproj.filters @@ -1,10 +1,6 @@  - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms - {957a8e3c-00c7-48bc-b63c-83b2140a8251} @@ -81,7 +77,7 @@ RatPack - + diff --git a/src/CalcManager/CalculatorHistory.Cpp b/src/CalcManager/CalculatorHistory.cpp similarity index 100% rename from src/CalcManager/CalculatorHistory.Cpp rename to src/CalcManager/CalculatorHistory.cpp diff --git a/src/CalcManager/ExpressionCommand.cpp b/src/CalcManager/ExpressionCommand.cpp index ec177a6..e671182 100644 --- a/src/CalcManager/ExpressionCommand.cpp +++ b/src/CalcManager/ExpressionCommand.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include "pch.h" @@ -7,6 +7,7 @@ #include "ExpressionCommand.h" using namespace std; +using namespace CalcEngine; constexpr wchar_t chNegate = L'-'; constexpr wchar_t chExp = L'e'; @@ -94,25 +95,19 @@ void CBinaryCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor) commandVisitor.Visit(*this); } -COpndCommand::COpndCommand(_In_ shared_ptr> const &commands, - _In_ bool fNegative, - _In_ bool fDecimal, - _In_ bool fSciFmt) : - m_commands(commands), m_fNegative(fNegative), m_fDecimal(fDecimal), m_fSciFmt(fSciFmt) -{ - m_hnoNum = nullptr; -} +COpndCommand::COpndCommand(shared_ptr> const &commands, bool fNegative, bool fDecimal, bool fSciFmt) : + m_commands(commands), + m_fNegative(fNegative), + m_fDecimal(fDecimal), + m_fSciFmt(fSciFmt), + m_fInitialized(false), + m_value{} +{} - -void COpndCommand::Initialize(_In_ PRAT hNoNum) +void COpndCommand::Initialize(Rational const& rat) { - assert(&m_hnoNum != nullptr); - if (m_hnoNum != nullptr) - { - destroyrat(m_hnoNum); - m_hnoNum = nullptr; - } - DUPRAT(m_hnoNum, hNoNum); + m_value = rat; + m_fInitialized = true; } const shared_ptr> & COpndCommand::GetCommands() const @@ -294,18 +289,16 @@ const wstring & COpndCommand::GetToken(wchar_t decimalSymbol) wstring COpndCommand::GetString(uint32_t radix, int32_t precision, wchar_t decimalSymbol) { - wstring numString{}; - if (m_hnoNum != nullptr) + wstring result{}; + + if (m_fInitialized) { - numString = NumObjToString(m_hnoNum, radix, eNUMOBJ_FMT::FMT_FLOAT, precision); + PRAT valRat = m_value.ToPRAT(); + result = NumObjToString(valRat, radix, eNUMOBJ_FMT::FMT_FLOAT, precision); + destroyrat(valRat); } - return numString; -} - -COpndCommand::~COpndCommand() -{ - destroyrat(m_hnoNum); + return result; } void COpndCommand::Accept(_In_ ISerializeCommandVisitor &commandVisitor) diff --git a/src/CalcManager/ExpressionCommand.h b/src/CalcManager/ExpressionCommand.h index d36c51a..0953ab2 100644 --- a/src/CalcManager/ExpressionCommand.h +++ b/src/CalcManager/ExpressionCommand.h @@ -1,9 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once #include "ExpressionCommandInterface.h" -#include "Header Files\CalcEngine.h" +#include "Header Files/CalcEngine.h" +#include "Header Files/Rational.h" class CParentheses : public IParenthesisCommand { @@ -48,12 +49,12 @@ private: class COpndCommand : public IOpndCommand { public: - COpndCommand(_In_ std::shared_ptr> const &commands, - _In_ bool fNegative, - _In_ bool fDecimal, - _In_ bool fSciFmt); - ~COpndCommand(); - void Initialize(_In_ PRAT hNoNum); + COpndCommand( + std::shared_ptr> const &commands, + bool fNegative, + bool fDecimal, + bool fSciFmt); + void Initialize(CalcEngine::Rational const& rat); const std::shared_ptr> & GetCommands() const; void SetCommands(std::shared_ptr> const& commands); @@ -73,8 +74,9 @@ private: bool m_fNegative; bool m_fSciFmt; bool m_fDecimal; + bool m_fInitialized; std::wstring m_token; - PRAT m_hnoNum; + CalcEngine::Rational m_value; void ClearAllAndAppendCommand(CalculationManager::Command command); }; diff --git a/src/CalcManager/Header Files/History.h b/src/CalcManager/Header Files/History.h index f885067..5deb5ff 100644 --- a/src/CalcManager/Header Files/History.h +++ b/src/CalcManager/Header Files/History.h @@ -5,6 +5,7 @@ #include "ICalcDisplay.h" #include "IHistoryDisplay.h" +#include "Rational.h" // maximum depth you can get by precedence. It is just an array's size limit. static constexpr size_t MAXPRECDEPTH = 25; @@ -16,7 +17,7 @@ class CHistoryCollector { public: CHistoryCollector(ICalcDisplay *pCalcDisplay, std::shared_ptr pHistoryDisplay, wchar_t decimalSymbol); // Can throw errors ~CHistoryCollector(); - void AddOpndToHistory(std::wstring_view numStr, PRAT hNoNum, bool fRepetition = false); + void AddOpndToHistory(std::wstring_view numStr, CalcEngine::Rational const& rat, bool fRepetition = false); void RemoveLastOpndFromHistory(); void AddBinOpToHistory(int nOpCode, bool fNoRepetition = true); void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher); diff --git a/src/CalcViewModel/CalcViewModel.vcxproj.filters b/src/CalcViewModel/CalcViewModel.vcxproj.filters index 5154242..d05aca0 100644 --- a/src/CalcViewModel/CalcViewModel.vcxproj.filters +++ b/src/CalcViewModel/CalcViewModel.vcxproj.filters @@ -1,10 +1,6 @@  - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms - {1daab7c4-63f6-4266-a259-f34acad66d09} diff --git a/src/CalcViewModel/Common/DateCalculator.cpp b/src/CalcViewModel/Common/DateCalculator.cpp index 6b7eba8..ac0dbbe 100644 --- a/src/CalcViewModel/Common/DateCalculator.cpp +++ b/src/CalcViewModel/Common/DateCalculator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include "pch.h" @@ -273,19 +273,33 @@ bool DateCalculationEngine::TryGetCalendarDaysInYear(_In_ DateTime date, _Out_ U // Adds/Subtracts certain value for a particular date unit DateTime DateCalculationEngine::AdjustCalendarDate(Windows::Foundation::DateTime date, DateUnit dateUnit, int difference) { + m_calendar->SetDateTime(date); switch (dateUnit) { - case DateUnit::Year: - m_calendar->AddYears(difference); - break; - case DateUnit::Month: - m_calendar->AddMonths(difference); - break; - case DateUnit::Week: - m_calendar->AddWeeks(difference); - break; + case DateUnit::Year: + { + // In the Japanese calendar, transition years have 2 partial years. + // It is not guaranteed that adding 1 year will always add 365 days in the Japanese Calendar. + // To work around this quirk, we will change the calendar system to Gregorian before adding 1 year in the Japanese Calendar case only. + // We will then return the calendar system back to the Japanese Calendar. + auto currentCalendarSystem = m_calendar->GetCalendarSystem(); + if (currentCalendarSystem == CalendarIdentifiers::Japanese) + { + m_calendar->ChangeCalendarSystem(CalendarIdentifiers::Gregorian); + } + + m_calendar->AddYears(difference); + m_calendar->ChangeCalendarSystem(currentCalendarSystem); + break; + } + case DateUnit::Month: + m_calendar->AddMonths(difference); + break; + case DateUnit::Week: + m_calendar->AddWeeks(difference); + break; } return m_calendar->GetDateTime(); diff --git a/src/Calculator.sln b/src/Calculator.sln index cfcae41..2d36a93 100644 --- a/src/Calculator.sln +++ b/src/Calculator.sln @@ -14,7 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalcViewModel", "CalcViewModel\CalcViewModel.vcxproj", "{90E9761D-9262-4773-942D-CAEAE75D7140}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalculatorUnitTests_VS", "CalculatorUnitTests_VS\CalculatorUnitTests_VS.vcxproj", "{D3BAED2C-4B07-4E1D-8807-9D6499450349}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CalculatorUnitTests", "CalculatorUnitTests\CalculatorUnitTests.vcxproj", "{D3BAED2C-4B07-4E1D-8807-9D6499450349}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/Calculator/App.xaml.cpp b/src/Calculator/App.xaml.cpp index 2c701ea..90e504d 100644 --- a/src/Calculator/App.xaml.cpp +++ b/src/Calculator/App.xaml.cpp @@ -12,7 +12,6 @@ #include "CalcViewModel\Common\Automation\NarratorNotifier.h" #include "CalcViewModel\Common\AppResourceProvider.h" #include "CalcViewModel\Common\LocalizationSettings.h" -#include "Common\SuspensionManager.h" #include "Views\MainPage.xaml.h" using namespace CalculatorApp; @@ -283,10 +282,8 @@ void App::OnAppLaunch(IActivatedEventArgs^ args, String^ argument) } } - // Create a Frame to act as the navigation context and associate it with - // a SuspensionManager key + // Create a Frame to act as the navigation context rootFrame = App::CreateFrame(); - //SuspensionManager::RegisterFrame(rootFrame, "AppFrame"); // When the navigation stack isn't restored navigate to the first page, // configuring the new page by passing required information as a navigation diff --git a/src/Calculator/Calculator.vcxproj b/src/Calculator/Calculator.vcxproj index 4140df3..1086d0c 100644 --- a/src/Calculator/Calculator.vcxproj +++ b/src/Calculator/Calculator.vcxproj @@ -136,11 +136,6 @@ false Never - - Always - $(Platform) - x86 - /bigobj /await /std:c++17 @@ -209,6 +204,11 @@ WindowsApp.lib;$(VC_ReferencesPath_VC_x64)\pgort.lib;%(AdditionalDependencies) + + + /DSEND_TELEMETRY %(AdditionalOptions) + + 0.0.0.0 @@ -224,8 +224,6 @@ - - @@ -360,8 +358,6 @@ - - @@ -822,9 +818,6 @@ - - {311e866d-8b93-4609-a691-265941fee101} - {90e9761d-9262-4773-942d-caeae75d7140} diff --git a/src/Calculator/Calculator.vcxproj.filters b/src/Calculator/Calculator.vcxproj.filters index 72aea21..f17fe36 100644 --- a/src/Calculator/Calculator.vcxproj.filters +++ b/src/Calculator/Calculator.vcxproj.filters @@ -14,9 +14,6 @@ {5a666ef7-54fb-46cc-9588-5cbcfaed3465} - - {1cba827f-63eb-4cda-8bf0-eea60190725e} - {f9b88d9e-918b-49ac-869b-a1a380ec3201} @@ -231,12 +228,6 @@ Common - - Common - - - Common - Controls @@ -327,12 +318,6 @@ Common - - Common - - - Common - Controls @@ -428,7 +413,6 @@ - @@ -1579,4 +1563,7 @@ Assets + + + \ No newline at end of file diff --git a/src/Calculator/Common/AppLifecycleLogger.cpp b/src/Calculator/Common/AppLifecycleLogger.cpp index 5bc2209..342cc19 100644 --- a/src/Calculator/Common/AppLifecycleLogger.cpp +++ b/src/Calculator/Common/AppLifecycleLogger.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include "pch.h" @@ -15,12 +15,21 @@ using namespace winrt::Windows::UI::ViewManagement; namespace CalculatorApp { + +#ifdef SEND_TELEMETRY // c.f. WINEVENT_KEYWORD_RESERVED_63-56 0xFF00000000000000 // Bits 63-56 - channel keywords // c.f. WINEVENT_KEYWORD_* 0x00FF000000000000 // Bits 55-48 - system-reserved keywords constexpr int64_t MICROSOFT_KEYWORD_CRITICAL_DATA = 0x0000800000000000; // Bit 47 - constexpr int64_t MICROSOFT_KEYWORD_MEASURES = 0x0000400000000000; // Bit 46 - constexpr int64_t MICROSOFT_KEYWORD_TELEMETRY = 0x0000200000000000; // Bit 45 - constexpr int64_t MICROSOFT_KEYWORD_RESERVED_44 = 0x0000100000000000; // Bit 44 (reserved for future assignment) + constexpr int64_t MICROSOFT_KEYWORD_MEASURES = 0x0000400000000000; // Bit 46 + constexpr int64_t MICROSOFT_KEYWORD_TELEMETRY = 0x0000200000000000; // Bit 45 + constexpr int64_t MICROSOFT_KEYWORD_RESERVED_44 = 0x0000100000000000; // Bit 44 (reserved for future assignment) +#else + // define all Keyword options as 0 when we do not want to upload app telemetry + constexpr int64_t MICROSOFT_KEYWORD_CRITICAL_DATA = 0; + constexpr int64_t MICROSOFT_KEYWORD_MEASURES = 0; + constexpr int64_t MICROSOFT_KEYWORD_TELEMETRY = 0; + constexpr int64_t MICROSOFT_KEYWORD_RESERVED_44 = 0; +#endif #pragma region TraceLogger setup and cleanup diff --git a/src/Calculator/Common/LayoutAwarePage.cpp b/src/Calculator/Common/LayoutAwarePage.cpp deleted file mode 100644 index c485640..0000000 --- a/src/Calculator/Common/LayoutAwarePage.cpp +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include "LayoutAwarePage.h" -#include "SuspensionManager.h" -#include "CalcViewModel\Common\LocalizationService.h" -#include "App.xaml.h" - -using namespace CalculatorApp::Common; - -using namespace Platform; -using namespace Platform::Collections; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -using namespace Windows::System; -using namespace Windows::UI::Core; -using namespace Windows::UI::ViewManagement; -using namespace Windows::UI::Xaml; -using namespace Windows::UI::Xaml::Controls; -using namespace Windows::UI::Xaml::Interop; -using namespace Windows::UI::Xaml::Navigation; - -/// -/// Initializes a new instance of the class. -/// -LayoutAwarePage::LayoutAwarePage() -{ - if (Windows::ApplicationModel::DesignMode::DesignModeEnabled) - { - return; - } - - // Create an empty default view model - DefaultViewModel = ref new Map(std::less()); - - // When this page is part of the visual tree make two changes: - // 1) Map application view state to visual state for the page - // 2) Handle keyboard and mouse navigation requests - Loaded += ref new RoutedEventHandler(this, &LayoutAwarePage::OnLoaded); - - // Undo the same changes when the page is no longer visible - Unloaded += ref new RoutedEventHandler(this, &LayoutAwarePage::OnUnloaded); - - Language = LocalizationService::GetInstance()->GetLanguage(); -} - -static DependencyProperty^ _defaultViewModelProperty = - DependencyProperty::Register("DefaultViewModel", - TypeName(IObservableMap::typeid), TypeName(LayoutAwarePage::typeid), nullptr); - -/// -/// Identifies the dependency property. -/// -DependencyProperty^ LayoutAwarePage::DefaultViewModelProperty::get() -{ - return _defaultViewModelProperty; -} - -/// -/// Gets an implementation of designed to be -/// used as a trivial view model. -/// -IObservableMap^ LayoutAwarePage::DefaultViewModel::get() -{ - return safe_cast^>(GetValue(DefaultViewModelProperty)); -} - -/// -/// Sets an implementation of designed to be -/// used as a trivial view model. -/// -void LayoutAwarePage::DefaultViewModel::set(IObservableMap^ value) -{ - SetValue(DefaultViewModelProperty, value); -} - -/// -/// Invoked when the page is part of the visual tree -/// -/// Instance that triggered the event. -/// Event data describing the conditions that led to the event. -void LayoutAwarePage::OnLoaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) -{ - // Keyboard and mouse navigation only apply when occupying the entire window - if (this->ActualHeight == Window::Current->Bounds.Height && - this->ActualWidth == Window::Current->Bounds.Width) - { - // Listen to the window directly so focus isn't required - _acceleratorKeyEventToken = Window::Current->CoreWindow->Dispatcher->AcceleratorKeyActivated += - ref new TypedEventHandler(this, - &LayoutAwarePage::CoreDispatcher_AcceleratorKeyActivated); - _pointerPressedEventToken = Window::Current->CoreWindow->PointerPressed += - ref new TypedEventHandler(this, - &LayoutAwarePage::CoreWindow_PointerPressed); - _navigationShortcutsRegistered = true; - } -} - -/// -/// Invoked when the page is removed from visual tree -/// -/// Instance that triggered the event. -/// Event data describing the conditions that led to the event. -void LayoutAwarePage::OnUnloaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) -{ - if (_navigationShortcutsRegistered) - { - Window::Current->CoreWindow->Dispatcher->AcceleratorKeyActivated -= _acceleratorKeyEventToken; - Window::Current->CoreWindow->PointerPressed -= _pointerPressedEventToken; - _navigationShortcutsRegistered = false; - } -} - -#pragma region Navigation support - -/// -/// Invoked as an event handler to navigate backward in the page's associated -/// until it reaches the top of the navigation stack. -/// -/// Instance that triggered the event. -/// Event data describing the conditions that led to the event. -void LayoutAwarePage::GoHome(Object^ sender, RoutedEventArgs^ e) -{ - (void) sender; // Unused parameter - (void) e; // Unused parameter - - // Use the navigation frame to return to the topmost page - if (Frame != nullptr) - { - while (Frame->CanGoBack) - { - Frame->GoBack(); - } - } -} - -/// -/// Invoked as an event handler to navigate backward in the navigation stack -/// associated with this page's . -/// -/// Instance that triggered the event. -/// Event data describing the conditions that led to the event. -void LayoutAwarePage::GoBack(Object^ sender, RoutedEventArgs^ e) -{ - (void) sender; // Unused parameter - (void) e; // Unused parameter - - // Use the navigation frame to return to the previous page - if (Frame != nullptr && Frame->CanGoBack) - { - Frame->GoBack(); - } -} - -/// -/// Invoked as an event handler to navigate forward in the navigation stack -/// associated with this page's . -/// -/// Instance that triggered the event. -/// Event data describing the conditions that led to the event. -void LayoutAwarePage::GoForward(Object^ sender, RoutedEventArgs^ e) -{ - (void) sender; // Unused parameter - (void) e; // Unused parameter - - // Use the navigation frame to advance to the next page - if (Frame != nullptr && Frame->CanGoForward) - { - Frame->GoForward(); - } -} - -/// -/// Invoked on every keystroke, including system keys such as Alt key combinations, when -/// this page is active and occupies the entire window. Used to detect keyboard navigation -/// between pages even when the page itself doesn't have focus. -/// -/// Instance that triggered the event. -/// Event data describing the conditions that led to the event. -void LayoutAwarePage::CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher^ sender, - AcceleratorKeyEventArgs^ args) -{ - auto virtualKey = args->VirtualKey; - - // Only investigate further when Left, Right, or the dedicated Previous or Next keys - // are pressed - if ((args->EventType == CoreAcceleratorKeyEventType::SystemKeyDown || - args->EventType == CoreAcceleratorKeyEventType::KeyDown) && - (virtualKey == VirtualKey::Left || virtualKey == VirtualKey::Right || - (int)virtualKey == 166 || (int)virtualKey == 167)) - { - auto coreWindow = Window::Current->CoreWindow; - auto downState = Windows::UI::Core::CoreVirtualKeyStates::Down; - bool menuKey = (coreWindow->GetKeyState(VirtualKey::Menu) & downState) == downState; - bool controlKey = (coreWindow->GetKeyState(VirtualKey::Control) & downState) == downState; - bool shiftKey = (coreWindow->GetKeyState(VirtualKey::Shift) & downState) == downState; - bool noModifiers = !menuKey && !controlKey && !shiftKey; - bool onlyAlt = menuKey && !controlKey && !shiftKey; - - if (((int)virtualKey == 166 && noModifiers) || - (virtualKey == VirtualKey::Left && onlyAlt)) - { - // When the previous key or Alt+Left are pressed navigate back - args->Handled = true; - GoBack(this, ref new RoutedEventArgs()); - } - else if (((int)virtualKey == 167 && noModifiers) || - (virtualKey == VirtualKey::Right && onlyAlt)) - { - // When the next key or Alt+Right are pressed navigate forward - args->Handled = true; - GoForward(this, ref new RoutedEventArgs()); - } - } -} - -/// -/// Invoked on every mouse click, touch screen tap, or equivalent interaction when this -/// page is active and occupies the entire window. Used to detect browser-style next and -/// previous mouse button clicks to navigate between pages. -/// -/// Instance that triggered the event. -/// Event data describing the conditions that led to the event. -void LayoutAwarePage::CoreWindow_PointerPressed(CoreWindow^ sender, PointerEventArgs^ args) -{ - auto properties = args->CurrentPoint->Properties; - - // Ignore button chords with the left, right, and middle buttons - if (properties->IsLeftButtonPressed || properties->IsRightButtonPressed || - properties->IsMiddleButtonPressed) return; - - // If back or foward are pressed (but not both) navigate appropriately - bool backPressed = properties->IsXButton1Pressed; - bool forwardPressed = properties->IsXButton2Pressed; - if (backPressed ^ forwardPressed) - { - args->Handled = true; - if (backPressed) GoBack(this, ref new RoutedEventArgs()); - if (forwardPressed) GoForward(this, ref new RoutedEventArgs()); - } -} - -#pragma endregion - -#pragma region Process lifetime management - -/// -/// Invoked when this page is about to be displayed in a Frame. -/// -/// Event data that describes how this page was reached. The Parameter -/// property provides the group to be displayed. -void LayoutAwarePage::OnNavigatedTo(NavigationEventArgs^ e) -{ - // Returning to a cached page through navigation shouldn't trigger state loading - if (_pageKey != nullptr) return; - - auto frameState = SuspensionManager::SessionStateForFrame(Frame); - _pageKey = "Page-" + Frame->BackStackDepth; - - if (e->NavigationMode == NavigationMode::New) - { - // Clear existing state for forward navigation when adding a new page to the - // navigation stack - auto nextPageKey = _pageKey; - int nextPageIndex = Frame->BackStackDepth; - while (frameState->HasKey(nextPageKey)) - { - frameState->Remove(nextPageKey); - nextPageIndex++; - nextPageKey = "Page-" + nextPageIndex; - } - - // Pass the navigation parameter to the new page - LoadState(e->Parameter, nullptr); - } - else - { - // Pass the navigation parameter and preserved page state to the page, using - // the same strategy for loading suspended state and recreating pages discarded - // from cache - LoadState(e->Parameter, safe_cast^>(frameState->Lookup(_pageKey))); - } -} - -/// -/// Invoked when this page will no longer be displayed in a Frame. -/// -/// Event data that describes how this page was reached. The Parameter -/// property provides the group to be displayed. -void LayoutAwarePage::OnNavigatedFrom(NavigationEventArgs^ e) -{ - auto frameState = SuspensionManager::SessionStateForFrame(Frame); - auto pageState = ref new Map(); - SaveState(pageState); - frameState->Insert(_pageKey, pageState); -} - -/// -/// Populates the page with content passed during navigation. Any saved state is also -/// provided when recreating a page from a prior session. -/// -/// The parameter value passed to -/// when this page was initially requested. -/// -/// A map of state preserved by this page during an earlier -/// session. This will be null the first time a page is visited. -void LayoutAwarePage::LoadState(Object^ navigationParameter, IMap^ pageState) -{ -} - -/// -/// Preserves state associated with this page in case the application is suspended or the -/// page is discarded from the navigation cache. Values must conform to the serialization -/// requirements of . -/// -/// An empty map to be populated with serializable state. -void LayoutAwarePage::SaveState(IMap^ pageState) -{ -} - -#pragma endregion diff --git a/src/Calculator/Common/LayoutAwarePage.h b/src/Calculator/Common/LayoutAwarePage.h deleted file mode 100644 index 298b58b..0000000 --- a/src/Calculator/Common/LayoutAwarePage.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#pragma once - -#include - -namespace CalculatorApp -{ - namespace Common - { - /// - /// Typical implementation of Page that provides several important conveniences: - /// - /// - /// Application view state to visual state mapping - /// - /// - /// GoBack, GoForward, and GoHome event handlers - /// - /// - /// Mouse and keyboard shortcuts for navigation - /// - /// - /// State management for navigation and process lifetime management - /// - /// - /// A default view model - /// - /// - /// - [Windows::Foundation::Metadata::WebHostHidden] - public ref class LayoutAwarePage : Windows::UI::Xaml::Controls::Page - { - internal: - LayoutAwarePage(); - - public: - static property Windows::UI::Xaml::DependencyProperty^ DefaultViewModelProperty - { - Windows::UI::Xaml::DependencyProperty^ get(); - }; - property Windows::Foundation::Collections::IObservableMap^ DefaultViewModel - { - Windows::Foundation::Collections::IObservableMap^ get(); - void set(Windows::Foundation::Collections::IObservableMap^ value); - } - - protected: - virtual void GoHome(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - virtual void GoBack(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - virtual void GoForward(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override; - virtual void OnNavigatedFrom(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override; - virtual void LoadState(Platform::Object^ navigationParameter, - Windows::Foundation::Collections::IMap^ pageState); - virtual void SaveState(Windows::Foundation::Collections::IMap^ pageState); - - private: - Platform::String^ _pageKey; - bool _navigationShortcutsRegistered; - Platform::Collections::Map^ _defaultViewModel; - Windows::Foundation::EventRegistrationToken _windowSizeEventToken, - _acceleratorKeyEventToken, _pointerPressedEventToken; - Platform::Collections::Vector^ _layoutAwareControls; - void OnLoaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void OnUnloaded(Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e); - void CoreDispatcher_AcceleratorKeyActivated(Windows::UI::Core::CoreDispatcher^ sender, - Windows::UI::Core::AcceleratorKeyEventArgs^ args); - void CoreWindow_PointerPressed(Windows::UI::Core::CoreWindow^ sender, - Windows::UI::Core::PointerEventArgs^ args); - LayoutAwarePage^ _this; // Strong reference to self, cleaned up in OnUnload - }; - } -} diff --git a/src/Calculator/Common/SuspensionManager.cpp b/src/Calculator/Common/SuspensionManager.cpp deleted file mode 100644 index 9cb7b91..0000000 --- a/src/Calculator/Common/SuspensionManager.cpp +++ /dev/null @@ -1,494 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// -// SuspensionManager.cpp -// Implementation of the SuspensionManager class -// - -#include "pch.h" -#include "SuspensionManager.h" - -using namespace CalculatorApp::Common; - -using namespace Concurrency; -using namespace Platform; -using namespace Platform::Collections; -using namespace Windows::Foundation; -using namespace Windows::Foundation::Collections; -using namespace Windows::Storage; -using namespace Windows::Storage::FileProperties; -using namespace Windows::Storage::Streams; -using namespace Windows::UI::Xaml; -using namespace Windows::UI::Xaml::Controls; -using namespace Windows::UI::Xaml::Interop; - -namespace -{ - Map^ _sessionState = ref new Map(); - String^ sessionStateFilename = "_sessionState.dat"; - - // Forward declarations for object object read / write support - void WriteObject(Windows::Storage::Streams::DataWriter^ writer, Platform::Object^ object); - Platform::Object^ ReadObject(Windows::Storage::Streams::DataReader^ reader); -} - -/// -/// Provides access to global session state for the current session. This state is serialized by -/// and restored by which require values to be -/// one of the following: boxed values including integers, floating-point singles and doubles, -/// wide characters, boolean, Strings and Guids, or Map where map values are -/// subject to the same constraints. Session state should be as compact as possible. -/// -IMap^ SuspensionManager::SessionState::get(void) -{ - return _sessionState; -} - -/// -/// Wrap a WeakReference as a reference object for use in a collection. -/// -private ref class WeakFrame sealed -{ -private: - WeakReference _frameReference; - -internal: - WeakFrame(Frame^ frame) { _frameReference = frame; } - property Frame^ ResolvedFrame - { - Frame^ get(void) { return _frameReference.Resolve(); } - }; -}; - -namespace -{ - std::vector _registeredFrames; - DependencyProperty^ FrameSessionStateKeyProperty = - DependencyProperty::RegisterAttached("_FrameSessionStateKeyProperty", - TypeName(String::typeid), TypeName(SuspensionManager::typeid), nullptr); - DependencyProperty^ FrameSessionStateProperty = - DependencyProperty::RegisterAttached("_FrameSessionStateProperty", - TypeName(IMap::typeid), TypeName(SuspensionManager::typeid), nullptr); -} - -/// -/// Registers a instance to allow its navigation history to be saved to -/// and restored from . Frames should be registered once -/// immediately after creation if they will participate in session state management. Upon -/// registration if state has already been restored for the specified key -/// the navigation history will immediately be restored. Subsequent invocations of -/// will also restore navigation history. -/// -/// An instance whose navigation history should be managed by -/// -/// A unique key into used to -/// store navigation-related information. -void SuspensionManager::RegisterFrame(Frame^ frame, String^ sessionStateKey) -{ - if (frame->GetValue(FrameSessionStateKeyProperty) != nullptr) - { - throw ref new FailureException("Frames can only be registered to one session state key"); - } - - if (frame->GetValue(FrameSessionStateProperty) != nullptr) - { - throw ref new FailureException("Frames must be either be registered before accessing frame session state, or not registered at all"); - } - - // Use a dependency property to associate the session key with a frame, and keep a list of frames whose - // navigation state should be managed - frame->SetValue(FrameSessionStateKeyProperty, sessionStateKey); - _registeredFrames.insert(_registeredFrames.begin(), ref new WeakFrame(frame)); - - // Check to see if navigation state can be restored - RestoreFrameNavigationState(frame); -} - -/// -/// Disassociates a previously registered by -/// from . Any navigation state previously captured will be -/// removed. -/// -/// An instance whose navigation history should no longer be -/// managed. -void SuspensionManager::UnregisterFrame(Frame^ frame) -{ - // Remove session state and remove the frame from the list of frames whose navigation - // state will be saved (along with any weak references that are no longer reachable) - auto key = safe_cast(frame->GetValue(FrameSessionStateKeyProperty)); - if (SessionState->HasKey(key)) SessionState->Remove(key); - _registeredFrames.erase( - std::remove_if(_registeredFrames.begin(), _registeredFrames.end(), [=](WeakFrame^& e) - { - auto testFrame = e->ResolvedFrame; - return testFrame == nullptr || testFrame == frame; - }), - _registeredFrames.end() - ); -} - -/// -/// Provides storage for session state associated with the specified . -/// Frames that have been previously registered with have -/// their session state saved and restored automatically as a part of the global -/// . Frames that are not registered have transient state -/// that can still be useful when restoring pages that have been discarded from the -/// navigation cache. -/// -/// Apps may choose to rely on to manage -/// page-specific state instead of working with frame session state directly. -/// The instance for which session state is desired. -/// A collection of state subject to the same serialization mechanism as -/// . -IMap^ SuspensionManager::SessionStateForFrame(Frame^ frame) -{ - auto frameState = safe_cast^>(frame->GetValue(FrameSessionStateProperty)); - - if (frameState == nullptr) - { - auto frameSessionKey = safe_cast(frame->GetValue(FrameSessionStateKeyProperty)); - if (frameSessionKey != nullptr) - { - // Registered frames reflect the corresponding session state - if (!_sessionState->HasKey(frameSessionKey)) - { - _sessionState->Insert(frameSessionKey, ref new Map()); - } - frameState = safe_cast^>(_sessionState->Lookup(frameSessionKey)); - } - else - { - // Frames that aren't registered have transient state - frameState = ref new Map(); - } - frame->SetValue(FrameSessionStateProperty, frameState); - } - return frameState; -} - -void SuspensionManager::RestoreFrameNavigationState(Frame^ frame) -{ - auto frameState = SessionStateForFrame(frame); - if (frameState->HasKey("Navigation")) - { - frame->SetNavigationState(safe_cast(frameState->Lookup("Navigation"))); - } -} - -void SuspensionManager::SaveFrameNavigationState(Frame^ frame) -{ - auto frameState = SessionStateForFrame(frame); - frameState->Insert("Navigation", frame->GetNavigationState()); -} - -/// -/// Save the current . Any instances -/// registered with will also preserve their current -/// navigation stack, which in turn gives their active an opportunity -/// to save its state. -/// -/// An asynchronous task that reflects when session state has been saved. -task SuspensionManager::SaveAsync(void) -{ - // Save the navigation state for all registered frames - for (auto&& weakFrame : _registeredFrames) - { - auto frame = weakFrame->ResolvedFrame; - if (frame != nullptr) SaveFrameNavigationState(frame); - } - - // Serialize the session state synchronously to avoid asynchronous access to shared - // state - auto sessionData = ref new InMemoryRandomAccessStream(); - auto sessionDataWriter = ref new DataWriter(sessionData->GetOutputStreamAt(0)); - WriteObject(sessionDataWriter, _sessionState); - - // Once session state has been captured synchronously, begin the asynchronous process - // of writing the result to disk - return task(sessionDataWriter->StoreAsync()).then([=](unsigned int) - { - return ApplicationData::Current->LocalFolder->CreateFileAsync(sessionStateFilename, - CreationCollisionOption::ReplaceExisting); - }).then([=](StorageFile^ createdFile) - { - return createdFile->OpenAsync(FileAccessMode::ReadWrite); - }).then([=](IRandomAccessStream^ newStream) - { - return RandomAccessStream::CopyAsync( - sessionData->GetInputStreamAt(0), newStream->GetOutputStreamAt(0)); - }).then([=](UINT64 copiedBytes) - { - (void)copiedBytes; // Unused parameter - return; - }); -} - -/// -/// Restores previously saved . Any instances -/// registered with will also restore their prior navigation -/// state, which in turn gives their active an opportunity restore its -/// state. -/// -/// A version identifer compared to the session state to prevent -/// incompatible versions of session state from reaching app code. Saved state with a -/// different version will be ignored, resulting in an empty -/// dictionary. -/// An asynchronous task that reflects when session state has been read. The -/// content of should not be relied upon until this task -/// completes. -task SuspensionManager::RestoreAsync(void) -{ - _sessionState->Clear(); - - task getFileTask(ApplicationData::Current->LocalFolder->GetFileAsync(sessionStateFilename)); - return getFileTask.then([=](StorageFile^ stateFile) - { - task getBasicPropertiesTask(stateFile->GetBasicPropertiesAsync()); - return getBasicPropertiesTask.then([=](BasicProperties^ stateFileProperties) - { - auto size = unsigned int(stateFileProperties->Size); - if (size != stateFileProperties->Size) throw ref new FailureException("Session state larger than 4GB"); - task openReadTask(stateFile->OpenReadAsync()); - return openReadTask.then([=](IRandomAccessStreamWithContentType^ stateFileStream) - { - auto stateReader = ref new DataReader(stateFileStream); - return task(stateReader->LoadAsync(size)).then([=](unsigned int bytesRead) - { - (void)bytesRead; // Unused parameter - // Deserialize the Session State - Object^ content = ReadObject(stateReader); - _sessionState = (Map^)content; - - // Restore any registered frames to their saved state - for (auto&& weakFrame : _registeredFrames) - { - auto frame = weakFrame->ResolvedFrame; - if (frame != nullptr) - { - frame->ClearValue(FrameSessionStateProperty); - RestoreFrameNavigationState(frame); - } - } - }, task_continuation_context::use_current()); - }); - }); - }); -} - -#pragma region Object serialization for a known set of types - -namespace -{ - // Codes used for identifying serialized types - enum StreamTypes { - NullPtrType = 0, - - // Supported IPropertyValue types - UInt8Type, UInt16Type, UInt32Type, UInt64Type, Int16Type, Int32Type, Int64Type, - SingleType, DoubleType, BooleanType, Char16Type, GuidType, StringType, - - // Array types - UInt8ArrayType, - - // Additional supported types - StringToObjectMapType, - - // Marker values used to ensure stream integrity - MapEndMarker - }; - - void WriteString(DataWriter^ writer, String^ string) - { - writer->WriteByte(StringType); - writer->WriteUInt32(writer->MeasureString(string)); - writer->WriteString(string); - } - - void WriteByteArray(DataWriter^ writer, Platform::Array^ data) - { - writer->WriteByte(UInt8ArrayType); - writer->WriteUInt32(data->Length); - writer->WriteBytes(data); - } - - void WriteProperty(DataWriter^ writer, IPropertyValue^ propertyValue) - { - switch (propertyValue->Type) - { - case PropertyType::UInt8: - writer->WriteByte(UInt8Type); - writer->WriteByte(propertyValue->GetUInt8()); - return; - case PropertyType::UInt8Array: - { - Array^ data; - propertyValue->GetUInt8Array(&data); - WriteByteArray(writer, data); - } - return; - case PropertyType::UInt16: - writer->WriteByte(UInt16Type); - writer->WriteUInt16(propertyValue->GetUInt16()); - return; - case PropertyType::UInt32: - writer->WriteByte(UInt32Type); - writer->WriteUInt32(propertyValue->GetUInt32()); - return; - case PropertyType::UInt64: - writer->WriteByte(UInt64Type); - writer->WriteUInt64(propertyValue->GetUInt64()); - return; - case PropertyType::Int16: - writer->WriteByte(Int16Type); - writer->WriteUInt16(propertyValue->GetInt16()); - return; - case PropertyType::Int32: - writer->WriteByte(Int32Type); - writer->WriteUInt32(propertyValue->GetInt32()); - return; - case PropertyType::Int64: - writer->WriteByte(Int64Type); - writer->WriteUInt64(propertyValue->GetInt64()); - return; - case PropertyType::Single: - writer->WriteByte(SingleType); - writer->WriteSingle(propertyValue->GetSingle()); - return; - case PropertyType::Double: - writer->WriteByte(DoubleType); - writer->WriteDouble(propertyValue->GetDouble()); - return; - case PropertyType::Boolean: - writer->WriteByte(BooleanType); - writer->WriteBoolean(propertyValue->GetBoolean()); - return; - case PropertyType::Char16: - writer->WriteByte(Char16Type); - writer->WriteUInt16(propertyValue->GetChar16()); - return; - case PropertyType::Guid: - writer->WriteByte(GuidType); - writer->WriteGuid(propertyValue->GetGuid()); - return; - case PropertyType::String: - WriteString(writer, propertyValue->GetString()); - return; - default: - throw ref new InvalidArgumentException("Unsupported property type"); - } - } - - void WriteStringToObjectMap(DataWriter^ writer, IMap^ map) - { - writer->WriteByte(StringToObjectMapType); - writer->WriteUInt32(map->Size); - for (auto&& pair : map) - { - WriteObject(writer, pair->Key); - WriteObject(writer, pair->Value); - } - writer->WriteByte(MapEndMarker); - } - - void WriteObject(DataWriter^ writer, Object^ object) - { - if (object == nullptr) - { - writer->WriteByte(NullPtrType); - return; - } - - auto propertyObject = dynamic_cast(object); - if (propertyObject != nullptr) - { - WriteProperty(writer, propertyObject); - return; - } - - auto mapObject = dynamic_cast^>(object); - if (mapObject != nullptr) - { - WriteStringToObjectMap(writer, mapObject); - return; - } - - throw ref new InvalidArgumentException("Unsupported data type"); - } - - String^ ReadString(DataReader^ reader) - { - int length = reader->ReadUInt32(); - String^ string = reader->ReadString(length); - return string; - } - - Object^ ReadByteArray(DataReader^ reader) - { - unsigned int length = reader->ReadUInt32(); - Array^ data = ref new Array(length); - reader->ReadBytes(data); - return data; - } - - IMap^ ReadStringToObjectMap(DataReader^ reader) - { - auto map = ref new Map(); - auto size = reader->ReadUInt32(); - for (unsigned int index = 0; index < size; index++) - { - auto key = safe_cast(ReadObject(reader)); - auto value = ReadObject(reader); - map->Insert(key, value); - } - if (reader->ReadByte() != MapEndMarker) - { - throw ref new InvalidArgumentException("Invalid stream"); - } - return map; - } - - Object^ ReadObject(DataReader^ reader) - { - auto type = reader->ReadByte(); - switch (type) - { - case NullPtrType: - return nullptr; - case UInt8Type: - return reader->ReadByte(); - case UInt8ArrayType: - return ReadByteArray(reader); - case UInt16Type: - return reader->ReadUInt16(); - case UInt32Type: - return reader->ReadUInt32(); - case UInt64Type: - return reader->ReadUInt64(); - case Int16Type: - return reader->ReadInt16(); - case Int32Type: - return reader->ReadInt32(); - case Int64Type: - return reader->ReadInt64(); - case SingleType: - return reader->ReadSingle(); - case DoubleType: - return reader->ReadDouble(); - case BooleanType: - return reader->ReadBoolean(); - case Char16Type: - return static_cast(reader->ReadUInt16()); - case GuidType: - return reader->ReadGuid(); - case StringType: - return ReadString(reader); - case StringToObjectMapType: - return ReadStringToObjectMap(reader); - default: - throw ref new InvalidArgumentException("Unsupported property type"); - } - } -} - -#pragma endregion diff --git a/src/Calculator/Common/SuspensionManager.h b/src/Calculator/Common/SuspensionManager.h deleted file mode 100644 index d96ece4..0000000 --- a/src/Calculator/Common/SuspensionManager.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -// -// SuspensionManager.h -// Declaration of the SuspensionManager class -// - -#pragma once - -#include - -namespace CalculatorApp -{ - namespace Common - { - /// - /// SuspensionManager captures global session state to simplify process lifetime management - /// for an application. Note that session state will be automatically cleared under a variety - /// of conditions and should only be used to store information that would be convenient to - /// carry across sessions, but that should be disacarded when an application crashes or is - /// upgraded. - /// - ref class SuspensionManager sealed - { - internal: - static void RegisterFrame(Windows::UI::Xaml::Controls::Frame^ frame, Platform::String^ sessionStateKey); - static void UnregisterFrame(Windows::UI::Xaml::Controls::Frame^ frame); - static Concurrency::task SaveAsync(void); - static Concurrency::task RestoreAsync(void); - static property Windows::Foundation::Collections::IMap^ SessionState - { - Windows::Foundation::Collections::IMap^ get(void); - }; - static Windows::Foundation::Collections::IMap^ SessionStateForFrame( - Windows::UI::Xaml::Controls::Frame^ frame); - - private: - static void RestoreFrameNavigationState(Windows::UI::Xaml::Controls::Frame^ frame); - static void SaveFrameNavigationState(Windows::UI::Xaml::Controls::Frame^ frame); - }; - } -} diff --git a/src/Calculator/Themes/Type.xaml b/src/Calculator/Themes/Type.xaml deleted file mode 100644 index bb0d126..0000000 --- a/src/Calculator/Themes/Type.xaml +++ /dev/null @@ -1,53 +0,0 @@ - - - 12 - 15 - 15 - 20 - 24 - 34 - 46 - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Calculator/Views/MainPage.xaml b/src/Calculator/Views/MainPage.xaml index e8a1d83..6136f42 100644 --- a/src/Calculator/Views/MainPage.xaml +++ b/src/Calculator/Views/MainPage.xaml @@ -1,20 +1,20 @@ - + @@ -160,4 +160,4 @@ - + diff --git a/src/Calculator/Views/MainPage.xaml.cpp b/src/Calculator/Views/MainPage.xaml.cpp index e8bf8d3..4cf229b 100644 --- a/src/Calculator/Views/MainPage.xaml.cpp +++ b/src/Calculator/Views/MainPage.xaml.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include "pch.h" @@ -85,105 +85,32 @@ MainPage::MainPage() : } } -/// -/// Populates the page with content passed during navigation. Any saved state is also -/// provided when recreating a page from a prior session. -/// -/// The parameter value passed to -/// when this page was initially requested. -/// -/// A map of state preserved by this page during an earlier -/// session. This will be null the first time a page is visited. -void MainPage::LoadState(_In_ Object^ navigationParameter, _In_ IMap^ pageState) +void MainPage::OnNavigatedTo(NavigationEventArgs^ e) { - if (pageState != nullptr) + if (m_model->CalculatorViewModel) { - if (pageState->HasKey("ConverterViewModelState")) + m_model->CalculatorViewModel->HistoryVM->ClearHistory(); + } + + ViewMode initialMode = ViewMode::Standard; + if (e->Parameter != nullptr) + { + String^ stringParameter = dynamic_cast(e->Parameter); + if (stringParameter != nullptr) { - auto converterViewModelState = safe_cast(pageState->Lookup("ConverterViewModelState")); - - m_model->ConverterViewModel->Deserialize(converterViewModelState); + initialMode = (ViewMode)stoi(stringParameter->Data()); } - - //Moving these below the converter view model deserialize, since the converter modes are also displayed in the MainPage NavBar and thus need to be deserialized before setting the current mode - if (pageState->HasKey(ApplicationViewModelProperties::Mode)) - { - m_model->Mode = NavCategory::Deserialize(pageState->Lookup(ApplicationViewModelProperties::Mode)); - } - - if (pageState->HasKey(ApplicationViewModelProperties::PreviousMode)) - { - m_model->PreviousMode = NavCategory::Deserialize(pageState->Lookup(ApplicationViewModelProperties::PreviousMode)); - } - - // rehydrate - if (pageState->HasKey("CalculatorViewModelState")) - { - auto calculatorViewModelState = safe_cast^>(pageState->Lookup("CalculatorViewModelState")); - - m_model->CalculatorViewModel->Deserialize(calculatorViewModelState); - } - - m_model->CalculatorViewModel->HistoryVM->RestoreCompleteHistory(); - m_model->CalculatorViewModel->HistoryVM->ReloadHistory(m_model->Mode); } else { - // initialize - if (m_model->CalculatorViewModel) + ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings; + if (localSettings->Values->HasKey(ApplicationViewModelProperties::Mode)) { - m_model->CalculatorViewModel->HistoryVM->ClearHistory(); + initialMode = NavCategory::Deserialize(localSettings->Values->Lookup(ApplicationViewModelProperties::Mode)); } - - ViewMode initialMode = ViewMode::Standard; - if (navigationParameter != nullptr) - { - String^ stringParameter = dynamic_cast(navigationParameter); - if (stringParameter != nullptr) - { - initialMode = (ViewMode)stoi(stringParameter->Data()); - } - } - else - { - ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings; - if (localSettings->Values->HasKey(ApplicationViewModelProperties::Mode)) - { - initialMode = NavCategory::Deserialize(localSettings->Values->Lookup(ApplicationViewModelProperties::Mode)); - } - } - - m_model->Initialize(initialMode); - } -} - -/// -/// Preserves state associated with this page in case the application is suspended or the -/// page is discarded from the navigation cache. Values must conform to the serialization -/// requirements of . -/// -/// An empty map to be populated with serializable state. -void MainPage::SaveState(_In_ IMap^ pageState) -{ - int serializedCurrentMode = NavCategory::Serialize(m_model->Mode); - - pageState->Insert(ApplicationViewModelProperties::Mode, serializedCurrentMode); - pageState->Insert(ApplicationViewModelProperties::PreviousMode, NavCategory::Serialize(m_model->PreviousMode)); - - ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings; - localSettings->Values->Insert(ApplicationViewModelProperties::Mode, serializedCurrentMode); - - auto serializedCalculatorData = m_model->CalculatorViewModel->Serialize(); - auto serializedConverterData = m_model->ConverterViewModel->Serialize(); - if (serializedCalculatorData->Length > 0) - { - pageState->Insert("CalculatorViewModelState", serializedCalculatorData); } - if (serializedConverterData != nullptr) - { - pageState->Insert("ConverterViewModelState", serializedConverterData); - } + m_model->Initialize(initialMode); } void MainPage::WindowSizeChanged(_In_ Platform::Object^ /*sender*/, _In_ Windows::UI::Core::WindowSizeChangedEventArgs^ e) diff --git a/src/Calculator/Views/MainPage.xaml.h b/src/Calculator/Views/MainPage.xaml.h index 902328b..4db633e 100644 --- a/src/Calculator/Views/MainPage.xaml.h +++ b/src/Calculator/Views/MainPage.xaml.h @@ -1,9 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #pragma once -#include "Common\LayoutAwarePage.h" // Required by generated header #include "Views\Calculator.xaml.h" #include "Views\MainPage.g.h" #include "Views\DateCalculator.xaml.h" @@ -40,9 +39,7 @@ namespace CalculatorApp Windows::Foundation::Collections::IObservableVector^ CreateUIElementsForCategories(_In_ Windows::Foundation::Collections::IObservableVector^ categories); protected: - virtual void LoadState(_In_ Platform::Object^ navigationParameter, - _In_ Windows::Foundation::Collections::IMap^ pageState) override; - virtual void SaveState(_In_ Windows::Foundation::Collections::IMap^ pageState) override; + void OnNavigatedTo(_In_ Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override; private: void WindowSizeChanged(_In_ Platform::Object^ sender, _In_ Windows::UI::Core::WindowSizeChangedEventArgs^ e); diff --git a/src/Calculator/WindowFrameService.cpp b/src/Calculator/WindowFrameService.cpp index d0eb9c7..387a958 100644 --- a/src/Calculator/WindowFrameService.cpp +++ b/src/Calculator/WindowFrameService.cpp @@ -1,9 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include "pch.h" #include "WindowFrameService.h" -#include "Common\SuspensionManager.h" #include "CalcViewModel\Common\KeyboardShortcutManager.h" using namespace concurrency; diff --git a/internal/CalculatorUnitTests/Assets/LockScreenLogo.scale-200.png b/src/CalculatorUnitTests/Assets/LockScreenLogo.scale-200.png similarity index 100% rename from internal/CalculatorUnitTests/Assets/LockScreenLogo.scale-200.png rename to src/CalculatorUnitTests/Assets/LockScreenLogo.scale-200.png diff --git a/internal/CalculatorUnitTests/Assets/SplashScreen.scale-200.png b/src/CalculatorUnitTests/Assets/SplashScreen.scale-200.png similarity index 100% rename from internal/CalculatorUnitTests/Assets/SplashScreen.scale-200.png rename to src/CalculatorUnitTests/Assets/SplashScreen.scale-200.png diff --git a/internal/CalculatorUnitTests/Assets/Square150x150Logo.scale-200.png b/src/CalculatorUnitTests/Assets/Square150x150Logo.scale-200.png similarity index 100% rename from internal/CalculatorUnitTests/Assets/Square150x150Logo.scale-200.png rename to src/CalculatorUnitTests/Assets/Square150x150Logo.scale-200.png diff --git a/internal/CalculatorUnitTests/Assets/Square44x44Logo.scale-200.png b/src/CalculatorUnitTests/Assets/Square44x44Logo.scale-200.png similarity index 100% rename from internal/CalculatorUnitTests/Assets/Square44x44Logo.scale-200.png rename to src/CalculatorUnitTests/Assets/Square44x44Logo.scale-200.png diff --git a/internal/CalculatorUnitTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/src/CalculatorUnitTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png similarity index 100% rename from internal/CalculatorUnitTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png rename to src/CalculatorUnitTests/Assets/Square44x44Logo.targetsize-24_altform-unplated.png diff --git a/internal/CalculatorUnitTests/Assets/StoreLogo.png b/src/CalculatorUnitTests/Assets/StoreLogo.png similarity index 100% rename from internal/CalculatorUnitTests/Assets/StoreLogo.png rename to src/CalculatorUnitTests/Assets/StoreLogo.png diff --git a/internal/CalculatorUnitTests/Assets/Wide310x150Logo.scale-200.png b/src/CalculatorUnitTests/Assets/Wide310x150Logo.scale-200.png similarity index 100% rename from internal/CalculatorUnitTests/Assets/Wide310x150Logo.scale-200.png rename to src/CalculatorUnitTests/Assets/Wide310x150Logo.scale-200.png diff --git a/internal/CalculatorUnitTests/AsyncHelper.cpp b/src/CalculatorUnitTests/AsyncHelper.cpp similarity index 100% rename from internal/CalculatorUnitTests/AsyncHelper.cpp rename to src/CalculatorUnitTests/AsyncHelper.cpp diff --git a/internal/CalculatorUnitTests/AsyncHelper.h b/src/CalculatorUnitTests/AsyncHelper.h similarity index 100% rename from internal/CalculatorUnitTests/AsyncHelper.h rename to src/CalculatorUnitTests/AsyncHelper.h diff --git a/src/CalculatorUnitTests_VS/CalcEngineTests.cpp b/src/CalculatorUnitTests/CalcEngineTests.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/CalcEngineTests.cpp rename to src/CalculatorUnitTests/CalcEngineTests.cpp diff --git a/src/CalculatorUnitTests_VS/CalcInputTest.cpp b/src/CalculatorUnitTests/CalcInputTest.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/CalcInputTest.cpp rename to src/CalculatorUnitTests/CalcInputTest.cpp diff --git a/src/CalculatorUnitTests_VS/CalculatorManagerTest.cpp b/src/CalculatorUnitTests/CalculatorManagerTest.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/CalculatorManagerTest.cpp rename to src/CalculatorUnitTests/CalculatorManagerTest.cpp diff --git a/src/CalculatorUnitTests_VS/CalculatorUnitTests_VS.rc b/src/CalculatorUnitTests/CalculatorUnitTests.rc similarity index 100% rename from src/CalculatorUnitTests_VS/CalculatorUnitTests_VS.rc rename to src/CalculatorUnitTests/CalculatorUnitTests.rc diff --git a/src/CalculatorUnitTests_VS/CalculatorUnitTests_VS.vcxproj b/src/CalculatorUnitTests/CalculatorUnitTests.vcxproj similarity index 98% rename from src/CalculatorUnitTests_VS/CalculatorUnitTests_VS.vcxproj rename to src/CalculatorUnitTests/CalculatorUnitTests.vcxproj index 63730e7..f7e40b2 100644 --- a/src/CalculatorUnitTests_VS/CalculatorUnitTests_VS.vcxproj +++ b/src/CalculatorUnitTests/CalculatorUnitTests.vcxproj @@ -2,7 +2,7 @@ {d3baed2c-4b07-4e1d-8807-9d6499450349} - CalculatorUnitTests_VS + CalculatorUnitTests en-US 15.0 true @@ -129,7 +129,7 @@ - CalculatorUnitTests_VS_TemporaryKey.pfx + CalculatorUnitTests_TemporaryKey.pfx 3F0C32266A4D995CC08C9AEC3960CFF3EF0D1853 @@ -259,7 +259,7 @@ - + @@ -269,7 +269,7 @@ - + diff --git a/src/CalculatorUnitTests_VS/CalculatorUnitTests_VS.vcxproj.filters b/src/CalculatorUnitTests/CalculatorUnitTests.vcxproj.filters similarity index 61% rename from src/CalculatorUnitTests_VS/CalculatorUnitTests_VS.vcxproj.filters rename to src/CalculatorUnitTests/CalculatorUnitTests.vcxproj.filters index 88ec497..57ac4fe 100644 --- a/src/CalculatorUnitTests_VS/CalculatorUnitTests_VS.vcxproj.filters +++ b/src/CalculatorUnitTests/CalculatorUnitTests.vcxproj.filters @@ -17,7 +17,6 @@ - @@ -27,36 +26,63 @@ + + Mocks + - + + Mocks + - + - - - - - - - + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + + + Assets + - + + + + + {f2987b0a-9832-46fc-b818-d5347362b3d8} + + + {d3ec8922-022d-4531-8744-f65a872f3841} + \ No newline at end of file diff --git a/src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx b/src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx new file mode 100644 index 0000000..d4e928e Binary files /dev/null and b/src/CalculatorUnitTests/CalculatorUnitTests_TemporaryKey.pfx differ diff --git a/src/CalculatorUnitTests_VS/CopyPasteManagerTest.cpp b/src/CalculatorUnitTests/CopyPasteManagerTest.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/CopyPasteManagerTest.cpp rename to src/CalculatorUnitTests/CopyPasteManagerTest.cpp diff --git a/src/CalculatorUnitTests_VS/CurrencyConverterUnitTests.cpp b/src/CalculatorUnitTests/CurrencyConverterUnitTests.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/CurrencyConverterUnitTests.cpp rename to src/CalculatorUnitTests/CurrencyConverterUnitTests.cpp diff --git a/src/CalculatorUnitTests_VS/DateCalculatorUnitTests.cpp b/src/CalculatorUnitTests/DateCalculatorUnitTests.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/DateCalculatorUnitTests.cpp rename to src/CalculatorUnitTests/DateCalculatorUnitTests.cpp diff --git a/src/CalculatorUnitTests_VS/DateUtils.h b/src/CalculatorUnitTests/DateUtils.h similarity index 100% rename from src/CalculatorUnitTests_VS/DateUtils.h rename to src/CalculatorUnitTests/DateUtils.h diff --git a/src/CalculatorUnitTests_VS/Helpers.h b/src/CalculatorUnitTests/Helpers.h similarity index 100% rename from src/CalculatorUnitTests_VS/Helpers.h rename to src/CalculatorUnitTests/Helpers.h diff --git a/src/CalculatorUnitTests_VS/HistoryTests.cpp b/src/CalculatorUnitTests/HistoryTests.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/HistoryTests.cpp rename to src/CalculatorUnitTests/HistoryTests.cpp diff --git a/src/CalculatorUnitTests_VS/Mocks/CurrencyHttpClient.cpp b/src/CalculatorUnitTests/Mocks/CurrencyHttpClient.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/Mocks/CurrencyHttpClient.cpp rename to src/CalculatorUnitTests/Mocks/CurrencyHttpClient.cpp diff --git a/internal/CalculatorUnitTests/Mocks/CurrencyHttpClient.h b/src/CalculatorUnitTests/Mocks/CurrencyHttpClient.h similarity index 100% rename from internal/CalculatorUnitTests/Mocks/CurrencyHttpClient.h rename to src/CalculatorUnitTests/Mocks/CurrencyHttpClient.h diff --git a/src/CalculatorUnitTests_VS/Module.cpp b/src/CalculatorUnitTests/Module.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/Module.cpp rename to src/CalculatorUnitTests/Module.cpp diff --git a/src/CalculatorUnitTests_VS/MultiWindowUnitTests.cpp b/src/CalculatorUnitTests/MultiWindowUnitTests.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/MultiWindowUnitTests.cpp rename to src/CalculatorUnitTests/MultiWindowUnitTests.cpp diff --git a/src/CalculatorUnitTests_VS/NavCategoryUnitTests.cpp b/src/CalculatorUnitTests/NavCategoryUnitTests.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/NavCategoryUnitTests.cpp rename to src/CalculatorUnitTests/NavCategoryUnitTests.cpp diff --git a/src/CalculatorUnitTests_VS/Package.appxmanifest b/src/CalculatorUnitTests/Package.appxmanifest similarity index 78% rename from src/CalculatorUnitTests_VS/Package.appxmanifest rename to src/CalculatorUnitTests/Package.appxmanifest index 9bd25f9..503376f 100644 --- a/src/CalculatorUnitTests_VS/Package.appxmanifest +++ b/src/CalculatorUnitTests/Package.appxmanifest @@ -3,7 +3,7 @@ - CalculatorUnitTests_VS + CalculatorUnitTests Microsoft Corporation Assets\StoreLogo.png @@ -14,8 +14,8 @@ - - + + diff --git a/src/CalculatorUnitTests_VS/StandardViewModelUnitTests.cpp b/src/CalculatorUnitTests/StandardViewModelUnitTests.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/StandardViewModelUnitTests.cpp rename to src/CalculatorUnitTests/StandardViewModelUnitTests.cpp diff --git a/src/CalculatorUnitTests_VS/Test.resw b/src/CalculatorUnitTests/Test.resw similarity index 100% rename from src/CalculatorUnitTests_VS/Test.resw rename to src/CalculatorUnitTests/Test.resw diff --git a/src/CalculatorUnitTests_VS/UnitConverterTest.cpp b/src/CalculatorUnitTests/UnitConverterTest.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/UnitConverterTest.cpp rename to src/CalculatorUnitTests/UnitConverterTest.cpp diff --git a/src/CalculatorUnitTests_VS/UnitConverterViewModelUnitTests.cpp b/src/CalculatorUnitTests/UnitConverterViewModelUnitTests.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/UnitConverterViewModelUnitTests.cpp rename to src/CalculatorUnitTests/UnitConverterViewModelUnitTests.cpp diff --git a/src/CalculatorUnitTests_VS/UnitConverterViewModelUnitTests.h b/src/CalculatorUnitTests/UnitConverterViewModelUnitTests.h similarity index 100% rename from src/CalculatorUnitTests_VS/UnitConverterViewModelUnitTests.h rename to src/CalculatorUnitTests/UnitConverterViewModelUnitTests.h diff --git a/src/CalculatorUnitTests_VS/UnitTestApp.rd.xml b/src/CalculatorUnitTests/UnitTestApp.rd.xml similarity index 100% rename from src/CalculatorUnitTests_VS/UnitTestApp.rd.xml rename to src/CalculatorUnitTests/UnitTestApp.rd.xml diff --git a/src/CalculatorUnitTests_VS/UnitTestApp.xaml b/src/CalculatorUnitTests/UnitTestApp.xaml similarity index 100% rename from src/CalculatorUnitTests_VS/UnitTestApp.xaml rename to src/CalculatorUnitTests/UnitTestApp.xaml diff --git a/src/CalculatorUnitTests_VS/UnitTestApp.xaml.cpp b/src/CalculatorUnitTests/UnitTestApp.xaml.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/UnitTestApp.xaml.cpp rename to src/CalculatorUnitTests/UnitTestApp.xaml.cpp diff --git a/src/CalculatorUnitTests_VS/UnitTestApp.xaml.h b/src/CalculatorUnitTests/UnitTestApp.xaml.h similarity index 100% rename from src/CalculatorUnitTests_VS/UnitTestApp.xaml.h rename to src/CalculatorUnitTests/UnitTestApp.xaml.h diff --git a/src/CalculatorUnitTests_VS/UtilsTests.cpp b/src/CalculatorUnitTests/UtilsTests.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/UtilsTests.cpp rename to src/CalculatorUnitTests/UtilsTests.cpp diff --git a/src/CalculatorUnitTests_VS/pch.cpp b/src/CalculatorUnitTests/pch.cpp similarity index 100% rename from src/CalculatorUnitTests_VS/pch.cpp rename to src/CalculatorUnitTests/pch.cpp diff --git a/src/CalculatorUnitTests_VS/pch.h b/src/CalculatorUnitTests/pch.h similarity index 100% rename from src/CalculatorUnitTests_VS/pch.h rename to src/CalculatorUnitTests/pch.h diff --git a/src/CalculatorUnitTests_VS/resource.h b/src/CalculatorUnitTests/resource.h similarity index 100% rename from src/CalculatorUnitTests_VS/resource.h rename to src/CalculatorUnitTests/resource.h diff --git a/src/CalculatorUnitTests_VS/Assets/LockScreenLogo.scale-200.png b/src/CalculatorUnitTests_VS/Assets/LockScreenLogo.scale-200.png deleted file mode 100644 index 735f57a..0000000 Binary files a/src/CalculatorUnitTests_VS/Assets/LockScreenLogo.scale-200.png and /dev/null differ diff --git a/src/CalculatorUnitTests_VS/Assets/SplashScreen.scale-200.png b/src/CalculatorUnitTests_VS/Assets/SplashScreen.scale-200.png deleted file mode 100644 index 023e7f1..0000000 Binary files a/src/CalculatorUnitTests_VS/Assets/SplashScreen.scale-200.png and /dev/null differ diff --git a/src/CalculatorUnitTests_VS/Assets/Square150x150Logo.scale-200.png b/src/CalculatorUnitTests_VS/Assets/Square150x150Logo.scale-200.png deleted file mode 100644 index af49fec..0000000 Binary files a/src/CalculatorUnitTests_VS/Assets/Square150x150Logo.scale-200.png and /dev/null differ diff --git a/src/CalculatorUnitTests_VS/Assets/Square44x44Logo.scale-200.png b/src/CalculatorUnitTests_VS/Assets/Square44x44Logo.scale-200.png deleted file mode 100644 index ce342a2..0000000 Binary files a/src/CalculatorUnitTests_VS/Assets/Square44x44Logo.scale-200.png and /dev/null differ diff --git a/src/CalculatorUnitTests_VS/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/src/CalculatorUnitTests_VS/Assets/Square44x44Logo.targetsize-24_altform-unplated.png deleted file mode 100644 index f6c02ce..0000000 Binary files a/src/CalculatorUnitTests_VS/Assets/Square44x44Logo.targetsize-24_altform-unplated.png and /dev/null differ diff --git a/src/CalculatorUnitTests_VS/Assets/StoreLogo.png b/src/CalculatorUnitTests_VS/Assets/StoreLogo.png deleted file mode 100644 index 7385b56..0000000 Binary files a/src/CalculatorUnitTests_VS/Assets/StoreLogo.png and /dev/null differ diff --git a/src/CalculatorUnitTests_VS/Assets/Wide310x150Logo.scale-200.png b/src/CalculatorUnitTests_VS/Assets/Wide310x150Logo.scale-200.png deleted file mode 100644 index 288995b..0000000 Binary files a/src/CalculatorUnitTests_VS/Assets/Wide310x150Logo.scale-200.png and /dev/null differ diff --git a/src/CalculatorUnitTests_VS/AsyncHelper.cpp b/src/CalculatorUnitTests_VS/AsyncHelper.cpp deleted file mode 100644 index 8d54d1d..0000000 --- a/src/CalculatorUnitTests_VS/AsyncHelper.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#include "pch.h" -#include "AsyncHelper.h" -#include -#include - -using namespace std; -using namespace concurrency; -using namespace Platform; -using namespace CalculatorApp; -using namespace Windows::UI::Core; -using namespace Windows::ApplicationModel::Core; - -task AsyncHelper::RunOnUIThreadAsync(function&& action) -{ - auto callback = ref new DispatchedHandler([action]() - { - action(); - }); - - return create_task(CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::Normal, callback)); -} - -void AsyncHelper::RunOnUIThread(function&& action, DWORD timeout) -{ - task waitTask = RunOnUIThreadAsync([action]() - { - action(); - }); - - WaitForTask(waitTask, timeout); -} - -void AsyncHelper::Delay(DWORD milliseconds) -{ - thread timer(bind(CalculatorApp::AsyncHelper::Sleep, milliseconds)); - timer.join(); -} - -void AsyncHelper::Sleep(DWORD milliseconds) -{ - this_thread::sleep_for(chrono::milliseconds(milliseconds)); -} diff --git a/src/CalculatorUnitTests_VS/AsyncHelper.h b/src/CalculatorUnitTests_VS/AsyncHelper.h deleted file mode 100644 index de3a88e..0000000 --- a/src/CalculatorUnitTests_VS/AsyncHelper.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#pragma once -#include - -namespace CalculatorApp -{ - class AsyncHelper - { - public: - static concurrency::task RunOnUIThreadAsync(std::function&& action); - static void RunOnUIThread(std::function&& action, DWORD timeout = INFINITE); - static void Delay(DWORD milliseconds); - - template - static void RunOnUIThread(std::function()>&& action, DWORD timeout = INFINITE) - { - concurrency::task t; - concurrency::task uiTask = RunOnUIThreadAsync([&t, action]() - { - t = action(); - }).then([&t]() - { - t.wait(); - }, concurrency::task_continuation_context::use_arbitrary()); - - WaitForTask(uiTask, timeout); - } - - template - static bool WaitForTask(concurrency::task& t, DWORD timeout = INFINITE) - { - Microsoft::WRL::Wrappers::Event event(CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS)); - if (!event.IsValid()) - { - throw std::bad_alloc(); - } - - Platform::Exception^ ex; - t.then([&event, &ex](concurrency::task prevTask) - { - try - { - prevTask.get(); - } - catch (Platform::Exception^ e) - { - ex = e; - } - - if (event.IsValid()) - { - SetEvent(event.Get()); - } - }, concurrency::task_continuation_context::use_arbitrary()); - - DWORD waitResult;// = STATUS_PENDING; - waitResult = WaitForSingleObjectEx(event.Get(), timeout, true); - event.Close(); - - if (ex != nullptr) - { - throw ex; - } - - if (waitResult == WAIT_FAILED) - { - throw ref new Platform::Exception(-1, L"Error in waiting for task completion: " + waitResult.ToString()); - } - - return waitResult == WAIT_OBJECT_0; - } - private: - static void Sleep(DWORD milliseconds); - }; -} diff --git a/src/CalculatorUnitTests_VS/Mocks/CurrencyHttpClient.h b/src/CalculatorUnitTests_VS/Mocks/CurrencyHttpClient.h deleted file mode 100644 index e9bff41..0000000 --- a/src/CalculatorUnitTests_VS/Mocks/CurrencyHttpClient.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -#pragma once - -#include "CalcViewModel\DataLoaders\ICurrencyHttpClient.h" - -namespace CalculatorApp -{ - namespace DataLoaders - { - class CurrencyHttpClient : public ICurrencyHttpClient - { - public: - CurrencyHttpClient(); - - static Platform::String^ GetRawStaticDataResponse(); - static Platform::String^ GetRawAllRatiosDataResponse(); - - // ICurrencyHttpClient - void SetSourceCurrencyCode(Platform::String^ sourceCurrencyCode) override {} - void SetResponseLanguage(Platform::String^ responseLanguage) override {} - - virtual Windows::Foundation::IAsyncOperationWithProgress^ GetCurrencyMetadata() override; - virtual Windows::Foundation::IAsyncOperationWithProgress^ GetCurrencyRatios() override; - // ICurrencyHttpClient - }; - - public ref class MockAsyncOperationWithProgress sealed : - public Windows::Foundation::IAsyncOperationWithProgress - { - public: - MockAsyncOperationWithProgress(Platform::String^ result); - - // IAsyncInfo - virtual property Windows::Foundation::HResult ErrorCode - { - Windows::Foundation::HResult get(); - } - - virtual property unsigned int Id - { - unsigned int get() { return 128u; } - } - - virtual property Windows::Foundation::AsyncStatus Status - { - Windows::Foundation::AsyncStatus get() { return Windows::Foundation::AsyncStatus::Completed; } - } - - virtual void Cancel() {} - virtual void Close() {} - // IAsyncInfo - - // IAsyncOperationWithProgress - virtual property Windows::Foundation::AsyncOperationProgressHandler^ Progress - { - Windows::Foundation::AsyncOperationProgressHandler^ get() { return nullptr; } - void set(Windows::Foundation::AsyncOperationProgressHandler^ handler) {} - } - - virtual property Windows::Foundation::AsyncOperationWithProgressCompletedHandler^ Completed - { - Windows::Foundation::AsyncOperationWithProgressCompletedHandler^ get() { return nullptr; } - void set(Windows::Foundation::AsyncOperationWithProgressCompletedHandler^ handler) {} - } - - virtual Platform::String^ GetResults() { return m_result; } - // IAsyncOperationWithProgress - - private: - Platform::String^ m_result; - }; - } -}