Skip to content

Commit

Permalink
Added extensions for AllOrNone and IsNotNullOrEmpty.
Browse files Browse the repository at this point in the history
  • Loading branch information
JeevanJames committed Feb 20, 2019
1 parent e53172a commit eee111b
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 23 deletions.
46 changes: 23 additions & 23 deletions src/Collections/Collections.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions src/Collections/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,45 @@ namespace System.Collections.Generic
{
public static class EnumerableExtensions
{
/// <summary>
/// Determines whether all or none of the elements in a <paramref name="sequence"/> match the specified
/// <paramref name="predicate"/>.
/// </summary>
/// <typeparam name="T">The type of the elements of sequence.</typeparam>
/// <param name="sequence">The sequence.</param>
/// <param name="predicate">The <paramref name="predicate"/> to check against.</param>
/// <returns>
/// <c>true</c>, if all or none of the elements in the sequence match the predicate. If some elements match
/// and others do not, then <c>false</c> is returned.
/// </returns>
/// <exception cref="ArgumentNullException">Thrown of the sequence is <c>null</c>.</exception>
/// <exception cref="ArgumentNullException">Thrown of the predicate is <c>null</c>.</exception>
public static bool AllOrNone<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
if (sequence == null)
throw new ArgumentNullException(nameof(sequence));
if (predicate == null)
throw new ArgumentNullException(nameof(predicate));

// Track state of the predicate for each element.
bool? result = null;

foreach (T element in sequence)
{
bool elementResult = predicate(element);
// If first element, set the tracking state variable. All subsequent elements should return the same
// value for the predicate.
if (!result.HasValue)
result = elementResult;
// If the predicate for the current element is different from the tracking value, then the sequence
// contains elements that return different values for the predicate and hence return false.
else if (elementResult != result.Value)
return false;
}

return true;
}

public static IEnumerable<T[]> Chunk<T>(this IEnumerable<T> sequence, int chunkSize)
{
if (sequence == null)
Expand Down Expand Up @@ -111,6 +150,17 @@ public static bool IsEmpty<T>(this IEnumerable<T> sequence)
return sequence is ICollection<T> coll ? coll.Count == 0 : !sequence.Any();
}

/// <summary>
/// Indicates whether the specified <paramref name="sequence"/> is not <c>null</c> and has at least one element.
/// </summary>
/// <typeparam name="T">The type of the elements of the sequence</typeparam>
/// <param name="sequence">The sequence.</param>
/// <returns><c>true</c>, if the sequence if not <c>null</c> and has elements.</returns>
public static bool IsNotNullOrEmpty<T>(this IEnumerable<T> sequence)
{
return sequence != null && sequence.Any();
}

/// <summary>
/// Indicates whether the specified sequence is null or does not contain any elements.
/// </summary>
Expand Down
70 changes: 70 additions & 0 deletions tests/Collection.Tests/CollectionExtensions/AllOrNone_Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#region --- License & Copyright Notice ---
/*
Custom collections and collection extensions for .NET
Copyright (c) 2018-2019 Jeevan James
All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#endregion

using System;
using System.Collections.Generic;

using Collection.Tests.DataAttributes;

using Shouldly;

using Xunit;

namespace Collection.Tests.CollectionExtensions
{
public sealed class AllOrNone_Tests
{
[Theory, DataAttributes.Collection(CollectionType.Null)]
public void Throws_if_sequence_is_null(IEnumerable<int> sequence)
{
Should.Throw<ArgumentNullException>(() => sequence.AllOrNone(n => n % 2 == 0));
}

[Theory, DataAttributes.Collection(CollectionType.NonEmpty)]
public void Throws_if_predicate_is_null(IEnumerable<int> sequence)
{
Should.Throw<ArgumentNullException>(() => sequence.AllOrNone(null));
}

[Theory, DataAttributes.Collection(CollectionType.Empty)]
public void Returns_true_for_empty_sequence(IEnumerable<int> sequence)
{
sequence.AllOrNone(n => n % 2 == 0).ShouldBeTrue();
}

[Theory, DataAttributes.Collection(CollectionType.NumbersOneToSix)]
public void Returns_true_if_all_items_match(IEnumerable<int> sequence)
{
sequence.AllOrNone(n => n < 7).ShouldBeTrue();
}

[Theory, DataAttributes.Collection(CollectionType.NumbersOneToSix)]
public void Returns_true_if_no_items_match(IEnumerable<int> sequence)
{
sequence.AllOrNone(n => n > 7).ShouldBeTrue();
}

[Theory, DataAttributes.Collection(CollectionType.NumbersOneToSix)]
public void Returns_false_if_some_items_match_and_some_dont(IEnumerable<int> sequence)
{
sequence.AllOrNone(n => n % 2 == 0).ShouldBeFalse();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections.Generic;

using Collection.Tests.DataAttributes;

using Shouldly;

using Xunit;

namespace Collection.Tests.CollectionExtensions
{
public sealed class IsNotNullOrEmpty_Tests
{
[Theory, DataAttributes.Collection(CollectionType.Null)]
public void Returns_false_if_sequence_is_null(IEnumerable<int> sequence)
{
sequence.IsNotNullOrEmpty().ShouldBeFalse();
}

[Theory, DataAttributes.Collection(CollectionType.Empty)]
public void Returns_false_if_sequence_is_empty(IEnumerable<int> sequence)
{
sequence.IsNotNullOrEmpty().ShouldBeFalse();
}

[Theory, DataAttributes.Collection(CollectionType.NonEmpty)]
public void Returns_true_if_sequence_is_not_empty(IEnumerable<int> sequence)
{
sequence.IsNotNullOrEmpty().ShouldBeTrue();
}
}
}

0 comments on commit eee111b

Please sign in to comment.