1// META: global=window,worker
2// META: script=../resources/rs-utils.js
3'use strict';
4
5// Prior to whatwg/stream#870 it was possible to construct a ReadableStreamBYOBRequest directly. This made it possible
6// to construct requests that were out-of-sync with the state of the ReadableStream. They could then be used to call
7// internal operations, resulting in asserts or bad behaviour. This file contains regression tests for the change.
8
9function getRealByteStreamController() {
10  let controller;
11  new ReadableStream({
12    start(c) {
13      controller = c;
14    },
15    type: 'bytes'
16  });
17  return controller;
18}
19
20// Create an object pretending to have prototype |prototype|, of type |type|. |type| is one of "undefined", "null",
21// "fake", or "real". "real" will call the realObjectCreator function to get a real instance of the object.
22function createDummyObject(prototype, type, realObjectCreator) {
23  switch (type) {
24    case 'undefined':
25      return undefined;
26
27    case 'null':
28      return null;
29
30    case 'fake':
31      return Object.create(prototype);
32
33    case 'real':
34      return realObjectCreator();
35  }
36
37  throw new Error('not reached');
38}
39
40const dummyTypes = ['undefined', 'null', 'fake', 'real'];
41
42for (const controllerType of dummyTypes) {
43  const controller = createDummyObject(ReadableByteStreamController.prototype, controllerType,
44                                        getRealByteStreamController);
45  for (const viewType of dummyTypes) {
46    const view = createDummyObject(Uint8Array.prototype, viewType, () => new Uint8Array(16));
47    test(() => {
48      assert_throws_js(TypeError, () => new ReadableStreamBYOBRequest(controller, view),
49                        'constructor should throw');
50    }, `ReadableStreamBYOBRequest constructor should throw when passed a ${controllerType} ` +
51        `ReadableByteStreamController and a ${viewType} view`);
52  }
53}
54