mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-22 06:13:14 -07:00
Merge branch 'master' into master
This commit is contained in:
commit
d93ee6a8f7
13 changed files with 42 additions and 45 deletions
|
@ -87,7 +87,7 @@ The ViewModel layer is contained in the [CalcViewModel][CalcViewModel folder] pr
|
||||||
data for the UI to bind against and act as the intermediary separating pure business logic from UI components that
|
data for the UI to bind against and act as the intermediary separating pure business logic from UI components that
|
||||||
should not care about the model's implementation. Just as the View layer consists of a hierarchy of XAML files, the
|
should not care about the model's implementation. Just as the View layer consists of a hierarchy of XAML files, the
|
||||||
ViewModel consists of a hierarchy of ViewModel files. The relationship between XAML and ViewModel files is often 1:1.
|
ViewModel consists of a hierarchy of ViewModel files. The relationship between XAML and ViewModel files is often 1:1.
|
||||||
Here are the noteable ViewModel files to start exploring with:
|
Here are the notable ViewModel files to start exploring with:
|
||||||
|
|
||||||
* [ApplicationViewModel.h][ApplicationViewModel.h]: The ViewModel for [MainPage.xaml][MainPage.xaml]. This ViewModel
|
* [ApplicationViewModel.h][ApplicationViewModel.h]: The ViewModel for [MainPage.xaml][MainPage.xaml]. This ViewModel
|
||||||
is the root of the other mode-specific ViewModels. The application changes between modes by updating the `Mode` property
|
is the root of the other mode-specific ViewModels. The application changes between modes by updating the `Mode` property
|
||||||
|
|
|
@ -11,7 +11,7 @@ These manual tests are run before every release of the Calculator app.
|
||||||
Steps:
|
Steps:
|
||||||
1. From the Standard Calculator page, input “3”, “+”, “3”, “Enter” on the keyboard
|
1. From the Standard Calculator page, input “3”, “+”, “3”, “Enter” on the keyboard
|
||||||
Expected: “6” shows up in the display
|
Expected: “6” shows up in the display
|
||||||
2. Input “4”, “-“, “2”, “=” using the in-app buttons
|
2. Input “4”, “-”, “2”, “=” using the in-app buttons
|
||||||
*Expected: “2” shows up in the display*
|
*Expected: “2” shows up in the display*
|
||||||
|
|
||||||
**Test 2**
|
**Test 2**
|
||||||
|
@ -31,7 +31,7 @@ Steps:
|
||||||
|
|
||||||
**Test 2**
|
**Test 2**
|
||||||
Steps:
|
Steps:
|
||||||
1. Input “5”, “n!“, “=” using the in-app buttons
|
1. Input “5”, “n!”, “=” using the in-app buttons
|
||||||
*Expected: “120” shows up in the display*
|
*Expected: “120” shows up in the display*
|
||||||
|
|
||||||
### Math in Programmer Calculator
|
### Math in Programmer Calculator
|
||||||
|
|
|
@ -35,8 +35,8 @@ void CHistoryCollector::ReinitHistory()
|
||||||
CHistoryCollector::CHistoryCollector(ICalcDisplay *pCalcDisplay, std::shared_ptr<IHistoryDisplay> pHistoryDisplay, wchar_t decimalSymbol) :
|
CHistoryCollector::CHistoryCollector(ICalcDisplay *pCalcDisplay, std::shared_ptr<IHistoryDisplay> pHistoryDisplay, wchar_t decimalSymbol) :
|
||||||
m_pHistoryDisplay(pHistoryDisplay),
|
m_pHistoryDisplay(pHistoryDisplay),
|
||||||
m_pCalcDisplay(pCalcDisplay),
|
m_pCalcDisplay(pCalcDisplay),
|
||||||
m_decimalSymbol(decimalSymbol),
|
m_iCurLineHistStart(-1),
|
||||||
m_iCurLineHistStart(-1)
|
m_decimalSymbol(decimalSymbol)
|
||||||
{
|
{
|
||||||
ReinitHistory();
|
ReinitHistory();
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ void CHistoryCollector::PopLastOpndStart()
|
||||||
|
|
||||||
void CHistoryCollector::AddOpenBraceToHistory()
|
void CHistoryCollector::AddOpenBraceToHistory()
|
||||||
{
|
{
|
||||||
int iCommandEnd = AddCommand(std::make_shared<CParentheses>(IDC_OPENP));
|
AddCommand(std::make_shared<CParentheses>(IDC_OPENP));
|
||||||
int ichOpndStart = IchAddSzToEquationSz(CCalcEngine::OpCodeToString(IDC_OPENP), -1);
|
int ichOpndStart = IchAddSzToEquationSz(CCalcEngine::OpCodeToString(IDC_OPENP), -1);
|
||||||
PushLastOpndStart(ichOpndStart);
|
PushLastOpndStart(ichOpndStart);
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ void CHistoryCollector::AddOpenBraceToHistory()
|
||||||
|
|
||||||
void CHistoryCollector::AddCloseBraceToHistory()
|
void CHistoryCollector::AddCloseBraceToHistory()
|
||||||
{
|
{
|
||||||
int iCommandEnd = AddCommand(std::make_shared<CParentheses>(IDC_CLOSEP));
|
AddCommand(std::make_shared<CParentheses>(IDC_CLOSEP));
|
||||||
IchAddSzToEquationSz(CCalcEngine::OpCodeToString(IDC_CLOSEP), -1);
|
IchAddSzToEquationSz(CCalcEngine::OpCodeToString(IDC_CLOSEP), -1);
|
||||||
SetExpressionDisplay();
|
SetExpressionDisplay();
|
||||||
PopLastOpndStart();
|
PopLastOpndStart();
|
||||||
|
@ -450,20 +450,16 @@ std::shared_ptr<CalculatorVector<int>> CHistoryCollector::GetOperandCommandsFrom
|
||||||
std::shared_ptr<CalculatorVector<int>> commands = std::make_shared<CalculatorVector<int>>();
|
std::shared_ptr<CalculatorVector<int>> commands = std::make_shared<CalculatorVector<int>>();
|
||||||
// Check for negate
|
// Check for negate
|
||||||
bool fNegative = (numStr[0] == L'-');
|
bool fNegative = (numStr[0] == L'-');
|
||||||
bool fSciFmt = false;
|
|
||||||
bool fDecimal = false;
|
|
||||||
|
|
||||||
for (size_t i = (fNegative ? 1 : 0); i < numStr.length(); i++)
|
for (size_t i = (fNegative ? 1 : 0); i < numStr.length(); i++)
|
||||||
{
|
{
|
||||||
if (numStr[i] == m_decimalSymbol)
|
if (numStr[i] == m_decimalSymbol)
|
||||||
{
|
{
|
||||||
IFT(commands->Append(IDC_PNT));
|
IFT(commands->Append(IDC_PNT));
|
||||||
fDecimal = true;
|
|
||||||
}
|
}
|
||||||
else if (numStr[i] == L'e')
|
else if (numStr[i] == L'e')
|
||||||
{
|
{
|
||||||
IFT(commands->Append(IDC_EXP));
|
IFT(commands->Append(IDC_EXP));
|
||||||
fSciFmt = true;
|
|
||||||
}
|
}
|
||||||
else if (numStr[i] == L'-')
|
else if (numStr[i] == L'-')
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,42 +55,42 @@ void CCalcEngine::InitialOneTimeOnlySetup(CalculationManager::IResourceProvider&
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
CCalcEngine::CCalcEngine(bool fPrecedence, bool fIntegerMode, CalculationManager::IResourceProvider* const pResourceProvider, __in_opt ICalcDisplay *pCalcDisplay, __in_opt shared_ptr<IHistoryDisplay> pHistoryDisplay) :
|
CCalcEngine::CCalcEngine(bool fPrecedence, bool fIntegerMode, CalculationManager::IResourceProvider* const pResourceProvider, __in_opt ICalcDisplay *pCalcDisplay, __in_opt shared_ptr<IHistoryDisplay> pHistoryDisplay) :
|
||||||
m_HistoryCollector(pCalcDisplay, pHistoryDisplay, DEFAULT_DEC_SEPARATOR),
|
|
||||||
m_resourceProvider(pResourceProvider),
|
|
||||||
m_bSetCalcState(false),
|
|
||||||
m_fPrecedence(fPrecedence),
|
m_fPrecedence(fPrecedence),
|
||||||
m_fIntegerMode(fIntegerMode),
|
m_fIntegerMode(fIntegerMode),
|
||||||
m_pCalcDisplay(pCalcDisplay),
|
m_pCalcDisplay(pCalcDisplay),
|
||||||
m_input(DEFAULT_DEC_SEPARATOR),
|
m_resourceProvider(pResourceProvider),
|
||||||
m_nOpCode(0),
|
m_nOpCode(0),
|
||||||
m_nPrevOpCode(0),
|
m_nPrevOpCode(0),
|
||||||
m_openParenCount(0),
|
|
||||||
m_precedenceOpCount(0),
|
|
||||||
m_nTempCom(0),
|
|
||||||
m_nLastCom(0),
|
|
||||||
m_parenVals{},
|
|
||||||
m_precedenceVals{},
|
|
||||||
m_bChangeOp(false),
|
m_bChangeOp(false),
|
||||||
m_bRecord(false),
|
m_bRecord(false),
|
||||||
m_bError(false),
|
m_bSetCalcState(false),
|
||||||
m_bInv(false),
|
m_input(DEFAULT_DEC_SEPARATOR),
|
||||||
m_nFE(FMT_FLOAT),
|
m_nFE(FMT_FLOAT),
|
||||||
m_nAE(AUTOFMT_DISABLED),
|
m_nAE(AUTOFMT_DISABLED),
|
||||||
|
m_memoryValue{ make_unique<Rational>() },
|
||||||
|
m_holdVal{},
|
||||||
|
m_currentVal{},
|
||||||
|
m_lastVal{},
|
||||||
|
m_parenVals{},
|
||||||
|
m_precedenceVals{},
|
||||||
|
m_bError(false),
|
||||||
|
m_bInv(false),
|
||||||
m_bNoPrevEqu(true),
|
m_bNoPrevEqu(true),
|
||||||
m_numwidth(QWORD_WIDTH),
|
|
||||||
m_angletype(ANGLE_DEG),
|
|
||||||
m_radix(DEFAULT_RADIX),
|
m_radix(DEFAULT_RADIX),
|
||||||
m_precision(DEFAULT_PRECISION),
|
m_precision(DEFAULT_PRECISION),
|
||||||
m_cIntDigitsSav(DEFAULT_MAX_DIGITS),
|
m_cIntDigitsSav(DEFAULT_MAX_DIGITS),
|
||||||
m_decGrouping(),
|
m_decGrouping(),
|
||||||
m_groupSeparator(DEFAULT_GRP_SEPARATOR),
|
|
||||||
m_numberString(DEFAULT_NUMBER_STR),
|
m_numberString(DEFAULT_NUMBER_STR),
|
||||||
|
m_nTempCom(0),
|
||||||
|
m_openParenCount(0),
|
||||||
m_nOp(),
|
m_nOp(),
|
||||||
m_nPrecOp(),
|
m_nPrecOp(),
|
||||||
m_memoryValue{ make_unique<Rational>() },
|
m_precedenceOpCount(0),
|
||||||
m_holdVal{},
|
m_nLastCom(0),
|
||||||
m_currentVal{},
|
m_angletype(ANGLE_DEG),
|
||||||
m_lastVal{}
|
m_numwidth(QWORD_WIDTH),
|
||||||
|
m_HistoryCollector(pCalcDisplay, pHistoryDisplay, DEFAULT_DEC_SEPARATOR),
|
||||||
|
m_groupSeparator(DEFAULT_GRP_SEPARATOR)
|
||||||
{
|
{
|
||||||
InitChopNumbers();
|
InitChopNumbers();
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,7 @@ CalcEngine::Rational CCalcEngine::SciCalcFunctions(CalcEngine::Rational const& r
|
||||||
// the degrees functionality was achieved as 'Inv' of 'dms' operation,
|
// the degrees functionality was achieved as 'Inv' of 'dms' operation,
|
||||||
// so setting the IDC_INV command first and then performing 'dms' operation as global variables m_bInv, m_bRecord
|
// so setting the IDC_INV command first and then performing 'dms' operation as global variables m_bInv, m_bRecord
|
||||||
// are set properly through ProcessCommand(IDC_INV)
|
// are set properly through ProcessCommand(IDC_INV)
|
||||||
|
[[fallthrough]];
|
||||||
case IDC_DMS:
|
case IDC_DMS:
|
||||||
{
|
{
|
||||||
if (!m_fIntegerMode)
|
if (!m_fIntegerMode)
|
||||||
|
|
|
@ -14,8 +14,8 @@ namespace CalcEngine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CalcNumSec() :
|
CalcNumSec() :
|
||||||
m_isNegative(false),
|
value(),
|
||||||
value()
|
m_isNegative(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
@ -37,12 +37,12 @@ namespace CalcEngine
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CalcInput(wchar_t decSymbol) :
|
CalcInput(wchar_t decSymbol) :
|
||||||
m_base(),
|
|
||||||
m_exponent(),
|
|
||||||
m_hasExponent(false),
|
m_hasExponent(false),
|
||||||
m_hasDecimal(false),
|
m_hasDecimal(false),
|
||||||
m_decPtIndex(0),
|
m_decPtIndex(0),
|
||||||
m_decSymbol(decSymbol)
|
m_decSymbol(decSymbol),
|
||||||
|
m_base(),
|
||||||
|
m_exponent()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
|
@ -235,7 +235,7 @@ void log10rat( PRAT *px, int32_t precision)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// return if the given x is even number. The assumption here is its numerator is 1 and we are testing the numerator is
|
// return if the given x is even number. The assumption here is its denominator is 1 and we are testing the numerator is
|
||||||
// even or not
|
// even or not
|
||||||
bool IsEven(PRAT x, uint32_t radix, int32_t precision)
|
bool IsEven(PRAT x, uint32_t radix, int32_t precision)
|
||||||
{
|
{
|
||||||
|
|
|
@ -903,7 +903,7 @@ shared_ptr<IConverterDataLoader> UnitConverter::GetDataLoaderForCategory(const C
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the intial values for m_fromType and m_toType.
|
/// Sets the initial values for m_fromType and m_toType.
|
||||||
/// This is an internal helper method as opposed to SetCurrentUnits
|
/// This is an internal helper method as opposed to SetCurrentUnits
|
||||||
/// which is for external use by clients.
|
/// which is for external use by clients.
|
||||||
/// If we fail to set units, we will fallback to the EMPTY_UNIT.
|
/// If we fail to set units, we will fallback to the EMPTY_UNIT.
|
||||||
|
|
|
@ -441,8 +441,8 @@ void KeyboardShortcutManager::OnVirtualKeyControlInverseChordPropertyChanged(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the three event handlers bellow we will not mark the event as handled
|
// In the three event handlers below we will not mark the event as handled
|
||||||
// because this is a sumplemental operation and we don't want to interfere with
|
// because this is a supplemental operation and we don't want to interfere with
|
||||||
// the normal keyboard handling.
|
// the normal keyboard handling.
|
||||||
void KeyboardShortcutManager::OnCharacterReceivedHandler(CoreWindow^ sender, CharacterReceivedEventArgs^ args)
|
void KeyboardShortcutManager::OnCharacterReceivedHandler(CoreWindow^ sender, CharacterReceivedEventArgs^ args)
|
||||||
{
|
{
|
||||||
|
|
|
@ -398,7 +398,7 @@ namespace Utils
|
||||||
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ args) {\
|
static void On##name##PropertyChangedImpl(Windows::UI::Xaml::DependencyObject^ sender, Windows::UI::Xaml::DependencyPropertyChangedEventArgs^ args) {\
|
||||||
On##name##PropertyChanged(sender, safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); } public:
|
On##name##PropertyChanged(sender, safe_cast<type>(args->OldValue), safe_cast<type>(args->NewValue)); } public:
|
||||||
|
|
||||||
// This goes into the cpp to initalize the static variable
|
// This goes into the cpp to initialize the static variable
|
||||||
#define DEPENDENCY_PROPERTY_INITIALIZATION(owner, name)\
|
#define DEPENDENCY_PROPERTY_INITIALIZATION(owner, name)\
|
||||||
Windows::UI::Xaml::DependencyProperty^ owner::s_##name##Property =\
|
Windows::UI::Xaml::DependencyProperty^ owner::s_##name##Property =\
|
||||||
owner::Initialize##name##Property();
|
owner::Initialize##name##Property();
|
||||||
|
|
|
@ -109,7 +109,7 @@ void SupplementaryResults::OnWindowSizeChanged(Platform::Object^ sender, Windows
|
||||||
|
|
||||||
void SupplementaryResults::OnSupplementaryValuesLayoutUpdated(Platform::Object^ sender, Platform::Object^ e)
|
void SupplementaryResults::OnSupplementaryValuesLayoutUpdated(Platform::Object^ sender, Platform::Object^ e)
|
||||||
{
|
{
|
||||||
// This means we overflowed and are cutting off, or in a very rare case we fit exactly. Unforunately
|
// This means we overflowed and are cutting off, or in a very rare case we fit exactly. Unfortunately
|
||||||
// the fitting exactly case will still have an item removed, as there is no other way for us to
|
// the fitting exactly case will still have an item removed, as there is no other way for us to
|
||||||
// detect that we need to trim.
|
// detect that we need to trim.
|
||||||
Grid^ parentGrid = dynamic_cast<Grid^>(VisualTreeHelper::GetParent(this));
|
Grid^ parentGrid = dynamic_cast<Grid^>(VisualTreeHelper::GetParent(this));
|
||||||
|
|
|
@ -101,7 +101,7 @@ namespace CalculatorUnitTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform calculations on diferent calculator modes and verify that they work independently
|
// Perform calculations on different calculator modes and verify that they work independently
|
||||||
TEST_METHOD(MultipleModesCalculationTest)
|
TEST_METHOD(MultipleModesCalculationTest)
|
||||||
{
|
{
|
||||||
std::vector<StandardCalculatorViewModel^> viewModels(3);
|
std::vector<StandardCalculatorViewModel^> viewModels(3);
|
||||||
|
|
|
@ -509,7 +509,7 @@ namespace CalculatorUnitTests
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch Calculator Mode and verify if mode switch is happening as expected.
|
// Switch Calculator Mode and verify if mode switch is happening as expected.
|
||||||
// Test precendence to check if mode switch is happening
|
// Test precedence to check if mode switch is happening
|
||||||
// Standard mode 1+2*3 = 9; Scientific mode 1+2*3 = 7
|
// 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
|
// Intermediate value is also different. after 1 + 2 * , standard shows 3, scientific shows 2
|
||||||
TEST_METHOD(ButtonPressedCalculatorModeSwitch)
|
TEST_METHOD(ButtonPressedCalculatorModeSwitch)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue