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

TypeError while initializing in Node 19 #438

Closed
jonathanschoeller opened this issue Oct 20, 2022 · 8 comments
Closed

TypeError while initializing in Node 19 #438

jonathanschoeller opened this issue Oct 20, 2022 · 8 comments

Comments

@jonathanschoeller
Copy link

jonathanschoeller commented Oct 20, 2022

  • FakeTimers version : 9.1.2
  • Environment : node:19.0-alpine@sha256:48e43334c84762aa05c18dac37ec5ca396e9d55c5cb053f15cd4edbfe89a0914 (not reproducible in node:18.11-alpine)
  • Example URL : N/A
  • Other libraries you are using: @jest/fake-timers

What did you expect to happen?
The code below to execute without throwing an exception.

What actually happens
An exception is thrown:

TypeError: Cannot assign to read only property 'performance' of object '[object global]

at hijackMethod (node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:946:32)
at Object.install (node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1733:17)

How to reproduce
Run the following:

var FakeTimers = require("@sinonjs/fake-timers");

var clock = FakeTimers.install();
@jonathanschoeller
Copy link
Author

I appreciate that node 19 is just barely a day old and it's expected that things might not be compatible at first. 😄

@benjamingr
Copy link
Member

Hey, this looks like a pretty simple fix - would you be interested in contributing a PR?

@SimenB
Copy link
Member

SimenB commented Oct 22, 2022

I was unable to reproduce it here in @sinonjs/fake-timers, so I ended up hacking around it in Jest: https://github.com/facebook/jest/pull/13467/files#diff-7e6b39bebf54c704e027085672211430b8241b080e103d997757bcea915d2041R95-R96

Would love for it to be a fix here though, so I can revert that PR and bump the dep 🙂

@SimenB
Copy link
Member

SimenB commented Nov 11, 2022

@jonathanschoeller I'm unable to reproduce the issue with your snippet, could you verify?

@jonathanschoeller
Copy link
Author

@SimenB I can't seem to reproduce the issue now either. I must have had some other environment details I didn't record. Happy to close this off. Thanks for having a look.

@akwodkiewicz
Copy link

FYI the issue with performance being not writable is also present in Node 18 since 18.19.0.

The Jest fix for Node 19 (jestjs/jest#13467) works fine there.

@fatso83
Copy link
Contributor

fatso83 commented Feb 27, 2024

@akwodkiewicz since we are not able to reproduce this outside of Jest, would you mind telling us exactly what you did?

@akwodkiewicz
Copy link

akwodkiewicz commented Feb 27, 2024

It would be very hard, because what made me look into this issue is one of my projects had Node upgraded from 18.18.2 to 18.19.1 and some of the tests suites (run with Jest) started failing with this issue.

All of those errors looked like this

    TypeError: Cannot assign to read only property 'performance' of object '[object global]'

      462 |
      463 |         beforeEach(() => {
    > 464 |             jest.useFakeTimers();
          |                  ^
      465 |         });
      466 |
      467 |         afterEach(() => {

      at hijackMethod (../../../node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:946:32)
      at Object.install (../../../node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1733:17)
      at Object.useFakeTimers (redacted.spec.ts:464:18)

Ultimately my issue was related to unexpected package hoisting by Yarn and having outdated jest-config used for tests. 1 So the only thing I'm doing here is calling jest.useFakeTimers. Since you are not able to reproduce the error, maybe it's somehow Jest's fault that it modifies some invariants that you rely on.

I just posted my previous comment to let people know that it's not only Node 19 upwards that needs to use Jest >=29, but 18.19.x as well.

EDIT: There were also these:

TypeError: Can't install fake timers twice on the same global object.

      32 |     beforeEach(async () => {
      33 |         fixtures = await getFixtures();
    > 34 |         jest.useFakeTimers();
         |              ^
      35 |     });
      36 |
      37 |     afterEach(() => {

      at Object.install (../../../node_modules/@sinonjs/fake-timers/src/fake-timers-src.js:1642:19)
      at Object.useFakeTimers (redacted.spec.ts:34:14)
      

but I guess it's just a side-effect of having the first error, so I dismissed it.

Footnotes

  1. I knew that there's this issue with Node >=19 and Jest 28, and I am explicitly using Jest 29. But I dug deeper and found Jest 28 in my indirect dependencies. Once I removed unnecessary packages that relied on Jest 28, the issue went away.

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

No branches or pull requests

5 participants