@@ -67,6 +67,7 @@ describe('structuredClone', () => {
6767
6868 expect ( structuredClone ( 0 ) ) . toBe ( 0 ) ;
6969 expect ( structuredClone ( 1 ) ) . toBe ( 1 ) ;
70+ expect ( Object . is ( structuredClone ( - 0 ) , - 0 ) ) . toBe ( true ) ;
7071
7172 expect ( structuredClone ( 0n ) ) . toBe ( 0n ) ;
7273 expect ( structuredClone ( 1n ) ) . toBe ( 1n ) ;
@@ -99,6 +100,12 @@ describe('structuredClone', () => {
99100 expect ( booleanClone ) . not . toBe ( booleanValue ) ;
100101 expect ( booleanClone ) . toBeInstanceOf ( Boolean ) ;
101102 expect ( booleanClone . valueOf ( ) ) . toBe ( true ) ;
103+
104+ const bigintValue = Object ( 1n ) ;
105+ const bigintClone = structuredClone ( bigintValue ) ;
106+ expect ( bigintClone ) . not . toBe ( bigintValue ) ;
107+ expect ( bigintClone ) . toBeInstanceOf ( BigInt ) ;
108+ expect ( bigintClone . valueOf ( ) ) . toBe ( 1n ) ;
102109 } ) ;
103110
104111 it ( 'throws with symbols, functions, WeakMap, WeakSet, Promise' , ( ) => {
@@ -223,6 +230,58 @@ describe('structuredClone', () => {
223230 expect ( clone ) . toEqual ( value ) ;
224231 } ) ;
225232
233+ it ( 'clones invalid dates' , ( ) => {
234+ const value = new Date ( NaN ) ;
235+ const clone = structuredClone ( value ) ;
236+ expect ( clone ) . not . toBe ( value ) ;
237+ expect ( clone ) . toBeInstanceOf ( Date ) ;
238+ expect ( Number . isNaN ( clone . getTime ( ) ) ) . toBe ( true ) ;
239+ } ) ;
240+
241+ it ( 'clones ArrayBuffer' , ( ) => {
242+ const value = new Uint8Array ( [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) . buffer ;
243+ const clone = structuredClone ( value ) ;
244+ expect ( clone ) . not . toBe ( value ) ;
245+ expect ( clone ) . toBeInstanceOf ( ArrayBuffer ) ;
246+ expect ( [ ...new Uint8Array ( clone ) ] ) . toEqual ( [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) ;
247+ } ) ;
248+
249+ it ( 'clones DataView' , ( ) => {
250+ const buffer = new Uint8Array ( [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) . buffer ;
251+ const value = new DataView ( buffer ) ;
252+ const clone = structuredClone ( value ) ;
253+ expect ( clone ) . not . toBe ( value ) ;
254+ expect ( clone ) . toBeInstanceOf ( DataView ) ;
255+ expect ( [ ...new Uint8Array ( clone . buffer ) ] ) . toEqual ( [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) ;
256+ } ) ;
257+
258+ it ( 'clones typed arrays' , ( ) => {
259+ const value = new Uint32Array ( [ 1 , 2 , 3 ] ) ;
260+ const clone = structuredClone ( value ) ;
261+ expect ( clone ) . not . toBe ( value ) ;
262+ expect ( clone ) . toBeInstanceOf ( Uint32Array ) ;
263+ expect ( [ ...clone ] ) . toEqual ( [ 1 , 2 , 3 ] ) ;
264+ } ) ;
265+
266+ it ( 'preserves shared buffers between views' , ( ) => {
267+ const buffer = new Uint8Array ( [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) . buffer ;
268+ const value = {
269+ typedArray : new Uint16Array ( buffer , 2 , 2 ) ,
270+ dataView : new DataView ( buffer , 1 , 6 ) ,
271+ buffer,
272+ } ;
273+
274+ const clone = structuredClone ( value ) ;
275+ expect ( clone . buffer ) . not . toBe ( buffer ) ;
276+ expect ( clone . dataView . buffer ) . toBe ( clone . buffer ) ;
277+ expect ( clone . typedArray . buffer ) . toBe ( clone . buffer ) ;
278+ expect ( clone . dataView . byteOffset ) . toBe ( value . dataView . byteOffset ) ;
279+ expect ( clone . dataView . byteLength ) . toBe ( value . dataView . byteLength ) ;
280+ expect ( clone . typedArray . byteOffset ) . toBe ( value . typedArray . byteOffset ) ;
281+ expect ( clone . typedArray . length ) . toBe ( value . typedArray . length ) ;
282+ expect ( [ ...clone . typedArray ] ) . toEqual ( [ ...value . typedArray ] ) ;
283+ } ) ;
284+
226285 it ( 'clones errors' , ( ) => {
227286 const cause = new Error ( 'cause message' ) ;
228287 const value = new Error ( 'error message' , { cause} ) ;
@@ -261,6 +320,28 @@ describe('structuredClone', () => {
261320 expect ( structuredClone ( value ) . name ) . toBe ( 'Error' ) ;
262321 } ) ;
263322
323+ it ( 'preserves error subclasses' , ( ) => {
324+ expect ( structuredClone ( new Error ( 'boom' ) ) ) . toBeInstanceOf ( Error ) ;
325+ expect ( structuredClone ( new EvalError ( 'boom' ) ) ) . toBeInstanceOf ( EvalError ) ;
326+ expect ( structuredClone ( new RangeError ( 'boom' ) ) ) . toBeInstanceOf ( RangeError ) ;
327+ expect ( structuredClone ( new ReferenceError ( 'boom' ) ) ) . toBeInstanceOf (
328+ ReferenceError ,
329+ ) ;
330+ expect ( structuredClone ( new SyntaxError ( 'boom' ) ) ) . toBeInstanceOf (
331+ SyntaxError ,
332+ ) ;
333+ expect ( structuredClone ( new TypeError ( 'boom' ) ) ) . toBeInstanceOf ( TypeError ) ;
334+ expect ( structuredClone ( new URIError ( 'boom' ) ) ) . toBeInstanceOf ( URIError ) ;
335+ } ) ;
336+
337+ it ( 'clones __proto__ as an own property' , ( ) => {
338+ const value = JSON . parse ( '{"__proto__":{"foo":"bar"}}' ) ;
339+ const clone = structuredClone ( value ) ;
340+
341+ expect ( clone . foo ) . toBeUndefined ( ) ;
342+ expect ( Object . hasOwn ( clone , '__proto__' ) ) . toBe ( true ) ;
343+ } ) ;
344+
264345 it ( 'clones values deeply' , ( ) => {
265346 const value = {
266347 obj : {
0 commit comments