Skip to content

Commit

Permalink
Streams: test always transferring the ArrayBuffer for BYOB reads
Browse files Browse the repository at this point in the history
  • Loading branch information
domenic committed Sep 22, 2017
1 parent 2020f55 commit 31fdb1c
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -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>
10 changes: 10 additions & 0 deletions streams/readable-byte-streams/detached-buffers.html
Original file line number Diff line number Diff line change
@@ -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>
156 changes: 156 additions & 0 deletions streams/readable-byte-streams/detached-buffers.js
Original file line number Diff line number Diff line change
@@ -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();
Original file line number Diff line number Diff line change
@@ -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>
11 changes: 11 additions & 0 deletions streams/readable-byte-streams/detached-buffers.sharedworker.html
Original file line number Diff line number Diff line change
@@ -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>
2 changes: 1 addition & 1 deletion streams/readable-byte-streams/general.js
Original file line number Diff line number Diff line change
Expand Up @@ -1906,7 +1906,7 @@ promise_test(() => {
start(c) {
controller = c;
},
type: "bytes"
type: 'bytes'
});

const readPromise = rs.getReader().read();
Expand Down

0 comments on commit 31fdb1c

Please sign in to comment.