fix(expr): Match spec behavior for identified float, string, and path differences - #305
Conversation
|
Reviewed this PR with mutation testing — all six fixes check out (each regression test fails by name when its fix is individually reverted; 8/8 mutants caught, suite/clippy/fmt green at the tip). One observation for a possible follow-up, not a blocker for this PR: (Self::String(a), Self::Path { value: b, .. })
| (Self::Path { value: b, .. }, Self::String(a)) => a == b,In the second alternative, |
4cea4dc to
cca0557
Compare
I'll look at this in a follow-up. |
Signed-off-by: Mark <399551+mwiebe@users.noreply.github.com>
Signed-off-by: Mark <399551+mwiebe@users.noreply.github.com>
Signed-off-by: Mark <399551+mwiebe@users.noreply.github.com>
Signed-off-by: Mark <399551+mwiebe@users.noreply.github.com>
Signed-off-by: Mark <399551+mwiebe@users.noreply.github.com>
Signed-off-by: Mark <399551+mwiebe@users.noreply.github.com>
Signed-off-by: Mark <399551+mwiebe@users.noreply.github.com>
cca0557 to
085c26b
Compare
Fixes: #290
What was the problem/requirement? (What/Why)
The OpenJD expression evaluator is intended to produce the same results as the
reference implementation. Differential testing found six cases where the Rust
implementation behaved differently:
a very large number by a small number.
division result had already been rounded.
1e-7instead of the canonical1e-07.on the wrong side.
\renders, to a relative pathincorrectly kept the relative path in front of it.
on the left. For example,
path("/a") < "/z"incorrectly evaluated tofalse.
These differences could change calculated parameter values, rendered text,
Windows file locations, or the ordering of values in an OpenJD expression.
What was the solution? (How)
Each behavior was corrected independently:
consistent quotient. This avoids losing useful precision or producing an
off-by-one result near a rounding boundary.
least two exponent digits.
reference implementation.
drive roots and network-share roots are still retained when present.
in which they appear in the expression. This also applies when those values are
inside lists.
The expression specification documents were updated alongside each behavior.
What is the impact of this change?
Expressions using these edge cases now produce results consistent with the
reference implementation. Most expressions are unaffected.
Users who depended on one of the incorrect results may observe a corrected
number, string, path, or comparison result. No public Rust API signatures were
changed.
How was this change tested?
changing the Rust implementation.
before the corresponding fix.
while testing floor division and a manual operand-reversal mutation for the
path/string comparison.
cargo test -p openjd-expr: 308 unit tests, 3,150 integration tests, and8 documentation tests passed.
cargo fmt --all -- --check.cargo clippy --all-features --all-targets --workspace -- -D warnings.failed locally because this machine returned the domain-unavailable error
0x8007051Finstead of the expected unknown-account error. The completeworkspace suite passed when only those two environment-dependent tests were
skipped.
Was this change documented?
Yes. The relevant behavior is documented in:
specs/expr/function-library.mdspecs/expr/path-mapping.mdspecs/expr/public-api.mdspecs/expr/values.mdNo code docstring changes were needed because the public function signatures did
not change.
Is this a breaking change?
No. This corrects behavior that differed from the documented reference behavior
and does not change the public API.
Does this change impact security?
No. It does not add privileges, external inputs, network access, or new
file/directory permission behavior. No threat model changes are needed.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.