Confusing and inconsistent comparison of NaN
Author: aradzieCreated Nov 5, 2024Updated Jul 30, 2025
Consider the following example:
import { test } from "node:test";
import { assert, expect } from "chai";
test("pass", () => {
expect([NaN]).to.deep.equal([NaN]);
expect({ a: NaN }).to.deep.equal({ a: NaN });
assert.deepStrictEqual([NaN], [NaN]);
assert.deepStrictEqual({ a: NaN }, { a: NaN });
});
test("fail/expect", () => {
expect(NaN).to.equal(NaN);
});
test("fail/assert", () => {
assert.strictEqual(NaN, NaN);
});✖ fail/expect
Error [AssertionError]: expected NaN to equal NaN
✖ fail/assert
Error [AssertionError]: expected NaN to equal NaNThe comparison algorithm behaves differently depending on whether NaN values are compared directly or as deep property/member values. This inconsistency creates confusion and diminishes the developer experience.
We suggest to change the behavior of expect(...).to.equal(...) and assert.strictEqual(..., ...) to match their deep counterparts.
Source: chaijs/chai