Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/Moryx/Workflows/Implementation/ComparingProperties.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Moryx.Workplans;
using System.Collections.Generic;

namespace Moryx.Workflows.Implementation
{
public class ComparingProperties
{
public IWorkplanStep Step { get; set;}
public IWorkplanStep NewStep { get; set; }
public Workplan Workplan { get; set; }
public Workplan NewWorkplan { get; set; }
public List<IWorkplanStep> IsChecked { get; set; }
public List<IWorkplanStep> NeedToCheck { get; set; }
public List<IWorkplanStep> NewNeedToCheck { get; set; }
}

}

97 changes: 91 additions & 6 deletions src/Moryx/Workflows/Implementation/Workplan.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using System.Collections.Generic;
using System.Runtime.Serialization;

using System.Linq;
using Moryx.Workflows.Implementation;

namespace Moryx.Workplans
{
/// <summary>
Expand Down Expand Up @@ -92,5 +91,91 @@ public static Workplan Restore(List<IConnector> connectors, List<IWorkplanStep>
{
return new Workplan(connectors, steps);
}
}
}

public static bool CompareOutputs(ComparingProperties outputProperties)
{

for (int a = 0; a < outputProperties.Step.Outputs.Length; a++)
{
var connector = outputProperties.Step.Outputs[a];
var newConnector = outputProperties.NewStep.Outputs[a];

bool isNotEndConnector = !(connector.Classification.Equals(NodeClassification.End)) && !(newConnector.Classification.Equals(NodeClassification.End));
bool isNotFailedConnector = !(connector.Classification.Equals(NodeClassification.Failed)) && !(newConnector.Classification.Equals(NodeClassification.Failed));

if (isNotEndConnector && isNotFailedConnector)
{
var follower = outputProperties.Workplan.Steps.FirstOrDefault(x => x.Inputs.Any(y => y.Equals(connector)));
var newFollower = outputProperties.NewWorkplan.Steps.FirstOrDefault(x => x.Inputs.Any(y => y.Equals(newConnector)));

bool isSameStep = CompareSteps(follower, newFollower);
if (!isSameStep)
{
return false;
}

bool isAlreadyChecked = (outputProperties.IsChecked.Contains(follower));

if (!(isAlreadyChecked))
{
outputProperties.NeedToCheck.Add(follower);
outputProperties.NewNeedToCheck.Add(newFollower);
}
}
}
return true;
}

public static bool CompareSteps(IWorkplanStep step1, IWorkplanStep step2)
{
return step1.GetType() == step2.GetType();
}

/// <summary>
/// Compare two workplans
/// </summary>
/// <param name="workplan"></param>
/// <param name="newWorkplan"></param>
/// <returns></returns>
public static bool Equals(Workplan workplan, Workplan newWorkplan)
{
var step = workplan.Steps.FirstOrDefault(x => x.Inputs.Any(y => y.Classification.Equals(NodeClassification.Start)));
var newStep = newWorkplan.Steps.FirstOrDefault(x => x.Inputs.Any(y => y.Classification.Equals(NodeClassification.Start)));

List<IWorkplanStep> needToCheck = new List<IWorkplanStep>() { step };
List<IWorkplanStep> newNeedToCheck = new List<IWorkplanStep>() { newStep };

List<IWorkplanStep> isChecked = new List<IWorkplanStep>();

while (needToCheck.Count != 0 && newNeedToCheck.Count != 0)
{

bool isSameStep = CompareSteps(step, newStep);
if (!isSameStep)
{
return false;
}
var properties = new ComparingProperties() {Step = step, NewStep = newStep, Workplan = workplan, NewWorkplan = newWorkplan,IsChecked = isChecked, NeedToCheck = needToCheck, NewNeedToCheck = newNeedToCheck };
bool sameConnections = CompareOutputs(properties);
if (!sameConnections)
{
return false;
}
needToCheck.Remove(step);
newNeedToCheck.Remove(newStep);

isChecked.Add(step);

if (needToCheck.Count != 0 && newNeedToCheck.Count != 0)
{
step = needToCheck[0];
newStep = newNeedToCheck[0];
}

}

return true;
}

}
}
1 change: 1 addition & 0 deletions src/Tests/Moryx.Tests/Moryx.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Moryx.AbstractionLayer\Moryx.AbstractionLayer.csproj" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that fine or should the test move to Moryx.AbstractionLayer.Tests @1nf0rmagician ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either that or alternatively the test could be limited to IWorkplanStep and reflection.

<ProjectReference Include="..\..\Moryx.TestTools.UnitTest\Moryx.TestTools.UnitTest.csproj" />
<ProjectReference Include="..\..\Moryx\Moryx.csproj" />
</ItemGroup>
Expand Down
23 changes: 23 additions & 0 deletions src/Tests/Moryx.Tests/Workplans/Dummies/AssemblingActivity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Moryx.AbstractionLayer;
using Moryx.AbstractionLayer.Capabilities;

namespace Moryx.Tests.Workplans.Dummies
{
[ActivityResults(typeof(DefaultActivityResult))]
public class AssemblingActivity : Activity<AssemblingParameters>
{
public override ProcessRequirement ProcessRequirement => ProcessRequirement.NotRequired;

public override ICapabilities RequiredCapabilities => new AssemblingCapabilities();

protected override ActivityResult CreateResult(long resultNumber)
{
return ActivityResult.Create((DefaultActivityResult)resultNumber);
}

protected override ActivityResult CreateFailureResult()
{
return ActivityResult.Create(DefaultActivityResult.Failed);
}
}
}
23 changes: 23 additions & 0 deletions src/Tests/Moryx.Tests/Workplans/Dummies/AssemblingCapabilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Moryx.AbstractionLayer.Capabilities;

namespace Moryx.Tests.Workplans.Dummies
{

public class AssemblingCapabilities : CapabilitiesBase
{
public int Value { get; set; }

protected override bool ProvidedBy(ICapabilities provided)
{
var providedAssembling = provided as AssemblingCapabilities;
if (providedAssembling == null)
return false;

if (providedAssembling.Value < Value) // Provided must be greater or equal
return false;

return true;
}
}

}
17 changes: 17 additions & 0 deletions src/Tests/Moryx.Tests/Workplans/Dummies/AssemblingParameters.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Moryx.AbstractionLayer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Moryx.Tests.Workplans.Dummies
{
public class AssemblingParameters : Parameters
{
protected override void Populate(IProcess process, Parameters instance)
{

}
}
}
16 changes: 16 additions & 0 deletions src/Tests/Moryx.Tests/Workplans/Dummies/AssemblingTask.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Moryx.AbstractionLayer;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Moryx.Tests.Workplans.Dummies
{
[Display(Name = "Assembling Task", Description = "Task which does something with a product")]
public class AssemblingTask : TaskStep<AssemblingActivity, AssemblingParameters>
{
}
}
16 changes: 16 additions & 0 deletions src/Tests/Moryx.Tests/Workplans/Dummies/ColorizingTask.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Moryx.AbstractionLayer;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Moryx.Tests.Workplans.Dummies
{
[Display(Name = "PackagingTask", Description = "Task which does something with a product")]
public class ColorizingTask : TaskStep<AssemblingActivity, AssemblingParameters>
{
}
}
16 changes: 16 additions & 0 deletions src/Tests/Moryx.Tests/Workplans/Dummies/PackagingTask.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Moryx.AbstractionLayer;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Moryx.Tests.Workplans.Dummies
{
[Display(Name = "PackagingTask", Description = "Task which does something with a product")]
public class PackagingTask : TaskStep<AssemblingActivity, AssemblingParameters>
{
}
}
127 changes: 127 additions & 0 deletions src/Tests/Moryx.Tests/Workplans/EqualTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using Moryx.Workplans;
using Moryx.AbstractionLayer;
using NUnit.Framework;
using Moryx.Tests.Workplans.Dummies;

namespace Moryx.Tests.Workplans
{

[TestFixture]
public class EqualTest
{
private Workplan firstWorkplan;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better names. What are the differences between each workplan?

private Workplan secondWorkplan;
private Workplan thirdWorkplan;
private Workplan fourthWorkplan;
private Workplan fifthWorkplan;
private Workplan sixthWorkplan;

public Workplan CreateSimpleWorkplan()
{
var plan = new Workplan();

var start = plan.AddConnector("Start", NodeClassification.Start);
var end = plan.AddConnector("End", NodeClassification.End);
var failed = plan.AddConnector("Failed", NodeClassification.Failed);

var input = start;
var outputA = plan.AddConnector("A");
var outputB = plan.AddConnector("B");

plan.AddStep(new AssemblingTask(), new AssemblingParameters(), input, outputA, outputB, failed);

input = outputA;
plan.AddStep(new PackagingTask(), new AssemblingParameters(), input, end, end, failed);

input = outputB;
plan.AddStep(new ColorizingTask(), new AssemblingParameters(), input, end, failed, failed);
return plan;
}

public Workplan CreateWorkplanWithLoop()
{
var plan = new Workplan();

var start = plan.AddConnector("Start", NodeClassification.Start);
var end = plan.AddConnector("End", NodeClassification.End);
var failed = plan.AddConnector("Failed", NodeClassification.Failed);

var input = start;
var outptuA = input;
var outputB = plan.AddConnector("A");

plan.AddStep(new AssemblingTask(), new AssemblingParameters(), input, outptuA, outputB, failed);

input = outputB;
plan.AddStep(new PackagingTask(), new AssemblingParameters(), input, outputB, end, failed);

return plan;
}

public Workplan CreateWorkplanWithLoopsAndBranches()
{
var plan = new Workplan();

var start = plan.AddConnector("Start", NodeClassification.Start);
var end = plan.AddConnector("End", NodeClassification.End);
var failed = plan.AddConnector("Failed", NodeClassification.Failed);

var outputA = plan.AddConnector("A");
var outputB = plan.AddConnector("B");

plan.AddStep(new AssemblingTask(), new AssemblingParameters(), start, outputA, outputB, failed);

var input = outputA;

plan.AddStep(new PackagingTask(), new AssemblingParameters(), input, start, end, failed);

input = outputB;

plan.AddStep(new ColorizingTask(), new AssemblingParameters(), input, outputA, end, failed);

return plan;
}

[SetUp]
public void SetUp()
{
firstWorkplan = CreateSimpleWorkplan();
secondWorkplan = CreateSimpleWorkplan();

thirdWorkplan = CreateWorkplanWithLoop();
fourthWorkplan = CreateWorkplanWithLoop();

fifthWorkplan = CreateWorkplanWithLoopsAndBranches();
sixthWorkplan = CreateWorkplanWithLoopsAndBranches();
}

[Test]
public void TestEqualWorkplans()
{
bool result = Workplan.Equals(firstWorkplan, secondWorkplan);
Assert.That(result, Is.True);
}

[Test]
public void TestEqualWorkplansSimpleLoop()
{
bool result = Workplan.Equals(thirdWorkplan, fourthWorkplan);
Assert.That(result, Is.True);
}

[Test]
public void TestEqualWorkplansDoubleLoop()
{
bool result = Workplan.Equals(fifthWorkplan, sixthWorkplan);
Assert.That(result, Is.True);
}

[Test]
public void TestUnequalWorkplans()
{
bool r = Workplan.Equals(firstWorkplan, sixthWorkplan);
Assert.That(r, Is.False);
}
}

}