11cb0ef41Sopenharmony_ci// META: global=window,worker
21cb0ef41Sopenharmony_ci// META: script=../resources/recording-streams.js
31cb0ef41Sopenharmony_ci// META: script=../resources/test-utils.js
41cb0ef41Sopenharmony_ci'use strict';
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci// Here we just test that the strategies are correctly passed to the readable and writable sides. We assume that
71cb0ef41Sopenharmony_ci// ReadableStream and WritableStream will correctly apply the strategies when they are being used by a TransformStream
81cb0ef41Sopenharmony_ci// and so it isn't necessary to repeat their tests here.
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_citest(() => {
111cb0ef41Sopenharmony_ci  const ts = new TransformStream({}, { highWaterMark: 17 });
121cb0ef41Sopenharmony_ci  assert_equals(ts.writable.getWriter().desiredSize, 17, 'desiredSize should be 17');
131cb0ef41Sopenharmony_ci}, 'writableStrategy highWaterMark should work');
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cipromise_test(() => {
161cb0ef41Sopenharmony_ci  const ts = recordingTransformStream({}, undefined, { highWaterMark: 9 });
171cb0ef41Sopenharmony_ci  const writer = ts.writable.getWriter();
181cb0ef41Sopenharmony_ci  for (let i = 0; i < 10; ++i) {
191cb0ef41Sopenharmony_ci    writer.write(i);
201cb0ef41Sopenharmony_ci  }
211cb0ef41Sopenharmony_ci  return delay(0).then(() => {
221cb0ef41Sopenharmony_ci    assert_array_equals(ts.events, [
231cb0ef41Sopenharmony_ci      'transform', 0, 'transform', 1, 'transform', 2, 'transform', 3, 'transform', 4,
241cb0ef41Sopenharmony_ci      'transform', 5, 'transform', 6, 'transform', 7, 'transform', 8],
251cb0ef41Sopenharmony_ci                        'transform() should have been called 9 times');
261cb0ef41Sopenharmony_ci  });
271cb0ef41Sopenharmony_ci}, 'readableStrategy highWaterMark should work');
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_cipromise_test(t => {
301cb0ef41Sopenharmony_ci  let writableSizeCalled = false;
311cb0ef41Sopenharmony_ci  let readableSizeCalled = false;
321cb0ef41Sopenharmony_ci  let transformCalled = false;
331cb0ef41Sopenharmony_ci  const ts = new TransformStream(
341cb0ef41Sopenharmony_ci    {
351cb0ef41Sopenharmony_ci      transform(chunk, controller) {
361cb0ef41Sopenharmony_ci        t.step(() => {
371cb0ef41Sopenharmony_ci          transformCalled = true;
381cb0ef41Sopenharmony_ci          assert_true(writableSizeCalled, 'writableStrategy.size() should have been called');
391cb0ef41Sopenharmony_ci          assert_false(readableSizeCalled, 'readableStrategy.size() should not have been called');
401cb0ef41Sopenharmony_ci          controller.enqueue(chunk);
411cb0ef41Sopenharmony_ci          assert_true(readableSizeCalled, 'readableStrategy.size() should have been called');
421cb0ef41Sopenharmony_ci        });
431cb0ef41Sopenharmony_ci      }
441cb0ef41Sopenharmony_ci    },
451cb0ef41Sopenharmony_ci    {
461cb0ef41Sopenharmony_ci      size() {
471cb0ef41Sopenharmony_ci        writableSizeCalled = true;
481cb0ef41Sopenharmony_ci        return 1;
491cb0ef41Sopenharmony_ci      }
501cb0ef41Sopenharmony_ci    },
511cb0ef41Sopenharmony_ci    {
521cb0ef41Sopenharmony_ci      size() {
531cb0ef41Sopenharmony_ci        readableSizeCalled = true;
541cb0ef41Sopenharmony_ci        return 1;
551cb0ef41Sopenharmony_ci      },
561cb0ef41Sopenharmony_ci      highWaterMark: Infinity
571cb0ef41Sopenharmony_ci    });
581cb0ef41Sopenharmony_ci  return ts.writable.getWriter().write().then(() => {
591cb0ef41Sopenharmony_ci    assert_true(transformCalled, 'transform() should be called');
601cb0ef41Sopenharmony_ci  });
611cb0ef41Sopenharmony_ci}, 'writable should have the correct size() function');
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_citest(() => {
641cb0ef41Sopenharmony_ci  const ts = new TransformStream();
651cb0ef41Sopenharmony_ci  const writer = ts.writable.getWriter();
661cb0ef41Sopenharmony_ci  assert_equals(writer.desiredSize, 1, 'default writable HWM is 1');
671cb0ef41Sopenharmony_ci  writer.write(undefined);
681cb0ef41Sopenharmony_ci  assert_equals(writer.desiredSize, 0, 'default chunk size is 1');
691cb0ef41Sopenharmony_ci}, 'default writable strategy should be equivalent to { highWaterMark: 1 }');
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_cipromise_test(t => {
721cb0ef41Sopenharmony_ci  const ts = new TransformStream({
731cb0ef41Sopenharmony_ci    transform(chunk, controller) {
741cb0ef41Sopenharmony_ci      return t.step(() => {
751cb0ef41Sopenharmony_ci        assert_equals(controller.desiredSize, 0, 'desiredSize should be 0');
761cb0ef41Sopenharmony_ci        controller.enqueue(undefined);
771cb0ef41Sopenharmony_ci        // The first chunk enqueued is consumed by the pending read().
781cb0ef41Sopenharmony_ci        assert_equals(controller.desiredSize, 0, 'desiredSize should still be 0');
791cb0ef41Sopenharmony_ci        controller.enqueue(undefined);
801cb0ef41Sopenharmony_ci        assert_equals(controller.desiredSize, -1, 'desiredSize should be -1');
811cb0ef41Sopenharmony_ci      });
821cb0ef41Sopenharmony_ci    }
831cb0ef41Sopenharmony_ci  });
841cb0ef41Sopenharmony_ci  const writePromise = ts.writable.getWriter().write();
851cb0ef41Sopenharmony_ci  return ts.readable.getReader().read().then(() => writePromise);
861cb0ef41Sopenharmony_ci}, 'default readable strategy should be equivalent to { highWaterMark: 0 }');
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_citest(() => {
891cb0ef41Sopenharmony_ci  assert_throws_js(RangeError, () => new TransformStream(undefined, { highWaterMark: -1 }),
901cb0ef41Sopenharmony_ci                   'should throw RangeError for negative writableHighWaterMark');
911cb0ef41Sopenharmony_ci  assert_throws_js(RangeError, () => new TransformStream(undefined, undefined, { highWaterMark: -1 }),
921cb0ef41Sopenharmony_ci                   'should throw RangeError for negative readableHighWaterMark');
931cb0ef41Sopenharmony_ci  assert_throws_js(RangeError, () => new TransformStream(undefined, { highWaterMark: NaN }),
941cb0ef41Sopenharmony_ci                   'should throw RangeError for NaN writableHighWaterMark');
951cb0ef41Sopenharmony_ci  assert_throws_js(RangeError, () => new TransformStream(undefined, undefined, { highWaterMark: NaN }),
961cb0ef41Sopenharmony_ci                   'should throw RangeError for NaN readableHighWaterMark');
971cb0ef41Sopenharmony_ci}, 'a RangeError should be thrown for an invalid highWaterMark');
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ciconst objectThatConvertsTo42 = {
1001cb0ef41Sopenharmony_ci  toString() {
1011cb0ef41Sopenharmony_ci    return '42';
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci};
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_citest(() => {
1061cb0ef41Sopenharmony_ci  const ts = new TransformStream(undefined, { highWaterMark: objectThatConvertsTo42 });
1071cb0ef41Sopenharmony_ci  const writer = ts.writable.getWriter();
1081cb0ef41Sopenharmony_ci  assert_equals(writer.desiredSize, 42, 'writable HWM is 42');
1091cb0ef41Sopenharmony_ci}, 'writableStrategy highWaterMark should be converted to a number');
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_citest(() => {
1121cb0ef41Sopenharmony_ci  const ts = new TransformStream({
1131cb0ef41Sopenharmony_ci    start(controller) {
1141cb0ef41Sopenharmony_ci      assert_equals(controller.desiredSize, 42, 'desiredSize should be 42');
1151cb0ef41Sopenharmony_ci    }
1161cb0ef41Sopenharmony_ci  }, undefined, { highWaterMark: objectThatConvertsTo42 });
1171cb0ef41Sopenharmony_ci}, 'readableStrategy highWaterMark should be converted to a number');
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_cipromise_test(t => {
1201cb0ef41Sopenharmony_ci  const ts = new TransformStream(undefined, undefined, {
1211cb0ef41Sopenharmony_ci    size() { return NaN; },
1221cb0ef41Sopenharmony_ci    highWaterMark: 1
1231cb0ef41Sopenharmony_ci  });
1241cb0ef41Sopenharmony_ci  const writer = ts.writable.getWriter();
1251cb0ef41Sopenharmony_ci  return promise_rejects_js(t, RangeError, writer.write(), 'write should reject');
1261cb0ef41Sopenharmony_ci}, 'a bad readableStrategy size function should cause writer.write() to reject on an identity transform');
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_cipromise_test(t => {
1291cb0ef41Sopenharmony_ci  const ts = new TransformStream({
1301cb0ef41Sopenharmony_ci    transform(chunk, controller) {
1311cb0ef41Sopenharmony_ci      // This assert has the important side-effect of catching the error, so transform() does not throw.
1321cb0ef41Sopenharmony_ci      assert_throws_js(RangeError, () => controller.enqueue(chunk), 'enqueue should throw');
1331cb0ef41Sopenharmony_ci    }
1341cb0ef41Sopenharmony_ci  }, undefined, {
1351cb0ef41Sopenharmony_ci    size() {
1361cb0ef41Sopenharmony_ci      return -1;
1371cb0ef41Sopenharmony_ci    },
1381cb0ef41Sopenharmony_ci    highWaterMark: 1
1391cb0ef41Sopenharmony_ci  });
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci  const writer = ts.writable.getWriter();
1421cb0ef41Sopenharmony_ci  return writer.write().then(() => {
1431cb0ef41Sopenharmony_ci    return Promise.all([
1441cb0ef41Sopenharmony_ci      promise_rejects_js(t, RangeError, writer.ready, 'ready should reject'),
1451cb0ef41Sopenharmony_ci      promise_rejects_js(t, RangeError, writer.closed, 'closed should reject'),
1461cb0ef41Sopenharmony_ci      promise_rejects_js(t, RangeError, ts.readable.getReader().closed, 'readable closed should reject')
1471cb0ef41Sopenharmony_ci    ]);
1481cb0ef41Sopenharmony_ci  });
1491cb0ef41Sopenharmony_ci}, 'a bad readableStrategy size function should error the stream on enqueue even when transformer.transform() ' +
1501cb0ef41Sopenharmony_ci   'catches the exception');
151