Skip to content

Conversation

edilson258
Copy link
Contributor

assert.deepStrictEqual now differentiates {} from Object.create(null)

This PR updates the object comparison logic to throw when comparing a plain object ({}) with an object created via Object.create(null), matching Node.js behavior.

Closes #27565

@edilson258
Copy link
Contributor Author

edilson258 commented May 24, 2025

There are some tests failing because they expect the old behavior where deepStrictEqual({}, Object.create(null)) is true, like:

t.assert.deepStrictEqual(
db.prepare('BEGIN').run(),
{ changes: 0, lastInsertRowid: 0 },
);
t.assert.deepStrictEqual(
db.prepare('INSERT INTO data (key) VALUES (100)').run(),
{ changes: 1, lastInsertRowid: 100 },
);
t.assert.deepStrictEqual(
db.prepare('COMMIT').run(),
{ changes: 1, lastInsertRowid: 100 },
);

All the above assertions now fails because db.prepare('BEGIN').run() returns an object whose prototype is null __proto__: null, whereas the expected object { changes: 0, lastInsertRowid: 0 } has the default Object.prototype. Since assert.deepStrictEqual NOW checks both property values and the prototype chain, the difference in prototypes causes the assertion to fail.

I think that setting __proto__: null in the expected object is the best solution because it ensures that the object has no prototype and is an approach that is already being used in similar cases, like:

t.assert.deepStrictEqual(
db.prepare('SELECT * FROM data').all(),
[{ __proto__: null, key: 100 }],
);

There are lots of assertions in the code base that rely on that old behavior, this patch will touch lots of files in the source tree.

Is that proposed change acceptable?

@kt3k
@bartlomieju

@kt3k
Copy link
Member

kt3k commented May 26, 2025

@edilson258 Thanks for the PR. The maintainers will work on the fixes for the existing test cases (they should be passing as is). Please wait for a moment.

@bartlomieju
Copy link
Member

bartlomieju commented Jun 2, 2025

Note to self (and the team):

Copy link
Member

@kt3k kt3k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Note: The fix is indirectly tested by the above compat cases

@kt3k kt3k merged commit 6bb3f6f into denoland:main Jun 4, 2025
18 checks passed
@edilson258
Copy link
Contributor Author

Thanks!

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

Successfully merging this pull request may close these issues.

ext/node: assert.deepStrictEqual({}, Object.create(null)) should throw
3 participants