Adds SetVariable activity unit tests (#6989)
* Update doc/qa/test-guidelines.md
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* Improvements on maintainability of sendhttprequest unit tests
* Improving tests and scheduled activity evaluation for activity context
* Refactor and splitting unnecessary grouped tests
* Improvements on SendHttp Unit tests
* Improvements on tests
* Update test/unit/Elsa.Activities.UnitTests/HTTP/SendHttpRequestTests.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Small suggestions from copilot
* Update test/unit/Elsa.Activities.UnitTests/HTTP/SendHttpRequestTests.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* small copilot suggestion
* Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts
- Added `IWorkflowExecutionContextSchedulerStrategy` and `IActivityExecutionContextSchedulerStrategy` interfaces.
- Implemented `WorkflowExecutionContextSchedulerStrategy` and `ActivityExecutionContextSchedulerStrategy` for scheduling activities in workflows.
- Refactored scheduling logic to utilize the new scheduler strategies.
- Updated unit tests and test helpers to reflect refactoring, introducing fake implementations for testing purposes.
- Adjusted background execution scheduling and improved extensibility for custom scheduler strategies.
* Refactor `SendHttpRequestTests`: simplify scheduling assertions, use shared extensions, and standardize method naming. Streamline helper methods and remove unused test logic.
* Refactor: Replace `ActivityTestHelper` with `ActivityTestFixture` in unit tests for streamlined activity testing
- Introduced `ActivityTestFixture` with a fluent API for better test setup and execution of activities.
- Added extension methods `ActivityTestFixtureExtensions` and `ActivityTestFixtureHttpExtensions` for configuring attributes and HTTP services.
- Updated test guidelines and unit tests to use the new fixture and extensions.
- Removed `ActivityTestHelper`.
* Refactor: Move `ActivityTestFixture` and related extensions to shared project for reuse across test suites
- Consolidated `ActivityTestFixture`, `ActivityTestFixtureExtensions`, and `ActivityTestFixtureHttpExtensions` into `Elsa.Testing.Shared`.
- Updated namespaces and imports across unit tests to reflect new structure.
- Enhanced `AssertActivityAttributes` and added fluent configuration APIs.
- Adjusted `Directory.Packages.props` with new dependencies, including `NSubstitute` and `xunit.assert`.
* Refactor `SetVariableTests`: inline `ActivityTestFixture` initialization to simplify test setup.
* Refactor `ActivityTestFixture`: eliminate redundant field `_services`, add `UsedImplicitly` attributes, and improve service collection management
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for `ActivityExecutionContextExtensions`, detailing methods and parameters.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for scheduler strategies and their methods
- Updated `IActivityExecutionContextSchedulerStrategy` and `IWorkflowExecutionContextSchedulerStrategy` interfaces with XML summaries for methods.
- Added XML documentation to implementations (`ActivityExecutionContextSchedulerStrategy`, `WorkflowExecutionContextSchedulerStrategy`) and test fakes for clarity.
* Refactor `WriteLineTests`: consolidate duplicate test logic, simplify setup with shared helper method, and enhance readability in assertions.
* Refactor `WriteLineTests` and `SetVariableTests`: replace `WriteLineAsync` assertions with synchronous `WriteLine`, streamline exception recording in `SetVariableTests`, and remove unused imports.
* Add integration and unit tests for `SetVariable` activity: ensure variable scoping, null handling, and value setting are covered.
* Add new `SetVariableOfTTests` and update `SetVariableTests` for improved test coverage and type handling.
* Add new unit and integration tests for activity input and expression evaluation
- Introduced comprehensive test suites covering activity input evaluation, expression handling, and fault scenarios.
- Added unit tests for `ExpressionDescriptorRegistry`, `ExpressionEvaluator`, and activity execution context extensions.
- Added integration tests: `CustomInputEvaluatorTests`, `InputEvaluationErrorTests`, and `InputPropertyEvaluationTests`.
- Enhanced code coverage for edge cases and async evaluation logic.
* Remove unused `RunWorkflowAsync` extension method from `RunActivityExtensions`.
* Rename `CustomInputEvaluatorTests` to `InputEvaluationTests` for consistency with naming conventions.
* Remove unused `Elsa.Workflows.Activities` import from `RunActivityExtensions`.
* Remove redundant comments from `InputEvaluationErrorTests` for clarity.
* Refactor unit tests to streamline activity and expression evaluations
- Refactored `ExecuteActivityAsync` and `ExecuteWriteLineAsync` into shared helpers for consistency and reuse across tests.
- Replaced redundant mock setups with helper methods in `ExpressionDescriptorRegistryTests`.
- Simplified test setup for expression and activity evaluation by removing unused imports and consolidating configuration logic.
- Enhanced readability by reducing duplicate code and leveraging shared utility methods.
* Refactor activity input evaluation tests
- Extracted `CreateContextAsync` helper into `EvaluationTestHelpers` for reuse across evaluation test suites.
- Replaced inline activity context setup with shared helper in `InputPropertyEvaluationTests`, `WrappedInputEvaluationTests`, and related test suites.
- Simplified test method names for clarity and consistency.
- Updated test annotations to enhance readability and align with naming conventions.
* Remove redundant test cases and unused imports
- Deleted duplicated and non-essential test cases across evaluation test suites.
- Removed unused imports to improve code cleanliness and readability.
- Streamlined variable initializations and method calls within test setups.
* Remove redundant test case from `InputEvaluationErrorTests`
- Deleted the `ContinuesEvaluationForMultipleInputs` test, as it overlaps with existing tests and does not provide additional coverage.
* Remove redundant assertion from `InputPropertyEvaluationTests`
- Deleted `Assert.True(context.GetHasEvaluatedProperties())`, as it is unnecessary for verifying test outcomes.
* Remove redundant test cases from `WrappedInputEvaluationTests`
- Deleted `UsesDefaultValueWhenInputIsNull` and `EvaluatesExpression` tests as they are either duplicated or unnecessary for current test coverage.
* Add unit test projects for `Elsa.Workflows.Management` and `Elsa.Expressions`
- Introduced new test projects to separate and organize unit tests for `Elsa.Workflows.Management` and `Elsa.Expressions`.
- Updated `Elsa.sln` to include references to the newly added test projects.
- Adjusted namespaces in affected test classes for consistency with the updated project structure.
* Refactor `ExpressionEvaluatorTests` for clarity and consistency
- Simplified test method names and annotations for improved readability.
- Replaced duplicate mock setups with helper functions (`CreateContextAsync`, `CreateContextWithMockHandlerAsync`, and related methods).
- Streamlined test setups by removing redundant code and consolidating context creation logic.
- Updated test annotations to include descriptive `DisplayName` attributes.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Remove redundant comment from `ExpressionEvaluatorTests` for clarity
* Remove redundant blank lines from unit test classes
- Eliminated unnecessary blank lines across `ActivityExecutionContextExtensions` test suites to improve code readability and consistency.
* Add unit tests for Flowchart activity
- Introduced `FlowchartTests` to verify common Flowchart behavior, including start activity scheduling, execution without a start activity, and `UseTokenFlow` handling.
- Added `FlowchartTestHelpers` to encapsulate shared test logic.
- Updated project file to include the new `Flow` folder for organization.
* Add integration tests for Flowchart activity execution strategies
- Introduced `FlowchartCounterBasedTests` and `FlowchartTokenBasedTests` to verify different Flowchart execution strategies.
- Added `FlowchartTestHelpers` for shared test logic, including helper methods for creating various flowchart configurations and connections.
- Enhanced test coverage with scenarios for linear, parallel, and conditional flows, mixed merge modes, nested flowcharts, and token handling.
- Updated project structure to include new test classes under the `Flow` folder.
* Remove obsolete tag from `FlowJoin` activity description
* Handle both string and enum values in `GetMergeMode` for backwards compatibility
* Group flowchart integration tests into non-parallelizable test collection
- Introduced `FlowchartTestCollection` to prevent parallel execution of flowchart tests due to shared `Flowchart.UseTokenFlow` flag.
- Updated `FlowchartCounterBasedTests` and `FlowchartTokenBasedTests` to implement `IDisposable` and manage `UseTokenFlow` cleanup.
* Remove unused `Flow` folder reference from test project file
* Add `ParallelTests` for unit and integration testing with various scenarios (#6988)
- Added unit tests for `Parallel` activity to ensure proper scheduling of child activities, including empty and mixed activity cases.
- Added integration tests to validate execution flow and edge cases for `Parallel` activities (e.g., nested parallelism, fault handling).
- Enhanced `ScheduleChildrenAsync` in `Parallel` to handle no activity scenario by completing immediately.
* Fix null-check and memory declaration in `ActivityTestFixture` to prevent potential `NullReferenceException`.
* Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts (#6984)
* Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts
- Added `IWorkflowExecutionContextSchedulerStrategy` and `IActivityExecutionContextSchedulerStrategy` interfaces.
- Implemented `WorkflowExecutionContextSchedulerStrategy` and `ActivityExecutionContextSchedulerStrategy` for scheduling activities in workflows.
- Refactored scheduling logic to utilize the new scheduler strategies.
- Updated unit tests and test helpers to reflect refactoring, introducing fake implementations for testing purposes.
- Adjusted background execution scheduling and improved extensibility for custom scheduler strategies.
* Refactor `SendHttpRequestTests`: simplify scheduling assertions, use shared extensions, and standardize method naming. Streamline helper methods and remove unused test logic.
* Refactor: Replace `ActivityTestHelper` with `ActivityTestFixture` in unit tests for streamlined activity testing
- Introduced `ActivityTestFixture` with a fluent API for better test setup and execution of activities.
- Added extension methods `ActivityTestFixtureExtensions` and `ActivityTestFixtureHttpExtensions` for configuring attributes and HTTP services.
- Updated test guidelines and unit tests to use the new fixture and extensions.
- Removed `ActivityTestHelper`.
* Refactor: Move `ActivityTestFixture` and related extensions to shared project for reuse across test suites
- Consolidated `ActivityTestFixture`, `ActivityTestFixtureExtensions`, and `ActivityTestFixtureHttpExtensions` into `Elsa.Testing.Shared`.
- Updated namespaces and imports across unit tests to reflect new structure.
- Enhanced `AssertActivityAttributes` and added fluent configuration APIs.
- Adjusted `Directory.Packages.props` with new dependencies, including `NSubstitute` and `xunit.assert`.
* Refactor `SetVariableTests`: inline `ActivityTestFixture` initialization to simplify test setup.
* Refactor `ActivityTestFixture`: eliminate redundant field `_services`, add `UsedImplicitly` attributes, and improve service collection management
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for `ActivityExecutionContextExtensions`, detailing methods and parameters.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for scheduler strategies and their methods
- Updated `IActivityExecutionContextSchedulerStrategy` and `IWorkflowExecutionContextSchedulerStrategy` interfaces with XML summaries for methods.
- Added XML documentation to implementations (`ActivityExecutionContextSchedulerStrategy`, `WorkflowExecutionContextSchedulerStrategy`) and test fakes for clarity.
* Refactor `WriteLineTests`: consolidate duplicate test logic, simplify setup with shared helper method, and enhance readability in assertions.
* Refactor `WriteLineTests` and `SetVariableTests`: replace `WriteLineAsync` assertions with synchronous `WriteLine`, streamline exception recording in `SetVariableTests`, and remove unused imports.
* Add `ParallelTests` for unit and integration testing with various scenarios (#6988)
- Added unit tests for `Parallel` activity to ensure proper scheduling of child activities, including empty and mixed activity cases.
- Added integration tests to validate execution flow and edge cases for `Parallel` activities (e.g., nested parallelism, fault handling).
- Enhanced `ScheduleChildrenAsync` in `Parallel` to handle no activity scenario by completing immediately.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add new unit and integration tests for activity input and expression evaluation (#6990)
* Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts
- Added `IWorkflowExecutionContextSchedulerStrategy` and `IActivityExecutionContextSchedulerStrategy` interfaces.
- Implemented `WorkflowExecutionContextSchedulerStrategy` and `ActivityExecutionContextSchedulerStrategy` for scheduling activities in workflows.
- Refactored scheduling logic to utilize the new scheduler strategies.
- Updated unit tests and test helpers to reflect refactoring, introducing fake implementations for testing purposes.
- Adjusted background execution scheduling and improved extensibility for custom scheduler strategies.
* Refactor `SendHttpRequestTests`: simplify scheduling assertions, use shared extensions, and standardize method naming. Streamline helper methods and remove unused test logic.
* Refactor: Replace `ActivityTestHelper` with `ActivityTestFixture` in unit tests for streamlined activity testing
- Introduced `ActivityTestFixture` with a fluent API for better test setup and execution of activities.
- Added extension methods `ActivityTestFixtureExtensions` and `ActivityTestFixtureHttpExtensions` for configuring attributes and HTTP services.
- Updated test guidelines and unit tests to use the new fixture and extensions.
- Removed `ActivityTestHelper`.
* Refactor: Move `ActivityTestFixture` and related extensions to shared project for reuse across test suites
- Consolidated `ActivityTestFixture`, `ActivityTestFixtureExtensions`, and `ActivityTestFixtureHttpExtensions` into `Elsa.Testing.Shared`.
- Updated namespaces and imports across unit tests to reflect new structure.
- Enhanced `AssertActivityAttributes` and added fluent configuration APIs.
- Adjusted `Directory.Packages.props` with new dependencies, including `NSubstitute` and `xunit.assert`.
* Refactor `SetVariableTests`: inline `ActivityTestFixture` initialization to simplify test setup.
* Refactor `ActivityTestFixture`: eliminate redundant field `_services`, add `UsedImplicitly` attributes, and improve service collection management
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for `ActivityExecutionContextExtensions`, detailing methods and parameters.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for scheduler strategies and their methods
- Updated `IActivityExecutionContextSchedulerStrategy` and `IWorkflowExecutionContextSchedulerStrategy` interfaces with XML summaries for methods.
- Added XML documentation to implementations (`ActivityExecutionContextSchedulerStrategy`, `WorkflowExecutionContextSchedulerStrategy`) and test fakes for clarity.
* Refactor `WriteLineTests`: consolidate duplicate test logic, simplify setup with shared helper method, and enhance readability in assertions.
* Refactor `WriteLineTests` and `SetVariableTests`: replace `WriteLineAsync` assertions with synchronous `WriteLine`, streamline exception recording in `SetVariableTests`, and remove unused imports.
* Add new unit and integration tests for activity input and expression evaluation
- Introduced comprehensive test suites covering activity input evaluation, expression handling, and fault scenarios.
- Added unit tests for `ExpressionDescriptorRegistry`, `ExpressionEvaluator`, and activity execution context extensions.
- Added integration tests: `CustomInputEvaluatorTests`, `InputEvaluationErrorTests`, and `InputPropertyEvaluationTests`.
- Enhanced code coverage for edge cases and async evaluation logic.
* Remove unused `RunWorkflowAsync` extension method from `RunActivityExtensions`.
* Rename `CustomInputEvaluatorTests` to `InputEvaluationTests` for consistency with naming conventions.
* Remove unused `Elsa.Workflows.Activities` import from `RunActivityExtensions`.
* Remove redundant comments from `InputEvaluationErrorTests` for clarity.
* Refactor unit tests to streamline activity and expression evaluations
- Refactored `ExecuteActivityAsync` and `ExecuteWriteLineAsync` into shared helpers for consistency and reuse across tests.
- Replaced redundant mock setups with helper methods in `ExpressionDescriptorRegistryTests`.
- Simplified test setup for expression and activity evaluation by removing unused imports and consolidating configuration logic.
- Enhanced readability by reducing duplicate code and leveraging shared utility methods.
* Refactor activity input evaluation tests
- Extracted `CreateContextAsync` helper into `EvaluationTestHelpers` for reuse across evaluation test suites.
- Replaced inline activity context setup with shared helper in `InputPropertyEvaluationTests`, `WrappedInputEvaluationTests`, and related test suites.
- Simplified test method names for clarity and consistency.
- Updated test annotations to enhance readability and align with naming conventions.
* Remove redundant test cases and unused imports
- Deleted duplicated and non-essential test cases across evaluation test suites.
- Removed unused imports to improve code cleanliness and readability.
- Streamlined variable initializations and method calls within test setups.
* Remove redundant test case from `InputEvaluationErrorTests`
- Deleted the `ContinuesEvaluationForMultipleInputs` test, as it overlaps with existing tests and does not provide additional coverage.
* Remove redundant assertion from `InputPropertyEvaluationTests`
- Deleted `Assert.True(context.GetHasEvaluatedProperties())`, as it is unnecessary for verifying test outcomes.
* Remove redundant test cases from `WrappedInputEvaluationTests`
- Deleted `UsesDefaultValueWhenInputIsNull` and `EvaluatesExpression` tests as they are either duplicated or unnecessary for current test coverage.
* Add unit test projects for `Elsa.Workflows.Management` and `Elsa.Expressions`
- Introduced new test projects to separate and organize unit tests for `Elsa.Workflows.Management` and `Elsa.Expressions`.
- Updated `Elsa.sln` to include references to the newly added test projects.
- Adjusted namespaces in affected test classes for consistency with the updated project structure.
* Refactor `ExpressionEvaluatorTests` for clarity and consistency
- Simplified test method names and annotations for improved readability.
- Replaced duplicate mock setups with helper functions (`CreateContextAsync`, `CreateContextWithMockHandlerAsync`, and related methods).
- Streamlined test setups by removing redundant code and consolidating context creation logic.
- Updated test annotations to include descriptive `DisplayName` attributes.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Remove redundant comment from `ExpressionEvaluatorTests` for clarity
* Remove redundant blank lines from unit test classes
- Eliminated unnecessary blank lines across `ActivityExecutionContextExtensions` test suites to improve code readability and consistency.
* Update src/modules/Elsa.Expressions/Services/ExpressionEvaluator.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Expand `test-guidelines.md` with testing best practices, helper references, and example snippets
- Added detailed guidance on test project organization, updated helper documentation, and streamlined example code for activity unit testing.
- Introduced scheduler strategy information and integration test patterns for deterministic tests.
- Clarified usage of shared infrastructure like `ActivityTestFixture` and `AsyncWorkflowRunner`.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix merge issue
* Add missing `using Elsa.Expressions.Models` directive to `SetVariableTests`
* Update `SetVariableTests` and `ActivityTestFixture` to fix exception type assertion and improve test utility execution handling.
* Update `SetVariableTests` and `ActivityTestFixture` to handle null variables, fix exception type assertion, and simplify context usage.
---------
Co-authored-by: lucas.hipolito <lukhipolito@yahoo.com.br>
Co-authored-by: lukhipolito-nexxbiz <lucas.hipolito@nexxbiz.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-22 18:54:58 +00:00
|
|
|
using Elsa.Testing.Shared;
|
|
|
|
|
using Elsa.Workflows.Activities;
|
|
|
|
|
using Elsa.Workflows.Activities.Flowchart.Activities;
|
|
|
|
|
using Elsa.Workflows.Activities.Flowchart.Extensions;
|
|
|
|
|
using Elsa.Workflows.Activities.Flowchart.Models;
|
|
|
|
|
using Xunit.Abstractions;
|
|
|
|
|
using static Elsa.Activities.IntegrationTests.Flow.FlowchartTestHelpers;
|
|
|
|
|
|
|
|
|
|
namespace Elsa.Activities.IntegrationTests.Flow;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Integration tests for token-based flowchart execution strategy.
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Collection("FlowchartTests")]
|
|
|
|
|
public class FlowchartTokenBasedTests : IDisposable
|
|
|
|
|
{
|
|
|
|
|
private readonly IServiceProvider _services;
|
|
|
|
|
private readonly CapturingTextWriter _output;
|
|
|
|
|
private readonly bool _originalFlowMode;
|
|
|
|
|
|
|
|
|
|
public FlowchartTokenBasedTests(ITestOutputHelper testOutputHelper)
|
|
|
|
|
{
|
|
|
|
|
_output = new();
|
|
|
|
|
_services = CreateServiceProvider(testOutputHelper, _output);
|
|
|
|
|
_originalFlowMode = Flowchart.UseTokenFlow;
|
|
|
|
|
Flowchart.UseTokenFlow = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
Flowchart.UseTokenFlow = _originalFlowMode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Executes simple linear flowchart")]
|
|
|
|
|
public async Task ExecutesSimpleLinearFlowchart()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var flowchart = CreateSimpleLinearFlowchart(
|
|
|
|
|
new WriteLine("First"),
|
|
|
|
|
new WriteLine("Second"),
|
|
|
|
|
new WriteLine("Third")
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Equal(3, _output.Lines.Count);
|
|
|
|
|
Assert.Equal("First", _output.Lines.ElementAt(0));
|
|
|
|
|
Assert.Equal("Second", _output.Lines.ElementAt(1));
|
|
|
|
|
Assert.Equal("Third", _output.Lines.ElementAt(2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Executes both branches in parallel flowchart")]
|
|
|
|
|
public async Task ExecutesBothBranches()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var branch1 = new WriteLine("Branch1");
|
|
|
|
|
var branch2 = new WriteLine("Branch2");
|
|
|
|
|
var flowchart = CreateBranchingFlowchart(start, branch1, branch2);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Equal(3, _output.Lines.Count);
|
|
|
|
|
Assert.Contains("Start", _output.Lines);
|
|
|
|
|
Assert.Contains("Branch1", _output.Lines);
|
|
|
|
|
Assert.Contains("Branch2", _output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Handles flowchart with no connections")]
|
|
|
|
|
public async Task HandlesNoConnections()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var activity = new WriteLine("Isolated");
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = activity,
|
|
|
|
|
Activities = { activity }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Single(_output.Lines);
|
|
|
|
|
Assert.Equal("Isolated", _output.Lines.ElementAt(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Completes when start activity is null")]
|
|
|
|
|
public async Task CompletesWhenStartIsNull()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = null
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
var result = await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.NotNull(result);
|
|
|
|
|
Assert.Empty(_output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Follows conditional branches with If activity")]
|
|
|
|
|
public async Task FollowsConditionalBranches()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var ifActivity = new If
|
|
|
|
|
{
|
|
|
|
|
Condition = new(true),
|
|
|
|
|
Then = new WriteLine("Then branch"),
|
|
|
|
|
Else = new WriteLine("Else branch")
|
|
|
|
|
};
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = ifActivity,
|
|
|
|
|
Activities = { ifActivity }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Single(_output.Lines);
|
|
|
|
|
Assert.Equal("Then branch", _output.Lines.ElementAt(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Executes Stream merge mode - schedules immediately")]
|
|
|
|
|
public async Task ExecutesStreamMergeMode()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var branch1 = new WriteLine("Branch1");
|
|
|
|
|
var branch2 = new WriteLine("Branch2");
|
|
|
|
|
var afterJoin = new WriteLine("AfterJoin");
|
|
|
|
|
afterJoin.SetMergeMode(MergeMode.Stream);
|
|
|
|
|
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = start,
|
|
|
|
|
Activities = { start, branch1, branch2, afterJoin },
|
|
|
|
|
Connections =
|
|
|
|
|
{
|
|
|
|
|
CreateConnection(start, branch1),
|
|
|
|
|
CreateConnection(start, branch2),
|
|
|
|
|
CreateConnection(branch1, afterJoin),
|
|
|
|
|
CreateConnection(branch2, afterJoin)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Contains("Start", _output.Lines);
|
|
|
|
|
Assert.Contains("AfterJoin", _output.Lines);
|
|
|
|
|
// In Stream mode, afterJoin executes as soon as first branch arrives
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Executes Race merge mode - cancels other branches")]
|
|
|
|
|
public async Task ExecutesRaceMergeMode()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var branch1 = new WriteLine("Branch1");
|
|
|
|
|
var branch2 = new WriteLine("Branch2");
|
|
|
|
|
var afterRace = new WriteLine("AfterRace");
|
|
|
|
|
afterRace.SetMergeMode(MergeMode.Race);
|
|
|
|
|
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = start,
|
|
|
|
|
Activities = { start, branch1, branch2, afterRace },
|
|
|
|
|
Connections =
|
|
|
|
|
{
|
|
|
|
|
CreateConnection(start, branch1),
|
|
|
|
|
CreateConnection(start, branch2),
|
|
|
|
|
CreateConnection(branch1, afterRace),
|
|
|
|
|
CreateConnection(branch2, afterRace)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Contains("Start", _output.Lines);
|
|
|
|
|
Assert.Contains("AfterRace", _output.Lines);
|
|
|
|
|
// In Race mode, afterRace executes on first arrival and blocks others
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Executes Converge merge mode - waits for all branches")]
|
|
|
|
|
public async Task ExecutesConvergeMergeMode()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var branch1 = new WriteLine("Branch1");
|
|
|
|
|
var branch2 = new WriteLine("Branch2");
|
|
|
|
|
var converge = new WriteLine("Converge");
|
|
|
|
|
converge.SetMergeMode(MergeMode.Converge);
|
|
|
|
|
var end = new WriteLine("End");
|
|
|
|
|
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = start,
|
|
|
|
|
Activities = { start, branch1, branch2, converge, end },
|
|
|
|
|
Connections =
|
|
|
|
|
{
|
|
|
|
|
CreateConnection(start, branch1),
|
|
|
|
|
CreateConnection(start, branch2),
|
|
|
|
|
CreateConnection(branch1, converge),
|
|
|
|
|
CreateConnection(branch2, converge),
|
|
|
|
|
CreateConnection(converge, end)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Contains("Start", _output.Lines);
|
|
|
|
|
Assert.Contains("Branch1", _output.Lines);
|
|
|
|
|
Assert.Contains("Branch2", _output.Lines);
|
|
|
|
|
Assert.Contains("Converge", _output.Lines);
|
|
|
|
|
Assert.Contains("End", _output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Executes None merge mode correctly")]
|
|
|
|
|
public async Task ExecutesNoneMergeMode()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var branch1 = new WriteLine("Branch1");
|
|
|
|
|
var branch2 = new WriteLine("Branch2");
|
|
|
|
|
var noneMode = new WriteLine("NoneMode");
|
2025-11-25 20:06:00 +00:00
|
|
|
noneMode.SetMergeMode(null);
|
Adds SetVariable activity unit tests (#6989)
* Update doc/qa/test-guidelines.md
Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
* Improvements on maintainability of sendhttprequest unit tests
* Improving tests and scheduled activity evaluation for activity context
* Refactor and splitting unnecessary grouped tests
* Improvements on SendHttp Unit tests
* Improvements on tests
* Update test/unit/Elsa.Activities.UnitTests/HTTP/SendHttpRequestTests.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Small suggestions from copilot
* Update test/unit/Elsa.Activities.UnitTests/HTTP/SendHttpRequestTests.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* small copilot suggestion
* Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts
- Added `IWorkflowExecutionContextSchedulerStrategy` and `IActivityExecutionContextSchedulerStrategy` interfaces.
- Implemented `WorkflowExecutionContextSchedulerStrategy` and `ActivityExecutionContextSchedulerStrategy` for scheduling activities in workflows.
- Refactored scheduling logic to utilize the new scheduler strategies.
- Updated unit tests and test helpers to reflect refactoring, introducing fake implementations for testing purposes.
- Adjusted background execution scheduling and improved extensibility for custom scheduler strategies.
* Refactor `SendHttpRequestTests`: simplify scheduling assertions, use shared extensions, and standardize method naming. Streamline helper methods and remove unused test logic.
* Refactor: Replace `ActivityTestHelper` with `ActivityTestFixture` in unit tests for streamlined activity testing
- Introduced `ActivityTestFixture` with a fluent API for better test setup and execution of activities.
- Added extension methods `ActivityTestFixtureExtensions` and `ActivityTestFixtureHttpExtensions` for configuring attributes and HTTP services.
- Updated test guidelines and unit tests to use the new fixture and extensions.
- Removed `ActivityTestHelper`.
* Refactor: Move `ActivityTestFixture` and related extensions to shared project for reuse across test suites
- Consolidated `ActivityTestFixture`, `ActivityTestFixtureExtensions`, and `ActivityTestFixtureHttpExtensions` into `Elsa.Testing.Shared`.
- Updated namespaces and imports across unit tests to reflect new structure.
- Enhanced `AssertActivityAttributes` and added fluent configuration APIs.
- Adjusted `Directory.Packages.props` with new dependencies, including `NSubstitute` and `xunit.assert`.
* Refactor `SetVariableTests`: inline `ActivityTestFixture` initialization to simplify test setup.
* Refactor `ActivityTestFixture`: eliminate redundant field `_services`, add `UsedImplicitly` attributes, and improve service collection management
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for `ActivityExecutionContextExtensions`, detailing methods and parameters.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for scheduler strategies and their methods
- Updated `IActivityExecutionContextSchedulerStrategy` and `IWorkflowExecutionContextSchedulerStrategy` interfaces with XML summaries for methods.
- Added XML documentation to implementations (`ActivityExecutionContextSchedulerStrategy`, `WorkflowExecutionContextSchedulerStrategy`) and test fakes for clarity.
* Refactor `WriteLineTests`: consolidate duplicate test logic, simplify setup with shared helper method, and enhance readability in assertions.
* Refactor `WriteLineTests` and `SetVariableTests`: replace `WriteLineAsync` assertions with synchronous `WriteLine`, streamline exception recording in `SetVariableTests`, and remove unused imports.
* Add integration and unit tests for `SetVariable` activity: ensure variable scoping, null handling, and value setting are covered.
* Add new `SetVariableOfTTests` and update `SetVariableTests` for improved test coverage and type handling.
* Add new unit and integration tests for activity input and expression evaluation
- Introduced comprehensive test suites covering activity input evaluation, expression handling, and fault scenarios.
- Added unit tests for `ExpressionDescriptorRegistry`, `ExpressionEvaluator`, and activity execution context extensions.
- Added integration tests: `CustomInputEvaluatorTests`, `InputEvaluationErrorTests`, and `InputPropertyEvaluationTests`.
- Enhanced code coverage for edge cases and async evaluation logic.
* Remove unused `RunWorkflowAsync` extension method from `RunActivityExtensions`.
* Rename `CustomInputEvaluatorTests` to `InputEvaluationTests` for consistency with naming conventions.
* Remove unused `Elsa.Workflows.Activities` import from `RunActivityExtensions`.
* Remove redundant comments from `InputEvaluationErrorTests` for clarity.
* Refactor unit tests to streamline activity and expression evaluations
- Refactored `ExecuteActivityAsync` and `ExecuteWriteLineAsync` into shared helpers for consistency and reuse across tests.
- Replaced redundant mock setups with helper methods in `ExpressionDescriptorRegistryTests`.
- Simplified test setup for expression and activity evaluation by removing unused imports and consolidating configuration logic.
- Enhanced readability by reducing duplicate code and leveraging shared utility methods.
* Refactor activity input evaluation tests
- Extracted `CreateContextAsync` helper into `EvaluationTestHelpers` for reuse across evaluation test suites.
- Replaced inline activity context setup with shared helper in `InputPropertyEvaluationTests`, `WrappedInputEvaluationTests`, and related test suites.
- Simplified test method names for clarity and consistency.
- Updated test annotations to enhance readability and align with naming conventions.
* Remove redundant test cases and unused imports
- Deleted duplicated and non-essential test cases across evaluation test suites.
- Removed unused imports to improve code cleanliness and readability.
- Streamlined variable initializations and method calls within test setups.
* Remove redundant test case from `InputEvaluationErrorTests`
- Deleted the `ContinuesEvaluationForMultipleInputs` test, as it overlaps with existing tests and does not provide additional coverage.
* Remove redundant assertion from `InputPropertyEvaluationTests`
- Deleted `Assert.True(context.GetHasEvaluatedProperties())`, as it is unnecessary for verifying test outcomes.
* Remove redundant test cases from `WrappedInputEvaluationTests`
- Deleted `UsesDefaultValueWhenInputIsNull` and `EvaluatesExpression` tests as they are either duplicated or unnecessary for current test coverage.
* Add unit test projects for `Elsa.Workflows.Management` and `Elsa.Expressions`
- Introduced new test projects to separate and organize unit tests for `Elsa.Workflows.Management` and `Elsa.Expressions`.
- Updated `Elsa.sln` to include references to the newly added test projects.
- Adjusted namespaces in affected test classes for consistency with the updated project structure.
* Refactor `ExpressionEvaluatorTests` for clarity and consistency
- Simplified test method names and annotations for improved readability.
- Replaced duplicate mock setups with helper functions (`CreateContextAsync`, `CreateContextWithMockHandlerAsync`, and related methods).
- Streamlined test setups by removing redundant code and consolidating context creation logic.
- Updated test annotations to include descriptive `DisplayName` attributes.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Remove redundant comment from `ExpressionEvaluatorTests` for clarity
* Remove redundant blank lines from unit test classes
- Eliminated unnecessary blank lines across `ActivityExecutionContextExtensions` test suites to improve code readability and consistency.
* Add unit tests for Flowchart activity
- Introduced `FlowchartTests` to verify common Flowchart behavior, including start activity scheduling, execution without a start activity, and `UseTokenFlow` handling.
- Added `FlowchartTestHelpers` to encapsulate shared test logic.
- Updated project file to include the new `Flow` folder for organization.
* Add integration tests for Flowchart activity execution strategies
- Introduced `FlowchartCounterBasedTests` and `FlowchartTokenBasedTests` to verify different Flowchart execution strategies.
- Added `FlowchartTestHelpers` for shared test logic, including helper methods for creating various flowchart configurations and connections.
- Enhanced test coverage with scenarios for linear, parallel, and conditional flows, mixed merge modes, nested flowcharts, and token handling.
- Updated project structure to include new test classes under the `Flow` folder.
* Remove obsolete tag from `FlowJoin` activity description
* Handle both string and enum values in `GetMergeMode` for backwards compatibility
* Group flowchart integration tests into non-parallelizable test collection
- Introduced `FlowchartTestCollection` to prevent parallel execution of flowchart tests due to shared `Flowchart.UseTokenFlow` flag.
- Updated `FlowchartCounterBasedTests` and `FlowchartTokenBasedTests` to implement `IDisposable` and manage `UseTokenFlow` cleanup.
* Remove unused `Flow` folder reference from test project file
* Add `ParallelTests` for unit and integration testing with various scenarios (#6988)
- Added unit tests for `Parallel` activity to ensure proper scheduling of child activities, including empty and mixed activity cases.
- Added integration tests to validate execution flow and edge cases for `Parallel` activities (e.g., nested parallelism, fault handling).
- Enhanced `ScheduleChildrenAsync` in `Parallel` to handle no activity scenario by completing immediately.
* Fix null-check and memory declaration in `ActivityTestFixture` to prevent potential `NullReferenceException`.
* Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts (#6984)
* Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts
- Added `IWorkflowExecutionContextSchedulerStrategy` and `IActivityExecutionContextSchedulerStrategy` interfaces.
- Implemented `WorkflowExecutionContextSchedulerStrategy` and `ActivityExecutionContextSchedulerStrategy` for scheduling activities in workflows.
- Refactored scheduling logic to utilize the new scheduler strategies.
- Updated unit tests and test helpers to reflect refactoring, introducing fake implementations for testing purposes.
- Adjusted background execution scheduling and improved extensibility for custom scheduler strategies.
* Refactor `SendHttpRequestTests`: simplify scheduling assertions, use shared extensions, and standardize method naming. Streamline helper methods and remove unused test logic.
* Refactor: Replace `ActivityTestHelper` with `ActivityTestFixture` in unit tests for streamlined activity testing
- Introduced `ActivityTestFixture` with a fluent API for better test setup and execution of activities.
- Added extension methods `ActivityTestFixtureExtensions` and `ActivityTestFixtureHttpExtensions` for configuring attributes and HTTP services.
- Updated test guidelines and unit tests to use the new fixture and extensions.
- Removed `ActivityTestHelper`.
* Refactor: Move `ActivityTestFixture` and related extensions to shared project for reuse across test suites
- Consolidated `ActivityTestFixture`, `ActivityTestFixtureExtensions`, and `ActivityTestFixtureHttpExtensions` into `Elsa.Testing.Shared`.
- Updated namespaces and imports across unit tests to reflect new structure.
- Enhanced `AssertActivityAttributes` and added fluent configuration APIs.
- Adjusted `Directory.Packages.props` with new dependencies, including `NSubstitute` and `xunit.assert`.
* Refactor `SetVariableTests`: inline `ActivityTestFixture` initialization to simplify test setup.
* Refactor `ActivityTestFixture`: eliminate redundant field `_services`, add `UsedImplicitly` attributes, and improve service collection management
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for `ActivityExecutionContextExtensions`, detailing methods and parameters.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for scheduler strategies and their methods
- Updated `IActivityExecutionContextSchedulerStrategy` and `IWorkflowExecutionContextSchedulerStrategy` interfaces with XML summaries for methods.
- Added XML documentation to implementations (`ActivityExecutionContextSchedulerStrategy`, `WorkflowExecutionContextSchedulerStrategy`) and test fakes for clarity.
* Refactor `WriteLineTests`: consolidate duplicate test logic, simplify setup with shared helper method, and enhance readability in assertions.
* Refactor `WriteLineTests` and `SetVariableTests`: replace `WriteLineAsync` assertions with synchronous `WriteLine`, streamline exception recording in `SetVariableTests`, and remove unused imports.
* Add `ParallelTests` for unit and integration testing with various scenarios (#6988)
- Added unit tests for `Parallel` activity to ensure proper scheduling of child activities, including empty and mixed activity cases.
- Added integration tests to validate execution flow and edge cases for `Parallel` activities (e.g., nested parallelism, fault handling).
- Enhanced `ScheduleChildrenAsync` in `Parallel` to handle no activity scenario by completing immediately.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add new unit and integration tests for activity input and expression evaluation (#6990)
* Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts
- Added `IWorkflowExecutionContextSchedulerStrategy` and `IActivityExecutionContextSchedulerStrategy` interfaces.
- Implemented `WorkflowExecutionContextSchedulerStrategy` and `ActivityExecutionContextSchedulerStrategy` for scheduling activities in workflows.
- Refactored scheduling logic to utilize the new scheduler strategies.
- Updated unit tests and test helpers to reflect refactoring, introducing fake implementations for testing purposes.
- Adjusted background execution scheduling and improved extensibility for custom scheduler strategies.
* Refactor `SendHttpRequestTests`: simplify scheduling assertions, use shared extensions, and standardize method naming. Streamline helper methods and remove unused test logic.
* Refactor: Replace `ActivityTestHelper` with `ActivityTestFixture` in unit tests for streamlined activity testing
- Introduced `ActivityTestFixture` with a fluent API for better test setup and execution of activities.
- Added extension methods `ActivityTestFixtureExtensions` and `ActivityTestFixtureHttpExtensions` for configuring attributes and HTTP services.
- Updated test guidelines and unit tests to use the new fixture and extensions.
- Removed `ActivityTestHelper`.
* Refactor: Move `ActivityTestFixture` and related extensions to shared project for reuse across test suites
- Consolidated `ActivityTestFixture`, `ActivityTestFixtureExtensions`, and `ActivityTestFixtureHttpExtensions` into `Elsa.Testing.Shared`.
- Updated namespaces and imports across unit tests to reflect new structure.
- Enhanced `AssertActivityAttributes` and added fluent configuration APIs.
- Adjusted `Directory.Packages.props` with new dependencies, including `NSubstitute` and `xunit.assert`.
* Refactor `SetVariableTests`: inline `ActivityTestFixture` initialization to simplify test setup.
* Refactor `ActivityTestFixture`: eliminate redundant field `_services`, add `UsedImplicitly` attributes, and improve service collection management
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for `ActivityExecutionContextExtensions`, detailing methods and parameters.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Add XML documentation for scheduler strategies and their methods
- Updated `IActivityExecutionContextSchedulerStrategy` and `IWorkflowExecutionContextSchedulerStrategy` interfaces with XML summaries for methods.
- Added XML documentation to implementations (`ActivityExecutionContextSchedulerStrategy`, `WorkflowExecutionContextSchedulerStrategy`) and test fakes for clarity.
* Refactor `WriteLineTests`: consolidate duplicate test logic, simplify setup with shared helper method, and enhance readability in assertions.
* Refactor `WriteLineTests` and `SetVariableTests`: replace `WriteLineAsync` assertions with synchronous `WriteLine`, streamline exception recording in `SetVariableTests`, and remove unused imports.
* Add new unit and integration tests for activity input and expression evaluation
- Introduced comprehensive test suites covering activity input evaluation, expression handling, and fault scenarios.
- Added unit tests for `ExpressionDescriptorRegistry`, `ExpressionEvaluator`, and activity execution context extensions.
- Added integration tests: `CustomInputEvaluatorTests`, `InputEvaluationErrorTests`, and `InputPropertyEvaluationTests`.
- Enhanced code coverage for edge cases and async evaluation logic.
* Remove unused `RunWorkflowAsync` extension method from `RunActivityExtensions`.
* Rename `CustomInputEvaluatorTests` to `InputEvaluationTests` for consistency with naming conventions.
* Remove unused `Elsa.Workflows.Activities` import from `RunActivityExtensions`.
* Remove redundant comments from `InputEvaluationErrorTests` for clarity.
* Refactor unit tests to streamline activity and expression evaluations
- Refactored `ExecuteActivityAsync` and `ExecuteWriteLineAsync` into shared helpers for consistency and reuse across tests.
- Replaced redundant mock setups with helper methods in `ExpressionDescriptorRegistryTests`.
- Simplified test setup for expression and activity evaluation by removing unused imports and consolidating configuration logic.
- Enhanced readability by reducing duplicate code and leveraging shared utility methods.
* Refactor activity input evaluation tests
- Extracted `CreateContextAsync` helper into `EvaluationTestHelpers` for reuse across evaluation test suites.
- Replaced inline activity context setup with shared helper in `InputPropertyEvaluationTests`, `WrappedInputEvaluationTests`, and related test suites.
- Simplified test method names for clarity and consistency.
- Updated test annotations to enhance readability and align with naming conventions.
* Remove redundant test cases and unused imports
- Deleted duplicated and non-essential test cases across evaluation test suites.
- Removed unused imports to improve code cleanliness and readability.
- Streamlined variable initializations and method calls within test setups.
* Remove redundant test case from `InputEvaluationErrorTests`
- Deleted the `ContinuesEvaluationForMultipleInputs` test, as it overlaps with existing tests and does not provide additional coverage.
* Remove redundant assertion from `InputPropertyEvaluationTests`
- Deleted `Assert.True(context.GetHasEvaluatedProperties())`, as it is unnecessary for verifying test outcomes.
* Remove redundant test cases from `WrappedInputEvaluationTests`
- Deleted `UsesDefaultValueWhenInputIsNull` and `EvaluatesExpression` tests as they are either duplicated or unnecessary for current test coverage.
* Add unit test projects for `Elsa.Workflows.Management` and `Elsa.Expressions`
- Introduced new test projects to separate and organize unit tests for `Elsa.Workflows.Management` and `Elsa.Expressions`.
- Updated `Elsa.sln` to include references to the newly added test projects.
- Adjusted namespaces in affected test classes for consistency with the updated project structure.
* Refactor `ExpressionEvaluatorTests` for clarity and consistency
- Simplified test method names and annotations for improved readability.
- Replaced duplicate mock setups with helper functions (`CreateContextAsync`, `CreateContextWithMockHandlerAsync`, and related methods).
- Streamlined test setups by removing redundant code and consolidating context creation logic.
- Updated test annotations to include descriptive `DisplayName` attributes.
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Remove redundant comment from `ExpressionEvaluatorTests` for clarity
* Remove redundant blank lines from unit test classes
- Eliminated unnecessary blank lines across `ActivityExecutionContextExtensions` test suites to improve code readability and consistency.
* Update src/modules/Elsa.Expressions/Services/ExpressionEvaluator.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Expand `test-guidelines.md` with testing best practices, helper references, and example snippets
- Added detailed guidance on test project organization, updated helper documentation, and streamlined example code for activity unit testing.
- Introduced scheduler strategy information and integration test patterns for deterministic tests.
- Clarified usage of shared infrastructure like `ActivityTestFixture` and `AsyncWorkflowRunner`.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix merge issue
* Add missing `using Elsa.Expressions.Models` directive to `SetVariableTests`
* Update `SetVariableTests` and `ActivityTestFixture` to fix exception type assertion and improve test utility execution handling.
* Update `SetVariableTests` and `ActivityTestFixture` to handle null variables, fix exception type assertion, and simplify context usage.
---------
Co-authored-by: lucas.hipolito <lukhipolito@yahoo.com.br>
Co-authored-by: lukhipolito-nexxbiz <lucas.hipolito@nexxbiz.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-22 18:54:58 +00:00
|
|
|
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = start,
|
|
|
|
|
Activities = { start, branch1, branch2, noneMode },
|
|
|
|
|
Connections =
|
|
|
|
|
{
|
|
|
|
|
CreateConnection(start, branch1),
|
|
|
|
|
CreateConnection(start, branch2),
|
|
|
|
|
CreateConnection(branch1, noneMode),
|
|
|
|
|
CreateConnection(branch2, noneMode)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Contains("Start", _output.Lines);
|
|
|
|
|
Assert.Contains("Branch1", _output.Lines);
|
|
|
|
|
Assert.Contains("Branch2", _output.Lines);
|
|
|
|
|
Assert.Contains("NoneMode", _output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Handles token consumption correctly")]
|
|
|
|
|
public async Task HandlesTokenConsumption()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var middle = new WriteLine("Middle");
|
|
|
|
|
var end = new WriteLine("End");
|
|
|
|
|
|
|
|
|
|
var flowchart = CreateSimpleLinearFlowchart(start, middle, end);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
// Tokens should be consumed after each activity completes
|
|
|
|
|
Assert.Equal(3, _output.Lines.Count);
|
|
|
|
|
Assert.Equal("Start", _output.Lines.ElementAt(0));
|
|
|
|
|
Assert.Equal("Middle", _output.Lines.ElementAt(1));
|
|
|
|
|
Assert.Equal("End", _output.Lines.ElementAt(2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Handles multiple sequential converge nodes")]
|
|
|
|
|
public async Task HandlesMultipleSequentialConvergeNodes()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var a1 = new WriteLine("A1");
|
|
|
|
|
var a2 = new WriteLine("A2");
|
|
|
|
|
var converge1 = new WriteLine("Converge1");
|
|
|
|
|
converge1.SetMergeMode(MergeMode.Converge);
|
|
|
|
|
var b1 = new WriteLine("B1");
|
|
|
|
|
var b2 = new WriteLine("B2");
|
|
|
|
|
var converge2 = new WriteLine("Converge2");
|
|
|
|
|
converge2.SetMergeMode(MergeMode.Converge);
|
|
|
|
|
var end = new WriteLine("End");
|
|
|
|
|
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = start,
|
|
|
|
|
Activities = { start, a1, a2, converge1, b1, b2, converge2, end },
|
|
|
|
|
Connections =
|
|
|
|
|
{
|
|
|
|
|
CreateConnection(start, a1),
|
|
|
|
|
CreateConnection(start, a2),
|
|
|
|
|
CreateConnection(a1, converge1),
|
|
|
|
|
CreateConnection(a2, converge1),
|
|
|
|
|
CreateConnection(converge1, b1),
|
|
|
|
|
CreateConnection(converge1, b2),
|
|
|
|
|
CreateConnection(b1, converge2),
|
|
|
|
|
CreateConnection(b2, converge2),
|
|
|
|
|
CreateConnection(converge2, end)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Contains("Start", _output.Lines);
|
|
|
|
|
Assert.Contains("A1", _output.Lines);
|
|
|
|
|
Assert.Contains("A2", _output.Lines);
|
|
|
|
|
Assert.Contains("Converge1", _output.Lines);
|
|
|
|
|
Assert.Contains("B1", _output.Lines);
|
|
|
|
|
Assert.Contains("B2", _output.Lines);
|
|
|
|
|
Assert.Contains("Converge2", _output.Lines);
|
|
|
|
|
Assert.Contains("End", _output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Handles complex diamond pattern with tokens")]
|
|
|
|
|
public async Task HandlesComplexDiamondPattern()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var left1 = new WriteLine("Left1");
|
|
|
|
|
var left2 = new WriteLine("Left2");
|
|
|
|
|
var right1 = new WriteLine("Right1");
|
|
|
|
|
var right2 = new WriteLine("Right2");
|
|
|
|
|
var converge = new WriteLine("Converge");
|
|
|
|
|
converge.SetMergeMode(MergeMode.Converge);
|
|
|
|
|
var end = new WriteLine("End");
|
|
|
|
|
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = start,
|
|
|
|
|
Activities = { start, left1, left2, right1, right2, converge, end },
|
|
|
|
|
Connections =
|
|
|
|
|
{
|
|
|
|
|
CreateConnection(start, left1),
|
|
|
|
|
CreateConnection(start, right1),
|
|
|
|
|
CreateConnection(left1, left2),
|
|
|
|
|
CreateConnection(right1, right2),
|
|
|
|
|
CreateConnection(left2, converge),
|
|
|
|
|
CreateConnection(right2, converge),
|
|
|
|
|
CreateConnection(converge, end)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Contains("Start", _output.Lines);
|
|
|
|
|
Assert.Contains("Left1", _output.Lines);
|
|
|
|
|
Assert.Contains("Left2", _output.Lines);
|
|
|
|
|
Assert.Contains("Right1", _output.Lines);
|
|
|
|
|
Assert.Contains("Right2", _output.Lines);
|
|
|
|
|
Assert.Contains("Converge", _output.Lines);
|
|
|
|
|
Assert.Contains("End", _output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Executes activities in correct order for sequential flow")]
|
|
|
|
|
public async Task ExecutesInCorrectOrderForSequential()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var flowchart = CreateSimpleLinearFlowchart(
|
|
|
|
|
new WriteLine("1"),
|
|
|
|
|
new WriteLine("2"),
|
|
|
|
|
new WriteLine("3"),
|
|
|
|
|
new WriteLine("4")
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Equal(4, _output.Lines.Count);
|
|
|
|
|
Assert.Equal("1", _output.Lines.ElementAt(0));
|
|
|
|
|
Assert.Equal("2", _output.Lines.ElementAt(1));
|
|
|
|
|
Assert.Equal("3", _output.Lines.ElementAt(2));
|
|
|
|
|
Assert.Equal("4", _output.Lines.ElementAt(3));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Handles nested flowcharts with tokens")]
|
|
|
|
|
public async Task HandlesNestedFlowcharts()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var innerFlowchart = CreateSimpleLinearFlowchart(
|
|
|
|
|
new WriteLine("Inner1"),
|
|
|
|
|
new WriteLine("Inner2")
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
var outerFlowchart = CreateSimpleLinearFlowchart(
|
|
|
|
|
new WriteLine("Outer1"),
|
|
|
|
|
innerFlowchart,
|
|
|
|
|
new WriteLine("Outer2")
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, outerFlowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Contains("Outer1", _output.Lines);
|
|
|
|
|
Assert.Contains("Inner1", _output.Lines);
|
|
|
|
|
Assert.Contains("Inner2", _output.Lines);
|
|
|
|
|
Assert.Contains("Outer2", _output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Handles unconnected activities in flowchart")]
|
|
|
|
|
public async Task HandlesUnconnectedActivities()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var connected = new WriteLine("Connected");
|
|
|
|
|
var unconnected = new WriteLine("Unconnected");
|
|
|
|
|
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = connected,
|
|
|
|
|
Activities = { connected, unconnected }
|
|
|
|
|
// No connection to unconnected activity
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Single(_output.Lines);
|
|
|
|
|
Assert.Equal("Connected", _output.Lines.ElementAt(0));
|
|
|
|
|
Assert.DoesNotContain("Unconnected", _output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Handles mixed merge modes in complex flow")]
|
|
|
|
|
public async Task HandlesMixedMergeModes()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var branch1 = new WriteLine("Branch1");
|
|
|
|
|
var branch2 = new WriteLine("Branch2");
|
|
|
|
|
var stream = new WriteLine("Stream");
|
|
|
|
|
stream.SetMergeMode(MergeMode.Stream);
|
|
|
|
|
var branch3 = new WriteLine("Branch3");
|
|
|
|
|
var branch4 = new WriteLine("Branch4");
|
|
|
|
|
var converge = new WriteLine("Converge");
|
|
|
|
|
converge.SetMergeMode(MergeMode.Converge);
|
|
|
|
|
var end = new WriteLine("End");
|
|
|
|
|
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = start,
|
|
|
|
|
Activities = { start, branch1, branch2, stream, branch3, branch4, converge, end },
|
|
|
|
|
Connections =
|
|
|
|
|
{
|
|
|
|
|
CreateConnection(start, branch1),
|
|
|
|
|
CreateConnection(start, branch2),
|
|
|
|
|
CreateConnection(branch1, stream),
|
|
|
|
|
CreateConnection(branch2, stream),
|
|
|
|
|
CreateConnection(stream, branch3),
|
|
|
|
|
CreateConnection(stream, branch4),
|
|
|
|
|
CreateConnection(branch3, converge),
|
|
|
|
|
CreateConnection(branch4, converge),
|
|
|
|
|
CreateConnection(converge, end)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Contains("Start", _output.Lines);
|
|
|
|
|
Assert.Contains("Stream", _output.Lines);
|
|
|
|
|
Assert.Contains("Converge", _output.Lines);
|
|
|
|
|
Assert.Contains("End", _output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Handles converge with single inbound connection")]
|
|
|
|
|
public async Task HandlesConvergeWithSingleInbound()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var start = new WriteLine("Start");
|
|
|
|
|
var single = new WriteLine("Single");
|
|
|
|
|
single.SetMergeMode(MergeMode.Converge);
|
|
|
|
|
var end = new WriteLine("End");
|
|
|
|
|
|
|
|
|
|
var flowchart = CreateSimpleLinearFlowchart(start, single, end);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
Assert.Contains("Start", _output.Lines);
|
|
|
|
|
Assert.Contains("Single", _output.Lines);
|
|
|
|
|
Assert.Contains("End", _output.Lines);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Fact(DisplayName = "Emits and consumes tokens correctly across multiple steps")]
|
|
|
|
|
public async Task EmitsAndConsumesTokensCorrectly()
|
|
|
|
|
{
|
|
|
|
|
// Arrange
|
|
|
|
|
var step1 = new WriteLine("Step1");
|
|
|
|
|
var step2a = new WriteLine("Step2a");
|
|
|
|
|
var step2b = new WriteLine("Step2b");
|
|
|
|
|
var step3 = new WriteLine("Step3");
|
|
|
|
|
step3.SetMergeMode(MergeMode.Converge);
|
|
|
|
|
var step4 = new WriteLine("Step4");
|
|
|
|
|
|
|
|
|
|
var flowchart = new Flowchart
|
|
|
|
|
{
|
|
|
|
|
Start = step1,
|
|
|
|
|
Activities = { step1, step2a, step2b, step3, step4 },
|
|
|
|
|
Connections =
|
|
|
|
|
{
|
|
|
|
|
CreateConnection(step1, step2a),
|
|
|
|
|
CreateConnection(step1, step2b),
|
|
|
|
|
CreateConnection(step2a, step3),
|
|
|
|
|
CreateConnection(step2b, step3),
|
|
|
|
|
CreateConnection(step3, step4)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
await RunFlowchartAsync(_services, flowchart);
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
// Verify all activities executed in a valid order
|
|
|
|
|
Assert.Contains("Step1", _output.Lines);
|
|
|
|
|
Assert.Contains("Step2a", _output.Lines);
|
|
|
|
|
Assert.Contains("Step2b", _output.Lines);
|
|
|
|
|
Assert.Contains("Step3", _output.Lines);
|
|
|
|
|
Assert.Contains("Step4", _output.Lines);
|
|
|
|
|
|
|
|
|
|
// Step3 should only appear once (tokens consumed properly)
|
|
|
|
|
Assert.Single(_output.Lines, l => l == "Step3");
|
|
|
|
|
}
|
|
|
|
|
}
|