diff --git a/CSharpEssentials.Tests/Any/AnyCollectionExtensionsTests.cs b/CSharpEssentials.Tests/Any/AnyCollectionExtensionsTests.cs index 058cef3..cbc8acb 100644 --- a/CSharpEssentials.Tests/Any/AnyCollectionExtensionsTests.cs +++ b/CSharpEssentials.Tests/Any/AnyCollectionExtensionsTests.cs @@ -176,6 +176,34 @@ public void CollectionExtensions_WithNullSource_ShouldThrowArgumentNullException action.Should().Throw().WithParameterName("source"); } + [Fact] + public void Traverse_T3_ShouldProjectAndPartition() + { + int[] source = [0, 1, 2, 3, 4]; + + var result = source.Traverse(value => value switch + { + 0 => value, + 1 => value.ToString(CultureInfo.InvariantCulture), + _ => true + }); + + result.First.Should().Equal(0); + result.Second.Should().Equal("1"); + result.Third.Should().Equal(true, true, true); + } + + [Fact] + public void Traverse_T4_WithNullSelector_ShouldThrowArgumentNullException() + { + int[] values = [1]; + Func> selector = null!; + + Action action = () => values.Traverse(selector); + + action.Should().Throw().WithParameterName("selector"); + } + [Fact] public void Traverse_WithNullSelector_ShouldThrowArgumentNullException() { diff --git a/CSharpEssentials.Tests/Results/ResultCollectionBatchTests.cs b/CSharpEssentials.Tests/Results/ResultCollectionBatchTests.cs index 61a8804..2dd5298 100644 --- a/CSharpEssentials.Tests/Results/ResultCollectionBatchTests.cs +++ b/CSharpEssentials.Tests/Results/ResultCollectionBatchTests.cs @@ -216,6 +216,64 @@ public void ResultCollectionExtensions_WithNullSource_ShouldThrowArgumentNullExc action.Should().Throw().WithParameterName("source"); } + [Fact] + public void Traverse_WithFailures_ShouldAggregateErrors() + { + int[] source = [1, 2, 3]; + + Result result = source.Traverse(value => + value == 2 + ? Result.Failure(Error.Validation("Traverse.Error", "Bad value")) + : $"item-{value}".ToResult()); + + result.IsFailure.Should().BeTrue(); + result.Errors.Should().ContainSingle(x => x.Code == "Traverse.Error"); + } + + [Fact] + public void Partition_IResult_ShouldReturnSuccessesAndErrors() + { + IResult[] source = + [ + (Result)10, + (Result)Error.Validation("First.Error", "First"), + (Result)20, + (Result)Error.Validation("Second.Error", "Second") + ]; + + (int[] successes, Error[] errors) = source.Partition(); + + successes.Should().Equal(10, 20); + errors.Select(x => x.Code).Should().Equal("First.Error", "Second.Error"); + } + + [Fact] + public void FirstFailureOrSuccesses_AllSuccesses_ShouldReturnSuccessWithValues() + { + Result[] source = [1, 2, 3]; + + Result result = source.FirstFailureOrSuccesses(); + + result.IsSuccess.Should().BeTrue(); + result.Value.Should().Equal(1, 2, 3); + } + + [Fact] + public void FirstFailureOrSuccesses_IResult_AllSuccesses_ShouldReturnSuccessWithValues() + { + IResult[] source = + [ + (Result)1, + (Result)2, + (Result)3 + ]; + + Result result = source.FirstFailureOrSuccesses(); + + result.IsSuccess.Should().BeTrue(); + result.Value.Should().Equal(1, 2, 3); + } + [Fact] public void Traverse_WithNullSelector_ShouldThrowArgumentNullException() { diff --git a/CSharpEssentials.Tests/Results/ResultSelectTests.cs b/CSharpEssentials.Tests/Results/ResultSelectTests.cs index 213c7c4..213b926 100644 --- a/CSharpEssentials.Tests/Results/ResultSelectTests.cs +++ b/CSharpEssentials.Tests/Results/ResultSelectTests.cs @@ -164,6 +164,21 @@ public void ResultT_SelectMany_WithProjector_OriginalFailure_ShouldNotExecute() #endregion + #region SelectAsync (Task> overloads) + + [Fact] + public async Task SelectAsync_Task_OnFailure_ShouldReturnFailure() + { + Task> task = Task.FromResult(Result.Failure(TestError)); + + Result result = await task.SelectAsync(x => Task.FromResult(x.ToString(System.Globalization.CultureInfo.InvariantCulture))); + + result.IsFailure.Should().BeTrue(); + result.FirstError.Should().Be(TestError); + } + + #endregion + #region Chaining (LINQ query syntax compatibility) [Fact] diff --git a/README.MD b/README.MD index 6db0720..fd24db4 100644 --- a/README.MD +++ b/README.MD @@ -6,7 +6,7 @@ [![Build](https://github.com/senrecep/CSharpEssentials/actions/workflows/build.yml/badge.svg)](https://github.com/senrecep/CSharpEssentials/actions/workflows/build.yml) -[![Tests](https://img.shields.io/badge/tests-2781%20passing-brightgreen)](https://github.com/senrecep/CSharpEssentials/actions/workflows/build.yml) +[![Tests](https://img.shields.io/badge/tests-2788%20passing-brightgreen)](https://github.com/senrecep/CSharpEssentials/actions/workflows/build.yml) ======= >>>>>>> pr-21 [![NuGet](https://img.shields.io/nuget/v/CSharpEssentials.svg)](https://www.nuget.org/packages/CSharpEssentials)