xref: /third_party/node/test/parallel/test-blob.js (revision 1cb0ef41)
1// Flags: --no-warnings
2'use strict';
3
4const common = require('../common');
5const assert = require('assert');
6const { Blob } = require('buffer');
7const { inspect } = require('util');
8const { EOL } = require('os');
9
10{
11  const b = new Blob();
12  assert.strictEqual(b.size, 0);
13  assert.strictEqual(b.type, '');
14}
15
16assert.throws(() => new Blob(false), {
17  code: 'ERR_INVALID_ARG_TYPE'
18});
19
20assert.throws(() => new Blob('hello'), {
21  code: 'ERR_INVALID_ARG_TYPE'
22});
23
24assert.throws(() => new Blob({}), {
25  code: 'ERR_INVALID_ARG_TYPE'
26});
27
28{
29  const b = new Blob([]);
30  assert(b);
31  assert.strictEqual(b.size, 0);
32  assert.strictEqual(b.type, '');
33
34  b.arrayBuffer().then(common.mustCall((ab) => {
35    assert.deepStrictEqual(ab, new ArrayBuffer(0));
36  }));
37  b.text().then(common.mustCall((text) => {
38    assert.strictEqual(text, '');
39  }));
40  const c = b.slice();
41  assert.strictEqual(c.size, 0);
42}
43
44{
45  assert.strictEqual(new Blob([], { type: 1 }).type, '1');
46  assert.strictEqual(new Blob([], { type: false }).type, 'false');
47  assert.strictEqual(new Blob([], { type: {} }).type, '[object object]');
48}
49
50{
51  const b = new Blob([Buffer.from('abc')]);
52  assert.strictEqual(b.size, 3);
53  b.text().then(common.mustCall((text) => {
54    assert.strictEqual(text, 'abc');
55  }));
56}
57
58{
59  const b = new Blob([new ArrayBuffer(3)]);
60  assert.strictEqual(b.size, 3);
61  b.text().then(common.mustCall((text) => {
62    assert.strictEqual(text, '\0\0\0');
63  }));
64}
65
66{
67  const b = new Blob([new Uint8Array(3)]);
68  assert.strictEqual(b.size, 3);
69  b.text().then(common.mustCall((text) => {
70    assert.strictEqual(text, '\0\0\0');
71  }));
72}
73
74{
75  const b = new Blob([new Blob(['abc'])]);
76  assert.strictEqual(b.size, 3);
77  b.text().then(common.mustCall((text) => {
78    assert.strictEqual(text, 'abc');
79  }));
80}
81
82{
83  const b = new Blob(['hello', Buffer.from('world')]);
84  assert.strictEqual(b.size, 10);
85  b.text().then(common.mustCall((text) => {
86    assert.strictEqual(text, 'helloworld');
87  }));
88}
89
90{
91  const b = new Blob(['hello', new Uint8Array([0xed, 0xa0, 0x88])]);
92  assert.strictEqual(b.size, 8);
93  b.text().then(common.mustCall((text) => {
94    assert.strictEqual(text, 'hello\ufffd\ufffd\ufffd');
95    assert.strictEqual(text.length, 8);
96  }));
97}
98
99{
100  const b = new Blob(
101    [
102      'h',
103      'e',
104      'l',
105      'lo',
106      Buffer.from('world'),
107    ]);
108  assert.strictEqual(b.size, 10);
109  b.text().then(common.mustCall((text) => {
110    assert.strictEqual(text, 'helloworld');
111  }));
112}
113
114{
115  const b = new Blob(['hello', Buffer.from('world')]);
116  assert.strictEqual(b.size, 10);
117  assert.strictEqual(b.type, '');
118
119  const c = b.slice(1, -1, 'foo');
120  assert.strictEqual(c.type, 'foo');
121  c.text().then(common.mustCall((text) => {
122    assert.strictEqual(text, 'elloworl');
123  }));
124
125  const d = c.slice(1, -1);
126  d.text().then(common.mustCall((text) => {
127    assert.strictEqual(text, 'llowor');
128  }));
129
130  const e = d.slice(1, -1);
131  e.text().then(common.mustCall((text) => {
132    assert.strictEqual(text, 'lowo');
133  }));
134
135  const f = e.slice(1, -1);
136  f.text().then(common.mustCall((text) => {
137    assert.strictEqual(text, 'ow');
138  }));
139
140  const g = f.slice(1, -1);
141  assert.strictEqual(g.type, '');
142  g.text().then(common.mustCall((text) => {
143    assert.strictEqual(text, '');
144  }));
145
146  const h = b.slice(-1, 1);
147  assert.strictEqual(h.size, 0);
148
149  const i = b.slice(1, 100);
150  assert.strictEqual(i.size, 9);
151
152  const j = b.slice(1, 2, false);
153  assert.strictEqual(j.type, 'false');
154
155  assert.strictEqual(b.size, 10);
156  assert.strictEqual(b.type, '');
157}
158
159{
160  const b = new Blob([Buffer.from('hello'), Buffer.from('world')]);
161  const mc = new MessageChannel();
162  mc.port1.onmessage = common.mustCall(({ data }) => {
163    data.text().then(common.mustCall((text) => {
164      assert.strictEqual(text, 'helloworld');
165    }));
166    mc.port1.close();
167  });
168  mc.port2.postMessage(b);
169  b.text().then(common.mustCall((text) => {
170    assert.strictEqual(text, 'helloworld');
171  }));
172}
173
174{
175  const b = new Blob(['hello'], { type: '\x01' });
176  assert.strictEqual(b.type, '');
177}
178
179{
180  const descriptor =
181      Object.getOwnPropertyDescriptor(Blob.prototype, Symbol.toStringTag);
182  assert.deepStrictEqual(descriptor, {
183    configurable: true,
184    enumerable: false,
185    value: 'Blob',
186    writable: false
187  });
188}
189
190{
191  const descriptors = Object.getOwnPropertyDescriptors(Blob.prototype);
192  const enumerable = [
193    'size',
194    'type',
195    'slice',
196    'stream',
197    'text',
198    'arrayBuffer',
199  ];
200
201  for (const prop of enumerable) {
202    assert.notStrictEqual(descriptors[prop], undefined);
203    assert.strictEqual(descriptors[prop].enumerable, true);
204  }
205}
206
207{
208  const b = new Blob(['test', 42]);
209  b.text().then(common.mustCall((text) => {
210    assert.strictEqual(text, 'test42');
211  }));
212}
213
214{
215  const b = new Blob();
216  assert.strictEqual(inspect(b, { depth: null }),
217                     'Blob { size: 0, type: \'\' }');
218  assert.strictEqual(inspect(b, { depth: 1 }),
219                     'Blob { size: 0, type: \'\' }');
220  assert.strictEqual(inspect(b, { depth: -1 }), '[Blob]');
221}
222
223{
224  // The Blob has to be over a specific size for the data to
225  // be copied asynchronously..
226  const b = new Blob(['hello', 'there'.repeat(820)]);
227  assert.strictEqual(b.arrayBuffer(), b.arrayBuffer());
228  b.arrayBuffer().then(common.mustCall());
229}
230
231(async () => {
232  const b = new Blob(['hello']);
233  const reader = b.stream().getReader();
234  let res = await reader.read();
235  assert.strictEqual(res.value.byteLength, 5);
236  assert(!res.done);
237  res = await reader.read();
238  assert(res.done);
239})().then(common.mustCall());
240
241{
242  const b = new Blob(['hello\n'], { endings: 'native' });
243  assert.strictEqual(b.size, EOL.length + 5);
244
245  [1, {}, 'foo'].forEach((endings) => {
246    assert.throws(() => new Blob([], { endings }), {
247      code: 'ERR_INVALID_ARG_VALUE',
248    });
249  });
250}
251
252{
253  assert.throws(() => Reflect.get(Blob.prototype, 'type', {}), {
254    code: 'ERR_INVALID_THIS',
255  });
256  assert.throws(() => Reflect.get(Blob.prototype, 'size', {}), {
257    code: 'ERR_INVALID_THIS',
258  });
259  assert.throws(() => Blob.prototype.slice(Blob.prototype, 0, 1), {
260    code: 'ERR_INVALID_THIS',
261  });
262  assert.throws(() => Blob.prototype.stream.call(), {
263    code: 'ERR_INVALID_THIS',
264  });
265}
266
267(async () => {
268  assert.rejects(async () => Blob.prototype.arrayBuffer.call(), {
269    code: 'ERR_INVALID_THIS',
270  });
271  assert.rejects(async () => Blob.prototype.text.call(), {
272    code: 'ERR_INVALID_THIS',
273  });
274})().then(common.mustCall());
275
276(async () => {
277  const blob = new Blob([
278    new Uint8Array([0x50, 0x41, 0x53, 0x53]),
279    new Int8Array([0x50, 0x41, 0x53, 0x53]),
280    new Uint16Array([0x4150, 0x5353]),
281    new Int16Array([0x4150, 0x5353]),
282    new Uint32Array([0x53534150]),
283    new Int32Array([0x53534150]),
284    new Float32Array([0xD341500000]),
285  ]);
286
287  assert.strictEqual(blob.size, 28);
288  assert.strictEqual(blob.type, '');
289})().then(common.mustCall());
290
291{
292  // Testing the defaults
293  [undefined, null, Object.create(null), { type: undefined }, {
294    get type() {}, // eslint-disable-line getter-return
295  }].forEach((options) => {
296    assert.strictEqual(
297      new Blob([], options).type,
298      new Blob([]).type,
299    );
300  });
301
302  Reflect.defineProperty(Object.prototype, 'type', {
303    __proto__: null,
304    configurable: true,
305    get: common.mustCall(() => 3, 7),
306  });
307
308  [{}, [], () => {}, Number, new Number(), new String(), new Boolean()].forEach(
309    (options) => {
310      assert.strictEqual(new Blob([], options).type, '3');
311    },
312  );
313  [0, '', true, Symbol(), 0n].forEach((options) => {
314    assert.throws(() => new Blob([], options), { code: 'ERR_INVALID_ARG_TYPE' });
315  });
316
317  delete Object.prototype.type;
318}
319