diff --git a/src/core/Elsa.Core/Builders/WorkflowDefinitionBuilder.cs b/src/core/Elsa.Core/Builders/WorkflowDefinitionBuilder.cs index 68f63d986..857b22bfc 100644 --- a/src/core/Elsa.Core/Builders/WorkflowDefinitionBuilder.cs +++ b/src/core/Elsa.Core/Builders/WorkflowDefinitionBuilder.cs @@ -72,4 +72,11 @@ public class WorkflowDefinitionBuilder : IWorkflowDefinitionBuilder var metadata = new WorkflowMetadata(); return new Workflow(identity, publication, metadata, root, Variables, Metadata, ApplicationProperties); } + + public Workflow BuildWorkflow(IWorkflow workflowDefinition) + { + WithDefinitionId(workflowDefinition.GetType().Name); + workflowDefinition.Build(this); + return BuildWorkflow(); + } } \ No newline at end of file diff --git a/src/runtime/Elsa.Runtime/Contracts/IWorkflow.cs b/src/core/Elsa.Core/Contracts/IWorkflow.cs similarity index 59% rename from src/runtime/Elsa.Runtime/Contracts/IWorkflow.cs rename to src/core/Elsa.Core/Contracts/IWorkflow.cs index 3f20e9c16..a361b6813 100644 --- a/src/runtime/Elsa.Runtime/Contracts/IWorkflow.cs +++ b/src/core/Elsa.Core/Contracts/IWorkflow.cs @@ -1,6 +1,4 @@ -using Elsa.Contracts; - -namespace Elsa.Runtime.Contracts; +namespace Elsa.Contracts; public interface IWorkflow { diff --git a/src/core/Elsa.Core/Elsa.Core.csproj b/src/core/Elsa.Core/Elsa.Core.csproj index ab2dce856..00dccc304 100644 --- a/src/core/Elsa.Core/Elsa.Core.csproj +++ b/src/core/Elsa.Core/Elsa.Core.csproj @@ -9,11 +9,11 @@ - - - - - + + + + + diff --git a/src/runtime/Elsa.Runtime/Extensions/WorkflowDictionaryExtensions.cs b/src/runtime/Elsa.Runtime/Extensions/WorkflowDictionaryExtensions.cs index 6ee19c492..eb1241362 100644 --- a/src/runtime/Elsa.Runtime/Extensions/WorkflowDictionaryExtensions.cs +++ b/src/runtime/Elsa.Runtime/Extensions/WorkflowDictionaryExtensions.cs @@ -1,3 +1,4 @@ +using Elsa.Contracts; using Elsa.Runtime.Contracts; using Microsoft.Extensions.DependencyInjection; diff --git a/src/runtime/Elsa.Runtime/Options/WorkflowRuntimeOptions.cs b/src/runtime/Elsa.Runtime/Options/WorkflowRuntimeOptions.cs index 115c309d7..682b6e756 100644 --- a/src/runtime/Elsa.Runtime/Options/WorkflowRuntimeOptions.cs +++ b/src/runtime/Elsa.Runtime/Options/WorkflowRuntimeOptions.cs @@ -1,3 +1,4 @@ +using Elsa.Contracts; using Elsa.Runtime.Contracts; using Elsa.Runtime.Services; using Microsoft.Extensions.DependencyInjection; diff --git a/test/Elsa.IntegrationTests/Workflows/ForEachWorkflowTests.cs b/test/Elsa.IntegrationTests/Workflows/ForEachWorkflowTests.cs new file mode 100644 index 000000000..2bfa59b6b --- /dev/null +++ b/test/Elsa.IntegrationTests/Workflows/ForEachWorkflowTests.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Elsa.Activities; +using Elsa.Builders; +using Elsa.Contracts; +using Elsa.Models; +using Elsa.Modules.Activities.Activities.Console; +using Elsa.Testing.Shared; +using Microsoft.Extensions.DependencyInjection; +using Xunit; +using Xunit.Abstractions; + +namespace Elsa.IntegrationTests.Workflows; + +public class ForEachWorkflowTests +{ + private readonly IWorkflowRunner _workflowRunner; + private readonly CapturingTextWriter _capturingTextWriter = new(); + private readonly Workflow _workflow; + + public ForEachWorkflowTests(ITestOutputHelper testOutputHelper) + { + var services = new TestContainerBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build(); + _workflowRunner = services.GetRequiredService(); + _workflow = new WorkflowDefinitionBuilder().BuildWorkflow(new ForEachWorkflow()); + } + + [Fact(DisplayName = "ForEach outputs each iteration")] + public async Task Test1() + { + await _workflowRunner.RunAsync(_workflow); + var lines = _capturingTextWriter.Lines.ToList(); + Assert.Equal("C#", lines[0]); + Assert.Equal("Rust", lines[1]); + Assert.Equal("Go", lines[2]); + } + + private class ForEachWorkflow : IWorkflow + { + public void Build(IWorkflowDefinitionBuilder workflow) + { + var items = new[] { "C#", "Rust", "Go" }; + var currentItem = new Variable(); + + workflow.WithRoot(new Sequence + { + Activities = + { + new ForEach + { + Items = new Input>(items), + CurrentValue = currentItem, + Body = new WriteLine(context => currentItem.Get(context)) + }, + } + }); + } + } +} \ No newline at end of file diff --git a/test/Elsa.IntegrationTests/Workflows/HelloWorldWorkflowTests.cs b/test/Elsa.IntegrationTests/Workflows/HelloWorldWorkflowTests.cs index 3c1b13302..def5e5741 100644 --- a/test/Elsa.IntegrationTests/Workflows/HelloWorldWorkflowTests.cs +++ b/test/Elsa.IntegrationTests/Workflows/HelloWorldWorkflowTests.cs @@ -3,8 +3,6 @@ using System.Threading.Tasks; using Elsa.Contracts; using Elsa.Models; using Elsa.Modules.Activities.Activities.Console; -using Elsa.Modules.Activities.Contracts; -using Elsa.Modules.Activities.Providers; using Elsa.Testing.Shared; using Microsoft.Extensions.DependencyInjection; using Xunit; @@ -19,11 +17,10 @@ public class HelloWorldWorkflowTests public HelloWorldWorkflowTests(ITestOutputHelper testOutputHelper) { - var combinedTextWriter = new CombinedTextWriter(_capturingTextWriter, new XunitConsoleTextWriter(testOutputHelper)); - var services = TestContainerBuilder.Build(testOutputHelper, x => x.AddSingleton(new StandardOutStreamProvider(combinedTextWriter))); + var services = new TestContainerBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build(); _workflowRunner = services.GetRequiredService(); } - + [Fact(DisplayName = "Run a simple workflow")] public async Task Test1() { diff --git a/test/Elsa.Testing.Shared/TestContainerBuilder.cs b/test/Elsa.Testing.Shared/TestContainerBuilder.cs index dc1263f44..c05ed1e2b 100644 --- a/test/Elsa.Testing.Shared/TestContainerBuilder.cs +++ b/test/Elsa.Testing.Shared/TestContainerBuilder.cs @@ -11,20 +11,34 @@ namespace Elsa.Testing.Shared; public class TestContainerBuilder { - public static IServiceProvider Build(ITestOutputHelper testOutputHelper, Action? configureServices = default) - { - var services = new ServiceCollection(); + private readonly ITestOutputHelper _testOutputHelper; + private readonly ServiceCollection _services; - services + public TestContainerBuilder(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + _services = new ServiceCollection(); + + _services .AddElsa() .AddInMemoryPersistence() + .AddSingleton(testOutputHelper) + .AddSingleton(new StandardOutStreamProvider(new XunitConsoleTextWriter(testOutputHelper))) .AddLogging(logging => logging.AddProvider(new XunitLoggerProvider(testOutputHelper)).SetMinimumLevel(LogLevel.Debug)); + } - services.AddSingleton(testOutputHelper); - services.AddSingleton(new StandardOutStreamProvider(new XunitConsoleTextWriter(testOutputHelper))); - - configureServices?.Invoke(services); + public IServiceProvider Build() => _services.BuildServiceProvider(); - return services.BuildServiceProvider(); + public TestContainerBuilder Configure(Action configure) + { + configure(_services); + return this; + } + + public TestContainerBuilder WithCapturingTextWriter(CapturingTextWriter capturingTextWriter) + { + var combinedTextWriter = new CombinedTextWriter(capturingTextWriter, new XunitConsoleTextWriter(_testOutputHelper)); + _services.AddSingleton(new StandardOutStreamProvider(combinedTextWriter)); + return this; } } \ No newline at end of file