phpunit icon indicating copy to clipboard operation
phpunit copied to clipboard

AssertEqualsCanonicalizing sorting doesn't work well with null values

Open ralphjsmit opened this issue 4 years ago • 1 comments

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: Schermafbeelding 2021-11-17 om 13 28 57

You can immediately see that those arrays are the same. However, when I do assertEqualsCanonicalizing, it gives this result:

Schermafbeelding 2021-11-17 om 13 29 11

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.

ralphjsmit avatar Nov 17 '21 12:11 ralphjsmit

@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);
image

kiler129 avatar Mar 09 '22 08:03 kiler129