Skip to content

Commit

Permalink
Major fix in Result Wrapper.
Browse files Browse the repository at this point in the history
  • Loading branch information
Bruno de Souza Melo committed Sep 9, 2024
1 parent 0b3dda4 commit d8e4b40
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 50 deletions.
2 changes: 1 addition & 1 deletion src/NuvTools.Common/NuvTools.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>NuvTools.Common.snk</AssemblyOriginatorKeyFile>
<Description>Common library for Web, Desktop and Mobile (MAUI) applications.</Description>
<Version>8.1.0</Version>
<Version>8.1.2</Version>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
<PackageIcon>icon.png</PackageIcon>
Expand Down
2 changes: 1 addition & 1 deletion src/NuvTools.Common/ResultWrapper/IResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ public interface IResult

public interface IResult<out T> : IResult
{
T Data { get; }
T? Data { get; }
}
80 changes: 39 additions & 41 deletions src/NuvTools.Common/ResultWrapper/Result.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;

namespace NuvTools.Common.ResultWrapper;

public abstract class ResultBase : IResult
public class Result : IResult
{
public bool Succeeded { get; protected set; }
public ResultType ResultType { get; protected set; }
public List<MessageDetail> Messages { get; protected set; } = [];
public bool Succeeded { get; set; }
public ResultType ResultType { get; set; } = ResultType.Success;
public List<MessageDetail> Messages { get; set; } = [];

protected static void Log(ResultType resultType, IEnumerable<MessageDetail>? messages, ILogger? logger)
protected static void Log(List<MessageDetail>? messages, ILogger? logger)
{
if (logger == null || messages == null) return;

Expand All @@ -33,55 +32,54 @@ protected static void Log(ResultType resultType, IEnumerable<MessageDetail>? mes
}
}
}
}

public class Result : ResultBase, IResult
{
private Result(bool succeeded, ResultType resultType, List<MessageDetail>? messages)
protected static List<MessageDetail> ConvertToMessageDetail(IEnumerable<string> value)
{
Succeeded = succeeded;
ResultType = resultType;
Messages = messages ?? [];
return value.Select(e => new MessageDetail(e)).ToList();
}

public static IResult Create(bool succeeded, ResultType resultType, List<MessageDetail>? messages = null, ILogger? logger = null)
private static Result CreateResult(ResultType resultType, List<MessageDetail>? messages = null, ILogger? logger = null)
{
Log(resultType, messages, logger);
return new Result(succeeded, resultType, messages);
Log(messages, logger);
return new Result { Succeeded = resultType == ResultType.Success, ResultType = resultType, Messages = messages ?? [] };
}

public static IResult Success(List<MessageDetail>? messages = null) => Create(true, ResultType.Success, messages);
public static IResult Fail(List<MessageDetail>? messages = null, ILogger? logger = null) => Create(false, ResultType.Error, messages, logger);
public static IResult ValidationFail(List<MessageDetail>? messages = null, ILogger? logger = null) => Create(false, ResultType.ValidationError, messages, logger);
public static IResult Fail(List<MessageDetail>? messages = null, ILogger? logger = null) => CreateResult(ResultType.Error, messages, logger);
public static IResult Fail(List<string> messages, ILogger? logger = null) => Fail(ConvertToMessageDetail(messages), logger);
public static IResult Fail(string message, ILogger? logger = null) => Fail([message], logger);
public static IResult Fail(MessageDetail message, ILogger? logger = null) => Fail([message], logger);

public static IResult ValidationFail(List<MessageDetail> messages, ILogger? logger = null) => CreateResult(ResultType.ValidationError, messages, logger);
public static IResult ValidationFail(List<string> messages, ILogger? logger = null) => ValidationFail(ConvertToMessageDetail(messages), logger);
public static IResult ValidationFail(MessageDetail message, ILogger? logger = null) => ValidationFail([message], logger);
public static IResult ValidationFail(string message, ILogger? logger = null) => ValidationFail([message], logger);

public static Task<IResult> SuccessAsync(List<MessageDetail>? messages = null) => Task.FromResult(Success(messages));
public static Task<IResult> FailAsync(List<MessageDetail>? messages = null, ILogger? logger = null) => Task.FromResult(Fail(messages, logger));
public static Task<IResult> ValidationFailAsync(List<MessageDetail>? messages = null, ILogger? logger = null) => Task.FromResult(ValidationFail(messages, logger));
public static IResult Success(MessageDetail? message = null) => new Result { Succeeded = true, Messages = [message] };
public static IResult Success(string message) => Success(new MessageDetail(message));
}

public class Result<T> : ResultBase, IResult<T>
public class Result<T> : Result, IResult<T>
{
public T Data { get; private set; }
public T? Data { get; set; }

private Result(bool succeeded, ResultType resultType, T data, List<MessageDetail>? messages) : base()
private static Result<T> CreateResult(ResultType resultType, T? data = default, List<MessageDetail>? messages = null, ILogger? logger = null)
{
Succeeded = succeeded;
ResultType = resultType;
Data = data;
Messages = messages ?? [];
Log(messages, logger);
return new Result<T> { Succeeded = resultType == ResultType.Success, ResultType = resultType, Data = data, Messages = messages ?? [] };
}

public static IResult<T> Create(bool succeeded, ResultType resultType, T data, List<MessageDetail>? messages = null, ILogger? logger = null)
{
Log(resultType, messages, logger);
return new Result<T>(succeeded, resultType, data, messages);
}
public static IResult<T> Fail(List<MessageDetail>? messages = null, T? data = default, ILogger? logger = null) => CreateResult(ResultType.Error, data, messages, logger);
public static IResult<T> Fail(List<string> messages, T? data = default, ILogger? logger = null) => Fail(ConvertToMessageDetail(messages), data, logger);
public static IResult<T> Fail(MessageDetail message, T? data = default, ILogger? logger = null) => Fail([message], data, logger);
public static IResult<T> Fail(string message, T? data = default, ILogger? logger = null) => Fail([new MessageDetail(message)], data, logger);

public static IResult<T> Success(T data, List<MessageDetail>? messages = null) => Create(true, ResultType.Success, data, messages);
public static IResult<T> Fail(T data, List<MessageDetail>? messages = null, ILogger? logger = null) => Create(false, ResultType.Error, data, messages, logger);
public static IResult<T> ValidationFail(T data, List<MessageDetail>? messages = null, ILogger? logger = null) => Create(false, ResultType.ValidationError, data, messages, logger);
public static IResult<T> ValidationFail(List<MessageDetail> messages, T? data = default, ILogger? logger = null) => CreateResult(ResultType.ValidationError, data, messages, logger);
public static IResult<T> ValidationFail(List<string> messages, T? data = default, ILogger? logger = null) => ValidationFail(ConvertToMessageDetail(messages), data, logger);
public static IResult<T> ValidationFail(MessageDetail message, T? data = default, ILogger? logger = null) => ValidationFail([message], data, logger);
public static IResult<T> ValidationFail(string message, T? data = default, ILogger? logger = null) => ValidationFail([message], data, logger);

public static Task<IResult<T>> SuccessAsync(T data, List<MessageDetail>? messages = null) => Task.FromResult(Success(data, messages));
public static Task<IResult<T>> FailAsync(T data, List<MessageDetail>? messages = null, ILogger? logger = null) => Task.FromResult(Fail(data, messages, logger));
public static Task<IResult<T>> ValidationFailAsync(T data, List<MessageDetail>? messages = null, ILogger? logger = null) => Task.FromResult(ValidationFail(data, messages, logger));
public static IResult<T> Success(T? data = default, MessageDetail? message = null) => CreateResult(ResultType.Success, data, [message]);
public static IResult<T> Success(T? data, string message) => Success(data, new MessageDetail(message));
public static new IResult<T> Success(MessageDetail? message) => Success(default, message);
public static new IResult<T> Success(string message) => Success(default, new MessageDetail(message));
}
1 change: 0 additions & 1 deletion src/NuvTools.Common/ResultWrapper/ResultExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace NuvTools.Common.ResultWrapper;
public static class ResultExtensions
{

private static readonly JsonSerializerOptions serializerOptions = new()
{
PropertyNameCaseInsensitive = true,
Expand Down
82 changes: 76 additions & 6 deletions tests/NuvTools.Common.Test/ResultWrapper/ResultTests.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,96 @@
using NUnit.Framework;
using NUnit.Framework.Internal;
using NuvTools.Common.ResultWrapper;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace NuvTools.Common.Tests.ResultWrapper;

[TestFixture()]
public class ResultTests
{
[Test()]
public async Task GetResultOnly()
public void ValidationFail()
{
var list = new List<MessageDetail>() { new("aa"), new("bb") };

await Result.ValidationFailAsync(messages: list);
Result.ValidationFail(list);

Result.ValidationFail(new MessageDetail("Validation error"));

Result.ValidationFail("Validation error");

var result = Result.ValidationFail(["Validation error"]);
Assert.That(result.Messages[0].Title, Is.EqualTo("Validation error"));
}

[Test()]
public async Task GetResultLong()
public void ValidationFailTyped()
{
var list = new List<MessageDetail>() { new("aa"), new("bb") };
Result<int>.ValidationFail("Validation error");
Result<int>.ValidationFail(new MessageDetail("Validation error"));

Result<int>.ValidationFail("Validation error", 1);
Result<int>.ValidationFail(new MessageDetail("Validation error"), 1);

var resultTyped = Result<int>.ValidationFail(["Validation error"]);
Assert.That(resultTyped.Messages[0].Title, Is.EqualTo("Validation error"));

resultTyped = Result<int>.ValidationFail(["Validation error"], 0);
Assert.That(resultTyped.Messages[0].Title, Is.EqualTo("Validation error"));
}

[Test()]
public void Fail()
{
Result.Fail();

var result = Result.Fail("Not work");

Assert.That(result.Messages[0].Title, Is.EqualTo("Not work"));

Result.Fail(new MessageDetail("Not work"));

Result.Fail(["not work"]);

Result.Fail([new MessageDetail("Not work")]);

Assert.That(result.Messages[0].Title, Is.EqualTo("Not work"));

}

[Test()]
public void FailTyped()
{
var resultTyped = Result<int>.Fail("Not work");
Assert.That(resultTyped.Messages[0].Title, Is.EqualTo("Not work"));
}

[Test()]
public void Success()
{
Result.Success();

var result = Result.Success("It works!");
Assert.That(result.Messages[0].Title, Is.EqualTo("It works!"));

Result.Success(new MessageDetail("It works!"));
}

private static IResult<int> TestSuccessTypedReturn()
{
return Result<int>.Success();
}

[Test()]
public void SuccessTyped()
{
TestSuccessTypedReturn();

Result<int>.Success(1);
Result<int>.Success(1, "It works!");

await Result<long>.ValidationFailAsync(0L, list);
var resultTyped = Result<int>.Success(1, new MessageDetail("It works!"));
Assert.That(resultTyped.Messages[0].Title, Is.EqualTo("It works!"));
Assert.That(resultTyped.Data, Is.EqualTo(1));
}
}

0 comments on commit d8e4b40

Please sign in to comment.