From 295849d5a728b77a84428c7d655d511d4bfeecf7 Mon Sep 17 00:00:00 2001 From: Orace Date: Mon, 30 Jan 2023 18:03:43 +0100 Subject: [PATCH 1/2] In `EndsWithTest`, convert some tests as a case of more generic tests. --- MoreLinq.Test/EndsWithTest.cs | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/MoreLinq.Test/EndsWithTest.cs b/MoreLinq.Test/EndsWithTest.cs index 108980360..2cf2f9c75 100644 --- a/MoreLinq.Test/EndsWithTest.cs +++ b/MoreLinq.Test/EndsWithTest.cs @@ -24,6 +24,9 @@ namespace MoreLinq.Test [TestFixture] public class EndsWithTest { + [TestCase(new int[0], new int[0], ExpectedResult = true)] + [TestCase(new int[0], new[] { 1, 2, 3 }, ExpectedResult = false)] + [TestCase(new[] { 1, 2, 3 }, new int[0], ExpectedResult = true)] [TestCase(new[] { 1, 2, 3 }, new[] { 2, 3 }, ExpectedResult = true)] [TestCase(new[] { 1, 2, 3 }, new[] { 1, 2, 3 }, ExpectedResult = true)] [TestCase(new[] { 1, 2, 3 }, new[] { 0, 1, 2, 3 }, ExpectedResult = false)] @@ -40,6 +43,9 @@ public bool EndsWithWithChars(IEnumerable first, IEnumerable second) return first.EndsWith(second); } + [TestCase("", "", ExpectedResult = true)] + [TestCase("", "1", ExpectedResult = false)] + [TestCase("1", "", ExpectedResult = true)] [TestCase("123", "23", ExpectedResult = true)] [TestCase("123", "123", ExpectedResult = true)] [TestCase("123", "0123", ExpectedResult = false)] @@ -49,26 +55,6 @@ public bool EndsWithWithStrings(string first, string second) return MoreEnumerable.EndsWith(first, second); } - [Test] - public void EndsWithReturnsTrueIfBothEmpty() - { - Assert.That(new int[0].EndsWith(new int[0]), Is.True); - } - - [Test] - public void EndsWithReturnsFalseIfOnlyFirstIsEmpty() - { - Assert.That(new int[0].EndsWith(new[] { 1, 2, 3 }), Is.False); - } - - [TestCase("", "", ExpectedResult = true)] - [TestCase("1", "", ExpectedResult = true)] - public bool EndsWithReturnsTrueIfSecondIsEmpty(string first, string second) - { - // Conflict with String.EndsWith(), which has precedence in this case - return MoreEnumerable.EndsWith(first, second); - } - [Test] public void EndsWithDisposesBothSequenceEnumerators() { From ff7d5dce98fd6e92be8d4ae5a33e4f7a31dab9a4 Mon Sep 17 00:00:00 2001 From: Orace Date: Mon, 30 Jan 2023 18:44:44 +0100 Subject: [PATCH 2/2] Add new `SourceKind`: `Collection` and `List`. Use it in EndsWithTest --- MoreLinq.Test/Collection.cs | 50 ++++++++++++++++++++++++++++ MoreLinq.Test/EndsWithTest.cs | 58 ++++++++++++++++++++------------- MoreLinq.Test/TestExtensions.cs | 4 +++ 3 files changed, 90 insertions(+), 22 deletions(-) create mode 100644 MoreLinq.Test/Collection.cs diff --git a/MoreLinq.Test/Collection.cs b/MoreLinq.Test/Collection.cs new file mode 100644 index 000000000..2c9c7c69e --- /dev/null +++ b/MoreLinq.Test/Collection.cs @@ -0,0 +1,50 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2023 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace MoreLinq.Test +{ + using System.Collections; + using System.Collections.Generic; + + /// + /// This class is a wrapper around a that only implement . + /// + sealed class Collection : ICollection + { + readonly IList _list; + + public Collection(IList list) => _list = list; + + public int Count => _list.Count; + + public bool IsReadOnly => false; + + public void Add(T item) => _list.Add(item); + + public void Clear() => _list.Clear(); + + public bool Contains(T item) => _list.Contains(item); + + public void CopyTo(T[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex); + + public IEnumerator GetEnumerator() => _list.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_list).GetEnumerator(); + + public bool Remove(T item) => _list.Remove(item); + } +} diff --git a/MoreLinq.Test/EndsWithTest.cs b/MoreLinq.Test/EndsWithTest.cs index 2cf2f9c75..1a638e00c 100644 --- a/MoreLinq.Test/EndsWithTest.cs +++ b/MoreLinq.Test/EndsWithTest.cs @@ -17,13 +17,30 @@ namespace MoreLinq.Test { + using System.Collections; using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; using NUnit.Framework; - [TestFixture] + [TestFixture(SourceKind.Sequence, SourceKind.Sequence)] + [TestFixture(SourceKind.Sequence, SourceKind.Collection)] + [TestFixture(SourceKind.Sequence, SourceKind.List)] + [TestFixture(SourceKind.Collection, SourceKind.Sequence)] + [TestFixture(SourceKind.Collection, SourceKind.Collection)] + [TestFixture(SourceKind.Collection, SourceKind.List)] + [TestFixture(SourceKind.List, SourceKind.Sequence)] + [TestFixture(SourceKind.List, SourceKind.Collection)] + [TestFixture(SourceKind.List, SourceKind.List)] public class EndsWithTest { + readonly SourceKind _firstSourceKind; + readonly SourceKind _secondSourceKind; + + public EndsWithTest(SourceKind firstSourceKind, SourceKind secondSourceKind) + { + _firstSourceKind = firstSourceKind; + _secondSourceKind = secondSourceKind; + } + [TestCase(new int[0], new int[0], ExpectedResult = true)] [TestCase(new int[0], new[] { 1, 2, 3 }, ExpectedResult = false)] [TestCase(new[] { 1, 2, 3 }, new int[0], ExpectedResult = true)] @@ -32,15 +49,7 @@ public class EndsWithTest [TestCase(new[] { 1, 2, 3 }, new[] { 0, 1, 2, 3 }, ExpectedResult = false)] public bool EndsWithWithIntegers(IEnumerable first, IEnumerable second) { - return first.EndsWith(second); - } - - [TestCase(new[] { '1', '2', '3' }, new[] { '2', '3' }, ExpectedResult = true)] - [TestCase(new[] { '1', '2', '3' }, new[] { '1', '2', '3' }, ExpectedResult = true)] - [TestCase(new[] { '1', '2', '3' }, new[] { '0', '1', '2', '3' }, ExpectedResult = false)] - public bool EndsWithWithChars(IEnumerable first, IEnumerable second) - { - return first.EndsWith(second); + return first.ToSourceKind(_firstSourceKind).EndsWith(second.ToSourceKind(_secondSourceKind)); } [TestCase("", "", ExpectedResult = true)] @@ -51,8 +60,7 @@ public bool EndsWithWithChars(IEnumerable first, IEnumerable second) [TestCase("123", "0123", ExpectedResult = false)] public bool EndsWithWithStrings(string first, string second) { - // Conflict with String.EndsWith(), which has precedence in this case - return MoreEnumerable.EndsWith(first, second); + return first.ToSourceKind(_firstSourceKind).EndsWith(second.ToSourceKind(_secondSourceKind)); } [Test] @@ -64,17 +72,23 @@ public void EndsWithDisposesBothSequenceEnumerators() _ = first.EndsWith(second); } - [Test] - [SuppressMessage("ReSharper", "RedundantArgumentDefaultValue")] - public void EndsWithUsesSpecifiedEqualityComparerOrDefault() + [TestCaseSource(nameof(EndsWithUsesSpecifiedEqualityComparerOrDefaultTestCases))] + public bool EndsWithUsesSpecifiedEqualityComparerOrDefault(IEqualityComparer? equalityComparer) { - var first = new[] { 1, 2, 3 }; - var second = new[] { 4, 5, 6 }; + var first = new[] { 1, 2, 3 }.ToSourceKind(_firstSourceKind); + var second = new[] { 4, 5, 6 }.ToSourceKind(_secondSourceKind); - Assert.That(first.EndsWith(second), Is.False); - Assert.That(first.EndsWith(second, null), Is.False); - Assert.That(first.EndsWith(second, EqualityComparer.Create(delegate { return false; })), Is.False); - Assert.That(first.EndsWith(second, EqualityComparer.Create(delegate { return true; })), Is.True); + return first.EndsWith(second, equalityComparer); + } + + public static IEnumerable EndsWithUsesSpecifiedEqualityComparerOrDefaultTestCases + { + get + { + yield return new TestCaseData(null).Returns(false); + yield return new TestCaseData(EqualityComparer.Create(delegate { return false; })).Returns(false); + yield return new TestCaseData(EqualityComparer.Create(delegate { return true; })).Returns(true); + } } [TestCase(SourceKind.BreakingCollection)] diff --git a/MoreLinq.Test/TestExtensions.cs b/MoreLinq.Test/TestExtensions.cs index e327c09e8..e0aecd82c 100644 --- a/MoreLinq.Test/TestExtensions.cs +++ b/MoreLinq.Test/TestExtensions.cs @@ -25,6 +25,8 @@ namespace MoreLinq.Test public enum SourceKind { Sequence, + Collection, + List, BreakingList, BreakingReadOnlyList, BreakingCollection, @@ -91,6 +93,8 @@ internal static IEnumerable ToSourceKind(this IEnumerable input, Source sourceKind switch { SourceKind.Sequence => input.Select(x => x), + SourceKind.Collection => new Collection(input.ToList()), + SourceKind.List => input.ToList(), SourceKind.BreakingList => new BreakingList(input.ToList()), SourceKind.BreakingReadOnlyList => new BreakingReadOnlyList(input.ToList()), SourceKind.BreakingCollection => new BreakingCollection(input.ToList()),