elsa-core/test/integration/Elsa.JavaScript.IntegrationTests
Marko Lahma ddc95d734d
Stop attaching Array.prototype to dictionary-like objects in JavaScript expressions (#7890)
* fix(javascript): stop attaching Array.prototype to dictionary-like objects

The custom `WrapObjectDelegate` installed by `JintJavaScriptEvaluator` duplicated
what Jint already does, and got it wrong in two ways.

Jint's default wrap handler is `ObjectWrapper.Create(engine, target, type)`, and
`ObjectWrapper` attaches `Array.prototype` to array-like wrappers by itself when
`Options.Interop.AttachArrayPrototype` is enabled (the default). Jint's own
array-likeness test deliberately excludes dictionary-like types, including
string-keyed generic dictionaries.

The handler we installed instead:

* Called `ObjectWrapper.Create(engine, target)`, dropping the declared `type`
  argument, so members were resolved against the runtime type rather than the
  declared one.
* Used `ObjectArrayHelper.DetermineIfObjectIsArrayLikeClrCollection`, which only
  excludes the non-generic `IDictionary`. `ExpandoObject` does not implement
  that interface, so it came out array-like.

Both the `variables` container and the `args` container are `ExpandoObject`
instances, which meant `Object.getPrototypeOf(variables) === Array.prototype`
was true and `variables.map`, `variables.filter`, `variables.reduce` and friends
were all visible on them, with `variables.length` reporting `0` instead of
`undefined`.

Removing the handler restores Jint's default, which handles every case the
custom one was written for: `List<T>`, `T[]`, `HashSet<T>`, `ImmutableArray<T>`,
`Queue<T>` and `Stack<T>` all still get `Array.prototype`, while dictionaries and
`ExpandoObject` no longer do.

`ObjectArrayHelper` is public, so it is marked obsolete rather than deleted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

* test(javascript): cast the ExpandoObject to its dictionary interface

`new ExpandoObject() as IDictionary<string, object>` reads as a conversion that
might fail and gives the variable a nullable declared type, when `ExpandoObject`
implements the interface unconditionally. A direct cast states that, and matches
the BCL's `IDictionary<string, object?>` annotation exactly so the value type
argument lines up too.

The two other `as IDictionary<string, object>` uses in this test project
(JintJavaScriptFunctionBehaviorTests) are deliberately left alone: there the
operand is the untyped result of a script evaluation, so the `as` is a genuine
type test paired with `Assert.NotNull`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0179sA2T7HuRfRfSc2JirFik

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 03:52:37 +02:00
..
ArrayConversionTests.cs Update Jint to 4.15.3 and stop blocking the calling thread on promises (#7894) 2026-08-17 01:02:04 +02:00
CommonFunctionGlobalTests.cs Adopt the Jint 4.15 host-integration surface: lazy type globals, enum names, and register-what-is-referenced (#7895) 2026-08-17 01:44:03 +02:00
Elsa.JavaScript.IntegrationTests.csproj Add JavaScript secret functions 2026-06-01 09:26:05 +02:00
EnumConversionTests.cs Adopt the Jint 4.15 host-integration surface: lazy type globals, enum names, and register-what-is-referenced (#7895) 2026-08-17 01:44:03 +02:00
ExecutionConstraintTests.cs Bound JavaScript expression execution (#7891) 2026-08-17 01:21:19 +02:00
GuidTests.cs Refactor flowchart activity execution logic to improve modularity and add enhanced support for FlowJoin activity types. 2025-12-10 21:34:00 +01:00
JavaScriptAndNetTypeTest.cs Parse VariableTestValues more robustly, leveraging ExpandoObject and type conversion logic. (#6883) 2025-08-31 08:50:07 +02:00
JintHostContractVerification.cs Adopt the Jint 4.15 host-integration surface: lazy type globals, enum names, and register-what-is-referenced (#7895) 2026-08-17 01:44:03 +02:00
JintJavaScriptEvaluatorTests.cs Add integration tests for JavaScript function availability and behavior validation 2025-10-21 21:31:47 +02:00
JintJavaScriptFunctionBehaviorTests.cs Add DispatchWorkflow tests with new workflow definitions (#7035) 2025-11-06 20:47:20 +01:00
JsonConverterTest.cs Add integration tests for RunJavaScript activity and introduce WorkflowTestFixture 2025-10-21 20:02:27 +02:00
JsonElementConverterTests.cs Add integration tests for RunJavaScript activity and introduce WorkflowTestFixture 2025-10-21 20:02:27 +02:00
LazyTypeGlobalTests.cs Adopt the Jint 4.15 host-integration surface: lazy type globals, enum names, and register-what-is-referenced (#7895) 2026-08-17 01:44:03 +02:00
ObjectWrappingTests.cs Stop attaching Array.prototype to dictionary-like objects in JavaScript expressions (#7890) 2026-09-14 03:52:37 +02:00
ReferencedGlobalTests.cs Adopt the Jint 4.15 host-integration surface: lazy type globals, enum names, and register-what-is-referenced (#7895) 2026-08-17 01:44:03 +02:00
RunJavaScriptTests.cs Enhance WorkflowTestFixture and RunJavaScript tests with additional examples and helper methods 2025-10-21 20:36:24 +02:00
ScriptCacheTests.cs Trim per-evaluation work in the JavaScript evaluator (#7892) 2026-08-17 01:16:38 +02:00
SecretsJavaScriptTests.cs Add JavaScript secret functions 2026-06-01 09:26:05 +02:00
ToJsonTests.cs Add integration tests for RunJavaScript activity and introduce WorkflowTestFixture 2025-10-21 20:02:27 +02:00
TypeRegistrationTests.cs Adopt the Jint 4.15 host-integration surface: lazy type globals, enum names, and register-what-is-referenced (#7895) 2026-08-17 01:44:03 +02:00
VariableMarshallingTests.cs Adopt the Jint 4.15 host-integration surface: lazy type globals, enum names, and register-what-is-referenced (#7895) 2026-08-17 01:44:03 +02:00