Take the boundary of signed negative values into account( Fix issue 1301) (#1336)

* Take the high boundary of signed negative values into account

* UI unit tests for the Copy/Paste menu are added

* Additional corner case for the number notations without negative values
This commit is contained in:
Jack Rainy 2020-09-15 01:11:17 +03:00 committed by GitHub
parent c508cc29ed
commit d256fb6c19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 151 additions and 7 deletions

View File

@ -310,6 +310,9 @@ bool CopyPasteManager::ExpressionRegExMatch(
if (operandMatched) if (operandMatched)
{ {
// Remember the sign of the operand
bool isNegativeValue = operand->Data()[0] == L'-';
// Remove characters that are valid in the expression but we do not want to include in length calculations // Remove characters that are valid in the expression but we do not want to include in length calculations
// or which will break conversion from string-to-ULL. // or which will break conversion from string-to-ULL.
auto operandValue = SanitizeOperand(operand); auto operandValue = SanitizeOperand(operand);
@ -332,7 +335,11 @@ bool CopyPasteManager::ExpressionRegExMatch(
break; break;
} }
if (operandAsULL->Value > maxOperandLengthAndValue.maxValue) // Calculate how much we exceed the maxValue.
// In case we exceed it for 1 only, and working with negative number - that's a corner case for max signed values (e.g. -32768)
bool isOverflow = operandAsULL->Value > maxOperandLengthAndValue.maxValue;
bool isMaxNegativeValue = operandAsULL->Value - 1 == maxOperandLengthAndValue.maxValue;
if (isOverflow && !(isNegativeValue && isMaxNegativeValue))
{ {
expMatched = false; expMatched = false;
break; break;

View File

@ -3,6 +3,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium.Windows; using OpenQA.Selenium.Appium.Windows;
using System; using System;
using OpenQA.Selenium.Interactions;
namespace CalculatorUITestFramework namespace CalculatorUITestFramework
{ {
@ -12,6 +13,8 @@ public class CalculatorResults
private WindowsElement CalculatorAlwaysOnTopResults => this.session.TryFindElementByAccessibilityId("CalculatorAlwaysOnTopResults"); private WindowsElement CalculatorAlwaysOnTopResults => this.session.TryFindElementByAccessibilityId("CalculatorAlwaysOnTopResults");
private WindowsElement CalculatorResult => this.session.TryFindElementByAccessibilityId("CalculatorResults"); private WindowsElement CalculatorResult => this.session.TryFindElementByAccessibilityId("CalculatorResults");
private WindowsElement CalculatorExpression => this.session.TryFindElementByAccessibilityId("CalculatorExpression"); private WindowsElement CalculatorExpression => this.session.TryFindElementByAccessibilityId("CalculatorExpression");
private WindowsElement MenuItemCopy => this.session.TryFindElementByAccessibilityId("CopyMenuItem");
private WindowsElement MenuItemPaste => this.session.TryFindElementByAccessibilityId("PasteMenuItem");
/// <summary> /// <summary>
/// Gets the text from the display control in AoT mode and removes the narrator text that is not displayed in the UI. /// Gets the text from the display control in AoT mode and removes the narrator text that is not displayed in the UI.
@ -61,5 +64,33 @@ public void IsResultsExpressionClear()
throw new Exception("The Calculator Expression is not clear"); throw new Exception("The Calculator Expression is not clear");
} }
} }
/// <summary>
/// Opens the context menu in order to be able to click its items
/// </summary>
private void OpenContextMenu()
{
Actions actions = new Actions(CalculatorResult.WrappedDriver);
// It is important to move not to the centre in order to avoid click on the text
actions.MoveToElement(CalculatorResult, 1,1).ContextClick().Perform();
}
/// <summary>
/// Opens the context menu and clicks the "Copy" item there
/// </summary>
public void ContextMenuItemCopyClick()
{
OpenContextMenu();
MenuItemCopy.Click();
}
/// <summary>
/// Opens the context menu and clicks the "Paste" item there
/// </summary>
public void ContextMenuItemPasteClick()
{
OpenContextMenu();
MenuItemPaste.Click();
}
} }
} }

View File

@ -4,9 +4,7 @@
using CalculatorUITestFramework; using CalculatorUITestFramework;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium; using OpenQA.Selenium;
using OpenQA.Selenium.Appium.Windows;
using System; using System;
using System.Collections.Generic;
namespace CalculatorUITests namespace CalculatorUITests
{ {
@ -890,5 +888,95 @@ public void ThroughCarry_Operator_Hex_RightShift()
Assert.AreEqual("8 0 8", page.CalculatorResults.GetCalculatorResultText()); Assert.AreEqual("8 0 8", page.CalculatorResults.GetCalculatorResultText());
} }
#endregion #endregion
/// <summary>
/// Copy and Paste the numbers into/from the calculator
/// </summary>
#region Copy-Paste operations
[TestMethod]
[Priority(1)]
public void Copy_And_Paste_Simple_Number()
{
page.ProgrammerOperators.BitFlip.Click();
page.ProgrammerOperators.Bit1.Click();
page.CalculatorResults.ContextMenuItemCopyClick();
page.ProgrammerOperators.FullKeypad.Click();
page.StandardOperators.ClearEntryButton.Click();
page.CalculatorResults.ContextMenuItemPasteClick();
Assert.AreEqual("2", page.CalculatorResults.GetCalculatorResultText());
}
[TestMethod]
[Priority(1)]
public void Copy_And_Paste_Invalid_Number()
{
page.ProgrammerOperators.BitFlip.Click();
page.ProgrammerOperators.Bit63.Click();
page.CalculatorResults.ContextMenuItemCopyClick();
page.ProgrammerOperators.FullKeypad.Click();
page.StandardOperators.ClearEntryButton.Click();
page.ProgrammerOperators.QWordButton.Click();
page.CalculatorResults.ContextMenuItemPasteClick();
Assert.AreEqual("Invalid input", page.CalculatorResults.GetCalculatorResultText());
}
[TestMethod]
[Priority(1)]
public void Copy_And_Paste_Big_QWord_Number()
{
page.ProgrammerOperators.BitFlip.Click();
page.ProgrammerOperators.Bit63.Click();
page.CalculatorResults.ContextMenuItemCopyClick();
page.ProgrammerOperators.FullKeypad.Click();
page.StandardOperators.ClearEntryButton.Click();
page.CalculatorResults.ContextMenuItemPasteClick();
Assert.AreEqual("-9,223,372,036,854,775,808", page.CalculatorResults.GetCalculatorResultText());
}
[TestMethod]
[Priority(1)]
public void Copy_And_Paste_Big_DWord_Number()
{
page.ProgrammerOperators.QWordButton.Click();
page.ProgrammerOperators.BitFlip.Click();
page.ProgrammerOperators.Bit31.Click();
page.CalculatorResults.ContextMenuItemCopyClick();
page.ProgrammerOperators.FullKeypad.Click();
page.StandardOperators.ClearEntryButton.Click();
page.CalculatorResults.ContextMenuItemPasteClick();
Assert.AreEqual("-2,147,483,648", page.CalculatorResults.GetCalculatorResultText());
}
[TestMethod]
[Priority(1)]
public void Copy_And_Paste_Big_Word_Number()
{
page.ProgrammerOperators.QWordButton.Click();
page.ProgrammerOperators.DWordButton.Click();
page.ProgrammerOperators.BitFlip.Click();
page.ProgrammerOperators.Bit15.Click();
page.CalculatorResults.ContextMenuItemCopyClick();
page.ProgrammerOperators.FullKeypad.Click();
page.StandardOperators.ClearEntryButton.Click();
page.CalculatorResults.ContextMenuItemPasteClick();
Assert.AreEqual("-32,768", page.CalculatorResults.GetCalculatorResultText());
}
[TestMethod]
[Priority(1)]
public void Copy_And_Paste_Big_Byte_Number()
{
page.ProgrammerOperators.QWordButton.Click();
page.ProgrammerOperators.DWordButton.Click();
page.ProgrammerOperators.WordButton.Click();
page.ProgrammerOperators.BitFlip.Click();
page.ProgrammerOperators.Bit7.Click();
page.CalculatorResults.ContextMenuItemCopyClick();
page.ProgrammerOperators.FullKeypad.Click();
page.StandardOperators.ClearEntryButton.Click();
page.CalculatorResults.ContextMenuItemPasteClick();
Assert.AreEqual("-128", page.CalculatorResults.GetCalculatorResultText());
}
#endregion
} }
} }

View File

@ -261,6 +261,14 @@ namespace CalculatorUnitTests
NumberBase::DecBase, NumberBase::DecBase,
BitLength::BitLengthQWord), BitLength::BitLengthQWord),
L"Verify operand values == max return true."); L"Verify operand values == max return true.");
VERIFY_IS_TRUE(
m_CopyPasteManager->ExpressionRegExMatch(
ref new Vector<String ^>({ L"-9223372036854775808" }),
ViewMode::Programmer,
CategoryGroupType::Calculator,
NumberBase::DecBase,
BitLength::BitLengthQWord),
L"Verify operand values == max negative return true.");
Logger::WriteMessage(L"Verify all operands must match patterns."); Logger::WriteMessage(L"Verify all operands must match patterns.");
VERIFY_IS_TRUE(m_CopyPasteManager->ExpressionRegExMatch( VERIFY_IS_TRUE(m_CopyPasteManager->ExpressionRegExMatch(
@ -950,6 +958,7 @@ namespace CalculatorUnitTests
L"aef", L"aef",
L"ABab", L"ABab",
L"A1a3" /*within boundary*/, L"A1a3" /*within boundary*/,
L"FFFF" /*boundary condition: max allowed number*/,
L"0x1234", L"0x1234",
L"0xab12", L"0xab12",
L"0X1234", L"0X1234",
@ -1046,7 +1055,7 @@ namespace CalculatorUnitTests
L"123*4*-3", L"123*4*-3",
L"123*+4*-3", L"123*+4*-3",
L"9223372036854775807", L"9223372036854775807",
L"-9223372036854775807" /*boundary condition: max/min allowed number*/, L"-9223372036854775808" /*boundary condition: max/min allowed number*/,
L"0n1234", L"0n1234",
L"0N1234", L"0N1234",
L"1234u", L"1234u",
@ -1069,6 +1078,7 @@ namespace CalculatorUnitTests
L"xyz", L"xyz",
L"ABab", L"ABab",
L"e+234", L"e+234",
L"9223372036854775808" /*boundary condition: greater than max allowed number 9223372036854775807*/,
L"9223372036854775809" /*boundary condition: greater than max allowed number 9223372036854775807*/, L"9223372036854775809" /*boundary condition: greater than max allowed number 9223372036854775807*/,
L"SIN(2)", L"SIN(2)",
L"-0n123", L"-0n123",
@ -1145,7 +1155,8 @@ namespace CalculatorUnitTests
L"123*4*-3", L"123*4*-3",
L"123*+4*-3", L"123*+4*-3",
L"32767", L"32767",
L"-32767" /*boundary condition: max/min allowed number*/, L"-32767",
L"-32768" /*boundary condition: max/min allowed number*/,
L"0n1234", L"0n1234",
L"0N1234", L"0N1234",
L"1234u", L"1234u",
@ -1208,7 +1219,8 @@ namespace CalculatorUnitTests
{ {
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", 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"\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= ", L"127%71" }; L"1234ul", L"1234ULL", L"2+2=", L"2+2= ",
L"127%71", L"1777777777777777777777" /*boundary condition: the max allowed number*/ };
String ^ qwordNegativeInput[] = { L"+123", String ^ qwordNegativeInput[] = { L"+123",
L"1.23", L"1.23",
L"1''2", L"1''2",
@ -1226,6 +1238,7 @@ namespace CalculatorUnitTests
L"ABab", L"ABab",
L"e+234", L"e+234",
L"12345678901234567890123" /*boundary condition: greater than max allowed digits 22*/, L"12345678901234567890123" /*boundary condition: greater than max allowed digits 22*/,
L"2000000000000000000000" /*boundary condition: greater than max allowed number*/,
L"SIN(2)", L"SIN(2)",
L"123+-234", L"123+-234",
L"0ot1234", L"0ot1234",
@ -1260,6 +1273,7 @@ namespace CalculatorUnitTests
L"ABab", L"ABab",
L"e+234", L"e+234",
L"377777777771" /*boundary condition: greater than max allowed number 37777777777*/, L"377777777771" /*boundary condition: greater than max allowed number 37777777777*/,
L"40000000000" /*boundary condition: greater than max allowed number 37777777777*/,
L"SIN(2)", L"SIN(2)",
L"123+-234", L"123+-234",
L"0ot1234", L"0ot1234",
@ -1303,6 +1317,7 @@ namespace CalculatorUnitTests
L"ABab", L"ABab",
L"e+234", L"e+234",
L"1777771" /*boundary condition: greater than max allowed number 177777*/, L"1777771" /*boundary condition: greater than max allowed number 177777*/,
L"200000" /*boundary condition: greater than max allowed number 177777*/,
L"SIN(2)", L"SIN(2)",
L"123+-234", L"123+-234",
L"0ot1234", L"0ot1234",
@ -1332,6 +1347,7 @@ namespace CalculatorUnitTests
L"ABab", L"ABab",
L"e+24", L"e+24",
L"477" /*boundary condition: greater than max allowed number 377*/, L"477" /*boundary condition: greater than max allowed number 377*/,
L"400" /*boundary condition: greater than max allowed number 377*/,
L"SIN(2)", L"SIN(2)",
L"123+-34", L"123+-34",
L"0ot123", L"0ot123",
@ -1497,7 +1513,8 @@ namespace CalculatorUnitTests
String 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", ^ 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"\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*/ }; L"1100b", L"1101B", L"1111u", L"1111ul", L"1111ULL", L"10100010",
L"11111111" /*boundary condition: max allowed number*/ };
String ^ byteNegativeInput[] = { L"+10101", String ^ byteNegativeInput[] = { L"+10101",
L"1.01", L"1.01",
L"1''0", L"1''0",
@ -1524,6 +1541,7 @@ namespace CalculatorUnitTests
L"1111uu", L"1111uu",
L"1111ulll", L"1111ulll",
L"101000101" /*boundary condition: greater than max allowed digits 8*/, L"101000101" /*boundary condition: greater than max allowed digits 8*/,
L"100000000" /*boundary condition: greater than max allowed value*/,
L"SIN(01010)", L"SIN(01010)",
L"10+-1010101" }; L"10+-1010101" };