Skip to content
File

Blob: src/workerd/api/tests/streams-no-auto-allocate-test.js

javascript167 lines
1// Copyright (c) 2026 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4// Test for streams_no_default_auto_allocate_chunk_size compat flag
5import { strictEqual, ok, deepStrictEqual } from 'node:assert';
6 
7export const byobRequestIsNullWithoutAutoAllocate = {
8 async test() {
9 // When autoAllocateChunkSize is NOT set, byobRequest should be null
10 // for non-BYOB reads (spec-compliant behavior)
11 let byobRequestWasNull = false;
12 let pullCalled = false;
13 
14 const rs = new ReadableStream({
15 type: 'bytes',
16 pull(controller) {
17 pullCalled = true;
18 byobRequestWasNull = controller.byobRequest === null;
19 // Must use enqueue() since byobRequest is null
20 controller.enqueue(new Uint8Array([1, 2, 3, 4]));
21 controller.close();
22 },
23 });
24 
25 const reader = rs.getReader();
26 const result = await reader.read();
27 
28 ok(pullCalled, 'pull should have been called');
29 ok(
30 byobRequestWasNull,
31 'byobRequest should be null when autoAllocateChunkSize is not set'
32 );
33 strictEqual(result.done, false);
34 deepStrictEqual([...result.value], [1, 2, 3, 4]);
35 },
36};
37 
38export const byobRequestAvailableWithAutoAllocate = {
39 async test() {
40 // When autoAllocateChunkSize IS set, byobRequest should be available
41 let byobRequestWasAvailable = false;
42 let pullCalled = false;
43 
44 const rs = new ReadableStream({
45 type: 'bytes',
46 autoAllocateChunkSize: 1024,
47 pull(controller) {
48 pullCalled = true;
49 byobRequestWasAvailable = controller.byobRequest !== null;
50 if (controller.byobRequest) {
51 // Use the BYOB request
52 const view = controller.byobRequest.view;
53 new Uint8Array(view.buffer, view.byteOffset, 4).set([5, 6, 7, 8]);
54 controller.byobRequest.respond(4);
55 } else {
56 controller.enqueue(new Uint8Array([5, 6, 7, 8]));
57 }
58 controller.close();
59 },
60 });
61 
62 const reader = rs.getReader();
63 const result = await reader.read();
64 
65 ok(pullCalled, 'pull should have been called');
66 ok(
67 byobRequestWasAvailable,
68 'byobRequest should be available when autoAllocateChunkSize is set'
69 );
70 strictEqual(result.done, false);
71 deepStrictEqual([...result.value], [5, 6, 7, 8]);
72 },
73};
74 
75export const byobReadStillWorks = {
76 async test() {
77 // BYOB reads should still work regardless of autoAllocateChunkSize
78 let byobRequestWasAvailable = false;
79 
80 const rs = new ReadableStream({
81 type: 'bytes',
82 // No autoAllocateChunkSize set
83 pull(controller) {
84 byobRequestWasAvailable = controller.byobRequest !== null;
85 if (controller.byobRequest) {
86 const view = controller.byobRequest.view;
87 new Uint8Array(view.buffer, view.byteOffset, 4).set([9, 10, 11, 12]);
88 controller.byobRequest.respond(4);
89 }
90 controller.close();
91 },
92 });
93 
94 // Use BYOB reader
95 const reader = rs.getReader({ mode: 'byob' });
96 const buffer = new Uint8Array(16);
97 const result = await reader.read(buffer);
98 
99 ok(
100 byobRequestWasAvailable,
101 'byobRequest should be available for BYOB reads'
102 );
103 strictEqual(result.done, false);
104 deepStrictEqual([...result.value], [9, 10, 11, 12]);
105 },
106};
107 
108export const multipleReadsWithEnqueue = {
109 async test() {
110 // Test that multiple reads work correctly with enqueue()
111 let pullCount = 0;
112 
113 const rs = new ReadableStream({
114 type: 'bytes',
115 pull(controller) {
116 pullCount++;
117 if (pullCount <= 3) {
118 controller.enqueue(new Uint8Array([pullCount]));
119 } else {
120 controller.close();
121 }
122 },
123 });
124 
125 const reader = rs.getReader();
126 const chunks = [];
127 
128 while (true) {
129 const { value, done } = await reader.read();
130 if (done) break;
131 chunks.push([...value]);
132 }
133 
134 strictEqual(chunks.length, 3);
135 deepStrictEqual(chunks[0], [1]);
136 deepStrictEqual(chunks[1], [2]);
137 deepStrictEqual(chunks[2], [3]);
138 },
139};
140 
141export const pipeToWorksWithoutAutoAllocate = {
142 async test() {
143 // Test that pipeTo works correctly without autoAllocateChunkSize
144 const allBytes = [];
145 
146 const rs = new ReadableStream({
147 type: 'bytes',
148 start(controller) {
149 controller.enqueue(new Uint8Array([1, 2]));
150 controller.enqueue(new Uint8Array([3, 4]));
151 controller.close();
152 },
153 });
154 
155 const ws = new WritableStream({
156 write(chunk) {
157 allBytes.push(...chunk);
158 },
159 });
160 
161 await rs.pipeTo(ws);
162 
163 // Verify all bytes were received (chunks may be combined)
164 deepStrictEqual(allBytes, [1, 2, 3, 4]);
165 },
166};