Skip to content

Commit

Permalink
add validation tests (#182)
Browse files Browse the repository at this point in the history
Signed-off-by: Kevin <kevin.dinh@lissi.id>
  • Loading branch information
Dindexx authored Sep 18, 2024
1 parent 58ad533 commit 81a3cc8
Show file tree
Hide file tree
Showing 5 changed files with 320 additions and 6 deletions.
12 changes: 6 additions & 6 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.0",
"rollForward": "latestFeature"
}
}
{
"sdk": {
"version": "8.0.0",
"rollForward": "latestFeature"
}
}
34 changes: 34 additions & 0 deletions src/WalletFramework.Core.Tests/Validation/ApplyTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using FluentAssertions;
using WalletFramework.Core.Functional;
using Xunit;

namespace WalletFramework.Core.Tests.Validation;

public class ApplyTests
{
private record Sample(int X1, int X2, int X3, int X4, int X5, int X6, int X7)
{
public int Sum() => X1 + X2 + X3 + X4 + X5 + X6 + X7;
}

private static Sample CreateSample(int x1, int x2, int x3, int x4, int x5, int x6, int x7) =>
new(x1, x2, x3, x4, x5, x6, x7);

[Fact]
public void ApplyWorks()
{
const int expected = 1 + 2 + 3 + 4 + 5 + 6 + 7;
var func = ValidationFun.Valid(CreateSample);

var sut = func
.Apply(1)
.Apply(2)
.Apply(3)
.Apply(4)
.Apply(5)
.Apply(6)
.Apply(7);

sut.UnwrapOrThrow().Sum().Should().Be(expected);
}
}
244 changes: 244 additions & 0 deletions src/WalletFramework.Core.Tests/Validation/ValidationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
using FluentAssertions;
using LanguageExt;
using WalletFramework.Core.Functional;
using WalletFramework.Core.Functional.Errors;
using Xunit;

namespace WalletFramework.Core.Tests.Validation;

public class ValidationTests
{
[Fact]
public void AggregationWorks()
{
Validator<int> greaterThanZero = i => i > 0
? ValidationFun.Valid(i)
: new SampleError();

Validator<int> isEven = i => i % 2 == 0
? ValidationFun.Valid(i)
: new SampleError();

var sut = new List<Validator<int>> { greaterThanZero, isEven }.AggregateValidators();

var one = sut(1);
var two = sut(2);

one.IsSuccess.Should().BeFalse();
two.IsSuccess.Should().BeTrue();
}

[Fact]
public void FallbackWorks()
{
var one = new SampleError().ToInvalid<Validation<int>>();

var sut = one.Fallback(2);

sut.UnwrapOrThrow().Should().Be(2);
}

[Fact]
public void FirstValidWorks()
{
const string one = "1";
const string nan = "NaN";
Validator<string, int> valid = str =>
{
try
{
return ValidationFun.Valid(int.Parse(str));
}
catch (Exception )
{
return new SampleError();
}
};
Validator<string, int> invalid = _ => new SampleError();

var sut = new List<Validator<string, int>> { invalid, valid }.FirstValid();

var oneValid = sut(one);
var nanInvalid = sut(nan);

oneValid.UnwrapOrThrow().Should().Be(1);
nanInvalid.Match(
i => Assert.Fail("Validation must fail"),
errors =>
{
errors.Should().AllBeOfType<NoItemsSucceededValidationError<int>>();
errors.Should().ContainSingle();
}
);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void MatchWorks(bool valid)
{
Validation<int> validation = valid
? 1
: new SampleError();

validation.Match(
_ => valid.Should().BeTrue(),
errors =>
{
valid.Should().BeFalse();
errors.Should().AllBeOfType<SampleError>();
errors.Should().ContainSingle();
});
}

[Fact]
public void OnSuccessWorks()
{
var one = ValidationFun.Valid("1");

var sut = one.OnSuccess(int.Parse);

sut.UnwrapOrThrow().Should().Be(1);
}

[Fact]
public async Task OnSuccessAsyncWorks()
{
var one = ValidationFun.Valid("1").AsTask();

var sut = await one.OnSuccess(int.Parse);

sut.UnwrapOrThrow().Should().Be(1);
}

[Fact]
public void SelectManyWorks()
{
var one = ValidationFun.Valid("1");

var sut = one.SelectMany(
_ => ValidationFun.Valid(1),
(e1, e2) => int.Parse(e1) + e2
);

sut.UnwrapOrThrow().Should().Be(2);
}

[Fact]
public void SelectWorks()
{
var one = ValidationFun.Valid("1");

var sut = one.Select(int.Parse);

sut.Match(
i => i.Should().Be(1),
_ => Assert.Fail("Validation must not fail"));
}

[Fact]
public void TraverseAllWorks()
{
var validStrs = new List<string>
{
"1",
"2",
"3"
};

var invalidStrs = new List<string>
{
"1",
"2",
"Three"
};

var sutValid = validStrs.TraverseAll(s =>
{
try
{
return ValidationFun.Valid(int.Parse(s));
}
catch (Exception)
{
return new SampleError();
}
});

var sutInvalid = invalidStrs.TraverseAll(str =>
{
try
{
return ValidationFun.Valid(int.Parse(str));
}
catch (Exception)
{
return new SampleError();
}
});

sutValid.IsSuccess.Should().BeTrue();
sutInvalid.IsSuccess.Should().BeFalse();
}

[Fact]
public void TraverseAnyWorks()
{
var strs = new List<string>
{
"One",
"2",
"Three"
};

var sut = strs.TraverseAny(str =>
{
try
{
return ValidationFun.Valid(int.Parse(str));
}
catch (Exception)
{
return new SampleError();
}
});

sut.Match(
ints =>
{
var list = ints.ToList();

list.Should().ContainSingle();
list.First().Should().Be(2);
},
errors =>
{
Assert.Fail("Validation must not fail");
errors.Should().ContainSingle();
errors.Should().AllBeOfType<SampleError>();
}
);
}

[Theory]
[InlineData(true)]
[InlineData(false)]
public void UnwrapOrThrowWorks(bool valid)
{
Validation<int> validation = valid
? 1
: new SampleError();

try
{
validation.UnwrapOrThrow();
valid.Should().BeTrue();
}
catch (Exception)
{
valid.Should().BeFalse();
}
}

private record SampleError() : Error("This is sample error for testing");
}
29 changes: 29 additions & 0 deletions src/WalletFramework.Core.Tests/WalletFramework.Core.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0"/>
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\WalletFramework.Core\WalletFramework.Core.csproj" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions src/WalletFramework.sln
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mdoc", "Mdoc", "{A1DD69B3-D
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WalletFramework.Integration.Tests", "..\test\WalletFramework.Integration.Tests\WalletFramework.Integration.Tests\WalletFramework.Integration.Tests.csproj", "{70DB749B-255A-4B71-8B76-BAD6B091DA7C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WalletFramework.Core.Tests", "WalletFramework.Core.Tests\WalletFramework.Core.Tests.csproj", "{93B3ED00-4158-4F79-9532-D3E940630A8A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -135,6 +137,10 @@ Global
{70DB749B-255A-4B71-8B76-BAD6B091DA7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70DB749B-255A-4B71-8B76-BAD6B091DA7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70DB749B-255A-4B71-8B76-BAD6B091DA7C}.Release|Any CPU.Build.0 = Release|Any CPU
{93B3ED00-4158-4F79-9532-D3E940630A8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93B3ED00-4158-4F79-9532-D3E940630A8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93B3ED00-4158-4F79-9532-D3E940630A8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93B3ED00-4158-4F79-9532-D3E940630A8A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -160,6 +166,7 @@ Global
{F6B3A24B-CDA2-4CC1-9F68-380203355099} = {873772C5-60B9-442B-B06E-C279919B963C}
{0EDD27CB-967F-4451-81AE-309E7F534F1C} = {A1DD69B3-DC35-43CF-AE14-D751722F074A}
{70DB749B-255A-4B71-8B76-BAD6B091DA7C} = {02ADBA96-A50C-44F0-A9D9-FA0629AA2DF4}
{93B3ED00-4158-4F79-9532-D3E940630A8A} = {02ADBA96-A50C-44F0-A9D9-FA0629AA2DF4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4FFA80F9-ADC6-40DB-BBD1-A522B8A68560}
Expand Down

0 comments on commit 81a3cc8

Please sign in to comment.