1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5
6const {
7  readFileSync,
8} = require('fs');
9
10const {
11  open,
12} = require('fs/promises');
13
14const check = readFileSync(__filename, { encoding: 'utf8' });
15
16// Make sure the ReadableStream works...
17(async () => {
18  const dec = new TextDecoder();
19  const file = await open(__filename);
20  let data = '';
21  for await (const chunk of file.readableWebStream())
22    data += dec.decode(chunk);
23
24  assert.strictEqual(check, data);
25
26  assert.throws(() => file.readableWebStream(), {
27    code: 'ERR_INVALID_STATE',
28  });
29
30  await file.close();
31})().then(common.mustCall());
32
33// Make sure that acquiring a ReadableStream fails if the
34// FileHandle is already closed.
35(async () => {
36  const file = await open(__filename);
37  await file.close();
38
39  assert.throws(() => file.readableWebStream(), {
40    code: 'ERR_INVALID_STATE',
41  });
42})().then(common.mustCall());
43
44// Make sure that acquiring a ReadableStream fails if the
45// FileHandle is already closing.
46(async () => {
47  const file = await open(__filename);
48  file.close();
49
50  assert.throws(() => file.readableWebStream(), {
51    code: 'ERR_INVALID_STATE',
52  });
53})().then(common.mustCall());
54
55// Make sure the ReadableStream is closed when the underlying
56// FileHandle is closed.
57(async () => {
58  const file = await open(__filename);
59  const readable = file.readableWebStream();
60  const reader = readable.getReader();
61  file.close();
62  await reader.closed;
63})().then(common.mustCall());
64
65// Make sure the ReadableStream is closed when the underlying
66// FileHandle is closed.
67(async () => {
68  const file = await open(__filename);
69  const readable = file.readableWebStream();
70  file.close();
71  const reader = readable.getReader();
72  await reader.closed;
73})().then(common.mustCall());
74
75// Make sure that the FileHandle is properly marked "in use"
76// when a ReadableStream has been acquired for it.
77(async () => {
78  const file = await open(__filename);
79  file.readableWebStream();
80  const mc = new MessageChannel();
81  mc.port1.onmessage = common.mustNotCall();
82  assert.throws(() => mc.port2.postMessage(file, [file]), {
83    code: 25,
84    name: 'DataCloneError',
85  });
86  mc.port1.close();
87  await file.close();
88})().then(common.mustCall());
89
90// Make sure 'bytes' stream works
91(async () => {
92  const file = await open(__filename);
93  const dec = new TextDecoder();
94  const readable = file.readableWebStream({ type: 'bytes' });
95  const reader = readable.getReader({ mode: 'byob' });
96
97  let data = '';
98  let result;
99  do {
100    const buff = new ArrayBuffer(100);
101    result = await reader.read(new DataView(buff));
102    if (result.value !== undefined) {
103      data += dec.decode(result.value);
104      assert.ok(result.value.byteLength <= 100);
105    }
106  } while (!result.done);
107
108  assert.strictEqual(check, data);
109
110  assert.throws(() => file.readableWebStream(), {
111    code: 'ERR_INVALID_STATE',
112  });
113
114  await file.close();
115})().then(common.mustCall());
116
117// Make sure that acquiring a ReadableStream 'bytes' stream
118// fails if the FileHandle is already closed.
119(async () => {
120  const file = await open(__filename);
121  await file.close();
122
123  assert.throws(() => file.readableWebStream({ type: 'bytes' }), {
124    code: 'ERR_INVALID_STATE',
125  });
126})().then(common.mustCall());
127
128// Make sure that acquiring a ReadableStream 'bytes' stream
129// fails if the FileHandle is already closing.
130(async () => {
131  const file = await open(__filename);
132  file.close();
133
134  assert.throws(() => file.readableWebStream({ type: 'bytes' }), {
135    code: 'ERR_INVALID_STATE',
136  });
137})().then(common.mustCall());
138
139// Make sure the 'bytes' ReadableStream is closed when the underlying
140// FileHandle is closed.
141(async () => {
142  const file = await open(__filename);
143  const readable = file.readableWebStream({ type: 'bytes' });
144  const reader = readable.getReader({ mode: 'byob' });
145  file.close();
146  await reader.closed;
147})().then(common.mustCall());
148
149// Make sure the 'bytes' ReadableStream is closed when the underlying
150// FileHandle is closed.
151(async () => {
152  const file = await open(__filename);
153  const readable = file.readableWebStream({ type: 'bytes' });
154  file.close();
155  const reader = readable.getReader({ mode: 'byob' });
156  await reader.closed;
157})().then(common.mustCall());
158
159// Make sure that the FileHandle is properly marked "in use"
160// when a 'bytes' ReadableStream has been acquired for it.
161(async () => {
162  const file = await open(__filename);
163  file.readableWebStream({ type: 'bytes' });
164  const mc = new MessageChannel();
165  mc.port1.onmessage = common.mustNotCall();
166  assert.throws(() => mc.port2.postMessage(file, [file]), {
167    code: 25,
168    name: 'DataCloneError',
169  });
170  mc.port1.close();
171  await file.close();
172})().then(common.mustCall());
173