| Differences between
and this patch
- a/LayoutTests/imported/w3c/ChangeLog +58 lines
Lines 1-3 a/LayoutTests/imported/w3c/ChangeLog_sec1
1
2016-02-25  Youenn Fablet  <youenn.fablet@crf.canon.fr>
2
3
        Move streams tests from web-platform-tests/streams-api to web-platform-tests/streams
4
        https://bugs.webkit.org/show_bug.cgi?id=154671
5
6
        Reviewed by Xabier Rodriguez Calvar.
7
8
        This will allow preparing resyncing web-platform-tests.
9
10
        * web-platform-tests/streams/README.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/README.txt.
11
        * web-platform-tests/streams/byte-length-queuing-strategy-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/byte-length-queuing-strategy-expected.txt.
12
        * web-platform-tests/streams/byte-length-queuing-strategy.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/byte-length-queuing-strategy.html.
13
        * web-platform-tests/streams/byte-length-queuing-strategy.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/byte-length-queuing-strategy.js.
14
        * web-platform-tests/streams/count-queuing-strategy-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/count-queuing-strategy-expected.txt.
15
        * web-platform-tests/streams/count-queuing-strategy.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/count-queuing-strategy.html.
16
        * web-platform-tests/streams/count-queuing-strategy.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/count-queuing-strategy.js.
17
        * web-platform-tests/streams/readable-streams/bad-strategies-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-strategies-expected.txt.
18
        * web-platform-tests/streams/readable-streams/bad-strategies.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-strategies.html.
19
        * web-platform-tests/streams/readable-streams/bad-strategies.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-strategies.js.
20
        * web-platform-tests/streams/readable-streams/bad-underlying-sources-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-underlying-sources-expected.txt.
21
        * web-platform-tests/streams/readable-streams/bad-underlying-sources.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-underlying-sources.html.
22
        * web-platform-tests/streams/readable-streams/bad-underlying-sources.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-underlying-sources.js.
23
        * web-platform-tests/streams/readable-streams/brand-checks-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/brand-checks-expected.txt.
24
        * web-platform-tests/streams/readable-streams/brand-checks.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/brand-checks.html.
25
        * web-platform-tests/streams/readable-streams/brand-checks.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/brand-checks.js.
26
        * web-platform-tests/streams/readable-streams/cancel-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/cancel-expected.txt.
27
        * web-platform-tests/streams/readable-streams/cancel.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/cancel.html.
28
        * web-platform-tests/streams/readable-streams/cancel.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/cancel.js.
29
        * web-platform-tests/streams/readable-streams/count-queuing-strategy-integration-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/count-queuing-strategy-integration-expected.txt.
30
        * web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/count-queuing-strategy-integration.html.
31
        * web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/count-queuing-strategy-integration.js.
32
        * web-platform-tests/streams/readable-streams/garbage-collection-1-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-1-expected.txt.
33
        * web-platform-tests/streams/readable-streams/garbage-collection-1.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-1.html.
34
        * web-platform-tests/streams/readable-streams/garbage-collection-2-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-2-expected.txt.
35
        * web-platform-tests/streams/readable-streams/garbage-collection-2.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-2.html.
36
        * web-platform-tests/streams/readable-streams/garbage-collection-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-expected.txt.
37
        * web-platform-tests/streams/readable-streams/garbage-collection.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection.html.
38
        * web-platform-tests/streams/readable-streams/garbage-collection.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection.js.
39
        * web-platform-tests/streams/readable-streams/general-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/general-expected.txt.
40
        * web-platform-tests/streams/readable-streams/general.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/general.html.
41
        * web-platform-tests/streams/readable-streams/general.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/general.js.
42
        * web-platform-tests/streams/readable-streams/pipe-through-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/pipe-through-expected.txt.
43
        * web-platform-tests/streams/readable-streams/pipe-through.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/pipe-through.html.
44
        * web-platform-tests/streams/readable-streams/pipe-through.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/pipe-through.js.
45
        * web-platform-tests/streams/readable-streams/readable-stream-reader-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/readable-stream-reader-expected.txt.
46
        * web-platform-tests/streams/readable-streams/readable-stream-reader.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/readable-stream-reader.html.
47
        * web-platform-tests/streams/readable-streams/readable-stream-reader.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/readable-stream-reader.js.
48
        * web-platform-tests/streams/readable-streams/tee-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/tee-expected.txt.
49
        * web-platform-tests/streams/readable-streams/tee.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/tee.html.
50
        * web-platform-tests/streams/readable-streams/tee.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/tee.js.
51
        * web-platform-tests/streams/readable-streams/templated-expected.txt: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/templated-expected.txt.
52
        * web-platform-tests/streams/readable-streams/templated.html: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/templated.html.
53
        * web-platform-tests/streams/readable-streams/templated.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/templated.js.
54
        * web-platform-tests/streams/resources/rs-test-templates.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/rs-test-templates.js.
55
        * web-platform-tests/streams/resources/rs-utils.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/rs-utils.js.
56
        * web-platform-tests/streams/resources/test-initializer.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/test-initializer.js.
57
        * web-platform-tests/streams/resources/test-utils.js: Renamed from LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/test-utils.js.
58
1
2016-02-24  Youenn Fablet  <youenn.fablet@crf.canon.fr>
59
2016-02-24  Youenn Fablet  <youenn.fablet@crf.canon.fr>
2
60
3
        [Fetch API] Implement Fetch API Response
61
        [Fetch API] Implement Fetch API Response
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/README.txt -6 lines
Lines 1-6 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/README.txt_sec1
1
This directory is imported from the the Streams API repository.
2
3
There is a plan to move these tests to web-platform-tests repository so from that moment on this importation will be
4
automatic.
5
6
Current version: https://github.com/whatwg/streams/tree/7f19175415d9b57af04cb8c2cd355ca38101f0aa/reference-implementation/web-platform-tests.
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/byte-length-queuing-strategy-expected.txt -18 lines
Lines 1-18 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/byte-length-queuing-strategy-expected.txt_sec1
1
2
PASS Can construct a ByteLengthQueuingStrategy with a valid high water mark 
3
PASS Can construct a ByteLengthQueuingStrategy with any value as its high water mark 
4
PASS ByteLengthQueuingStrategy constructor behaves as expected with strange arguments 
5
PASS ByteLengthQueuingStrategy size behaves as expected with strange arguments 
6
PASS ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments 
7
PASS ByteLengthQueuingStrategy instances have the correct properties 
8
PASS ByteLengthQueuingStrategy's highWaterMark property can be set to anything 
9
FAIL Load byte-length-queuing-strategy.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
10
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
11
PASS Can construct a ByteLengthQueuingStrategy with a valid high water mark 
12
PASS Can construct a ByteLengthQueuingStrategy with any value as its high water mark 
13
PASS ByteLengthQueuingStrategy constructor behaves as expected with strange arguments 
14
PASS ByteLengthQueuingStrategy size behaves as expected with strange arguments 
15
PASS ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments 
16
PASS ByteLengthQueuingStrategy instances have the correct properties 
17
PASS ByteLengthQueuingStrategy's highWaterMark property can be set to anything 
18
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/byte-length-queuing-strategy.html -12 lines
Lines 1-12 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/byte-length-queuing-strategy.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="resources/test-initializer.js"></script>
7
8
<script src="byte-length-queuing-strategy.js"></script>
9
<script>
10
'use strict';
11
worker_test('byte-length-queuing-strategy.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/byte-length-queuing-strategy.js -107 lines
Lines 1-107 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/byte-length-queuing-strategy.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
test(() => {
8
9
  new ByteLengthQueuingStrategy({ highWaterMark: 4 });
10
11
}, 'Can construct a ByteLengthQueuingStrategy with a valid high water mark');
12
13
test(() => {
14
15
  for (const highWaterMark of [-Infinity, NaN, 'foo', {}, () => {}]) {
16
    const strategy = new ByteLengthQueuingStrategy({ highWaterMark });
17
    assert_equals(strategy.highWaterMark, highWaterMark, `${highWaterMark} gets set correctly`);
18
  }
19
20
}, 'Can construct a ByteLengthQueuingStrategy with any value as its high water mark');
21
22
test(() => {
23
24
  const highWaterMark = 1;
25
  const highWaterMarkObjectGetter = {
26
    get highWaterMark() { return highWaterMark; }
27
  };
28
  const error = new Error('wow!');
29
  const highWaterMarkObjectGetterThrowing = {
30
    get highWaterMark() { throw error; }
31
  };
32
33
  assert_throws({ name: 'TypeError' }, () => new ByteLengthQueuingStrategy(), 'construction fails with undefined');
34
  assert_throws({ name: 'TypeError' }, () => new ByteLengthQueuingStrategy(null), 'construction fails with null');
35
  assert_throws({ name: 'Error' }, () => new ByteLengthQueuingStrategy(highWaterMarkObjectGetterThrowing),
36
    'construction fails with an object with a throwing highWaterMark getter');
37
38
  // Should not fail:
39
  new ByteLengthQueuingStrategy('potato');
40
  new ByteLengthQueuingStrategy({});
41
  new ByteLengthQueuingStrategy(highWaterMarkObjectGetter);
42
43
}, 'ByteLengthQueuingStrategy constructor behaves as expected with strange arguments');
44
45
test(() => {
46
47
  const size = 1024;
48
  const chunk = { byteLength: size };
49
  const chunkGetter = {
50
    get byteLength() { return size; }
51
  };
52
  const error = new Error('wow!');
53
  const chunkGetterThrowing = {
54
    get byteLength() { throw error; }
55
  };
56
  assert_throws({ name: 'TypeError' }, () => ByteLengthQueuingStrategy.prototype.size(), 'size fails with undefined');
57
  assert_throws({ name: 'TypeError' }, () => ByteLengthQueuingStrategy.prototype.size(null), 'size fails with null');
58
  assert_equals(ByteLengthQueuingStrategy.prototype.size('potato'), undefined,
59
    'size succeeds with undefined with a random non-object type');
60
  assert_equals(ByteLengthQueuingStrategy.prototype.size({}), undefined,
61
    'size succeeds with undefined with an object without hwm property');
62
  assert_equals(ByteLengthQueuingStrategy.prototype.size(chunk), size,
63
    'size succeeds with the right amount with an object with a hwm');
64
  assert_equals(ByteLengthQueuingStrategy.prototype.size(chunkGetter), size,
65
    'size succeeds with the right amount with an object with a hwm getter');
66
  assert_throws({ name: 'Error' }, () => ByteLengthQueuingStrategy.prototype.size(chunkGetterThrowing),
67
    'size fails with the error thrown by the getter');
68
69
}, 'ByteLengthQueuingStrategy size behaves as expected with strange arguments');
70
71
test(() => {
72
73
  const thisValue = null;
74
  const returnValue = { 'returned from': 'byteLength getter' };
75
  const chunk = {
76
    get byteLength() { return returnValue; }
77
  };
78
79
  assert_equals(ByteLengthQueuingStrategy.prototype.size.call(thisValue, chunk), returnValue);
80
81
}, 'ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments');
82
83
test(() => {
84
85
  const strategy = new ByteLengthQueuingStrategy({ highWaterMark: 4 });
86
87
  assert_object_equals(Object.getOwnPropertyDescriptor(strategy, 'highWaterMark'),
88
    { value: 4, writable: true, enumerable: true, configurable: true },
89
    'highWaterMark property should be a data property with the value passed the constructor');
90
  assert_equals(typeof strategy.size, 'function');
91
92
}, 'ByteLengthQueuingStrategy instances have the correct properties');
93
94
test(() => {
95
96
  const strategy = new ByteLengthQueuingStrategy({ highWaterMark: 4 });
97
  assert_equals(strategy.highWaterMark, 4);
98
99
  strategy.highWaterMark = 10;
100
  assert_equals(strategy.highWaterMark, 10);
101
102
  strategy.highWaterMark = 'banana';
103
  assert_equals(strategy.highWaterMark, 'banana');
104
105
}, 'ByteLengthQueuingStrategy\'s highWaterMark property can be set to anything');
106
107
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/count-queuing-strategy-expected.txt -18 lines
Lines 1-18 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/count-queuing-strategy-expected.txt_sec1
1
2
PASS Can construct a CountQueuingStrategy with a valid high water mark 
3
PASS Can construct a CountQueuingStrategy with any value as its high water mark 
4
PASS CountQueuingStrategy constructor behaves as expected with strange arguments 
5
PASS CountQueuingStrategy.prototype.size should work generically on its this and its arguments 
6
PASS CountQueuingStrategy size behaves as expected with strange arguments 
7
PASS CountQueuingStrategy instances have the correct properties 
8
PASS CountQueuingStrategy's highWaterMark property can be set to anything 
9
FAIL Load count-queuing-strategy.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
10
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
11
PASS Can construct a CountQueuingStrategy with a valid high water mark 
12
PASS Can construct a CountQueuingStrategy with any value as its high water mark 
13
PASS CountQueuingStrategy constructor behaves as expected with strange arguments 
14
PASS CountQueuingStrategy.prototype.size should work generically on its this and its arguments 
15
PASS CountQueuingStrategy size behaves as expected with strange arguments 
16
PASS CountQueuingStrategy instances have the correct properties 
17
PASS CountQueuingStrategy's highWaterMark property can be set to anything 
18
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/count-queuing-strategy.html -12 lines
Lines 1-12 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/count-queuing-strategy.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="resources/test-initializer.js"></script>
7
8
<script src="count-queuing-strategy.js"></script>
9
<script>
10
'use strict';
11
worker_test('count-queuing-strategy.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/count-queuing-strategy.js -106 lines
Lines 1-106 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/count-queuing-strategy.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
test(() => {
8
9
  new CountQueuingStrategy({ highWaterMark: 4 });
10
11
}, 'Can construct a CountQueuingStrategy with a valid high water mark');
12
13
test(() => {
14
15
  for (const highWaterMark of [-Infinity, NaN, 'foo', {}, () => {}]) {
16
    const strategy = new CountQueuingStrategy({ highWaterMark });
17
    assert_equals(strategy.highWaterMark, highWaterMark, `${highWaterMark} gets set correctly`);
18
  }
19
20
}, 'Can construct a CountQueuingStrategy with any value as its high water mark');
21
22
test(() => {
23
24
  const highWaterMark = 1;
25
  const highWaterMarkObjectGetter = {
26
    get highWaterMark() { return highWaterMark; }
27
  };
28
  const error = new Error('wow!');
29
  const highWaterMarkObjectGetterThrowing = {
30
    get highWaterMark() { throw error; }
31
  };
32
33
  assert_throws({ name: 'TypeError' }, () => new CountQueuingStrategy(), 'construction fails with undefined');
34
  assert_throws({ name: 'TypeError' }, () => new CountQueuingStrategy(null), 'construction fails with null');
35
  assert_throws({ name: 'Error' }, () => new CountQueuingStrategy(highWaterMarkObjectGetterThrowing),
36
    'construction fails with an object with a throwing highWaterMark getter');
37
38
  // Should not fail:
39
  new CountQueuingStrategy('potato');
40
  new CountQueuingStrategy({});
41
  new CountQueuingStrategy(highWaterMarkObjectGetter);
42
43
}, 'CountQueuingStrategy constructor behaves as expected with strange arguments');
44
45
46
test(() => {
47
48
  const thisValue = null;
49
  const chunk = {
50
    get byteLength() {
51
      throw new TypeError('shouldn\'t be called');
52
    }
53
  };
54
55
  assert_equals(CountQueuingStrategy.prototype.size.call(thisValue, chunk), 1);
56
57
}, 'CountQueuingStrategy.prototype.size should work generically on its this and its arguments');
58
59
test(() => {
60
61
  const size = 1024;
62
  const chunk = { byteLength: size };
63
  const chunkGetter = {
64
    get byteLength() { return size; }
65
  };
66
  const error = new Error('wow!');
67
  const chunkGetterThrowing = {
68
    get byteLength() { throw error; }
69
  };
70
71
  assert_equals(CountQueuingStrategy.prototype.size(), 1, 'size returns 1 with undefined');
72
  assert_equals(CountQueuingStrategy.prototype.size(null), 1, 'size returns 1 with null');
73
  assert_equals(CountQueuingStrategy.prototype.size('potato'), 1, 'size returns 1 with non-object type');
74
  assert_equals(CountQueuingStrategy.prototype.size({}), 1, 'size returns 1 with empty object');
75
  assert_equals(CountQueuingStrategy.prototype.size(chunk), 1, 'size returns 1 with a chunk');
76
  assert_equals(CountQueuingStrategy.prototype.size(chunkGetter), 1, 'size returns 1 with chunk getter');
77
  assert_equals(CountQueuingStrategy.prototype.size(chunkGetterThrowing), 1,
78
    'size returns 1 with chunk getter that throws');
79
80
}, 'CountQueuingStrategy size behaves as expected with strange arguments');
81
82
test(() => {
83
84
  const strategy = new CountQueuingStrategy({ highWaterMark: 4 });
85
86
  assert_object_equals(Object.getOwnPropertyDescriptor(strategy, 'highWaterMark'),
87
    { value: 4, writable: true, enumerable: true, configurable: true },
88
    'highWaterMark property should be a data property with the value passed the constructor');
89
  assert_equals(typeof strategy.size, 'function');
90
91
}, 'CountQueuingStrategy instances have the correct properties');
92
93
test(() => {
94
95
  const strategy = new CountQueuingStrategy({ highWaterMark: 4 });
96
  assert_equals(strategy.highWaterMark, 4);
97
98
  strategy.highWaterMark = 10;
99
  assert_equals(strategy.highWaterMark, 10);
100
101
  strategy.highWaterMark = 'banana';
102
  assert_equals(strategy.highWaterMark, 'banana');
103
104
}, 'CountQueuingStrategy\'s highWaterMark property can be set to anything');
105
106
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-strategies-expected.txt -18 lines
Lines 1-18 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-strategies-expected.txt_sec1
1
2
PASS Readable stream: throwing strategy.size getter 
3
PASS Readable stream: strategy.size errors the stream and then throws 
4
PASS Readable stream: strategy.size errors the stream and then returns Infinity 
5
PASS Readable stream: throwing strategy.size method 
6
PASS Readable stream: throwing strategy.highWaterMark getter 
7
PASS Readable stream: invalid strategy.highWaterMark 
8
PASS Readable stream: invalid strategy.size return value 
9
FAIL Load bad-strategies.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
10
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
11
PASS Readable stream: throwing strategy.size getter 
12
PASS Readable stream: strategy.size errors the stream and then throws 
13
PASS Readable stream: strategy.size errors the stream and then returns Infinity 
14
PASS Readable stream: throwing strategy.size method 
15
PASS Readable stream: throwing strategy.highWaterMark getter 
16
PASS Readable stream: invalid strategy.highWaterMark 
17
PASS Readable stream: invalid strategy.size return value 
18
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-strategies.html -12 lines
Lines 1-12 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-strategies.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="bad-strategies.js"></script>
9
<script>
10
'use strict';
11
worker_test('bad-strategies.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-strategies.js -175 lines
Lines 1-175 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-strategies.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
test(() => {
8
9
  const theError = new Error('a unique string');
10
11
  assert_throws(theError, () => {
12
    new ReadableStream({}, {
13
      get size() {
14
        throw theError;
15
      },
16
      highWaterMark: 5
17
    });
18
  }, 'construction should re-throw the error');
19
20
}, 'Readable stream: throwing strategy.size getter');
21
22
promise_test(t => {
23
24
  const controllerError = { name: 'controller error' };
25
  const thrownError = { name: 'thrown error' };
26
27
  let controller;
28
  const rs = new ReadableStream(
29
    {
30
      start(c) {
31
        controller = c;
32
      }
33
    },
34
    {
35
      size() {
36
        controller.error(controllerError);
37
        throw thrownError;
38
      },
39
      highWaterMark: 5
40
    }
41
  );
42
43
  assert_throws(thrownError, () => controller.enqueue('a'), 'enqueue should re-throw the error');
44
45
  return promise_rejects(t, controllerError, rs.getReader().closed);
46
47
}, 'Readable stream: strategy.size errors the stream and then throws');
48
49
promise_test(t => {
50
51
  const theError = { name: 'my error' };
52
53
  let controller;
54
  const rs = new ReadableStream(
55
    {
56
      start(c) {
57
        controller = c;
58
      }
59
    },
60
    {
61
      size() {
62
        controller.error(theError);
63
        return Infinity;
64
      },
65
      highWaterMark: 5
66
    }
67
  );
68
69
  assert_throws(new RangeError(), () => controller.enqueue('a'), 'enqueue should throw a RangeError');
70
71
  return promise_rejects(t, theError, rs.getReader().closed, 'closed should reject with the error');
72
73
}, 'Readable stream: strategy.size errors the stream and then returns Infinity');
74
75
promise_test(() => {
76
77
  const theError = new Error('a unique string');
78
  const rs = new ReadableStream(
79
    {
80
      start(c) {
81
        assert_throws(theError, () => c.enqueue('a'), 'enqueue should throw the error');
82
      }
83
    },
84
    {
85
      size() {
86
        throw theError;
87
      },
88
      highWaterMark: 5
89
    }
90
  );
91
92
  return rs.getReader().closed.catch(e => {
93
    assert_equals(e, theError, 'closed should reject with the error');
94
  });
95
96
}, 'Readable stream: throwing strategy.size method');
97
98
test(() => {
99
100
  const theError = new Error('a unique string');
101
102
  assert_throws(theError, () => {
103
    new ReadableStream({}, {
104
      size() {
105
        return 1;
106
      },
107
      get highWaterMark() {
108
        throw theError;
109
      }
110
    });
111
  }, 'construction should re-throw the error');
112
113
}, 'Readable stream: throwing strategy.highWaterMark getter');
114
115
test(() => {
116
117
  for (const highWaterMark of [-1, -Infinity]) {
118
    assert_throws(new RangeError(), () => {
119
      new ReadableStream({}, {
120
        size() {
121
          return 1;
122
        },
123
        highWaterMark
124
      });
125
    }, 'construction should throw a RangeError for ' + highWaterMark);
126
  }
127
128
  for (const highWaterMark of [NaN, 'foo', {}]) {
129
    assert_throws(new TypeError(), () => {
130
      new ReadableStream({}, {
131
        size() {
132
          return 1;
133
        },
134
        highWaterMark
135
      });
136
    }, 'construction should throw a TypeError for ' + highWaterMark);
137
  }
138
139
}, 'Readable stream: invalid strategy.highWaterMark');
140
141
promise_test(() => {
142
143
  const promises = [];
144
  for (const size of [NaN, -Infinity, Infinity, -1]) {
145
    let theError;
146
    const rs = new ReadableStream(
147
      {
148
        start(c) {
149
          try {
150
            c.enqueue('hi');
151
            assert_unreached('enqueue didn\'t throw');
152
          } catch (error) {
153
            assert_equals(error.name, 'RangeError', 'enqueue should throw a RangeError for ' + size);
154
            theError = error;
155
          }
156
        }
157
      },
158
      {
159
        size() {
160
          return size;
161
        },
162
        highWaterMark: 5
163
      }
164
    );
165
166
    promises.push(rs.getReader().closed.catch(e => {
167
      assert_equals(e, theError, 'closed should reject with the error for ' + size);
168
    }));
169
  }
170
171
  return Promise.all(promises);
172
173
}, 'Readable stream: invalid strategy.size return value');
174
175
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-underlying-sources-expected.txt -46 lines
Lines 1-46 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-underlying-sources-expected.txt_sec1
1
2
PASS Underlying source start: throwing getter 
3
PASS Underlying source start: throwing method 
4
PASS Underlying source: throwing pull getter (initial pull) 
5
PASS Underlying source: throwing pull method (initial pull) 
6
PASS Underlying source pull: throwing getter (second pull) 
7
PASS Underlying source pull: throwing method (second pull) 
8
PASS Underlying source cancel: throwing getter 
9
PASS Underlying source cancel: throwing method 
10
PASS Underlying source: calling enqueue on an empty canceled stream should not throw 
11
PASS Underlying source: calling enqueue on a non-empty canceled stream should not throw 
12
PASS Underlying source: calling enqueue on a closed stream should throw 
13
PASS Underlying source: calling enqueue on an errored stream should throw 
14
PASS Underlying source: calling close twice on an empty stream should throw the second time 
15
PASS Underlying source: calling close twice on a non-empty stream should throw the second time 
16
PASS Underlying source: calling close on an empty canceled stream should not throw 
17
PASS Underlying source: calling close on a non-empty canceled stream should not throw 
18
PASS Underlying source: calling close after error should throw 
19
PASS Underlying source: calling error twice should throw the second time 
20
PASS Underlying source: calling error after close should throw 
21
PASS Underlying source: calling error and returning a rejected promise from start should cause the stream to error with the first error 
22
PASS Underlying source: calling error and returning a rejected promise from pull should cause the stream to error with the first error 
23
FAIL Load bad-underlying-sources.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
24
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
25
PASS Underlying source start: throwing getter 
26
PASS Underlying source start: throwing method 
27
PASS Underlying source: throwing pull getter (initial pull) 
28
PASS Underlying source: throwing pull method (initial pull) 
29
PASS Underlying source pull: throwing getter (second pull) 
30
PASS Underlying source pull: throwing method (second pull) 
31
PASS Underlying source cancel: throwing getter 
32
PASS Underlying source cancel: throwing method 
33
PASS Underlying source: calling enqueue on an empty canceled stream should not throw 
34
PASS Underlying source: calling enqueue on a non-empty canceled stream should not throw 
35
PASS Underlying source: calling enqueue on a closed stream should throw 
36
PASS Underlying source: calling enqueue on an errored stream should throw 
37
PASS Underlying source: calling close twice on an empty stream should throw the second time 
38
PASS Underlying source: calling close twice on a non-empty stream should throw the second time 
39
PASS Underlying source: calling close on an empty canceled stream should not throw 
40
PASS Underlying source: calling close on a non-empty canceled stream should not throw 
41
PASS Underlying source: calling close after error should throw 
42
PASS Underlying source: calling error twice should throw the second time 
43
PASS Underlying source: calling error after close should throw 
44
PASS Underlying source: calling error and returning a rejected promise from start should cause the stream to error with the first error 
45
PASS Underlying source: calling error and returning a rejected promise from pull should cause the stream to error with the first error 
46
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-underlying-sources.html -12 lines
Lines 1-12 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-underlying-sources.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="bad-underlying-sources.js"></script>
9
<script>
10
'use strict';
11
worker_test('bad-underlying-sources.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-underlying-sources.js -383 lines
Lines 1-383 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/bad-underlying-sources.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
8
test(() => {
9
10
  const theError = new Error('a unique string');
11
12
  assert_throws(theError, () => {
13
    new ReadableStream({
14
      get start() {
15
        throw theError;
16
      }
17
    });
18
  }, 'constructing the stream should re-throw the error');
19
20
}, 'Underlying source start: throwing getter');
21
22
23
test(() => {
24
25
  const theError = new Error('a unique string');
26
27
  assert_throws(theError, () => {
28
    new ReadableStream({
29
      start() {
30
        throw theError;
31
      }
32
    });
33
  }, 'constructing the stream should re-throw the error');
34
35
}, 'Underlying source start: throwing method');
36
37
38
promise_test(t => {
39
40
  const theError = new Error('a unique string');
41
  const rs = new ReadableStream({
42
    get pull() {
43
      throw theError;
44
    }
45
  });
46
47
  return promise_rejects(t, theError, rs.getReader().closed);
48
49
}, 'Underlying source: throwing pull getter (initial pull)');
50
51
52
promise_test(t => {
53
54
  const theError = new Error('a unique string');
55
  const rs = new ReadableStream({
56
    pull() {
57
      throw theError;
58
    }
59
  });
60
61
  return promise_rejects(t, theError, rs.getReader().closed);
62
63
}, 'Underlying source: throwing pull method (initial pull)');
64
65
66
promise_test(t => {
67
68
  const theError = new Error('a unique string');
69
70
  let counter = 0;
71
  const rs = new ReadableStream({
72
    get pull() {
73
      ++counter;
74
      if (counter === 1) {
75
        return c => c.enqueue('a');
76
      }
77
78
      throw theError;
79
    }
80
  });
81
  const reader = rs.getReader();
82
83
  return Promise.all([
84
    reader.read().then(r => {
85
      assert_object_equals(r, { value: 'a', done: false }, 'the chunk read should be correct');
86
    }),
87
    promise_rejects(t, theError, reader.closed)
88
  ]);
89
90
}, 'Underlying source pull: throwing getter (second pull)');
91
92
93
promise_test(t => {
94
95
  const theError = new Error('a unique string');
96
97
  let counter = 0;
98
  const rs = new ReadableStream({
99
    pull(c) {
100
      ++counter;
101
      if (counter === 1) {
102
        c.enqueue('a');
103
        return;
104
      }
105
106
      throw theError;
107
    }
108
  });
109
  const reader = rs.getReader();
110
111
  return Promise.all([
112
    reader.read().then(r => {
113
      assert_object_equals(r, { value: 'a', done: false }, 'the chunk read should be correct');
114
    }),
115
    promise_rejects(t, theError, reader.closed)
116
  ]);
117
118
}, 'Underlying source pull: throwing method (second pull)');
119
120
promise_test(t => {
121
122
  const theError = new Error('a unique string');
123
  const rs = new ReadableStream({
124
    get cancel() {
125
      throw theError;
126
    }
127
  });
128
129
  return promise_rejects(t, theError, rs.cancel());
130
131
}, 'Underlying source cancel: throwing getter');
132
133
promise_test(t => {
134
135
  const theError = new Error('a unique string');
136
  const rs = new ReadableStream({
137
    cancel() {
138
      throw theError;
139
    }
140
  });
141
142
  return promise_rejects(t, theError, rs.cancel());
143
144
}, 'Underlying source cancel: throwing method');
145
146
promise_test(() => {
147
148
  let controller;
149
  const rs = new ReadableStream({
150
    start(c) {
151
      controller = c;
152
    }
153
  });
154
155
  rs.cancel();
156
  controller.enqueue('a'); // Calling enqueue after canceling should not throw anything.
157
158
  return rs.getReader().closed;
159
160
}, 'Underlying source: calling enqueue on an empty canceled stream should not throw');
161
162
promise_test(() => {
163
164
  let controller;
165
  const rs = new ReadableStream({
166
    start(c) {
167
      c.enqueue('a');
168
      c.enqueue('b');
169
      controller = c;
170
    }
171
  });
172
173
  rs.cancel();
174
  controller.enqueue('c'); // Calling enqueue after canceling should not throw anything.
175
176
  return rs.getReader().closed;
177
178
}, 'Underlying source: calling enqueue on a non-empty canceled stream should not throw');
179
180
promise_test(() => {
181
182
  return new ReadableStream({
183
    start(c) {
184
      c.close();
185
      assert_throws(new TypeError(), () => c.enqueue('a'), 'call to enqueue should throw a TypeError');
186
    }
187
  }).getReader().closed;
188
189
}, 'Underlying source: calling enqueue on a closed stream should throw');
190
191
promise_test(t => {
192
193
  const theError = new Error('boo');
194
  const closed = new ReadableStream({
195
    start(c) {
196
      c.error(theError);
197
      assert_throws(theError, () => c.enqueue('a'), 'call to enqueue should throw the error');
198
    }
199
  }).getReader().closed;
200
201
  return promise_rejects(t, theError, closed);
202
203
}, 'Underlying source: calling enqueue on an errored stream should throw');
204
205
promise_test(() => {
206
207
  return new ReadableStream({
208
    start(c) {
209
      c.close();
210
      assert_throws(new TypeError(), () => c.close(), 'second call to close should throw a TypeError');
211
    }
212
  }).getReader().closed;
213
214
}, 'Underlying source: calling close twice on an empty stream should throw the second time');
215
216
promise_test(() => {
217
218
  let startCalled = false;
219
  let readCalled = false;
220
  const reader = new ReadableStream({
221
    start(c) {
222
      c.enqueue('a');
223
      c.close();
224
      assert_throws(new TypeError(), () => c.close(), 'second call to close should throw a TypeError');
225
      startCalled = true;
226
    }
227
  }).getReader();
228
229
  return Promise.all([
230
    reader.read().then(r => {
231
      assert_object_equals(r, { value: 'a', done: false }, 'read() should read the enqueued chunk');
232
      readCalled = true;
233
    }),
234
    reader.closed.then(() => {
235
      assert_true(startCalled);
236
      assert_true(readCalled);
237
    })
238
  ]);
239
240
}, 'Underlying source: calling close twice on a non-empty stream should throw the second time');
241
242
promise_test(() => {
243
244
  let controller;
245
  let startCalled = false;
246
  const rs = new ReadableStream({
247
    start(c) {
248
      controller = c;
249
      startCalled = true;
250
    }
251
  });
252
253
  rs.cancel();
254
  controller.close(); // Calling close after canceling should not throw anything.
255
256
  return rs.getReader().closed.then(() => {
257
    assert_true(startCalled);
258
  });
259
260
}, 'Underlying source: calling close on an empty canceled stream should not throw');
261
262
promise_test(() => {
263
264
  let controller;
265
  let startCalled = false;
266
  const rs = new ReadableStream({
267
    start(c) {
268
      controller = c;
269
      c.enqueue('a');
270
      startCalled = true;
271
    }
272
  });
273
274
  rs.cancel();
275
  controller.close(); // Calling close after canceling should not throw anything.
276
277
  return rs.getReader().closed.then(() => {
278
    assert_true(startCalled);
279
  });
280
281
}, 'Underlying source: calling close on a non-empty canceled stream should not throw');
282
283
promise_test(() => {
284
285
  const theError = new Error('boo');
286
  let startCalled = false;
287
288
  const closed = new ReadableStream({
289
    start(c) {
290
      c.error(theError);
291
      assert_throws(new TypeError(), () => c.close(), 'call to close should throw a TypeError');
292
      startCalled = true;
293
    }
294
  }).getReader().closed;
295
296
  return closed.catch(e => {
297
    assert_true(startCalled);
298
    assert_equals(e, theError, 'closed should reject with the error');
299
  });
300
301
}, 'Underlying source: calling close after error should throw');
302
303
promise_test(() => {
304
305
  const theError = new Error('boo');
306
  let startCalled = false;
307
308
  const closed = new ReadableStream({
309
    start(c) {
310
      c.error(theError);
311
      assert_throws(new TypeError(), () => c.error(), 'second call to error should throw a TypeError');
312
      startCalled = true;
313
    }
314
  }).getReader().closed;
315
316
  return closed.catch(e => {
317
    assert_true(startCalled);
318
    assert_equals(e, theError, 'closed should reject with the error');
319
  });
320
321
}, 'Underlying source: calling error twice should throw the second time');
322
323
promise_test(() => {
324
325
  let startCalled = false;
326
327
  const closed = new ReadableStream({
328
    start(c) {
329
      c.close();
330
      assert_throws(new TypeError(), () => c.error(), 'second call to error should throw a TypeError');
331
      startCalled = true;
332
    }
333
  }).getReader().closed;
334
335
  return closed.then(() => assert_true(startCalled));
336
337
}, 'Underlying source: calling error after close should throw');
338
339
promise_test(() => {
340
341
  let startCalled = false;
342
  const firstError = new Error('1');
343
  const secondError = new Error('2');
344
345
  const closed = new ReadableStream({
346
    start(c) {
347
      c.error(firstError);
348
      startCalled = true;
349
      return Promise.reject(secondError);
350
    }
351
  }).getReader().closed;
352
353
  return closed.catch(e => {
354
    assert_true(startCalled);
355
    assert_equals(e, firstError, 'closed should reject with the first error');
356
  });
357
358
}, 'Underlying source: calling error and returning a rejected promise from start should cause the stream to error ' +
359
   'with the first error');
360
361
promise_test(() => {
362
363
  let startCalled = false;
364
  const firstError = new Error('1');
365
  const secondError = new Error('2');
366
367
  const closed = new ReadableStream({
368
    pull(c) {
369
      c.error(firstError);
370
      startCalled = true;
371
      return Promise.reject(secondError);
372
    }
373
  }).getReader().closed;
374
375
  return closed.catch(e => {
376
    assert_true(startCalled);
377
    assert_equals(e, firstError, 'closed should reject with the first error');
378
  });
379
380
}, 'Underlying source: calling error and returning a rejected promise from pull should cause the stream to error ' +
381
   'with the first error');
382
383
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/brand-checks-expected.txt -34 lines
Lines 1-34 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/brand-checks-expected.txt_sec1
1
2
PASS Can get the ReadableStreamReader constructor indirectly 
3
PASS Can get the ReadableStreamController constructor indirectly 
4
PASS ReadableStream.prototype.cancel enforces a brand check 
5
PASS ReadableStream.prototype.getReader enforces a brand check 
6
PASS ReadableStream.prototype.tee enforces a brand check 
7
PASS ReadableStreamReader enforces a brand check on its argument 
8
PASS ReadableStreamReader.prototype.closed enforces a brand check 
9
PASS ReadableStreamReader.prototype.cancel enforces a brand check 
10
PASS ReadableStreamReader.prototype.read enforces a brand check 
11
PASS ReadableStreamReader.prototype.releaseLock enforces a brand check 
12
PASS ReadableStreamController enforces a brand check on its argument 
13
PASS ReadableStreamController can't be given a fully-constructed ReadableStream 
14
PASS ReadableStreamController.prototype.close enforces a brand check 
15
PASS ReadableStreamController.prototype.enqueue enforces a brand check 
16
PASS ReadableStreamController.prototype.error enforces a brand check 
17
FAIL Load brand-checks.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
18
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
19
PASS Can get the ReadableStreamReader constructor indirectly 
20
PASS Can get the ReadableStreamController constructor indirectly 
21
PASS ReadableStream.prototype.cancel enforces a brand check 
22
PASS ReadableStream.prototype.getReader enforces a brand check 
23
PASS ReadableStream.prototype.tee enforces a brand check 
24
PASS ReadableStreamReader enforces a brand check on its argument 
25
PASS ReadableStreamReader.prototype.closed enforces a brand check 
26
PASS ReadableStreamReader.prototype.cancel enforces a brand check 
27
PASS ReadableStreamReader.prototype.read enforces a brand check 
28
PASS ReadableStreamReader.prototype.releaseLock enforces a brand check 
29
PASS ReadableStreamController enforces a brand check on its argument 
30
PASS ReadableStreamController can't be given a fully-constructed ReadableStream 
31
PASS ReadableStreamController.prototype.close enforces a brand check 
32
PASS ReadableStreamController.prototype.enqueue enforces a brand check 
33
PASS ReadableStreamController.prototype.error enforces a brand check 
34
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/brand-checks.html -13 lines
Lines 1-13 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/brand-checks.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="brand-checks.js"></script>
10
<script>
11
'use strict';
12
worker_test('brand-checks.js');
13
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/brand-checks.js -151 lines
Lines 1-151 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/brand-checks.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
let ReadableStreamReader;
9
let ReadableStreamController;
10
11
test(() => {
12
13
  // It's not exposed globally, but we test a few of its properties here.
14
  ReadableStreamReader = (new ReadableStream()).getReader().constructor;
15
16
}, 'Can get the ReadableStreamReader constructor indirectly');
17
18
test(() => {
19
20
  // It's not exposed globally, but we test a few of its properties here.
21
  new ReadableStream({
22
    start(c) {
23
      ReadableStreamController = c.constructor;
24
    }
25
  });
26
27
}, 'Can get the ReadableStreamController constructor indirectly');
28
29
function fakeReadableStream() {
30
  return {
31
    cancel() { return Promise.resolve(); },
32
    getReader() { return new ReadableStreamReader(new ReadableStream()); },
33
    pipeThrough(obj) { return obj.readable; },
34
    pipeTo() { return Promise.resolve(); },
35
    tee() { return [realReadableStream(), realReadableStream()]; }
36
  };
37
}
38
39
function realReadableStream() {
40
  return new ReadableStream();
41
}
42
43
function fakeReadableStreamReader() {
44
  return {
45
    get closed() { return Promise.resolve(); },
46
    cancel() { return Promise.resolve(); },
47
    read() { return Promise.resolve({ value: undefined, done: true }); },
48
    releaseLock() { return; }
49
  };
50
}
51
52
function fakeReadableStreamController() {
53
  return {
54
    close() { },
55
    enqueue() { },
56
    error() { }
57
  };
58
}
59
60
promise_test(t => {
61
62
  return methodRejects(t, ReadableStream.prototype, 'cancel', fakeReadableStream());
63
64
}, 'ReadableStream.prototype.cancel enforces a brand check');
65
66
test(() => {
67
68
  methodThrows(ReadableStream.prototype, 'getReader', fakeReadableStream());
69
70
}, 'ReadableStream.prototype.getReader enforces a brand check');
71
72
test(() => {
73
74
  methodThrows(ReadableStream.prototype, 'tee', fakeReadableStream());
75
76
}, 'ReadableStream.prototype.tee enforces a brand check');
77
78
test(() => {
79
80
  assert_throws(new TypeError(), () => new ReadableStreamReader(fakeReadableStream()),
81
                'Constructing a ReadableStreamReader should throw');
82
83
}, 'ReadableStreamReader enforces a brand check on its argument');
84
85
promise_test(t => {
86
87
  return Promise.all([
88
    getterRejects(t, ReadableStreamReader.prototype, 'closed', fakeReadableStreamReader()),
89
    getterRejects(t, ReadableStreamReader.prototype, 'closed', realReadableStream())
90
  ]);
91
92
}, 'ReadableStreamReader.prototype.closed enforces a brand check');
93
94
promise_test(t => {
95
96
  return Promise.all([
97
    methodRejects(t, ReadableStreamReader.prototype, 'cancel', fakeReadableStreamReader()),
98
    methodRejects(t, ReadableStreamReader.prototype, 'cancel', realReadableStream())
99
  ]);
100
101
}, 'ReadableStreamReader.prototype.cancel enforces a brand check');
102
103
promise_test(t => {
104
105
  return Promise.all([
106
    methodRejects(t, ReadableStreamReader.prototype, 'read', fakeReadableStreamReader()),
107
    methodRejects(t, ReadableStreamReader.prototype, 'read', realReadableStream())
108
  ]);
109
110
}, 'ReadableStreamReader.prototype.read enforces a brand check');
111
112
test(() => {
113
114
  methodThrows(ReadableStreamReader.prototype, 'releaseLock', fakeReadableStreamReader());
115
  methodThrows(ReadableStreamReader.prototype, 'releaseLock', realReadableStream());
116
117
}, 'ReadableStreamReader.prototype.releaseLock enforces a brand check');
118
119
test(() => {
120
121
  assert_throws(new TypeError(), () => new ReadableStreamController(fakeReadableStream()),
122
                'Constructing a ReadableStreamController should throw');
123
124
}, 'ReadableStreamController enforces a brand check on its argument');
125
126
test(() => {
127
128
  assert_throws(new TypeError(), () => new ReadableStreamController(realReadableStream()),
129
                'Constructing a ReadableStreamController should throw');
130
131
}, 'ReadableStreamController can\'t be given a fully-constructed ReadableStream');
132
133
test(() => {
134
135
  methodThrows(ReadableStreamController.prototype, 'close', fakeReadableStreamController());
136
137
}, 'ReadableStreamController.prototype.close enforces a brand check');
138
139
test(() => {
140
141
  methodThrows(ReadableStreamController.prototype, 'enqueue', fakeReadableStreamController());
142
143
}, 'ReadableStreamController.prototype.enqueue enforces a brand check');
144
145
test(() => {
146
147
  methodThrows(ReadableStreamController.prototype, 'error', fakeReadableStreamController());
148
149
}, 'ReadableStreamController.prototype.error enforces a brand check');
150
151
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/cancel-expected.txt -24 lines
Lines 1-24 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/cancel-expected.txt_sec1
1
2
PASS ReadableStream cancellation: integration test on an infinite stream derived from a random push source 
3
PASS ReadableStream cancellation: cancel(reason) should pass through the given reason to the underlying source 
4
PASS ReadableStream cancellation: cancel() on a locked stream should fail and not call the underlying source cancel 
5
PASS ReadableStream cancellation: should fulfill promise when cancel callback went fine 
6
PASS ReadableStream cancellation: returning a value from the underlying source's cancel should not affect the fulfillment value of the promise returned by the stream's cancel 
7
PASS ReadableStream cancellation: should reject promise when cancel callback raises an exception 
8
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (1) 
9
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (2) 
10
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should reject when that one does 
11
PASS ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called 
12
FAIL Load cancel.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
13
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
14
PASS ReadableStream cancellation: integration test on an infinite stream derived from a random push source 
15
PASS ReadableStream cancellation: cancel(reason) should pass through the given reason to the underlying source 
16
PASS ReadableStream cancellation: cancel() on a locked stream should fail and not call the underlying source cancel 
17
PASS ReadableStream cancellation: should fulfill promise when cancel callback went fine 
18
PASS ReadableStream cancellation: returning a value from the underlying source's cancel should not affect the fulfillment value of the promise returned by the stream's cancel 
19
PASS ReadableStream cancellation: should reject promise when cancel callback raises an exception 
20
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (1) 
21
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (2) 
22
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should reject when that one does 
23
PASS ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called 
24
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/cancel.html -14 lines
Lines 1-14 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/cancel.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="../resources/rs-utils.js"></script>
10
<script src="cancel.js"></script>
11
<script>
12
'use strict';
13
worker_test('cancel.js');
14
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/cancel.js -242 lines
Lines 1-242 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/cancel.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('../resources/rs-utils.js');
6
  self.importScripts('/resources/testharness.js');
7
}
8
9
promise_test(() => {
10
11
  const randomSource = new RandomPushSource();
12
13
  let cancellationFinished = false;
14
  const rs = new ReadableStream({
15
    start(c) {
16
      randomSource.ondata = c.enqueue.bind(c);
17
      randomSource.onend = c.close.bind(c);
18
      randomSource.onerror = c.error.bind(c);
19
    },
20
21
    pull() {
22
      randomSource.readStart();
23
    },
24
25
    cancel() {
26
      randomSource.readStop();
27
      randomSource.onend();
28
29
      return new Promise(resolve => {
30
        setTimeout(() => {
31
          cancellationFinished = true;
32
          resolve();
33
        }, 1);
34
      });
35
    }
36
  });
37
38
  const reader = rs.getReader();
39
40
  // We call delay multiple times to avoid cancelling too early for the
41
  // source to enqueue at least one chunk.
42
  const cancel = delay(5).then(() => delay(5)).then(() => delay(5)).then(() => {
43
    let cancelPromise = reader.cancel();
44
    assert_false(cancellationFinished, 'cancellation in source should happen later');
45
    return cancelPromise;
46
  })
47
48
  return readableStreamToArray(rs, reader).then(chunks => {
49
    assert_greater_than(chunks.length, 0, 'at least one chunk should be read');
50
    for (let i = 0; i < chunks.length; i++) {
51
      assert_equals(chunks[i].length, 128, 'chunk ' + i + ' should have 128 bytes');
52
    }
53
    return cancel;
54
  }).then(() => {
55
    assert_true(cancellationFinished, 'it returns a promise that is fulfilled when the cancellation finishes');
56
  });
57
58
}, 'ReadableStream cancellation: integration test on an infinite stream derived from a random push source');
59
60
test(() => {
61
62
  let recordedReason;
63
  const rs = new ReadableStream({
64
    cancel(reason) {
65
      recordedReason = reason;
66
    }
67
  });
68
69
  const passedReason = new Error('Sorry, it just wasn\'t meant to be.');
70
  rs.cancel(passedReason);
71
72
  assert_equals(recordedReason, passedReason,
73
    'the error passed to the underlying source\'s cancel method should equal the one passed to the stream\'s cancel');
74
75
}, 'ReadableStream cancellation: cancel(reason) should pass through the given reason to the underlying source');
76
77
promise_test(() => {
78
79
  const rs = new ReadableStream({
80
    start(c) {
81
      c.enqueue('a');
82
      c.close();
83
    },
84
    cancel() {
85
      assert_unreached('underlying source cancel() should not have been called');
86
    }
87
  });
88
89
  const reader = rs.getReader();
90
91
  return rs.cancel().then(() => {
92
    assert_unreached('cancel() should be rejected');
93
  }, e => {
94
    assert_equals(e.name, 'TypeError', 'cancel() should be rejected with a TypeError');
95
  }).then(() => {
96
    return reader.read();
97
  }).then(result => {
98
    assert_object_equals(result, { value: 'a', done: false }, 'read() should still work after the attempted cancel');
99
    return reader.closed;
100
  });
101
102
}, 'ReadableStream cancellation: cancel() on a locked stream should fail and not call the underlying source cancel');
103
104
promise_test(() => {
105
106
  let cancelReceived = false;
107
  const cancelReason = new Error('I am tired of this stream, I prefer to cancel it');
108
  const rs = new ReadableStream({
109
    cancel(reason) {
110
      cancelReceived = true;
111
      assert_equals(reason, cancelReason, 'cancellation reason given to the underlying source should be equal to the one passed');
112
    }
113
  });
114
115
  return rs.cancel(cancelReason).then(() => {
116
    assert_true(cancelReceived);
117
  });
118
119
}, 'ReadableStream cancellation: should fulfill promise when cancel callback went fine');
120
121
promise_test(() => {
122
123
  const rs = new ReadableStream({
124
    cancel() {
125
      return 'Hello';
126
    }
127
  });
128
129
  return rs.cancel().then(v => {
130
    assert_equals(v, undefined, 'cancel() return value should be fulfilled with undefined');
131
  });
132
133
}, 'ReadableStream cancellation: returning a value from the underlying source\'s cancel should not affect the fulfillment value of the promise returned by the stream\'s cancel');
134
135
promise_test(() => {
136
137
  const thrownError = new Error('test');
138
  let cancelCalled = false;
139
140
  const rs = new ReadableStream({
141
    cancel() {
142
      cancelCalled = true;
143
      throw thrownError;
144
    }
145
  });
146
147
  return rs.cancel('test').then(() => {
148
    assert_unreached('cancel should reject');
149
  }, e => {
150
    assert_true(cancelCalled);
151
    assert_equals(e, thrownError);
152
  });
153
154
}, 'ReadableStream cancellation: should reject promise when cancel callback raises an exception');
155
156
promise_test(() => {
157
158
  const cancelReason = new Error('test');
159
160
  const rs = new ReadableStream({
161
    cancel(error) {
162
      assert_equals(error, cancelReason);
163
      return delay(1);
164
    }
165
  });
166
167
  return rs.cancel(cancelReason);
168
169
}, 'ReadableStream cancellation: if the underlying source\'s cancel method returns a promise, the promise returned by the stream\'s cancel should fulfill when that one does (1)');
170
171
promise_test(() => {
172
173
  let resolveSourceCancelPromise;
174
  let sourceCancelPromiseHasFulfilled = false;
175
176
  const rs = new ReadableStream({
177
    cancel() {
178
      const sourceCancelPromise = new Promise(resolve => resolveSourceCancelPromise = resolve);
179
180
      sourceCancelPromise.then(() => {
181
        sourceCancelPromiseHasFulfilled = true;
182
      });
183
184
      return sourceCancelPromise;
185
    }
186
  });
187
188
  setTimeout(() => resolveSourceCancelPromise('Hello'), 1);
189
190
  return rs.cancel().then(value => {
191
    assert_true(sourceCancelPromiseHasFulfilled, 'cancel() return value should be fulfilled only after the promise returned by the underlying source\'s cancel');
192
    assert_equals(value, undefined, 'cancel() return value should be fulfilled with undefined');
193
  });
194
195
}, 'ReadableStream cancellation: if the underlying source\'s cancel method returns a promise, the promise returned by the stream\'s cancel should fulfill when that one does (2)');
196
197
promise_test(() => {
198
199
  let rejectSourceCancelPromise;
200
  let sourceCancelPromiseHasRejected = false;
201
202
  const rs = new ReadableStream({
203
    cancel() {
204
      const sourceCancelPromise = new Promise((resolve, reject) => rejectSourceCancelPromise = reject);
205
206
      sourceCancelPromise.catch(() => {
207
        sourceCancelPromiseHasRejected = true;
208
      });
209
210
      return sourceCancelPromise;
211
    }
212
  });
213
214
  const errorInCancel = new Error('Sorry, it just wasn\'t meant to be.');
215
216
  setTimeout(() => rejectSourceCancelPromise(errorInCancel), 1);
217
218
  return rs.cancel().then(() => {
219
    assert_unreached('cancel() return value should be rejected');
220
  }, r => {
221
    assert_true(sourceCancelPromiseHasRejected, 'cancel() return value should be rejected only after the promise returned by the underlying source\'s cancel');
222
    assert_equals(r, errorInCancel, 'cancel() return value should be rejected with the underlying source\'s rejection reason');
223
  });
224
225
}, 'ReadableStream cancellation: if the underlying source\'s cancel method returns a promise, the promise returned by the stream\'s cancel should reject when that one does');
226
227
promise_test(() => {
228
229
  const rs = new ReadableStream({
230
    start() {
231
      return new Promise(() => {});
232
    },
233
    pull() {
234
      assert_unreached('pull should not have been called');
235
    }
236
  });
237
238
  return Promise.all([rs.cancel(), rs.getReader().closed]);
239
240
}, 'ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called');
241
242
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/count-queuing-strategy-integration-expected.txt -12 lines
Lines 1-12 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/count-queuing-strategy-integration-expected.txt_sec1
1
2
PASS Can construct a readable stream with a valid CountQueuingStrategy 
3
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 0) 
4
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 1) 
5
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 4) 
6
FAIL Load count-queuing-strategy-integration.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
7
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
8
PASS Can construct a readable stream with a valid CountQueuingStrategy 
9
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 0) 
10
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 1) 
11
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 4) 
12
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/count-queuing-strategy-integration.html -12 lines
Lines 1-12 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/count-queuing-strategy-integration.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="count-queuing-strategy-integration.js"></script>
9
<script>
10
'use strict';
11
worker_test('count-queuing-strategy-integration.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/count-queuing-strategy-integration.js -213 lines
Lines 1-213 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/count-queuing-strategy-integration.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
test(() => {
8
9
  new ReadableStream({}, new CountQueuingStrategy({ highWaterMark: 4 }));
10
11
}, 'Can construct a readable stream with a valid CountQueuingStrategy');
12
13
promise_test(() => {
14
15
  let controller;
16
  const rs = new ReadableStream(
17
    {
18
      start(c) {
19
        controller = c;
20
      }
21
    },
22
    new CountQueuingStrategy({ highWaterMark: 0 })
23
  );
24
  const reader = rs.getReader();
25
26
  assert_equals(controller.desiredSize, 0, '0 reads, 0 enqueues: desiredSize should be 0');
27
  controller.enqueue('a');
28
  assert_equals(controller.desiredSize, -1, '0 reads, 1 enqueue: desiredSize should be -1');
29
  controller.enqueue('b');
30
  assert_equals(controller.desiredSize, -2, '0 reads, 2 enqueues: desiredSize should be -2');
31
  controller.enqueue('c');
32
  assert_equals(controller.desiredSize, -3, '0 reads, 3 enqueues: desiredSize should be -3');
33
  controller.enqueue('d');
34
  assert_equals(controller.desiredSize, -4, '0 reads, 4 enqueues: desiredSize should be -4');
35
36
  return reader.read()
37
    .then(result => {
38
      assert_object_equals(result, { value: 'a', done: false },
39
                           '1st read gives back the 1st chunk enqueued (queue now contains 3 chunks)');
40
      return reader.read();
41
    })
42
    .then(result => {
43
      assert_object_equals(result, { value: 'b', done: false },
44
                           '2nd read gives back the 2nd chunk enqueued (queue now contains 2 chunks)');
45
      return reader.read();
46
    })
47
    .then(result => {
48
      assert_object_equals(result, { value: 'c', done: false },
49
                           '3rd read gives back the 3rd chunk enqueued (queue now contains 1 chunk)');
50
51
      assert_equals(controller.desiredSize, -1, '3 reads, 4 enqueues: desiredSize should be -1');
52
      controller.enqueue('e');
53
      assert_equals(controller.desiredSize, -2, '3 reads, 5 enqueues: desiredSize should be -2');
54
55
      return reader.read();
56
    })
57
    .then(result => {
58
      assert_object_equals(result, { value: 'd', done: false },
59
                           '4th read gives back the 4th chunk enqueued (queue now contains 1 chunks)');
60
      return reader.read();
61
62
    }).then(result => {
63
      assert_object_equals(result, { value: 'e', done: false },
64
                           '5th read gives back the 5th chunk enqueued (queue now contains 0 chunks)');
65
66
      assert_equals(controller.desiredSize, 0, '5 reads, 5 enqueues: desiredSize should be 0');
67
      controller.enqueue('f');
68
      assert_equals(controller.desiredSize, -1, '5 reads, 6 enqueues: desiredSize should be -1');
69
      controller.enqueue('g');
70
      assert_equals(controller.desiredSize, -2, '5 reads, 7 enqueues: desiredSize should be -2');
71
    });
72
73
}, 'Correctly governs a ReadableStreamController\'s desiredSize property (HWM = 0)');
74
75
promise_test(() => {
76
77
  let controller;
78
  const rs = new ReadableStream(
79
    {
80
      start(c) {
81
        controller = c;
82
      }
83
    },
84
    new CountQueuingStrategy({ highWaterMark: 1 })
85
  );
86
  const reader = rs.getReader();
87
88
  assert_equals(controller.desiredSize, 1, '0 reads, 0 enqueues: desiredSize should be 1');
89
  controller.enqueue('a');
90
  assert_equals(controller.desiredSize, 0, '0 reads, 1 enqueue: desiredSize should be 0');
91
  controller.enqueue('b');
92
  assert_equals(controller.desiredSize, -1, '0 reads, 2 enqueues: desiredSize should be -1');
93
  controller.enqueue('c');
94
  assert_equals(controller.desiredSize, -2, '0 reads, 3 enqueues: desiredSize should be -2');
95
  controller.enqueue('d');
96
  assert_equals(controller.desiredSize, -3, '0 reads, 4 enqueues: desiredSize should be -3');
97
98
  return reader.read()
99
    .then(result => {
100
      assert_object_equals(result, { value: 'a', done: false },
101
                           '1st read gives back the 1st chunk enqueued (queue now contains 3 chunks)');
102
      return reader.read();
103
    })
104
    .then(result => {
105
      assert_object_equals(result, { value: 'b', done: false },
106
                           '2nd read gives back the 2nd chunk enqueued (queue now contains 2 chunks)');
107
      return reader.read();
108
    })
109
    .then(result => {
110
      assert_object_equals(result, { value: 'c', done: false },
111
                           '3rd read gives back the 3rd chunk enqueued (queue now contains 1 chunk)');
112
113
      assert_equals(controller.desiredSize, 0, '3 reads, 4 enqueues: desiredSize should be 0');
114
      controller.enqueue('e');
115
      assert_equals(controller.desiredSize, -1, '3 reads, 5 enqueues: desiredSize should be -1');
116
117
      return reader.read();
118
    })
119
    .then(result => {
120
      assert_object_equals(result, { value: 'd', done: false },
121
                           '4th read gives back the 4th chunk enqueued (queue now contains 1 chunks)');
122
      return reader.read();
123
    })
124
    .then(result => {
125
      assert_object_equals(result, { value: 'e', done: false },
126
                           '5th read gives back the 5th chunk enqueued (queue now contains 0 chunks)');
127
128
      assert_equals(controller.desiredSize, 1, '5 reads, 5 enqueues: desiredSize should be 1');
129
      controller.enqueue('f');
130
      assert_equals(controller.desiredSize, 0, '5 reads, 6 enqueues: desiredSize should be 0');
131
      controller.enqueue('g');
132
      assert_equals(controller.desiredSize, -1, '5 reads, 7 enqueues: desiredSize should be -1');
133
    });
134
135
}, 'Correctly governs a ReadableStreamController\'s desiredSize property (HWM = 1)');
136
137
promise_test(() => {
138
139
  let controller;
140
  const rs = new ReadableStream(
141
    {
142
      start(c) {
143
        controller = c;
144
      }
145
    },
146
    new CountQueuingStrategy({ highWaterMark: 4 })
147
  );
148
  const reader = rs.getReader();
149
150
  assert_equals(controller.desiredSize, 4, '0 reads, 0 enqueues: desiredSize should be 4');
151
  controller.enqueue('a');
152
  assert_equals(controller.desiredSize, 3, '0 reads, 1 enqueue: desiredSize should be 3');
153
  controller.enqueue('b');
154
  assert_equals(controller.desiredSize, 2, '0 reads, 2 enqueues: desiredSize should be 2');
155
  controller.enqueue('c');
156
  assert_equals(controller.desiredSize, 1, '0 reads, 3 enqueues: desiredSize should be 1');
157
  controller.enqueue('d');
158
  assert_equals(controller.desiredSize, 0, '0 reads, 4 enqueues: desiredSize should be 0');
159
  controller.enqueue('e');
160
  assert_equals(controller.desiredSize, -1, '0 reads, 5 enqueues: desiredSize should be -1');
161
  controller.enqueue('f');
162
  assert_equals(controller.desiredSize, -2, '0 reads, 6 enqueues: desiredSize should be -2');
163
164
165
  reader.read()
166
    .then(result => {
167
      assert_object_equals(result, { value: 'a', done: false },
168
                           '1st read gives back the 1st chunk enqueued (queue now contains 5 chunks)');
169
      return reader.read();
170
    })
171
    .then(result => {
172
      assert_object_equals(result, { value: 'b', done: false },
173
                           '2nd read gives back the 2nd chunk enqueued (queue now contains 4 chunks)');
174
175
      assert_equals(controller.desiredSize, 0, '2 reads, 6 enqueues: desiredSize should be 0');
176
      controller.enqueue('g');
177
      assert_equals(controller.desiredSize, -1, '2 reads, 7 enqueues: desiredSize should be -1');
178
179
      return reader.read();
180
    })
181
    .then(result => {
182
      assert_object_equals(result, { value: 'c', done: false },
183
                           '3rd read gives back the 3rd chunk enqueued (queue now contains 4 chunks)');
184
      return reader.read();
185
    })
186
    .then(result => {
187
      assert_object_equals(result, { value: 'd', done: false },
188
                           '4th read gives back the 4th chunk enqueued (queue now contains 3 chunks)');
189
      return reader.read();
190
    })
191
    .then(result => {
192
      assert_object_equals(result, { value: 'e', done: false },
193
                           '5th read gives back the 5th chunk enqueued (queue now contains 2 chunks)');
194
      return reader.read();
195
    })
196
    .then(result => {
197
      assert_object_equals(result, { value: 'f', done: false },
198
                           '6th read gives back the 6th chunk enqueued (queue now contains 0 chunks)');
199
200
      assert_equals(controller.desiredSize, 3, '6 reads, 7 enqueues: desiredSize should be 3');
201
      controller.enqueue('h');
202
      assert_equals(controller.desiredSize, 2, '6 reads, 8 enqueues: desiredSize should be 2');
203
      controller.enqueue('i');
204
      assert_equals(controller.desiredSize, 1, '6 reads, 9 enqueues: desiredSize should be 1');
205
      controller.enqueue('j');
206
      assert_equals(controller.desiredSize, 0, '6 reads, 10 enqueues: desiredSize should be 0');
207
      controller.enqueue('k');
208
      assert_equals(controller.desiredSize, -1, '6 reads, 11 enqueues: desiredSize should be -1');
209
    });
210
211
}, 'Correctly governs a ReadableStreamController\'s desiredSize property (HWM = 4)');
212
213
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-1-expected.txt -6 lines
Lines 1-6 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-1-expected.txt_sec1
1
2
PASS ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream 
3
PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost 
4
PASS ReadableStream closed promise should reject even if stream and reader JS references are lost 
5
PASS Garbage-collecting a ReadableStreamReader should not unlock its stream 
6
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-1.html -10 lines
Lines 1-10 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-1.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<!-- File to be removed once https://bugs.webkit.org/show_bug.cgi?id=152436 is resolved -->
10
<script src="garbage-collection.js"></script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-2-expected.txt -4 lines
Lines 1-4 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-2-expected.txt_sec1
1
2
PASS ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream 
3
PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost 
4
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-2.html -48 lines
Lines 1-48 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-2.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<!-- File to be removed once https://bugs.webkit.org/show_bug.cgi?id=152436 is resolved -->
10
<script>
11
'use strict';
12
13
promise_test(() => {
14
15
  let controller;
16
  new ReadableStream({
17
    start(c) {
18
      controller = c;
19
    }
20
  });
21
22
  garbageCollect();
23
24
  return delay(50).then(() => {
25
    controller.close();
26
    assert_throws(new TypeError(), () => controller.close(), 'close should throw a TypeError the second time');
27
    assert_throws(new TypeError(), () => controller.error(), 'error should throw a TypeError on a closed stream');
28
  });
29
30
}, 'ReadableStreamController methods should continue working properly when scripts lose their reference to the ' +
31
   'readable stream');
32
33
promise_test(() => {
34
35
  let controller;
36
37
  const closedPromise = new ReadableStream({
38
    start(c) {
39
      controller = c;
40
    }
41
  }).getReader().closed;
42
43
  garbageCollect();
44
45
  return delay(50).then(() => controller.close()).then(() => closedPromise);
46
47
}, 'ReadableStream closed promise should fulfill even if the stream and reader JS references are lost');
48
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-expected.txt -16 lines
Lines 1-16 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection-expected.txt_sec1
1
CONSOLE MESSAGE: line 37: Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.
2
CONSOLE MESSAGE: line 37: Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.
3
CONSOLE MESSAGE: line 37: Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.
4
CONSOLE MESSAGE: line 37: Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.
5
6
PASS ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream 
7
PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost 
8
PASS ReadableStream closed promise should reject even if stream and reader JS references are lost 
9
PASS Garbage-collecting a ReadableStreamReader should not unlock its stream 
10
FAIL Load garbage-collection.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
11
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
12
PASS ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream 
13
PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost 
14
PASS ReadableStream closed promise should reject even if stream and reader JS references are lost 
15
PASS Garbage-collecting a ReadableStreamReader should not unlock its stream 
16
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection.html -13 lines
Lines 1-13 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="garbage-collection.js"></script>
10
<script>
11
'use strict';
12
worker_test('garbage-collection.js');
13
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection.js -75 lines
Lines 1-75 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/garbage-collection.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
promise_test(() => {
9
10
  let controller;
11
  new ReadableStream({
12
    start(c) {
13
      controller = c;
14
    }
15
  });
16
17
  garbageCollect();
18
19
  return delay(50).then(() => {
20
    controller.close();
21
    assert_throws(new TypeError(), () => controller.close(), 'close should throw a TypeError the second time');
22
    assert_throws(new TypeError(), () => controller.error(), 'error should throw a TypeError on a closed stream');
23
  });
24
25
}, 'ReadableStreamController methods should continue working properly when scripts lose their reference to the ' +
26
   'readable stream');
27
28
promise_test(() => {
29
30
  let controller;
31
32
  const closedPromise = new ReadableStream({
33
    start(c) {
34
      controller = c;
35
    }
36
  }).getReader().closed;
37
38
  garbageCollect();
39
40
  return delay(50).then(() => controller.close()).then(() => closedPromise);
41
42
}, 'ReadableStream closed promise should fulfill even if the stream and reader JS references are lost');
43
44
promise_test(t => {
45
46
  const theError = new Error('boo');
47
  let controller;
48
49
  const closedPromise = new ReadableStream({
50
    start(c) {
51
      controller = c;
52
    }
53
  }).getReader().closed;
54
55
  garbageCollect();
56
57
  return delay(50).then(() => controller.error(theError))
58
                  .then(() => promise_rejects(t, theError, closedPromise));
59
60
}, 'ReadableStream closed promise should reject even if stream and reader JS references are lost');
61
62
promise_test(() => {
63
64
  const rs = new ReadableStream({});
65
66
  rs.getReader();
67
68
  garbageCollect();
69
70
  return delay(50).then(() => assert_throws(new TypeError(), () => rs.getReader(),
71
    'old reader should still be locking the stream even after garbage collection'));
72
73
}, 'Garbage-collecting a ReadableStreamReader should not unlock its stream');
74
75
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/general-expected.txt -70 lines
Lines 1-70 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/general-expected.txt_sec1
1
2
PASS ReadableStream can be constructed with no errors 
3
PASS ReadableStream can't be constructed with garbage 
4
FAIL ReadableStream instances should have the correct list of properties assert_false: method should be non-enumerable expected false got true
5
PASS ReadableStream constructor should throw for non-function start arguments 
6
PASS ReadableStream constructor can get initial garbage as cancel argument 
7
PASS ReadableStream constructor can get initial garbage as pull argument 
8
FAIL ReadableStream start should be called with the proper parameters assert_false: close should be non-enumerable expected false got true
9
PASS ReadableStream start controller parameter should be extensible 
10
PASS ReadableStream should be able to call start method within prototype chain of its source 
11
PASS ReadableStream start should be able to return a promise 
12
PASS ReadableStream start should be able to return a promise and reject it 
13
PASS ReadableStream should be able to enqueue different objects. 
14
PASS ReadableStream: if pull rejects, it should error the stream 
15
PASS ReadableStream: should only call pull once upon starting the stream 
16
PASS ReadableStream: should call pull when trying to read from a started, empty stream 
17
PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills 
18
PASS ReadableStream: should only call pull once on a non-empty stream read from after start fulfills 
19
PASS ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining 
20
PASS ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining 
21
PASS ReadableStream: should not call pull until the previous pull call's promise fulfills 
22
PASS ReadableStream: should pull after start, and after every read 
23
PASS ReadableStream: should not call pull after start if the stream is now closed 
24
PASS ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows 
25
PASS ReadableStream pull should be able to close a stream. 
26
PASS ReadableStream: enqueue should throw when the stream is readable but draining 
27
PASS ReadableStream: enqueue should throw when the stream is closed 
28
PASS ReadableStream: enqueue should throw the stored error when the stream is errored 
29
PASS ReadableStream: should call underlying source methods as methods 
30
PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue 
31
PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately 
32
PASS ReadableStream integration test: adapting a random push source 
33
PASS ReadableStream integration test: adapting a sync pull source 
34
PASS ReadableStream integration test: adapting an async pull source 
35
FAIL Load general.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
36
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
37
PASS ReadableStream can be constructed with no errors 
38
PASS ReadableStream can't be constructed with garbage 
39
FAIL ReadableStream instances should have the correct list of properties assert_false: method should be non-enumerable expected false got true
40
PASS ReadableStream constructor should throw for non-function start arguments 
41
PASS ReadableStream constructor can get initial garbage as cancel argument 
42
PASS ReadableStream constructor can get initial garbage as pull argument 
43
FAIL ReadableStream start should be called with the proper parameters assert_false: close should be non-enumerable expected false got true
44
PASS ReadableStream start controller parameter should be extensible 
45
PASS ReadableStream should be able to call start method within prototype chain of its source 
46
PASS ReadableStream start should be able to return a promise 
47
PASS ReadableStream start should be able to return a promise and reject it 
48
PASS ReadableStream should be able to enqueue different objects. 
49
PASS ReadableStream: if pull rejects, it should error the stream 
50
PASS ReadableStream: should only call pull once upon starting the stream 
51
PASS ReadableStream: should call pull when trying to read from a started, empty stream 
52
PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills 
53
PASS ReadableStream: should only call pull once on a non-empty stream read from after start fulfills 
54
PASS ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining 
55
PASS ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining 
56
PASS ReadableStream: should not call pull until the previous pull call's promise fulfills 
57
PASS ReadableStream: should pull after start, and after every read 
58
PASS ReadableStream: should not call pull after start if the stream is now closed 
59
PASS ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows 
60
PASS ReadableStream pull should be able to close a stream. 
61
PASS ReadableStream: enqueue should throw when the stream is readable but draining 
62
PASS ReadableStream: enqueue should throw when the stream is closed 
63
PASS ReadableStream: enqueue should throw the stored error when the stream is errored 
64
PASS ReadableStream: should call underlying source methods as methods 
65
PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue 
66
PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately 
67
PASS ReadableStream integration test: adapting a random push source 
68
PASS ReadableStream integration test: adapting a sync pull source 
69
PASS ReadableStream integration test: adapting an async pull source 
70
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/general.html -14 lines
Lines 1-14 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/general.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="../resources/rs-utils.js"></script>
10
<script src="general.js"></script>
11
<script>
12
'use strict';
13
worker_test('general.js');
14
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/general.js -831 lines
Lines 1-831 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/general.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('../resources/rs-utils.js');
6
  self.importScripts('/resources/testharness.js');
7
}
8
9
test(() => {
10
11
  new ReadableStream(); // ReadableStream constructed with no parameters
12
  new ReadableStream({ }); // ReadableStream constructed with an empty object as parameter
13
  new ReadableStream(undefined); // ReadableStream constructed with undefined as parameter
14
15
  let x;
16
  new ReadableStream(x); // ReadableStream constructed with an undefined variable as parameter
17
18
}, 'ReadableStream can be constructed with no errors');
19
20
test(() => {
21
22
  assert_throws(new TypeError(), () => new ReadableStream(null), 'constructor should throw when the source is null');
23
24
}, 'ReadableStream can\'t be constructed with garbage');
25
26
test(() => {
27
28
  const methods = ['cancel', 'constructor', 'getReader', 'pipeThrough', 'pipeTo', 'tee'];
29
  const properties = methods.concat(['locked']).sort();
30
31
  const rs = new ReadableStream();
32
  const proto = Object.getPrototypeOf(rs);
33
34
  assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties, 'should have all the correct methods');
35
36
  for (const m of methods) {
37
    const propDesc = Object.getOwnPropertyDescriptor(proto, m);
38
    assert_false(propDesc.enumerable, 'method should be non-enumerable');
39
    assert_true(propDesc.configurable, 'method should be configurable');
40
    assert_true(propDesc.writable, 'method should be writable');
41
    assert_equals(typeof rs[m], 'function', 'method should be a function');
42
  }
43
44
  const lockedPropDesc = Object.getOwnPropertyDescriptor(proto, 'locked');
45
  assert_false(lockedPropDesc.enumerable, 'locked should be non-enumerable');
46
  assert_equals(lockedPropDesc.writable, undefined, 'locked should not be a data property');
47
  assert_equals(typeof lockedPropDesc.get, 'function', 'locked should have a getter');
48
  assert_equals(lockedPropDesc.set, undefined, 'locked should not have a setter');
49
  assert_true(lockedPropDesc.configurable, 'locked should be configurable');
50
51
  assert_equals(rs.cancel.length, 1, 'cancel should have 1 parameter');
52
  assert_equals(rs.constructor.length, 0, 'constructor should have no parameters');
53
  assert_equals(rs.getReader.length, 0, 'getReader should have no parameters');
54
  assert_equals(rs.pipeThrough.length, 2, 'pipeThrough should have 2 parameters');
55
  assert_equals(rs.pipeTo.length, 1, 'pipeTo should have 1 parameter');
56
  assert_equals(rs.tee.length, 0, 'tee should have no parameters');
57
58
}, 'ReadableStream instances should have the correct list of properties');
59
60
test(() => {
61
62
  assert_throws(new TypeError(), () => {
63
    new ReadableStream({ start: 'potato' });
64
  }, 'constructor should throw when start is not a function');
65
66
}, 'ReadableStream constructor should throw for non-function start arguments');
67
68
test(() => {
69
70
  new ReadableStream({ cancel: '2' });
71
72
}, 'ReadableStream constructor can get initial garbage as cancel argument');
73
74
test(() => {
75
76
  new ReadableStream({ pull: { } });
77
78
}, 'ReadableStream constructor can get initial garbage as pull argument');
79
80
test(() => {
81
82
  let startCalled = false;
83
84
  const source = {
85
    start(controller) {
86
      assert_equals(this, source, 'source is this during start');
87
88
      const methods = ['close', 'enqueue', 'error', 'constructor'];
89
      const properties = ['desiredSize'].concat(methods).sort();
90
      const proto = Object.getPrototypeOf(controller);
91
92
      assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties,
93
        'the controller should have the right properties');
94
95
      for (const m of methods) {
96
        const propDesc = Object.getOwnPropertyDescriptor(proto, m);
97
        assert_equals(typeof controller[m], 'function', `should have a ${m} method`);
98
        assert_false(propDesc.enumerable, m + ' should be non-enumerable');
99
        assert_true(propDesc.configurable, m + ' should be configurable');
100
        assert_true(propDesc.writable, m + ' should be writable');
101
      }
102
103
      const desiredSizePropDesc = Object.getOwnPropertyDescriptor(proto, 'desiredSize');
104
      assert_false(desiredSizePropDesc.enumerable, 'desiredSize should be non-enumerable');
105
      assert_equals(desiredSizePropDesc.writable, undefined, 'desiredSize should not be a data property');
106
      assert_equals(typeof desiredSizePropDesc.get, 'function', 'desiredSize should have a getter');
107
      assert_equals(desiredSizePropDesc.set, undefined, 'desiredSize should not have a setter');
108
      assert_true(desiredSizePropDesc.configurable, 'desiredSize should be configurable');
109
110
      assert_equals(controller.close.length, 0, 'close should have no parameters');
111
      assert_equals(controller.constructor.length, 1, 'constructor should have 1 parameter');
112
      assert_equals(controller.enqueue.length, 1, 'enqueue should have 1 parameter');
113
      assert_equals(controller.error.length, 1, 'error should have 1 parameter');
114
115
      startCalled = true;
116
    }
117
  };
118
119
  new ReadableStream(source);
120
  assert_true(startCalled);
121
122
}, 'ReadableStream start should be called with the proper parameters');
123
124
test(() => {
125
126
  let startCalled = false;
127
  const source = {
128
    start(controller) {
129
      const properties = ['close', 'constructor', 'desiredSize', 'enqueue', 'error'];
130
      assert_array_equals(Object.getOwnPropertyNames(Object.getPrototypeOf(controller)).sort(), properties,
131
        'prototype should have the right properties');
132
133
      controller.test = '';
134
      assert_array_equals(Object.getOwnPropertyNames(Object.getPrototypeOf(controller)).sort(), properties,
135
        'prototype should still have the right properties');
136
      assert_not_equals(Object.getOwnPropertyNames(controller).indexOf('test'), -1,
137
        '"test" should be a property of the controller');
138
139
      startCalled = true;
140
    }
141
  };
142
143
  new ReadableStream(source);
144
  assert_true(startCalled);
145
146
}, 'ReadableStream start controller parameter should be extensible');
147
148
promise_test(() => {
149
150
  function SimpleStreamSource() {}
151
  let resolve;
152
  const promise = new Promise(r => resolve = r);
153
  SimpleStreamSource.prototype = {
154
    start: resolve
155
  };
156
157
  new ReadableStream(new SimpleStreamSource());
158
  return promise;
159
160
}, 'ReadableStream should be able to call start method within prototype chain of its source');
161
162
promise_test(() => {
163
164
  const rs = new ReadableStream({
165
    start(c) {
166
      return delay(5).then(() => {
167
        c.enqueue('a');
168
        c.close();
169
      });
170
    }
171
  });
172
173
  const reader = rs.getReader();
174
  return reader.read().then(r => {
175
    assert_object_equals(r, { value: 'a', done: false }, 'value read should be the one enqueued');
176
    return reader.closed;
177
  });
178
179
}, 'ReadableStream start should be able to return a promise');
180
181
promise_test(() => {
182
183
  const theError = new Error('rejected!');
184
  const rs = new ReadableStream({
185
    start() {
186
      return delay(1).then(() => { throw theError; });
187
    }
188
  });
189
190
  return rs.getReader().closed.then(() => {
191
    assert_unreached('closed promise should be rejected');
192
  }, e => {
193
    assert_equals(e, theError, 'promise should be rejected with the same error');
194
  });
195
196
}, 'ReadableStream start should be able to return a promise and reject it');
197
198
promise_test(() => {
199
200
  const objects = [
201
    { potato: 'Give me more!' },
202
    'test',
203
    1
204
  ];
205
206
  const rs = new ReadableStream({
207
    start(c) {
208
      for (const o of objects) {
209
        c.enqueue(o);
210
      }
211
      c.close();
212
    }
213
  });
214
215
  const reader = rs.getReader();
216
217
  return Promise.all([reader.read(), reader.read(), reader.read(), reader.closed]).then(r => {
218
    assert_object_equals(r[0], { value: objects[0], done: false }, 'value read should be the one enqueued');
219
    assert_object_equals(r[1], { value: objects[1], done: false }, 'value read should be the one enqueued');
220
    assert_object_equals(r[2], { value: objects[2], done: false }, 'value read should be the one enqueued');
221
  });
222
223
}, 'ReadableStream should be able to enqueue different objects.');
224
225
promise_test(() => {
226
227
  const error = new Error('pull failure');
228
  const rs = new ReadableStream({
229
    pull() {
230
      return Promise.reject(error);
231
    }
232
  });
233
234
  const reader = rs.getReader();
235
236
  let closed = false;
237
  let read = false;
238
239
  return Promise.all([
240
    reader.closed.then(() => {
241
      assert_unreached('closed should be rejected');
242
    }, e => {
243
      closed = true;
244
      assert_true(read);
245
      assert_equals(e, error, 'closed should be rejected with the thrown error');
246
    }),
247
    reader.read().then(() => {
248
      assert_unreached('read() should be rejected');
249
    }, e => {
250
      read = true;
251
      assert_false(closed);
252
      assert_equals(e, error, 'read() should be rejected with the thrown error');
253
    })
254
  ]);
255
256
}, 'ReadableStream: if pull rejects, it should error the stream');
257
258
promise_test(() => {
259
260
  let pullCount = 0;
261
  const startPromise = Promise.resolve();
262
263
  new ReadableStream({
264
    start() {
265
      return startPromise;
266
    },
267
    pull() {
268
      pullCount++;
269
    }
270
  });
271
272
  return startPromise.then(() => {
273
    assert_equals(pullCount, 1, 'pull should be called once start finishes');
274
    return delay(10);
275
  }).then(() => {
276
    assert_equals(pullCount, 1, 'pull should be called exactly once');
277
  });
278
279
}, 'ReadableStream: should only call pull once upon starting the stream');
280
281
promise_test(() => {
282
283
  let pullCount = 0;
284
285
  const rs = new ReadableStream({
286
    pull(c) {
287
      // Don't enqueue immediately after start. We want the stream to be empty when we call .read() on it.
288
      if (pullCount > 0) {
289
        c.enqueue(pullCount);
290
      }
291
      ++pullCount;
292
    }
293
  });
294
295
  return delay(1).then(() => {
296
    assert_equals(pullCount, 1, 'pull should be called once start finishes');
297
298
    const reader = rs.getReader();
299
    const read = reader.read();
300
    assert_equals(pullCount, 2, 'pull should be called when read is called');
301
    return read;
302
  }).then(result => {
303
    assert_equals(pullCount, 3, 'pull should be called again in reaction to calling read');
304
    assert_object_equals(result, { value: 1, done: false }, 'the result read should be the one enqueued');
305
  });
306
307
}, 'ReadableStream: should call pull when trying to read from a started, empty stream');
308
309
promise_test(() => {
310
311
  let pullCount = 0;
312
  const startPromise = Promise.resolve();
313
314
  const rs = new ReadableStream({
315
    start(c) {
316
      c.enqueue('a');
317
      return startPromise;
318
    },
319
    pull() {
320
      pullCount++;
321
    }
322
  });
323
324
  const read = rs.getReader().read();
325
  assert_equals(pullCount, 0, 'calling read() should not cause pull to be called yet');
326
327
  return startPromise.then(() => {
328
    assert_equals(pullCount, 1, 'pull should be called once start finishes');
329
    return read;
330
  }).then(r => {
331
    assert_object_equals(r, { value: 'a', done: false }, 'first read() should return first chunk');
332
    assert_equals(pullCount, 1, 'pull should not have been called again');
333
    return delay(10);
334
  }).then(() => {
335
    assert_equals(pullCount, 1, 'pull should be called exactly once');
336
  });
337
338
}, 'ReadableStream: should only call pull once on a non-empty stream read from before start fulfills');
339
340
promise_test(() => {
341
342
  let pullCount = 0;
343
  const startPromise = Promise.resolve();
344
345
  const rs = new ReadableStream({
346
    start(c) {
347
      c.enqueue('a');
348
      return startPromise;
349
    },
350
    pull() {
351
      pullCount++;
352
    }
353
  });
354
355
  return startPromise.then(() => {
356
    assert_equals(pullCount, 0, 'pull should not be called once start finishes, since the queue is full');
357
358
    const read = rs.getReader().read();
359
    assert_equals(pullCount, 1, 'calling read() should cause pull to be called immediately');
360
    return read;
361
  }).then(r => {
362
    assert_object_equals(r, { value: 'a', done: false }, 'first read() should return first chunk');
363
    return delay(10);
364
  }).then(() => {
365
    assert_equals(pullCount, 1, 'pull should be called exactly once');
366
  });
367
368
}, 'ReadableStream: should only call pull once on a non-empty stream read from after start fulfills');
369
370
promise_test(() => {
371
372
  let pullCount = 0;
373
  let controller;
374
  const startPromise = Promise.resolve();
375
376
  const rs = new ReadableStream({
377
    start(c) {
378
      controller = c;
379
      return startPromise;
380
    },
381
    pull() {
382
      ++pullCount;
383
    }
384
  });
385
386
  const reader = rs.getReader();
387
  return startPromise.then(() => {
388
    assert_equals(pullCount, 1, 'pull should have been called once by the time the stream starts');
389
390
    controller.enqueue('a');
391
    assert_equals(pullCount, 1, 'pull should not have been called again after enqueue');
392
393
    return reader.read();
394
  }).then(() => {
395
    assert_equals(pullCount, 2, 'pull should have been called again after read');
396
397
    return delay(10);
398
  }).then(() => {
399
    assert_equals(pullCount, 2, 'pull should be called exactly twice');
400
  });
401
}, 'ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining');
402
403
promise_test(() => {
404
405
  let pullCount = 0;
406
  let controller;
407
  const startPromise = Promise.resolve();
408
409
  const rs = new ReadableStream({
410
    start(c) {
411
      controller = c;
412
      return startPromise;
413
    },
414
    pull() {
415
      ++pullCount;
416
    }
417
  });
418
419
  const reader = rs.getReader();
420
421
  return startPromise.then(() => {
422
    assert_equals(pullCount, 1, 'pull should have been called once by the time the stream starts');
423
424
    controller.enqueue('a');
425
    assert_equals(pullCount, 1, 'pull should not have been called again after enqueue');
426
427
    controller.close();
428
429
    return reader.read();
430
  }).then(() => {
431
    assert_equals(pullCount, 1, 'pull should not have been called a second time after read');
432
433
    return delay(10);
434
  }).then(() => {
435
    assert_equals(pullCount, 1, 'pull should be called exactly once');
436
  });
437
438
}, 'ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining');
439
440
promise_test(() => {
441
442
  let resolve;
443
  let returnedPromise;
444
  let timesCalled = 0;
445
  const startPromise = Promise.resolve();
446
447
  const rs = new ReadableStream({
448
    start() {
449
      return startPromise;
450
    },
451
    pull(c) {
452
      c.enqueue(++timesCalled);
453
      returnedPromise = new Promise(r => resolve = r);
454
      return returnedPromise;
455
    }
456
  });
457
  const reader = rs.getReader();
458
459
  return startPromise.then(() => {
460
    return reader.read();
461
  }).then(result1 => {
462
    assert_equals(timesCalled, 1,
463
      'pull should have been called once after start, but not yet have been called a second time');
464
    assert_object_equals(result1, { value: 1, done: false }, 'read() should fulfill with the enqueued value');
465
466
    return delay(10);
467
  }).then(() => {
468
    assert_equals(timesCalled, 1, 'after 10 ms, pull should still only have been called once');
469
470
    resolve();
471
    return returnedPromise;
472
  }).then(() => {
473
    assert_equals(timesCalled, 2,
474
      'after the promise returned by pull is fulfilled, pull should be called a second time');
475
  });
476
477
}, 'ReadableStream: should not call pull until the previous pull call\'s promise fulfills');
478
479
promise_test(() => {
480
481
  let timesCalled = 0;
482
  const startPromise = Promise.resolve();
483
484
  const rs = new ReadableStream(
485
    {
486
      start(c) {
487
        c.enqueue('a');
488
        c.enqueue('b');
489
        c.enqueue('c');
490
        return startPromise;
491
      },
492
      pull() {
493
        ++timesCalled;
494
      }
495
    },
496
    {
497
      size() {
498
        return 1;
499
      },
500
      highWaterMark: Infinity
501
    }
502
  );
503
  const reader = rs.getReader();
504
505
  return startPromise.then(() => {
506
    return reader.read();
507
  }).then(result1 => {
508
    assert_object_equals(result1, { value: 'a', done: false }, 'first chunk should be as expected');
509
510
    return reader.read();
511
  }).then(result2 => {
512
    assert_object_equals(result2, { value: 'b', done: false }, 'second chunk should be as expected');
513
514
    return reader.read();
515
  }).then(result3 => {
516
    assert_object_equals(result3, { value: 'c', done: false }, 'third chunk should be as expected');
517
518
    return delay(10);
519
  }).then(() => {
520
    // Once for after start, and once for every read.
521
    assert_equals(timesCalled, 4, 'pull() should be called exactly four times');
522
  });
523
524
}, 'ReadableStream: should pull after start, and after every read');
525
526
promise_test(() => {
527
528
  let timesCalled = 0;
529
  const startPromise = Promise.resolve();
530
531
  const rs = new ReadableStream({
532
    start(c) {
533
      c.enqueue('a');
534
      c.close();
535
      return startPromise;
536
    },
537
    pull() {
538
      ++timesCalled;
539
    }
540
  });
541
542
  const reader = rs.getReader();
543
  return startPromise.then(() => {
544
    assert_equals(timesCalled, 0, 'after start finishes, pull should not have been called');
545
546
    return reader.read();
547
  }).then(() => {
548
    assert_equals(timesCalled, 0, 'reading should not have triggered a pull call');
549
550
    return reader.closed;
551
  }).then(() => {
552
    assert_equals(timesCalled, 0, 'stream should have closed with still no calls to pull');
553
  });
554
555
}, 'ReadableStream: should not call pull after start if the stream is now closed');
556
557
promise_test(() => {
558
559
  let timesCalled = 0;
560
  let resolve;
561
  const ready = new Promise(r => resolve = r);
562
563
  new ReadableStream(
564
    {
565
      start() {},
566
      pull(c) {
567
        c.enqueue(++timesCalled);
568
569
        if (timesCalled === 4) {
570
          resolve();
571
        }
572
      }
573
    },
574
    {
575
      size() {
576
        return 1;
577
      },
578
      highWaterMark: 4
579
    }
580
  );
581
582
  return ready.then(() => {
583
    // after start: size = 0, pull()
584
    // after enqueue(1): size = 1, pull()
585
    // after enqueue(2): size = 2, pull()
586
    // after enqueue(3): size = 3, pull()
587
    // after enqueue(4): size = 4, do not pull
588
    assert_equals(timesCalled, 4, 'pull() should have been called four times');
589
  });
590
591
}, 'ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows');
592
593
promise_test(() => {
594
595
  let pullCalled = false;
596
597
  const rs = new ReadableStream({
598
    pull(c) {
599
      pullCalled = true;
600
      c.close();
601
    }
602
  });
603
604
  const reader = rs.getReader();
605
  return reader.closed.then(() => {
606
    assert_true(pullCalled);
607
  });
608
609
}, 'ReadableStream pull should be able to close a stream.');
610
611
test(() => {
612
613
  let startCalled = false;
614
615
  new ReadableStream({
616
    start(c) {
617
      assert_equals(c.enqueue('a'), undefined, 'the first enqueue should return undefined');
618
      c.close();
619
620
      assert_throws(new TypeError(), () => c.enqueue('b'), 'enqueue after close should throw a TypeError');
621
      startCalled = true;
622
    }
623
  });
624
625
  assert_true(startCalled);
626
627
}, 'ReadableStream: enqueue should throw when the stream is readable but draining');
628
629
test(() => {
630
631
  let startCalled = false;
632
633
  new ReadableStream({
634
    start(c) {
635
      c.close();
636
637
      assert_throws(new TypeError(), () => c.enqueue('a'), 'enqueue after close should throw a TypeError');
638
      startCalled = true;
639
    }
640
  });
641
642
  assert_true(startCalled);
643
644
}, 'ReadableStream: enqueue should throw when the stream is closed');
645
646
test(() => {
647
648
  let startCalled = false;
649
  const expectedError = new Error('i am sad');
650
651
  new ReadableStream({
652
    start(c) {
653
      c.error(expectedError);
654
655
      assert_throws(expectedError, () => c.enqueue('a'), 'enqueue after error should throw that error');
656
      startCalled = true;
657
    }
658
  });
659
660
  assert_true(startCalled);
661
662
}, 'ReadableStream: enqueue should throw the stored error when the stream is errored');
663
664
promise_test(() => {
665
666
  let startCalled = 0;
667
  let pullCalled = 0;
668
  let cancelCalled = 0;
669
670
  /* eslint-disable no-use-before-define */
671
  class Source {
672
    start(c) {
673
      startCalled++;
674
      assert_equals(this, theSource, 'start() should be called with the correct this');
675
      c.enqueue('a');
676
    }
677
678
    pull() {
679
      pullCalled++;
680
      assert_equals(this, theSource, 'pull() should be called with the correct this');
681
    }
682
683
    cancel() {
684
      cancelCalled++;
685
      assert_equals(this, theSource, 'cancel() should be called with the correct this');
686
    }
687
  }
688
  /* eslint-enable no-use-before-define */
689
690
  const theSource = new Source();
691
  theSource.debugName = 'the source object passed to the constructor'; // makes test failures easier to diagnose
692
693
  const rs = new ReadableStream(theSource);
694
  const reader = rs.getReader();
695
696
  return reader.read().then(() => {
697
    reader.releaseLock();
698
    rs.cancel();
699
    assert_equals(startCalled, 1);
700
    assert_equals(pullCalled, 1);
701
    assert_equals(cancelCalled, 1);
702
    return rs.getReader().closed;
703
  });
704
705
}, 'ReadableStream: should call underlying source methods as methods');
706
707
test(() => {
708
709
  let startCalled = false;
710
  new ReadableStream({
711
    start(c) {
712
      assert_equals(c.desiredSize, 1);
713
      c.enqueue('a');
714
      assert_equals(c.desiredSize, 0);
715
      c.enqueue('b');
716
      assert_equals(c.desiredSize, -1);
717
      c.enqueue('c');
718
      assert_equals(c.desiredSize, -2);
719
      c.enqueue('d');
720
      assert_equals(c.desiredSize, -3);
721
      c.enqueue('e');
722
      startCalled = true;
723
    }
724
  });
725
726
  assert_true(startCalled);
727
728
}, 'ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue');
729
730
promise_test(() => {
731
732
  let controller;
733
  const rs = new ReadableStream({
734
    start(c) {
735
      controller = c;
736
    }
737
  });
738
  const reader = rs.getReader();
739
740
  assert_equals(controller.desiredSize, 1, 'desiredSize should start at 1');
741
  controller.enqueue('a');
742
  assert_equals(controller.desiredSize, 0, 'desiredSize should decrease to 0 after first enqueue');
743
744
  return reader.read().then(result1 => {
745
    assert_object_equals(result1, { value: 'a', done: false }, 'first chunk read should be correct');
746
747
    assert_equals(controller.desiredSize, 1, 'desiredSize should go up to 1 after the first read');
748
    controller.enqueue('b');
749
    assert_equals(controller.desiredSize, 0, 'desiredSize should go down to 0 after the second enqueue');
750
751
    return reader.read();
752
  }).then(result2 => {
753
    assert_object_equals(result2, { value: 'b', done: false }, 'second chunk read should be correct');
754
755
    assert_equals(controller.desiredSize, 1, 'desiredSize should go up to 1 after the second read');
756
    controller.enqueue('c');
757
    assert_equals(controller.desiredSize, 0, 'desiredSize should go down to 0 after the third enqueue');
758
759
    return reader.read();
760
  }).then(result3 => {
761
    assert_object_equals(result3, { value: 'c', done: false }, 'third chunk read should be correct');
762
763
    assert_equals(controller.desiredSize, 1, 'desiredSize should go up to 1 after the third read');
764
    controller.enqueue('d');
765
    assert_equals(controller.desiredSize, 0, 'desiredSize should go down to 0 after the fourth enqueue');
766
  });
767
768
}, 'ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately');
769
770
promise_test(t => {
771
772
  const randomSource = new RandomPushSource(8);
773
774
  const rs = new ReadableStream({
775
    start(c) {
776
      assert_equals(typeof c, 'object', 'c should be an object in start');
777
      assert_equals(typeof c.enqueue, 'function', 'enqueue should be a function in start');
778
      assert_equals(typeof c.close, 'function', 'close should be a function in start');
779
      assert_equals(typeof c.error, 'function', 'error should be a function in start');
780
781
      randomSource.ondata = t.step_func(chunk => {
782
        if (!c.enqueue(chunk) <= 0) {
783
          randomSource.readStop();
784
        }
785
      });
786
787
      randomSource.onend = c.close.bind(c);
788
      randomSource.onerror = c.error.bind(c);
789
    },
790
791
    pull(c) {
792
      assert_equals(typeof c, 'object', 'c should be an object in pull');
793
      assert_equals(typeof c.enqueue, 'function', 'enqueue should be a function in pull');
794
      assert_equals(typeof c.close, 'function', 'close should be a function in pull');
795
796
      randomSource.readStart();
797
    }
798
  });
799
800
  return readableStreamToArray(rs).then(chunks => {
801
    assert_equals(chunks.length, 8, '8 chunks should be read');
802
    for (const chunk of chunks) {
803
      assert_equals(chunk.length, 128, 'chunk should have 128 bytes');
804
    }
805
  });
806
807
}, 'ReadableStream integration test: adapting a random push source');
808
809
promise_test(() => {
810
811
  const rs = sequentialReadableStream(10);
812
813
  return readableStreamToArray(rs).then(chunks => {
814
    assert_true(rs.source.closed, 'source should be closed after all chunks are read');
815
    assert_array_equals(chunks, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'the expected 10 chunks should be read');
816
  });
817
818
}, 'ReadableStream integration test: adapting a sync pull source');
819
820
promise_test(() => {
821
822
  const rs = sequentialReadableStream(10, { async: true });
823
824
  return readableStreamToArray(rs).then(chunks => {
825
    assert_true(rs.source.closed, 'source should be closed after all chunks are read');
826
    assert_array_equals(chunks, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'the expected 10 chunks should be read');
827
  });
828
829
}, 'ReadableStream integration test: adapting an async pull source');
830
831
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/pipe-through-expected.txt -14 lines
Lines 1-14 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/pipe-through-expected.txt_sec1
1
2
PASS ReadableStream.prototype.pipeThrough should work generically on its this and its arguments 
3
PASS ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object 
4
PASS ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method 
5
PASS ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable 
6
PASS ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options 
7
FAIL Load pipe-through.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
8
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
9
PASS ReadableStream.prototype.pipeThrough should work generically on its this and its arguments 
10
PASS ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object 
11
PASS ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method 
12
PASS ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable 
13
PASS ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options 
14
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/pipe-through.html -13 lines
Lines 1-13 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/pipe-through.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="pipe-through.js"></script>
10
<script>
11
'use strict';
12
worker_test('pipe-through.js');
13
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/pipe-through.js -108 lines
Lines 1-108 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/pipe-through.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
test(() => {
9
10
  let pipeToArguments;
11
  const thisValue = {
12
    pipeTo() {
13
      pipeToArguments = arguments;
14
    }
15
  };
16
17
  const input = { readable: {}, writable: {} };
18
  const options = {};
19
  const result = ReadableStream.prototype.pipeThrough.call(thisValue, input, options);
20
21
  assert_array_equals(pipeToArguments, [input.writable, options],
22
    'correct arguments should be passed to thisValue.pipeTo');
23
  assert_equals(result, input.readable, 'return value should be the passed readable property');
24
25
}, 'ReadableStream.prototype.pipeThrough should work generically on its this and its arguments');
26
27
test(() => {
28
29
  const thisValue = {
30
    pipeTo() {
31
      assert_unreached('pipeTo should not be called');
32
    }
33
  };
34
35
  methodThrows(ReadableStream.prototype, 'pipeThrough', thisValue, [undefined, {}]);
36
  methodThrows(ReadableStream.prototype, 'pipeThrough', thisValue, [null, {}]);
37
38
}, 'ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object');
39
40
test(() => {
41
42
  const args = [{ readable: {}, writable: {} }, {}];
43
44
  methodThrows(ReadableStream.prototype, 'pipeThrough', undefined, args);
45
  methodThrows(ReadableStream.prototype, 'pipeThrough', null, args);
46
  methodThrows(ReadableStream.prototype, 'pipeThrough', 1, args);
47
  methodThrows(ReadableStream.prototype, 'pipeThrough', { pipeTo: 'test' }, args);
48
49
}, 'ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method');
50
51
test(() => {
52
  const error = new Error('potato');
53
54
  const throwingPipeTo = {
55
    get pipeTo() {
56
      throw error;
57
    }
58
  };
59
  assert_throws(error,
60
    () => ReadableStream.prototype.pipeThrough.call(throwingPipeTo, { readable: { }, writable: { } }, {}),
61
    'pipeThrough should rethrow the error thrown by pipeTo');
62
63
  const thisValue = {
64
    pipeTo() {
65
      assert_unreached('pipeTo should not be called');
66
    }
67
  };
68
69
  const throwingWritable = {
70
    readable: {},
71
    get writable() {
72
      throw error;
73
    }
74
  };
75
  assert_throws(error,
76
    () => ReadableStream.prototype.pipeThrough.call(thisValue, throwingWritable, {}),
77
    'pipeThrough should rethrow the error thrown by the writable getter');
78
79
  const throwingReadable = {
80
    get readable() {
81
      throw error;
82
    },
83
    writable: {}
84
  };
85
  assert_throws(error,
86
    () => ReadableStream.prototype.pipeThrough.call(thisValue, throwingReadable, {}),
87
    'pipeThrough should rethrow the error thrown by the readable getter');
88
89
}, 'ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable');
90
91
test(() => {
92
93
  let count = 0;
94
  const thisValue = {
95
    pipeTo() {
96
      ++count;
97
    }
98
  };
99
100
  ReadableStream.prototype.pipeThrough.call(thisValue, { readable: {}, writable: {} });
101
  ReadableStream.prototype.pipeThrough.call(thisValue, { readable: {} }, {});
102
  ReadableStream.prototype.pipeThrough.call(thisValue, { writable: {} }, {});
103
104
  assert_equals(count, 3, 'pipeTo was called 3 times');
105
106
}, 'ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options');
107
108
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/readable-stream-reader-expected.txt -56 lines
Lines 1-56 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/readable-stream-reader-expected.txt_sec1
1
2
PASS Can get the ReadableStreamReader constructor indirectly 
3
PASS ReadableStreamReader constructor should get a ReadableStream object as argument 
4
FAIL ReadableStreamReader instances should have the correct list of properties assert_equals: method should be non-enumerable expected false but got true
5
PASS ReadableStreamReader closed should always return the same promise object 
6
PASS Constructing a ReadableStreamReader directly should fail if the stream is already locked (via direct construction) 
7
PASS Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via direct construction) 
8
PASS Constructing a ReadableStreamReader directly should fail if the stream is already locked (via getReader) 
9
PASS Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via getReader) 
10
PASS Constructing a ReadableStreamReader directly should be OK if the stream is closed 
11
PASS Constructing a ReadableStreamReader directly should be OK if the stream is errored 
12
PASS Reading from a reader for an empty stream will wait until a chunk is available 
13
PASS cancel() on a reader does not release the reader 
14
PASS closed should be fulfilled after stream is closed (.closed access before acquiring) 
15
PASS closed should be rejected after reader releases its lock (multiple stream locks) 
16
PASS Multiple readers can access the stream in sequence 
17
PASS Cannot use an already-released reader to unlock a stream again 
18
PASS cancel() on a released reader is a no-op and does not pass through 
19
PASS Getting a second reader after erroring the stream and releasing the reader should succeed 
20
PASS ReadableStreamReader closed promise should be rejected with undefined if that is the error 
21
PASS ReadableStreamReader: if start rejects with no parameter, it should error the stream with an undefined error 
22
PASS Erroring a ReadableStream after checking closed should reject ReadableStreamReader closed promise 
23
PASS Erroring a ReadableStream before checking closed should reject ReadableStreamReader closed promise 
24
PASS Reading twice on a stream that gets closed 
25
PASS Reading twice on a closed stream 
26
PASS Reading twice on an errored stream 
27
PASS Reading twice on a stream that gets errored 
28
FAIL Load readable-stream-reader.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
29
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
30
PASS Can get the ReadableStreamReader constructor indirectly 
31
PASS ReadableStreamReader constructor should get a ReadableStream object as argument 
32
FAIL ReadableStreamReader instances should have the correct list of properties assert_equals: method should be non-enumerable expected false but got true
33
PASS ReadableStreamReader closed should always return the same promise object 
34
PASS Constructing a ReadableStreamReader directly should fail if the stream is already locked (via direct construction) 
35
PASS Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via direct construction) 
36
PASS Constructing a ReadableStreamReader directly should fail if the stream is already locked (via getReader) 
37
PASS Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via getReader) 
38
PASS Constructing a ReadableStreamReader directly should be OK if the stream is closed 
39
PASS Constructing a ReadableStreamReader directly should be OK if the stream is errored 
40
PASS Reading from a reader for an empty stream will wait until a chunk is available 
41
PASS cancel() on a reader does not release the reader 
42
PASS closed should be fulfilled after stream is closed (.closed access before acquiring) 
43
PASS closed should be rejected after reader releases its lock (multiple stream locks) 
44
PASS Multiple readers can access the stream in sequence 
45
PASS Cannot use an already-released reader to unlock a stream again 
46
PASS cancel() on a released reader is a no-op and does not pass through 
47
PASS Getting a second reader after erroring the stream and releasing the reader should succeed 
48
PASS ReadableStreamReader closed promise should be rejected with undefined if that is the error 
49
PASS ReadableStreamReader: if start rejects with no parameter, it should error the stream with an undefined error 
50
PASS Erroring a ReadableStream after checking closed should reject ReadableStreamReader closed promise 
51
PASS Erroring a ReadableStream before checking closed should reject ReadableStreamReader closed promise 
52
PASS Reading twice on a stream that gets closed 
53
PASS Reading twice on a closed stream 
54
PASS Reading twice on an errored stream 
55
PASS Reading twice on a stream that gets errored 
56
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/readable-stream-reader.html -12 lines
Lines 1-12 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/readable-stream-reader.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="readable-stream-reader.js"></script>
9
<script>
10
'use strict';
11
worker_test('readable-stream-reader.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/readable-stream-reader.js -485 lines
Lines 1-485 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/readable-stream-reader.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/rs-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
let ReadableStreamReader;
9
10
test(() => {
11
12
  // It's not exposed globally, but we test a few of its properties here.
13
  ReadableStreamReader = (new ReadableStream()).getReader().constructor;
14
15
}, 'Can get the ReadableStreamReader constructor indirectly');
16
17
test(() => {
18
19
  assert_throws(new TypeError(), () => new ReadableStreamReader('potato'));
20
  assert_throws(new TypeError(), () => new ReadableStreamReader({}));
21
  assert_throws(new TypeError(), () => new ReadableStreamReader());
22
23
}, 'ReadableStreamReader constructor should get a ReadableStream object as argument');
24
25
test(() => {
26
27
  const methods = ['cancel', 'constructor', 'read', 'releaseLock'];
28
  const properties = methods.concat(['closed']).sort();
29
30
  const rsReader = new ReadableStreamReader(new ReadableStream());
31
  const proto = Object.getPrototypeOf(rsReader);
32
33
  assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties);
34
35
  for (const m of methods) {
36
    const propDesc = Object.getOwnPropertyDescriptor(proto, m);
37
    assert_equals(propDesc.enumerable, false, 'method should be non-enumerable');
38
    assert_equals(propDesc.configurable, true, 'method should be configurable');
39
    assert_equals(propDesc.writable, true, 'method should be writable');
40
    assert_equals(typeof rsReader[m], 'function', 'should have be a method');
41
  }
42
43
  const closedPropDesc = Object.getOwnPropertyDescriptor(proto, 'closed');
44
  assert_equals(closedPropDesc.enumerable, false, 'closed should be non-enumerable');
45
  assert_equals(closedPropDesc.configurable, true, 'closed should be configurable');
46
  assert_not_equals(closedPropDesc.get, undefined, 'closed should have a getter');
47
  assert_equals(closedPropDesc.set, undefined, 'closed should not have a setter');
48
49
  assert_equals(rsReader.cancel.length, 1, 'cancel has 1 parameter');
50
  assert_not_equals(rsReader.closed, undefined, 'has a non-undefined closed property');
51
  assert_equals(typeof rsReader.closed.then, 'function', 'closed property is thenable');
52
  assert_equals(typeof rsReader.constructor, 'function', 'has a constructor method');
53
  assert_equals(rsReader.constructor.length, 1, 'constructor has 1 parameter');
54
  assert_equals(typeof rsReader.read, 'function', 'has a getReader method');
55
  assert_equals(rsReader.read.length, 0, 'read has no parameters');
56
  assert_equals(typeof rsReader.releaseLock, 'function', 'has a releaseLock method');
57
  assert_equals(rsReader.releaseLock.length, 0, 'releaseLock has no parameters');
58
59
}, 'ReadableStreamReader instances should have the correct list of properties');
60
61
test(() => {
62
63
  const rsReader = new ReadableStreamReader(new ReadableStream());
64
  assert_equals(rsReader.closed, rsReader.closed, 'closed should return the same promise');
65
66
}, 'ReadableStreamReader closed should always return the same promise object');
67
68
test(() => {
69
70
  const rs = new ReadableStream();
71
  new ReadableStreamReader(rs); // Constructing directly the first time should be fine.
72
  assert_throws(new TypeError(), () => new ReadableStreamReader(rs),
73
                'constructing directly the second time should fail');
74
75
}, 'Constructing a ReadableStreamReader directly should fail if the stream is already locked (via direct ' +
76
   'construction)');
77
78
test(() => {
79
80
  const rs = new ReadableStream();
81
  new ReadableStreamReader(rs); // Constructing directly should be fine.
82
  assert_throws(new TypeError(), () => rs.getReader(), 'getReader() should fail');
83
84
}, 'Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via direct ' +
85
   'construction)');
86
87
test(() => {
88
89
  const rs = new ReadableStream();
90
  rs.getReader(); // getReader() should be fine.
91
  assert_throws(new TypeError(), () => new ReadableStreamReader(rs), 'constructing directly should fail');
92
93
}, 'Constructing a ReadableStreamReader directly should fail if the stream is already locked (via getReader)');
94
95
test(() => {
96
97
  const rs = new ReadableStream();
98
  rs.getReader(); // getReader() should be fine.
99
  assert_throws(new TypeError(), () => rs.getReader(), 'getReader() should fail');
100
101
}, 'Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via getReader)');
102
103
test(() => {
104
105
  const rs = new ReadableStream({
106
    start(c) {
107
      c.close();
108
    }
109
  });
110
111
  new ReadableStreamReader(rs); // Constructing directly should not throw.
112
113
}, 'Constructing a ReadableStreamReader directly should be OK if the stream is closed');
114
115
test(() => {
116
117
  const theError = new Error('don\'t say i didn\'t warn ya');
118
  const rs = new ReadableStream({
119
    start(c) {
120
      c.error(theError);
121
    }
122
  });
123
124
  new ReadableStreamReader(rs); // Constructing directly should not throw.
125
126
}, 'Constructing a ReadableStreamReader directly should be OK if the stream is errored');
127
128
promise_test(() => {
129
130
  let controller;
131
  const rs = new ReadableStream({
132
    start(c) {
133
      controller = c;
134
    }
135
  });
136
  const reader = rs.getReader();
137
138
  const promise = reader.read().then(result => {
139
    assert_object_equals(result, { value: 'a', done: false }, 'read() should fulfill with the enqueued chunk');
140
  });
141
142
  controller.enqueue('a');
143
  return promise;
144
145
}, 'Reading from a reader for an empty stream will wait until a chunk is available');
146
147
promise_test(() => {
148
149
  let cancelCalled = false;
150
  const passedReason = new Error('it wasn\'t the right time, sorry');
151
  const rs = new ReadableStream({
152
    cancel(reason) {
153
      assert_true(rs.locked, 'the stream should still be locked');
154
      assert_throws(new TypeError(), () => rs.getReader(), 'should not be able to get another reader');
155
      assert_equals(reason, passedReason, 'the cancellation reason is passed through to the underlying source');
156
      cancelCalled = true;
157
    }
158
  });
159
160
  const reader = rs.getReader();
161
  return reader.cancel(passedReason).then(() => assert_true(cancelCalled));
162
163
}, 'cancel() on a reader does not release the reader');
164
165
promise_test(() => {
166
167
  let controller;
168
  const rs = new ReadableStream({
169
    start(c) {
170
      controller = c;
171
    }
172
  });
173
174
  const reader = rs.getReader();
175
  const promise = reader.closed;
176
177
  controller.close();
178
  return promise;
179
180
}, 'closed should be fulfilled after stream is closed (.closed access before acquiring)');
181
182
promise_test(t => {
183
184
  let controller;
185
  const rs = new ReadableStream({
186
    start(c) {
187
      controller = c;
188
    }
189
  });
190
191
  const reader1 = rs.getReader();
192
193
  reader1.releaseLock();
194
195
  const reader2 = rs.getReader();
196
  controller.close();
197
198
  return Promise.all([
199
    promise_rejects(t, new TypeError(), reader1.closed),
200
    reader2.closed
201
  ]);
202
203
}, 'closed should be rejected after reader releases its lock (multiple stream locks)');
204
205
promise_test(() => {
206
207
  const rs = new ReadableStream({
208
    start(c) {
209
      c.enqueue('a');
210
      c.enqueue('b');
211
      c.close();
212
    }
213
  });
214
215
  const reader1 = rs.getReader();
216
  const promise1 = reader1.read().then(r => {
217
    assert_object_equals(r, { value: 'a', done: false }, 'reading the first chunk from reader1 works');
218
  });
219
  reader1.releaseLock();
220
221
  const reader2 = rs.getReader();
222
  const promise2 = reader2.read().then(r => {
223
    assert_object_equals(r, { value: 'b', done: false }, 'reading the second chunk from reader2 works');
224
  });
225
  reader2.releaseLock();
226
227
  return Promise.all([promise1, promise2]);
228
229
}, 'Multiple readers can access the stream in sequence');
230
231
promise_test(() => {
232
  const rs = new ReadableStream({
233
    start(c) {
234
      c.enqueue('a');
235
    }
236
  });
237
238
  const reader1 = rs.getReader();
239
  reader1.releaseLock();
240
241
  const reader2 = rs.getReader();
242
243
  // Should be a no-op
244
  reader1.releaseLock();
245
246
  return reader2.read().then(result => {
247
    assert_object_equals(result, { value: 'a', done: false },
248
                         'read() should still work on reader2 even after reader1 is released');
249
  });
250
251
}, 'Cannot use an already-released reader to unlock a stream again');
252
253
promise_test(t => {
254
255
  const rs = new ReadableStream({
256
    start(c) {
257
      c.enqueue('a');
258
    },
259
    cancel() {
260
      assert_unreached('underlying source cancel should not be called');
261
    }
262
  });
263
264
  const reader = rs.getReader();
265
  reader.releaseLock();
266
  const cancelPromise = reader.cancel();
267
268
  const reader2 = rs.getReader();
269
  const readPromise = reader2.read().then(r => {
270
    assert_object_equals(r, { value: 'a', done: false }, 'a new reader should be able to read a chunk');
271
  });
272
273
  return Promise.all([
274
    promise_rejects(t, new TypeError(), cancelPromise),
275
    readPromise
276
  ]);
277
278
}, 'cancel() on a released reader is a no-op and does not pass through');
279
280
promise_test(t => {
281
282
  const promiseAsserts = [];
283
284
  let controller;
285
  const theError = { name: 'unique error' };
286
  const rs = new ReadableStream({
287
    start(c) {
288
      controller = c;
289
    }
290
  });
291
292
  const reader1 = rs.getReader();
293
294
  promiseAsserts.push(
295
    promise_rejects(t, theError, reader1.closed),
296
    promise_rejects(t, theError, reader1.read())
297
  );
298
299
  assert_throws(new TypeError(), () => rs.getReader(), 'trying to get another reader before erroring should throw');
300
301
  controller.error(theError);
302
303
  reader1.releaseLock();
304
305
  const reader2 = rs.getReader();
306
307
  promiseAsserts.push(
308
    promise_rejects(t, theError, reader2.closed),
309
    promise_rejects(t, theError, reader2.read())
310
  );
311
312
  return Promise.all(promiseAsserts);
313
314
}, 'Getting a second reader after erroring the stream and releasing the reader should succeed');
315
316
promise_test(t => {
317
318
  let controller;
319
  const rs = new ReadableStream({
320
    start(c) {
321
      controller = c;
322
    }
323
  });
324
325
  const promise = rs.getReader().closed.then(
326
    t.unreached_func('closed promise should not be fulfilled when stream is errored'),
327
    err => {
328
      assert_equals(err, undefined, 'passed error should be undefined as it was');
329
    }
330
  );
331
332
  controller.error();
333
  return promise;
334
335
}, 'ReadableStreamReader closed promise should be rejected with undefined if that is the error');
336
337
338
promise_test(t => {
339
340
  const rs = new ReadableStream({
341
    start() {
342
      return Promise.reject();
343
    }
344
  });
345
346
  return rs.getReader().read().then(
347
    t.unreached_func('read promise should not be fulfilled when stream is errored'),
348
    err => {
349
      assert_equals(err, undefined, 'passed error should be undefined as it was');
350
    }
351
  );
352
353
}, 'ReadableStreamReader: if start rejects with no parameter, it should error the stream with an undefined error');
354
355
promise_test(t => {
356
357
  const theError = { name: 'unique string' };
358
  let controller;
359
  const rs = new ReadableStream({
360
    start(c) {
361
      controller = c;
362
    }
363
  });
364
365
  const promise = promise_rejects(t, theError, rs.getReader().closed);
366
367
  controller.error(theError);
368
  return promise;
369
370
}, 'Erroring a ReadableStream after checking closed should reject ReadableStreamReader closed promise');
371
372
promise_test(t => {
373
374
  const theError = { name: 'unique string' };
375
  let controller;
376
  const rs = new ReadableStream({
377
    start(c) {
378
      controller = c;
379
    }
380
  });
381
382
  controller.error(theError);
383
384
  // Let's call getReader twice for extra test coverage of this code path.
385
  rs.getReader().releaseLock();
386
387
  return promise_rejects(t, theError, rs.getReader().closed);
388
389
}, 'Erroring a ReadableStream before checking closed should reject ReadableStreamReader closed promise');
390
391
promise_test(() => {
392
393
  let controller;
394
  const rs = new ReadableStream({
395
    start(c) {
396
      controller = c;
397
    }
398
  });
399
  const reader = rs.getReader();
400
401
  const promise = Promise.all([
402
    reader.read().then(result => {
403
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (1)');
404
    }),
405
    reader.read().then(result => {
406
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (2)');
407
    }),
408
    reader.closed
409
  ]);
410
411
  controller.close();
412
  return promise;
413
414
}, 'Reading twice on a stream that gets closed');
415
416
promise_test(() => {
417
418
  let controller;
419
  const rs = new ReadableStream({
420
    start(c) {
421
      controller = c;
422
    }
423
  });
424
425
  controller.close();
426
  const reader = rs.getReader();
427
428
  return Promise.all([
429
    reader.read().then(result => {
430
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (1)');
431
    }),
432
    reader.read().then(result => {
433
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (2)');
434
    }),
435
    reader.closed
436
  ]);
437
438
}, 'Reading twice on a closed stream');
439
440
promise_test(t => {
441
442
  let controller;
443
  const rs = new ReadableStream({
444
    start(c) {
445
      controller = c;
446
    }
447
  });
448
449
  const myError = { name: 'mashed potatoes' };
450
  controller.error(myError);
451
452
  const reader = rs.getReader();
453
454
  return Promise.all([
455
    promise_rejects(t, myError, reader.read()),
456
    promise_rejects(t, myError, reader.read()),
457
    promise_rejects(t, myError, reader.closed)
458
  ]);
459
460
}, 'Reading twice on an errored stream');
461
462
promise_test(t => {
463
464
  let controller;
465
  const rs = new ReadableStream({
466
    start(c) {
467
      controller = c;
468
    }
469
  });
470
471
  const myError = { name: 'mashed potatoes' };
472
  const reader = rs.getReader();
473
474
  const promise = Promise.all([
475
    promise_rejects(t, myError, reader.read()),
476
    promise_rejects(t, myError, reader.read()),
477
    promise_rejects(t, myError, reader.closed)
478
  ]);
479
480
  controller.error(myError);
481
  return promise;
482
483
}, 'Reading twice on a stream that gets errored');
484
485
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/tee-expected.txt -24 lines
Lines 1-24 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/tee-expected.txt_sec1
1
2
PASS ReadableStream teeing: rs.tee() returns an array of two ReadableStreams 
3
PASS ReadableStream teeing: should be able to read one branch to the end without affecting the other 
4
PASS ReadableStream teeing: values should be equal across each branch 
5
PASS ReadableStream teeing: errors in the source should propagate to both branches 
6
PASS ReadableStream teeing: canceling branch1 should not impact branch2 
7
PASS ReadableStream teeing: canceling branch2 should not impact branch2 
8
PASS ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array 
9
PASS ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches 
10
PASS ReadableStream teeing: closing the original should immediately close the branches 
11
PASS ReadableStream teeing: erroring the original should immediately error the branches 
12
FAIL Load tee.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
13
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
14
PASS ReadableStream teeing: rs.tee() returns an array of two ReadableStreams 
15
PASS ReadableStream teeing: should be able to read one branch to the end without affecting the other 
16
PASS ReadableStream teeing: values should be equal across each branch 
17
PASS ReadableStream teeing: errors in the source should propagate to both branches 
18
PASS ReadableStream teeing: canceling branch1 should not impact branch2 
19
PASS ReadableStream teeing: canceling branch2 should not impact branch2 
20
PASS ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array 
21
PASS ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches 
22
PASS ReadableStream teeing: closing the original should immediately close the branches 
23
PASS ReadableStream teeing: erroring the original should immediately error the branches 
24
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/tee.html -13 lines
Lines 1-13 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/tee.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/rs-utils.js"></script>
9
<script src="tee.js"></script>
10
<script>
11
'use strict';
12
worker_test('tee.js');
13
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/tee.js -254 lines
Lines 1-254 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/tee.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/rs-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
test(() => {
9
10
  const rs = new ReadableStream();
11
  const result = rs.tee();
12
13
  assert_true(Array.isArray(result), 'return value should be an array');
14
  assert_equals(result.length, 2, 'array should have length 2');
15
  assert_equals(result[0].constructor, ReadableStream, '0th element should be a ReadableStream');
16
  assert_equals(result[1].constructor, ReadableStream, '1st element should be a ReadableStream');
17
18
}, 'ReadableStream teeing: rs.tee() returns an array of two ReadableStreams');
19
20
promise_test(t => {
21
22
  const rs = new ReadableStream({
23
    start(c) {
24
      c.enqueue('a');
25
      c.enqueue('b');
26
      c.close();
27
    }
28
  });
29
30
  const branch = rs.tee();
31
  const branch1 = branch[0];
32
  const branch2 = branch[1];
33
  const reader1 = branch1.getReader();
34
  const reader2 = branch2.getReader();
35
36
  reader2.closed.then(t.unreached_func('branch2 should not be closed'));
37
38
  return Promise.all([
39
    reader1.closed,
40
    reader1.read().then(r => {
41
      assert_object_equals(r, { value: 'a', done: false }, 'first chunk from branch1 should be correct');
42
    }),
43
    reader1.read().then(r => {
44
      assert_object_equals(r, { value: 'b', done: false }, 'second chunk from branch1 should be correct');
45
    }),
46
    reader1.read().then(r => {
47
      assert_object_equals(r, { value: undefined, done: true }, 'third read() from branch1 should be done');
48
    }),
49
    reader2.read().then(r => {
50
      assert_object_equals(r, { value: 'a', done: false }, 'first chunk from branch2 should be correct');
51
    })
52
  ]);
53
54
}, 'ReadableStream teeing: should be able to read one branch to the end without affecting the other');
55
56
promise_test(() => {
57
58
  const theObject = { the: 'test object' };
59
  const rs = new ReadableStream({
60
    start(c) {
61
      c.enqueue(theObject);
62
    }
63
  });
64
65
  const branch = rs.tee();
66
  const branch1 = branch[0];
67
  const branch2 = branch[1];
68
  const reader1 = branch1.getReader();
69
  const reader2 = branch2.getReader();
70
71
  return Promise.all([reader1.read(), reader2.read()]).then(values => {
72
    assert_object_equals(values[0], values[1], 'the values should be equal');
73
  });
74
75
}, 'ReadableStream teeing: values should be equal across each branch');
76
77
promise_test(t => {
78
79
  const theError = { name: 'boo!' };
80
  const rs = new ReadableStream({
81
    start(c) {
82
      c.enqueue('a');
83
      c.enqueue('b');
84
    },
85
    pull() {
86
      throw theError;
87
    }
88
  });
89
90
  const branches = rs.tee();
91
  const reader1 = branches[0].getReader();
92
  const reader2 = branches[1].getReader();
93
94
  reader1.label = 'reader1';
95
  reader2.label = 'reader2';
96
97
  return Promise.all([
98
    promise_rejects(t, theError, reader1.closed),
99
    promise_rejects(t, theError, reader2.closed),
100
    reader1.read().then(r => {
101
      assert_object_equals(r, { value: 'a', done: false }, 'should be able to read the first chunk in branch1');
102
    }),
103
    reader1.read().then(r => {
104
      assert_object_equals(r, { value: 'b', done: false }, 'should be able to read the second chunk in branch1');
105
106
      return promise_rejects(t, theError, reader2.read());
107
    })
108
    .then(() => promise_rejects(t, theError, reader1.read()))
109
  ]);
110
111
}, 'ReadableStream teeing: errors in the source should propagate to both branches');
112
113
promise_test(() => {
114
115
  const rs = new ReadableStream({
116
    start(c) {
117
      c.enqueue('a');
118
      c.enqueue('b');
119
      c.close();
120
    }
121
  });
122
123
  const branches = rs.tee();
124
  const branch1 = branches[0];
125
  const branch2 = branches[1];
126
  branch1.cancel();
127
128
  return Promise.all([
129
    readableStreamToArray(branch1).then(chunks => {
130
      assert_array_equals(chunks, [], 'branch1 should have no chunks');
131
    }),
132
    readableStreamToArray(branch2).then(chunks => {
133
      assert_array_equals(chunks, ['a', 'b'], 'branch2 should have two chunks');
134
    })
135
  ]);
136
137
}, 'ReadableStream teeing: canceling branch1 should not impact branch2');
138
139
promise_test(() => {
140
141
  const rs = new ReadableStream({
142
    start(c) {
143
      c.enqueue('a');
144
      c.enqueue('b');
145
      c.close();
146
    }
147
  });
148
149
  const branches = rs.tee();
150
  const branch1 = branches[0];
151
  const branch2 = branches[1];
152
  branch2.cancel();
153
154
  return Promise.all([
155
    readableStreamToArray(branch1).then(chunks => {
156
      assert_array_equals(chunks, ['a', 'b'], 'branch1 should have two chunks');
157
    }),
158
    readableStreamToArray(branch2).then(chunks => {
159
      assert_array_equals(chunks, [], 'branch2 should have no chunks');
160
    })
161
  ]);
162
163
}, 'ReadableStream teeing: canceling branch2 should not impact branch2');
164
165
promise_test(() => {
166
167
  const reason1 = new Error('We\'re wanted men.');
168
  const reason2 = new Error('I have the death sentence on twelve systems.');
169
170
  let resolve;
171
  const promise = new Promise(r => resolve = r);
172
  const rs = new ReadableStream({
173
    cancel(reason) {
174
      assert_array_equals(reason, [reason1, reason2],
175
                          'the cancel reason should be an array containing those from the branches');
176
      resolve();
177
    }
178
  });
179
180
  const branch = rs.tee();
181
  const branch1 = branch[0];
182
  const branch2 = branch[1];
183
  branch1.cancel(reason1);
184
  branch2.cancel(reason2);
185
186
  return promise;
187
188
}, 'ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array');
189
190
promise_test(t => {
191
192
  const theError = { name: 'I\'ll be careful.' };
193
  const rs = new ReadableStream({
194
    cancel() {
195
      throw theError;
196
    }
197
  });
198
199
  const branch = rs.tee();
200
  const branch1 = branch[0];
201
  const branch2 = branch[1];
202
203
  return Promise.all([
204
    promise_rejects(t, theError, branch1.cancel()),
205
    promise_rejects(t, theError, branch2.cancel())
206
  ]);
207
208
}, 'ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches');
209
210
promise_test(() => {
211
212
  let controller;
213
  const rs = new ReadableStream({
214
    start(c) {
215
      controller = c;
216
    }
217
  });
218
219
  const branches = rs.tee();
220
  const reader1 = branches[0].getReader();
221
  const reader2 = branches[1].getReader();
222
223
  const promise = Promise.all([reader1.closed, reader2.closed]);
224
225
  controller.close();
226
  return promise;
227
228
}, 'ReadableStream teeing: closing the original should immediately close the branches');
229
230
promise_test(t => {
231
232
  let controller;
233
  const rs = new ReadableStream({
234
    start(c) {
235
      controller = c;
236
    }
237
  });
238
239
  const branches = rs.tee();
240
  const reader1 = branches[0].getReader();
241
  const reader2 = branches[1].getReader();
242
243
  const theError = { name: 'boo!' };
244
  const promise = Promise.all([
245
    promise_rejects(t, theError, reader1.closed),
246
    promise_rejects(t, theError, reader2.closed)
247
  ]);
248
249
  controller.error(theError);
250
  return promise;
251
252
}, 'ReadableStream teeing: erroring the original should immediately error the branches');
253
254
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/templated-expected.txt -174 lines
Lines 1-174 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/templated-expected.txt_sec1
1
2
PASS Running templatedRSEmpty with ReadableStream (empty) 
3
PASS instances have the correct methods and properties 
4
PASS Running templatedRSEmptyReader with ReadableStream (empty) reader 
5
PASS instances have the correct methods and properties 
6
PASS locked should be true 
7
PASS read() should never settle 
8
PASS two read()s should both never settle 
9
PASS read() should return distinct promises each time 
10
PASS getReader() again on the stream should fail 
11
PASS releasing the lock with pending read requests should throw but the read requests should stay pending 
12
PASS releasing the lock should cause further read() calls to reject with a TypeError 
13
PASS releasing the lock should cause closed calls to reject with a TypeError 
14
PASS releasing the lock should cause locked to become false 
15
PASS canceling via the reader should cause the reader to act closed 
16
PASS canceling via the stream should fail 
17
PASS Running templatedRSClosed with ReadableStream (closed via call in start) 
18
PASS cancel() should return a distinct fulfilled promise each time 
19
PASS locked should be false 
20
PASS getReader() should be OK 
21
PASS should be able to acquire multiple readers if they are released in succession 
22
PASS should not be able to acquire a second reader if we don't release the first one 
23
PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader) 
24
PASS read() should fulfill with { value: undefined, done: true } 
25
PASS read() multiple times should fulfill with { value: undefined, done: true } 
26
PASS read() should work when used within another read() fulfill callback 
27
PASS closed should fulfill with undefined 
28
PASS releasing the lock should cause closed to reject and change identity 
29
PASS cancel() should return a distinct fulfilled promise each time 
30
PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader) 
31
PASS read() should fulfill with { value: undefined, done: true } 
32
PASS read() multiple times should fulfill with { value: undefined, done: true } 
33
PASS read() should work when used within another read() fulfill callback 
34
PASS closed should fulfill with undefined 
35
PASS releasing the lock should cause closed to reject and change identity 
36
PASS cancel() should return a distinct fulfilled promise each time 
37
PASS Running templatedRSClosed with ReadableStream (closed via cancel) 
38
PASS cancel() should return a distinct fulfilled promise each time 
39
PASS locked should be false 
40
PASS getReader() should be OK 
41
PASS should be able to acquire multiple readers if they are released in succession 
42
PASS should not be able to acquire a second reader if we don't release the first one 
43
PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader) 
44
PASS read() should fulfill with { value: undefined, done: true } 
45
PASS read() multiple times should fulfill with { value: undefined, done: true } 
46
PASS read() should work when used within another read() fulfill callback 
47
PASS closed should fulfill with undefined 
48
PASS releasing the lock should cause closed to reject and change identity 
49
PASS cancel() should return a distinct fulfilled promise each time 
50
PASS Running templatedRSErrored with ReadableStream (errored via call in start) 
51
PASS getReader() should return a reader that acts errored 
52
PASS read() twice should give the error each time 
53
PASS locked should be false 
54
PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start) 
55
PASS should be able to obtain a second reader, with the correct closed promise 
56
PASS should not be able to obtain additional readers if we don't release the first lock 
57
PASS cancel() should return a distinct rejected promise each time 
58
PASS reader cancel() should return a distinct rejected promise each time 
59
PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start) 
60
PASS getReader() should return a reader that acts errored 
61
PASS read() twice should give the error each time 
62
PASS locked should be false 
63
PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader 
64
PASS closed should reject with the error 
65
PASS releasing the lock should cause closed to reject and change identity 
66
PASS read() should reject with the error 
67
PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader) 
68
PASS closed should reject with the error 
69
PASS releasing the lock should cause closed to reject and change identity 
70
PASS read() should reject with the error 
71
PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader) 
72
PASS closed should reject with the error 
73
PASS releasing the lock should cause closed to reject and change identity 
74
PASS read() should reject with the error 
75
PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader 
76
PASS calling read() twice without waiting will eventually give both chunks (sequential) 
77
PASS calling read() twice without waiting will eventually give both chunks (nested) 
78
PASS read() should return distinct promises each time 
79
PASS cancel() after a read() should still give that single read result 
80
PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader 
81
PASS third read(), without waiting, should give { value: undefined, done: true } (sequential) 
82
PASS third read(), without waiting, should give { value: undefined, done: true } (nested) 
83
PASS draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true 
84
PASS releasing the lock after the stream is closed should cause locked to become false 
85
PASS releasing the lock should cause further read() calls to reject with a TypeError 
86
PASS reader's closed property always returns the same promise 
87
FAIL Load templated.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
88
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
89
PASS Running templatedRSEmpty with ReadableStream (empty) 
90
PASS instances have the correct methods and properties 
91
PASS Running templatedRSEmptyReader with ReadableStream (empty) reader 
92
PASS instances have the correct methods and properties 
93
PASS locked should be true 
94
PASS read() should never settle 
95
PASS two read()s should both never settle 
96
PASS read() should return distinct promises each time 
97
PASS getReader() again on the stream should fail 
98
PASS releasing the lock with pending read requests should throw but the read requests should stay pending 
99
PASS releasing the lock should cause further read() calls to reject with a TypeError 
100
PASS releasing the lock should cause closed calls to reject with a TypeError 
101
PASS releasing the lock should cause locked to become false 
102
PASS canceling via the reader should cause the reader to act closed 
103
PASS canceling via the stream should fail 
104
PASS Running templatedRSClosed with ReadableStream (closed via call in start) 
105
PASS cancel() should return a distinct fulfilled promise each time 
106
PASS locked should be false 
107
PASS getReader() should be OK 
108
PASS should be able to acquire multiple readers if they are released in succession 
109
PASS should not be able to acquire a second reader if we don't release the first one 
110
PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader) 
111
PASS read() should fulfill with { value: undefined, done: true } 
112
PASS read() multiple times should fulfill with { value: undefined, done: true } 
113
PASS read() should work when used within another read() fulfill callback 
114
PASS closed should fulfill with undefined 
115
PASS releasing the lock should cause closed to reject and change identity 
116
PASS cancel() should return a distinct fulfilled promise each time 
117
PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader) 
118
PASS read() should fulfill with { value: undefined, done: true } 
119
PASS read() multiple times should fulfill with { value: undefined, done: true } 
120
PASS read() should work when used within another read() fulfill callback 
121
PASS closed should fulfill with undefined 
122
PASS releasing the lock should cause closed to reject and change identity 
123
PASS cancel() should return a distinct fulfilled promise each time 
124
PASS Running templatedRSClosed with ReadableStream (closed via cancel) 
125
PASS cancel() should return a distinct fulfilled promise each time 
126
PASS locked should be false 
127
PASS getReader() should be OK 
128
PASS should be able to acquire multiple readers if they are released in succession 
129
PASS should not be able to acquire a second reader if we don't release the first one 
130
PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader) 
131
PASS read() should fulfill with { value: undefined, done: true } 
132
PASS read() multiple times should fulfill with { value: undefined, done: true } 
133
PASS read() should work when used within another read() fulfill callback 
134
PASS closed should fulfill with undefined 
135
PASS releasing the lock should cause closed to reject and change identity 
136
PASS cancel() should return a distinct fulfilled promise each time 
137
PASS Running templatedRSErrored with ReadableStream (errored via call in start) 
138
PASS getReader() should return a reader that acts errored 
139
PASS read() twice should give the error each time 
140
PASS locked should be false 
141
PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start) 
142
PASS should be able to obtain a second reader, with the correct closed promise 
143
PASS should not be able to obtain additional readers if we don't release the first lock 
144
PASS cancel() should return a distinct rejected promise each time 
145
PASS reader cancel() should return a distinct rejected promise each time 
146
PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start) 
147
PASS getReader() should return a reader that acts errored 
148
PASS read() twice should give the error each time 
149
PASS locked should be false 
150
PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader 
151
PASS closed should reject with the error 
152
PASS releasing the lock should cause closed to reject and change identity 
153
PASS read() should reject with the error 
154
PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader) 
155
PASS closed should reject with the error 
156
PASS releasing the lock should cause closed to reject and change identity 
157
PASS read() should reject with the error 
158
PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader) 
159
PASS closed should reject with the error 
160
PASS releasing the lock should cause closed to reject and change identity 
161
PASS read() should reject with the error 
162
PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader 
163
PASS calling read() twice without waiting will eventually give both chunks (sequential) 
164
PASS calling read() twice without waiting will eventually give both chunks (nested) 
165
PASS read() should return distinct promises each time 
166
PASS cancel() after a read() should still give that single read result 
167
PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader 
168
PASS third read(), without waiting, should give { value: undefined, done: true } (sequential) 
169
PASS third read(), without waiting, should give { value: undefined, done: true } (nested) 
170
PASS draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true 
171
PASS releasing the lock after the stream is closed should cause locked to become false 
172
PASS releasing the lock should cause further read() calls to reject with a TypeError 
173
PASS reader's closed property always returns the same promise 
174
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/templated.html -14 lines
Lines 1-14 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/templated.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="../resources/rs-test-templates.js"></script>
10
<script src="templated.js"></script>
11
<script>
12
'use strict';
13
worker_test('templated.js');
14
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/templated.js -148 lines
Lines 1-148 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/readable-streams/templated.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
  self.importScripts('../resources/test-utils.js');
6
  self.importScripts('../resources/rs-test-templates.js');
7
}
8
9
// Run the readable stream test templates against readable streams created directly using the constructor
10
11
const theError = { name: 'boo!' };
12
const chunks = ['a', 'b'];
13
14
templatedRSEmpty('ReadableStream (empty)', () => {
15
  return new ReadableStream();
16
});
17
18
templatedRSEmptyReader('ReadableStream (empty) reader', () => {
19
  return streamAndDefaultReader(new ReadableStream());
20
});
21
22
templatedRSClosed('ReadableStream (closed via call in start)', () => {
23
  return new ReadableStream({
24
    start(c) {
25
      c.close();
26
    }
27
  });
28
});
29
30
templatedRSClosedReader('ReadableStream reader (closed before getting reader)', () => {
31
  let controller;
32
  const stream = new ReadableStream({
33
    start(c) {
34
      controller = c;
35
    }
36
  });
37
  controller.close();
38
  const result = streamAndDefaultReader(stream);
39
  return result;
40
});
41
42
templatedRSClosedReader('ReadableStream reader (closed after getting reader)', () => {
43
  let controller;
44
  const stream = new ReadableStream({
45
    start(c) {
46
      controller = c;
47
    }
48
  });
49
  const result = streamAndDefaultReader(stream);
50
  controller.close();
51
  return result;
52
});
53
54
templatedRSClosed('ReadableStream (closed via cancel)', () => {
55
  const stream = new ReadableStream();
56
  stream.cancel();
57
  return stream;
58
});
59
60
templatedRSClosedReader('ReadableStream reader (closed via cancel after getting reader)', () => {
61
  const stream = new ReadableStream();
62
  const result = streamAndDefaultReader(stream);
63
  result.reader.cancel();
64
  return result;
65
});
66
67
templatedRSErrored('ReadableStream (errored via call in start)', () => {
68
  return new ReadableStream({
69
    start(c) {
70
      c.error(theError);
71
    }
72
  });
73
}, theError);
74
75
templatedRSErroredSyncOnly('ReadableStream (errored via call in start)', () => {
76
  return new ReadableStream({
77
    start(c) {
78
      c.error(theError);
79
    }
80
  });
81
}, theError);
82
83
templatedRSErrored('ReadableStream (errored via returning a rejected promise in start)', () => {
84
  return new ReadableStream({
85
    start() {
86
      return Promise.reject(theError);
87
    }
88
  });
89
}, theError);
90
91
templatedRSErroredReader('ReadableStream (errored via returning a rejected promise in start) reader', () => {
92
  return streamAndDefaultReader(new ReadableStream({
93
    start() {
94
      return Promise.reject(theError);
95
    }
96
  }));
97
}, theError);
98
99
templatedRSErroredReader('ReadableStream reader (errored before getting reader)', () => {
100
  let controller;
101
  const stream = new ReadableStream({
102
    start(c) {
103
      controller = c;
104
    }
105
  });
106
  controller.error(theError);
107
  return streamAndDefaultReader(stream);
108
}, theError);
109
110
templatedRSErroredReader('ReadableStream reader (errored after getting reader)', () => {
111
  let controller;
112
  const result = streamAndDefaultReader(new ReadableStream({
113
    start(c) {
114
      controller = c;
115
    }
116
  }));
117
  controller.error(theError);
118
  return result;
119
}, theError);
120
121
templatedRSTwoChunksOpenReader('ReadableStream (two chunks enqueued, still open) reader', () => {
122
  return streamAndDefaultReader(new ReadableStream({
123
    start(c) {
124
      c.enqueue(chunks[0]);
125
      c.enqueue(chunks[1]);
126
    }
127
  }));
128
}, chunks);
129
130
templatedRSTwoChunksClosedReader('ReadableStream (two chunks enqueued, then closed) reader', () => {
131
  let doClose;
132
  const stream = new ReadableStream({
133
    start(c) {
134
      c.enqueue(chunks[0]);
135
      c.enqueue(chunks[1]);
136
      doClose = c.close.bind(c);
137
    }
138
  });
139
  const result = streamAndDefaultReader(stream);
140
  doClose();
141
  return result;
142
}, chunks);
143
144
function streamAndDefaultReader(stream) {
145
  return { stream, reader: stream.getReader() };
146
}
147
148
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/rs-test-templates.js -624 lines
Lines 1-624 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/rs-test-templates.js_sec1
1
'use strict';
2
3
// These tests can be run against any readable stream produced by the web platform that meets the given descriptions.
4
// For readable stream tests, the factory should return the stream. For reader tests, the factory should return a
5
// { stream, reader } object. (You can use this to vary the time at which you acquire a reader.)
6
7
self.templatedRSEmpty = (label, factory) => {
8
  test(() => {}, 'Running templatedRSEmpty with ' + label);
9
10
  test(() => {
11
12
    const rs = factory();
13
14
    assert_equals(typeof rs.locked, 'boolean', 'has a boolean locked getter');
15
    assert_equals(typeof rs.cancel, 'function', 'has a cancel method');
16
    assert_equals(typeof rs.getReader, 'function', 'has a getReader method');
17
    assert_equals(typeof rs.pipeThrough, 'function', 'has a pipeThrough method');
18
    assert_equals(typeof rs.pipeTo, 'function', 'has a pipeTo method');
19
    assert_equals(typeof rs.tee, 'function', 'has a tee method');
20
21
  }, 'instances have the correct methods and properties');
22
};
23
24
self.templatedRSClosed = (label, factory) => {
25
  test(() => {}, 'Running templatedRSClosed with ' + label);
26
27
  promise_test(() => {
28
29
    const rs = factory();
30
    const cancelPromise1 = rs.cancel();
31
    const cancelPromise2 = rs.cancel();
32
33
    assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should return distinct promises');
34
35
    return Promise.all([
36
      cancelPromise1.then(v => assert_equals(v, undefined, 'first cancel() call should fulfill with undefined')),
37
      cancelPromise2.then(v => assert_equals(v, undefined, 'second cancel() call should fulfill with undefined'))
38
    ]);
39
40
  }, 'cancel() should return a distinct fulfilled promise each time');
41
42
  test(() => {
43
44
    const rs = factory();
45
    assert_false(rs.locked, 'locked getter should return false');
46
47
  }, 'locked should be false');
48
49
  test(() => {
50
51
    const rs = factory();
52
    rs.getReader(); // getReader() should not throw.
53
54
  }, 'getReader() should be OK');
55
56
  test(() => {
57
58
    const rs = factory();
59
60
    const reader = rs.getReader();
61
    reader.releaseLock();
62
63
    const reader2 = rs.getReader(); // Getting a second reader should not throw.
64
    reader2.releaseLock();
65
66
    rs.getReader(); // Getting a third reader should not throw.
67
68
  }, 'should be able to acquire multiple readers if they are released in succession');
69
70
  test(() => {
71
72
    const rs = factory();
73
74
    rs.getReader();
75
76
    assert_throws(new TypeError(), () => rs.getReader(), 'getting a second reader should throw');
77
    assert_throws(new TypeError(), () => rs.getReader(), 'getting a third reader should throw');
78
79
  }, 'should not be able to acquire a second reader if we don\'t release the first one');
80
};
81
82
self.templatedRSErrored = (label, factory, error) => {
83
  test(() => {}, 'Running templatedRSErrored with ' + label);
84
85
  promise_test(t => {
86
87
    const rs = factory();
88
    const reader = rs.getReader();
89
90
    return Promise.all([
91
      promise_rejects(t, error, reader.closed),
92
      promise_rejects(t, error, reader.read())
93
    ]);
94
95
  }, 'getReader() should return a reader that acts errored');
96
97
  promise_test(t => {
98
99
    const rs = factory();
100
    const reader = rs.getReader();
101
102
    return Promise.all([
103
      promise_rejects(t, error, reader.read()),
104
      promise_rejects(t, error, reader.read()),
105
      promise_rejects(t, error, reader.closed)
106
    ]);
107
108
  }, 'read() twice should give the error each time');
109
110
  test(() => {
111
    const rs = factory();
112
113
    assert_false(rs.locked, 'locked getter should return false');
114
  }, 'locked should be false');
115
};
116
117
self.templatedRSErroredSyncOnly = (label, factory, error) => {
118
  test(() => {}, 'Running templatedRSErroredSyncOnly with ' + label);
119
120
  promise_test(t => {
121
122
    const rs = factory();
123
    rs.getReader().releaseLock();
124
    const reader = rs.getReader(); // Calling getReader() twice does not throw (the stream is not locked).
125
126
    return promise_rejects(t, error, reader.closed);
127
128
  }, 'should be able to obtain a second reader, with the correct closed promise');
129
130
  test(() => {
131
132
    const rs = factory();
133
    rs.getReader();
134
135
    assert_throws(new TypeError(), () => rs.getReader(), 'getting a second reader should throw a TypeError');
136
    assert_throws(new TypeError(), () => rs.getReader(), 'getting a third reader should throw a TypeError');
137
138
  }, 'should not be able to obtain additional readers if we don\'t release the first lock');
139
140
  promise_test(t => {
141
142
    const rs = factory();
143
    const cancelPromise1 = rs.cancel();
144
    const cancelPromise2 = rs.cancel();
145
146
    assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should return distinct promises');
147
148
    return Promise.all([
149
      promise_rejects(t, error, cancelPromise1),
150
      promise_rejects(t, error, cancelPromise2)
151
    ]);
152
153
  }, 'cancel() should return a distinct rejected promise each time');
154
155
  promise_test(t => {
156
157
    const rs = factory();
158
    const reader = rs.getReader();
159
    const cancelPromise1 = reader.cancel();
160
    const cancelPromise2 = reader.cancel();
161
162
    assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should return distinct promises');
163
164
    return Promise.all([
165
      promise_rejects(t, error, cancelPromise1),
166
      promise_rejects(t, error, cancelPromise2)
167
    ]);
168
169
  }, 'reader cancel() should return a distinct rejected promise each time');
170
};
171
172
self.templatedRSEmptyReader = (label, factory) => {
173
  test(() => {}, 'Running templatedRSEmptyReader with ' + label);
174
175
  test(() => {
176
177
    const reader = factory().reader;
178
179
    assert_true('closed' in reader, 'has a closed property');
180
    assert_equals(typeof reader.closed.then, 'function', 'closed property is thenable');
181
182
    assert_equals(typeof reader.cancel, 'function', 'has a cancel method');
183
    assert_equals(typeof reader.read, 'function', 'has a read method');
184
    assert_equals(typeof reader.releaseLock, 'function', 'has a releaseLock method');
185
186
  }, 'instances have the correct methods and properties');
187
188
  test(() => {
189
190
    const stream = factory().stream;
191
192
    assert_true(stream.locked, 'locked getter should return true');
193
194
  }, 'locked should be true');
195
196
  promise_test(t => {
197
198
    const reader = factory().reader;
199
200
    reader.read().then(
201
      t.unreached_func('read() should not fulfill'),
202
      t.unreached_func('read() should not reject')
203
    );
204
205
    return delay(500);
206
207
  }, 'read() should never settle');
208
209
  promise_test(t => {
210
211
    const reader = factory().reader;
212
213
    reader.read().then(
214
      t.unreached_func('read() should not fulfill'),
215
      t.unreached_func('read() should not reject')
216
    );
217
218
    reader.read().then(
219
      t.unreached_func('read() should not fulfill'),
220
      t.unreached_func('read() should not reject')
221
    );
222
223
    return delay(500);
224
225
  }, 'two read()s should both never settle');
226
227
  test(() => {
228
229
    const reader = factory().reader;
230
    assert_not_equals(reader.read(), reader.read(), 'the promises returned should be distinct');
231
232
  }, 'read() should return distinct promises each time');
233
234
  test(() => {
235
236
    const stream = factory().stream;
237
    assert_throws(new TypeError(), () => stream.getReader(), 'stream.getReader() should throw a TypeError');
238
239
  }, 'getReader() again on the stream should fail');
240
241
  promise_test(t => {
242
243
    const streamAndReader = factory();
244
    const stream = streamAndReader.stream;
245
    const reader = streamAndReader.reader;
246
247
    reader.read().then(
248
      t.unreached_func('first read() should not fulfill'),
249
      t.unreached_func('first read() should not reject')
250
    );
251
252
    reader.read().then(
253
      t.unreached_func('second read() should not fulfill'),
254
      t.unreached_func('second read() should not reject')
255
    );
256
257
    reader.closed.then(
258
      t.unreached_func('closed should not fulfill'),
259
      t.unreached_func('closed should not reject')
260
    );
261
262
    assert_throws(new TypeError(), () => reader.releaseLock(), 'releaseLock should throw a TypeError');
263
264
    assert_true(stream.locked, 'the stream should still be locked');
265
266
    return delay(500);
267
268
  }, 'releasing the lock with pending read requests should throw but the read requests should stay pending');
269
270
  promise_test(t => {
271
272
    const reader = factory().reader;
273
    reader.releaseLock();
274
275
    return Promise.all([
276
      promise_rejects(t, new TypeError(), reader.read()),
277
      promise_rejects(t, new TypeError(), reader.read())
278
    ]);
279
280
  }, 'releasing the lock should cause further read() calls to reject with a TypeError');
281
282
  promise_test(t => {
283
284
    const reader = factory().reader;
285
286
    const closedBefore = reader.closed;
287
    reader.releaseLock();
288
    const closedAfter = reader.closed;
289
290
    assert_equals(closedBefore, closedAfter, 'the closed promise should not change identity');
291
292
    return promise_rejects(t, new TypeError(), closedBefore);
293
294
  }, 'releasing the lock should cause closed calls to reject with a TypeError');
295
296
  test(() => {
297
298
    const streamAndReader = factory();
299
    const stream = streamAndReader.stream;
300
    const reader = streamAndReader.reader;
301
302
    reader.releaseLock();
303
    assert_false(stream.locked, 'locked getter should return false');
304
305
  }, 'releasing the lock should cause locked to become false');
306
307
  promise_test(() => {
308
309
    const reader = factory().reader;
310
    reader.cancel();
311
312
    return reader.read().then(r => {
313
      assert_object_equals(r, { value: undefined, done: true }, 'read()ing from the reader should give a done result');
314
    });
315
316
  }, 'canceling via the reader should cause the reader to act closed');
317
318
  promise_test(t => {
319
320
    const stream = factory().stream;
321
    return promise_rejects(t, new TypeError(), stream.cancel());
322
323
  }, 'canceling via the stream should fail');
324
};
325
326
self.templatedRSClosedReader = (label, factory) => {
327
  test(() => {}, 'Running templatedRSClosedReader with ' + label);
328
329
  promise_test(() => {
330
331
    const reader = factory().reader;
332
333
    return reader.read().then(v => {
334
      assert_object_equals(v, { value: undefined, done: true }, 'read() should fulfill correctly');
335
    });
336
337
  }, 'read() should fulfill with { value: undefined, done: true }');
338
339
  promise_test(() => {
340
341
    const reader = factory().reader;
342
343
    return Promise.all([
344
      reader.read().then(v => {
345
        assert_object_equals(v, { value: undefined, done: true }, 'read() should fulfill correctly');
346
      }),
347
      reader.read().then(v => {
348
        assert_object_equals(v, { value: undefined, done: true }, 'read() should fulfill correctly');
349
      })
350
    ]);
351
352
  }, 'read() multiple times should fulfill with { value: undefined, done: true }');
353
354
  promise_test(() => {
355
356
    const reader = factory().reader;
357
358
    return reader.read().then(() => reader.read()).then(v => {
359
      assert_object_equals(v, { value: undefined, done: true }, 'read() should fulfill correctly');
360
    });
361
362
  }, 'read() should work when used within another read() fulfill callback');
363
364
  promise_test(() => {
365
366
    const reader = factory().reader;
367
368
    return reader.closed.then(v => assert_equals(v, undefined, 'reader closed should fulfill with undefined'));
369
370
  }, 'closed should fulfill with undefined');
371
372
  promise_test(t => {
373
374
    const reader = factory().reader;
375
376
    const closedBefore = reader.closed;
377
    reader.releaseLock();
378
    const closedAfter = reader.closed;
379
380
    assert_not_equals(closedBefore, closedAfter, 'the closed promise should change identity');
381
382
    return Promise.all([
383
      closedBefore.then(v => assert_equals(v, undefined, 'reader.closed acquired before release should fulfill')),
384
      promise_rejects(t, new TypeError(), closedAfter)
385
    ]);
386
387
  }, 'releasing the lock should cause closed to reject and change identity');
388
389
  promise_test(() => {
390
391
    const reader = factory().reader;
392
    const cancelPromise1 = reader.cancel();
393
    const cancelPromise2 = reader.cancel();
394
    const closedReaderPromise = reader.closed;
395
396
    assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should return distinct promises');
397
    assert_not_equals(cancelPromise1, closedReaderPromise, 'cancel() promise 1 should be distinct from reader.closed');
398
    assert_not_equals(cancelPromise2, closedReaderPromise, 'cancel() promise 2 should be distinct from reader.closed');
399
400
    return Promise.all([
401
      cancelPromise1.then(v => assert_equals(v, undefined, 'first cancel() should fulfill with undefined')),
402
      cancelPromise2.then(v => assert_equals(v, undefined, 'second cancel() should fulfill with undefined'))
403
    ]);
404
405
  }, 'cancel() should return a distinct fulfilled promise each time');
406
};
407
408
self.templatedRSErroredReader = (label, factory, error) => {
409
  test(() => {}, 'Running templatedRSErroredReader with ' + label);
410
411
  promise_test(t => {
412
413
    const reader = factory().reader;
414
    return promise_rejects(t, error, reader.closed);
415
416
  }, 'closed should reject with the error');
417
418
  promise_test(t => {
419
420
    const reader = factory().reader;
421
    const closedBefore = reader.closed;
422
423
    return promise_rejects(t, error, closedBefore).then(() => {
424
      reader.releaseLock();
425
426
      const closedAfter = reader.closed;
427
      assert_not_equals(closedBefore, closedAfter, 'the closed promise should change identity');
428
429
      return promise_rejects(t, new TypeError(), closedAfter);
430
    });
431
432
  }, 'releasing the lock should cause closed to reject and change identity');
433
434
  promise_test(t => {
435
436
    const reader = factory().reader;
437
    return promise_rejects(t, error, reader.read());
438
439
  }, 'read() should reject with the error');
440
};
441
442
self.templatedRSTwoChunksOpenReader = (label, factory, chunks) => {
443
  test(() => {}, 'Running templatedRSTwoChunksOpenReader with ' + label);
444
445
  promise_test(() => {
446
447
    const reader = factory().reader;
448
449
    return Promise.all([
450
      reader.read().then(r => {
451
        assert_object_equals(r, { value: chunks[0], done: false }, 'first result should be correct');
452
      }),
453
      reader.read().then(r => {
454
        assert_object_equals(r, { value: chunks[1], done: false }, 'second result should be correct');
455
      })
456
    ]);
457
458
  }, 'calling read() twice without waiting will eventually give both chunks (sequential)');
459
460
  promise_test(() => {
461
462
    const reader = factory().reader;
463
464
    return reader.read().then(r => {
465
      assert_object_equals(r, { value: chunks[0], done: false }, 'first result should be correct');
466
467
      return reader.read().then(r2 => {
468
        assert_object_equals(r2, { value: chunks[1], done: false }, 'second result should be correct');
469
      });
470
    });
471
472
  }, 'calling read() twice without waiting will eventually give both chunks (nested)');
473
474
  test(() => {
475
476
    const reader = factory().reader;
477
    assert_not_equals(reader.read(), reader.read(), 'the promises returned should be distinct');
478
479
  }, 'read() should return distinct promises each time');
480
481
  promise_test(() => {
482
483
    const reader = factory().reader;
484
485
    const promise1 = reader.closed.then(v => {
486
      assert_equals(v, undefined, 'reader closed should fulfill with undefined');
487
    });
488
489
    const promise2 = reader.read().then(r => {
490
      assert_object_equals(r, { value: chunks[0], done: false },
491
                           'promise returned before cancellation should fulfill with a chunk');
492
    });
493
494
    reader.cancel();
495
496
    const promise3 = reader.read().then(r => {
497
      assert_object_equals(r, { value: undefined, done: true },
498
                           'promise returned after cancellation should fulfill with an end-of-stream signal');
499
    });
500
501
    return Promise.all([promise1, promise2, promise3]);
502
503
  }, 'cancel() after a read() should still give that single read result');
504
};
505
506
self.templatedRSTwoChunksClosedReader = function (label, factory, chunks) {
507
  test(() => {}, 'Running templatedRSTwoChunksClosedReader with ' + label);
508
509
  promise_test(() => {
510
511
    const reader = factory().reader;
512
513
    return Promise.all([
514
      reader.read().then(r => {
515
        assert_object_equals(r, { value: chunks[0], done: false }, 'first result should be correct');
516
      }),
517
      reader.read().then(r => {
518
        assert_object_equals(r, { value: chunks[1], done: false }, 'second result should be correct');
519
      }),
520
      reader.read().then(r => {
521
        assert_object_equals(r, { value: undefined, done: true }, 'third result should be correct');
522
      })
523
    ]);
524
525
  }, 'third read(), without waiting, should give { value: undefined, done: true } (sequential)');
526
527
  promise_test(() => {
528
529
    const reader = factory().reader;
530
531
    return reader.read().then(r => {
532
      assert_object_equals(r, { value: chunks[0], done: false }, 'first result should be correct');
533
534
      return reader.read().then(r2 => {
535
        assert_object_equals(r2, { value: chunks[1], done: false }, 'second result should be correct');
536
537
        return reader.read().then(r3 => {
538
          assert_object_equals(r3, { value: undefined, done: true }, 'third result should be correct');
539
        });
540
      });
541
    });
542
543
  }, 'third read(), without waiting, should give { value: undefined, done: true } (nested)');
544
545
  promise_test(() => {
546
547
    const streamAndReader = factory();
548
    const stream = streamAndReader.stream;
549
    const reader = streamAndReader.reader;
550
551
    assert_true(stream.locked, 'stream should start locked');
552
553
    const promise = reader.closed.then(v => {
554
      assert_equals(v, undefined, 'reader closed should fulfill with undefined');
555
      assert_true(stream.locked, 'stream should remain locked');
556
    });
557
558
    reader.read();
559
    reader.read();
560
561
    return promise;
562
563
  }, 'draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true');
564
565
  promise_test(() => {
566
567
    const streamAndReader = factory();
568
    const stream = streamAndReader.stream;
569
    const reader = streamAndReader.reader;
570
571
    const promise = reader.closed.then(() => {
572
      assert_true(stream.locked, 'the stream should start locked');
573
      reader.releaseLock(); // Releasing the lock after reader closed should not throw.
574
      assert_false(stream.locked, 'the stream should end unlocked');
575
    });
576
577
    reader.read();
578
    reader.read();
579
580
    return promise;
581
582
  }, 'releasing the lock after the stream is closed should cause locked to become false');
583
584
  promise_test(t => {
585
586
    const reader = factory().reader;
587
588
    reader.releaseLock();
589
590
    return Promise.all([
591
      promise_rejects(t, new TypeError(), reader.read()),
592
      promise_rejects(t, new TypeError(), reader.read()),
593
      promise_rejects(t, new TypeError(), reader.read())
594
    ]);
595
596
  }, 'releasing the lock should cause further read() calls to reject with a TypeError');
597
598
  promise_test(() => {
599
600
    const streamAndReader = factory();
601
    const stream = streamAndReader.stream;
602
    const reader = streamAndReader.reader;
603
604
    const readerClosed = reader.closed;
605
606
    assert_equals(reader.closed, readerClosed, 'accessing reader.closed twice in succession gives the same value');
607
608
    const promise = reader.read().then(() => {
609
      assert_equals(reader.closed, readerClosed, 'reader.closed is the same after read() fulfills');
610
611
      reader.releaseLock();
612
613
      assert_equals(reader.closed, readerClosed, 'reader.closed is the same after releasing the lock');
614
615
      const newReader = stream.getReader();
616
      return newReader.read();
617
    });
618
619
    assert_equals(reader.closed, readerClosed, 'reader.closed is the same after calling read()');
620
621
    return promise;
622
623
  }, 'reader\'s closed property always returns the same promise');
624
};
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/rs-utils.js -185 lines
Lines 1-185 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/rs-utils.js_sec1
1
'use strict';
2
(function () {
3
4
  class RandomPushSource {
5
    constructor(toPush) {
6
      this.pushed = 0;
7
      this.toPush = toPush;
8
      this.started = false;
9
      this.paused = false;
10
      this.closed = false;
11
12
      this._intervalHandle = null;
13
    }
14
15
    readStart() {
16
      if (this.closed) {
17
        return;
18
      }
19
20
      if (!this.started) {
21
        this._intervalHandle = setInterval(writeChunk, 2);
22
        this.started = true;
23
      }
24
25
      if (this.paused) {
26
        this._intervalHandle = setInterval(writeChunk, 2);
27
        this.paused = false;
28
      }
29
30
      const source = this;
31
      function writeChunk() {
32
        if (source.paused) {
33
          return;
34
        }
35
36
        source.pushed++;
37
38
        if (source.toPush > 0 && source.pushed > source.toPush) {
39
          if (source._intervalHandle) {
40
            clearInterval(source._intervalHandle);
41
            source._intervalHandle = undefined;
42
          }
43
          source.closed = true;
44
          source.onend();
45
        } else {
46
          source.ondata(randomChunk(128));
47
        }
48
      }
49
    }
50
51
    readStop() {
52
      if (this.paused) {
53
        return;
54
      }
55
56
      if (this.started) {
57
        this.paused = true;
58
        clearInterval(this._intervalHandle);
59
        this._intervalHandle = undefined;
60
      } else {
61
        throw new Error('Can\'t pause reading an unstarted source.');
62
      }
63
    }
64
  }
65
66
  function randomChunk(size) {
67
    let chunk = '';
68
69
    for (let i = 0; i < size; ++i) {
70
      // Add a random character from the basic printable ASCII set.
71
      chunk += String.fromCharCode(Math.round(Math.random() * 84) + 32);
72
    }
73
74
    return chunk;
75
  }
76
77
  function readableStreamToArray(readable, reader) {
78
    if (reader === undefined) {
79
      reader = readable.getReader();
80
    }
81
82
    const chunks = [];
83
84
    return pump();
85
86
    function pump() {
87
      return reader.read().then(result => {
88
        if (result.done) {
89
          return chunks;
90
        }
91
92
        chunks.push(result.value);
93
        return pump();
94
      });
95
    }
96
  }
97
98
  class SequentialPullSource {
99
    constructor(limit, options) {
100
      const async = options && options.async;
101
102
      this.current = 0;
103
      this.limit = limit;
104
      this.opened = false;
105
      this.closed = false;
106
107
      this._exec = f => f();
108
      if (async) {
109
        this._exec = f => setTimeout(f, 0);
110
      }
111
    }
112
113
    open(cb) {
114
      this._exec(() => {
115
        this.opened = true;
116
        cb();
117
      });
118
    }
119
120
    read(cb) {
121
      this._exec(() => {
122
        if (++this.current <= this.limit) {
123
          cb(null, false, this.current);
124
        } else {
125
          cb(null, true, null);
126
        }
127
      });
128
    }
129
130
    close(cb) {
131
      this._exec(() => {
132
        this.closed = true;
133
        cb();
134
      });
135
    }
136
  }
137
138
  function sequentialReadableStream(limit, options) {
139
    const sequentialSource = new SequentialPullSource(limit, options);
140
141
    const stream = new ReadableStream({
142
      start() {
143
        return new Promise((resolve, reject) => {
144
          sequentialSource.open(err => {
145
            if (err) {
146
              reject(err);
147
            }
148
            resolve();
149
          });
150
        });
151
      },
152
153
      pull(c) {
154
        return new Promise((resolve, reject) => {
155
          sequentialSource.read((err, done, chunk) => {
156
            if (err) {
157
              reject(err);
158
            } else if (done) {
159
              sequentialSource.close(err2 => {
160
                if (err2) {
161
                  reject(err2);
162
                }
163
                c.close();
164
                resolve();
165
              });
166
            } else {
167
              c.enqueue(chunk);
168
              resolve();
169
            }
170
          });
171
        });
172
      }
173
    });
174
175
    stream.source = sequentialSource;
176
177
    return stream;
178
  }
179
180
181
  self.RandomPushSource = RandomPushSource;
182
  self.readableStreamToArray = readableStreamToArray;
183
  self.sequentialReadableStream = sequentialReadableStream;
184
185
}());
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/test-initializer.js -14 lines
Lines 1-14 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/test-initializer.js_sec1
1
'use strict';
2
3
function worker_test(file) {
4
  fetch_tests_from_worker(new Worker(file));
5
  if (typeof SharedWorker === 'function') {
6
    fetch_tests_from_worker(new SharedWorker(file));
7
  } else {
8
    test(() => {
9
      assert_unreached('SharedWorker is unavailable');
10
    }, 'Load ' + file + ' with SharedWorker');
11
  }
12
  service_worker_test(file);
13
}
14
- a/LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/test-utils.js -43 lines
Lines 1-43 a/LayoutTests/imported/w3c/web-platform-tests/streams-api/resources/test-utils.js_sec1
1
'use strict';
2
3
self.getterRejects = (t, obj, getterName, target) => {
4
  const getter = Object.getOwnPropertyDescriptor(obj, getterName).get;
5
6
  return promise_rejects(t, new TypeError(), getter.call(target));
7
};
8
9
self.methodRejects = (t, obj, methodName, target) => {
10
  const method = obj[methodName];
11
12
  return promise_rejects(t, new TypeError(), method.call(target));
13
};
14
15
self.getterThrows = (obj, getterName, target) => {
16
  const getter = Object.getOwnPropertyDescriptor(obj, getterName).get;
17
18
  assert_throws(new TypeError(), () => getter.call(target), getterName + ' should throw a TypeError');
19
};
20
21
self.methodThrows = (obj, methodName, target, args) => {
22
  const method = obj[methodName];
23
24
  assert_throws(new TypeError(), () => method.apply(target, args), methodName + ' should throw a TypeError');
25
};
26
27
self.garbageCollect = () => {
28
  if (self.gc) {
29
    // Use --expose_gc for V8 (and Node.js)
30
    // Exposed in SpiderMonkey shell as well
31
    self.gc();
32
  } else if (self.GCController) {
33
    // Present in some WebKit development environments
34
    GCController.collect();
35
  } else {
36
    /* eslint-disable no-console */
37
    console.warn('Tests are running without the ability to do manual garbage collection. They will still work, but ' +
38
      'coverage will be suboptimal.');
39
    /* eslint-enable no-console */
40
  }
41
};
42
43
self.delay = ms => new Promise(resolve => step_timeout(resolve, ms));
- a/LayoutTests/imported/w3c/web-platform-tests/streams/README.txt +6 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/README.txt_sec1
1
This directory is imported from the the Streams API repository.
2
3
There is a plan to move these tests to web-platform-tests repository so from that moment on this importation will be
4
automatic.
5
6
Current version: https://github.com/whatwg/streams/tree/7f19175415d9b57af04cb8c2cd355ca38101f0aa/reference-implementation/web-platform-tests.
- a/LayoutTests/imported/w3c/web-platform-tests/streams/byte-length-queuing-strategy-expected.txt +18 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/byte-length-queuing-strategy-expected.txt_sec1
1
2
PASS Can construct a ByteLengthQueuingStrategy with a valid high water mark 
3
PASS Can construct a ByteLengthQueuingStrategy with any value as its high water mark 
4
PASS ByteLengthQueuingStrategy constructor behaves as expected with strange arguments 
5
PASS ByteLengthQueuingStrategy size behaves as expected with strange arguments 
6
PASS ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments 
7
PASS ByteLengthQueuingStrategy instances have the correct properties 
8
PASS ByteLengthQueuingStrategy's highWaterMark property can be set to anything 
9
FAIL Load byte-length-queuing-strategy.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
10
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
11
PASS Can construct a ByteLengthQueuingStrategy with a valid high water mark 
12
PASS Can construct a ByteLengthQueuingStrategy with any value as its high water mark 
13
PASS ByteLengthQueuingStrategy constructor behaves as expected with strange arguments 
14
PASS ByteLengthQueuingStrategy size behaves as expected with strange arguments 
15
PASS ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments 
16
PASS ByteLengthQueuingStrategy instances have the correct properties 
17
PASS ByteLengthQueuingStrategy's highWaterMark property can be set to anything 
18
- a/LayoutTests/imported/w3c/web-platform-tests/streams/byte-length-queuing-strategy.html +12 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/byte-length-queuing-strategy.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="resources/test-initializer.js"></script>
7
8
<script src="byte-length-queuing-strategy.js"></script>
9
<script>
10
'use strict';
11
worker_test('byte-length-queuing-strategy.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/byte-length-queuing-strategy.js +107 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/byte-length-queuing-strategy.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
test(() => {
8
9
  new ByteLengthQueuingStrategy({ highWaterMark: 4 });
10
11
}, 'Can construct a ByteLengthQueuingStrategy with a valid high water mark');
12
13
test(() => {
14
15
  for (const highWaterMark of [-Infinity, NaN, 'foo', {}, () => {}]) {
16
    const strategy = new ByteLengthQueuingStrategy({ highWaterMark });
17
    assert_equals(strategy.highWaterMark, highWaterMark, `${highWaterMark} gets set correctly`);
18
  }
19
20
}, 'Can construct a ByteLengthQueuingStrategy with any value as its high water mark');
21
22
test(() => {
23
24
  const highWaterMark = 1;
25
  const highWaterMarkObjectGetter = {
26
    get highWaterMark() { return highWaterMark; }
27
  };
28
  const error = new Error('wow!');
29
  const highWaterMarkObjectGetterThrowing = {
30
    get highWaterMark() { throw error; }
31
  };
32
33
  assert_throws({ name: 'TypeError' }, () => new ByteLengthQueuingStrategy(), 'construction fails with undefined');
34
  assert_throws({ name: 'TypeError' }, () => new ByteLengthQueuingStrategy(null), 'construction fails with null');
35
  assert_throws({ name: 'Error' }, () => new ByteLengthQueuingStrategy(highWaterMarkObjectGetterThrowing),
36
    'construction fails with an object with a throwing highWaterMark getter');
37
38
  // Should not fail:
39
  new ByteLengthQueuingStrategy('potato');
40
  new ByteLengthQueuingStrategy({});
41
  new ByteLengthQueuingStrategy(highWaterMarkObjectGetter);
42
43
}, 'ByteLengthQueuingStrategy constructor behaves as expected with strange arguments');
44
45
test(() => {
46
47
  const size = 1024;
48
  const chunk = { byteLength: size };
49
  const chunkGetter = {
50
    get byteLength() { return size; }
51
  };
52
  const error = new Error('wow!');
53
  const chunkGetterThrowing = {
54
    get byteLength() { throw error; }
55
  };
56
  assert_throws({ name: 'TypeError' }, () => ByteLengthQueuingStrategy.prototype.size(), 'size fails with undefined');
57
  assert_throws({ name: 'TypeError' }, () => ByteLengthQueuingStrategy.prototype.size(null), 'size fails with null');
58
  assert_equals(ByteLengthQueuingStrategy.prototype.size('potato'), undefined,
59
    'size succeeds with undefined with a random non-object type');
60
  assert_equals(ByteLengthQueuingStrategy.prototype.size({}), undefined,
61
    'size succeeds with undefined with an object without hwm property');
62
  assert_equals(ByteLengthQueuingStrategy.prototype.size(chunk), size,
63
    'size succeeds with the right amount with an object with a hwm');
64
  assert_equals(ByteLengthQueuingStrategy.prototype.size(chunkGetter), size,
65
    'size succeeds with the right amount with an object with a hwm getter');
66
  assert_throws({ name: 'Error' }, () => ByteLengthQueuingStrategy.prototype.size(chunkGetterThrowing),
67
    'size fails with the error thrown by the getter');
68
69
}, 'ByteLengthQueuingStrategy size behaves as expected with strange arguments');
70
71
test(() => {
72
73
  const thisValue = null;
74
  const returnValue = { 'returned from': 'byteLength getter' };
75
  const chunk = {
76
    get byteLength() { return returnValue; }
77
  };
78
79
  assert_equals(ByteLengthQueuingStrategy.prototype.size.call(thisValue, chunk), returnValue);
80
81
}, 'ByteLengthQueuingStrategy.prototype.size should work generically on its this and its arguments');
82
83
test(() => {
84
85
  const strategy = new ByteLengthQueuingStrategy({ highWaterMark: 4 });
86
87
  assert_object_equals(Object.getOwnPropertyDescriptor(strategy, 'highWaterMark'),
88
    { value: 4, writable: true, enumerable: true, configurable: true },
89
    'highWaterMark property should be a data property with the value passed the constructor');
90
  assert_equals(typeof strategy.size, 'function');
91
92
}, 'ByteLengthQueuingStrategy instances have the correct properties');
93
94
test(() => {
95
96
  const strategy = new ByteLengthQueuingStrategy({ highWaterMark: 4 });
97
  assert_equals(strategy.highWaterMark, 4);
98
99
  strategy.highWaterMark = 10;
100
  assert_equals(strategy.highWaterMark, 10);
101
102
  strategy.highWaterMark = 'banana';
103
  assert_equals(strategy.highWaterMark, 'banana');
104
105
}, 'ByteLengthQueuingStrategy\'s highWaterMark property can be set to anything');
106
107
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/count-queuing-strategy-expected.txt +18 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/count-queuing-strategy-expected.txt_sec1
1
2
PASS Can construct a CountQueuingStrategy with a valid high water mark 
3
PASS Can construct a CountQueuingStrategy with any value as its high water mark 
4
PASS CountQueuingStrategy constructor behaves as expected with strange arguments 
5
PASS CountQueuingStrategy.prototype.size should work generically on its this and its arguments 
6
PASS CountQueuingStrategy size behaves as expected with strange arguments 
7
PASS CountQueuingStrategy instances have the correct properties 
8
PASS CountQueuingStrategy's highWaterMark property can be set to anything 
9
FAIL Load count-queuing-strategy.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
10
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
11
PASS Can construct a CountQueuingStrategy with a valid high water mark 
12
PASS Can construct a CountQueuingStrategy with any value as its high water mark 
13
PASS CountQueuingStrategy constructor behaves as expected with strange arguments 
14
PASS CountQueuingStrategy.prototype.size should work generically on its this and its arguments 
15
PASS CountQueuingStrategy size behaves as expected with strange arguments 
16
PASS CountQueuingStrategy instances have the correct properties 
17
PASS CountQueuingStrategy's highWaterMark property can be set to anything 
18
- a/LayoutTests/imported/w3c/web-platform-tests/streams/count-queuing-strategy.html +12 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/count-queuing-strategy.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="resources/test-initializer.js"></script>
7
8
<script src="count-queuing-strategy.js"></script>
9
<script>
10
'use strict';
11
worker_test('count-queuing-strategy.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/count-queuing-strategy.js +106 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/count-queuing-strategy.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
test(() => {
8
9
  new CountQueuingStrategy({ highWaterMark: 4 });
10
11
}, 'Can construct a CountQueuingStrategy with a valid high water mark');
12
13
test(() => {
14
15
  for (const highWaterMark of [-Infinity, NaN, 'foo', {}, () => {}]) {
16
    const strategy = new CountQueuingStrategy({ highWaterMark });
17
    assert_equals(strategy.highWaterMark, highWaterMark, `${highWaterMark} gets set correctly`);
18
  }
19
20
}, 'Can construct a CountQueuingStrategy with any value as its high water mark');
21
22
test(() => {
23
24
  const highWaterMark = 1;
25
  const highWaterMarkObjectGetter = {
26
    get highWaterMark() { return highWaterMark; }
27
  };
28
  const error = new Error('wow!');
29
  const highWaterMarkObjectGetterThrowing = {
30
    get highWaterMark() { throw error; }
31
  };
32
33
  assert_throws({ name: 'TypeError' }, () => new CountQueuingStrategy(), 'construction fails with undefined');
34
  assert_throws({ name: 'TypeError' }, () => new CountQueuingStrategy(null), 'construction fails with null');
35
  assert_throws({ name: 'Error' }, () => new CountQueuingStrategy(highWaterMarkObjectGetterThrowing),
36
    'construction fails with an object with a throwing highWaterMark getter');
37
38
  // Should not fail:
39
  new CountQueuingStrategy('potato');
40
  new CountQueuingStrategy({});
41
  new CountQueuingStrategy(highWaterMarkObjectGetter);
42
43
}, 'CountQueuingStrategy constructor behaves as expected with strange arguments');
44
45
46
test(() => {
47
48
  const thisValue = null;
49
  const chunk = {
50
    get byteLength() {
51
      throw new TypeError('shouldn\'t be called');
52
    }
53
  };
54
55
  assert_equals(CountQueuingStrategy.prototype.size.call(thisValue, chunk), 1);
56
57
}, 'CountQueuingStrategy.prototype.size should work generically on its this and its arguments');
58
59
test(() => {
60
61
  const size = 1024;
62
  const chunk = { byteLength: size };
63
  const chunkGetter = {
64
    get byteLength() { return size; }
65
  };
66
  const error = new Error('wow!');
67
  const chunkGetterThrowing = {
68
    get byteLength() { throw error; }
69
  };
70
71
  assert_equals(CountQueuingStrategy.prototype.size(), 1, 'size returns 1 with undefined');
72
  assert_equals(CountQueuingStrategy.prototype.size(null), 1, 'size returns 1 with null');
73
  assert_equals(CountQueuingStrategy.prototype.size('potato'), 1, 'size returns 1 with non-object type');
74
  assert_equals(CountQueuingStrategy.prototype.size({}), 1, 'size returns 1 with empty object');
75
  assert_equals(CountQueuingStrategy.prototype.size(chunk), 1, 'size returns 1 with a chunk');
76
  assert_equals(CountQueuingStrategy.prototype.size(chunkGetter), 1, 'size returns 1 with chunk getter');
77
  assert_equals(CountQueuingStrategy.prototype.size(chunkGetterThrowing), 1,
78
    'size returns 1 with chunk getter that throws');
79
80
}, 'CountQueuingStrategy size behaves as expected with strange arguments');
81
82
test(() => {
83
84
  const strategy = new CountQueuingStrategy({ highWaterMark: 4 });
85
86
  assert_object_equals(Object.getOwnPropertyDescriptor(strategy, 'highWaterMark'),
87
    { value: 4, writable: true, enumerable: true, configurable: true },
88
    'highWaterMark property should be a data property with the value passed the constructor');
89
  assert_equals(typeof strategy.size, 'function');
90
91
}, 'CountQueuingStrategy instances have the correct properties');
92
93
test(() => {
94
95
  const strategy = new CountQueuingStrategy({ highWaterMark: 4 });
96
  assert_equals(strategy.highWaterMark, 4);
97
98
  strategy.highWaterMark = 10;
99
  assert_equals(strategy.highWaterMark, 10);
100
101
  strategy.highWaterMark = 'banana';
102
  assert_equals(strategy.highWaterMark, 'banana');
103
104
}, 'CountQueuingStrategy\'s highWaterMark property can be set to anything');
105
106
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies-expected.txt +18 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies-expected.txt_sec1
1
2
PASS Readable stream: throwing strategy.size getter 
3
PASS Readable stream: strategy.size errors the stream and then throws 
4
PASS Readable stream: strategy.size errors the stream and then returns Infinity 
5
PASS Readable stream: throwing strategy.size method 
6
PASS Readable stream: throwing strategy.highWaterMark getter 
7
PASS Readable stream: invalid strategy.highWaterMark 
8
PASS Readable stream: invalid strategy.size return value 
9
FAIL Load bad-strategies.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
10
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
11
PASS Readable stream: throwing strategy.size getter 
12
PASS Readable stream: strategy.size errors the stream and then throws 
13
PASS Readable stream: strategy.size errors the stream and then returns Infinity 
14
PASS Readable stream: throwing strategy.size method 
15
PASS Readable stream: throwing strategy.highWaterMark getter 
16
PASS Readable stream: invalid strategy.highWaterMark 
17
PASS Readable stream: invalid strategy.size return value 
18
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.html +12 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="bad-strategies.js"></script>
9
<script>
10
'use strict';
11
worker_test('bad-strategies.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.js +175 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-strategies.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
test(() => {
8
9
  const theError = new Error('a unique string');
10
11
  assert_throws(theError, () => {
12
    new ReadableStream({}, {
13
      get size() {
14
        throw theError;
15
      },
16
      highWaterMark: 5
17
    });
18
  }, 'construction should re-throw the error');
19
20
}, 'Readable stream: throwing strategy.size getter');
21
22
promise_test(t => {
23
24
  const controllerError = { name: 'controller error' };
25
  const thrownError = { name: 'thrown error' };
26
27
  let controller;
28
  const rs = new ReadableStream(
29
    {
30
      start(c) {
31
        controller = c;
32
      }
33
    },
34
    {
35
      size() {
36
        controller.error(controllerError);
37
        throw thrownError;
38
      },
39
      highWaterMark: 5
40
    }
41
  );
42
43
  assert_throws(thrownError, () => controller.enqueue('a'), 'enqueue should re-throw the error');
44
45
  return promise_rejects(t, controllerError, rs.getReader().closed);
46
47
}, 'Readable stream: strategy.size errors the stream and then throws');
48
49
promise_test(t => {
50
51
  const theError = { name: 'my error' };
52
53
  let controller;
54
  const rs = new ReadableStream(
55
    {
56
      start(c) {
57
        controller = c;
58
      }
59
    },
60
    {
61
      size() {
62
        controller.error(theError);
63
        return Infinity;
64
      },
65
      highWaterMark: 5
66
    }
67
  );
68
69
  assert_throws(new RangeError(), () => controller.enqueue('a'), 'enqueue should throw a RangeError');
70
71
  return promise_rejects(t, theError, rs.getReader().closed, 'closed should reject with the error');
72
73
}, 'Readable stream: strategy.size errors the stream and then returns Infinity');
74
75
promise_test(() => {
76
77
  const theError = new Error('a unique string');
78
  const rs = new ReadableStream(
79
    {
80
      start(c) {
81
        assert_throws(theError, () => c.enqueue('a'), 'enqueue should throw the error');
82
      }
83
    },
84
    {
85
      size() {
86
        throw theError;
87
      },
88
      highWaterMark: 5
89
    }
90
  );
91
92
  return rs.getReader().closed.catch(e => {
93
    assert_equals(e, theError, 'closed should reject with the error');
94
  });
95
96
}, 'Readable stream: throwing strategy.size method');
97
98
test(() => {
99
100
  const theError = new Error('a unique string');
101
102
  assert_throws(theError, () => {
103
    new ReadableStream({}, {
104
      size() {
105
        return 1;
106
      },
107
      get highWaterMark() {
108
        throw theError;
109
      }
110
    });
111
  }, 'construction should re-throw the error');
112
113
}, 'Readable stream: throwing strategy.highWaterMark getter');
114
115
test(() => {
116
117
  for (const highWaterMark of [-1, -Infinity]) {
118
    assert_throws(new RangeError(), () => {
119
      new ReadableStream({}, {
120
        size() {
121
          return 1;
122
        },
123
        highWaterMark
124
      });
125
    }, 'construction should throw a RangeError for ' + highWaterMark);
126
  }
127
128
  for (const highWaterMark of [NaN, 'foo', {}]) {
129
    assert_throws(new TypeError(), () => {
130
      new ReadableStream({}, {
131
        size() {
132
          return 1;
133
        },
134
        highWaterMark
135
      });
136
    }, 'construction should throw a TypeError for ' + highWaterMark);
137
  }
138
139
}, 'Readable stream: invalid strategy.highWaterMark');
140
141
promise_test(() => {
142
143
  const promises = [];
144
  for (const size of [NaN, -Infinity, Infinity, -1]) {
145
    let theError;
146
    const rs = new ReadableStream(
147
      {
148
        start(c) {
149
          try {
150
            c.enqueue('hi');
151
            assert_unreached('enqueue didn\'t throw');
152
          } catch (error) {
153
            assert_equals(error.name, 'RangeError', 'enqueue should throw a RangeError for ' + size);
154
            theError = error;
155
          }
156
        }
157
      },
158
      {
159
        size() {
160
          return size;
161
        },
162
        highWaterMark: 5
163
      }
164
    );
165
166
    promises.push(rs.getReader().closed.catch(e => {
167
      assert_equals(e, theError, 'closed should reject with the error for ' + size);
168
    }));
169
  }
170
171
  return Promise.all(promises);
172
173
}, 'Readable stream: invalid strategy.size return value');
174
175
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources-expected.txt +46 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources-expected.txt_sec1
1
2
PASS Underlying source start: throwing getter 
3
PASS Underlying source start: throwing method 
4
PASS Underlying source: throwing pull getter (initial pull) 
5
PASS Underlying source: throwing pull method (initial pull) 
6
PASS Underlying source pull: throwing getter (second pull) 
7
PASS Underlying source pull: throwing method (second pull) 
8
PASS Underlying source cancel: throwing getter 
9
PASS Underlying source cancel: throwing method 
10
PASS Underlying source: calling enqueue on an empty canceled stream should not throw 
11
PASS Underlying source: calling enqueue on a non-empty canceled stream should not throw 
12
PASS Underlying source: calling enqueue on a closed stream should throw 
13
PASS Underlying source: calling enqueue on an errored stream should throw 
14
PASS Underlying source: calling close twice on an empty stream should throw the second time 
15
PASS Underlying source: calling close twice on a non-empty stream should throw the second time 
16
PASS Underlying source: calling close on an empty canceled stream should not throw 
17
PASS Underlying source: calling close on a non-empty canceled stream should not throw 
18
PASS Underlying source: calling close after error should throw 
19
PASS Underlying source: calling error twice should throw the second time 
20
PASS Underlying source: calling error after close should throw 
21
PASS Underlying source: calling error and returning a rejected promise from start should cause the stream to error with the first error 
22
PASS Underlying source: calling error and returning a rejected promise from pull should cause the stream to error with the first error 
23
FAIL Load bad-underlying-sources.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
24
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
25
PASS Underlying source start: throwing getter 
26
PASS Underlying source start: throwing method 
27
PASS Underlying source: throwing pull getter (initial pull) 
28
PASS Underlying source: throwing pull method (initial pull) 
29
PASS Underlying source pull: throwing getter (second pull) 
30
PASS Underlying source pull: throwing method (second pull) 
31
PASS Underlying source cancel: throwing getter 
32
PASS Underlying source cancel: throwing method 
33
PASS Underlying source: calling enqueue on an empty canceled stream should not throw 
34
PASS Underlying source: calling enqueue on a non-empty canceled stream should not throw 
35
PASS Underlying source: calling enqueue on a closed stream should throw 
36
PASS Underlying source: calling enqueue on an errored stream should throw 
37
PASS Underlying source: calling close twice on an empty stream should throw the second time 
38
PASS Underlying source: calling close twice on a non-empty stream should throw the second time 
39
PASS Underlying source: calling close on an empty canceled stream should not throw 
40
PASS Underlying source: calling close on a non-empty canceled stream should not throw 
41
PASS Underlying source: calling close after error should throw 
42
PASS Underlying source: calling error twice should throw the second time 
43
PASS Underlying source: calling error after close should throw 
44
PASS Underlying source: calling error and returning a rejected promise from start should cause the stream to error with the first error 
45
PASS Underlying source: calling error and returning a rejected promise from pull should cause the stream to error with the first error 
46
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.html +12 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="bad-underlying-sources.js"></script>
9
<script>
10
'use strict';
11
worker_test('bad-underlying-sources.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.js +383 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/bad-underlying-sources.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
8
test(() => {
9
10
  const theError = new Error('a unique string');
11
12
  assert_throws(theError, () => {
13
    new ReadableStream({
14
      get start() {
15
        throw theError;
16
      }
17
    });
18
  }, 'constructing the stream should re-throw the error');
19
20
}, 'Underlying source start: throwing getter');
21
22
23
test(() => {
24
25
  const theError = new Error('a unique string');
26
27
  assert_throws(theError, () => {
28
    new ReadableStream({
29
      start() {
30
        throw theError;
31
      }
32
    });
33
  }, 'constructing the stream should re-throw the error');
34
35
}, 'Underlying source start: throwing method');
36
37
38
promise_test(t => {
39
40
  const theError = new Error('a unique string');
41
  const rs = new ReadableStream({
42
    get pull() {
43
      throw theError;
44
    }
45
  });
46
47
  return promise_rejects(t, theError, rs.getReader().closed);
48
49
}, 'Underlying source: throwing pull getter (initial pull)');
50
51
52
promise_test(t => {
53
54
  const theError = new Error('a unique string');
55
  const rs = new ReadableStream({
56
    pull() {
57
      throw theError;
58
    }
59
  });
60
61
  return promise_rejects(t, theError, rs.getReader().closed);
62
63
}, 'Underlying source: throwing pull method (initial pull)');
64
65
66
promise_test(t => {
67
68
  const theError = new Error('a unique string');
69
70
  let counter = 0;
71
  const rs = new ReadableStream({
72
    get pull() {
73
      ++counter;
74
      if (counter === 1) {
75
        return c => c.enqueue('a');
76
      }
77
78
      throw theError;
79
    }
80
  });
81
  const reader = rs.getReader();
82
83
  return Promise.all([
84
    reader.read().then(r => {
85
      assert_object_equals(r, { value: 'a', done: false }, 'the chunk read should be correct');
86
    }),
87
    promise_rejects(t, theError, reader.closed)
88
  ]);
89
90
}, 'Underlying source pull: throwing getter (second pull)');
91
92
93
promise_test(t => {
94
95
  const theError = new Error('a unique string');
96
97
  let counter = 0;
98
  const rs = new ReadableStream({
99
    pull(c) {
100
      ++counter;
101
      if (counter === 1) {
102
        c.enqueue('a');
103
        return;
104
      }
105
106
      throw theError;
107
    }
108
  });
109
  const reader = rs.getReader();
110
111
  return Promise.all([
112
    reader.read().then(r => {
113
      assert_object_equals(r, { value: 'a', done: false }, 'the chunk read should be correct');
114
    }),
115
    promise_rejects(t, theError, reader.closed)
116
  ]);
117
118
}, 'Underlying source pull: throwing method (second pull)');
119
120
promise_test(t => {
121
122
  const theError = new Error('a unique string');
123
  const rs = new ReadableStream({
124
    get cancel() {
125
      throw theError;
126
    }
127
  });
128
129
  return promise_rejects(t, theError, rs.cancel());
130
131
}, 'Underlying source cancel: throwing getter');
132
133
promise_test(t => {
134
135
  const theError = new Error('a unique string');
136
  const rs = new ReadableStream({
137
    cancel() {
138
      throw theError;
139
    }
140
  });
141
142
  return promise_rejects(t, theError, rs.cancel());
143
144
}, 'Underlying source cancel: throwing method');
145
146
promise_test(() => {
147
148
  let controller;
149
  const rs = new ReadableStream({
150
    start(c) {
151
      controller = c;
152
    }
153
  });
154
155
  rs.cancel();
156
  controller.enqueue('a'); // Calling enqueue after canceling should not throw anything.
157
158
  return rs.getReader().closed;
159
160
}, 'Underlying source: calling enqueue on an empty canceled stream should not throw');
161
162
promise_test(() => {
163
164
  let controller;
165
  const rs = new ReadableStream({
166
    start(c) {
167
      c.enqueue('a');
168
      c.enqueue('b');
169
      controller = c;
170
    }
171
  });
172
173
  rs.cancel();
174
  controller.enqueue('c'); // Calling enqueue after canceling should not throw anything.
175
176
  return rs.getReader().closed;
177
178
}, 'Underlying source: calling enqueue on a non-empty canceled stream should not throw');
179
180
promise_test(() => {
181
182
  return new ReadableStream({
183
    start(c) {
184
      c.close();
185
      assert_throws(new TypeError(), () => c.enqueue('a'), 'call to enqueue should throw a TypeError');
186
    }
187
  }).getReader().closed;
188
189
}, 'Underlying source: calling enqueue on a closed stream should throw');
190
191
promise_test(t => {
192
193
  const theError = new Error('boo');
194
  const closed = new ReadableStream({
195
    start(c) {
196
      c.error(theError);
197
      assert_throws(theError, () => c.enqueue('a'), 'call to enqueue should throw the error');
198
    }
199
  }).getReader().closed;
200
201
  return promise_rejects(t, theError, closed);
202
203
}, 'Underlying source: calling enqueue on an errored stream should throw');
204
205
promise_test(() => {
206
207
  return new ReadableStream({
208
    start(c) {
209
      c.close();
210
      assert_throws(new TypeError(), () => c.close(), 'second call to close should throw a TypeError');
211
    }
212
  }).getReader().closed;
213
214
}, 'Underlying source: calling close twice on an empty stream should throw the second time');
215
216
promise_test(() => {
217
218
  let startCalled = false;
219
  let readCalled = false;
220
  const reader = new ReadableStream({
221
    start(c) {
222
      c.enqueue('a');
223
      c.close();
224
      assert_throws(new TypeError(), () => c.close(), 'second call to close should throw a TypeError');
225
      startCalled = true;
226
    }
227
  }).getReader();
228
229
  return Promise.all([
230
    reader.read().then(r => {
231
      assert_object_equals(r, { value: 'a', done: false }, 'read() should read the enqueued chunk');
232
      readCalled = true;
233
    }),
234
    reader.closed.then(() => {
235
      assert_true(startCalled);
236
      assert_true(readCalled);
237
    })
238
  ]);
239
240
}, 'Underlying source: calling close twice on a non-empty stream should throw the second time');
241
242
promise_test(() => {
243
244
  let controller;
245
  let startCalled = false;
246
  const rs = new ReadableStream({
247
    start(c) {
248
      controller = c;
249
      startCalled = true;
250
    }
251
  });
252
253
  rs.cancel();
254
  controller.close(); // Calling close after canceling should not throw anything.
255
256
  return rs.getReader().closed.then(() => {
257
    assert_true(startCalled);
258
  });
259
260
}, 'Underlying source: calling close on an empty canceled stream should not throw');
261
262
promise_test(() => {
263
264
  let controller;
265
  let startCalled = false;
266
  const rs = new ReadableStream({
267
    start(c) {
268
      controller = c;
269
      c.enqueue('a');
270
      startCalled = true;
271
    }
272
  });
273
274
  rs.cancel();
275
  controller.close(); // Calling close after canceling should not throw anything.
276
277
  return rs.getReader().closed.then(() => {
278
    assert_true(startCalled);
279
  });
280
281
}, 'Underlying source: calling close on a non-empty canceled stream should not throw');
282
283
promise_test(() => {
284
285
  const theError = new Error('boo');
286
  let startCalled = false;
287
288
  const closed = new ReadableStream({
289
    start(c) {
290
      c.error(theError);
291
      assert_throws(new TypeError(), () => c.close(), 'call to close should throw a TypeError');
292
      startCalled = true;
293
    }
294
  }).getReader().closed;
295
296
  return closed.catch(e => {
297
    assert_true(startCalled);
298
    assert_equals(e, theError, 'closed should reject with the error');
299
  });
300
301
}, 'Underlying source: calling close after error should throw');
302
303
promise_test(() => {
304
305
  const theError = new Error('boo');
306
  let startCalled = false;
307
308
  const closed = new ReadableStream({
309
    start(c) {
310
      c.error(theError);
311
      assert_throws(new TypeError(), () => c.error(), 'second call to error should throw a TypeError');
312
      startCalled = true;
313
    }
314
  }).getReader().closed;
315
316
  return closed.catch(e => {
317
    assert_true(startCalled);
318
    assert_equals(e, theError, 'closed should reject with the error');
319
  });
320
321
}, 'Underlying source: calling error twice should throw the second time');
322
323
promise_test(() => {
324
325
  let startCalled = false;
326
327
  const closed = new ReadableStream({
328
    start(c) {
329
      c.close();
330
      assert_throws(new TypeError(), () => c.error(), 'second call to error should throw a TypeError');
331
      startCalled = true;
332
    }
333
  }).getReader().closed;
334
335
  return closed.then(() => assert_true(startCalled));
336
337
}, 'Underlying source: calling error after close should throw');
338
339
promise_test(() => {
340
341
  let startCalled = false;
342
  const firstError = new Error('1');
343
  const secondError = new Error('2');
344
345
  const closed = new ReadableStream({
346
    start(c) {
347
      c.error(firstError);
348
      startCalled = true;
349
      return Promise.reject(secondError);
350
    }
351
  }).getReader().closed;
352
353
  return closed.catch(e => {
354
    assert_true(startCalled);
355
    assert_equals(e, firstError, 'closed should reject with the first error');
356
  });
357
358
}, 'Underlying source: calling error and returning a rejected promise from start should cause the stream to error ' +
359
   'with the first error');
360
361
promise_test(() => {
362
363
  let startCalled = false;
364
  const firstError = new Error('1');
365
  const secondError = new Error('2');
366
367
  const closed = new ReadableStream({
368
    pull(c) {
369
      c.error(firstError);
370
      startCalled = true;
371
      return Promise.reject(secondError);
372
    }
373
  }).getReader().closed;
374
375
  return closed.catch(e => {
376
    assert_true(startCalled);
377
    assert_equals(e, firstError, 'closed should reject with the first error');
378
  });
379
380
}, 'Underlying source: calling error and returning a rejected promise from pull should cause the stream to error ' +
381
   'with the first error');
382
383
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/brand-checks-expected.txt +34 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/brand-checks-expected.txt_sec1
1
2
PASS Can get the ReadableStreamReader constructor indirectly 
3
PASS Can get the ReadableStreamController constructor indirectly 
4
PASS ReadableStream.prototype.cancel enforces a brand check 
5
PASS ReadableStream.prototype.getReader enforces a brand check 
6
PASS ReadableStream.prototype.tee enforces a brand check 
7
PASS ReadableStreamReader enforces a brand check on its argument 
8
PASS ReadableStreamReader.prototype.closed enforces a brand check 
9
PASS ReadableStreamReader.prototype.cancel enforces a brand check 
10
PASS ReadableStreamReader.prototype.read enforces a brand check 
11
PASS ReadableStreamReader.prototype.releaseLock enforces a brand check 
12
PASS ReadableStreamController enforces a brand check on its argument 
13
PASS ReadableStreamController can't be given a fully-constructed ReadableStream 
14
PASS ReadableStreamController.prototype.close enforces a brand check 
15
PASS ReadableStreamController.prototype.enqueue enforces a brand check 
16
PASS ReadableStreamController.prototype.error enforces a brand check 
17
FAIL Load brand-checks.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
18
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
19
PASS Can get the ReadableStreamReader constructor indirectly 
20
PASS Can get the ReadableStreamController constructor indirectly 
21
PASS ReadableStream.prototype.cancel enforces a brand check 
22
PASS ReadableStream.prototype.getReader enforces a brand check 
23
PASS ReadableStream.prototype.tee enforces a brand check 
24
PASS ReadableStreamReader enforces a brand check on its argument 
25
PASS ReadableStreamReader.prototype.closed enforces a brand check 
26
PASS ReadableStreamReader.prototype.cancel enforces a brand check 
27
PASS ReadableStreamReader.prototype.read enforces a brand check 
28
PASS ReadableStreamReader.prototype.releaseLock enforces a brand check 
29
PASS ReadableStreamController enforces a brand check on its argument 
30
PASS ReadableStreamController can't be given a fully-constructed ReadableStream 
31
PASS ReadableStreamController.prototype.close enforces a brand check 
32
PASS ReadableStreamController.prototype.enqueue enforces a brand check 
33
PASS ReadableStreamController.prototype.error enforces a brand check 
34
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/brand-checks.html +13 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/brand-checks.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="brand-checks.js"></script>
10
<script>
11
'use strict';
12
worker_test('brand-checks.js');
13
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/brand-checks.js +151 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/brand-checks.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
let ReadableStreamReader;
9
let ReadableStreamController;
10
11
test(() => {
12
13
  // It's not exposed globally, but we test a few of its properties here.
14
  ReadableStreamReader = (new ReadableStream()).getReader().constructor;
15
16
}, 'Can get the ReadableStreamReader constructor indirectly');
17
18
test(() => {
19
20
  // It's not exposed globally, but we test a few of its properties here.
21
  new ReadableStream({
22
    start(c) {
23
      ReadableStreamController = c.constructor;
24
    }
25
  });
26
27
}, 'Can get the ReadableStreamController constructor indirectly');
28
29
function fakeReadableStream() {
30
  return {
31
    cancel() { return Promise.resolve(); },
32
    getReader() { return new ReadableStreamReader(new ReadableStream()); },
33
    pipeThrough(obj) { return obj.readable; },
34
    pipeTo() { return Promise.resolve(); },
35
    tee() { return [realReadableStream(), realReadableStream()]; }
36
  };
37
}
38
39
function realReadableStream() {
40
  return new ReadableStream();
41
}
42
43
function fakeReadableStreamReader() {
44
  return {
45
    get closed() { return Promise.resolve(); },
46
    cancel() { return Promise.resolve(); },
47
    read() { return Promise.resolve({ value: undefined, done: true }); },
48
    releaseLock() { return; }
49
  };
50
}
51
52
function fakeReadableStreamController() {
53
  return {
54
    close() { },
55
    enqueue() { },
56
    error() { }
57
  };
58
}
59
60
promise_test(t => {
61
62
  return methodRejects(t, ReadableStream.prototype, 'cancel', fakeReadableStream());
63
64
}, 'ReadableStream.prototype.cancel enforces a brand check');
65
66
test(() => {
67
68
  methodThrows(ReadableStream.prototype, 'getReader', fakeReadableStream());
69
70
}, 'ReadableStream.prototype.getReader enforces a brand check');
71
72
test(() => {
73
74
  methodThrows(ReadableStream.prototype, 'tee', fakeReadableStream());
75
76
}, 'ReadableStream.prototype.tee enforces a brand check');
77
78
test(() => {
79
80
  assert_throws(new TypeError(), () => new ReadableStreamReader(fakeReadableStream()),
81
                'Constructing a ReadableStreamReader should throw');
82
83
}, 'ReadableStreamReader enforces a brand check on its argument');
84
85
promise_test(t => {
86
87
  return Promise.all([
88
    getterRejects(t, ReadableStreamReader.prototype, 'closed', fakeReadableStreamReader()),
89
    getterRejects(t, ReadableStreamReader.prototype, 'closed', realReadableStream())
90
  ]);
91
92
}, 'ReadableStreamReader.prototype.closed enforces a brand check');
93
94
promise_test(t => {
95
96
  return Promise.all([
97
    methodRejects(t, ReadableStreamReader.prototype, 'cancel', fakeReadableStreamReader()),
98
    methodRejects(t, ReadableStreamReader.prototype, 'cancel', realReadableStream())
99
  ]);
100
101
}, 'ReadableStreamReader.prototype.cancel enforces a brand check');
102
103
promise_test(t => {
104
105
  return Promise.all([
106
    methodRejects(t, ReadableStreamReader.prototype, 'read', fakeReadableStreamReader()),
107
    methodRejects(t, ReadableStreamReader.prototype, 'read', realReadableStream())
108
  ]);
109
110
}, 'ReadableStreamReader.prototype.read enforces a brand check');
111
112
test(() => {
113
114
  methodThrows(ReadableStreamReader.prototype, 'releaseLock', fakeReadableStreamReader());
115
  methodThrows(ReadableStreamReader.prototype, 'releaseLock', realReadableStream());
116
117
}, 'ReadableStreamReader.prototype.releaseLock enforces a brand check');
118
119
test(() => {
120
121
  assert_throws(new TypeError(), () => new ReadableStreamController(fakeReadableStream()),
122
                'Constructing a ReadableStreamController should throw');
123
124
}, 'ReadableStreamController enforces a brand check on its argument');
125
126
test(() => {
127
128
  assert_throws(new TypeError(), () => new ReadableStreamController(realReadableStream()),
129
                'Constructing a ReadableStreamController should throw');
130
131
}, 'ReadableStreamController can\'t be given a fully-constructed ReadableStream');
132
133
test(() => {
134
135
  methodThrows(ReadableStreamController.prototype, 'close', fakeReadableStreamController());
136
137
}, 'ReadableStreamController.prototype.close enforces a brand check');
138
139
test(() => {
140
141
  methodThrows(ReadableStreamController.prototype, 'enqueue', fakeReadableStreamController());
142
143
}, 'ReadableStreamController.prototype.enqueue enforces a brand check');
144
145
test(() => {
146
147
  methodThrows(ReadableStreamController.prototype, 'error', fakeReadableStreamController());
148
149
}, 'ReadableStreamController.prototype.error enforces a brand check');
150
151
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel-expected.txt +24 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel-expected.txt_sec1
1
2
PASS ReadableStream cancellation: integration test on an infinite stream derived from a random push source 
3
PASS ReadableStream cancellation: cancel(reason) should pass through the given reason to the underlying source 
4
PASS ReadableStream cancellation: cancel() on a locked stream should fail and not call the underlying source cancel 
5
PASS ReadableStream cancellation: should fulfill promise when cancel callback went fine 
6
PASS ReadableStream cancellation: returning a value from the underlying source's cancel should not affect the fulfillment value of the promise returned by the stream's cancel 
7
PASS ReadableStream cancellation: should reject promise when cancel callback raises an exception 
8
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (1) 
9
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (2) 
10
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should reject when that one does 
11
PASS ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called 
12
FAIL Load cancel.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
13
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
14
PASS ReadableStream cancellation: integration test on an infinite stream derived from a random push source 
15
PASS ReadableStream cancellation: cancel(reason) should pass through the given reason to the underlying source 
16
PASS ReadableStream cancellation: cancel() on a locked stream should fail and not call the underlying source cancel 
17
PASS ReadableStream cancellation: should fulfill promise when cancel callback went fine 
18
PASS ReadableStream cancellation: returning a value from the underlying source's cancel should not affect the fulfillment value of the promise returned by the stream's cancel 
19
PASS ReadableStream cancellation: should reject promise when cancel callback raises an exception 
20
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (1) 
21
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (2) 
22
PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should reject when that one does 
23
PASS ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called 
24
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.html +14 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="../resources/rs-utils.js"></script>
10
<script src="cancel.js"></script>
11
<script>
12
'use strict';
13
worker_test('cancel.js');
14
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.js +242 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/cancel.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('../resources/rs-utils.js');
6
  self.importScripts('/resources/testharness.js');
7
}
8
9
promise_test(() => {
10
11
  const randomSource = new RandomPushSource();
12
13
  let cancellationFinished = false;
14
  const rs = new ReadableStream({
15
    start(c) {
16
      randomSource.ondata = c.enqueue.bind(c);
17
      randomSource.onend = c.close.bind(c);
18
      randomSource.onerror = c.error.bind(c);
19
    },
20
21
    pull() {
22
      randomSource.readStart();
23
    },
24
25
    cancel() {
26
      randomSource.readStop();
27
      randomSource.onend();
28
29
      return new Promise(resolve => {
30
        setTimeout(() => {
31
          cancellationFinished = true;
32
          resolve();
33
        }, 1);
34
      });
35
    }
36
  });
37
38
  const reader = rs.getReader();
39
40
  // We call delay multiple times to avoid cancelling too early for the
41
  // source to enqueue at least one chunk.
42
  const cancel = delay(5).then(() => delay(5)).then(() => delay(5)).then(() => {
43
    let cancelPromise = reader.cancel();
44
    assert_false(cancellationFinished, 'cancellation in source should happen later');
45
    return cancelPromise;
46
  })
47
48
  return readableStreamToArray(rs, reader).then(chunks => {
49
    assert_greater_than(chunks.length, 0, 'at least one chunk should be read');
50
    for (let i = 0; i < chunks.length; i++) {
51
      assert_equals(chunks[i].length, 128, 'chunk ' + i + ' should have 128 bytes');
52
    }
53
    return cancel;
54
  }).then(() => {
55
    assert_true(cancellationFinished, 'it returns a promise that is fulfilled when the cancellation finishes');
56
  });
57
58
}, 'ReadableStream cancellation: integration test on an infinite stream derived from a random push source');
59
60
test(() => {
61
62
  let recordedReason;
63
  const rs = new ReadableStream({
64
    cancel(reason) {
65
      recordedReason = reason;
66
    }
67
  });
68
69
  const passedReason = new Error('Sorry, it just wasn\'t meant to be.');
70
  rs.cancel(passedReason);
71
72
  assert_equals(recordedReason, passedReason,
73
    'the error passed to the underlying source\'s cancel method should equal the one passed to the stream\'s cancel');
74
75
}, 'ReadableStream cancellation: cancel(reason) should pass through the given reason to the underlying source');
76
77
promise_test(() => {
78
79
  const rs = new ReadableStream({
80
    start(c) {
81
      c.enqueue('a');
82
      c.close();
83
    },
84
    cancel() {
85
      assert_unreached('underlying source cancel() should not have been called');
86
    }
87
  });
88
89
  const reader = rs.getReader();
90
91
  return rs.cancel().then(() => {
92
    assert_unreached('cancel() should be rejected');
93
  }, e => {
94
    assert_equals(e.name, 'TypeError', 'cancel() should be rejected with a TypeError');
95
  }).then(() => {
96
    return reader.read();
97
  }).then(result => {
98
    assert_object_equals(result, { value: 'a', done: false }, 'read() should still work after the attempted cancel');
99
    return reader.closed;
100
  });
101
102
}, 'ReadableStream cancellation: cancel() on a locked stream should fail and not call the underlying source cancel');
103
104
promise_test(() => {
105
106
  let cancelReceived = false;
107
  const cancelReason = new Error('I am tired of this stream, I prefer to cancel it');
108
  const rs = new ReadableStream({
109
    cancel(reason) {
110
      cancelReceived = true;
111
      assert_equals(reason, cancelReason, 'cancellation reason given to the underlying source should be equal to the one passed');
112
    }
113
  });
114
115
  return rs.cancel(cancelReason).then(() => {
116
    assert_true(cancelReceived);
117
  });
118
119
}, 'ReadableStream cancellation: should fulfill promise when cancel callback went fine');
120
121
promise_test(() => {
122
123
  const rs = new ReadableStream({
124
    cancel() {
125
      return 'Hello';
126
    }
127
  });
128
129
  return rs.cancel().then(v => {
130
    assert_equals(v, undefined, 'cancel() return value should be fulfilled with undefined');
131
  });
132
133
}, 'ReadableStream cancellation: returning a value from the underlying source\'s cancel should not affect the fulfillment value of the promise returned by the stream\'s cancel');
134
135
promise_test(() => {
136
137
  const thrownError = new Error('test');
138
  let cancelCalled = false;
139
140
  const rs = new ReadableStream({
141
    cancel() {
142
      cancelCalled = true;
143
      throw thrownError;
144
    }
145
  });
146
147
  return rs.cancel('test').then(() => {
148
    assert_unreached('cancel should reject');
149
  }, e => {
150
    assert_true(cancelCalled);
151
    assert_equals(e, thrownError);
152
  });
153
154
}, 'ReadableStream cancellation: should reject promise when cancel callback raises an exception');
155
156
promise_test(() => {
157
158
  const cancelReason = new Error('test');
159
160
  const rs = new ReadableStream({
161
    cancel(error) {
162
      assert_equals(error, cancelReason);
163
      return delay(1);
164
    }
165
  });
166
167
  return rs.cancel(cancelReason);
168
169
}, 'ReadableStream cancellation: if the underlying source\'s cancel method returns a promise, the promise returned by the stream\'s cancel should fulfill when that one does (1)');
170
171
promise_test(() => {
172
173
  let resolveSourceCancelPromise;
174
  let sourceCancelPromiseHasFulfilled = false;
175
176
  const rs = new ReadableStream({
177
    cancel() {
178
      const sourceCancelPromise = new Promise(resolve => resolveSourceCancelPromise = resolve);
179
180
      sourceCancelPromise.then(() => {
181
        sourceCancelPromiseHasFulfilled = true;
182
      });
183
184
      return sourceCancelPromise;
185
    }
186
  });
187
188
  setTimeout(() => resolveSourceCancelPromise('Hello'), 1);
189
190
  return rs.cancel().then(value => {
191
    assert_true(sourceCancelPromiseHasFulfilled, 'cancel() return value should be fulfilled only after the promise returned by the underlying source\'s cancel');
192
    assert_equals(value, undefined, 'cancel() return value should be fulfilled with undefined');
193
  });
194
195
}, 'ReadableStream cancellation: if the underlying source\'s cancel method returns a promise, the promise returned by the stream\'s cancel should fulfill when that one does (2)');
196
197
promise_test(() => {
198
199
  let rejectSourceCancelPromise;
200
  let sourceCancelPromiseHasRejected = false;
201
202
  const rs = new ReadableStream({
203
    cancel() {
204
      const sourceCancelPromise = new Promise((resolve, reject) => rejectSourceCancelPromise = reject);
205
206
      sourceCancelPromise.catch(() => {
207
        sourceCancelPromiseHasRejected = true;
208
      });
209
210
      return sourceCancelPromise;
211
    }
212
  });
213
214
  const errorInCancel = new Error('Sorry, it just wasn\'t meant to be.');
215
216
  setTimeout(() => rejectSourceCancelPromise(errorInCancel), 1);
217
218
  return rs.cancel().then(() => {
219
    assert_unreached('cancel() return value should be rejected');
220
  }, r => {
221
    assert_true(sourceCancelPromiseHasRejected, 'cancel() return value should be rejected only after the promise returned by the underlying source\'s cancel');
222
    assert_equals(r, errorInCancel, 'cancel() return value should be rejected with the underlying source\'s rejection reason');
223
  });
224
225
}, 'ReadableStream cancellation: if the underlying source\'s cancel method returns a promise, the promise returned by the stream\'s cancel should reject when that one does');
226
227
promise_test(() => {
228
229
  const rs = new ReadableStream({
230
    start() {
231
      return new Promise(() => {});
232
    },
233
    pull() {
234
      assert_unreached('pull should not have been called');
235
    }
236
  });
237
238
  return Promise.all([rs.cancel(), rs.getReader().closed]);
239
240
}, 'ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called');
241
242
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration-expected.txt +12 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration-expected.txt_sec1
1
2
PASS Can construct a readable stream with a valid CountQueuingStrategy 
3
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 0) 
4
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 1) 
5
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 4) 
6
FAIL Load count-queuing-strategy-integration.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
7
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
8
PASS Can construct a readable stream with a valid CountQueuingStrategy 
9
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 0) 
10
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 1) 
11
PASS Correctly governs a ReadableStreamController's desiredSize property (HWM = 4) 
12
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.html +12 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="count-queuing-strategy-integration.js"></script>
9
<script>
10
'use strict';
11
worker_test('count-queuing-strategy-integration.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.js +213 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/count-queuing-strategy-integration.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
}
6
7
test(() => {
8
9
  new ReadableStream({}, new CountQueuingStrategy({ highWaterMark: 4 }));
10
11
}, 'Can construct a readable stream with a valid CountQueuingStrategy');
12
13
promise_test(() => {
14
15
  let controller;
16
  const rs = new ReadableStream(
17
    {
18
      start(c) {
19
        controller = c;
20
      }
21
    },
22
    new CountQueuingStrategy({ highWaterMark: 0 })
23
  );
24
  const reader = rs.getReader();
25
26
  assert_equals(controller.desiredSize, 0, '0 reads, 0 enqueues: desiredSize should be 0');
27
  controller.enqueue('a');
28
  assert_equals(controller.desiredSize, -1, '0 reads, 1 enqueue: desiredSize should be -1');
29
  controller.enqueue('b');
30
  assert_equals(controller.desiredSize, -2, '0 reads, 2 enqueues: desiredSize should be -2');
31
  controller.enqueue('c');
32
  assert_equals(controller.desiredSize, -3, '0 reads, 3 enqueues: desiredSize should be -3');
33
  controller.enqueue('d');
34
  assert_equals(controller.desiredSize, -4, '0 reads, 4 enqueues: desiredSize should be -4');
35
36
  return reader.read()
37
    .then(result => {
38
      assert_object_equals(result, { value: 'a', done: false },
39
                           '1st read gives back the 1st chunk enqueued (queue now contains 3 chunks)');
40
      return reader.read();
41
    })
42
    .then(result => {
43
      assert_object_equals(result, { value: 'b', done: false },
44
                           '2nd read gives back the 2nd chunk enqueued (queue now contains 2 chunks)');
45
      return reader.read();
46
    })
47
    .then(result => {
48
      assert_object_equals(result, { value: 'c', done: false },
49
                           '3rd read gives back the 3rd chunk enqueued (queue now contains 1 chunk)');
50
51
      assert_equals(controller.desiredSize, -1, '3 reads, 4 enqueues: desiredSize should be -1');
52
      controller.enqueue('e');
53
      assert_equals(controller.desiredSize, -2, '3 reads, 5 enqueues: desiredSize should be -2');
54
55
      return reader.read();
56
    })
57
    .then(result => {
58
      assert_object_equals(result, { value: 'd', done: false },
59
                           '4th read gives back the 4th chunk enqueued (queue now contains 1 chunks)');
60
      return reader.read();
61
62
    }).then(result => {
63
      assert_object_equals(result, { value: 'e', done: false },
64
                           '5th read gives back the 5th chunk enqueued (queue now contains 0 chunks)');
65
66
      assert_equals(controller.desiredSize, 0, '5 reads, 5 enqueues: desiredSize should be 0');
67
      controller.enqueue('f');
68
      assert_equals(controller.desiredSize, -1, '5 reads, 6 enqueues: desiredSize should be -1');
69
      controller.enqueue('g');
70
      assert_equals(controller.desiredSize, -2, '5 reads, 7 enqueues: desiredSize should be -2');
71
    });
72
73
}, 'Correctly governs a ReadableStreamController\'s desiredSize property (HWM = 0)');
74
75
promise_test(() => {
76
77
  let controller;
78
  const rs = new ReadableStream(
79
    {
80
      start(c) {
81
        controller = c;
82
      }
83
    },
84
    new CountQueuingStrategy({ highWaterMark: 1 })
85
  );
86
  const reader = rs.getReader();
87
88
  assert_equals(controller.desiredSize, 1, '0 reads, 0 enqueues: desiredSize should be 1');
89
  controller.enqueue('a');
90
  assert_equals(controller.desiredSize, 0, '0 reads, 1 enqueue: desiredSize should be 0');
91
  controller.enqueue('b');
92
  assert_equals(controller.desiredSize, -1, '0 reads, 2 enqueues: desiredSize should be -1');
93
  controller.enqueue('c');
94
  assert_equals(controller.desiredSize, -2, '0 reads, 3 enqueues: desiredSize should be -2');
95
  controller.enqueue('d');
96
  assert_equals(controller.desiredSize, -3, '0 reads, 4 enqueues: desiredSize should be -3');
97
98
  return reader.read()
99
    .then(result => {
100
      assert_object_equals(result, { value: 'a', done: false },
101
                           '1st read gives back the 1st chunk enqueued (queue now contains 3 chunks)');
102
      return reader.read();
103
    })
104
    .then(result => {
105
      assert_object_equals(result, { value: 'b', done: false },
106
                           '2nd read gives back the 2nd chunk enqueued (queue now contains 2 chunks)');
107
      return reader.read();
108
    })
109
    .then(result => {
110
      assert_object_equals(result, { value: 'c', done: false },
111
                           '3rd read gives back the 3rd chunk enqueued (queue now contains 1 chunk)');
112
113
      assert_equals(controller.desiredSize, 0, '3 reads, 4 enqueues: desiredSize should be 0');
114
      controller.enqueue('e');
115
      assert_equals(controller.desiredSize, -1, '3 reads, 5 enqueues: desiredSize should be -1');
116
117
      return reader.read();
118
    })
119
    .then(result => {
120
      assert_object_equals(result, { value: 'd', done: false },
121
                           '4th read gives back the 4th chunk enqueued (queue now contains 1 chunks)');
122
      return reader.read();
123
    })
124
    .then(result => {
125
      assert_object_equals(result, { value: 'e', done: false },
126
                           '5th read gives back the 5th chunk enqueued (queue now contains 0 chunks)');
127
128
      assert_equals(controller.desiredSize, 1, '5 reads, 5 enqueues: desiredSize should be 1');
129
      controller.enqueue('f');
130
      assert_equals(controller.desiredSize, 0, '5 reads, 6 enqueues: desiredSize should be 0');
131
      controller.enqueue('g');
132
      assert_equals(controller.desiredSize, -1, '5 reads, 7 enqueues: desiredSize should be -1');
133
    });
134
135
}, 'Correctly governs a ReadableStreamController\'s desiredSize property (HWM = 1)');
136
137
promise_test(() => {
138
139
  let controller;
140
  const rs = new ReadableStream(
141
    {
142
      start(c) {
143
        controller = c;
144
      }
145
    },
146
    new CountQueuingStrategy({ highWaterMark: 4 })
147
  );
148
  const reader = rs.getReader();
149
150
  assert_equals(controller.desiredSize, 4, '0 reads, 0 enqueues: desiredSize should be 4');
151
  controller.enqueue('a');
152
  assert_equals(controller.desiredSize, 3, '0 reads, 1 enqueue: desiredSize should be 3');
153
  controller.enqueue('b');
154
  assert_equals(controller.desiredSize, 2, '0 reads, 2 enqueues: desiredSize should be 2');
155
  controller.enqueue('c');
156
  assert_equals(controller.desiredSize, 1, '0 reads, 3 enqueues: desiredSize should be 1');
157
  controller.enqueue('d');
158
  assert_equals(controller.desiredSize, 0, '0 reads, 4 enqueues: desiredSize should be 0');
159
  controller.enqueue('e');
160
  assert_equals(controller.desiredSize, -1, '0 reads, 5 enqueues: desiredSize should be -1');
161
  controller.enqueue('f');
162
  assert_equals(controller.desiredSize, -2, '0 reads, 6 enqueues: desiredSize should be -2');
163
164
165
  reader.read()
166
    .then(result => {
167
      assert_object_equals(result, { value: 'a', done: false },
168
                           '1st read gives back the 1st chunk enqueued (queue now contains 5 chunks)');
169
      return reader.read();
170
    })
171
    .then(result => {
172
      assert_object_equals(result, { value: 'b', done: false },
173
                           '2nd read gives back the 2nd chunk enqueued (queue now contains 4 chunks)');
174
175
      assert_equals(controller.desiredSize, 0, '2 reads, 6 enqueues: desiredSize should be 0');
176
      controller.enqueue('g');
177
      assert_equals(controller.desiredSize, -1, '2 reads, 7 enqueues: desiredSize should be -1');
178
179
      return reader.read();
180
    })
181
    .then(result => {
182
      assert_object_equals(result, { value: 'c', done: false },
183
                           '3rd read gives back the 3rd chunk enqueued (queue now contains 4 chunks)');
184
      return reader.read();
185
    })
186
    .then(result => {
187
      assert_object_equals(result, { value: 'd', done: false },
188
                           '4th read gives back the 4th chunk enqueued (queue now contains 3 chunks)');
189
      return reader.read();
190
    })
191
    .then(result => {
192
      assert_object_equals(result, { value: 'e', done: false },
193
                           '5th read gives back the 5th chunk enqueued (queue now contains 2 chunks)');
194
      return reader.read();
195
    })
196
    .then(result => {
197
      assert_object_equals(result, { value: 'f', done: false },
198
                           '6th read gives back the 6th chunk enqueued (queue now contains 0 chunks)');
199
200
      assert_equals(controller.desiredSize, 3, '6 reads, 7 enqueues: desiredSize should be 3');
201
      controller.enqueue('h');
202
      assert_equals(controller.desiredSize, 2, '6 reads, 8 enqueues: desiredSize should be 2');
203
      controller.enqueue('i');
204
      assert_equals(controller.desiredSize, 1, '6 reads, 9 enqueues: desiredSize should be 1');
205
      controller.enqueue('j');
206
      assert_equals(controller.desiredSize, 0, '6 reads, 10 enqueues: desiredSize should be 0');
207
      controller.enqueue('k');
208
      assert_equals(controller.desiredSize, -1, '6 reads, 11 enqueues: desiredSize should be -1');
209
    });
210
211
}, 'Correctly governs a ReadableStreamController\'s desiredSize property (HWM = 4)');
212
213
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-1-expected.txt +6 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-1-expected.txt_sec1
1
2
PASS ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream 
3
PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost 
4
PASS ReadableStream closed promise should reject even if stream and reader JS references are lost 
5
PASS Garbage-collecting a ReadableStreamReader should not unlock its stream 
6
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-1.html +10 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-1.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<!-- File to be removed once https://bugs.webkit.org/show_bug.cgi?id=152436 is resolved -->
10
<script src="garbage-collection.js"></script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-2-expected.txt +4 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-2-expected.txt_sec1
1
2
PASS ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream 
3
PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost 
4
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-2.html +48 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-2.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<!-- File to be removed once https://bugs.webkit.org/show_bug.cgi?id=152436 is resolved -->
10
<script>
11
'use strict';
12
13
promise_test(() => {
14
15
  let controller;
16
  new ReadableStream({
17
    start(c) {
18
      controller = c;
19
    }
20
  });
21
22
  garbageCollect();
23
24
  return delay(50).then(() => {
25
    controller.close();
26
    assert_throws(new TypeError(), () => controller.close(), 'close should throw a TypeError the second time');
27
    assert_throws(new TypeError(), () => controller.error(), 'error should throw a TypeError on a closed stream');
28
  });
29
30
}, 'ReadableStreamController methods should continue working properly when scripts lose their reference to the ' +
31
   'readable stream');
32
33
promise_test(() => {
34
35
  let controller;
36
37
  const closedPromise = new ReadableStream({
38
    start(c) {
39
      controller = c;
40
    }
41
  }).getReader().closed;
42
43
  garbageCollect();
44
45
  return delay(50).then(() => controller.close()).then(() => closedPromise);
46
47
}, 'ReadableStream closed promise should fulfill even if the stream and reader JS references are lost');
48
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-expected.txt +16 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection-expected.txt_sec1
1
CONSOLE MESSAGE: line 37: Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.
2
CONSOLE MESSAGE: line 37: Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.
3
CONSOLE MESSAGE: line 37: Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.
4
CONSOLE MESSAGE: line 37: Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.
5
6
PASS ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream 
7
PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost 
8
PASS ReadableStream closed promise should reject even if stream and reader JS references are lost 
9
PASS Garbage-collecting a ReadableStreamReader should not unlock its stream 
10
FAIL Load garbage-collection.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
11
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
12
PASS ReadableStreamController methods should continue working properly when scripts lose their reference to the readable stream 
13
PASS ReadableStream closed promise should fulfill even if the stream and reader JS references are lost 
14
PASS ReadableStream closed promise should reject even if stream and reader JS references are lost 
15
PASS Garbage-collecting a ReadableStreamReader should not unlock its stream 
16
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.html +13 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="garbage-collection.js"></script>
10
<script>
11
'use strict';
12
worker_test('garbage-collection.js');
13
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.js +75 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/garbage-collection.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
promise_test(() => {
9
10
  let controller;
11
  new ReadableStream({
12
    start(c) {
13
      controller = c;
14
    }
15
  });
16
17
  garbageCollect();
18
19
  return delay(50).then(() => {
20
    controller.close();
21
    assert_throws(new TypeError(), () => controller.close(), 'close should throw a TypeError the second time');
22
    assert_throws(new TypeError(), () => controller.error(), 'error should throw a TypeError on a closed stream');
23
  });
24
25
}, 'ReadableStreamController methods should continue working properly when scripts lose their reference to the ' +
26
   'readable stream');
27
28
promise_test(() => {
29
30
  let controller;
31
32
  const closedPromise = new ReadableStream({
33
    start(c) {
34
      controller = c;
35
    }
36
  }).getReader().closed;
37
38
  garbageCollect();
39
40
  return delay(50).then(() => controller.close()).then(() => closedPromise);
41
42
}, 'ReadableStream closed promise should fulfill even if the stream and reader JS references are lost');
43
44
promise_test(t => {
45
46
  const theError = new Error('boo');
47
  let controller;
48
49
  const closedPromise = new ReadableStream({
50
    start(c) {
51
      controller = c;
52
    }
53
  }).getReader().closed;
54
55
  garbageCollect();
56
57
  return delay(50).then(() => controller.error(theError))
58
                  .then(() => promise_rejects(t, theError, closedPromise));
59
60
}, 'ReadableStream closed promise should reject even if stream and reader JS references are lost');
61
62
promise_test(() => {
63
64
  const rs = new ReadableStream({});
65
66
  rs.getReader();
67
68
  garbageCollect();
69
70
  return delay(50).then(() => assert_throws(new TypeError(), () => rs.getReader(),
71
    'old reader should still be locking the stream even after garbage collection'));
72
73
}, 'Garbage-collecting a ReadableStreamReader should not unlock its stream');
74
75
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general-expected.txt +70 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general-expected.txt_sec1
1
2
PASS ReadableStream can be constructed with no errors 
3
PASS ReadableStream can't be constructed with garbage 
4
FAIL ReadableStream instances should have the correct list of properties assert_false: method should be non-enumerable expected false got true
5
PASS ReadableStream constructor should throw for non-function start arguments 
6
PASS ReadableStream constructor can get initial garbage as cancel argument 
7
PASS ReadableStream constructor can get initial garbage as pull argument 
8
FAIL ReadableStream start should be called with the proper parameters assert_false: close should be non-enumerable expected false got true
9
PASS ReadableStream start controller parameter should be extensible 
10
PASS ReadableStream should be able to call start method within prototype chain of its source 
11
PASS ReadableStream start should be able to return a promise 
12
PASS ReadableStream start should be able to return a promise and reject it 
13
PASS ReadableStream should be able to enqueue different objects. 
14
PASS ReadableStream: if pull rejects, it should error the stream 
15
PASS ReadableStream: should only call pull once upon starting the stream 
16
PASS ReadableStream: should call pull when trying to read from a started, empty stream 
17
PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills 
18
PASS ReadableStream: should only call pull once on a non-empty stream read from after start fulfills 
19
PASS ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining 
20
PASS ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining 
21
PASS ReadableStream: should not call pull until the previous pull call's promise fulfills 
22
PASS ReadableStream: should pull after start, and after every read 
23
PASS ReadableStream: should not call pull after start if the stream is now closed 
24
PASS ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows 
25
PASS ReadableStream pull should be able to close a stream. 
26
PASS ReadableStream: enqueue should throw when the stream is readable but draining 
27
PASS ReadableStream: enqueue should throw when the stream is closed 
28
PASS ReadableStream: enqueue should throw the stored error when the stream is errored 
29
PASS ReadableStream: should call underlying source methods as methods 
30
PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue 
31
PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately 
32
PASS ReadableStream integration test: adapting a random push source 
33
PASS ReadableStream integration test: adapting a sync pull source 
34
PASS ReadableStream integration test: adapting an async pull source 
35
FAIL Load general.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
36
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
37
PASS ReadableStream can be constructed with no errors 
38
PASS ReadableStream can't be constructed with garbage 
39
FAIL ReadableStream instances should have the correct list of properties assert_false: method should be non-enumerable expected false got true
40
PASS ReadableStream constructor should throw for non-function start arguments 
41
PASS ReadableStream constructor can get initial garbage as cancel argument 
42
PASS ReadableStream constructor can get initial garbage as pull argument 
43
FAIL ReadableStream start should be called with the proper parameters assert_false: close should be non-enumerable expected false got true
44
PASS ReadableStream start controller parameter should be extensible 
45
PASS ReadableStream should be able to call start method within prototype chain of its source 
46
PASS ReadableStream start should be able to return a promise 
47
PASS ReadableStream start should be able to return a promise and reject it 
48
PASS ReadableStream should be able to enqueue different objects. 
49
PASS ReadableStream: if pull rejects, it should error the stream 
50
PASS ReadableStream: should only call pull once upon starting the stream 
51
PASS ReadableStream: should call pull when trying to read from a started, empty stream 
52
PASS ReadableStream: should only call pull once on a non-empty stream read from before start fulfills 
53
PASS ReadableStream: should only call pull once on a non-empty stream read from after start fulfills 
54
PASS ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining 
55
PASS ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining 
56
PASS ReadableStream: should not call pull until the previous pull call's promise fulfills 
57
PASS ReadableStream: should pull after start, and after every read 
58
PASS ReadableStream: should not call pull after start if the stream is now closed 
59
PASS ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows 
60
PASS ReadableStream pull should be able to close a stream. 
61
PASS ReadableStream: enqueue should throw when the stream is readable but draining 
62
PASS ReadableStream: enqueue should throw when the stream is closed 
63
PASS ReadableStream: enqueue should throw the stored error when the stream is errored 
64
PASS ReadableStream: should call underlying source methods as methods 
65
PASS ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue 
66
PASS ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately 
67
PASS ReadableStream integration test: adapting a random push source 
68
PASS ReadableStream integration test: adapting a sync pull source 
69
PASS ReadableStream integration test: adapting an async pull source 
70
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.html +14 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="../resources/rs-utils.js"></script>
10
<script src="general.js"></script>
11
<script>
12
'use strict';
13
worker_test('general.js');
14
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.js +831 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('../resources/rs-utils.js');
6
  self.importScripts('/resources/testharness.js');
7
}
8
9
test(() => {
10
11
  new ReadableStream(); // ReadableStream constructed with no parameters
12
  new ReadableStream({ }); // ReadableStream constructed with an empty object as parameter
13
  new ReadableStream(undefined); // ReadableStream constructed with undefined as parameter
14
15
  let x;
16
  new ReadableStream(x); // ReadableStream constructed with an undefined variable as parameter
17
18
}, 'ReadableStream can be constructed with no errors');
19
20
test(() => {
21
22
  assert_throws(new TypeError(), () => new ReadableStream(null), 'constructor should throw when the source is null');
23
24
}, 'ReadableStream can\'t be constructed with garbage');
25
26
test(() => {
27
28
  const methods = ['cancel', 'constructor', 'getReader', 'pipeThrough', 'pipeTo', 'tee'];
29
  const properties = methods.concat(['locked']).sort();
30
31
  const rs = new ReadableStream();
32
  const proto = Object.getPrototypeOf(rs);
33
34
  assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties, 'should have all the correct methods');
35
36
  for (const m of methods) {
37
    const propDesc = Object.getOwnPropertyDescriptor(proto, m);
38
    assert_false(propDesc.enumerable, 'method should be non-enumerable');
39
    assert_true(propDesc.configurable, 'method should be configurable');
40
    assert_true(propDesc.writable, 'method should be writable');
41
    assert_equals(typeof rs[m], 'function', 'method should be a function');
42
  }
43
44
  const lockedPropDesc = Object.getOwnPropertyDescriptor(proto, 'locked');
45
  assert_false(lockedPropDesc.enumerable, 'locked should be non-enumerable');
46
  assert_equals(lockedPropDesc.writable, undefined, 'locked should not be a data property');
47
  assert_equals(typeof lockedPropDesc.get, 'function', 'locked should have a getter');
48
  assert_equals(lockedPropDesc.set, undefined, 'locked should not have a setter');
49
  assert_true(lockedPropDesc.configurable, 'locked should be configurable');
50
51
  assert_equals(rs.cancel.length, 1, 'cancel should have 1 parameter');
52
  assert_equals(rs.constructor.length, 0, 'constructor should have no parameters');
53
  assert_equals(rs.getReader.length, 0, 'getReader should have no parameters');
54
  assert_equals(rs.pipeThrough.length, 2, 'pipeThrough should have 2 parameters');
55
  assert_equals(rs.pipeTo.length, 1, 'pipeTo should have 1 parameter');
56
  assert_equals(rs.tee.length, 0, 'tee should have no parameters');
57
58
}, 'ReadableStream instances should have the correct list of properties');
59
60
test(() => {
61
62
  assert_throws(new TypeError(), () => {
63
    new ReadableStream({ start: 'potato' });
64
  }, 'constructor should throw when start is not a function');
65
66
}, 'ReadableStream constructor should throw for non-function start arguments');
67
68
test(() => {
69
70
  new ReadableStream({ cancel: '2' });
71
72
}, 'ReadableStream constructor can get initial garbage as cancel argument');
73
74
test(() => {
75
76
  new ReadableStream({ pull: { } });
77
78
}, 'ReadableStream constructor can get initial garbage as pull argument');
79
80
test(() => {
81
82
  let startCalled = false;
83
84
  const source = {
85
    start(controller) {
86
      assert_equals(this, source, 'source is this during start');
87
88
      const methods = ['close', 'enqueue', 'error', 'constructor'];
89
      const properties = ['desiredSize'].concat(methods).sort();
90
      const proto = Object.getPrototypeOf(controller);
91
92
      assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties,
93
        'the controller should have the right properties');
94
95
      for (const m of methods) {
96
        const propDesc = Object.getOwnPropertyDescriptor(proto, m);
97
        assert_equals(typeof controller[m], 'function', `should have a ${m} method`);
98
        assert_false(propDesc.enumerable, m + ' should be non-enumerable');
99
        assert_true(propDesc.configurable, m + ' should be configurable');
100
        assert_true(propDesc.writable, m + ' should be writable');
101
      }
102
103
      const desiredSizePropDesc = Object.getOwnPropertyDescriptor(proto, 'desiredSize');
104
      assert_false(desiredSizePropDesc.enumerable, 'desiredSize should be non-enumerable');
105
      assert_equals(desiredSizePropDesc.writable, undefined, 'desiredSize should not be a data property');
106
      assert_equals(typeof desiredSizePropDesc.get, 'function', 'desiredSize should have a getter');
107
      assert_equals(desiredSizePropDesc.set, undefined, 'desiredSize should not have a setter');
108
      assert_true(desiredSizePropDesc.configurable, 'desiredSize should be configurable');
109
110
      assert_equals(controller.close.length, 0, 'close should have no parameters');
111
      assert_equals(controller.constructor.length, 1, 'constructor should have 1 parameter');
112
      assert_equals(controller.enqueue.length, 1, 'enqueue should have 1 parameter');
113
      assert_equals(controller.error.length, 1, 'error should have 1 parameter');
114
115
      startCalled = true;
116
    }
117
  };
118
119
  new ReadableStream(source);
120
  assert_true(startCalled);
121
122
}, 'ReadableStream start should be called with the proper parameters');
123
124
test(() => {
125
126
  let startCalled = false;
127
  const source = {
128
    start(controller) {
129
      const properties = ['close', 'constructor', 'desiredSize', 'enqueue', 'error'];
130
      assert_array_equals(Object.getOwnPropertyNames(Object.getPrototypeOf(controller)).sort(), properties,
131
        'prototype should have the right properties');
132
133
      controller.test = '';
134
      assert_array_equals(Object.getOwnPropertyNames(Object.getPrototypeOf(controller)).sort(), properties,
135
        'prototype should still have the right properties');
136
      assert_not_equals(Object.getOwnPropertyNames(controller).indexOf('test'), -1,
137
        '"test" should be a property of the controller');
138
139
      startCalled = true;
140
    }
141
  };
142
143
  new ReadableStream(source);
144
  assert_true(startCalled);
145
146
}, 'ReadableStream start controller parameter should be extensible');
147
148
promise_test(() => {
149
150
  function SimpleStreamSource() {}
151
  let resolve;
152
  const promise = new Promise(r => resolve = r);
153
  SimpleStreamSource.prototype = {
154
    start: resolve
155
  };
156
157
  new ReadableStream(new SimpleStreamSource());
158
  return promise;
159
160
}, 'ReadableStream should be able to call start method within prototype chain of its source');
161
162
promise_test(() => {
163
164
  const rs = new ReadableStream({
165
    start(c) {
166
      return delay(5).then(() => {
167
        c.enqueue('a');
168
        c.close();
169
      });
170
    }
171
  });
172
173
  const reader = rs.getReader();
174
  return reader.read().then(r => {
175
    assert_object_equals(r, { value: 'a', done: false }, 'value read should be the one enqueued');
176
    return reader.closed;
177
  });
178
179
}, 'ReadableStream start should be able to return a promise');
180
181
promise_test(() => {
182
183
  const theError = new Error('rejected!');
184
  const rs = new ReadableStream({
185
    start() {
186
      return delay(1).then(() => { throw theError; });
187
    }
188
  });
189
190
  return rs.getReader().closed.then(() => {
191
    assert_unreached('closed promise should be rejected');
192
  }, e => {
193
    assert_equals(e, theError, 'promise should be rejected with the same error');
194
  });
195
196
}, 'ReadableStream start should be able to return a promise and reject it');
197
198
promise_test(() => {
199
200
  const objects = [
201
    { potato: 'Give me more!' },
202
    'test',
203
    1
204
  ];
205
206
  const rs = new ReadableStream({
207
    start(c) {
208
      for (const o of objects) {
209
        c.enqueue(o);
210
      }
211
      c.close();
212
    }
213
  });
214
215
  const reader = rs.getReader();
216
217
  return Promise.all([reader.read(), reader.read(), reader.read(), reader.closed]).then(r => {
218
    assert_object_equals(r[0], { value: objects[0], done: false }, 'value read should be the one enqueued');
219
    assert_object_equals(r[1], { value: objects[1], done: false }, 'value read should be the one enqueued');
220
    assert_object_equals(r[2], { value: objects[2], done: false }, 'value read should be the one enqueued');
221
  });
222
223
}, 'ReadableStream should be able to enqueue different objects.');
224
225
promise_test(() => {
226
227
  const error = new Error('pull failure');
228
  const rs = new ReadableStream({
229
    pull() {
230
      return Promise.reject(error);
231
    }
232
  });
233
234
  const reader = rs.getReader();
235
236
  let closed = false;
237
  let read = false;
238
239
  return Promise.all([
240
    reader.closed.then(() => {
241
      assert_unreached('closed should be rejected');
242
    }, e => {
243
      closed = true;
244
      assert_true(read);
245
      assert_equals(e, error, 'closed should be rejected with the thrown error');
246
    }),
247
    reader.read().then(() => {
248
      assert_unreached('read() should be rejected');
249
    }, e => {
250
      read = true;
251
      assert_false(closed);
252
      assert_equals(e, error, 'read() should be rejected with the thrown error');
253
    })
254
  ]);
255
256
}, 'ReadableStream: if pull rejects, it should error the stream');
257
258
promise_test(() => {
259
260
  let pullCount = 0;
261
  const startPromise = Promise.resolve();
262
263
  new ReadableStream({
264
    start() {
265
      return startPromise;
266
    },
267
    pull() {
268
      pullCount++;
269
    }
270
  });
271
272
  return startPromise.then(() => {
273
    assert_equals(pullCount, 1, 'pull should be called once start finishes');
274
    return delay(10);
275
  }).then(() => {
276
    assert_equals(pullCount, 1, 'pull should be called exactly once');
277
  });
278
279
}, 'ReadableStream: should only call pull once upon starting the stream');
280
281
promise_test(() => {
282
283
  let pullCount = 0;
284
285
  const rs = new ReadableStream({
286
    pull(c) {
287
      // Don't enqueue immediately after start. We want the stream to be empty when we call .read() on it.
288
      if (pullCount > 0) {
289
        c.enqueue(pullCount);
290
      }
291
      ++pullCount;
292
    }
293
  });
294
295
  return delay(1).then(() => {
296
    assert_equals(pullCount, 1, 'pull should be called once start finishes');
297
298
    const reader = rs.getReader();
299
    const read = reader.read();
300
    assert_equals(pullCount, 2, 'pull should be called when read is called');
301
    return read;
302
  }).then(result => {
303
    assert_equals(pullCount, 3, 'pull should be called again in reaction to calling read');
304
    assert_object_equals(result, { value: 1, done: false }, 'the result read should be the one enqueued');
305
  });
306
307
}, 'ReadableStream: should call pull when trying to read from a started, empty stream');
308
309
promise_test(() => {
310
311
  let pullCount = 0;
312
  const startPromise = Promise.resolve();
313
314
  const rs = new ReadableStream({
315
    start(c) {
316
      c.enqueue('a');
317
      return startPromise;
318
    },
319
    pull() {
320
      pullCount++;
321
    }
322
  });
323
324
  const read = rs.getReader().read();
325
  assert_equals(pullCount, 0, 'calling read() should not cause pull to be called yet');
326
327
  return startPromise.then(() => {
328
    assert_equals(pullCount, 1, 'pull should be called once start finishes');
329
    return read;
330
  }).then(r => {
331
    assert_object_equals(r, { value: 'a', done: false }, 'first read() should return first chunk');
332
    assert_equals(pullCount, 1, 'pull should not have been called again');
333
    return delay(10);
334
  }).then(() => {
335
    assert_equals(pullCount, 1, 'pull should be called exactly once');
336
  });
337
338
}, 'ReadableStream: should only call pull once on a non-empty stream read from before start fulfills');
339
340
promise_test(() => {
341
342
  let pullCount = 0;
343
  const startPromise = Promise.resolve();
344
345
  const rs = new ReadableStream({
346
    start(c) {
347
      c.enqueue('a');
348
      return startPromise;
349
    },
350
    pull() {
351
      pullCount++;
352
    }
353
  });
354
355
  return startPromise.then(() => {
356
    assert_equals(pullCount, 0, 'pull should not be called once start finishes, since the queue is full');
357
358
    const read = rs.getReader().read();
359
    assert_equals(pullCount, 1, 'calling read() should cause pull to be called immediately');
360
    return read;
361
  }).then(r => {
362
    assert_object_equals(r, { value: 'a', done: false }, 'first read() should return first chunk');
363
    return delay(10);
364
  }).then(() => {
365
    assert_equals(pullCount, 1, 'pull should be called exactly once');
366
  });
367
368
}, 'ReadableStream: should only call pull once on a non-empty stream read from after start fulfills');
369
370
promise_test(() => {
371
372
  let pullCount = 0;
373
  let controller;
374
  const startPromise = Promise.resolve();
375
376
  const rs = new ReadableStream({
377
    start(c) {
378
      controller = c;
379
      return startPromise;
380
    },
381
    pull() {
382
      ++pullCount;
383
    }
384
  });
385
386
  const reader = rs.getReader();
387
  return startPromise.then(() => {
388
    assert_equals(pullCount, 1, 'pull should have been called once by the time the stream starts');
389
390
    controller.enqueue('a');
391
    assert_equals(pullCount, 1, 'pull should not have been called again after enqueue');
392
393
    return reader.read();
394
  }).then(() => {
395
    assert_equals(pullCount, 2, 'pull should have been called again after read');
396
397
    return delay(10);
398
  }).then(() => {
399
    assert_equals(pullCount, 2, 'pull should be called exactly twice');
400
  });
401
}, 'ReadableStream: should call pull in reaction to read()ing the last chunk, if not draining');
402
403
promise_test(() => {
404
405
  let pullCount = 0;
406
  let controller;
407
  const startPromise = Promise.resolve();
408
409
  const rs = new ReadableStream({
410
    start(c) {
411
      controller = c;
412
      return startPromise;
413
    },
414
    pull() {
415
      ++pullCount;
416
    }
417
  });
418
419
  const reader = rs.getReader();
420
421
  return startPromise.then(() => {
422
    assert_equals(pullCount, 1, 'pull should have been called once by the time the stream starts');
423
424
    controller.enqueue('a');
425
    assert_equals(pullCount, 1, 'pull should not have been called again after enqueue');
426
427
    controller.close();
428
429
    return reader.read();
430
  }).then(() => {
431
    assert_equals(pullCount, 1, 'pull should not have been called a second time after read');
432
433
    return delay(10);
434
  }).then(() => {
435
    assert_equals(pullCount, 1, 'pull should be called exactly once');
436
  });
437
438
}, 'ReadableStream: should not call pull() in reaction to read()ing the last chunk, if draining');
439
440
promise_test(() => {
441
442
  let resolve;
443
  let returnedPromise;
444
  let timesCalled = 0;
445
  const startPromise = Promise.resolve();
446
447
  const rs = new ReadableStream({
448
    start() {
449
      return startPromise;
450
    },
451
    pull(c) {
452
      c.enqueue(++timesCalled);
453
      returnedPromise = new Promise(r => resolve = r);
454
      return returnedPromise;
455
    }
456
  });
457
  const reader = rs.getReader();
458
459
  return startPromise.then(() => {
460
    return reader.read();
461
  }).then(result1 => {
462
    assert_equals(timesCalled, 1,
463
      'pull should have been called once after start, but not yet have been called a second time');
464
    assert_object_equals(result1, { value: 1, done: false }, 'read() should fulfill with the enqueued value');
465
466
    return delay(10);
467
  }).then(() => {
468
    assert_equals(timesCalled, 1, 'after 10 ms, pull should still only have been called once');
469
470
    resolve();
471
    return returnedPromise;
472
  }).then(() => {
473
    assert_equals(timesCalled, 2,
474
      'after the promise returned by pull is fulfilled, pull should be called a second time');
475
  });
476
477
}, 'ReadableStream: should not call pull until the previous pull call\'s promise fulfills');
478
479
promise_test(() => {
480
481
  let timesCalled = 0;
482
  const startPromise = Promise.resolve();
483
484
  const rs = new ReadableStream(
485
    {
486
      start(c) {
487
        c.enqueue('a');
488
        c.enqueue('b');
489
        c.enqueue('c');
490
        return startPromise;
491
      },
492
      pull() {
493
        ++timesCalled;
494
      }
495
    },
496
    {
497
      size() {
498
        return 1;
499
      },
500
      highWaterMark: Infinity
501
    }
502
  );
503
  const reader = rs.getReader();
504
505
  return startPromise.then(() => {
506
    return reader.read();
507
  }).then(result1 => {
508
    assert_object_equals(result1, { value: 'a', done: false }, 'first chunk should be as expected');
509
510
    return reader.read();
511
  }).then(result2 => {
512
    assert_object_equals(result2, { value: 'b', done: false }, 'second chunk should be as expected');
513
514
    return reader.read();
515
  }).then(result3 => {
516
    assert_object_equals(result3, { value: 'c', done: false }, 'third chunk should be as expected');
517
518
    return delay(10);
519
  }).then(() => {
520
    // Once for after start, and once for every read.
521
    assert_equals(timesCalled, 4, 'pull() should be called exactly four times');
522
  });
523
524
}, 'ReadableStream: should pull after start, and after every read');
525
526
promise_test(() => {
527
528
  let timesCalled = 0;
529
  const startPromise = Promise.resolve();
530
531
  const rs = new ReadableStream({
532
    start(c) {
533
      c.enqueue('a');
534
      c.close();
535
      return startPromise;
536
    },
537
    pull() {
538
      ++timesCalled;
539
    }
540
  });
541
542
  const reader = rs.getReader();
543
  return startPromise.then(() => {
544
    assert_equals(timesCalled, 0, 'after start finishes, pull should not have been called');
545
546
    return reader.read();
547
  }).then(() => {
548
    assert_equals(timesCalled, 0, 'reading should not have triggered a pull call');
549
550
    return reader.closed;
551
  }).then(() => {
552
    assert_equals(timesCalled, 0, 'stream should have closed with still no calls to pull');
553
  });
554
555
}, 'ReadableStream: should not call pull after start if the stream is now closed');
556
557
promise_test(() => {
558
559
  let timesCalled = 0;
560
  let resolve;
561
  const ready = new Promise(r => resolve = r);
562
563
  new ReadableStream(
564
    {
565
      start() {},
566
      pull(c) {
567
        c.enqueue(++timesCalled);
568
569
        if (timesCalled === 4) {
570
          resolve();
571
        }
572
      }
573
    },
574
    {
575
      size() {
576
        return 1;
577
      },
578
      highWaterMark: 4
579
    }
580
  );
581
582
  return ready.then(() => {
583
    // after start: size = 0, pull()
584
    // after enqueue(1): size = 1, pull()
585
    // after enqueue(2): size = 2, pull()
586
    // after enqueue(3): size = 3, pull()
587
    // after enqueue(4): size = 4, do not pull
588
    assert_equals(timesCalled, 4, 'pull() should have been called four times');
589
  });
590
591
}, 'ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows');
592
593
promise_test(() => {
594
595
  let pullCalled = false;
596
597
  const rs = new ReadableStream({
598
    pull(c) {
599
      pullCalled = true;
600
      c.close();
601
    }
602
  });
603
604
  const reader = rs.getReader();
605
  return reader.closed.then(() => {
606
    assert_true(pullCalled);
607
  });
608
609
}, 'ReadableStream pull should be able to close a stream.');
610
611
test(() => {
612
613
  let startCalled = false;
614
615
  new ReadableStream({
616
    start(c) {
617
      assert_equals(c.enqueue('a'), undefined, 'the first enqueue should return undefined');
618
      c.close();
619
620
      assert_throws(new TypeError(), () => c.enqueue('b'), 'enqueue after close should throw a TypeError');
621
      startCalled = true;
622
    }
623
  });
624
625
  assert_true(startCalled);
626
627
}, 'ReadableStream: enqueue should throw when the stream is readable but draining');
628
629
test(() => {
630
631
  let startCalled = false;
632
633
  new ReadableStream({
634
    start(c) {
635
      c.close();
636
637
      assert_throws(new TypeError(), () => c.enqueue('a'), 'enqueue after close should throw a TypeError');
638
      startCalled = true;
639
    }
640
  });
641
642
  assert_true(startCalled);
643
644
}, 'ReadableStream: enqueue should throw when the stream is closed');
645
646
test(() => {
647
648
  let startCalled = false;
649
  const expectedError = new Error('i am sad');
650
651
  new ReadableStream({
652
    start(c) {
653
      c.error(expectedError);
654
655
      assert_throws(expectedError, () => c.enqueue('a'), 'enqueue after error should throw that error');
656
      startCalled = true;
657
    }
658
  });
659
660
  assert_true(startCalled);
661
662
}, 'ReadableStream: enqueue should throw the stored error when the stream is errored');
663
664
promise_test(() => {
665
666
  let startCalled = 0;
667
  let pullCalled = 0;
668
  let cancelCalled = 0;
669
670
  /* eslint-disable no-use-before-define */
671
  class Source {
672
    start(c) {
673
      startCalled++;
674
      assert_equals(this, theSource, 'start() should be called with the correct this');
675
      c.enqueue('a');
676
    }
677
678
    pull() {
679
      pullCalled++;
680
      assert_equals(this, theSource, 'pull() should be called with the correct this');
681
    }
682
683
    cancel() {
684
      cancelCalled++;
685
      assert_equals(this, theSource, 'cancel() should be called with the correct this');
686
    }
687
  }
688
  /* eslint-enable no-use-before-define */
689
690
  const theSource = new Source();
691
  theSource.debugName = 'the source object passed to the constructor'; // makes test failures easier to diagnose
692
693
  const rs = new ReadableStream(theSource);
694
  const reader = rs.getReader();
695
696
  return reader.read().then(() => {
697
    reader.releaseLock();
698
    rs.cancel();
699
    assert_equals(startCalled, 1);
700
    assert_equals(pullCalled, 1);
701
    assert_equals(cancelCalled, 1);
702
    return rs.getReader().closed;
703
  });
704
705
}, 'ReadableStream: should call underlying source methods as methods');
706
707
test(() => {
708
709
  let startCalled = false;
710
  new ReadableStream({
711
    start(c) {
712
      assert_equals(c.desiredSize, 1);
713
      c.enqueue('a');
714
      assert_equals(c.desiredSize, 0);
715
      c.enqueue('b');
716
      assert_equals(c.desiredSize, -1);
717
      c.enqueue('c');
718
      assert_equals(c.desiredSize, -2);
719
      c.enqueue('d');
720
      assert_equals(c.desiredSize, -3);
721
      c.enqueue('e');
722
      startCalled = true;
723
    }
724
  });
725
726
  assert_true(startCalled);
727
728
}, 'ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue');
729
730
promise_test(() => {
731
732
  let controller;
733
  const rs = new ReadableStream({
734
    start(c) {
735
      controller = c;
736
    }
737
  });
738
  const reader = rs.getReader();
739
740
  assert_equals(controller.desiredSize, 1, 'desiredSize should start at 1');
741
  controller.enqueue('a');
742
  assert_equals(controller.desiredSize, 0, 'desiredSize should decrease to 0 after first enqueue');
743
744
  return reader.read().then(result1 => {
745
    assert_object_equals(result1, { value: 'a', done: false }, 'first chunk read should be correct');
746
747
    assert_equals(controller.desiredSize, 1, 'desiredSize should go up to 1 after the first read');
748
    controller.enqueue('b');
749
    assert_equals(controller.desiredSize, 0, 'desiredSize should go down to 0 after the second enqueue');
750
751
    return reader.read();
752
  }).then(result2 => {
753
    assert_object_equals(result2, { value: 'b', done: false }, 'second chunk read should be correct');
754
755
    assert_equals(controller.desiredSize, 1, 'desiredSize should go up to 1 after the second read');
756
    controller.enqueue('c');
757
    assert_equals(controller.desiredSize, 0, 'desiredSize should go down to 0 after the third enqueue');
758
759
    return reader.read();
760
  }).then(result3 => {
761
    assert_object_equals(result3, { value: 'c', done: false }, 'third chunk read should be correct');
762
763
    assert_equals(controller.desiredSize, 1, 'desiredSize should go up to 1 after the third read');
764
    controller.enqueue('d');
765
    assert_equals(controller.desiredSize, 0, 'desiredSize should go down to 0 after the fourth enqueue');
766
  });
767
768
}, 'ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately');
769
770
promise_test(t => {
771
772
  const randomSource = new RandomPushSource(8);
773
774
  const rs = new ReadableStream({
775
    start(c) {
776
      assert_equals(typeof c, 'object', 'c should be an object in start');
777
      assert_equals(typeof c.enqueue, 'function', 'enqueue should be a function in start');
778
      assert_equals(typeof c.close, 'function', 'close should be a function in start');
779
      assert_equals(typeof c.error, 'function', 'error should be a function in start');
780
781
      randomSource.ondata = t.step_func(chunk => {
782
        if (!c.enqueue(chunk) <= 0) {
783
          randomSource.readStop();
784
        }
785
      });
786
787
      randomSource.onend = c.close.bind(c);
788
      randomSource.onerror = c.error.bind(c);
789
    },
790
791
    pull(c) {
792
      assert_equals(typeof c, 'object', 'c should be an object in pull');
793
      assert_equals(typeof c.enqueue, 'function', 'enqueue should be a function in pull');
794
      assert_equals(typeof c.close, 'function', 'close should be a function in pull');
795
796
      randomSource.readStart();
797
    }
798
  });
799
800
  return readableStreamToArray(rs).then(chunks => {
801
    assert_equals(chunks.length, 8, '8 chunks should be read');
802
    for (const chunk of chunks) {
803
      assert_equals(chunk.length, 128, 'chunk should have 128 bytes');
804
    }
805
  });
806
807
}, 'ReadableStream integration test: adapting a random push source');
808
809
promise_test(() => {
810
811
  const rs = sequentialReadableStream(10);
812
813
  return readableStreamToArray(rs).then(chunks => {
814
    assert_true(rs.source.closed, 'source should be closed after all chunks are read');
815
    assert_array_equals(chunks, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'the expected 10 chunks should be read');
816
  });
817
818
}, 'ReadableStream integration test: adapting a sync pull source');
819
820
promise_test(() => {
821
822
  const rs = sequentialReadableStream(10, { async: true });
823
824
  return readableStreamToArray(rs).then(chunks => {
825
    assert_true(rs.source.closed, 'source should be closed after all chunks are read');
826
    assert_array_equals(chunks, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'the expected 10 chunks should be read');
827
  });
828
829
}, 'ReadableStream integration test: adapting an async pull source');
830
831
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/pipe-through-expected.txt +14 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/pipe-through-expected.txt_sec1
1
2
PASS ReadableStream.prototype.pipeThrough should work generically on its this and its arguments 
3
PASS ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object 
4
PASS ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method 
5
PASS ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable 
6
PASS ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options 
7
FAIL Load pipe-through.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
8
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
9
PASS ReadableStream.prototype.pipeThrough should work generically on its this and its arguments 
10
PASS ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object 
11
PASS ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method 
12
PASS ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable 
13
PASS ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options 
14
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/pipe-through.html +13 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/pipe-through.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="pipe-through.js"></script>
10
<script>
11
'use strict';
12
worker_test('pipe-through.js');
13
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/pipe-through.js +108 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/pipe-through.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/test-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
test(() => {
9
10
  let pipeToArguments;
11
  const thisValue = {
12
    pipeTo() {
13
      pipeToArguments = arguments;
14
    }
15
  };
16
17
  const input = { readable: {}, writable: {} };
18
  const options = {};
19
  const result = ReadableStream.prototype.pipeThrough.call(thisValue, input, options);
20
21
  assert_array_equals(pipeToArguments, [input.writable, options],
22
    'correct arguments should be passed to thisValue.pipeTo');
23
  assert_equals(result, input.readable, 'return value should be the passed readable property');
24
25
}, 'ReadableStream.prototype.pipeThrough should work generically on its this and its arguments');
26
27
test(() => {
28
29
  const thisValue = {
30
    pipeTo() {
31
      assert_unreached('pipeTo should not be called');
32
    }
33
  };
34
35
  methodThrows(ReadableStream.prototype, 'pipeThrough', thisValue, [undefined, {}]);
36
  methodThrows(ReadableStream.prototype, 'pipeThrough', thisValue, [null, {}]);
37
38
}, 'ReadableStream.prototype.pipeThrough should throw when its first argument is not convertible to an object');
39
40
test(() => {
41
42
  const args = [{ readable: {}, writable: {} }, {}];
43
44
  methodThrows(ReadableStream.prototype, 'pipeThrough', undefined, args);
45
  methodThrows(ReadableStream.prototype, 'pipeThrough', null, args);
46
  methodThrows(ReadableStream.prototype, 'pipeThrough', 1, args);
47
  methodThrows(ReadableStream.prototype, 'pipeThrough', { pipeTo: 'test' }, args);
48
49
}, 'ReadableStream.prototype.pipeThrough should throw when "this" has no pipeTo method');
50
51
test(() => {
52
  const error = new Error('potato');
53
54
  const throwingPipeTo = {
55
    get pipeTo() {
56
      throw error;
57
    }
58
  };
59
  assert_throws(error,
60
    () => ReadableStream.prototype.pipeThrough.call(throwingPipeTo, { readable: { }, writable: { } }, {}),
61
    'pipeThrough should rethrow the error thrown by pipeTo');
62
63
  const thisValue = {
64
    pipeTo() {
65
      assert_unreached('pipeTo should not be called');
66
    }
67
  };
68
69
  const throwingWritable = {
70
    readable: {},
71
    get writable() {
72
      throw error;
73
    }
74
  };
75
  assert_throws(error,
76
    () => ReadableStream.prototype.pipeThrough.call(thisValue, throwingWritable, {}),
77
    'pipeThrough should rethrow the error thrown by the writable getter');
78
79
  const throwingReadable = {
80
    get readable() {
81
      throw error;
82
    },
83
    writable: {}
84
  };
85
  assert_throws(error,
86
    () => ReadableStream.prototype.pipeThrough.call(thisValue, throwingReadable, {}),
87
    'pipeThrough should rethrow the error thrown by the readable getter');
88
89
}, 'ReadableStream.prototype.pipeThrough should rethrow errors from accessing pipeTo, readable, or writable');
90
91
test(() => {
92
93
  let count = 0;
94
  const thisValue = {
95
    pipeTo() {
96
      ++count;
97
    }
98
  };
99
100
  ReadableStream.prototype.pipeThrough.call(thisValue, { readable: {}, writable: {} });
101
  ReadableStream.prototype.pipeThrough.call(thisValue, { readable: {} }, {});
102
  ReadableStream.prototype.pipeThrough.call(thisValue, { writable: {} }, {});
103
104
  assert_equals(count, 3, 'pipeTo was called 3 times');
105
106
}, 'ReadableStream.prototype.pipeThrough should work with missing readable, writable, or options');
107
108
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/readable-stream-reader-expected.txt +56 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/readable-stream-reader-expected.txt_sec1
1
2
PASS Can get the ReadableStreamReader constructor indirectly 
3
PASS ReadableStreamReader constructor should get a ReadableStream object as argument 
4
FAIL ReadableStreamReader instances should have the correct list of properties assert_equals: method should be non-enumerable expected false but got true
5
PASS ReadableStreamReader closed should always return the same promise object 
6
PASS Constructing a ReadableStreamReader directly should fail if the stream is already locked (via direct construction) 
7
PASS Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via direct construction) 
8
PASS Constructing a ReadableStreamReader directly should fail if the stream is already locked (via getReader) 
9
PASS Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via getReader) 
10
PASS Constructing a ReadableStreamReader directly should be OK if the stream is closed 
11
PASS Constructing a ReadableStreamReader directly should be OK if the stream is errored 
12
PASS Reading from a reader for an empty stream will wait until a chunk is available 
13
PASS cancel() on a reader does not release the reader 
14
PASS closed should be fulfilled after stream is closed (.closed access before acquiring) 
15
PASS closed should be rejected after reader releases its lock (multiple stream locks) 
16
PASS Multiple readers can access the stream in sequence 
17
PASS Cannot use an already-released reader to unlock a stream again 
18
PASS cancel() on a released reader is a no-op and does not pass through 
19
PASS Getting a second reader after erroring the stream and releasing the reader should succeed 
20
PASS ReadableStreamReader closed promise should be rejected with undefined if that is the error 
21
PASS ReadableStreamReader: if start rejects with no parameter, it should error the stream with an undefined error 
22
PASS Erroring a ReadableStream after checking closed should reject ReadableStreamReader closed promise 
23
PASS Erroring a ReadableStream before checking closed should reject ReadableStreamReader closed promise 
24
PASS Reading twice on a stream that gets closed 
25
PASS Reading twice on a closed stream 
26
PASS Reading twice on an errored stream 
27
PASS Reading twice on a stream that gets errored 
28
FAIL Load readable-stream-reader.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
29
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
30
PASS Can get the ReadableStreamReader constructor indirectly 
31
PASS ReadableStreamReader constructor should get a ReadableStream object as argument 
32
FAIL ReadableStreamReader instances should have the correct list of properties assert_equals: method should be non-enumerable expected false but got true
33
PASS ReadableStreamReader closed should always return the same promise object 
34
PASS Constructing a ReadableStreamReader directly should fail if the stream is already locked (via direct construction) 
35
PASS Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via direct construction) 
36
PASS Constructing a ReadableStreamReader directly should fail if the stream is already locked (via getReader) 
37
PASS Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via getReader) 
38
PASS Constructing a ReadableStreamReader directly should be OK if the stream is closed 
39
PASS Constructing a ReadableStreamReader directly should be OK if the stream is errored 
40
PASS Reading from a reader for an empty stream will wait until a chunk is available 
41
PASS cancel() on a reader does not release the reader 
42
PASS closed should be fulfilled after stream is closed (.closed access before acquiring) 
43
PASS closed should be rejected after reader releases its lock (multiple stream locks) 
44
PASS Multiple readers can access the stream in sequence 
45
PASS Cannot use an already-released reader to unlock a stream again 
46
PASS cancel() on a released reader is a no-op and does not pass through 
47
PASS Getting a second reader after erroring the stream and releasing the reader should succeed 
48
PASS ReadableStreamReader closed promise should be rejected with undefined if that is the error 
49
PASS ReadableStreamReader: if start rejects with no parameter, it should error the stream with an undefined error 
50
PASS Erroring a ReadableStream after checking closed should reject ReadableStreamReader closed promise 
51
PASS Erroring a ReadableStream before checking closed should reject ReadableStreamReader closed promise 
52
PASS Reading twice on a stream that gets closed 
53
PASS Reading twice on a closed stream 
54
PASS Reading twice on an errored stream 
55
PASS Reading twice on a stream that gets errored 
56
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/readable-stream-reader.html +12 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/readable-stream-reader.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="readable-stream-reader.js"></script>
9
<script>
10
'use strict';
11
worker_test('readable-stream-reader.js');
12
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/readable-stream-reader.js +485 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/readable-stream-reader.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/rs-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
let ReadableStreamReader;
9
10
test(() => {
11
12
  // It's not exposed globally, but we test a few of its properties here.
13
  ReadableStreamReader = (new ReadableStream()).getReader().constructor;
14
15
}, 'Can get the ReadableStreamReader constructor indirectly');
16
17
test(() => {
18
19
  assert_throws(new TypeError(), () => new ReadableStreamReader('potato'));
20
  assert_throws(new TypeError(), () => new ReadableStreamReader({}));
21
  assert_throws(new TypeError(), () => new ReadableStreamReader());
22
23
}, 'ReadableStreamReader constructor should get a ReadableStream object as argument');
24
25
test(() => {
26
27
  const methods = ['cancel', 'constructor', 'read', 'releaseLock'];
28
  const properties = methods.concat(['closed']).sort();
29
30
  const rsReader = new ReadableStreamReader(new ReadableStream());
31
  const proto = Object.getPrototypeOf(rsReader);
32
33
  assert_array_equals(Object.getOwnPropertyNames(proto).sort(), properties);
34
35
  for (const m of methods) {
36
    const propDesc = Object.getOwnPropertyDescriptor(proto, m);
37
    assert_equals(propDesc.enumerable, false, 'method should be non-enumerable');
38
    assert_equals(propDesc.configurable, true, 'method should be configurable');
39
    assert_equals(propDesc.writable, true, 'method should be writable');
40
    assert_equals(typeof rsReader[m], 'function', 'should have be a method');
41
  }
42
43
  const closedPropDesc = Object.getOwnPropertyDescriptor(proto, 'closed');
44
  assert_equals(closedPropDesc.enumerable, false, 'closed should be non-enumerable');
45
  assert_equals(closedPropDesc.configurable, true, 'closed should be configurable');
46
  assert_not_equals(closedPropDesc.get, undefined, 'closed should have a getter');
47
  assert_equals(closedPropDesc.set, undefined, 'closed should not have a setter');
48
49
  assert_equals(rsReader.cancel.length, 1, 'cancel has 1 parameter');
50
  assert_not_equals(rsReader.closed, undefined, 'has a non-undefined closed property');
51
  assert_equals(typeof rsReader.closed.then, 'function', 'closed property is thenable');
52
  assert_equals(typeof rsReader.constructor, 'function', 'has a constructor method');
53
  assert_equals(rsReader.constructor.length, 1, 'constructor has 1 parameter');
54
  assert_equals(typeof rsReader.read, 'function', 'has a getReader method');
55
  assert_equals(rsReader.read.length, 0, 'read has no parameters');
56
  assert_equals(typeof rsReader.releaseLock, 'function', 'has a releaseLock method');
57
  assert_equals(rsReader.releaseLock.length, 0, 'releaseLock has no parameters');
58
59
}, 'ReadableStreamReader instances should have the correct list of properties');
60
61
test(() => {
62
63
  const rsReader = new ReadableStreamReader(new ReadableStream());
64
  assert_equals(rsReader.closed, rsReader.closed, 'closed should return the same promise');
65
66
}, 'ReadableStreamReader closed should always return the same promise object');
67
68
test(() => {
69
70
  const rs = new ReadableStream();
71
  new ReadableStreamReader(rs); // Constructing directly the first time should be fine.
72
  assert_throws(new TypeError(), () => new ReadableStreamReader(rs),
73
                'constructing directly the second time should fail');
74
75
}, 'Constructing a ReadableStreamReader directly should fail if the stream is already locked (via direct ' +
76
   'construction)');
77
78
test(() => {
79
80
  const rs = new ReadableStream();
81
  new ReadableStreamReader(rs); // Constructing directly should be fine.
82
  assert_throws(new TypeError(), () => rs.getReader(), 'getReader() should fail');
83
84
}, 'Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via direct ' +
85
   'construction)');
86
87
test(() => {
88
89
  const rs = new ReadableStream();
90
  rs.getReader(); // getReader() should be fine.
91
  assert_throws(new TypeError(), () => new ReadableStreamReader(rs), 'constructing directly should fail');
92
93
}, 'Constructing a ReadableStreamReader directly should fail if the stream is already locked (via getReader)');
94
95
test(() => {
96
97
  const rs = new ReadableStream();
98
  rs.getReader(); // getReader() should be fine.
99
  assert_throws(new TypeError(), () => rs.getReader(), 'getReader() should fail');
100
101
}, 'Getting a ReadableStreamReader via getReader should fail if the stream is already locked (via getReader)');
102
103
test(() => {
104
105
  const rs = new ReadableStream({
106
    start(c) {
107
      c.close();
108
    }
109
  });
110
111
  new ReadableStreamReader(rs); // Constructing directly should not throw.
112
113
}, 'Constructing a ReadableStreamReader directly should be OK if the stream is closed');
114
115
test(() => {
116
117
  const theError = new Error('don\'t say i didn\'t warn ya');
118
  const rs = new ReadableStream({
119
    start(c) {
120
      c.error(theError);
121
    }
122
  });
123
124
  new ReadableStreamReader(rs); // Constructing directly should not throw.
125
126
}, 'Constructing a ReadableStreamReader directly should be OK if the stream is errored');
127
128
promise_test(() => {
129
130
  let controller;
131
  const rs = new ReadableStream({
132
    start(c) {
133
      controller = c;
134
    }
135
  });
136
  const reader = rs.getReader();
137
138
  const promise = reader.read().then(result => {
139
    assert_object_equals(result, { value: 'a', done: false }, 'read() should fulfill with the enqueued chunk');
140
  });
141
142
  controller.enqueue('a');
143
  return promise;
144
145
}, 'Reading from a reader for an empty stream will wait until a chunk is available');
146
147
promise_test(() => {
148
149
  let cancelCalled = false;
150
  const passedReason = new Error('it wasn\'t the right time, sorry');
151
  const rs = new ReadableStream({
152
    cancel(reason) {
153
      assert_true(rs.locked, 'the stream should still be locked');
154
      assert_throws(new TypeError(), () => rs.getReader(), 'should not be able to get another reader');
155
      assert_equals(reason, passedReason, 'the cancellation reason is passed through to the underlying source');
156
      cancelCalled = true;
157
    }
158
  });
159
160
  const reader = rs.getReader();
161
  return reader.cancel(passedReason).then(() => assert_true(cancelCalled));
162
163
}, 'cancel() on a reader does not release the reader');
164
165
promise_test(() => {
166
167
  let controller;
168
  const rs = new ReadableStream({
169
    start(c) {
170
      controller = c;
171
    }
172
  });
173
174
  const reader = rs.getReader();
175
  const promise = reader.closed;
176
177
  controller.close();
178
  return promise;
179
180
}, 'closed should be fulfilled after stream is closed (.closed access before acquiring)');
181
182
promise_test(t => {
183
184
  let controller;
185
  const rs = new ReadableStream({
186
    start(c) {
187
      controller = c;
188
    }
189
  });
190
191
  const reader1 = rs.getReader();
192
193
  reader1.releaseLock();
194
195
  const reader2 = rs.getReader();
196
  controller.close();
197
198
  return Promise.all([
199
    promise_rejects(t, new TypeError(), reader1.closed),
200
    reader2.closed
201
  ]);
202
203
}, 'closed should be rejected after reader releases its lock (multiple stream locks)');
204
205
promise_test(() => {
206
207
  const rs = new ReadableStream({
208
    start(c) {
209
      c.enqueue('a');
210
      c.enqueue('b');
211
      c.close();
212
    }
213
  });
214
215
  const reader1 = rs.getReader();
216
  const promise1 = reader1.read().then(r => {
217
    assert_object_equals(r, { value: 'a', done: false }, 'reading the first chunk from reader1 works');
218
  });
219
  reader1.releaseLock();
220
221
  const reader2 = rs.getReader();
222
  const promise2 = reader2.read().then(r => {
223
    assert_object_equals(r, { value: 'b', done: false }, 'reading the second chunk from reader2 works');
224
  });
225
  reader2.releaseLock();
226
227
  return Promise.all([promise1, promise2]);
228
229
}, 'Multiple readers can access the stream in sequence');
230
231
promise_test(() => {
232
  const rs = new ReadableStream({
233
    start(c) {
234
      c.enqueue('a');
235
    }
236
  });
237
238
  const reader1 = rs.getReader();
239
  reader1.releaseLock();
240
241
  const reader2 = rs.getReader();
242
243
  // Should be a no-op
244
  reader1.releaseLock();
245
246
  return reader2.read().then(result => {
247
    assert_object_equals(result, { value: 'a', done: false },
248
                         'read() should still work on reader2 even after reader1 is released');
249
  });
250
251
}, 'Cannot use an already-released reader to unlock a stream again');
252
253
promise_test(t => {
254
255
  const rs = new ReadableStream({
256
    start(c) {
257
      c.enqueue('a');
258
    },
259
    cancel() {
260
      assert_unreached('underlying source cancel should not be called');
261
    }
262
  });
263
264
  const reader = rs.getReader();
265
  reader.releaseLock();
266
  const cancelPromise = reader.cancel();
267
268
  const reader2 = rs.getReader();
269
  const readPromise = reader2.read().then(r => {
270
    assert_object_equals(r, { value: 'a', done: false }, 'a new reader should be able to read a chunk');
271
  });
272
273
  return Promise.all([
274
    promise_rejects(t, new TypeError(), cancelPromise),
275
    readPromise
276
  ]);
277
278
}, 'cancel() on a released reader is a no-op and does not pass through');
279
280
promise_test(t => {
281
282
  const promiseAsserts = [];
283
284
  let controller;
285
  const theError = { name: 'unique error' };
286
  const rs = new ReadableStream({
287
    start(c) {
288
      controller = c;
289
    }
290
  });
291
292
  const reader1 = rs.getReader();
293
294
  promiseAsserts.push(
295
    promise_rejects(t, theError, reader1.closed),
296
    promise_rejects(t, theError, reader1.read())
297
  );
298
299
  assert_throws(new TypeError(), () => rs.getReader(), 'trying to get another reader before erroring should throw');
300
301
  controller.error(theError);
302
303
  reader1.releaseLock();
304
305
  const reader2 = rs.getReader();
306
307
  promiseAsserts.push(
308
    promise_rejects(t, theError, reader2.closed),
309
    promise_rejects(t, theError, reader2.read())
310
  );
311
312
  return Promise.all(promiseAsserts);
313
314
}, 'Getting a second reader after erroring the stream and releasing the reader should succeed');
315
316
promise_test(t => {
317
318
  let controller;
319
  const rs = new ReadableStream({
320
    start(c) {
321
      controller = c;
322
    }
323
  });
324
325
  const promise = rs.getReader().closed.then(
326
    t.unreached_func('closed promise should not be fulfilled when stream is errored'),
327
    err => {
328
      assert_equals(err, undefined, 'passed error should be undefined as it was');
329
    }
330
  );
331
332
  controller.error();
333
  return promise;
334
335
}, 'ReadableStreamReader closed promise should be rejected with undefined if that is the error');
336
337
338
promise_test(t => {
339
340
  const rs = new ReadableStream({
341
    start() {
342
      return Promise.reject();
343
    }
344
  });
345
346
  return rs.getReader().read().then(
347
    t.unreached_func('read promise should not be fulfilled when stream is errored'),
348
    err => {
349
      assert_equals(err, undefined, 'passed error should be undefined as it was');
350
    }
351
  );
352
353
}, 'ReadableStreamReader: if start rejects with no parameter, it should error the stream with an undefined error');
354
355
promise_test(t => {
356
357
  const theError = { name: 'unique string' };
358
  let controller;
359
  const rs = new ReadableStream({
360
    start(c) {
361
      controller = c;
362
    }
363
  });
364
365
  const promise = promise_rejects(t, theError, rs.getReader().closed);
366
367
  controller.error(theError);
368
  return promise;
369
370
}, 'Erroring a ReadableStream after checking closed should reject ReadableStreamReader closed promise');
371
372
promise_test(t => {
373
374
  const theError = { name: 'unique string' };
375
  let controller;
376
  const rs = new ReadableStream({
377
    start(c) {
378
      controller = c;
379
    }
380
  });
381
382
  controller.error(theError);
383
384
  // Let's call getReader twice for extra test coverage of this code path.
385
  rs.getReader().releaseLock();
386
387
  return promise_rejects(t, theError, rs.getReader().closed);
388
389
}, 'Erroring a ReadableStream before checking closed should reject ReadableStreamReader closed promise');
390
391
promise_test(() => {
392
393
  let controller;
394
  const rs = new ReadableStream({
395
    start(c) {
396
      controller = c;
397
    }
398
  });
399
  const reader = rs.getReader();
400
401
  const promise = Promise.all([
402
    reader.read().then(result => {
403
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (1)');
404
    }),
405
    reader.read().then(result => {
406
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (2)');
407
    }),
408
    reader.closed
409
  ]);
410
411
  controller.close();
412
  return promise;
413
414
}, 'Reading twice on a stream that gets closed');
415
416
promise_test(() => {
417
418
  let controller;
419
  const rs = new ReadableStream({
420
    start(c) {
421
      controller = c;
422
    }
423
  });
424
425
  controller.close();
426
  const reader = rs.getReader();
427
428
  return Promise.all([
429
    reader.read().then(result => {
430
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (1)');
431
    }),
432
    reader.read().then(result => {
433
      assert_object_equals(result, { value: undefined, done: true }, 'read() should fulfill with close (2)');
434
    }),
435
    reader.closed
436
  ]);
437
438
}, 'Reading twice on a closed stream');
439
440
promise_test(t => {
441
442
  let controller;
443
  const rs = new ReadableStream({
444
    start(c) {
445
      controller = c;
446
    }
447
  });
448
449
  const myError = { name: 'mashed potatoes' };
450
  controller.error(myError);
451
452
  const reader = rs.getReader();
453
454
  return Promise.all([
455
    promise_rejects(t, myError, reader.read()),
456
    promise_rejects(t, myError, reader.read()),
457
    promise_rejects(t, myError, reader.closed)
458
  ]);
459
460
}, 'Reading twice on an errored stream');
461
462
promise_test(t => {
463
464
  let controller;
465
  const rs = new ReadableStream({
466
    start(c) {
467
      controller = c;
468
    }
469
  });
470
471
  const myError = { name: 'mashed potatoes' };
472
  const reader = rs.getReader();
473
474
  const promise = Promise.all([
475
    promise_rejects(t, myError, reader.read()),
476
    promise_rejects(t, myError, reader.read()),
477
    promise_rejects(t, myError, reader.closed)
478
  ]);
479
480
  controller.error(myError);
481
  return promise;
482
483
}, 'Reading twice on a stream that gets errored');
484
485
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee-expected.txt +24 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee-expected.txt_sec1
1
2
PASS ReadableStream teeing: rs.tee() returns an array of two ReadableStreams 
3
PASS ReadableStream teeing: should be able to read one branch to the end without affecting the other 
4
PASS ReadableStream teeing: values should be equal across each branch 
5
PASS ReadableStream teeing: errors in the source should propagate to both branches 
6
PASS ReadableStream teeing: canceling branch1 should not impact branch2 
7
PASS ReadableStream teeing: canceling branch2 should not impact branch2 
8
PASS ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array 
9
PASS ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches 
10
PASS ReadableStream teeing: closing the original should immediately close the branches 
11
PASS ReadableStream teeing: erroring the original should immediately error the branches 
12
FAIL Load tee.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
13
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
14
PASS ReadableStream teeing: rs.tee() returns an array of two ReadableStreams 
15
PASS ReadableStream teeing: should be able to read one branch to the end without affecting the other 
16
PASS ReadableStream teeing: values should be equal across each branch 
17
PASS ReadableStream teeing: errors in the source should propagate to both branches 
18
PASS ReadableStream teeing: canceling branch1 should not impact branch2 
19
PASS ReadableStream teeing: canceling branch2 should not impact branch2 
20
PASS ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array 
21
PASS ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches 
22
PASS ReadableStream teeing: closing the original should immediately close the branches 
23
PASS ReadableStream teeing: erroring the original should immediately error the branches 
24
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.html +13 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/rs-utils.js"></script>
9
<script src="tee.js"></script>
10
<script>
11
'use strict';
12
worker_test('tee.js');
13
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.js +254 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/tee.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('../resources/rs-utils.js');
5
  self.importScripts('/resources/testharness.js');
6
}
7
8
test(() => {
9
10
  const rs = new ReadableStream();
11
  const result = rs.tee();
12
13
  assert_true(Array.isArray(result), 'return value should be an array');
14
  assert_equals(result.length, 2, 'array should have length 2');
15
  assert_equals(result[0].constructor, ReadableStream, '0th element should be a ReadableStream');
16
  assert_equals(result[1].constructor, ReadableStream, '1st element should be a ReadableStream');
17
18
}, 'ReadableStream teeing: rs.tee() returns an array of two ReadableStreams');
19
20
promise_test(t => {
21
22
  const rs = new ReadableStream({
23
    start(c) {
24
      c.enqueue('a');
25
      c.enqueue('b');
26
      c.close();
27
    }
28
  });
29
30
  const branch = rs.tee();
31
  const branch1 = branch[0];
32
  const branch2 = branch[1];
33
  const reader1 = branch1.getReader();
34
  const reader2 = branch2.getReader();
35
36
  reader2.closed.then(t.unreached_func('branch2 should not be closed'));
37
38
  return Promise.all([
39
    reader1.closed,
40
    reader1.read().then(r => {
41
      assert_object_equals(r, { value: 'a', done: false }, 'first chunk from branch1 should be correct');
42
    }),
43
    reader1.read().then(r => {
44
      assert_object_equals(r, { value: 'b', done: false }, 'second chunk from branch1 should be correct');
45
    }),
46
    reader1.read().then(r => {
47
      assert_object_equals(r, { value: undefined, done: true }, 'third read() from branch1 should be done');
48
    }),
49
    reader2.read().then(r => {
50
      assert_object_equals(r, { value: 'a', done: false }, 'first chunk from branch2 should be correct');
51
    })
52
  ]);
53
54
}, 'ReadableStream teeing: should be able to read one branch to the end without affecting the other');
55
56
promise_test(() => {
57
58
  const theObject = { the: 'test object' };
59
  const rs = new ReadableStream({
60
    start(c) {
61
      c.enqueue(theObject);
62
    }
63
  });
64
65
  const branch = rs.tee();
66
  const branch1 = branch[0];
67
  const branch2 = branch[1];
68
  const reader1 = branch1.getReader();
69
  const reader2 = branch2.getReader();
70
71
  return Promise.all([reader1.read(), reader2.read()]).then(values => {
72
    assert_object_equals(values[0], values[1], 'the values should be equal');
73
  });
74
75
}, 'ReadableStream teeing: values should be equal across each branch');
76
77
promise_test(t => {
78
79
  const theError = { name: 'boo!' };
80
  const rs = new ReadableStream({
81
    start(c) {
82
      c.enqueue('a');
83
      c.enqueue('b');
84
    },
85
    pull() {
86
      throw theError;
87
    }
88
  });
89
90
  const branches = rs.tee();
91
  const reader1 = branches[0].getReader();
92
  const reader2 = branches[1].getReader();
93
94
  reader1.label = 'reader1';
95
  reader2.label = 'reader2';
96
97
  return Promise.all([
98
    promise_rejects(t, theError, reader1.closed),
99
    promise_rejects(t, theError, reader2.closed),
100
    reader1.read().then(r => {
101
      assert_object_equals(r, { value: 'a', done: false }, 'should be able to read the first chunk in branch1');
102
    }),
103
    reader1.read().then(r => {
104
      assert_object_equals(r, { value: 'b', done: false }, 'should be able to read the second chunk in branch1');
105
106
      return promise_rejects(t, theError, reader2.read());
107
    })
108
    .then(() => promise_rejects(t, theError, reader1.read()))
109
  ]);
110
111
}, 'ReadableStream teeing: errors in the source should propagate to both branches');
112
113
promise_test(() => {
114
115
  const rs = new ReadableStream({
116
    start(c) {
117
      c.enqueue('a');
118
      c.enqueue('b');
119
      c.close();
120
    }
121
  });
122
123
  const branches = rs.tee();
124
  const branch1 = branches[0];
125
  const branch2 = branches[1];
126
  branch1.cancel();
127
128
  return Promise.all([
129
    readableStreamToArray(branch1).then(chunks => {
130
      assert_array_equals(chunks, [], 'branch1 should have no chunks');
131
    }),
132
    readableStreamToArray(branch2).then(chunks => {
133
      assert_array_equals(chunks, ['a', 'b'], 'branch2 should have two chunks');
134
    })
135
  ]);
136
137
}, 'ReadableStream teeing: canceling branch1 should not impact branch2');
138
139
promise_test(() => {
140
141
  const rs = new ReadableStream({
142
    start(c) {
143
      c.enqueue('a');
144
      c.enqueue('b');
145
      c.close();
146
    }
147
  });
148
149
  const branches = rs.tee();
150
  const branch1 = branches[0];
151
  const branch2 = branches[1];
152
  branch2.cancel();
153
154
  return Promise.all([
155
    readableStreamToArray(branch1).then(chunks => {
156
      assert_array_equals(chunks, ['a', 'b'], 'branch1 should have two chunks');
157
    }),
158
    readableStreamToArray(branch2).then(chunks => {
159
      assert_array_equals(chunks, [], 'branch2 should have no chunks');
160
    })
161
  ]);
162
163
}, 'ReadableStream teeing: canceling branch2 should not impact branch2');
164
165
promise_test(() => {
166
167
  const reason1 = new Error('We\'re wanted men.');
168
  const reason2 = new Error('I have the death sentence on twelve systems.');
169
170
  let resolve;
171
  const promise = new Promise(r => resolve = r);
172
  const rs = new ReadableStream({
173
    cancel(reason) {
174
      assert_array_equals(reason, [reason1, reason2],
175
                          'the cancel reason should be an array containing those from the branches');
176
      resolve();
177
    }
178
  });
179
180
  const branch = rs.tee();
181
  const branch1 = branch[0];
182
  const branch2 = branch[1];
183
  branch1.cancel(reason1);
184
  branch2.cancel(reason2);
185
186
  return promise;
187
188
}, 'ReadableStream teeing: canceling both branches should aggregate the cancel reasons into an array');
189
190
promise_test(t => {
191
192
  const theError = { name: 'I\'ll be careful.' };
193
  const rs = new ReadableStream({
194
    cancel() {
195
      throw theError;
196
    }
197
  });
198
199
  const branch = rs.tee();
200
  const branch1 = branch[0];
201
  const branch2 = branch[1];
202
203
  return Promise.all([
204
    promise_rejects(t, theError, branch1.cancel()),
205
    promise_rejects(t, theError, branch2.cancel())
206
  ]);
207
208
}, 'ReadableStream teeing: failing to cancel the original stream should cause cancel() to reject on branches');
209
210
promise_test(() => {
211
212
  let controller;
213
  const rs = new ReadableStream({
214
    start(c) {
215
      controller = c;
216
    }
217
  });
218
219
  const branches = rs.tee();
220
  const reader1 = branches[0].getReader();
221
  const reader2 = branches[1].getReader();
222
223
  const promise = Promise.all([reader1.closed, reader2.closed]);
224
225
  controller.close();
226
  return promise;
227
228
}, 'ReadableStream teeing: closing the original should immediately close the branches');
229
230
promise_test(t => {
231
232
  let controller;
233
  const rs = new ReadableStream({
234
    start(c) {
235
      controller = c;
236
    }
237
  });
238
239
  const branches = rs.tee();
240
  const reader1 = branches[0].getReader();
241
  const reader2 = branches[1].getReader();
242
243
  const theError = { name: 'boo!' };
244
  const promise = Promise.all([
245
    promise_rejects(t, theError, reader1.closed),
246
    promise_rejects(t, theError, reader2.closed)
247
  ]);
248
249
  controller.error(theError);
250
  return promise;
251
252
}, 'ReadableStream teeing: erroring the original should immediately error the branches');
253
254
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated-expected.txt +174 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated-expected.txt_sec1
1
2
PASS Running templatedRSEmpty with ReadableStream (empty) 
3
PASS instances have the correct methods and properties 
4
PASS Running templatedRSEmptyReader with ReadableStream (empty) reader 
5
PASS instances have the correct methods and properties 
6
PASS locked should be true 
7
PASS read() should never settle 
8
PASS two read()s should both never settle 
9
PASS read() should return distinct promises each time 
10
PASS getReader() again on the stream should fail 
11
PASS releasing the lock with pending read requests should throw but the read requests should stay pending 
12
PASS releasing the lock should cause further read() calls to reject with a TypeError 
13
PASS releasing the lock should cause closed calls to reject with a TypeError 
14
PASS releasing the lock should cause locked to become false 
15
PASS canceling via the reader should cause the reader to act closed 
16
PASS canceling via the stream should fail 
17
PASS Running templatedRSClosed with ReadableStream (closed via call in start) 
18
PASS cancel() should return a distinct fulfilled promise each time 
19
PASS locked should be false 
20
PASS getReader() should be OK 
21
PASS should be able to acquire multiple readers if they are released in succession 
22
PASS should not be able to acquire a second reader if we don't release the first one 
23
PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader) 
24
PASS read() should fulfill with { value: undefined, done: true } 
25
PASS read() multiple times should fulfill with { value: undefined, done: true } 
26
PASS read() should work when used within another read() fulfill callback 
27
PASS closed should fulfill with undefined 
28
PASS releasing the lock should cause closed to reject and change identity 
29
PASS cancel() should return a distinct fulfilled promise each time 
30
PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader) 
31
PASS read() should fulfill with { value: undefined, done: true } 
32
PASS read() multiple times should fulfill with { value: undefined, done: true } 
33
PASS read() should work when used within another read() fulfill callback 
34
PASS closed should fulfill with undefined 
35
PASS releasing the lock should cause closed to reject and change identity 
36
PASS cancel() should return a distinct fulfilled promise each time 
37
PASS Running templatedRSClosed with ReadableStream (closed via cancel) 
38
PASS cancel() should return a distinct fulfilled promise each time 
39
PASS locked should be false 
40
PASS getReader() should be OK 
41
PASS should be able to acquire multiple readers if they are released in succession 
42
PASS should not be able to acquire a second reader if we don't release the first one 
43
PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader) 
44
PASS read() should fulfill with { value: undefined, done: true } 
45
PASS read() multiple times should fulfill with { value: undefined, done: true } 
46
PASS read() should work when used within another read() fulfill callback 
47
PASS closed should fulfill with undefined 
48
PASS releasing the lock should cause closed to reject and change identity 
49
PASS cancel() should return a distinct fulfilled promise each time 
50
PASS Running templatedRSErrored with ReadableStream (errored via call in start) 
51
PASS getReader() should return a reader that acts errored 
52
PASS read() twice should give the error each time 
53
PASS locked should be false 
54
PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start) 
55
PASS should be able to obtain a second reader, with the correct closed promise 
56
PASS should not be able to obtain additional readers if we don't release the first lock 
57
PASS cancel() should return a distinct rejected promise each time 
58
PASS reader cancel() should return a distinct rejected promise each time 
59
PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start) 
60
PASS getReader() should return a reader that acts errored 
61
PASS read() twice should give the error each time 
62
PASS locked should be false 
63
PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader 
64
PASS closed should reject with the error 
65
PASS releasing the lock should cause closed to reject and change identity 
66
PASS read() should reject with the error 
67
PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader) 
68
PASS closed should reject with the error 
69
PASS releasing the lock should cause closed to reject and change identity 
70
PASS read() should reject with the error 
71
PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader) 
72
PASS closed should reject with the error 
73
PASS releasing the lock should cause closed to reject and change identity 
74
PASS read() should reject with the error 
75
PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader 
76
PASS calling read() twice without waiting will eventually give both chunks (sequential) 
77
PASS calling read() twice without waiting will eventually give both chunks (nested) 
78
PASS read() should return distinct promises each time 
79
PASS cancel() after a read() should still give that single read result 
80
PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader 
81
PASS third read(), without waiting, should give { value: undefined, done: true } (sequential) 
82
PASS third read(), without waiting, should give { value: undefined, done: true } (nested) 
83
PASS draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true 
84
PASS releasing the lock after the stream is closed should cause locked to become false 
85
PASS releasing the lock should cause further read() calls to reject with a TypeError 
86
PASS reader's closed property always returns the same promise 
87
FAIL Load templated.js with SharedWorker assert_unreached: SharedWorker is unavailable Reached unreachable code
88
FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
89
PASS Running templatedRSEmpty with ReadableStream (empty) 
90
PASS instances have the correct methods and properties 
91
PASS Running templatedRSEmptyReader with ReadableStream (empty) reader 
92
PASS instances have the correct methods and properties 
93
PASS locked should be true 
94
PASS read() should never settle 
95
PASS two read()s should both never settle 
96
PASS read() should return distinct promises each time 
97
PASS getReader() again on the stream should fail 
98
PASS releasing the lock with pending read requests should throw but the read requests should stay pending 
99
PASS releasing the lock should cause further read() calls to reject with a TypeError 
100
PASS releasing the lock should cause closed calls to reject with a TypeError 
101
PASS releasing the lock should cause locked to become false 
102
PASS canceling via the reader should cause the reader to act closed 
103
PASS canceling via the stream should fail 
104
PASS Running templatedRSClosed with ReadableStream (closed via call in start) 
105
PASS cancel() should return a distinct fulfilled promise each time 
106
PASS locked should be false 
107
PASS getReader() should be OK 
108
PASS should be able to acquire multiple readers if they are released in succession 
109
PASS should not be able to acquire a second reader if we don't release the first one 
110
PASS Running templatedRSClosedReader with ReadableStream reader (closed before getting reader) 
111
PASS read() should fulfill with { value: undefined, done: true } 
112
PASS read() multiple times should fulfill with { value: undefined, done: true } 
113
PASS read() should work when used within another read() fulfill callback 
114
PASS closed should fulfill with undefined 
115
PASS releasing the lock should cause closed to reject and change identity 
116
PASS cancel() should return a distinct fulfilled promise each time 
117
PASS Running templatedRSClosedReader with ReadableStream reader (closed after getting reader) 
118
PASS read() should fulfill with { value: undefined, done: true } 
119
PASS read() multiple times should fulfill with { value: undefined, done: true } 
120
PASS read() should work when used within another read() fulfill callback 
121
PASS closed should fulfill with undefined 
122
PASS releasing the lock should cause closed to reject and change identity 
123
PASS cancel() should return a distinct fulfilled promise each time 
124
PASS Running templatedRSClosed with ReadableStream (closed via cancel) 
125
PASS cancel() should return a distinct fulfilled promise each time 
126
PASS locked should be false 
127
PASS getReader() should be OK 
128
PASS should be able to acquire multiple readers if they are released in succession 
129
PASS should not be able to acquire a second reader if we don't release the first one 
130
PASS Running templatedRSClosedReader with ReadableStream reader (closed via cancel after getting reader) 
131
PASS read() should fulfill with { value: undefined, done: true } 
132
PASS read() multiple times should fulfill with { value: undefined, done: true } 
133
PASS read() should work when used within another read() fulfill callback 
134
PASS closed should fulfill with undefined 
135
PASS releasing the lock should cause closed to reject and change identity 
136
PASS cancel() should return a distinct fulfilled promise each time 
137
PASS Running templatedRSErrored with ReadableStream (errored via call in start) 
138
PASS getReader() should return a reader that acts errored 
139
PASS read() twice should give the error each time 
140
PASS locked should be false 
141
PASS Running templatedRSErroredSyncOnly with ReadableStream (errored via call in start) 
142
PASS should be able to obtain a second reader, with the correct closed promise 
143
PASS should not be able to obtain additional readers if we don't release the first lock 
144
PASS cancel() should return a distinct rejected promise each time 
145
PASS reader cancel() should return a distinct rejected promise each time 
146
PASS Running templatedRSErrored with ReadableStream (errored via returning a rejected promise in start) 
147
PASS getReader() should return a reader that acts errored 
148
PASS read() twice should give the error each time 
149
PASS locked should be false 
150
PASS Running templatedRSErroredReader with ReadableStream (errored via returning a rejected promise in start) reader 
151
PASS closed should reject with the error 
152
PASS releasing the lock should cause closed to reject and change identity 
153
PASS read() should reject with the error 
154
PASS Running templatedRSErroredReader with ReadableStream reader (errored before getting reader) 
155
PASS closed should reject with the error 
156
PASS releasing the lock should cause closed to reject and change identity 
157
PASS read() should reject with the error 
158
PASS Running templatedRSErroredReader with ReadableStream reader (errored after getting reader) 
159
PASS closed should reject with the error 
160
PASS releasing the lock should cause closed to reject and change identity 
161
PASS read() should reject with the error 
162
PASS Running templatedRSTwoChunksOpenReader with ReadableStream (two chunks enqueued, still open) reader 
163
PASS calling read() twice without waiting will eventually give both chunks (sequential) 
164
PASS calling read() twice without waiting will eventually give both chunks (nested) 
165
PASS read() should return distinct promises each time 
166
PASS cancel() after a read() should still give that single read result 
167
PASS Running templatedRSTwoChunksClosedReader with ReadableStream (two chunks enqueued, then closed) reader 
168
PASS third read(), without waiting, should give { value: undefined, done: true } (sequential) 
169
PASS third read(), without waiting, should give { value: undefined, done: true } (nested) 
170
PASS draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true 
171
PASS releasing the lock after the stream is closed should cause locked to become false 
172
PASS releasing the lock should cause further read() calls to reject with a TypeError 
173
PASS reader's closed property always returns the same promise 
174
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.html +14 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.html_sec1
1
<!DOCTYPE html>
2
<meta charset="utf-8">
3
<script src="/resources/testharness.js"></script>
4
<script src="/resources/testharnessreport.js"></script>
5
<script src="/service-workers/service-workers/resources/test-helpers.js"></script>
6
<script src="../resources/test-initializer.js"></script>
7
8
<script src="../resources/test-utils.js"></script>
9
<script src="../resources/rs-test-templates.js"></script>
10
<script src="templated.js"></script>
11
<script>
12
'use strict';
13
worker_test('templated.js');
14
</script>
- a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.js +148 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/templated.js_sec1
1
'use strict';
2
3
if (self.importScripts) {
4
  self.importScripts('/resources/testharness.js');
5
  self.importScripts('../resources/test-utils.js');
6
  self.importScripts('../resources/rs-test-templates.js');
7
}
8
9
// Run the readable stream test templates against readable streams created directly using the constructor
10
11
const theError = { name: 'boo!' };
12
const chunks = ['a', 'b'];
13
14
templatedRSEmpty('ReadableStream (empty)', () => {
15
  return new ReadableStream();
16
});
17
18
templatedRSEmptyReader('ReadableStream (empty) reader', () => {
19
  return streamAndDefaultReader(new ReadableStream());
20
});
21
22
templatedRSClosed('ReadableStream (closed via call in start)', () => {
23
  return new ReadableStream({
24
    start(c) {
25
      c.close();
26
    }
27
  });
28
});
29
30
templatedRSClosedReader('ReadableStream reader (closed before getting reader)', () => {
31
  let controller;
32
  const stream = new ReadableStream({
33
    start(c) {
34
      controller = c;
35
    }
36
  });
37
  controller.close();
38
  const result = streamAndDefaultReader(stream);
39
  return result;
40
});
41
42
templatedRSClosedReader('ReadableStream reader (closed after getting reader)', () => {
43
  let controller;
44
  const stream = new ReadableStream({
45
    start(c) {
46
      controller = c;
47
    }
48
  });
49
  const result = streamAndDefaultReader(stream);
50
  controller.close();
51
  return result;
52
});
53
54
templatedRSClosed('ReadableStream (closed via cancel)', () => {
55
  const stream = new ReadableStream();
56
  stream.cancel();
57
  return stream;
58
});
59
60
templatedRSClosedReader('ReadableStream reader (closed via cancel after getting reader)', () => {
61
  const stream = new ReadableStream();
62
  const result = streamAndDefaultReader(stream);
63
  result.reader.cancel();
64
  return result;
65
});
66
67
templatedRSErrored('ReadableStream (errored via call in start)', () => {
68
  return new ReadableStream({
69
    start(c) {
70
      c.error(theError);
71
    }
72
  });
73
}, theError);
74
75
templatedRSErroredSyncOnly('ReadableStream (errored via call in start)', () => {
76
  return new ReadableStream({
77
    start(c) {
78
      c.error(theError);
79
    }
80
  });
81
}, theError);
82
83
templatedRSErrored('ReadableStream (errored via returning a rejected promise in start)', () => {
84
  return new ReadableStream({
85
    start() {
86
      return Promise.reject(theError);
87
    }
88
  });
89
}, theError);
90
91
templatedRSErroredReader('ReadableStream (errored via returning a rejected promise in start) reader', () => {
92
  return streamAndDefaultReader(new ReadableStream({
93
    start() {
94
      return Promise.reject(theError);
95
    }
96
  }));
97
}, theError);
98
99
templatedRSErroredReader('ReadableStream reader (errored before getting reader)', () => {
100
  let controller;
101
  const stream = new ReadableStream({
102
    start(c) {
103
      controller = c;
104
    }
105
  });
106
  controller.error(theError);
107
  return streamAndDefaultReader(stream);
108
}, theError);
109
110
templatedRSErroredReader('ReadableStream reader (errored after getting reader)', () => {
111
  let controller;
112
  const result = streamAndDefaultReader(new ReadableStream({
113
    start(c) {
114
      controller = c;
115
    }
116
  }));
117
  controller.error(theError);
118
  return result;
119
}, theError);
120
121
templatedRSTwoChunksOpenReader('ReadableStream (two chunks enqueued, still open) reader', () => {
122
  return streamAndDefaultReader(new ReadableStream({
123
    start(c) {
124
      c.enqueue(chunks[0]);
125
      c.enqueue(chunks[1]);
126
    }
127
  }));
128
}, chunks);
129
130
templatedRSTwoChunksClosedReader('ReadableStream (two chunks enqueued, then closed) reader', () => {
131
  let doClose;
132
  const stream = new ReadableStream({
133
    start(c) {
134
      c.enqueue(chunks[0]);
135
      c.enqueue(chunks[1]);
136
      doClose = c.close.bind(c);
137
    }
138
  });
139
  const result = streamAndDefaultReader(stream);
140
  doClose();
141
  return result;
142
}, chunks);
143
144
function streamAndDefaultReader(stream) {
145
  return { stream, reader: stream.getReader() };
146
}
147
148
done();
- a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-test-templates.js +624 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-test-templates.js_sec1
1
'use strict';
2
3
// These tests can be run against any readable stream produced by the web platform that meets the given descriptions.
4
// For readable stream tests, the factory should return the stream. For reader tests, the factory should return a
5
// { stream, reader } object. (You can use this to vary the time at which you acquire a reader.)
6
7
self.templatedRSEmpty = (label, factory) => {
8
  test(() => {}, 'Running templatedRSEmpty with ' + label);
9
10
  test(() => {
11
12
    const rs = factory();
13
14
    assert_equals(typeof rs.locked, 'boolean', 'has a boolean locked getter');
15
    assert_equals(typeof rs.cancel, 'function', 'has a cancel method');
16
    assert_equals(typeof rs.getReader, 'function', 'has a getReader method');
17
    assert_equals(typeof rs.pipeThrough, 'function', 'has a pipeThrough method');
18
    assert_equals(typeof rs.pipeTo, 'function', 'has a pipeTo method');
19
    assert_equals(typeof rs.tee, 'function', 'has a tee method');
20
21
  }, 'instances have the correct methods and properties');
22
};
23
24
self.templatedRSClosed = (label, factory) => {
25
  test(() => {}, 'Running templatedRSClosed with ' + label);
26
27
  promise_test(() => {
28
29
    const rs = factory();
30
    const cancelPromise1 = rs.cancel();
31
    const cancelPromise2 = rs.cancel();
32
33
    assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should return distinct promises');
34
35
    return Promise.all([
36
      cancelPromise1.then(v => assert_equals(v, undefined, 'first cancel() call should fulfill with undefined')),
37
      cancelPromise2.then(v => assert_equals(v, undefined, 'second cancel() call should fulfill with undefined'))
38
    ]);
39
40
  }, 'cancel() should return a distinct fulfilled promise each time');
41
42
  test(() => {
43
44
    const rs = factory();
45
    assert_false(rs.locked, 'locked getter should return false');
46
47
  }, 'locked should be false');
48
49
  test(() => {
50
51
    const rs = factory();
52
    rs.getReader(); // getReader() should not throw.
53
54
  }, 'getReader() should be OK');
55
56
  test(() => {
57
58
    const rs = factory();
59
60
    const reader = rs.getReader();
61
    reader.releaseLock();
62
63
    const reader2 = rs.getReader(); // Getting a second reader should not throw.
64
    reader2.releaseLock();
65
66
    rs.getReader(); // Getting a third reader should not throw.
67
68
  }, 'should be able to acquire multiple readers if they are released in succession');
69
70
  test(() => {
71
72
    const rs = factory();
73
74
    rs.getReader();
75
76
    assert_throws(new TypeError(), () => rs.getReader(), 'getting a second reader should throw');
77
    assert_throws(new TypeError(), () => rs.getReader(), 'getting a third reader should throw');
78
79
  }, 'should not be able to acquire a second reader if we don\'t release the first one');
80
};
81
82
self.templatedRSErrored = (label, factory, error) => {
83
  test(() => {}, 'Running templatedRSErrored with ' + label);
84
85
  promise_test(t => {
86
87
    const rs = factory();
88
    const reader = rs.getReader();
89
90
    return Promise.all([
91
      promise_rejects(t, error, reader.closed),
92
      promise_rejects(t, error, reader.read())
93
    ]);
94
95
  }, 'getReader() should return a reader that acts errored');
96
97
  promise_test(t => {
98
99
    const rs = factory();
100
    const reader = rs.getReader();
101
102
    return Promise.all([
103
      promise_rejects(t, error, reader.read()),
104
      promise_rejects(t, error, reader.read()),
105
      promise_rejects(t, error, reader.closed)
106
    ]);
107
108
  }, 'read() twice should give the error each time');
109
110
  test(() => {
111
    const rs = factory();
112
113
    assert_false(rs.locked, 'locked getter should return false');
114
  }, 'locked should be false');
115
};
116
117
self.templatedRSErroredSyncOnly = (label, factory, error) => {
118
  test(() => {}, 'Running templatedRSErroredSyncOnly with ' + label);
119
120
  promise_test(t => {
121
122
    const rs = factory();
123
    rs.getReader().releaseLock();
124
    const reader = rs.getReader(); // Calling getReader() twice does not throw (the stream is not locked).
125
126
    return promise_rejects(t, error, reader.closed);
127
128
  }, 'should be able to obtain a second reader, with the correct closed promise');
129
130
  test(() => {
131
132
    const rs = factory();
133
    rs.getReader();
134
135
    assert_throws(new TypeError(), () => rs.getReader(), 'getting a second reader should throw a TypeError');
136
    assert_throws(new TypeError(), () => rs.getReader(), 'getting a third reader should throw a TypeError');
137
138
  }, 'should not be able to obtain additional readers if we don\'t release the first lock');
139
140
  promise_test(t => {
141
142
    const rs = factory();
143
    const cancelPromise1 = rs.cancel();
144
    const cancelPromise2 = rs.cancel();
145
146
    assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should return distinct promises');
147
148
    return Promise.all([
149
      promise_rejects(t, error, cancelPromise1),
150
      promise_rejects(t, error, cancelPromise2)
151
    ]);
152
153
  }, 'cancel() should return a distinct rejected promise each time');
154
155
  promise_test(t => {
156
157
    const rs = factory();
158
    const reader = rs.getReader();
159
    const cancelPromise1 = reader.cancel();
160
    const cancelPromise2 = reader.cancel();
161
162
    assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should return distinct promises');
163
164
    return Promise.all([
165
      promise_rejects(t, error, cancelPromise1),
166
      promise_rejects(t, error, cancelPromise2)
167
    ]);
168
169
  }, 'reader cancel() should return a distinct rejected promise each time');
170
};
171
172
self.templatedRSEmptyReader = (label, factory) => {
173
  test(() => {}, 'Running templatedRSEmptyReader with ' + label);
174
175
  test(() => {
176
177
    const reader = factory().reader;
178
179
    assert_true('closed' in reader, 'has a closed property');
180
    assert_equals(typeof reader.closed.then, 'function', 'closed property is thenable');
181
182
    assert_equals(typeof reader.cancel, 'function', 'has a cancel method');
183
    assert_equals(typeof reader.read, 'function', 'has a read method');
184
    assert_equals(typeof reader.releaseLock, 'function', 'has a releaseLock method');
185
186
  }, 'instances have the correct methods and properties');
187
188
  test(() => {
189
190
    const stream = factory().stream;
191
192
    assert_true(stream.locked, 'locked getter should return true');
193
194
  }, 'locked should be true');
195
196
  promise_test(t => {
197
198
    const reader = factory().reader;
199
200
    reader.read().then(
201
      t.unreached_func('read() should not fulfill'),
202
      t.unreached_func('read() should not reject')
203
    );
204
205
    return delay(500);
206
207
  }, 'read() should never settle');
208
209
  promise_test(t => {
210
211
    const reader = factory().reader;
212
213
    reader.read().then(
214
      t.unreached_func('read() should not fulfill'),
215
      t.unreached_func('read() should not reject')
216
    );
217
218
    reader.read().then(
219
      t.unreached_func('read() should not fulfill'),
220
      t.unreached_func('read() should not reject')
221
    );
222
223
    return delay(500);
224
225
  }, 'two read()s should both never settle');
226
227
  test(() => {
228
229
    const reader = factory().reader;
230
    assert_not_equals(reader.read(), reader.read(), 'the promises returned should be distinct');
231
232
  }, 'read() should return distinct promises each time');
233
234
  test(() => {
235
236
    const stream = factory().stream;
237
    assert_throws(new TypeError(), () => stream.getReader(), 'stream.getReader() should throw a TypeError');
238
239
  }, 'getReader() again on the stream should fail');
240
241
  promise_test(t => {
242
243
    const streamAndReader = factory();
244
    const stream = streamAndReader.stream;
245
    const reader = streamAndReader.reader;
246
247
    reader.read().then(
248
      t.unreached_func('first read() should not fulfill'),
249
      t.unreached_func('first read() should not reject')
250
    );
251
252
    reader.read().then(
253
      t.unreached_func('second read() should not fulfill'),
254
      t.unreached_func('second read() should not reject')
255
    );
256
257
    reader.closed.then(
258
      t.unreached_func('closed should not fulfill'),
259
      t.unreached_func('closed should not reject')
260
    );
261
262
    assert_throws(new TypeError(), () => reader.releaseLock(), 'releaseLock should throw a TypeError');
263
264
    assert_true(stream.locked, 'the stream should still be locked');
265
266
    return delay(500);
267
268
  }, 'releasing the lock with pending read requests should throw but the read requests should stay pending');
269
270
  promise_test(t => {
271
272
    const reader = factory().reader;
273
    reader.releaseLock();
274
275
    return Promise.all([
276
      promise_rejects(t, new TypeError(), reader.read()),
277
      promise_rejects(t, new TypeError(), reader.read())
278
    ]);
279
280
  }, 'releasing the lock should cause further read() calls to reject with a TypeError');
281
282
  promise_test(t => {
283
284
    const reader = factory().reader;
285
286
    const closedBefore = reader.closed;
287
    reader.releaseLock();
288
    const closedAfter = reader.closed;
289
290
    assert_equals(closedBefore, closedAfter, 'the closed promise should not change identity');
291
292
    return promise_rejects(t, new TypeError(), closedBefore);
293
294
  }, 'releasing the lock should cause closed calls to reject with a TypeError');
295
296
  test(() => {
297
298
    const streamAndReader = factory();
299
    const stream = streamAndReader.stream;
300
    const reader = streamAndReader.reader;
301
302
    reader.releaseLock();
303
    assert_false(stream.locked, 'locked getter should return false');
304
305
  }, 'releasing the lock should cause locked to become false');
306
307
  promise_test(() => {
308
309
    const reader = factory().reader;
310
    reader.cancel();
311
312
    return reader.read().then(r => {
313
      assert_object_equals(r, { value: undefined, done: true }, 'read()ing from the reader should give a done result');
314
    });
315
316
  }, 'canceling via the reader should cause the reader to act closed');
317
318
  promise_test(t => {
319
320
    const stream = factory().stream;
321
    return promise_rejects(t, new TypeError(), stream.cancel());
322
323
  }, 'canceling via the stream should fail');
324
};
325
326
self.templatedRSClosedReader = (label, factory) => {
327
  test(() => {}, 'Running templatedRSClosedReader with ' + label);
328
329
  promise_test(() => {
330
331
    const reader = factory().reader;
332
333
    return reader.read().then(v => {
334
      assert_object_equals(v, { value: undefined, done: true }, 'read() should fulfill correctly');
335
    });
336
337
  }, 'read() should fulfill with { value: undefined, done: true }');
338
339
  promise_test(() => {
340
341
    const reader = factory().reader;
342
343
    return Promise.all([
344
      reader.read().then(v => {
345
        assert_object_equals(v, { value: undefined, done: true }, 'read() should fulfill correctly');
346
      }),
347
      reader.read().then(v => {
348
        assert_object_equals(v, { value: undefined, done: true }, 'read() should fulfill correctly');
349
      })
350
    ]);
351
352
  }, 'read() multiple times should fulfill with { value: undefined, done: true }');
353
354
  promise_test(() => {
355
356
    const reader = factory().reader;
357
358
    return reader.read().then(() => reader.read()).then(v => {
359
      assert_object_equals(v, { value: undefined, done: true }, 'read() should fulfill correctly');
360
    });
361
362
  }, 'read() should work when used within another read() fulfill callback');
363
364
  promise_test(() => {
365
366
    const reader = factory().reader;
367
368
    return reader.closed.then(v => assert_equals(v, undefined, 'reader closed should fulfill with undefined'));
369
370
  }, 'closed should fulfill with undefined');
371
372
  promise_test(t => {
373
374
    const reader = factory().reader;
375
376
    const closedBefore = reader.closed;
377
    reader.releaseLock();
378
    const closedAfter = reader.closed;
379
380
    assert_not_equals(closedBefore, closedAfter, 'the closed promise should change identity');
381
382
    return Promise.all([
383
      closedBefore.then(v => assert_equals(v, undefined, 'reader.closed acquired before release should fulfill')),
384
      promise_rejects(t, new TypeError(), closedAfter)
385
    ]);
386
387
  }, 'releasing the lock should cause closed to reject and change identity');
388
389
  promise_test(() => {
390
391
    const reader = factory().reader;
392
    const cancelPromise1 = reader.cancel();
393
    const cancelPromise2 = reader.cancel();
394
    const closedReaderPromise = reader.closed;
395
396
    assert_not_equals(cancelPromise1, cancelPromise2, 'cancel() calls should return distinct promises');
397
    assert_not_equals(cancelPromise1, closedReaderPromise, 'cancel() promise 1 should be distinct from reader.closed');
398
    assert_not_equals(cancelPromise2, closedReaderPromise, 'cancel() promise 2 should be distinct from reader.closed');
399
400
    return Promise.all([
401
      cancelPromise1.then(v => assert_equals(v, undefined, 'first cancel() should fulfill with undefined')),
402
      cancelPromise2.then(v => assert_equals(v, undefined, 'second cancel() should fulfill with undefined'))
403
    ]);
404
405
  }, 'cancel() should return a distinct fulfilled promise each time');
406
};
407
408
self.templatedRSErroredReader = (label, factory, error) => {
409
  test(() => {}, 'Running templatedRSErroredReader with ' + label);
410
411
  promise_test(t => {
412
413
    const reader = factory().reader;
414
    return promise_rejects(t, error, reader.closed);
415
416
  }, 'closed should reject with the error');
417
418
  promise_test(t => {
419
420
    const reader = factory().reader;
421
    const closedBefore = reader.closed;
422
423
    return promise_rejects(t, error, closedBefore).then(() => {
424
      reader.releaseLock();
425
426
      const closedAfter = reader.closed;
427
      assert_not_equals(closedBefore, closedAfter, 'the closed promise should change identity');
428
429
      return promise_rejects(t, new TypeError(), closedAfter);
430
    });
431
432
  }, 'releasing the lock should cause closed to reject and change identity');
433
434
  promise_test(t => {
435
436
    const reader = factory().reader;
437
    return promise_rejects(t, error, reader.read());
438
439
  }, 'read() should reject with the error');
440
};
441
442
self.templatedRSTwoChunksOpenReader = (label, factory, chunks) => {
443
  test(() => {}, 'Running templatedRSTwoChunksOpenReader with ' + label);
444
445
  promise_test(() => {
446
447
    const reader = factory().reader;
448
449
    return Promise.all([
450
      reader.read().then(r => {
451
        assert_object_equals(r, { value: chunks[0], done: false }, 'first result should be correct');
452
      }),
453
      reader.read().then(r => {
454
        assert_object_equals(r, { value: chunks[1], done: false }, 'second result should be correct');
455
      })
456
    ]);
457
458
  }, 'calling read() twice without waiting will eventually give both chunks (sequential)');
459
460
  promise_test(() => {
461
462
    const reader = factory().reader;
463
464
    return reader.read().then(r => {
465
      assert_object_equals(r, { value: chunks[0], done: false }, 'first result should be correct');
466
467
      return reader.read().then(r2 => {
468
        assert_object_equals(r2, { value: chunks[1], done: false }, 'second result should be correct');
469
      });
470
    });
471
472
  }, 'calling read() twice without waiting will eventually give both chunks (nested)');
473
474
  test(() => {
475
476
    const reader = factory().reader;
477
    assert_not_equals(reader.read(), reader.read(), 'the promises returned should be distinct');
478
479
  }, 'read() should return distinct promises each time');
480
481
  promise_test(() => {
482
483
    const reader = factory().reader;
484
485
    const promise1 = reader.closed.then(v => {
486
      assert_equals(v, undefined, 'reader closed should fulfill with undefined');
487
    });
488
489
    const promise2 = reader.read().then(r => {
490
      assert_object_equals(r, { value: chunks[0], done: false },
491
                           'promise returned before cancellation should fulfill with a chunk');
492
    });
493
494
    reader.cancel();
495
496
    const promise3 = reader.read().then(r => {
497
      assert_object_equals(r, { value: undefined, done: true },
498
                           'promise returned after cancellation should fulfill with an end-of-stream signal');
499
    });
500
501
    return Promise.all([promise1, promise2, promise3]);
502
503
  }, 'cancel() after a read() should still give that single read result');
504
};
505
506
self.templatedRSTwoChunksClosedReader = function (label, factory, chunks) {
507
  test(() => {}, 'Running templatedRSTwoChunksClosedReader with ' + label);
508
509
  promise_test(() => {
510
511
    const reader = factory().reader;
512
513
    return Promise.all([
514
      reader.read().then(r => {
515
        assert_object_equals(r, { value: chunks[0], done: false }, 'first result should be correct');
516
      }),
517
      reader.read().then(r => {
518
        assert_object_equals(r, { value: chunks[1], done: false }, 'second result should be correct');
519
      }),
520
      reader.read().then(r => {
521
        assert_object_equals(r, { value: undefined, done: true }, 'third result should be correct');
522
      })
523
    ]);
524
525
  }, 'third read(), without waiting, should give { value: undefined, done: true } (sequential)');
526
527
  promise_test(() => {
528
529
    const reader = factory().reader;
530
531
    return reader.read().then(r => {
532
      assert_object_equals(r, { value: chunks[0], done: false }, 'first result should be correct');
533
534
      return reader.read().then(r2 => {
535
        assert_object_equals(r2, { value: chunks[1], done: false }, 'second result should be correct');
536
537
        return reader.read().then(r3 => {
538
          assert_object_equals(r3, { value: undefined, done: true }, 'third result should be correct');
539
        });
540
      });
541
    });
542
543
  }, 'third read(), without waiting, should give { value: undefined, done: true } (nested)');
544
545
  promise_test(() => {
546
547
    const streamAndReader = factory();
548
    const stream = streamAndReader.stream;
549
    const reader = streamAndReader.reader;
550
551
    assert_true(stream.locked, 'stream should start locked');
552
553
    const promise = reader.closed.then(v => {
554
      assert_equals(v, undefined, 'reader closed should fulfill with undefined');
555
      assert_true(stream.locked, 'stream should remain locked');
556
    });
557
558
    reader.read();
559
    reader.read();
560
561
    return promise;
562
563
  }, 'draining the stream via read() should cause the reader closed promise to fulfill, but locked stays true');
564
565
  promise_test(() => {
566
567
    const streamAndReader = factory();
568
    const stream = streamAndReader.stream;
569
    const reader = streamAndReader.reader;
570
571
    const promise = reader.closed.then(() => {
572
      assert_true(stream.locked, 'the stream should start locked');
573
      reader.releaseLock(); // Releasing the lock after reader closed should not throw.
574
      assert_false(stream.locked, 'the stream should end unlocked');
575
    });
576
577
    reader.read();
578
    reader.read();
579
580
    return promise;
581
582
  }, 'releasing the lock after the stream is closed should cause locked to become false');
583
584
  promise_test(t => {
585
586
    const reader = factory().reader;
587
588
    reader.releaseLock();
589
590
    return Promise.all([
591
      promise_rejects(t, new TypeError(), reader.read()),
592
      promise_rejects(t, new TypeError(), reader.read()),
593
      promise_rejects(t, new TypeError(), reader.read())
594
    ]);
595
596
  }, 'releasing the lock should cause further read() calls to reject with a TypeError');
597
598
  promise_test(() => {
599
600
    const streamAndReader = factory();
601
    const stream = streamAndReader.stream;
602
    const reader = streamAndReader.reader;
603
604
    const readerClosed = reader.closed;
605
606
    assert_equals(reader.closed, readerClosed, 'accessing reader.closed twice in succession gives the same value');
607
608
    const promise = reader.read().then(() => {
609
      assert_equals(reader.closed, readerClosed, 'reader.closed is the same after read() fulfills');
610
611
      reader.releaseLock();
612
613
      assert_equals(reader.closed, readerClosed, 'reader.closed is the same after releasing the lock');
614
615
      const newReader = stream.getReader();
616
      return newReader.read();
617
    });
618
619
    assert_equals(reader.closed, readerClosed, 'reader.closed is the same after calling read()');
620
621
    return promise;
622
623
  }, 'reader\'s closed property always returns the same promise');
624
};
- a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-utils.js +185 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/rs-utils.js_sec1
1
'use strict';
2
(function () {
3
4
  class RandomPushSource {
5
    constructor(toPush) {
6
      this.pushed = 0;
7
      this.toPush = toPush;
8
      this.started = false;
9
      this.paused = false;
10
      this.closed = false;
11
12
      this._intervalHandle = null;
13
    }
14
15
    readStart() {
16
      if (this.closed) {
17
        return;
18
      }
19
20
      if (!this.started) {
21
        this._intervalHandle = setInterval(writeChunk, 2);
22
        this.started = true;
23
      }
24
25
      if (this.paused) {
26
        this._intervalHandle = setInterval(writeChunk, 2);
27
        this.paused = false;
28
      }
29
30
      const source = this;
31
      function writeChunk() {
32
        if (source.paused) {
33
          return;
34
        }
35
36
        source.pushed++;
37
38
        if (source.toPush > 0 && source.pushed > source.toPush) {
39
          if (source._intervalHandle) {
40
            clearInterval(source._intervalHandle);
41
            source._intervalHandle = undefined;
42
          }
43
          source.closed = true;
44
          source.onend();
45
        } else {
46
          source.ondata(randomChunk(128));
47
        }
48
      }
49
    }
50
51
    readStop() {
52
      if (this.paused) {
53
        return;
54
      }
55
56
      if (this.started) {
57
        this.paused = true;
58
        clearInterval(this._intervalHandle);
59
        this._intervalHandle = undefined;
60
      } else {
61
        throw new Error('Can\'t pause reading an unstarted source.');
62
      }
63
    }
64
  }
65
66
  function randomChunk(size) {
67
    let chunk = '';
68
69
    for (let i = 0; i < size; ++i) {
70
      // Add a random character from the basic printable ASCII set.
71
      chunk += String.fromCharCode(Math.round(Math.random() * 84) + 32);
72
    }
73
74
    return chunk;
75
  }
76
77
  function readableStreamToArray(readable, reader) {
78
    if (reader === undefined) {
79
      reader = readable.getReader();
80
    }
81
82
    const chunks = [];
83
84
    return pump();
85
86
    function pump() {
87
      return reader.read().then(result => {
88
        if (result.done) {
89
          return chunks;
90
        }
91
92
        chunks.push(result.value);
93
        return pump();
94
      });
95
    }
96
  }
97
98
  class SequentialPullSource {
99
    constructor(limit, options) {
100
      const async = options && options.async;
101
102
      this.current = 0;
103
      this.limit = limit;
104
      this.opened = false;
105
      this.closed = false;
106
107
      this._exec = f => f();
108
      if (async) {
109
        this._exec = f => setTimeout(f, 0);
110
      }
111
    }
112
113
    open(cb) {
114
      this._exec(() => {
115
        this.opened = true;
116
        cb();
117
      });
118
    }
119
120
    read(cb) {
121
      this._exec(() => {
122
        if (++this.current <= this.limit) {
123
          cb(null, false, this.current);
124
        } else {
125
          cb(null, true, null);
126
        }
127
      });
128
    }
129
130
    close(cb) {
131
      this._exec(() => {
132
        this.closed = true;
133
        cb();
134
      });
135
    }
136
  }
137
138
  function sequentialReadableStream(limit, options) {
139
    const sequentialSource = new SequentialPullSource(limit, options);
140
141
    const stream = new ReadableStream({
142
      start() {
143
        return new Promise((resolve, reject) => {
144
          sequentialSource.open(err => {
145
            if (err) {
146
              reject(err);
147
            }
148
            resolve();
149
          });
150
        });
151
      },
152
153
      pull(c) {
154
        return new Promise((resolve, reject) => {
155
          sequentialSource.read((err, done, chunk) => {
156
            if (err) {
157
              reject(err);
158
            } else if (done) {
159
              sequentialSource.close(err2 => {
160
                if (err2) {
161
                  reject(err2);
162
                }
163
                c.close();
164
                resolve();
165
              });
166
            } else {
167
              c.enqueue(chunk);
168
              resolve();
169
            }
170
          });
171
        });
172
      }
173
    });
174
175
    stream.source = sequentialSource;
176
177
    return stream;
178
  }
179
180
181
  self.RandomPushSource = RandomPushSource;
182
  self.readableStreamToArray = readableStreamToArray;
183
  self.sequentialReadableStream = sequentialReadableStream;
184
185
}());
- a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/test-initializer.js +14 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/test-initializer.js_sec1
1
'use strict';
2
3
function worker_test(file) {
4
  fetch_tests_from_worker(new Worker(file));
5
  if (typeof SharedWorker === 'function') {
6
    fetch_tests_from_worker(new SharedWorker(file));
7
  } else {
8
    test(() => {
9
      assert_unreached('SharedWorker is unavailable');
10
    }, 'Load ' + file + ' with SharedWorker');
11
  }
12
  service_worker_test(file);
13
}
14
- a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/test-utils.js +43 lines
Line 0 a/LayoutTests/imported/w3c/web-platform-tests/streams/resources/test-utils.js_sec1
1
'use strict';
2
3
self.getterRejects = (t, obj, getterName, target) => {
4
  const getter = Object.getOwnPropertyDescriptor(obj, getterName).get;
5
6
  return promise_rejects(t, new TypeError(), getter.call(target));
7
};
8
9
self.methodRejects = (t, obj, methodName, target) => {
10
  const method = obj[methodName];
11
12
  return promise_rejects(t, new TypeError(), method.call(target));
13
};
14
15
self.getterThrows = (obj, getterName, target) => {
16
  const getter = Object.getOwnPropertyDescriptor(obj, getterName).get;
17
18
  assert_throws(new TypeError(), () => getter.call(target), getterName + ' should throw a TypeError');
19
};
20
21
self.methodThrows = (obj, methodName, target, args) => {
22
  const method = obj[methodName];
23
24
  assert_throws(new TypeError(), () => method.apply(target, args), methodName + ' should throw a TypeError');
25
};
26
27
self.garbageCollect = () => {
28
  if (self.gc) {
29
    // Use --expose_gc for V8 (and Node.js)
30
    // Exposed in SpiderMonkey shell as well
31
    self.gc();
32
  } else if (self.GCController) {
33
    // Present in some WebKit development environments
34
    GCController.collect();
35
  } else {
36
    /* eslint-disable no-console */
37
    console.warn('Tests are running without the ability to do manual garbage collection. They will still work, but ' +
38
      'coverage will be suboptimal.');
39
    /* eslint-enable no-console */
40
  }
41
};
42
43
self.delay = ms => new Promise(resolve => step_timeout(resolve, ms));

Return to Bug 154671