Skip to content

Commit

Permalink
Add Enumerable extensions for common scenarios and unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Codeh4ck committed Sep 7, 2023
1 parent b2b189b commit f077d4c
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 0 deletions.
51 changes: 51 additions & 0 deletions Codelux.Common/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Codelux.Common.Extensions;

public static class EnumerableExtensions
{
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> enumerable) => enumerable ?? Enumerable.Empty<T>();

public static IEnumerable<T> EnsureList<T>(this IEnumerable<T> enumerable)
{
return enumerable switch
{
null => new List<T>(),
IList<T> list => list,
_ => enumerable.ToList()
};
}

public static IEnumerable<T> CreateSingleton<T>(T value)
{
yield return value;
}

public static IEnumerable<T> CreateEnumerable<T>(params T[] values) => values;

public static IEnumerable<T> Remove<T>(this IEnumerable<T> enumerable, T value)
{
if (enumerable == null) throw new ArgumentNullException(nameof(enumerable));
return enumerable.Remove(x => x.Equals(value));
}

public static IEnumerable<T> Remove<T>(this IEnumerable<T> enumerable, Func<T, bool> predicate)
{
if (enumerable == null) throw new ArgumentNullException(nameof(enumerable));
return enumerable.Where(x => !predicate(x));
}

public static IEnumerable<T> Replace<T>(this IEnumerable<T> enumerable, T value, Func<T, bool> predicate)
{
if (enumerable == null) throw new ArgumentNullException(nameof(enumerable));
return enumerable.Select(x => predicate(x) ? value : x);
}

public static IEnumerable<T> Replace<T>(this IEnumerable<T> enumerable, T currentValue, T newValue)
{
if (enumerable == null) throw new ArgumentNullException(nameof(enumerable));
return enumerable.Replace(newValue, x => x.Equals(currentValue));
}
}
131 changes: 131 additions & 0 deletions Codelux.Tests/Extensions/EnumerableExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using System.Collections.Generic;
using System.Linq;
using Codelux.Common.Extensions;
using NUnit.Framework;

// ReSharper disable PossibleMultipleEnumeration

namespace Codelux.Tests.Extensions;

[TestFixture]
public class EnumerableExtensionsTests
{
[Test]
public void GivenIEnumerableListWhenIEnsureListThenListIsReturned()
{
IEnumerable<string> list = new List<string>() { "Hello", "World" };

var result = list.EnsureList();

Assert.IsNotNull(result);
Assert.IsNotEmpty(result);

Assert.AreEqual(typeof(List<string>), result.GetType());
Assert.AreEqual(typeof(List<string>), result.GetType());

foreach (string listItem in list)
Assert.IsTrue(result.Contains(listItem));
}

[Test]
public void GivenIEnumerableNullWhenIEmptyIfNullThenEmptyEnumerableIsReturned()
{
IEnumerable<string> list = null;

var result = list.EmptyIfNull();

Assert.IsNotNull(result);
Assert.IsEmpty(result);
}

[Test]
public void GivenSingleObjectWhenIConvertToEnumerableSingletonThenEnumerableIsReturnedAndContainsOnlyOneValue()
{
var testString = "This is a test string";

var result = EnumerableExtensions.CreateSingleton(testString);

Assert.IsNotNull(result);
Assert.IsNotEmpty(result);

Assert.AreEqual(1, result.Count());
Assert.AreEqual(testString, result.ToList()[0]);
}

[Test]
public void GivenMultipleValuesWhenICreateEnumerableThenEnumerableIsReturnedAndValuesAreCorrect()
{
var testString1 = "This is a test string";
var testString2 = "This is another test string";
var testString3 = "This is yet another test string";

var result = EnumerableExtensions.CreateEnumerable(testString1, testString2, testString3);

Assert.IsNotNull(result);
Assert.IsNotEmpty(result);

Assert.AreEqual(3, result.Count());
Assert.AreEqual(testString1, result.ToList()[0]);
Assert.AreEqual(testString2, result.ToList()[1]);
Assert.AreEqual(testString3, result.ToList()[2]);
}

[Test]
public void GivenExistingEnumerableWhenIRemoveAValueThenEnumerableIsReturnedAndValueIsRemoved()
{
var testString1 = "This is a test string";
var testString2 = "REM This is another test string";
var testString3 = "REM This is yet another test string";

var result = EnumerableExtensions.CreateEnumerable(testString1, testString2, testString3);

Assert.IsNotNull(result);
Assert.IsNotEmpty(result);

Assert.AreEqual(3, result.Count());

result = result.Remove(x => x.StartsWith("REM"));
Assert.AreEqual(1, result.Count());
}

[Test]
public void GivenExistingEnumerableWhenIReplaceAValueThenEnumerableIsReturnedAndValueIsReplaced()
{
var testString1 = "This is a test string";
var testString2 = "This is another test string";
var testStringToReplace = "This is yet another test string";

var result = EnumerableExtensions.CreateEnumerable(testString1, testString2, testStringToReplace);

Assert.IsNotNull(result);
Assert.IsNotEmpty(result);

Assert.AreEqual(3, result.Count());

result = result.Replace(testStringToReplace, "Replaced");
Assert.AreEqual(3, result.Count());

Assert.AreEqual("Replaced", result.ToList()[2]);
}

[Test]
public void GivenExistingEnumerableWhenIReplaceValuesThenEnumerableIsReturnedAndValuesAreReplaced()
{
var testString1 = "This is a test string";
var testString2 = "REPLACE This is another test string";
var testStringToReplace = "REPLACE This is yet another test string";

var result = EnumerableExtensions.CreateEnumerable(testString1, testString2, testStringToReplace);

Assert.IsNotNull(result);
Assert.IsNotEmpty(result);

Assert.AreEqual(3, result.Count());

result = result.Replace("Replaced", x => x.StartsWith("REPLACE"));
Assert.AreEqual(3, result.Count());

Assert.AreEqual("Replaced", result.ToList()[1]);
Assert.AreEqual("Replaced", result.ToList()[2]);
}
}

0 comments on commit f077d4c

Please sign in to comment.