aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-07-31 06:17:56 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-07-31 06:17:56 -0700
commitf2983e50b7004277800a14c4bf9371906884693c (patch)
treef4f97db8720b4a4a4c8dc957eafdbfec715e0ac9
parente47a448434acc6c5ebfcaf2d22ed1c96a979e761 (diff)
downloadbun-f2983e50b7004277800a14c4bf9371906884693c.tar.gz
bun-f2983e50b7004277800a14c4bf9371906884693c.tar.zst
bun-f2983e50b7004277800a14c4bf9371906884693c.zip
Add a test for TransformStream
-rw-r--r--src/js/builtins/ReadableStreamDefaultReader.ts1
-rw-r--r--src/js/builtins/TransformStreamInternals.ts6
-rw-r--r--src/js/out/WebCoreJSBuiltins.cpp14
-rw-r--r--test/js/web/streams/streams.test.js47
4 files changed, 53 insertions, 15 deletions
diff --git a/src/js/builtins/ReadableStreamDefaultReader.ts b/src/js/builtins/ReadableStreamDefaultReader.ts
index b4e0c2bd3..ea1a64b68 100644
--- a/src/js/builtins/ReadableStreamDefaultReader.ts
+++ b/src/js/builtins/ReadableStreamDefaultReader.ts
@@ -59,7 +59,6 @@ export function readMany(this: ReadableStreamDefaultReader): ReadableStreamDefau
var controller = $getByIdDirectPrivate(stream, "readableStreamController");
var queue = $getByIdDirectPrivate(controller, "queue");
-
if (!queue) {
// This is a ReadableStream direct controller implemented in JS
// It hasn't been started yet.
diff --git a/src/js/builtins/TransformStreamInternals.ts b/src/js/builtins/TransformStreamInternals.ts
index 103b0651f..833fafdc6 100644
--- a/src/js/builtins/TransformStreamInternals.ts
+++ b/src/js/builtins/TransformStreamInternals.ts
@@ -241,7 +241,7 @@ export function transformStreamDefaultControllerPerformTransform(controller, chu
const transformPromise = $getByIdDirectPrivate(controller, "transformAlgorithm").$call(undefined, chunk);
transformPromise.$then(
() => {
- promiseCapability.$resolve();
+ promiseCapability.resolve();
},
r => {
$transformStreamError($getByIdDirectPrivate(controller, "stream"), r);
@@ -286,7 +286,7 @@ export function transformStreamDefaultSinkWriteAlgorithm(stream, chunk) {
$assert(state === "writable");
$transformStreamDefaultControllerPerformTransform(controller, chunk).$then(
() => {
- promiseCapability.$resolve();
+ promiseCapability.resolve();
},
e => {
promiseCapability.reject.$call(undefined, e);
@@ -329,7 +329,7 @@ export function transformStreamDefaultSinkCloseAlgorithm(stream) {
// FIXME: Update readableStreamDefaultControllerClose to make this check.
if ($readableStreamDefaultControllerCanCloseOrEnqueue(readableController))
$readableStreamDefaultControllerClose(readableController);
- promiseCapability.$resolve();
+ promiseCapability.resolve();
},
r => {
$transformStreamError($getByIdDirectPrivate(controller, "stream"), r);
diff --git a/src/js/out/WebCoreJSBuiltins.cpp b/src/js/out/WebCoreJSBuiltins.cpp
index a28464a57..06be7ba77 100644
--- a/src/js/out/WebCoreJSBuiltins.cpp
+++ b/src/js/out/WebCoreJSBuiltins.cpp
@@ -580,9 +580,9 @@ const char* const s_transformStreamInternalsTransformStreamDefaultControllerErro
const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeConstructorKind = JSC::ConstructorKind::None;
const JSC::ImplementationVisibility s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
-const int s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeLength = 275;
+const int s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeLength = 274;
static const JSC::Intrinsic s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCodeIntrinsic = JSC::NoIntrinsic;
-const char* const s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCode = "(function (d,g){\"use strict\";const _=@newPromiseCapability(@Promise);return @getByIdDirectPrivate(d,\"transformAlgorithm\").@call(@undefined,g).@then(()=>{_.@resolve()},(f)=>{@transformStreamError(@getByIdDirectPrivate(d,\"stream\"),f),_.reject.@call(@undefined,f)}),_.promise})\n";
+const char* const s_transformStreamInternalsTransformStreamDefaultControllerPerformTransformCode = "(function (d,g){\"use strict\";const _=@newPromiseCapability(@Promise);return @getByIdDirectPrivate(d,\"transformAlgorithm\").@call(@undefined,g).@then(()=>{_.resolve()},(f)=>{@transformStreamError(@getByIdDirectPrivate(d,\"stream\"),f),_.reject.@call(@undefined,f)}),_.promise})\n";
// transformStreamDefaultControllerTerminate
const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultControllerTerminateCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
@@ -596,9 +596,9 @@ const char* const s_transformStreamInternalsTransformStreamDefaultControllerTerm
const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeConstructorKind = JSC::ConstructorKind::None;
const JSC::ImplementationVisibility s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
-const int s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeLength = 759;
+const int s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeLength = 758;
static const JSC::Intrinsic s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCodeIntrinsic = JSC::NoIntrinsic;
-const char* const s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCode = "(function (d,q){\"use strict\";const j=@getByIdDirectPrivate(d,\"internalWritable\");@assert(@getByIdDirectPrivate(j,\"state\")===\"writable\");const v=@getByIdDirectPrivate(d,\"controller\");if(@getByIdDirectPrivate(d,\"backpressure\")){const _=@newPromiseCapability(@Promise),x=@getByIdDirectPrivate(d,\"backpressureChangePromise\");return @assert(x!==@undefined),x.promise.@then(()=>{const f=@getByIdDirectPrivate(j,\"state\");if(f===\"erroring\"){_.reject.@call(@undefined,@getByIdDirectPrivate(j,\"storedError\"));return}@assert(f===\"writable\"),@transformStreamDefaultControllerPerformTransform(v,q).@then(()=>{_.@resolve()},(z)=>{_.reject.@call(@undefined,z)})},(f)=>{_.reject.@call(@undefined,f)}),_.promise}return @transformStreamDefaultControllerPerformTransform(v,q)})\n";
+const char* const s_transformStreamInternalsTransformStreamDefaultSinkWriteAlgorithmCode = "(function (d,q){\"use strict\";const j=@getByIdDirectPrivate(d,\"internalWritable\");@assert(@getByIdDirectPrivate(j,\"state\")===\"writable\");const v=@getByIdDirectPrivate(d,\"controller\");if(@getByIdDirectPrivate(d,\"backpressure\")){const _=@newPromiseCapability(@Promise),x=@getByIdDirectPrivate(d,\"backpressureChangePromise\");return @assert(x!==@undefined),x.promise.@then(()=>{const f=@getByIdDirectPrivate(j,\"state\");if(f===\"erroring\"){_.reject.@call(@undefined,@getByIdDirectPrivate(j,\"storedError\"));return}@assert(f===\"writable\"),@transformStreamDefaultControllerPerformTransform(v,q).@then(()=>{_.resolve()},(z)=>{_.reject.@call(@undefined,z)})},(f)=>{_.reject.@call(@undefined,f)}),_.promise}return @transformStreamDefaultControllerPerformTransform(v,q)})\n";
// transformStreamDefaultSinkAbortAlgorithm
const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultSinkAbortAlgorithmCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
@@ -612,9 +612,9 @@ const char* const s_transformStreamInternalsTransformStreamDefaultSinkAbortAlgor
const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeConstructorKind = JSC::ConstructorKind::None;
const JSC::ImplementationVisibility s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
-const int s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeLength = 786;
+const int s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeLength = 785;
static const JSC::Intrinsic s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCodeIntrinsic = JSC::NoIntrinsic;
-const char* const s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCode = "(function (j){\"use strict\";const _=@getByIdDirectPrivate(j,\"readable\"),I=@getByIdDirectPrivate(j,\"controller\"),k=@getByIdDirectPrivate(_,\"readableStreamController\"),q=@getByIdDirectPrivate(I,\"flushAlgorithm\");@assert(q!==@undefined);const u=@getByIdDirectPrivate(I,\"flushAlgorithm\").@call();@transformStreamDefaultControllerClearAlgorithms(I);const S=@newPromiseCapability(@Promise);return u.@then(()=>{if(@getByIdDirectPrivate(_,\"state\")===@streamErrored){S.reject.@call(@undefined,@getByIdDirectPrivate(_,\"storedError\"));return}if(@readableStreamDefaultControllerCanCloseOrEnqueue(k))@readableStreamDefaultControllerClose(k);S.@resolve()},(v)=>{@transformStreamError(@getByIdDirectPrivate(I,\"stream\"),v),S.reject.@call(@undefined,@getByIdDirectPrivate(_,\"storedError\"))}),S.promise})\n";
+const char* const s_transformStreamInternalsTransformStreamDefaultSinkCloseAlgorithmCode = "(function (S){\"use strict\";const _=@getByIdDirectPrivate(S,\"readable\"),u=@getByIdDirectPrivate(S,\"controller\"),c=@getByIdDirectPrivate(_,\"readableStreamController\"),g=@getByIdDirectPrivate(u,\"flushAlgorithm\");@assert(g!==@undefined);const j=@getByIdDirectPrivate(u,\"flushAlgorithm\").@call();@transformStreamDefaultControllerClearAlgorithms(u);const I=@newPromiseCapability(@Promise);return j.@then(()=>{if(@getByIdDirectPrivate(_,\"state\")===@streamErrored){I.reject.@call(@undefined,@getByIdDirectPrivate(_,\"storedError\"));return}if(@readableStreamDefaultControllerCanCloseOrEnqueue(c))@readableStreamDefaultControllerClose(c);I.resolve()},(k)=>{@transformStreamError(@getByIdDirectPrivate(u,\"stream\"),k),I.reject.@call(@undefined,@getByIdDirectPrivate(_,\"storedError\"))}),I.promise})\n";
// transformStreamDefaultSourcePullAlgorithm
const JSC::ConstructAbility s_transformStreamInternalsTransformStreamDefaultSourcePullAlgorithmCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
@@ -2054,7 +2054,7 @@ const JSC::ConstructorKind s_readableStreamDefaultReaderReadManyCodeConstructorK
const JSC::ImplementationVisibility s_readableStreamDefaultReaderReadManyCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
const int s_readableStreamDefaultReaderReadManyCodeLength = 2598;
static const JSC::Intrinsic s_readableStreamDefaultReaderReadManyCodeIntrinsic = JSC::NoIntrinsic;
-const char* const s_readableStreamDefaultReaderReadManyCode = "(function (){\"use strict\";if(!@isReadableStreamDefaultReader(this))@throwTypeError(\"ReadableStreamDefaultReader.readMany() should not be called directly\");const j=@getByIdDirectPrivate(this,\"ownerReadableStream\");if(!j)@throwTypeError(\"readMany() called on a reader owned by no readable stream\");const I=@getByIdDirectPrivate(j,\"state\");if(@putByIdDirectPrivate(j,\"disturbed\",!0),I===@streamClosed)return{value:[],size:0,done:!0};else if(I===@streamErrored)throw @getByIdDirectPrivate(j,\"storedError\");var B=@getByIdDirectPrivate(j,\"readableStreamController\"),F=@getByIdDirectPrivate(B,\"queue\");if(!F)return B.@pull(B).@then(function({done:_,value:w}){return _\?{done:!0,value:[],size:0}:{value:[w],size:1,done:!1}});const N=F.content;var Q=F.size,x=N.toArray(!1),C=x.length;if(C>0){var D=@newArrayWithSize(C);if(@isReadableByteStreamController(B)){{const _=x[0];if(!(@ArrayBuffer.@isView(_)||_ instanceof @ArrayBuffer))@putByValDirect(D,0,new @Uint8Array(_.buffer,_.byteOffset,_.byteLength));else @putByValDirect(D,0,_)}for(var d=1;d<C;d++){const _=x[d];if(!(@ArrayBuffer.@isView(_)||_ instanceof @ArrayBuffer))@putByValDirect(D,d,new @Uint8Array(_.buffer,_.byteOffset,_.byteLength));else @putByValDirect(D,d,_)}}else{@putByValDirect(D,0,x[0].value);for(var d=1;d<C;d++)@putByValDirect(D,d,x[d].value)}if(@resetQueue(@getByIdDirectPrivate(B,\"queue\")),@getByIdDirectPrivate(B,\"closeRequested\"))@readableStreamClose(@getByIdDirectPrivate(B,\"controlledReadableStream\"));else if(@isReadableStreamDefaultController(B))@readableStreamDefaultControllerCallPullIfNeeded(B);else if(@isReadableByteStreamController(B))@readableByteStreamControllerCallPullIfNeeded(B);return{value:D,size:Q,done:!1}}var J=(_)=>{if(_.done)return{value:[],size:0,done:!0};var w=@getByIdDirectPrivate(j,\"readableStreamController\"),G=@getByIdDirectPrivate(w,\"queue\"),k=[_.value].concat(G.content.toArray(!1)),K=k.length;if(@isReadableByteStreamController(w))for(var A=0;A<K;A++){const H=k[A];if(!(@ArrayBuffer.@isView(H)||H instanceof @ArrayBuffer)){const{buffer:T,byteOffset:U,byteLength:W}=H;@putByValDirect(k,A,new @Uint8Array(T,U,W))}}else for(var A=1;A<K;A++)@putByValDirect(k,A,k[A].value);var S=G.size;if(@resetQueue(G),@getByIdDirectPrivate(w,\"closeRequested\"))@readableStreamClose(@getByIdDirectPrivate(w,\"controlledReadableStream\"));else if(@isReadableStreamDefaultController(w))@readableStreamDefaultControllerCallPullIfNeeded(w);else if(@isReadableByteStreamController(w))@readableByteStreamControllerCallPullIfNeeded(w);return{value:k,size:S,done:!1}},E=B.@pull(B);if(E&&@isPromise(E))return E.@then(J);return J(E)})\n";
+const char* const s_readableStreamDefaultReaderReadManyCode = "(function (){\"use strict\";if(!@isReadableStreamDefaultReader(this))@throwTypeError(\"ReadableStreamDefaultReader.readMany() should not be called directly\");const k=@getByIdDirectPrivate(this,\"ownerReadableStream\");if(!k)@throwTypeError(\"readMany() called on a reader owned by no readable stream\");const H=@getByIdDirectPrivate(k,\"state\");if(@putByIdDirectPrivate(k,\"disturbed\",!0),H===@streamClosed)return{value:[],size:0,done:!0};else if(H===@streamErrored)throw @getByIdDirectPrivate(k,\"storedError\");var d=@getByIdDirectPrivate(k,\"readableStreamController\"),E=@getByIdDirectPrivate(d,\"queue\");if(!E)return d.@pull(d).@then(function({done:_,value:B}){return _\?{done:!0,value:[],size:0}:{value:[B],size:1,done:!1}});const L=E.content;var N=E.size,A=L.toArray(!1),C=A.length;if(C>0){var j=@newArrayWithSize(C);if(@isReadableByteStreamController(d)){{const _=A[0];if(!(@ArrayBuffer.@isView(_)||_ instanceof @ArrayBuffer))@putByValDirect(j,0,new @Uint8Array(_.buffer,_.byteOffset,_.byteLength));else @putByValDirect(j,0,_)}for(var w=1;w<C;w++){const _=A[w];if(!(@ArrayBuffer.@isView(_)||_ instanceof @ArrayBuffer))@putByValDirect(j,w,new @Uint8Array(_.buffer,_.byteOffset,_.byteLength));else @putByValDirect(j,w,_)}}else{@putByValDirect(j,0,A[0].value);for(var w=1;w<C;w++)@putByValDirect(j,w,A[w].value)}if(@resetQueue(@getByIdDirectPrivate(d,\"queue\")),@getByIdDirectPrivate(d,\"closeRequested\"))@readableStreamClose(@getByIdDirectPrivate(d,\"controlledReadableStream\"));else if(@isReadableStreamDefaultController(d))@readableStreamDefaultControllerCallPullIfNeeded(d);else if(@isReadableByteStreamController(d))@readableByteStreamControllerCallPullIfNeeded(d);return{value:j,size:N,done:!1}}var J=(_)=>{if(_.done)return{value:[],size:0,done:!0};var B=@getByIdDirectPrivate(k,\"readableStreamController\"),F=@getByIdDirectPrivate(B,\"queue\"),x=[_.value].concat(F.content.toArray(!1)),K=x.length;if(@isReadableByteStreamController(B))for(var I=0;I<K;I++){const G=x[I];if(!(@ArrayBuffer.@isView(G)||G instanceof @ArrayBuffer)){const{buffer:S,byteOffset:T,byteLength:U}=G;@putByValDirect(x,I,new @Uint8Array(S,T,U))}}else for(var I=1;I<K;I++)@putByValDirect(x,I,x[I].value);var Q=F.size;if(@resetQueue(F),@getByIdDirectPrivate(B,\"closeRequested\"))@readableStreamClose(@getByIdDirectPrivate(B,\"controlledReadableStream\"));else if(@isReadableStreamDefaultController(B))@readableStreamDefaultControllerCallPullIfNeeded(B);else if(@isReadableByteStreamController(B))@readableByteStreamControllerCallPullIfNeeded(B);return{value:x,size:Q,done:!1}},D=d.@pull(d);if(D&&@isPromise(D))return D.@then(J);return J(D)})\n";
// read
const JSC::ConstructAbility s_readableStreamDefaultReaderReadCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
diff --git a/test/js/web/streams/streams.test.js b/test/js/web/streams/streams.test.js
index 55843cb23..7359009b7 100644
--- a/test/js/web/streams/streams.test.js
+++ b/test/js/web/streams/streams.test.js
@@ -5,6 +5,48 @@ import { realpathSync, unlinkSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "os";
+it("TransformStream", async () => {
+ // https://developer.mozilla.org/en-US/docs/Web/API/TransformStream
+ const TextEncoderStreamInterface = {
+ start() {
+ this.encoder = new TextEncoder();
+ },
+ transform(chunk, controller) {
+ controller.enqueue(this.encoder.encode(chunk));
+ },
+ };
+
+ let instances = new WeakMap();
+ class JSTextEncoderStream extends TransformStream {
+ constructor() {
+ super(TextEncoderStreamInterface);
+ instances.set(this, TextEncoderStreamInterface);
+ }
+ get encoding() {
+ return instances.get(this).encoder.encoding;
+ }
+ }
+
+ const stream = new JSTextEncoderStream();
+ const { writable, readable } = stream;
+
+ const writer = writable.getWriter();
+ writer.write("hello");
+ writer.write("world");
+ writer.close();
+
+ const reader = readable.getReader();
+ const chunks = [];
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) break;
+ chunks.push(value);
+ }
+ reader.cancel();
+
+ expect(Buffer.concat(chunks).toString()).toEqual("helloworld");
+});
+
describe("readableStreamToFormData", () => {
const fixtures = {
withTextFile: [
@@ -171,10 +213,7 @@ describe("WritableStream", () => {
write(chunk, controller) {
chunks.push(chunk);
},
- close(er) {
- console.log("closed");
- console.log(er);
- },
+ close(er) {},
abort(reason) {
console.log("aborted!");
console.log(reason);