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

Vitest considers -0 and +0 to be different values #7667

Open
6 tasks done
psychedelicious opened this issue Mar 13, 2025 · 4 comments
Open
6 tasks done

Vitest considers -0 and +0 to be different values #7667

psychedelicious opened this issue Mar 13, 2025 · 4 comments

Comments

@psychedelicious
Copy link

Describe the bug

I have a utility that may return -0.

This is technically a distinct value from +0, but per IEEE_754, "negative zero" and "positive zero" should be considered to be equal in numerical comparisons.

But vitest's .toBe() and .toEqual() methods appears to not consider them to be equal, causing unit tests to fail.

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-dgy7dtwc?file=test%2Fbasic.test.ts

System Info

The issue is reproduced in StackBlitz above, but here is my system info.

  System:
    OS: Linux 6.8 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish)
    CPU: (20) x64 13th Gen Intel(R) Core(TM) i5-13600K
    Memory: 19.04 GB / 31.12 GB
    Container: Yes
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 20.13.1 - ~/.nvm/versions/node/v20.13.1/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v20.13.1/bin/yarn
    npm: 10.5.2 - ~/.nvm/versions/node/v20.13.1/bin/npm
    pnpm: 8.15.9 - ~/.nvm/versions/node/v20.13.1/bin/pnpm
  npmPackages:
    @vitejs/plugin-react-swc: ^3.8.0 => 3.8.0 
    @vitest/coverage-v8: ^3.0.6 => 3.0.6 
    @vitest/ui: ^3.0.6 => 3.0.6 
    vite: ^6.1.0 => 6.1.0 
    vitest: ^3.0.6 => 3.0.6

Used Package Manager

pnpm

Validations

@psychedelicious
Copy link
Author

Digging into vitest's codebase, the root cause is clear:

I think .toBe() kinda makes sense to fail here, because -0 truly is not +0. But I think toEqual() should pass.

@hi-ogawa
Copy link
Contributor

I'm not sure if it's obvious to say which is right 🤔
I'd assume Jest's equality has same behavior. On node, equal/deepEqual passes since it uses ==, while strictEqual/strictDeepEqual fails since it uses Object.is. https://nodejs.org/docs/v22.14.0/api/assert.html#assertdeepequalactual-expected-message

> assert.equal(+0, -0)
undefined
> assert.strictEqual(+0, -0)
Uncaught AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected

+ 0
- -0

Quick workaround would be to use custom equality tester like this https://stackblitz.com/edit/vitest-dev-vitest-firxqjfs?file=test%2Fbasic.test.ts

expect.addEqualityTesters([
  function (a, b) {
    if (typeof a === 'number' && typeof b === 'number') {
      return a === b;
    }
  },
]);

@psychedelicious
Copy link
Author

Thanks! Adding a custom equality tester is a good solution for my use case.

I noticed a code comment saying the .toEqual() logic was copied from underscore. I suspect the existing behaviour is ubiquitous and am therefore wary of changing it, even if it feels wrong. Who knows what implicitly relies on it.

I'm happy to close this issue if y'all prefer to leave the logic as-is.

@pengooseDev
Copy link
Contributor

If this issue needs to be resolved, we can refer to the issue #5744 and PR for handling -0 and -NaN in the View.

Docs Ref

IEEE 754

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants