-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
assertSame ignoring key order #6088
Comments
I've been working with JSON api stuff for years and always required this (I wanted the /**
* Asserts that the non-array values of the arrays are the same
* (using assertSame) but the order of keys within the arrays
* does not matter.
*
* Implementation detail:
* - uses SORT_NATURAL for sorting keys so that the order for keys like
* 0 and "a" are defined (without it, sort will return them in order
* of 0,"a" or "a",0).
*
* Inspired by http://stackoverflow.com/a/33029270/47573
*
* @param array $aryPath Only used internally for constructing the
* assert message helping to figure out where the arrays differ.
*/
public static function assertArraySame(array $expectedAry, array $actualAry, array $aryPath = ['/']): void
{
if (['/'] === $aryPath) {
// The built-in assert has very useful diffing capability.
// By first checking whether the array "equals" we
// already established lots of tests we would
// otherwise # need to do ourselves (e.g.
// checking if no keys are missing, etc.)
Assert::assertEquals($expectedAry, $actualAry);
}
foreach ($expectedAry as $expectedKey => $expectedValue) {
$actualValue = $actualAry[$expectedKey];
$currentPath = $aryPath;
$currentPath[] = $expectedKey;
if (\is_object($expectedValue) && \is_object($actualValue)) {
Assert::assertEquals($expectedValue, $actualValue);
continue;
}
if (\is_array($expectedValue) && \is_array($actualValue)) {
static::assertArraySame($expectedValue, $actualValue, $currentPath);
continue;
}
Assert::assertSame(
$expectedValue,
$actualValue,
'Failed asserting that values in array at ' . implode('/', $currentPath) . ' are the same.'
);
}
} |
Thanks for sharing the code. This indeed is probably not that hard to implement, but I believe it might qualify as something worth having built-in, which is why I opened the issue. |
Key order when we're talking about associative arrays is quite often irrelevant, especially when checking stuff that will end up being json serialized where dictionaries do not guarantee the key order.
Right now I'm stuck between using assertEqualsCanonicalizing and risking datatype errors, e.g.:
Or use assertSame but then key order tends to make tests extra brittle. Having an option for assertSame or a new assertDictionarySame or something would be great.
The text was updated successfully, but these errors were encountered: