Skip to content

assert.deepStrictEqual() and the vm module are incompatible #44462

@Qix-

Description

@Qix-

Version

v18.8.0

Platform

Linux DESKTOP-TBGODF1 4.4.0-19041-Microsoft #1237-Microsoft Sat Sep 11 14:32:00 PST 2021 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?

import vm from 'node:vm';
import assert from 'node:assert/strict';
const g = {exports: {}};
const result = vm.runInNewContext(`exports.result = {foo:'bar'};`, g);
assert.deepStrictEqual(g.exports.result, {foo: 'bar'});

How often does it reproduce? Is there a required condition?

No response

What is the expected behavior?

These two objects are structurally identical and have the Object prototype. The assert library should accept them as deep-equal.

What do you see instead?

Since the VM script's context creates its own Object for use in prototypes, therefore the prototype check introduced to the assert library in 02b66b5 (#24974, ref #24917) fails since they're not equal (even though they represent the same underlying 'facility' in Javascript).

This caused some confusing output:

AssertionError [ERR_ASSERTION]: Values have same structure but are not reference-equal:

{
  foo: 'bar'
}

Further, of course they're not reference equal - that would defeat the entire purpose of a deepEqual check, would it not? 🙃 I had to google to figure out it was referring to prototype checking. Perhaps the error message could be improved here?

Additional information

It'd be great if we could get a variant of the node:assert library that is 1) strict and 2) ignores prototypes for cases like this. I don't see how this could be fixed otherwise, given how v8's contexts work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    assertIssues and PRs related to the assert subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions