-
Notifications
You must be signed in to change notification settings - Fork 30.6k
/
Copy pathtest-blob-file-backed.js
145 lines (119 loc) Β· 4.09 KB
/
test-blob-file-backed.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
'use strict';
const common = require('../common');
const {
strictEqual,
rejects,
throws,
} = require('assert');
const { TextDecoder } = require('util');
const {
writeFileSync,
openAsBlob,
} = require('fs');
const {
unlink
} = require('fs/promises');
const { Blob } = require('buffer');
const tmpdir = require('../common/tmpdir');
const testfile = tmpdir.resolve('test-file-backed-blob.txt');
const testfile2 = tmpdir.resolve('test-file-backed-blob2.txt');
const testfile3 = tmpdir.resolve('test-file-backed-blob3.txt');
const testfile4 = tmpdir.resolve('test-file-backed-blob4.txt');
const testfile5 = tmpdir.resolve('test-file-backed-blob5.txt');
tmpdir.refresh();
const data = `${'a'.repeat(1000)}${'b'.repeat(2000)}`;
writeFileSync(testfile, data);
writeFileSync(testfile2, data);
writeFileSync(testfile3, data.repeat(100));
writeFileSync(testfile4, '');
writeFileSync(testfile5, '');
(async () => {
const blob = await openAsBlob(testfile);
const ab = await blob.arrayBuffer();
const dec = new TextDecoder();
strictEqual(dec.decode(new Uint8Array(ab)), data);
strictEqual(await blob.text(), data);
// Can be read multiple times
let stream = blob.stream();
let check = '';
for await (const chunk of stream)
check = dec.decode(chunk);
strictEqual(check, data);
// Can be combined with other Blob's and read
const combined = new Blob(['hello', blob, 'world']);
const ab2 = await combined.arrayBuffer();
strictEqual(dec.decode(ab2.slice(0, 5)), 'hello');
strictEqual(dec.decode(ab2.slice(5, -5)), data);
strictEqual(dec.decode(ab2.slice(-5)), 'world');
// If the file is modified tho, the stream errors.
writeFileSync(testfile, data + 'abc');
stream = blob.stream();
const read = async () => {
// eslint-disable-next-line no-unused-vars, no-empty
for await (const _ of stream) {}
};
await rejects(read(), { name: 'NotReadableError' });
await unlink(testfile);
})().then(common.mustCall());
(async () => {
// Refs: https://github.com/nodejs/node/issues/47683
const blob = await openAsBlob(testfile2);
const res = blob.slice(10, 20);
const ab = await res.arrayBuffer();
strictEqual(res.size, ab.byteLength);
let length = 0;
const stream = await res.stream();
for await (const chunk of stream)
length += chunk.length;
strictEqual(res.size, length);
const res1 = blob.slice(995, 1005);
strictEqual(await res1.text(), data.slice(995, 1005));
// Refs: https://github.com/nodejs/node/issues/53908
for (const res2 of [
blob.slice(995, 1005).slice(),
blob.slice(995).slice(0, 10),
blob.slice(0, 1005).slice(995),
]) {
strictEqual(await res2.text(), data.slice(995, 1005));
}
await unlink(testfile2);
})().then(common.mustCall());
(async () => {
const blob = await openAsBlob(testfile3);
const stream = blob.stream();
const read = async () => {
// eslint-disable-next-line no-unused-vars
for await (const _ of stream) {
writeFileSync(testfile3, data + 'abc');
}
};
await rejects(read(), { name: 'NotReadableError' });
await unlink(testfile3);
})().then(common.mustCall());
(async () => {
const blob = await openAsBlob(testfile4);
strictEqual(blob.size, 0);
strictEqual(await blob.text(), '');
writeFileSync(testfile4, 'abc');
await rejects(blob.text(), { name: 'NotReadableError' });
await unlink(testfile4);
})().then(common.mustCall());
(async () => {
const blob = await openAsBlob(testfile5);
strictEqual(blob.size, 0);
writeFileSync(testfile5, 'abc');
const stream = blob.stream();
const reader = stream.getReader();
await rejects(() => reader.read(), { name: 'NotReadableError' });
await unlink(testfile5);
})().then(common.mustCall());
(async () => {
// We currently do not allow File-backed blobs to be cloned or transferred
// across worker threads. This is largely because the underlying FdEntry
// is bound to the Environment/Realm under which is was created.
const blob = await openAsBlob(__filename);
throws(() => structuredClone(blob), {
code: 'ERR_INVALID_STATE',
message: 'Invalid state: File-backed Blobs are not cloneable'
});
})().then(common.mustCall());