-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
0.34.3 doens't work with Uint8Array
and TextEncoder
#4043
Comments
I believe this also effects esbuild directly. Using vitest with a utility that calls esbuild results in:
|
I think #3998 is likely the culprit. Something about the |
The cause is this removal, specifically:
jestjs/jest#9983 has more context and jsdom/jsdom#2524 would be the proper fix, but it's stale. How does vitest want to proceed? I see two options:
Both are fine with me, but the current situation where only |
The issue doesn't specify what mode it is running, so I assume it's not experimental-vm ( But yeah, this one is quite hard to fix in general because jsdom uses its internal Uint8Array for its APIs, and Node.js uses its own implementation so they clash in different APIs, just like with URL. |
Config is pretty much default configuration. |
- `TextEncoder/TextDecoder` is a Node API - `Uint8Array` is a jsdom API vitest-dev/vitest#4043
- `TextEncoder/TextDecoder` is a Node API - `Uint8Array` is a jsdom API vitest-dev/vitest#4043
- `TextEncoder/TextDecoder` is a Node API - `Uint8Array` is a jsdom API vitest-dev/vitest#4043
I am still seeing this issue. Is the workaround published as part of |
…nceof Uint8Array" is incorrectly false' Bug: vitest-dev/vitest#4043
Temporarily fix for node environment: // @vitest-environment node |
got the same issue with vitest 0.34.3, prev versions worked as expected. For the below function (source), export function isU8a (value?: unknown): value is Uint8Array {
// here we defer the instanceof check which is actually slightly
// slower than just checking the constrctor (direct instances)
return (
((value && (value as Uint8Array).constructor) === Uint8Array) ||
value instanceof Uint8Array
);
} |
Is it not covered in the specs? u8a.spec.ts |
it is covered, but vitest 0.34.3 has this bug that causes it to fail, the |
@sheremet-va btw what is the correct way to use AbortController, TextEncoder and others within |
Environments (jsdom/happy-dom) should provide these APIs. |
@sheremet-va and as I understand it's impossible to transfer (assign it to window/global in setup file) classes like |
It is possible to pass down implementations to VM threads, but some APIs will not accept them, while others will. For example, if we use const blob = new Blob(['Hello'], { type: 'text/plain' })
const arraybuffer = await new Promise<ArrayBuffer>((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => resolve(reader.result as ArrayBuffer)
reader.onerror = () => reject(reader.error)
reader.readAsArrayBuffer(blob)
})
expect(arraybuffer instanceof ArrayBuffer).toBeTruthy() // fails, because ArrayBuffer is node.ArrayBuffer, but FileReader resolves to jsdom.ArrayBuffer If we use I am not sure where the middle ground is, and open to suggestions. |
Also, looks like happy-dom doesn't have these issues. |
Oh, yeah, I remember this infamous jest issue jestjs/jest#2549 And yeah, it feels like the latest happy-dom has many globals. At least, Request, AbortController, AbortSignal. And it's easy to polyfill TextEncoder/TextDecoder via https://github.com/samthor/fast-text-encoding |
Super simple workaround that actually works. Thanks! Put it at the top of your test spec file. |
I was banging my head against the wall for a while on this one. None of the solutions I encountered here (or in the JSDom, Jest, or ESBuild repos) were working for my use case. Ultimately, what I ended up doing to get this fixed was to introduce a shim of First, in my // vite.config.ts
import "./setupTestEnvironmentCompatibility"; // This MUST be the first import
// ... And then the // Only overwrite this if we are in test mode. This is an env var we happen to have in our repo
if (process.env.VITE_IS_TEST === "true") {
class ESBuildAndJSDOMCompatibleTextEncoder extends TextEncoder {
constructor() {
super();
}
encode(input: string) {
if (typeof input !== "string") {
throw new TypeError("`input` must be a string");
}
const decodedURI = decodeURIComponent(encodeURIComponent(input));
const arr = new Uint8Array(decodedURI.length);
const chars = decodedURI.split("");
for (let i = 0; i < chars.length; i++) {
arr[i] = decodedURI[i].charCodeAt(0);
}
return arr;
}
}
Object.defineProperty(global, "TextEncoder", {
value: ESBuildAndJSDOMCompatibleTextEncoder,
writable: true,
});
} Hope this helps others. |
Following @kyledetella's workaround, putting the import: import "./setupTestEnvironmentCompatibility"; in my |
@sheremet-va What is the status of this issue? |
@eduardhasanaj I am not sure why @kyledetella inserted the code into vite.config.ts directly - that may be a problem for you. Since this issue is with the JSDom environment and vitest, I put a slightly simplified version of @kyledetella's code in my // JSDom + Vitest don't play well with each other. Long story short - default
// TextEncoder produces Uint8Array objects that are _different_ from the global
// Uint8Array objects, so some functions that compare their types explode.
// https://github.com/vitest-dev/vitest/issues/4043#issuecomment-1905172846
class ESBuildAndJSDOMCompatibleTextEncoder extends TextEncoder {
constructor() {
super();
}
encode(input: string) {
if (typeof input !== "string") {
throw new TypeError("`input` must be a string");
}
const decodedURI = decodeURIComponent(encodeURIComponent(input));
const arr = new Uint8Array(decodedURI.length);
const chars = decodedURI.split("");
for (let i = 0; i < chars.length; i++) {
arr[i] = decodedURI[i].charCodeAt(0);
}
return arr;
}
}
global.TextEncoder = ESBuildAndJSDOMCompatibleTextEncoder; In {
// ...
test: {
setupFiles: ["src/setupTests.ts"],
},
} |
@KholdStare Thank you very much for you time. It worked! |
Describe the bug
The test works in 0.34.2, but doesn't work in 0.34.3
Reproduction
System Info
Used Package Manager
npm
Validations
The text was updated successfully, but these errors were encountered: