From 2f8b94e5ab951b2ddcc99459ae33d3a30f5ffafa Mon Sep 17 00:00:00 2001 From: Petr Sramek Date: Mon, 1 Jan 2024 23:31:08 +0100 Subject: [PATCH] memory allocation optimized --- .../DecodePerformanceBenchmark.cs | 26 +- .../EncodePerformanceBenchmark.cs | 12 +- src/DropoutCoder.PolylineAlgorithm.csproj | 3 + src/Encoding/PolylineEncodingBase.cs | 2 - src/PolylineAlgorithm.cs | 28 +- tests/Defaults.cs | 118 +++--- tests/Encoding/PolylineEncodingBaseTest.cs | 343 +++++++++--------- tests/Encoding/PolylineEncodingTest.cs | 77 ++-- tests/PolylineAlgorithmTest.cs | 307 ++++++++-------- tests/Properties/AssemblyInfo.cs | 1 - tests/Validation/CoordinateValidatorTest.cs | 229 ++++++------ 11 files changed, 601 insertions(+), 545 deletions(-) diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs index fd4ca47b..43289f5d 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/DecodePerformanceBenchmark.cs @@ -2,12 +2,12 @@ { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Engines; + using System; [MemoryDiagnoser] public class DecodePerformanceBenchmark { private Consumer _consumer = new Consumer(); - public static IEnumerable<(int, char[])> Polylines() { yield return (1, "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI".ToCharArray()); @@ -21,15 +21,15 @@ public class DecodePerformanceBenchmark [Benchmark] [ArgumentsSource(nameof(Polylines))] - public void Decode_V2((int, char[]) arg) => V2.Decode(arg.Item2).Consume(_consumer); + public void Decode_V1_Parallel((int, char[]) arg) => Parallel.For(0, 100, (i) => V1.Decode(arg.Item2).Consume(_consumer)); [Benchmark] [ArgumentsSource(nameof(Polylines))] - public void Decode_V1_Parallel((int, char[]) arg) => Parallel.For(100, 200, (i) => V1.Decode(arg.Item2).Consume(_consumer)); + public void Decode_V2((int, char[]) arg) => V2.Decode(arg.Item2).Consume(_consumer); [Benchmark] [ArgumentsSource(nameof(Polylines))] - public void Decode_V2_Parallel((int, char[]) arg) => Parallel.For(100, 200, (i) => V2.Decode(arg.Item2).Consume(_consumer)); + public void Decode_V2_Parallel((int, char[]) arg) => Parallel.For(0, 100, (i) => V2.Decode(arg.Item2).Consume(_consumer)); private class V1 { @@ -125,18 +125,18 @@ private class V2 throw new ArgumentException(nameof(polyline)); } - int index = 0; + int offset = 0; int latitude = 0; int longitude = 0; - while (index < polyline.Length) + while (offset < polyline.Length) { - if (!TryCalculateNext(ref polyline, ref index, ref latitude)) + if (!TryCalculateNext(ref polyline, ref offset, ref latitude)) { throw new InvalidOperationException(); } - if (!TryCalculateNext(ref polyline, ref index, ref longitude)) + if (!TryCalculateNext(ref polyline, ref offset, ref longitude)) { throw new InvalidOperationException(); } @@ -152,7 +152,7 @@ private class V2 } } - private static bool TryCalculateNext(ref char[] polyline, ref int index, ref int value) + private static bool TryCalculateNext(ref char[] polyline, ref int offset, ref int value) { int chunk; int sum = 0; @@ -160,12 +160,12 @@ private static bool TryCalculateNext(ref char[] polyline, ref int index, ref int do { - chunk = polyline[index++] - Constants.ASCII.QuestionMark; + chunk = polyline[offset++] - Constants.ASCII.QuestionMark; sum |= (chunk & Constants.ASCII.UnitSeparator) << shifter; shifter += Constants.ShiftLength; - } while (chunk >= Constants.ASCII.Space && index < polyline.Length); + } while (chunk >= Constants.ASCII.Space && offset < polyline.Length); - if (index >= polyline.Length && chunk >= Constants.ASCII.Space) + if (offset >= polyline.Length && chunk >= Constants.ASCII.Space) return false; value += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1; @@ -175,7 +175,7 @@ private static bool TryCalculateNext(ref char[] polyline, ref int index, ref int private static double GetDoubleRepresentation(int value) { - return Convert.ToDouble(value) / Constants.Precision; + return value / Constants.Precision; } public static class CoordinateValidator diff --git a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs index dff6e192..d7a75e02 100644 --- a/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs +++ b/benchmarks/DropoutCoder.PolylineAlgorithm.Implementation.Benchmarks/EncodePerformanceBenchmark.cs @@ -137,8 +137,8 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo EnsureCoordinates(coordinates); - int lastLatitude = 0; - int lastLongitude = 0; + int previousLatitude = 0; + int previousLongitude = 0; var sb = _pool.Get(); @@ -147,11 +147,11 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo int latitude = GetIntegerRepresentation(coordinate.Latitude); int longitude = GetIntegerRepresentation(coordinate.Longitude); - sb.Append(GetEncodedCharacters(latitude - lastLatitude).ToArray()); - sb.Append(GetEncodedCharacters(longitude - lastLongitude).ToArray()); + sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); + sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); - lastLatitude = latitude; - lastLongitude = longitude; + previousLatitude = latitude; + previousLongitude = longitude; } var result = sb.ToString(); diff --git a/src/DropoutCoder.PolylineAlgorithm.csproj b/src/DropoutCoder.PolylineAlgorithm.csproj index e7dd8e2e..9972fb37 100644 --- a/src/DropoutCoder.PolylineAlgorithm.csproj +++ b/src/DropoutCoder.PolylineAlgorithm.csproj @@ -10,6 +10,9 @@ + + + True diff --git a/src/Encoding/PolylineEncodingBase.cs b/src/Encoding/PolylineEncodingBase.cs index b2107a7a..b3de4cfb 100644 --- a/src/Encoding/PolylineEncodingBase.cs +++ b/src/Encoding/PolylineEncodingBase.cs @@ -3,8 +3,6 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -using DropoutCoder.PolylineAlgorithm; - namespace DropoutCoder.PolylineAlgorithm.Encoding { using System; diff --git a/src/PolylineAlgorithm.cs b/src/PolylineAlgorithm.cs index 6dbb7e0f..1f700191 100644 --- a/src/PolylineAlgorithm.cs +++ b/src/PolylineAlgorithm.cs @@ -6,6 +6,7 @@ namespace DropoutCoder.PolylineAlgorithm { using DropoutCoder.PolylineAlgorithm.Validation; + using Microsoft.Extensions.ObjectPool; using System; using System.Collections.Generic; using System.Linq; @@ -16,6 +17,8 @@ namespace DropoutCoder.PolylineAlgorithm /// public static class PolylineAlgorithm { + private static readonly ObjectPool _pool = new DefaultObjectPoolProvider().CreateStringBuilderPool(5, 250); + #region Methods /// @@ -37,7 +40,6 @@ public static class PolylineAlgorithm int index = 0; int latitude = 0; int longitude = 0; - var result = new List<(double Latitude, double Longitude)>(); // Looping through encoded polyline char array while (index < polyline.Length) @@ -61,10 +63,8 @@ public static class PolylineAlgorithm throw new InvalidOperationException(ExceptionMessageResource.PolylineCharArrayIsMalformed); } - result.Add(coordinate); + yield return coordinate; } - - return result; } /// @@ -85,9 +85,9 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo EnsureCoordinates(coordinates); // Initializing local variables - int lastLat = 0; - int lastLng = 0; - var sb = new StringBuilder(); + int previousLatitude = 0; + int previousLongitude = 0; + var sb = _pool.Get(); // Looping over coordinates and building encoded result foreach (var coordinate in coordinates) @@ -95,14 +95,18 @@ public static string Encode(IEnumerable<(double Latitude, double Longitude)> coo int latitude = GetIntegerRepresentation(coordinate.Latitude); int longitude = GetIntegerRepresentation(coordinate.Longitude); - sb.Append(GetEncodedCharacters(latitude - lastLat).ToArray()); - sb.Append(GetEncodedCharacters(longitude - lastLng).ToArray()); + sb.Append(GetEncodedCharacters(latitude - previousLatitude).ToArray()); + sb.Append(GetEncodedCharacters(longitude - previousLongitude).ToArray()); - lastLat = latitude; - lastLng = longitude; + previousLatitude = latitude; + previousLongitude = longitude; } - return sb.ToString(); + var result = sb.ToString(); + + _pool.Return(sb); + + return result; } /// diff --git a/tests/Defaults.cs b/tests/Defaults.cs index 380d416c..bc54f777 100644 --- a/tests/Defaults.cs +++ b/tests/Defaults.cs @@ -3,71 +3,75 @@ // Licensed under the MIT License. See LICENSE file in the project root for full license information. // -namespace DropoutCoder.PolylineAlgorithm.Tests { - using System; - using System.Collections.Generic; - using System.Linq; +namespace DropoutCoder.PolylineAlgorithm.Tests +{ + using System; + using System.Collections.Generic; + using System.Linq; - /// - /// Defines default values and objects used for testing purposes - /// - public static class Defaults { - /// - /// Defines default decoded values and objects udśed for testing purposes - /// - public static class Coordinate { - #region Fields + /// + /// Defines default values and objects used for testing purposes + /// + public static class Defaults + { + /// + /// Defines default decoded values and objects udśed for testing purposes + /// + public static class Coordinate + { + #region Fields - /// - /// Defines empty range of coordinates. Equals to decoded - /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Empty = Enumerable.Empty<(double Latitude, double Longitude)>(); + /// + /// Defines empty range of coordinates. Equals to decoded + /// + public static readonly IEnumerable<(double Latitude, double Longitude)> Empty = Enumerable.Empty<(double Latitude, double Longitude)>(); - /// - /// Defines range of invalid coordinates. Equals to decoded - /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Invalid = new[] { - (149.47383, 259.06250), - (-158.37407, 225.31250), - (152.99363, -220.93750), - (-144.49024, -274.37500) - }; + /// + /// Defines range of invalid coordinates. Equals to decoded + /// + public static readonly IEnumerable<(double Latitude, double Longitude)> Invalid = new[] { + (149.47383, 259.06250), + (-158.37407, 225.31250), + (152.99363, -220.93750), + (-144.49024, -274.37500) + }; - /// - /// Defines range of valid coordinates. Equals to decoded - /// - public static readonly IEnumerable<(double Latitude, double Longitude)> Valid = new[] { - (49.47383, 59.06250), - (-58.37407, 25.31250), - (52.99363, -120.93750), - (-44.49024, -174.37500) - }; + /// + /// Defines range of valid coordinates. Equals to decoded + /// + public static readonly IEnumerable<(double Latitude, double Longitude)> Valid = new[] { + (49.47383, 59.06250), + (-58.37407, 25.31250), + (52.99363, -120.93750), + (-44.49024, -174.37500) + }; - #endregion - } + #endregion + } - /// - /// Defines default encoded values and objects udśed for testing purposes - /// - public static class Polyline { - #region Fields + /// + /// Defines default encoded values and objects udśed for testing purposes + /// + public static class Polyline + { + #region Fields - /// - /// Defines empty string of polyline encoded coordinates. Equals to encoded - /// - public static readonly string Empty = String.Empty; + /// + /// Defines empty string of polyline encoded coordinates. Equals to encoded + /// + public static readonly string Empty = String.Empty; - /// - /// Defines polyline encoded range of invalid coordinates. Equals to encoded - /// - public static readonly string Invalid = "mnc~Qsm_ja@"; + /// + /// Defines polyline encoded range of invalid coordinates. Equals to encoded + /// + public static readonly string Invalid = "mnc~Qsm_ja@"; - /// - /// Defines polyline encoded range of valid coordinates. Equals to encoded - /// - public static readonly string Valid = "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; + /// + /// Defines polyline encoded range of valid coordinates. Equals to encoded + /// + public static readonly string Valid = "mz}lHssngJj`gqSnx~lEcovfTnms{Zdy~qQj_deI"; - #endregion - } - } + #endregion + } + } } diff --git a/tests/Encoding/PolylineEncodingBaseTest.cs b/tests/Encoding/PolylineEncodingBaseTest.cs index 4dbb0bc9..94993c83 100644 --- a/tests/Encoding/PolylineEncodingBaseTest.cs +++ b/tests/Encoding/PolylineEncodingBaseTest.cs @@ -5,175 +5,192 @@ namespace DropoutCoder.PolylineAlgorithm.Tests.Encoding { + using DropoutCoder.PolylineAlgorithm.Encoding; + using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Linq; - using DropoutCoder.PolylineAlgorithm.Encoding; - using Microsoft.VisualStudio.TestTools.UnitTesting; /// /// Defines the /// [TestClass] - [TestCategory(nameof(PolylineEncodingBase<(double latitude, double longitude)>))] - public class PolylineEncodingBaseTest : PolylineEncodingBase<(double latitude, double longitude)> { - #region Methods - - /// - /// The Decode_NullInput - /// - [TestMethod] - public void Decode_NullInput_ThrowsException() { - // Arrange - var nullPolylineString = (string)null; - - // Act - void DecodeNullPolylineString() { - this.Decode(nullPolylineString); - } - - // Assert - Assert.ThrowsException(() => DecodeNullPolylineString()); - } - - /// - /// The Decode_EmptyInput - /// - [TestMethod] - public void Decode_EmptyInput_ThrowsException() { - // Arrange - var emptyPolylineString = Defaults.Polyline.Empty; - - // Act - void DecodeEmptyPolylineString() { - this.Decode(emptyPolylineString); - } - - // Assert - Assert.ThrowsException(() => DecodeEmptyPolylineString()); - } - - /// - /// The Decode_InvalidInput - /// - [TestMethod] - public void Decode_InvalidInput_ThrowsException() { - // Arrange - var invalidPolylineString = Defaults.Polyline.Invalid; - - // Act - void DecodeInvalidPolylineString() { - this.Decode(Defaults.Polyline.Invalid); - } - - // Assert - Assert.ThrowsException(() => DecodeInvalidPolylineString()); - } - - /// - /// The Decode_ValidInput - /// - [TestMethod] - public void Decode_ValidInput_AreEquivalent() { - // Arrange - var validPolylineString = Defaults.Polyline.Valid; - - // Act - var result = this.Decode(validPolylineString); - - // Assert - CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); - } - - /// - /// The Encode_NullInput - /// - [TestMethod] - public void Encode_NullInput_ThrowsException() { - // Arrange - var nullCoordinates = (IEnumerable<(double, double)>)null; - - // Act - void EncodeNullCoordinateCollection() { - this.Encode(nullCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeNullCoordinateCollection()); - } - - /// - /// The Encode_EmptyInput - /// - [TestMethod] - public void Encode_EmptyInput_ThrowsException() { - // Arrange - var emptyCoordinates = Defaults.Coordinate.Empty; - - // Act - void EncodeEmptyCoordinateCollection() { - this.Encode(emptyCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeEmptyCoordinateCollection()); - } - - /// - /// The Encode_InvalidInput - /// - [TestMethod] - public void Encode_InvalidInput_ThrowsException() { - // Arrange - var invalidCoordinates = Defaults.Coordinate.Invalid; - - // Act - void EncodeInvalidCoordinateCollection() { - this.Encode(invalidCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeInvalidCoordinateCollection()); - } - - /// - /// The Encode_ValidInput - /// - [TestMethod] - public void Encode_ValidInput_AreEqual() { - // Arrange - var validCoordinateCollection = Defaults.Coordinate.Valid; - - // Act - var result = this.Encode(validCoordinateCollection); - - // Assert - Assert.AreEqual(Defaults.Polyline.Valid, result); - } - - #region Overriden methods - - /// - /// The CreateResult - /// - /// The - /// The - /// The - protected override (double latitude, double longitude) CreateResult(double latitude, double longitude) { - return (latitude, longitude); - } - - /// - /// The GetCoordinate - /// - /// The - /// The - protected override (double Latitude, double Longitude) GetCoordinate((double latitude, double longitude) source) { - return source; - } - - #endregion - - #endregion - } + [TestCategory(nameof(PolylineEncodingBase<(double latitude, double longitude)>))] + public class PolylineEncodingBaseTest : PolylineEncodingBase<(double latitude, double longitude)> + { + #region Methods + + /// + /// The Decode_NullInput + /// + [TestMethod] + public void Decode_NullInput_ThrowsException() + { + // Arrange + var nullPolylineString = (string)null; + + // Act + void DecodeNullPolylineString() + { + this.Decode(nullPolylineString).ToArray(); + } + + // Assert + Assert.ThrowsException(() => DecodeNullPolylineString()); + } + + /// + /// The Decode_EmptyInput + /// + [TestMethod] + public void Decode_EmptyInput_ThrowsException() + { + // Arrange + var emptyPolylineString = Defaults.Polyline.Empty; + + // Act + void DecodeEmptyPolylineString() + { + this.Decode(emptyPolylineString).ToArray(); + } + + // Assert + Assert.ThrowsException(() => DecodeEmptyPolylineString()); + } + + /// + /// The Decode_InvalidInput + /// + [TestMethod] + public void Decode_InvalidInput_ThrowsException() + { + // Arrange + var invalidPolylineString = Defaults.Polyline.Invalid; + + // Act + void DecodeInvalidPolylineString() + { + this.Decode(Defaults.Polyline.Invalid).ToArray(); + } + + // Assert + Assert.ThrowsException(() => DecodeInvalidPolylineString()); + } + + /// + /// The Decode_ValidInput + /// + [TestMethod] + public void Decode_ValidInput_AreEquivalent() + { + // Arrange + var validPolylineString = Defaults.Polyline.Valid; + + // Act + var result = this.Decode(validPolylineString).ToArray(); + + // Assert + CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); + } + + /// + /// The Encode_NullInput + /// + [TestMethod] + public void Encode_NullInput_ThrowsException() + { + // Arrange + var nullCoordinates = (IEnumerable<(double, double)>)null; + + // Act + void EncodeNullCoordinateCollection() + { + this.Encode(nullCoordinates); + } + + // Assert + Assert.ThrowsException(() => EncodeNullCoordinateCollection()); + } + + /// + /// The Encode_EmptyInput + /// + [TestMethod] + public void Encode_EmptyInput_ThrowsException() + { + // Arrange + var emptyCoordinates = Defaults.Coordinate.Empty; + + // Act + void EncodeEmptyCoordinateCollection() + { + this.Encode(emptyCoordinates); + } + + // Assert + Assert.ThrowsException(() => EncodeEmptyCoordinateCollection()); + } + + /// + /// The Encode_InvalidInput + /// + [TestMethod] + public void Encode_InvalidInput_ThrowsException() + { + // Arrange + var invalidCoordinates = Defaults.Coordinate.Invalid; + + // Act + void EncodeInvalidCoordinateCollection() + { + this.Encode(invalidCoordinates); + } + + // Assert + Assert.ThrowsException(() => EncodeInvalidCoordinateCollection()); + } + + /// + /// The Encode_ValidInput + /// + [TestMethod] + public void Encode_ValidInput_AreEqual() + { + // Arrange + var validCoordinateCollection = Defaults.Coordinate.Valid; + + // Act + var result = this.Encode(validCoordinateCollection); + + // Assert + Assert.AreEqual(Defaults.Polyline.Valid, result); + } + + #region Overriden methods + + /// + /// The CreateResult + /// + /// The + /// The + /// The + protected override (double latitude, double longitude) CreateResult(double latitude, double longitude) + { + return (latitude, longitude); + } + + /// + /// The GetCoordinate + /// + /// The + /// The + protected override (double Latitude, double Longitude) GetCoordinate((double latitude, double longitude) source) + { + return source; + } + + #endregion + + #endregion + } } diff --git a/tests/Encoding/PolylineEncodingTest.cs b/tests/Encoding/PolylineEncodingTest.cs index df499114..d7fdf05f 100644 --- a/tests/Encoding/PolylineEncodingTest.cs +++ b/tests/Encoding/PolylineEncodingTest.cs @@ -5,48 +5,51 @@ namespace DropoutCoder.PolylineAlgorithm.Tests.Encoding { - using System.Linq; using DropoutCoder.PolylineAlgorithm.Encoding; using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Linq; /// /// Defines the /// [TestClass] - [TestCategory(nameof(PolylineEncoding))] - public class PolylineEncodingTest : PolylineEncoding { - #region Methods - - /// - /// The CreateResult_AreEqual - /// - [TestMethod] - public void CreateResult_AreEqual() { - // Arrange - var validCoordinate = Defaults.Coordinate.Valid.First(); - - // Act - var result = this.CreateResult(validCoordinate.Latitude, validCoordinate.Longitude); - - // Assert - Assert.AreEqual(validCoordinate, result); - } - - /// - /// The GetCoordinate_AreEqual - /// - [TestMethod] - public void GetCoordinate_AreEqual() { - // Arrange - var validCoordinate = Defaults.Coordinate.Valid.First(); - - // Act - var result = this.GetCoordinate(validCoordinate); - - // Assert - Assert.AreEqual(validCoordinate, result); - } - - #endregion - } + [TestCategory(nameof(PolylineEncoding))] + public class PolylineEncodingTest : PolylineEncoding + { + #region Methods + + /// + /// The CreateResult_AreEqual + /// + [TestMethod] + public void CreateResult_AreEqual() + { + // Arrange + var validCoordinate = Defaults.Coordinate.Valid.First(); + + // Act + var result = this.CreateResult(validCoordinate.Latitude, validCoordinate.Longitude); + + // Assert + Assert.AreEqual(validCoordinate, result); + } + + /// + /// The GetCoordinate_AreEqual + /// + [TestMethod] + public void GetCoordinate_AreEqual() + { + // Arrange + var validCoordinate = Defaults.Coordinate.Valid.First(); + + // Act + var result = this.GetCoordinate(validCoordinate); + + // Assert + Assert.AreEqual(validCoordinate, result); + } + + #endregion + } } diff --git a/tests/PolylineAlgorithmTest.cs b/tests/PolylineAlgorithmTest.cs index 257b1dc5..bb1bbce8 100644 --- a/tests/PolylineAlgorithmTest.cs +++ b/tests/PolylineAlgorithmTest.cs @@ -5,158 +5,173 @@ namespace DropoutCoder.PolylineAlgorithm.Tests { + using DropoutCoder.PolylineAlgorithm; + using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Linq; - using DropoutCoder.PolylineAlgorithm; - using Microsoft.VisualStudio.TestTools.UnitTesting; /// /// Defines the /// [TestClass] - [TestCategory(nameof(PolylineAlgorithm))] - public class PolylineAlgorithmTest { - #region Methods - - /// - /// Method is testing method. Empty [] is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_EmptyInput_ThrowsException() { - // Arrange - var emptyPolylineCharArray = Defaults.Polyline.Empty.ToCharArray(); - - // Act - void DecodeEmptyPolylineCharArray() { - PolylineAlgorithm.Decode(emptyPolylineCharArray); - } - - // Assert - Assert.ThrowsException(() => DecodeEmptyPolylineCharArray()); - } - - /// - /// Method is testing method. [] with invalid coordinates is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_InvalidInput_ThrowsException() { - // Arrange - var invalidPolylineCharrArray = Defaults.Polyline.Invalid.ToCharArray(); - - // Act - void DecodeInvalidPolylineCharArray() { - PolylineAlgorithm.Decode(invalidPolylineCharrArray); - } - - // Assert - Assert.ThrowsException(() => DecodeInvalidPolylineCharArray()); - } - - /// - /// Method is testing method. is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_NullInput_ThrowsException() { - // Arrange - var nullPolylineCharArray = (char[])null; - - // Act - void DecodeNullPolylineCharArray() { - PolylineAlgorithm.Decode(nullPolylineCharArray); - } - - // Assert - Assert.ThrowsException(() => DecodeNullPolylineCharArray()); - } - - /// - /// Method is testing method. [] with valid coordinates is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Decode_ValidInput_AreEquivalent() { - // Arrange - var validPolylineCharArray = Defaults.Polyline.Valid.ToCharArray(); - - // Act - var result = PolylineAlgorithm.Decode(validPolylineCharArray); - - // Assert - CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); - } - - /// - /// Method is testing method. Empty is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Encode_EmptyInput_ThrowsException() { - // Arrange - var emptyCoordinates = Defaults.Coordinate.Empty; - - // Act - void EncodeEmptyCoordinates() { - PolylineAlgorithm.Encode(emptyCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeEmptyCoordinates()); - } - - /// - /// The Encode_InvalidInput - /// - [TestMethod] - public void Encode_InvalidInput_ThrowsException() { - // Arrange - var invalidCoordinates = Defaults.Coordinate.Invalid; - - // Act - void EncodeInvalidCoordinates() { - PolylineAlgorithm.Encode(invalidCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeInvalidCoordinates()); - } - - /// - /// Method is testing method. is passed as parameter. - /// Expected result is . - /// - [TestMethod] - public void Encode_NullInput_ThrowsException() { - // Arrange - var nullCoordinates = (IEnumerable<(double, double)>)null; - - // Act - void EncodeNullCoordinates() { - PolylineAlgorithm.Encode(nullCoordinates); - } - - // Assert - Assert.ThrowsException(() => EncodeNullCoordinates()); - } - - /// - /// The Encode_ValidInput - /// - [TestMethod] - public void Encode_ValidInput_AreEqual() { - // Arrange - var validCoordinates = Defaults.Coordinate.Valid; - - // Act - var result = PolylineAlgorithm.Encode(validCoordinates); - - // Assert - Assert.AreEqual(Defaults.Polyline.Valid, result); - } - - #endregion - } + [TestCategory(nameof(PolylineAlgorithm))] + public class PolylineAlgorithmTest + { + #region Methods + + /// + /// Method is testing method. Empty [] is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_EmptyInput_ThrowsException() + { + // Arrange + var emptyPolylineCharArray = Defaults.Polyline.Empty.ToCharArray(); + + // Act + void DecodeEmptyPolylineCharArray() + { + PolylineAlgorithm.Decode(emptyPolylineCharArray).ToArray(); + } + + // Assert + Assert.ThrowsException(() => DecodeEmptyPolylineCharArray()); + } + + /// + /// Method is testing method. [] with invalid coordinates is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_InvalidInput_ThrowsException() + { + // Arrange + var invalidPolylineCharrArray = Defaults.Polyline.Invalid.ToCharArray(); + + // Act + void DecodeInvalidPolylineCharArray() + { + PolylineAlgorithm.Decode(invalidPolylineCharrArray).ToArray(); + } + + // Assert + Assert.ThrowsException(() => DecodeInvalidPolylineCharArray()); + } + + /// + /// Method is testing method. is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_NullInput_ThrowsException() + { + // Arrange + var nullPolylineCharArray = (char[])null; + + // Act + void DecodeNullPolylineCharArray() + { + PolylineAlgorithm.Decode(nullPolylineCharArray).ToArray(); + } + + // Assert + Assert.ThrowsException(() => DecodeNullPolylineCharArray()); + } + + /// + /// Method is testing method. [] with valid coordinates is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Decode_ValidInput_AreEquivalent() + { + // Arrange + var validPolylineCharArray = Defaults.Polyline.Valid.ToCharArray(); + + // Act + var result = PolylineAlgorithm.Decode(validPolylineCharArray); + + // Assert + CollectionAssert.AreEquivalent(Defaults.Coordinate.Valid.ToList(), result.ToList()); + } + + /// + /// Method is testing method. Empty is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Encode_EmptyInput_ThrowsException() + { + // Arrange + var emptyCoordinates = Defaults.Coordinate.Empty; + + // Act + void EncodeEmptyCoordinates() + { + PolylineAlgorithm.Encode(emptyCoordinates); + } + + // Assert + Assert.ThrowsException(() => EncodeEmptyCoordinates()); + } + + /// + /// The Encode_InvalidInput + /// + [TestMethod] + public void Encode_InvalidInput_ThrowsException() + { + // Arrange + var invalidCoordinates = Defaults.Coordinate.Invalid; + + // Act + void EncodeInvalidCoordinates() + { + PolylineAlgorithm.Encode(invalidCoordinates); + } + + // Assert + Assert.ThrowsException(() => EncodeInvalidCoordinates()); + } + + /// + /// Method is testing method. is passed as parameter. + /// Expected result is . + /// + [TestMethod] + public void Encode_NullInput_ThrowsException() + { + // Arrange + var nullCoordinates = (IEnumerable<(double, double)>)null; + + // Act + void EncodeNullCoordinates() + { + PolylineAlgorithm.Encode(nullCoordinates); + } + + // Assert + Assert.ThrowsException(() => EncodeNullCoordinates()); + } + + /// + /// The Encode_ValidInput + /// + [TestMethod] + public void Encode_ValidInput_AreEqual() + { + // Arrange + var validCoordinates = Defaults.Coordinate.Valid; + + // Act + var result = PolylineAlgorithm.Encode(validCoordinates); + + // Assert + Assert.AreEqual(Defaults.Polyline.Valid, result); + } + + #endregion + } } diff --git a/tests/Properties/AssemblyInfo.cs b/tests/Properties/AssemblyInfo.cs index ff7527e5..63a08d67 100644 --- a/tests/Properties/AssemblyInfo.cs +++ b/tests/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Test = Microsoft.VisualStudio.TestTools.UnitTesting; [assembly: AssemblyTrademark("")] diff --git a/tests/Validation/CoordinateValidatorTest.cs b/tests/Validation/CoordinateValidatorTest.cs index 64ccb7e5..1d3f6540 100644 --- a/tests/Validation/CoordinateValidatorTest.cs +++ b/tests/Validation/CoordinateValidatorTest.cs @@ -12,112 +12,125 @@ namespace DropoutCoder.PolylineAlgorithm.Tests.Validation /// Defines the /// [TestClass] - [TestCategory(nameof(CoordinateValidator))] - public class CoordinateValidatorTest { - #region Methods - - /// - /// The IsValid_InvalidInput - /// - [TestMethod] - public void IsValid_InvalidInput_IsFalse() { - // Act - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) { - // Arrange - var result = CoordinateValidator.IsValid(item); - - // Assert - Assert.IsFalse(result); - } - } - - /// - /// The IsValid_ValidInput - /// - [TestMethod] - public void IsValid_ValidInput_IsTrue() { - // Act - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach (var item in validCoordinateCollection) { - // Arrange - var result = CoordinateValidator.IsValid(item); - - // Assert - Assert.IsTrue(result); - } - } - - /// - /// The IsValidLatitude_InvalidInput - /// - [TestMethod] - public void IsValidLatitude_InvalidInput_IsFalse() { - // Act - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) { - // Act - var result = CoordinateValidator.IsValidLatitude(item.Latitude); - - // Arrange - Assert.IsFalse(result); - } - } - - /// - /// The IsValidLatitude_ValidInput - /// - [TestMethod] - public void IsValidLatitude_ValidInput_IsTrue() { - // Arrange - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach ((double Latitude, double Longitude) in validCoordinateCollection) { - // Act - var result = CoordinateValidator.IsValidLatitude(Latitude); - - // Assert - Assert.IsTrue(result); - } - } - - /// - /// The IsValidLongitude_InvalidInput - /// - [TestMethod] - public void IsValidLongitude_InvalidInput_IsFalse() { - // Arrange - var invalidCoordinateCollection = Defaults.Coordinate.Invalid; - - foreach (var item in invalidCoordinateCollection) { - // Act - var result = CoordinateValidator.IsValidLongitude(item.Longitude); - - // Assert - Assert.IsFalse(result); - } - } - - /// - /// The IsValidLongitude_ValidInput - /// - [TestMethod] - public void IsValidLongitude_ValidInput_IsTrue() { - // Arrange - var validCoordinateCollection = Defaults.Coordinate.Valid; - - foreach (var item in validCoordinateCollection) { - // Act - var result = CoordinateValidator.IsValidLongitude(item.Longitude); - - // Assert - Assert.IsTrue(result); - } - } - - #endregion - } + [TestCategory(nameof(CoordinateValidator))] + public class CoordinateValidatorTest + { + #region Methods + + /// + /// The IsValid_InvalidInput + /// + [TestMethod] + public void IsValid_InvalidInput_IsFalse() + { + // Act + var invalidCoordinateCollection = Defaults.Coordinate.Invalid; + + foreach (var item in invalidCoordinateCollection) + { + // Arrange + var result = CoordinateValidator.IsValid(item); + + // Assert + Assert.IsFalse(result); + } + } + + /// + /// The IsValid_ValidInput + /// + [TestMethod] + public void IsValid_ValidInput_IsTrue() + { + // Act + var validCoordinateCollection = Defaults.Coordinate.Valid; + + foreach (var item in validCoordinateCollection) + { + // Arrange + var result = CoordinateValidator.IsValid(item); + + // Assert + Assert.IsTrue(result); + } + } + + /// + /// The IsValidLatitude_InvalidInput + /// + [TestMethod] + public void IsValidLatitude_InvalidInput_IsFalse() + { + // Act + var invalidCoordinateCollection = Defaults.Coordinate.Invalid; + + foreach (var item in invalidCoordinateCollection) + { + // Act + var result = CoordinateValidator.IsValidLatitude(item.Latitude); + + // Arrange + Assert.IsFalse(result); + } + } + + /// + /// The IsValidLatitude_ValidInput + /// + [TestMethod] + public void IsValidLatitude_ValidInput_IsTrue() + { + // Arrange + var validCoordinateCollection = Defaults.Coordinate.Valid; + + foreach ((double Latitude, double Longitude) in validCoordinateCollection) + { + // Act + var result = CoordinateValidator.IsValidLatitude(Latitude); + + // Assert + Assert.IsTrue(result); + } + } + + /// + /// The IsValidLongitude_InvalidInput + /// + [TestMethod] + public void IsValidLongitude_InvalidInput_IsFalse() + { + // Arrange + var invalidCoordinateCollection = Defaults.Coordinate.Invalid; + + foreach (var item in invalidCoordinateCollection) + { + // Act + var result = CoordinateValidator.IsValidLongitude(item.Longitude); + + // Assert + Assert.IsFalse(result); + } + } + + /// + /// The IsValidLongitude_ValidInput + /// + [TestMethod] + public void IsValidLongitude_ValidInput_IsTrue() + { + // Arrange + var validCoordinateCollection = Defaults.Coordinate.Valid; + + foreach (var item in validCoordinateCollection) + { + // Act + var result = CoordinateValidator.IsValidLongitude(item.Longitude); + + // Assert + Assert.IsTrue(result); + } + } + + #endregion + } }