Skip to content

Commit

Permalink
Fix Jest 28+ expect.extend is not a function error (#3559)
Browse files Browse the repository at this point in the history
## Description
Reanimated is not fully compatible with Jest 28+ even after the PR #3347. Using it with Jest 28+ leads to this error:

<img width="796" alt="Ekran Resmi 2022-09-10 15 00 33" src="https://user-images.githubusercontent.com/22980987/189482337-cc2655f6-9463-4a05-9998-5fc3592f5cc0.png">

The reason is, the "expect" module's export approach has changed starting from Jest 28. It used to export the `expect` function directly, as can be seen [here](https://github.com/facebook/jest/blob/v27.5.1/packages/expect/src/index.ts#L441). 

This means, requiring the "expect" module like this

```ts
const expect = require('expect')
```

was providing direct access to the `expect` function alongside with its attached methods, like `extend`.

This has [changed with Jest 28](https://github.com/facebook/jest/blob/v28.0.0/packages/expect/src/index.ts#L449). `export default expect` is the new export statement, which means requiring the "expect" package returns the module object, instead of the function.

#3347 PR attempts to fix this error by assuming "expect" package should throw an error with Jest 28 and it can catch that and require the "expect" from the `@jest/globals` package for Jest 28+ project but it's not the case in reality. "expect" package is still shipped with Jest 28, so, requiring it doesn't throw an error as expected in the PR.

By knowing the export difference, I checked if the value of the module is object or not after requiring it. If it's an object, it means user is on Jest 28+ codebase. The rest is the same with the previous PR. I require the "expect" function from `@jest/globals` and use it.

Tested on Jest 29 and Jest 27.5.1

Fixes #3553 and #3215.
  • Loading branch information
yusufyildirim authored and piaskowyk committed Nov 3, 2022
1 parent 719242f commit 541828e
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/reanimated2/jestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,21 @@ export const advanceAnimationByFrame = (count) => {
};

export const setUpTests = (userConfig = {}) => {
let expect;
try {
expect = require('expect');
} catch (_) {
// for Jest in version 28+
const { expect: expectModule } = require('@jest/globals');
let expect = global.expect;
if (expect === undefined) {
const expectModule = require('expect');
expect = expectModule;
// Starting from Jest 28, "expect" package uses named exports instead of default export.
// So, requiring "expect" package doesn't give direct access to "expect" function anymore.
// It gives access to the module object instead.
// We use this info to detect if the project uses Jest 28 or higher.
if (typeof expect === 'object') {
const jestGlobals = require('@jest/globals');
expect = jestGlobals.expect;
}
if (expect === undefined || expect.extend === undefined) {
expect = expectModule.default;
}
}

require('setimmediate');
Expand Down

0 comments on commit 541828e

Please sign in to comment.