diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/NumberTranslatorTests.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/NumberTranslatorTests.cs new file mode 100644 index 0000000000..e6e7def7c7 --- /dev/null +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTest/NumberTranslatorTests.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Globalization; +using NUnit.Framework; + +namespace Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests +{ + [TestFixture] + public class NumberTranslatorTests + { + [TestCase(null, "en-US")] + [TestCase("de-DE", null)] + public void Create_ThrowError_WhenCalledNullOrEmpty(string sourceCultureName, string targetCultureName) + { + // Arrange + CultureInfo sourceCulture = sourceCultureName != null ? new CultureInfo(sourceCultureName) : null; + CultureInfo targetCulture = targetCultureName != null ? new CultureInfo(targetCultureName) : null; + + // Act + Assert.Catch(() => NumberTranslator.Create(sourceCulture, targetCulture)); + } + + [TestCase("en-US", "en-US")] + [TestCase("en-EN", "en-US")] + [TestCase("de-DE", "en-US")] + public void Create_WhenCalled(string sourceCultureName, string targetCultureName) + { + // Arrange + CultureInfo sourceCulture = new CultureInfo(sourceCultureName); + CultureInfo targetCulture = new CultureInfo(targetCultureName); + + // Act + var translator = NumberTranslator.Create(sourceCulture, targetCulture); + + // Assert + Assert.IsNotNull(translator); + } + + [TestCase(null)] + public void Translate_ThrowError_WhenCalledNull(string input) + { + // Arrange + var translator = NumberTranslator.Create(new CultureInfo("de-DE"), new CultureInfo("en-US")); + + // Act + Assert.Catch(() => translator.Translate(input)); + } + + [TestCase("")] + [TestCase(" ")] + public void Translate_WhenCalledEmpty(string input) + { + // Arrange + var translator = NumberTranslator.Create(new CultureInfo("de-DE"), new CultureInfo("en-US")); + + // Act + var result = translator.Translate(input); + + // Assert + Assert.AreEqual(input, result); + } + + [TestCase("2,0 * 2", "2.0 * 2")] + [TestCase("4 * 3,6 + 9", "4 * 3.6 + 9")] + [TestCase("5,2+6", "5.2+6")] + [TestCase("round(2,5)", "round(2.5)")] + [TestCase("3,3333", "3.3333")] + public void Translate_NoErrors_WhenCalled(string input, string expectedResult) + { + // Arrange + var translator = NumberTranslator.Create(new CultureInfo("de-DE"), new CultureInfo("en-US")); + + // Act + var result = translator.Translate(input); + + // Assert + Assert.IsNotNull(result); + Assert.AreEqual(expectedResult, result); + } + + [TestCase("2.0 * 2", "2,0 * 2")] + [TestCase("4 * 3.6 + 9", "4 * 3,6 + 9")] + [TestCase("5.2+6", "5,2+6")] + [TestCase("round(2.5)", "round(2,5)")] + [TestCase("3.3333", "3,3333")] + public void TranslateBack_NoErrors_WhenCalled(string input, string expectedResult) + { + // Arrange + var translator = NumberTranslator.Create(new CultureInfo("de-DE"), new CultureInfo("en-US")); + + // Act + var result = translator.TranslateBack(input); + + // Assert + Assert.IsNotNull(result); + Assert.AreEqual(expectedResult, result); + } + + [TestCase(".", ",", "2,000,000", "2000000")] + [TestCase(".", ",", "2,000,000.6", "2000000.6")] + [TestCase(",", ".", "2.000.000", "2000000")] + [TestCase(",", ".", "2.000.000,6", "2000000.6")] + public void Translate_RemoveNumberGroupSeparator_WhenCalled(string decimalSeparator, string groupSeparator, string input, string expectedResult) + { + // Arrange + var sourceCulture = new CultureInfo("en-US") + { + NumberFormat = + { + NumberDecimalSeparator = decimalSeparator, + NumberGroupSeparator = groupSeparator, + }, + }; + var translator = NumberTranslator.Create(sourceCulture, new CultureInfo("en-US")); + + // Act + var result = translator.Translate(input); + + // Assert + Assert.IsNotNull(result); + Assert.AreEqual(expectedResult, result); + } + } +} diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Main.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Main.cs index 456b00bb68..4b8957d0cf 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Main.cs @@ -28,7 +28,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator throw new ArgumentNullException(paramName: nameof(query)); } - if (!CalculateHelper.InputValid(query.Search)) + NumberTranslator translator = NumberTranslator.Create(CultureInfo.CurrentCulture, new CultureInfo("en-US")); + var input = translator.Translate(query.Search); + + if (!CalculateHelper.InputValid(input)) { return new List(); } @@ -36,7 +39,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator try { // Using CurrentUICulture since this is user facing - var result = CalculateEngine.Interpret(query.Search, CultureInfo.CurrentUICulture); + var result = CalculateEngine.Interpret(input, CultureInfo.CurrentUICulture); // This could happen for some incorrect queries, like pi(2) if (result.Equals(default(CalculateResult))) diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/NumberTranslator.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/NumberTranslator.cs index 96f1194c20..6fdb639310 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/NumberTranslator.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/NumberTranslator.cs @@ -29,8 +29,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator } /// - /// Create a new - returns null if no number conversion - /// is required between the cultures. + /// Create a new . /// /// source culture /// target culture @@ -44,15 +43,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator if (targetCulture == null) { - throw new ArgumentNullException(paramName: nameof(sourceCulture)); + throw new ArgumentNullException(paramName: nameof(targetCulture)); } - bool conversionRequired = sourceCulture.NumberFormat.NumberDecimalSeparator != targetCulture.NumberFormat.NumberDecimalSeparator - || sourceCulture.NumberFormat.PercentGroupSeparator != targetCulture.NumberFormat.PercentGroupSeparator - || sourceCulture.NumberFormat.NumberGroupSizes != targetCulture.NumberFormat.NumberGroupSizes; - return conversionRequired - ? new NumberTranslator(sourceCulture, targetCulture) - : null; + return new NumberTranslator(sourceCulture, targetCulture); } ///