Skip to content

Commit

Permalink
Add Rescue methods
Browse files Browse the repository at this point in the history
  • Loading branch information
bfriesen committed Apr 17, 2023
1 parent 89795e3 commit 2a7ebaf
Show file tree
Hide file tree
Showing 3 changed files with 534 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning].

- RandomSkunk.Results:
- Add `Maybe<T>.ToFailIfNone` method.
- Add `Rescue` methods.

### Fixed
- RandomSkunk.Results:
Expand Down
290 changes: 290 additions & 0 deletions RandomSkunk.Results.UnitTests/Rescue_methods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
namespace RandomSkunk.Results.UnitTests;

public class Rescue_methods
{
public class For_Result_sync
{
[Fact]
public void Given_IsSuccess_Returns_source()
{
var sourceResult = Result.Success();
var rescueResult = Result.Fail();

var actual = sourceResult.Rescue(error => rescueResult);

actual.Should().Be(sourceResult);
}

[Fact]
public void Given_IsFail_Returns_result_from_rescue_function()
{
var sourceResult = Result.Fail();
var rescueResult = Result.Success();
Error? capturedError = null;

var actual = sourceResult.Rescue(error =>
{
capturedError = error;
return rescueResult;
});

actual.Should().Be(rescueResult);
capturedError.Should().Be(sourceResult.Error);
}

[Fact]
public void Given_IsFail_When_rescue_function_throws_Returns_result_from_caught_exception()
{
var sourceResult = Result.Fail();
var thrownException = new Exception();

var actual = sourceResult.Rescue((Func<Error, Result>)(error => throw thrownException));

actual.IsFail.Should().BeTrue();
actual.Error.ErrorCode.Should().Be(ErrorCodes.CaughtException);
actual.Error.InnerError!.Title.Should().Be(nameof(Exception));
}
}

public class For_Result_async
{
[Fact]
public async Task Given_IsSuccess_Returns_source()
{
var sourceResult = Result.Success();
var rescueResult = Result.Fail();

var actual = await sourceResult.Rescue(error => Task.FromResult(rescueResult));

actual.Should().Be(sourceResult);
}

[Fact]
public async Task Given_IsFail_Returns_result_from_rescue_function()
{
var sourceResult = Result.Fail();
var rescueResult = Result.Success();
Error? capturedError = null;

var actual = await sourceResult.Rescue(error =>
{
capturedError = error;
return Task.FromResult(rescueResult);
});

actual.Should().Be(rescueResult);
capturedError.Should().Be(sourceResult.Error);
}

[Fact]
public async Task Given_IsFail_When_rescue_function_throws_Returns_result_from_caught_exception()
{
var sourceResult = Result.Fail();
var thrownException = new Exception();

var actual = await sourceResult.Rescue((Func<Error, Task<Result>>)(error => throw thrownException));

actual.IsFail.Should().BeTrue();
actual.Error.ErrorCode.Should().Be(ErrorCodes.CaughtException);
actual.Error.InnerError!.Title.Should().Be(nameof(Exception));
}
}

public class For_Result_of_T_sync
{
[Fact]
public void Given_IsSuccess_Returns_source()
{
var sourceResult = Result<int>.Success(123);
var rescueResult = Result<int>.Fail();

var actual = sourceResult.Rescue(error => rescueResult);

actual.Should().Be(sourceResult);
}

[Fact]
public void Given_IsFail_Returns_result_from_rescue_function()
{
var sourceResult = Result<int>.Fail();
var rescueResult = Result<int>.Success(123);
Error? capturedError = null;

var actual = sourceResult.Rescue(error =>
{
capturedError = error;
return rescueResult;
});

actual.Should().Be(rescueResult);
capturedError.Should().Be(sourceResult.Error);
}

[Fact]
public void Given_IsFail_When_rescue_function_throws_Returns_result_from_caught_exception()
{
var sourceResult = Result<int>.Fail();
var thrownException = new Exception();

var actual = sourceResult.Rescue((Func<Error, Result<int>>)(error => throw thrownException));

actual.IsFail.Should().BeTrue();
actual.Error.ErrorCode.Should().Be(ErrorCodes.CaughtException);
actual.Error.InnerError!.Title.Should().Be(nameof(Exception));
}
}

public class For_Result_of_T_async
{
[Fact]
public async Task Given_IsSuccess_Returns_source()
{
var sourceResult = Result<int>.Success(123);
var rescueResult = Result<int>.Fail();

var actual = await sourceResult.Rescue(error => Task.FromResult(rescueResult));

actual.Should().Be(sourceResult);
}

[Fact]
public async Task Given_IsFail_Returns_result_from_rescue_function()
{
var sourceResult = Result<int>.Fail();
var rescueResult = Result<int>.Success(123);
Error? capturedError = null;

var actual = await sourceResult.Rescue(error =>
{
capturedError = error;
return Task.FromResult(rescueResult);
});

actual.Should().Be(rescueResult);
capturedError.Should().Be(sourceResult.Error);
}

[Fact]
public async Task Given_IsFail_When_rescue_function_throws_Returns_result_from_caught_exception()
{
var sourceResult = Result<int>.Fail();
var thrownException = new Exception();

var actual = await sourceResult.Rescue((Func<Error, Task<Result<int>>>)(error => throw thrownException));

actual.IsFail.Should().BeTrue();
actual.Error.ErrorCode.Should().Be(ErrorCodes.CaughtException);
actual.Error.InnerError!.Title.Should().Be(nameof(Exception));
}
}

public class For_Maybe_of_T_sync
{
[Fact]
public void Given_IsSuccess_Returns_source()
{
var sourceResult = Maybe<int>.Success(123);
var rescueResult = Maybe<int>.Fail();

var actual = sourceResult.Rescue(error => rescueResult);

actual.Should().Be(sourceResult);
}

[Fact]
public void Given_None_Returns_source()
{
var sourceResult = Maybe<int>.None;
var rescueResult = Maybe<int>.Fail();

var actual = sourceResult.Rescue(error => rescueResult);

actual.Should().Be(sourceResult);
}

[Fact]
public void Given_IsFail_Returns_result_from_rescue_function()
{
var sourceResult = Maybe<int>.Fail();
var rescueResult = Maybe<int>.Success(123);
Error? capturedError = null;

var actual = sourceResult.Rescue(error =>
{
capturedError = error;
return rescueResult;
});

actual.Should().Be(rescueResult);
capturedError.Should().Be(sourceResult.Error);
}

[Fact]
public void Given_IsFail_When_rescue_function_throws_Returns_result_from_caught_exception()
{
var sourceResult = Maybe<int>.Fail();
var thrownException = new Exception();

var actual = sourceResult.Rescue((Func<Error, Maybe<int>>)(error => throw thrownException));

actual.IsFail.Should().BeTrue();
actual.Error.ErrorCode.Should().Be(ErrorCodes.CaughtException);
actual.Error.InnerError!.Title.Should().Be(nameof(Exception));
}
}

public class For_Maybe_of_T_async
{
[Fact]
public async Task Given_IsSuccess_Returns_source()
{
var sourceResult = Maybe<int>.Success(123);
var rescueResult = Maybe<int>.Fail();

var actual = await sourceResult.Rescue(error => Task.FromResult(rescueResult));

actual.Should().Be(sourceResult);
}

[Fact]
public async Task Given_IsNone_Returns_source()
{
var sourceResult = Maybe<int>.None;
var rescueResult = Maybe<int>.Fail();

var actual = await sourceResult.Rescue(error => Task.FromResult(rescueResult));

actual.Should().Be(sourceResult);
}

[Fact]
public async Task Given_IsFail_Returns_result_from_rescue_function()
{
var sourceResult = Maybe<int>.Fail();
var rescueResult = Maybe<int>.Success(123);
Error? capturedError = null;

var actual = await sourceResult.Rescue(error =>
{
capturedError = error;
return Task.FromResult(rescueResult);
});

actual.Should().Be(rescueResult);
capturedError.Should().Be(sourceResult.Error);
}

[Fact]
public async Task Given_IsFail_When_rescue_function_throws_Returns_result_from_caught_exception()
{
var sourceResult = Maybe<int>.Fail();
var thrownException = new Exception();

var actual = await sourceResult.Rescue((Func<Error, Task<Maybe<int>>>)(error => throw thrownException));

actual.IsFail.Should().BeTrue();
actual.Error.ErrorCode.Should().Be(ErrorCodes.CaughtException);
actual.Error.InnerError!.Title.Should().Be(nameof(Exception));
}
}
}
Loading

0 comments on commit 2a7ebaf

Please sign in to comment.