-
Notifications
You must be signed in to change notification settings - Fork 35
test: Add 27 EXPR expression-language conformance fixtures #160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: mainline
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| # Boundary edges for let bindings (Template Schemas §3.6, §3.6.1): | ||
| # exactly 50 bindings is the maximum and must be accepted (the 51-binding | ||
| # reject twin is 3.6--let-too-many.invalid.yaml); a 512-character | ||
| # <UserIdentifier> is the maximum length and must be accepted (the | ||
| # 513-character reject twin is parked in a proposed/ directory added by | ||
| # the separate expected-failures PR — see its README there; it is not on | ||
| # this branch); | ||
| # names may start with an underscore; and later bindings may reference | ||
| # earlier bindings in the same let block (a 10-deep forward-reference | ||
| # chain). | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| let: | ||
| - _lead = 1 | ||
| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 42 | ||
| - chain0 = _lead + 1 | ||
| - chain1 = chain0 + 1 | ||
| - chain2 = chain1 + 1 | ||
| - chain3 = chain2 + 1 | ||
| - chain4 = chain3 + 1 | ||
| - chain5 = chain4 + 1 | ||
| - chain6 = chain5 + 1 | ||
| - chain7 = chain6 + 1 | ||
| - chain8 = chain7 + 1 | ||
| - chain9 = chain8 + 1 | ||
| - pad0 = 0 | ||
| - pad1 = 1 | ||
| - pad2 = 2 | ||
| - pad3 = 3 | ||
| - pad4 = 4 | ||
| - pad5 = 5 | ||
| - pad6 = 6 | ||
| - pad7 = 7 | ||
| - pad8 = 8 | ||
| - pad9 = 9 | ||
| - pad10 = 10 | ||
| - pad11 = 11 | ||
| - pad12 = 12 | ||
| - pad13 = 13 | ||
| - pad14 = 14 | ||
| - pad15 = 15 | ||
| - pad16 = 16 | ||
| - pad17 = 17 | ||
| - pad18 = 18 | ||
| - pad19 = 19 | ||
| - pad20 = 20 | ||
| - pad21 = 21 | ||
| - pad22 = 22 | ||
| - pad23 = 23 | ||
| - pad24 = 24 | ||
| - pad25 = 25 | ||
| - pad26 = 26 | ||
| - pad27 = 27 | ||
| - pad28 = 28 | ||
| - pad29 = 29 | ||
| - pad30 = 30 | ||
| - pad31 = 31 | ||
| - pad32 = 32 | ||
| - pad33 = 33 | ||
| - pad34 = 34 | ||
| - pad35 = 35 | ||
| - pad36 = 36 | ||
| - pad37 = 37 | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - | | ||
| print(r'LEAD:{{ _lead }}') | ||
| print(r'LONG:{{ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa }}') | ||
| print(r'CHAIN:{{ chain9 }}') | ||
| print(r'PAD_LAST:{{ pad37 }}') |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: §3.6.2 table (EnvironmentScript.let excludes Task.Param.*). Nit: no accept twin exercises a valid EnvironmentScript.let, so an implementation lacking env-script let entirely also passes; consider one accept fixture. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # An <EnvironmentScript>.let binding may reference only Param.*, RawParam.*, | ||
| # Session.*, Env.File.*, Job.Name, and earlier bindings (Template Schemas | ||
| # §3.6.2). Task.Param.* is never in scope for an environment script — even | ||
| # for a stepEnvironment whose enclosing step defines the task parameter — | ||
| # so this template must be rejected. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| parameterSpace: | ||
| taskParameterDefinitions: | ||
| - name: Frame | ||
| type: INT | ||
| range: "1-5" | ||
| stepEnvironments: | ||
| - name: Setup | ||
| script: | ||
| let: | ||
| - f = Task.Param.Frame | ||
| actions: | ||
| onEnter: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - "print(r'{{ f }}')" | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - "print()" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Template Schemas §3.6.2: the accept twin of the env-script let-scope | ||
| # negatives. An <EnvironmentScript>.let may reference Param.*, RawParam.*, | ||
| # and Job.Name (plus Session.* and Env.File.* at run time) — a template | ||
| # using exactly the allowed compile-time symbols must VALIDATE. Without | ||
| # this accept fixture, an implementation lacking `let` support in | ||
| # environment scripts entirely would pass every 3.6.2--env-script-let-* | ||
| # negative for the wrong reason. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| parameterDefinitions: | ||
| - name: Prefix | ||
| type: STRING | ||
| default: run | ||
| jobEnvironments: | ||
| - name: Env1 | ||
| script: | ||
| let: | ||
| - banner = Param.Prefix + '-' + Job.Name | ||
| actions: | ||
| onEnter: | ||
| command: python | ||
| args: ["-c", "print(r'{{ banner }}')"] | ||
| steps: | ||
| - name: Step1 | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: ["-c", "print()"] |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: §3.6.2 (Session.* out of StepTemplate.let scope even nested in an expression tree). len/string are valid calls, so rejection isolates the buried symbol. Coverage nit: marginal over the bare-reference twin, kept for tree-walk validators. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # Session.WorkingDirectory is out of scope for a <StepTemplate>.let binding | ||
| # (Template Schemas §3.6.2). Here the out-of-scope symbol is nested deep in | ||
| # an expression tree rather than being the whole binding — a validator that | ||
| # only inspects top-level references in let bindings would incorrectly | ||
| # accept this. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| let: | ||
| - n = len(string(Session.WorkingDirectory)) + 1 | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - "print(r'{{ n }}')" |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: §3.6.2 (StepTemplate.let may reference only Param/RawParam/Job.Name/Step.Name/earlier bindings). Minimal single defect. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # A <StepTemplate>.let binding may reference only Param.*, RawParam.*, | ||
| # Job.Name, Step.Name, and earlier bindings (Template Schemas §3.6.2). | ||
| # Session.WorkingDirectory is a host-context symbol and must be rejected here. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| let: | ||
| - wd = Session.WorkingDirectory | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - "print(r'{{ wd }}')" |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: §3.6.2 (Task.File.* scoped to StepScript.let only). The "no Task.File support at all" wrong-reason risk is closed by this PR's own 7.3 Task.File accept fixtures. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # A <StepTemplate>.let binding may reference only Param.*, RawParam.*, | ||
| # Job.Name, Step.Name, and earlier bindings (Template Schemas §3.6.2). | ||
| # Task.File.* is only available in <StepScript>.let, so referencing an | ||
| # embedded file from the step-level let must be rejected. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| let: | ||
| - cfg = Task.File.config | ||
| script: | ||
| embeddedFiles: | ||
| - name: config | ||
| type: TEXT | ||
| data: "hello" | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - "print(r'{{ cfg }}')" |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: §3.6.2 (Task.Param.* unavailable in StepTemplate.let). parameterSpace defines Frame correctly, isolating the scope violation. The four 3.6.2 negatives cover three distinct excluded-symbol families — mainline had zero. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # A <StepTemplate>.let binding may reference only Param.*, RawParam.*, | ||
| # Job.Name, Step.Name, and earlier bindings (Template Schemas §3.6.2). | ||
| # Task.Param.* is only available in <StepScript>.let and <SimpleAction>.let, | ||
| # so referencing it from the step-level let must be rejected. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| parameterSpace: | ||
| taskParameterDefinitions: | ||
| - name: Frame | ||
| type: INT | ||
| range: "1-5" | ||
| let: | ||
| - f = Task.Param.Frame | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - "print(r'{{ f }}')" |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: §7.3.1 (Session.* not in hostRequirements scope), buried in a call. upper/string are valid, so rejection traces to the scoped symbol. Nits: filename says 7.3 while citing §7.3.1 (matches its sibling; repo mixes prefixes); marginal over the existing bare-reference negative. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Session.WorkingDirectory is not available in the submission-time host | ||
| # requirements context (Template Schemas §7.3.1). Unlike the existing bare | ||
| # "{{ Session.WorkingDirectory }}" negative, the symbol here is buried inside | ||
| # a function call — a validator that walks bare format-string references but | ||
| # not full expression trees would incorrectly accept this. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| hostRequirements: | ||
| attributes: | ||
| - name: attr.worker.os.family | ||
| anyOf: | ||
| - "{{ upper(string(Session.WorkingDirectory)) }}" | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - "print()" |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: EL §1.1.6 (no underscore adjacent to the decimal point). No alternate tokenization yields a valid parse; accept twin (valid underscores) on mainline. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # Underscores in numeric literals cannot appear adjacent to the decimal | ||
| # point (Expression Language §1.1.6). "1_.5" must be rejected as a syntax | ||
| # error. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - -c | ||
| - print(r'{{ 1_.5 }}') |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5, one nit) — spec: EL §1.1.6 (no underscore adjacent to the exponent marker). Nit: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # Underscores in numeric literals cannot appear adjacent to the exponent | ||
| # marker (Expression Language §1.1.6). "1_e10" must be rejected as a syntax | ||
| # error. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - -c | ||
| - print(r'{{ 1_e10 }}') |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: EL §1.1.6 (no trailing underscore). Invalid under every tokenization. The three underscore negatives map to three distinct spec clauses — not duplicates. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Underscores in numeric literals cannot appear at the end of a number | ||
| # (Expression Language §1.1.6). "123_" must be rejected as a syntax error. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - -c | ||
| - print(r'{{ 123_ }}') |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD-WITH-NITS — one logic check requested. Spec: EL §1.2.1 unresolved-condition rule (failing arm's error suppressed under unresolved[bool]). The assertion direction (must validate) can't over-reject, but one reviewer challenges the premise: §1.2.3's single-scalar-target coercion may make |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # When the condition of an if/else is unresolved[bool], both branches are | ||
| # evaluated; if one branch succeeds and the other fails, the failing branch's | ||
| # error is suppressed and the result takes the succeeding branch's type | ||
| # (Expression Language: Static Type Checking via Unresolved Values, | ||
| # "Conditional Expressions with Unknown Conditions"). Here upper(int) has no | ||
| # signature, so the else-arm fails to type-check — but the template must | ||
| # still VALIDATE. An eager checker that reports errors from both arms | ||
| # over-rejects. (Verified that upper(int) really is the failing arm: no | ||
| # int->string call-position coercion exists — a standalone `upper(5)` let | ||
| # binding is rejected with "No matching signature for upper(int)".) | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| parameterSpace: | ||
| taskParameterDefinitions: | ||
| - name: Frame | ||
| type: INT | ||
| range: "1-5" | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - "print(r'{{ Task.Param.Frame if Task.Param.Frame < 100 else upper(Task.Param.Frame) }}')" |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: EL §1.2.1 + e432ebe asymmetry rule (reject only when no resolved value could succeed): bool+int has no overload and no bool→int coercion exists, so every concrete value fails too — validation-time rejection is correct. Wrong-reason risk closed by the two accept twins in this PR. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # Session.HasPathMappingRules is unresolved[bool] at template parse time | ||
| # (Expression Language §1.2.1; §1.2.2 Session Symbols). Operations on | ||
| # unresolved values propagate the constraint type, so bool + int has no | ||
| # __add__ signature (§2.1.1) and openjd check must reject this template | ||
| # even though the symbol's concrete value is not yet known. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - "print(r'{{ Session.HasPathMappingRules + 1 }}')" |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — spec: EL §1.2.1 / §7.4 (valid ops on unresolved values must type-check). The anti-over-rejection direction — exactly what the unresolved trio needed. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # At template parse time (openjd check), host-context symbols like | ||
| # Task.Param.* and Session.* are unresolved[T] placeholders (Expression | ||
| # Language §1.2.1; Static Type Checking via Unresolved Values; Template | ||
| # Schemas §7.4). Valid operations on unresolved values must type-check and | ||
| # the template must validate — a checker that rejects any expression it | ||
| # cannot fully evaluate over-rejects. | ||
| specificationVersion: jobtemplate-2023-09 | ||
| extensions: | ||
| - EXPR | ||
| name: TestJob | ||
| steps: | ||
| - name: Step1 | ||
| parameterSpace: | ||
| taskParameterDefinitions: | ||
| - name: Frame | ||
| type: INT | ||
| range: "1-5" | ||
| script: | ||
| actions: | ||
| onRun: | ||
| command: python | ||
| args: | ||
| - "-c" | ||
| - | | ||
| print(r'NEXT:{{ Task.Param.Frame + 1 }}') | ||
| print(r'OUT:{{ Session.WorkingDirectory / "out" }}') | ||
| print(r'HASWD:{{ len(string(Session.WorkingDirectory)) > 0 }}') |
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quorum verdict: GOOD (5/5) — R100 rename tracking the spec renumber (§1.3.11→§1.3.12, Task Parameter Range Field Extensions); no stale in-file refs. Same for the path/string siblings. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quorum verdict: GOOD (5/5) — spec: §3.6/§3.6.1 (exactly 50 bindings, exactly 512-char identifier,
[a-z_]start, forward chains — all mechanically verified). Nit: header references../proposed/(the 513 reject twin lives on PR #164's branch, not here) — note the dependency.