Skip to content
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

deep.equal assetion between function? #697

Closed
chentsulin opened this issue May 4, 2016 · 2 comments
Closed

deep.equal assetion between function? #697

chentsulin opened this issue May 4, 2016 · 2 comments

Comments

@chentsulin
Copy link

When I try to use deep.equal assertion between function

expect(() => {}).to.deep.equal(() => {});

I got a AssertionError

AssertionError: expected [Function] to deeply equal [Function]
+ expected - actual

Is this a expected behavior? When not just use .toString() to compare between functions?

> (() => {}).toString()
'() => {}'
@keithamus
Copy link
Member

Hey @chentsulin thanks for the issue.

I have two points to make on this:

  1. Deep equal is designed to compare deeply not loosely, if that makes sense. In other words, it is designed to traverse the keys of an object or array (and soon iterables) and compare the values of those properties with each other. Importantly, when it gets to a value that isn't an iterable, array, or object, it actually uses a stricter-than-strict equality comparison (it uses SameValue). Functions are not iterables, they have no keys which could make a good quality comparison, and as such are given the SameValue treatment.
  2. As an extra convenience, it also compares Regular Expressions (because if their String representation then they have identical behaviours) and Dates (because if their numeric representation is identical then they are identical dates). Functions, however, are much more nuanced and possibly too difficult to compare like this. For example:
// Are these the same?
const foo = (x) => x;
const bar = (x) => { return x };
function baz(x) { return x }

// They have the same behaviours but different string representations
foo.toString() === 'function (x) => x'
bar.toString() === 'function (x) => { return x }'
baz.toString() === 'function baz(x) { return x }'

// Are these the same?
const foo = (x) => {
  // foo
  return x;
}
const bar = (x) => {
  // bar
  return x;
}

// They also are identical in behaviour, but return different strings:
foo.toString() === '(x) => {\n  // foo\n  return x;\n}';
bar.toString() === '(x) => {''n  // bar\n  return x;\n}';

Hopefully this illustrates the minefield that would be comparing functions by source. If a function has the same source, it is likely the same reference.

However, I'm going to go on a hunch and suggest you take a look at #644 which might solve the problems you're having in your tests. We will eventually have a matcher API whereby you can make loose assertions inside deep.equal, including on functions.

I'll close this issue - because I'm pretty sure you want #644. If not, then I think realistically we won't support loose equality on functions because of the above 2 points. Feel free to continue the discussion here, or in #644 if you have ideas there.

@jlabonski
Copy link

jlabonski commented Jun 4, 2017

This just had me waste two days on failing tests. This should be explicitly called out on the docs, it's easy to slide right past the implications. :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants