Source code

Revision control

Copy as Markdown

Other Tools

// |reftest| skip-if(!this.hasOwnProperty("ReadableStream"))
if ("ignoreUnhandledRejections" in this) {
ignoreUnhandledRejections();
}
async function test() {
if (typeof newGlobal !== 'undefined') {
otherGlobal = newGlobal();
}
OtherReadableStream = otherGlobal.ReadableStream;
ReadableStreamReader = new ReadableStream().getReader().constructor;
OtherReadableStreamReader = new otherGlobal.ReadableStream().getReader().constructor;
let byteStreamsSupported = false;
try {
let controller;
let reader = new ReadableStream({
start(c) {
ByteStreamController = c.constructor;
controller = c;
},
type: "bytes"
}).getReader({ mode: "byob" })
ReadableStreamBYOBReader = reader.constructor;
reader.read(new Uint8Array(10));
BYOBRequest = controller.byobRequest.constructor;
reader = new otherGlobal.ReadableStream({
start(c) {
OtherByteStreamController = c.constructor;
controller = c;
},
type: "bytes"
}).getReader({ mode: "byob" });
OtherReadableStreamBYOBReader = reader.constructor;
reader.read(new Uint8Array(10));
OtherBYOBRequest = controller.byobRequest.constructor;
BYOBRequestGetter = Object.getOwnPropertyDescriptor(ByteStreamController.prototype,
"byobRequest").get;
OtherBYOBRequestGetter = Object.getOwnPropertyDescriptor(OtherByteStreamController.prototype,
"byobRequest").get;
byteStreamsSupported = true;
} catch (e) {
}
let chunk = { name: "chunk" };
let enqueuedError = { name: "enqueuedError" };
let controller;
let stream;
let otherStream;
let otherController;
let reader;
let otherReader;
function getFreshInstances(type, otherType = type) {
stream = new ReadableStream({ start(c) { controller = c; }, type });
otherStream = new OtherReadableStream({ start(c) { otherController = c; }, type: otherType });
}
getFreshInstances();
Controller = controller.constructor;
OtherController = otherController.constructor;
otherReader = OtherReadableStream.prototype.getReader.call(stream);
assertEq(otherReader instanceof ReadableStreamReader, false);
assertEq(otherReader instanceof OtherReadableStreamReader, true);
assertEq(otherController instanceof Controller, false);
assertEq(stream.locked, true);
Object.defineProperty(stream, "locked",
Object.getOwnPropertyDescriptor(OtherReadableStream.prototype, "locked"));
assertEq(stream.locked, true);
request = otherReader.read();
assertEq(request instanceof otherGlobal.Promise, true);
controller.close();
assertEq(await request instanceof Object, true);
getFreshInstances();
otherReader = new OtherReadableStreamReader(stream);
getFreshInstances();
otherReader = new OtherReadableStreamReader(stream);
let cancelSucceeded = false;
let cancelPromise = ReadableStreamReader.prototype.cancel.call(otherReader);
assertEq(cancelPromise instanceof Promise, true);
assertEq(await cancelPromise, undefined);
getFreshInstances();
otherReader = new OtherReadableStreamReader(stream);
let closeSucceeded = false;
Object.defineProperty(otherReader, "closed",
Object.getOwnPropertyDescriptor(ReadableStreamReader.prototype, "closed"));
let closedPromise = otherReader.closed;
assertEq(closedPromise instanceof otherGlobal.Promise, true);
controller.close();
assertEq(await closedPromise, undefined);
getFreshInstances();
otherReader = OtherReadableStream.prototype.getReader.call(stream);
request = otherReader.read();
assertEq(request instanceof otherGlobal.Promise, true);
otherController.close.call(controller);
assertEq(await request instanceof otherGlobal.Object, true);
getFreshInstances();
assertEq(controller.desiredSize, 1);
Object.defineProperty(controller, "desiredSize",
Object.getOwnPropertyDescriptor(OtherController.prototype, "desiredSize"));
assertEq(controller.desiredSize, 1);
request = otherReader.read();
controller.error(enqueuedError);
expectException(() => controller.close(), TypeError);
expectException(() => otherController.close.call(controller), otherGlobal.TypeError);
otherReader.releaseLock();
reader = stream.getReader();
assertEq(await expectAsyncException(async () => reader.read(), enqueuedError.constructor),
enqueuedError);
otherReader.releaseLock.call(reader);
assertEq(reader.closed instanceof otherGlobal.Promise, true);
// getFreshInstances();
// reader = stream.getReader();
// request = otherReader.read.call(reader);
// assertEq(request instanceof otherGlobal.Promise, true);
// controller.enqueue(chunk);
// assertEq((await request).value, chunk);
// reader.releaseLock();
// getFreshInstances();
// reader = stream.getReader();
// request = otherReader.read.call(reader);
// otherController.enqueue.call(controller, chunk);
// otherController.enqueue.call(controller, new otherGlobal.Uint8Array(10));
// controller.enqueue(new otherGlobal.Uint8Array(10));
// request = otherReader.read.call(reader);
getFreshInstances();
stream = new ReadableStream({ start(c) { controller = c; } }, { size() {return 1} });
otherController.enqueue.call(controller, chunk);
otherController.enqueue.call(controller, new otherGlobal.Uint8Array(10));
controller.enqueue(new otherGlobal.Uint8Array(10));
getFreshInstances();
controller.close();
expectException(() => controller.enqueue(new otherGlobal.Uint8Array(10)), TypeError);
expectException(() => otherController.enqueue.call(controller, chunk), otherGlobal.TypeError);
expectException(() => otherController.enqueue.call(controller, new otherGlobal.Uint8Array(10)),
otherGlobal.TypeError);
getFreshInstances();
let [branch1, branch2] = otherGlobal.ReadableStream.prototype.tee.call(stream);
assertEq(branch1 instanceof otherGlobal.ReadableStream, true);
assertEq(branch2 instanceof otherGlobal.ReadableStream, true);
controller.enqueue(chunk);
reader = branch1.getReader();
result = await reader.read();
reader.releaseLock();
let subPromiseCreated = false;
let speciesInvoked = false;
class SubPromise extends Promise {
constructor(executor) {
super(executor);
subPromiseCreated = true;
}
}
Object.defineProperty(Promise, Symbol.species, {get: function() {
speciesInvoked = true;
return SubPromise;
}
});
otherGlobal.eval(`
subPromiseCreated = false;
speciesInvoked = false;
class OtherSubPromise extends Promise {
constructor(executor) {
super(executor);
subPromiseCreated = true;
}
}
Object.defineProperty(Promise, Symbol.species, {get: function() {
speciesInvoked = true;
return OtherSubPromise;
}
});`);
controller.error(enqueuedError);
subPromiseCreated = false;
speciesInvoked = false;
otherGlobal.subPromiseCreated = false;
otherGlobal.speciesInvoked = false;
let cancelPromise1 = branch1.cancel({ name: "cancel 1" });
assertEq(cancelPromise1 instanceof otherGlobal.Promise, true);
assertEq(subPromiseCreated, false);
assertEq(speciesInvoked, false);
assertEq(otherGlobal.subPromiseCreated, false);
assertEq(otherGlobal.speciesInvoked, false);
subPromiseCreated = false;
speciesInvoked = false;
otherGlobal.subPromiseCreated = false;
otherGlobal.speciesInvoked = false;
let cancelPromise2 = branch2.cancel({ name: "cancel 2" });
assertEq(cancelPromise2 instanceof otherGlobal.Promise, true);
assertEq(subPromiseCreated, false);
assertEq(speciesInvoked, false);
assertEq(otherGlobal.subPromiseCreated, false);
assertEq(otherGlobal.speciesInvoked, false);
await 1;
getFreshInstances();
[branch1, branch2] = otherGlobal.ReadableStream.prototype.tee.call(stream);
assertEq(branch1 instanceof otherGlobal.ReadableStream, true);
assertEq(branch2 instanceof otherGlobal.ReadableStream, true);
controller.enqueue(chunk);
reader = branch1.getReader();
result = await reader.read();
reader.releaseLock();
assertEq(result.value, chunk);
controller.error(enqueuedError);
subPromiseCreated = false;
speciesInvoked = false;
otherGlobal.subPromiseCreated = false;
otherGlobal.speciesInvoked = false;
cancelPromise1 = ReadableStream.prototype.cancel.call(branch1, { name: "cancel 1" });
assertEq(cancelPromise1 instanceof Promise, true);
assertEq(subPromiseCreated, false);
assertEq(speciesInvoked, false);
assertEq(otherGlobal.subPromiseCreated, false);
assertEq(otherGlobal.speciesInvoked, false);
subPromiseCreated = false;
speciesInvoked = false;
otherGlobal.subPromiseCreated = false;
otherGlobal.speciesInvoked = false;
cancelPromise2 = ReadableStream.prototype.cancel.call(branch2, { name: "cancel 2" });
assertEq(cancelPromise2 instanceof Promise, true);
assertEq(subPromiseCreated, false);
assertEq(speciesInvoked, false);
assertEq(otherGlobal.subPromiseCreated, false);
assertEq(otherGlobal.speciesInvoked, false);
if (!byteStreamsSupported) {
return;
}
if (typeof nukeCCW === 'function') {
getFreshInstances("bytes");
assertEq(otherController instanceof OtherByteStreamController, true);
reader = ReadableStream.prototype.getReader.call(otherStream);
otherGlobal.reader = reader;
otherGlobal.nukeCCW(otherGlobal.reader);
let chunk = new Uint8Array(10);
expectException(() => otherController.enqueue(chunk), otherGlobal.TypeError);
// otherController.error();
expectException(() => reader.read(), TypeError);
}
function testBYOBRequest(controller, view) {
const request = new BYOBRequest(controller, view);
let storedView = request.view;
assertEq(storedView, view);
storedView = Object.getOwnPropertyDescriptor(OtherBYOBRequest.prototype, "view").get.call(request);
assertEq(storedView, view);
request.respond(10);
OtherBYOBRequest.prototype.respond.call(request, 10);
request.respondWithNewView(new view.constructor(10));
OtherBYOBRequest.prototype.respondWithNewView.call(request, new view.constructor(10));
}
expectException(() => new BYOBRequest(), TypeError);
getFreshInstances("bytes");
expectException(() => new BYOBRequest(controller, new Uint8Array(10)), TypeError);
expectException(() => new BYOBRequest(otherController, new Uint8Array(10)), TypeError);
expectException(() => new BYOBRequest(otherController, new Uint8Array(10)), TypeError);
expectException(() => new BYOBRequest(otherController, new otherGlobal.Uint8Array(10)), TypeError);
getFreshInstances("bytes");
reader = stream.getReader({ mode: "byob" });
request = OtherReadableStreamBYOBReader.prototype.read.call(reader, new Uint8Array(10));
assertEq(request instanceof otherGlobal.Promise, true);
controller.enqueue(new Uint8Array([1, 2, 3, 4]));
result = await request;
getFreshInstances("bytes");
reader = stream.getReader({ mode: "byob" });
request = OtherReadableStreamBYOBReader.prototype.read.call(reader, new Uint8Array(10));
assertEq(request instanceof otherGlobal.Promise, true);
try {
let byobRequest = OtherBYOBRequestGetter.call(controller);
} catch (e) {
print(e, '\n', e.stack);
}
controller.enqueue(new Uint8Array([1, 2, 3, 4]));
result = await request;
await 1;
}
function expectException(closure, errorType) {
let error;
try {
closure();
} catch (e) {
error = e;
}
assertEq(error !== undefined, true);
assertEq(error.constructor, errorType);
return error;
}
async function expectAsyncException(closure, errorType) {
let error;
try {
await closure();
} catch (e) {
error = e;
}
assertEq(error !== undefined, true);
assertEq(error.constructor, errorType);
return error;
}
async function runTest() {
try {
await test();
} catch (e) {
assertEq(false, true, `Unexpected exception ${e}\n${e.stack}`);
}
console.log("done");
if (typeof reportCompare === "function")
reportCompare(true, true);
}
runTest();