11cb0ef41Sopenharmony_ci// META: global=window,worker
21cb0ef41Sopenharmony_ci'use strict';
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_ci// Tests which patch the global environment are kept separate to avoid
51cb0ef41Sopenharmony_ci// interfering with other tests.
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciconst ReadableStream_prototype_locked_get =
81cb0ef41Sopenharmony_ci      Object.getOwnPropertyDescriptor(ReadableStream.prototype, 'locked').get;
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci// Verify that |rs| passes the brand check as a readable stream.
111cb0ef41Sopenharmony_cifunction isReadableStream(rs) {
121cb0ef41Sopenharmony_ci  try {
131cb0ef41Sopenharmony_ci    ReadableStream_prototype_locked_get.call(rs);
141cb0ef41Sopenharmony_ci    return true;
151cb0ef41Sopenharmony_ci  } catch (e) {
161cb0ef41Sopenharmony_ci    return false;
171cb0ef41Sopenharmony_ci  }
181cb0ef41Sopenharmony_ci}
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_citest(t => {
211cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci  const trappedProperties = ['highWaterMark', 'size', 'start', 'type', 'mode'];
241cb0ef41Sopenharmony_ci  for (const property of trappedProperties) {
251cb0ef41Sopenharmony_ci    // eslint-disable-next-line no-extend-native, accessor-pairs
261cb0ef41Sopenharmony_ci    Object.defineProperty(Object.prototype, property, {
271cb0ef41Sopenharmony_ci      get() { throw new Error(`${property} getter called`); },
281cb0ef41Sopenharmony_ci      configurable: true
291cb0ef41Sopenharmony_ci    });
301cb0ef41Sopenharmony_ci  }
311cb0ef41Sopenharmony_ci  t.add_cleanup(() => {
321cb0ef41Sopenharmony_ci    for (const property of trappedProperties) {
331cb0ef41Sopenharmony_ci      delete Object.prototype[property];
341cb0ef41Sopenharmony_ci    }
351cb0ef41Sopenharmony_ci  });
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  const [branch1, branch2] = rs.tee();
381cb0ef41Sopenharmony_ci  assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream');
391cb0ef41Sopenharmony_ci  assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream');
401cb0ef41Sopenharmony_ci}, 'ReadableStream tee() should not touch Object.prototype properties');
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_citest(t => {
431cb0ef41Sopenharmony_ci  const rs = new ReadableStream();
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  const oldReadableStream = self.ReadableStream;
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  self.ReadableStream = function() {
481cb0ef41Sopenharmony_ci    throw new Error('ReadableStream called on global object');
491cb0ef41Sopenharmony_ci  };
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  t.add_cleanup(() => {
521cb0ef41Sopenharmony_ci    self.ReadableStream = oldReadableStream;
531cb0ef41Sopenharmony_ci  });
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  const [branch1, branch2] = rs.tee();
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream');
581cb0ef41Sopenharmony_ci  assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream');
591cb0ef41Sopenharmony_ci}, 'ReadableStream tee() should not call the global ReadableStream');
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_cipromise_test(async t => {
621cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
631cb0ef41Sopenharmony_ci    start(c) {
641cb0ef41Sopenharmony_ci      c.enqueue(1);
651cb0ef41Sopenharmony_ci      c.enqueue(2);
661cb0ef41Sopenharmony_ci      c.enqueue(3);
671cb0ef41Sopenharmony_ci      c.close();
681cb0ef41Sopenharmony_ci    }
691cb0ef41Sopenharmony_ci  });
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  const oldReadableStreamGetReader = ReadableStream.prototype.getReader;
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  const ReadableStreamDefaultReader = (new ReadableStream()).getReader().constructor;
741cb0ef41Sopenharmony_ci  const oldDefaultReaderRead = ReadableStreamDefaultReader.prototype.read;
751cb0ef41Sopenharmony_ci  const oldDefaultReaderCancel = ReadableStreamDefaultReader.prototype.cancel;
761cb0ef41Sopenharmony_ci  const oldDefaultReaderReleaseLock = ReadableStreamDefaultReader.prototype.releaseLock;
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  self.ReadableStream.prototype.getReader = function() {
791cb0ef41Sopenharmony_ci    throw new Error('patched getReader() called');
801cb0ef41Sopenharmony_ci  };
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  ReadableStreamDefaultReader.prototype.read = function() {
831cb0ef41Sopenharmony_ci    throw new Error('patched read() called');
841cb0ef41Sopenharmony_ci  };
851cb0ef41Sopenharmony_ci  ReadableStreamDefaultReader.prototype.cancel = function() {
861cb0ef41Sopenharmony_ci    throw new Error('patched cancel() called');
871cb0ef41Sopenharmony_ci  };
881cb0ef41Sopenharmony_ci  ReadableStreamDefaultReader.prototype.releaseLock = function() {
891cb0ef41Sopenharmony_ci    throw new Error('patched releaseLock() called');
901cb0ef41Sopenharmony_ci  };
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  t.add_cleanup(() => {
931cb0ef41Sopenharmony_ci    self.ReadableStream.prototype.getReader = oldReadableStreamGetReader;
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci    ReadableStreamDefaultReader.prototype.read = oldDefaultReaderRead;
961cb0ef41Sopenharmony_ci    ReadableStreamDefaultReader.prototype.cancel = oldDefaultReaderCancel;
971cb0ef41Sopenharmony_ci    ReadableStreamDefaultReader.prototype.releaseLock = oldDefaultReaderReleaseLock;
981cb0ef41Sopenharmony_ci  });
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  // read the first chunk, then cancel
1011cb0ef41Sopenharmony_ci  for await (const chunk of rs) {
1021cb0ef41Sopenharmony_ci    break;
1031cb0ef41Sopenharmony_ci  }
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  // should be able to acquire a new reader
1061cb0ef41Sopenharmony_ci  const reader = oldReadableStreamGetReader.call(rs);
1071cb0ef41Sopenharmony_ci  // stream should be cancelled
1081cb0ef41Sopenharmony_ci  await reader.closed;
1091cb0ef41Sopenharmony_ci}, 'ReadableStream async iterator should use the original values of getReader() and ReadableStreamDefaultReader ' +
1101cb0ef41Sopenharmony_ci   'methods');
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_citest(t => {
1131cb0ef41Sopenharmony_ci  const oldPromiseThen = Promise.prototype.then;
1141cb0ef41Sopenharmony_ci  Promise.prototype.then = () => {
1151cb0ef41Sopenharmony_ci    throw new Error('patched then() called');
1161cb0ef41Sopenharmony_ci  };
1171cb0ef41Sopenharmony_ci  t.add_cleanup(() => {
1181cb0ef41Sopenharmony_ci    Promise.prototype.then = oldPromiseThen;
1191cb0ef41Sopenharmony_ci  });
1201cb0ef41Sopenharmony_ci  const [branch1, branch2] = new ReadableStream().tee();
1211cb0ef41Sopenharmony_ci  assert_true(isReadableStream(branch1), 'branch1 should be a ReadableStream');
1221cb0ef41Sopenharmony_ci  assert_true(isReadableStream(branch2), 'branch2 should be a ReadableStream');
1231cb0ef41Sopenharmony_ci}, 'tee() should not call Promise.prototype.then()');
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_citest(t => {
1261cb0ef41Sopenharmony_ci  const oldPromiseThen = Promise.prototype.then;
1271cb0ef41Sopenharmony_ci  Promise.prototype.then = () => {
1281cb0ef41Sopenharmony_ci    throw new Error('patched then() called');
1291cb0ef41Sopenharmony_ci  };
1301cb0ef41Sopenharmony_ci  t.add_cleanup(() => {
1311cb0ef41Sopenharmony_ci    Promise.prototype.then = oldPromiseThen;
1321cb0ef41Sopenharmony_ci  });
1331cb0ef41Sopenharmony_ci  let readableController;
1341cb0ef41Sopenharmony_ci  const rs = new ReadableStream({
1351cb0ef41Sopenharmony_ci    start(c) {
1361cb0ef41Sopenharmony_ci      readableController = c;
1371cb0ef41Sopenharmony_ci    }
1381cb0ef41Sopenharmony_ci  });
1391cb0ef41Sopenharmony_ci  const ws = new WritableStream();
1401cb0ef41Sopenharmony_ci  rs.pipeTo(ws);
1411cb0ef41Sopenharmony_ci  readableController.close();
1421cb0ef41Sopenharmony_ci}, 'pipeTo() should not call Promise.prototype.then()');
143