diff --git a/src/libraries/System.Linq/src/System/Linq/SkipTake.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/SkipTake.SpeedOpt.cs index 5cb53aa2997e06..ef043f9f6755e7 100644 --- a/src/libraries/System.Linq/src/System/Linq/SkipTake.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/SkipTake.SpeedOpt.cs @@ -430,9 +430,12 @@ public override Iterator Take(int count) { if (_source is Iterator iterator && iterator.GetCount(onlyIfCheap: true) is int count && - count >= _minIndexInclusive) + count > _minIndexInclusive) { - return !HasLimit ? + // If there's no upper bound, or if there are fewer items in the list + // than the upper bound allows, just return the last element of the list. + // Otherwise, get the element at the upper bound. + return (uint)count <= (uint)_maxIndexInclusive ? iterator.TryGetLast(out found) : iterator.TryGetElementAt(_maxIndexInclusive, out found); } diff --git a/src/libraries/System.Linq/tests/AggregateByTests.cs b/src/libraries/System.Linq/tests/AggregateByTests.cs index b574660c9e5ac8..43b9262f78b813 100644 --- a/src/libraries/System.Linq/tests/AggregateByTests.cs +++ b/src/libraries/System.Linq/tests/AggregateByTests.cs @@ -11,10 +11,10 @@ public class AggregateByTests : EnumerableTests [Fact] public void Empty() { - Assert.All(IdentityTransforms(), transform => + Assert.All(CreateSources([]), source => { - Assert.Equal(Enumerable.Empty>(), transform(Enumerable.Empty()).AggregateBy(i => i, i => i, (a, i) => a + i)); - Assert.Equal(Enumerable.Empty>(), transform(Enumerable.Empty()).AggregateBy(i => i, 0, (a, i) => a + i)); + Assert.Equal([], source.AggregateBy(i => i, i => i, (a, i) => a + i)); + Assert.Equal([], source.AggregateBy(i => i, 0, (a, i) => a + i)); }); } diff --git a/src/libraries/System.Linq/tests/ChunkTests.cs b/src/libraries/System.Linq/tests/ChunkTests.cs index 31433ddabff30f..1a12ac7fd6765d 100644 --- a/src/libraries/System.Linq/tests/ChunkTests.cs +++ b/src/libraries/System.Linq/tests/ChunkTests.cs @@ -42,10 +42,8 @@ public void ChunkSourceLazily() [InlineData(new[] {9999, 0, 888, -1, 66, -777, 1, 2, -12345})] public void ChunkSourceRepeatCalls(int[] array) { - Assert.All(IdentityTransforms(), t => + Assert.All(CreateSources(array), source => { - IEnumerable source = t(array); - Assert.Equal(source.Chunk(3), source.Chunk(3)); }); } @@ -54,10 +52,8 @@ public void ChunkSourceRepeatCalls(int[] array) [InlineData(new[] {9999, 0, 888, -1, 66, -777, 1, 2, -12345})] public void ChunkSourceEvenly(int[] array) { - Assert.All(IdentityTransforms(), t => + Assert.All(CreateSources(array), source => { - IEnumerable source = t(array); - using IEnumerator chunks = source.Chunk(3).GetEnumerator(); chunks.MoveNext(); Assert.Equal(new[] { 9999, 0, 888 }, chunks.Current); @@ -73,10 +69,8 @@ public void ChunkSourceEvenly(int[] array) [InlineData(new[] {9999, 0, 888, -1, 66, -777, 1, 2})] public void ChunkSourceUnevenly(int[] array) { - Assert.All(IdentityTransforms(), t => + Assert.All(CreateSources(array), source => { - IEnumerable source = t(array); - using IEnumerator chunks = source.Chunk(3).GetEnumerator(); chunks.MoveNext(); Assert.Equal(new[] { 9999, 0, 888 }, chunks.Current); @@ -92,10 +86,8 @@ public void ChunkSourceUnevenly(int[] array) [InlineData(new[] {9999, 0})] public void ChunkSourceSmallerThanMaxSize(int[] array) { - Assert.All(IdentityTransforms(), t => + Assert.All(CreateSources(array), source => { - IEnumerable source = t(array); - using IEnumerator chunks = source.Chunk(3).GetEnumerator(); chunks.MoveNext(); Assert.Equal(new[] { 9999, 0 }, chunks.Current); @@ -107,10 +99,8 @@ public void ChunkSourceSmallerThanMaxSize(int[] array) [InlineData(new int[0])] public void EmptySourceYieldsNoChunks(int[] array) { - Assert.All(IdentityTransforms(), t => + Assert.All(CreateSources(array), source => { - IEnumerable source = t(array); - using IEnumerator chunks = source.Chunk(3).GetEnumerator(); Assert.False(chunks.MoveNext()); }); diff --git a/src/libraries/System.Linq/tests/ConcatTests.cs b/src/libraries/System.Linq/tests/ConcatTests.cs index 544027450d80c2..4069bbdf5de5a4 100644 --- a/src/libraries/System.Linq/tests/ConcatTests.cs +++ b/src/libraries/System.Linq/tests/ConcatTests.cs @@ -31,8 +31,8 @@ private static void SameResultsWithQueryAndRepeatCallsWorker(IEnumerable f first = from item in first select item; second = from item in second select item; - VerifyEqualsWorker(first.Concat(second), first.Concat(second)); - VerifyEqualsWorker(second.Concat(first), second.Concat(first)); + Assert.Equal(first.Concat(second), first.Concat(second)); + Assert.Equal(second.Concat(first), second.Concat(first)); } [Theory] @@ -41,8 +41,8 @@ private static void SameResultsWithQueryAndRepeatCallsWorker(IEnumerable f [InlineData(new int[] { 2, 3, 5, 9 }, new int[] { 8, 10 }, new int[] { 2, 3, 5, 9, 8, 10 })] // Neither side is empty public void PossiblyEmptyInputs(IEnumerable first, IEnumerable second, IEnumerable expected) { - VerifyEqualsWorker(expected, first.Concat(second)); - VerifyEqualsWorker(expected.Skip(first.Count()).Concat(expected.Take(first.Count())), second.Concat(first)); // Swap the inputs around + Assert.Equal(expected, first.Concat(second)); + Assert.Equal(expected.Skip(first.Count()).Concat(expected.Take(first.Count())), second.Concat(first)); // Swap the inputs around } [Fact] @@ -80,7 +80,7 @@ public void SecondNull() public void VerifyEquals(IEnumerable expected, IEnumerable actual) { // workaround: xUnit type inference doesn't work if the input type is not T (like IEnumerable) - VerifyEqualsWorker(expected, actual); + Assert.Equal(expected, actual); } [Theory] @@ -133,23 +133,6 @@ public void First_Last_ElementAt(IEnumerable _, IEnumerable actual) } } - private static void VerifyEqualsWorker(IEnumerable expected, IEnumerable actual) - { - // Returns a list of functions that, when applied to enumerable, should return - // another one that has equivalent contents. - var identityTransforms = IdentityTransforms(); - - // We run the transforms N^2 times, by testing all transforms - // of expected against all transforms of actual. - foreach (var outTransform in identityTransforms) - { - foreach (var inTransform in identityTransforms) - { - Assert.Equal(outTransform(expected), inTransform(actual)); - } - } - } - public static IEnumerable ArraySourcesData() => GenerateSourcesData(outerTransform: e => e.ToArray()); public static IEnumerable SelectArraySourcesData() => GenerateSourcesData(outerTransform: e => e.Select(i => i).ToArray()); @@ -292,7 +275,7 @@ public void ManyConcats(IEnumerable> sources) } Assert.Equal(sources.Sum(s => s.Count()), concatee.Count()); - VerifyEqualsWorker(sources.SelectMany(s => s), concatee); + Assert.Equal(sources.SelectMany(s => s), concatee); } } diff --git a/src/libraries/System.Linq/tests/CountTests.cs b/src/libraries/System.Linq/tests/CountTests.cs index 5b0730163721db..2937f116367f71 100644 --- a/src/libraries/System.Linq/tests/CountTests.cs +++ b/src/libraries/System.Linq/tests/CountTests.cs @@ -99,9 +99,9 @@ public void RunOnce(int count, IEnumerable enumerable) private static IEnumerable EnumerateCollectionTypesAndCounts(int count, IEnumerable enumerable) { - foreach (var transform in IdentityTransforms()) + foreach (IEnumerable source in CreateSources(enumerable)) { - yield return new object[] { count, transform(enumerable) }; + yield return [count, source]; } } diff --git a/src/libraries/System.Linq/tests/EnumerableTests.cs b/src/libraries/System.Linq/tests/EnumerableTests.cs index d28ace92a4026b..66bc25861e080e 100644 --- a/src/libraries/System.Linq/tests/EnumerableTests.cs +++ b/src/libraries/System.Linq/tests/EnumerableTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using Xunit; +using Xunit.Sdk; namespace System.Linq.Tests { @@ -243,6 +244,7 @@ protected static IEnumerable FlipIsCollection(IEnumerable source) { return source is ICollection ? ForceNotCollection(source) : new List(source); } + protected static T[] Repeat(Func factory, int count) { T[] results = new T[count]; @@ -316,26 +318,83 @@ protected static IEnumerable> CreateSources(IEnumerable sou } } - protected static List, IEnumerable>> IdentityTransforms() + protected static IEnumerable, IEnumerable>> IdentityTransforms() { - // All of these transforms should take an enumerable and produce - // another enumerable with the same contents. - return new List, IEnumerable>> + // Various collection types all representing the same source. + List, IEnumerable>> sources = + [ + e => e, // original + e => e.ToArray(), // T[] + e => e.ToList(), // List + e => new ReadOnlyCollection(e.ToArray()), // IList that's not List/T[] + e => new TestCollection(e.ToArray()), // ICollection that's not IList + e => new TestReadOnlyCollection(e.ToArray()), // IReadOnlyCollection that's not ICollection + e => ForceNotCollection(e), // IEnumerable with no other interfaces + ]; + if (typeof(T) == typeof(char)) { - e => e, - e => e.ToArray(), - e => e.ToList(), - e => e.ToList().Take(int.MaxValue), + sources.Add(e => (IEnumerable)(object)string.Concat((IEnumerable)(object)e)); // string + } + + // Various transforms that all yield the same elements as the source. + List, IEnumerable>> transforms = + [ + // Append + e => + { + T[] values = e.ToArray(); + return values.Length == 0 ? [] : values[0..^1].Append(values[^1]); + }, + + // Concat + e => e.Concat(ForceNotCollection([])), + e => ForceNotCollection([]).Concat(e), + + // Prepend + e => + { + T[] values = e.ToArray(); + return values.Length == 0 ? [] : values[1..].Prepend(values[0]); + }, + + // Reverse + e => e.Reverse().Reverse(), + + // Select e => e.Select(i => i), - e => e.Select(i => i).Take(int.MaxValue), - e => e.Select(i => i).Where(i => true), + + // SelectMany + e => e.SelectMany(i => [i]), + + // Take + e => e.Take(int.MaxValue), + e => e.TakeLast(int.MaxValue), + e => e.TakeWhile(i => true), + + // Skip + e => e.SkipWhile(i => false), + + // Where e => e.Where(i => true), - e => e.Concat(Array.Empty()), - e => e.Concat(ForceNotCollection(Array.Empty())), - e => ForceNotCollection(e), - e => ForceNotCollection(e).Skip(0), - e => new ReadOnlyCollection(e.ToArray()), - }; + ]; + + foreach (Func, IEnumerable> source in sources) + { + // Yield the source itself. + yield return source; + + foreach (Func, IEnumerable> transform in transforms) + { + // Yield a single transform on the source + yield return e => transform(source(e)); + + foreach (Func, IEnumerable> transform2 in transforms) + { + // Yield a second transform on the first transform on the source. + yield return e => transform2(transform(source(e))); + } + } + } } protected sealed class DelegateIterator : IEnumerable, IEnumerator diff --git a/src/libraries/System.Linq/tests/SelectManyTests.cs b/src/libraries/System.Linq/tests/SelectManyTests.cs index cb359f067848ba..98f2e37e54e32b 100644 --- a/src/libraries/System.Linq/tests/SelectManyTests.cs +++ b/src/libraries/System.Linq/tests/SelectManyTests.cs @@ -372,31 +372,23 @@ public void ForcedToEnumeratorDoesntEnumerateIndexedResultSel() Assert.False(en is not null && en.MoveNext()); } - [Theory] - [MemberData(nameof(ParameterizedTestsData))] - public void ParameterizedTests(IEnumerable source, Func> selector) + [Fact] + public void ParameterizedTests() { - Assert.All(CreateSources(source), source => + for (int i = 1; i <= 20; i++) { - var expected = source.Select(i => selector(i)).Aggregate((l, r) => l.Concat(r)); - var actual = source.SelectMany(selector); + Assert.All(CreateSources(Enumerable.Range(1, i)), source => + { + Func> selector = n => Enumerable.Range(i, n); - Assert.Equal(expected, actual); - Assert.Equal(expected.Count(), actual.Count()); // SelectMany may employ an optimized Count implementation. - Assert.Equal(expected.ToArray(), actual.ToArray()); - Assert.Equal(expected.ToList(), actual.ToList()); - }); - } + var expected = source.Select(i => selector(i)).Aggregate((l, r) => l.Concat(r)).ToArray(); + var actual = source.SelectMany(selector); - public static IEnumerable ParameterizedTestsData() - { - foreach (Func, IEnumerable> transform in IdentityTransforms()) - { - for (int i = 1; i <= 20; i++) - { - Func> selector = n => transform(Enumerable.Range(i, n)); - yield return new object[] { Enumerable.Range(1, i), selector }; - } + Assert.Equal(expected, actual); + Assert.Equal(expected.Length, actual.Count()); // SelectMany may employ an optimized Count implementation. + Assert.Equal(expected, actual.ToArray()); + Assert.Equal(expected, actual.ToList()); + }); } } diff --git a/src/libraries/System.Linq/tests/SingleOrDefaultTests.cs b/src/libraries/System.Linq/tests/SingleOrDefaultTests.cs index 8441f8a3c68a34..e04279bd00eac4 100644 --- a/src/libraries/System.Linq/tests/SingleOrDefaultTests.cs +++ b/src/libraries/System.Linq/tests/SingleOrDefaultTests.cs @@ -27,81 +27,33 @@ public void SameResultsRepeatCallsStringQuery() } [Fact] - public void EmptyIList() + public void Empty() { - int?[] source = { }; - int? expected = null; - - Assert.Equal(expected, source.SingleOrDefault()); - } - - [Fact] - public void EmptyIListDefault() - { - int?[] source = { }; - int expected = 5; - - Assert.Equal(expected, source.SingleOrDefault(5)); - } - - [Fact] - public void SingleElementIList() - { - int[] source = { 4 }; - int expected = 4; - - Assert.Equal(expected, source.SingleOrDefault()); + foreach (IEnumerable source in CreateSources([])) + { + Assert.Null(source.SingleOrDefault()); + Assert.Equal(5, source.SingleOrDefault(5)); + } } [Fact] - public void SingleElementIListDefault() + public void SingleElement() { - int[] source = { 4 }; - int expected = 4; - - Assert.Equal(expected, source.SingleOrDefault(5)); + foreach (IEnumerable source in CreateSources([4])) + { + Assert.Equal(4, source.SingleOrDefault()); + Assert.Equal(4, source.SingleOrDefault(5)); + } } [Fact] public void ManyElementIList() { - int[] source = { 4, 4, 4, 4, 4 }; - - Assert.Throws(() => source.SingleOrDefault()); - } - - [Fact] - public void ManyElementIListDefault() - { - int[] source = { 4, 4, 4, 4, 4 }; - - Assert.Throws(() => source.SingleOrDefault(5)); - } - - [Fact] - public void EmptyNotIList() - { - IEnumerable source = RepeatedNumberGuaranteedNotCollectionType(0, 0); - int expected = default(int); - - Assert.Equal(expected, source.SingleOrDefault()); - } - - [Fact] - public void SingleElementNotIList() - { - IEnumerable source = RepeatedNumberGuaranteedNotCollectionType(-5, 1); - int expected = -5; - - Assert.Equal(expected, source.SingleOrDefault()); - } - - [Fact] - public void ManyElementNotIList() - { - IEnumerable source = RepeatedNumberGuaranteedNotCollectionType(3, 5); - - Assert.Throws(() => source.SingleOrDefault()); + foreach (IEnumerable source in CreateSources([4, 4, 4, 4, 4])) + { + Assert.Throws(() => source.SingleOrDefault()); + Assert.Throws(() => source.SingleOrDefault(4)); + } } [Fact] diff --git a/src/libraries/System.Linq/tests/SingleTests.cs b/src/libraries/System.Linq/tests/SingleTests.cs index 09e49daae1c099..21028511505289 100644 --- a/src/libraries/System.Linq/tests/SingleTests.cs +++ b/src/libraries/System.Linq/tests/SingleTests.cs @@ -37,53 +37,31 @@ public void SameResultsRepeatCallsIntQueryWithZero() } [Fact] - public void EmptyIList() + public void Empty() { - int[] source = { }; - - Assert.Throws(() => source.Single()); + foreach (IEnumerable source in CreateSources([])) + { + Assert.Throws(() => source.Single()); + } } [Fact] - public void SingleElementIList() + public void SingleElement() { - int[] source = { 4 }; int expected = 4; - - Assert.Equal(expected, source.Single()); - } - - [Fact] - public void ManyElementIList() - { - int[] source = { 4, 4, 4, 4, 4 }; - - Assert.Throws(() => source.Single()); - } - - [Fact] - public void EmptyNotIList() - { - IEnumerable source = RepeatedNumberGuaranteedNotCollectionType(0, 0); - - Assert.Throws(() => source.Single()); - } - - [Fact] - public void SingleElementNotIList() - { - IEnumerable source = RepeatedNumberGuaranteedNotCollectionType(-5, 1); - int expected = -5; - - Assert.Equal(expected, source.Single()); + foreach (IEnumerable source in CreateSources([4])) + { + Assert.Equal(expected, source.Single()); + } } [Fact] - public void ManyElementNotIList() + public void ManyElement() { - IEnumerable source = RepeatedNumberGuaranteedNotCollectionType(3, 5); - - Assert.Throws(() => source.Single()); + foreach (IEnumerable source in CreateSources([4, 4, 4, 4, 4])) + { + Assert.Throws(() => source.Single()); + } } [Fact] diff --git a/src/libraries/System.Linq/tests/SkipLastTests.cs b/src/libraries/System.Linq/tests/SkipLastTests.cs index c4770410870d47..0a2080a1ad37af 100644 --- a/src/libraries/System.Linq/tests/SkipLastTests.cs +++ b/src/libraries/System.Linq/tests/SkipLastTests.cs @@ -19,25 +19,26 @@ public void SkipLastThrowsOnNull() [MemberData(nameof(EnumerableData), MemberType = typeof(SkipTakeData))] public void SkipLast(IEnumerable source, int count) { - Assert.All(IdentityTransforms(), transform => - { - IEnumerable equivalent = transform(source); + int[] expected = source.Reverse().Skip(count).Reverse().ToArray(); - IEnumerable expected = equivalent.Reverse().Skip(count).Reverse(); - IEnumerable actual = equivalent.SkipLast(count); + Assert.All(CreateSources(source), source => + { + IEnumerable actual = source.SkipLast(count); Assert.Equal(expected, actual); - Assert.Equal(expected.Count(), actual.Count()); + + Assert.Equal(expected.Length, actual.Count()); Assert.Equal(expected, actual.ToArray()); Assert.Equal(expected, actual.ToList()); - Assert.Equal(expected.FirstOrDefault(), actual.FirstOrDefault()); Assert.Equal(expected.LastOrDefault(), actual.LastOrDefault()); - Assert.All(Enumerable.Range(0, expected.Count()), index => + if (expected.Length > 0) { - Assert.Equal(expected.ElementAt(index), actual.ElementAt(index)); - }); + Assert.Equal(expected[0], actual.ElementAt(0)); + Assert.Equal(expected[^1], actual.ElementAt(expected.Length - 1)); + Assert.Equal(expected[expected.Length / 2], actual.ElementAt(expected.Length / 2)); + } Assert.Equal(0, actual.ElementAtOrDefault(-1)); Assert.Equal(0, actual.ElementAtOrDefault(actual.Count())); diff --git a/src/libraries/System.Linq/tests/SkipTests.cs b/src/libraries/System.Linq/tests/SkipTests.cs index cf4d16b1309907..226c8f6b9152f8 100644 --- a/src/libraries/System.Linq/tests/SkipTests.cs +++ b/src/libraries/System.Linq/tests/SkipTests.cs @@ -10,12 +10,6 @@ namespace System.Linq.Tests { public class SkipTests : EnumerableTests { - private static IEnumerable GuaranteeNotIList(IEnumerable source) - { - foreach (T element in source) - yield return element; - } - [Fact] public void SkipSome() { @@ -87,139 +81,95 @@ public void SkipThrowsOnNullIList() [Fact] public void SkipOnEmpty() { - Assert.Equal(Enumerable.Empty(), GuaranteeNotIList(Enumerable.Empty()).Skip(0)); - Assert.Equal(Enumerable.Empty(), GuaranteeNotIList(Enumerable.Empty()).Skip(-1)); - Assert.Equal(Enumerable.Empty(), GuaranteeNotIList(Enumerable.Empty()).Skip(1)); - } + foreach (IEnumerable source in CreateSources([])) + { + Assert.Equal([], source.Skip(0)); + Assert.Equal([], source.Skip(-1)); + Assert.Equal([], source.Skip(1)); + } - [Fact] - public void SkipOnEmptyIList() - { - // Enumerable.Empty does return an IList, but not guaranteed as such - // by the spec. - Assert.Equal(Enumerable.Empty(), Enumerable.Empty().ToList().Skip(0)); - Assert.Equal(Enumerable.Empty(), Enumerable.Empty().ToList().Skip(-1)); - Assert.Equal(Enumerable.Empty(), Enumerable.Empty().ToList().Skip(1)); + foreach (IEnumerable source in CreateSources([])) + { + Assert.Equal([], source.Skip(0)); + Assert.Equal([], source.Skip(-1)); + Assert.Equal([], source.Skip(1)); + } } [Fact] public void SkipNegative() { - Assert.Equal(Enumerable.Range(0, 20), NumberRangeGuaranteedNotCollectionType(0, 20).Skip(-42)); - } - - [Fact] - public void SkipNegativeIList() - { - Assert.Equal(Enumerable.Range(0, 20), NumberRangeGuaranteedNotCollectionType(0, 20).ToList().Skip(-42)); + foreach (IEnumerable source in CreateSources(Enumerable.Range(0, 20))) + { + Assert.Equal(Enumerable.Range(0, 20), source.Skip(-42)); + } } [Fact] public void SameResultsRepeatCallsIntQuery() { - var q = GuaranteeNotIList(from x in new[] { 9999, 0, 888, -1, 66, -777, 1, 2, -12345 } - where x > int.MinValue - select x); - - Assert.Equal(q.Skip(0), q.Skip(0)); - } - - [Fact] - public void SameResultsRepeatCallsIntQueryIList() - { - var q = (from x in new[] { 9999, 0, 888, -1, 66, -777, 1, 2, -12345 } - where x > Int32.MinValue - select x).ToList(); + foreach (IEnumerable source in CreateSources([9999, 0, 888, -1, 66, -777, 1, 2, -12345])) + { + IEnumerable q = from x in source + where x > int.MinValue + select x; - Assert.Equal(q.Skip(0), q.Skip(0)); + Assert.Equal(q.Skip(0), q.Skip(0)); + } } [Fact] public void SameResultsRepeatCallsStringQuery() { - var q = GuaranteeNotIList(from x in new[] { "!@#$%^", "C", "AAA", "", "Calling Twice", "SoS", string.Empty } - where !string.IsNullOrEmpty(x) - select x); - - Assert.Equal(q.Skip(0), q.Skip(0)); - } - - [Fact] - public void SameResultsRepeatCallsStringQueryIList() - { - var q = (from x in new[] { "!@#$%^", "C", "AAA", "", "Calling Twice", "SoS", String.Empty } - where !String.IsNullOrEmpty(x) - select x).ToList(); + foreach (IEnumerable source in CreateSources(["!@#$%^", "C", "AAA", "", "Calling Twice", "SoS", string.Empty])) + { + IEnumerable q = from x in source + where !string.IsNullOrEmpty(x) + select x; - Assert.Equal(q.Skip(0), q.Skip(0)); + Assert.Equal(q.Skip(0), q.Skip(0)); + } } [Fact] public void SkipOne() { - int?[] source = { 3, 100, 4, null, 10 }; - int?[] expected = { 100, 4, null, 10 }; - - Assert.Equal(expected, source.Skip(1)); - } - - [Fact] - public void SkipOneNotIList() - { - int?[] source = { 3, 100, 4, null, 10 }; - int?[] expected = { 100, 4, null, 10 }; - - Assert.Equal(expected, GuaranteeNotIList(source).Skip(1)); + int?[] expected = [100, 4, null, 10]; + foreach (IEnumerable source in CreateSources([3, 100, 4, null, 10])) + { + Assert.Equal(expected, source.Skip(1)); + } } [Fact] public void SkipAllButOne() { - int?[] source = { 3, 100, null, 4, 10 }; - int?[] expected = { 10 }; - - Assert.Equal(expected, source.Skip(source.Length - 1)); - } - - [Fact] - public void SkipAllButOneNotIList() - { - int?[] source = { 3, 100, null, 4, 10 }; - int?[] expected = { 10 }; - - Assert.Equal(expected, GuaranteeNotIList(source.Skip(source.Length - 1))); + int?[] expected = [10]; + foreach (IEnumerable source in CreateSources([3, 100, 4, null, 10])) + { + Assert.Equal(expected, source.Skip(4)); + } } [Fact] public void SkipOneMoreThanAll() { - int[] source = { 3, 100, 4, 10 }; - Assert.Empty(source.Skip(source.Length + 1)); - } - - [Fact] - public void SkipOneMoreThanAllNotIList() - { - int[] source = { 3, 100, 4, 10 }; - Assert.Empty(GuaranteeNotIList(source).Skip(source.Length + 1)); + foreach (IEnumerable source in CreateSources([3, 100, 4, 10])) + { + Assert.Empty(source.Skip(5)); + } } [Fact] public void ForcedToEnumeratorDoesntEnumerate() { - var iterator = NumberRangeGuaranteedNotCollectionType(0, 3).Skip(2); - // Don't insist on this behaviour, but check it's correct if it happens - var en = iterator as IEnumerator; - Assert.False(en is not null && en.MoveNext()); - } - - [Fact] - public void ForcedToEnumeratorDoesntEnumerateIList() - { - var iterator = (new[] { 0, 1, 2 }).Skip(2); - // Don't insist on this behaviour, but check it's correct if it happens - var en = iterator as IEnumerator; - Assert.False(en is not null && en.MoveNext()); + foreach (IEnumerable source in CreateSources(Enumerable.Range(0, 3))) + { + // Don't insist on this behaviour, but check it's correct if it happens + IEnumerable iterator = source.Skip(2); + var en = iterator as IEnumerator; + Assert.False(en is not null && en.MoveNext()); + } } [Fact] @@ -232,243 +182,150 @@ public void Count() [Fact] public void FollowWithTake() { - var source = new[] { 5, 6, 7, 8 }; - var expected = new[] { 6, 7 }; - Assert.Equal(expected, source.Skip(1).Take(2)); - } - - [Fact] - public void FollowWithTakeNotIList() - { - var source = NumberRangeGuaranteedNotCollectionType(5, 4); - var expected = new[] { 6, 7 }; - Assert.Equal(expected, source.Skip(1).Take(2)); + int[] expected = [6, 7]; + foreach (IEnumerable source in CreateSources(Enumerable.Range(5, 4))) + { + Assert.Equal(expected, source.Skip(1).Take(2)); + } } [Fact] public void FollowWithTakeThenMassiveTake() { - var source = new[] { 5, 6, 7, 8 }; - var expected = new[] { 7 }; - Assert.Equal(expected, source.Skip(2).Take(1).Take(int.MaxValue)); - } - [Fact] - public void FollowWithTakeThenMassiveTakeNotIList() - { - var source = NumberRangeGuaranteedNotCollectionType(5, 4); - var expected = new[] { 7 }; - Assert.Equal(expected, source.Skip(2).Take(1).Take(int.MaxValue)); + int[] expected = [7]; + foreach (IEnumerable source in CreateSources([5, 6, 7, 8])) + { + Assert.Equal(expected, source.Skip(2).Take(1).Take(int.MaxValue)); + } } [Fact] public void FollowWithSkip() { - var source = new[] { 1, 2, 3, 4, 5, 6 }; - var expected = new[] { 4, 5, 6 }; - Assert.Equal(expected, source.Skip(1).Skip(2).Skip(-4)); - } - - [Fact] - public void FollowWithSkipNotIList() - { - var source = NumberRangeGuaranteedNotCollectionType(1, 6); - var expected = new[] { 4, 5, 6 }; - Assert.Equal(expected, source.Skip(1).Skip(2).Skip(-4)); + int[] expected = [4, 5, 6]; + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5, 6])) + { + Assert.Equal(expected, source.Skip(1).Skip(2).Skip(-4)); + } } [Fact] public void ElementAt() { - var source = new[] { 1, 2, 3, 4, 5, 6 }; - var remaining = source.Skip(2); - Assert.Equal(3, remaining.ElementAt(0)); - Assert.Equal(4, remaining.ElementAt(1)); - Assert.Equal(6, remaining.ElementAt(3)); - AssertExtensions.Throws("index", () => remaining.ElementAt(-1)); - AssertExtensions.Throws("index", () => remaining.ElementAt(4)); - } - - [Fact] - public void ElementAtNotIList() - { - var source = GuaranteeNotIList(new[] { 1, 2, 3, 4, 5, 6 }); - var remaining = source.Skip(2); - Assert.Equal(3, remaining.ElementAt(0)); - Assert.Equal(4, remaining.ElementAt(1)); - Assert.Equal(6, remaining.ElementAt(3)); - AssertExtensions.Throws("index", () => remaining.ElementAt(-1)); - AssertExtensions.Throws("index", () => remaining.ElementAt(4)); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5, 6])) + { + IEnumerable remaining = source.Skip(2); + Assert.Equal(3, remaining.ElementAt(0)); + Assert.Equal(4, remaining.ElementAt(1)); + Assert.Equal(6, remaining.ElementAt(3)); + AssertExtensions.Throws("index", () => remaining.ElementAt(-1)); + AssertExtensions.Throws("index", () => remaining.ElementAt(4)); + } } [Fact] public void ElementAtOrDefault() { - var source = new[] { 1, 2, 3, 4, 5, 6 }; - var remaining = source.Skip(2); - Assert.Equal(3, remaining.ElementAtOrDefault(0)); - Assert.Equal(4, remaining.ElementAtOrDefault(1)); - Assert.Equal(6, remaining.ElementAtOrDefault(3)); - Assert.Equal(0, remaining.ElementAtOrDefault(-1)); - Assert.Equal(0, remaining.ElementAtOrDefault(4)); - } - - [Fact] - public void ElementAtOrDefaultNotIList() - { - var source = GuaranteeNotIList(new[] { 1, 2, 3, 4, 5, 6 }); - var remaining = source.Skip(2); - Assert.Equal(3, remaining.ElementAtOrDefault(0)); - Assert.Equal(4, remaining.ElementAtOrDefault(1)); - Assert.Equal(6, remaining.ElementAtOrDefault(3)); - Assert.Equal(0, remaining.ElementAtOrDefault(-1)); - Assert.Equal(0, remaining.ElementAtOrDefault(4)); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5, 6])) + { + IEnumerable remaining = source.Skip(2); + Assert.Equal(3, remaining.ElementAtOrDefault(0)); + Assert.Equal(4, remaining.ElementAtOrDefault(1)); + Assert.Equal(6, remaining.ElementAtOrDefault(3)); + Assert.Equal(0, remaining.ElementAtOrDefault(-1)); + Assert.Equal(0, remaining.ElementAtOrDefault(4)); + } } [Fact] public void First() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(1, source.Skip(0).First()); - Assert.Equal(3, source.Skip(2).First()); - Assert.Equal(5, source.Skip(4).First()); - Assert.Throws(() => source.Skip(5).First()); - } - - [Fact] - public void FirstNotIList() - { - var source = GuaranteeNotIList(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(1, source.Skip(0).First()); - Assert.Equal(3, source.Skip(2).First()); - Assert.Equal(5, source.Skip(4).First()); - Assert.Throws(() => source.Skip(5).First()); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(1, source.Skip(0).First()); + Assert.Equal(3, source.Skip(2).First()); + Assert.Equal(5, source.Skip(4).First()); + Assert.Throws(() => source.Skip(5).First()); + } } [Fact] public void FirstOrDefault() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(1, source.Skip(0).FirstOrDefault()); - Assert.Equal(3, source.Skip(2).FirstOrDefault()); - Assert.Equal(5, source.Skip(4).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).FirstOrDefault()); - } - - [Fact] - public void FirstOrDefaultNotIList() - { - var source = GuaranteeNotIList(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(1, source.Skip(0).FirstOrDefault()); - Assert.Equal(3, source.Skip(2).FirstOrDefault()); - Assert.Equal(5, source.Skip(4).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).FirstOrDefault()); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(1, source.Skip(0).FirstOrDefault()); + Assert.Equal(3, source.Skip(2).FirstOrDefault()); + Assert.Equal(5, source.Skip(4).FirstOrDefault()); + Assert.Equal(0, source.Skip(5).FirstOrDefault()); + } } [Fact] public void Last() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(5, source.Skip(0).Last()); - Assert.Equal(5, source.Skip(1).Last()); - Assert.Equal(5, source.Skip(4).Last()); - Assert.Throws(() => source.Skip(5).Last()); - } - - [Fact] - public void LastNotList() - { - var source = GuaranteeNotIList(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(5, source.Skip(0).Last()); - Assert.Equal(5, source.Skip(1).Last()); - Assert.Equal(5, source.Skip(4).Last()); - Assert.Throws(() => source.Skip(5).Last()); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(5, source.Skip(0).Last()); + Assert.Equal(5, source.Skip(1).Last()); + Assert.Equal(5, source.Skip(4).Last()); + Assert.Throws(() => source.Skip(5).Last()); + } } [Fact] public void LastOrDefault() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(5, source.Skip(0).LastOrDefault()); - Assert.Equal(5, source.Skip(1).LastOrDefault()); - Assert.Equal(5, source.Skip(4).LastOrDefault()); - Assert.Equal(0, source.Skip(5).LastOrDefault()); - } - - [Fact] - public void LastOrDefaultNotList() - { - var source = GuaranteeNotIList(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(5, source.Skip(0).LastOrDefault()); - Assert.Equal(5, source.Skip(1).LastOrDefault()); - Assert.Equal(5, source.Skip(4).LastOrDefault()); - Assert.Equal(0, source.Skip(5).LastOrDefault()); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(5, source.Skip(0).LastOrDefault()); + Assert.Equal(5, source.Skip(1).LastOrDefault()); + Assert.Equal(5, source.Skip(4).LastOrDefault()); + Assert.Equal(0, source.Skip(5).LastOrDefault()); + } } [Fact] public void ToArray() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Skip(0).ToArray()); - Assert.Equal(new[] { 2, 3, 4, 5 }, source.Skip(1).ToArray()); - Assert.Equal(5, source.Skip(4).ToArray().Single()); - Assert.Empty(source.Skip(5).ToArray()); - Assert.Empty(source.Skip(40).ToArray()); - } - - [Fact] - public void ToArrayNotList() - { - var source = GuaranteeNotIList(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Skip(0).ToArray()); - Assert.Equal(new[] { 2, 3, 4, 5 }, source.Skip(1).ToArray()); - Assert.Equal(5, source.Skip(4).ToArray().Single()); - Assert.Empty(source.Skip(5).ToArray()); - Assert.Empty(source.Skip(40).ToArray()); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Skip(0).ToArray()); + Assert.Equal(new[] { 2, 3, 4, 5 }, source.Skip(1).ToArray()); + Assert.Equal(5, source.Skip(4).ToArray().Single()); + Assert.Empty(source.Skip(5).ToArray()); + Assert.Empty(source.Skip(40).ToArray()); + } } [Fact] public void ToList() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Skip(0).ToList()); - Assert.Equal(new[] { 2, 3, 4, 5 }, source.Skip(1).ToList()); - Assert.Equal(5, source.Skip(4).ToList().Single()); - Assert.Empty(source.Skip(5).ToList()); - Assert.Empty(source.Skip(40).ToList()); - } - - [Fact] - public void ToListNotList() - { - var source = GuaranteeNotIList(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Skip(0).ToList()); - Assert.Equal(new[] { 2, 3, 4, 5 }, source.Skip(1).ToList()); - Assert.Equal(5, source.Skip(4).ToList().Single()); - Assert.Empty(source.Skip(5).ToList()); - Assert.Empty(source.Skip(40).ToList()); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Skip(0).ToList()); + Assert.Equal(new[] { 2, 3, 4, 5 }, source.Skip(1).ToList()); + Assert.Equal(5, source.Skip(4).ToList().Single()); + Assert.Empty(source.Skip(5).ToList()); + Assert.Empty(source.Skip(40).ToList()); + } } [Fact] public void RepeatEnumerating() { - var source = new[] { 1, 2, 3, 4, 5 }; - var remaining = source.Skip(1); - Assert.Equal(remaining, remaining); - } - - [Fact] - public void RepeatEnumeratingNotList() - { - var source = GuaranteeNotIList(new[] { 1, 2, 3, 4, 5 }); - var remaining = source.Skip(1); - Assert.Equal(remaining, remaining); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5])) + { + IEnumerable remaining = source.Skip(1); + Assert.Equal(remaining, remaining); + } } [Fact] public void LazySkipMoreThan32Bits() { - var range = NumberRangeGuaranteedNotCollectionType(1, 100); - var skipped = range.Skip(50).Skip(int.MaxValue); // Could cause an integer overflow. + IEnumerable range = NumberRangeGuaranteedNotCollectionType(1, 100); + IEnumerable skipped = range.Skip(50).Skip(int.MaxValue); // Could cause an integer overflow. Assert.Empty(skipped); Assert.Equal(0, skipped.Count()); Assert.Empty(skipped.ToArray()); @@ -489,7 +346,7 @@ public void IteratorStateShouldNotChangeIfNumberOfElementsIsUnbounded() // so that it does not overflow to a negative number and enumeration does not // stop prematurely. - var iterator = new FastInfiniteEnumerator().Skip(1).GetEnumerator(); + using IEnumerator iterator = new FastInfiniteEnumerator().Skip(1).GetEnumerator(); iterator.MoveNext(); // Make sure the underlying enumerator has been initialized. FieldInfo state = iterator.GetType().GetTypeInfo() diff --git a/src/libraries/System.Linq/tests/TakeLastTests.cs b/src/libraries/System.Linq/tests/TakeLastTests.cs index b39d59e94263a6..4d011d50cfd63c 100644 --- a/src/libraries/System.Linq/tests/TakeLastTests.cs +++ b/src/libraries/System.Linq/tests/TakeLastTests.cs @@ -19,25 +19,26 @@ public void SkipLastThrowsOnNull() [MemberData(nameof(EnumerableData), MemberType = typeof(SkipTakeData))] public void TakeLast(IEnumerable source, int count) { - Assert.All(IdentityTransforms(), transform => - { - IEnumerable equivalent = transform(source); + int[] expected = source.Reverse().Take(count).Reverse().ToArray(); - IEnumerable expected = equivalent.Reverse().Take(count).Reverse(); - IEnumerable actual = equivalent.TakeLast(count); + Assert.All(CreateSources(source), source => + { + IEnumerable actual = source.TakeLast(count); Assert.Equal(expected, actual); - Assert.Equal(expected.Count(), actual.Count()); + + Assert.Equal(expected.Length, actual.Count()); Assert.Equal(expected, actual.ToArray()); Assert.Equal(expected, actual.ToList()); - Assert.Equal(expected.FirstOrDefault(), actual.FirstOrDefault()); Assert.Equal(expected.LastOrDefault(), actual.LastOrDefault()); - Assert.All(Enumerable.Range(0, expected.Count()), index => + if (expected.Length > 0) { - Assert.Equal(expected.ElementAt(index), actual.ElementAt(index)); - }); + Assert.Equal(expected[0], actual.ElementAt(0)); + Assert.Equal(expected[^1], actual.ElementAt(expected.Length - 1)); + Assert.Equal(expected[expected.Length / 2], actual.ElementAt(expected.Length / 2)); + } Assert.Equal(0, actual.ElementAtOrDefault(-1)); Assert.Equal(0, actual.ElementAtOrDefault(actual.Count())); diff --git a/src/libraries/System.Linq/tests/TakeTests.cs b/src/libraries/System.Linq/tests/TakeTests.cs index d9408a157124bf..c39c9357ea7c57 100644 --- a/src/libraries/System.Linq/tests/TakeTests.cs +++ b/src/libraries/System.Linq/tests/TakeTests.cs @@ -72,135 +72,85 @@ public void SameResultsRepeatCallsStringQueryIList() [Fact] public void SourceEmptyCountPositive() { - var source = new int[] { }; - Assert.Empty(source.Take(5)); - - Assert.Empty(source.Take(0..5)); - Assert.Empty(source.Take(^5..5)); - Assert.Empty(source.Take(0..^0)); - Assert.Empty(source.Take(^5..^0)); - } - - [Fact] - public void SourceEmptyCountPositiveNotIList() - { - var source = NumberRangeGuaranteedNotCollectionType(0, 0); - Assert.Empty(source.Take(5)); + foreach (IEnumerable source in CreateSources([])) + { + Assert.Empty(source.Take(5)); - Assert.Empty(source.Take(0..5)); - Assert.Empty(source.Take(^5..5)); - Assert.Empty(source.Take(0..^0)); - Assert.Empty(source.Take(^5..^0)); + Assert.Empty(source.Take(0..5)); + Assert.Empty(source.Take(^5..5)); + Assert.Empty(source.Take(0..^0)); + Assert.Empty(source.Take(^5..^0)); + } } [Fact] public void SourceNonEmptyCountNegative() { - var source = new[] { 2, 5, 9, 1 }; - Assert.Empty(source.Take(-5)); - - Assert.Empty(source.Take(^9..0)); - } - - [Fact] - public void SourceNonEmptyCountNegativeNotIList() - { - var source = ForceNotCollection(new[] { 2, 5, 9, 1 }); - Assert.Empty(source.Take(-5)); - - Assert.Empty(source.Take(^9..0)); + foreach (IEnumerable source in CreateSources([2, 5, 9, 1])) + { + Assert.Empty(source.Take(-5)); + Assert.Empty(source.Take(^9..0)); + } } [Fact] public void SourceNonEmptyCountZero() { - var source = new[] { 2, 5, 9, 1 }; - Assert.Empty(source.Take(0)); - - Assert.Empty(source.Take(0..0)); - Assert.Empty(source.Take(^4..0)); - Assert.Empty(source.Take(0..^4)); - Assert.Empty(source.Take(^4..^4)); - } - - [Fact] - public void SourceNonEmptyCountZeroNotIList() - { - var source = ForceNotCollection(new[] { 2, 5, 9, 1 }); - Assert.Empty(source.Take(0)); + foreach (IEnumerable source in CreateSources([2, 5, 9, 1])) + { + Assert.Empty(source.Take(0)); - Assert.Empty(source.Take(0..0)); - Assert.Empty(source.Take(^4..0)); - Assert.Empty(source.Take(0..^4)); - Assert.Empty(source.Take(^4..^4)); + Assert.Empty(source.Take(0..0)); + Assert.Empty(source.Take(^4..0)); + Assert.Empty(source.Take(0..^4)); + Assert.Empty(source.Take(^4..^4)); + } } [Fact] public void SourceNonEmptyCountOne() { - var source = new[] { 2, 5, 9, 1 }; - int[] expected = { 2 }; + int[] expected = [2]; - Assert.Equal(expected, source.Take(1)); - - Assert.Equal(expected, source.Take(0..1)); - Assert.Equal(expected, source.Take(^4..1)); - Assert.Equal(expected, source.Take(0..^3)); - Assert.Equal(expected, source.Take(^4..^3)); - } - - [Fact] - public void SourceNonEmptyCountOneNotIList() - { - var source = ForceNotCollection(new[] { 2, 5, 9, 1 }); - int[] expected = { 2 }; - - Assert.Equal(expected, source.Take(1)); + foreach (IEnumerable source in CreateSources([2, 5, 9, 1])) + { + Assert.Equal(expected, source.Take(1)); - Assert.Equal(expected, source.Take(0..1)); - Assert.Equal(expected, source.Take(^4..1)); - Assert.Equal(expected, source.Take(0..^3)); - Assert.Equal(expected, source.Take(^4..^3)); + Assert.Equal(expected, source.Take(0..1)); + Assert.Equal(expected, source.Take(^4..1)); + Assert.Equal(expected, source.Take(0..^3)); + Assert.Equal(expected, source.Take(^4..^3)); + } } [Fact] public void SourceNonEmptyTakeAllExactly() { - var source = new[] { 2, 5, 9, 1 }; - - Assert.Equal(source, source.Take(source.Length)); - - Assert.Equal(source, source.Take(0..source.Length)); - Assert.Equal(source, source.Take(^source.Length..source.Length)); - Assert.Equal(source, source.Take(0..^0)); - Assert.Equal(source, source.Take(^source.Length..^0)); - } - - [Fact] - public void SourceNonEmptyTakeAllExactlyNotIList() - { - var source = ForceNotCollection(new[] { 2, 5, 9, 1 }); - - Assert.Equal(source, source.Take(source.Count())); + foreach (IEnumerable source in CreateSources([2, 5, 9, 1])) + { + Assert.Equal(source, source.Take(4)); - Assert.Equal(source, source.Take(0..source.Count())); - Assert.Equal(source, source.Take(^source.Count()..source.Count())); - Assert.Equal(source, source.Take(0..^0)); - Assert.Equal(source, source.Take(^source.Count()..^0)); + Assert.Equal(source, source.Take(0..4)); + Assert.Equal(source, source.Take(^4..4)); + Assert.Equal(source, source.Take(0..^0)); + Assert.Equal(source, source.Take(^4..^0)); + } } [Fact] public void SourceNonEmptyTakeAllButOne() { - var source = new[] { 2, 5, 9, 1 }; - int[] expected = { 2, 5, 9 }; + int[] expected = [2, 5, 9]; - Assert.Equal(expected, source.Take(3)); + foreach (IEnumerable source in CreateSources([2, 5, 9, 1])) + { + Assert.Equal(expected, source.Take(3)); - Assert.Equal(expected, source.Take(0..3)); - Assert.Equal(expected, source.Take(^4..3)); - Assert.Equal(expected, source.Take(0..^1)); - Assert.Equal(expected, source.Take(^4..^1)); + Assert.Equal(expected, source.Take(0..3)); + Assert.Equal(expected, source.Take(^4..3)); + Assert.Equal(expected, source.Take(0..^1)); + Assert.Equal(expected, source.Take(^4..^1)); + } } [Fact] @@ -217,40 +167,16 @@ public void RunOnce() Assert.Equal(expected, source.RunOnce().Take(^4..^1)); } - [Fact] - public void SourceNonEmptyTakeAllButOneNotIList() - { - var source = ForceNotCollection(new[] { 2, 5, 9, 1 }); - int[] expected = { 2, 5, 9 }; - - Assert.Equal(expected, source.RunOnce().Take(3)); - - Assert.Equal(expected, source.RunOnce().Take(0..3)); - Assert.Equal(expected, source.RunOnce().Take(^4..3)); - Assert.Equal(expected, source.RunOnce().Take(0..^1)); - Assert.Equal(expected, source.RunOnce().Take(^4..^1)); - } - [Fact] public void SourceNonEmptyTakeExcessive() { - var source = new int?[] { 2, 5, null, 9, 1 }; - - Assert.Equal(source, source.Take(source.Length + 1)); - - Assert.Equal(source, source.Take(0..(source.Length + 1))); - Assert.Equal(source, source.Take(^(source.Length + 1)..(source.Length + 1))); - } - - [Fact] - public void SourceNonEmptyTakeExcessiveNotIList() - { - var source = ForceNotCollection(new int?[] { 2, 5, null, 9, 1 }); - - Assert.Equal(source, source.Take(source.Count() + 1)); + foreach (IEnumerable source in CreateSources([2, 5, null, 9, 1])) + { + Assert.Equal(source, source.Take(5)); - Assert.Equal(source, source.Take(0..(source.Count() + 1))); - Assert.Equal(source, source.Take(^(source.Count() + 1)..(source.Count() + 1))); + Assert.Equal(source, source.Take(0..5)); + Assert.Equal(source, source.Take(^6..6)); + } } [Fact] @@ -342,741 +268,405 @@ public void ForcedToEnumeratorDoesntEnumerateIList() [Fact] public void FollowWithTake() { - var source = new[] { 5, 6, 7, 8 }; var expected = new[] { 5, 6 }; - Assert.Equal(expected, source.Take(5).Take(3).Take(2).Take(40)); - Assert.Equal(expected, source.Take(0..5).Take(0..3).Take(0..2).Take(0..40)); - Assert.Equal(expected, source.Take(^4..5).Take(^4..3).Take(^3..2).Take(^2..40)); - Assert.Equal(expected, source.Take(0..^0).Take(0..^1).Take(0..^1).Take(0..^0)); - Assert.Equal(expected, source.Take(^4..^0).Take(^4..^1).Take(^3..^1).Take(^2..^0)); - } - - [Fact] - public void FollowWithTakeNotIList() - { - var source = NumberRangeGuaranteedNotCollectionType(5, 4); - var expected = new[] { 5, 6 }; - Assert.Equal(expected, source.Take(5).Take(3).Take(2)); + foreach (IEnumerable source in CreateSources([5, 6, 7, 8])) + { + Assert.Equal(expected, source.Take(5).Take(3).Take(2).Take(40)); - Assert.Equal(expected, source.Take(0..5).Take(0..3).Take(0..2)); - Assert.Equal(expected, source.Take(^4..5).Take(^4..3).Take(^3..2)); - Assert.Equal(expected, source.Take(0..^0).Take(0..^1).Take(0..^1)); - Assert.Equal(expected, source.Take(^4..^0).Take(^4..^1).Take(^3..^1)); + Assert.Equal(expected, source.Take(0..5).Take(0..3).Take(0..2).Take(0..40)); + Assert.Equal(expected, source.Take(^4..5).Take(^4..3).Take(^3..2).Take(^2..40)); + Assert.Equal(expected, source.Take(0..^0).Take(0..^1).Take(0..^1).Take(0..^0)); + Assert.Equal(expected, source.Take(^4..^0).Take(^4..^1).Take(^3..^1).Take(^2..^0)); + } } [Fact] public void FollowWithSkip() { - var source = new[] { 1, 2, 3, 4, 5, 6 }; var expected = new[] { 3, 4, 5 }; - Assert.Equal(expected, source.Take(5).Skip(2).Skip(-4)); - - Assert.Equal(expected, source.Take(0..5).Skip(2).Skip(-4)); - Assert.Equal(expected, source.Take(^6..5).Skip(2).Skip(-4)); - Assert.Equal(expected, source.Take(0..^1).Skip(2).Skip(-4)); - Assert.Equal(expected, source.Take(^6..^1).Skip(2).Skip(-4)); - } - [Fact] - public void FollowWithSkipNotIList() - { - var source = NumberRangeGuaranteedNotCollectionType(1, 6); - var expected = new[] { 3, 4, 5 }; - Assert.Equal(expected, source.Take(5).Skip(2).Skip(-4)); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5, 6])) + { + Assert.Equal(expected, source.Take(5).Skip(2).Skip(-4)); - Assert.Equal(expected, source.Take(0..5).Skip(2).Skip(-4)); - Assert.Equal(expected, source.Take(^6..5).Skip(2).Skip(-4)); - Assert.Equal(expected, source.Take(0..^1).Skip(2).Skip(-4)); - Assert.Equal(expected, source.Take(^6..^1).Skip(2).Skip(-4)); + Assert.Equal(expected, source.Take(0..5).Skip(2).Skip(-4)); + Assert.Equal(expected, source.Take(^6..5).Skip(2).Skip(-4)); + Assert.Equal(expected, source.Take(0..^1).Skip(2).Skip(-4)); + Assert.Equal(expected, source.Take(^6..^1).Skip(2).Skip(-4)); + } } [Fact] public void ElementAt() { - var source = new[] { 1, 2, 3, 4, 5, 6 }; - var taken0 = source.Take(3); - Assert.Equal(1, taken0.ElementAt(0)); - Assert.Equal(3, taken0.ElementAt(2)); - Assert.Throws("index", () => taken0.ElementAt(-1)); - Assert.Throws("index", () => taken0.ElementAt(3)); - - var taken1 = source.Take(0..3); - Assert.Equal(1, taken1.ElementAt(0)); - Assert.Equal(3, taken1.ElementAt(2)); - Assert.Throws("index", () => taken1.ElementAt(-1)); - Assert.Throws("index", () => taken1.ElementAt(3)); - - var taken2 = source.Take(^6..3); - Assert.Equal(1, taken2.ElementAt(0)); - Assert.Equal(3, taken2.ElementAt(2)); - Assert.Throws("index", () => taken2.ElementAt(-1)); - Assert.Throws("index", () => taken2.ElementAt(3)); - - var taken3 = source.Take(0..^3); - Assert.Equal(1, taken3.ElementAt(0)); - Assert.Equal(3, taken3.ElementAt(2)); - Assert.Throws("index", () => taken3.ElementAt(-1)); - Assert.Throws("index", () => taken3.ElementAt(3)); - - var taken4 = source.Take(^6..^3); - Assert.Equal(1, taken4.ElementAt(0)); - Assert.Equal(3, taken4.ElementAt(2)); - Assert.Throws("index", () => taken4.ElementAt(-1)); - Assert.Throws("index", () => taken4.ElementAt(3)); - } - - [Fact] - public void ElementAtNotIList() - { - var source = ForceNotCollection(new[] { 1, 2, 3, 4, 5, 6 }); - var taken0 = source.Take(3); - Assert.Equal(1, taken0.ElementAt(0)); - Assert.Equal(3, taken0.ElementAt(2)); - Assert.Throws("index", () => taken0.ElementAt(-1)); - Assert.Throws("index", () => taken0.ElementAt(3)); - - var taken1 = source.Take(0..3); - Assert.Equal(1, taken1.ElementAt(0)); - Assert.Equal(3, taken1.ElementAt(2)); - Assert.Throws("index", () => taken1.ElementAt(-1)); - Assert.Throws("index", () => taken1.ElementAt(3)); - - var taken2 = source.Take(^6..3); - Assert.Equal(1, taken2.ElementAt(0)); - Assert.Equal(3, taken2.ElementAt(2)); - Assert.Throws("index", () => taken2.ElementAt(-1)); - Assert.Throws("index", () => taken2.ElementAt(3)); - - var taken3 = source.Take(0..^3); - Assert.Equal(1, taken3.ElementAt(0)); - Assert.Equal(3, taken3.ElementAt(2)); - Assert.Throws("index", () => taken3.ElementAt(-1)); - Assert.Throws("index", () => taken3.ElementAt(3)); - - var taken4 = source.Take(^6..^3); - Assert.Equal(1, taken4.ElementAt(0)); - Assert.Equal(3, taken4.ElementAt(2)); - Assert.Throws("index", () => taken4.ElementAt(-1)); - Assert.Throws("index", () => taken4.ElementAt(3)); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5, 6])) + { + var taken0 = source.Take(3); + Assert.Equal(1, taken0.ElementAt(0)); + Assert.Equal(3, taken0.ElementAt(2)); + Assert.Throws("index", () => taken0.ElementAt(-1)); + Assert.Throws("index", () => taken0.ElementAt(3)); + + var taken1 = source.Take(0..3); + Assert.Equal(1, taken1.ElementAt(0)); + Assert.Equal(3, taken1.ElementAt(2)); + Assert.Throws("index", () => taken1.ElementAt(-1)); + Assert.Throws("index", () => taken1.ElementAt(3)); + + var taken2 = source.Take(^6..3); + Assert.Equal(1, taken2.ElementAt(0)); + Assert.Equal(3, taken2.ElementAt(2)); + Assert.Throws("index", () => taken2.ElementAt(-1)); + Assert.Throws("index", () => taken2.ElementAt(3)); + + var taken3 = source.Take(0..^3); + Assert.Equal(1, taken3.ElementAt(0)); + Assert.Equal(3, taken3.ElementAt(2)); + Assert.Throws("index", () => taken3.ElementAt(-1)); + Assert.Throws("index", () => taken3.ElementAt(3)); + + var taken4 = source.Take(^6..^3); + Assert.Equal(1, taken4.ElementAt(0)); + Assert.Equal(3, taken4.ElementAt(2)); + Assert.Throws("index", () => taken4.ElementAt(-1)); + Assert.Throws("index", () => taken4.ElementAt(3)); + } } [Fact] public void ElementAtOrDefault() { - var source = new[] { 1, 2, 3, 4, 5, 6 }; - var taken0 = source.Take(3); - Assert.Equal(1, taken0.ElementAtOrDefault(0)); - Assert.Equal(3, taken0.ElementAtOrDefault(2)); - Assert.Equal(0, taken0.ElementAtOrDefault(-1)); - Assert.Equal(0, taken0.ElementAtOrDefault(3)); - - var taken1 = source.Take(0..3); - Assert.Equal(1, taken1.ElementAtOrDefault(0)); - Assert.Equal(3, taken1.ElementAtOrDefault(2)); - Assert.Equal(0, taken1.ElementAtOrDefault(-1)); - Assert.Equal(0, taken1.ElementAtOrDefault(3)); - - var taken2 = source.Take(^6..3); - Assert.Equal(1, taken2.ElementAtOrDefault(0)); - Assert.Equal(3, taken2.ElementAtOrDefault(2)); - Assert.Equal(0, taken2.ElementAtOrDefault(-1)); - Assert.Equal(0, taken2.ElementAtOrDefault(3)); - - var taken3 = source.Take(0..^3); - Assert.Equal(1, taken3.ElementAtOrDefault(0)); - Assert.Equal(3, taken3.ElementAtOrDefault(2)); - Assert.Equal(0, taken3.ElementAtOrDefault(-1)); - Assert.Equal(0, taken3.ElementAtOrDefault(3)); - - var taken4 = source.Take(^6..^3); - Assert.Equal(1, taken4.ElementAtOrDefault(0)); - Assert.Equal(3, taken4.ElementAtOrDefault(2)); - Assert.Equal(0, taken4.ElementAtOrDefault(-1)); - Assert.Equal(0, taken4.ElementAtOrDefault(3)); - } - - [Fact] - public void ElementAtOrDefaultNotIList() - { - var source = ForceNotCollection(new[] { 1, 2, 3, 4, 5, 6 }); - var taken0 = source.Take(3); - Assert.Equal(1, taken0.ElementAtOrDefault(0)); - Assert.Equal(3, taken0.ElementAtOrDefault(2)); - Assert.Equal(0, taken0.ElementAtOrDefault(-1)); - Assert.Equal(0, taken0.ElementAtOrDefault(3)); - - var taken1 = source.Take(0..3); - Assert.Equal(1, taken1.ElementAtOrDefault(0)); - Assert.Equal(3, taken1.ElementAtOrDefault(2)); - Assert.Equal(0, taken1.ElementAtOrDefault(-1)); - Assert.Equal(0, taken1.ElementAtOrDefault(3)); - - var taken2 = source.Take(^6..3); - Assert.Equal(1, taken2.ElementAtOrDefault(0)); - Assert.Equal(3, taken2.ElementAtOrDefault(2)); - Assert.Equal(0, taken2.ElementAtOrDefault(-1)); - Assert.Equal(0, taken2.ElementAtOrDefault(3)); - - var taken3 = source.Take(0..^3); - Assert.Equal(1, taken3.ElementAtOrDefault(0)); - Assert.Equal(3, taken3.ElementAtOrDefault(2)); - Assert.Equal(0, taken3.ElementAtOrDefault(-1)); - Assert.Equal(0, taken3.ElementAtOrDefault(3)); - - var taken4 = source.Take(^6..^3); - Assert.Equal(1, taken4.ElementAtOrDefault(0)); - Assert.Equal(3, taken4.ElementAtOrDefault(2)); - Assert.Equal(0, taken4.ElementAtOrDefault(-1)); - Assert.Equal(0, taken4.ElementAtOrDefault(3)); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5, 6])) + { + var taken0 = source.Take(3); + Assert.Equal(1, taken0.ElementAtOrDefault(0)); + Assert.Equal(3, taken0.ElementAtOrDefault(2)); + Assert.Equal(0, taken0.ElementAtOrDefault(-1)); + Assert.Equal(0, taken0.ElementAtOrDefault(3)); + + var taken1 = source.Take(0..3); + Assert.Equal(1, taken1.ElementAtOrDefault(0)); + Assert.Equal(3, taken1.ElementAtOrDefault(2)); + Assert.Equal(0, taken1.ElementAtOrDefault(-1)); + Assert.Equal(0, taken1.ElementAtOrDefault(3)); + + var taken2 = source.Take(^6..3); + Assert.Equal(1, taken2.ElementAtOrDefault(0)); + Assert.Equal(3, taken2.ElementAtOrDefault(2)); + Assert.Equal(0, taken2.ElementAtOrDefault(-1)); + Assert.Equal(0, taken2.ElementAtOrDefault(3)); + + var taken3 = source.Take(0..^3); + Assert.Equal(1, taken3.ElementAtOrDefault(0)); + Assert.Equal(3, taken3.ElementAtOrDefault(2)); + Assert.Equal(0, taken3.ElementAtOrDefault(-1)); + Assert.Equal(0, taken3.ElementAtOrDefault(3)); + + var taken4 = source.Take(^6..^3); + Assert.Equal(1, taken4.ElementAtOrDefault(0)); + Assert.Equal(3, taken4.ElementAtOrDefault(2)); + Assert.Equal(0, taken4.ElementAtOrDefault(-1)); + Assert.Equal(0, taken4.ElementAtOrDefault(3)); + } } [Fact] public void First() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(1, source.Take(1).First()); - Assert.Equal(1, source.Take(4).First()); - Assert.Equal(1, source.Take(40).First()); - Assert.Throws(() => source.Take(0).First()); - Assert.Throws(() => source.Skip(5).Take(10).First()); - - Assert.Equal(1, source.Take(0..1).First()); - Assert.Equal(1, source.Take(0..4).First()); - Assert.Equal(1, source.Take(0..40).First()); - Assert.Throws(() => source.Take(0..0).First()); - Assert.Throws(() => source.Skip(5).Take(0..10).First()); - - Assert.Equal(1, source.Take(^5..1).First()); - Assert.Equal(1, source.Take(^5..4).First()); - Assert.Equal(1, source.Take(^5..40).First()); - Assert.Throws(() => source.Take(^5..0).First()); - Assert.Throws(() => source.Skip(5).Take(^5..10).First()); - - Assert.Equal(1, source.Take(0..^4).First()); - Assert.Equal(1, source.Take(0..^1).First()); - Assert.Equal(1, source.Take(0..^0).First()); - Assert.Throws(() => source.Take(0..^5).First()); - Assert.Throws(() => source.Skip(5).Take(0..^5).First()); - - Assert.Equal(1, source.Take(^5..^4).First()); - Assert.Equal(1, source.Take(^5..^1).First()); - Assert.Equal(1, source.Take(^5..^0).First()); - Assert.Throws(() => source.Take(^5..^5).First()); - Assert.Throws(() => source.Skip(5).Take(^10..^0).First()); - } - - [Fact] - public void FirstNotIList() - { - var source = ForceNotCollection(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(1, source.Take(1).First()); - Assert.Equal(1, source.Take(4).First()); - Assert.Equal(1, source.Take(40).First()); - Assert.Throws(() => source.Take(0).First()); - Assert.Throws(() => source.Skip(5).Take(10).First()); - - Assert.Equal(1, source.Take(0..1).First()); - Assert.Equal(1, source.Take(0..4).First()); - Assert.Equal(1, source.Take(0..40).First()); - Assert.Throws(() => source.Take(0..0).First()); - Assert.Throws(() => source.Skip(5).Take(0..10).First()); - - Assert.Equal(1, source.Take(^5..1).First()); - Assert.Equal(1, source.Take(^5..4).First()); - Assert.Equal(1, source.Take(^5..40).First()); - Assert.Throws(() => source.Take(^5..0).First()); - Assert.Throws(() => source.Skip(5).Take(^5..10).First()); - - Assert.Equal(1, source.Take(0..^4).First()); - Assert.Equal(1, source.Take(0..^1).First()); - Assert.Equal(1, source.Take(0..^0).First()); - Assert.Throws(() => source.Take(0..^5).First()); - Assert.Throws(() => source.Skip(5).Take(0..^5).First()); - - Assert.Equal(1, source.Take(^5..^4).First()); - Assert.Equal(1, source.Take(^5..^1).First()); - Assert.Equal(1, source.Take(^5..^0).First()); - Assert.Throws(() => source.Take(^5..^5).First()); - Assert.Throws(() => source.Skip(5).Take(^10..^0).First()); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(1, source.Take(1).First()); + Assert.Equal(1, source.Take(4).First()); + Assert.Equal(1, source.Take(40).First()); + Assert.Throws(() => source.Take(0).First()); + Assert.Throws(() => source.Skip(5).Take(10).First()); + + Assert.Equal(1, source.Take(0..1).First()); + Assert.Equal(1, source.Take(0..4).First()); + Assert.Equal(1, source.Take(0..40).First()); + Assert.Throws(() => source.Take(0..0).First()); + Assert.Throws(() => source.Skip(5).Take(0..10).First()); + + Assert.Equal(1, source.Take(^5..1).First()); + Assert.Equal(1, source.Take(^5..4).First()); + Assert.Equal(1, source.Take(^5..40).First()); + Assert.Throws(() => source.Take(^5..0).First()); + Assert.Throws(() => source.Skip(5).Take(^5..10).First()); + + Assert.Equal(1, source.Take(0..^4).First()); + Assert.Equal(1, source.Take(0..^1).First()); + Assert.Equal(1, source.Take(0..^0).First()); + Assert.Throws(() => source.Take(0..^5).First()); + Assert.Throws(() => source.Skip(5).Take(0..^5).First()); + + Assert.Equal(1, source.Take(^5..^4).First()); + Assert.Equal(1, source.Take(^5..^1).First()); + Assert.Equal(1, source.Take(^5..^0).First()); + Assert.Throws(() => source.Take(^5..^5).First()); + Assert.Throws(() => source.Skip(5).Take(^10..^0).First()); + } } [Fact] public void FirstOrDefault() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(1, source.Take(1).FirstOrDefault()); - Assert.Equal(1, source.Take(4).FirstOrDefault()); - Assert.Equal(1, source.Take(40).FirstOrDefault()); - Assert.Equal(0, source.Take(0).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(10).FirstOrDefault()); - - Assert.Equal(1, source.Take(0..1).FirstOrDefault()); - Assert.Equal(1, source.Take(0..4).FirstOrDefault()); - Assert.Equal(1, source.Take(0..40).FirstOrDefault()); - Assert.Equal(0, source.Take(0..0).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(0..10).FirstOrDefault()); - - Assert.Equal(1, source.Take(^5..1).FirstOrDefault()); - Assert.Equal(1, source.Take(^5..4).FirstOrDefault()); - Assert.Equal(1, source.Take(^5..40).FirstOrDefault()); - Assert.Equal(0, source.Take(^5..0).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(^10..10).FirstOrDefault()); - - Assert.Equal(1, source.Take(0..^4).FirstOrDefault()); - Assert.Equal(1, source.Take(0..^1).FirstOrDefault()); - Assert.Equal(1, source.Take(0..^0).FirstOrDefault()); - Assert.Equal(0, source.Take(0..^5).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(0..^10).FirstOrDefault()); - - Assert.Equal(1, source.Take(^5..^4).FirstOrDefault()); - Assert.Equal(1, source.Take(^5..^1).FirstOrDefault()); - Assert.Equal(1, source.Take(^5..^0).FirstOrDefault()); - Assert.Equal(0, source.Take(^5..^5).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(^10..^0).FirstOrDefault()); - } - - [Fact] - public void FirstOrDefaultNotIList() - { - var source = ForceNotCollection(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(1, source.Take(1).FirstOrDefault()); - Assert.Equal(1, source.Take(4).FirstOrDefault()); - Assert.Equal(1, source.Take(40).FirstOrDefault()); - Assert.Equal(0, source.Take(0).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(10).FirstOrDefault()); - - Assert.Equal(1, source.Take(0..1).FirstOrDefault()); - Assert.Equal(1, source.Take(0..4).FirstOrDefault()); - Assert.Equal(1, source.Take(0..40).FirstOrDefault()); - Assert.Equal(0, source.Take(0..0).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(0..10).FirstOrDefault()); - - Assert.Equal(1, source.Take(^5..1).FirstOrDefault()); - Assert.Equal(1, source.Take(^5..4).FirstOrDefault()); - Assert.Equal(1, source.Take(^5..40).FirstOrDefault()); - Assert.Equal(0, source.Take(^5..0).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(^10..10).FirstOrDefault()); - - Assert.Equal(1, source.Take(0..^4).FirstOrDefault()); - Assert.Equal(1, source.Take(0..^1).FirstOrDefault()); - Assert.Equal(1, source.Take(0..^0).FirstOrDefault()); - Assert.Equal(0, source.Take(0..^5).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(0..^10).FirstOrDefault()); - - Assert.Equal(1, source.Take(^5..^4).FirstOrDefault()); - Assert.Equal(1, source.Take(^5..^1).FirstOrDefault()); - Assert.Equal(1, source.Take(^5..^0).FirstOrDefault()); - Assert.Equal(0, source.Take(^5..^5).FirstOrDefault()); - Assert.Equal(0, source.Skip(5).Take(^10..^0).FirstOrDefault()); + foreach (IEnumerable source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(1, source.Take(1).FirstOrDefault()); + Assert.Equal(1, source.Take(4).FirstOrDefault()); + Assert.Equal(1, source.Take(40).FirstOrDefault()); + Assert.Equal(0, source.Take(0).FirstOrDefault()); + Assert.Equal(0, source.Skip(5).Take(10).FirstOrDefault()); + + Assert.Equal(1, source.Take(0..1).FirstOrDefault()); + Assert.Equal(1, source.Take(0..4).FirstOrDefault()); + Assert.Equal(1, source.Take(0..40).FirstOrDefault()); + Assert.Equal(0, source.Take(0..0).FirstOrDefault()); + Assert.Equal(0, source.Skip(5).Take(0..10).FirstOrDefault()); + + Assert.Equal(1, source.Take(^5..1).FirstOrDefault()); + Assert.Equal(1, source.Take(^5..4).FirstOrDefault()); + Assert.Equal(1, source.Take(^5..40).FirstOrDefault()); + Assert.Equal(0, source.Take(^5..0).FirstOrDefault()); + Assert.Equal(0, source.Skip(5).Take(^10..10).FirstOrDefault()); + + Assert.Equal(1, source.Take(0..^4).FirstOrDefault()); + Assert.Equal(1, source.Take(0..^1).FirstOrDefault()); + Assert.Equal(1, source.Take(0..^0).FirstOrDefault()); + Assert.Equal(0, source.Take(0..^5).FirstOrDefault()); + Assert.Equal(0, source.Skip(5).Take(0..^10).FirstOrDefault()); + + Assert.Equal(1, source.Take(^5..^4).FirstOrDefault()); + Assert.Equal(1, source.Take(^5..^1).FirstOrDefault()); + Assert.Equal(1, source.Take(^5..^0).FirstOrDefault()); + Assert.Equal(0, source.Take(^5..^5).FirstOrDefault()); + Assert.Equal(0, source.Skip(5).Take(^10..^0).FirstOrDefault()); + } } [Fact] public void Last() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(1, source.Take(1).Last()); - Assert.Equal(5, source.Take(5).Last()); - Assert.Equal(5, source.Take(40).Last()); - Assert.Throws(() => source.Take(0).Last()); - Assert.Throws(() => Array.Empty().Take(40).Last()); - - Assert.Equal(1, source.Take(0..1).Last()); - Assert.Equal(5, source.Take(0..5).Last()); - Assert.Equal(5, source.Take(0..40).Last()); - Assert.Throws(() => source.Take(0..0).Last()); - Assert.Throws(() => Array.Empty().Take(0..40).Last()); - - Assert.Equal(1, source.Take(^5..1).Last()); - Assert.Equal(5, source.Take(^5..5).Last()); - Assert.Equal(5, source.Take(^5..40).Last()); - Assert.Throws(() => source.Take(^5..0).Last()); - Assert.Throws(() => Array.Empty().Take(^5..40).Last()); - - Assert.Equal(1, source.Take(0..^4).Last()); - Assert.Equal(5, source.Take(0..^0).Last()); - Assert.Equal(5, source.Take(3..^0).Last()); - Assert.Throws(() => source.Take(0..^5).Last()); - Assert.Throws(() => Array.Empty().Take(0..^0).Last()); - - Assert.Equal(1, source.Take(^5..^4).Last()); - Assert.Equal(5, source.Take(^5..^0).Last()); - Assert.Equal(5, source.Take(^5..^0).Last()); - Assert.Throws(() => source.Take(^5..^5).Last()); - Assert.Throws(() => Array.Empty().Take(^40..^0).Last()); - } - - [Fact] - public void LastNotIList() - { - var source = ForceNotCollection(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(1, source.Take(1).Last()); - Assert.Equal(5, source.Take(5).Last()); - Assert.Equal(5, source.Take(40).Last()); - Assert.Throws(() => source.Take(0).Last()); - Assert.Throws(() => ForceNotCollection(Array.Empty()).Take(40).Last()); - - Assert.Equal(1, source.Take(0..1).Last()); - Assert.Equal(5, source.Take(0..5).Last()); - Assert.Equal(5, source.Take(0..40).Last()); - Assert.Throws(() => source.Take(0..0).Last()); - Assert.Throws(() => ForceNotCollection(Array.Empty()).Take(0..40).Last()); - - Assert.Equal(1, source.Take(^5..1).Last()); - Assert.Equal(5, source.Take(^5..5).Last()); - Assert.Equal(5, source.Take(^5..40).Last()); - Assert.Throws(() => source.Take(^5..0).Last()); - Assert.Throws(() => ForceNotCollection(Array.Empty()).Take(^5..40).Last()); - - Assert.Equal(1, source.Take(0..^4).Last()); - Assert.Equal(5, source.Take(0..^0).Last()); - Assert.Equal(5, source.Take(3..^0).Last()); - Assert.Throws(() => source.Take(0..^5).Last()); - Assert.Throws(() => ForceNotCollection(Array.Empty()).Take(0..^0).Last()); - - Assert.Equal(1, source.Take(^5..^4).Last()); - Assert.Equal(5, source.Take(^5..^0).Last()); - Assert.Equal(5, source.Take(^5..^0).Last()); - Assert.Throws(() => source.Take(^5..^5).Last()); - Assert.Throws(() => ForceNotCollection(Array.Empty()).Take(^40..^0).Last()); + foreach (var source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(1, source.Take(1).Last()); + Assert.Equal(2, source.Take(2).Last()); + Assert.Equal(3, source.Take(3).Last()); + Assert.Equal(4, source.Take(4).Last()); + Assert.Equal(5, source.Take(5).Last()); + Assert.Equal(5, source.Take(6).Last()); + Assert.Equal(5, source.Take(40).Last()); + Assert.Throws(() => source.Take(0).Last()); + Assert.Throws(() => Array.Empty().Take(40).Last()); + + Assert.Equal(1, source.Take(0..1).Last()); + Assert.Equal(5, source.Take(0..5).Last()); + Assert.Equal(5, source.Take(0..40).Last()); + Assert.Throws(() => source.Take(0..0).Last()); + Assert.Throws(() => Array.Empty().Take(0..40).Last()); + + Assert.Equal(1, source.Take(^5..1).Last()); + Assert.Equal(5, source.Take(^5..5).Last()); + Assert.Equal(5, source.Take(^5..40).Last()); + Assert.Throws(() => source.Take(^5..0).Last()); + Assert.Throws(() => Array.Empty().Take(^5..40).Last()); + + Assert.Equal(1, source.Take(0..^4).Last()); + Assert.Equal(5, source.Take(0..^0).Last()); + Assert.Equal(5, source.Take(3..^0).Last()); + Assert.Throws(() => source.Take(0..^5).Last()); + Assert.Throws(() => Array.Empty().Take(0..^0).Last()); + + Assert.Equal(1, source.Take(^5..^4).Last()); + Assert.Equal(5, source.Take(^5..^0).Last()); + Assert.Equal(5, source.Take(^5..^0).Last()); + Assert.Throws(() => source.Take(^5..^5).Last()); + Assert.Throws(() => Array.Empty().Take(^40..^0).Last()); + } } [Fact] public void LastOrDefault() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(1, source.Take(1).LastOrDefault()); - Assert.Equal(5, source.Take(5).LastOrDefault()); - Assert.Equal(5, source.Take(40).LastOrDefault()); - Assert.Equal(0, source.Take(0).LastOrDefault()); - Assert.Equal(0, Array.Empty().Take(40).LastOrDefault()); - - Assert.Equal(1, source.Take(0..1).LastOrDefault()); - Assert.Equal(5, source.Take(0..5).LastOrDefault()); - Assert.Equal(5, source.Take(0..40).LastOrDefault()); - Assert.Equal(0, source.Take(0..0).LastOrDefault()); - Assert.Equal(0, Array.Empty().Take(0..40).LastOrDefault()); - - Assert.Equal(1, source.Take(^5..1).LastOrDefault()); - Assert.Equal(5, source.Take(^5..5).LastOrDefault()); - Assert.Equal(5, source.Take(^5..40).LastOrDefault()); - Assert.Equal(0, source.Take(^5..0).LastOrDefault()); - Assert.Equal(0, Array.Empty().Take(^5..40).LastOrDefault()); - - Assert.Equal(1, source.Take(0..^4).LastOrDefault()); - Assert.Equal(5, source.Take(0..^0).LastOrDefault()); - Assert.Equal(5, source.Take(3..^0).LastOrDefault()); - Assert.Equal(0, source.Take(0..^5).LastOrDefault()); - Assert.Equal(0, Array.Empty().Take(0..^0).LastOrDefault()); - - Assert.Equal(1, source.Take(^5..^4).LastOrDefault()); - Assert.Equal(5, source.Take(^5..^0).LastOrDefault()); - Assert.Equal(5, source.Take(^40..^0).LastOrDefault()); - Assert.Equal(0, source.Take(^5..^5).LastOrDefault()); - Assert.Equal(0, Array.Empty().Take(^40..^0).LastOrDefault()); - } - - [Fact] - public void LastOrDefaultNotIList() - { - var source = ForceNotCollection(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(1, source.Take(1).LastOrDefault()); - Assert.Equal(5, source.Take(5).LastOrDefault()); - Assert.Equal(5, source.Take(40).LastOrDefault()); - Assert.Equal(0, source.Take(0).LastOrDefault()); - Assert.Equal(0, ForceNotCollection(Array.Empty()).Take(40).LastOrDefault()); - - Assert.Equal(1, source.Take(0..1).LastOrDefault()); - Assert.Equal(5, source.Take(0..5).LastOrDefault()); - Assert.Equal(5, source.Take(0..40).LastOrDefault()); - Assert.Equal(0, source.Take(0..0).LastOrDefault()); - Assert.Equal(0, ForceNotCollection(Array.Empty()).Take(0..40).LastOrDefault()); - - Assert.Equal(1, source.Take(^5..1).LastOrDefault()); - Assert.Equal(5, source.Take(^5..5).LastOrDefault()); - Assert.Equal(5, source.Take(^5..40).LastOrDefault()); - Assert.Equal(0, source.Take(^5..0).LastOrDefault()); - Assert.Equal(0, ForceNotCollection(Array.Empty()).Take(^5..40).LastOrDefault()); - - Assert.Equal(1, source.Take(0..^4).LastOrDefault()); - Assert.Equal(5, source.Take(0..^0).LastOrDefault()); - Assert.Equal(5, source.Take(3..^0).LastOrDefault()); - Assert.Equal(0, source.Take(0..^5).LastOrDefault()); - Assert.Equal(0, ForceNotCollection(Array.Empty()).Take(0..^0).LastOrDefault()); - - Assert.Equal(1, source.Take(^5..^4).LastOrDefault()); - Assert.Equal(5, source.Take(^5..^0).LastOrDefault()); - Assert.Equal(5, source.Take(^40..^0).LastOrDefault()); - Assert.Equal(0, source.Take(^5..^5).LastOrDefault()); - Assert.Equal(0, ForceNotCollection(Array.Empty()).Take(^40..^0).LastOrDefault()); + foreach (var source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(1, source.Take(1).LastOrDefault()); + Assert.Equal(2, source.Take(2).LastOrDefault()); + Assert.Equal(3, source.Take(3).LastOrDefault()); + Assert.Equal(4, source.Take(4).LastOrDefault()); + Assert.Equal(5, source.Take(5).LastOrDefault()); + Assert.Equal(5, source.Take(6).LastOrDefault()); + Assert.Equal(5, source.Take(40).LastOrDefault()); + Assert.Equal(0, source.Take(0).LastOrDefault()); + Assert.Equal(0, Array.Empty().Take(40).LastOrDefault()); + + Assert.Equal(1, source.Take(0..1).LastOrDefault()); + Assert.Equal(5, source.Take(0..5).LastOrDefault()); + Assert.Equal(5, source.Take(0..40).LastOrDefault()); + Assert.Equal(0, source.Take(0..0).LastOrDefault()); + Assert.Equal(0, Array.Empty().Take(0..40).LastOrDefault()); + + Assert.Equal(1, source.Take(^5..1).LastOrDefault()); + Assert.Equal(5, source.Take(^5..5).LastOrDefault()); + Assert.Equal(5, source.Take(^5..40).LastOrDefault()); + Assert.Equal(0, source.Take(^5..0).LastOrDefault()); + Assert.Equal(0, Array.Empty().Take(^5..40).LastOrDefault()); + + Assert.Equal(1, source.Take(0..^4).LastOrDefault()); + Assert.Equal(5, source.Take(0..^0).LastOrDefault()); + Assert.Equal(5, source.Take(3..^0).LastOrDefault()); + Assert.Equal(0, source.Take(0..^5).LastOrDefault()); + Assert.Equal(0, Array.Empty().Take(0..^0).LastOrDefault()); + + Assert.Equal(1, source.Take(^5..^4).LastOrDefault()); + Assert.Equal(5, source.Take(^5..^0).LastOrDefault()); + Assert.Equal(5, source.Take(^40..^0).LastOrDefault()); + Assert.Equal(0, source.Take(^5..^5).LastOrDefault()); + Assert.Equal(0, Array.Empty().Take(^40..^0).LastOrDefault()); + } } [Fact] public void ToArray() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(5).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(6).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(40).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(4).ToArray()); - Assert.Equal(1, source.Take(1).ToArray().Single()); - Assert.Empty(source.Take(0).ToArray()); - Assert.Empty(source.Take(-10).ToArray()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..5).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..6).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..40).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..4).ToArray()); - Assert.Equal(1, source.Take(0..1).ToArray().Single()); - Assert.Empty(source.Take(0..0).ToArray()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..5).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..6).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..40).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..4).ToArray()); - Assert.Equal(1, source.Take(^5..1).ToArray().Single()); - Assert.Empty(source.Take(^5..0).ToArray()); - Assert.Empty(source.Take(^15..0).ToArray()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..^0).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..^1).ToArray()); - Assert.Equal(1, source.Take(0..^4).ToArray().Single()); - Assert.Empty(source.Take(0..^5).ToArray()); - Assert.Empty(source.Take(0..^15).ToArray()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..^0).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^6..^0).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^45..^0).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..^1).ToArray()); - Assert.Equal(1, source.Take(^5..^4).ToArray().Single()); - Assert.Empty(source.Take(^5..^5).ToArray()); - Assert.Empty(source.Take(^15..^5).ToArray()); - } - - [Fact] - public void ToArrayNotList() - { - var source = ForceNotCollection(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(5).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(6).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(40).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(4).ToArray()); - Assert.Equal(1, source.Take(1).ToArray().Single()); - Assert.Empty(source.Take(0).ToArray()); - Assert.Empty(source.Take(-10).ToArray()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..5).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..6).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..40).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..4).ToArray()); - Assert.Equal(1, source.Take(0..1).ToArray().Single()); - Assert.Empty(source.Take(0..0).ToArray()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..5).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..6).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..40).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..4).ToArray()); - Assert.Equal(1, source.Take(^5..1).ToArray().Single()); - Assert.Empty(source.Take(^5..0).ToArray()); - Assert.Empty(source.Take(^15..0).ToArray()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..^0).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..^1).ToArray()); - Assert.Equal(1, source.Take(0..^4).ToArray().Single()); - Assert.Empty(source.Take(0..^5).ToArray()); - Assert.Empty(source.Take(0..^15).ToArray()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..^0).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^6..^0).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^45..^0).ToArray()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..^1).ToArray()); - Assert.Equal(1, source.Take(^5..^4).ToArray().Single()); - Assert.Empty(source.Take(^5..^5).ToArray()); - Assert.Empty(source.Take(^15..^5).ToArray()); + foreach (var source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(5).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(6).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(40).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(4).ToArray()); + Assert.Equal(1, source.Take(1).ToArray().Single()); + Assert.Empty(source.Take(0).ToArray()); + Assert.Empty(source.Take(-10).ToArray()); + + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..5).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..6).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..40).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..4).ToArray()); + Assert.Equal(1, source.Take(0..1).ToArray().Single()); + Assert.Empty(source.Take(0..0).ToArray()); + + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..5).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..6).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..40).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..4).ToArray()); + Assert.Equal(1, source.Take(^5..1).ToArray().Single()); + Assert.Empty(source.Take(^5..0).ToArray()); + Assert.Empty(source.Take(^15..0).ToArray()); + + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..^0).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..^1).ToArray()); + Assert.Equal(1, source.Take(0..^4).ToArray().Single()); + Assert.Empty(source.Take(0..^5).ToArray()); + Assert.Empty(source.Take(0..^15).ToArray()); + + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..^0).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^6..^0).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^45..^0).ToArray()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..^1).ToArray()); + Assert.Equal(1, source.Take(^5..^4).ToArray().Single()); + Assert.Empty(source.Take(^5..^5).ToArray()); + Assert.Empty(source.Take(^15..^5).ToArray()); + } } [Fact] public void ToList() { - var source = new[] { 1, 2, 3, 4, 5 }; - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(5).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(6).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(40).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(4).ToList()); - Assert.Equal(1, source.Take(1).ToList().Single()); - Assert.Empty(source.Take(0).ToList()); - Assert.Empty(source.Take(-10).ToList()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..5).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..6).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..40).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..4).ToList()); - Assert.Equal(1, source.Take(0..1).ToList().Single()); - Assert.Empty(source.Take(0..0).ToList()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..5).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..6).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..40).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..4).ToList()); - Assert.Equal(1, source.Take(^5..1).ToList().Single()); - Assert.Empty(source.Take(^5..0).ToList()); - Assert.Empty(source.Take(^15..0).ToList()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..^0).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..^1).ToList()); - Assert.Equal(1, source.Take(0..^4).ToList().Single()); - Assert.Empty(source.Take(0..^5).ToList()); - Assert.Empty(source.Take(0..^15).ToList()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..^0).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^6..^0).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^45..^0).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..^1).ToList()); - Assert.Equal(1, source.Take(^5..^4).ToList().Single()); - Assert.Empty(source.Take(^5..^5).ToList()); - Assert.Empty(source.Take(^15..^5).ToList()); - } - - [Fact] - public void ToListNotList() - { - var source = ForceNotCollection(new[] { 1, 2, 3, 4, 5 }); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(5).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(6).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(40).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(4).ToList()); - Assert.Equal(1, source.Take(1).ToList().Single()); - Assert.Empty(source.Take(0).ToList()); - Assert.Empty(source.Take(-10).ToList()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..5).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..6).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..40).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..4).ToList()); - Assert.Equal(1, source.Take(0..1).ToList().Single()); - Assert.Empty(source.Take(0..0).ToList()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..5).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..6).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..40).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..4).ToList()); - Assert.Equal(1, source.Take(^5..1).ToList().Single()); - Assert.Empty(source.Take(^5..0).ToList()); - Assert.Empty(source.Take(^15..0).ToList()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..^0).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..^1).ToList()); - Assert.Equal(1, source.Take(0..^4).ToList().Single()); - Assert.Empty(source.Take(0..^5).ToList()); - Assert.Empty(source.Take(0..^15).ToList()); - - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..^0).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^6..^0).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^45..^0).ToList()); - Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..^1).ToList()); - Assert.Equal(1, source.Take(^5..^4).ToList().Single()); - Assert.Empty(source.Take(^5..^5).ToList()); - Assert.Empty(source.Take(^15..^5).ToList()); + foreach (var source in CreateSources([1, 2, 3, 4, 5])) + { + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(5).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(6).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(40).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(4).ToList()); + Assert.Equal(1, source.Take(1).ToList().Single()); + Assert.Empty(source.Take(0).ToList()); + Assert.Empty(source.Take(-10).ToList()); + + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..5).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..6).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..40).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..4).ToList()); + Assert.Equal(1, source.Take(0..1).ToList().Single()); + Assert.Empty(source.Take(0..0).ToList()); + + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..5).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..6).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..40).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..4).ToList()); + Assert.Equal(1, source.Take(^5..1).ToList().Single()); + Assert.Empty(source.Take(^5..0).ToList()); + Assert.Empty(source.Take(^15..0).ToList()); + + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(0..^0).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(0..^1).ToList()); + Assert.Equal(1, source.Take(0..^4).ToList().Single()); + Assert.Empty(source.Take(0..^5).ToList()); + Assert.Empty(source.Take(0..^15).ToList()); + + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^5..^0).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^6..^0).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4, 5 }, source.Take(^45..^0).ToList()); + Assert.Equal(new[] { 1, 2, 3, 4 }, source.Take(^5..^1).ToList()); + Assert.Equal(1, source.Take(^5..^4).ToList().Single()); + Assert.Empty(source.Take(^5..^5).ToList()); + Assert.Empty(source.Take(^15..^5).ToList()); + } } [Fact] public void TakeCanOnlyBeOneList() { - var source = new[] { 2, 4, 6, 8, 10 }; - Assert.Equal(new[] { 2 }, source.Take(1)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(1)); - Assert.Equal(new[] { 6 }, source.Take(3).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(3).Take(1)); - - Assert.Equal(new[] { 2 }, source.Take(0..1)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(0..1)); - Assert.Equal(new[] { 6 }, source.Take(0..3).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(0..3).Take(0..1)); - - Assert.Equal(new[] { 2 }, source.Take(^5..1)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(^4..1)); - Assert.Equal(new[] { 6 }, source.Take(^5..3).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(^5..3).Take(^4..1)); - - Assert.Equal(new[] { 2 }, source.Take(0..^4)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(0..^3)); - Assert.Equal(new[] { 6 }, source.Take(0..^2).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(0..^2).Take(0..^2)); - - Assert.Equal(new[] { 2 }, source.Take(^5..^4)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(^4..^3)); - Assert.Equal(new[] { 6 }, source.Take(^5..^2).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(^5..^2).Take(^4..^2)); - } - - [Fact] - public void TakeCanOnlyBeOneNotList() - { - var source = ForceNotCollection(new[] { 2, 4, 6, 8, 10 }); - Assert.Equal(new[] { 2 }, source.Take(1)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(1)); - Assert.Equal(new[] { 6 }, source.Take(3).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(3).Take(1)); - - Assert.Equal(new[] { 2 }, source.Take(0..1)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(0..1)); - Assert.Equal(new[] { 6 }, source.Take(0..3).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(0..3).Take(0..1)); - - Assert.Equal(new[] { 2 }, source.Take(^5..1)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(^4..1)); - Assert.Equal(new[] { 6 }, source.Take(^5..3).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(^5..3).Take(^4..1)); - - Assert.Equal(new[] { 2 }, source.Take(0..^4)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(0..^3)); - Assert.Equal(new[] { 6 }, source.Take(0..^2).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(0..^2).Take(0..^2)); - - Assert.Equal(new[] { 2 }, source.Take(^5..^4)); - Assert.Equal(new[] { 4 }, source.Skip(1).Take(^4..^3)); - Assert.Equal(new[] { 6 }, source.Take(^5..^2).Skip(2)); - Assert.Equal(new[] { 2 }, source.Take(^5..^2).Take(^4..^2)); + foreach (var source in CreateSources([2, 4, 6, 8, 10])) + { + Assert.Equal([2], source.Take(1)); + Assert.Equal([4], source.Skip(1).Take(1)); + Assert.Equal([6], source.Take(3).Skip(2)); + Assert.Equal([2], source.Take(3).Take(1)); + + Assert.Equal([2], source.Take(0..1)); + Assert.Equal([4], source.Skip(1).Take(0..1)); + Assert.Equal([6], source.Take(0..3).Skip(2)); + Assert.Equal([2], source.Take(0..3).Take(0..1)); + + Assert.Equal([2], source.Take(^5..1)); + Assert.Equal([4], source.Skip(1).Take(^4..1)); + Assert.Equal([6], source.Take(^5..3).Skip(2)); + Assert.Equal([2], source.Take(^5..3).Take(^4..1)); + + Assert.Equal([2], source.Take(0..^4)); + Assert.Equal([4], source.Skip(1).Take(0..^3)); + Assert.Equal([6], source.Take(0..^2).Skip(2)); + Assert.Equal([2], source.Take(0..^2).Take(0..^2)); + + Assert.Equal([2], source.Take(^5..^4)); + Assert.Equal([4], source.Skip(1).Take(^4..^3)); + Assert.Equal([6], source.Take(^5..^2).Skip(2)); + Assert.Equal([2], source.Take(^5..^2).Take(^4..^2)); + } } [Fact] public void RepeatEnumerating() { - var source = new[] { 1, 2, 3, 4, 5 }; - var taken1 = source.Take(3); - Assert.Equal(taken1, taken1); - - var taken2 = source.Take(0..3); - Assert.Equal(taken2, taken2); - - var taken3 = source.Take(^5..3); - Assert.Equal(taken3, taken3); - - var taken4 = source.Take(0..^2); - Assert.Equal(taken4, taken4); - - var taken5 = source.Take(^5..^2); - Assert.Equal(taken5, taken5); - } - - [Fact] - public void RepeatEnumeratingNotList() - { - var source = ForceNotCollection(new[] { 1, 2, 3, 4, 5 }); - var taken1 = source.Take(3); - Assert.Equal(taken1, taken1); + foreach (var source in CreateSources([1, 2, 3, 4, 5])) + { + var taken1 = source.Take(3); + Assert.Equal(taken1, taken1); - var taken2 = source.Take(0..3); - Assert.Equal(taken2, taken2); + var taken2 = source.Take(0..3); + Assert.Equal(taken2, taken2); - var taken3 = source.Take(^5..3); - Assert.Equal(taken3, taken3); + var taken3 = source.Take(^5..3); + Assert.Equal(taken3, taken3); - var taken4 = source.Take(0..^2); - Assert.Equal(taken4, taken4); + var taken4 = source.Take(0..^2); + Assert.Equal(taken4, taken4); - var taken5 = source.Take(^5..^2); - Assert.Equal(taken5, taken5); + var taken5 = source.Take(^5..^2); + Assert.Equal(taken5, taken5); + } } [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsSpeedOptimized))] diff --git a/src/libraries/System.Linq/tests/WhereTests.cs b/src/libraries/System.Linq/tests/WhereTests.cs index 0cf0ff50cd38a2..a80e8076629ce2 100644 --- a/src/libraries/System.Linq/tests/WhereTests.cs +++ b/src/libraries/System.Linq/tests/WhereTests.cs @@ -1097,44 +1097,40 @@ public void ToCollection(IEnumerable source) [Fact] public void WhereFirstLast() { - Assert.All(IdentityTransforms(), transform => + Assert.All(CreateSources(Enumerable.Range(0, 10)), source => { - IEnumerable data = transform(Enumerable.Range(0, 10)); + Assert.Equal(3, source.Where(i => i == 3).First()); + Assert.Equal(0, source.Where(i => i % 2 == 0).First()); - Assert.Equal(3, data.Where(i => i == 3).First()); - Assert.Equal(0, data.Where(i => i % 2 == 0).First()); + Assert.Equal(3, source.Where(i => i == 3).Last()); + Assert.Equal(8, source.Where(i => i % 2 == 0).Last()); - Assert.Equal(3, data.Where(i => i == 3).Last()); - Assert.Equal(8, data.Where(i => i % 2 == 0).Last()); + Assert.Equal(3, source.Where(i => i == 3).ElementAt(0)); + Assert.Equal(8, source.Where(i => i % 2 == 0).ElementAt(4)); - Assert.Equal(3, data.Where(i => i == 3).ElementAt(0)); - Assert.Equal(8, data.Where(i => i % 2 == 0).ElementAt(4)); - - Assert.Throws(() => data.Where(i => i == 10).First()); - Assert.Throws(() => data.Where(i => i == 10).Last()); - Assert.Throws(() => data.Where(i => i == 10).ElementAt(0)); + Assert.Throws(() => source.Where(i => i == 10).First()); + Assert.Throws(() => source.Where(i => i == 10).Last()); + Assert.Throws(() => source.Where(i => i == 10).ElementAt(0)); }); } [Fact] public void WhereSelectFirstLast() { - Assert.All(IdentityTransforms(), transform => + Assert.All(CreateSources(Enumerable.Range(0, 10)), source => { - IEnumerable data = transform(Enumerable.Range(0, 10)); - - Assert.Equal(6, data.Where(i => i == 3).Select(i => i * 2).First()); - Assert.Equal(0, data.Where(i => i % 2 == 0).Select(i => i * 2).First()); + Assert.Equal(6, source.Where(i => i == 3).Select(i => i * 2).First()); + Assert.Equal(0, source.Where(i => i % 2 == 0).Select(i => i * 2).First()); - Assert.Equal(6, data.Where(i => i == 3).Select(i => i * 2).Last()); - Assert.Equal(16, data.Where(i => i % 2 == 0).Select(i => i * 2).Last()); + Assert.Equal(6, source.Where(i => i == 3).Select(i => i * 2).Last()); + Assert.Equal(16, source.Where(i => i % 2 == 0).Select(i => i * 2).Last()); - Assert.Equal(6, data.Where(i => i == 3).Select(i => i * 2).ElementAt(0)); - Assert.Equal(16, data.Where(i => i % 2 == 0).Select(i => i * 2).ElementAt(4)); + Assert.Equal(6, source.Where(i => i == 3).Select(i => i * 2).ElementAt(0)); + Assert.Equal(16, source.Where(i => i % 2 == 0).Select(i => i * 2).ElementAt(4)); - Assert.Throws(() => data.Where(i => i == 10).Select(i => i * 2).First()); - Assert.Throws(() => data.Where(i => i == 10).Select(i => i * 2).Last()); - Assert.Throws(() => data.Where(i => i == 10).Select(i => i * 2).ElementAt(0)); + Assert.Throws(() => source.Where(i => i == 10).Select(i => i * 2).First()); + Assert.Throws(() => source.Where(i => i == 10).Select(i => i * 2).Last()); + Assert.Throws(() => source.Where(i => i == 10).Select(i => i * 2).ElementAt(0)); }); } @@ -1142,7 +1138,7 @@ public static IEnumerable ToCollectionData() { IEnumerable seq = GenerateRandomSequnce(seed: 0xdeadbeef, count: 10); - foreach (IEnumerable seq2 in IdentityTransforms().Select(t => t(seq))) + foreach (IEnumerable seq2 in CreateSources(seq)) { yield return new object[] { seq2 }; }