From 058923a39d0c2e3ef9758085eeb61bf8b90490a1 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 5 Mar 2024 12:14:55 -0500 Subject: [PATCH] Add comparison tests --- .../Compare/NaturalComparerTests.cs | 38 ++++++++++++ .../Compare/NaturalComparerUtilTests.cs | 59 +++++++++++++++++++ .../SabreTools.Matching.Test.csproj | 1 + .../Compare/NaturalComparer.cs | 20 ++----- .../Compare/NaturalComparerUtil.cs | 21 ++++--- .../Compare/NaturalReversedComparer.cs | 20 ++----- 6 files changed, 120 insertions(+), 39 deletions(-) create mode 100644 SabreTools.Matching.Test/Compare/NaturalComparerTests.cs create mode 100644 SabreTools.Matching.Test/Compare/NaturalComparerUtilTests.cs diff --git a/SabreTools.Matching.Test/Compare/NaturalComparerTests.cs b/SabreTools.Matching.Test/Compare/NaturalComparerTests.cs new file mode 100644 index 0000000..8aaf18d --- /dev/null +++ b/SabreTools.Matching.Test/Compare/NaturalComparerTests.cs @@ -0,0 +1,38 @@ +using System; +using System.Linq; +using SabreTools.Matching.Compare; +using Xunit; + +namespace SabreTools.Matching.Test.Compare +{ + public class NaturalComparerTests + { + [Fact] + public void NaturalComparerListSortTest() + { + // Setup arrays + string[] sortable = ["0", "100", "5", "2", "1000"]; + string[] expected = ["0", "2", "5", "100", "1000"]; + + // Run sorting on array + Array.Sort(sortable, new NaturalComparer()); + + // Check the output + Assert.True(sortable.SequenceEqual(expected)); + } + + [Fact] + public void NaturalReversedComparerListSortTest() + { + // Setup arrays + string[] sortable = ["0", "100", "5", "2", "1000"]; + string[] expected = ["1000", "100", "5", "2", "0"]; + + // Run sorting on array + Array.Sort(sortable, new NaturalReversedComparer()); + + // Check the output + Assert.True(sortable.SequenceEqual(expected)); + } + } +} \ No newline at end of file diff --git a/SabreTools.Matching.Test/Compare/NaturalComparerUtilTests.cs b/SabreTools.Matching.Test/Compare/NaturalComparerUtilTests.cs new file mode 100644 index 0000000..a50c73d --- /dev/null +++ b/SabreTools.Matching.Test/Compare/NaturalComparerUtilTests.cs @@ -0,0 +1,59 @@ +using SabreTools.Matching.Compare; +using Xunit; + +namespace SabreTools.Matching.Test.Compare +{ + public class NaturalComparerUtilTests + { + [Fact] + public void CompareNumericBothNullTest() + { + int actual = NaturalComparerUtil.CompareNumeric(null, null); + Assert.Equal(0, actual); + } + + [Fact] + public void CompareNumericSingleNullTest() + { + int actual = NaturalComparerUtil.CompareNumeric(null, "notnull"); + Assert.Equal(-1, actual); + + actual = NaturalComparerUtil.CompareNumeric("notnull", null); + Assert.Equal(1, actual); + } + + [Fact] + public void CompareNumericBothEqualTest() + { + int actual = NaturalComparerUtil.CompareNumeric("notnull", "notnull"); + Assert.Equal(0, actual); + } + + [Fact] + public void CompareNumericBothEqualWithPathTest() + { + int actual = NaturalComparerUtil.CompareNumeric("notnull/file.ext", "notnull/file.ext"); + Assert.Equal(0, actual); + } + + [Fact] + public void CompareNumericNumericNonDecimalStringTest() + { + int actual = NaturalComparerUtil.CompareNumeric("100", "10"); + Assert.Equal(1, actual); + + actual = NaturalComparerUtil.CompareNumeric("10", "100"); + Assert.Equal(-1, actual); + } + + [Fact] + public void CompareNumericNumericDecimalStringTest() + { + int actual = NaturalComparerUtil.CompareNumeric("100.100", "100.10"); + Assert.Equal(1, actual); + + actual = NaturalComparerUtil.CompareNumeric("100.10", "100.100"); + Assert.Equal(-1, actual); + } + } +} \ No newline at end of file diff --git a/SabreTools.Matching.Test/SabreTools.Matching.Test.csproj b/SabreTools.Matching.Test/SabreTools.Matching.Test.csproj index db16aab..b910acd 100644 --- a/SabreTools.Matching.Test/SabreTools.Matching.Test.csproj +++ b/SabreTools.Matching.Test/SabreTools.Matching.Test.csproj @@ -3,6 +3,7 @@ net6.0;net8.0 false + latest enable diff --git a/SabreTools.Matching/Compare/NaturalComparer.cs b/SabreTools.Matching/Compare/NaturalComparer.cs index a2e815f..b77e9b3 100644 --- a/SabreTools.Matching/Compare/NaturalComparer.cs +++ b/SabreTools.Matching/Compare/NaturalComparer.cs @@ -41,16 +41,17 @@ namespace SabreTools.Matching.Compare else return 0; } + if (x.ToLowerInvariant() == y.ToLowerInvariant()) - { return x.CompareTo(y); - } + if (!table.TryGetValue(x, out string[]? x1)) { //x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)"); x1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrEmpty(s)).ToArray(); table.Add(x, x1); } + if (!table.TryGetValue(y, out string[]? y1)) { //y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)"); @@ -61,41 +62,28 @@ namespace SabreTools.Matching.Compare for (int i = 0; i < x1.Length && i < y1.Length; i++) { if (x1[i] != y1[i]) - { return PartCompare(x1[i], y1[i]); - } } + if (y1.Length > x1.Length) - { return 1; - } else if (x1.Length > y1.Length) - { return -1; - } else - { return x.CompareTo(y); - } } private static int PartCompare(string left, string right) { if (!long.TryParse(left, out long x)) - { return NaturalComparerUtil.CompareNumeric(left, right); - } if (!long.TryParse(right, out long y)) - { return NaturalComparerUtil.CompareNumeric(left, right); - } // If we have an equal part, then make sure that "longer" ones are taken into account if (x.CompareTo(y) == 0) - { return left.Length - right.Length; - } return x.CompareTo(y); } diff --git a/SabreTools.Matching/Compare/NaturalComparerUtil.cs b/SabreTools.Matching/Compare/NaturalComparerUtil.cs index b907b23..80fcfc8 100644 --- a/SabreTools.Matching/Compare/NaturalComparerUtil.cs +++ b/SabreTools.Matching/Compare/NaturalComparerUtil.cs @@ -4,8 +4,21 @@ namespace SabreTools.Matching.Compare { public static class NaturalComparerUtil { - public static int CompareNumeric(string s1, string s2) + /// + /// Compare two strings by numeric parts + /// + public static int CompareNumeric(string? s1, string? s2) { + // If both strings are null, return + if (s1 == null && s2 == null) + return 0; + + // If one is null, then say that's less than + if (s1 == null) + return -1; + if (s2 == null) + return 1; + // Save the orginal strings, for later comparison string s1orig = s1; string s2orig = s2; @@ -18,12 +31,6 @@ namespace SabreTools.Matching.Compare if (s1 == s2) return s1orig.CompareTo(s2orig); - // If one is null, then say that's less than - if (s1 == null) - return -1; - if (s2 == null) - return 1; - // Now split into path parts after converting AltDirSeparator to DirSeparator s1 = s1.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); s2 = s2.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); diff --git a/SabreTools.Matching/Compare/NaturalReversedComparer.cs b/SabreTools.Matching/Compare/NaturalReversedComparer.cs index 0fe2698..f44eea0 100644 --- a/SabreTools.Matching/Compare/NaturalReversedComparer.cs +++ b/SabreTools.Matching/Compare/NaturalReversedComparer.cs @@ -41,16 +41,17 @@ namespace SabreTools.Matching.Compare else return 0; } + if (y.ToLowerInvariant() == x.ToLowerInvariant()) - { return y.CompareTo(x); - } + if (!table.TryGetValue(x, out string[]? x1)) { //x1 = Regex.Split(x.Replace(" ", string.Empty), "([0-9]+)"); x1 = Regex.Split(x.ToLowerInvariant(), "([0-9]+)").Where(s => !string.IsNullOrEmpty(s)).ToArray(); table.Add(x, x1); } + if (!table.TryGetValue(y, out string[]? y1)) { //y1 = Regex.Split(y.Replace(" ", string.Empty), "([0-9]+)"); @@ -61,41 +62,28 @@ namespace SabreTools.Matching.Compare for (int i = 0; i < x1.Length && i < y1.Length; i++) { if (x1[i] != y1[i]) - { return PartCompare(x1[i], y1[i]); - } } + if (y1.Length > x1.Length) - { return 1; - } else if (x1.Length > y1.Length) - { return -1; - } else - { return y.CompareTo(x); - } } private static int PartCompare(string left, string right) { if (!long.TryParse(left, out long x)) - { return NaturalComparerUtil.CompareNumeric(right, left); - } if (!long.TryParse(right, out long y)) - { return NaturalComparerUtil.CompareNumeric(right, left); - } // If we have an equal part, then make sure that "longer" ones are taken into account if (y.CompareTo(x) == 0) - { return right.Length - left.Length; - } return y.CompareTo(x); }