1'use strict';
2
3(() => {
4  // Create a ReadableStream that will pass the tests in
5  // testTransferredReadableStream(), below.
6  function createOriginalReadableStream() {
7    return new ReadableStream({
8      start(controller) {
9        controller.enqueue('a');
10        controller.close();
11      }
12    });
13  }
14
15  // Common tests to roughly determine that |rs| is a correctly transferred
16  // version of a stream created by createOriginalReadableStream().
17  function testTransferredReadableStream(rs) {
18    assert_equals(rs.constructor, ReadableStream,
19                  'rs should be a ReadableStream in this realm');
20    assert_true(rs instanceof ReadableStream,
21                'instanceof check should pass');
22
23    // Perform a brand-check on |rs| in the process of calling getReader().
24    const reader = ReadableStream.prototype.getReader.call(rs);
25
26    return reader.read().then(({value, done}) => {
27      assert_false(done, 'done should be false');
28      assert_equals(value, 'a', 'value should be "a"');
29      return reader.read();
30    }).then(({done}) => {
31      assert_true(done, 'done should be true');
32    });
33  }
34
35  function testMessage(msg) {
36    assert_array_equals(msg.ports, [], 'there should be no ports in the event');
37    return testTransferredReadableStream(msg.data);
38  }
39
40  function testMessageEvent(target) {
41    return new Promise((resolve, reject) => {
42      target.addEventListener('message', ev => {
43        try {
44          resolve(testMessage(ev));
45        } catch (e) {
46          reject(e);
47        }
48      }, {once: true});
49    });
50  }
51
52  function testMessageEventOrErrorMessage(target) {
53    return new Promise((resolve, reject) => {
54      target.addEventListener('message', ev => {
55        if (typeof ev.data === 'string') {
56          // Assume it's an error message and reject with it.
57          reject(ev.data);
58          return;
59        }
60
61        try {
62          resolve(testMessage(ev));
63        } catch (e) {
64          reject(e);
65        }
66      }, {once: true});
67    });
68  }
69
70  function checkTestResults(target) {
71    return new Promise((resolve, reject) => {
72      target.onmessage = msg => {
73        // testharness.js sends us objects which we need to ignore.
74        if (typeof msg.data !== 'string')
75        return;
76
77        if (msg.data === 'OK') {
78          resolve();
79        } else {
80          reject(msg.data);
81        }
82      };
83    });
84  }
85
86  // These tests assume that a transferred ReadableStream will behave the same
87  // regardless of how it was transferred. This enables us to simply transfer the
88  // stream to ourselves.
89  function createTransferredReadableStream(underlyingSource) {
90    const original = new ReadableStream(underlyingSource);
91    const promise = new Promise((resolve, reject) => {
92      addEventListener('message', msg => {
93        const rs = msg.data;
94        if (rs instanceof ReadableStream) {
95          resolve(rs);
96        } else {
97          reject(new Error(`what is this thing: "${rs}"?`));
98        }
99      }, {once: true});
100    });
101    postMessage(original, '*', [original]);
102    return promise;
103  }
104
105  function recordingTransferredReadableStream(underlyingSource, strategy) {
106    const original = recordingReadableStream(underlyingSource, strategy);
107    const promise = new Promise((resolve, reject) => {
108      addEventListener('message', msg => {
109        const rs = msg.data;
110        if (rs instanceof ReadableStream) {
111          rs.events = original.events;
112          rs.eventsWithoutPulls = original.eventsWithoutPulls;
113          rs.controller = original.controller;
114          resolve(rs);
115        } else {
116          reject(new Error(`what is this thing: "${rs}"?`));
117        }
118      }, {once: true});
119    });
120    postMessage(original, '*', [original]);
121    return promise;
122  }
123
124  self.createOriginalReadableStream = createOriginalReadableStream;
125  self.testMessage = testMessage;
126  self.testMessageEvent = testMessageEvent;
127  self.testMessageEventOrErrorMessage = testMessageEventOrErrorMessage;
128  self.checkTestResults = checkTestResults;
129  self.createTransferredReadableStream = createTransferredReadableStream;
130  self.recordingTransferredReadableStream = recordingTransferredReadableStream;
131
132})();
133