Skip to content

Commit

Permalink
Create own workflow engine instead of using Microsoft RulesEngine
Browse files Browse the repository at this point in the history
  • Loading branch information
jakemoresca committed Nov 17, 2023
1 parent 8c3564f commit 823c4b0
Show file tree
Hide file tree
Showing 36 changed files with 606 additions and 570 deletions.
5 changes: 5 additions & 0 deletions ActionFlow.Tests/ActionFlow.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DynamicExpresso.Core" Version="2.16.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
Expand All @@ -21,4 +22,8 @@
<ProjectReference Include="..\ActionFlow\ActionFlow.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Actions\" />
</ItemGroup>

</Project>
55 changes: 55 additions & 0 deletions ActionFlow.Tests/Engine/ActionFlowEngineTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using ActionFlow.Domain.Engine;
using ActionFlow.Engine;
using ActionFlow.Engine.Factories;
using ActionFlow.Engine.Providers;
using NSubstitute;

namespace ActionFlow.Tests.Engine
{
[TestClass]
public class ActionFlowEngineTests
{
[TestMethod]
public async Task When_running_rule_engine_with_basic_workflow_it_should_execute()
{
//Arrange
var workflowProvider = Substitute.For<IWorkflowProvider>();
workflowProvider.GetAllWorkflows().Returns(CreateFakeWorkflows());

var stepActionFactory = Substitute.For<IStepActionFactory>();
var stepExecutionEvaluator = Substitute.For<IStepExecutionEvaluator>();

var rulesEngine = new ActionFlowEngine(workflowProvider, stepActionFactory, stepExecutionEvaluator);

var inputs = new Parameter[]
{
new Parameter { Name = "test", Expression = "true"}
};

//Act
await rulesEngine.ExecuteWorkflowAsync("Test Workflow Rule 1", inputs);

//Assert
stepExecutionEvaluator.Received(1);
}

private List<Workflow> CreateFakeWorkflows()
{
List<Workflow> workflows = new List<Workflow>();
var steps = new List<Step>
{
new Step("initialize", "Variable", new Dictionary<string, string>
{
{ "age", "1" },
{ "canWalk", "true" },
}),
new Step("test variable value", "Variable", new Dictionary<string, string>(), "age == 1 && canWalk == true")
};

Workflow workflow = new Workflow("Test Workflow Rule 1", steps);
workflows.Add(workflow);

return workflows;
}
}
}
65 changes: 0 additions & 65 deletions ActionFlow.Tests/Engine/RuleEngineWrapperTests.cs

This file was deleted.

114 changes: 114 additions & 0 deletions ActionFlow.Tests/Engine/StepActionFactoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using ActionFlow.Actions;
using ActionFlow.Engine.Factories;
using NSubstitute;

namespace ActionFlow.Tests.Engine
{
[TestClass]
public class StepActionFactoryTests
{
[TestMethod]
public void When_adding_an_action_it_should_not_fail()
{
//Arrange
var sut = new StepActionFactory();
var actionName = "test";
var fakeAction = Substitute.For<ActionBase>();

//Act
//Assert
sut.AddOrUpdate(actionName, () => fakeAction);
}

[TestMethod]
public void When_adding_an_existing_action_it_should_not_fail()
{
//Arrange
var sut = new StepActionFactory();
var actionName = "test";
var fakeAction = Substitute.For<ActionBase>();

sut.AddOrUpdate(actionName, () => fakeAction);

//Act
//Assert
sut.AddOrUpdate(actionName, () => fakeAction);
}

[TestMethod]
public void When_removing_an_existing_action_it_should_return_true()
{
//Arrange
var sut = new StepActionFactory();
var actionName = "test";
var fakeAction = Substitute.For<ActionBase>();

sut.AddOrUpdate(actionName, () => fakeAction);

//Act
var result = sut.Remove(actionName);

//Assert
Assert.IsTrue(result);
}

[TestMethod]
public void When_removing_a_non_existing_action_it_should_return_false()
{
//Arrange
var sut = new StepActionFactory();
var actionName = "test";

//Act
var result = sut.Remove(actionName);

//Assert
Assert.IsFalse(result);
}

[TestMethod]
public void When_getting_it_should_return_the_action()
{
//Arrange
var sut = new StepActionFactory();
var actionName = "test";
var fakeAction = Substitute.For<ActionBase>();

sut.AddOrUpdate(actionName, () => fakeAction);

//Act
var actionBase = sut.Get(actionName);

//Assert
Assert.AreEqual(fakeAction, actionBase);
}

[TestMethod]
[ExpectedException(typeof(KeyNotFoundException), "Action with name: test does not exist")]
public void When_getting_non_existing_action_it_should_throw_exception()
{
//Arrange
var sut = new StepActionFactory();
var actionName = "test";

//Act
//Assert
sut.Get(actionName);
}

[TestMethod]
public void When_clearing_it_should_not_fail()
{
//Arrange
var sut = new StepActionFactory();
var actionName = "test";
var fakeAction = Substitute.For<ActionBase>();

sut.AddOrUpdate(actionName, () => fakeAction);

//Act
//Assert
sut.Clear();
}
}
}
67 changes: 67 additions & 0 deletions ActionFlow.Tests/Engine/StepExecutionEvaluatorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using ActionFlow.Actions;
using ActionFlow.Domain.Engine;
using ActionFlow.Engine;
using ActionFlow.Engine.Factories;
using NSubstitute;
using ExecutionContext = ActionFlow.Domain.Engine.ExecutionContext;

namespace ActionFlow.Tests.Engine
{
[TestClass]
public class StepExecutionEvaluatorTests
{
[TestMethod]
public void When_evaluating_step_with_a_true_condition_it_should_execute_action()
{
//Arrange
var step = new Step("test", "action", null, "age == 3");
var executionContext = new ExecutionContext
{
Parameters =
{
new Parameter { Name = "age", Expression = "1+2"}
}
};

var action = Substitute.For<ActionBase>();

var stepActionFactory = Substitute.For<IStepActionFactory>();
stepActionFactory.Get("action").Returns(action);

var sut = new StepExecutionEvaluator();

//Act
var result = sut.EvaluateAndRunStep(step, executionContext, stepActionFactory);

//Assert
stepActionFactory.Received(1);
}

[TestMethod]
public void When_evaluating_step_with_a_false_condition_it_should_execute_action()
{
//Arrange
var step = new Step("test", "action", null, "age == 3");
var executionContext = new ExecutionContext
{
Parameters =
{
new Parameter { Name = "age", Expression = "2+2"}
}
};

var action = Substitute.For<ActionBase>();

var stepActionFactory = Substitute.For<IStepActionFactory>();
stepActionFactory.Get("action").Returns(action);

var sut = new StepExecutionEvaluator();

//Act
var result = sut.EvaluateAndRunStep(step, executionContext, stepActionFactory);

//Assert
stepActionFactory.Received(0);
}
}
}
45 changes: 0 additions & 45 deletions ActionFlow.Tests/Engine/WorkflowTests.cs

This file was deleted.

Loading

0 comments on commit 823c4b0

Please sign in to comment.