MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1import { test, testDeep, testThrows, summary } from './helpers.js';
2
3console.log('TextEncoderStream / TextDecoderStream Tests\n');
4
5test('TES typeof', typeof TextEncoderStream, 'function');
6test('TES toStringTag', Object.prototype.toString.call(new TextEncoderStream()), '[object TextEncoderStream]');
7
8testThrows('TES requires new', () => TextEncoderStream());
9
10const tes0 = new TextEncoderStream();
11test('TES encoding', tes0.encoding, 'utf-8');
12test('TES readable is ReadableStream', tes0.readable instanceof ReadableStream, true);
13test('TES writable is WritableStream', tes0.writable instanceof WritableStream, true);
14
15async function testTESBasic() {
16 const tes = new TextEncoderStream();
17 const writer = tes.writable.getWriter();
18 const reader = tes.readable.getReader();
19 writer.write('hello');
20 const { value } = await reader.read();
21 test('TES basic encode type', value instanceof Uint8Array, true);
22 testDeep('TES basic encode value', Array.from(value), [104, 101, 108, 108, 111]);
23 writer.close();
24}
25
26async function testTESEmpty() {
27 const tes = new TextEncoderStream();
28 const writer = tes.writable.getWriter();
29 const reader = tes.readable.getReader();
30 writer.write('a');
31 writer.close();
32 const { value } = await reader.read();
33 testDeep('TES non-empty chunk', Array.from(value), [97]);
34 const { done } = await reader.read();
35 test('TES stream closes', done, true);
36}
37
38async function testTESMultiChunks() {
39 const tes = new TextEncoderStream();
40 const writer = tes.writable.getWriter();
41 const reader = tes.readable.getReader();
42 writer.write('abc');
43 writer.write('def');
44 const r1 = await reader.read();
45 const r2 = await reader.read();
46 testDeep('TES chunk1', Array.from(r1.value), [97, 98, 99]);
47 testDeep('TES chunk2', Array.from(r2.value), [100, 101, 102]);
48}
49
50async function testTESUnicode() {
51 const tes = new TextEncoderStream();
52 const writer = tes.writable.getWriter();
53 const reader = tes.readable.getReader();
54 writer.write('caf茅');
55 const { value } = await reader.read();
56 testDeep('TES unicode', Array.from(value), [99, 97, 102, 195, 169]);
57}
58
59async function testTESPipeThrough() {
60 const rs = new ReadableStream({
61 start(c) {
62 c.enqueue('hello');
63 c.close();
64 }
65 });
66 const tes = new TextEncoderStream();
67 const reader = rs.pipeThrough(tes).getReader();
68 const { value } = await reader.read();
69 test('TES pipeThrough type', value instanceof Uint8Array, true);
70 testDeep('TES pipeThrough value', Array.from(value), [104, 101, 108, 108, 111]);
71}
72
73test('TDS typeof', typeof TextDecoderStream, 'function');
74test('TDS toStringTag', Object.prototype.toString.call(new TextDecoderStream()), '[object TextDecoderStream]');
75testThrows('TDS requires new', () => TextDecoderStream());
76
77const tds0 = new TextDecoderStream();
78test('TDS encoding default', tds0.encoding, 'utf-8');
79test('TDS fatal default', tds0.fatal, false);
80test('TDS ignoreBOM default', tds0.ignoreBOM, false);
81test('TDS readable is ReadableStream', tds0.readable instanceof ReadableStream, true);
82test('TDS writable is WritableStream', tds0.writable instanceof WritableStream, true);
83
84const tds1 = new TextDecoderStream('utf-8', { fatal: true, ignoreBOM: true });
85test('TDS fatal option', tds1.fatal, true);
86test('TDS ignoreBOM option', tds1.ignoreBOM, true);
87
88testThrows('TDS invalid encoding', () => new TextDecoderStream('invalid-encoding'));
89
90async function testTDSBasic() {
91 const tds = new TextDecoderStream();
92 const writer = tds.writable.getWriter();
93 const reader = tds.readable.getReader();
94 writer.write(new Uint8Array([104, 101, 108, 108, 111]));
95 const { value } = await reader.read();
96 test('TDS basic decode', value, 'hello');
97 writer.close();
98}
99
100async function testTDSMultiChunks() {
101 const tds = new TextDecoderStream();
102 const writer = tds.writable.getWriter();
103 const reader = tds.readable.getReader();
104 writer.write(new Uint8Array([97, 98, 99]));
105 writer.write(new Uint8Array([100, 101, 102]));
106 const r1 = await reader.read();
107 const r2 = await reader.read();
108 test('TDS chunk1', r1.value, 'abc');
109 test('TDS chunk2', r2.value, 'def');
110}
111
112async function testTDSSplitMultibyte() {
113 const tds = new TextDecoderStream();
114 const writer = tds.writable.getWriter();
115 const reader = tds.readable.getReader();
116 writer.write(new Uint8Array([99, 97, 102, 0xc3]));
117 writer.write(new Uint8Array([0xa9]));
118 writer.close();
119 const chunks = [];
120 while (true) {
121 const { value, done } = await reader.read();
122 if (done) break;
123 if (value) chunks.push(value);
124 }
125 test('TDS split multibyte', chunks.join(''), 'caf茅');
126}
127
128async function testTDSPipeThrough() {
129 const rs = new ReadableStream({
130 start(c) {
131 c.enqueue(new Uint8Array([104, 101, 108, 108, 111]));
132 c.close();
133 }
134 });
135 const tds = new TextDecoderStream();
136 const reader = rs.pipeThrough(tds).getReader();
137 const { value } = await reader.read();
138 test('TDS pipeThrough', value, 'hello');
139}
140
141async function testRoundTrip() {
142 const rs = new ReadableStream({
143 start(c) {
144 c.enqueue('hello world');
145 c.close();
146 }
147 });
148 const reader = rs.pipeThrough(new TextEncoderStream()).pipeThrough(new TextDecoderStream()).getReader();
149 const { value } = await reader.read();
150 test('encode鈫抎ecode roundtrip', value, 'hello world');
151}
152
153async function testTDSUTF16LE() {
154 const tds = new TextDecoderStream('utf-16le');
155 test('TDS utf-16le encoding', tds.encoding, 'utf-16le');
156 const writer = tds.writable.getWriter();
157 const reader = tds.readable.getReader();
158 writer.write(new Uint8Array([0x68, 0x00, 0x69, 0x00]));
159 const { value } = await reader.read();
160 test('TDS utf-16le decode', value, 'hi');
161}
162
163await testTESBasic();
164await testTESEmpty();
165await testTESMultiChunks();
166await testTESUnicode();
167await testTESPipeThrough();
168await testTDSBasic();
169await testTDSMultiChunks();
170await testTDSSplitMultibyte();
171await testTDSPipeThrough();
172await testRoundTrip();
173await testTDSUTF16LE();
174
175summary();