NaN as a special case #83

AndreasMadsen opened this Issue Jun 4, 2013 · 17 comments

6 participants


It would be nice if NaN was treaded as a special case, so the following would be OK:

t.deepEqual({ prop: NaN }, { prop: NaN });

Right now the diff says:

diff:    |
    "prop" : NaN, // != NaN

and that is just a bit odd.


Using will solve the issue.


Actually I created deep-is for that reason, but t.deepEqual behaving more like a traversing === makes sense here.
Therefore deep-equal is preferred for testing.


@thlorenz I would actually prefer to have deepEqual working with Currently I don't see a use case to have both deepIs and deepEqual, it just adds complexity.


@medikoo Never suggested to use both.
tap should stick with deep-equal since as I pointed out that is what makes most sense.
Just pointed out deep-is to be used elsewhere if a diff between NaNs is not desirable.


@thlorenz what issues do you see in deep-equal relying on


It would be inconsistent with JavaScript's definition of equal, i.e. ===.
It could also break people's tests if they depend on the current implementation.

Instead if a deep is check is desired, we should think about adding another assertion, i.e. t.deepIs.


@thlorenz I totally disagree, Real equality lies in and this what we expect when testing equality in tests, just this issue is proof for that.

I'm also pretty sure there is no test that would fail cause of that change, and even if it would, it will most likely be due to bug which that change would expose. You can only win in that case.


Ok, then we disagree, but the fact that it is called and not Object.equal is something to note.
Also deepEqual is meant to just traverse an object tree and check all objects for equality which in JavaScript means ===.

I actually proposed to @substack at one point to change deep-equal's implementation (via a PR), but he rightfully convinced me that it was not a good idea to change this implementation, but create deep-is instead.


@thlorenz JavaScript doesn't define an equality term, it's english language that does it.

There's an equality operator in JavaScript who has known quirks and doesn't provide perfect equality check, and that is done by

TAP in JavaScript member

So, you're proposing that instead of testing a === b it should be a === b || (a !== a && b !== b), is that right?

I'm ok with that.




@isaacs in that case all you'd need to do is replace deep-equal with deep-is. It also fixes +0, -0.


@isaacs should t.equal be fixed as well?


@isaacs would you consider applying this fix to node core's .equal & .deepEqual


@Raynos as far as I understand .equal is supposed to mirror the behavior of === whose specification dictates that NaN !==NaN. The same applies to .deepEqual (except nested).

So in order to not break that clear association their implementation shouldn't be changed.
Adding .is, .deepIs to tap assertions and possible the assert library may be a better choice.


I agree with @thlorenz -- I left a comment to that effect on the PR. NaN's behavior is counterintuitive and requires irritatingly specialized handling, but it is well-specified.

TAP in JavaScript member

By design, NaN is poison.

Yes, we could attempt to take the poison into ourselves, and convert it into the water of life, binding us all as one and sharing our souls and memories throughout the ages.

But are we prepared for the tests that await us as the arbiters of Desert Power?

No. We will uphold the traditions of the IEEE, and leave NaN poisonous, as it is intended.

Do not fear this. Fear is the mind killer. We must face our fear, and let is pass over and through us. When the NaN has gone, we will turn the inner eye to see it's path. When the fear has gone, not a number will remain.

@isaacs isaacs closed this Feb 12, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment