Skip to content

Commit

Permalink
added validation
Browse files Browse the repository at this point in the history
  • Loading branch information
mattiasnordqvist committed Jun 8, 2024
1 parent 8ce3783 commit 14761c8
Show file tree
Hide file tree
Showing 18 changed files with 1,226 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

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

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="xunit.core" Version="2.8.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\DotNetThoughts.Results.Validation\DotNetThoughts.Results.Validation.csproj" />
</ItemGroup>

</Project>
214 changes: 214 additions & 0 deletions DotNetThoughts.Results.Validation.Tests/EnumLoaderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
using FluentAssertions;

using Xunit;

namespace DotNetThoughts.Results.Validation.Tests;

public class EnumLoaderTests
{
enum Planet
{
Mercury,
Venus,
Earth,
Mars,
Jupiter,
Saturn,
Uranus,
Neptune,
Pluto
}

[Fact]
public void Parse_ExistsAsGivenEnum_Success()
{
// Arrange
var validPlanet = "Mercury";

// Act
var result = EnumLoader.Parse<Planet>(validPlanet);

// Assert
result.Success.Should().BeTrue();
result.Value.Should().Be(Planet.Mercury);
}

[Fact]
public void Parse_DoesNotExistAsGivenEnum_Error()
{
// Arrange
var invalidPlanet = "Xena";

// Act
var result = EnumLoader.Parse<Planet>(invalidPlanet);

// Assert
result.Success.Should().BeFalse();
result.HasError<EnumValueMustExistError<Planet>>().Should().BeTrue();
}

[Fact]
public void Parse_Null_Error()
{
// Arrange
// Act
var result = EnumLoader.Parse<Planet>(null);

// Assert
result.Success.Should().BeFalse();
result.HasError<EnumValueMustExistError<Planet>>().Should().BeTrue();
}

[Fact]
public void Parse_ImplicitlyNumeric_Success()
{
// Arrange
var enumFormat = Planet.Venus;
var implicitlyNumericFormat = ((int)enumFormat).ToString();

// Act
var result = EnumLoader.Parse<Planet>(implicitlyNumericFormat);

// Assert
result.Success.Should().BeTrue();
result.Value.Should().Be(enumFormat);
}

[Fact]
public void ParseAllowNull_Null_Success()
{
// Arrange
// Act
var result = EnumLoader.ParseAllowNull<Planet>(null);

// Assert
result.Success.Should().BeTrue();
result.Value.Should().BeNull();
}

[Fact]
public void ParseAllowNull_NotNull_Success()
{
// Arrange
var validPlanet = "Neptune";

// Act
var result = EnumLoader.ParseAllowNull<Planet>(validPlanet);

// Assert
result.Success.Should().BeTrue();
result.Value.Should().Be(Planet.Neptune);
}

[Fact]
public void ParseAllowNull_DoesNotExistAsGivenEnum_Error()
{
// Arrange
var invalidPlanet = "Murrcurry";

// Act
var result = EnumLoader.ParseAllowNull<Planet>(invalidPlanet);

// Assert
result.Success.Should().BeFalse();
result.HasError<EnumValueMustExistError<Planet>>().Should().BeTrue();
}

[Fact]
public void Parse_UpperCased_Error()
{
// Arrange
var invalidPlanet = "MERCURY";

// Act
var result = EnumLoader.Parse<Planet>(invalidPlanet);

// Assert
result.Success.Should().BeFalse();
}

[Fact]
public void ParseCaseInsensitive_UpperCased_Success()
{
// Arrange
var validPlanet = "MERCURY";

// Act
var result = EnumLoader.Parse<Planet>(validPlanet, true);

// Assert
result.Success.Should().BeTrue();
result.Value.Should().Be(Planet.Mercury);
}


[Fact]
public void ParseCaseInsensitive_RandomCased_Success()
{
// Arrange
var validPlanet = "MeRCuRY";

// Act
var result = EnumLoader.Parse<Planet>(validPlanet, true);

// Assert
result.Success.Should().BeTrue();
result.Value.Should().Be(Planet.Mercury);
}

[Fact]
public void ParseAllowNull_UpperCased_Error()
{
// Arrange
var invalidPlanet = "MERCURY";

// Act
var result = EnumLoader.ParseAllowNull<Planet>(invalidPlanet);

// Assert
result.Success.Should().BeFalse();
}

[Fact]
public void ParseAllowNullCaseInsensitive_UpperCased_Success()
{
// Arrange
var validPlanet = "MERCURY";

// Act
var result = EnumLoader.ParseAllowNull<Planet>(validPlanet, true);

// Assert
result.Success.Should().BeTrue();
result.Value.Should().Be(Planet.Mercury);
}


[Fact]
public void ParseAllowNullCaseInsensitive_RandomCased_Success()
{
// Arrange
var validPlanet = "MeRCuRY";

// Act
var result = EnumLoader.ParseAllowNull<Planet>(validPlanet, true);

// Assert
result.Success.Should().BeTrue();
result.Value.Should().Be(Planet.Mercury);
}

[Fact]
public void ParseAllowNullCaseInsensitive_null_Success()
{
// Act
var result = EnumLoader.ParseAllowNull<Planet>(null, true);

// Assert
result.Success.Should().BeTrue();
result.Value.Should().Be(null);
}



}
115 changes: 115 additions & 0 deletions DotNetThoughts.Results.Validation.Tests/GeneralValidationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using FluentAssertions;

using Xunit;

namespace DotNetThoughts.Results.Validation.Tests;

public class GeneralValidationTests
{
[Fact]
public void Parse_Parseable_Success()
{
// Arrange
var parseable = "4000";
// Act
var parseResult = GeneralValidation.Parse<long, string?>(parseable, StringToLong);
// Assert
parseResult.Success.Should().BeTrue();
parseResult.Value.Should().Be(long.Parse(parseable));
}

[Fact]
public void Parse_NotParseable_Error()
{
// Arrange
var unparseable = "fyratusen";
// Act
var parseResult = GeneralValidation.Parse<long, string?>(unparseable, StringToLong);
// Assert
parseResult.Success.Should().BeFalse();
parseResult.HasError<UnparseableError>().Should().BeTrue();
}

[Fact]
public void Parse_Null_Error()
{
// Arrange
// Act
var parseResult = GeneralValidation.Parse<long, string?>((string?)null, StringToLong);
// Assert
parseResult.Success.Should().BeFalse();
parseResult.HasError<MissingArgumentError>().Should().BeTrue();
}

[Fact]
public void ParseAllowNull_Null_Success()
{
// Arrange
// Act
var parseResult = GeneralValidation.ParseAllowNull((string?)null, StringToValueObject);
// Assert
parseResult.Success.Should().BeTrue();
parseResult.Value.Should().Be(null);
}

[Fact]
public void ParseAllowNull_NotNullParseable_Success()
{
// Arrange
var parseable = "10";
// Act
var parseResult = GeneralValidation.ParseAllowNull(parseable, StringToValueObject);
// Assert
parseResult.Success.Should().BeTrue();
parseResult.Value.Should().Be(new SomeValueObject(long.Parse(parseable)));
}

[Fact]
public void ParseAllowNull_NotNullNotParseable_Error()
{
// Arrange
var parseable = "tio";
// Act
var parseResult = GeneralValidation.ParseAllowNull(parseable, StringToValueObject);
// Assert
parseResult.Success.Should().BeFalse();
parseResult.HasError<UnparseableError>().Should().BeTrue();
}

[Fact]
public void ParseAllowNull_NullableStructs()
{
// Arrange
string? parseable = "2022-12-01";
// Act
var parseResult = GeneralValidation.ParseAllowNullStruct(parseable, v => DateOnly.TryParse(v, out var result) ? result.Return() : Result<DateOnly>.Error(new InvalidDateError()));
// Assert
parseResult.Success.Should().BeTrue();
parseResult.Value.Should().Be(new DateOnly(2022, 12, 1));
}

[Fact]
public void ParseAllowNull_NullableStructs2()
{
// Arrange
string? parseable = null;
// Act
var parseResult = GeneralValidation.ParseAllowNullStruct(parseable, v => DateOnly.TryParse(v, out var result) ? result.Return() : Result<DateOnly>.Error(new InvalidDateError()));
// Assert
parseResult.Success.Should().BeTrue();
parseResult.Value.Should().Be(null);
}
public record UnparseableError(string? Candidate) : ErrorBase;
public static Result<long> StringToLong(string? candidate) =>
long.TryParse(candidate, out var longified)
? longified.Return()
: Result<long>.Error(new UnparseableError(candidate));
public record class SomeValueObject(long Value);
public static Result<SomeValueObject> StringToValueObject(string? candidate)
{
var fitsValueDataType = StringToLong(candidate);
return fitsValueDataType.Success
? new SomeValueObject(fitsValueDataType.Value).Return()
: Result<SomeValueObject>.Error(new UnparseableError(candidate));
}
}
3 changes: 3 additions & 0 deletions DotNetThoughts.Results.Validation.Tests/InvalidDateError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace DotNetThoughts.Results.Validation.Tests;

internal record InvalidDateError : ErrorBase;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.5.7</Version>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Results\DotNetThoughts.Results.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit 14761c8

Please sign in to comment.