diff --git a/Kritner.ExtensionMethods.sln b/Kritner.ExtensionMethods.sln new file mode 100644 index 0000000..66b6f45 --- /dev/null +++ b/Kritner.ExtensionMethods.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2050 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{484A8DCA-7AF8-48E0-880F-4D1DB0A02FAD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{AF09B244-7FC2-4077-A3D3-969DD6D68CD7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kritner.ExtensionMethods", "src\Kritner.ExtensionMethods\Kritner.ExtensionMethods.csproj", "{BDA56FBA-DD3E-489E-BA4E-175BED05D53A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kritner.ExtensionMethods.Tests", "test\Kritner.ExtensionMethods.Tests\Kritner.ExtensionMethods.Tests.csproj", "{D5F701C5-FBF7-4825-BA6F-7861A4AB6F77}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BDA56FBA-DD3E-489E-BA4E-175BED05D53A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BDA56FBA-DD3E-489E-BA4E-175BED05D53A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDA56FBA-DD3E-489E-BA4E-175BED05D53A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BDA56FBA-DD3E-489E-BA4E-175BED05D53A}.Release|Any CPU.Build.0 = Release|Any CPU + {D5F701C5-FBF7-4825-BA6F-7861A4AB6F77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D5F701C5-FBF7-4825-BA6F-7861A4AB6F77}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D5F701C5-FBF7-4825-BA6F-7861A4AB6F77}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D5F701C5-FBF7-4825-BA6F-7861A4AB6F77}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {BDA56FBA-DD3E-489E-BA4E-175BED05D53A} = {484A8DCA-7AF8-48E0-880F-4D1DB0A02FAD} + {D5F701C5-FBF7-4825-BA6F-7861A4AB6F77} = {AF09B244-7FC2-4077-A3D3-969DD6D68CD7} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4C63CCD4-16B5-4554-8E94-505F1390A0E9} + EndGlobalSection +EndGlobal diff --git a/src/Kritner.ExtensionMethods/EnumerableExtensions.cs b/src/Kritner.ExtensionMethods/EnumerableExtensions.cs new file mode 100644 index 0000000..df2d56c --- /dev/null +++ b/src/Kritner.ExtensionMethods/EnumerableExtensions.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kritner.ExtensionMethods +{ + /// + /// extension methods. + /// + public static class EnumerableExtensions + { + /// + /// Attempts to find the first item in + /// meeting . + /// + /// Returns the when item found, + /// when not. + /// + /// Found result is contained within out parameter . + /// + /// + /// + /// + /// + /// when item found. otherwise. + /// + /// Thrown when or is null. + /// + public static bool TryFirst( + this IEnumerable items, + Func predicate, + out T result + ) + { + if (items == null) + throw new ArgumentNullException(nameof(items)); + if (predicate == null) + throw new ArgumentNullException(nameof(predicate)); + + result = default(T); + foreach (var item in items) + { + if (predicate(item)) + { + result = item; + return true; + } + } + return false; + } + } +} diff --git a/src/Kritner.ExtensionMethods/Kritner.ExtensionMethods.csproj b/src/Kritner.ExtensionMethods/Kritner.ExtensionMethods.csproj new file mode 100644 index 0000000..9f5c4f4 --- /dev/null +++ b/src/Kritner.ExtensionMethods/Kritner.ExtensionMethods.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/src/Kritner.ExtensionMethods/ListExtensions.cs b/src/Kritner.ExtensionMethods/ListExtensions.cs new file mode 100644 index 0000000..609595c --- /dev/null +++ b/src/Kritner.ExtensionMethods/ListExtensions.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Kritner.ExtensionMethods +{ + /// + /// extensions. + /// + public static class ListExtensions + { + /// + /// Add object to only when not null. + /// + /// The type contained within the . + /// The . + /// The item to potentially add. + /// Thrown if is null + public static void AddIfNotNull(this IList obj, T item) + { + if (obj == null) + { + throw new ArgumentNullException($"{nameof(obj)} is null"); + } + + if (item == null) + { + return; + } + + obj.Add(item); + } + + /// + /// Adds a to an . + /// + /// The type contained within the . + /// The . + /// The items to potentially add. + /// Thrown if is null + public static void AddRangeIfNotNull(this IList obj, IEnumerable items) + { + if (obj == null) + { + throw new ArgumentNullException($"{nameof(obj)} is null"); + } + + if (items == null) + { + return; + } + + if (obj is List objList) + { + objList.AddRange(items); + return; + } + + foreach (var item in items) + { + obj.Add(item); + } + } + } +} diff --git a/src/Kritner.ExtensionMethods/TaskExtensions.cs.cs b/src/Kritner.ExtensionMethods/TaskExtensions.cs.cs new file mode 100644 index 0000000..5c674d9 --- /dev/null +++ b/src/Kritner.ExtensionMethods/TaskExtensions.cs.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; + +namespace Kritner.ExtensionMethods +{ + /// + /// Extension Methods for + /// + public static class TaskExtensions + { + /// + /// Can be used to fire off a Task and not await the reuslt. + /// + /// + public static void FireAndForget(this Task task) { } + } +} diff --git a/test/Kritner.ExtensionMethods.Tests/EnumerableExtensionTests.cs b/test/Kritner.ExtensionMethods.Tests/EnumerableExtensionTests.cs new file mode 100644 index 0000000..0bf52ff --- /dev/null +++ b/test/Kritner.ExtensionMethods.Tests/EnumerableExtensionTests.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace Kritner.ExtensionMethods.Tests +{ + public class EnumerableExtensionTests + { + public class EnumerableTest + { + public int SomeInt { get; set; } + } + + public static List EnumerableTestData => + new List() + { + new object[] + { + new List() + { + new EnumerableTest() { SomeInt = 1 }, + new EnumerableTest() { SomeInt = 42 }, + } + } + }; + + [Fact] + public void ShouldThrowWhenItemsNull() + { + List items = null; + + Assert.Throws(() => + items.TryFirst(t => t.SomeInt == 42, out var result) + ); + } + + [Theory] + [MemberData(nameof(EnumerableTestData))] + public void ShouldThrowWhenPredicateNull(List items) + { + Assert.Throws(() => + items.TryFirst(null, out var result) + ); + } + + [Theory] + [MemberData(nameof(EnumerableTestData))] + public void ShouldReturnFalseWhenDataNotFound(List items) + { + var found = items.TryFirst( + t => t.SomeInt == 100, out var result + ); + + Assert.False(found); + } + + [Theory] + [MemberData(nameof(EnumerableTestData))] + public void ShouldReturnTrueWhenDataFound(List items) + { + var found = items.TryFirst( + t => t.SomeInt == 42, out var result + ); + + Assert.True(found); + } + + [Theory] + [MemberData(nameof(EnumerableTestData))] + public void ShouldReturnDataWhenDataFound(List items) + { + var dataToSearch = 42; + + var found = items.TryFirst( + t => t.SomeInt == dataToSearch, out var result + ); + + Assert.Equal(dataToSearch, result.SomeInt); + } + } +} diff --git a/test/Kritner.ExtensionMethods.Tests/Kritner.ExtensionMethods.Tests.csproj b/test/Kritner.ExtensionMethods.Tests/Kritner.ExtensionMethods.Tests.csproj new file mode 100644 index 0000000..6018a27 --- /dev/null +++ b/test/Kritner.ExtensionMethods.Tests/Kritner.ExtensionMethods.Tests.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + diff --git a/test/Kritner.ExtensionMethods.Tests/ListExtensionTests.cs b/test/Kritner.ExtensionMethods.Tests/ListExtensionTests.cs new file mode 100644 index 0000000..a8b8e3c --- /dev/null +++ b/test/Kritner.ExtensionMethods.Tests/ListExtensionTests.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using Xunit; + +namespace Kritner.ExtensionMethods.Tests +{ + public class ListExtensionTests + { + public class TestClass { } + + #region AddIfNotNull + [Fact] + public void AddIfNotNull_ShouldAddItemWhenNotNull() + { + var list = new List(); + var notNullItem = new TestClass(); + + list.AddIfNotNull(notNullItem); + + Assert.True(list.Count == 1); + } + + [Fact] + public void AddIfNotNull_ShouldNotAddItemWhenNull() + { + var list = new List(); + TestClass nullItem = null; + + list.AddIfNotNull(nullItem); + + Assert.True(list.Count == 0); + } + + [Fact] + public void AddIfNotNull_ShouldThrowIfListIsNull() + { + List list = null; + var item = new TestClass(); + + Assert.Throws(() => list.AddIfNotNull(item)); + } + #endregion AddIfNotNull + + #region AddRangeIfNotNull + public static IEnumerable AddRangeSuccessMultipleType => + new List() + { + new object[] + { + new TestClass[] { new TestClass(), }, 1 + }, + new object[] + { + new TestClass[] { new TestClass(), new TestClass() }, 2 + }, + new object[] + { + new List { new TestClass(), }, 1 + }, + new object[] + { + new List { new TestClass(), new TestClass() }, 2 + } + }; + + [Theory] + [MemberData(nameof(AddRangeSuccessMultipleType))] + public void AddRangeIfNotNull_ShouldAddItemsWhenNotNull( + IEnumerable testData, + int numberOfElementsToAdd + ) + { + var list = new List(); + + list.AddRangeIfNotNull(testData); + + Assert.Equal(numberOfElementsToAdd, list.Count); + } + + public static IEnumerable AddRangeNoItemsMultipleType => + new List() + { + new object[] + { + new TestClass[] { } + }, + new object[] + { + null + }, + new object[] + { + new List () + } + }; + + [Theory] + [MemberData(nameof(AddRangeNoItemsMultipleType))] + public void AddRangeIfNotNull_ShouldNotAddItemsWhenNoItemsToAdd(IEnumerable testData) + { + var list = new List(); + + list.AddRangeIfNotNull(testData); + + Assert.Empty(list); + } + + [Fact] + public void AddRangeIfNotNull_ShouldThrowIfListIsNull() + { + List list = null; + var item = new TestClass(); + + Assert.Throws( + () => list.AddRangeIfNotNull(new[] { item }) + ); + } + #endregion AddRangeIfNotNull + } +}