17
17
import { expect } from 'chai' ;
18
18
import {
19
19
BundleReader ,
20
- SizedBundleElement ,
21
- toReadableStream
20
+ SizedBundleElement
22
21
} from '../../../src/util/bundle_reader' ;
23
22
import { isNode } from '../../util/test_platform' ;
24
23
24
+ /**
25
+ * Create a `ReadableStream` from a underlying buffer.
26
+ *
27
+ * @param data: Underlying buffer.
28
+ * @param bytesPerRead: How many bytes to read from the underlying buffer from each read through the stream.
29
+ */
25
30
function readableStreamFromString (
26
31
content : string ,
27
32
bytesPerRead : number
28
- ) : ReadableStream {
29
- return toReadableStream ( new TextEncoder ( ) . encode ( content ) , bytesPerRead ) ;
30
- }
31
-
32
- function lengthPrefixedString ( o : { } ) : string {
33
- const str = JSON . stringify ( o ) ;
34
- const l = new TextEncoder ( ) . encode ( str ) . byteLength ;
35
- return `${ l } ${ str } ` ;
33
+ ) : ReadableStream < Uint8Array | ArrayBuffer > {
34
+ const data = new TextEncoder ( ) . encode ( content ) ;
35
+ let readFrom = 0 ;
36
+ return new ReadableStream ( {
37
+ start ( controller ) { } ,
38
+ async pull ( controller ) : Promise < void > {
39
+ controller . enqueue ( data . slice ( readFrom , readFrom + bytesPerRead ) ) ;
40
+ readFrom += bytesPerRead ;
41
+ if ( readFrom >= data . byteLength ) {
42
+ controller . close ( ) ;
43
+ }
44
+ }
45
+ } ) ;
36
46
}
37
47
38
48
// eslint-disable-next-line no-restricted-properties
@@ -60,16 +70,82 @@ function lengthPrefixedString(o: {}): string {
60
70
} ) ;
61
71
} ) ;
62
72
63
- // eslint-disable-next-line no-restricted-properties
64
- ( isNode ( ) ? describe . skip : describe ) ( 'Bundle ' , ( ) => {
65
- genericBundleReadingTests ( 1 ) ;
66
- genericBundleReadingTests ( 4 ) ;
67
- genericBundleReadingTests ( 64 ) ;
68
- genericBundleReadingTests ( 1024 ) ;
73
+ describe . only ( 'Bundle ' , ( ) => {
74
+ if ( ! isNode ( ) ) {
75
+ genericBundleReadingTests ( 1 ) ;
76
+ genericBundleReadingTests ( 4 ) ;
77
+ genericBundleReadingTests ( 64 ) ;
78
+ genericBundleReadingTests ( 1024 ) ;
79
+ }
80
+ genericBundleReadingTests ( 0 ) ;
69
81
} ) ;
70
82
71
83
function genericBundleReadingTests ( bytesPerRead : number ) : void {
72
84
const encoder = new TextEncoder ( ) ;
85
+
86
+ function testTextSuffix ( ) : string {
87
+ if ( bytesPerRead > 0 ) {
88
+ return ` from ReadableStream with bytesPerRead: ${ bytesPerRead } ` ;
89
+ }
90
+ return ' from Uint8Array' ;
91
+ }
92
+
93
+ function bundleFromString ( s : string ) : BundleReader {
94
+ if ( bytesPerRead > 0 ) {
95
+ return new BundleReader ( readableStreamFromString ( s , bytesPerRead ) ) ;
96
+ }
97
+ return new BundleReader ( encoder . encode ( s ) ) ;
98
+ }
99
+
100
+ function lengthPrefixedString ( o : { } ) : string {
101
+ const str = JSON . stringify ( o ) ;
102
+ const l = new TextEncoder ( ) . encode ( str ) . byteLength ;
103
+ return `${ l } ${ str } ` ;
104
+ }
105
+
106
+ async function parseThroughBundle (
107
+ bundleString : string ,
108
+ validMeta = false
109
+ ) : Promise < void > {
110
+ const bundle = bundleFromString ( bundleString ) ;
111
+
112
+ if ( ! validMeta ) {
113
+ await expect ( await bundle . getMetadata ( ) ) . should . be . rejected ;
114
+ } else {
115
+ expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
116
+ }
117
+
118
+ await getAllElement ( bundle ) ;
119
+ }
120
+
121
+ async function getAllElement (
122
+ bundle : BundleReader
123
+ ) : Promise < SizedBundleElement [ ] > {
124
+ const result : SizedBundleElement [ ] = [ ] ;
125
+ while ( true ) {
126
+ const sizedElement = await bundle . nextElement ( ) ;
127
+ if ( sizedElement === null ) {
128
+ break ;
129
+ }
130
+ if ( ! sizedElement . isBundleMetadata ( ) ) {
131
+ result . push ( sizedElement ) ;
132
+ }
133
+ }
134
+
135
+ return Promise . resolve ( result ) ;
136
+ }
137
+
138
+ function verifySizedElement (
139
+ element : SizedBundleElement ,
140
+ payload : unknown ,
141
+ payloadString : string
142
+ ) : void {
143
+ expect ( element . payload ) . to . deep . equal ( payload ) ;
144
+ expect ( element . byteLength ) . to . equal (
145
+ encoder . encode ( payloadString ) . byteLength
146
+ ) ;
147
+ }
148
+
73
149
// Setting up test data.
74
150
const meta = {
75
151
metadata : {
@@ -165,61 +241,14 @@ function genericBundleReadingTests(bytesPerRead: number): void {
165
241
} ;
166
242
const limitToLastQueryString = lengthPrefixedString ( limitToLastQuery ) ;
167
243
168
- async function getAllElement (
169
- bundle : BundleReader
170
- ) : Promise < SizedBundleElement [ ] > {
171
- const result : SizedBundleElement [ ] = [ ] ;
172
- while ( true ) {
173
- const sizedElement = await bundle . nextElement ( ) ;
174
- if ( sizedElement === null ) {
175
- break ;
176
- }
177
- if ( ! sizedElement . isBundleMetadata ( ) ) {
178
- result . push ( sizedElement ) ;
179
- }
180
- }
181
-
182
- return Promise . resolve ( result ) ;
183
- }
184
-
185
- function verifySizedElement (
186
- element : SizedBundleElement ,
187
- payload : unknown ,
188
- payloadString : string
189
- ) : void {
190
- expect ( element . payload ) . to . deep . equal ( payload ) ;
191
- expect ( element . byteLength ) . to . equal (
192
- encoder . encode ( payloadString ) . byteLength
193
- ) ;
194
- }
195
-
196
- async function parseThroughBundle (
197
- bundleString : string ,
198
- bytesPerRead : number ,
199
- validMeta = false
200
- ) : Promise < void > {
201
- const bundleStream = readableStreamFromString ( bundleString , bytesPerRead ) ;
202
- const bundle = new BundleReader ( bundleStream ) ;
203
-
204
- if ( ! validMeta ) {
205
- await expect ( await bundle . getMetadata ( ) ) . should . be . rejected ;
206
- } else {
207
- expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
208
- }
209
-
210
- await getAllElement ( bundle ) ;
211
- }
212
-
213
- it ( 'reads with query and doc with bytesPerRead ' + bytesPerRead , async ( ) => {
214
- const bundleStream = readableStreamFromString (
244
+ it ( 'reads with query and doc' + testTextSuffix ( ) , async ( ) => {
245
+ const bundle = bundleFromString (
215
246
metaString +
216
247
limitQueryString +
217
248
limitToLastQueryString +
218
249
doc1MetaString +
219
- doc1String ,
220
- bytesPerRead
250
+ doc1String
221
251
) ;
222
- const bundle = new BundleReader ( bundleStream ) ;
223
252
224
253
expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
225
254
@@ -231,57 +260,43 @@ function genericBundleReadingTests(bytesPerRead: number): void {
231
260
verifySizedElement ( actual [ 3 ] , doc1 , doc1String ) ;
232
261
} ) ;
233
262
234
- it (
235
- 'reads with unexpected orders with bytesPerRead ' + bytesPerRead ,
236
- async ( ) => {
237
- const bundleStream = readableStreamFromString (
238
- metaString +
239
- doc1MetaString +
240
- doc1String +
241
- limitQueryString +
242
- doc2MetaString +
243
- doc2String ,
244
- bytesPerRead
245
- ) ;
246
- const bundle = new BundleReader ( bundleStream ) ;
247
-
248
- const actual = await getAllElement ( bundle ) ;
249
- expect ( actual . length ) . to . equal ( 5 ) ;
250
- verifySizedElement ( actual [ 0 ] , doc1Meta , doc1MetaString ) ;
251
- verifySizedElement ( actual [ 1 ] , doc1 , doc1String ) ;
252
- verifySizedElement ( actual [ 2 ] , limitQuery , limitQueryString ) ;
253
- verifySizedElement ( actual [ 3 ] , doc2Meta , doc2MetaString ) ;
254
- verifySizedElement ( actual [ 4 ] , doc2 , doc2String ) ;
255
-
256
- // Reading metadata after other elements should also work.
257
- expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
258
- }
259
- ) ;
263
+ it ( 'reads with unexpected orders' + testTextSuffix ( ) , async ( ) => {
264
+ const bundle = bundleFromString (
265
+ metaString +
266
+ doc1MetaString +
267
+ doc1String +
268
+ limitQueryString +
269
+ doc2MetaString +
270
+ doc2String
271
+ ) ;
260
272
261
- it (
262
- 'reads without named query with bytesPerRead ' + bytesPerRead ,
263
- async ( ) => {
264
- const bundleStream = readableStreamFromString (
265
- metaString + doc1MetaString + doc1String ,
266
- bytesPerRead
267
- ) ;
268
- const bundle = new BundleReader ( bundleStream ) ;
273
+ const actual = await getAllElement ( bundle ) ;
274
+ expect ( actual . length ) . to . equal ( 5 ) ;
275
+ verifySizedElement ( actual [ 0 ] , doc1Meta , doc1MetaString ) ;
276
+ verifySizedElement ( actual [ 1 ] , doc1 , doc1String ) ;
277
+ verifySizedElement ( actual [ 2 ] , limitQuery , limitQueryString ) ;
278
+ verifySizedElement ( actual [ 3 ] , doc2Meta , doc2MetaString ) ;
279
+ verifySizedElement ( actual [ 4 ] , doc2 , doc2String ) ;
280
+
281
+ // Reading metadata after other elements should also work.
282
+ expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
283
+ } ) ;
269
284
270
- expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
285
+ it ( 'reads without named query' + testTextSuffix ( ) , async ( ) => {
286
+ const bundle = bundleFromString ( metaString + doc1MetaString + doc1String ) ;
271
287
272
- const actual = await getAllElement ( bundle ) ;
273
- expect ( actual . length ) . to . equal ( 2 ) ;
274
- verifySizedElement ( actual [ 0 ] , doc1Meta , doc1MetaString ) ;
275
- verifySizedElement ( actual [ 1 ] , doc1 , doc1String ) ;
276
- }
277
- ) ;
288
+ expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
289
+
290
+ const actual = await getAllElement ( bundle ) ;
291
+ expect ( actual . length ) . to . equal ( 2 ) ;
292
+ verifySizedElement ( actual [ 0 ] , doc1Meta , doc1MetaString ) ;
293
+ verifySizedElement ( actual [ 1 ] , doc1 , doc1String ) ;
294
+ } ) ;
278
295
279
- it ( 'reads with deleted doc with bytesPerRead ' + bytesPerRead , async ( ) => {
280
- const bundleStream = readableStreamFromString (
281
- metaString + noDocMetaString + doc1MetaString + doc1String ,
282
- bytesPerRead
296
+ it ( 'reads with deleted doc' + testTextSuffix ( ) , async ( ) => {
297
+ const bundle = bundleFromString (
298
+ metaString + noDocMetaString + doc1MetaString + doc1String
283
299
) ;
284
- const bundle = new BundleReader ( bundleStream ) ;
285
300
286
301
expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
287
302
@@ -292,41 +307,29 @@ function genericBundleReadingTests(bytesPerRead: number): void {
292
307
verifySizedElement ( actual [ 2 ] , doc1 , doc1String ) ;
293
308
} ) ;
294
309
295
- it (
296
- 'reads without documents or query with bytesPerRead ' + bytesPerRead ,
297
- async ( ) => {
298
- const bundleStream = readableStreamFromString ( metaString , bytesPerRead ) ;
299
- const bundle = new BundleReader ( bundleStream ) ;
310
+ it ( 'reads without documents or query' + testTextSuffix ( ) , async ( ) => {
311
+ const bundle = bundleFromString ( metaString ) ;
300
312
301
- expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
313
+ expect ( await bundle . getMetadata ( ) ) . to . deep . equal ( meta . metadata ) ;
302
314
303
- const actual = await getAllElement ( bundle ) ;
304
- expect ( actual . length ) . to . equal ( 0 ) ;
305
- }
306
- ) ;
307
-
308
- it (
309
- 'throws with ill-formatted bundle with bytesPerRead ' + bytesPerRead ,
310
- async ( ) => {
311
- await expect (
312
- parseThroughBundle ( 'metadata: "no length prefix"' , bytesPerRead )
313
- ) . to . be . rejected ;
314
-
315
- await expect (
316
- parseThroughBundle ( '{metadata: "no length prefix"}' , bytesPerRead )
317
- ) . to . be . rejected ;
318
-
319
- await expect (
320
- parseThroughBundle ( metaString + 'invalid-string' , bytesPerRead , true )
321
- ) . to . be . rejected ;
322
-
323
- await expect ( parseThroughBundle ( '1' + metaString , bytesPerRead ) ) . to . be
324
- . rejected ;
325
-
326
- // First element is not BundleMetadata.
327
- await expect (
328
- parseThroughBundle ( doc1MetaString + doc1String , bytesPerRead )
329
- ) . to . be . rejected ;
330
- }
331
- ) ;
315
+ const actual = await getAllElement ( bundle ) ;
316
+ expect ( actual . length ) . to . equal ( 0 ) ;
317
+ } ) ;
318
+
319
+ it ( 'throws with ill-formatted bundle' + testTextSuffix ( ) , async ( ) => {
320
+ await expect ( parseThroughBundle ( 'metadata: "no length prefix"' ) ) . to . be
321
+ . rejected ;
322
+
323
+ await expect ( parseThroughBundle ( '{metadata: "no length prefix"}' ) ) . to . be
324
+ . rejected ;
325
+
326
+ await expect ( parseThroughBundle ( metaString + 'invalid-string' , true ) ) . to . be
327
+ . rejected ;
328
+
329
+ await expect ( parseThroughBundle ( '1' + metaString ) ) . to . be . rejected ;
330
+
331
+ // First element is not BundleMetadata.
332
+ await expect ( parseThroughBundle ( doc1MetaString + doc1String ) ) . to . be
333
+ . rejected ;
334
+ } ) ;
332
335
}
0 commit comments