mirror of
https://github.com/servo/servo.git
synced 2025-08-18 11:55:39 +01:00
Update web-platform-tests to revision 8a2ceb5f18911302b7a5c1cd2791f4ab50ad4326
This commit is contained in:
parent
462c272380
commit
1f531f66ea
5377 changed files with 174916 additions and 84369 deletions
|
@ -104,4 +104,11 @@ test(() => {
|
|||
|
||||
}, 'ByteLengthQueuingStrategy\'s highWaterMark property can be set to anything');
|
||||
|
||||
test(() => {
|
||||
|
||||
assert_equals(ByteLengthQueuingStrategy.name, 'ByteLengthQueuingStrategy',
|
||||
'ByteLengthQueuingStrategy.name must be "ByteLengthQueuingStrategy"');
|
||||
|
||||
}, 'ByteLengthQueuingStrategy.name is correct');
|
||||
|
||||
done();
|
||||
|
|
|
@ -103,4 +103,11 @@ test(() => {
|
|||
|
||||
}, 'CountQueuingStrategy\'s highWaterMark property can be set to anything');
|
||||
|
||||
test(() => {
|
||||
|
||||
assert_equals(CountQueuingStrategy.name, 'CountQueuingStrategy',
|
||||
'CountQueuingStrategy.name must be "CountQueuingStrategy"');
|
||||
|
||||
}, 'CountQueuingStrategy.name is correct');
|
||||
|
||||
done();
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
"use strict";
|
||||
// Usage: `node generate-test-wrappers.js js-filename1.js [js-filename2.js ...]` will generate:
|
||||
// - js-filename1.https.html
|
||||
// - js-filename1.html
|
||||
// - js-filename1.sharedworker.html
|
||||
// - js-filename1.dedicatedworker.html
|
||||
// - js-filename1.serviceworker.html
|
||||
// - js-filename1.serviceworker.https.html
|
||||
// (for each passed filename)
|
||||
//
|
||||
// It will turn any importScripts inside the .js file into <script>s in the browser context wrapper.
|
||||
//
|
||||
// This could become obsolete if all of the following happen:
|
||||
// - https://github.com/w3c/web-platform-tests/issues/4210 gets fixed, allowing .any.js to work with all four contexts
|
||||
// - We find some way to include scripts (<script>/importScripts) in .any.js files
|
||||
// - Chrome becomes able to run .any.js tests on its infrastructure
|
||||
// (https://bugs.chromium.org/p/chromium/issues/detail?id=653514)
|
||||
// This could become obsolete if https://github.com/w3c/web-platform-tests/issues/4210 gets fixed,
|
||||
// allowing .any.js to work with all four contexts.
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
|
|
@ -30,6 +30,10 @@ function duckTypedPassThroughTransform() {
|
|||
};
|
||||
}
|
||||
|
||||
function uninterestingReadableWritablePair() {
|
||||
return { writable: new WritableStream(), readable: new ReadableStream() };
|
||||
}
|
||||
|
||||
promise_test(() => {
|
||||
const readableEnd = sequentialReadableStream(5).pipeThrough(duckTypedPassThroughTransform());
|
||||
|
||||
|
@ -68,10 +72,12 @@ test(() => {
|
|||
const fakeReadable = { fake: 'readable' };
|
||||
const arg2 = { arg: 'arg2' };
|
||||
const arg3 = { arg: 'arg3' };
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, { writable: fakeWritable, readable: fakeReadable }, arg2, arg3);
|
||||
const result =
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, { writable: fakeWritable, readable: fakeReadable }, arg2, arg3);
|
||||
|
||||
assert_array_equals(calledWithArgs, [fakeWritable, arg2],
|
||||
'The this value\'s pipeTo method should be called with the appropriate arguments');
|
||||
assert_equals(result, fakeReadable, 'return value should be the passed readable property');
|
||||
|
||||
}, 'pipeThrough generically calls pipeTo with the appropriate args');
|
||||
|
||||
|
@ -82,7 +88,7 @@ test(() => {
|
|||
}
|
||||
};
|
||||
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, { });
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, uninterestingReadableWritablePair());
|
||||
|
||||
// Test passes if this doesn't throw or crash.
|
||||
|
||||
|
@ -98,7 +104,7 @@ test(() => {
|
|||
}
|
||||
};
|
||||
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, { });
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, uninterestingReadableWritablePair());
|
||||
|
||||
// Test passes if this doesn't throw or crash.
|
||||
|
||||
|
@ -111,7 +117,7 @@ promise_test(() => {
|
|||
}
|
||||
};
|
||||
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, { });
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, uninterestingReadableWritablePair());
|
||||
|
||||
// The test harness should complain about unhandled rejections by then.
|
||||
return flushAsyncEvents();
|
||||
|
@ -119,7 +125,7 @@ promise_test(() => {
|
|||
}, 'pipeThrough should mark a real promise from a fake readable as handled');
|
||||
|
||||
test(() => {
|
||||
let thenCalled = false
|
||||
let thenCalled = false;
|
||||
let catchCalled = false;
|
||||
const dummy = {
|
||||
pipeTo() {
|
||||
|
@ -136,7 +142,7 @@ test(() => {
|
|||
};
|
||||
|
||||
// An incorrect implementation which uses an internal method to mark the promise as handled will throw or crash here.
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, { });
|
||||
ReadableStream.prototype.pipeThrough.call(dummy, uninterestingReadableWritablePair());
|
||||
|
||||
// An incorrect implementation that tries to mark the promise as handled by calling .then() or .catch() on the object
|
||||
// will fail these tests.
|
||||
|
@ -144,4 +150,112 @@ test(() => {
|
|||
assert_false(catchCalled, 'catch should not be called');
|
||||
}, 'pipeThrough should not be fooled by an object whose instanceof Promise returns true');
|
||||
|
||||
test(() => {
|
||||
const pairs = [
|
||||
{},
|
||||
{ readable: undefined, writable: undefined },
|
||||
{ readable: 'readable' },
|
||||
{ readable: 'readable', writable: undefined },
|
||||
{ writable: 'writable' },
|
||||
{ readable: undefined, writable: 'writable' }
|
||||
];
|
||||
for (let i = 0; i < pairs.length; ++i) {
|
||||
const pair = pairs[i];
|
||||
const rs = new ReadableStream();
|
||||
assert_throws(new TypeError(), () => rs.pipeThrough(pair),
|
||||
`pipeThrough should throw for argument ${JSON.stringify(pair)} (index ${i});`);
|
||||
}
|
||||
}, 'undefined readable or writable arguments should cause pipeThrough to throw');
|
||||
|
||||
test(() => {
|
||||
const invalidArguments = [null, 0, NaN, '', [], {}, false, () => {}];
|
||||
for (const arg of invalidArguments) {
|
||||
const rs = new ReadableStream();
|
||||
assert_equals(arg, rs.pipeThrough({ writable: new WritableStream(), readable: arg }),
|
||||
'pipeThrough() should not throw for readable: ' + JSON.stringify(arg));
|
||||
const rs2 = new ReadableStream();
|
||||
assert_equals(rs2, rs.pipeThrough({ writable: arg, readable: rs2 }),
|
||||
'pipeThrough() should not throw for writable: ' + JSON.stringify(arg));
|
||||
}
|
||||
}, 'invalid but not undefined arguments should not cause pipeThrough to throw');
|
||||
|
||||
test(() => {
|
||||
|
||||
const thisValue = {
|
||||
pipeTo() {
|
||||
assert_unreached('pipeTo should not be called');
|
||||
}
|
||||
};
|
||||
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', thisValue, [undefined, {}]);
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', thisValue, [null, {}]);
|
||||
|
||||
}, 'pipeThrough should throw when its first argument is not convertible to an object');
|
||||
|
||||
test(() => {
|
||||
|
||||
const args = [{ readable: {}, writable: {} }, {}];
|
||||
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', undefined, args);
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', null, args);
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', 1, args);
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', { pipeTo: 'test' }, args);
|
||||
|
||||
}, 'pipeThrough should throw when "this" has no pipeTo method');
|
||||
|
||||
test(() => {
|
||||
const error = new Error('potato');
|
||||
|
||||
const throwingPipeTo = {
|
||||
get pipeTo() {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
assert_throws(error,
|
||||
() => ReadableStream.prototype.pipeThrough.call(throwingPipeTo, { readable: { }, writable: { } }, {}),
|
||||
'pipeThrough should rethrow the error thrown by pipeTo');
|
||||
|
||||
const thisValue = {
|
||||
pipeTo() {
|
||||
assert_unreached('pipeTo should not be called');
|
||||
}
|
||||
};
|
||||
|
||||
const throwingWritable = {
|
||||
readable: {},
|
||||
get writable() {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
assert_throws(error,
|
||||
() => ReadableStream.prototype.pipeThrough.call(thisValue, throwingWritable, {}),
|
||||
'pipeThrough should rethrow the error thrown by the writable getter');
|
||||
|
||||
const throwingReadable = {
|
||||
get readable() {
|
||||
throw error;
|
||||
},
|
||||
writable: {}
|
||||
};
|
||||
assert_throws(error,
|
||||
() => ReadableStream.prototype.pipeThrough.call(thisValue, throwingReadable, {}),
|
||||
'pipeThrough should rethrow the error thrown by the readable getter');
|
||||
|
||||
}, 'pipeThrough should rethrow errors from accessing pipeTo, readable, or writable');
|
||||
|
||||
test(() => {
|
||||
|
||||
let count = 0;
|
||||
const thisValue = {
|
||||
pipeTo() {
|
||||
++count;
|
||||
}
|
||||
};
|
||||
|
||||
ReadableStream.prototype.pipeThrough.call(thisValue, { readable: {}, writable: {} });
|
||||
|
||||
assert_equals(count, 1, 'pipeTo was called once');
|
||||
|
||||
}, 'pipeThrough should work with no options argument');
|
||||
|
||||
done();
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>pipe-through.js dedicated worker wrapper file</title>
|
||||
<title>brand-checks.js dedicated worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new Worker('pipe-through.js'));
|
||||
fetch_tests_from_worker(new Worker('brand-checks.js'));
|
||||
</script>
|
|
@ -1,10 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>pipe-through.js browser context wrapper file</title>
|
||||
<title>brand-checks.js browser context wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="../resources/test-utils.js"></script>
|
||||
|
||||
<script src="pipe-through.js"></script>
|
||||
<script src="brand-checks.js"></script>
|
|
@ -0,0 +1,194 @@
|
|||
'use strict';
|
||||
|
||||
if (self.importScripts) {
|
||||
self.importScripts('../resources/test-utils.js');
|
||||
self.importScripts('/resources/testharness.js');
|
||||
}
|
||||
|
||||
let ReadableStreamBYOBReader;
|
||||
let ReadableByteStreamController;
|
||||
|
||||
test(() => {
|
||||
|
||||
// It's not exposed globally, but we test a few of its properties here.
|
||||
ReadableStreamBYOBReader = realRSBYOBReader().constructor;
|
||||
|
||||
assert_equals(ReadableStreamBYOBReader.name, 'ReadableStreamBYOBReader', 'ReadableStreamBYOBReader should be set');
|
||||
|
||||
}, 'Can get the ReadableStreamBYOBReader constructor indirectly');
|
||||
|
||||
test(() => {
|
||||
|
||||
// It's not exposed globally, but we test a few of its properties here.
|
||||
ReadableByteStreamController = realRBSController().constructor;
|
||||
|
||||
assert_equals(ReadableByteStreamController.name, 'ReadableByteStreamController',
|
||||
'ReadableByteStreamController should be set');
|
||||
|
||||
}, 'Can get the ReadableByteStreamController constructor indirectly');
|
||||
|
||||
function fakeRS() {
|
||||
return Object.setPrototypeOf({
|
||||
cancel() { return Promise.resolve(); },
|
||||
getReader() { return realRSBYOBReader(); },
|
||||
pipeThrough(obj) { return obj.readable; },
|
||||
pipeTo() { return Promise.resolve(); },
|
||||
tee() { return [realRS(), realRS()]; }
|
||||
}, ReadableStream.prototype);
|
||||
}
|
||||
|
||||
function realRS() {
|
||||
return new ReadableStream();
|
||||
}
|
||||
|
||||
function fakeRSBYOBReader() {
|
||||
return Object.setPrototypeOf({
|
||||
get closed() { return Promise.resolve(); },
|
||||
cancel() { return Promise.resolve(); },
|
||||
read() { return Promise.resolve({ value: undefined, done: true }); },
|
||||
releaseLock() { return; }
|
||||
}, ReadableStreamBYOBReader.prototype);
|
||||
}
|
||||
|
||||
function realRSBYOBReader() {
|
||||
return new ReadableStream({ type: 'bytes' }).getReader({ mode: 'byob' });
|
||||
}
|
||||
|
||||
function fakeRBSController() {
|
||||
return Object.setPrototypeOf({
|
||||
close() { },
|
||||
enqueue() { },
|
||||
error() { }
|
||||
}, ReadableByteStreamController.prototype);
|
||||
}
|
||||
|
||||
function realRBSController() {
|
||||
let controller;
|
||||
new ReadableStream({
|
||||
start(c) {
|
||||
controller = c;
|
||||
},
|
||||
type: 'bytes'
|
||||
});
|
||||
return controller;
|
||||
}
|
||||
|
||||
test(() => {
|
||||
|
||||
assert_throws(new TypeError(), () => new ReadableStreamBYOBReader(fakeRS()), 'constructor should throw');
|
||||
|
||||
}, 'ReadableStreamBYOBReader enforces a brand check on its argument');
|
||||
|
||||
promise_test(t => {
|
||||
|
||||
return getterRejectsForAll(t, ReadableStreamBYOBReader.prototype, 'closed',
|
||||
[fakeRSBYOBReader(), realRS(), realRBSController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamBYOBReader.prototype.closed enforces a brand check');
|
||||
|
||||
promise_test(t => {
|
||||
|
||||
return methodRejectsForAll(t, ReadableStreamBYOBReader.prototype, 'cancel',
|
||||
[fakeRSBYOBReader(), realRS(), realRBSController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamBYOBReader.prototype.cancel enforces a brand check');
|
||||
|
||||
promise_test(t => {
|
||||
|
||||
return methodRejectsForAll(t, ReadableStreamBYOBReader.prototype, 'read',
|
||||
[fakeRSBYOBReader(), realRS(), realRBSController(), undefined, null], [new Uint8Array(1)]);
|
||||
|
||||
}, 'ReadableStreamBYOBReader.prototype.read enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrowsForAll(ReadableStreamBYOBReader.prototype, 'releaseLock',
|
||||
[fakeRSBYOBReader(), realRS(), realRBSController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamBYOBReader.prototype.releaseLock enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
assert_throws(new TypeError(), () => new ReadableByteStreamController(fakeRS()),
|
||||
'Constructing a ReadableByteStreamController should throw');
|
||||
|
||||
}, 'ReadableByteStreamController enforces a brand check on its arguments');
|
||||
|
||||
test(() => {
|
||||
|
||||
assert_throws(new TypeError(), () => new ReadableByteStreamController(realRS()),
|
||||
'Constructing a ReadableByteStreamController should throw');
|
||||
|
||||
}, 'ReadableByteStreamController can\'t be given a fully-constructed ReadableStream');
|
||||
|
||||
test(() => {
|
||||
|
||||
getterThrowsForAll(ReadableByteStreamController.prototype, 'byobRequest',
|
||||
[fakeRBSController(), realRS(), realRSBYOBReader(), undefined, null]);
|
||||
|
||||
}, 'ReadableByteStreamController.prototype.byobRequest enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrowsForAll(ReadableByteStreamController.prototype, 'close',
|
||||
[fakeRBSController(), realRS(), realRSBYOBReader(), undefined, null]);
|
||||
|
||||
}, 'ReadableByteStreamController.prototype.close enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrowsForAll(ReadableByteStreamController.prototype, 'enqueue',
|
||||
[fakeRBSController(), realRS(), realRSBYOBReader(), undefined, null], [new Uint8Array(1)]);
|
||||
|
||||
}, 'ReadableByteStreamController.prototype.enqueue enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrowsForAll(ReadableByteStreamController.prototype, 'error',
|
||||
[fakeRBSController(), realRS(), realRSBYOBReader(), undefined, null]);
|
||||
|
||||
}, 'ReadableByteStreamController.prototype.error enforces a brand check');
|
||||
|
||||
// ReadableStreamBYOBRequest can only be accessed asynchronously, so cram everything into one test.
|
||||
promise_test(t => {
|
||||
|
||||
let ReadableStreamBYOBRequest;
|
||||
const rs = new ReadableStream({
|
||||
pull(controller) {
|
||||
return t.step(() => {
|
||||
const byobRequest = controller.byobRequest;
|
||||
ReadableStreamBYOBRequest = byobRequest.constructor;
|
||||
brandChecks();
|
||||
byobRequest.respond(1);
|
||||
});
|
||||
},
|
||||
type: 'bytes'
|
||||
});
|
||||
const reader = rs.getReader({ mode: 'byob' });
|
||||
return reader.read(new Uint8Array(1));
|
||||
|
||||
function fakeRSBYOBRequest() {
|
||||
return Object.setPrototypeOf({
|
||||
get view() {},
|
||||
respond() {},
|
||||
respondWithNewView() {}
|
||||
}, ReadableStreamBYOBRequest.prototype);
|
||||
}
|
||||
|
||||
function brandChecks() {
|
||||
for (const badController of [fakeRBSController(), realRS(), realRSBYOBReader(), undefined, null]) {
|
||||
assert_throws(new TypeError(), () => new ReadableStreamBYOBRequest(badController, new Uint8Array(1)),
|
||||
'ReadableStreamBYOBRequest constructor must throw for an invalid controller argument');
|
||||
}
|
||||
getterThrowsForAll(ReadableStreamBYOBRequest.prototype, 'view',
|
||||
[fakeRSBYOBRequest(), realRS(), realRSBYOBReader(), realRBSController(), undefined, null]);
|
||||
methodThrowsForAll(ReadableStreamBYOBRequest.prototype, 'respond',
|
||||
[fakeRSBYOBRequest(), realRS(), realRSBYOBReader(), realRBSController(), undefined, null], [1]);
|
||||
methodThrowsForAll(ReadableStreamBYOBRequest.prototype, 'respondWithNewView',
|
||||
[fakeRSBYOBRequest(), realRS(), realRSBYOBReader(), realRBSController(), undefined, null],
|
||||
[new Uint8Array(1)]);
|
||||
}
|
||||
|
||||
}, 'ReadableStreamBYOBRequest enforces brand checks');
|
||||
|
||||
done();
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>pipe-through.js service worker wrapper file</title>
|
||||
<title>brand-checks.js service worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
@ -8,5 +8,5 @@
|
|||
|
||||
<script>
|
||||
'use strict';
|
||||
service_worker_test('pipe-through.js', 'Service worker test setup');
|
||||
service_worker_test('brand-checks.js', 'Service worker test setup');
|
||||
</script>
|
|
@ -1,11 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>pipe-through.js shared worker wrapper file</title>
|
||||
<title>brand-checks.js shared worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new SharedWorker('pipe-through.js'));
|
||||
fetch_tests_from_worker(new SharedWorker('brand-checks.js'));
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>detached-buffers.js dedicated worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new Worker('detached-buffers.js'));
|
||||
</script>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>detached-buffers.js browser context wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
|
||||
|
||||
<script src="detached-buffers.js"></script>
|
|
@ -0,0 +1,156 @@
|
|||
'use strict';
|
||||
|
||||
if (self.importScripts) {
|
||||
self.importScripts('/resources/testharness.js');
|
||||
}
|
||||
|
||||
promise_test(() => {
|
||||
const stream = new ReadableStream({
|
||||
start(c) {
|
||||
c.close();
|
||||
},
|
||||
type: 'bytes'
|
||||
});
|
||||
|
||||
const reader = stream.getReader({ mode: 'byob' });
|
||||
const view = new Uint8Array([1, 2, 3]);
|
||||
return reader.read(view).then(({ value, done }) => {
|
||||
// Sanity checks
|
||||
assert_true(value instanceof Uint8Array, 'The value read must be a Uint8Array');
|
||||
assert_not_equals(value, view, 'The value read must not be the *same* Uint8Array');
|
||||
assert_array_equals(value, [], 'The value read must be an empty Uint8Array, since the stream is closed');
|
||||
assert_true(done, 'done must be true, since the stream is closed');
|
||||
|
||||
// The important assertions
|
||||
assert_not_equals(value.buffer, view.buffer, 'a different ArrayBuffer must underlie the value');
|
||||
assert_equals(view.buffer.byteLength, 0, 'the original buffer must be detached');
|
||||
});
|
||||
}, 'ReadableStream with byte source: read()ing from a closed stream still transfers the buffer');
|
||||
|
||||
promise_test(() => {
|
||||
const stream = new ReadableStream({
|
||||
start(c) {
|
||||
c.enqueue(new Uint8Array([1, 2, 3]));
|
||||
},
|
||||
type: 'bytes'
|
||||
});
|
||||
|
||||
const reader = stream.getReader({ mode: 'byob' });
|
||||
const view = new Uint8Array([4, 5, 6]);
|
||||
return reader.read(view).then(({ value, done }) => {
|
||||
// Sanity checks
|
||||
assert_true(value instanceof Uint8Array, 'The value read must be a Uint8Array');
|
||||
assert_not_equals(value, view, 'The value read must not be the *same* Uint8Array');
|
||||
assert_array_equals(value, [1, 2, 3], 'The value read must be the enqueued Uint8Array, not the original values');
|
||||
assert_false(done, 'done must be false, since the stream is not closed');
|
||||
|
||||
// The important assertions
|
||||
assert_not_equals(value.buffer, view.buffer, 'a different ArrayBuffer must underlie the value');
|
||||
assert_equals(view.buffer.byteLength, 0, 'the original buffer must be detached');
|
||||
});
|
||||
}, 'ReadableStream with byte source: read()ing from a stream with queued chunks still transfers the buffer');
|
||||
|
||||
test(() => {
|
||||
const stream = new ReadableStream({
|
||||
start(c) {
|
||||
const view = new Uint8Array([1, 2, 3]);
|
||||
c.enqueue(view);
|
||||
assert_throws(new TypeError(), () => c.enqueue(view), 'enqueuing an already-detached buffer must throw');
|
||||
},
|
||||
type: 'bytes'
|
||||
});
|
||||
}, 'ReadableStream with byte source: enqueuing an already-detached buffer throws');
|
||||
|
||||
promise_test(t => {
|
||||
const stream = new ReadableStream({
|
||||
start(c) {
|
||||
c.enqueue(new Uint8Array([1, 2, 3]));
|
||||
},
|
||||
type: 'bytes'
|
||||
});
|
||||
const reader = stream.getReader({ mode: 'byob' });
|
||||
|
||||
const view = new Uint8Array([4, 5, 6]);
|
||||
return reader.read(view).then(() => {
|
||||
// view is now detached
|
||||
return promise_rejects(t, new TypeError(), reader.read(view),
|
||||
'read(view) must reject when given an already-detached buffer');
|
||||
});
|
||||
}, 'ReadableStream with byte source: reading into an already-detached buffer rejects');
|
||||
|
||||
async_test(t => {
|
||||
const stream = new ReadableStream({
|
||||
pull: t.step_func_done(c => {
|
||||
// Detach it by reading into it
|
||||
reader.read(c.byobRequest.view);
|
||||
|
||||
assert_throws(new TypeError(), () => c.byobRequest.respond(1),
|
||||
'respond() must throw if the corresponding view has become detached');
|
||||
}),
|
||||
type: 'bytes'
|
||||
});
|
||||
const reader = stream.getReader({ mode: 'byob' });
|
||||
|
||||
reader.read(new Uint8Array([4, 5, 6]));
|
||||
}, 'ReadableStream with byte source: respond() throws if the BYOB request\'s buffer has been detached (in the ' +
|
||||
'readable state)');
|
||||
|
||||
async_test(t => {
|
||||
const stream = new ReadableStream({
|
||||
pull: t.step_func_done(c => {
|
||||
// Detach it by reading into it
|
||||
reader.read(c.byobRequest.view);
|
||||
|
||||
c.close();
|
||||
|
||||
assert_throws(new TypeError(), () => c.byobRequest.respond(0),
|
||||
'respond() must throw if the corresponding view has become detached');
|
||||
}),
|
||||
type: 'bytes'
|
||||
});
|
||||
const reader = stream.getReader({ mode: 'byob' });
|
||||
|
||||
reader.read(new Uint8Array([4, 5, 6]));
|
||||
}, 'ReadableStream with byte source: respond() throws if the BYOB request\'s buffer has been detached (in the ' +
|
||||
'closed state)');
|
||||
|
||||
async_test(t => {
|
||||
const stream = new ReadableStream({
|
||||
pull: t.step_func_done(c => {
|
||||
// Detach it by reading into it
|
||||
const view = new Uint8Array([1, 2, 3]);
|
||||
reader.read(view);
|
||||
|
||||
assert_throws(new TypeError(), () => c.byobRequest.respondWithNewView(view),
|
||||
'respondWithNewView() must throw if passed a detached view');
|
||||
}),
|
||||
type: 'bytes'
|
||||
});
|
||||
const reader = stream.getReader({ mode: 'byob' });
|
||||
|
||||
reader.read(new Uint8Array([4, 5, 6]));
|
||||
}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has been detached ' +
|
||||
'(in the readable state)');
|
||||
|
||||
async_test(t => {
|
||||
const stream = new ReadableStream({
|
||||
pull: t.step_func_done(c => {
|
||||
// Detach it by reading into it
|
||||
const view = new Uint8Array([1, 2, 3]);
|
||||
reader.read(view);
|
||||
|
||||
c.close();
|
||||
|
||||
const zeroLengthView = new Uint8Array(view.buffer, 0, 0);
|
||||
assert_throws(new TypeError(), () => c.byobRequest.respondWithNewView(zeroLengthView),
|
||||
'respondWithNewView() must throw if passed a (zero-length) view whose buffer has been detached');
|
||||
}),
|
||||
type: 'bytes'
|
||||
});
|
||||
const reader = stream.getReader({ mode: 'byob' });
|
||||
|
||||
reader.read(new Uint8Array([4, 5, 6]));
|
||||
}, 'ReadableStream with byte source: respondWithNewView() throws if the supplied view\'s buffer has been detached ' +
|
||||
'(in the closed state)');
|
||||
|
||||
done();
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>detached-buffers.js service worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
service_worker_test('detached-buffers.js', 'Service worker test setup');
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>detached-buffers.js shared worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new SharedWorker('detached-buffers.js'));
|
||||
</script>
|
|
@ -1906,7 +1906,7 @@ promise_test(() => {
|
|||
start(c) {
|
||||
controller = c;
|
||||
},
|
||||
type: "bytes"
|
||||
type: 'bytes'
|
||||
});
|
||||
|
||||
const readPromise = rs.getReader().read();
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>properties.js dedicated worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new Worker('properties.js'));
|
||||
</script>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>properties.js browser context wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="../resources/rs-utils.js"></script>
|
||||
|
||||
<script src="properties.js"></script>
|
|
@ -0,0 +1,147 @@
|
|||
'use strict';
|
||||
|
||||
if (self.importScripts) {
|
||||
self.importScripts('../resources/rs-utils.js');
|
||||
self.importScripts('/resources/testharness.js');
|
||||
}
|
||||
|
||||
let ReadableStreamBYOBReader;
|
||||
|
||||
test(() => {
|
||||
|
||||
// It's not exposed globally, but we test a few of its properties here.
|
||||
ReadableStreamBYOBReader = (new ReadableStream({ type: 'bytes' }))
|
||||
.getReader({ mode: 'byob' }).constructor;
|
||||
|
||||
}, 'Can get the ReadableStreamBYOBReader constructor indirectly');
|
||||
|
||||
test(() => {
|
||||
|
||||
assert_throws(new TypeError(), () => new ReadableStreamBYOBReader('potato'));
|
||||
assert_throws(new TypeError(), () => new ReadableStreamBYOBReader({}));
|
||||
assert_throws(new TypeError(), () => new ReadableStreamBYOBReader());
|
||||
|
||||
}, 'ReadableStreamBYOBReader constructor should get a ReadableStream object as argument');
|
||||
|
||||
test(() => {
|
||||
|
||||
const methods = ['cancel', 'constructor', 'read', 'releaseLock'];
|
||||
const properties = methods.concat(['closed']).sort();
|
||||
|
||||
const rsReader = new ReadableStreamBYOBReader(new ReadableStream({ type: 'bytes' }));
|
||||
const proto = Object.getPrototypeOf(rsReader);
|
||||
|
||||
assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties);
|
||||
|
||||
for (const m of methods) {
|
||||
const propDesc = Object.getOwnPropertyDescriptor(proto, m);
|
||||
assert_equals(propDesc.enumerable, false, 'method should be non-enumerable');
|
||||
assert_equals(propDesc.configurable, true, 'method should be configurable');
|
||||
assert_equals(propDesc.writable, true, 'method should be writable');
|
||||
assert_equals(typeof rsReader[m], 'function', 'should have be a method');
|
||||
const expectedName = m === 'constructor' ? 'ReadableStreamBYOBReader' : m;
|
||||
assert_equals(rsReader[m].name, expectedName, 'method should have the correct name');
|
||||
}
|
||||
|
||||
const closedPropDesc = Object.getOwnPropertyDescriptor(proto, 'closed');
|
||||
assert_equals(closedPropDesc.enumerable, false, 'closed should be non-enumerable');
|
||||
assert_equals(closedPropDesc.configurable, true, 'closed should be configurable');
|
||||
assert_not_equals(closedPropDesc.get, undefined, 'closed should have a getter');
|
||||
assert_equals(closedPropDesc.set, undefined, 'closed should not have a setter');
|
||||
|
||||
assert_equals(rsReader.cancel.length, 1, 'cancel has 1 parameter');
|
||||
assert_not_equals(rsReader.closed, undefined, 'has a non-undefined closed property');
|
||||
assert_equals(typeof rsReader.closed.then, 'function', 'closed property is thenable');
|
||||
assert_equals(rsReader.constructor.length, 1, 'constructor has 1 parameter');
|
||||
assert_equals(rsReader.read.length, 1, 'read has 1 parameter');
|
||||
assert_equals(rsReader.releaseLock.length, 0, 'releaseLock has no parameters');
|
||||
|
||||
}, 'ReadableStreamBYOBReader instances should have the correct list of properties');
|
||||
|
||||
promise_test(t => {
|
||||
|
||||
const rs = new ReadableStream({
|
||||
pull(controller) {
|
||||
return t.step(() => {
|
||||
const byobRequest = controller.byobRequest;
|
||||
|
||||
const methods = ['constructor', 'respond', 'respondWithNewView'];
|
||||
const properties = methods.concat(['view']).sort();
|
||||
|
||||
const proto = Object.getPrototypeOf(byobRequest);
|
||||
|
||||
assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties);
|
||||
|
||||
for (const m of methods) {
|
||||
const propDesc = Object.getOwnPropertyDescriptor(proto, m);
|
||||
assert_equals(propDesc.enumerable, false, 'method should be non-enumerable');
|
||||
assert_equals(propDesc.configurable, true, 'method should be configurable');
|
||||
assert_equals(propDesc.writable, true, 'method should be writable');
|
||||
assert_equals(typeof byobRequest[m], 'function', 'should have a method');
|
||||
const expectedName = m === 'constructor' ? 'ReadableStreamBYOBRequest' : m;
|
||||
assert_equals(byobRequest[m].name, expectedName, 'method should have the correct name');
|
||||
}
|
||||
|
||||
const viewPropDesc = Object.getOwnPropertyDescriptor(proto, 'view');
|
||||
assert_equals(viewPropDesc.enumerable, false, 'view should be non-enumerable');
|
||||
assert_equals(viewPropDesc.configurable, true, 'view should be configurable');
|
||||
assert_not_equals(viewPropDesc.get, undefined, 'view should have a getter');
|
||||
assert_equals(viewPropDesc.set, undefined, 'view should not have a setter');
|
||||
assert_not_equals(byobRequest.view, undefined, 'has a non-undefined view property');
|
||||
assert_equals(byobRequest.constructor.length, 2, 'constructor has 1 parameter');
|
||||
assert_equals(byobRequest.respond.length, 1, 'respond has 1 parameter');
|
||||
assert_equals(byobRequest.respondWithNewView.length, 1, 'releaseLock has 1 parameter');
|
||||
|
||||
byobRequest.respond(1);
|
||||
|
||||
});
|
||||
},
|
||||
type: 'bytes' });
|
||||
const reader = rs.getReader({ mode: 'byob' });
|
||||
return reader.read(new Uint8Array(1));
|
||||
|
||||
}, 'ReadableStreamBYOBRequest instances should have the correct list of properties');
|
||||
|
||||
test(() => {
|
||||
|
||||
const methods = ['close', 'constructor', 'enqueue', 'error'];
|
||||
const accessors = ['byobRequest', 'desiredSize'];
|
||||
const properties = methods.concat(accessors).sort();
|
||||
|
||||
let controller;
|
||||
new ReadableStream({
|
||||
start(c) {
|
||||
controller = c;
|
||||
},
|
||||
type: 'bytes'
|
||||
});
|
||||
const proto = Object.getPrototypeOf(controller);
|
||||
|
||||
assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties);
|
||||
|
||||
for (const m of methods) {
|
||||
const propDesc = Object.getOwnPropertyDescriptor(proto, m);
|
||||
assert_equals(propDesc.enumerable, false, 'method should be non-enumerable');
|
||||
assert_equals(propDesc.configurable, true, 'method should be configurable');
|
||||
assert_equals(propDesc.writable, true, 'method should be writable');
|
||||
assert_equals(typeof controller[m], 'function', 'should have be a method');
|
||||
const expectedName = m === 'constructor' ? 'ReadableByteStreamController' : m;
|
||||
assert_equals(controller[m].name, expectedName, 'method should have the correct name');
|
||||
}
|
||||
|
||||
for (const a of accessors) {
|
||||
const propDesc = Object.getOwnPropertyDescriptor(proto, a);
|
||||
assert_equals(propDesc.enumerable, false, `${a} should be non-enumerable`);
|
||||
assert_equals(propDesc.configurable, true, `${a} should be configurable`);
|
||||
assert_not_equals(propDesc.get, undefined, `${a} should have a getter`);
|
||||
assert_equals(propDesc.set, undefined, `${a} should not have a setter`);
|
||||
}
|
||||
|
||||
assert_equals(controller.close.length, 0, 'cancel has no parameters');
|
||||
assert_equals(controller.constructor.length, 3, 'constructor has 3 parameters');
|
||||
assert_equals(controller.enqueue.length, 1, 'enqueue has 1 parameter');
|
||||
assert_equals(controller.error.length, 1, 'releaseLock has 1 parameter');
|
||||
|
||||
}, 'ReadableByteStreamController instances should have the correct list of properties');
|
||||
|
||||
done();
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>properties.js service worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
service_worker_test('properties.js', 'Service worker test setup');
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>properties.js shared worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new SharedWorker('properties.js'));
|
||||
</script>
|
|
@ -6,7 +6,7 @@ if (self.importScripts) {
|
|||
}
|
||||
|
||||
let ReadableStreamDefaultReader;
|
||||
let ReadableStreamController;
|
||||
let ReadableStreamDefaultController;
|
||||
|
||||
test(() => {
|
||||
|
||||
|
@ -20,132 +20,145 @@ test(() => {
|
|||
// It's not exposed globally, but we test a few of its properties here.
|
||||
new ReadableStream({
|
||||
start(c) {
|
||||
ReadableStreamController = c.constructor;
|
||||
ReadableStreamDefaultController = c.constructor;
|
||||
}
|
||||
});
|
||||
|
||||
}, 'Can get the ReadableStreamController constructor indirectly');
|
||||
}, 'Can get the ReadableStreamDefaultController constructor indirectly');
|
||||
|
||||
function fakeReadableStream() {
|
||||
return {
|
||||
function fakeRS() {
|
||||
return Object.setPrototypeOf({
|
||||
cancel() { return Promise.resolve(); },
|
||||
getReader() { return new ReadableStreamDefaultReader(new ReadableStream()); },
|
||||
pipeThrough(obj) { return obj.readable; },
|
||||
pipeTo() { return Promise.resolve(); },
|
||||
tee() { return [realReadableStream(), realReadableStream()]; }
|
||||
};
|
||||
tee() { return [realRS(), realRS()]; }
|
||||
}, ReadableStream.prototype);
|
||||
}
|
||||
|
||||
function realReadableStream() {
|
||||
function realRS() {
|
||||
return new ReadableStream();
|
||||
}
|
||||
|
||||
function fakeReadableStreamDefaultReader() {
|
||||
return {
|
||||
function fakeRSDefaultReader() {
|
||||
return Object.setPrototypeOf({
|
||||
get closed() { return Promise.resolve(); },
|
||||
cancel() { return Promise.resolve(); },
|
||||
read() { return Promise.resolve({ value: undefined, done: true }); },
|
||||
releaseLock() { return; }
|
||||
};
|
||||
}, ReadableStreamDefaultReader.prototype);
|
||||
}
|
||||
|
||||
function fakeReadableStreamController() {
|
||||
return {
|
||||
function realRSDefaultReader() {
|
||||
return new ReadableStream().getReader();
|
||||
}
|
||||
|
||||
function fakeRSDefaultController() {
|
||||
return Object.setPrototypeOf({
|
||||
close() { },
|
||||
enqueue() { },
|
||||
error() { }
|
||||
};
|
||||
}, ReadableStreamDefaultController.prototype);
|
||||
}
|
||||
|
||||
function realRSDefaultController() {
|
||||
let controller;
|
||||
new ReadableStream({
|
||||
start(c) {
|
||||
controller = c;
|
||||
}
|
||||
});
|
||||
return controller;
|
||||
}
|
||||
|
||||
promise_test(t => {
|
||||
|
||||
return methodRejects(t, ReadableStream.prototype, 'cancel', fakeReadableStream());
|
||||
return methodRejectsForAll(t, ReadableStream.prototype, 'cancel',
|
||||
[fakeRS(), realRSDefaultReader(), realRSDefaultController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStream.prototype.cancel enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrows(ReadableStream.prototype, 'getReader', fakeReadableStream());
|
||||
methodThrowsForAll(ReadableStream.prototype, 'getReader',
|
||||
[fakeRS(), realRSDefaultReader(), realRSDefaultController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStream.prototype.getReader enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrows(ReadableStream.prototype, 'tee', fakeReadableStream());
|
||||
methodThrowsForAll(ReadableStream.prototype, 'tee', [fakeRS(), realRSDefaultReader(), realRSDefaultController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStream.prototype.tee enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
assert_throws(new TypeError(), () => new ReadableStreamDefaultReader(fakeReadableStream()),
|
||||
assert_throws(new TypeError(), () => new ReadableStreamDefaultReader(fakeRS()),
|
||||
'Constructing a ReadableStreamDefaultReader should throw');
|
||||
|
||||
}, 'ReadableStreamDefaultReader enforces a brand check on its argument');
|
||||
|
||||
promise_test(t => {
|
||||
|
||||
return Promise.all([
|
||||
getterRejects(t, ReadableStreamDefaultReader.prototype, 'closed', fakeReadableStreamDefaultReader()),
|
||||
getterRejects(t, ReadableStreamDefaultReader.prototype, 'closed', realReadableStream())
|
||||
]);
|
||||
return getterRejectsForAll(t, ReadableStreamDefaultReader.prototype, 'closed',
|
||||
[fakeRSDefaultReader(), realRS(), realRSDefaultController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamDefaultReader.prototype.closed enforces a brand check');
|
||||
|
||||
promise_test(t => {
|
||||
|
||||
return Promise.all([
|
||||
methodRejects(t, ReadableStreamDefaultReader.prototype, 'cancel', fakeReadableStreamDefaultReader()),
|
||||
methodRejects(t, ReadableStreamDefaultReader.prototype, 'cancel', realReadableStream())
|
||||
]);
|
||||
return methodRejectsForAll(t, ReadableStreamDefaultReader.prototype, 'cancel',
|
||||
[fakeRSDefaultReader(), realRS(), realRSDefaultController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamDefaultReader.prototype.cancel enforces a brand check');
|
||||
|
||||
promise_test(t => {
|
||||
|
||||
return Promise.all([
|
||||
methodRejects(t, ReadableStreamDefaultReader.prototype, 'read', fakeReadableStreamDefaultReader()),
|
||||
methodRejects(t, ReadableStreamDefaultReader.prototype, 'read', realReadableStream())
|
||||
]);
|
||||
return methodRejectsForAll(t, ReadableStreamDefaultReader.prototype, 'read',
|
||||
[fakeRSDefaultReader(), realRS(), realRSDefaultController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamDefaultReader.prototype.read enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrows(ReadableStreamDefaultReader.prototype, 'releaseLock', fakeReadableStreamDefaultReader());
|
||||
methodThrows(ReadableStreamDefaultReader.prototype, 'releaseLock', realReadableStream());
|
||||
methodThrowsForAll(ReadableStreamDefaultReader.prototype, 'releaseLock',
|
||||
[fakeRSDefaultReader(), realRS(), realRSDefaultController(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamDefaultReader.prototype.releaseLock enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
assert_throws(new TypeError(), () => new ReadableStreamController(fakeReadableStream()),
|
||||
'Constructing a ReadableStreamController should throw');
|
||||
assert_throws(new TypeError(), () => new ReadableStreamDefaultController(fakeRS()),
|
||||
'Constructing a ReadableStreamDefaultController should throw');
|
||||
|
||||
}, 'ReadableStreamController enforces a brand check on its argument');
|
||||
}, 'ReadableStreamDefaultController enforces a brand check on its argument');
|
||||
|
||||
test(() => {
|
||||
|
||||
assert_throws(new TypeError(), () => new ReadableStreamController(realReadableStream()),
|
||||
'Constructing a ReadableStreamController should throw');
|
||||
assert_throws(new TypeError(), () => new ReadableStreamDefaultController(realRS()),
|
||||
'Constructing a ReadableStreamDefaultController should throw');
|
||||
|
||||
}, 'ReadableStreamController can\'t be given a fully-constructed ReadableStream');
|
||||
}, 'ReadableStreamDefaultController can\'t be given a fully-constructed ReadableStream');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrows(ReadableStreamController.prototype, 'close', fakeReadableStreamController());
|
||||
methodThrowsForAll(ReadableStreamDefaultController.prototype, 'close',
|
||||
[fakeRSDefaultController(), realRS(), realRSDefaultReader(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamController.prototype.close enforces a brand check');
|
||||
}, 'ReadableStreamDefaultController.prototype.close enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrows(ReadableStreamController.prototype, 'enqueue', fakeReadableStreamController());
|
||||
methodThrowsForAll(ReadableStreamDefaultController.prototype, 'enqueue',
|
||||
[fakeRSDefaultController(), realRS(), realRSDefaultReader(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamController.prototype.enqueue enforces a brand check');
|
||||
}, 'ReadableStreamDefaultController.prototype.enqueue enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
|
||||
methodThrows(ReadableStreamController.prototype, 'error', fakeReadableStreamController());
|
||||
methodThrowsForAll(ReadableStreamDefaultController.prototype, 'error',
|
||||
[fakeRSDefaultController(), realRS(), realRSDefaultReader(), undefined, null]);
|
||||
|
||||
}, 'ReadableStreamController.prototype.error enforces a brand check');
|
||||
}, 'ReadableStreamDefaultController.prototype.error enforces a brand check');
|
||||
|
||||
done();
|
||||
|
|
|
@ -38,6 +38,8 @@ test(() => {
|
|||
assert_equals(propDesc.configurable, true, 'method should be configurable');
|
||||
assert_equals(propDesc.writable, true, 'method should be writable');
|
||||
assert_equals(typeof rsReader[m], 'function', 'should have be a method');
|
||||
const expectedName = m === 'constructor' ? 'ReadableStreamDefaultReader' : m;
|
||||
assert_equals(rsReader[m].name, expectedName, 'method should have the correct name');
|
||||
}
|
||||
|
||||
const closedPropDesc = Object.getOwnPropertyDescriptor(proto, 'closed');
|
||||
|
|
|
@ -56,6 +56,8 @@ test(() => {
|
|||
assert_true(propDesc.configurable, 'method should be configurable');
|
||||
assert_true(propDesc.writable, 'method should be writable');
|
||||
assert_equals(typeof rs[m], 'function', 'method should be a function');
|
||||
const expectedName = m === 'constructor' ? 'ReadableStream' : m;
|
||||
assert_equals(rs[m].name, expectedName, 'method should have the correct name');
|
||||
}
|
||||
|
||||
const lockedPropDesc = Object.getOwnPropertyDescriptor(proto, 'locked');
|
||||
|
@ -115,6 +117,8 @@ test(() => {
|
|||
assert_false(propDesc.enumerable, m + ' should be non-enumerable');
|
||||
assert_true(propDesc.configurable, m + ' should be configurable');
|
||||
assert_true(propDesc.writable, m + ' should be writable');
|
||||
const expectedName = m === 'constructor' ? 'ReadableStreamDefaultController' : m;
|
||||
assert_equals(controller[m].name, expectedName, 'method should have the correct name');
|
||||
}
|
||||
|
||||
const desiredSizePropDesc = Object.getOwnPropertyDescriptor(proto, 'desiredSize');
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
if (self.importScripts) {
|
||||
self.importScripts('../resources/test-utils.js');
|
||||
self.importScripts('/resources/testharness.js');
|
||||
}
|
||||
|
||||
test(() => {
|
||||
|
||||
let pipeToArguments;
|
||||
const thisValue = {
|
||||
pipeTo(...args) {
|
||||
pipeToArguments = args;
|
||||
}
|
||||
};
|
||||
|
||||
const input = { readable: {}, writable: {} };
|
||||
const options = {};
|
||||
const result = ReadableStream.prototype.pipeThrough.call(thisValue, input, options);
|
||||
|
||||
assert_array_equals(pipeToArguments, [input.writable, options],
|
||||
'correct arguments should be passed to thisValue.pipeTo');
|
||||
assert_equals(result, input.readable, 'return value should be the passed readable property');
|
||||
|
||||
}, 'ReadableStream.prototype.pipeThrough should work generically on its this and its arguments');
|
||||
|
||||
test(() => {
|
||||
|
||||
const thisValue = {
|
||||
pipeTo() {
|
||||
assert_unreached('pipeTo should not be called');
|
||||
}
|
||||
};
|
||||
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', thisValue, [undefined, {}]);
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', thisValue, [null, {}]);
|
||||
|
||||
}, 'ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object');
|
||||
|
||||
test(() => {
|
||||
|
||||
const args = [{ readable: {}, writable: {} }, {}];
|
||||
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', undefined, args);
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', null, args);
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', 1, args);
|
||||
methodThrows(ReadableStream.prototype, 'pipeThrough', { pipeTo: 'test' }, args);
|
||||
|
||||
}, 'ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method');
|
||||
|
||||
test(() => {
|
||||
const error = new Error('potato');
|
||||
|
||||
const throwingPipeTo = {
|
||||
get pipeTo() {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
assert_throws(error,
|
||||
() => ReadableStream.prototype.pipeThrough.call(throwingPipeTo, { readable: { }, writable: { } }, {}),
|
||||
'pipeThrough should rethrow the error thrown by pipeTo');
|
||||
|
||||
const thisValue = {
|
||||
pipeTo() {
|
||||
assert_unreached('pipeTo should not be called');
|
||||
}
|
||||
};
|
||||
|
||||
const throwingWritable = {
|
||||
readable: {},
|
||||
get writable() {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
assert_throws(error,
|
||||
() => ReadableStream.prototype.pipeThrough.call(thisValue, throwingWritable, {}),
|
||||
'pipeThrough should rethrow the error thrown by the writable getter');
|
||||
|
||||
const throwingReadable = {
|
||||
get readable() {
|
||||
throw error;
|
||||
},
|
||||
writable: {}
|
||||
};
|
||||
assert_throws(error,
|
||||
() => ReadableStream.prototype.pipeThrough.call(thisValue, throwingReadable, {}),
|
||||
'pipeThrough should rethrow the error thrown by the readable getter');
|
||||
|
||||
}, 'ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable');
|
||||
|
||||
test(() => {
|
||||
|
||||
let count = 0;
|
||||
const thisValue = {
|
||||
pipeTo() {
|
||||
++count;
|
||||
}
|
||||
};
|
||||
|
||||
ReadableStream.prototype.pipeThrough.call(thisValue, { readable: {}, writable: {} });
|
||||
ReadableStream.prototype.pipeThrough.call(thisValue, { readable: {} }, {});
|
||||
ReadableStream.prototype.pipeThrough.call(thisValue, { writable: {} }, {});
|
||||
|
||||
assert_equals(count, 3, 'pipeTo was called 3 times');
|
||||
|
||||
}, 'ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options');
|
||||
|
||||
done();
|
|
@ -3,13 +3,22 @@
|
|||
self.getterRejects = (t, obj, getterName, target) => {
|
||||
const getter = Object.getOwnPropertyDescriptor(obj, getterName).get;
|
||||
|
||||
return promise_rejects(t, new TypeError(), getter.call(target));
|
||||
return promise_rejects(t, new TypeError(), getter.call(target), getterName + ' should reject with a TypeError');
|
||||
};
|
||||
|
||||
self.getterRejectsForAll = (t, obj, getterName, targets) => {
|
||||
return Promise.all(targets.map(target => getterRejects(t, obj, getterName, target)));
|
||||
};
|
||||
|
||||
self.methodRejects = (t, obj, methodName, target, args) => {
|
||||
const method = obj[methodName];
|
||||
|
||||
return promise_rejects(t, new TypeError(), method.apply(target, args));
|
||||
return promise_rejects(t, new TypeError(), method.apply(target, args),
|
||||
methodName + ' should reject with a TypeError');
|
||||
};
|
||||
|
||||
self.methodRejectsForAll = (t, obj, methodName, targets, args) => {
|
||||
return Promise.all(targets.map(target => methodRejects(t, obj, methodName, target, args)));
|
||||
};
|
||||
|
||||
self.getterThrows = (obj, getterName, target) => {
|
||||
|
@ -18,12 +27,21 @@ self.getterThrows = (obj, getterName, target) => {
|
|||
assert_throws(new TypeError(), () => getter.call(target), getterName + ' should throw a TypeError');
|
||||
};
|
||||
|
||||
self.getterThrowsForAll = (obj, getterName, targets) => {
|
||||
targets.forEach(target => getterThrows(obj, getterName, target));
|
||||
}
|
||||
|
||||
self.methodThrows = (obj, methodName, target, args) => {
|
||||
const method = obj[methodName];
|
||||
assert_equals(typeof method, 'function', methodName + ' should exist');
|
||||
|
||||
assert_throws(new TypeError(), () => method.apply(target, args), methodName + ' should throw a TypeError');
|
||||
};
|
||||
|
||||
self.methodThrowsForAll = (obj, methodName, targets, args) => {
|
||||
targets.forEach(target => methodThrows(obj, methodName, target, args));
|
||||
}
|
||||
|
||||
self.garbageCollect = () => {
|
||||
if (self.gc) {
|
||||
// Use --expose_gc for V8 (and Node.js)
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
|
||||
<script src="../resources/test-utils.js"></script>
|
||||
|
||||
<script src="brand-checks.js"></script>
|
||||
|
|
|
@ -2,78 +2,113 @@
|
|||
|
||||
if (self.importScripts) {
|
||||
self.importScripts('/resources/testharness.js');
|
||||
self.importScripts('../resources/test-utils.js');
|
||||
}
|
||||
|
||||
function fakeWritableStreamDefaultWriter() {
|
||||
return {
|
||||
const WritableStreamDefaultWriter = new WritableStream().getWriter().constructor;
|
||||
const WriterProto = WritableStreamDefaultWriter.prototype;
|
||||
const WritableStreamDefaultController = getWritableStreamDefaultControllerConstructor();
|
||||
|
||||
function getWritableStreamDefaultControllerConstructor() {
|
||||
return realWSDefaultController().constructor;
|
||||
}
|
||||
|
||||
function fakeWS() {
|
||||
return Object.setPrototypeOf({
|
||||
get locked() { return false; },
|
||||
abort() { return Promise.resolve(); },
|
||||
getWriter() { return fakeWSDefaultWriter(); }
|
||||
}, WritableStream.prototype);
|
||||
}
|
||||
|
||||
function realWS() {
|
||||
return new WritableStream();
|
||||
}
|
||||
|
||||
function fakeWSDefaultWriter() {
|
||||
return Object.setPrototypeOf({
|
||||
get closed() { return Promise.resolve(); },
|
||||
get desiredSize() { return 1; },
|
||||
get ready() { return Promise.resolve(); },
|
||||
abort() { return Promise.resolve(); },
|
||||
close() { return Promise.resolve(); },
|
||||
write() { return Promise.resolve(); }
|
||||
};
|
||||
}, WritableStreamDefaultWriter.prototype);
|
||||
}
|
||||
|
||||
function realReadableStreamDefaultWriter() {
|
||||
const rs = new ReadableStream();
|
||||
return rs.getReader();
|
||||
function realWSDefaultWriter() {
|
||||
const ws = new WritableStream();
|
||||
return ws.getWriter();
|
||||
}
|
||||
|
||||
function getterRejects(t, obj, getterName, target) {
|
||||
const getter = Object.getOwnPropertyDescriptor(obj, getterName).get;
|
||||
|
||||
return promise_rejects(t, new TypeError(), getter.call(target),
|
||||
getterName + ' should reject with a TypeError');
|
||||
function fakeWSDefaultController() {
|
||||
return Object.setPrototypeOf({
|
||||
error() { return Promise.resolve(); }
|
||||
}, WritableStreamDefaultController.prototype);
|
||||
}
|
||||
|
||||
function methodRejects(t, obj, methodName, target) {
|
||||
const method = obj[methodName];
|
||||
|
||||
return promise_rejects(t, new TypeError(), method.call(target),
|
||||
methodName + ' should reject with a TypeError');
|
||||
function realWSDefaultController() {
|
||||
let controller;
|
||||
new WritableStream({
|
||||
start(c) {
|
||||
controller = c;
|
||||
}
|
||||
});
|
||||
return controller;
|
||||
}
|
||||
|
||||
function getterThrows(obj, getterName, target) {
|
||||
const getter = Object.getOwnPropertyDescriptor(obj, getterName).get;
|
||||
|
||||
assert_throws(new TypeError(), () => getter.call(target), getterName + ' should throw a TypeError');
|
||||
}
|
||||
|
||||
const ws = new WritableStream();
|
||||
const writer = ws.getWriter();
|
||||
const WritableStreamDefaultWriter = writer.constructor;
|
||||
const WriterProto = WritableStreamDefaultWriter.prototype;
|
||||
|
||||
test(() => {
|
||||
getterThrows(WriterProto, 'desiredSize', fakeWritableStreamDefaultWriter());
|
||||
getterThrows(WriterProto, 'desiredSize', realReadableStreamDefaultWriter());
|
||||
getterThrowsForAll(WritableStream.prototype, 'locked',
|
||||
[fakeWS(), realWSDefaultWriter(), realWSDefaultController(), undefined, null]);
|
||||
}, 'WritableStream.prototype.locked enforces a brand check');
|
||||
|
||||
promise_test(t => {
|
||||
return methodRejectsForAll(t, WritableStream.prototype, 'abort',
|
||||
[fakeWS(), realWSDefaultWriter(), realWSDefaultController(), undefined, null]);
|
||||
}, 'WritableStream.prototype.abort enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
methodThrowsForAll(WritableStream.prototype, 'getWriter',
|
||||
[fakeWS(), realWSDefaultWriter(), realWSDefaultController(), undefined, null]);
|
||||
}, 'WritableStream.prototype.getWriter enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
assert_throws(new TypeError(), () => new WritableStreamDefaultWriter(fakeWS()), 'constructor should throw');
|
||||
}, 'WritableStreamDefaultWriter constructor enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
getterThrowsForAll(WriterProto, 'desiredSize',
|
||||
[fakeWSDefaultWriter(), realWS(), realWSDefaultController(), undefined, null]);
|
||||
}, 'WritableStreamDefaultWriter.prototype.desiredSize enforces a brand check');
|
||||
|
||||
promise_test(t => {
|
||||
return Promise.all([getterRejects(t, WriterProto, 'closed', fakeWritableStreamDefaultWriter()),
|
||||
getterRejects(t, WriterProto, 'closed', realReadableStreamDefaultWriter())]);
|
||||
return getterRejectsForAll(t, WriterProto, 'closed',
|
||||
[fakeWSDefaultWriter(), realWS(), realWSDefaultController(), undefined, null]);
|
||||
}, 'WritableStreamDefaultWriter.prototype.closed enforces a brand check');
|
||||
|
||||
promise_test(t => {
|
||||
return Promise.all([getterRejects(t, WriterProto, 'ready', fakeWritableStreamDefaultWriter()),
|
||||
getterRejects(t, WriterProto, 'ready', realReadableStreamDefaultWriter())]);
|
||||
return getterRejectsForAll(t, WriterProto, 'ready',
|
||||
[fakeWSDefaultWriter(), realWS(), realWSDefaultController(), undefined, null]);
|
||||
}, 'WritableStreamDefaultWriter.prototype.ready enforces a brand check');
|
||||
|
||||
test(t => {
|
||||
return Promise.all([methodRejects(t, WriterProto, 'abort', fakeWritableStreamDefaultWriter()),
|
||||
methodRejects(t, WriterProto, 'abort', realReadableStreamDefaultWriter())]);
|
||||
|
||||
promise_test(t => {
|
||||
return methodRejectsForAll(t, WriterProto, 'abort',
|
||||
[fakeWSDefaultWriter(), realWS(), realWSDefaultController(), undefined, null]);
|
||||
}, 'WritableStreamDefaultWriter.prototype.abort enforces a brand check');
|
||||
|
||||
promise_test(t => {
|
||||
return Promise.all([methodRejects(t, WriterProto, 'write', fakeWritableStreamDefaultWriter()),
|
||||
methodRejects(t, WriterProto, 'write', realReadableStreamDefaultWriter())]);
|
||||
return methodRejectsForAll(t, WriterProto, 'write',
|
||||
[fakeWSDefaultWriter(), realWS(), realWSDefaultController(), undefined, null]);
|
||||
}, 'WritableStreamDefaultWriter.prototype.write enforces a brand check');
|
||||
|
||||
promise_test(t => {
|
||||
return Promise.all([methodRejects(t, WriterProto, 'close', fakeWritableStreamDefaultWriter()),
|
||||
methodRejects(t, WriterProto, 'close', realReadableStreamDefaultWriter())]);
|
||||
return methodRejectsForAll(t, WriterProto, 'close',
|
||||
[fakeWSDefaultWriter(), realWS(), realWSDefaultController(), undefined, null]);
|
||||
}, 'WritableStreamDefaultWriter.prototype.close enforces a brand check');
|
||||
|
||||
test(() => {
|
||||
methodThrowsForAll(WritableStreamDefaultController.prototype, 'error',
|
||||
[fakeWSDefaultController(), realWS(), realWSDefaultWriter(), undefined, null]);
|
||||
}, 'WritableStreamDefaultController.prototype.error enforces a brand check');
|
||||
|
||||
done();
|
||||
|
|
|
@ -127,8 +127,10 @@ for (const c in expected) {
|
|||
`${name} should take ${properties[name].length} arguments`);
|
||||
if (type === 'constructor') {
|
||||
assert_true(IsConstructor(prototype[name]), `${name} should be a constructor`);
|
||||
assert_equals(prototype[name].name, c, `${name}.name should be '${c}'`);
|
||||
} else {
|
||||
assert_false(IsConstructor(prototype[name]), `${name} should not be a constructor`);
|
||||
assert_equals(prototype[name].name, name, `${name}.name should be '${name}`);
|
||||
}
|
||||
}, `${fullName} should be a ${type}`);
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue