W-23530974: Add TCK conformance harness for the Node.js binding#135
Merged
Conversation
First of three commits for the Group C conformance harness. Pure, dwlib-free logic that lands in the unit lane; the suite sourcing + driver and CI wiring follow in later commits. - tests/tck/formats.ts: extension ↔ MIME mapping limited to the formats this dwlib compiles in (json, xml, csv, txt, dw, octet-stream, properties, urlencoded, multipart). YAML is not compiled in, so yaml/yml cases are treated as unsupported. - tests/tck/case-loader.ts: parseCase() turns a case directory's file listing into runnable scenarios or a skip decision, mirroring the CLI's structural filters (single transform.dwl, no *-config.properties, no groovy/java, no bare config.properties, no _wip) and dropping unsupported-format scenarios. - tests/tck/compare.ts: compareOutput() does extension-dispatched semantic comparison ported from AssertionHelper — structural JSON deep-equal, whitespace-collapsed XML, EOL-normalized csv/txt/yaml, all-whitespace-stripped dwl, exact bytes for bin. Not naive byte equality. - 33 unit tests (tck-case-loader.test.ts, tck-compare.test.ts). Unit lane: 70 -> 103 tests passing. tsc clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Second commit for Group C: source the conformance corpus and run it. - native-lib/build.gradle: stageTckSuites task downloads the runtime and core-modules :test@zip artifacts at the pinned weaveTestSuiteVersion and unzips each into node/tests/tck/suites/<suite>/ (gitignored). Not wired into nodeTest (PR builds); invoked on demand and by master CI. - tests/tck/transform.ts: ensureOutputDirective() appends an output directive matching the expected file's format when the header lacks one (bare-body and headered transforms both handled). do-block headers and transforms that pin a conflicting output are out of scope for text rewriting and are skipped. - tests/tck/compare.ts: XML comparison upgraded from whitespace-strip to a structural compare via fast-xml-parser — ignores attribute quote style, self-closing vs explicit-close tags, and xmlns declaration placement. This recovered ~52 XML cases that the naive string compare mis-flagged. Adds the fast-xml-parser devDependency. - tests/tck/tck.test.ts: driver — discovers cases across staged suites, parses, normalizes, runs via run(), compares. Skips ignore-listed cases with reasons; no-ops (describe.skip) when the corpus is not staged so source-only runs pass. - tests/tck/ignore-list.ts: empirically-seeded skips grouped by root cause (unresolved-module, java, do-block, output-directive-mismatch, dwl-output-format, multipart, nondeterministic, coercion/runtime, residual xml), overlapping the CLI's ignoreTests(). - Unit tests for transform.ts and the XML compare path. TCK lane: 640 cases pass, 77 skipped, 0 failures against the staged corpus. Unit lane: 103 -> 113. tsc clean; all lanes green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a master-gated CI step that stages the DataWeave test-suite corpus and runs the Node tck vitest project against the built package. Gated with if: github.ref == 'refs/heads/master', mirroring the native-cli regression steps, so PRs keep running only the fast unit/integration lanes while the heavier conformance replay runs post-merge. ci.yml (the weekly latest-version build) is intentionally left unchanged, as it does not run the native-cli TCK regression either. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…separator
ensureOutputDirective split the transform on the first `---` matched with
trim(), which also matched the indented `---` inside a `do { … }` block — so
the output directive was appended mid-do-block, failing with "Invalid output
directive in do block". Match only a column-0 `---` (the document body
separator); a do-block's indented `---` is left alone, and a transform whose
only `---` is inside a do-block is treated as a bare body.
- transform.ts: detect the separator with /^---\s*$/ instead of trim()==="---".
- ignore-list.ts: 10 do-block cases now run (do-1, do-block, do-overload,
csv-streaming, range-selector, etc.); the remaining try-handle-* and
private_scope_directives fail on unresolved-module and are regrouped there.
- 2 new unit tests for the column-0 vs do-block separator handling.
TCK lane: 640 -> 650 passing, 77 -> 67 skipped, 0 failures. Unit lane: 115.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…recover TCK cases ensureOutputDirective now also replaces a pinned output mime when it targets a different format family than the expected file, matching what the CLI's AST rewriter does. Previously it only appended when the header had no directive, so transforms pinning e.g. `output application/json` with an expected `out.xml` were skipped as "output-directive-mismatch". The replace is guarded to avoid corrupting directives that were already correct: it only rewrites a plain `mime/type` token whose family differs from the target, leaving `output :Type json` selectors and `multipart/*` subtypes (with their boundary= options) untouched. Verified across the full corpus: +10 recovered, 0 regressions. - formats.ts: add familyForMime() (collapses multipart/* subtypes; maps known mimes to their extension key). - transform.ts: guarded mime replacement; refreshed docs. - ignore-list.ts: drop the 10 recovered cases (recursive_mapObject, xml-root-with-text, groupby-complex, tree-filter*, bad-inline, string_interpolation_selection, overload-functions, dynamic_attribute_name); regroup the dw::Runtime cases under their real cause. - 4 new/updated transform unit tests (replace, option preservation, multipart subtype guard, :Type selector guard). TCK lane: 650 -> 660 passing, 67 -> 57 skipped, 0 failures. Unit lane: 119. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
martincousido
approved these changes
Jul 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fills the empty
tcklane with a DataWeave conformance harness for the@dataweave/nativebinding. Mirrors the CLI'sTCKCliTest: replays the runtime's own test corpus against the binding, in-process viarun().Structured as five commits: harness core → sourcing + driver → CI wiring → do-block separator fix → guarded output-directive replace.
Changes
tests/tck/formats.ts— extension ↔ MIME map for formats thisdwlibcompiles in (YAML isn't, so yaml/yml cases are unsupported), plusfamilyForMime()for directive comparison.tests/tck/case-loader.ts— pureparseCase(): folder listing → scenarios or a skip decision, with the CLI's structural filters. Unit-tested.tests/tck/compare.ts— extension-dispatched semantic comparison: structural JSON, structural XML viafast-xml-parser(ignores attribute quoting, self-closing tags, andxmlnsdeclaration placement), EOL-normalized text, byte-compare for bin. Unit-tested.tests/tck/transform.ts—ensureOutputDirective()normalizes the transform's output format to the expected extension: splits on the column-0---(so an indenteddo {}separator isn't mistaken for the body split) and replaces a conflicting output mime (guarded so it won't clobberoutput :Type jsonselectors ormultipart/*subtypes). Unit-tested.tests/tck/tck.test.ts— driver: discover → parse → normalize → run → compare; skips ignore-listed cases; no-ops when the corpus isn't staged (source-only runs pass).tests/tck/ignore-list.ts— empirically-seeded skips grouped by root cause, overlapping the CLI'signoreTests().native-lib/build.gradle—stageTckSuitesdownloads the runtime + core-modules:test@zipartifacts and unzips intotests/tck/suites/(gitignored). Not innodeTest..github/workflows/main.yml— master-only TCK step, mirroring the native-cli regression gating.Testing
npm run test:unit→ 119 passed (incl. TCK core)npm run test:integration→ 35 passedtsc --noEmitcleanConformance coverage
Strengthening the directive normalizer recovered 20 cases with zero regressions:
npm run test:unit→ 119 passed (incl. TCK core)npm run test:integration→ 35 passednpm run test:tck→ 660 passed, 57 skipped, 0 failures against the staged corpustsc --noEmitcleanConformance coverage
Strengthening the directive normalizer recovered 20 cases with zero regressions:
The remaining 57 skips are environmental limits, not harness gaps: modules/Java not compiled into this
dwlib,dw::Runtimebehavior, multipart write edges, nondeterministic timestamps, and a few residual XML/DWL serialization differences — consistent with the CLI's ownignoreTests().Notes
fast-xml-parser(devDependency) — required for semantic XML comparison; a whitespace-strip compare mis-flagged ~52 XML cases.CodeGeneratorAST rewrite; the residual directive-shaped skips would need that rewriter (or arun()output-MIME override) and are left as documented skips.🤖 Generated with Claude Code