sindresorhus / ky-universal

Use Ky in both Node.js and browsers
https://github.com/sindresorhus/ky
MIT License
670 stars 20 forks source link

Tests fail after upgrading ky-universal from 0.9.1 to 0.10.x (underlying error: TextDecoder is not defined) #41

Closed targumon closed 2 years ago

targumon commented 2 years ago

I use ky in a React app. For tests (jest on node) I inject ky-universal instead. (with beforeRequest hook set to return canned responses - also useful for mocks during developments! 😁)

Recently upgraded from 0.9.1 to 0.10.x and all tests relying on ky failed. Since the diff is mostly a node-fetch minor bump and everything else being equal, obviously it's NOT an issue with ky-universal, but with a dependency.

Took me a while, but I was able to find the underlying error: ReferenceError: TextDecoder is not defined (thrown by this line: https://github.com/node-fetch/node-fetch/blob/main/src/body.js#L159)

From there, the way to a workaround was shorter. In my setupTests file, I just added:

import {TextDecoder} from 'util'
global.TextDecoder = TextDecoder

(I you use TS, you can easily appease its complaint with: global.TextDecoder = TextDecoder as typeof global.TextDecoder)

And although I still don't understand how such a built-in api became undefined, at least I was back to green ✅

I know ky-universal is not as popular as ky, but if a search engine brings even a single soul to this text and they find it helpful, I'll be happy.

LLAP! 🖖

targumon commented 2 years ago

Further investigation: NOT a direct issue with node-fetch. They started using TextDecoder very recently, but putting the following in a file, let's call it r.js:

import {Response} from 'node-fetch'
console.log(await new Response('foo', {status: 200}).text())

and running node r.js works fine (i.e. node-fetch relies on global TextDecoder to exist, and it indeed exists)

Seems like an issue with Jest. The environment it provides is lacking this global. See discussion here: https://github.com/jsdom/jsdom/issues/2524#issuecomment-902027138