Skip to content

feature/result-monad-updates #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 210 additions & 0 deletions OnixLabs.Core.UnitTests/ResultExtensionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,170 @@ namespace OnixLabs.Core.UnitTests;

public sealed class ResultExtensionTests
{
[Fact(DisplayName = "Result Success.GetExceptionOrDefaultAsync should produce the expected result.")]
public async Task ResultSuccessGetExceptionOrDefaultAsyncShouldProduceExpectedResult()
{
// Given
Result result = Result.Success();

// When
Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync();

// Then
Assert.Null(actual);
}

[Fact(DisplayName = "Result Success.GetExceptionOrDefaultAsync with default value should produce the expected result.")]
public async Task ResultSuccessGetExceptionOrDefaultAsyncWithDefaultValueShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result result = Result.Success();

// When
Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(expected);

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result Success.GetExceptionOrThrowAsync should produce the expected result.")]
public async Task ResultSuccessGetExceptionOrThrowAsyncShouldProduceExpectedResult()
{
// Given
Result result = Result.Success();

// When
Exception exception = await Assert.ThrowsAsync<InvalidOperationException>(async () => await Task.FromResult(result).GetExceptionOrThrowAsync());

// Then
Assert.Equal("The current result is not in a Failure state.", exception.Message);
}

[Fact(DisplayName = "Result Failure.GetExceptionOrDefaultAsync should produce the expected result.")]
public async Task ResultFailureGetExceptionOrDefaultAsyncShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result result = Result.Failure(expected);

// When
Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync();

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result Failure.GetExceptionOrDefaultAsync with default value should produce the expected result.")]
public async Task ResultFailureGetExceptionOrDefaultAsyncWithDefaultValueShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result result = Result.Failure(expected);

// When
Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(new Exception("unexpected exception"));

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result Failure.GetExceptionOrThrowAsync should produce the expected result.")]
public async Task ResultFailureGetExceptionOrThrowAsyncShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result result = Result.Failure(expected);

// When
Exception actual = await Task.FromResult(result).GetExceptionOrThrowAsync();

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result<T> Success.GetExceptionOrDefaultAsync should produce the expected result.")]
public async Task ResultOfTSuccessGetExceptionOrDefaultAsyncShouldProduceExpectedResult()
{
// Given
Result<int> result = Result<int>.Success(123);

// When
Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync();

// Then
Assert.Null(actual);
}

[Fact(DisplayName = "Result<T> Success.GetExceptionOrDefaultAsync with default value should produce the expected result.")]
public async Task ResultOfTSuccessGetExceptionOrDefaultAsyncWithDefaultValueShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result<int> result = Result<int>.Success(123);

// When
Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(expected);

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result<T> Success.GetExceptionOrThrowAsync should produce the expected result.")]
public async Task ResultOfTSuccessGetExceptionOrThrowAsyncShouldProduceExpectedResult()
{
// Given
Result<int> result = Result<int>.Success(123);

// When
Exception exception = await Assert.ThrowsAsync<InvalidOperationException>(async () => await Task.FromResult(result).GetExceptionOrThrowAsync());

// Then
Assert.Equal("The current result is not in a Failure<T> state.", exception.Message);
}

[Fact(DisplayName = "Result<T> Failure.GetExceptionOrDefaultAsync should produce the expected result.")]
public async Task ResultOfTFailureGetExceptionOrDefaultAsyncShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result<int> result = Result<int>.Failure(expected);

// When
Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync();

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result<T> Failure.GetExceptionOrDefaultAsync with default value should produce the expected result.")]
public async Task ResultOfTFailureGetExceptionOrDefaultAsyncWithDefaultValueShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result<int> result = Result<int>.Failure(expected);

// When
Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(new Exception("unexpected exception"));

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result<T> Failure.GetExceptionOrThrowAsync should produce the expected result.")]
public async Task ResultOfTFailureGetExceptionOrThrowAsyncShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result<int> result = Result<int>.Failure(expected);

// When
Exception actual = await Task.FromResult(result).GetExceptionOrThrowAsync();

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result.GetValueOrDefaultAsync should return the result value when the result is Success")]
public async Task ResultGetValueOrDefaultAsyncShouldReturnResultValueWhenResultIsSuccess()
{
Expand Down Expand Up @@ -68,6 +232,7 @@ public async Task ResultGetValueOrDefaultAsyncWithDefaultValueShouldReturnResult

// When
int actualNumber = await numberTask.GetValueOrDefaultAsync(456);
// ReSharper disable once VariableCanBeNotNullable
string? actualText = await textTask.GetValueOrDefaultAsync("xyz");

// Then
Expand Down Expand Up @@ -843,4 +1008,49 @@ public async Task ResultOfTFailureThrowAsyncShouldThrowException()
// When / Then
await Assert.ThrowsAsync<Exception>(async () => await Task.FromResult(result).ThrowAsync());
}

[Fact(DisplayName = "Result Failure.ToTypedResultAsync should produce the expected result.")]
public async Task ResultFailureToTypedResultAsyncShouldProduceExpectedResult()
{
// Given
Exception exception = new("failure");
Failure result = Result.Failure(exception);

// When
Result<int> actual = await Task.FromResult(result).ToTypedResultAsync<int>();

// Then
Assert.IsType<Failure<int>>(actual);
Assert.Equal("System.Exception: failure", actual.GetExceptionOrThrow().ToString());
}

[Fact(DisplayName = "Result<T> Failure.ToTypedResultAsync should produce the expected result.")]
public async Task ResultOfTFailureToTypedResultAsyncShouldProduceExpectedResult()
{
// Given
Exception exception = new("failure");
Failure<string> result = Result<string>.Failure(exception);

// When
Result<int> actual = await Task.FromResult(result).ToTypedResultAsync<string, int>();

// Then
Assert.IsType<Failure<int>>(actual);
Assert.Equal("System.Exception: failure", actual.GetExceptionOrThrow().ToString());
}

[Fact(DisplayName = "Result<T> Failure.ToUntypedResultAsync should produce the expected result.")]
public async Task ResultOfTFailureToUntypedResultAsyncShouldProduceExpectedResult()
{
// Given
Exception exception = new("failure");
Failure<string> result = Result<string>.Failure(exception);

// When
Result actual = await Task.FromResult(result).ToUntypedResultAsync();

// Then
Assert.IsType<Failure>(actual);
Assert.Equal("System.Exception: failure", actual.GetExceptionOrThrow().ToString());
}
}
112 changes: 112 additions & 0 deletions OnixLabs.Core.UnitTests/ResultGenericTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,88 @@ public void ResultFailureGetHashCodeShouldProduceExpectedResult()
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result Success.GetExceptionOrDefault should produce the expected result.")]
public void ResultSuccessGetExceptionOrDefaultShouldProduceExpectedResult()
{
// Given
Result<int> result = Result<int>.Success(123);

// When
Exception? actual = result.GetExceptionOrDefault();

// Then
Assert.Null(actual);
}

[Fact(DisplayName = "Result Success.GetExceptionOrDefault with default value should produce the expected result.")]
public void ResultSuccessGetExceptionOrDefaultWithDefaultValueShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result<int> result = Result<int>.Success(123);

// When
Exception actual = result.GetExceptionOrDefault(expected);

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result Success.GetExceptionOrThrow should produce the expected result.")]
public void ResultSuccessGetExceptionOrThrowShouldProduceExpectedResult()
{
// Given
Result<int> result = Result<int>.Success(123);

// When
Exception exception = Assert.Throws<InvalidOperationException>(() => result.GetExceptionOrThrow());

// Then
Assert.Equal("The current result is not in a Failure<T> state.", exception.Message);
}

[Fact(DisplayName = "Result Failure.GetExceptionOrDefault should produce the expected result.")]
public void ResultFailureGetExceptionOrDefaultShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result<int> result = Result<int>.Failure(expected);

// When
Exception? actual = result.GetExceptionOrDefault();

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result Failure.GetExceptionOrDefault with default value should produce the expected result.")]
public void ResultFailureGetExceptionOrDefaultWithDefaultValueShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result<int> result = Result<int>.Failure(expected);

// When
Exception actual = result.GetExceptionOrDefault(new Exception("unexpected exception"));

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result Failure.GetExceptionOrThrow should produce the expected result.")]
public void ResultFailureGetExceptionOrThrowShouldProduceExpectedResult()
{
// Given
Exception expected = new("failure");
Result<int> result = Result<int>.Failure(expected);

// When
Exception actual = result.GetExceptionOrThrow();

// Then
Assert.Equal(expected, actual);
}

[Fact(DisplayName = "Result Success.GetValueOrDefault should produce the expected result.")]
public void ResultSuccessGetValueOrDefaultShouldProduceExpectedResult()
{
Expand Down Expand Up @@ -683,6 +765,36 @@ public void ResultFailureToStringShouldProduceExpectedResult()
Assert.Equal("System.Exception: failure", textString);
}

[Fact(DisplayName = "Result Failure.ToTypedResult should produce the expected result.")]
public void ResultFailureToTypedResultShouldProduceExpectedResult()
{
// Given
Exception exception = new("failure");
Failure<string> result = Result<string>.Failure(exception);

// When
Result<int> actual = result.ToTypedResult<int>();

// Then
Assert.IsType<Failure<int>>(actual);
Assert.Equal("System.Exception: failure", actual.GetExceptionOrThrow().ToString());
}

[Fact(DisplayName = "Result Failure.ToUntypedResult should produce the expected result.")]
public void ResultFailureToUntypedResultShouldProduceExpectedResult()
{
// Given
Exception exception = new("failure");
Failure<string> result = Result<string>.Failure(exception);

// When
Result actual = result.ToUntypedResult();

// Then
Assert.IsType<Failure>(actual);
Assert.Equal("System.Exception: failure", actual.GetExceptionOrThrow().ToString());
}

[Fact(DisplayName = "Result Success.Dispose should dispose of the underlying value.")]
public void ResultSuccessDisposeShouldDisposeUnderlyingValue()
{
Expand Down
Loading
Loading