blob: fe82fa5a1a36b06176f643010686361f3bbbc40b [file] [log] [blame]
'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();