[Readable Streams API] Implement ReadableStreamBYOBRequest respondWithNewView()
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Apr 2017 17:25:10 +0000 (17:25 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Apr 2017 17:25:10 +0000 (17:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170339

Patch by Romain Bellessort <romain.bellessort@crf.canon.fr> on 2017-04-06
Reviewed by Youenn Fablet.

Source/WebCore:

Implemented ReadableStreamBYOBRequest respondWithNewView().

Added new tests to check respondWithNewView() behaviour.

* Modules/streams/ReadableByteStreamInternals.js:
(readableByteStreamControllerRespondWithNewView): Added.
* Modules/streams/ReadableStreamBYOBRequest.js:
(respondWithNewView): Updated.

LayoutTests:

Added new tests addressing respondWithNewView() behaviour.

* streams/readable-stream-byob-request-expected.txt: Updated.
* streams/readable-stream-byob-request.js: Added new tests.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@215043 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/streams/readable-stream-byob-request-expected.txt
LayoutTests/streams/readable-stream-byob-request.js
Source/WebCore/ChangeLog
Source/WebCore/Modules/streams/ReadableByteStreamInternals.js
Source/WebCore/Modules/streams/ReadableStreamBYOBRequest.js

index 9cdfcfc..5a8c1e3 100644 (file)
@@ -1,3 +1,15 @@
+2017-04-06  Romain Bellessort  <romain.bellessort@crf.canon.fr>
+
+        [Readable Streams API] Implement ReadableStreamBYOBRequest respondWithNewView()
+        https://bugs.webkit.org/show_bug.cgi?id=170339
+
+        Reviewed by Youenn Fablet.
+
+        Added new tests addressing respondWithNewView() behaviour.
+
+        * streams/readable-stream-byob-request-expected.txt: Updated.
+        * streams/readable-stream-byob-request.js: Added new tests.
+
 2017-04-06  Dave Hyatt  <hyatt@apple.com>
 
         Rendering flexbox children across columns
index 1a6cf1c..5b6709b 100644 (file)
@@ -10,6 +10,12 @@ PASS Calling respond() with a bytesWritten value different from 0 when stream is
 PASS Calling respond() with a bytesWritten value of 0 when stream is closed should succeed 
 PASS Calling respond() with a bytesWritten value greater than autoAllocateChunkSize should fail 
 PASS Calling respond() with a bytesWritten value lower than autoAllocateChunkSize should succeed 
+PASS Calling respondWithNewView() with a this object different from ReadableStreamBYOBRequest should throw a TypeError 
+PASS Calling respondWithNewView() with an argument that is not an object should throw a TypeError 
+PASS Calling respondWithNewView() with an argument that is not an ArrayBufferView should throw a TypeError 
+PASS When using autoAllocateChunkSize, calling respondWithNewView() should succeed if view.byteLength is equal to autoAllocateChunkSize 
+PASS When using autoAllocateChunkSize, calling respondWithNewView() should throw a RangeError if view.byteOffset is different from 0 
+PASS When using autoAllocateChunkSize, calling respondWithNewView() should throw a RangeError if view.byteLength is different from autoAllocateChunkSize 
 PASS ReadableStreamBYOBRequest instances should have the correct list of properties 
 PASS By default, byobRequest should be undefined 
 PASS byobRequest.view length should be equal to autoAllocateChunkSize 
@@ -21,4 +27,10 @@ PASS Calling respond() with a bytesWritten value different from 0 when stream is
 PASS Calling respond() with a bytesWritten value of 0 when stream is closed should succeed 
 PASS Calling respond() with a bytesWritten value greater than autoAllocateChunkSize should fail 
 PASS Calling respond() with a bytesWritten value lower than autoAllocateChunkSize should succeed 
+PASS Calling respondWithNewView() with a this object different from ReadableStreamBYOBRequest should throw a TypeError 
+PASS Calling respondWithNewView() with an argument that is not an object should throw a TypeError 
+PASS Calling respondWithNewView() with an argument that is not an ArrayBufferView should throw a TypeError 
+PASS When using autoAllocateChunkSize, calling respondWithNewView() should succeed if view.byteLength is equal to autoAllocateChunkSize 
+PASS When using autoAllocateChunkSize, calling respondWithNewView() should throw a RangeError if view.byteOffset is different from 0 
+PASS When using autoAllocateChunkSize, calling respondWithNewView() should throw a RangeError if view.byteLength is different from autoAllocateChunkSize 
 
index b4ad4c4..57a4117 100644 (file)
@@ -241,4 +241,117 @@ promise_test(function() {
 // 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();
index 0c28f78..7cdbe6d 100644 (file)
@@ -1,3 +1,19 @@
+2017-04-06  Romain Bellessort  <romain.bellessort@crf.canon.fr>
+
+        [Readable Streams API] Implement ReadableStreamBYOBRequest respondWithNewView()
+        https://bugs.webkit.org/show_bug.cgi?id=170339
+
+        Reviewed by Youenn Fablet.
+
+        Implemented ReadableStreamBYOBRequest respondWithNewView().
+
+        Added new tests to check respondWithNewView() behaviour.
+
+        * Modules/streams/ReadableByteStreamInternals.js:
+        (readableByteStreamControllerRespondWithNewView): Added.
+        * Modules/streams/ReadableStreamBYOBRequest.js:
+        (respondWithNewView): Updated.
+
 2017-04-06  Eric Carlson  <eric.carlson@apple.com>
 
         [MediaStream] Host application should be able to mute and unmute media streams
index 3a755d8..b82de00 100644 (file)
@@ -347,6 +347,24 @@ function readableByteStreamControllerEnqueueChunk(controller, buffer, byteOffset
     controller.@totalQueuedBytes += byteLength;
 }
 
+function readableByteStreamControllerRespondWithNewView(controller, view)
+{
+    "use strict";
+
+    @assert(controller.@pendingPullIntos.length > 0);
+
+    let firstDescriptor = controller.@pendingPullIntos[0];
+
+    if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset)
+        @throwRangeError("Invalid value for view.byteOffset");
+
+    if (firstDescriptor.byteLength !== view.byteLength)
+        @throwRangeError("Invalid value for view.byteLength");
+
+    firstDescriptor.buffer = view.buffer;
+    @readableByteStreamControllerRespondInternal(controller, view.byteLength);
+}
+
 function readableByteStreamControllerRespond(controller, bytesWritten)
 {
     "use strict";
index 552b6e4..b924d99 100644 (file)
@@ -42,8 +42,19 @@ function respondWithNewView(view)
 {
     "use strict";
 
-    // FIXME: Implement appropriate behavior.
-    @throwTypeError("ReadableStreamBYOBRequest respondWithNewView() is not implemented");
+    if (!@isReadableStreamBYOBRequest(this))
+        throw @makeThisTypeError("ReadableStreamBYOBRequest", "respond");
+
+    if (this.@associatedReadableByteStreamController === @undefined)
+        @throwTypeError("ReadableStreamBYOBRequest.associatedReadableByteStreamController is undefined");
+
+    if (!@isObject(view))
+        @throwTypeError("Provided view is not an object");
+
+    if (!@ArrayBuffer.@isView(view))
+        @throwTypeError("Provided view is not an ArrayBufferView");
+
+    return @readableByteStreamControllerRespondWithNewView(this.@associatedReadableByteStreamController, view);
 }
 
 function view()