M module-apps/application-calculator/data/CalculatorInputProcessor.cpp => module-apps/application-calculator/data/CalculatorInputProcessor.cpp +0 -8
@@ 9,15 9,10 @@ bool calc::InputProcessor::isSymbol(uint32_t code) noexcept
switch (code) {
case plus:
- [[fallthrough]];
case minus:
- [[fallthrough]];
case division:
- [[fallthrough]];
case multiplication:
- [[fallthrough]];
case comma:
- [[fallthrough]];
case full_stop:
return true;
default:
@@ 31,11 26,8 @@ bool calc::InputProcessor::isOperation(uint32_t code) noexcept
switch (code) {
case plus:
- [[fallthrough]];
case minus:
- [[fallthrough]];
case division:
- [[fallthrough]];
case multiplication:
return true;
default:
M module-apps/application-calculator/data/CalculatorInputProcessorText.cpp => module-apps/application-calculator/data/CalculatorInputProcessorText.cpp +16 -32
@@ 13,7 13,7 @@ calc::InputProcessorText::InputProcessorText(gsl::strict_not_null<gui::Text *> i
bool calc::InputProcessorText::handle(const gui::InputEvent &event)
{
- if (clearInput || inputContainsExponent()) {
+ if (clearInput) {
clear();
}
@@ 90,7 90,7 @@ bool calc::InputProcessorText::handle(const gui::InputEvent &event)
return true;
}
- if (prohibidInput(event)) {
+ if (prohibitInput(event)) {
// Consume event to don't allow more decimals
return true;
}
@@ 119,13 119,18 @@ std::optional<uint32_t> calc::InputProcessorText::lastCharacter() const
bool calc::InputProcessorText::lastCharacterIsSymbol() const
{
const auto &c = lastCharacter();
- return c ? isSymbol(*c) : false;
+ return c && isSymbol(*c);
}
bool calc::InputProcessorText::lastCharacterIsOperation() const
{
const auto &c = lastCharacter();
- return c ? isOperation(*c) : false;
+ return c && isOperation(*c);
+}
+
+bool calc::InputProcessorText::isThereOnlyOneChar() const
+{
+ return inputField->getText().length() == 1;
}
std::optional<uint32_t> calc::InputProcessorText::penultimateCharacter() const
@@ 143,13 148,13 @@ std::optional<uint32_t> calc::InputProcessorText::penultimateCharacter() const
bool calc::InputProcessorText::penultimateCharacterIsSymbol() const
{
const auto &c = penultimateCharacter();
- return c ? isSymbol(*c) : false;
+ return c && isSymbol(*c);
}
bool calc::InputProcessorText::penultimateCharacterIsDecimalSeparator() const
{
const auto &c = penultimateCharacter();
- return c ? isDecimalSeparator(*c) : false;
+ return c && isDecimalSeparator(*c);
}
bool calc::InputProcessorText::shouldComputeBeforeNextOperation() const
@@ 178,7 183,7 @@ void calc::InputProcessorText::addSymbol(const UTF8 &symbol)
{
if (!inputField->getText().empty()) {
- if (lastCharacterIsSymbol() && symbol != symbols::strings::minus) {
+ if (lastCharacterIsSymbol()) {
if (!penultimateCharacterIsSymbol() && inputField->getText().length() > 1) {
inputField->removeChar();
inputField->addText(symbol);
@@ 195,19 200,7 @@ void calc::InputProcessorText::addSymbol(const UTF8 &symbol)
bool calc::InputProcessorText::shouldHideInput(const gui::InputEvent &event) const
{
- if (!lastCharacterIsOperation()) {
- return false;
- }
-
- if (!event.isDigit() && !event.is(gui::KeyCode::KEY_DOWN)) {
- return false;
- }
-
- if (inputField->getText() == symbols::strings::minus) {
- return false;
- }
-
- return true;
+ return not isThereOnlyOneChar() and lastCharacterIsOperation() and event.isDigit();
}
bool calc::InputProcessorText::shouldRestoreInput(const gui::InputEvent &event) const
@@ 263,12 256,7 @@ bool calc::InputProcessorText::isCurrentNumberDecimal() const
return false;
}
-bool calc::InputProcessorText::inputContainsExponent() const
-{
- return std::string{inputField->getText()}.find('e') != std::string::npos;
-}
-
-bool calc::InputProcessorText::prohibidInput(const gui::InputEvent &event) const
+bool calc::InputProcessorText::prohibitInput(const gui::InputEvent &event) const
{
if (!event.isDigit()) {
return false;
@@ 295,16 283,12 @@ bool calc::InputProcessorText::decimalLimitReached() const
const auto &txt = std::string{inputField->getText()};
const auto separator_pos = txt.find_last_of(symbols::strings::decimal_separator_str());
- if ((txt.size() - separator_pos) > limits::MaxDecimalDigits) {
- return true;
- }
-
- return false;
+ return (txt.size() - separator_pos) > limits::MaxDecimalDigits;
}
void calc::InputProcessorText::compute()
{
- auto result = Calculator().calculate(hiddenPartOfEquation + inputField->getText());
+ const auto result = Calculator().calculate(hiddenPartOfEquation + inputField->getText());
inputField->setText(result.value);
hiddenPartOfEquation.clear();
clearInput = result.isError;
M module-apps/application-calculator/data/CalculatorInputProcessorText.hpp => module-apps/application-calculator/data/CalculatorInputProcessorText.hpp +2 -2
@@ 25,6 25,7 @@ namespace calc
std::optional<std::uint32_t> lastCharacter() const;
bool lastCharacterIsSymbol() const;
bool lastCharacterIsOperation() const;
+ bool isThereOnlyOneChar() const;
std::optional<std::uint32_t> penultimateCharacter() const;
bool penultimateCharacterIsSymbol() const;
@@ 41,9 42,8 @@ namespace calc
bool hasHiddenPart() const;
bool isCurrentNumberDecimal() const;
- bool inputContainsExponent() const;
- bool prohibidInput(const gui::InputEvent &event) const;
+ bool prohibitInput(const gui::InputEvent &event) const;
bool charactedLimitReached() const;
bool decimalLimitReached() const;
M module-apps/application-calculator/data/CalculatorUtility.cpp => module-apps/application-calculator/data/CalculatorUtility.cpp +5 -4
@@ 22,7 22,7 @@ namespace calc
}
int error;
- double result = te_interp(source.c_str(), &error);
+ const auto result = te_interp(source.c_str(), &error);
if (error == 0 && !std::isinf(result) && !std::isnan(result)) {
auto output = utils::to_string(result);
if (output.length() > MaxStringLength) {
@@ 49,8 49,9 @@ namespace calc
size_t index = 0;
while (true) {
index = input.find(from, index);
- if (index == std::string::npos)
+ if (index == std::string::npos) {
break;
+ }
input.replace(index, from.length(), to);
index += to.length();
}
@@ 61,8 62,8 @@ namespace calc
{
using namespace calc::limits;
- auto base = static_cast<long long>(result);
- auto length = utils::to_string(base).length();
+ const auto base = static_cast<long long>(result);
+ auto length = utils::to_string(base).length();
if (base < 0) {
length -= 1;
}
A module-apps/application-calculator/readme.md => module-apps/application-calculator/readme.md +23 -0
@@ 0,0 1,23 @@
+# Assumptions
+
+* It's not possible to type numbers with `+` prefix like `+5`
+* It's not possible to type operation like `5--5`. Instead, use `5+5`
+* Dividing by 0 will result in displaying `Error` message
+* Input is limited to the 7 characters including
+* Maximal input value can be set to `9999999` or `99999.9`
+* Minimal input value can be set to `-999999` or `-9999.9`
+* Press `*` to remove the last typed input. It can be used multiple times to revert more than one input value.
+* It is possible to recall the last typed operation by using the `*` key. First you have to clear the current input, and
+ then press the `*` once again.
+
+```
+123+
+322 <- start pressing `*`
+32
+3
+ <- empty input field, press the `*` once again
+123+
+```
+
+* Trying to execute operations without right operand will trigger displaying `Error` message, i.e. `100+=`
+* There is no support for typing values using scientific notation, i.e. `10e9`
M module-apps/application-calculator/tests/CalculatorInput_tests.cpp => module-apps/application-calculator/tests/CalculatorInput_tests.cpp +83 -27
@@ 47,13 47,15 @@ SCENARIO("Input Processor tests")
auto passLongKeyPress = [&](KeyCodes code) { passEvent(longPressEvent(code)); };
auto passShortKeyPresses = [&](const std::vector<KeyCodes> &codes) {
- for (const auto &code : codes)
+ for (const auto &code : codes) {
passShortKeyPress(code);
+ }
};
auto passLongKeyPresses = [&](const std::vector<KeyCodes> &codes) {
- for (const auto &code : codes)
+ for (const auto &code : codes) {
passLongKeyPress(code);
+ }
};
THEN("The text is empty")
@@ 260,27 262,6 @@ SCENARIO("Input Processor tests")
}
}
- WHEN("We enter a negative number")
- {
- passShortKeyPresses({MinusKey, KeyCodes::NumericKey2, KeyCodes::NumericKey3});
-
- THEN("It is shown")
- {
- REQUIRE(inputField.getText() == "-23");
- }
-
- AND_WHEN("We try to subtract a negitive number")
- {
- passShortKeyPresses(
- {MinusKey, MinusKey, KeyCodes::NumericKey1, KeyCodes::NumericKey3, KeyCodes::JoystickEnter});
-
- THEN("The result is computed properly")
- {
- REQUIRE(inputField.getText() == "-10");
- }
- }
- }
-
WHEN("We enter a number")
{
passShortKeyPresses({KeyCodes::NumericKey1, KeyCodes::NumericKey2, KeyCodes::NumericKey3});
@@ 332,9 313,9 @@ SCENARIO("Input Processor tests")
{
passShortKeyPresses({MinusKey, KeyCodes::NumericKey5, KeyCodes::NumericKey6});
- THEN("Previous input is hidden and negative number is shown")
+ THEN("Previous input is hidden and typed number is shown")
{
- REQUIRE(inputField.getText() == "-56");
+ REQUIRE(inputField.getText() == "56");
}
AND_WHEN("We press enter")
@@ 349,7 330,7 @@ SCENARIO("Input Processor tests")
AND_WHEN("We delete the input")
{
- passShortKeyPresses({3, KeyCodes::NumericKeyPnd});
+ passShortKeyPresses({2, KeyCodes::NumericKeyPnd});
THEN("Input is deleted")
{
@@ 362,7 343,7 @@ SCENARIO("Input Processor tests")
THEN("Previous input is restored")
{
- REQUIRE(inputField.getText() == "123+");
+ REQUIRE(inputField.getText() == "123-");
}
}
}
@@ 478,6 459,26 @@ SCENARIO("Input Processor tests")
REQUIRE(inputField.getText() == "56");
}
}
+
+ AND_WHEN("We invoke any operation")
+ {
+ passShortKeyPress(KeyCodes::JoystickUp);
+
+ THEN("We should see")
+ {
+ REQUIRE(inputField.getText() == "9.9998e9+");
+ }
+
+ AND_WHEN("We proceed to type more input")
+ {
+ passShortKeyPresses({KeyCodes::NumericKey1, KeyCodes::NumericKey5, KeyCodes::NumericKey6});
+
+ THEN("We should see")
+ {
+ REQUIRE(inputField.getText() == "156");
+ }
+ }
+ }
}
WHEN("We enter an equation")
@@ 508,5 509,60 @@ SCENARIO("Input Processor tests")
}
}
}
+
+ WHEN("We enter the minus key")
+ {
+ passShortKeyPress(MinusKey);
+
+ AND_WHEN("We press another minus")
+ {
+ passShortKeyPress(MinusKey);
+
+ THEN("We should see only one minus sign")
+ {
+ REQUIRE(inputField.getText() == "-");
+ }
+
+ AND_WHEN("We continue inputting minus sign")
+ {
+ passShortKeyPress(MinusKey);
+
+ THEN("We still should see only one minus sign")
+ {
+ REQUIRE(inputField.getText() == "-");
+ }
+ }
+ }
+
+ AND_WHEN("We input a number")
+ {
+ passShortKeyPress(KeyCodes::NumericKey5);
+
+ THEN("We should see a '-5' value")
+ {
+ REQUIRE(inputField.getText() == "-5");
+ }
+
+ AND_WHEN("We input another minus sign")
+ {
+ passShortKeyPress(MinusKey);
+
+ THEN("We should see a '-5-' value")
+ {
+ REQUIRE(inputField.getText() == "-5-");
+ }
+
+ AND_WHEN("We input another minus sign")
+ {
+ passShortKeyPress(MinusKey);
+
+ THEN("We should still see a '-5-' value")
+ {
+ REQUIRE(inputField.getText() == "-5-");
+ }
+ }
+ }
+ }
+ }
}
}
M module-utils/rotator/include/rotator/Rotator.hpp => module-utils/rotator/include/rotator/Rotator.hpp +1 -1
@@ 44,7 44,7 @@ namespace utils
return path;
}
- uint getFileNumber(const std::string &filename) const
+ std::size_t getFileNumber(const std::string &filename) const
{
const auto position = filename.rfind(".");
if (position == std::string::npos) {
M pure_changelog.md => pure_changelog.md +1 -0
@@ 71,6 71,7 @@
* Fixed screen ghosting after emoji selection
* Fixed incorrect loudspeaker icon in call window when headset was connected during a call
* Fixed invalid screen displayed after missed call
+* Fixed minor issues in the Calculator Application
## [1.5.0 2022-12-20]