Add integration tests for enumerables with projection to arrays#7290
Add integration tests for enumerables with projection to arrays#7290sfmskywalker merged 2 commits intorelease/3.6.0from
Conversation
Introduce integration tests to verify the conversion of a Select-projected IEnumerable to an array using JavaScript execution. This includes creating new test cases, activities, and workflows to ensure the end-to-end process behaves as expected. Also refined type inference in `ExpressionExecutionContextExtensions` for projection operators.
There was a problem hiding this comment.
Pull request overview
Adds an end-to-end integration test scenario that reproduces and validates JavaScript-triggered conversion of a Select-projected IEnumerable into an array, along with a small update to the enumerable-to-array conversion heuristic in core expression execution.
Changes:
- Added a new integration test scenario (
ProjectedEnumerableToArray) with a custom activity + workflow to reproduce the projected-enumerable conversion case. - Added an integration test asserting the workflow finishes and that the projected enumerable is materialized as a
string[]. - Updated
ConvertIEnumerableToArrayto use the last generic argument when inferring the element type (to supportSelectiterators).
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/unit/Elsa.Workflows.Core.UnitTests/Extensions/ExpressionExecutionContextExtensions/ExpressionExecutionContextExtensionsTests.cs | Minor unit test refactor (target-typed new), plus new (currently unused) usings. |
| test/integration/Elsa.Workflows.IntegrationTests/Scenarios/ProjectedEnumerableToArray/TestOutputItem.cs | Adds a simple DTO used to build projected strings in the test scenario. |
| test/integration/Elsa.Workflows.IntegrationTests/Scenarios/ProjectedEnumerableToArray/TestEnumerableActivity.cs | Adds a custom activity that produces a Select iterator to reproduce the conversion issue. |
| test/integration/Elsa.Workflows.IntegrationTests/Scenarios/ProjectedEnumerableToArray/EnumerableProjectionTests.cs | Adds an integration test asserting JS-driven enumerable-to-array conversion. |
| test/integration/Elsa.Workflows.IntegrationTests/Scenarios/ProjectedEnumerableToArray/EnumerableProjectionTestWorkflow.cs | Adds a code-first workflow wiring the custom activity into RunJavaScript to trigger conversion. |
| src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs | Adjusts element type inference for enumerable-to-array conversion to handle projection iterators. |
Comments suppressed due to low confidence (2)
src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs:566
ConvertIEnumerableToArrayinfers the element type viaobj.GetType().GetGenericArguments().LastOrDefault(). This is still a brittle heuristic: for manyIEnumerable<T>implementations the enumerated element type is not the last generic argument of the concrete type (e.g., types likeLookup<TKey, TElement>enumerateIGrouping<TKey,TElement>). Consider deriving the element type from the implementedIEnumerable<T>interface instead (there is alreadyTypeExtensions.GetEnumerableElementTypeinElsa.Extensions) and only callingEnumerable.ToArray<T>when a realIEnumerable<T>element type can be determined.
// For projection operators like Select, the element type is the LAST generic argument
// (e.g., ListSelectIterator<TSource, TResult> where TResult is the element type)
var elementType = obj.GetType().GetGenericArguments().LastOrDefault();
if (elementType == null)
return obj;
var toArrayMethod = typeof(Enumerable).GetMethod("ToArray")!.MakeGenericMethod(elementType);
test/unit/Elsa.Workflows.Core.UnitTests/Extensions/ExpressionExecutionContextExtensions/ExpressionExecutionContextExtensionsTests.cs:5
- The newly added
usingdirectives appear to be unused in this test file (e.g.,Elsa.Expressions.JavaScript.Activities,Elsa.Testing.Shared,Elsa.Workflows.Activities). Consider removing them to keep the unit test file warning-free and focused.
...Workflows.IntegrationTests/Scenarios/ProjectedEnumerableToArray/EnumerableProjectionTests.cs
Show resolved
Hide resolved
Greptile OverviewGreptile SummaryThis PR fixes a bug in Key Changes:
Impact: Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs | Fixed type inference bug in ConvertIEnumerableToArray by using LastOrDefault() instead of FirstOrDefault() to correctly handle LINQ projection operators like Select |
| test/integration/Elsa.Workflows.IntegrationTests/Scenarios/ProjectedEnumerableToArray/EnumerableProjectionTests.cs | Added integration test verifying JavaScript can convert Select-projected IEnumerable variables to arrays without faulting |
| test/integration/Elsa.Workflows.IntegrationTests/Scenarios/ProjectedEnumerableToArray/TestEnumerableActivity.cs | Added test activity that produces Select-projected IEnumerable with two generic arguments to reproduce the conversion bug |
Sequence Diagram
sequenceDiagram
participant Workflow
participant TestEnumerableActivity
participant Variable as Messages Variable
participant RunJavaScript
participant ExpressionContext
participant ConvertToArray as ConvertIEnumerableToArray
Workflow->>TestEnumerableActivity: Execute activity
TestEnumerableActivity->>TestEnumerableActivity: Create items with Select projection
Note over TestEnumerableActivity: Creates ListSelectIterator<TestOutputItem, string>
TestEnumerableActivity->>Variable: Set EnumerableResult (IEnumerable)
Workflow->>RunJavaScript: Execute JavaScript
RunJavaScript->>ExpressionContext: getMessages()
ExpressionContext->>ExpressionContext: GetVariableInScope("Messages")
ExpressionContext->>ConvertToArray: Convert IEnumerable to array
Note over ConvertToArray: GetGenericArguments().LastOrDefault()<br/>Gets string (TResult) instead of TestOutputItem (TSource)
ConvertToArray->>ConvertToArray: Enumerable.ToArray<string>()
ConvertToArray->>ExpressionContext: Return string[]
ExpressionContext->>RunJavaScript: Return array
RunJavaScript->>Variable: Set Result
RunJavaScript->>Workflow: Complete
j03y-nxxbz
left a comment
There was a problem hiding this comment.
Simple effective solution. Proper testing
Introduce integration tests to verify the conversion of a Select-projected IEnumerable to an array using JavaScript execution. This includes creating new test cases, activities, and workflows to ensure the end-to-end process behaves as expected. Also refined type inference in
ExpressionExecutionContextExtensionsfor projection operators.