Skip to content

Commit

Permalink
ExtractTypeFromMemory tests added
Browse files Browse the repository at this point in the history
  • Loading branch information
Theauxm committed Jul 10, 2024
1 parent be11907 commit dfcecd2
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 62 deletions.
2 changes: 1 addition & 1 deletion ChainSharp.Tests.Unit/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
global using NUnit.Framework;
global using NUnit.Framework;
101 changes: 101 additions & 0 deletions ChainSharp.Tests.Unit/UnitTests/ExtractTypeFromMemoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using ChainSharp.Extensions;
using ChainSharp.Workflow;
using FluentAssertions;
using LanguageExt;

namespace ChainSharp.Tests.Unit.UnitTests;

public class ExtractTypeFromMemoryTests : TestSetup
{
[Theory]
public async Task TestExtractTypeFromMemory()
{
// Arrange
var input = 1;

var workflow = new TestWorkflow().Activate(input);

// Act
var result = workflow.ExtractTypeFromMemory<int, int, string>();

// Assert
result.Should().Be(input);
workflow.Exception.Should().BeNull();
}

[Theory]
public async Task TestTupleExtractTypeFromMemory()
{
// Arrange
var input = 1;
var tupleInput = ("hello", false);

var workflow = new TestWorkflow().Activate(input, tupleInput);

// Act
var result = workflow.ExtractTypeFromMemory<(string, bool), int, string>();

// Assert
result.Should().NotBeNull();
result.Should().Be(tupleInput);
workflow.Exception.Should().BeNull();
}

[Theory]
public async Task TestTupleExtractTypeFromMemoryTypeInput()
{
// Arrange
var input = 1;
var tupleInput = ("hello", false);

var workflow = new TestWorkflow().Activate(input, tupleInput);

// Act
var result = ((string, bool)?)workflow.ExtractTypeFromMemory(typeof((string, bool)));

// Assert
result.Should().NotBeNull();
result.Should().Be(tupleInput);
workflow.Exception.Should().BeNull();
}

[Theory]
public async Task TestInvalidTupleExtractTypeFromMemoryTypeInput()
{
// Arrange
var input = 1;
var tupleInput = ValueTuple.Create(1);

var workflow = new TestWorkflow().Activate(input, tupleInput);

// Act
var result = (ValueTuple<int>?)workflow.ExtractTypeFromMemory(typeof(ValueTuple<int>));

// Assert
workflow.Exception.Should().NotBeNull();
result.Should().BeNull();
}

[Theory]
public async Task TestInvalidTupleExtractTypeFromMemory()
{
// Arrange
var input = 1;
var tupleInput = ValueTuple.Create(1);

var workflow = new TestWorkflow().Activate(input, tupleInput);

// Act
var result = workflow.ExtractTypeFromMemory<ValueTuple<int>?, int, string>();

// Assert
workflow.Exception.Should().NotBeNull();
result.Should().BeNull();
}

private class TestWorkflow : Workflow<int, string>
{
protected override async Task<Either<Exception, string>> RunInternal(int input) =>
Resolve();
}
}
20 changes: 9 additions & 11 deletions ChainSharp.Tests.Unit/UnitTests/InitializeStepTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ public async Task TestInitializeStep()
{
// Arrange
var input = 1;

var workflow = new TestWorkflow();

// Act
var step = workflow.InitializeStep<TestValidStep, int, string>();

// Assert
step.Should().NotBeNull();

var result = await step!.Run(input);
result.Should().Be(input.ToString());
}
Expand All @@ -31,18 +31,18 @@ public async Task TestInvalidInitializeStep()
{
// Arrange
var workflow = new TestWorkflow().Activate(1);

// Act
var step = workflow.InitializeStep<TestInvalidStep, int, string>();

// Assert
workflow.Exception.Should().NotBeNull();
}

private class TestWorkflow : Workflow<int, string>
{
protected override async Task<Either<Exception, string>> RunInternal(int input)
=> Resolve();
protected override async Task<Either<Exception, string>> RunInternal(int input) =>
Resolve();
}

private class TestValidStep : Step<int, string>
Expand All @@ -53,7 +53,5 @@ public override async Task<string> Run(int input)
}
}

private class TestInvalidStep(int intInput, string stringInput)
{
}
private class TestInvalidStep(int intInput, string stringInput) { }
}
2 changes: 1 addition & 1 deletion ChainSharp/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("ChainSharp.Tests.Unit")]
[assembly: InternalsVisibleTo("ChainSharp.Tests.Unit")]
4 changes: 0 additions & 4 deletions ChainSharp/ChainSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,4 @@
<PackageReference Include="LanguageExt.Core" Version="4.4.7" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
</ItemGroup>

<PropertyGroup>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup>
</Project>
3 changes: 2 additions & 1 deletion ChainSharp/Extensions/FunctionalExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ internal static R Unwrap<L, R>(this Either<L, R> option)
}

internal static bool IsTuple(this Type type) =>
type.IsGenericType && type.FullName.StartsWith("System.ValueTuple`");
(type.IsGenericType && type.FullName.StartsWith("System.ValueTuple`"))
|| type.FullName.StartsWith("System.Runtime.CompilerServices.ITuple");
}
85 changes: 44 additions & 41 deletions ChainSharp/Extensions/WorkflowExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,64 +62,58 @@ this Workflow<TInput, TReturn> workflow
return initializedStep;
}

internal static dynamic?[] ExtractTypesFromMemory<TInput, TReturn>(
this Workflow<TInput, TReturn> workflow,
IEnumerable<Type> types
) => types.Select(type => ExtractTypeFromMemory(workflow, type)).ToArray();

internal static T? ExtractTypeFromMemory<T, TInput, TReturn>(
this Workflow<TInput, TReturn> workflow
)
{
T? input = default;

var inputType = typeof(T);
if (inputType.IsTuple())
try
{
try
{
input = ExtractTuple(workflow, inputType);
}
catch (Exception e)
{
workflow.Exception ??= e;
}
}
var inputType = typeof(T);

input ??= (T?)workflow.Memory.GetValueOrDefault(inputType);
var input = inputType.IsTuple()
? ExtractTuple(workflow, inputType)
: (T?)workflow.Memory.GetValueOrDefault(inputType);

if (input is null)
workflow.Exception ??= new WorkflowException($"Could not find type: ({inputType}).");
if (input is null)
workflow.Exception ??= new WorkflowException(
$"Could not find type: ({inputType})."
);

return input;
return input;
}
catch (Exception e)
{
workflow.Exception ??= e;
return default;
}
}

internal static dynamic[] ExtractTypesFromMemory<TInput, TReturn>(
this Workflow<TInput, TReturn> workflow,
IEnumerable<Type> types
) => types.Select(type => ExtractTypeFromMemory(workflow, type)).ToArray();

internal static dynamic ExtractTypeFromMemory<TInput, TReturn>(
internal static dynamic? ExtractTypeFromMemory<TInput, TReturn>(
this Workflow<TInput, TReturn> workflow,
Type tIn
)
{
dynamic? input = null;

var inputType = tIn;
if (inputType.IsTuple())
try
{
try
{
input = ExtractTuple(workflow, inputType);
}
catch (Exception e)
{
workflow.Exception ??= e;
}
}
var input = tIn.IsTuple()
? ExtractTuple(workflow, tIn)
: workflow.Memory.GetValueOrDefault(tIn);

input ??= workflow.Memory.GetValueOrDefault(inputType);
if (input is null)
throw new WorkflowException($"Could not find type: ({tIn}).");

if (input is null)
workflow.Exception ??= new WorkflowException($"Could not find type: ({inputType}).");

return input!;
return input;
}
catch (Exception e)
{
workflow.Exception ??= e;
return null;
}
}

internal static dynamic ExtractTuple<TInput, TReturn>(
Expand All @@ -132,6 +126,10 @@ Type inputType
return typeTuples.Count switch
{
0 => throw new WorkflowException($"Cannot have Tuple of length 0."),
1
=> throw new WorkflowException(
"Tuple of a single length should be passed as the value itself."
),
2 => TypeHelpers.ConvertTwoTuple(typeTuples),
3 => TypeHelpers.ConvertThreeTuple(typeTuples),
4 => TypeHelpers.ConvertFourTuple(typeTuples),
Expand All @@ -157,6 +155,11 @@ TIn input

var inputTuple = (ITuple)input;

if (inputTuple.Length > 7)
throw new WorkflowException(
$"Tuple input ({typeof(TIn)}) cannot have a length greater than 7."
);

var tupleList = Enumerable.Range(0, inputTuple.Length).Select(i => inputTuple[i]!).ToList();

foreach (var tupleValue in tupleList)
Expand Down
14 changes: 11 additions & 3 deletions ChainSharp/Workflow/Activate.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;
using ChainSharp.Exceptions;
using ChainSharp.Extensions;
using LanguageExt;
Expand All @@ -6,7 +7,7 @@ namespace ChainSharp.Workflow;

public partial class Workflow<TInput, TReturn>
{
public Workflow<TInput, TReturn> Activate(TInput input, params object[] otherTypes)
public Workflow<TInput, TReturn> Activate(TInput input, params object[] otherInputs)
{
// Always allow input type of Unit for parameterless invocation
Memory ??= new Dictionary<Type, object>() { { typeof(Unit), Unit.Default } };
Expand All @@ -24,8 +25,15 @@ public Workflow<TInput, TReturn> Activate(TInput input, params object[] otherTyp
else
Memory[inputType] = input;

foreach (var otherType in otherTypes)
Memory[otherType.GetType()] = otherType;
foreach (var otherInput in otherInputs)
{
var otherType = otherInput.GetType();

if (otherType.IsTuple())
this.AddTupleToMemory((ITuple)otherInput);
else
Memory[otherType] = otherInput;
}

return this;
}
Expand Down

0 comments on commit dfcecd2

Please sign in to comment.