Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unexpected diff on assert.deepStrictEqual #51733

Closed
dev-ardi opened this issue Feb 12, 2024 · 7 comments · Fixed by #54862
Closed

unexpected diff on assert.deepStrictEqual #51733

dev-ardi opened this issue Feb 12, 2024 · 7 comments · Fixed by #54862
Labels
assert Issues and PRs related to the assert subsystem. feature request Issues that request new features to be added to Node.js.

Comments

@dev-ardi
Copy link

dev-ardi commented Feb 12, 2024

Version

v20.5.0 (tried on node 16 and 21)

Platform

([ronment]::OSVersion.VersionString) x64

What steps will reproduce the bug?

require("assert").deepStrictEqual(
  {
    common: {},
    key1: "",
    creator: "123",
  },
  {
    creator: "123",
  },
);

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

Always

What is the expected behavior? Why is that the expected behavior?

Only comon and key1 exist so

  {
+   common: {},
+   key1: ''
  }

What do you see instead?

  {
+   common: {},
+   creator: '123',
+   key1: ''
-   creator: '123'
  }

Additional information

No response

@alepefe
Copy link

alepefe commented Feb 12, 2024

It happened to me as well.

@BridgeAR BridgeAR added assert Issues and PRs related to the assert subsystem. feature request Issues that request new features to be added to Node.js. labels Feb 12, 2024
@BridgeAR
Copy link
Member

The current implementation for the diff is a quick best effort implementation and we have to change it to Myers algorithm or similar to properly detect these changes without a bad runtime.

@dev-ardi
Copy link
Author

Would a fix to this get added to node 20?

Copy link
Contributor

There has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the never-stale Mark issue so that it is never considered stale label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment.
For more information on how the project manages feature requests, please consult the feature request management document.

@github-actions github-actions bot added the stale label Aug 12, 2024
@dev-ardi
Copy link
Author

bump

@github-actions github-actions bot removed the stale label Aug 13, 2024
@puskin94
Copy link
Contributor

puskin94 commented Sep 4, 2024

After spending A LOT of time looking around and trying things, I don't think implementing any standard diff algorithm is going to be perfect for us. Why? Because we have a couple of edgecases which would deviate from any diff algorithm, ending up into something custom anyway:

  1. https://github.com/nodejs/node/blob/main/lib/internal/assert/assertion_error.js#L235
  2. https://github.com/nodejs/node/blob/main/lib/internal/assert/assertion_error.js#L155

I actually ended up implementing the myerDiff algorithm myself in the assertion_error and (with some caveat) is working fine:

image

There is a couple of problems tho:

  1. right at the beginning of the createErrDiff function, we do this:
  const actualInspected = inspectValue(actual);
  const actualLines = StringPrototypeSplit(actualInspected, '\n');
  const expectedLines = StringPrototypeSplit(inspectValue(expected), '\n');

which converts the input:

{
    common: {},
    key1: "",
    creator: "123",
  }

  {
    creator: "123",
  },

to

[ '{', '  common: {},', "  creator: '123',", "  key1: ''", '}' ]
[ '{', "  creator: '123'", '}' ]

and, if you pay enough attention, in actual (the first array), creator: '123', has a trailing comma, which is not present in the second array, that's why the diff with the already implemented diff looks the way it looks, hence the creation of this issue.

The naive solution to this problem is to do something like this:

    // Remove trailing comma from each line
  if (typeof actual === 'object' && actual !== null) {
    for (let i = 0; i < actualLines.length; i++) {
      actualLines[i] = actualLines[i].replace(/,$/, '');
    }
  }
  if (typeof expected === 'object' && expected !== null) {
    for (let i = 0; i < expectedLines.length; i++) {
      expectedLines[i] = expectedLines[i].replace(/,$/, '');
    }
  }

which is NOT ideal. The problem I am pretty sure should be resolved in the inspect function, but I am not smart enough to both fix the issue and not break anything else in the codebase.

  1. in the current implementation there is a gazillion of exceptions just for proper formatting the output: object too nested? hide part of it. Too many consecutive unchanged lines? crop some of them. The terminal is too narrow? ellipse some lines.

I am not sure the whole effort of implementing all these things into the new algorithm is worth it.

To fix the issue OP reported, we need to tweak this check: https://github.com/nodejs/node/blob/main/lib/internal/assert/assertion_error.js#L235

right now only works if expected has the trailing comma, it does not check if the actual has it.

I could make that change and it should solve the issue, without adapting the algorithm I built to cover all the edge cases.

What do you think?

@puskin94
Copy link
Contributor

puskin94 commented Sep 4, 2024

actually, I worked a lot on it today and for such an example:

const {deepStrictEqual} = require('assert');

let actual = {
  common: {},
  key1: "",
  test: {},
  creator: "123",
};

let expected = {
  creator: "123",
  test: {},
};

for (let i = 0 ; i < 55; i++) {
  actual.test[i] = i;
  expected.test[i] = i;
}

deepStrictEqual(actual, expected);

this is what I get back with the new algorithm:

image

it behaves a little bit differently than before, but it is working nice so far. I still have many broken tests I need to fix, but it is a working solution.

The main problem I am having is how to tackle point 1 of the issues I mentioned before; if you guys have any idea or suggestion, you know how to find me 😄

puskin94 added a commit to puskin94/node that referenced this issue Sep 9, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 9, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 9, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 9, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 9, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 9, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 9, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 9, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 15, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 15, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 15, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 15, 2024
puskin94 added a commit to puskin94/node that referenced this issue Sep 15, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 3, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 5, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 7, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 7, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 7, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 8, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 8, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 8, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 8, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 8, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 8, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 8, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 9, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 15, 2024
puskin94 added a commit to puskin94/node that referenced this issue Oct 15, 2024
nodejs-github-bot pushed a commit that referenced this issue Oct 17, 2024
Fixes: #51733

Co-Authored-By: Pietro Marchini <[email protected]>
PR-URL: #54862
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
aduh95 pushed a commit that referenced this issue Oct 19, 2024
Fixes: #51733

Co-Authored-By: Pietro Marchini <[email protected]>
PR-URL: #54862
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
louwers pushed a commit to louwers/node that referenced this issue Nov 2, 2024
Fixes: nodejs#51733

Co-Authored-By: Pietro Marchini <[email protected]>
PR-URL: nodejs#54862
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assert Issues and PRs related to the assert subsystem. feature request Issues that request new features to be added to Node.js.
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

4 participants