Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Unified Diff: third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/readable-stream-reader.js

Issue 1404523005: Implement author-constructible ReadableStream using V8 extras (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/readable-stream-reader.js
diff --git a/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/readable-stream-reader.js b/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/readable-stream-reader.js
new file mode 100644
index 0000000000000000000000000000000000000000..f82b1d67db2fdaa1365bbd7884c8407a29e92dd1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/streams/readable-streams/readable-stream-reader.js
@@ -0,0 +1,335 @@
+'use strict';
+
+if (self.importScripts) {
+ self.importScripts('../resources/rs-utils.js');
+ self.importScripts('/resources/testharness.js');
+}
+
+var ReadableStreamReader;
+
+test(function() {
+ // It's not exposed globally, but we test a few of its properties here.
+ ReadableStreamReader = (new ReadableStream()).getReader().constructor;
+}, 'Can get the ReadableStreamReader constructor indirectly');
+
+test(function() {
+ assert_throws(new TypeError(), function() {
+ new ReadableStreamReader('potato');
+ });
+ assert_throws(new TypeError(), function() {
+ new ReadableStreamReader({});
+ });
+ assert_throws(new TypeError(), function() {
+ new ReadableStreamReader();
+ });
+}, 'ReadableStreamReader constructor should get a ReadableStream object as argument');
+
+test(function() {
+ var methods = ['cancel', 'constructor', 'read', 'releaseLock'];
+ var properties = methods.concat(['closed']).sort();
+
+ var rsReader = new ReadableStreamReader(new ReadableStream());
+ var proto = Object.getPrototypeOf(rsReader);
+
+ assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties);
+
+ for (var m of methods) {
+ var 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');
+ }
+
+ var 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(typeof rsReader.constructor, 'function', 'has a constructor method');
+ assert_equals(rsReader.constructor.length, 1, 'constructor has 1 parameter');
+ assert_equals(typeof rsReader.read, 'function', 'has a getReader method');
+ assert_equals(rsReader.read.length, 0, 'read has no parameters');
+ assert_equals(typeof rsReader.releaseLock, 'function', 'has a releaseLock method');
+ assert_equals(rsReader.releaseLock.length, 0, 'releaseLock has no parameters');
+}, 'ReadableStreamReader instances should have the correct list of properties');
+
+test(function() {
+ var rsReader = new ReadableStreamReader(new ReadableStream());
+
+ assert_equals(rsReader.closed, rsReader.closed, 'closed should return the same promise');
+}, 'ReadableStreamReader closed should always return the same promise object');
+
+test(function() {
+ var rs = new ReadableStream();
+ new ReadableStreamReader(rs); // Constructing directly the first time should be fine.
+ assert_throws(new TypeError(), function() { new ReadableStreamReader(rs); }, 'constructing directly the second time should fail');
+}, 'Constructing a ReadableStreamReader directly should fail if the stream is already locked (via direct construction)');
+
+test(function() {
+ var rs = new ReadableStream();
+ new ReadableStreamReader(rs); // Constructing directly should be fine.
+ assert_throws(new TypeError(), function() { rs.getReader(); }, 'getReader() should fail');
+}, 'Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via direct construction)');
+
+test(function() {
+ var rs = new ReadableStream();
+ rs.getReader(); // getReader() should be fine.
+ assert_throws(new TypeError(), function() { new ReadableStreamReader(rs); }, 'constructing directly should fail');
+}, 'Constructing a ReadableStreamReader directly should fail if the stream is already locked (via getReader)');
+
+test(function() {
+ var rs = new ReadableStream();
+ rs.getReader(); // getReader() should be fine.
+ assert_throws(new TypeError(), function() { rs.getReader(); }, 'getReader() should fail');
+}, 'Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via getReader)');
+
+test(function() {
+ var rs = new ReadableStream({
+ start: function(c) {
+ c.close();
+ }
+ });
+
+ new ReadableStreamReader(rs); // Constructing directly should not throw.
+}, 'Constructing a ReadableStreamReader directly should be OK if the stream is closed');
+
+test(function() {
+ var theError = new Error('don\'t say i didn\'t warn ya');
+ var rs = new ReadableStream({
+ start: function(c) {
+ c.error(theError);
+ }
+ });
+
+ new ReadableStreamReader(rs); // Constructing directly should not throw.
+}, 'Constructing a ReadableStreamReader directly should be OK if the stream is errored');
+
+var test1 = async_test('Reading from a reader for an empty stream will wait until a chunk is available');
+test1.step(function() {
+ var controller;
+ var rs = new ReadableStream({
+ start: function(c) {
+ controller = c;
+ }
+ });
+ var reader = rs.getReader();
+
+ reader.read().then(test1.step_func(function(result) {
+ assert_object_equals(result, { value: 'a', done: false }, 'read() should fulfill with the enqueued chunk');
+ test1.done();
+ }));
+
+ controller.enqueue('a');
+});
+
+var test2 = async_test('cancel() on a reader does not release the reader');
+test2.step(function() {
+ var cancelCalled = false;
+ var passedReason = new Error('it wasn\'t the right time, sorry');
+ var rs = new ReadableStream({
+ cancel: function(reason) {
+ assert_true(rs.locked, 'the stream should still be locked');
+ assert_throws(new TypeError(), function() { rs.getReader(); }, 'should not be able to get another reader');
+ assert_equals(reason, passedReason, 'the cancellation reason is passed through to the underlying source');
+ cancelCalled = true;
+ }
+ });
+
+ var reader = rs.getReader();
+ reader.cancel(passedReason).then(
+ test2.step_func(function() {
+ assert_true(cancelCalled);
+ test2.done('reader.cancel() should fulfill');
+ }),
+ test2.step_func(function(e) { assert_unreached('reader.cancel() should not reject'); })
+ );
+});
+
+var test3 = async_test('closed should be fulfilled after stream is closed (.closed access before acquiring)');
+test3.step(function() {
+ var controller;
+ var rs = new ReadableStream({
+ start: function(c) {
+ controller = c;
+ }
+ });
+
+ var reader = rs.getReader();
+ reader.closed.then(test3.step_func(function() {
+ test3.done('reader closed should be fulfilled');
+ }));
+
+ controller.close();
+});
+
+var test4 = async_test('closed should be rejected after reader releases its lock (multiple stream locks)');
+test4.step(function() {
+ var promiseCalls = 0;
+ var controller;
+ var rs = new ReadableStream({
+ start: function(c) {
+ controller = c;
+ }
+ });
+
+ var reader1 = rs.getReader();
+
+ reader1.releaseLock();
+
+ var reader2 = rs.getReader();
+ controller.close();
+
+ reader1.closed.catch(test4.step_func(function(e) {
+ assert_throws(new TypeError(), function() { throw e; }, 'reader1 closed should be rejected with a TypeError');
+ assert_equals(++promiseCalls, 1);
+ }));
+
+ reader2.closed.then(test4.step_func(function() {
+ assert_equals(++promiseCalls, 2);
+ test4.done('reader2 closed should be fulfilled');
+ }));
+});
+
+var test5 = async_test('Multiple readers can access the stream in sequence');
+test5.step(function() {
+ var readCount = 0;
+ var rs = new ReadableStream({
+ start: function(c) {
+ c.enqueue('a');
+ c.enqueue('b');
+ c.close();
+ }
+ });
+
+ var reader1 = rs.getReader();
+ reader1.read().then(test5.step_func(function(r) {
+ assert_object_equals(r, { value: 'a', done: false }, 'reading the first chunk from reader1 works');
+ ++readCount;
+ }));
+ reader1.releaseLock();
+
+ var reader2 = rs.getReader();
+ reader2.read().then(test5.step_func(function(r) {
+ assert_object_equals(r, { value: 'b', done: false }, 'reading the second chunk from reader2 works');
+ assert_equals(++readCount, 2);
+ test5.done();
+ }));
+ reader2.releaseLock();
+});
+
+var test6 = async_test('Cannot use an already-released reader to unlock a stream again');
+test6.step(function() {
+ var rs = new ReadableStream({
+ start: function(c) {
+ c.enqueue('a');
+ }
+ });
+
+ var reader1 = rs.getReader();
+ reader1.releaseLock();
+
+ var reader2 = rs.getReader();
+
+ reader1.releaseLock();
+ reader2.read().then(test6.step_func(function(result) {
+ assert_object_equals(result, { value: 'a', done: false }, 'read() should still work on reader2 even after reader1 is released');
+ test6.done();
+ }));
+});
+
+var test7 = async_test('cancel() on a released reader is a no-op and does not pass through');
+test7.step(function() {
+ var promiseCalls = 0;
+ var rs = new ReadableStream({
+ start: function(c) {
+ c.enqueue('a');
+ },
+ cancel: function() {
+ assert_unreached('underlying source cancel should not be called');
+ }
+ });
+
+ var reader = rs.getReader();
+ reader.releaseLock();
+ reader.cancel().then(test7.step_func(function(v) {
+ assert_unreached('cancel promise should not fulfill');
+ })).catch(test7.step_func(function(e) {
+ assert_equals(++promiseCalls, 2);
+ test7.done();
+ }));
+
+ var reader2 = rs.getReader();
+ reader2.read().then(test7.step_func(function(r) {
+ assert_object_equals(r, { value: 'a', done: false }, 'a new reader should be able to read a chunk');
+ assert_equals(++promiseCalls, 1);
+ }));
+});
+
+var test8 = async_test('Getting a second reader after erroring the stream should succeed');
+test8.step(function() {
+ var controller;
+ var receivedErrors = 0;
+ var theError = new Error('bad');
+ var rs = new ReadableStream({
+ start: function(c) {
+ controller = c;
+ }
+ });
+
+ var reader1 = rs.getReader();
+
+ reader1.closed.catch(test8.step_func(function(e) {
+ assert_equals(e, theError, 'the first reader closed getter should be rejected with the error');
+ ++receivedErrors;
+ }));
+
+ reader1.read().catch(test8.step_func(function(e) {
+ assert_equals(e, theError, 'the first reader read() should be rejected with the error');
+ ++receivedErrors;
+ }));
+
+ assert_throws(new TypeError(), function() { rs.getReader(); }, 'trying to get another reader before erroring should throw');
+
+ controller.error(theError);
+
+ reader1.releaseLock();
+
+ var reader2 = rs.getReader();
+
+ reader2.closed.catch(test8.step_func(function(e) {
+ assert_equals(e, theError, 'the second reader closed getter should be rejected with the error');
+ ++receivedErrors;
+ }));
+
+ reader2.read().catch(test8.step_func(function(e) {
+ assert_equals(e, theError, 'the third reader read() should be rejected with the error');
+ assert_equals(++receivedErrors, 4);
+ test8.done();
+ }));
+});
+
+var test9 = async_test('ReadableStreamReader closed promise should be rejected with undefined if that is the error');
+test9.step(function() {
+ var controller;
+ var rs = new ReadableStream({
+ start: function(c) {
+ controller = c;
+ }
+ });
+
+ rs.getReader().closed.then(test9.step_func(function() {
+ assert_unreached("closed promise should not be resolved when stream is errored");
+ }), test9.step_func(function(err) {
+ assert_equals(err, undefined, 'passed error should be undefined as it was');
+ test9.done();
+ }));
+
+ controller.error();
+});
+
+done();

Powered by Google App Engine
This is Rietveld 408576698