blob: d5a6f8e778f7c2d49d32b1b442a8f88c79193fb3 [file] [log] [blame]
'use strict';
if (self.importScripts) {
self.importScripts('../resources/testharness.js');
}
// FIXME: Remove next line when bug https://bugs.webkit.org/show_bug.cgi?id=167697
// is fixed. For the moment, so that test may pass, we have to insert a reference
// to Uint8Array here (otherwise, the private variable cannot be resolved).
const d = new Uint8Array(1);
test(function() {
let controller;
const rs = new ReadableStream({
start: function(c) {
controller = c;
},
type: "bytes"
});
assert_equals(controller.byobRequest, undefined, "by default byobRequest should be undefined");
}, "By default, byobRequest should be undefined");
test(function() {
let controller;
const autoAllocateChunkSize = 128;
const rs = new ReadableStream({
autoAllocateChunkSize,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
assert_equals(byobReq.view.length, autoAllocateChunkSize, "byobRequest length should be equal to autoAllocateChunkSize value")
}, "byobRequest.view length should be equal to autoAllocateChunkSize")
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
assert_throws(new TypeError("Can only call ReadableStreamBYOBRequest.respond on instances of ReadableStreamBYOBRequest"),
function() { byobReq.respond.apply(rs, 1); });
}, "Calling respond() with a this object different from ReadableStreamBYOBRequest should throw a TypeError");
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
assert_throws(new RangeError("bytesWritten has an incorrect value"),
function() { byobReq.respond(-1); });
}, "Calling respond() with a negative bytesWritten value should throw a RangeError");
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
assert_throws(new RangeError("bytesWritten has an incorrect value"),
function() { byobReq.respond("abc"); });
}, "Calling respond() with a bytesWritten value which is not a number should throw a RangeError");
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
assert_throws(new RangeError("bytesWritten has an incorrect value"),
function() { byobReq.respond(Number.POSITIVE_INFINITY); });
}, "Calling respond() with a positive infinity bytesWritten value should throw a RangeError");
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
controller.close();
assert_throws(new TypeError("bytesWritten is different from 0 even though stream is closed"),
function() { byobReq.respond(1); });
}, "Calling respond() with a bytesWritten value different from 0 when stream is closed should throw a TypeError");
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
// FIXME: When ReadableStreamBYOBReader is implemented, another test (or even several ones)
// based on this one should be added so that reader's readIntoRequests attribute is not empty
// and currently unreachable code is reached.
rs.getReader().read();
const byobReq = controller.byobRequest;
controller.close();
byobReq.respond(0);
}, "Calling respond() with a bytesWritten value of 0 when stream is closed should succeed");
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
assert_throws(new RangeError("bytesWritten value is too great"),
function() { byobReq.respond(17); });
}, "Calling respond() with a bytesWritten value greater than autoAllocateChunkSize should fail");
promise_test(function() {
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
pull: function(controller) {
const br = controller.byobRequest;
br.view[0] = 1;
br.view[1] = 2;
br.respond(2);
},
type: "bytes"
});
return rs.getReader().read().then(result => {
assert_equals(result.value.byteLength, 2);
assert_equals(result.value.byteOffset, 0);
assert_equals(result.value.buffer.byteLength, 16);
assert_equals(result.value[0], 1);
assert_equals(result.value[1], 2);
});
}, "Calling respond() with a bytesWritten value lower than autoAllocateChunkSize should succeed");
// FIXME: when ReadableStreamBYOBReader is implemented, add tests with elementSize different from 1
// so that more code can be covered.
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
assert_throws(new TypeError("Can only call ReadableStreamBYOBRequest.respondWithNewView on instances of ReadableStreamBYOBRequest"),
function() { byobReq.respondWithNewView.apply(rs, new Uint8Array(1)); });
}, "Calling respondWithNewView() with a this object different from ReadableStreamBYOBRequest should throw a TypeError");
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
assert_throws(new TypeError("Provided view is not an object"),
function() { byobReq.respondWithNewView(function() {}); });
}, "Calling respondWithNewView() with an argument that is not an object should throw a TypeError");
test(function() {
let controller;
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
start: function(c) {
controller = c;
},
type: "bytes"
});
rs.getReader().read();
const byobReq = controller.byobRequest;
assert_throws(new TypeError("Provided view is not an ArrayBufferView"),
function() { byobReq.respondWithNewView({}); });
}, "Calling respondWithNewView() with an argument that is not an ArrayBufferView should throw a TypeError");
promise_test(function() {
const rs = new ReadableStream({
autoAllocateChunkSize: 2,
pull: function(controller) {
const newView = new Uint8Array([3, 6]);
const br = controller.byobRequest;
br.respondWithNewView(newView);
},
type: "bytes"
});
return rs.getReader().read().then(result => {
assert_equals(result.value.byteLength, 2);
assert_equals(result.value.byteOffset, 0);
assert_equals(result.value.buffer.byteLength, 2);
assert_equals(result.value[0], 3);
assert_equals(result.value[1], 6);
});
}, "When using autoAllocateChunkSize, calling respondWithNewView() should succeed if view.byteLength is equal to autoAllocateChunkSize");
promise_test(function(test) {
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
pull: function(controller) {
const newView = new Uint8Array([3, 6]);
const br = controller.byobRequest;
br.respondWithNewView(newView);
},
type: "bytes"
});
const error = new RangeError("Invalid value for view.byteLength");
return promise_rejects(test, error, rs.getReader().read());
}, "When using autoAllocateChunkSize, calling respondWithNewView() should throw a RangeError if view.byteOffset is different from 0");
promise_test(function(test) {
const rs = new ReadableStream({
autoAllocateChunkSize: 16,
pull: function(controller) {
const buffer = new ArrayBuffer(3);
const newView = new Uint8Array(buffer, 1); // byteOffset of 1
const br = controller.byobRequest;
br.respondWithNewView(newView);
},
type: "bytes"
});
const error = new RangeError("Invalid value for view.byteOffset");
return promise_rejects(test, error, rs.getReader().read());
}, "When using autoAllocateChunkSize, calling respondWithNewView() should throw a RangeError if view.byteLength is different from autoAllocateChunkSize");
done();