@logtape/logtape 1.0.0-dev.240 → 1.0.0-dev.246
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist/sink.cjs +10 -107
- package/dist/sink.d.cts +2 -71
- package/dist/sink.d.cts.map +1 -1
- package/dist/sink.d.ts +2 -71
- package/dist/sink.d.ts.map +1 -1
- package/dist/sink.js +10 -107
- package/dist/sink.js.map +1 -1
- package/package.json +23 -7
- package/sink.test.ts +5 -424
- package/sink.ts +13 -245
package/sink.test.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { suite } from "@alinea/suite";
|
|
2
|
-
import { assert } from "@std/assert/assert";
|
|
3
2
|
import { assertEquals } from "@std/assert/equals";
|
|
4
3
|
import { assertInstanceOf } from "@std/assert/instance-of";
|
|
5
4
|
import { assertThrows } from "@std/assert/throws";
|
|
@@ -68,254 +67,6 @@ test("getStreamSink()", async () => {
|
|
|
68
67
|
);
|
|
69
68
|
});
|
|
70
69
|
|
|
71
|
-
test("getStreamSink() with nonBlocking - simple boolean", async () => {
|
|
72
|
-
let buffer: string = "";
|
|
73
|
-
const decoder = new TextDecoder();
|
|
74
|
-
const sink = getStreamSink(
|
|
75
|
-
new WritableStream({
|
|
76
|
-
write(chunk: Uint8Array) {
|
|
77
|
-
buffer += decoder.decode(chunk);
|
|
78
|
-
return Promise.resolve();
|
|
79
|
-
},
|
|
80
|
-
}),
|
|
81
|
-
{ nonBlocking: true },
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
// Check that it returns AsyncDisposable
|
|
85
|
-
assertInstanceOf(sink, Function);
|
|
86
|
-
assert(Symbol.asyncDispose in sink);
|
|
87
|
-
|
|
88
|
-
// Add records - they should not be written immediately
|
|
89
|
-
sink(trace);
|
|
90
|
-
sink(debug);
|
|
91
|
-
assertEquals(buffer, ""); // Not written yet
|
|
92
|
-
|
|
93
|
-
// Wait for flush interval (default 100ms)
|
|
94
|
-
await delay(150);
|
|
95
|
-
assertEquals(
|
|
96
|
-
buffer,
|
|
97
|
-
`2023-11-14 22:13:20.000 +00:00 [TRC] my-app·junk: Hello, 123 & 456!
|
|
98
|
-
2023-11-14 22:13:20.000 +00:00 [DBG] my-app·junk: Hello, 123 & 456!
|
|
99
|
-
`,
|
|
100
|
-
);
|
|
101
|
-
|
|
102
|
-
await sink[Symbol.asyncDispose]();
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test("getStreamSink() with nonBlocking - custom buffer config", async () => {
|
|
106
|
-
let buffer: string = "";
|
|
107
|
-
const decoder = new TextDecoder();
|
|
108
|
-
const sink = getStreamSink(
|
|
109
|
-
new WritableStream({
|
|
110
|
-
write(chunk: Uint8Array) {
|
|
111
|
-
buffer += decoder.decode(chunk);
|
|
112
|
-
return Promise.resolve();
|
|
113
|
-
},
|
|
114
|
-
}),
|
|
115
|
-
{
|
|
116
|
-
nonBlocking: {
|
|
117
|
-
bufferSize: 2,
|
|
118
|
-
flushInterval: 50,
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
// Add records up to buffer size
|
|
124
|
-
sink(trace);
|
|
125
|
-
assertEquals(buffer, ""); // Not flushed yet
|
|
126
|
-
|
|
127
|
-
sink(debug); // This should trigger immediate flush (buffer size = 2)
|
|
128
|
-
await delay(10); // Small delay for async flush
|
|
129
|
-
assertEquals(
|
|
130
|
-
buffer,
|
|
131
|
-
`2023-11-14 22:13:20.000 +00:00 [TRC] my-app·junk: Hello, 123 & 456!
|
|
132
|
-
2023-11-14 22:13:20.000 +00:00 [DBG] my-app·junk: Hello, 123 & 456!
|
|
133
|
-
`,
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
// Add more records
|
|
137
|
-
const prevLength = buffer.length;
|
|
138
|
-
sink(info);
|
|
139
|
-
assertEquals(buffer.length, prevLength); // Not flushed yet
|
|
140
|
-
|
|
141
|
-
// Wait for flush interval
|
|
142
|
-
await delay(60);
|
|
143
|
-
assertEquals(
|
|
144
|
-
buffer.substring(prevLength),
|
|
145
|
-
`2023-11-14 22:13:20.000 +00:00 [INF] my-app·junk: Hello, 123 & 456!
|
|
146
|
-
`,
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
await sink[Symbol.asyncDispose]();
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
test("getStreamSink() with nonBlocking - no operations after dispose", async () => {
|
|
153
|
-
let buffer: string = "";
|
|
154
|
-
const decoder = new TextDecoder();
|
|
155
|
-
const sink = getStreamSink(
|
|
156
|
-
new WritableStream({
|
|
157
|
-
write(chunk: Uint8Array) {
|
|
158
|
-
buffer += decoder.decode(chunk);
|
|
159
|
-
return Promise.resolve();
|
|
160
|
-
},
|
|
161
|
-
}),
|
|
162
|
-
{ nonBlocking: true },
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
// Dispose immediately
|
|
166
|
-
await sink[Symbol.asyncDispose]();
|
|
167
|
-
|
|
168
|
-
// Try to add records after dispose
|
|
169
|
-
sink(trace);
|
|
170
|
-
sink(debug);
|
|
171
|
-
|
|
172
|
-
// No records should be written
|
|
173
|
-
assertEquals(buffer, "");
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
test("getStreamSink() with nonBlocking - error handling", async () => {
|
|
177
|
-
const sink = getStreamSink(
|
|
178
|
-
new WritableStream({
|
|
179
|
-
write() {
|
|
180
|
-
return Promise.reject(new Error("Write error"));
|
|
181
|
-
},
|
|
182
|
-
}),
|
|
183
|
-
{ nonBlocking: true },
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
// Should not throw when adding records
|
|
187
|
-
sink(trace);
|
|
188
|
-
sink(info);
|
|
189
|
-
sink(error);
|
|
190
|
-
|
|
191
|
-
// Wait for flush - errors should be silently ignored
|
|
192
|
-
await delay(150);
|
|
193
|
-
|
|
194
|
-
// Dispose - should not throw
|
|
195
|
-
await sink[Symbol.asyncDispose]();
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
test("getStreamSink() with nonBlocking - flush on dispose", async () => {
|
|
199
|
-
let buffer: string = "";
|
|
200
|
-
const decoder = new TextDecoder();
|
|
201
|
-
const sink = getStreamSink(
|
|
202
|
-
new WritableStream({
|
|
203
|
-
write(chunk: Uint8Array) {
|
|
204
|
-
buffer += decoder.decode(chunk);
|
|
205
|
-
return Promise.resolve();
|
|
206
|
-
},
|
|
207
|
-
}),
|
|
208
|
-
{
|
|
209
|
-
nonBlocking: {
|
|
210
|
-
bufferSize: 100,
|
|
211
|
-
flushInterval: 5000, // Very long interval
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
// Add records
|
|
217
|
-
sink(trace);
|
|
218
|
-
sink(debug);
|
|
219
|
-
sink(info);
|
|
220
|
-
assertEquals(buffer, ""); // Not flushed yet due to large buffer and long interval
|
|
221
|
-
|
|
222
|
-
// Dispose should flush all remaining records
|
|
223
|
-
await sink[Symbol.asyncDispose]();
|
|
224
|
-
assertEquals(
|
|
225
|
-
buffer,
|
|
226
|
-
`2023-11-14 22:13:20.000 +00:00 [TRC] my-app·junk: Hello, 123 & 456!
|
|
227
|
-
2023-11-14 22:13:20.000 +00:00 [DBG] my-app·junk: Hello, 123 & 456!
|
|
228
|
-
2023-11-14 22:13:20.000 +00:00 [INF] my-app·junk: Hello, 123 & 456!
|
|
229
|
-
`,
|
|
230
|
-
);
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
test("getStreamSink() with nonBlocking - buffer overflow protection", async () => {
|
|
234
|
-
let buffer: string = "";
|
|
235
|
-
const decoder = new TextDecoder();
|
|
236
|
-
let recordsReceived = 0;
|
|
237
|
-
const sink = getStreamSink(
|
|
238
|
-
new WritableStream({
|
|
239
|
-
write(chunk: Uint8Array) {
|
|
240
|
-
const text = decoder.decode(chunk);
|
|
241
|
-
buffer += text;
|
|
242
|
-
// Count how many log records we actually receive
|
|
243
|
-
recordsReceived += text.split("\n").filter((line) =>
|
|
244
|
-
line.trim() !== ""
|
|
245
|
-
).length;
|
|
246
|
-
return Promise.resolve();
|
|
247
|
-
},
|
|
248
|
-
}),
|
|
249
|
-
{
|
|
250
|
-
nonBlocking: {
|
|
251
|
-
bufferSize: 3,
|
|
252
|
-
flushInterval: 50, // Short interval to ensure flushes happen
|
|
253
|
-
},
|
|
254
|
-
},
|
|
255
|
-
);
|
|
256
|
-
|
|
257
|
-
// Add many more records than maxBufferSize (6) very rapidly
|
|
258
|
-
// This should trigger multiple flushes and potentially overflow protection
|
|
259
|
-
for (let i = 0; i < 20; i++) {
|
|
260
|
-
sink(trace);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Wait for all flushes to complete
|
|
264
|
-
await delay(200);
|
|
265
|
-
|
|
266
|
-
// Force final flush
|
|
267
|
-
await sink[Symbol.asyncDispose]();
|
|
268
|
-
|
|
269
|
-
// Due to overflow protection, we should receive fewer than 20 records
|
|
270
|
-
// The exact number depends on timing, but some should be dropped
|
|
271
|
-
assert(
|
|
272
|
-
recordsReceived < 20,
|
|
273
|
-
`Expected < 20 records due to potential overflow, got ${recordsReceived}`,
|
|
274
|
-
);
|
|
275
|
-
assert(recordsReceived > 0, "Expected some records to be logged");
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
test("getStreamSink() with nonBlocking - high volume non-blocking behavior", async () => {
|
|
279
|
-
let buffer: string = "";
|
|
280
|
-
const decoder = new TextDecoder();
|
|
281
|
-
const sink = getStreamSink(
|
|
282
|
-
new WritableStream({
|
|
283
|
-
write(chunk: Uint8Array) {
|
|
284
|
-
buffer += decoder.decode(chunk);
|
|
285
|
-
return Promise.resolve();
|
|
286
|
-
},
|
|
287
|
-
}),
|
|
288
|
-
{
|
|
289
|
-
nonBlocking: {
|
|
290
|
-
bufferSize: 3,
|
|
291
|
-
flushInterval: 50,
|
|
292
|
-
},
|
|
293
|
-
},
|
|
294
|
-
);
|
|
295
|
-
|
|
296
|
-
// Simulate rapid logging - this should not block
|
|
297
|
-
const startTime = performance.now();
|
|
298
|
-
for (let i = 0; i < 100; i++) {
|
|
299
|
-
sink(trace);
|
|
300
|
-
}
|
|
301
|
-
const endTime = performance.now();
|
|
302
|
-
|
|
303
|
-
// Adding logs should be very fast (non-blocking)
|
|
304
|
-
const duration = endTime - startTime;
|
|
305
|
-
assert(
|
|
306
|
-
duration < 100,
|
|
307
|
-
`Adding 100 logs took ${duration}ms, should be much faster`,
|
|
308
|
-
);
|
|
309
|
-
|
|
310
|
-
// Wait for flushes to complete
|
|
311
|
-
await delay(200);
|
|
312
|
-
|
|
313
|
-
// Should have logged some records
|
|
314
|
-
assert(buffer.length > 0, "Expected some records to be logged");
|
|
315
|
-
|
|
316
|
-
await sink[Symbol.asyncDispose]();
|
|
317
|
-
});
|
|
318
|
-
|
|
319
70
|
test("getConsoleSink()", () => {
|
|
320
71
|
// @ts-ignore: consolemock is not typed
|
|
321
72
|
const mock: ConsoleMock = makeConsoleMock();
|
|
@@ -506,176 +257,6 @@ test("getConsoleSink()", () => {
|
|
|
506
257
|
]);
|
|
507
258
|
});
|
|
508
259
|
|
|
509
|
-
test("getConsoleSink() with nonBlocking - simple boolean", async () => {
|
|
510
|
-
// @ts-ignore: consolemock is not typed
|
|
511
|
-
const mock: ConsoleMock = makeConsoleMock();
|
|
512
|
-
const sink = getConsoleSink({ console: mock, nonBlocking: true });
|
|
513
|
-
|
|
514
|
-
// Check that it returns a Disposable
|
|
515
|
-
assertInstanceOf(sink, Function);
|
|
516
|
-
assert(Symbol.dispose in sink);
|
|
517
|
-
|
|
518
|
-
// Add records - they should not be logged immediately
|
|
519
|
-
sink(trace);
|
|
520
|
-
sink(debug);
|
|
521
|
-
assertEquals(mock.history().length, 0); // Not logged yet
|
|
522
|
-
|
|
523
|
-
// Wait for flush interval (default 100ms)
|
|
524
|
-
await delay(150);
|
|
525
|
-
assertEquals(mock.history().length, 2); // Now they should be logged
|
|
526
|
-
|
|
527
|
-
// Dispose the sink
|
|
528
|
-
(sink as Sink & Disposable)[Symbol.dispose]();
|
|
529
|
-
});
|
|
530
|
-
|
|
531
|
-
test("getConsoleSink() with nonBlocking - custom buffer config", async () => {
|
|
532
|
-
// @ts-ignore: consolemock is not typed
|
|
533
|
-
const mock: ConsoleMock = makeConsoleMock();
|
|
534
|
-
const sink = getConsoleSink({
|
|
535
|
-
console: mock,
|
|
536
|
-
nonBlocking: {
|
|
537
|
-
bufferSize: 3,
|
|
538
|
-
flushInterval: 50,
|
|
539
|
-
},
|
|
540
|
-
});
|
|
541
|
-
|
|
542
|
-
// Add records up to buffer size
|
|
543
|
-
sink(trace);
|
|
544
|
-
sink(debug);
|
|
545
|
-
assertEquals(mock.history().length, 0); // Not flushed yet
|
|
546
|
-
|
|
547
|
-
sink(info); // This should trigger scheduled flush (buffer size = 3)
|
|
548
|
-
await delay(10); // Wait for scheduled flush to execute
|
|
549
|
-
assertEquals(mock.history().length, 3); // Flushed due to buffer size
|
|
550
|
-
|
|
551
|
-
// Add more records
|
|
552
|
-
sink(warning);
|
|
553
|
-
assertEquals(mock.history().length, 3); // Not flushed yet
|
|
554
|
-
|
|
555
|
-
// Wait for flush interval
|
|
556
|
-
await delay(60);
|
|
557
|
-
assertEquals(mock.history().length, 4); // Flushed due to interval
|
|
558
|
-
|
|
559
|
-
// Dispose and check remaining records are flushed
|
|
560
|
-
sink(error);
|
|
561
|
-
sink(fatal);
|
|
562
|
-
(sink as Sink & Disposable)[Symbol.dispose]();
|
|
563
|
-
assertEquals(mock.history().length, 6); // All records flushed on dispose
|
|
564
|
-
});
|
|
565
|
-
|
|
566
|
-
test("getConsoleSink() with nonBlocking - no operations after dispose", () => {
|
|
567
|
-
// @ts-ignore: consolemock is not typed
|
|
568
|
-
const mock: ConsoleMock = makeConsoleMock();
|
|
569
|
-
const sink = getConsoleSink({ console: mock, nonBlocking: true });
|
|
570
|
-
|
|
571
|
-
// Dispose immediately
|
|
572
|
-
(sink as Sink & Disposable)[Symbol.dispose]();
|
|
573
|
-
|
|
574
|
-
// Try to add records after dispose
|
|
575
|
-
sink(trace);
|
|
576
|
-
sink(debug);
|
|
577
|
-
|
|
578
|
-
// No records should be logged
|
|
579
|
-
assertEquals(mock.history().length, 0);
|
|
580
|
-
});
|
|
581
|
-
|
|
582
|
-
test("getConsoleSink() with nonBlocking - error handling", async () => {
|
|
583
|
-
const errorConsole = {
|
|
584
|
-
...console,
|
|
585
|
-
debug: () => {
|
|
586
|
-
throw new Error("Console error");
|
|
587
|
-
},
|
|
588
|
-
info: () => {
|
|
589
|
-
throw new Error("Console error");
|
|
590
|
-
},
|
|
591
|
-
warn: () => {
|
|
592
|
-
throw new Error("Console error");
|
|
593
|
-
},
|
|
594
|
-
error: () => {
|
|
595
|
-
throw new Error("Console error");
|
|
596
|
-
},
|
|
597
|
-
};
|
|
598
|
-
|
|
599
|
-
const sink = getConsoleSink({
|
|
600
|
-
console: errorConsole,
|
|
601
|
-
nonBlocking: true,
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
// Should not throw when adding records
|
|
605
|
-
sink(trace);
|
|
606
|
-
sink(info);
|
|
607
|
-
sink(error);
|
|
608
|
-
|
|
609
|
-
// Wait for flush - errors should be silently ignored
|
|
610
|
-
await delay(150);
|
|
611
|
-
|
|
612
|
-
// Dispose - should not throw
|
|
613
|
-
(sink as Sink & Disposable)[Symbol.dispose]();
|
|
614
|
-
});
|
|
615
|
-
|
|
616
|
-
test("getConsoleSink() with nonBlocking - buffer overflow protection", async () => {
|
|
617
|
-
// @ts-ignore: consolemock is not typed
|
|
618
|
-
const mock: ConsoleMock = makeConsoleMock();
|
|
619
|
-
const sink = getConsoleSink({
|
|
620
|
-
console: mock,
|
|
621
|
-
nonBlocking: {
|
|
622
|
-
bufferSize: 5,
|
|
623
|
-
flushInterval: 1000, // Long interval to prevent automatic flushing
|
|
624
|
-
},
|
|
625
|
-
});
|
|
626
|
-
|
|
627
|
-
// Add more records than 2x buffer size (which should trigger overflow protection)
|
|
628
|
-
for (let i = 0; i < 12; i++) {
|
|
629
|
-
sink(trace);
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
// Should have dropped oldest records, keeping buffer size manageable
|
|
633
|
-
// Wait a bit for any scheduled flushes
|
|
634
|
-
await delay(10);
|
|
635
|
-
|
|
636
|
-
// Force flush by disposing
|
|
637
|
-
(sink as Sink & Disposable)[Symbol.dispose]();
|
|
638
|
-
|
|
639
|
-
// Should have logged records, but not more than maxBufferSize (10)
|
|
640
|
-
const historyLength = mock.history().length;
|
|
641
|
-
assert(historyLength <= 10, `Expected <= 10 records, got ${historyLength}`);
|
|
642
|
-
assert(historyLength > 0, "Expected some records to be logged");
|
|
643
|
-
});
|
|
644
|
-
|
|
645
|
-
test("getConsoleSink() with nonBlocking - high volume non-blocking behavior", async () => {
|
|
646
|
-
// @ts-ignore: consolemock is not typed
|
|
647
|
-
const mock: ConsoleMock = makeConsoleMock();
|
|
648
|
-
const sink = getConsoleSink({
|
|
649
|
-
console: mock,
|
|
650
|
-
nonBlocking: {
|
|
651
|
-
bufferSize: 3,
|
|
652
|
-
flushInterval: 50,
|
|
653
|
-
},
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
// Simulate rapid logging - this should not block
|
|
657
|
-
const startTime = performance.now();
|
|
658
|
-
for (let i = 0; i < 100; i++) {
|
|
659
|
-
sink(trace);
|
|
660
|
-
}
|
|
661
|
-
const endTime = performance.now();
|
|
662
|
-
|
|
663
|
-
// Adding logs should be very fast (non-blocking)
|
|
664
|
-
const duration = endTime - startTime;
|
|
665
|
-
assert(
|
|
666
|
-
duration < 100,
|
|
667
|
-
`Adding 100 logs took ${duration}ms, should be much faster`,
|
|
668
|
-
);
|
|
669
|
-
|
|
670
|
-
// Wait for flushes to complete
|
|
671
|
-
await delay(200);
|
|
672
|
-
|
|
673
|
-
// Should have logged some records
|
|
674
|
-
assert(mock.history().length > 0, "Expected some records to be logged");
|
|
675
|
-
|
|
676
|
-
(sink as Sink & Disposable)[Symbol.dispose]();
|
|
677
|
-
});
|
|
678
|
-
|
|
679
260
|
test("withBuffer() - buffer size limit", async () => {
|
|
680
261
|
const buffer: LogRecord[] = [];
|
|
681
262
|
const sink = withBuffer(buffer.push.bind(buffer), { bufferSize: 3 });
|
|
@@ -800,7 +381,7 @@ test("withBuffer() - disposes underlying AsyncDisposable sink", async () => {
|
|
|
800
381
|
|
|
801
382
|
await bufferedSink[Symbol.asyncDispose]();
|
|
802
383
|
|
|
803
|
-
|
|
384
|
+
assertEquals(disposed, true); // Underlying sink should be disposed
|
|
804
385
|
});
|
|
805
386
|
|
|
806
387
|
test("withBuffer() - disposes underlying Disposable sink", async () => {
|
|
@@ -818,7 +399,7 @@ test("withBuffer() - disposes underlying Disposable sink", async () => {
|
|
|
818
399
|
|
|
819
400
|
await bufferedSink[Symbol.asyncDispose]();
|
|
820
401
|
|
|
821
|
-
|
|
402
|
+
assertEquals(disposed, true); // Underlying sink should be disposed
|
|
822
403
|
});
|
|
823
404
|
|
|
824
405
|
test("withBuffer() - handles non-disposable sink gracefully", async () => {
|
|
@@ -833,7 +414,7 @@ test("withBuffer() - handles non-disposable sink gracefully", async () => {
|
|
|
833
414
|
await bufferedSink[Symbol.asyncDispose]();
|
|
834
415
|
|
|
835
416
|
// This test passes if no error is thrown
|
|
836
|
-
|
|
417
|
+
assertEquals(true, true);
|
|
837
418
|
});
|
|
838
419
|
|
|
839
420
|
test("withBuffer() - edge case: bufferSize 1", async () => {
|
|
@@ -1016,7 +597,7 @@ test("withBuffer() - edge case: underlying AsyncDisposable throws error", async
|
|
|
1016
597
|
} catch (error) {
|
|
1017
598
|
assertInstanceOf(error, Error);
|
|
1018
599
|
assertEquals(error.message, "Dispose error");
|
|
1019
|
-
|
|
600
|
+
assertEquals(disposed, true); // Should still be disposed
|
|
1020
601
|
assertEquals(buffer.length, 1); // Buffer should have been flushed before dispose error
|
|
1021
602
|
}
|
|
1022
603
|
});
|
|
@@ -1253,5 +834,5 @@ test("fromAsyncSink() - empty async sink", async () => {
|
|
|
1253
834
|
await sink[Symbol.asyncDispose]();
|
|
1254
835
|
|
|
1255
836
|
// Test passes if no errors thrown
|
|
1256
|
-
|
|
837
|
+
assertEquals(true, true);
|
|
1257
838
|
});
|