| // META: title=Blob textStream | |
| // META: global=window,worker | |
| // META: script=../support/Blob.js | |
| 'use strict'; | |
| async function readAllChunks(stream) { | |
| const reader = stream.getReader(); | |
| const chunks = []; | |
| while (true) { | |
| const {done, value} = await reader.read(); | |
| if (done) { | |
| break; | |
| } | |
| chunks.push(value); | |
| } | |
| return chunks; | |
| } | |
| test(() => { | |
| assert_true('textStream' in Blob.prototype, "textStream exists on Blob.prototype"); | |
| assert_equals(typeof Blob.prototype.textStream, "function", "Blob.prototype.textStream is a function"); | |
| }, "textStream method existence"); | |
| promise_test(async () => { | |
| const blob = new Blob(["hello world"]); | |
| const stream = blob.textStream(); | |
| assert_true(stream instanceof ReadableStream, "textStream() returns a ReadableStream"); | |
| const chunks = await readAllChunks(stream); | |
| assert_greater_than(chunks.length, 0); | |
| for (const chunk of chunks) { | |
| assert_equals(typeof chunk, "string", "each chunk should be a string"); | |
| } | |
| assert_equals(chunks.join(""), "hello world", "concatenated chunks match the blob content"); | |
| }, "Blob.textStream() basic functionality"); | |
| promise_test(async () => { | |
| const blob = new Blob(); | |
| const stream = blob.textStream(); | |
| assert_true(stream instanceof ReadableStream); | |
| const chunks = await readAllChunks(stream); | |
| assert_equals(chunks.length, 0, "no chunks should be read from empty blob textStream"); | |
| }, "Blob.textStream() with empty blob"); | |
| promise_test(async () => { | |
| const blob = new Blob(["hello ", "world"]); | |
| const stream = blob.textStream(); | |
| const chunks = await readAllChunks(stream); | |
| assert_equals(chunks.join(""), "hello world"); | |
| }, "Blob.textStream() with multi-part blob"); | |
| promise_test(async () => { | |
| const buffer = new Uint8Array([0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00]); // "hello" in UTF-16LE | |
| const blob = new Blob([buffer], { | |
| type: "text/plain; charset=utf-16le" | |
| }); | |
| const stream = blob.textStream(); | |
| const chunks = await readAllChunks(stream); | |
| assert_equals(chunks.join(""), "h\0e\0l\0l\0o\0", "ignores charset=utf-16le type parameter"); | |
| }, "Blob.textStream() ignores type charset (UTF-16LE)"); | |
| promise_test(async () => { | |
| const blob = new Blob([new TextEncoder().encode("hello")], { | |
| type: "text/plain; charset=invalid-charset" | |
| }); | |
| const stream = blob.textStream(); | |
| const chunks = await readAllChunks(stream); | |
| assert_equals(chunks.join(""), "hello", "ignores invalid-charset type parameter and decodes as UTF-8"); | |
| }, "Blob.textStream() ignores invalid type charset (invalid-charset)"); | |
| promise_test(async () => { | |
| const blob = new Blob([new TextEncoder().encode("é")], { | |
| type: "text/plain; charset=iso-8859-1" | |
| }); | |
| const stream = blob.textStream(); | |
| const chunks = await readAllChunks(stream); | |
| assert_equals(chunks.join(""), "é", "ignores charset=iso-8859-1 type parameter and decodes as UTF-8"); | |
| }, "Blob.textStream() ignores type charset (iso-8859-1)"); | |
| promise_test(async () => { | |
| const blob = new Blob(["hello"]); | |
| const stream1 = blob.textStream(); | |
| const stream2 = blob.textStream(); | |
| assert_not_equals(stream1, stream2, "multiple calls return new streams"); | |
| const chunks1 = await readAllChunks(stream1); | |
| const chunks2 = await readAllChunks(stream2); | |
| assert_equals(chunks1.join(""), "hello"); | |
| assert_equals(chunks2.join(""), "hello"); | |
| }, "Blob.textStream() can be called multiple times"); |