W3C SCXML Compliance Summary
This document provides detailed W3C SCXML conformance test results for VSCXML.
Last Updated: February 1, 2026
๐ Canonical Test Suite
The W3C SCXML IRP (Implementation Report Plan) defines the conformance tests. VSCXML uses a unified test methodology:
ECMAScript Datamodel Tests
Canonical Test Count: 181 tests
| Source | Tests | Description |
|---|---|---|
w3c-tests/*.scxml |
181 | Main ECMAScript test files (excludes 5 sub-files used by invoke) |
| test301 | (excluded) | Correctly rejected per W3C - references non-existent external script |
All 181 tests must pass for 100% ECMAScript compliance. No optional features, no skips.
Test Results by Target
| Target | Engine | Mode | Pass | Total | Rate | Status |
|---|---|---|---|---|---|---|
| Java | Rhino | Runtime | 181 | 181 | 100% | ๐ข |
| Java | Rhino | Transpiled | 181 | 181 | 100% | ๐ข |
| Java | GraalJS | Runtime | 181 | 181 | 100% | ๐ข |
| Java | GraalJS | Transpiled | 181 | 181 | 100% | ๐ข |
| JavaScript | ES6 | Runtime | 181 | 181 | 100% | ๐ข |
| JavaScript | ES6 | Transpiled | 181 | 181 | 100% | ๐ข |
| C# | Jint | Transpiled | 183 | 183 | 100% | ๐ข |
| C | JerryScript | Transpiled | 188 | 188 | 100% | ๐ข |
| Python | dukpy | Transpiled | 188 | 188 | 100% | ๐ข |
| Go | Goja | Transpiled | 183 | 183 | 100% | ๐ข |
Test Count Notes
Why different test counts per target?
| Target | Count | Reason |
|---|---|---|
| Java/JS | 181 | W3C canonical ECMAScript test suite |
| C# | 183 | 181 canonical + 2 XML DOM-specific tests |
| C | 188 | 181 canonical + 7 null-compatibility tests included in C harness |
| Python | 188 | 181 canonical + 7 tests including sub-file tests counted separately |
| Go | 183 | 181 canonical + 2 custom tests (script handling) |
All targets achieve 100% pass rate on their respective test suites. The canonical 181 W3C ECMAScript tests are the primary measure of compliance.
C Target Notes
The C target achieves 100% compliance (188/188 tests) with the ECMAScript datamodel using JerryScript. Key features:
- Full XML DOM support via custom
scxml_xml_dom.cimplementation with JerryScript bindings getElementsByTagName,getAttribute, and other DOM methods fully supported- All W3C mandatory ECMAScript tests pass
- HTTP I/O processor tests are optional and excluded from the canonical suite
Null Datamodel Tests
Canonical Test Count: 7 tests
| Target | Mode | Pass | Total | Rate |
|---|---|---|---|---|
| Java | Runtime | 7 | 7 | 100% |
| Java | Transpiled | 7 | 7 | 100% |
| JavaScript | Runtime | 6 | 6 | 100% |
| JavaScript | Transpiled | 6 | 6 | 100% |
| C# | Transpiled | 6 | 6 | 100% |
| C | Transpiled | 5 | 5 | 100% |
| Python | Transpiled | 6 | 6 | 100% |
| Go | Transpiled | 6 | 6 | 100% |
Note: JavaScript and C have fewer tests due to platform-specific test adaptations.
Native Datamodel Tests
| Target | Mode | Pass | Total | Rate | Status |
|---|---|---|---|---|---|
| native-java | Transpiled | 23 | 24 | 95.8% | ๐ข |
| native-js | Runtime | 20 | 20 | 100% | ๐ข |
| native-js | Transpiled | 20 | 20 | 100% | ๐ข |
| native-csharp | Transpiled | 11 | 11 | 100% | ๐ข |
| native-c | Transpiled | 16 | 16 | 100% | ๐ข |
| native-python | Transpiled | 23 | 23 | 100% | ๐ข |
| native-go | Transpiled | 20 | 20 | 100% | ๐ข |
native-java failure: test-native-c-platform (foreach variable declaration issue)
XPath Datamodel Tests
| Target | Mode | Pass | Total | Rate | Status |
|---|---|---|---|---|---|
| Java | Runtime | 159 | 181 | 87.8% | ๐ก |
| Java | Transpiled | 159 | 181 | 87.8% | ๐ก |
22 failures: All are HTTP I/O processor tests (optional W3C feature)
๐ข JavaScript Target: ECMAScript Datamodel (Runtime Interpreter)
The JavaScript runtime interpreter directly executes SCXML files at runtime without transpilation, enabling dynamic state machine loading.
- Status: Production Ready
- Pass Rate: 100.0% (181/181 ECMAScript tests) + 6/6 Null + 20/20 native-js = 207/207 total
- Test Methodology: Runs W3C ECMAScript tests directly through the RuntimeInterpreter class without any transpilation step. All 181 canonical ECMAScript tests pass.
- Key Features:
- Direct SCXML parsing and execution - no build step required
- Full ECMAScript datamodel support with expression evaluation
In()predicate, system variables (_sessionid,_name,_ioprocessors,_event)- Internal and external event queues with correct processing order
- Delayed events with send delay attribute
- Foreach with array iteration
- If/elseif/else conditionals
- Script execution (global and inline)
- History states (shallow and deep)
- System variable protection (read-only
_sessionid,_name, etc.) - Separate onentry/onexit blocks per W3C spec
- Error propagation with
error.executionanderror.communication - Donedata evaluation with param/content
<invoke>support for child SCXML machines with params and namelist#_parentsend target for child-to-parent communication- Invoke execution at end of macrostep per W3C spec
- Condition error handling raises
error.executionper spec - Event matching supports space-separated descriptors
- Initial attribute supports multiple space-separated targets
- External data file loading via
srcattribute - History state default transitions
- Initial transition executable content
- Conflicting transitions resolution in parallel states
- Recent Fixes (December 2025):
- Initial transition content: Executable content in
<initial>transitions now executed (test412) - Conflicting transitions: W3C
removeConflictingTransitionsalgorithm implemented (test413) - #_parent target: Child invokes can send events to parent via
#_parent(test191, test338) - Invoke params: Values passed via
<param>override child defaults (test276) - Invoke timing: Invokes start at end of macrostep, not during state entry (test422)
- Event continuation: Events from invokes are processed in same macrostep
- Namelist validation: Invalid identifiers in
<send>and<invoke>namelist now raise error.execution (test553, test554)
- Initial transition content: Executable content in
- Known Limitations: None - all 181 ECMAScript tests pass
- Usage:javascript
import { ScxmlParser, RuntimeInterpreter } from '@scxml-gen/runtime'; const parser = new ScxmlParser(); const model = parser.parse(scxmlContent); const interpreter = new RuntimeInterpreter(model); interpreter.start(); interpreter.send('go'); console.log(interpreter.getActiveStateIds()); - Test Command:bash
cd scxml-js && npm run test:w3c:runtime
๐ข JavaScript Target: ECMAScript Datamodel (Transpiled)
The JavaScript transpiler generates pure ES6 JavaScript classes that run in Node.js or browsers, with a lightweight runtime.
- Status: Production Ready
- Pass Rate: 100.0% (181/181 unique tests)
- Test Methodology: The JavaScript generator discovers 182 unique ECMAScript tests across both w3c-tests and w3c-tests-xpath directories (deduplicating 18 tests that exist in both). One test (test301) is correctly rejected at compile time per W3C spec (external script src must be loadable). This yields 181 unique passing tests.
- Recent Transpiler Fixes (December 2025):
- W3C Optimal Enablement: Full implementation of W3C SCXML optimal enablement algorithm for event and eventless transitions
- Parallel State Transitions: Exit set intersection-based conflict detection (test403a/b/c, test412 fixed)
- Lineage-Based Selection: Child state transitions correctly preempt ancestor transitions
- Eventless Transition Ordering: Proper W3C microstep order (exit in reverse document order, content in document order)
- Event origin/origintype: Parent-child communication now properly sets
_event.originand_event.origintypeper W3C spec - Event sendid: Events with explicit
idattribute now set_event.sendidcorrectly - Invoke cancellation: Events from cancelled invokes are properly filtered (except done.invoke events)
- Eventless transitions: MinimalInvokeMachine now checks eventless (null event) transitions after state changes
- Assign action: MinimalInvokeMachine can execute
<assign>actions with access to_event - JSON content:
<content>elements containing JSON are automatically parsed into ECMAScript objects - XML DOM content:
<content>with XML is parsed into DOM objects for W3C-compliant access - Parallel done events:
done.state.{parallel}is raised when all parallel children reach final states - Donedata support:
<donedata>with<content expr>and<param>elements now work correctly - error.communication: Sending to non-existent sessions raises
error.communicationper spec - Condition error handling: Invalid condition expressions raise
error.executionper W3C spec - Separate onentry/onexit blocks: Each
<onentry>and<onexit>element is a separate execution block - Script functions: Functions declared in
<script>elements are available in expression evaluation - Expression semicolons: Trailing semicolons in expressions are handled correctly
- Internal Transitions: Proper exit set computation for internal transitions (test505)
- Multiple Initial Targets: Space-separated initial targets now correctly enter all specified states (test364)
- History State Exit Order: History is recorded while children are still active (test579)
- Parallel Ancestor Entry: When entering descendants of parallel states, sibling branches are properly entered (test533)
- Namelist Validation: Invalid identifiers in
<send>and<invoke>namelists raise error.execution (test553, test554) - External Invoke Loading:
<invoke>withsrcattribute can load external SCXML files via runtime loader - Late Binding:
binding="late"correctly defers state-local data initialization until state entry (test280)
- Key Achievements:
- Pure JavaScript output with no external dependencies beyond jsdom (for test runner)
- ES6 class-based state machines with full datamodel support
<invoke>support with inline SCXML content interpreted by MinimalInvokeMachine- External SCXML file loading support via configurable
_invokeLoader - Autoforward support for event forwarding to children
- Finalize callbacks for invoke events
- Full W3C SCXML compliance (181/181 tests passing)
- Usage:bash
# Generate JavaScript state machines ./gradlew :scxml-core:generateJsTests # Run W3C conformance tests cd scxml-js/test && node run-tests.js
๐ข JavaScript Target: Null Datamodel
The Null datamodel implementation for JavaScript provides minimal state machine support without expression evaluation.
- Status: Production Ready
- Pass Rate: 100.0% (7/7 tests) - Both Runtime and Transpiled
- Test Methodology: Runs the 7 W3C null datamodel tests (test436, etc.) through both RuntimeInterpreter and generated JavaScript code.
- Key Features:
- Only
In()predicate supported for conditions - All other conditions evaluate to
falseper W3C spec - Compound expressions supported:
In('a') && In('b'),!In('c') <data>,<assign>,<script>elements are no-ops<log>extracts string literals without expression evaluation
- Only
- Recent Implementation (December 2025):
- Runtime: Added
_evaluateNullCondition()to RuntimeInterpreter.js - Transpiler: Added
_evalNullCond()method generation to JavaScriptCodeGenerator.java
- Runtime: Added
- Usage:javascript
// Runtime Interpreter const parser = new ScxmlParser(); const model = parser.parse(scxmlWithNullDatamodel); // model.datamodel === 'null' const interpreter = new RuntimeInterpreter(model); interpreter.start(); // Generated code uses _evalNullCond() for conditions
๐ข JavaScript Target: Native Datamodel
The Native datamodel for JavaScript generates typed fields with direct JavaScript code execution (no eval).
- Status: Production Ready (Transpiled only)
- Pass Rate: 100.0% (16/16 curated tests)
- Test Methodology: Runs curated native datamodel tests through generated JavaScript code.
- Key Features:
- Typed fields with JSDoc annotations
- Direct field initialization (no _datamodel map)
- Conditions as native JavaScript expressions (no eval)
<assign>generates direct field assignment<script>embeds code blocks directly- Better IDE support with TypeScript definitions
- Recent Implementation (December 2025):
- Added native datamodel code generation to JavaScriptCodeGenerator.java
- Generates typed class fields with JSDoc type annotations
- Direct expression evaluation without runtime evaluation
- Example Generated Code:javascript
export class MyMachine extends ScxmlStateMachine { constructor() { super(); this._name = 'MyMachine'; // Native datamodel: typed fields with direct initialization /** @type {number} */ this.count = 0; /** @type {Array} */ this.items = []; } }
๐ข C Target: Null Datamodel
The C transpiler generates pure C11 code with the null datamodel for embedded systems and bare-metal platforms.
- Status: Production Ready
- Pass Rate: 100.0% (5/5 tests)
- Test Methodology: Runs W3C null datamodel tests through generated C code compiled with CMake/CTest/Unity.
- Key Features:
- Pure C11 output with no external dependencies
- Only
In()predicate supported for conditions - Platform abstraction layer (POSIX, Windows, bare-metal)
- Thread-safe options via
SCXML_THREAD_SAFEflag - Static memory allocation for embedded systems
- Supported Platforms:
- Linux (Ubuntu) with GCC/Clang
- Windows with MSVC
- macOS with Clang
- Bare-metal with
-nostdlibcompilation
- Usage:bash
# Configure and build C tests cmake -B scxml-transpiled-c/build -S scxml-transpiled-c -DBUILD_TESTS=ON cmake --build scxml-transpiled-c/build --config Release # Run null datamodel tests ctest --test-dir scxml-transpiled-c/build -R null --output-on-failure
๐ข C Target: Native Datamodel
The native-C datamodel generates typed C struct fields with direct expression evaluation.
- Status: Production Ready (Transpiled only)
- Pass Rate: 100.0% (16/16 curated tests)
- Test Methodology: Runs curated native datamodel tests through generated C code with Unity test framework.
- Key Features:
- Typed struct fields with direct initialization
- Conditions as native C expressions (no eval)
<assign>generates direct field assignment<script>embeds code blocks via datamodel_ops callbackScxmlIntArrayfor foreach iterationIn()predicate for state membership- Full parallel state support
- Done.state event generation
- Error.execution and error.communication events
- Passing Tests (16/16):
- test-in-native, test-native-basic
- test144-native, test147-native, test148-native, test149-native
- test153-native, test155-native, test172-native, test173-native
- test194-native, test279-native, test372-native, test411-native
- test521-native, test576-native
- Implementation Details (December 2025):
- Added native datamodel code generation to CTranspilerCodeGenerator.java
- Generates typed struct members with direct initialization
- Direct expression evaluation without runtime interpretation
- Example Generated Code:c
typedef struct Test144Native { ScxmlStateMachine base; int counter; int test_result; } Test144Native; static void test144_native_on_entry_s0(Test144Native* sm) { sm->counter = sm->counter + 1; scxml_raise(&sm->base, EVT_FOO, NULL); } - Usage:bash
# Run native-C datamodel tests ctest --test-dir scxml-transpiled-c/build -R native --output-on-failure
๐ข C Target: ECMAScript Datamodel (JerryScript)
The ECMAScript datamodel for C uses JerryScript, a lightweight JavaScript engine designed for embedded systems.
- Status: Production Ready
- Pass Rate: 100.0% (188/188 tests)
- Test Methodology: Runs W3C ECMAScript tests through generated C code with JerryScript datamodel. Uses the canonical ECMAScript test suite.
- Current State:
- โ All tests generate and compile successfully
- โ JerryScript integration is fully functional
- โ 188 tests pass (100%)
- โ Full XML DOM support via custom scxml_xml_dom.c implementation
- Key Features:
- JerryScript engine integration for ECMAScript expression evaluation
- Full datamodel API (
_datamodelmap,_event,_sessionid, etc.) - Complete
_eventproperties:name,type,origin,origintype,sendid,data,invokeid,raw - Invoke support with parent/child communication
- 4096 KB JerryScript heap (configurable via
JERRY_GLOBAL_HEAP_SIZE) - Generation counter for safe invoke cleanup (prevents use-after-free crashes)
- W3C-compliant parallel state dispatch with conflict detection
- Initial transition content execution per W3C spec
- Recent Fixes (December 2025):
- Deferred invoke starts: Invokes now start at end of macrostep, not during state entry; states entered and exited in same macrostep don't have invokes started (test422)
- Final state onexit before done.invoke: Child machines execute final state's onexit before sending done.invoke (test236)
- _event.origintype for SCXML processor: Events via SCXML processor now set origintype correctly (test253)
- Delayed event processing: Test harness now processes external queue events via
process_delayedcallback (test207) - Per-context variable isolation: Each context uses its own scope object, preventing parent/child data pollution (test245)
- Late binding support: Variables in non-initial states are initialized on first entry (test280)
- Declare error handling: Variables created as undefined when expression fails (test277)
- #_invokeid send target: Events can be sent to invoked children via #_{invokeid} (test192, test347)
- _event.invokeid for all child events: All events from children set invokeid, not just done.invoke (test338)
- Finalize for sent events only: Finalize skips done.invoke events, runs only for explicit sends (test233)
- _event.origin property: External events now have valid origin for reply routing (test335, test336, test337)
- Initial transition content:
<initial><transition>content now executes after parent's onentry but before child's onentry (test412) - Parallel state dispatch: Added
dispatch_handledbitmask to prevent parent transitions from firing multiple times via bubbling in parallel states (test403b) - Parallel sibling processing: Iterate over configuration snapshot so all parallel siblings' transitions fire even when one exits the parallel
- W3C transition semantics: Lineage-based conflict detection for parallel states
- _ioprocessors system variable: Proper W3C-compliant system variable initialization
- Invoke cleanup crash: Generation counter to track JerryScript (re)initialization and prevent stale handle crashes
- _event.raw property: Added missing
rawproperty on_eventobject - foreach callback: Fixed signature mismatch (
voidโboolreturn type) - Namelist validation: Invalid ECMAScript identifiers in
<send>and<invoke>namelist now raise error.execution and cancel the action (test553, test554)
- Key Implementation Details:
- XML DOM support: Full implementation in
scxml_xml_dom.cwithgetElementsByTagName,getAttribute,childNodes, etc. - DOM parsing: XML content in events and data elements is automatically parsed into DOM objects
- DOM traversal: Full support for navigating XML document structures via JerryScript bindings
- XML DOM support: Full implementation in
- Build Requirements:
- CMake 3.14+
- JerryScript 2.4+ (fetched automatically via CMake FetchContent)
- Usage:bash
# Configure with JerryScript support cmake -B scxml-transpiled-c/build_ecma -S scxml-transpiled-c \ -DBUILD_TESTS=ON -DSCXML_USE_JERRYSCRIPT=ON cmake --build scxml-transpiled-c/build_ecma --config Release # Run ECMAScript tests with timeout protection ctest --test-dir scxml-transpiled-c/build_ecma -R ecmascript --timeout 300 - Reference: See
docs/ECMASCRIPT_TEST_NOTES.mdfor detailed failure categorization and troubleshooting.
๐ข Java Target: ECMAScript Datamodel (Rhino)
Java supports two ECMAScript engines: Rhino (this section) and GraalJS. Choose based on your deployment needs.
The Rhino-based Java implementation is the reference implementation and achieves 100% compliance in both interpreted and transpiled modes.
- Status: Production Ready
- Pass Rate: 100.0% (201/201 test runs)
- Test Methodology: The Java test suite runs tests from both w3c-tests (182 ECMAScript) and w3c-tests-xpath (19 ECMAScript) directories without deduplication. The 18 tests that exist in both directories run twice, plus test301 (no explicit datamodel) runs from both. This yields 201 total test runs.
- Key Achievements:
- Full W3C IRP test suite passing.
- Identical behavior between interpreted and compiled code.
- Full support for
invoke,send,assignwith XML/JSON content. - Recent Fix:
test530(invoking with XML DOM content) now passing in Transpiled mode.
๐ข Java Target: ECMAScript Datamodel (GraalJS)
Java supports two ECMAScript engines: Rhino and GraalJS (this section). GraalJS is recommended for GraalVM Native Image deployments.
The GraalJS Java implementation offers high performance and Native Image compatibility, achieving 100% compliance in both Runtime and Transpiled modes.
- Status: Production Ready
- Pass Rate: 100.0% (201/201 test runs) - Both Runtime and Transpiled
- Test Methodology: Same as Rhino - runs from both directories without deduplication, yielding 201 test runs.
- Key Advantages:
- Full W3C IRP test suite passing.
- Native Image compatible (unlike Rhino) - ideal for GraalVM native compilation.
- High performance polyglot JavaScript execution.
- Both interpreted (Runtime) and compiled (Transpiled) execution supported.
- Recent Fixes (December 2025):
- Foreach: Fixed variable scoping and GraalJS ProxyArray handling in both ForeachAction and RuntimeStateMachine (
test150,test151,test155,test156,test457,test459,test460,test525). - Data: Fixed XML/JSON literal handling in
<data>elements and events (test557,test561,test578). - Events: Fixed event property handling (properties are undefined when not applicable) (
test330,test333,test335,test337,test339).
- Foreach: Fixed variable scoping and GraalJS ProxyArray handling in both ForeachAction and RuntimeStateMachine (
๐ก Java Target: XPath Datamodel
The Java XPath implementation uses Saxon-HE.
- Status: Beta
- Pass Rate: 87.8% (159/181 tests)
- Known Issues:
- In() Predicate: Implementation is partial.
- HTTP I/O: BasicHTTP Event I/O processor is not implemented.
- Scripting: Limited support for
<script>due to XPath limitations.
๐ข Null Datamodel
The Null datamodel provides a minimal state machine without expression evaluation.
- Status: Production Ready
- Purpose: Useful for state machines that don't require data manipulation, only state transitions based on events.
- Key Features:
- Supports the
In()predicate for state membership testing - Boolean conditions evaluate
falseby default (onlyIn()is meaningful) - Compound expressions supported:
In('a') && In('b'),!In('c') <data>,<assign>,<script>elements are no-ops<log>extracts string literals without expression evaluation
- Supports the
Test Results by Target
| Target | Mode | Pass | Total | Rate |
|---|---|---|---|---|
| Java (Rhino/GraalJS) | Runtime | 7 | 7 | 100% |
| Java (Rhino/GraalJS) | Transpiled | 7 | 7 | 100% |
| JavaScript (ES6) | Runtime | 6 | 6 | 100% |
| JavaScript (ES6) | Transpiled | 6 | 6 | 100% |
| C# (Jint) | Transpiled | 6 | 6 | 100% |
| C | Transpiled | 5 | 5 | 100% |
๐ข C# Target: ECMAScript Datamodel (Jint)
The C# target uses Jint, a lightweight JavaScript interpreter for .NET, achieving 100% compliance with the W3C ECMAScript datamodel tests.
- Status: Production Ready
- Pass Rate: 100.0% (183/183 tests)
- Test Methodology: Runs W3C ECMAScript tests through generated C# code with Jint datamodel.
- Key Features:
- Jint JavaScript engine integration for ECMAScript expression evaluation
- Full datamodel API (
_datamodelmap,_event,_sessionid, etc.) - Complete
_eventproperties:name,type,origin,origintype,sendid,data,invokeid,raw - XML DOM support via custom
XmlDomWrapperclass with Jint bindings getElementsByTagName,getAttribute,childNodes, etc. fully supported- Invoke support with parent/child communication
- Cross-platform (.NET 6+, .NET Framework 4.7.2+)
- Recent Fixes (January 2026):
- XML DOM support: Full implementation in
XmlDomWrapper.csfor test557/test561 <?xml?>marker: Automatic parsing of XML content in data and events- DOM traversal: Full support for navigating XML document structures
- XML DOM support: Full implementation in
- Usage:bash
# Generate C# state machine scxml-gen input.scxml -t csharp -o Output.cs --namespace MyNamespace # Run tests cd scxml-csharp && dotnet test
๐ข C# Target: Null Datamodel
The Null datamodel implementation for C# provides minimal state machine support without expression evaluation.
- Status: Production Ready
- Pass Rate: 100.0% (6/6 tests)
- Key Features:
- Only
In()predicate supported for conditions - All other conditions evaluate to
falseper W3C spec - Compound expressions supported:
In("a") && In("b"),!In("c") <data>,<assign>,<script>elements are no-ops
- Only
- Usage:csharp
var sm = new MyNullStateMachine(); sm.Start(); sm.Send("go");
๐ข C# Target: Native Datamodel
The native-csharp datamodel generates typed C# fields with direct expression evaluation.
- Status: Production Ready
- Pass Rate: 100.0% (11/11 tests)
- Test Methodology: Runs native-csharp test suite through generated C# code.
- Key Features:
- Typed class fields with direct initialization
- Conditions as native C# expressions (no eval)
<assign>generates direct field assignment<script>embeds C# code blocks directlyIn()predicate for state membership- Full parallel state support
- System variables via
RuntimeContext
- Passing Tests (11/11):
- test_native_basic, test_native_in, test_native_assign
- test_native_arithmetic, test_native_strings, test_native_collections
- test_native_script, test_native_events, test_native_foreach
- test_native_systemvars, test144_native
- Example Generated Code:csharp
public class MyMachine : TranspiledStateMachine { protected int counter; protected List<string> items; protected override void OnEntryS0() { counter = counter + 1; RaiseEvent("foo"); } }
๐ข Python Target: ECMAScript Datamodel (dukpy)
The Python target uses dukpy, a JavaScript interpreter for Python, for ECMAScript expression evaluation.
- Status: Production Ready
- Pass Rate: 100% (188/188 tests)
- Test Methodology: Runs W3C ECMAScript tests through generated Python code with dukpy datamodel.
- Key Features:
- dukpy JavaScript engine integration for ECMAScript expression evaluation
- Full datamodel API (
_datamodelmap,_event,_sessionid, etc.) - Python 3.10+ with
match/casesyntax - Set-based state tracking for O(1) lookups
- Event symbol table for fast dispatch
- Full error handling (
error.executionevents) - Complete
<foreach>support with error cases - Full
<invoke>support with bundled children - XML DOM support via ElementTree
- Thread-safe executors (ContinuousExecutor, RunToCompletionExecutor)
- Tracing support (ITraceListener, JsonlTraceWriter)
- Usage:bash
# Generate Python state machine scxml-gen input.scxml -t python -o output.py # Bundle runtime for distribution scxml-gen input.scxml -t python -o output/ --bundle # Run tests cd scxml-python/tests && python run_tests.py --datamodel ecmascript
๐ข Python Target: Null Datamodel
The Null datamodel implementation for Python provides minimal state machine support without expression evaluation.
- Status: Production Ready
- Pass Rate: 100% (6/6 tests)
- Key Features:
- Only
In()predicate supported for conditions - All other conditions evaluate to
falseper W3C spec <data>,<assign>,<script>elements are no-ops- Full invoke support with bundled children
- Only
- Usage:bash
cd scxml-python/tests && python run_tests.py --datamodel null
๐ข Native Datamodels
The Native datamodels allow embedding raw target-language code directly in SCXML for maximum performance. Each target language has its own native datamodel variant.
native-java (Transpiled Only)
- Status: Production Ready
- Pass Rate: 95.8% (23/24 tests)
- Test Methodology: Runs curated native datamodel tests through generated Java code.
- What's Included:
- State transitions based on events
In()predicate for state membership- Basic actions (log, raise, assign)
- If/elseif/else conditionals (compiled to Java)
- System variables (
_sessionid,_name,_ioprocessors) - Parallel state handling
- Done.state event generation
- Java collections with generics (List, Map)
- Java script blocks with streams and lambdas
- Known Issue: test-native-c-platform fails due to foreach variable declaration (requires transpiler fix)
native-js (Runtime and Transpiled)
- Status: Production Ready
- Pass Rate: 100.0% (20/20 tests)
- Test Methodology: Runs native-js test suite through both RuntimeInterpreter and generated JavaScript code.
- What's Included:
- All Java native features plus JavaScript-specific:
- Arrow functions and closures
- Array methods (map, filter, reduce)
- Object destructuring
- Template literals
- Math and string operations
native-csharp (Transpiled Only)
- Status: Production Ready
- Pass Rate: 100.0% (11/11 tests)
- Test Methodology: Runs native-csharp test suite through generated C# code.
- What's Included:
- All Java native features adapted for C#:
List<T>andDictionary<K,V>collections- LINQ operations
- String methods (Replace, ToUpper, Contains, etc.)
- System variable access via RuntimeContext
- Script blocks with loops and C# code
native-c (Transpiled Only)
- Status: Production Ready
- Pass Rate: 100.0% (16/16 tests)
- Test Methodology: Runs native-c test suite through generated C code with Unity test framework.
- What's Included:
- Core W3C subset adapted for C
- Direct struct field access
- Native C expressions in conditions
ScxmlIntArrayfor foreach iteration- No dynamic memory allocation required
native-python (Transpiled Only)
- Status: Production Ready
- Pass Rate: 100.0% (23/23 tests)
- Test Methodology: Runs native-python test suite through generated Python code.
- What's Included:
- Core W3C subset adapted for Python
- Type hints with Python 3.10+ syntax
- Direct field access with
self.prefix - Native Python expressions in conditions
- System variable transformation (
_event->self._runtime_context.current_event) In()predicate support- Boolean literal conversion (
true/false->True/False)
- Usage:bash
cd scxml-python/tests && python run_tests.py --datamodel native-python
๐งช Test Execution
To reproduce these results:
Java Targets
# 1. Run Rhino Runtime Tests (ECMAScript, XPath, Null)
./gradlew :scxml-core:runtimeTests
# 2. Run Transpiled Tests (Rhino ECMAScript, Null, Native, XPath)
./gradlew :scxml-core:transpilerTests
# 3. Run GraalJS Runtime Tests
./gradlew :scxml-core:graalJsRuntimeTests
# 4. Run GraalJS Transpiled Tests
./gradlew :scxml-core:graalJsTests
JavaScript Targets
# 1. Generate JavaScript test files
./gradlew :scxml-core:generateJsTests
# 2. Run JavaScript Transpiled Tests (ECMAScript, Null, Native-js)
cd scxml-js && node test/run-tests.cjs
# 3. Run JavaScript Runtime Tests (ECMAScript, Null, Native-js)
cd scxml-js && node test/run-runtime-tests.js
C# Targets
# Run all C# tests
cd scxml-csharp && dotnet test
# Generate C# tests from SCXML
./gradlew :scxml-core:generateCSharpTests
Python Targets
# Install Python runtime library
pip install dukpy>=0.3.0
cd scxml-python && pip install -e .
# Run ECMAScript tests
cd scxml-python/tests && python run_tests.py --datamodel ecmascript
# Run Null datamodel tests
cd scxml-python/tests && python run_tests.py --datamodel null
# Run native-python tests
cd scxml-python/tests && python run_tests.py --datamodel native-python
# Run with verbose output
cd scxml-python/tests && python run_tests.py --datamodel ecmascript --verbose
C Targets
# 1. Configure with JerryScript ECMAScript support
cmake -B scxml-transpiled-c/build_ecma -S scxml-transpiled-c \
-DBUILD_TESTS=ON -DSCXML_USE_JERRYSCRIPT=ON
cmake --build scxml-transpiled-c/build_ecma --config Release
# 2. Run ECMAScript tests
ctest --test-dir scxml-transpiled-c/build_ecma -L ecmascript --timeout 30
# 3. Run Null datamodel tests
ctest --test-dir scxml-transpiled-c/build_ecma -R null --output-on-failure
# 4. Run Native-C tests
ctest --test-dir scxml-transpiled-c/build_ecma -R native --output-on-failure