430 lines
12 KiB
JavaScript
430 lines
12 KiB
JavaScript
'use strict';
|
|
|
|
if (self.importScripts) {
|
|
self.importScripts('../resources/testharness.js');
|
|
}
|
|
|
|
test(function() {
|
|
const rs = new ReadableStream({
|
|
type: "bytes"
|
|
});
|
|
}, "Creating a ReadableStream with an underlyingSource with type property set to 'bytes' should succeed");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
assert_throws(new TypeError("Can only call ReadableByteStreamController.error on instances of ReadableByteStreamController"),
|
|
function() { controller.error.apply(rs); });
|
|
}, "Calling error() with a this object different from ReadableByteStreamController should throw a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
assert_throws(new TypeError("Can only call ReadableByteStreamController.close on instances of ReadableByteStreamController"),
|
|
function() { controller.close.apply(rs); });
|
|
}, "Calling close() with a this object different from ReadableByteStreamController should throw a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
assert_throws(new TypeError("Can only call ReadableByteStreamController.enqueue on instances of ReadableByteStreamController"),
|
|
function() { controller.enqueue.apply(rs, new Int8Array(1)); });
|
|
}, "Calling enqueue() with a this object different from ReadableByteStreamController should throw a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
controller.enqueue(new Int8Array(2));
|
|
controller.close();
|
|
|
|
assert_throws(new TypeError("ReadableByteStreamController is requested to close"),
|
|
function() { controller.enqueue(new Int8Array(1)); });
|
|
}, "Calling enqueue() when close has been requested but not yet performed should throw a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
controller.close();
|
|
|
|
assert_throws(new TypeError("ReadableStream is not readable"),
|
|
function() {
|
|
controller.enqueue(new Int8Array(1));
|
|
});
|
|
}, "Calling enqueue() when stream is not readable should throw a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
const invalidChunk = function() {};
|
|
|
|
assert_throws(new TypeError("Provided chunk is not an object"),
|
|
function() { controller.enqueue(invalidChunk); });
|
|
}, "Calling enqueue() with a chunk that is not an object should trhow a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
const invalidChunk = {};
|
|
|
|
assert_throws(new TypeError("Provided chunk is not an object"),
|
|
function() { controller.enqueue(invalidChunk); });
|
|
}, "Calling enqueue() with a chunk that is not an ArrayBufferView should throw a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
assert_throws(new TypeError("ReadableStream is not readable"),
|
|
function() {
|
|
controller.close();
|
|
controller.error();
|
|
});
|
|
}, "Calling error() after calling close() should throw a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
assert_throws(new TypeError("ReadableStream is not readable"),
|
|
function() {
|
|
controller.error();
|
|
controller.error();
|
|
});
|
|
}, "Calling error() after calling error() should throw a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
assert_throws(new TypeError("Close has already been requested"),
|
|
function() {
|
|
controller.close();
|
|
controller.close();
|
|
});
|
|
}, "Calling close() after calling close() should throw a TypeError");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
assert_throws(new TypeError("ReadableStream is not readable"),
|
|
function() {
|
|
controller.error();
|
|
controller.close();
|
|
});
|
|
}, "Calling close() after calling error() should throw a TypeError");
|
|
|
|
promise_test(function(test) {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
const myError = new Error("my error");
|
|
controller.error(myError);
|
|
|
|
return promise_rejects(test, myError, rs.getReader().read());
|
|
}, "Calling read() on a reader associated to a controller that has been errored should fail with provided error");
|
|
|
|
promise_test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
controller.close();
|
|
|
|
return rs.getReader().read().then(
|
|
function(res) {
|
|
assert_object_equals(res, {value: undefined, done: true});
|
|
}
|
|
);
|
|
}, "Calling read() on a reader associated to a controller that has been closed should not be rejected");
|
|
|
|
promise_test(function(test) {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
const myError = new Error("My error");
|
|
let readingPromise = rs.getReader().read();
|
|
controller.error(myError);
|
|
|
|
return promise_rejects(test, myError, readingPromise);
|
|
}, "Pending reading promise should be rejected if controller is errored (case where autoAllocateChunkSize is undefined)");
|
|
|
|
promise_test(function(test) {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
autoAllocateChunkSize: 128,
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
const myError = new Error("My error");
|
|
let readingPromise = rs.getReader().read();
|
|
controller.error(myError);
|
|
|
|
return promise_rejects(test, myError, readingPromise);
|
|
}, "Pending reading promise should be rejected if controller is errored (case where autoAllocateChunkSize is specified)");
|
|
|
|
promise_test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
const buffer = new Uint8Array([3]);
|
|
controller.enqueue(buffer);
|
|
|
|
return rs.getReader().read().then(
|
|
function(res) {
|
|
assert_object_equals(res, {value: buffer, done: false});
|
|
}
|
|
);
|
|
}, "Enqueuing a chunk, getting a reader and calling read should result in a promise resolved with said chunk");
|
|
|
|
promise_test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
let promise = rs.getReader().read();
|
|
const buffer = new Uint8Array([1]);
|
|
controller.enqueue(buffer);
|
|
return promise.then(
|
|
function(res) {
|
|
assert_object_equals(res, {value: buffer, done: false});
|
|
}
|
|
);
|
|
}, "Getting a reader, calling read and enqueuing a chunk should result in the read promise being resolved with said chunk");
|
|
|
|
promise_test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
const reader = rs.getReader();
|
|
const buffer = new Uint8Array([1]);
|
|
controller.enqueue(buffer);
|
|
return reader.read().then(
|
|
function(res) {
|
|
assert_object_equals(res, {value: buffer, done: false});
|
|
}
|
|
);
|
|
}, "Getting a reader, enqueuing a chunk and finally calling read should result in a promise resolved with said chunk");
|
|
|
|
test(function() {
|
|
let controller;
|
|
|
|
const rs = new ReadableStream({
|
|
start: function(c) {
|
|
controller = c;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
assert_equals(controller.desiredSize, 0, "by default initial value of desiredSize should be 0");
|
|
}, "By default initial value of desiredSize should be 0");
|
|
|
|
promise_test(function() {
|
|
const rs = new ReadableStream({
|
|
type: "bytes"
|
|
});
|
|
|
|
return rs.cancel().then(
|
|
function(res) {
|
|
assert_object_equals(res, undefined);
|
|
}
|
|
);
|
|
}, "Calling cancel() on a readable ReadableStream that is not locked to a reader should return a promise whose fulfillment handler returns undefined");
|
|
|
|
promise_test(function() {
|
|
let pullCalls = 0;
|
|
const rs = new ReadableStream({
|
|
pull: function () {
|
|
pullCalls++;
|
|
},
|
|
type: "bytes"
|
|
});
|
|
return new Promise(function(resolve, reject) {
|
|
setTimeout(function() {
|
|
if (pullCalls === 0)
|
|
resolve("ok");
|
|
else
|
|
reject("No call should have been made to pull function");
|
|
}, 200);
|
|
});
|
|
}, "Test that pull is not called when a new ReadableStream is created with default strategy parameters and a ReadableByteStreamController");
|
|
|
|
promise_test(function() {
|
|
let pullCalls = 0;
|
|
const rs = new ReadableStream({
|
|
pull: function () {
|
|
pullCalls++;
|
|
},
|
|
type: "bytes"
|
|
}, {
|
|
highWaterMark: 1
|
|
});
|
|
return new Promise(function(resolve, reject) {
|
|
setTimeout(function() {
|
|
if (pullCalls === 1)
|
|
resolve("ok");
|
|
else
|
|
reject("1 call should have been made to pull function");
|
|
}, 200);
|
|
});
|
|
}, "Test that pull is called once when a new ReadableStream is created with a highWaterMark of 1 and a ReadableByteStreamController");
|
|
|
|
promise_test(function() {
|
|
const myError = new Error("Pull failed");
|
|
const rs = new ReadableStream({
|
|
pull: function () {
|
|
throw myError;
|
|
},
|
|
type: "bytes"
|
|
}, {
|
|
highWaterMark: 1
|
|
});
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
setTimeout(function() {
|
|
rs.cancel().then(
|
|
function (res) { reject("Cancel should return a promise resolved with rejection"); },
|
|
function (err) {
|
|
if (err === myError)
|
|
resolve();
|
|
else
|
|
reject("Reason for rejection should be the error that was thrown in pull");
|
|
}
|
|
)
|
|
}, 200)});
|
|
}, "For a ReadableStream created with a highWaterMark of 1 and a ReadableByteStreamController, calling cancel after pull has thrown an error should result in a promise rejected with the same error");
|
|
|
|
promise_test(function() {
|
|
const myError = new Error("Start failed");
|
|
const rs = new ReadableStream({
|
|
start: function () {
|
|
return new Promise(function(resolve, reject) { reject(myError); });
|
|
},
|
|
type: "bytes"
|
|
});
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
setTimeout(function() {
|
|
rs.cancel().then(
|
|
function (res) { reject("An error should have been thrown"); },
|
|
function (err) {
|
|
if (err === myError)
|
|
resolve();
|
|
else
|
|
reject("Reason for rejection should be the error that led the promise returned by start to fail");
|
|
}
|
|
)
|
|
}, 200)});
|
|
}, "Calling cancel after creating a ReadableStream with an underlyingByteStream's start function returning a rejected promise should result in a promise rejected with the same error");
|
|
|
|
done();
|