Skip to content

Commit

Permalink
Workflow Tests (#36)
Browse files Browse the repository at this point in the history
* Added Workflow and Activate tests

* Fixed tuple test

* AddServicesTests added

* Resolve Tests implemented

* Incremented version to 2.1.0 to reflect bug fixes

* Extract Tests Added

* Chain tests added

* Started short circuit testing

* Implemented rest of ShortCircuit Tests

* Solution Version (#37)

* Created build props file for solution version as opposed to project version

* Updated github action. Version bump.

* Abstrated Tests project into an integration project.

* Updated Workflow tests

* Updated ShortCircuit

* CSharpier
  • Loading branch information
Theauxm authored Jul 15, 2024
1 parent 2c71bcc commit 1c32f06
Show file tree
Hide file tree
Showing 44 changed files with 2,170 additions and 25 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/nuget_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- main
paths:
- 'ChainSharp/ChainSharp.csproj'
- 'Directory.Build.Props'

permissions:
contents: write # Ensure the token has write permissions to contents
Expand All @@ -26,15 +26,15 @@ jobs:
uses: actions/cache@v3
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('ChainSharp/ChainSharp.csproj') }}
key: ${{ runner.os }}-nuget-${{ hashFiles('Directory.Build.Props') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Verify version change
id: version
run: |
csproj_file="ChainSharp/ChainSharp.csproj"
version_line=$(grep '<Version>' $csproj_file)
props_file="Directory.Build.Props"
version_line=$(grep '<Version>' $props_file)
new_version=$(echo $version_line | sed -E 's/.*<Version>(.*)<\/Version>.*/\1/')
echo "New version: $new_version"
git fetch --tags
Expand Down Expand Up @@ -62,7 +62,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
new_version=$(grep '<Version>' ChainSharp/ChainSharp.csproj | sed -E 's/.*<Version>(.*)<\/Version>.*/\1/')
new_version=$(grep '<Version>' Directory.Build.Props | sed -E 's/.*<Version>(.*)<\/Version>.*/\1/')
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag v$new_version
Expand Down
29 changes: 29 additions & 0 deletions ChainSharp.Tests.Integration/ChainSharp.Tests.Integration.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>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/>
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="NUnit" Version="3.13.3"/>
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1"/>
<PackageReference Include="NUnit.Analyzers" Version="3.6.1"/>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ChainSharp\ChainSharp.csproj" />
</ItemGroup>

</Project>
23 changes: 23 additions & 0 deletions ChainSharp.Tests.Integration/Examples/Brewery/Cider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using ChainSharp.Exceptions;
using ChainSharp.Tests.Examples.Brewery.Steps.Bottle;
using ChainSharp.Tests.Examples.Brewery.Steps.Brew;
using ChainSharp.Tests.Examples.Brewery.Steps.Ferment;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;
using ChainSharp.Workflow;
using LanguageExt;

namespace ChainSharp.Tests.Examples.Brewery;

public class Cider(IPrepare prepare, IFerment ferment, IBrew brew, IBottle bottle)
: Workflow<Ingredients, List<GlassBottle>>,
ICider
{
protected override async Task<Either<Exception, List<GlassBottle>>> RunInternal(
Ingredients input
) =>
this.Chain<IPrepare, Ingredients, BrewingJug>(prepare, input, out var jug)
.Chain<IFerment, BrewingJug>(ferment, jug)
.Chain<IBrew, BrewingJug>(brew, jug)
.Chain<IBottle, BrewingJug, List<GlassBottle>>(bottle, jug, out var bottles)
.Resolve(bottles);
}
7 changes: 7 additions & 0 deletions ChainSharp.Tests.Integration/Examples/Brewery/ICider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using ChainSharp.Tests.Examples.Brewery.Steps.Bottle;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;
using ChainSharp.Workflow;

namespace ChainSharp.Tests.Examples.Brewery;

public interface ICider : IWorkflow<Ingredients, List<GlassBottle>> { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using ChainSharp.Exceptions;
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Ferment;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;
using LanguageExt;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Bottle;

public class Bottle(IFerment ferment) : Step<BrewingJug, List<GlassBottle>>, IBottle
{
public override async Task<List<GlassBottle>> Run(BrewingJug input)
{
if (!input.IsBrewed)
throw new WorkflowException(
"We don't want to bottle un-brewed beer! What are we, trying to make poison?"
);

// 16 oz bottles
var bottlesNeeded = input.Gallons / 8;

var filledBottles = new List<GlassBottle>();
for (var i = 0; i < bottlesNeeded; i++)
{
filledBottles.Add(new GlassBottle() { HasCider = true });
}

return filledBottles;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ChainSharp.Tests.Examples.Brewery.Steps.Bottle;

public class GlassBottle
{
public bool HasCider { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Bottle;

public interface IBottle : IStep<BrewingJug, List<GlassBottle>> { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using ChainSharp.Exceptions;
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;
using LanguageExt;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Bottle;

public class StealCinnamonAndRunAway : Step<BrewingJug, List<GlassBottle>>
{
public override async Task<List<GlassBottle>> Run(BrewingJug input)
{
// We steal the Cinnamon Sticks and make a run for it with some empty bottles
input.Ingredients.Cinnamon = 0;
input.HasCinnamonSticks = false;
var emptyBottles = new List<GlassBottle>()
{
new() { },
new() { },
new() { },
};
return emptyBottles;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using ChainSharp.Exceptions;
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;
using LanguageExt;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Bottle;

public class TripTryingToSteal : Step<BrewingJug, List<GlassBottle>>
{
public override async Task<List<GlassBottle>> Run(BrewingJug input)
{
// We try to steal the cinnamon, but we trip and fall and GO LEFT
throw new WorkflowException("You done messed up now, son.");
}
}
20 changes: 20 additions & 0 deletions ChainSharp.Tests.Integration/Examples/Brewery/Steps/Brew/Brew.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using ChainSharp.Exceptions;
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;
using LanguageExt;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Brew;

public class Brew : Step<BrewingJug, Unit>, IBrew
{
public override async Task<Unit> Run(BrewingJug input)
{
if (!input.IsFermented)
throw new WorkflowException("We cannot brew our Cider before it is fermented!");

// Pretend that we waited 2 days...
input.IsBrewed = true;

return Unit.Default;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;
using LanguageExt;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Brew;

public interface IBrew : IStep<BrewingJug, Unit> { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using ChainSharp.Exceptions;
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;
using LanguageExt;
using LanguageExt.UnsafeValueAccess;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Ferment;

public class Ferment : Step<BrewingJug, Unit>, IFerment
{
public override async Task<Unit> Run(BrewingJug input)
{
var cinnamonSticks = await AddCinnamonSticks(input);

if (cinnamonSticks.IsLeft)
throw cinnamonSticks.Swap().ValueUnsafe();

var yeast = await AddYeast(input);

if (yeast.IsLeft)
throw yeast.Swap().ValueUnsafe();

input.IsFermented = true;

return Unit.Default;
}

public async Task<Either<WorkflowException, Unit>> AddCinnamonSticks(BrewingJug jug)
{
jug.HasCinnamonSticks = jug.Ingredients.Cinnamon > 0;

return Unit.Default;
}

public async Task<Either<WorkflowException, Unit>> AddYeast(BrewingJug jug)
{
if (jug.Ingredients.Yeast <= 0)
return new WorkflowException("We need yeast to make Cider!");

jug.Yeast = jug.Ingredients.Yeast;

return Unit.Default;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Prepare;
using LanguageExt;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Ferment;

public interface IFerment : IStep<BrewingJug, Unit> { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace ChainSharp.Tests.Examples.Brewery.Steps.Prepare;

public class BrewingJug : IBrewingJug
{
public required int Gallons { get; set; }

public int Yeast { get; set; }

public bool HasCinnamonSticks { get; set; }

public bool IsFermented { get; set; }

public bool IsBrewed { get; set; }

public Ingredients Ingredients { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace ChainSharp.Tests.Examples.Brewery.Steps.Prepare;

public interface IBrewingJug
{
int Gallons { get; set; }
int Yeast { get; set; }
bool HasCinnamonSticks { get; set; }
bool IsFermented { get; set; }
bool IsBrewed { get; set; }
Ingredients Ingredients { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using ChainSharp.Step;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Prepare;

public interface IPrepare : IStep<Ingredients, BrewingJug> { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace ChainSharp.Tests.Examples.Brewery.Steps.Prepare;

public class Ingredients
{
public required int Apples { get; set; }

public required int BrownSugar { get; set; }

public required int Cinnamon { get; set; }

public required int Yeast { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using ChainSharp.Exceptions;
using ChainSharp.Step;
using LanguageExt;
using LanguageExt.UnsafeValueAccess;
using static LanguageExt.Prelude;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Prepare;

internal class Meditate : Step<Unit, Unit>
{
public override async Task<Unit> Run(Unit input)
{
// You silently consider what you should brew
return unit;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using ChainSharp.Exceptions;
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Ferment;
using LanguageExt;
using LanguageExt.UnsafeValueAccess;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Prepare;

public class Prepare(IFerment ferment) : Step<Ingredients, BrewingJug>, IPrepare
{
public override async Task<BrewingJug> Run(Ingredients input)
{
const int gallonWater = 1;

var gallonAppleJuice = await Boil(gallonWater, input.Apples, input.BrownSugar);

if (gallonAppleJuice.IsLeft)
throw gallonAppleJuice.Swap().ValueUnsafe();

return new BrewingJug() { Gallons = gallonAppleJuice.ValueUnsafe(), Ingredients = input };
}

private async Task<Either<WorkflowException, int>> Boil(
int gallonWater,
int numApples,
int ozBrownSugar
)
{
return gallonWater + (numApples / 8) + (ozBrownSugar / 128);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using ChainSharp.Exceptions;
using ChainSharp.Step;
using ChainSharp.Tests.Examples.Brewery.Steps.Ferment;
using LanguageExt;
using LanguageExt.UnsafeValueAccess;

namespace ChainSharp.Tests.Examples.Brewery.Steps.Prepare;

public class PrepareWithInterface(IFerment ferment) : Step<Ingredients, IBrewingJug>
{
public override async Task<IBrewingJug> Run(Ingredients input)
{
const int gallonWater = 1;

var gallonAppleJuice = await Boil(gallonWater, input.Apples, input.BrownSugar);

if (gallonAppleJuice.IsLeft)
throw gallonAppleJuice.Swap().ValueUnsafe();

return new BrewingJug() { Gallons = gallonAppleJuice.ValueUnsafe(), Ingredients = input };
}

private async Task<Either<WorkflowException, int>> Boil(
int gallonWater,
int numApples,
int ozBrownSugar
)
{
return gallonWater + (numApples / 8) + (ozBrownSugar / 128);
}
}
1 change: 1 addition & 0 deletions ChainSharp.Tests.Integration/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using NUnit.Framework;
Loading

0 comments on commit 1c32f06

Please sign in to comment.