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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

BigInt support #6829

Closed
jseijas opened this issue Aug 10, 2018 · 14 comments 路 Fixed by #8382
Closed

BigInt support #6829

jseijas opened this issue Aug 10, 2018 · 14 comments 路 Fixed by #8382

Comments

@jseijas
Copy link

jseijas commented Aug 10, 2018

馃悰 Bug Report

BigInt was introduced in Node.js v10.4.0. This feature is expected to be supported by jest.
An script to test is added in this issue.

Currently the situation is:

  • BigInt(x) can be used inside Jest but is only supported by the toBeEqual function, but not by toBeGreaterThan, toBeGreaterThanOrEqual, toBeLessThan or toBeLessThanOrEqual.
    image

  • The format 123n is not supported and causes an error without executing the tests:
    image

To Reproduce

Use this script. As the format 123n is not supported and break the execution, you can comment the second test to check the other behaviours.

describe('BigInt', () => {
  test('It should accept BigInt("x") way', () => {
    const a = BigInt('123456789012345678901234567890');
    expect(typeof a).toEqual('bigint');
  });
  test('It should accept bigint in 123n format', () => {
    const a = 123456789012345678901234567890n;
    expect(typeof a).toEqual('bigint');
  });
  test('It should allow to do equal comparision', () => {
    const a = BigInt(2);
    expect(a).toEqual(BigInt(2));
  });
  test('It should allow to do greater than comparision', () => {
    const a = BigInt(2);
    expect(a).toBeGreaterThan(1);
  });
  test('It should allow to do greater than or equal comparision', () => {
    const a = BigInt(2);
    expect(a).toBeGreaterThanOrEqual(2);
  });
  test('It should allow to do less than comparision', () => {
    const a = BigInt(2);
    expect(a).toBeLessThan(3);
  });
  test('It should allow to do less than or equal comparision', () => {
    const a = BigInt(2);
    expect(a).toBeLessThanOrEqual(2);
  });
});

Expected behavior

  • Jest should accept bigints in the format 123n.
  • Functions of jest should support bigints.

Link to repl or repo (highly encouraged)

Script is already added to the issue

Run npx envinfo --preset jest

Paste the results here:

> npx envinfo --preset jest
npx: installed 1 in 2.649s

  System:
    OS: Windows 10
    CPU: x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
  Binaries:
    Yarn: 1.7.0 - C:\Program Files\node\yarn.CMD
    npm: 6.1.0 - C:\Program Files\node\npm.CMD
@nickmccurdy
Copy link
Contributor

nickmccurdy commented Aug 10, 2018

I can confirm the 123n syntax is broken on Jest 23.5.0 and Node 10.8.0, with default configuration.

@thymikee
Copy link
Collaborator

It's not a bug, it's lack of functionality... Happy to accept PR supporting BigInt properly. But actually, shouldn't this have its own matcher?
cc @mattphillips @SimenB

@nickmccurdy
Copy link
Contributor

nickmccurdy commented Aug 11, 2018

I understand the matchers would have to be updated for BigInt support, they're semantically different from Numbers.

From a syntax perspective, I don't understand why this isn't working, as the 123n syntax already works in the same version of Node. As far as I'm aware Jest runs code in a VM in Node 10 without a custom parser (using default config). Shouldn't all Node code work (ignoring VM differences, which are unrelated because this is a syntax issue)?

@SimenB
Copy link
Member

SimenB commented Aug 11, 2018

Syntax error is babel I think, you need the syntax plugin (not the transform) or disable babel-jest in your project

@nickmccurdy
Copy link
Contributor

I tried this on a fresh install of Jest, and it happened with and without babel-jest.

@SimenB
Copy link
Member

SimenB commented Aug 12, 2018

babel-jest is loaded by default, so to disable it, add transform: {} to your configuration. Note that this means code coverage won't work, so you'll have to add the syntax plugin if you want that.

This is node 10.8.0 with no transform:

image

@SimenB
Copy link
Member

SimenB commented Aug 12, 2018

Also see babel/babel#7660

@nickmccurdy
Copy link
Contributor

Thanks, I didn't realize Babel was loaded by default. I think it would be less surprising if it didn't so Jest behaves like the current Node version as closely as possible. Or perhaps there could be different defaults in the node (off) and jsdom (on) environments.

@SimenB
Copy link
Member

SimenB commented Aug 13, 2018

It's part of the zero config experience, I don't think we want to change that. And I don't think the test environment should mess with the config oif the project, that'd be super confusing.

We could possibly add a cleaner error. We've added one when node gets a syntax error (#6275), but we could also print some helpful text if we get a syntax error from Babel ("This is a syntax error from babel, which normally menas that you're missing a syntax plugin, even though the underlying version of node might support your syntax. blablabla Jest always uses babel for mocking and code coverage, blablabla"). Something like that?

@nickmccurdy
Copy link
Contributor

If we're going to bundle Babel anyway, could we enable all syntax plugins? Or at least whatever's in babel-preset-env?

@SimenB
Copy link
Member

SimenB commented Aug 13, 2018

Again, see babel/babel#7660

@MattMorgis
Copy link
Contributor

I understand this is hoping to get fixed upstream in babel/babel#7660, but I think an error message like @SimenB mentioned above would be helpful. I can try to poke around and submit a PR.

I was testing a pure Node 10 project using async iterators. I was super confused when Jest couldn't run tests but Mocha had no problems until I found this issue, and the fix.

@rickhanlonii
Copy link
Member

+1 on a better error message if you want to submit the PR @MattMorgis

@ddziara
Copy link

ddziara commented Jun 22, 2021

There is a problem with BigInt but it seems to disappear when "actual" property is removed from object returned by a custom matcher.

const {diff} = require('jest-diff');
expect.extend({
toEqualBigInt(received, expected) {
const options = {
comment: 'Object.is equality',
isNot: this.isNot,
promise: this.promise,
};

const pass = Object.is(received, expected);

const message = pass
  ? () =>
      this.utils.matcherHint('toEqualBigInt', undefined, undefined, options) +
      '\n\n' +
      `Expected: not ${this.utils.printExpected(expected)}\n` +
      `Received: ${this.utils.printReceived(received)}`
  : () => {
      const diffString = diff(expected, received, {
        expand: this.expand,
      });
      return (
        this.utils.matcherHint('toEqualBigInt', undefined, undefined, options) +
        '\n\n' +
        (diffString && diffString.includes('- Expect')
          ? `Difference:\n\n${diffString}`
          : `Expected: ${this.utils.printExpected(expected)}\n` +
            `Received: ${this.utils.printReceived(received)}`)
      );
    };

                   // removing this helps
                   //     V  
return {/*actual: received,*/ message, pass};

},
});

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

Successfully merging a pull request may close this issue.

7 participants