namespace Raliway.Tests.Results; public class GeneralUsage { [Fact] public void ChainedResultExtensions_WhenThereIsNoError() { // Given // When var result = Result.Success() .Append(() => Result.Success(1)) .Append("test") .Map((i, s) => $"{s}_{i}") .Append("some") .Bind((s1, s2) => Result.Success(string.Join(';', s1, s2))) .Match( onSuccess: s => s.ToUpper(), onFailure: _ => { true.ShouldBeFalse("should not reach this path"); return ""; } ); result.ShouldBe("TEST_1;SOME"); } [Fact] public void ChainedResultExtensions_WhenThereIsAnError() { // Given var error = Error.New("test"); // When var result = Result.Success() .Append(() => Result.Failure(error)) .Append("test") .Map((i, s) => { true.ShouldBeFalse("should not reach this path"); return ""; }) .Append("some") .Bind((s1, s2) => { true.ShouldBeFalse("should not reach this path"); return Result.Success(""); }) .Match( onSuccess: _ => { true.ShouldBeFalse("should not reach this path"); return ""; }, onFailure: err => { err.ShouldBe(error); return "satisfied"; } ); // Then result.ShouldBe("satisfied"); } [Fact] public async Task ChainedResultAsyncExtensions_WhenThereIsNoError() { // Given // When var result = await Result.Success() .Append(() => Task.FromResult(Result.Success(1))) .Append("test") .Map((i, s) => $"{s}_{i}") .Append("some") .Bind(async (s1, s2) => await ValueTask.FromResult(Result.Success(string.Join(';', s1, s2)))) .Match( onSuccess: s => s.ToUpper(), onFailure: _ => { true.ShouldBeFalse("should not reach this path"); return ""; } ); result.ShouldBe("TEST_1;SOME"); } [Fact] public async Task ChainedResultAsyncExtensions_WhenThereIsAnError() { // Given var error = Error.New("test"); // When var result = await Result.Success() .Append(() => Task.FromResult(Result.Failure(error))) .Append("test") .Map((i, s) => { true.ShouldBeFalse("should not reach this path"); return ""; }) .Append("some") .Bind(async (s1, s2) => { true.ShouldBeFalse("should not reach this path"); await Task.CompletedTask; return Result.Success(""); }) .Match( onSuccess: _ => { true.ShouldBeFalse("should not reach this path"); return ""; }, onFailure: err => { err.ShouldBe(error); return "satisfied"; } ); // Then result.ShouldBe("satisfied"); } [Fact] public void RecoverResultFromFailureState() { // Given Result failed = new NotImplementedException(); // When var result = failed.TryRecover(err => { err.ToException().ShouldBeOfType(); if (err.Type == "System.NotImplementedException") return "recovered"; true.ShouldBeFalse("should not reach this path"); return ""; }); // Then result.IsSuccess.ShouldBeTrue(); result.Value.ShouldBe("recovered"); } [Fact] public void WhenCanNotRecoverResultFromFailureState() { // Given var error = Error.New("test"); Result failed = new NotImplementedException(); // When var result = failed.TryRecover(err => { if (err.Type == "System.NotImplementedException") return error; true.ShouldBeFalse("should not reach this path"); return ""; }); // Then result.IsFailure.ShouldBeTrue(); result.Error.ShouldBe(error); } [Fact] public void WhenExtendingSuccessWithSuccess_ShouldReturnSuccess() { var success = Result.Success(1) .Append("2"); var result = success .Extend((i, s) => Result.Success($"{i} + {s}")); result.IsSuccess.ShouldBeTrue(); result.Value.ShouldBe((1, "2", "1 + 2")); } [Fact] public void WhenExtendingFailureWithSuccess_ShouldNotEvaluateExtension() { var failure = Result.Success(1) .Append(Result.Failure("failure")); var result = failure .Extend((i, s) => { true.ShouldBeFalse("should not reach this path"); return Result.Success(""); }); result.IsFailure.ShouldBeTrue(); result.Error.ShouldBe(Error.New("failure")); } [Fact] public void WhenExtendingSuccessWithFailure_ShouldReturnFailure() { var success = Result.Success(1) .Append("2"); var result = success .Extend((i, s) => Result.Failure("failure")); result.IsFailure.ShouldBeTrue(); result.Error.ShouldBe(Error.New("failure")); } }