#1653·chai

Confusing and inconsistent comparison of NaN

Author: aradzieCreated Nov 5, 2024Updated Jul 30, 2025

Consider the following example:

javascript
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 NaN

The 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.