The TextEncoder.encode does not seem to yield a valid U8a, or rather, it cannot be compared. When the output from this is passed into a function expecting a Uint8Array it does indeed fail.
This is a failing test -
it('encodes string as Uint8array', (): void => {
expect(
new TextEncoder().encode('袩褉懈胁械褌, 屑懈褉!')
).toEqual(
new Uint8Array([208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 44, 32, 208, 188, 208, 184, 209, 128, 33])
);
});
The output does not match, rather it fails with -
expect(received).toEqual(expected) // deep equality
- Expected - 23
+ Received + 23
- Uint8Array [
- 208,
- 159,
- 209,
- 128,
- 208,
- 184,
- 208,
- 178,
- 208,
- 181,
- 209,
- 130,
- 44,
- 32,
- 208,
- 188,
- 208,
- 184,
- 209,
- 128,
- 33,
- ]
+ Uint8Array {
+ "0": 208,
+ "1": 159,
+ "10": 209,
+ "11": 130,
+ "12": 44,
+ "13": 32,
+ "14": 208,
+ "15": 188,
+ "16": 208,
+ "17": 184,
+ "18": 209,
+ "19": 128,
+ "2": 209,
+ "20": 33,
+ "3": 128,
+ "4": 208,
+ "5": 184,
+ "6": 208,
+ "7": 178,
+ "8": 208,
+ "9": 181,
+ }
It was still working on the 25.4.x version before I updated.
Failing test included above.
System:
OS: macOS 10.15.2
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Binaries:
Node: 13.8.0 - /usr/local/bin/node
Yarn: 2.0.0-rc.30 - /usr/local/bin/yarn
npm: 6.13.7 - /usr/local/bin/npm
@jacogr Does this happen only in JSDOM environment? If yes, can you try removing this line in your node_modules directory: https://github.com/facebook/jest/blob/4bd3d4a05999170f423f7050d4e0537648499e88/packages/jest-environment-jsdom/src/index.ts#L49
This example still fails.
https://github.com/facebook/jest/issues/9993
It does indeed fail like @TrySound suggested, even with the line commented.
However, I can make both test cases pass by adding testEnvironment: "node" to the config.
Hmm, seems like JSDOM doesn't support TextEncoder at all - https://github.com/jsdom/jsdom/issues/2524. Not sure why it's available in jest-environment-jsdom, or why it worked before.
Is this
Each jsdom
Windownow exposes all JavaScript-spec-defined globals uniformly. WhenrunScriptsis disabled, it exposes them as aliases of the ones from the outer Node.js environment. Whereas whenrunScriptsis enabled, it exposes fresh copies of each global from the new scripting environment. (Previously, a few typed array classes would always be aliased, and withrunScriptsdisabled, the other classes would not be exposed at all.)
from https://github.com/jsdom/jsdom/blob/master/Changelog.md#1600?
Seems to be in progress here: https://github.com/jsdom/whatwg-encoding/pull/11
Node 11+ supports the TextEncoder global as part of their efforts to align further with browser environments
@SimenB Look at my issue https://github.com/facebook/jest/issues/9993. TextEncoder is not the only problem. Here simple buffer instanceof Uint8Array does not work in jsdom environment.
Also TextEncoder is available in Node.
What node supports and what jsdom supports is not the same thing. We usually point to jsdom for missing web APIs, this seems like the same thing?
I dug, in the case of no TextEncoder it injects a polyfill in the project where this was uncovered, which is this -
if (typeof TextEncoder === 'undefined') {
global.TextEncoder = require('util').TextEncoder;
}
So the issue is exactly the same as @TrySound reported - since doing the above will no doubt use Buffer internally, so the test-case he has is the simplest and the actual underlying cause -
it('has Buffer & Uint8array equivalency', () => {
expect(Buffer.from('') instanceof Uint8Array).toBeTruthy();
});
Sorry about the confusion, it has been literally 2 years since that polyfill was added. (Since it just worked in the meantime, totally lost track of it)
We also polyfill this and have failing tests on JSDOM 16 with jest:
// Polyfill for encoding which isn't present globally in jsdom
import { TextEncoder, TextDecoder } from 'util'
global.TextEncoder = TextEncoder
global.TextDecoder = TextDecoder
Since Buffer.from('') instanceof Uint8Array evaluates true in node, I'm confused about where the problem actually is. Is JSDOM polyfilling in a slightly different implementation of Uint8Array?
Most helpful comment
I dug, in the case of no TextEncoder it injects a polyfill in the project where this was uncovered, which is this -
So the issue is exactly the same as @TrySound reported - since doing the above will no doubt use
Bufferinternally, so the test-case he has is the simplest and the actual underlying cause -Sorry about the confusion, it has been literally 2 years since that polyfill was added. (Since it just worked in the meantime, totally lost track of it)