Describe the bug
Asserting calledWith ignores mismatched properties if they keys are JavaScript symbols.
To Reproduce
Steps to reproduce the behavior:
var sinon = require('sinon');
var mock = sinon.mock();
mock({
[Symbol("a")]: true
});
sinon.assert.calledWith(
mock,
{
[Symbol("a")]: false
}
);
Expected behavior
The above script should throw an AssertError because the mock was called with an object containing a true value when we were expecting a false value. It should behave similarly to this example that uses non-symbolic keys:
var sinon = require('sinon');
var mock = sinon.mock();
mock({
a: true
});
sinon.assert.calledWith(
mock,
{
a: false
}
);

Context (please complete the following information):
Additional context
I started working on a solution, but I wanted to raise an issue before opening pull requests like the contributing guide suggests to make sure I'm going down the right path. Using this change for samsam and this change for formatio, I get the behavior I expected for the script in the _To Reproduce_ section:

Because symbols are unique, this:
var sinon = require('sinon');
var mock = sinon.mock();
mock({
[Symbol("a")]: true
});
sinon.assert.calledWith(
mock,
{
[Symbol("a")]: true
}
);
will throw an AssertError (thanks @pettyalex for pointing this out):

This, however, will not throw an AssertError:
var sinon = require('sinon');
var mock = sinon.mock();
const symbol = Symbol("a");
mock({
[symbol]: true
});
sinon.assert.calledWith(
mock,
{
[symbol]: true
}
);
Unfortunately, the samsam change breaks one unit test:

This is because arguments has a property symbol called iterator:
> function test() { return Object.getOwnPropertySymbols(arguments) } test();
[ Symbol(Symbol.iterator) ]
Thank you for putting this detailed analysis and code changes together. We're definitely lacking proper Symbol support in Sinon and should do something about it.
Regarding your suggested solution, I think the fix should be slightly different: I'd say we should check the expectation for any symbol properties and only compare those to the actual. This means that additional symbol properties being added to the actual object do not break existing assertions. If we want to enforce strict matching of all symbols, then this would be a breaking change, because Sinon never looked at symbol properties before.
Any opinions or other ideas @sinonjs/sinon-core?
I like your suggestion. I'll put that solution together and open a PR for both samsam and formatio.
That's some very detailed analysis, thank you 鉂わ笍
I like the proposed solution that doesn't break existing assertions 馃憤
Resolved by https://github.com/sinonjs/samsam/pull/64
Most helpful comment
I like your suggestion. I'll put that solution together and open a PR for both samsam and formatio.