From cf644fba7a60708f401eb27897cca5512abb36cd Mon Sep 17 00:00:00 2001 From: David Leong <116610336+leongdl@users.noreply.github.com> Date: Sat, 1 Aug 2026 19:35:02 -0700 Subject: [PATCH] test: Add expected-failure WRAP_ACTIONS fixtures (parked in proposed/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spec-correct fixtures that FAIL against current reference implementations, parked in a proposed/ directory the conformance runner does not discover, so merging keeps the suite green. Each entry in proposed/README.md records the observed output, spec citation, and classification. Promote each fixture up one directory unchanged when its implementation fix lands. Companion to conformance-wrap-actions-gaps. Review: quorum-review fixes — kind-level proposed/ placement (jobs/proposed/); README corrected: the defect fails BOTH implementations (2026-08-12 sweep), the §5.2 ArgString conflict is now the stated promotion gate rather than a footnote (the fixture's own args are arguably spec-invalid until that is resolved), and the unit-level repr_py twin in the func-lib expected-failures PR is cross-referenced. Signed-off-by: David Leong <116610336+leongdl@users.noreply.github.com> --- .../WRAP_ACTIONS/jobs/proposed/README.md | 47 ++++++++++++++++ ...-escapes-newline-in-wrapped-args.test.yaml | 54 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 conformance-tests/2023-09/WRAP_ACTIONS/jobs/proposed/README.md create mode 100644 conformance-tests/2023-09/WRAP_ACTIONS/jobs/proposed/wrap-repr-py-escapes-newline-in-wrapped-args.test.yaml diff --git a/conformance-tests/2023-09/WRAP_ACTIONS/jobs/proposed/README.md b/conformance-tests/2023-09/WRAP_ACTIONS/jobs/proposed/README.md new file mode 100644 index 0000000..1c7e82e --- /dev/null +++ b/conformance-tests/2023-09/WRAP_ACTIONS/jobs/proposed/README.md @@ -0,0 +1,47 @@ +# Proposed WRAP_ACTIONS fixtures (parked) — jobs + +Fixtures in this directory are believed spec-correct but FAIL against the +current reference implementations. They are parked here so the main suite +stays green; promotion is a mechanical move up one directory +(kind-level `//proposed/` placement). The conformance +runner does not scan `proposed/` directories. + +## wrap-repr-py-escapes-newline-in-wrapped-args + +**Classification: spec conflict to resolve first; then an implementation +bug in BOTH implementations.** + +Expression Language §2.2.6 documents `repr_py` as following Python's +`repr`, with the explicit example `repr_py("hello\nworld")` → +`'hello\\nworld'`. Both reference implementations (openjd-rs AND the +Python CLI — 2026-08-12 sweep, fails on both) instead embed the newline +raw into the emitted literal, so round-tripping a multi-line `python -c` +program through `repr_py(WrappedAction.Args)` produces broken Python: + +``` +File "", line 1 + print(repr(['-c', 'import sys + ^ +SyntaxError: EOL while scanning string literal +``` + +Reproduce: run this fixture through the conformance runner, or wrap any +action whose args contain U+000A and forward with the reference +`repr_py` pattern. + +**The promotion gate is a spec decision, not just the repr_py fix:** +Template Schemas §5.2 restricts `` to characters outside the +Cc unicode category, which excludes newlines — so this fixture's own +onRun args are arguably spec-INVALID as written, and a conforming +validator could reject the template before repr_py is ever exercised. +Neither implementation enforces §5.2 today, and several merged fixtures +(plus the common multi-line `python -c` convention, which container +queue environments also rely on) depend on the acceptance. Either §5.2 +is relaxed to permit newlines (making this fixture promotable once +repr_py is fixed), or the validator rejects them (making this fixture, +and the multi-line convention suite-wide, invalid). The two cannot both +stand; resolve the spec question first. + +Unit-level twin: `EXPR/jobs/proposed/expr2.2.6--repr-py-newline-roundtrip` +(func-lib expected-failures PR) pins the same repr_py defect without the +WRAP_ACTIONS forwarding layer; this fixture adds the end-to-end path. diff --git a/conformance-tests/2023-09/WRAP_ACTIONS/jobs/proposed/wrap-repr-py-escapes-newline-in-wrapped-args.test.yaml b/conformance-tests/2023-09/WRAP_ACTIONS/jobs/proposed/wrap-repr-py-escapes-newline-in-wrapped-args.test.yaml new file mode 100644 index 0000000..0fdb2a5 --- /dev/null +++ b/conformance-tests/2023-09/WRAP_ACTIONS/jobs/proposed/wrap-repr-py-escapes-newline-in-wrapped-args.test.yaml @@ -0,0 +1,54 @@ +# PARKED — fails against openjd-rs (implementation bug); see proposed/README.md. +# +# Expression Language §2.2 (String Functions): "repr_py follows the +# behavior of Python's repr", with the worked example +# repr_py("hello\nworld") returning 'hello\\nworld' — control characters +# in the value MUST be escaped in the emitted Python literal. RFC 0008's +# reference forwarding pattern round-trips WrappedAction.Args through +# repr_py; a wrapped action whose arg carries a real newline (a multi-line +# python -c program, the suite's own portable-fixture convention) must +# survive the round-trip and run. +# +# Against openjd-rs the newline is embedded RAW into the generated Python +# source, which dies with "SyntaxError: EOL while scanning string +# literal" — the grand-child never runs. Catches a repr implementation +# that quotes but does not escape. +template: + specificationVersion: jobtemplate-2023-09 + name: WrapReprPyEscapesNewlineInWrappedArgs + steps: + - name: Step1 + script: + actions: + onRun: + command: python + args: + - "-c" + - "import sys\nprint('GRAND_CHILD_RAN')" +environments: +- specificationVersion: environment-2023-09 + extensions: + - WRAP_ACTIONS + - EXPR + environment: + name: WrapEnv + script: + actions: + onWrapEnvEnter: + command: python + args: + - "-c" + - "import subprocess,sys; sys.exit(subprocess.run([{{repr_py(WrappedAction.Command)}}]+{{repr_py(WrappedAction.Args)}}).returncode)" + onWrapTaskRun: + command: python + args: + - "-c" + - "import subprocess,sys; sys.exit(subprocess.run([{{repr_py(WrappedAction.Command)}}]+{{repr_py(WrappedAction.Args)}}).returncode)" + onWrapEnvExit: + command: python + args: + - "-c" + - "import subprocess,sys; sys.exit(subprocess.run([{{repr_py(WrappedAction.Command)}}]+{{repr_py(WrappedAction.Args)}}).returncode)" +expected: + output: + - GRAND_CHILD_RAN