Skip to content

Commit

Permalink
Simplify tests for count family of methods
Browse files Browse the repository at this point in the history
This is a squashed merge of PR #507 that closes #445.

Co-authored-by: Avi Levin <[email protected]>
Co-authored-by: Atif Aziz <[email protected]>
  • Loading branch information
3 people authored Jan 22, 2023
1 parent 0be76fd commit d587f73
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 199 deletions.
82 changes: 21 additions & 61 deletions MoreLinq.Test/AtLeastTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
namespace MoreLinq.Test
{
using NUnit.Framework;
using System.Collections.Generic;

[TestFixture]
public class AtLeastTest
Expand All @@ -29,68 +30,27 @@ public void AtLeastWithNegativeCount()
Throws.ArgumentOutOfRangeException("count"));
}

[Test]
public void AtLeastWithEmptySequenceHasAtLeastZeroElements()
{
foreach (var xs in Enumerable.Empty<int>().ArrangeCollectionTestCases())
Assert.That(xs.AtLeast(0), Is.True);
}

[Test]
public void AtLeastWithEmptySequenceHasAtLeastOneElement()
{
foreach (var xs in Enumerable.Empty<int>().ArrangeCollectionTestCases())
Assert.That(xs.AtLeast(1), Is.False);
}

[Test]
public void AtLeastWithEmptySequenceHasAtLeastManyElements()
{
foreach (var xs in Enumerable.Empty<int>().ArrangeCollectionTestCases())
Assert.That(xs.AtLeast(2), Is.False);
}

[Test]
public void AtLeastWithSingleElementHasAtLeastZeroElements()
{
foreach (var xs in new[] { 1 }.ArrangeCollectionTestCases())
Assert.That(xs.AtLeast(0), Is.True);
}

[Test]
public void AtLeastWithSingleElementHasAtLeastOneElement()
{
foreach (var xs in new[] { 1 }.ArrangeCollectionTestCases())
Assert.That(xs.AtLeast(1), Is.True);
}
public static IEnumerable<TestCaseData> AtLeastSource =>
from k in SourceKinds.Sequence.Concat(SourceKinds.Collection)
from e in new[]
{
(Size: 0, Count: 0),
(Size: 0, Count: 1),
(Size: 0, Count: 2),
(Size: 1, Count: 0),
(Size: 1, Count: 1),
(Size: 1, Count: 2),
(Size: 3, Count: 0),
(Size: 3, Count: 1),
(Size: 3, Count: 2)
}
select new TestCaseData(k, e.Size, e.Count)
.Returns(e.Size >= e.Count)
.SetName($"{{m}}({k}[{e.Size}], {e.Count})");

[Test]
public void AtLeastWithSingleElementHasAtLeastManyElements()
{
foreach (var xs in new[] { 1 }.ArrangeCollectionTestCases())
Assert.That(xs.AtLeast(2), Is.False);
}

[Test]
public void AtLeastWithManyElementsHasAtLeastZeroElements()
{
foreach (var xs in new[] { 1, 2, 3 }.ArrangeCollectionTestCases())
Assert.That(xs.AtLeast(0), Is.True);
}

[Test]
public void AtLeastWithManyElementsHasAtLeastOneElement()
{
foreach (var xs in new[] { 1, 2, 3 }.ArrangeCollectionTestCases())
Assert.That(xs.AtLeast(1), Is.True);
}

[Test]
public void AtLeastWithManyElementsHasAtLeastManyElements()
{
foreach (var xs in new[] { 1, 2, 3 }.ArrangeCollectionTestCases())
Assert.That(xs.AtLeast(2), Is.True);
}
[TestCaseSource(nameof(AtLeastSource))]
public bool AtLeast(SourceKind sourceKind, int sequenceSize, int atLeastAssertCount) =>
Enumerable.Range(0, sequenceSize).ToSourceKind(sourceKind).AtLeast(atLeastAssertCount);

[Test]
public void AtLeastDoesNotIterateUnnecessaryElements()
Expand Down
60 changes: 19 additions & 41 deletions MoreLinq.Test/AtMostTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
namespace MoreLinq.Test
{
using NUnit.Framework;
using System.Collections.Generic;

[TestFixture]
public class AtMostTest
Expand All @@ -29,47 +30,24 @@ public void AtMostWithNegativeCount()
Throws.ArgumentOutOfRangeException("count"));
}

[Test]
public void AtMostWithEmptySequenceHasAtMostZeroElements()
{
foreach (var xs in Enumerable.Empty<int>().ArrangeCollectionTestCases())
Assert.That(xs.AtMost(0), Is.True);
}

[Test]
public void AtMostWithEmptySequenceHasAtMostOneElement()
{
foreach (var xs in Enumerable.Empty<int>().ArrangeCollectionTestCases())
Assert.That(xs.AtMost(1), Is.True);
}

[Test]
public void AtMostWithSingleElementHasAtMostZeroElements()
{
foreach (var xs in new[] { 1 }.ArrangeCollectionTestCases())
Assert.That(xs.AtMost(0), Is.False);
}

[Test]
public void AtMostWithSingleElementHasAtMostOneElement()
{
foreach (var xs in new[] { 1 }.ArrangeCollectionTestCases())
Assert.That(xs.AtMost(1), Is.True);
}

[Test]
public void AtMostWithSingleElementHasAtMostManyElements()
{
foreach (var xs in new[] { 1 }.ArrangeCollectionTestCases())
Assert.That(xs.AtMost(2), Is.True);
}

[Test]
public void AtMostWithManyElementsHasAtMostOneElements()
{
foreach (var xs in new[] { 1, 2, 3 }.ArrangeCollectionTestCases())
Assert.That(xs.AtMost(1), Is.False);
}
public static IEnumerable<TestCaseData> AtMostSource =>
from k in SourceKinds.Sequence.Concat(SourceKinds.Collection)
from e in new[]
{
(Size: 0, Count: 0),
(Size: 0, Count: 1),
(Size: 1, Count: 0),
(Size: 1, Count: 1),
(Size: 1, Count: 2),
(Size: 3, Count: 1)
}
select new TestCaseData(k, e.Size, e.Count)
.Returns(e.Size <= e.Count)
.SetName($"{{m}}({k}[{e.Size}], {e.Count})");

[TestCaseSource(nameof(AtMostSource))]
public bool AtMost(SourceKind sourceKind, int sequenceSize, int atMostAssertCount) =>
Enumerable.Range(0, sequenceSize).ToSourceKind(sourceKind).AtMost(atMostAssertCount);

[Test]
public void AtMostDoesNotIterateUnnecessaryElements()
Expand Down
63 changes: 13 additions & 50 deletions MoreLinq.Test/CompareCountTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,28 @@

namespace MoreLinq.Test
{
using System;
using System.Collections.Generic;
using NUnit.Framework;

[TestFixture]
public class CompareCountTest
{
static readonly IEnumerable<TestCaseData> CompareCountData =
static IEnumerable<TestCaseData> CompareCountData =>
from e in new[]
{
new { Count1 = 0, Count2 = 0, Comparison = 0 },
new { Count1 = 0, Count2 = 1, Comparison = -1 },
new { Count1 = 1, Count2 = 0, Comparison = 1 },
new { Count1 = 1, Count2 = 1, Comparison = 0 },
(Count1: 0, Count2: 0, Comparison: 0 ),
(Count1: 0, Count2: 1, Comparison: -1 ),
(Count1: 1, Count2: 0, Comparison: 1 ),
(Count1: 1, Count2: 1, Comparison: 0 )
}
from s in GetTestSequenceKinds(
Enumerable.Range(1, e.Count1),
Enumerable.Range(1, e.Count2),
(xs, ys) => new { First = xs, Second = ys })
select new TestCaseData(s.First.Data, s.Second.Data)
.Returns(e.Comparison)
.SetName($"{{m}}({s.First.Kind}[{e.Count1}], {s.Second.Kind}[{e.Count2}]) = {e.Comparison}");
from firstKind in SourceKinds.Sequence.Concat(SourceKinds.Collection)
from secondKind in SourceKinds.Sequence.Concat(SourceKinds.Collection)
select new TestCaseData(
Enumerable.Range(1, e.Count1).ToSourceKind(firstKind),
Enumerable.Range(1, e.Count2).ToSourceKind(secondKind))
.Returns(e.Comparison)
.SetName($"{{m}}({firstKind}[{e.Count1}], {secondKind}[{e.Count2}]) = {e.Comparison}");


[TestCaseSource(nameof(CompareCountData))]
public int CompareCount(IEnumerable<int> xs, IEnumerable<int> ys) =>
Expand Down Expand Up @@ -138,42 +138,5 @@ public void CompareCountDoesNotIterateUnnecessaryElements()
Assert.That(seq1.CompareCount(seq2), Is.EqualTo( 1));
Assert.That(seq2.CompareCount(seq1), Is.EqualTo(-1));
}

enum SequenceKind
{
Sequence,
Collection,
ReadOnlyCollection,
}

static IEnumerable<TResult> GetTestSequenceKinds<T, TResult>(
IEnumerable<T> s1, IEnumerable<T> s2,
Func<(IEnumerable<T> Data, SequenceKind Kind),
(IEnumerable<T> Data, SequenceKind Kind), TResult> selector)
{
// Test that the operator is optimized for collections

var s1Seq = (s1.Select(x => x), SequenceKind.Sequence);
var s2Seq = (s2.Select(x => x), SequenceKind.Sequence);

var s1Col = (s1.ToSourceKind(SourceKind.BreakingCollection), SequenceKind.Collection);
var s2Col = (s2.ToSourceKind(SourceKind.BreakingCollection), SequenceKind.Collection);

var s1ReadOnlyCol = (s1.ToSourceKind(SourceKind.BreakingReadOnlyCollection), SequenceKind.ReadOnlyCollection);
var s2ReadOnlyCol = (s2.ToSourceKind(SourceKind.BreakingReadOnlyCollection), SequenceKind.ReadOnlyCollection);

// sequences
yield return selector(s1Seq, s2Seq);

// sequences and collections
yield return selector(s1Seq, s2Col);
yield return selector(s1Col, s2Seq);
yield return selector(s1Col, s2Col);

// sequences and readOnlyCollections
yield return selector(s1Seq, s2ReadOnlyCol);
yield return selector(s1ReadOnlyCol, s2Seq);
yield return selector(s1ReadOnlyCol, s2ReadOnlyCol);
}
}
}
32 changes: 18 additions & 14 deletions MoreLinq.Test/CountBetweenTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
namespace MoreLinq.Test
{
using NUnit.Framework;
using System.Collections.Generic;

[TestFixture]
public class CountBetweenTest
Expand All @@ -43,22 +44,25 @@ public void CountBetweenWithMaxLesserThanMin()
Throws.ArgumentOutOfRangeException("max"));
}

[Test]
public void CountBetweenWithMaxEqualsMin()
{
foreach (var xs in new[] { 1 }.ArrangeCollectionTestCases())
Assert.That(xs.CountBetween(1, 1), Is.True);
}
static IEnumerable<TestCaseData> CountBetweenSource =>
from args in new[]
{
(Count: 1, Min: 1, Max: 1),
(Count: 1, Min: 2, Max: 4),
(Count: 2, Min: 2, Max: 4),
(Count: 3, Min: 2, Max: 4),
(Count: 4, Min: 2, Max: 4),
(Count: 5, Min: 2, Max: 4),
}
from type in SourceKinds.Sequence.Concat(SourceKinds.Collection)
select new TestCaseData(type, args.Count, args.Min, args.Max)
.Returns(args.Count >= args.Min && args.Count <= args.Max)
.SetName($"{{m}}({type}[{args.Count}], {args.Min}, {args.Max})");

[TestCase(1, 2, 4, false)]
[TestCase(2, 2, 4, true)]
[TestCase(3, 2, 4, true)]
[TestCase(4, 2, 4, true)]
[TestCase(5, 2, 4, false)]
public void CountBetweenRangeTests(int count, int min, int max, bool expecting)
[TestCaseSource(nameof(CountBetweenSource))]
public bool CountBetween(SourceKind sourceKind, int count, int min, int max)
{
foreach (var xs in Enumerable.Range(1, count).ArrangeCollectionTestCases())
Assert.That(xs.CountBetween(min, max), Is.EqualTo(expecting));
return Enumerable.Range(0, count).ToSourceKind(sourceKind).CountBetween(min, max);
}

[Test]
Expand Down
2 changes: 1 addition & 1 deletion MoreLinq.Test/CountDownTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ static IEnumerable<T> GetData<T>(Func<int[], int, int?[], T> selector)
{
Source = xs, Count = count, Countdown = countdown
})
from kind in new[] { SourceKind.BreakingList, SourceKind.BreakingReadOnlyList }
from kind in SourceKinds.List
select new TestCaseData(e.Source.ToSourceKind(kind), e.Count)
.Returns(e.Source.Zip(e.Countdown, ValueTuple.Create))
.SetName($"{nameof(WithList)}({kind} {{ {string.Join(", ", e.Source)} }}, {e.Count})");
Expand Down
41 changes: 16 additions & 25 deletions MoreLinq.Test/ExactlyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
namespace MoreLinq.Test
{
using NUnit.Framework;
using System.Collections.Generic;

[TestFixture]
public class ExactlyTest
Expand All @@ -29,33 +30,23 @@ public void ExactlyWithNegativeCount()
Throws.ArgumentOutOfRangeException("count"));
}

[Test]
public void ExactlyWithEmptySequenceHasExactlyZeroElements()
{
foreach (var xs in Enumerable.Empty<int>().ArrangeCollectionTestCases())
Assert.That(xs.Exactly(0), Is.True);
}
static IEnumerable<TestCaseData> ExactlySource =>
from k in SourceKinds.Sequence.Concat(SourceKinds.Collection)
from e in new[]
{
(Size: 0, Count: 0),
(Size: 0, Count: 1),
(Size: 1, Count: 1),
(Size: 3, Count: 1)
}
select new TestCaseData(k, e.Size, e.Count)
.Returns(e.Size == e.Count)
.SetName($"{{m}}({k}[{e.Size}], {e.Count})");

[Test]
public void ExactlyWithEmptySequenceHasExactlyOneElement()
{
foreach (var xs in Enumerable.Empty<int>().ArrangeCollectionTestCases())
Assert.That(xs.Exactly(1), Is.False);
}
[TestCaseSource(nameof(ExactlySource))]
public bool Exactly(SourceKind sourceKind, int sequenceSize, int exactlyAssertCount) =>
Enumerable.Range(0, sequenceSize).ToSourceKind(sourceKind).Exactly(exactlyAssertCount);

[Test]
public void ExactlyWithSingleElementHasExactlyOneElements()
{
foreach (var xs in new[] { 1 }.ArrangeCollectionTestCases())
Assert.That(xs.Exactly(1), Is.True);
}

[Test]
public void ExactlyWithManyElementHasExactlyOneElement()
{
foreach (var xs in new[] { 1, 2, 3 }.ArrangeCollectionTestCases())
Assert.That(xs.Exactly(1), Is.False);
}

[Test]
public void ExactlyDoesNotIterateUnnecessaryElements()
Expand Down
Loading

0 comments on commit d587f73

Please sign in to comment.