AssertEqualsCanonicalizing sorting doesn't work well with null values
| Q | A |
|---|---|
| PHPUnit version | 9.5.9 |
| PHP version | 8.0.12 |
| Installation Method | Composer / PHAR |
Summary
I'm trying to test whether two arrays are equal, except for the order, which doesn't matter. I've always learned that assertEqualsCanonicalizing() is the go-to method for this use case, because it does sorting etc.
I'm trying to compare two arrays, but it looks like assertEqualsCanonicalizing applies a different sorting mechanism on the $expected and $output arrays.
Current behavior
I'm trying to compare two relatively simple arrays:

You can immediately see that those arrays are the same. However, when I do assertEqualsCanonicalizing, it gives this result:
It looks like it adds the null value at the original position in the expected array, whilst putting it on top in the second array.
Shouldn't the sorting be the same for both the expected and the output?
How to reproduce
$input = [
'object' => 'user',
'id' => 'ID',
'type' => 'bot',
'bot' => [],
'name' => null,
'avatar_url' => 'https://secure.notion-static.com/BOT',
];
$output = [
'object' => 'user',
'id' => 'ID',
'type' => 'bot',
'name' => null,
'bot' => [],
'avatar_url' => 'https://secure.notion-static.com/BOT',
];
$this->assertEqualsCanonicalizing($input, $output);
Expected behavior
AssertEqualsCanonicalizing() asserts true.
@sebastianbergmann I think this is actually a bug as assertEqualsCanonicalizing() doesn't really apply the sorting correctly:
$expected = [
'typeFloat' => 3.0,
'typeString' => 'foo bar',
'data' => 'foobar',
'typeInt' => 42,
'typeBool' => true,
];
$given = [
'data' => 'foobar',
'typeBool' => true,
'typeFloat' => 3.0,
'typeInt' => 42,
'typeString' => 'foo bar',
];
$expectedSorted = $expected;
$givenSorted = $expected;
\ksort($expectedSorted);
\ksort($givenSorted);
var_dump($expectedSorted === $givenSorted); //bool(true)
$this->assertEqualsCanonicalizing($expected, $given);