Skip to content
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

Add FluentAssertions extension methods #226

Merged
merged 42 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
589bcef
Add new project Ardalis.Result.FluentAssertions
MigMax Jan 3, 2025
2e82773
Add unit test project
MigMax Jan 4, 2025
d592892
Add empty FluentAssertionsResultExtensions
MigMax Jan 4, 2025
d872411
Add ResultErrorShouldBeError
MigMax Jan 4, 2025
8077669
Add ResultErrorShouldBeErrorWithMessage
MigMax Jan 4, 2025
3476e2a
Refactor tests
MigMax Jan 4, 2025
f202ee3
Add NotFoundResultShouldBeNotFound
MigMax Jan 4, 2025
a90ad24
refactor tests
MigMax Jan 4, 2025
5e38120
Add all ShouldBeFailure Tests
MigMax Jan 5, 2025
cd582b0
refactor ShouldBeFailure
MigMax Jan 5, 2025
c164d6d
Add Utils ShouldBeOfTypeBooleanAssertionConstraint
MigMax Jan 5, 2025
d3fedf9
Refacto tests
MigMax Jan 5, 2025
57fde75
return AndConstraintObject instead of AndContraintBoolean
MigMax Jan 5, 2025
a500617
Add ShouldBEFailureWithMessage api
MigMax Jan 5, 2025
445b1c9
Refacto
MigMax Jan 5, 2025
dd88e91
Add ConflictResult_ShouldBeConflict
MigMax Jan 5, 2025
2a1aabf
Finalize Conflict Api
MigMax Jan 5, 2025
e86d408
Finalize CriticalError api
MigMax Jan 5, 2025
5b5b4ba
Finish adding Error api
MigMax Jan 6, 2025
e00987d
refactoring FluentAssertionsResultExtensions
MigMax Jan 6, 2025
a2fe268
Add ForbiddenResultWithMessage_ShouldBeForbidden
MigMax Jan 6, 2025
2773d47
Add InvalidResultr_ShouldBeInvalid
MigMax Jan 6, 2025
38b534d
Add InvalidResultWithValidationError_ShouldBeInvalidWithValidationError
MigMax Jan 6, 2025
9d400d2
Add NotFoundResult_ShouldBeNotFound
MigMax Jan 6, 2025
165bbb6
Add NotFoundResultWithErrorMessages_ShouldBeNotFoundWithErrorMessages
MigMax Jan 6, 2025
46abc83
Add ShouldBeUnauthorized
MigMax Jan 6, 2025
527f185
Add ShouldBeUnavailable api
MigMax Jan 6, 2025
510cc8d
Remove redundant qualifier in tests
MigMax Jan 6, 2025
fa50ebb
Add success
MigMax Jan 11, 2025
673a66a
Extract Conflict Result test classe
MigMax Jan 11, 2025
95fe5b0
Split all Error Result test classes
MigMax Jan 11, 2025
c8968b7
Restruct test project
MigMax Jan 11, 2025
cc06dde
Refacto tests
MigMax Jan 11, 2025
5c733a8
Add ShouldHaveValidationErrorWithIdentifier
MigMax Jan 11, 2025
a6d5b68
ShouldHaveValidationErrorWithErrorMessage
MigMax Jan 11, 2025
e84ec03
Add some extension for InvalidResult
MigMax Jan 11, 2025
4e18406
Add test WithErrorMessages_ShouldBeCorrespondingResult
MigMax Jan 11, 2025
3a1aaca
Add SuccessResultTests
MigMax Jan 11, 2025
855183a
Add ShouldBeSuccessWithMessage
MigMax Jan 11, 2025
f2df65f
SuccessWithMessage_ShouldBeSuccess
MigMax Jan 11, 2025
9fa73e8
Add some Success Apis
MigMax Jan 11, 2025
e2a9ad5
Delete PackagreReleaseNotes
MigMax Jan 11, 2025
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
14 changes: 14 additions & 0 deletions Ardalis.Result.sln
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Directory.Packages.props = Directory.Packages.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ardalis.Result.FluentAssertions", "src\Ardalis.Result.FluentAssertions\Ardalis.Result.FluentAssertions.csproj", "{94145FF9-5A56-4479-87AF-3A99939B38F0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ardalis.Result.FluentAssertions.UnitTests", "tests\Ardalis.Result.FluentAssertions.UnitTests\Ardalis.Result.FluentAssertions.UnitTests.csproj", "{0800019A-0B40-4923-96E1-656A745E79C2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -95,6 +99,14 @@ Global
{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E}.Release|Any CPU.Build.0 = Release|Any CPU
{94145FF9-5A56-4479-87AF-3A99939B38F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94145FF9-5A56-4479-87AF-3A99939B38F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94145FF9-5A56-4479-87AF-3A99939B38F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94145FF9-5A56-4479-87AF-3A99939B38F0}.Release|Any CPU.Build.0 = Release|Any CPU
{0800019A-0B40-4923-96E1-656A745E79C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0800019A-0B40-4923-96E1-656A745E79C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0800019A-0B40-4923-96E1-656A745E79C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0800019A-0B40-4923-96E1-656A745E79C2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -111,6 +123,8 @@ Global
{60860685-37BB-47D9-B0DC-6FE7F0DB2AE5} = {FA061DC6-61B7-401F-87A4-D338B396CCD9}
{A9769533-C9B2-4AD4-8B24-70C474D8EBB0} = {FA061DC6-61B7-401F-87A4-D338B396CCD9}
{C522FE42-BBEF-46A7-9E3E-44EA8339AF2E} = {42693FB1-04E1-4635-B249-E1847609E801}
{94145FF9-5A56-4479-87AF-3A99939B38F0} = {865A74CD-F478-4AA5-AFA5-6C26FB38B849}
{0800019A-0B40-4923-96E1-656A745E79C2} = {42693FB1-04E1-4635-B249-E1847609E801}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7CD0ED8C-3B1C-4F16-8B8D-3D8F1A8F1A5A}
Expand Down
3 changes: 2 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ItemGroup>
<PackageVersion Include="Ardalis.ApiEndpoints" Version="4.1.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="FluentAssertions" Version="6.10.0" />
<PackageVersion Include="FluentAssertions" Version="7.0.0" />
<PackageVersion Include="FluentValidation" Version="11.9.2" />
<PackageVersion Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.1.0" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
Expand All @@ -14,6 +14,7 @@
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageVersion Include="Microsoft.TestPlatform.ObjectModel" Version="17.5.0" />
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.4" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageVersion Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageId>Ardalis.Result.FluentAssertions</PackageId>
<Title>Ardalis.Result.FluentAssertions</Title>
<Description>A simple package to implement FluentAssertions with the Ardalis.Result package.</Description>
<Summary>A simple package to implement FluentAssertions with the Ardalis.Result package.</Summary>
<PackageTags>result;pattern;web;api;aspnetcore;mvc;FluentAssertions;Validation</PackageTags>
<PackageReleaseNotes>
</PackageReleaseNotes>
<AssemblyName>Ardalis.Result.FluentAssertions</AssemblyName>
<Version>1.0.0</Version>
</PropertyGroup>


<ItemGroup>
<None Include="icon.png" Pack="true" Visible="false" PackagePath="" />
</ItemGroup>


<ItemGroup>
<PackageReference Include="FluentAssertions" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Ardalis.Result\Ardalis.Result.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using FluentAssertions.Primitives;

namespace Ardalis.Result.FluentAssertions;

public static class FluentAssertionsResultExtensions
{
public static AndConstraint<ObjectAssertions> ShouldBeFailure(this Result result)
{
result.IsSuccess.Should().BeFalse();

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeConflict(this Result result)
{
result.Status.Should().Be(ResultStatus.Conflict);

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeConflict(this Result result, params string[] errorMessages)
{
return result.ShouldBeEquivalentTo(Result.Conflict(errorMessages));
}

public static AndConstraint<ObjectAssertions> ShouldBeCriticalError(this Result result)
{
result.Status.Should().Be(ResultStatus.CriticalError);

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeCriticalError(this Result result, params string[] errorMessages)
{
return result.ShouldBeEquivalentTo(Result.CriticalError(errorMessages));
}

public static AndConstraint<ObjectAssertions> ShouldBeError(this Result result)
{
result.Status.Should().Be(ResultStatus.Error);

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeError(this Result result, string errorMessage)
{
return result.ShouldBeEquivalentTo(Result.Error(errorMessage));
}

public static AndConstraint<ObjectAssertions> ShouldBeError(this Result result, ErrorList errorList)
{
return result.ShouldBeEquivalentTo(Result.Error(errorList));
}

public static AndConstraint<ObjectAssertions> ShouldBeError(this Result result, IEnumerable<string> errorMessages, string? correlationId)

Check warning on line 58 in src/Ardalis.Result.FluentAssertions/FluentAssertionsResultExtensions.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 58 in src/Ardalis.Result.FluentAssertions/FluentAssertionsResultExtensions.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 58 in src/Ardalis.Result.FluentAssertions/FluentAssertionsResultExtensions.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
{
return result.ShouldBeEquivalentTo(Result.Error(new ErrorList(errorMessages, correlationId)));
}

public static AndConstraint<ObjectAssertions> ShouldBeForbidden(this Result result)
{
result.Status.Should().Be(ResultStatus.Forbidden);

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeForbidden(this Result result, params string[] errorMessages)
{
return result.ShouldBeEquivalentTo(Result.Forbidden(errorMessages));
}

public static AndConstraint<ObjectAssertions> ShouldBeInvalid(this Result result)
{
result.Status.Should().Be(ResultStatus.Invalid);

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeInvalid(this Result result, params ValidationError[] validationErrors)
{
return result.ShouldBeEquivalentTo(Result.Invalid(validationErrors));
}

public static AndConstraint<ObjectAssertions> ShouldBeNotFound(this Result result)
{
result.Status.Should().Be(ResultStatus.NotFound);

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeNotFound(this Result result, params string[] errorMessages)
{
return result.ShouldBeEquivalentTo(Result.NotFound(errorMessages));
}

public static AndConstraint<ObjectAssertions> ShouldBeUnauthorized(this Result result)
{
result.Status.Should().Be(ResultStatus.Unauthorized);

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeUnauthorized(this Result result, params string[] errorMessages)
{
return result.ShouldBeEquivalentTo(Result.Unauthorized(errorMessages));
}

public static AndConstraint<ObjectAssertions> ShouldBeUnavailable(this Result result)
{
result.Status.Should().Be(ResultStatus.Unavailable);

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeUnavailable(this Result result, params string[] errorMessages)
{
return result.ShouldBeEquivalentTo(Result.Unavailable(errorMessages));
}

public static AndConstraint<ObjectAssertions> ShouldBeFailure(this Result result, params string[] errorMessages)
{
var andConstraint = result.ShouldBeFailure();

result.Errors.Should().BeEquivalentTo(errorMessages);

return andConstraint;
}

public static AndConstraint<ObjectAssertions> ShouldHaveValidationErrorWithCode(this Result result, string errorCode)
{
var andConstraint = result.ShouldBeInvalid();

result.ValidationErrors.Count().Should().BePositive();

result.ValidationErrors.Should().Satisfy(validationError => validationError.ErrorCode == errorCode);

return andConstraint;
}

public static AndConstraint<ObjectAssertions> ShouldHaveValidationErrorWithIdentifier(this Result result, string identifier)
{
var andConstraint = result.ShouldBeInvalid();

result.ValidationErrors.Count().Should().BePositive();

result.ValidationErrors.Should().Satisfy(validationError => validationError.Identifier == identifier);

return andConstraint;
}

public static AndConstraint<ObjectAssertions> ShouldHaveValidationErrorWithMessage(this Result result, string errorMessage)
{
var andConstraint = result.ShouldBeInvalid();

result.ValidationErrors.Count().Should().BePositive();

result.ValidationErrors.Should().Satisfy(validationError => validationError.ErrorMessage == errorMessage);

return andConstraint;
}

public static AndConstraint<ObjectAssertions> ShouldHaveValidationErrorWithSeverity(this Result result, ValidationSeverity severity)
{
var andConstraint = result.ShouldBeInvalid();

result.ValidationErrors.Count().Should().BePositive();

result.ValidationErrors.Should().Satisfy(validationError => validationError.Severity == severity);

return andConstraint;
}

public static AndConstraint<ObjectAssertions> ShouldBeSuccess<TResult>(this Result<TResult> result)
{
result.IsSuccess.Should().BeTrue();

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeSuccess(this Result result)
{
result.IsSuccess.Should().BeTrue();

return new AndConstraint<ObjectAssertions>(result.Should());
}

public static AndConstraint<ObjectAssertions> ShouldBeCreatedWithLocation<TResult>(this Result<TResult> result, string location)
{
return result.Should().BeEquivalentTo(Result.Created(result.Value, location));
}

public static AndConstraint<ObjectAssertions> ShouldBeSuccessWithMessage(this Result result, string successMessage)
{
return result.ShouldBeEquivalentTo(Result.SuccessWithMessage(successMessage));
}

private static AndConstraint<ObjectAssertions> ShouldBeEquivalentTo(this Result result, Result assertingResult)
{
return result.Should().BeEquivalentTo(assertingResult);
}
}
Binary file added src/Ardalis.Result.FluentAssertions/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Microsoft.TestPlatform.ObjectModel" />
<PackageReference Include="Moq" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Ardalis.Result.FluentAssertions\Ardalis.Result.FluentAssertions.csproj" />
<ProjectReference Include="..\..\src\Ardalis.Result\Ardalis.Result.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Xunit;
using static Ardalis.Result.Result;
using static Ardalis.Result.FluentAssertions.UnitTests.Utils.Constants;

namespace Ardalis.Result.FluentAssertions.UnitTests.FailureResults;

public class ConflictResult
{
[Fact]
public void ShouldBeFailure()
{
Conflict().ShouldBeFailure();
}

[Fact]
public void WithErrorMessages_ShouldBeFailureWithErrorMessages()
{
Conflict(ErrorMessage).ShouldBeFailure(ErrorMessage);
}

[Fact]
public void ShouldBeConflict()
{
Conflict().ShouldBeConflict();
}

[Fact]
public void WithErrorMessages_ShouldBeConflict()
{
Conflict(ErrorMessage).ShouldBeConflict();
}

[Fact]
public void WithErrorMessages_ShouldBeConflictWithErrorMessages()
{
Conflict(ErrorMessage).ShouldBeConflict(ErrorMessage);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Xunit;
using static Ardalis.Result.Result;
using static Ardalis.Result.FluentAssertions.UnitTests.Utils.Constants;

namespace Ardalis.Result.FluentAssertions.UnitTests.FailureResults;

public class CriticalErrorResult
{
[Fact]
public void ShouldBeFailure()
{
CriticalError().ShouldBeFailure();
}

[Fact]
public void WithErrorMessages_ShouldBeFailureWithErrorMessages()
{
CriticalError(ErrorMessage).ShouldBeFailure(ErrorMessage);
}

[Fact]
public void ShouldBeCriticalError()
{
CriticalError().ShouldBeCriticalError();
}

[Fact]
public void WithErrorMessages_ShouldBeCriticalError()
{
CriticalError(ErrorMessage).ShouldBeCriticalError();
}

[Fact]
public void ShouldBeCriticalErrorWithErrorMessages()
{
CriticalError(ErrorMessage).ShouldBeCriticalError(ErrorMessage);
}
}
Loading
Loading