Something went wrong. Try again.
javascript for 🐜's, a tiny runtime with big ambitions antjs.org
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162// Arguments objects share Array storage but are ordinary objects. APIs that// expect an Array (structuredClone, v8.serialize, JSON replacer lists,// Buffer.concat, process.hrtime, child_process args, assert deep equality)// must not treat them as one, and readers must honor a reassigned length.// Output must match what Node prints.const assert = require('node:assert');const { spawnSync } = require('node:child_process');
const body = String.raw`function A(){ return arguments; }function S(){ 'use strict'; return arguments; }function L(){ arguments.length = 1; return arguments; }function G(){ arguments[5] = 9; arguments.length = 6; return arguments; }const show=r=>{ if (r===undefined) return 'undefined'; try { return JSON.stringify(r); } catch { return String(r); } };const t=(n,fn)=>{ try { console.log(n, show(fn())); } catch(e){ console.log(n,'throws',e.name, e.code||''); } };const cp=require('child_process'), util=require('util'), assert=require('assert'), v8=require('v8');for (const [n,mk] of [['sloppy',A],['strict',S]]) { t(n+' isArray', ()=>Array.isArray(mk(1))); t(n+' toString', ()=>Object.prototype.toString.call(mk(1))); t(n+' json', ()=>JSON.stringify(mk(1,2))); t(n+' keys', ()=>Object.keys(mk(1,2))); t(n+' names', ()=>Object.getOwnPropertyNames(mk(1,2))); t(n+' concat', ()=>[].concat(mk(1))); t(n+' spread obj', ()=>({...mk(1,2)})); t(n+' inspect', ()=>util.inspect(mk(1,'a'))); t(n+' inspect empty', ()=>util.inspect(mk()));}t('structuredClone', ()=>structuredClone(A(1,2)));t('structuredClone nested', ()=>structuredClone({x:A(1)}));t('v8 serialize', ()=>v8.serialize(A(1,2)));t('v8 serialize fn', ()=>v8.serialize(()=>1));t('v8 serialize sym', ()=>v8.serialize(Symbol('s')));t('v8 roundtrip', ()=>v8.deserialize(v8.serialize({a:[1,'x',null]})));t('deepStrictEqual arr', ()=>assert.deepStrictEqual(A(1,2), [1,2]));t('deepEqual arr', ()=>assert.deepEqual(A(1,2), [1,2]));t('deepStrictEqual args', ()=>assert.deepStrictEqual(A(1,2), A(1,2)));t('JSON replacer args', ()=>JSON.stringify({a:1,b:2}, A('a')));t('JSON replacer arraylike', ()=>JSON.stringify({a:1,b:2}, {length:1, 0:'a'}));t('JSON replacer array', ()=>JSON.stringify({a:1,b:2}, ['a']));t('JSON replacer proxy', ()=>JSON.stringify({a:1,b:2}, new Proxy(['b'], {})));t('Buffer.concat args', ()=>Buffer.concat(A(Buffer.from('a'))));t('Buffer.concat obj', ()=>Buffer.concat({length:0}));t('Buffer.concat array', ()=>Buffer.concat([Buffer.from('a'), Buffer.from('b')]).toString());t('hrtime args', ()=>process.hrtime(A(0,0)));t('hrtime len', ()=>process.hrtime([1,2,3]));t('hrtime ok', ()=>process.hrtime([0,0]).length);t('execFileSync args', ()=>String(cp.execFileSync('echo', A('x'))).trim());t('execFileSync array', ()=>String(cp.execFileSync('echo', ['x'])).trim());t('u8 from modified length', ()=>[...new Uint8Array(L(1,2,3))]);t('u8 from grown', ()=>[...new Uint8Array(G(1))]);t('spread modified length', ()=>[...L(1,2,3)]);t('apply modified length', ()=>Math.max.apply(null, L(1,5,9)));t('Array.from modified', ()=>Array.from(G(1)));`;
const env = { ...process.env, NO_COLOR: '1' };delete env.FORCE_COLOR;const child = spawnSync(process.execPath, ['-e', body], { encoding: 'utf8', timeout: 60000, env });assert.strictEqual(child.status, 0, child.stderr);assert.strictEqual(child.stdout, "sloppy isArray false\nsloppy toString \"[object Arguments]\"\nsloppy json \"{\\\"0\\\":1,\\\"1\\\":2}\"\nsloppy keys [\"0\",\"1\"]\nsloppy names [\"0\",\"1\",\"length\",\"callee\"]\nsloppy concat [{\"0\":1}]\nsloppy spread obj {\"0\":1,\"1\":2}\nsloppy inspect \"[Arguments] { '0': 1, '1': 'a' }\"\nsloppy inspect empty \"[Arguments] {}\"\nstrict isArray false\nstrict toString \"[object Arguments]\"\nstrict json \"{\\\"0\\\":1,\\\"1\\\":2}\"\nstrict keys [\"0\",\"1\"]\nstrict names [\"0\",\"1\",\"length\",\"callee\"]\nstrict concat [{\"0\":1}]\nstrict spread obj {\"0\":1,\"1\":2}\nstrict inspect \"[Arguments] { '0': 1, '1': 'a' }\"\nstrict inspect empty \"[Arguments] {}\"\nstructuredClone throws DataCloneError 25\nstructuredClone nested throws DataCloneError 25\nv8 serialize throws Error \nv8 serialize fn throws Error \nv8 serialize sym throws Error \nv8 roundtrip {\"a\":[1,\"x\",null]}\ndeepStrictEqual arr throws AssertionError ERR_ASSERTION\ndeepEqual arr throws AssertionError ERR_ASSERTION\ndeepStrictEqual args undefined\nJSON replacer args \"{\\\"a\\\":1,\\\"b\\\":2}\"\nJSON replacer arraylike \"{\\\"a\\\":1,\\\"b\\\":2}\"\nJSON replacer array \"{\\\"a\\\":1}\"\nJSON replacer proxy \"{\\\"b\\\":2}\"\nBuffer.concat args throws TypeError ERR_INVALID_ARG_TYPE\nBuffer.concat obj throws TypeError ERR_INVALID_ARG_TYPE\nBuffer.concat array \"ab\"\nhrtime args throws TypeError ERR_INVALID_ARG_TYPE\nhrtime len throws RangeError ERR_OUT_OF_RANGE\nhrtime ok 2\nexecFileSync args \"\"\nexecFileSync array \"x\"\nu8 from modified length [1]\nu8 from grown [1,0,0,0,0,9]\nspread modified length [1]\napply modified length 1\nArray.from modified [1,null,null,null,null,9]\n");console.log('PASS arguments objects are not treated as arrays');