• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// META: global=window,worker
2'use strict';
3
4const error1 = new Error('error1');
5error1.name = 'error1';
6
7const error2 = new Error('error2');
8error2.name = 'error2';
9
10promise_test(() => {
11  let controller;
12  const ws = new WritableStream({
13    start(c) {
14      controller = c;
15    }
16  });
17
18  // Now error the stream after its construction.
19  controller.error(error1);
20
21  const writer = ws.getWriter();
22
23  assert_equals(writer.desiredSize, null, 'desiredSize should be null');
24  return writer.closed.catch(r => {
25    assert_equals(r, error1, 'ws should be errored by the passed error');
26  });
27}, 'controller argument should be passed to start method');
28
29promise_test(t => {
30  const ws = new WritableStream({
31    write(chunk, controller) {
32      controller.error(error1);
33    }
34  });
35
36  const writer = ws.getWriter();
37
38  return Promise.all([
39    writer.write('a'),
40    promise_rejects_exactly(t, error1, writer.closed, 'controller.error() in write() should error the stream')
41  ]);
42}, 'controller argument should be passed to write method');
43
44// Older versions of the standard had the controller argument passed to close(). It wasn't useful, and so has been
45// removed. This test remains to identify implementations that haven't been updated.
46promise_test(t => {
47  const ws = new WritableStream({
48    close(...args) {
49      t.step(() => {
50        assert_array_equals(args, [], 'no arguments should be passed to close');
51      });
52    }
53  });
54
55  return ws.getWriter().close();
56}, 'controller argument should not be passed to close method');
57
58promise_test(() => {
59  const ws = new WritableStream({}, {
60    highWaterMark: 1000,
61    size() { return 1; }
62  });
63
64  const writer = ws.getWriter();
65
66  assert_equals(writer.desiredSize, 1000, 'desiredSize should be 1000');
67  return writer.ready.then(v => {
68    assert_equals(v, undefined, 'ready promise should fulfill with undefined');
69  });
70}, 'highWaterMark should be reflected to desiredSize');
71
72promise_test(() => {
73  const ws = new WritableStream({}, {
74    highWaterMark: Infinity,
75    size() { return 0; }
76  });
77
78  const writer = ws.getWriter();
79
80  assert_equals(writer.desiredSize, Infinity, 'desiredSize should be Infinity');
81
82  return writer.ready;
83}, 'WritableStream should be writable and ready should fulfill immediately if the strategy does not apply ' +
84    'backpressure');
85
86test(() => {
87  new WritableStream();
88}, 'WritableStream should be constructible with no arguments');
89
90test(() => {
91  const underlyingSink = { get start() { throw error1; } };
92  const queuingStrategy = { highWaterMark: 0, get size() { throw error2; } };
93
94  // underlyingSink is converted in prose in the method body, whereas queuingStrategy is done at the IDL layer.
95  // So the queuingStrategy exception should be encountered first.
96  assert_throws_exactly(error2, () => new WritableStream(underlyingSink, queuingStrategy));
97}, 'underlyingSink argument should be converted after queuingStrategy argument');
98
99test(() => {
100  const ws = new WritableStream({});
101
102  const writer = ws.getWriter();
103
104  assert_equals(typeof writer.write, 'function', 'writer should have a write method');
105  assert_equals(typeof writer.abort, 'function', 'writer should have an abort method');
106  assert_equals(typeof writer.close, 'function', 'writer should have a close method');
107
108  assert_equals(writer.desiredSize, 1, 'desiredSize should start at 1');
109
110  assert_not_equals(typeof writer.ready, 'undefined', 'writer should have a ready property');
111  assert_equals(typeof writer.ready.then, 'function', 'ready property should be thenable');
112  assert_not_equals(typeof writer.closed, 'undefined', 'writer should have a closed property');
113  assert_equals(typeof writer.closed.then, 'function', 'closed property should be thenable');
114}, 'WritableStream instances should have standard methods and properties');
115
116test(() => {
117  let WritableStreamDefaultController;
118  new WritableStream({
119    start(c) {
120      WritableStreamDefaultController = c.constructor;
121    }
122  });
123
124  assert_throws_js(TypeError, () => new WritableStreamDefaultController({}),
125                   'constructor should throw a TypeError exception');
126}, 'WritableStreamDefaultController constructor should throw');
127
128test(() => {
129  let WritableStreamDefaultController;
130  const stream = new WritableStream({
131    start(c) {
132      WritableStreamDefaultController = c.constructor;
133    }
134  });
135
136  assert_throws_js(TypeError, () => new WritableStreamDefaultController(stream),
137                   'constructor should throw a TypeError exception');
138}, 'WritableStreamDefaultController constructor should throw when passed an initialised WritableStream');
139
140test(() => {
141  const stream = new WritableStream();
142  const writer = stream.getWriter();
143  const WritableStreamDefaultWriter = writer.constructor;
144  writer.releaseLock();
145  assert_throws_js(TypeError, () => new WritableStreamDefaultWriter({}),
146                   'constructor should throw a TypeError exception');
147}, 'WritableStreamDefaultWriter should throw unless passed a WritableStream');
148
149test(() => {
150  const stream = new WritableStream();
151  const writer = stream.getWriter();
152  const WritableStreamDefaultWriter = writer.constructor;
153  assert_throws_js(TypeError, () => new WritableStreamDefaultWriter(stream),
154                   'constructor should throw a TypeError exception');
155}, 'WritableStreamDefaultWriter constructor should throw when stream argument is locked');
156