According to the JSON spec outlined at json.org, an object (dictionaries) "is an unordered set of name/value pairs". PHPUnit's JSON comparsion assertions (assertJsonStringEqualsJsonString and friends) appear to enforce an ordered set.
good compare
Failed asserting that '{"a":{},"d":1,"b":[],"e":-1,"0":null,"c":"1","f":[1,2],"h":{"2":"2","1":"1","0":"0"},"g":[2,1]}' matches JSON string "{
"0": null,
"a": {},
"b": [],
"c": "1",
"d": 1,
"e": -1,
"f": [1,2],
"g": [2,1],
"h": {"0":"0","1":"1","2":"2"}
}".
--- Expected
+++ Actual
@@ @@
{
- "0": null,
"a": {},
"b": [],
- "c": "1",
"d": 1,
"e": -1,
+ "0": null,
+ "c": "1",
"f": [
1,
2
public function testJson(): void
{
$expected = <<<'JSON'
{
"0": null,
"a": {},
"b": [],
"c": "1",
"d": 1,
"e": -1,
"f": [1,2],
"g": [2,1],
"h": {"0":"0","1":"1","2":"2"}
}
JSON;
$this->assertJsonStringEqualsJsonString(
$expected,
'{"a":{},"d":1,"b":[],"e":-1,"0":null,"c":"1","f":[1,2],"h":{"2":"2","1":"1","0":"0"},"g":[2,1]}',
'good compare',
);
try {
$this->assertJsonStringEqualsJsonString(
$expected,
'{"a":{},"d":1,"b":[],"e":-1,"0":null,"c":"1","f":[2,1],"h":{"2":"2","1":"1","0":"0"},"g":[2,1]}',
'bad!',
);
$this->fail('should fail: f is transposed');
} catch (\Throwable $e) {}
try {
$this->assertJsonStringEqualsJsonString(
$expected,
'{"a":{},"d":1,"b":[],"e":-1,"0":null,"c":"1","f":[1,2],"h":[0,1,2],"g":[2,1]}',
'bad!',
);
$this->fail('should fail: h changed from obj to array (intvals)');
} catch (\Throwable $e) {}
//#4584?
try {
$this->assertJsonStringEqualsJsonString(
$expected,
'{"a":{},"d":1,"b":[],"e":-1,"0":null,"c":"1","f":[1,2],"h":["0","1","2"],"g":[2,1]}',
'bad!',
);
$this->fail('should fail: h changed from obj to array (strings)');
} catch (\Throwable $e) {}
}
Above test case passes.
Summary
According to the JSON spec outlined at json.org, an object (dictionaries) "is an unordered set of name/value pairs". PHPUnit's JSON comparsion assertions (
assertJsonStringEqualsJsonStringand friends) appear to enforce an ordered set.The internals suggest this is supposed to be handled already. I tried adding
SORT_STRINGas a flag toksorthere and it seemed to fix things, but I hardly did exhaustive testing.Somewhat related to #4584, but more in the sense that it's impossible to maintain a native PHP array that 1:1 matches certain JSON due to numeric key conversion. Getting that all correct is tragically difficult.
Current behavior
How to reproduce
Expected behavior
Above test case passes.