Something went wrong. Try again.
javascript for 🐜's, a tiny runtime with big ambitions antjs.org
Something went wrong. Try again.
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141import { test, testThrows, testDeep, summary } from './helpers.js';
console.log('FormData constructor\n');
const fd0 = new FormData();test('empty constructor', fd0.has('x'), false);
testThrows('requires new', () => FormData());testThrows('rejects form element', () => new FormData(document));
console.log('\nappend / get / has / delete / set\n');
const fd = new FormData();
fd.append('name', 'Alice');test('append then get', fd.get('name'), 'Alice');test('has returns true', fd.has('name'), true);test('has missing returns false', fd.has('other'), false);
fd.append('name', 'Bob');const all = fd.getAll('name');test('getAll length after two appends', all.length, 2);test('getAll first', all[0], 'Alice');test('getAll second', all[1], 'Bob');
fd.set('name', 'Carol');test('set replaces all', fd.getAll('name').length, 1);test('set value', fd.get('name'), 'Carol');
fd.delete('name');test('delete removes all', fd.has('name'), false);test('get after delete returns null', fd.get('name'), null);
console.log('\nBlob values\n');
const blob = new Blob(['hello'], { type: 'text/plain' });const fdb = new FormData();fdb.append('file', blob);
const got = fdb.get('file');test('blob entry is File instance', got instanceof File, true);test('blob entry filename default', got.name, 'blob');test('blob entry type', got.type, 'text/plain');
fdb.append('file2', blob, 'custom.txt');const got2 = fdb.get('file2');test('blob with filename', got2.name, 'custom.txt');
console.log('\nFile values\n');
const file = new File(['world'], 'test.txt', { type: 'text/html' });const fdf = new FormData();fdf.append('upload', file);
const gotf = fdf.get('upload');test('file entry is File instance', gotf instanceof File, true);test('file entry name from File', gotf.name, 'test.txt');test('file entry type', gotf.type, 'text/html');
fdf.append('upload2', file, 'override.txt');test('file entry name overridden', fdf.get('upload2').name, 'override.txt');
console.log('\ngetAll with mixed types\n');
const fdm = new FormData();fdm.append('x', 'str');fdm.append('x', new Blob(['data']));const mixed = fdm.getAll('x');test('mixed getAll length', mixed.length, 2);test('mixed first is string', mixed[0], 'str');test('mixed second is File', mixed[1] instanceof File, true);
console.log('\nforEach\n');
const fdfe = new FormData();fdfe.append('b', '2');fdfe.append('a', '1');const seen = [];fdfe.forEach((val, name) => seen.push(`${name}=${val}`));test('forEach visits all entries', seen.length, 2);test('forEach insertion order first', seen[0], 'b=2');test('forEach insertion order second', seen[1], 'a=1');
console.log('\nentries / keys / values\n');
const fdi = new FormData();fdi.append('x', '1');fdi.append('y', '2');fdi.append('x', '3');
const keys = [...fdi.keys()];test('keys length', keys.length, 3);test('keys first', keys[0], 'x');test('keys second', keys[1], 'y');test('keys third', keys[2], 'x');
const vals = [...fdi.values()];test('values first', vals[0], '1');test('values second', vals[1], '2');test('values third', vals[2], '3');
const entries = [...fdi.entries()];test('entries length', entries.length, 3);test('entries first name', entries[0][0], 'x');test('entries first value', entries[0][1], '1');
console.log('\nSymbol.iterator\n');
const fds = new FormData();fds.append('k', 'v');const iter_result = [...fds];test('Symbol.iterator yields entries', iter_result.length, 1);test('Symbol.iterator entry name', iter_result[0][0], 'k');test('Symbol.iterator entry value', iter_result[0][1], 'v');
console.log('\ntoStringTag\n');
test('toStringTag', Object.prototype.toString.call(new FormData()), '[object FormData]');
console.log('\nmultipart parameter parsing\n');
const boundary = 'spec-boundary';const multipartBody = `--${boundary}\r\n` + `Content-Disposition: form-data; name="field"\r\n\r\n` + `value\r\n` + `--${boundary}--\r\n`;
const multipartReq = new Request('https://example.com/', { method: 'POST', headers: { 'Content-Type': `multipart/form-data; boundaryx=wrong; boundary="${boundary}"`, }, body: multipartBody,});
const multipartFd = await multipartReq.formData();test('multipart boundary lookup skips longer prefix match', multipartFd.get('field'), 'value');
summary();