Possibly invalid test fromRdf#tjs03
Hi,
I'm having trouble reproducing the output of https://w3c.github.io/json-ld-api/tests/fromRdf-manifest.html#tjs03 in the new version of the json-ld Rust library I'm working on. The input value is the 1.23 literal, but for some reason it is transformed into 1.23E0 in the output. I don't understand this transformation given that it's not the JCS form of 1.23 (as far as I know) and even if it was, the serialization algorithm doesn't require any canonicalization.
Hmm, this is an interesting case. I suspect the test output should instead read 1.23. Though 1.23 and 1.23E0 are equivalent in the number space, when outputting the result as JSON-LD I'd expect most implementations to output 1.23 since the type is a JSON literal and JCS is recommended but not (yet) strictly enforced by the spec.
We should probably make the test match this for that reason -- even if it's technically possible for a processor to read in 1.23, convert it to a JSON number, and then output JSON-LD with a JSON literal w/o using JCS and have JSON library/platform internals (Ruby?) perhaps produce the lexical representation of that number as 1.23E0.
I also wonder if some implementations are passing this test because comparisons of JSON are done in value space, not lexical space (or if the test results are parsed and reserialized and then compared which could also cause this to be overlooked).
cc: @davidlehn
I would assume all implementations are passing because they parse the expected JSON output before doing a compare. jsonld.js is doing that. Those fromRdf output files look like they have arbitrary whitespace and property ordering in them too. So there's no real way to strictly equal that entire serialized JSON.
The testing fromRdf section and JSON-LD Object comparison section are, in theory, what should be used: https://w3c.github.io/json-ld-api/tests/ https://w3c.github.io/json-ld-api/tests/#json-ld-object-comparison
Perhaps the language there needs to be cleared up to match the intent of the tests and what's happening in practice.
Out of curiosity, how did you find this issue?
I'm only using the JSON-LD Object comparison section to compare compact documents, but even that algorithm says "JSON values are compared using strict equality" and does not mention JCS. I'm being very careful to preserve the lexical representation of JSON numbers as much as possible for one reason: JCS is based on I-JSON a subset of JSON where numbers are limited to IEEE 754 doubles. That is an issue because actual JSON uses decimal numbers which are not all representable as IEEE 754 doubles, even very simple ones (e.g. 0.3). This means JCS is lossy.
JSON-LD itself requires the use of non IEEE 754 numbers when setting the value of the context @version entry to 1.1 (here for instance). Using JCS, this number is transformed into 1.10000000000000008882.
Out of curiosity, how did you find this issue?
The current version of my json-ld library doesn't implement the fromRdf test suite. I'm implementing it as part of the new version I'm working on. That's when I found this issue.
JSON-LD itself requires the use of non IEEE 754 numbers when setting the value of the context
@versionentry to1.1(here for instance). Using JCS, this number is transformed into1.10000000000000008882.
The sadness I feel is deep about having to use a number for a version instead of anything else. Compatibility forced our hands. Issue is sort of similar here where we figured anyone comparing 1.1 in their code would get the same value as reading 1.1 from JSON, even if those are not strictly exactly 1.1.
Out of curiosity, how did you find this issue?
The current version of my
json-ldlibrary doesn't implement thefromRdftest suite. I'm implementing it as part of the new version I'm working on. That's when I found this issue.
Ok. I meant what is your code doing to detect the issue? In jsonld.js, you get output from fromRdf, and the result of JSON.parse(expected), and deep compare their object structure. So that test suite is never going to see this issue. And I'm unclear on if it should. To see this error it seems like the test would need to serialize the test result back to JSON, use a custom parser that and the expected JSON, and do some sort of raw token comparison maybe? That's a lot to ask of every implementation.
To see this error it seems like the test would need to serialize the test result back to JSON
I'm not sure I'm following. The result of fromRdf is an expanded JSON-LD document, just like the expected value. Then I just compare them both recursively. At some point it will try to compare 1.23 and 1.23E0, and fail. I do compare the lexical representations, I don't canonicalize numbers to avoid any loss.