diff --git a/src/Sqids/SqidsEncoder.cs b/src/Sqids/SqidsEncoder.cs index 23cfaef..78edfeb 100644 --- a/src/Sqids/SqidsEncoder.cs +++ b/src/Sqids/SqidsEncoder.cs @@ -269,9 +269,9 @@ private string Encode(ReadOnlySpan numbers, int increment = 0) /// empty, or includes characters not found in the alphabet. /// #if NET7_0_OR_GREATER - public T[] Decode(ReadOnlySpan id) + public IReadOnlyList Decode(ReadOnlySpan id) #else - public int[] Decode(ReadOnlySpan id) + public IReadOnlyList Decode(ReadOnlySpan id) #endif { if (id.IsEmpty) @@ -318,7 +318,7 @@ public int[] Decode(ReadOnlySpan id) id = separatorIndex == -1 ? default : id[(separatorIndex + 1)..]; // NOTE: Everything to the right of the separator will be `id` for the next iteration if (chunk.IsEmpty) - return result.ToArray(); + return result; var alphabetWithoutSeparator = alphabetTemp[1..]; // NOTE: Exclude the first character — which is the separator var decodedNumber = ToNumber(chunk, alphabetWithoutSeparator); @@ -328,7 +328,7 @@ public int[] Decode(ReadOnlySpan id) ConsistentShuffle(alphabetTemp); } - return result.ToArray(); // TODO: A way to return an array without creating a new array from the list like this? + return result; } // NOTE: Implicit `string` => `Span` conversion was introduced in .NET Standard 2.1 (see https://learn.microsoft.com/en-us/dotnet/api/system.string.op_implicit), which means without this overload, calling `Decode` with a string on versions older than .NET Standard 2.1 would require calling `.AsSpan()` on the string, which is cringe. @@ -342,7 +342,7 @@ public int[] Decode(ReadOnlySpan id) /// if the ID represents a single number); or an empty array if the input ID is null, /// empty, or includes characters not found in the alphabet. /// - public int[] Decode(string id) => Decode(id.AsSpan()); + public IReadOnlyList Decode(string id) => Decode(id.AsSpan()); #endif private bool IsBlockedId(ReadOnlySpan id) diff --git a/test/Sqids.Tests/AlphabetTests.cs b/test/Sqids.Tests/AlphabetTests.cs index 31ab9b3..15a7043 100644 --- a/test/Sqids.Tests/AlphabetTests.cs +++ b/test/Sqids.Tests/AlphabetTests.cs @@ -17,7 +17,7 @@ string id #endif sqids.Encode(numbers).ShouldBe(id); - sqids.Decode(id).ShouldBeEquivalentTo(numbers); + sqids.Decode(id).ShouldBe(numbers); } [TestCase("abc", new[] { 1, 2, 3 })] // NOTE: Shortest possible alphabet diff --git a/test/Sqids.Tests/BlockListTests.cs b/test/Sqids.Tests/BlockListTests.cs index a67da77..e9d7caa 100644 --- a/test/Sqids.Tests/BlockListTests.cs +++ b/test/Sqids.Tests/BlockListTests.cs @@ -11,7 +11,7 @@ public void EncodeAndDecode_WithDefaultBlockList_BlocksWordsInDefaultBlockList() var sqids = new SqidsEncoder(); #endif - sqids.Decode("aho1e").ShouldBeEquivalentTo(new[] { 4572721 }); + sqids.Decode("aho1e").ShouldBe(new[] { 4572721 }); sqids.Encode(4572721).ShouldBe("JExTR"); } @@ -27,7 +27,7 @@ public void EncodeAndDecode_WithEmptyBlockList_DoesNotBlockWords() BlockList = new(), }); - sqids.Decode("aho1e").ShouldBeEquivalentTo(new[] { 4572721 }); + sqids.Decode("aho1e").ShouldBe(new[] { 4572721 }); sqids.Encode(4572721).ShouldBe("aho1e"); } @@ -47,13 +47,13 @@ public void EncodeAndDecode_WithCustomBlockList_OnlyBlocksWordsInCustomBlockList }); // NOTE: Make sure the default blocklist isn't used - sqids.Decode("aho1e").ShouldBeEquivalentTo(new[] { 4572721 }); + sqids.Decode("aho1e").ShouldBe(new[] { 4572721 }); sqids.Encode(4572721).ShouldBe("aho1e"); // NOTE: Make sure the passed blocklist IS used: - sqids.Decode("ArUO").ShouldBeEquivalentTo(new[] { 100000 }); + sqids.Decode("ArUO").ShouldBe(new[] { 100000 }); sqids.Encode(100000).ShouldBe("QyG4"); - sqids.Decode("QyG4").ShouldBeEquivalentTo(new[] { 100000 }); + sqids.Decode("QyG4").ShouldBe(new[] { 100000 }); } [Test] @@ -76,7 +76,7 @@ public void EncodeAndDecode_WithBlockListBlockingMultipleEncodings_RespectsBlock }); sqids.Encode(1_000_000, 2_000_000).ShouldBe("1aYeB7bRUt"); - sqids.Decode("1aYeB7bRUt").ShouldBeEquivalentTo(new[] { 1_000_000, 2_000_000 }); + sqids.Decode("1aYeB7bRUt").ShouldBe(new[] { 1_000_000, 2_000_000 }); } [Test] @@ -98,11 +98,11 @@ public void Decode_BlockedIds_StillDecodesSuccessfully() }, }); - sqids.Decode("86Rf07").ShouldBeEquivalentTo(new[] { 1, 2, 3 }); - sqids.Decode("se8ojk").ShouldBeEquivalentTo(new[] { 1, 2, 3 }); - sqids.Decode("ARsz1p").ShouldBeEquivalentTo(new[] { 1, 2, 3 }); - sqids.Decode("Q8AI49").ShouldBeEquivalentTo(new[] { 1, 2, 3 }); - sqids.Decode("5sQRZO").ShouldBeEquivalentTo(new[] { 1, 2, 3 }); + sqids.Decode("86Rf07").ShouldBe(new[] { 1, 2, 3 }); + sqids.Decode("se8ojk").ShouldBe(new[] { 1, 2, 3 }); + sqids.Decode("ARsz1p").ShouldBe(new[] { 1, 2, 3 }); + sqids.Decode("Q8AI49").ShouldBe(new[] { 1, 2, 3 }); + sqids.Decode("5sQRZO").ShouldBe(new[] { 1, 2, 3 }); } [Test] @@ -120,7 +120,7 @@ public void EncodeAndDecode_WithShortCustomBlockList_RoundTripsSuccessfully() }, }); - sqids.Decode(sqids.Encode(1000)).ShouldBeEquivalentTo(new[] { 1000 }); + sqids.Decode(sqids.Encode(1000)).ShouldBe(new[] { 1000 }); } [Test] @@ -140,7 +140,7 @@ public void EncodeAndDecode_WithLowerCaseBlockListAndUpperCaseAlphabet_IgnoresCa }); sqids.Encode(1, 2, 3).ShouldBe("IBSHOZ"); // NOTE: Without the blocklist, would've been "SQNMPN". - sqids.Decode("IBSHOZ").ShouldBeEquivalentTo(new[] { 1, 2, 3 }); + sqids.Decode("IBSHOZ").ShouldBe(new[] { 1, 2, 3 }); } [Test] diff --git a/test/Sqids.Tests/EncodingTests.cs b/test/Sqids.Tests/EncodingTests.cs index f211983..fefb82d 100644 --- a/test/Sqids.Tests/EncodingTests.cs +++ b/test/Sqids.Tests/EncodingTests.cs @@ -26,7 +26,7 @@ public void EncodeAndDecode_SingleNumber_ReturnsExactMatch(int number, string id #endif sqids.Encode(number).ShouldBe(id); - sqids.Decode(id).ShouldBeEquivalentTo(new[] { number }); + sqids.Decode(id).ShouldBe(new[] { number }); } // NOTE: Simple case @@ -65,7 +65,7 @@ public void EncodeAndDecode_MultipleNumbers_ReturnsExactMatch(int[] numbers, str sqids.Encode(numbers).ShouldBe(id); sqids.Encode(numbers.ToList()).ShouldBe(id); // NOTE: Selects the `IEnumerable` overload - sqids.Decode(id).ShouldBeEquivalentTo(numbers); + sqids.Decode(id).ShouldBe(numbers); } [TestCase(new[] { 0, 0, 0, 1, 2, 3, 100, 1_000, 100_000, 1_000_000, int.MaxValue })] @@ -85,7 +85,7 @@ public void EncodeAndDecode_MultipleNumbers_RoundTripsSuccessfully(int[] numbers var sqids = new SqidsEncoder(); #endif - sqids.Decode(sqids.Encode(numbers)).ShouldBeEquivalentTo(numbers); + sqids.Decode(sqids.Encode(numbers)).ShouldBe(numbers); } [TestCase("*")] // NOTE: Character not found in the alphabet @@ -127,7 +127,7 @@ T number ) where T : unmanaged, IBinaryInteger, IMinMaxValue { var sqids = new SqidsEncoder(); - sqids.Decode(sqids.Encode(number)).ShouldBeEquivalentTo(new[] { number }); + sqids.Decode(sqids.Encode(number)).ShouldBe(new[] { number }); } [TestCaseSource(nameof(MultipleNumbersOfDifferentIntegerTypesTestCaseSource))] @@ -136,7 +136,7 @@ T[] numbers ) where T : unmanaged, IBinaryInteger, IMinMaxValue { var sqids = new SqidsEncoder(); - sqids.Decode(sqids.Encode(numbers)).ShouldBeEquivalentTo(numbers); + sqids.Decode(sqids.Encode(numbers)).ShouldBe(numbers); } private static TestCaseData[] MultipleNumbersOfDifferentIntegerTypesTestCaseSource => new TestCaseData[] diff --git a/test/Sqids.Tests/MinLengthTests.cs b/test/Sqids.Tests/MinLengthTests.cs index d58cab7..c9cbc5f 100644 --- a/test/Sqids.Tests/MinLengthTests.cs +++ b/test/Sqids.Tests/MinLengthTests.cs @@ -25,7 +25,7 @@ public void EncodeAndDecode_WithHighMinLength_ReturnsExactMatch(int[] numbers, s }); sqids.Encode(numbers).ShouldBe(id); - sqids.Decode(id).ShouldBeEquivalentTo(numbers); + sqids.Decode(id).ShouldBe(numbers); } [TestCaseSource(nameof(IncrementalMinLengthsSource))] @@ -47,7 +47,7 @@ string id sqids.Encode(numbers).ShouldBe(id); sqids.Encode(numbers).Length.ShouldBeGreaterThanOrEqualTo(minLength); - sqids.Decode(id).ShouldBeEquivalentTo(numbers); + sqids.Decode(id).ShouldBe(numbers); } private static TestCaseData[] IncrementalMinLengthsSource => new TestCaseData[] { @@ -100,7 +100,7 @@ int[] numbers var id = sqids.Encode(numbers); id.Length.ShouldBeGreaterThanOrEqualTo(minLength); - sqids.Decode(id).ShouldBeEquivalentTo(numbers); + sqids.Decode(id).ShouldBe(numbers); } private static int[] MinLengthsValueSource => new[] { diff --git a/test/Sqids.Tests/UniquenessTests.cs b/test/Sqids.Tests/UniquenessTests.cs index df3047b..242bf04 100644 --- a/test/Sqids.Tests/UniquenessTests.cs +++ b/test/Sqids.Tests/UniquenessTests.cs @@ -30,7 +30,7 @@ public void EncodeAndDecode_LargeRange_ReturnsUniqueIdsAndRoundTripsSuccessfully var numbers = Enumerable.Repeat(i, numbersCount).ToArray(); var id = sqids.Encode(numbers); hashSet.Add(id); - sqids.Decode(id).ShouldBeEquivalentTo(numbers); + sqids.Decode(id).ShouldBe(numbers); } hashSet.Count.ShouldBe(range); // NOTE: Ensures that all the IDs were unique.