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